def data(self, index, role): ''' PyQt API Method -- see PyQt for documentation ''' if not index.isValid(): return QVariant() node = index.internalPointer().node if node is None: return QVariant() # only override displaying of left column if index.column() != 0: return XmlModel.data(self, index, role) # give some nodes special icons if role == Qt.DecorationRole: if node.tag in ['structure', 'specification']: if node.getparent().tag == 'model': return QVariant(IconLibrary.icon('folder_development')) elif node.getparent().tag == 'structure': return QVariant(IconLibrary.icon('method')) elif node.getparent().tag == 'specification' and node.tag != 'submodel': # assume it's a submodel group return QVariant(IconLibrary.icon('folder_development')) # fall back on default return XmlModel.data(self, index, role)
def process_custom_menu(self, position): self.currentColumn = self.treeview.indexAt(position).column() self.currentIndex = self.treeview.indexAt(position) self.menu = QMenu(self.treeview) if self.currentIndex.isValid(): if self.model.fileInfo(self.currentIndex).suffix() == "txt": self.menu.addAction(self.actOpenTextFile) else: # Do stuff for directories export_choices, import_choices = self.fillInAvailableTools() if self.classification == "dataset" or self.classification == "database" or self.classification == "database_collection": self.export_menu = QMenu( QString('Export Opus %s to' % self.classification), self.treeview) self.export_menu.setIcon(IconLibrary.icon('export')) self.import_menu = QMenu( QString('Import Opus %s from' % self.classification), self.treeview) self.import_menu.setIcon(IconLibrary.icon('import')) if len(export_choices) > 0: self.export_dynactions = {} for export_type, tool_node in export_choices.iteritems( ): dynaction = QAction( IconLibrary.icon('spreadsheet'), export_type, self.treeview) self.export_menu.addAction(dynaction) self.export_dynactions[export_type] = tool_node QObject.connect(self.export_menu, SIGNAL("triggered(QAction*)"), self.dataActionMenuFunctionExport) self.menu.addMenu(self.export_menu) if len(import_choices) > 0: self.import_dynactions = {} for import_type, tool_node in import_choices.iteritems( ): dynaction = QAction( IconLibrary.icon('spreadsheet'), import_type, self.treeview) self.import_menu.addAction(dynaction) self.import_dynactions[import_type] = tool_node QObject.connect(self.import_menu, SIGNAL("triggered(QAction*)"), self.dataActionMenuFunctionImport) self.menu.addMenu(self.import_menu) self.menu.addSeparator() # We need to provide the option to open the dataset self.menu.addAction(self.actViewDataset) # Now tack on a refresh for all right clicks #print "Setting model refresh" self.menu.addAction(self.actRefresh) self.menu.exec_(QCursor.pos())
def __init__(self, mainwindow, text, detailed_text=None, mode=ERROR, flags=Qt.Dialog): QDialog.__init__(self, mainwindow, Qt.Dialog | Qt.WindowMaximizeButtonHint) self.setupUi(self) if mode == MessageBox.ERROR: img = IconLibrary.icon('messagebox_critical' ) #QPixmap(':/Images/Images/big_error.png') elif mode == MessageBox.WARNING: img = IconLibrary.icon( 'messagebox_warning' ) # QPixmap(':/Images/Images/big_warning.png') elif mode == MessageBox.INFORMATION: img = IconLibrary.icon( 'messagebox_info' ) # QPixmap(':/Images/Images/big_information.png') pixmap = img.pixmap(64, 64) self.lblImage.setPixmap(pixmap) self.lblText.setText('<qt><b>%s</b></qt>' % text) if detailed_text: self.lblDetailText.setText(QString(detailed_text)) else: self.pbnShowDetails.hide() self.details_showing = True self.detail_expansion_size = self.frame_details.height() + self.layout( ).spacing() self.on_pbnShowDetails_clicked()
def data(self, index, role): ''' PyQt API Method -- see PyQt for documentation ''' if not index.isValid(): return QVariant() node = index.internalPointer().node if node is None: return QVariant() # only override displaying of left column if index.column() != 0: return XmlModel.data(self, index, role) # give some nodes special icons if role == Qt.DecorationRole: if node.tag in ['structure', 'specification']: if node.getparent().tag == 'model': return QVariant(IconLibrary.icon('folder_development')) elif node.getparent().tag == 'structure': return QVariant(IconLibrary.icon('method')) elif node.getparent( ).tag == 'specification' and node.tag != 'submodel': # assume it's a submodel group return QVariant(IconLibrary.icon('folder_development')) # fall back on default return XmlModel.data(self, index, role)
def __init__(self, manager, data_path, parent_widget): FileController.__init__(self, manager, data_path, parent_widget) self.actRefresh = QAction(IconLibrary.icon('reload'), "Refresh Tree", self.treeview) QObject.connect(self.actRefresh, SIGNAL("triggered()"), self.refreshAction) self.actViewDataset = QAction(IconLibrary.icon('inspect'), "View Dataset", self.treeview) QObject.connect(self.actViewDataset, SIGNAL("triggered()"), self.viewDatasetAction) self.actOpenTextFile = QAction(IconLibrary.icon('text'), "Open Text File", self.treeview) QObject.connect(self.actOpenTextFile, SIGNAL("triggered()"), self.openTextFile) self.tool_library_node = self.manager.project.find('data_manager/tool_library')
def process_custom_menu(self, position): self.currentColumn = self.treeview.indexAt(position).column() self.currentIndex=self.treeview.indexAt(position) self.menu = QMenu(self.treeview) if self.currentIndex.isValid(): if self.model.fileInfo(self.currentIndex).suffix() == "txt": self.menu.addAction(self.actOpenTextFile) else: # Do stuff for directories export_choices, import_choices = self.fillInAvailableTools() if self.classification == "dataset" or self.classification == "database" or self.classification == "database_collection": self.export_menu = QMenu(QString('Export Opus %s to' % self.classification), self.treeview) self.export_menu.setIcon(IconLibrary.icon('export')) self.import_menu = QMenu(QString('Import Opus %s from' % self.classification), self.treeview) self.import_menu.setIcon(IconLibrary.icon('import')) if len(export_choices) > 0: self.export_dynactions = {} for export_type,tool_node in export_choices.iteritems(): dynaction = QAction(IconLibrary.icon('spreadsheet'), export_type, self.treeview) self.export_menu.addAction(dynaction) self.export_dynactions[export_type] = tool_node QObject.connect(self.export_menu, SIGNAL("triggered(QAction*)"), self.dataActionMenuFunctionExport) self.menu.addMenu(self.export_menu) if len(import_choices) > 0: self.import_dynactions = {} for import_type,tool_node in import_choices.iteritems(): dynaction = QAction(IconLibrary.icon('spreadsheet'), import_type, self.treeview) self.import_menu.addAction(dynaction) self.import_dynactions[import_type] = tool_node QObject.connect(self.import_menu, SIGNAL("triggered(QAction*)"), self.dataActionMenuFunctionImport) self.menu.addMenu(self.import_menu) self.menu.addSeparator() # We need to provide the option to open the dataset self.menu.addAction(self.actViewDataset) # Now tack on a refresh for all right clicks #print "Setting model refresh" self.menu.addAction(self.actRefresh) self.menu.exec_(QCursor.pos())
def _update_available_variables(self): # populate the list of available variables while considering A) what dataset filter the user # has selected, an d B) what variables that have already been selected) self.lst_available_variables.clear() if self.cbo_dataset_filter.currentIndex() > 0: dataset_filter = str(self.cbo_dataset_filter.currentText()) else: dataset_filter = None selected_variable_names = [node.get('name') for node in self.selector_table_model._variable_nodes] available_variable_nodes = [] variable_nodes_per_dataset = get_variable_nodes_per_dataset(self.project) if not dataset_filter: # take all variables for variable_nodes in variable_nodes_per_dataset.values(): available_variable_nodes.extend(variable_nodes) else: available_variable_nodes = variable_nodes_per_dataset[dataset_filter] available_variable_nodes.append(get_built_in_constant_node()) # filter already selected variables and show the list of available variables not_selected_variables = [var_node for var_node in available_variable_nodes if not var_node.get('name') in selected_variable_names] for variable_node in not_selected_variables: item = QtGui.QListWidgetItem(self.lst_available_variables) item.setIcon(IconLibrary.icon('variable')) item.node = variable_node # monkey in the node for adding later item.setText(get_variable_name(variable_node)) self.lst_available_variables.addItem(item) self.lst_available_variables.sortItems()
def process_custom_menu(self, point): ''' See XmlController for documentation ''' item = self.select_item_at(point) if not item: return menu = QMenu() node = item.node if node.get('executable') == 'True': menu.addAction(self.actRunScenario) elif node.get('type') in ['selectable', 'model_choice']: menu.addAction(self.actMoveNodeUp) menu.addAction(self.actMoveNodeDown) elif node.tag == 'models_to_run': # special case of a selectable list models_menu = QMenu(menu) models_menu.setTitle('Add model to run') models_menu.setIcon(IconLibrary.icon('add')) available_model_names = get_model_names(self.project) for model_name in available_model_names: cb = lambda x=model_name, y=self.selected_index( ): self.addModel(y, x) action = self.create_action('model', model_name, cb) models_menu.addAction(action) menu.addMenu(models_menu) self.add_default_menu_items_for_node(node, menu) if not menu.isEmpty(): menu.exec_(QCursor.pos())
def process_custom_menu(self, point): ''' See XmlController for documentation ''' item = self.select_item_at(point) if not item: return menu = QMenu() node = item.node if node.get('executable') == 'True': menu.addAction(self.actRunScenario) elif node.get('type') in ['selectable', 'model_choice']: menu.addAction(self.actMoveNodeUp) menu.addAction(self.actMoveNodeDown) elif node.tag == 'models_to_run': # special case of a selectable list models_menu = QMenu(menu) models_menu.setTitle('Add model to run') models_menu.setIcon(IconLibrary.icon('add')) available_model_names = get_model_names(self.project) for model_name in available_model_names: cb = lambda x = model_name, y = self.selected_index(): self.addModel(y, x) action = self.create_action('model', model_name, cb) models_menu.addAction(action) menu.addMenu(models_menu) self.add_default_menu_items_for_node(node, menu) if not menu.isEmpty(): menu.exec_(QCursor.pos())
def add_custom_menu_items_for_node(self, node, menu): if node.get('type') == 'scenario': node_executable = (node.get('executable') == 'True') menu.addAction(self.actExecutable) # Workaround: disabled items do not show check marks if node.get('inherited') is None: self.actExecutable.setEnabled(True) self.actExecutable.setText('Executable') self.actExecutable.setChecked(node_executable) else: self.actExecutable.setDisabled(True) self.actExecutable.setText('Executable: %s' % ('Yes' if node_executable else 'No')) if node_executable: menu.addAction(self.actRunScenario) if node.find('models_to_run') is None: #if there isn't a child node models_to_run menu.addAction(self.actModelsToRun) elif node.get('type') in ['selectable', 'model_choice']: menu.addAction(self.actMoveNodeUp) menu.addAction(self.actMoveNodeDown) elif node.tag == 'models_to_run': # special case of a selectable list models_menu = QMenu(menu) models_menu.setTitle('Add model to run') models_menu.setIcon(IconLibrary.icon('add')) available_model_names = get_model_names(self.project) for model_name in available_model_names: cb = lambda x = model_name, y = self.selected_index(): self.addModel(y, x) action = self.create_action('model', model_name, cb) models_menu.addAction(action) menu.addMenu(models_menu)
def openLogTab(self): ''' Open a log viewer ''' if self.tabWidget.indexOf(self.log_tab) == -1: self.tabWidget.insertTab(0, self.log_tab, IconLibrary.icon('table'), 'Log Window') self.log_tab.do_refresh() self.tabWidget.setCurrentWidget(self.log_tab)
def add_custom_menu_items_for_node(self, node, menu): if node.get('type') == 'scenario': node_executable = (node.get('executable') == 'True') menu.addAction(self.actExecutable) # Workaround: disabled items do not show check marks if node.get('inherited') is None: self.actExecutable.setEnabled(True) self.actExecutable.setText('Executable') self.actExecutable.setChecked(node_executable) else: self.actExecutable.setDisabled(True) self.actExecutable.setText( 'Executable: %s' % ('Yes' if node_executable else 'No')) if node_executable: menu.addAction(self.actRunScenario) if node.find('models_to_run') is None: #if there isn't a child node models_to_run menu.addAction(self.actModelsToRun) elif node.get('type') in ['selectable', 'model_choice']: menu.addAction(self.actMoveNodeUp) menu.addAction(self.actMoveNodeDown) elif node.tag == 'models_to_run': # special case of a selectable list models_menu = QMenu(menu) models_menu.setTitle('Add model to run') models_menu.setIcon(IconLibrary.icon('add')) available_model_names = get_model_names(self.project) for model_name in available_model_names: cb = lambda x=model_name, y=self.selected_index( ): self.addModel(y, x) action = self.create_action('model', model_name, cb) models_menu.addAction(action) menu.addMenu(models_menu)
def on_pbnShowDetails_released(self): if self.details_showing: self.detail_expansion_size = self.frame_details.height() + self.layout().spacing() self.details_showing = False self.pbnShowDetails.setText("Show Details...") self.pbnShowDetails.setIcon(IconLibrary.icon("arrow_right")) self.setUpdatesEnabled(False) self.frame_details.hide() self.resize(self.width(), self.height() - self.detail_expansion_size) self.setUpdatesEnabled(True) self.adjustSize() else: self.pbnShowDetails.setText("Hide Details...") self.pbnShowDetails.setIcon(IconLibrary.icon("arrow_down")) self.details_showing = True self.frame_details.show() self.adjustSize()
def _generate_widgets(self): ''' Iterate over all templated nodes and create a field (hidden or with a widget) for each. ''' self.fields_to_data_methods = {} self.widgets = [] # PyQt is buggy about removing dynamic widgets, so we need to be very explicit here while self.dynamic_widgets.count() > 0: item = self.dynamic_widgets.takeAt(0) widget = item.widget() widget.hide() widget.deleteLater() del widget del item # fetch all nodes that have a field_identifier attribute on them and index them by # this attribute (field_identifier -> xml node) templated_nodes = [(n.get('field_identifier'), n) for n in self.model_node.getiterator() if n.get('field_identifier') is not None] for field_id, node in templated_nodes: if field_id in self.fields_to_data_methods: continue # field_id already mapped to a widget + data-method widget, data_method = self._widget_and_method_for_template_node( node) # ensure that the data-method return clean Python strings self.fields_to_data_methods[field_id] = lambda fn=data_method: str( fn()).strip() if widget is not None: current_row = len(self.widgets) label = QtGui.QLabel(field_id) label.setMinimumWidth(100) label.setSizePolicy(self.label_size_policy) self.dynamic_widgets.addWidget(label, current_row, 0) widget.setSizePolicy(self.widget_size_policy) self.dynamic_widgets.addWidget(widget, current_row, 1) field_description = node.get('field_description') if field_description: description_label = QtGui.QLabel() description_label.setSizePolicy( self.description_size_policy) description_label.setPixmap( IconLibrary.icon('info_small').pixmap(32, 32)) desc = '<qt><b>%s</b><br/>%s</qt>' % (field_id, field_description) description_label.setToolTip(desc) self.dynamic_widgets.addWidget(description_label, current_row, 2) else: description_label = None # keep a list of widgets for testing purposes self.widgets.append((label, widget, description_label))
def on_pbnShowDetails_clicked(self): if self.details_showing: self.detail_expansion_size = self.frame_details.height( ) + self.layout().spacing() self.details_showing = False self.pbnShowDetails.setText('Show Details...') self.pbnShowDetails.setIcon(IconLibrary.icon('arrow_right')) self.setUpdatesEnabled(False) self.frame_details.hide() self.resize(self.width(), self.height() - self.detail_expansion_size) self.setUpdatesEnabled(True) self.adjustSize() else: self.pbnShowDetails.setText('Hide Details...') self.pbnShowDetails.setIcon(IconLibrary.icon('arrow_down')) self.details_showing = True self.frame_details.show() self.adjustSize()
def __init__(self, mainwindow, text, detailed_text=None, mode=ERROR, flags=Qt.Dialog): QDialog.__init__(self, mainwindow, Qt.Dialog | Qt.WindowMaximizeButtonHint) self.setupUi(self) if mode == MessageBox.ERROR: img = IconLibrary.icon("messagebox_critical") # QPixmap(':/Images/Images/big_error.png') elif mode == MessageBox.WARNING: img = IconLibrary.icon("messagebox_warning") # QPixmap(':/Images/Images/big_warning.png') elif mode == MessageBox.INFORMATION: img = IconLibrary.icon("messagebox_info") # QPixmap(':/Images/Images/big_information.png') pixmap = img.pixmap(64, 64) self.lblImage.setPixmap(pixmap) self.lblText.setText("<qt><b>%s</b></qt>" % text) if detailed_text: self.lblDetailText.setText(QString(detailed_text)) else: self.pbnShowDetails.hide() self.details_showing = True self.detail_expansion_size = self.frame_details.height() + self.layout().spacing() self.on_pbnShowDetails_released()
def __init__(self, project, parent_widget): QWidget.__init__(self, parent_widget) self.setupUi(self) self.project = project #TODO handle this as the variables are handled try: obj = get_manager_instance('results').xml_controller.model self.connect(obj, SIGNAL("layoutChanged()"), self._setup_simulation_data) except AttributeError: pass def test(): print 'Variables updated' self.connect(get_mainwindow_instance(), SIGNAL('variables_updated'), test) tool_tip = ('If checked, indicator results will automatically be\n' 'created for the currently selected simulation run,\n' 'indicator, and years. If unchecked, click\n' 'Generate results in order to make results available.') self.cb_auto_gen.setToolTip(tool_tip) self.inGui = False self.logFileKey = 0 self.available_years_for_simulation_runs = {} self.current_indicator = '' self.current_indicator_dataset = '' self.current_run = '' self.current_year = '' self._update_current_label() self.running_key = None self.queued_results = None self.setup = True self._setup_available_indicators() self._setup_simulation_data() self.setup = False self.already_browsed = {} self.generating_results = False if self.cb_auto_gen.isChecked(): self.on_pb_generate_results_clicked() # self.pb_export_results.setEnabled(False) self.tabwidget_visualizations.removeTab(0) self.tabIcon = IconLibrary.icon('table') self.tabLabel = "Result Browser"
def __init__(self, project, parent_widget): QWidget.__init__(self, parent_widget) self.setupUi(self) self.project = project # TODO handle this as the variables are handled try: obj = get_manager_instance("results").xml_controller.model self.connect(obj, SIGNAL("layoutChanged()"), self._setup_simulation_data) except AttributeError: pass def test(): print "Variables updated" self.connect(get_mainwindow_instance(), SIGNAL("variables_updated"), test) tool_tip = ( "If checked, indicator results will automatically be\n" "created for the currently selected simulation run,\n" "indicator, and years. If unchecked, click\n" "Generate results in order to make results available." ) self.cb_auto_gen.setToolTip(tool_tip) self.inGui = False self.logFileKey = 0 self.available_years_for_simulation_runs = {} self.current_indicator = "" self.current_indicator_dataset = "" self.current_run = "" self.current_year = "" self._update_current_label() self.running_key = None self.queued_results = None self.setup = True self._setup_available_indicators() self._setup_simulation_data() self.setup = False self.already_browsed = {} self.generating_results = False if self.cb_auto_gen.isChecked(): self.on_pb_generate_results_clicked() # self.pb_export_results.setEnabled(False) self.tabwidget_visualizations.removeTab(0) self.tabIcon = IconLibrary.icon("table") self.tabLabel = "Result Browser"
def __init__(self, manager, data_path, parent_widget): FileController.__init__(self, manager, data_path, parent_widget) self.actRefresh = QAction(IconLibrary.icon('reload'), "Refresh Tree", self.treeview) QObject.connect(self.actRefresh, SIGNAL("triggered()"), self.refreshAction) self.actViewDataset = QAction(IconLibrary.icon('inspect'), "View Dataset", self.treeview) QObject.connect(self.actViewDataset, SIGNAL("triggered()"), self.viewDatasetAction) self.actOpenTextFile = QAction(IconLibrary.icon('text'), "Open Text File", self.treeview) QObject.connect(self.actOpenTextFile, SIGNAL("triggered()"), self.openTextFile) self.tool_library_node = self.manager.project.find( 'data_manager/tool_library')
def __init__(self, project, parent_widget=None): QDialog.__init__(self, parent_widget, Qt.Window) self.setupUi(self) self.project = project # Change PICK MODE to true for old school selector self.variables_table = VariablesTableView(parent_widget = self) self.original_nodes = set() self.cancel_validation_flag = {'value': False} self.model = None self.problem_variables = [] self.pb_create_new.setIcon(IconLibrary.icon('add')) self.initialize() self.table_container.addWidget(self.variables_table) # Automatically update the save button state on model data change self.connect(self.model, SIGNAL('model_changed'), self._update_apply_button) # Automatically enable or disable the validate selected vars button def on_sel_change(dummy_a, dummy_b): enabled = len(self.variables_table.selectedIndexes()) > 0 self.pb_validate_selected.setEnabled(enabled) sel_changed = SIGNAL('selectionChanged(const QItemSelection&,const QItemSelection&)') self.connect(self.variables_table.selectionModel(), sel_changed, on_sel_change) # Double clicking an item in the table brings up the editor def edit_wrapper(index): variable = self.model.variables[index.row()] if not variable['inherited']: self._edit_variable(variable) self.connect(self.variables_table, SIGNAL('doubleClicked(QModelIndex)'), edit_wrapper) def apply_and_close(): self._apply_variable_changes() self.accept() def cancel_validation(): self.cancel_validation_flag['value'] = True self.connect(self.pb_apply_and_close, SIGNAL("clicked()"), apply_and_close) self.connect(self.pb_apply, SIGNAL("clicked()"), self._apply_variable_changes) self.connect(self.pb_create_new, SIGNAL("clicked()"), self._add_variable) self.connect(self.pb_problems, SIGNAL("clicked()"), self._show_problem_variables) self.connect(self.pb_cancel_validation, SIGNAL("clicked()"), cancel_validation) signal = SIGNAL('customContextMenuRequested(const QPoint &)') self.connect(self.variables_table, signal, self._show_right_click_menu) signal = SIGNAL('currentIndexChanged(int)') self.connect(self.cbo_dataset_filter, signal, lambda x: self._set_dataset_filter()) self.validator = VariableValidator(self.project) self.editor = VariableEditor(self)
def _right_click_variables(self, point): ''' construct and show an operations operations_menu when the user right clicks the variable selector ''' operations_menu = QtGui.QMenu(self) add_variable_menu = self._create_add_variable_menu() add_variable_menu.setTitle('Add a variable') add_variable_menu.setIcon(IconLibrary.icon('add')) operations_menu.addMenu(add_variable_menu) index_under_cursor = self.table_selected_variables.indexAt(point) if index_under_cursor.isValid(): row = index_under_cursor.row() variable_node = self.selector_table_model.get_variable(row) self.table_selected_variables.selectRow(row) action = create_qt_action( None, 'Remove %s' % get_variable_name(variable_node), self._remove_selected_variables, self.table_selected_variables) action.setIcon(IconLibrary.icon('delete')) operations_menu.addAction(action) else: # if the index is not valid -- assume that the user clicked the "white space" of the table pass operations_menu.exec_(QtGui.QCursor.pos())
def _right_click_variables(self, point): ''' construct and show an operations operations_menu when the user right clicks the variable selector ''' operations_menu = QtGui.QMenu(self) add_variable_menu = self._create_add_variable_menu() add_variable_menu.setTitle('Add a variable') add_variable_menu.setIcon(IconLibrary.icon('add')) operations_menu.addMenu(add_variable_menu) index_under_cursor = self.table_selected_variables.indexAt(point) if index_under_cursor.isValid(): row = index_under_cursor.row() variable_node = self.selector_table_model.get_variable(row) self.table_selected_variables.selectRow(row) action = create_qt_action(None, 'Remove %s' % get_variable_name(variable_node), self._remove_selected_variables, self.table_selected_variables) action.setIcon(IconLibrary.icon('delete')) operations_menu.addAction(action) else: # if the index is not valid -- assume that the user clicked the "white space" of the table pass operations_menu.exec_(QtGui.QCursor.pos())
def _generate_widgets(self): ''' Iterate over all templated nodes and create a field (hidden or with a widget) for each. ''' self.fields_to_data_methods = {} self.widgets = [] # PyQt is buggy about removing dynamic widgets, so we need to be very explicit here while self.dynamic_widgets.count() > 0: item = self.dynamic_widgets.takeAt(0) widget = item.widget() widget.hide() widget.deleteLater() del widget del item # fetch all nodes that have a field_identifier attribute on them and index them by # this attribute (field_identifier -> xml node) templated_nodes = [(n.get('field_identifier'), n) for n in self.model_node.getiterator() if n.get('field_identifier') is not None] for field_id, node in templated_nodes: if field_id in self.fields_to_data_methods: continue # field_id already mapped to a widget + data-method widget, data_method = self._widget_and_method_for_template_node(node) # ensure that the data-method return clean Python strings self.fields_to_data_methods[field_id] = lambda fn = data_method: str(fn()).strip() if widget is not None: current_row = len(self.widgets) label = QtGui.QLabel(field_id) label.setMinimumWidth(100) label.setSizePolicy(self.label_size_policy) self.dynamic_widgets.addWidget(label, current_row, 0) widget.setSizePolicy(self.widget_size_policy) self.dynamic_widgets.addWidget(widget, current_row, 1) field_description = node.get('field_description') if field_description: description_label = QtGui.QLabel() description_label.setSizePolicy(self.description_size_policy) description_label.setPixmap(IconLibrary.icon('info_small').pixmap(32, 32)) desc = '<qt><b>%s</b><br/>%s</qt>' % (field_id, field_description) description_label.setToolTip(desc) self.dynamic_widgets.addWidget(description_label, current_row, 2) else: description_label = None # keep a list of widgets for testing purposes self.widgets.append((label, widget, description_label))
def create_qt_action(icon_name, text, callback, parent_qt_object): ''' Convenience method to create actions. @param icon_name (str) name of icon to use (no Icon is used of the value is None) @param text (str) action label @param callback (function) callback function to call when triggered (no parameters) @param parent_qt_object (QObject) parent object of action @return: the created action (QAction) ''' if icon_name is None: action = QtGui.QAction(text, parent_qt_object) else: action = QtGui.QAction(IconLibrary.icon(icon_name), text, parent_qt_object) QObject.connect(action, SIGNAL('triggered()'), callback) return action
def initialize(self): # reset the variable library to reflect the current state of expression library in xml nodes_per_dataset = get_variable_nodes_per_dataset(self.project) variables = [] all_original_nodes = set() for dataset in nodes_per_dataset: for variable_node in nodes_per_dataset[dataset]: new_variable = variable_from_node(variable_node) new_variable['originalnode'] = variable_node variables.append(new_variable) all_original_nodes.add( variable_node) # save original values for comparison self.original_nodes = all_original_nodes self.cancel_validation_flag = {'value': False} # to avoid quirky behavior when applying changes, store the column widths and restore them # after the model update col_widths = [ self.variables_table.columnWidth(col) for col in range(5) ] # bind to self to prevent PyQt from "losing" the object ref self.model = VariablesTableModel(project=self.project, variables=variables, parent_widget=self.variables_table) self.variables_table.setModel(self.model) self.model.re_sort() self.connect(self.model, SIGNAL('layoutChanged()'), self.variables_table.resizeRowsToContents) self._update_apply_button() self.group_progress.setVisible(False) self.pb_problems.setIcon(IconLibrary.icon('warning_small')) self.pb_problems.setAttribute(Qt.WA_AlwaysShowToolTips) self._set_problem_variables([]) self._update_dataset_filter() # use the inital size if the column widths is all zeroes if sum(abs(w) for w in col_widths) == 0: col_widths = [195, 80, 45, 50, -1] for col in range(5): if col_widths[col] > 0: self.variables_table.setColumnWidth(col, col_widths[col]) self.variables_table.resizeRowsToContents()
def data(self, index, role): ''' PyQt API Method -- See the PyQt documentation for a description ''' # Handle special drawing of missing models node = index.internalPointer().node if node.tag != 'model' or node.get('name') not in self.missing_models: # Not a missing model -- use default data handler return XmlModel.data(self, index, role) # Missing models get a colored description label and a special icon if index.column() == 1: if role == Qt.ForegroundRole: return QVariant(QColor(Qt.red)) elif role == Qt.DisplayRole: return QVariant("(no such model)") # Give it a special icon elif role == Qt.DecorationRole and index.column() == 0: return QVariant(IconLibrary.icon('missing_model')) # Other data properties are handled by the default data() method return XmlModel.data(self, index, role)
def data(self, index, role): """ PyQt API Method -- See the PyQt documentation for a description """ # Handle special drawing of missing models node = index.internalPointer().node if node.tag != "model" or node.get("name") not in self.missing_models: # Not a missing model -- use default data handler return XmlModel.data(self, index, role) # Missing models get a colored description label and a special icon if index.column() == 1: if role == Qt.ForegroundRole: return QVariant(QColor(Qt.red)) elif role == Qt.DisplayRole: return QVariant("(no such model)") # Give it a special icon elif role == Qt.DecorationRole and index.column() == 0: return QVariant(IconLibrary.icon("missing_model")) # Other data properties are handled by the default data() method return XmlModel.data(self, index, role)
def initialize(self): # reset the variable library to reflect the current state of expression library in xml nodes_per_dataset = get_variable_nodes_per_dataset(self.project) variables = [] all_original_nodes = set() for dataset in nodes_per_dataset: for variable_node in nodes_per_dataset[dataset]: new_variable = variable_from_node(variable_node) new_variable['originalnode'] = variable_node variables.append(new_variable) all_original_nodes.add(variable_node) # save original values for comparison self.original_nodes = all_original_nodes self.cancel_validation_flag = {'value': False} # to avoid quirky behavior when applying changes, store the column widths and restore them # after the model update col_widths = [self.variables_table.columnWidth(col) for col in range(5)] # bind to self to prevent PyQt from "losing" the object ref self.model = VariablesTableModel(project = self.project, variables = variables, parent_widget = self.variables_table) self.variables_table.setModel(self.model) self.model.re_sort() self.connect(self.model, SIGNAL('layoutChanged()'), self.variables_table.resizeRowsToContents) self._update_apply_button() self.group_progress.setVisible(False) self.pb_problems.setIcon(IconLibrary.icon('warning_small')) self.pb_problems.setAttribute(Qt.WA_AlwaysShowToolTips) self._set_problem_variables([]) self._update_dataset_filter() # use the inital size if the column widths is all zeroes if sum(abs(w) for w in col_widths) == 0: col_widths = [195, 80, 45, 50, -1] for col in range(5): if col_widths[col] > 0: self.variables_table.setColumnWidth(col, col_widths[col]) self.variables_table.resizeRowsToContents()
def _createBatchRunMenu(self, attach_to_menu): ''' Create and populate a 'Run indicator batch' menu for all available runs @param attach_to_menu (QMenu) menu to attach actions to ''' # TODO Verify that this is correct -- it was based on looking in a xml # file for 'source_data' and simulation_runs was the only section I # could find it in. run_nodes = get_available_run_nodes(self.project) if not run_nodes: attach_to_menu.setEnabled(False) return #T: the following loop causes a problem where # only "baseyear_data" will be passed to the _indicatorBatchRun method. # I don't know why. for run_node in run_nodes: cb = lambda x = run_node.get('name'): self._indicatorBatchRun(run_name = x) action = self.create_action(IconLibrary.icon('add'), run_node.get('name'), cb) attach_to_menu.addAction(action)
def _update_available_variables(self): # populate the list of available variables while considering A) what dataset filter the user # has selected, an d B) what variables that have already been selected) self.lst_available_variables.clear() if self.cbo_dataset_filter.currentIndex() > 0: dataset_filter = str(self.cbo_dataset_filter.currentText()) else: dataset_filter = None selected_variable_names = [ node.get('name') for node in self.selector_table_model._variable_nodes ] available_variable_nodes = [] variable_nodes_per_dataset = get_variable_nodes_per_dataset( self.project) if not dataset_filter: # take all variables for variable_nodes in variable_nodes_per_dataset.values(): available_variable_nodes.extend(variable_nodes) else: available_variable_nodes = variable_nodes_per_dataset[ dataset_filter] available_variable_nodes.append(get_built_in_constant_node()) # filter already selected variables and show the list of available variables not_selected_variables = [ var_node for var_node in available_variable_nodes if not var_node.get('name') in selected_variable_names ] for variable_node in not_selected_variables: item = QtGui.QListWidgetItem(self.lst_available_variables) item.setIcon(IconLibrary.icon('variable')) item.node = variable_node # monkey in the node for adding later item.setText(get_variable_name(variable_node)) self.lst_available_variables.addItem(item) self.lst_available_variables.sortItems()
def __init__(self, mainwindow, modelsManagerBase, estimation): QWidget.__init__(self, mainwindow) self.setupUi(self) self.mainwindow = mainwindow self.estimation = estimation self.estimation.guiElement = self self.inGui = False self.running = False self.paused = False self.timer = None self.runThread = None self.manager = modelsManagerBase self.tabIcon = IconLibrary.icon('estimation') self.tabLabel = QString('%s estimation'%estimation.model_name) # LAYOUT FOR THE MODEL ELEMENT IN THE GUI self.runProgressBar.setProperty("value",QVariant(0)) self.runProgressBar.reset()
def __init__(self, mainwindow, modelsManagerBase, estimation): QWidget.__init__(self, mainwindow) self.setupUi(self) self.mainwindow = mainwindow self.estimation = estimation self.estimation.guiElement = self self.inGui = False self.running = False self.paused = False self.timer = None self.runThread = None self.manager = modelsManagerBase self.tabIcon = IconLibrary.icon('estimation') self.tabLabel = QString('%s estimation' % estimation.model_name) # LAYOUT FOR THE MODEL ELEMENT IN THE GUI self.runProgressBar.setProperty("value", QVariant(0)) self.runProgressBar.reset()
def data(self, index, role): if not index.isValid(): return QVariant() row = index.row() header = self._headers[index.column()] node = self._variable_nodes[row] # look up the definition once for easy access by multiple roles if header == self.HEADER_DEFINITION: dataset, name = get_variable_dataset_and_name(node) if name == 'constant': definition = '<built-in constant>' elif (name, dataset) in self._names_to_definition_nodes: definition_node = self._names_to_definition_nodes[(name, dataset)] if definition_node is not None: definition = definition_node.text else: definition = '<empty definition>' else: definition = '<unknown definition>' if role == Qt.DecorationRole: if header == self.HEADER_VARIABLE: return QVariant(IconLibrary.icon('variable')) if role == Qt.DisplayRole: var_name = get_variable_name(self._variable_nodes[row]) if header == self.HEADER_VARIABLE: return QVariant(var_name) if header == self.HEADER_DEFINITION: return QVariant(definition) if header == self.HEADER_COEFF_NAME: if 'coefficient_name' in node.attrib: return QVariant(node.get('coefficient_name')) return QVariant(var_name) if header == self.HEADER_STARTING_VAL: return QVariant(node.get('starting_value') or '') if role == Qt.EditRole: if header == self.HEADER_STARTING_VAL: return self.data(index, Qt.DisplayRole) if header == self.HEADER_COEFF_NAME: # give a clear coeff name if it's not set yet if 'coefficient_name' in node.attrib: return QVariant(node.get('coefficient_name')) return QVariant() if role == Qt.CheckStateRole: if header == self.HEADER_IGNORE: return QVariant(Qt.Checked if node.get('ignore') == 'True' else Qt.Unchecked) if header == self.HEADER_FIXED: return QVariant(Qt.Checked if node.get('keep_fixed') == 'True' else Qt.Unchecked) if role == Qt.FontRole: font = QtGui.QFont() if header == self.HEADER_VARIABLE: if node.get('ignore') != 'True': font.setBold(True) return QVariant(font) elif header == self.HEADER_COEFF_NAME and node.get('coefficient_name'): font.setBold(True) return QVariant(font) if role == Qt.ForegroundRole: # color default values of coefficient name as light gray if header == self.HEADER_COEFF_NAME: if 'coefficient_name' not in node.attrib: return QVariant(QtGui.QColor(Qt.gray)) if role == Qt.ToolTipRole: if header == self.HEADER_DEFINITION: # defs easily get cramped so show in tool tip as well return QVariant(definition) return QVariant()
def _generate_widgets(self): ''' Iterate over all templated nodes and create a field (hidden or with a widget) for each. Note that the behavior is undefined when multiple nodes have the same field_identifier but different node types. ''' self.data_extractors = { } # value extracting method for each field identifier self.widgets = [] # list of widgets to populate the GUI with # sizing policies for the generated widgets label_size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding) widget_size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) description_size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) def get_widget_label(text): ''' Helper to generate a QLabel containing the given text ''' l = QtGui.QLabel(field_id) l.setMinimumWidth(100) l.setSizePolicy(label_size_policy) return l # Remove the existing widgets. PyQt is buggy about removing dynamic widgets, # so we need to explicitly call deleteLater() and 'del' the Python objects while self.dynamic_widgets.count() > 0: item = self.dynamic_widgets.takeAt(0) widget = item.widget() widget.hide() widget.deleteLater() del widget del item prev_widget = self.le_project_filename # prev_widget is used to link the tab order of widgets # create a widget for each field_identifier for field_id, nodes in self.fields_to_nodes.items(): # pick the first node out of the list of nodes for this field identifier (there are at least one) node = nodes[0] current_row = len( self.widgets ) # keep track of where to insert widgets (top to bottom) # get a suitable widget and a data-extrating method for the node widget, data_extractor = self._get_widget_and_method_from_node_type( node) self.data_extractors[ field_id] = data_extractor # map the field_identifier to the data extractor label = get_widget_label(field_id) self.dynamic_widgets.addWidget(label, current_row, 0) widget.setSizePolicy(widget_size_policy ) # make the widget expand to fill it's space self.dynamic_widgets.addWidget(widget, current_row, 1) # set the tab order so we get a nice tab flow between fields self.setTabOrder(prev_widget, widget) prev_widget = widget # an information widget is created if the templated node contains the optional field_description # argument was given field_description = node.get('field_description') if field_description: description_label = QtGui.QLabel() description_label.setSizePolicy(description_size_policy) description_label.setPixmap( IconLibrary.icon('info_small').pixmap(32, 32)) desc = '<qt><b>%s</b><br/>%s</qt>' % (field_id, field_description) description_label.setToolTip(desc) self.dynamic_widgets.addWidget(description_label, current_row, 2) else: description_label = None self.widgets.append(widget)
def _generate_widgets(self): ''' Iterate over all templated nodes and create a field (hidden or with a widget) for each. Note that the behavior is undefined when multiple nodes have the same field_identifier but different node types. ''' self.data_extractors = {} # value extracting method for each field identifier self.widgets = [] # list of widgets to populate the GUI with # sizing policies for the generated widgets label_size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding) widget_size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) description_size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) def get_widget_label(text): ''' Helper to generate a QLabel containing the given text ''' l = QtGui.QLabel(field_id) l.setMinimumWidth(100) l.setSizePolicy(label_size_policy) return l # Remove the existing widgets. PyQt is buggy about removing dynamic widgets, # so we need to explicitly call deleteLater() and 'del' the Python objects while self.dynamic_widgets.count() > 0: item = self.dynamic_widgets.takeAt(0) widget = item.widget() widget.hide() widget.deleteLater() del widget del item prev_widget = self.le_project_filename # prev_widget is used to link the tab order of widgets # create a widget for each field_identifier for field_id, nodes in self.fields_to_nodes.items(): # pick the first node out of the list of nodes for this field identifier (there are at least one) node = nodes[0] current_row = len(self.widgets) # keep track of where to insert widgets (top to bottom) # get a suitable widget and a data-extrating method for the node widget, data_extractor = self._get_widget_and_method_from_node_type(node) self.data_extractors[field_id] = data_extractor # map the field_identifier to the data extractor label = get_widget_label(field_id) self.dynamic_widgets.addWidget(label, current_row, 0) widget.setSizePolicy(widget_size_policy) # make the widget expand to fill it's space self.dynamic_widgets.addWidget(widget, current_row, 1) # set the tab order so we get a nice tab flow between fields self.setTabOrder(prev_widget, widget) prev_widget = widget # an information widget is created if the templated node contains the optional field_description # argument was given field_description = node.get('field_description') if field_description: description_label = QtGui.QLabel() description_label.setSizePolicy(description_size_policy) description_label.setPixmap(IconLibrary.icon('info_small').pixmap(32, 32)) desc = '<qt><b>%s</b><br/>%s</qt>' % (field_id, field_description) description_label.setToolTip(desc) self.dynamic_widgets.addWidget(description_label, current_row, 2) else: description_label = None self.widgets.append(widget)
def viewDatasetAction(self): #print "viewDatasetAction" model = self.model table_name = str(model.fileName(self.currentIndex)) table_name_full = str(model.filePath(self.currentIndex)) parentIndex = model.parent(self.currentIndex) parent_name = str(model.fileName(parentIndex)) parent_name_full = str(model.filePath(parentIndex)) storage = StorageFactory().get_storage('flt_storage', storage_location=parent_name_full) columns = storage.get_column_names(table_name) # temporarily use the table name for the dataset name # dataset_name = DatasetFactory().dataset_name_for_table(table_name) # Aaron - please check this way of getting the XMLConfiguration -- is this the best way? # general = self.mainwindow.toolboxBase.opus_core_xml_configuration.get_section('general') # # problem: this gets the package order for the current project, but the viewer shows all the data # package_order = general['dataset_pool_configuration'].package_order # PREVIOUS HACK: # package_order = ['seattle_parcel','urbansim_parcel', 'eugene', 'urbansim', 'opus_core'] # temporary code: just use a generic dataset for now data = Dataset(in_storage=storage, dataset_name=table_name, in_table_name=table_name, id_name=[]) # code to get a more specialized dataset if possible (doesn't work with table names not ending in 's' # unless they are in the exceptions list in DatasetFactory) # data = DatasetFactory().search_for_dataset_with_hidden_id(dataset_name, package_order, # arguments={'in_storage': storage, 'in_table_name': table_name}) # Need to add a new tab to the main tabs for display of the data container = QWidget() widgetLayout = QVBoxLayout(container) summaryGroupBox = QGroupBox(container) summaryGroupBox.setTitle(QString("Year: %s Run name: %s" % (parent_name,table_name_full.split('/')[-3]))) summaryGroupBox.setFlat(True) summaryGroupBoxLayout = QVBoxLayout(summaryGroupBox) # Grab the summary data buffer = StringIO() data.summary(output=buffer) strng = buffer.getvalue() buffer.close() textBrowser = QTextBrowser() # textBrowser.insertPlainText(strng) textBrowser.insertHtml(self.parse_dataset_summary(strng)) summaryGroupBoxLayout.addWidget(textBrowser) widgetLayout.addWidget(summaryGroupBox) tableGroupBox = QGroupBox(container) tableGroupBox.setTitle(QString("Table View")) tableGroupBox.setFlat(True) tableGroupBoxLayout = QVBoxLayout(tableGroupBox) tv = QTableView() header = columns tabledata_tmp = [] for column in columns: tabledata_tmp.append(data.get_attribute(column)) # Transpose the lists tabledata = map(None,*tabledata_tmp) # If the table data is not empty then we display it if tabledata: #tv.resizeColumnsToContents() tm = TableModel(tabledata, header, container) tv.setModel(tm) tv.setSortingEnabled(True) tableGroupBoxLayout.addWidget(tv) widgetLayout.addWidget(tableGroupBox) container.tabIcon = IconLibrary.icon('inspect') container.tabLabel = QString(table_name) self.manager._attach_tab(container)
def data(self, index, role): ''' PyQt API Method -- See the PyQt documentation for a description ''' if not index.isValid(): return QVariant() item = index.internalPointer() node = item.node # Foreground Coloring if role == Qt.ForegroundRole: if node.get('inherited') or (is_comment(node) and node.getparent().get('inherited')): return QVariant(QColor(Qt.darkBlue)) return QVariant() # = default color # Font elif role == Qt.FontRole: if item.hidden: font = QFont() font.setItalic(True) return QVariant(font) return QVariant() # = default # Display elif role == Qt.DisplayRole: if index.column() == 0: return QVariant(self._get_node_name(node)) elif index.column() == 1: return QVariant(self._get_node_text(node)) elif role == Qt.ToolTipRole: # don't need to worry about inheritance when there is no project if not self.project: return QVariant() if index.column() == 0: value = self._get_node_text(node) if value: value = 'Value: %s\n' % value else: value_list = self._get_item_children_text_list(item, 5) if value_list: value = '\n '.join([''] + value_list) value = 'Children:%s\n' % value inheritance = '' if node.get('inherited'): inheritance = 'Inherited value from file: %s' % node.get( 'inherited') elif self.project.is_shadowing(node): prototype_node = self.project.get_prototype_node(node) shadowing_value = self._get_node_text(prototype_node) if shadowing_value: inheritance += 'Shadowing value: %s\n' % shadowing_value inheritance += 'Original value defined in file: %s' % prototype_node.get( 'inherited') else: inheritance = 'Value is defined in this file.' text = 'Name: %s\n%s%s' % (self._get_node_name(node), value, inheritance) return QVariant(text) elif index.column() == 1: return QVariant(self._get_node_text(node)) # elif role == Qt.FontRole: # if index.column() == 0: # if node.tag == 'model': # font = QFont() # font.setPointSize(14) # return QVariant(font) # CK: Experimenting with making shadowing nodes bold to differentiate them from local nodes # elif role == Qt.FontRole: # f = QFont() # if self.project is not None: # f.setBold(self.project.is_shadowing(node)) # return QVariant(f) # Icons elif role == Qt.DecorationRole: if index.column() == 0 and is_no_comment(node): return QVariant(IconLibrary.icon_for_type(node.tag)) # Checkboxes elif role == Qt.CheckStateRole and index.column() == 1: if node.tag == 'selectable' or node.get('type') == 'boolean': return QVariant(Qt.Checked if ( node.text.strip() == 'True') else Qt.Unchecked) # Unhandled index/role return QVariant()
def data(self, index, role): if not index.isValid(): return QVariant() row = index.row() header = self._headers[index.column()] node = self._variable_nodes[row] # look up the definition once for easy access by multiple roles if header == self.HEADER_DEFINITION: dataset, name = get_variable_dataset_and_name(node) if name == 'constant': definition = '<built-in constant>' elif (name, dataset) in self._names_to_definition_nodes: definition_node = self._names_to_definition_nodes[(name, dataset)] if definition_node is not None: definition = definition_node.text else: definition = '<empty definition>' else: definition = '<unknown definition>' if role == Qt.DecorationRole: if header == self.HEADER_VARIABLE: return QVariant(IconLibrary.icon('variable')) if role == Qt.DisplayRole: var_name = get_variable_name(self._variable_nodes[row]) if header == self.HEADER_VARIABLE: return QVariant(var_name) if header == self.HEADER_DEFINITION: return QVariant(definition) if header == self.HEADER_COEFF_NAME: if 'coefficient_name' in node.attrib: return QVariant(node.get('coefficient_name')) return QVariant(var_name) if header == self.HEADER_STARTING_VAL: return QVariant(node.get('starting_value') or '') if role == Qt.EditRole: if header == self.HEADER_STARTING_VAL: return self.data(index, Qt.DisplayRole) if header == self.HEADER_COEFF_NAME: # give a clear coeff name if it's not set yet if 'coefficient_name' in node.attrib: return QVariant(node.get('coefficient_name')) return QVariant() if role == Qt.CheckStateRole: if header == self.HEADER_IGNORE: return QVariant(Qt.Checked if node.get('ignore') == 'True' else Qt.Unchecked) if header == self.HEADER_FIXED: return QVariant(Qt.Checked if node.get('keep_fixed') == 'True' else Qt.Unchecked) if role == Qt.FontRole: font = QtGui.QFont() if header == self.HEADER_VARIABLE: if node.get('ignore') != 'True': font.setBold(True) return QVariant(font) elif header == self.HEADER_COEFF_NAME and node.get( 'coefficient_name'): font.setBold(True) return QVariant(font) if role == Qt.ForegroundRole: # color default values of coefficient name as light gray if header == self.HEADER_COEFF_NAME: if 'coefficient_name' not in node.attrib: return QVariant(QtGui.QColor(Qt.gray)) if role == Qt.ToolTipRole: if header == self.HEADER_DEFINITION: # defs easily get cramped so show in tool tip as well return QVariant(definition) return QVariant()
def __init__(self, project, parent_widget=None): QDialog.__init__(self, parent_widget, Qt.Window) self.setupUi(self) self.project = project # Change PICK MODE to true for old school selector self.variables_table = VariablesTableView(parent_widget=self) self.original_nodes = set() self.cancel_validation_flag = {'value': False} self.model = None self.problem_variables = [] self.pb_create_new.setIcon(IconLibrary.icon('add')) self.initialize() self.table_container.addWidget(self.variables_table) # Automatically update the save button state on model data change self.connect(self.model, SIGNAL('model_changed'), self._update_apply_button) # Automatically enable or disable the validate selected vars button def on_sel_change(dummy_a, dummy_b): enabled = len(self.variables_table.selectedIndexes()) > 0 self.pb_validate_selected.setEnabled(enabled) sel_changed = SIGNAL( 'selectionChanged(const QItemSelection&,const QItemSelection&)') self.connect(self.variables_table.selectionModel(), sel_changed, on_sel_change) # Double clicking an item in the table brings up the editor def edit_wrapper(index): variable = self.model.variables[index.row()] if not variable['inherited']: self._edit_variable(variable) self.connect(self.variables_table, SIGNAL('doubleClicked(QModelIndex)'), edit_wrapper) def apply_and_close(): self._apply_variable_changes() self.accept() def cancel_validation(): self.cancel_validation_flag['value'] = True self.connect(self.pb_apply_and_close, SIGNAL("clicked()"), apply_and_close) self.connect(self.pb_apply, SIGNAL("clicked()"), self._apply_variable_changes) self.connect(self.pb_create_new, SIGNAL("clicked()"), self._add_variable) self.connect(self.pb_problems, SIGNAL("clicked()"), self._show_problem_variables) self.connect(self.pb_cancel_validation, SIGNAL("clicked()"), cancel_validation) signal = SIGNAL('customContextMenuRequested(const QPoint &)') self.connect(self.variables_table, signal, self._show_right_click_menu) signal = SIGNAL('currentIndexChanged(int)') self.connect(self.cbo_dataset_filter, signal, lambda x: self._set_dataset_filter()) self.validator = VariableValidator(self.project) self.editor = VariableEditor(self)
def data(self, index, role): ''' PyQt API Method -- See the PyQt documentation for a description ''' if not index.isValid(): return QVariant() node = index.internalPointer().node # Foreground Coloring if role == Qt.ForegroundRole: if node.get('inherited'): return QVariant(QColor(Qt.darkBlue)) return QVariant() # = default color # Display elif role == Qt.DisplayRole: if index.column() == 0: if node.get('type') == 'selectable': return QVariant( node.get('return_value') or node.get('name') or node.tag) return QVariant(node.get('name') or node.tag) elif index.column() == 1: if node.get('type') == "password": return QVariant(QString("*********")) # hide the text value for checkable nodes elif node.tag == 'selectable' or node.get('type') == 'boolean': return QVariant() elif node.text: return QVariant(node.text.strip()) return QVariant() elif role == Qt.ToolTipRole: if index.column( ) == 0 and self.project: # don't need to worry about inheritance when there is no project if node.get('inherited'): return QVariant('Inherited value from file: %s' % node.get('inherited')) elif self.project.is_shadowing(node): prototype_node = self.project.get_prototype_node(node) return QVariant('Original value defined in file: %s' % prototype_node.get('inherited')) else: return QVariant('Value is defined in this file.') # elif role == Qt.FontRole: # if index.column() == 0: # if node.tag == 'model': # font = QFont() # font.setPointSize(14) # return QVariant(font) # CK: Experimenting with making shadowing nodes bold to differentiate them from local nodes # elif role == Qt.FontRole: # f = QFont() # if self.project is not None: # f.setBold(self.project.is_shadowing(node)) # return QVariant(f) # Icons elif role == Qt.DecorationRole: if index.column() == 0: return QVariant(IconLibrary.icon_for_type(node.tag)) # Checkboxes elif role == Qt.CheckStateRole and index.column() == 1: if node.tag == 'selectable' or node.get('type') == 'boolean': return QVariant(Qt.Checked if ( node.text.strip() == 'True') else Qt.Unchecked) # Unhandled index/role return QVariant()
def data(self, index, role): ''' PyQt API Method -- See the PyQt documentation for a description ''' if not index.isValid(): return QVariant() item = index.internalPointer() node = item.node # Foreground Coloring if role == Qt.ForegroundRole: if node.get('inherited') or (is_comment(node) and node.getparent().get('inherited')): return QVariant(QColor(Qt.darkBlue)) return QVariant() # = default color # Font elif role == Qt.FontRole: if item.hidden: font = QFont() font.setItalic(True) return QVariant(font) return QVariant() # = default # Display elif role == Qt.DisplayRole: if index.column() == 0: return QVariant(self._get_node_name(node)) elif index.column() == 1: return QVariant(self._get_node_text(node)) elif role == Qt.ToolTipRole: # don't need to worry about inheritance when there is no project if not self.project: return QVariant() if index.column() == 0: value = self._get_node_text(node) if value: value = 'Value: %s\n' % value else: value_list = self._get_item_children_text_list(item, 5) if value_list: value = '\n '.join([''] + value_list) value = 'Children:%s\n' % value inheritance = '' if node.get('inherited'): inheritance = 'Inherited value from file: %s' % node.get('inherited') elif self.project.is_shadowing(node): prototype_node = self.project.get_prototype_node(node) shadowing_value = self._get_node_text(prototype_node) if shadowing_value: inheritance += 'Shadowing value: %s\n' % shadowing_value inheritance += 'Original value defined in file: %s' % prototype_node.get('inherited') else: inheritance = 'Value is defined in this file.' text = 'Name: %s\n%s%s' % (self._get_node_name(node), value, inheritance) return QVariant(text) elif index.column() == 1: return QVariant(self._get_node_text(node)) # elif role == Qt.FontRole: # if index.column() == 0: # if node.tag == 'model': # font = QFont() # font.setPointSize(14) # return QVariant(font) # CK: Experimenting with making shadowing nodes bold to differentiate them from local nodes # elif role == Qt.FontRole: # f = QFont() # if self.project is not None: # f.setBold(self.project.is_shadowing(node)) # return QVariant(f) # Icons elif role == Qt.DecorationRole: if index.column() == 0 and is_no_comment(node): return QVariant(IconLibrary.icon_for_type(node.tag)) # Checkboxes elif role == Qt.CheckStateRole and index.column() == 1: if node.tag == 'selectable' or node.get('type') == 'boolean': return QVariant(Qt.Checked if (node.text.strip() == 'True') else Qt.Unchecked) # Unhandled index/role return QVariant()
def data(self, index, role): ''' PyQt4 API Method ''' if not index.isValid(): return QVariant() row = index.row() col = index.column() var = self.variables[row] col_key = None if -1 < col < len(self.keys): col_key = self.keys[col] if role == Qt.DisplayRole: # Displayed text # Show a single letter for variable use if col_key == 'use': abbr = var['use'] if var['use'] == 'model variable': abbr = 'M' elif var['use'] == 'indicator': abbr = 'I' elif var['use'] == 'both': abbr = 'I+M' return QVariant(abbr) elif col_key == 'source': abbr = '?' if var['source'] == 'expression': abbr = 'Exp' elif var['source'] == 'Python class': abbr = 'PyC' elif var['source'] == 'primary attribute': abbr = 'Pri' return QVariant(abbr) elif col_key: return QVariant(var[col_key]) elif role == Qt.ToolTipRole: tooltip = '' if col_key == 'use': tooltip = 'use: <b>%s</b>' % var['use'] elif col_key == 'source': tooltip = 'source: <b>%s</b>' % var['source'] elif col_key == 'name': tooltip = 'name: <b>%s</b>' % var['name'] return QVariant(tooltip) elif role == Qt.ForegroundRole: # Color of text if var['inherited']: return QVariant(QColor(Qt.darkBlue)) elif role == Qt.TextAlignmentRole: if col in (2, 3): return QVariant(Qt.AlignCenter) return QVariant() elif role == Qt.FontRole: if var['dirty']: font = QFont() font.setBold(True) return QVariant(font) elif role == Qt.DecorationRole: if col_key == 'name': return QVariant(IconLibrary.icon('variable')) return QVariant()
def data(self, index, role): ''' PyQt API Method -- See the PyQt documentation for a description ''' if not index.isValid(): return QVariant() node = index.internalPointer().node # Foreground Coloring if role == Qt.ForegroundRole: if node.get('inherited'): return QVariant(QColor(Qt.darkBlue)) return QVariant() # = default color # Display elif role == Qt.DisplayRole: if index.column() == 0: if node.get('type') == 'selectable': return QVariant(node.get('return_value') or node.get('name') or node.tag) return QVariant(node.get('name') or node.tag) elif index.column() == 1: if node.get('type') == "password": return QVariant(QString("*********")) # hide the text value for checkable nodes elif node.tag == 'selectable' or node.get('type') == 'boolean': return QVariant() elif node.text: return QVariant(node.text.strip()) return QVariant() elif role == Qt.ToolTipRole: if index.column() == 0 and self.project: # don't need to worry about inheritance when there is no project if node.get('inherited'): return QVariant('Inherited value from file: %s' % node.get('inherited')) elif self.project.is_shadowing(node): prototype_node = self.project.get_prototype_node(node) return QVariant('Original value defined in file: %s' % prototype_node.get('inherited')) else: return QVariant('Value is defined in this file.') # elif role == Qt.FontRole: # if index.column() == 0: # if node.tag == 'model': # font = QFont() # font.setPointSize(14) # return QVariant(font) # CK: Experimenting with making shadowing nodes bold to differentiate them from local nodes # elif role == Qt.FontRole: # f = QFont() # if self.project is not None: # f.setBold(self.project.is_shadowing(node)) # return QVariant(f) # Icons elif role == Qt.DecorationRole: if index.column() == 0: return QVariant(IconLibrary.icon_for_type(node.tag)) # Checkboxes elif role == Qt.CheckStateRole and index.column() == 1: if node.tag == 'selectable' or node.get('type') == 'boolean': return QVariant(Qt.Checked if (node.text.strip() == 'True') else Qt.Unchecked) # Unhandled index/role return QVariant()
def viewDatasetAction(self): #print "viewDatasetAction" model = self.model table_name = str(model.fileName(self.currentIndex)) table_name_full = str(model.filePath(self.currentIndex)) parentIndex = model.parent(self.currentIndex) parent_name = str(model.fileName(parentIndex)) parent_name_full = str(model.filePath(parentIndex)) storage = StorageFactory().get_storage( 'flt_storage', storage_location=parent_name_full) columns = storage.get_column_names(table_name) # temporarily use the table name for the dataset name # dataset_name = DatasetFactory().dataset_name_for_table(table_name) # Aaron - please check this way of getting the XMLConfiguration -- is this the best way? # general = self.mainwindow.toolboxBase.opus_core_xml_configuration.get_section('general') # # problem: this gets the package order for the current project, but the viewer shows all the data # package_order = general['dataset_pool_configuration'].package_order # PREVIOUS HACK: # package_order = ['seattle_parcel','urbansim_parcel', 'eugene', 'urbansim', 'opus_core'] # temporary code: just use a generic dataset for now data = Dataset(in_storage=storage, dataset_name=table_name, in_table_name=table_name, id_name=[]) # code to get a more specialized dataset if possible (doesn't work with table names not ending in 's' # unless they are in the exceptions list in DatasetFactory) # data = DatasetFactory().search_for_dataset_with_hidden_id(dataset_name, package_order, # arguments={'in_storage': storage, 'in_table_name': table_name}) # Need to add a new tab to the main tabs for display of the data container = QWidget() widgetLayout = QVBoxLayout(container) summaryGroupBox = QGroupBox(container) summaryGroupBox.setTitle( QString("Year: %s Run name: %s" % (parent_name, table_name_full.split('/')[-3]))) summaryGroupBox.setFlat(True) summaryGroupBoxLayout = QVBoxLayout(summaryGroupBox) # Grab the summary data buffer = StringIO() data.summary(output=buffer, unload_after_each_attribute=True) strng = buffer.getvalue() buffer.close() textBrowser = QTextBrowser() # textBrowser.insertPlainText(strng) textBrowser.insertHtml(self.parse_dataset_summary(strng)) summaryGroupBoxLayout.addWidget(textBrowser) widgetLayout.addWidget(summaryGroupBox) tableGroupBox = QGroupBox(container) tableGroupBox.setTitle(QString("Table View")) tableGroupBox.setFlat(True) tableGroupBoxLayout = QVBoxLayout(tableGroupBox) tv = QTableView() header = columns tabledata_tmp = [] for column in columns: tabledata_tmp.append(data.get_attribute(column)) # Transpose the lists tabledata = map(None, *tabledata_tmp) # If the table data is not empty then we display it if tabledata: #tv.resizeColumnsToContents() tm = TableModel(tabledata, header, container) tv.setModel(tm) tv.setSortingEnabled(True) tableGroupBoxLayout.addWidget(tv) widgetLayout.addWidget(tableGroupBox) container.tabIcon = IconLibrary.icon('inspect') container.tabLabel = QString(table_name) self.manager._attach_tab(container)