class ChooseBlogDialog(QDialog, Ui_ChooseBlogDialog): def __init__(self, available_blogs, addToDB): QDialog.__init__(self) Ui_ChooseBlogDialog.__init__(self) self.func = addToDB self.setupUi(self) radioboxLayout = QVBoxLayout() self.radiobuttonGroup = QButtonGroup() self.radios = [] for blog in available_blogs: radio = BlogRadio("Blog Title: %s, Url: %s" %(blog.blogname, blog.homeurl), blog) self.radiobuttonGroup.addButton(radio) radioboxLayout.addWidget(radio) self.radios.append(radio) self.chooseBlogFrame.setLayout(radioboxLayout) self.adjustSize() connect(self.chooseBlogButtonBox, SIGNAL("accepted()"), self.addBlog) #AddBlogDialog.accept) connect(self.chooseBlogButtonBox, SIGNAL("rejected()"), self.reject)#AddBlogDialog.reject) def addBlog(self): if self.radiobuttonGroup.checkedButton(): self.func(self.radiobuttonGroup.checkedButton().blog) self.accept() else: QMessageBox.warning(self, "Choose A Blog", "Please choose a blog and click OK. If you do not want to add a blog, Please click 'Cancel'", QMessageBox.Ok, QMessageBox.Ok) pass
class DefaultSelectParameterWidget(SelectParameterWidget): """Widget class for Default Select Parameter.""" def __init__(self, parameter, parent=None): """Constructor :param parameter: A DefaultSelectParameter object. :type parameter: DefaultSelectParameter """ super(DefaultSelectParameterWidget, self).__init__(parameter, parent) self.default_layout = QHBoxLayout() self.radio_button_layout = QHBoxLayout() self.radio_button_widget = QWidget() self.default_label = QLabel(tr('Default')) # Create radio button group self.default_input_button_group = QButtonGroup() # Define string enabler for radio button self.radio_button_enabler = self.input.itemData(0, Qt.UserRole) for i in range(len(self._parameter.default_labels)): if '%s' in self._parameter.default_labels[i]: label = (self._parameter.default_labels[i] % self._parameter.default_values[i]) else: label = self._parameter.default_labels[i] radio_button = QRadioButton(label) self.radio_button_layout.addWidget(radio_button) self.default_input_button_group.addButton(radio_button, i) if self._parameter.default_value == \ self._parameter.default_values[i]: radio_button.setChecked(True) # Create double spin box for custom value self.custom_value = QDoubleSpinBox() if self._parameter.default_values[-1]: self.custom_value.setValue(self._parameter.default_values[-1]) has_min = False if self._parameter.minimum is not None: has_min = True self.custom_value.setMinimum(self._parameter.minimum) has_max = False if self._parameter.maximum is not None: has_max = True self.custom_value.setMaximum(self._parameter.maximum) if has_min and has_max: step = (self._parameter.maximum - self._parameter.minimum) / 100.0 self.custom_value.setSingleStep(step) self.radio_button_layout.addWidget(self.custom_value) self.toggle_custom_value() # Reset the layout self.input_layout.setParent(None) self.help_layout.setParent(None) self.label.setParent(None) self.inner_input_layout.setParent(None) self.input_layout = QGridLayout() self.input_layout.setSpacing(0) self.input_layout.addWidget(self.label, 0, 0) self.input_layout.addLayout(self.inner_input_layout, 0, 1) self.input_layout.addWidget(self.default_label, 1, 0) self.input_layout.addLayout(self.radio_button_layout, 1, 1) self.main_layout.addLayout(self.input_layout) self.main_layout.addLayout(self.help_layout) # check every added combobox, it could have been toggled by # the existing keyword self.toggle_input() # Connect # noinspection PyUnresolvedReferences self.input.currentIndexChanged.connect(self.toggle_input) self.default_input_button_group.buttonClicked.connect( self.toggle_custom_value) def raise_invalid_type_exception(self): message = 'Expecting element type of %s' % ( self._parameter.element_type.__name__) err = ValueError(message) return err def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A DefaultSelectParameter from the current state of widget. """ current_index = self.input.currentIndex() selected_value = self.input.itemData(current_index, Qt.UserRole) if hasattr(selected_value, 'toPyObject'): selected_value = selected_value.toPyObject() try: self._parameter.value = selected_value except ValueError: err = self.raise_invalid_type_exception() raise err radio_button_checked_id = self.default_input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id == -1: self._parameter.default = None # The last radio button (custom) is checked, get the value from the # line edit elif (radio_button_checked_id == len(self._parameter.default_values) - 1): self._parameter.default_values[radio_button_checked_id] \ = self.custom_value.value() self._parameter.default = self.custom_value.value() else: self._parameter.default = self._parameter.default_values[ radio_button_checked_id] return self._parameter def set_default(self, default): """Set default value by item's string. :param default: The default. :type default: str, int :returns: True if success, else False. :rtype: bool """ # Find index of choice try: default_index = self._parameter.default_values.index(default) self.default_input_button_group.button(default_index).setChecked( True) except ValueError: last_index = len(self._parameter.default_values) - 1 self.default_input_button_group.button(last_index).setChecked(True) self.custom_value.setValue(default) self.toggle_custom_value() def toggle_custom_value(self): radio_button_checked_id = self.default_input_button_group.checkedId() if (radio_button_checked_id == len(self._parameter.default_values) - 1): self.custom_value.setDisabled(False) else: self.custom_value.setDisabled(True) def toggle_input(self): """Change behaviour of radio button based on input.""" current_index = self.input.currentIndex() # If current input is not a radio button enabler, disable radio button. if self.input.itemData(current_index, Qt.UserRole) != (self.radio_button_enabler): self.disable_radio_button() # Otherwise, enable radio button. else: self.enable_radio_button() def set_selected_radio_button(self): """Set selected radio button to 'Do not report'.""" dont_use_button = self.default_input_button_group.button( len(self._parameter.default_values) - 2) dont_use_button.setChecked(True) def disable_radio_button(self): """Disable radio button group and custom value input area.""" checked = self.default_input_button_group.checkedButton() if checked: self.default_input_button_group.setExclusive(False) checked.setChecked(False) self.default_input_button_group.setExclusive(True) for button in self.default_input_button_group.buttons(): button.setDisabled(True) self.custom_value.setDisabled(True) def enable_radio_button(self): """Enable radio button and custom value input area then set selected radio button to 'Do not report'. """ for button in self.default_input_button_group.buttons(): button.setEnabled(True) self.set_selected_radio_button() self.custom_value.setEnabled(True)
class AutoFieldsDockWidget( QDockWidget, Ui_AutoFieldsDockWidget ): """ Class in charge of all the UI logic """ def __init__( self, parent, iface, autoFieldManager, messageManager, language='en' ): self.iface = iface self.msg = messageManager self.language = language QDockWidget.__init__( self, parent ) # Set up the user interface from Designer. self.setupUi( self ) self.autoFieldManager = autoFieldManager self.geometryDict = ['points','lines','polygons'] self.fieldTypesDict = ['Integer','Real','String','Date'] self.root = QgsProject.instance().layerTreeRoot() # UI stuff that wasn't set/initialized in Qt-Designer self.tblLayers.setColumnWidth( 0, 24 ) self.tblLayers.setColumnWidth( 1, 140 ) self.tblLayers.setColumnWidth( 2, 110 ) self.tblLayers.horizontalHeader().setResizeMode( 0, QHeaderView.Fixed ) self.tblLayers.sortItems(1, Qt.AscendingOrder) self.cboField.setEnabled( False ) self.cboFieldType.setItemData( 0, QVariant.Int, Qt.UserRole ) self.cboFieldType.setItemData( 1, QVariant.Double, Qt.UserRole ) self.cboFieldType.setItemData( 2, QVariant.String, Qt.UserRole ) self.cboFieldType.setItemData( 3, QVariant.Date, Qt.UserRole ) self.fieldTypeChanged( self.cboFieldType.currentIndex() ) # Update length/precision controls self.btnGroup = QButtonGroup() self.btnGroup.addButton( self.optXCoord ) self.btnGroup.addButton( self.optYCoord ) self.btnGroup.addButton( self.optLength ) self.btnGroup.addButton( self.optPerimeter ) self.btnGroup.addButton( self.optArea ) self.btnGroup.addButton( self.optDate ) self.btnGroup.addButton( self.optCustomExpression ) #self.btnGroup.addButton( self.optSpatialValue ) self.updateExpressionControls( self.optCustomExpression ) self.frameFields.setEnabled( False ) self.frameExpression.setEnabled( False ) self.populateLayersTable() QgsMapLayerRegistry.instance().legendLayersAdded.connect( self.populateLayersTable ) QgsMapLayerRegistry.instance().layersRemoved.connect( self.populateLayersTable ) # Also listen to Layer Tree node position changes self.root.addedChildren.connect( self.populateLayersTable ) self.root.removedChildren.connect( self.populateLayersTable ) self.tblLayers.itemSelectionChanged.connect( self.updateFieldAndExpressionControls ) self.optNewField.toggled.connect( self.newFieldToggled ) self.cboField.currentIndexChanged.connect( self.fieldChanged ) self.cboFieldType.currentIndexChanged.connect( self.fieldTypeChanged ) self.btnSaveAutoField.clicked.connect( self.saveAutoField ) self.btnNewCustomExpression.clicked.connect( self.setCustomExpression ) self.btnGroup.buttonClicked.connect( self.updateExpressionControls ) self.expressionDlg = None # 'List of AutoFields' Tab settings = QSettings() check = settings.value( self.autoFieldManager.settingsPrefix + "/showOnlyEnabledAutoFields", True, type=bool ) self.chkOnlyEnabledAutoFields.setChecked( check ) check = settings.value( self.autoFieldManager.settingsPrefix + "/calculateOnExistingFeatures", True, type=bool ) self.chkCalculateOnExisting.setChecked( check ) self.btnRemoveAutoFields.setEnabled( False ) self.tblAutoFields.sortItems(0, Qt.AscendingOrder) self.populateAutoFieldsTable() self.autoFieldManager.autoFieldCreated.connect( self.populateAutoFieldsTable ) self.autoFieldManager.autoFieldRemoved.connect( self.populateAutoFieldsTable ) self.autoFieldManager.autoFieldEnabled.connect( self.populateAutoFieldsTable ) self.autoFieldManager.autoFieldDisabled.connect( self.populateAutoFieldsTable ) self.tblAutoFields.itemSelectionChanged.connect( self.updateRemoveAutoFieldButton ) self.chkOnlyEnabledAutoFields.toggled.connect( self.saveShowOnlyEnabledPreference ) self.chkCalculateOnExisting.toggled.connect( self.saveCalculateOnExistingPreference ) self.btnRemoveAutoFields.clicked.connect( self.removeAutoFieldFromTable ) # Context menu self.tblAutoFields.setContextMenuPolicy( Qt.CustomContextMenu ) self.tblAutoFields.customContextMenuRequested.connect( self.openAutoFieldContextMenu ) # About Tab self.btnHelp.clicked.connect( self.openDocumentation ) def populateLayersTable( self, foo=None, foo2=None, foo3=None ): """ List vector layers that support changes in attributes and are writable. Arguments are 3 and optional because this function listens to several SIGNALs. """ # Initialize Layers Table self.tblLayers.clearContents() self.tblLayers.setRowCount( 0 ) vLayers = [] for layer in QgsMapLayerRegistry.instance().mapLayers().values(): if layer.type() == QgsMapLayer.VectorLayer: if layer.dataProvider().capabilities() & QgsVectorDataProvider.ChangeAttributeValues: if not layer.isReadOnly(): if layer.geometryType() < 3: # Avoid UnknownGeometry and NoGeometry vLayers.append( layer ) self.tblLayers.setRowCount( len( vLayers ) ) self.tblLayers.setColumnCount( 3 ) self.tblLayers.setSortingEnabled( False ) for row, lyr in enumerate( vLayers ): item = QTableWidgetItem( QIcon( ":/plugins/AutoFields/icons/" + \ self.geometryDict[lyr.geometryType()] + ".png"), str( lyr.geometryType() ) ) self.tblLayers.setItem( row, 0, item ) item = QTableWidgetItem( lyr.name() ) item.setData( Qt.UserRole, lyr.id() ) self.tblLayers.setItem( row, 1, item ) tmpTreeLayer = self.root.findLayer( lyr.id() ) if tmpTreeLayer: group = tmpTreeLayer.parent().name() self.tblLayers.setItem(row, 2, QTableWidgetItem( group if group else QApplication.translate("AutoFieldsDockWidgetPy", "< root >" ) ) ) self.tblLayers.setSortingEnabled( True ) def updateFieldAndExpressionControls( self ): """ After a selection is changed, reflect possible values in field controls """ self.msg.show( "New selection " + str(len( self.tblLayers.selectedItems() ) / 3), 'info', True ) if not self.tblLayers.selectedItems(): self.frameFields.setEnabled( False ) self.frameExpression.setEnabled( False ) return else: self.frameFields.setEnabled( True ) self.frameExpression.setEnabled( True ) # List common fields in cboField and get geometries selected geometryTypeSet = self.updateFieldList() # Update expression controls if 0 in geometryTypeSet and len( geometryTypeSet ) == 1: # Points self.optXCoord.setEnabled( True ) self.optYCoord.setEnabled( True ) self.optLength.setEnabled( False ) self.optPerimeter.setEnabled( False ) self.optArea.setEnabled( False ) elif 1 in geometryTypeSet and len( geometryTypeSet ) == 1: # Lines self.optXCoord.setEnabled( False ) self.optYCoord.setEnabled( False ) self.optLength.setEnabled( True ) self.optPerimeter.setEnabled( False ) self.optArea.setEnabled( False ) elif 2 in geometryTypeSet and len( geometryTypeSet ) == 1: # Polygons self.optXCoord.setEnabled( False ) self.optYCoord.setEnabled( False ) self.optLength.setEnabled( False ) self.optPerimeter.setEnabled( True ) self.optArea.setEnabled( True ) else: self.optXCoord.setEnabled( False ) self.optYCoord.setEnabled( False ) self.optLength.setEnabled( False ) self.optPerimeter.setEnabled( False ) self.optArea.setEnabled( False ) if not self.btnGroup.checkedButton().isEnabled(): self.optCustomExpression.setChecked( True ) # Default selection self.updateExpressionControls( self.optCustomExpression ) self.expressionDlg = None # Initialize the dialog def updateFieldList( self ): """ Update field list and return geometries selected """ commonFields = [] geometryTypeSet = set() bFirstFlag = True for item in self.tblLayers.selectedItems(): if item.column() == 1: # It's the layer name item self.msg.show( "ID " + item.data( Qt.UserRole ), 'info', True ) # Get layer id layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) ) geometryTypeSet.add( layer.geometryType() ) tmpFields = [field.name() for field in layer.dataProvider().fields()] # Get field names stored in the provider if bFirstFlag: # Initialize commonFields commonFields = tmpFields bFirstFlag = False else: # Intersect fields if commonFields: # Avoid intersecting if no common fields commonFields = list( set( commonFields ) & set( tmpFields ) ) commonFields.sort() self.msg.show( "FIELDS: "+ str(commonFields), 'info', True) self.cboField.clear() if not commonFields: self.optExistingField.setEnabled( False ) self.optNewField.setChecked( True ) else: self.optExistingField.setEnabled( True ) self.cboField.addItems( commonFields ) return geometryTypeSet def newFieldToggled( self ): """ Alternate between controls of new field and existing field """ newIsChecked = self.optNewField.isChecked() self.cboField.setEnabled( not newIsChecked ) self.lblFieldName.setEnabled( newIsChecked ) self.lblFieldType.setEnabled( newIsChecked ) self.txtFieldName.setEnabled( newIsChecked ) self.cboFieldType.setEnabled( newIsChecked ) if newIsChecked: self.fieldTypeChanged( self.cboFieldType.currentIndex() ) else: self.lblFieldLength.setEnabled( newIsChecked ) self.lblFieldPrecision.setEnabled( newIsChecked ) self.txtFieldLength.setEnabled( newIsChecked ) self.txtFieldPrecision.setEnabled( newIsChecked ) self.expressionDlg = None # Initialize the dialog def fieldTypeChanged( self, idx ): """ Update field length and field precision controls' state and values """ text = self.fieldTypesDict[idx] if text == 'Integer': self.txtFieldLength.setRange( 1, 10 ) self.txtFieldLength.setEnabled( True ) self.txtFieldPrecision.setEnabled( False ) self.lblFieldLength.setEnabled( True ) self.lblFieldPrecision.setEnabled( False ) elif text == 'Real': self.txtFieldLength.setRange( 1, 20 ) self.txtFieldPrecision.setRange( 0, 15 ) self.txtFieldLength.setEnabled( True ) self.txtFieldPrecision.setEnabled( True ) self.lblFieldLength.setEnabled( True ) self.lblFieldPrecision.setEnabled( True ) elif text == 'String': self.txtFieldLength.setRange( 1, 255 ) self.txtFieldLength.setEnabled( True ) self.txtFieldPrecision.setEnabled( False ) self.lblFieldLength.setEnabled( True ) self.lblFieldPrecision.setEnabled( False ) else: # Date self.txtFieldLength.setEnabled( False ) self.txtFieldPrecision.setEnabled( False ) self.lblFieldLength.setEnabled( False ) self.lblFieldPrecision.setEnabled( False ) def fieldChanged( self, idx ): """ Just to initialize the expression dialog if selected field changes """ self.expressionDlg = None # Initialize the dialog def saveAutoField( self ): """ Do some validation and then call AutoFieldManager """ # Check layers if not self.tblLayers.selectedItems(): self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Warning] Please first select a layer." ), 'warning' ) return # Check expression expression = u'' if self.optXCoord.isChecked(): expression = u'$x' elif self.optYCoord.isChecked(): expression = u'$y' elif self.optLength.isChecked(): expression = u'$length' elif self.optPerimeter.isChecked(): expression = u'$perimeter' elif self.optArea.isChecked(): expression = u'$area' elif self.optDate.isChecked(): expression = u'now()' elif self.optCustomExpression.isChecked(): if self.expressionDlg: expression = self.expressionDlg.expression if not self.expressionDlg or not expression: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Warning] Please first set a valid custom expression." ), 'warning' ) return else: # optSpatialValue pass # Check fields fieldName = '' if self.optNewField.isChecked(): if self.txtFieldName.text(): fieldName = self.txtFieldName.text().strip() newField = QgsField( fieldName, self.cboFieldType.itemData( self.cboFieldType.currentIndex(), Qt.UserRole) ) length = self.txtFieldLength.value() precision = self.txtFieldPrecision.value() # Ensure length and precision are valid values when dealing with Real numbers if self.fieldTypesDict[self.cboFieldType.currentIndex()] == 'Real': if precision > length: precision = length newField.setLength( length ) newField.setPrecision( precision ) for item in self.tblLayers.selectedItems(): if item.column() == 1: # It's the layer name item layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) ) if layer.fieldNameIndex( fieldName ) != -1: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Error] The field " ) + fieldName + \ QApplication.translate( "AutoFieldsDockWidgetPy", " already exists in layer " ) + layer.name() + ". " + \ QApplication.translate( "AutoFieldsDockWidgetPy", " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ), 'warning' ) else: res = layer.dataProvider().addAttributes( [ newField ] ) if res: layer.updateFields() # Check if fieldName is preserved by the provider after field creation. if layer.fieldNameIndex( fieldName ) == -1: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Error] The field " ) + fieldName + \ QApplication.translate( "AutoFieldsDockWidgetPy", " was probably created with another name by the layer (" ) + \ layer.name() + \ QApplication.translate( "AutoFieldsDockWidgetPy", ") provider. " ) + \ QApplication.translate( "AutoFieldsDockWidgetPy", " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ), 'warning' ) else: self.doSaveAutoField( layer, fieldName, expression ) else: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Error] Couldn't create " ) + newField.name() + \ QApplication.translate( "AutoFieldsDockWidgetPy", " field in " ) + layer.name() + \ QApplication.translate( "AutoFieldsDockWidgetPy", " layer." ), 'warning' ) # Some fields might have been created, update the field list once self.updateFieldList() else: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Warning] Please first set a name for the new field." ), 'warning' ) return else: fieldName = self.cboField.currentText() for item in self.tblLayers.selectedItems(): if item.column() == 1: # It's the layer name item layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) ) self.doSaveAutoField( layer, fieldName, expression ) def doSaveAutoField( self, layer, fieldName, expression ): """ Repetitive logic to save or overwrite an AutoField """ # Check if the field is an AutoField and ask if we should overwrite it res = True bCalculateOnExisting = self.chkCalculateOnExisting.isChecked() if self.autoFieldManager.isFieldAnAutoField( layer, fieldName ): reply = QMessageBox.question( self.iface.mainWindow(), QApplication.translate( "AutoFieldsDockWidgetPy", "Confirmation" ), QApplication.translate( "AutoFieldsDockWidgetPy", "The field '" ) + \ fieldName + QApplication.translate( "AutoFieldsDockWidgetPy", "' from layer '" ) + layer.name() + \ QApplication.translate( "AutoFieldsDockWidgetPy", "' is already an AutoField.\nDo you want to overwrite it?" ), QMessageBox.Yes | QMessageBox.No, QMessageBox.No ) if reply == QMessageBox.Yes: res = self.autoFieldManager.overwriteAutoField( layer, fieldName, expression, calculateOnExisting=bCalculateOnExisting ) else: res = self.autoFieldManager.createAutoField( layer, fieldName, expression, calculateOnExisting=bCalculateOnExisting ) if not res: # res will only be False if create/overwriteAutoField return False self.msg.show( "[Error] The AutoField for layer '" + layer.name() + \ "' and field '" + fieldName + "' couldn't be created.", 'warning', True ) def setCustomExpression( self ): """ Initialize and show the expression builder dialog """ layer = None if len( self.tblLayers.selectedItems() ) / 3 == 1: # Single layer selected? for item in self.tblLayers.selectedItems(): if item.column() == 1: # It's the layer name item layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) ) if not self.expressionDlg: self.expressionDlg = ExpressionBuilderDialog( self.iface.mainWindow() ) context = QgsExpressionContext() context.appendScope( QgsExpressionContextUtils.globalScope() ) context.appendScope( QgsExpressionContextUtils.projectScope() ) # Initialize dialog with layer-based names and variables if single layer selected if len( self.tblLayers.selectedItems() ) / 3 == 1: context.appendScope( QgsExpressionContextUtils.layerScope( layer ) ) self.expressionDlg.expressionBuilderWidget.setLayer( layer ) self.expressionDlg.expressionBuilderWidget.loadFieldNames() # This block was borrowed from QGIS/python/plugins/processing/algs/qgis/FieldsCalculator.py da = QgsDistanceArea() da.setSourceCrs( layer.crs().srsid() ) da.setEllipsoidalMode( self.iface.mapCanvas().mapSettings().hasCrsTransformEnabled() ) da.setEllipsoid( QgsProject.instance().readEntry( 'Measure', '/Ellipsoid', GEO_NONE )[0] ) self.expressionDlg.expressionBuilderWidget.setGeomCalculator( da ) # If this layer-field is an AutoField, get its expression if self.optExistingField.isChecked(): fieldName = self.cboField.currentText() expression = self.autoFieldManager.getFieldExpression( layer, fieldName ) self.expressionDlg.expressionBuilderWidget.setExpressionText( expression ) self.expressionDlg.expression = expression # To remember it when closing/opening self.expressionDlg.expressionBuilderWidget.setExpressionContext( context ) self.expressionDlg.show() def updateExpressionControls( self, button ): """ Enable/disable push buttons when appropriate """ if button.objectName() == 'optCustomExpression': self.btnNewCustomExpression.setEnabled( True ) #self.btnNewSpatialValue.setEnabled( False ) #elif button.objectName() == 'optSpatialValue': #self.btnNewCustomExpression.setEnabled( False ) #self.btnNewSpatialValue.setEnabled( True ) else: self.btnNewCustomExpression.setEnabled( False ) #self.btnNewSpatialValue.setEnabled( False ) def populateAutoFieldsTable( self, autoFieldId=None ): """ Listens to any modification on AutoFields to update the list """ dictAutoFields = self.autoFieldManager.listAutoFields() if autoFieldId: # Just update this one if not autoFieldId in dictAutoFields: # AutoField removed self.msg.show( "[Info] Removing AutoField from table.", 'info', True ) # Iterate through AF rows and remove row where data matches AFID deleteRow = self.findRowOfItemDataInAutoFieldsTable( autoFieldId, 0) if deleteRow != -1: self.tblAutoFields.removeRow( deleteRow ) else: # if it's in the table: remove it and re-add it (from new dict) deleteRow = self.findRowOfItemDataInAutoFieldsTable( autoFieldId, 0) if deleteRow != -1: self.msg.show( "[Info] Refreshing AutoField status in table.", 'info', True ) self.tblAutoFields.removeRow( deleteRow ) self.addAutoFieldToAutoFieldsTable( autoFieldId, dictAutoFields[autoFieldId] ) else: # New AutoField, just add it to table self.msg.show( "[Info] Adding new AutoField to table.", 'info', True ) self.addAutoFieldToAutoFieldsTable( autoFieldId, dictAutoFields[autoFieldId] ) else: # Initialize AutoFields Table self.tblAutoFields.clearContents() self.tblAutoFields.setRowCount( 0 ) #self.tblAutoFields.setRowCount( len( dictAutoFields ) ) self.tblAutoFields.setColumnCount( 4 ) self.tblAutoFields.setSortingEnabled( False ) for key in dictAutoFields.keys(): autoField = dictAutoFields[key] self.addAutoFieldToAutoFieldsTable( key, autoField, False ) self.tblAutoFields.setSortingEnabled( True ) def findRowOfItemDataInAutoFieldsTable( self, data, col ): """ Get the row number that matches its data to a given data (check only the given column) """ for numRow in range( self.tblAutoFields.rowCount() ): item = self.tblAutoFields.item( numRow, col ) if item.data( Qt.UserRole ) == data: return numRow return -1 def addAutoFieldToAutoFieldsTable( self, autoFieldId, autoField, freezeSorting=True ): """ Add a whole row to the AutoFields table """ if self.chkOnlyEnabledAutoFields.isChecked() and not autoField['enabled']: return if freezeSorting: self.tblAutoFields.setSortingEnabled( False ) row = self.tblAutoFields.rowCount() self.tblAutoFields.insertRow( row ) name = autoField['layer'] if 'layerId' in autoField: lyr = QgsMapLayerRegistry.instance().mapLayer( autoField['layerId'] ) name = lyr.name() item = QTableWidgetItem( name ) item.setData( Qt.UserRole, autoFieldId ) item.setData( Qt.ToolTipRole, autoField['layer'] ) if not autoField['enabled']: item.setForeground( QBrush( Qt.gray ) ) self.tblAutoFields.setItem( row, 0, item ) item = QTableWidgetItem( autoField['field'] ) if not autoField['enabled']: item.setForeground( QBrush( Qt.gray ) ) self.tblAutoFields.setItem( row, 1, item ) item = QTableWidgetItem( autoField['expression'] ) if not autoField['enabled']: item.setForeground( QBrush( Qt.gray ) ) self.tblAutoFields.setItem( row, 2, item ) item = QTableWidgetItem( QApplication.translate( "AutoFieldsDockWidgetPy", "Enabled" ) if autoField['enabled'] else QApplication.translate( "AutoFieldsDockWidgetPy", "Disabled" ) ) item.setData( Qt.UserRole, 'enabled' if autoField['enabled'] else 'disabled' ) if not autoField['enabled']: item.setForeground( QBrush( Qt.gray ) ) self.tblAutoFields.setItem( row, 3, item ) if freezeSorting: self.tblAutoFields.setSortingEnabled( True ) def openAutoFieldContextMenu( self, position ): bLayers = False layers = QgsMapLayerRegistry.instance().mapLayers().values() for layer in layers: if layer.type() == QgsMapLayer.VectorLayer: if layer.dataProvider().capabilities() & QgsVectorDataProvider.AddFeatures: bLayers = True break item = self.tblAutoFields.itemAt( position ) if item: row = item.row() self.menu = QMenu() self.action = QAction( "Assign this AutoField to another layer", None ) self.action.setObjectName('action') if self.tblAutoFields.item( row, 3 ).data( Qt.UserRole ) == 'enabled': self.action.setEnabled( False ) self.menu.addAction( self.action ) action = self.menu.exec_(self.tblAutoFields.mapToGlobal(position)) if action and action.objectName() == 'action': if not bLayers: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "First load some vector layers to QGIS to be able to assign disabled AutoFields." ), 'warning' ) return autoFieldId = self.tblAutoFields.item( row, 0 ).data( Qt.UserRole ) bCalculateOnExisting = self.chkCalculateOnExisting.isChecked() dlg = AssignAutoFieldToLayerDialog( self.iface.mainWindow(), self.autoFieldManager, autoFieldId, bCalculateOnExisting ) dlg.show() def updateRemoveAutoFieldButton( self ): """ Enable/disable button to remove AutoFields when appropriate """ self.btnRemoveAutoFields.setEnabled( len( self.tblAutoFields.selectedItems() ) / 4 ) def removeAutoFieldFromTable( self ): """ Show a confirmation dialog for all AutoFields selected. If confirmed, remove AutoFields from table. """ # Column 0 has the AutoField id autoFieldsToRemove = [ item.data( Qt.UserRole ) for item in self.tblAutoFields.selectedItems() if item.column() == 0 ] reply = QMessageBox.question( self.iface.mainWindow(), QApplication.translate( "AutoFieldsDockWidgetPy", "Confirmation" ), QApplication.translate( "AutoFieldsDockWidgetPy", "Do you really want to remove " ) + \ str(len( autoFieldsToRemove )) + \ (" AutoFields?" if len( autoFieldsToRemove ) > 1 else " AutoField?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.No ) if reply == QMessageBox.Yes: for autoFieldId in autoFieldsToRemove: self.autoFieldManager.removeAutoField( autoFieldId ) def saveShowOnlyEnabledPreference( self, status ): """ Saves the preference in QSettings and updates list of AutoFields """ settings = QSettings() settings.setValue( self.autoFieldManager.settingsPrefix + "/showOnlyEnabledAutoFields" , status ) self.populateAutoFieldsTable() def saveCalculateOnExistingPreference( self, status ): """ Saves the preference in QSettings """ settings = QSettings() settings.setValue( self.autoFieldManager.settingsPrefix + "/calculateOnExistingFeatures" , status ) def openDocumentation( self ): """ Open a browser to show documentation page """ import webbrowser webbrowser.open( "http://geotux.tuxfamily.org/index.php/"+ self.language +"/geo-blogs/item/333-autofields-plugin-for-qgis" ) def disconnectAll( self ): """ Terminates all SIGNAL/SLOT connections created by this class """ QgsMapLayerRegistry.instance().legendLayersAdded.disconnect( self.populateLayersTable ) QgsMapLayerRegistry.instance().layersRemoved.disconnect( self.populateLayersTable ) self.root.addedChildren.disconnect( self.populateLayersTable ) self.root.removedChildren.disconnect( self.populateLayersTable ) self.tblLayers.itemSelectionChanged.disconnect( self.updateFieldAndExpressionControls ) self.optNewField.toggled.disconnect( self.newFieldToggled ) self.cboField.currentIndexChanged.disconnect( self.fieldChanged ) self.cboFieldType.currentIndexChanged.disconnect( self.fieldTypeChanged ) self.btnSaveAutoField.clicked.disconnect( self.saveAutoField ) self.btnNewCustomExpression.clicked.disconnect( self.setCustomExpression ) self.btnGroup.buttonClicked.disconnect( self.updateExpressionControls ) self.autoFieldManager.autoFieldCreated.disconnect( self.populateAutoFieldsTable ) self.autoFieldManager.autoFieldRemoved.disconnect( self.populateAutoFieldsTable ) self.autoFieldManager.autoFieldEnabled.disconnect( self.populateAutoFieldsTable ) self.autoFieldManager.autoFieldDisabled.disconnect( self.populateAutoFieldsTable ) self.tblAutoFields.itemSelectionChanged.disconnect( self.updateRemoveAutoFieldButton ) self.chkOnlyEnabledAutoFields.toggled.disconnect( self.saveShowOnlyEnabledPreference ) self.btnRemoveAutoFields.clicked.disconnect( self.removeAutoFieldFromTable )
class DefaultSelectParameterWidget(SelectParameterWidget): """Widget class for Default Select Parameter.""" def __init__(self, parameter, parent=None): """Constructor :param parameter: A DefaultSelectParameter object. :type parameter: DefaultSelectParameter """ super(DefaultSelectParameterWidget, self).__init__(parameter, parent) self.default_layout = QHBoxLayout() self.radio_button_layout = QHBoxLayout() self.radio_button_widget = QWidget() self.default_label = QLabel(tr('Default')) # Create radio button group self.default_input_button_group = QButtonGroup() # Define string enabler for radio button self.radio_button_enabler = self.input.itemData(0, Qt.UserRole) for i in range(len(self._parameter.default_labels)): if '%s' in self._parameter.default_labels[i]: label = ( self._parameter.default_labels[i] % self._parameter.default_values[i]) else: label = self._parameter.default_labels[i] radio_button = QRadioButton(label) self.radio_button_layout.addWidget(radio_button) self.default_input_button_group.addButton(radio_button, i) if self._parameter.default_value == \ self._parameter.default_values[i]: radio_button.setChecked(True) # Create double spin box for custom value self.custom_value = QDoubleSpinBox() if self._parameter.default_values[-1]: self.custom_value.setValue(self._parameter.default_values[-1]) has_min = False if self._parameter.minimum is not None: has_min = True self.custom_value.setMinimum(self._parameter.minimum) has_max = False if self._parameter.maximum is not None: has_max = True self.custom_value.setMaximum(self._parameter.maximum) if has_min and has_max: step = (self._parameter.maximum - self._parameter.minimum) / 100.0 self.custom_value.setSingleStep(step) self.radio_button_layout.addWidget(self.custom_value) self.toggle_custom_value() # Reset the layout self.input_layout.setParent(None) self.help_layout.setParent(None) self.label.setParent(None) self.inner_input_layout.setParent(None) self.input_layout = QGridLayout() self.input_layout.setSpacing(0) self.input_layout.addWidget(self.label, 0, 0) self.input_layout.addLayout(self.inner_input_layout, 0, 1) self.input_layout.addWidget(self.default_label, 1, 0) self.input_layout.addLayout(self.radio_button_layout, 1, 1) self.main_layout.addLayout(self.input_layout) self.main_layout.addLayout(self.help_layout) # check every added combobox, it could have been toggled by # the existing keyword self.toggle_input() # Connect # noinspection PyUnresolvedReferences self.input.currentIndexChanged.connect(self.toggle_input) self.default_input_button_group.buttonClicked.connect( self.toggle_custom_value) def raise_invalid_type_exception(self): message = 'Expecting element type of %s' % ( self._parameter.element_type.__name__) err = ValueError(message) return err def get_parameter(self): """Obtain list parameter object from the current widget state. :returns: A DefaultSelectParameter from the current state of widget. """ current_index = self.input.currentIndex() selected_value = self.input.itemData(current_index, Qt.UserRole) if hasattr(selected_value, 'toPyObject'): selected_value = selected_value.toPyObject() try: self._parameter.value = selected_value except ValueError: err = self.raise_invalid_type_exception() raise err radio_button_checked_id = self.default_input_button_group.checkedId() # No radio button checked, then default value = None if radio_button_checked_id == -1: self._parameter.default = None # The last radio button (custom) is checked, get the value from the # line edit elif (radio_button_checked_id == len(self._parameter.default_values) - 1): self._parameter.default_values[radio_button_checked_id] \ = self.custom_value.value() self._parameter.default = self.custom_value.value() else: self._parameter.default = self._parameter.default_values[ radio_button_checked_id] return self._parameter def set_default(self, default): """Set default value by item's string. :param default: The default. :type default: str, int :returns: True if success, else False. :rtype: bool """ # Find index of choice try: default_index = self._parameter.default_values.index(default) self.default_input_button_group.button(default_index).setChecked( True) except ValueError: last_index = len(self._parameter.default_values) - 1 self.default_input_button_group.button(last_index).setChecked( True) self.custom_value.setValue(default) self.toggle_custom_value() def toggle_custom_value(self): radio_button_checked_id = self.default_input_button_group.checkedId() if (radio_button_checked_id == len(self._parameter.default_values) - 1): self.custom_value.setDisabled(False) else: self.custom_value.setDisabled(True) def toggle_input(self): """Change behaviour of radio button based on input.""" current_index = self.input.currentIndex() # If current input is not a radio button enabler, disable radio button. if self.input.itemData(current_index, Qt.UserRole) != ( self.radio_button_enabler): self.disable_radio_button() # Otherwise, enable radio button. else: self.enable_radio_button() def set_selected_radio_button(self): """Set selected radio button to 'Do not report'.""" dont_use_button = self.default_input_button_group.button( len(self._parameter.default_values) - 2) dont_use_button.setChecked(True) def disable_radio_button(self): """Disable radio button group and custom value input area.""" checked = self.default_input_button_group.checkedButton() if checked: self.default_input_button_group.setExclusive(False) checked.setChecked(False) self.default_input_button_group.setExclusive(True) for button in self.default_input_button_group.buttons(): button.setDisabled(True) self.custom_value.setDisabled(True) def enable_radio_button(self): """Enable radio button and custom value input area then set selected radio button to 'Do not report'. """ for button in self.default_input_button_group.buttons(): button.setEnabled(True) self.set_selected_radio_button() self.custom_value.setEnabled(True)
class OptionWidget(EditorWidget): widgettype = 'Option Row' def __init__(self, *args, **kwargs): super(OptionWidget, self).__init__(*args, **kwargs) self._bindvalue = None self.group = QButtonGroup() self.group.buttonClicked.connect(self.emitvaluechanged) def createWidget(self, parent=None): widget = QWidget(parent) return widget def _buildfromlist(self, listconfig, multiselect): def chunks(l, n): """ Yield successive n-sized chunks from l. """ for i in xrange(0, len(l), n): yield l[i:i+n] items = listconfig['items'] wrap = self.config.get('wrap', 0) showcolor = self.config.get('always_color', False) if wrap > 0: rows = list(chunks(items, wrap)) else: rows = [items] for rowcount, row in enumerate(rows): for column, item in enumerate(row): parts = item.split(';') data = parts[0] try: desc = parts[1] except IndexError: desc = data button = QPushButton() button.setCheckable(multiselect) self.group.setExclusive(not multiselect) icon = QIcon() try: path = parts[2] if path.startswith("#"): # Colour the button with the hex value. # If show color is enabled we always show the color regardless of selection. print showcolor if not showcolor: style = """ QPushButton::checked {{ border: 3px solid rgb(137, 175, 255); background-color: {colour}; }}""".format(colour=path) else: style = """ QPushButton::checked {{ border: 3px solid rgb(137, 175, 255); }} QPushButton {{ background-color: {colour}; }}""".format(colour=path) button.setStyleSheet(style) elif path.endswith("_icon"): icon = QIcon(":/icons/{}".format(path)) else: icon = QIcon(path) except: icon = QIcon() button.setCheckable(True) button.setText(desc) button.setProperty("value", data) button.setIcon(icon) button.setIconSize(QSize(24, 24)) if isinstance(self.widget.layout(), QBoxLayout): self.widget.layout().addWidget(button) else: self.widget.layout().addWidget(button, rowcount, column) self.group.addButton(button) def initWidget(self, widget, config): if not widget.layout(): widget.setLayout(QGridLayout()) widget.layout().setContentsMargins(0, 0, 0, 0) def updatefromconfig(self): super(OptionWidget, self).updatefromconfig() for button in self.group.buttons(): self.group.removeButton(button) self.widget.layout().removeWidget(button) button.deleteLater() button.setParent(None) listconfig = self.config['list'] multiselect = self.config.get('multi', False) self._buildfromlist(listconfig, multiselect) super(OptionWidget, self).endupdatefromconfig() def validate(self, *args): button = self.group.checkedButton() if button: return True return False @property def buttons(self): return self.group.buttons() @property def nullvalues(self): return ['NULL'] @property def multioption(self): return self.config.get('multi', False) def setvalue(self, value): def set_button(setvalue): for button in self.group.buttons(): buttonvalue = button.property("value") if (setvalue is None and buttonvalue in self.nullvalues) or buttonvalue == str(setvalue): button.setChecked(True) self.emitvaluechanged() return if value in self.nullvalues: value = None if self.multioption and value: values = value.split(';') else: values = [value] for value in values: set_button(value) def value(self): def _returnvalue(): if self.multioption: _values = [] checked = [button for button in self.group.buttons() if button.isChecked()] for button in checked: value = button.property("value") _values.append(value) if not _values: return None return ";".join(_values) else: checked = self.group.checkedButton() if not checked: return None value = checked.property("value") return value returnvalue = _returnvalue() if returnvalue in self.nullvalues: returnvalue = None return returnvalue
class OptionWidget(EditorWidget): widgettype = 'Option Row' def __init__(self, *args): super(OptionWidget, self).__init__(*args) self._bindvalue = None self.group = QButtonGroup() self.group.setExclusive(True) self.group.buttonClicked.connect(self.emitvaluechanged) def createWidget(self, parent): widget = QWidget(parent) return widget def _buildfromlist(self, listconfig): items = listconfig['items'] for item in items: parts = item.split(';') data = parts[0] try: desc = parts[1] except IndexError: desc = data button = QPushButton() icon = QIcon() try: path = parts[2] if path.startswith("#"): # Colour the button with the hex value style = """ QPushButton:checked {{ border: 3px solid rgb(137, 175, 255); background-color: {colour}; }}""".format(colour=path) button.setStyleSheet(style) elif path.endswith("_icon"): icon = QIcon(":/icons/{}".format(path)) else: icon = QIcon(path) except: icon = QIcon() button.setCheckable(True) button.setText(desc) button.setProperty("value", data) button.setIcon(icon) button.setIconSize(QSize(24, 24)) self.widget.layout().addWidget(button) self.group.addButton(button) def initWidget(self, widget): if not widget.layout(): widget.setLayout(QHBoxLayout()) widget.layout().setContentsMargins(0, 0, 0, 0) def updatefromconfig(self): super(OptionWidget, self).updatefromconfig() for button in self.group.buttons(): self.group.removeButton(button) self.widget.layout().removeWidget(button) button.deleteLater() button.setParent(None) listconfig = self.config['list'] self._buildfromlist(listconfig) super(OptionWidget, self).endupdatefromconfig() def validate(self, *args): button = self.group.checkedButton() if button: return True return False @property def nullvalues(self): return ['NULL'] def setvalue(self, value): if value in self.nullvalues: value = None for button in self.group.buttons(): buttonvalue = button.property("value") if (value is None and buttonvalue in self.nullvalues) or buttonvalue == str(value): button.setChecked(True) self.emitvaluechanged() return def value(self): button = self.group.checkedButton() if not button: return None value = button.property("value") if value in self.nullvalues: value = None return value
class ItemWidget(QWidget): """ @brief Auflistung der Gegenstände. \todo Drag&Drop wäre auch nicht schlecht. \todo Momentan finde ich die Waffenkategorie über die Hintergrundfarbe heraus. Das ist nicht wirklich gut. """ def __init__(self, template, character, parent=None): super(ItemWidget, self).__init__(parent) self.ui = Ui_ItemWidget() self.ui.setupUi(self) self.__character = character self.__storage = template ## Weapons weaponStore = AbstractStoreWidget(template, character) weaponStore.setEnhancedItemTraitsVisible(True) weaponStore.setMagicalItemTraitsVisible(False) weaponStore.setAddCustomVisible(False) self.ui.layout_weapons.addWidget(weaponStore) for category in self.__storage.weapons: for weapon in self.__storage.weapons[category]: weaponStore.addItemToStore( weapon, category, QIcon(Config.ICONS_WEAPONS[category])) weaponStore.itemBought.connect(self.__character.addWeapon) weaponStore.itemSold.connect(self.__character.deleteWeapon) self.__character.weaponAdded.connect(weaponStore.moveItemToInventory) self.__character.weaponRemoved.connect(weaponStore.moveItemToStore) ## Equipment equipmentStore = AbstractStoreWidget(template, character) equipmentStore.setEnhancedItemTraitsVisible(False) equipmentStore.setMagicalItemTraitsVisible(False) equipmentStore.setAddCustomVisible(True) self.ui.layout_equipment.addWidget(equipmentStore) for equipment in self.__storage.equipment: equipmentStore.addItemToStore(equipment) equipmentStore.itemBought.connect(self.__character.addEquipment) equipmentStore.itemSold.connect(self.__character.deleteEquipment) self.__character.equipmentAdded.connect( equipmentStore.moveItemToInventory) self.__character.equipmentRemoved.connect( equipmentStore.moveItemToStore) ## Automobiles automobileStore = AbstractStoreWidget(template, character) automobileStore.setEnhancedItemTraitsVisible(False) automobileStore.setMagicalItemTraitsVisible(False) automobileStore.setAddCustomVisible(False) self.ui.layout_automobiles.addWidget(automobileStore) for category in self.__storage.automobiles: for automobile in self.__storage.automobiles[category]: automobileStore.addItemToStore( automobile, category, QIcon(Config.ICONS_AUTOMOBILES[category])) automobileStore.itemBought.connect(self.__character.addAutomobile) automobileStore.itemSold.connect(self.__character.deleteAutomobile) self.__character.automobileAdded.connect( automobileStore.moveItemToInventory) self.__character.automobileRemoved.connect( automobileStore.moveItemToStore) ## ExtraordinaryItems extraordinaryItemStore = AbstractStoreWidget(template, character) extraordinaryItemStore.setEnhancedItemTraitsVisible(False) extraordinaryItemStore.setMagicalItemTraitsVisible(True) extraordinaryItemStore.setAddCustomVisible(False) self.ui.layout_extraordinaryItems.addWidget(extraordinaryItemStore) for category in self.__storage.extraordinaryItems: for extraordinaryItem in self.__storage.extraordinaryItems[ category]: extraordinaryItemStore.addItemToStore( extraordinaryItem, category, QIcon(Config.ICONS_ITEMS_EXTRAORDINARY[category])) extraordinaryItemStore.itemBought.connect( self.__character.addExtraordinaryItem) extraordinaryItemStore.itemSold.connect( self.__character.deleteExtraordinaryItem) self.__character.extraordinaryItemAdded.connect( extraordinaryItemStore.moveItemToInventory) self.__character.extraordinaryItemRemoved.connect( extraordinaryItemStore.moveItemToStore) ## \todo Sollte nicht vom Betriebssystem, sondern vom verwendeten Style abhängen. self.ui.tabWidget_items.setObjectName("transparentWidget") if os.name == "nt": self.ui.tabWidget_items.setStyleSheet( "QWidget#transparentWidget { background: transparent; }") self.ui.tabWidget_items.setCurrentIndex(0) ## Resources self.ui.traitDots_armorResources.valueChanged.connect( self.__character.traits["Merit"]["Social"]["Resources"].setValue) #self.ui.traitDots_equipmentResources.valueChanged.connect(self.__character.traits["Merit"]["Social"]["Resources"].setValue) self.__character.traits["Merit"]["Social"][ "Resources"].valueChanged.connect( self.ui.traitDots_armorResources.setValue) #self.__character.traits["Merit"]["Social"]["Resources"].valueChanged.connect(self.ui.traitDots_equipmentResources.setValue) self.ui.traitDots_armorEnhancedItem.valueChanged.connect( self.__character.traits["Merit"]["Item"]["Enhanced Item"].setValue) #self.ui.traitDots_equipmentEnhancedItem.valueChanged.connect(self.__character.traits["Merit"]["Item"]["Enhanced Item"].setValue) self.__character.traits["Merit"]["Item"][ "Enhanced Item"].valueChanged.connect( self.ui.traitDots_armorEnhancedItem.setValue) #self.__character.traits["Merit"]["Item"]["Enhanced Item"].valueChanged.connect(self.ui.traitDots_equipmentEnhancedItem.setValue) ## Armor self.__noArmorText = "None" self.__buttonArmorDict = {} self.__buttonGroup_armor = QButtonGroup(self) ## Natürlich muß auch die Wahl bestehen, keine Rüstung zu tragen. Dies ist zu Anfang gewählt. radioButton = QRadioButton(self.__noArmorText) self.ui.layout_armor.addWidget(radioButton) self.__buttonGroup_armor.addButton(radioButton) radioButton.setChecked(True) self.__buttonArmorDict[radioButton.text()] = radioButton for armor in self.__storage.armor: radioButton = QRadioButton(armor) self.ui.layout_armor.addWidget(radioButton) self.__buttonGroup_armor.addButton(radioButton) self.__buttonArmorDict[radioButton.text()] = radioButton self.__buttonGroup_armor.buttonClicked.connect(self.takeArmor) self.ui.checkBox_armorDedicated.toggled.connect(self.takeArmor) self.__character.armorChanged.connect(self.selectArmor) self.__character.speciesChanged.connect(self.hideShowDedicated) ### Equipment #self.ui.pushButton_equipmentAdd.setIcon(QIcon(":/icons/images/actions/1leftarrow.png")) #self.ui.pushButton_equipmentRemove.setIcon(QIcon(":/icons/images/actions/1rightarrow.png")) #for item in self.__storage.equipment: #listItem = QListWidgetItem() #listItem.setText(item) ##listItem.setIcon(QIcon(Config.ICONS_WEAPONS[category])) ##listItem.setData(Qt.BackgroundRole, QColor(Config.weaponsColor[category])) #self.ui.listWidget_equipmentStore.addItem(listItem) #self.ui.pushButton_equipmentAdd.clicked.connect(self.addEquipment) #self.ui.listWidget_equipmentStore.itemDoubleClicked.connect(self.addEquipment) #self.ui.pushButton_equipmentRemove.clicked.connect(self.removeEquipment) #self.ui.listWidget_equipmentInventory.itemDoubleClicked.connect(self.removeEquipment) #self.ui.pushButton_equipmentAddCustom.clicked.connect(self.addCustomEquipment) #self.__character.equipmentChanged.connect(self.refillEquipmentInventory) #self.__character.equipmentChanged.connect(self.refillEquipmentStore) #self.__character.equipmentChanged.connect(self.checkButtonEnabledEquipment) ## Magical Tool self.__character.speciesChanged.connect(self.hideShowMagicalTool) self.ui.lineEdit_magicalTool.textEdited.connect( self.__character.setMagicalTool) self.__character.magicalToolChanged.connect( self.ui.lineEdit_magicalTool.setText) def takeArmor(self): """ Speichert die gewählte Rüstung im Charakter-Speicher. """ armorName = self.__buttonGroup_armor.checkedButton().text() if armorName == self.__noArmorText: armorName = "" dedicated = False if self.ui.checkBox_armorDedicated.isChecked(): dedicated = True self.__character.setArmor(armorName, dedicated=dedicated) def selectArmor(self, armor, dedicated): """ Wählt den Knopf mit der Passenden Bezeichnung aus. """ armorName = armor if not armorName: armorName = self.__noArmorText if armorName in self.__buttonArmorDict: self.__buttonArmorDict[armorName].setChecked(True) if dedicated: self.ui.checkBox_armorDedicated.setChecked(True) else: self.ui.checkBox_armorDedicated.setChecked(False) def hideShowDedicated(self, species): """ Nur bei Werwölfen macht es Sinn, eine Rüstung zuzueignen. Entsprechendes Widget wird für alle anderen Spezies versteckt. """ if species == "Werewolf": self.ui.checkBox_armorDedicated.setVisible(True) else: self.ui.checkBox_armorDedicated.setVisible(False) #def addCustomEquipment(self): #""" #Fügt dem Inventar des Charakters einen Gegenstand hinzu. #\todo Nach dem Drücken des Hinzufügen.Knopfes, sollte der Fokus wieder auf das LineEdit gehen. #""" #newItem = self.ui.lineEdit_equipmentCustom.text() #if newItem: #self.__character.addEquipment(newItem) ### Textzeile löschen #self.ui.lineEdit_equipmentCustom.setText("") #def addEquipment(self): #""" #Der Charakter erhält den in \ref listWidget_equipmentStore markierte Ausrüstungsgegenstand. #""" #item = self.ui.listWidget_equipmentStore.takeItem(self.ui.listWidget_equipmentStore.row(self.ui.listWidget_equipmentStore.currentItem())) #if item: #self.__character.addEquipment(item.text()) #def removeEquipment(self): #""" #Entfernt einen Gegenstand aus dem Inventar des Charakters. Wenn er aus der Liste der vorgeschlagenen Ausrüsrtung stammt, wird er dort wieder hinzugefügt. #""" #if self.ui.listWidget_equipmentInventory.currentItem(): #item = self.ui.listWidget_equipmentInventory.takeItem(self.ui.listWidget_equipmentInventory.row(self.ui.listWidget_equipmentInventory.currentItem())) #self.__character.delEquipment(item.text()) #def refillEquipmentInventory(self, itemList): #""" #Schreibt alle Gegenstände aus dem Charakterspeicher in die Liste #""" #self.ui.listWidget_equipmentInventory.clear() #for item in itemList: #listItem = QListWidgetItem() #listItem.setText(item) ##listItem.setIcon(QIcon(Config.ICONS_WEAPONS[category])) ##listItem.setFlags(listItem.flags() | Qt.ItemIsEditable) #self.ui.listWidget_equipmentInventory.addItem(listItem) #def refillEquipmentStore(self, itemList): #""" #Löschte alle Gegenstände, die im Inventar des Charakters sind aus dem Laden. #""" #self.ui.listWidget_equipmentStore.clear() #for item in self.__storage.equipment: #if item not in itemList: #listItem = QListWidgetItem() #listItem.setText(item) #listItem = self.ui.listWidget_equipmentStore.addItem(listItem) #def checkButtonEnabledEquipment(self): #""" #Aktiviert/Deaktiviert die Knöpfe für das Übertragen von Ausrüstung. #""" #if self.ui.listWidget_equipmentStore.count() < 1: #self.ui.pushButton_equipmentAdd.setEnabled(False) #else: #self.ui.pushButton_equipmentAdd.setEnabled(True) def hideShowMagicalTool(self, species): """ Nur bei Magiern wird ein Magische Werkzeug angeboten. """ if species == "Mage": self.ui.widget_magicalTool.setVisible(True) else: self.ui.widget_magicalTool.setVisible(False)
class OptionWidget(EditorWidget): widgettype = 'Option Row' def __init__(self, *args): super(OptionWidget, self).__init__(*args) self._bindvalue = None self.group = QButtonGroup() self.group.setExclusive(True) self.group.buttonClicked.connect(self.emitvaluechanged) def createWidget(self, parent): widget = QWidget(parent) widget.setLayout(QHBoxLayout()) widget.layout().setContentsMargins(0,0,0,0) return widget def _buildfromlist(self, listconfig): items = listconfig['items'] for item in items: parts = item.split(';') data = parts[0] try: desc = parts[1] except IndexError: desc = data try: path = parts[2] if path.endswith("_icon"): icon = QIcon(":/icons/{}".format(path)) else: icon = QIcon(path) except: icon = QIcon() button = QPushButton() button.setCheckable(True) button.setText(desc) button.setProperty("value", data) button.setIcon(icon) button.setIconSize(QSize(24,24)) self.widget.layout().addWidget(button) self.group.addButton(button) def initWidget(self, widget): pass def updatefromconfig(self): super(OptionWidget, self).updatefromconfig() listconfig = self.config['list'] self._buildfromlist(listconfig) super(OptionWidget, self).endupdatefromconfig() def validate(self, *args): button = self.group.checkedButton() if button: self.raisevalidationupdate(True) else: self.raisevalidationupdate(False) self.emitvaluechanged() def setvalue(self, value): for button in self.group.buttons(): if button.property("value") == value: button.setChecked(True) return def value(self): button = self.group.checkedButton() if not button: return None return button.property("value")
class AutoFieldsDockWidget(QDockWidget, Ui_AutoFieldsDockWidget): """ Class in charge of all the UI logic """ def __init__(self, parent, iface, autoFieldManager, messageManager, language='en'): self.iface = iface self.msg = messageManager self.language = language QDockWidget.__init__(self, parent) # Set up the user interface from Designer. self.setupUi(self) self.autoFieldManager = autoFieldManager self.geometryDict = ['points', 'lines', 'polygons'] self.fieldTypesDict = ['Integer', 'Real', 'String', 'Date'] self.root = QgsProject.instance().layerTreeRoot() # UI stuff that wasn't set/initialized in Qt-Designer self.tblLayers.setColumnWidth(0, 24) self.tblLayers.setColumnWidth(1, 140) self.tblLayers.setColumnWidth(2, 110) self.tblLayers.horizontalHeader().setResizeMode(0, QHeaderView.Fixed) self.tblLayers.sortItems(1, Qt.AscendingOrder) self.cboField.setEnabled(False) self.cboFieldType.setItemData(0, QVariant.Int, Qt.UserRole) self.cboFieldType.setItemData(1, QVariant.Double, Qt.UserRole) self.cboFieldType.setItemData(2, QVariant.String, Qt.UserRole) self.cboFieldType.setItemData(3, QVariant.Date, Qt.UserRole) self.fieldTypeChanged(self.cboFieldType.currentIndex() ) # Update length/precision controls self.btnGroup = QButtonGroup() self.btnGroup.addButton(self.optXCoord) self.btnGroup.addButton(self.optYCoord) self.btnGroup.addButton(self.optLength) self.btnGroup.addButton(self.optPerimeter) self.btnGroup.addButton(self.optArea) self.btnGroup.addButton(self.optDate) self.btnGroup.addButton(self.optCustomExpression) #self.btnGroup.addButton( self.optSpatialValue ) self.updateExpressionControls(self.optCustomExpression) self.frameFields.setEnabled(False) self.frameExpression.setEnabled(False) self.populateLayersTable() QgsMapLayerRegistry.instance().legendLayersAdded.connect( self.populateLayersTable) QgsMapLayerRegistry.instance().layersRemoved.connect( self.populateLayersTable) # Also listen to Layer Tree node position changes self.root.addedChildren.connect(self.populateLayersTable) self.root.removedChildren.connect(self.populateLayersTable) self.tblLayers.itemSelectionChanged.connect( self.updateFieldAndExpressionControls) self.optNewField.toggled.connect(self.newFieldToggled) self.cboField.currentIndexChanged.connect(self.fieldChanged) self.cboFieldType.currentIndexChanged.connect(self.fieldTypeChanged) self.btnSaveAutoField.clicked.connect(self.saveAutoField) self.btnNewCustomExpression.clicked.connect(self.setCustomExpression) self.btnGroup.buttonClicked.connect(self.updateExpressionControls) self.expressionDlg = None # 'List of AutoFields' Tab settings = QSettings() check = settings.value(self.autoFieldManager.settingsPrefix + "/showOnlyEnabledAutoFields", True, type=bool) self.chkOnlyEnabledAutoFields.setChecked(check) check = settings.value(self.autoFieldManager.settingsPrefix + "/calculateOnExistingFeatures", True, type=bool) self.chkCalculateOnExisting.setChecked(check) self.btnRemoveAutoFields.setEnabled(False) self.tblAutoFields.sortItems(0, Qt.AscendingOrder) self.populateAutoFieldsTable() self.autoFieldManager.autoFieldCreated.connect( self.populateAutoFieldsTable) self.autoFieldManager.autoFieldRemoved.connect( self.populateAutoFieldsTable) self.autoFieldManager.autoFieldEnabled.connect( self.populateAutoFieldsTable) self.autoFieldManager.autoFieldDisabled.connect( self.populateAutoFieldsTable) self.tblAutoFields.itemSelectionChanged.connect( self.updateRemoveAutoFieldButton) self.chkOnlyEnabledAutoFields.toggled.connect( self.saveShowOnlyEnabledPreference) self.chkCalculateOnExisting.toggled.connect( self.saveCalculateOnExistingPreference) self.btnRemoveAutoFields.clicked.connect(self.removeAutoFieldFromTable) # Context menu self.tblAutoFields.setContextMenuPolicy(Qt.CustomContextMenu) self.tblAutoFields.customContextMenuRequested.connect( self.openAutoFieldContextMenu) # About Tab self.btnHelp.clicked.connect(self.openDocumentation) def populateLayersTable(self, foo=None, foo2=None, foo3=None): """ List vector layers that support changes in attributes and are writable. Arguments are 3 and optional because this function listens to several SIGNALs. """ # Initialize Layers Table self.tblLayers.clearContents() self.tblLayers.setRowCount(0) vLayers = [] for layer in QgsMapLayerRegistry.instance().mapLayers().values(): if layer.type() == QgsMapLayer.VectorLayer: if layer.dataProvider().capabilities( ) & QgsVectorDataProvider.ChangeAttributeValues: if not layer.isReadOnly(): if layer.geometryType( ) < 3: # Avoid UnknownGeometry and NoGeometry vLayers.append(layer) self.tblLayers.setRowCount(len(vLayers)) self.tblLayers.setColumnCount(3) self.tblLayers.setSortingEnabled(False) for row, lyr in enumerate(vLayers): item = QTableWidgetItem( QIcon( ":/plugins/AutoFields/icons/" + \ self.geometryDict[lyr.geometryType()] + ".png"), str( lyr.geometryType() ) ) self.tblLayers.setItem(row, 0, item) item = QTableWidgetItem(lyr.name()) item.setData(Qt.UserRole, lyr.id()) self.tblLayers.setItem(row, 1, item) tmpTreeLayer = self.root.findLayer(lyr.id()) if tmpTreeLayer: group = tmpTreeLayer.parent().name() self.tblLayers.setItem( row, 2, QTableWidgetItem( group if group else QApplication. translate("AutoFieldsDockWidgetPy", "< root >"))) self.tblLayers.setSortingEnabled(True) def updateFieldAndExpressionControls(self): """ After a selection is changed, reflect possible values in field controls """ self.msg.show( "New selection " + str(len(self.tblLayers.selectedItems()) / 3), 'info', True) if not self.tblLayers.selectedItems(): self.frameFields.setEnabled(False) self.frameExpression.setEnabled(False) return else: self.frameFields.setEnabled(True) self.frameExpression.setEnabled(True) # List common fields in cboField and get geometries selected geometryTypeSet = self.updateFieldList() # Update expression controls if 0 in geometryTypeSet and len(geometryTypeSet) == 1: # Points self.optXCoord.setEnabled(True) self.optYCoord.setEnabled(True) self.optLength.setEnabled(False) self.optPerimeter.setEnabled(False) self.optArea.setEnabled(False) elif 1 in geometryTypeSet and len(geometryTypeSet) == 1: # Lines self.optXCoord.setEnabled(False) self.optYCoord.setEnabled(False) self.optLength.setEnabled(True) self.optPerimeter.setEnabled(False) self.optArea.setEnabled(False) elif 2 in geometryTypeSet and len(geometryTypeSet) == 1: # Polygons self.optXCoord.setEnabled(False) self.optYCoord.setEnabled(False) self.optLength.setEnabled(False) self.optPerimeter.setEnabled(True) self.optArea.setEnabled(True) else: self.optXCoord.setEnabled(False) self.optYCoord.setEnabled(False) self.optLength.setEnabled(False) self.optPerimeter.setEnabled(False) self.optArea.setEnabled(False) if not self.btnGroup.checkedButton().isEnabled(): self.optCustomExpression.setChecked(True) # Default selection self.updateExpressionControls(self.optCustomExpression) self.expressionDlg = None # Initialize the dialog def updateFieldList(self): """ Update field list and return geometries selected """ commonFields = [] geometryTypeSet = set() bFirstFlag = True for item in self.tblLayers.selectedItems(): if item.column() == 1: # It's the layer name item self.msg.show("ID " + item.data(Qt.UserRole), 'info', True) # Get layer id layer = QgsMapLayerRegistry.instance().mapLayer( item.data(Qt.UserRole)) geometryTypeSet.add(layer.geometryType()) tmpFields = [ field.name() for field in layer.dataProvider().fields() ] # Get field names stored in the provider if bFirstFlag: # Initialize commonFields commonFields = tmpFields bFirstFlag = False else: # Intersect fields if commonFields: # Avoid intersecting if no common fields commonFields = list(set(commonFields) & set(tmpFields)) commonFields.sort() self.msg.show("FIELDS: " + str(commonFields), 'info', True) self.cboField.clear() if not commonFields: self.optExistingField.setEnabled(False) self.optNewField.setChecked(True) else: self.optExistingField.setEnabled(True) self.cboField.addItems(commonFields) return geometryTypeSet def newFieldToggled(self): """ Alternate between controls of new field and existing field """ newIsChecked = self.optNewField.isChecked() self.cboField.setEnabled(not newIsChecked) self.lblFieldName.setEnabled(newIsChecked) self.lblFieldType.setEnabled(newIsChecked) self.txtFieldName.setEnabled(newIsChecked) self.cboFieldType.setEnabled(newIsChecked) if newIsChecked: self.fieldTypeChanged(self.cboFieldType.currentIndex()) else: self.lblFieldLength.setEnabled(newIsChecked) self.lblFieldPrecision.setEnabled(newIsChecked) self.txtFieldLength.setEnabled(newIsChecked) self.txtFieldPrecision.setEnabled(newIsChecked) self.expressionDlg = None # Initialize the dialog def fieldTypeChanged(self, idx): """ Update field length and field precision controls' state and values """ text = self.fieldTypesDict[idx] if text == 'Integer': self.txtFieldLength.setRange(1, 10) self.txtFieldLength.setEnabled(True) self.txtFieldPrecision.setEnabled(False) self.lblFieldLength.setEnabled(True) self.lblFieldPrecision.setEnabled(False) elif text == 'Real': self.txtFieldLength.setRange(1, 20) self.txtFieldPrecision.setRange(0, 15) self.txtFieldLength.setEnabled(True) self.txtFieldPrecision.setEnabled(True) self.lblFieldLength.setEnabled(True) self.lblFieldPrecision.setEnabled(True) elif text == 'String': self.txtFieldLength.setRange(1, 255) self.txtFieldLength.setEnabled(True) self.txtFieldPrecision.setEnabled(False) self.lblFieldLength.setEnabled(True) self.lblFieldPrecision.setEnabled(False) else: # Date self.txtFieldLength.setEnabled(False) self.txtFieldPrecision.setEnabled(False) self.lblFieldLength.setEnabled(False) self.lblFieldPrecision.setEnabled(False) def fieldChanged(self, idx): """ Just to initialize the expression dialog if selected field changes """ self.expressionDlg = None # Initialize the dialog def saveAutoField(self): """ Do some validation and then call AutoFieldManager """ # Check layers if not self.tblLayers.selectedItems(): self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Warning] Please first select a layer."), 'warning') return # Check expression expression = u'' if self.optXCoord.isChecked(): expression = u'$x' elif self.optYCoord.isChecked(): expression = u'$y' elif self.optLength.isChecked(): expression = u'$length' elif self.optPerimeter.isChecked(): expression = u'$perimeter' elif self.optArea.isChecked(): expression = u'$area' elif self.optDate.isChecked(): expression = u'now()' elif self.optCustomExpression.isChecked(): if self.expressionDlg: expression = self.expressionDlg.expression if not self.expressionDlg or not expression: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Warning] Please first set a valid custom expression." ), 'warning') return else: # optSpatialValue pass # Check fields fieldName = '' if self.optNewField.isChecked(): if self.txtFieldName.text(): fieldName = self.txtFieldName.text().strip() newField = QgsField( fieldName, self.cboFieldType.itemData( self.cboFieldType.currentIndex(), Qt.UserRole)) length = self.txtFieldLength.value() precision = self.txtFieldPrecision.value() # Ensure length and precision are valid values when dealing with Real numbers if self.fieldTypesDict[ self.cboFieldType.currentIndex()] == 'Real': if precision > length: precision = length newField.setLength(length) newField.setPrecision(precision) for item in self.tblLayers.selectedItems(): if item.column() == 1: # It's the layer name item layer = QgsMapLayerRegistry.instance().mapLayer( item.data(Qt.UserRole)) if layer.fieldNameIndex(fieldName) != -1: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Error] The field " ) + fieldName + \ QApplication.translate( "AutoFieldsDockWidgetPy", " already exists in layer " ) + layer.name() + ". " + \ QApplication.translate( "AutoFieldsDockWidgetPy", " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ), 'warning' ) else: res = layer.dataProvider().addAttributes( [newField]) if res: layer.updateFields() # Check if fieldName is preserved by the provider after field creation. if layer.fieldNameIndex(fieldName) == -1: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Error] The field " ) + fieldName + \ QApplication.translate( "AutoFieldsDockWidgetPy", " was probably created with another name by the layer (" ) + \ layer.name() + \ QApplication.translate( "AutoFieldsDockWidgetPy", ") provider. " ) + \ QApplication.translate( "AutoFieldsDockWidgetPy", " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ), 'warning' ) else: self.doSaveAutoField( layer, fieldName, expression) else: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Error] Couldn't create " ) + newField.name() + \ QApplication.translate( "AutoFieldsDockWidgetPy", " field in " ) + layer.name() + \ QApplication.translate( "AutoFieldsDockWidgetPy", " layer." ), 'warning' ) # Some fields might have been created, update the field list once self.updateFieldList() else: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "[Warning] Please first set a name for the new field." ), 'warning') return else: fieldName = self.cboField.currentText() for item in self.tblLayers.selectedItems(): if item.column() == 1: # It's the layer name item layer = QgsMapLayerRegistry.instance().mapLayer( item.data(Qt.UserRole)) self.doSaveAutoField(layer, fieldName, expression) def doSaveAutoField(self, layer, fieldName, expression): """ Repetitive logic to save or overwrite an AutoField """ # Check if the field is an AutoField and ask if we should overwrite it res = True bCalculateOnExisting = self.chkCalculateOnExisting.isChecked() if self.autoFieldManager.isFieldAnAutoField(layer, fieldName): reply = QMessageBox.question( self.iface.mainWindow(), QApplication.translate( "AutoFieldsDockWidgetPy", "Confirmation" ), QApplication.translate( "AutoFieldsDockWidgetPy", "The field '" ) + \ fieldName + QApplication.translate( "AutoFieldsDockWidgetPy", "' from layer '" ) + layer.name() + \ QApplication.translate( "AutoFieldsDockWidgetPy", "' is already an AutoField.\nDo you want to overwrite it?" ), QMessageBox.Yes | QMessageBox.No, QMessageBox.No ) if reply == QMessageBox.Yes: res = self.autoFieldManager.overwriteAutoField( layer, fieldName, expression, calculateOnExisting=bCalculateOnExisting) else: res = self.autoFieldManager.createAutoField( layer, fieldName, expression, calculateOnExisting=bCalculateOnExisting) if not res: # res will only be False if create/overwriteAutoField return False self.msg.show( "[Error] The AutoField for layer '" + layer.name() + \ "' and field '" + fieldName + "' couldn't be created.", 'warning', True ) def setCustomExpression(self): """ Initialize and show the expression builder dialog """ layer = None if len(self.tblLayers.selectedItems() ) / 3 == 1: # Single layer selected? for item in self.tblLayers.selectedItems(): if item.column() == 1: # It's the layer name item layer = QgsMapLayerRegistry.instance().mapLayer( item.data(Qt.UserRole)) if not self.expressionDlg: self.expressionDlg = ExpressionBuilderDialog( self.iface.mainWindow()) context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope()) # Initialize dialog with layer-based names and variables if single layer selected if len(self.tblLayers.selectedItems()) / 3 == 1: context.appendScope( QgsExpressionContextUtils.layerScope(layer)) self.expressionDlg.expressionBuilderWidget.setLayer(layer) self.expressionDlg.expressionBuilderWidget.loadFieldNames() # This block was borrowed from QGIS/python/plugins/processing/algs/qgis/FieldsCalculator.py da = QgsDistanceArea() da.setSourceCrs(layer.crs().srsid()) da.setEllipsoidalMode(self.iface.mapCanvas().mapSettings(). hasCrsTransformEnabled()) da.setEllipsoid(QgsProject.instance().readEntry( 'Measure', '/Ellipsoid', GEO_NONE)[0]) self.expressionDlg.expressionBuilderWidget.setGeomCalculator( da) # If this layer-field is an AutoField, get its expression if self.optExistingField.isChecked(): fieldName = self.cboField.currentText() expression = self.autoFieldManager.getFieldExpression( layer, fieldName) self.expressionDlg.expressionBuilderWidget.setExpressionText( expression) self.expressionDlg.expression = expression # To remember it when closing/opening self.expressionDlg.expressionBuilderWidget.setExpressionContext( context) self.expressionDlg.show() def updateExpressionControls(self, button): """ Enable/disable push buttons when appropriate """ if button.objectName() == 'optCustomExpression': self.btnNewCustomExpression.setEnabled(True) #self.btnNewSpatialValue.setEnabled( False ) #elif button.objectName() == 'optSpatialValue': #self.btnNewCustomExpression.setEnabled( False ) #self.btnNewSpatialValue.setEnabled( True ) else: self.btnNewCustomExpression.setEnabled(False) #self.btnNewSpatialValue.setEnabled( False ) def populateAutoFieldsTable(self, autoFieldId=None): """ Listens to any modification on AutoFields to update the list """ dictAutoFields = self.autoFieldManager.listAutoFields() if autoFieldId: # Just update this one if not autoFieldId in dictAutoFields: # AutoField removed self.msg.show("[Info] Removing AutoField from table.", 'info', True) # Iterate through AF rows and remove row where data matches AFID deleteRow = self.findRowOfItemDataInAutoFieldsTable( autoFieldId, 0) if deleteRow != -1: self.tblAutoFields.removeRow(deleteRow) else: # if it's in the table: remove it and re-add it (from new dict) deleteRow = self.findRowOfItemDataInAutoFieldsTable( autoFieldId, 0) if deleteRow != -1: self.msg.show( "[Info] Refreshing AutoField status in table.", 'info', True) self.tblAutoFields.removeRow(deleteRow) self.addAutoFieldToAutoFieldsTable( autoFieldId, dictAutoFields[autoFieldId]) else: # New AutoField, just add it to table self.msg.show("[Info] Adding new AutoField to table.", 'info', True) self.addAutoFieldToAutoFieldsTable( autoFieldId, dictAutoFields[autoFieldId]) else: # Initialize AutoFields Table self.tblAutoFields.clearContents() self.tblAutoFields.setRowCount(0) #self.tblAutoFields.setRowCount( len( dictAutoFields ) ) self.tblAutoFields.setColumnCount(4) self.tblAutoFields.setSortingEnabled(False) for key in dictAutoFields.keys(): autoField = dictAutoFields[key] self.addAutoFieldToAutoFieldsTable(key, autoField, False) self.tblAutoFields.setSortingEnabled(True) def findRowOfItemDataInAutoFieldsTable(self, data, col): """ Get the row number that matches its data to a given data (check only the given column) """ for numRow in range(self.tblAutoFields.rowCount()): item = self.tblAutoFields.item(numRow, col) if item.data(Qt.UserRole) == data: return numRow return -1 def addAutoFieldToAutoFieldsTable(self, autoFieldId, autoField, freezeSorting=True): """ Add a whole row to the AutoFields table """ if self.chkOnlyEnabledAutoFields.isChecked( ) and not autoField['enabled']: return if freezeSorting: self.tblAutoFields.setSortingEnabled(False) row = self.tblAutoFields.rowCount() self.tblAutoFields.insertRow(row) name = autoField['layer'] if 'layerId' in autoField: lyr = QgsMapLayerRegistry.instance().mapLayer(autoField['layerId']) name = lyr.name() item = QTableWidgetItem(name) item.setData(Qt.UserRole, autoFieldId) item.setData(Qt.ToolTipRole, autoField['layer']) if not autoField['enabled']: item.setForeground(QBrush(Qt.gray)) self.tblAutoFields.setItem(row, 0, item) item = QTableWidgetItem(autoField['field']) if not autoField['enabled']: item.setForeground(QBrush(Qt.gray)) self.tblAutoFields.setItem(row, 1, item) item = QTableWidgetItem(autoField['expression']) if not autoField['enabled']: item.setForeground(QBrush(Qt.gray)) self.tblAutoFields.setItem(row, 2, item) item = QTableWidgetItem( QApplication.translate("AutoFieldsDockWidgetPy", "Enabled" ) if autoField['enabled'] else QApplication. translate("AutoFieldsDockWidgetPy", "Disabled")) item.setData(Qt.UserRole, 'enabled' if autoField['enabled'] else 'disabled') if not autoField['enabled']: item.setForeground(QBrush(Qt.gray)) self.tblAutoFields.setItem(row, 3, item) if freezeSorting: self.tblAutoFields.setSortingEnabled(True) def openAutoFieldContextMenu(self, position): bLayers = False layers = QgsMapLayerRegistry.instance().mapLayers().values() for layer in layers: if layer.type() == QgsMapLayer.VectorLayer: if layer.dataProvider().capabilities( ) & QgsVectorDataProvider.AddFeatures: bLayers = True break item = self.tblAutoFields.itemAt(position) if item: row = item.row() self.menu = QMenu() self.action = QAction("Assign this AutoField to another layer", None) self.action.setObjectName('action') if self.tblAutoFields.item(row, 3).data(Qt.UserRole) == 'enabled': self.action.setEnabled(False) self.menu.addAction(self.action) action = self.menu.exec_(self.tblAutoFields.mapToGlobal(position)) if action and action.objectName() == 'action': if not bLayers: self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy", "First load some vector layers to QGIS to be able to assign disabled AutoFields." ), 'warning') return autoFieldId = self.tblAutoFields.item(row, 0).data(Qt.UserRole) bCalculateOnExisting = self.chkCalculateOnExisting.isChecked() dlg = AssignAutoFieldToLayerDialog(self.iface.mainWindow(), self.autoFieldManager, autoFieldId, bCalculateOnExisting) dlg.show() def updateRemoveAutoFieldButton(self): """ Enable/disable button to remove AutoFields when appropriate """ self.btnRemoveAutoFields.setEnabled( len(self.tblAutoFields.selectedItems()) / 4) def removeAutoFieldFromTable(self): """ Show a confirmation dialog for all AutoFields selected. If confirmed, remove AutoFields from table. """ # Column 0 has the AutoField id autoFieldsToRemove = [ item.data(Qt.UserRole) for item in self.tblAutoFields.selectedItems() if item.column() == 0 ] reply = QMessageBox.question( self.iface.mainWindow(), QApplication.translate( "AutoFieldsDockWidgetPy", "Confirmation" ), QApplication.translate( "AutoFieldsDockWidgetPy", "Do you really want to remove " ) + \ str(len( autoFieldsToRemove )) + \ (" AutoFields?" if len( autoFieldsToRemove ) > 1 else " AutoField?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.No ) if reply == QMessageBox.Yes: for autoFieldId in autoFieldsToRemove: self.autoFieldManager.removeAutoField(autoFieldId) def saveShowOnlyEnabledPreference(self, status): """ Saves the preference in QSettings and updates list of AutoFields """ settings = QSettings() settings.setValue( self.autoFieldManager.settingsPrefix + "/showOnlyEnabledAutoFields", status) self.populateAutoFieldsTable() def saveCalculateOnExistingPreference(self, status): """ Saves the preference in QSettings """ settings = QSettings() settings.setValue( self.autoFieldManager.settingsPrefix + "/calculateOnExistingFeatures", status) def openDocumentation(self): """ Open a browser to show documentation page """ import webbrowser webbrowser.open("http://geotux.tuxfamily.org/index.php/" + self.language + "/geo-blogs/item/333-autofields-plugin-for-qgis") def disconnectAll(self): """ Terminates all SIGNAL/SLOT connections created by this class """ QgsMapLayerRegistry.instance().legendLayersAdded.disconnect( self.populateLayersTable) QgsMapLayerRegistry.instance().layersRemoved.disconnect( self.populateLayersTable) self.root.addedChildren.disconnect(self.populateLayersTable) self.root.removedChildren.disconnect(self.populateLayersTable) self.tblLayers.itemSelectionChanged.disconnect( self.updateFieldAndExpressionControls) self.optNewField.toggled.disconnect(self.newFieldToggled) self.cboField.currentIndexChanged.disconnect(self.fieldChanged) self.cboFieldType.currentIndexChanged.disconnect(self.fieldTypeChanged) self.btnSaveAutoField.clicked.disconnect(self.saveAutoField) self.btnNewCustomExpression.clicked.disconnect( self.setCustomExpression) self.btnGroup.buttonClicked.disconnect(self.updateExpressionControls) self.autoFieldManager.autoFieldCreated.disconnect( self.populateAutoFieldsTable) self.autoFieldManager.autoFieldRemoved.disconnect( self.populateAutoFieldsTable) self.autoFieldManager.autoFieldEnabled.disconnect( self.populateAutoFieldsTable) self.autoFieldManager.autoFieldDisabled.disconnect( self.populateAutoFieldsTable) self.tblAutoFields.itemSelectionChanged.disconnect( self.updateRemoveAutoFieldButton) self.chkOnlyEnabledAutoFields.toggled.disconnect( self.saveShowOnlyEnabledPreference) self.btnRemoveAutoFields.clicked.disconnect( self.removeAutoFieldFromTable)
class EthernetEditor(QFrame): def __init__(self, ethernet, parent=None): QFrame.__init__(self, parent) self.ethernet = ethernet self.buildGUI() self.fillValues() def buildGUI(self): #general setup form = QFormLayout(self) self.label = OptionnalLine(hint="Optional interface name") form.addRow(self.tr("Interface name"), self.label) self.speed_group = QButtonGroup() self.speed_box = QGroupBox(tr("Force an ethernet speed")) speed_layout = QVBoxLayout(self.speed_box) self.speed_GFull = QRadioButton(tr("Gigabit full duplex")) self.speed_GHalf = QRadioButton(tr("Gigabit half duplex")) self.speed_100Full = QRadioButton(tr("100 Mb Full duplex")) self.speed_100Half = QRadioButton(tr("100 Mb Half duplex")) self.speed_10Full = QRadioButton(tr("10 Mb Full duplex")) self.speed_10Half = QRadioButton(tr("10 Mb Half duplex")) def toggle(value): if value: self.speed_GFull.click() self.speed_box.setCheckable(True) self.speed_box.setChecked(Qt.Unchecked) self.connect(self.speed_box, SIGNAL('toggled(bool)'), toggle) for item in ( self.speed_GFull, self.speed_GHalf, self.speed_100Full, self.speed_100Half, self.speed_10Full, self.speed_10Half, ): self.speed_group.addButton(item) speed_layout.addWidget(item) form.addRow(self.speed_box) def fillValues(self): name = self.ethernet.user_label if name != "": self.label.setText(name) self.label.checkEmpty() self.label.setStyleSheet('') if self.ethernet.eth_auto: self.speed_box.setChecked(Qt.Unchecked) return self.speed_box.setChecked(Qt.Checked) if self.ethernet.eth_duplex == Ethernet.FULL: if self.ethernet.eth_speed == 10: button = self.speed_10Full elif self.ethernet.eth_speed == 100: button = self.speed_100Full else: button = self.speed_GFull else: if self.ethernet.eth_speed == 10: button = self.speed_10Half elif self.ethernet.eth_speed == 100: button = self.speed_100Half else: button = self.speed_GHalf button.setChecked(Qt.Checked) def getConfig(self): auto = not self.speed_box.isChecked() if auto: return True, None, None selection = self.speed_group.checkedButton() if selection is self.speed_GFull: return False, 1000, Ethernet.FULL elif self.speed_GHalf: return False, 1000, Ethernet.HALF elif self.speed_100Full: return False, 100, Ethernet.FULL elif self.speed_100Half: return False, 100, Ethernet.HALF elif self.speed_10Full: return False, 10, Ethernet.FULL elif self.speed_10Half: return False, 10, Ethernet.HALF assert False, "this selection is unknown" def setName(self): new_name = self.label.value() if new_name != self.ethernet.user_label: self.ethernet.user_label = new_name #message = tr("renamed ethernet interface to: %s'") % new_name return True def accept(self, *args, **kwargs): ok = True ok &= self.setName() self.ethernet.setEthernetMode(*self.getConfig()) if ok: self.emit(SIGNAL('edited'), "edited ethernet interface '%s'" \ % self.ethernet.fullName()) return ok
class OptionWidget(EditorWidget): widgettype = 'Option Row' def __init__(self, *args): super(OptionWidget, self).__init__(*args) self._bindvalue = None self.group = QButtonGroup() self.group.setExclusive(True) self.group.buttonClicked.connect(self.emitvaluechanged) def createWidget(self, parent): widget = QWidget(parent) widget.setLayout(QHBoxLayout()) widget.layout().setContentsMargins(0, 0, 0, 0) return widget def _buildfromlist(self, listconfig): items = listconfig['items'] for item in items: parts = item.split(';') data = parts[0] try: desc = parts[1] except IndexError: desc = data try: path = parts[2] if path.endswith("_icon"): icon = QIcon(":/icons/{}".format(path)) else: icon = QIcon(path) except: icon = QIcon() button = QPushButton() button.setCheckable(True) button.setText(desc) button.setProperty("value", data) button.setIcon(icon) button.setIconSize(QSize(24, 24)) self.widget.layout().addWidget(button) self.group.addButton(button) def initWidget(self, widget): pass def updatefromconfig(self): super(OptionWidget, self).updatefromconfig() listconfig = self.config['list'] self._buildfromlist(listconfig) super(OptionWidget, self).endupdatefromconfig() def validate(self, *args): button = self.group.checkedButton() if button: return True return False def setvalue(self, value): for button in self.group.buttons(): if button.property("value") == str(value): button.setChecked(True) return def value(self): button = self.group.checkedButton() if not button: return None return button.property("value")
class CategoriesTab(QWidget): """ Widget for displaying the categories tab in the SettingsDialog. This is embedded into the SettingsDialog. The user can add or remove a category using several options. For some reason, PyQt does not recognize QButtonGroup objects, hence they need to be defined explicitely. Also, a reference to FinanceagerWindow is stored as private attribute self.__parent because later referencing does not work otherwise. """ def __init__(self, parent=None): super(CategoriesTab, self).__init__(parent) loadUi(__file__, self) self.__parent = parent self.removeFromMonthButtons = QButtonGroup() self.removeFromMonthButtons.addButton(self.removeAllMonthsButton) self.removeFromMonthButtons.addButton( self.removeAllMonthsFromNowButton) self.removeFromMonthButtons.addButton(self.removeCurrentMonthButton) self.addToMonthButtons = QButtonGroup() self.addToMonthButtons.addButton(self.addAllMonthsButton) self.addToMonthButtons.addButton(self.addAllMonthsFromNowButton) self.addToMonthButtons.addButton(self.addCurrentMonthButton) self.expAndRecButtons = QButtonGroup() self.expAndRecButtons.addButton(self.expendituresButton) self.expAndRecButtons.addButton(self.receiptsButton) self.removeCategoryCombo.addItems(self.categoriesStringList()) # CONNECTIONS self.addCategoryGroup.clicked.connect( self.newCategoryLineEdit.setFocus) def categoriesStringList(self): """ Returns a sorted list of all the categories that occur in the parentwidget's (== FinanceagerWindow's) tabs. Used for both populating the removeCategoryCombo and preventing the user from adding an already existing category. The latter is important in order to avoid ambiguities when removing a category. :return list(str) """ categories = set() tabWidget = self.__parent.monthsTabWidget for m in range(12): monthTab = tabWidget.widget(m) categories = categories.union(monthTab.categoriesStringList()) categories = list(categories) categories.sort() return categories def checkForUniqueCategory(self, name): """ Called from updateChangesToApply() to verify that the given category name is unique. Pops up a warning and resets newCategoryLineEdit if not. :param name | str :return uniqueCategory | bool """ #FIXME this also prevents adding a category that exists in any other month! if name in self.categoriesStringList(): QMessageBox.warning( self.__parent, 'Name conflict', 'This category name already exists. Please enter a unique name.' ) self.newCategoryLineEdit.setText('') self.newCategoryLineEdit.setFocus() return False else: return True def updateChangesToApply(self, changes): """ Checks for checked GroupBoxes. Creates a tuple consisting of a function string and a tuple that contains name, typ and option. Those three are fetched from the tab's widgets. function: 'addCategory' | 'removeCategory' name: new category name | category to delete option: 0 (all months) | 1 (all months from now) | 2 (current month) typ: 0 (expenditure) | 1 (receipt) The tuple is eventually evaluated by SettingsDialog.applyChanges() if the dialog is not cancelled. :param changes | set """ if self.addCategoryGroup.isChecked(): name = unicode(self.newCategoryLineEdit.text()).strip() if len(name): if self.checkForUniqueCategory(name): typ = self.expAndRecButtons.buttons().index( self.expAndRecButtons.checkedButton()) option = self.addToMonthButtons.buttons().index( self.addToMonthButtons.checkedButton()) changes.add(('addCategory', (name, typ, option))) if self.removeCategoryGroup.isChecked(): name = unicode(self.removeCategoryCombo.currentText()) option = self.removeFromMonthButtons.buttons().index( self.removeFromMonthButtons.checkedButton()) changes.add(('removeCategory', (name, option)))