class MetadadoSNIMar(QWidget): def __init__(self, parent, scope=None, xml_doc=None, md=None): super(MetadadoSNIMar, self).__init__(parent) if scope is None: self.scope = SCOPES.get_code_representation(md.hierarchy) else: self.scope = scope self.current_index = 0 self.widgetStalker = {} if platform.system() != "Linux": font = QFont() font.setFamily(u"Segoe UI Symbol") self.setFont(font) self.sidelist = QListWidget(self) self.sidelist.setMinimumWidth(150) self.sidelist.setMaximumWidth(150) self.sidelist.setWordWrap(True) self.sidelist.setTextElideMode(Qt.ElideNone) self.sidelist.setIconSize(QSize(25, 25)) self.sidelist.clicked.connect(self.list_clicked) index = 0 if self.scope == SCOPES.SERVICES: tabs = cons.TABLIST_SERVICES else: tabs = cons.TABLIST_CDG_SERIES for tab_element in tabs: bufWidget = QListWidgetItem( qgui.QIcon(':/resourcesFolder/icons/' + tab_element[1]), tab_element[0]) self.widgetStalker[tab_element[2]] = { "widget": bufWidget, "missingFields": set(), "incompleteEntries": set() } bufWidget.setSizeHint(QSize(150, 50)) if platform.system() != "Linux": font = QFont() font.setFamily(u"Segoe UI Symbol") bufWidget.setFont(font) self.sidelist.insertItem(index, bufWidget) index += 1 self.widgetstack = QStackedWidget(self) # Setup metadata stuff self.xml_doc = xml_doc self.is_new_file = True if xml_doc is None else False self.md = md self.codelist = self.parent().codelists self.helps = self.parent().helps self.orgs = self.parent().orgs f = open( os.path.join(pluginDirectory('EditorMetadadosMarswInforbiomares'), 'resourcesFolder/stylesheet.qtcss')) self.sytlesheet = f.read() for btn in self.findChildren(QPushButton): btn.setStyleSheet(self.sytlesheet) btn.setFocusPolicy(Qt.NoFocus) self.reference_systems_list = self.parent().reference_systems tab_list = [] # Setup snimarEditorController self.identification = snimarEditorController.IdentificationWidget( self, self.scope) tab_list.append(self.identification) if self.scope == SCOPES.SERVICES: self.operations = snimarEditorController.ServiceOperationsWidget( self) tab_list.append(self.operations) self.keywords = snimarEditorController.KeywordsWidget(self, self.scope) tab_list.append(self.keywords) self.geographicinfo = snimarEditorController.GeographicInfoWidget( self, self.scope) tab_list.append(self.geographicinfo) self.temporalinfo = snimarEditorController.TemporalInfoWidget( self, self.scope) tab_list.append(self.temporalinfo) self.quality = snimarEditorController.QualityWidget(self, self.scope) tab_list.append(self.quality) self.restrictions = snimarEditorController.RestrictionsWidget( self, self.scope) tab_list.append(self.restrictions) self.distribution = snimarEditorController.DistributionWidget( self, self.scope) tab_list.append(self.distribution) self.metadata = snimarEditorController.MetadataWidget(self) tab_list.append(self.metadata) self.setupUi() if not self.is_new_file: # Setup data self.identification.set_data(self.md) if self.scope == SCOPES.SERVICES: self.operations.set_data(md) self.temporalinfo.set_data(self.md) self.keywords.set_data(self.md) self.metadata.set_data(self.md) self.distribution.set_data(self.md) self.restrictions.set_data(self.md) self.quality.set_data(self.md) self.geographicinfo.set_data(self.md) def setupUi(self): self.widgetstack.addWidget(self.identification) if self.scope == SCOPES.SERVICES: self.widgetstack.addWidget(self.operations) self.widgetstack.addWidget(self.keywords) self.widgetstack.addWidget(self.geographicinfo) self.widgetstack.addWidget(self.temporalinfo) self.widgetstack.addWidget(self.quality) self.widgetstack.addWidget(self.restrictions) self.widgetstack.addWidget(self.distribution) self.widgetstack.addWidget(self.metadata) self.grid = QGridLayout(self) self.grid.addWidget(self.sidelist, 0, 0, 1, 1) self.grid.addWidget(self.widgetstack, 0, 1, 1, 1) self.setLayout(self.grid) self.widgetstack.setCurrentIndex(0) @qcore.pyqtSlot() def list_clicked(self): index = self.sidelist.currentRow() if index != self.current_index: self.widgetstack.setCurrentIndex(index) self.current_index = index def get_tab_data(self, md): if self.scope != SCOPES.SERVICES: md.identification = snimarProfileModel.MD_DataIdentification() else: md.serviceidentification = snimarProfileModel.SV_ServiceIdentification( ) self.identification.get_data(md) if self.scope == SCOPES.SERVICES: self.operations.get_data(md) self.keywords.get_data(md) self.geographicinfo.get_data(md) self.temporalinfo.get_data(md) self.quality.get_data(md) self.restrictions.get_data(md) self.distribution.get_data(md) self.metadata.get_data(md) # ------------------------------------------------------------------------ # Validation STUFF # ------------------------------------------------------------------------ def is_doc_Snimar_Valid(self): for x in list(self.widgetStalker.values()): if len(x["missingFields"]) > 0 or len(x["incompleteEntries"]) > 0: return False return True def register_mandatory_missingfield(self, widgetName, fieldName): self.widgetStalker[widgetName]["missingFields"].add( fieldName.replace(u'\u26a0', '').strip()) self.widgetStalker[widgetName]["widget"].setToolTip( self.genToolTip(widgetName)) self.widgetStalker[widgetName]["widget"].setForeground( QColor(cons.ERROR_COLOR)) self.widgetStalker[widgetName]["widget"].setText( self.widgetStalker[widgetName]["widget"].text().replace( u'\u26a0', '') + u'\u26a0') def unregister_mandatory_missingfield(self, widgetName, fieldName): self.widgetStalker[widgetName]["missingFields"].discard(fieldName) if len(self.widgetStalker[widgetName] ["incompleteEntries"]) != 0 or len( self.widgetStalker[widgetName]["missingFields"]) != 0: self.widgetStalker[widgetName]["widget"].setText( self.widgetStalker[widgetName]["widget"].text().replace( u'\u26a0', '') + u'\u26a0') else: self.widgetStalker[widgetName]["widget"].setForeground( QColor("black")) self.widgetStalker[widgetName]["widget"].setText( self.widgetStalker[widgetName]["widget"].text().replace( u'\u26a0', '')) self.widgetStalker[widgetName]["widget"].setToolTip( self.genToolTip(widgetName)) def register_incomplete_entries(self, widgetName, fieldName): self.widgetStalker[widgetName]["incompleteEntries"].add( fieldName.replace(u'\u26a0', '').strip()) self.widgetStalker[widgetName]["widget"].setToolTip( self.genToolTip(widgetName)) self.widgetStalker[widgetName]["widget"].setForeground( QColor(cons.ERROR_COLOR)) self.widgetStalker[widgetName]["widget"].setText( self.widgetStalker[widgetName]["widget"].text().replace( u'\u26a0', '') + u'\u26a0') def unregister_incomplete_entries(self, widgetName, fieldName): self.widgetStalker[widgetName]["incompleteEntries"].discard(fieldName) if len(self.widgetStalker[widgetName] ["incompleteEntries"]) != 0 or len( self.widgetStalker[widgetName]["missingFields"]) != 0: self.widgetStalker[widgetName]["widget"].setText( self.widgetStalker[widgetName]["widget"].text().replace( u'\u26a0', '') + u'\u26a0') else: self.widgetStalker[widgetName]["widget"].setForeground( QColor("black")) self.widgetStalker[widgetName]["widget"].setText( self.widgetStalker[widgetName]["widget"].text().replace( u'\u26a0', '')) self.widgetStalker[widgetName]["widget"].setToolTip( self.genToolTip(widgetName)) def genToolTip(self, widgetName): tooltip = "" if len(self.widgetStalker[widgetName]["missingFields"]) > 0: tooltip += u"Campos Obrigatórios\nem falta:\n-" + "\n-".join( self.widgetStalker[widgetName]["missingFields"]) if len(self.widgetStalker[widgetName]["missingFields"]) > 0 and len( self.widgetStalker[widgetName]["incompleteEntries"]) > 0: tooltip += u"\n---------------------\n" if len(self.widgetStalker[widgetName]["incompleteEntries"]) > 0: tooltip += u"Campos Incompletos\Incorrectos:\n-" + "\n-".join( self.widgetStalker[widgetName]["incompleteEntries"]) tooltip += u"\n---------------------\n" return tooltip + u"\nA Conformidade diz respeito\n" \ u"as obrigações de formato " \ u"\ne completude do documento.\n" \ u"A validade do conteúdo é da\n" \ u"inteira responsabilidade\n" \ u"do utilizador. "
class GraphDialog(QDialog): edit_patterns = 0 edit_curves = 1 titles = {edit_patterns: 'Pattern editor', edit_curves: 'Curve editor'} labels = {edit_patterns: 'Patterns', edit_curves: 'Curves'} def __init__(self, dockwidget, parent, params, edit_type): QDialog.__init__(self, parent) main_lay = QVBoxLayout(self) self.dockwidget = dockwidget self.params = params self.edit_type = edit_type self.x_label = '' self.y_label = '' self.setMinimumWidth(600) self.setMinimumHeight(400) self.setWindowTitle(self.titles[edit_type]) # TODO: softcode self.setWindowModality(QtCore.Qt.ApplicationModal) self.current = None self.current_saved = False # File self.lbl_file = QLabel('File:') self.fra_file = QFrame() self.fra_file.setContentsMargins(0, 0, 0, 0) fra_file_lay = QHBoxLayout(self.fra_file) if edit_type == self.edit_patterns: self.txt_file = QLineEdit(self.params.patterns_file) elif edit_type == self.edit_curves: self.txt_file = QLineEdit(self.params.curves_file) self.txt_file.setReadOnly(True) self.txt_file.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.txt_file.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) fra_file_lay.addWidget(self.txt_file) self.btn_file = QPushButton('Change') # TODO: softcode self.btn_file.clicked.connect(self.import_file) fra_file_lay.addWidget(self.btn_file) fra_file_lay.setContentsMargins(0, 0, 0, 0) self.lbl_list = QLabel(self.labels[edit_type]) self.lst_list = QListWidget() self.lst_list.currentItemChanged.connect(self.list_item_changed) # Form self.fra_form = QFrame() fra_form1_lay = QFormLayout(self.fra_form) fra_form1_lay.setContentsMargins(0, 0, 0, 0) fra_form1_lay.addRow(self.lbl_list, self.lst_list) # Buttons self.fra_buttons = QFrame() fra_buttons_lay = QHBoxLayout(self.fra_buttons) fra_buttons_lay.setContentsMargins(0, 0, 0, 0) if self.edit_type == self.edit_patterns: ele_name = 'pattern' elif self.edit_type == self.edit_curves: ele_name = 'curve' self.btn_new = QPushButton('New ' + ele_name) # TODO: softcode self.btn_new.clicked.connect(self.new_element) fra_buttons_lay.addWidget(self.btn_new) self.btn_import = QPushButton('Import ' + ele_name + 's') # TODO: softcode self.btn_import.clicked.connect(self.import_file) fra_buttons_lay.addWidget(self.btn_import) self.btn_save = QPushButton('Save current ' + ele_name) # TODO: softcode self.btn_save.clicked.connect(self.save) fra_buttons_lay.addWidget(self.btn_save) self.btn_del = QPushButton('Delete current ' + ele_name) # TODO: softcode self.btn_del.clicked.connect(self.del_item) fra_buttons_lay.addWidget(self.btn_del) # ID self.lbl_id = QLabel('ID:') self.txt_id = QLineEdit() self.txt_id.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.MinimumExpanding) self.lbl_desc = QLabel('Desc.:') self.txt_desc = QLineEdit() self.fra_id = QFrame() fra_id_lay = QHBoxLayout(self.fra_id) fra_id_lay.addWidget(self.lbl_id) fra_id_lay.addWidget(self.txt_id) fra_id_lay.addWidget(self.lbl_desc) fra_id_lay.addWidget(self.txt_desc) # Table form self.table = QTableWidget(self) self.rows_nr = 24 self.cols_nr = 2 self.table.setRowCount(self.rows_nr) self.table.setColumnCount(self.cols_nr) self.table.verticalHeader().setVisible(False) # Initialize empty table self.clear_table() self.table.itemChanged.connect(self.data_changed) self.fra_table = QFrame() fra_table_lay = QVBoxLayout(self.fra_table) fra_table_lay.setContentsMargins(0, 0, 0, 0) if edit_type == self.edit_curves: self.fra_pump_type = QFrame() fra_pump_type_lay = QFormLayout(self.fra_pump_type) self.lbl_pump_type = QLabel('Curve type:') # TODO: softcode self.cbo_pump_type = QComboBox() for key, name in Curve.type_names.items(): self.cbo_pump_type.addItem(name, key) fra_pump_type_lay.addRow(self.lbl_pump_type, self.cbo_pump_type) fra_table_lay.addWidget(self.fra_pump_type) self.cbo_pump_type.activated.connect(self.cbo_pump_type_activated) fra_table_lay.addWidget(self.table) self.btn_add_row = QPushButton('Add row') self.btn_add_row.clicked.connect(self.add_row) fra_table_lay.addWidget(self.btn_add_row) # Graph canvas self.fra_graph = QFrame() self.static_canvas = StaticMplCanvas(self.fra_graph, width=5, height=4, dpi=100) fra_graph_lay = QVBoxLayout(self.fra_graph) fra_graph_lay.addWidget(self.static_canvas) # Top frame self.fra_top = QFrame() fra_top_lay = QVBoxLayout(self.fra_top) fra_top_lay.addWidget(self.fra_form) fra_top_lay.addWidget(self.fra_id) fra_top_lay.addWidget(self.fra_buttons) # Bottom frame self.fra_bottom = QFrame() fra_bottom_lay = QHBoxLayout(self.fra_bottom) fra_bottom_lay.addWidget(self.fra_table) fra_bottom_lay.addWidget(self.fra_graph) # Main main_lay.addWidget(self.fra_top) main_lay.addWidget(self.fra_bottom) # Get existing patterns/curves self.need_to_update_graph = False if self.edit_type == self.edit_patterns: for pattern_id, pattern in self.params.patterns.items(): self.lst_list.addItem(pattern.id) elif self.edit_type == self.edit_curves: for curve_id, curve in self.params.curves.items(): self.lst_list.addItem(curve.id) if self.lst_list.count() > 0: self.lst_list.setCurrentRow(0) self.txt_id.setEnabled(True) self.txt_desc.setEnabled(True) self.btn_save.setEnabled(True) self.btn_del.setEnabled(True) self.table.setEnabled(True) self.table.setEditTriggers(QAbstractItemView.AllEditTriggers) else: self.txt_id.setEnabled(False) self.txt_desc.setEnabled(False) self.btn_save.setEnabled(False) self.btn_del.setEnabled(False) self.table.setEnabled(False) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.new_dialog = None self.need_to_update_graph = True def cbo_pump_type_activated(self): self.update_table_headers() self.update_graph() def add_row(self): row_pos = self.table.rowCount() self.table.insertRow(row_pos) col = 0 item = QTableWidgetItem(str(row_pos)) if self.edit_type == self.edit_patterns: self.table.setItem(row_pos, col, item) item.setFlags(QtCore.Qt.ItemIsSelectable) def setVisible(self, bool): QDialog.setVisible(self, bool) self.update_table_headers() self.update_graph() def list_item_changed(self): p_index = self.lst_list.currentRow() flags = Qt.ItemFlags() flags != Qt.ItemIsEnabled # Clear table self.clear_table() self.need_to_update_graph = False if p_index >= 0: self.table.setRowCount(0) if self.edit_type == self.edit_patterns: self.current = self.params.patterns[ self.lst_list.currentItem().text()] for v in range(len(self.current.values)): row_pos = self.table.rowCount() self.table.insertRow(row_pos) item = QTableWidgetItem(str(v)) item.setFlags(flags) self.table.setItem(v, 0, item) self.table.setItem( v, 1, QTableWidgetItem(str(self.current.values[v]))) elif self.edit_type == self.edit_curves: self.current = self.params.curves[ self.lst_list.currentItem().text()] for v in range(len(self.current.xs)): row_pos = self.table.rowCount() self.table.insertRow(row_pos) self.table.setItem( v, 0, QTableWidgetItem(str(self.current.xs[v]))) self.table.setItem( v, 1, QTableWidgetItem(str(self.current.ys[v]))) curve_type = self.current.type self.cbo_pump_type.setCurrentIndex(curve_type) # Update GUI self.txt_id.setText(self.current.id) self.txt_desc.setText(self.current.desc) self.update_table_headers() # Update graph self.need_to_update_graph = True self.update_graph() else: # No curves self.txt_id.setText('') self.txt_desc.setText('') # Update table and chart self.need_to_update_graph = False for v in range(self.table.columnCount()): self.table.setItem(v, 1, QTableWidgetItem('')) self.need_to_update_graph = True self.update_graph() def import_file(self): config_file = ConfigFile(Parameters.config_file_path) directory = None if self.edit_type == GraphDialog.edit_curves: directory = self.params.last_curves_dir elif self.edit_type == GraphDialog.edit_patterns: directory = self.params.last_patterns_dir if directory is None: directory = self.params.last_project_dir file_path, __ = QFileDialog.getOpenFileName(self, 'Select file', directory, 'Files (*.txt *.inp)') if file_path is None or file_path == '': return else: if self.edit_type == GraphDialog.edit_patterns: # Save patterns file path in configuration file config_file.set_patterns_file_path(file_path) Parameters.patterns_file = file_path elif self.edit_type == GraphDialog.edit_curves: # Save curve file path in configuration file config_file.set_curves_file_path(file_path) Parameters.curves_file = file_path self.read(file_path) def read(self, file_path): self.lst_list.clear() if self.edit_type == self.edit_patterns: InpFile.read_patterns(self.params, file_path) for pattern_id, pattern in self.params.patterns.items(): # desc = ' (' + pattern.desc + ')' if pattern.desc is not None else '' self.lst_list.addItem(pattern.id) self.params.patterns[pattern.id] = pattern elif self.edit_type == self.edit_curves: InpFile.read_curves(self.params, file_path) for curve_id, curve in self.params.curves.items(): # desc = ' (' + curve.desc + ')' if curve.desc is not None else '' self.lst_list.addItem(curve.id) self.params.curves[curve.id] = curve if self.lst_list.count() > 0: self.lst_list.setCurrentRow(0) def new_element(self): old_ids = [] if self.edit_type == self.edit_patterns: for pattern in self.params.patterns.values(): old_ids.append(pattern.id) elif self.edit_type == self.edit_curves: for curve in self.params.curves.values(): old_ids.append(curve.id) self.new_dialog = NewIdDialog(self, old_ids) self.new_dialog.exec_() new_id = self.new_dialog.get_newid() description = self.new_dialog.get_description() if new_id is None or description is None: return if self.edit_type == self.edit_patterns: new_pattern = Pattern(new_id, description) self.params.patterns[new_pattern.id] = new_pattern self.lst_list.addItem(new_pattern.id) elif self.edit_type == self.edit_curves: curve_type = self.cbo_pump_type.itemData( self.cbo_pump_type.currentIndex()) new_curve = Curve(new_id, curve_type, desc=description) self.params.curves[new_curve.id] = new_curve self.lst_list.addItem(new_curve.id) self.lst_list.setCurrentRow(self.lst_list.count() - 1) self.txt_id.setText(new_id) self.txt_desc.setText(description) # Clear table self.clear_table() self.static_canvas.axes.clear() self.txt_id.setEnabled(True) self.txt_desc.setEnabled(True) self.btn_save.setEnabled(True) self.btn_del.setEnabled(True) self.table.setEnabled(True) self.table.setEditTriggers(QAbstractItemView.AllEditTriggers) def save(self): self.need_to_update_graph = False # Check for ID if not self.txt_id.text(): QMessageBox.warning( self, Parameters.plug_in_name, u'Please specify the ID.', # TODO: softcode QMessageBox.Ok) return if self.edit_type == GraphDialog.edit_patterns: values = [] for row in range(self.table.rowCount()): item = self.table.item(row, 1) if item is not None and item.text() != '': values.append(self.from_item_to_val(item)) else: values.append('0') pattern = Pattern(self.txt_id.text(), self.txt_desc.text(), values) old_patterns = self.params.patterns old_patterns[pattern.id] = pattern self.params.patterns = old_patterns self.lst_list.currentItem().setText(pattern.id) elif self.edit_type == GraphDialog.edit_curves: # Check for ID unique xs = [] ys = [] for row in range(self.table.rowCount()): item_x = self.table.item(row, 0) item_y = self.table.item(row, 1) if item_x.text().strip() != '' and item_y.text().strip() != '': xs.append(self.from_item_to_val(item_x)) ys.append(self.from_item_to_val(item_y)) curve_type = self.cbo_pump_type.itemData( self.cbo_pump_type.currentIndex()) curve = Curve(self.txt_id.text(), curve_type, self.txt_desc.text()) for v in range(len(xs)): curve.append_xy(xs[v], ys[v]) old_curves = self.params.curves old_curves[curve.id] = curve self.params.curves = old_curves self.lst_list.currentItem().setText(curve.id) # Update GUI self.dockwidget.update_curves_combo() # self.read() self.need_to_update_graph = True def clear_table(self): self.need_to_update_graph = False for r in range(self.table.rowCount()): self.table.setItem(r, 0, QTableWidgetItem(None)) self.table.setItem(r, 1, QTableWidgetItem(None)) for row in range(self.rows_nr): for col in range(self.cols_nr): if self.edit_type == self.edit_patterns: if col == 0: item = QTableWidgetItem(str(row)) self.table.setItem(row, col, item) item.setFlags(QtCore.Qt.ItemIsSelectable) # elif col == 1 and row == 0: # item = QTableWidgetItem(str(1)) # self.table.setItem(row, col, item) # item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) # elif self.edit_type == self.edit_curves: # if row == 0: # item = QTableWidgetItem(str(0)) # self.table.setItem(row, 0, item) # item = QTableWidgetItem(str(1)) # self.table.setItem(row, 1, item) # item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.need_to_update_graph = True def del_item(self): selected_row = self.lst_list.currentRow() name = self.lst_list.currentItem().text() if selected_row < 0: return self.lst_list.takeItem(selected_row) if self.lst_list.count() == 0: self.txt_id.setEnabled(False) self.txt_desc.setEnabled(False) self.btn_save.setEnabled(False) self.btn_del.setEnabled(False) self.table.setEnabled(False) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) if self.edit_type == GraphDialog.edit_curves: del self.params.curves[name] # Update GUI self.dockwidget.update_curves_combo() elif self.edit_type == GraphDialog.edit_patterns: del self.params.patterns[name] # Update GUI self.dockwidget.update_patterns_combo() def data_changed(self): if self.need_to_update_graph: self.update_graph() def update_table_headers(self): if self.edit_type == self.edit_patterns: self.x_label = 'Time period' self.y_label = 'Multiplier' elif self.edit_type == self.edit_curves: cbo_data = self.cbo_pump_type.itemData( self.cbo_pump_type.currentIndex()) if cbo_data == Curve.type_efficiency: self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']' self.y_label = 'Efficiency ' + '[' + self.params.options.units_deltaz[ self.params.options.units] + ']' if cbo_data == Curve.type_headloss: self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']' self.y_label = 'Headloss ' + '[' + self.params.options.units_deltaz[ self.params.options.units] + ']' if cbo_data == Curve.type_pump: self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']' self.y_label = 'Head ' + '[' + self.params.options.units_deltaz[ self.params.options.units] + ']' if cbo_data == Curve.type_volume: self.x_label = 'Height ' + '[' + self.params.options.flow_units + ']' self.y_label = 'Volume ' + '[' + self.params.options.units_deltaz[ self.params.options.units] + ']' self.table.setHorizontalHeaderLabels([self.x_label, self.y_label]) # TODO: softcode def update_graph(self): if not self.need_to_update_graph: return xs = [] ys = [] for row in range(self.table.rowCount()): item = self.table.item(row, 0) x = self.from_item_to_val(item) item = self.table.item(row, 1) y = self.from_item_to_val(item) if x is not None: xs.append(float(x)) if y is not None: ys.append(float(y)) if len(xs) == 0 or len(ys) == 0: self.static_canvas.clear() return xys_t = list(zip(xs, ys)) xys_t.sort() xys = list(zip(*xys_t)) xs = xys[0] ys = xys[1] if self.edit_type == self.edit_patterns: y_axis_label = 'Mult. avg.: ' + '{0:.2f}'.format( (numpy.average(ys))) self.static_canvas.draw_bars_graph( ys, time_period=self.params.times.pattern_timestep, y_axes_label=y_axis_label) elif self.edit_type == self.edit_curves: # Account for different types of curves cbo_data = self.cbo_pump_type.itemData( self.cbo_pump_type.currentIndex()) series_length = min(len(xs), len(ys)) # Need to account for different types of curves if cbo_data == Curve.type_efficiency or cbo_data == Curve.type_headloss or cbo_data == Curve.type_volume: self.static_canvas.draw_line_graph(xs[:series_length], ys[:series_length], self.x_label, self.y_label) elif cbo_data == Curve.type_pump: if series_length == 1 or series_length == 3: if series_length == 1: # 3 curve points curve_xs = [0, xs[0], xs[0] * 2] curve_ys = [ys[0] * 1.33, ys[0], 0] # y = a * x^2 + b * x + c elif series_length == 3: # 3 curve points curve_xs = [xs[0], xs[1], xs[2]] curve_ys = [ys[0], ys[1], ys[2]] (a, b, c) = numpy.polyfit(curve_xs, curve_ys, 2) # Create a few interpolated values interp_xs = [] interp_ys = [] n_vals = 30 for v in range(n_vals + 1): x = (curve_xs[2] - curve_xs[0]) / n_vals * v interp_xs.append(x) y = a * x**2 + b * x + c interp_ys.append(y) self.static_canvas.draw_line_graph(interp_xs, interp_ys, self.x_label, self.y_label) else: self.static_canvas.draw_line_graph(xs[:series_length], ys[:series_length], self.x_label, self.y_label) def from_item_to_val(self, item): if item is None: value = None else: value = item.text() try: value = float(value) value = max(value, 0) except: value = None return value
class TagsDialog(QDialog): def __init__(self, dockwidget, parent, params): QDialog.__init__(self, parent) main_lay = QVBoxLayout(self) self.dockwidget = dockwidget self.params = params self.setWindowTitle('Tags editor') # Top frame self.fra_top = QFrame() fra_top_lay = QVBoxLayout(self.fra_top) self.lst_main = QListWidget(self) self.btn_add = QPushButton('Add tag') self.btn_add.clicked.connect(self.add_tag) self.btn_remove = QPushButton('Remove tag') self.btn_remove.clicked.connect(self.remove_tag) fra_top_lay.addWidget(self.lst_main) fra_top_lay.addWidget(self.btn_add) fra_top_lay.addWidget(self.btn_remove) # Bottom frame self.fra_bottom = QFrame() fra_bottom_lay = QHBoxLayout(self.fra_bottom) btb_main = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) btb_main.accepted.connect(self.ok) btb_main.rejected.connect(self.reject) fra_bottom_lay.addWidget(btb_main) # Main main_lay.addWidget(self.fra_top) main_lay.addWidget(self.fra_bottom) self.initialize() def initialize(self): for tag_name in self.params.tag_names: self.lst_main.insertItem(self.lst_main.count(), QListWidgetItem(tag_name, self.lst_main)) def ok(self): tag_names = [] for r in range(self.lst_main.count()): tag_names.append(self.lst_main.item(r).text()) self.params.tag_names = tag_names self.setVisible(False) def reject(self): self.setVisible(False) def add_tag(self): tag_name_dialog = TagNameDialog(self.dockwidget, self) tag_name_dialog.exec_() tag_name = tag_name_dialog.get_tag_name() if tag_name is not None: current_row = self.lst_main.currentRow() if current_row is None: current_row = self.lst_main.count() self.lst_main.insertItem(current_row, QListWidgetItem(tag_name, self.lst_main)) def remove_tag(self): sel_items = self.lst_main.selectedItems() for sel_item in sel_items: self.lst_main.takeItem(self.lst_main.row(sel_item))
class PlotLayoutItemWidget(QgsLayoutItemBaseWidget): """ Configuration widget for layout plot items """ def __init__(self, parent, layout_object): super().__init__(parent, layout_object) self.plot_item = layout_object self.message_bar = None vl = QVBoxLayout() vl.setContentsMargins(0, 0, 0, 0) plot_tools_layout = QHBoxLayout() plot_add_button = QPushButton() plot_add_button.setIcon(GuiUtils.get_icon('symbologyAdd.svg')) plot_add_button.setToolTip('Add a new plot') plot_tools_layout.addWidget(plot_add_button) plot_add_button.clicked.connect(self.add_plot) plot_remove_button = QPushButton() plot_remove_button.setIcon(GuiUtils.get_icon('symbologyRemove.svg')) plot_remove_button.setToolTip('Remove selected plot') plot_tools_layout.addWidget(plot_remove_button) plot_remove_button.clicked.connect(self.remove_plot) plot_duplicate_button = QPushButton() plot_duplicate_button.setIcon( GuiUtils.get_icon('mActionDuplicateLayer.svg')) plot_duplicate_button.setToolTip('Duplicates the selected plot') plot_tools_layout.addWidget(plot_duplicate_button) plot_duplicate_button.clicked.connect(self.duplicate_plot) plot_move_up_button = QPushButton() plot_move_up_button.setIcon(GuiUtils.get_icon('mActionArrowUp.svg')) plot_move_up_button.setToolTip('Move selected plot up') plot_tools_layout.addWidget(plot_move_up_button) plot_move_up_button.clicked.connect(self.move_up_plot) plot_move_down_button = QPushButton() plot_move_down_button.setIcon( GuiUtils.get_icon('mActionArrowDown.svg')) plot_move_down_button.setToolTip('Move selected plot down') plot_tools_layout.addWidget(plot_move_down_button) plot_move_down_button.clicked.connect(self.move_down_plot) vl.addLayout(plot_tools_layout) self.plot_list = QListWidget() self.plot_list.setSelectionMode(QListWidget.SingleSelection) self.plot_list.doubleClicked.connect(self.show_properties) vl.addWidget(self.plot_list) self.populate_plot_list() plot_properties_button = QPushButton(self.tr('Setup Selected Plot')) vl.addWidget(plot_properties_button) plot_properties_button.clicked.connect(self.show_properties) self.panel = None self.setPanelTitle(self.tr('Plot Properties')) self.item_properties_widget = QgsLayoutItemPropertiesWidget( self, layout_object) vl.addWidget(self.item_properties_widget) self.setLayout(vl) def populate_plot_list(self): """ Clears and re-populates the plot list widget. The currently selection is retained """ selected_index = self.plot_list.currentRow() self.plot_list.clear() for setting in self.plot_item.plot_settings: plot_type = setting.plot_type if setting.plot_type is not None else '(not set)' legend_title = ('[' + setting.properties.get('name') + ']') \ if setting.properties.get('name', '') != '' else '' self.plot_list.addItem(plot_type + ' ' + legend_title) # select index within range [0, len(plot_settings)-1] selected_index = max( 0, min(len(self.plot_item.plot_settings) - 1, selected_index)) self.plot_list.setCurrentRow(selected_index, QItemSelectionModel.SelectCurrent) def add_plot(self): """ Adds a new plot and updates the plot list and the plot item """ self.plot_item.add_plot() self.populate_plot_list() self.plot_item.refresh() def duplicate_plot(self): """ Duplicates an existing plot and updates the plot list and the plot item """ selected_plot_index = self.plot_list.currentRow() if selected_plot_index < 0: return self.plot_item.duplicate_plot(selected_plot_index) self.populate_plot_list() self.plot_item.refresh() def remove_plot(self): """ Removes the selected plot and updates the plot list and the plot item """ selected_index = self.plot_list.currentRow() if selected_index < 0: return self.plot_item.remove_plot(selected_index) self.populate_plot_list() self.plot_item.refresh() def move_up_plot(self): """ Moves the selected plot up and updates the plot list and the plot item """ selected_index = self.plot_list.currentRow() if selected_index <= 0: return item = self.plot_item.plot_settings.pop(selected_index) self.plot_item.plot_settings.insert(selected_index - 1, item) self.plot_list.setCurrentRow(selected_index - 1, QItemSelectionModel.SelectCurrent) self.populate_plot_list() self.plot_item.refresh() def move_down_plot(self): """ Moves the selected plot down and updates the plot list and the plot item """ selected_index = self.plot_list.currentRow() if selected_index >= len(self.plot_item.plot_settings) - 1: return item = self.plot_item.plot_settings.pop(selected_index) self.plot_item.plot_settings.insert(selected_index + 1, item) self.plot_list.setCurrentRow(selected_index + 1, QItemSelectionModel.SelectCurrent) self.populate_plot_list() self.plot_item.refresh() def show_properties(self): """ Shows the plot properties panel """ selected_plot_index = self.plot_list.currentRow() if selected_plot_index < 0: return self.panel = DataPlotlyPanelWidget( mode=DataPlotlyPanelWidget.MODE_LAYOUT, message_bar=self.message_bar) # not quite right -- we ideally want to also add the source layer scope into the context given by plot item, # but that causes a hard lock in the Python GIL (because PyQt doesn't release the GIL when creating the menu # for the property override buttons). Nothing much we can do about that here (or in QGIS, # it's a Python/PyQt limitation) self.panel.registerExpressionContextGenerator(self.plot_item) self.panel.set_print_layout(self.plot_item.layout()) self.panel.linked_map_combo.blockSignals(True) self.panel.linked_map_combo.setItem(self.plot_item.linked_map) self.panel.linked_map_combo.blockSignals(False) self.panel.linked_map_combo.itemChanged.connect( self.linked_map_changed) self.panel.set_settings( self.plot_item.plot_settings[selected_plot_index]) # self.panel.set_settings(self.layoutItem().plot_settings) self.openPanel(self.panel) self.panel.widgetChanged.connect(self.update_item_settings) self.panel.panelAccepted.connect(self.set_item_settings) def update_item_settings(self): """ Updates the plot item without dismissing the properties panel """ if not self.panel: return self.plot_item.set_plot_settings(self.plot_list.currentRow(), self.panel.get_settings()) self.populate_plot_list() self.plot_item.update() def set_item_settings(self): """ Updates the plot item based on the settings from the properties panel """ if not self.panel: return self.plot_item.set_plot_settings(self.plot_list.currentRow(), self.panel.get_settings()) self.populate_plot_list() self.panel = None self.plot_item.update() def linked_map_changed(self, linked_map): """ Triggered when the linked map is changed """ self.plot_item.set_linked_map(linked_map) self.plot_item.update() def setNewItem(self, item): # pylint: disable=missing-docstring if item.type() != ITEM_TYPE: return False self.plot_item = item self.item_properties_widget.setItem(item) self.populate_plot_list() if self.panel is not None: self.panel.set_settings(self.plot_item.plot_settings[0]) self.panel.linked_map_combo.blockSignals(True) self.panel.linked_map_combo.setItem(self.plot_item.linked_map) self.panel.linked_map_combo.blockSignals(False) return True def setDesignerInterface(self, iface): # pylint: disable=missing-docstring super().setDesignerInterface(iface) self.message_bar = iface.messageBar() if self.panel: self.panel.message_bar = self.message_bar