def extra_keywords_to_widgets(extra_keyword_definition): """Create widgets for extra keyword. :param extra_keyword_definition: An extra keyword definition. :type extra_keyword_definition: dict :return: QCheckBox and The input widget :rtype: (QCheckBox, QWidget) """ # Check box check_box = QCheckBox(extra_keyword_definition['name']) check_box.setToolTip(extra_keyword_definition['description']) check_box.setChecked(True) # Input widget if extra_keyword_definition['type'] == float: input_widget = QDoubleSpinBox() input_widget.setMinimum(extra_keyword_definition['minimum']) input_widget.setMaximum(extra_keyword_definition['maximum']) input_widget.setSuffix(extra_keyword_definition['unit_string']) elif extra_keyword_definition['type'] == int: input_widget = QSpinBox() input_widget.setMinimum(extra_keyword_definition['minimum']) input_widget.setMaximum(extra_keyword_definition['maximum']) input_widget.setSuffix(extra_keyword_definition['unit_string']) elif extra_keyword_definition['type'] == str: if extra_keyword_definition.get('options'): input_widget = QComboBox() options = extra_keyword_definition['options'] for option in options: input_widget.addItem( option['name'], option['key'], ) default_option_index = input_widget.findData( extra_keyword_definition['default_option']) input_widget.setCurrentIndex(default_option_index) else: input_widget = QLineEdit() elif extra_keyword_definition['type'] == datetime: input_widget = QDateTimeEdit() input_widget.setCalendarPopup(True) input_widget.setDisplayFormat('hh:mm:ss, d MMM yyyy') input_widget.setDateTime(datetime.now()) else: raise Exception input_widget.setToolTip(extra_keyword_definition['description']) # Signal # noinspection PyUnresolvedReferences check_box.stateChanged.connect(input_widget.setEnabled) return check_box, input_widget
def _set_up_tools(self): if self._tools_set_up: return for a, b in self._order_bundles.tools(): # Strip ' Scene' to reduce horizontal width of 2-column layout cb = QCheckBox(b, parent=self.grpBoxTools) cb.setChecked(False) cb.setProperty('tool', a) cb.setToolTip(b) self.grpBoxTools.layout().addWidget(cb) self._tools_set_up = True
def __init__(self, parent=None, plugin=None): super().__init__(parent=parent) self.setupUi(self) self._plugin = plugin # Set up sources (in 2 columns; layout is grid) checked = ['PSScene4Band'] row_total = floor(len(DAILY_ITEM_TYPES) / 2) row = col = 0 gl = QGridLayout(self.frameSources) gl.setContentsMargins(0, 0, 0, 0) for a, b in DAILY_ITEM_TYPES: # Strip ' Scene' to reduce horizontal width of 2-column layout cb = QCheckBox(b.replace(' Scene', ''), parent=self.frameSources) cb.setChecked(a in checked) cb.setProperty('api-name', a) cb.setToolTip(b) # noinspection PyUnresolvedReferences cb.stateChanged[int].connect(self.filtersChanged) gl.addWidget(cb, row, col) row += 1 if row > row_total: row = 0 col += 1 self.frameSources.setLayout(gl) # TODO: (Eventually) Add multi-date range widget with and/or selector # noinspection PyUnresolvedReferences self.startDateEdit.valueChanged['QDateTime'].connect( self.filtersChanged) # noinspection PyUnresolvedReferences self.startDateEdit.valueChanged['QDateTime'].connect( self.set_min_enddate) # noinspection PyUnresolvedReferences self.startDateEdit.valueChanged['QDateTime'].connect( self.change_date_vis) # noinspection PyUnresolvedReferences self.endDateEdit.valueChanged['QDateTime'].connect(self.filtersChanged) # noinspection PyUnresolvedReferences self.endDateEdit.valueChanged['QDateTime'].connect( self.set_max_startdate) # noinspection PyUnresolvedReferences self.endDateEdit.valueChanged['QDateTime'].connect( self.change_date_vis) # Setup datetime boxes current_day = QDateTime().currentDateTimeUtc() self.startDateEdit.setDateTime(current_day.addMonths(-3)) self.endDateEdit.setDateTime(current_day) self.cmbBoxDateType.clear() for i, (a, b) in enumerate(self.SORT_ORDER_DATE_TYPES): self.cmbBoxDateType.insertItem(i, b, userData=a) # Set a default (acquired) self.cmbBoxDateType.setCurrentIndex(0) # noinspection PyUnresolvedReferences self.cmbBoxDateType.currentIndexChanged[int].connect( self.filters_changed) self.cmbBoxDateSort.clear() for i, (a, b) in enumerate(self.SORT_ORDER_TYPES): self.cmbBoxDateSort.insertItem(i, b, userData=a) # Set a default self.cmbBoxDateSort.setCurrentIndex(0) # noinspection PyUnresolvedReferences self.cmbBoxDateSort.currentIndexChanged[int].connect( self.filters_changed) # TODO: (Eventually) Add multi-field searching, with +/- operation # of adding new field/QLineEdit, without duplicates # noinspection PyUnresolvedReferences self.leStringIDs.textChanged['QString'].connect(self.filters_changed) # TODO: Figure out how area coverage filter works in Explorer # TODO: Consolidate range filters for basemap/mosaic reusability self.rangeCloudCover = PlanetExplorerRangeSlider( title='Cloud cover', filter_key='cloud_cover', prefix='', suffix='%', minimum=0, maximum=100, low=0, high=100, step=1, precision=1) # Layout's parent widget takes ownership self.frameRangeSliders.layout().addWidget(self.rangeCloudCover) self.rangeCloudCover.rangeChanged[float, float].connect(self.filters_changed) self.rangeAzimuth = PlanetExplorerRangeSlider(title='Sun Azimuth', filter_key='sun_azimuth', prefix='', suffix='°', minimum=0, maximum=360, low=0, high=360, step=1, precision=1) # Layout's parent widget takes ownership self.frameRangeSliders.layout().addWidget(self.rangeAzimuth) self.rangeAzimuth.rangeChanged[float, float].connect(self.filters_changed) self.rangeElevation = PlanetExplorerRangeSlider( title='Sun Elevation', filter_key='sun_elevation', prefix='', suffix='°', minimum=0, maximum=90, low=0, high=90, step=1, precision=1) # Layout's parent widget takes ownership self.frameRangeSliders.layout().addWidget(self.rangeElevation) self.rangeElevation.rangeChanged[float, float].connect(self.filters_changed) self.rangeViewAngle = PlanetExplorerRangeSlider( title='View Angle', filter_key='view_angle', prefix='', suffix='°', minimum=-25, maximum=25, low=0, high=25, step=1, precision=1) # Layout's parent widget takes ownership self.frameRangeSliders.layout().addWidget(self.rangeViewAngle) self.rangeViewAngle.rangeChanged[float, float].connect(self.filters_changed) self.rangeGsd = PlanetExplorerRangeSlider( title='Ground Sample Distance', filter_key='gsd', prefix='', suffix='m', minimum=0, maximum=50, low=0, high=50, step=1, precision=1) # Layout's parent widget takes ownership self.frameRangeSliders.layout().addWidget(self.rangeGsd) self.rangeGsd.rangeChanged[float, float].connect(self.filters_changed) self.rangeAnomalousPx = PlanetExplorerRangeSlider( title='Anomalous Pixels', filter_key='anomalous_pixels', prefix='', suffix='%', minimum=0, maximum=100, low=0, high=100, step=1, precision=1) # Layout's parent widget takes ownership self.frameRangeSliders.layout().addWidget(self.rangeAnomalousPx) self.rangeAnomalousPx.rangeChanged[float, float].connect(self.filters_changed) self.rangeUsable = PlanetExplorerRangeSlider(title='Usable Pixels', filter_key='usable_data', prefix='', suffix='%', minimum=0, maximum=100, low=0, high=100, step=1, precision=1) # Layout's parent widget takes ownership self.frameRangeSliders.layout().addWidget(self.rangeUsable) self.rangeUsable.rangeChanged[float, float].connect(self.filters_changed) # TODO: Add rest of range sliders # Ground control filter checkbox # noinspection PyUnresolvedReferences self.chkBxGroundControl.stateChanged[int].connect(self.filters_changed) # Access Filter checkbox # noinspection PyUnresolvedReferences self.chkBxCanDownload.stateChanged[int].connect(self.filters_changed)
def __select_wfs_layer(self) -> None: indexes = self.tbl_wdgt_stored_queries.selectedIndexes() if not indexes: LOGGER.warning( tr("Could not execute select"), extra=bar_msg(tr("Data source must be selected first!")), ) return self.selected_stored_query = self.stored_queries[indexes[0].row()] LOGGER.info( tr("Selected query id: {}", self.selected_stored_query.id)) # type: ignore # noqa E501 self.sq_factory.expand(self.selected_stored_query) # type: ignore for widget_set in self.parameter_rows.values(): for widget in widget_set: if isinstance(widget, QVBoxLayout): self.grid.removeItem(widget) else: self.grid.removeWidget(widget) widget.hide() widget.setParent(None) widget = None self.parameter_rows = {} row_idx = -1 self.extent_group_box_bbox.setEnabled(False) for param_name, parameter in self.selected_stored_query.parameters.items( ): # type: ignore # noqa E501 possible_values = parameter.possible_values widgets = set() # type: ignore if parameter.type in (QVariant.Rect, QVariant.RectF): self.parameter_rows[param_name] = widgets self.extent_group_box_bbox.setEnabled(True) if possible_values: dataset_extent = QgsRectangle( *(map(float, possible_values[0].split(",")))) current_extent: QgsRectangle = ( self.extent_group_box_bbox.outputExtent()) extent_msg = tr( "Your extent: {}, dataset maximum extent: {}", current_extent.toString(2), dataset_extent.toString(2), ) if dataset_extent.area() / current_extent.area() > 100: LOGGER.warning( tr("Big difference in bounding boxes"), extra=bar_msg( tr( "You might want to get a larger extent. {}", extent_msg, )), ) elif current_extent.area() / dataset_extent.area() > 100: LOGGER.warning( tr("Big difference in bounding boxes"), extra=bar_msg( tr( "You might want to get a smaller extent. {}", extent_msg, )), ) if not current_extent.toRectF().intersects( dataset_extent.toRectF()): LOGGER.warning( tr("Your bounding box and dataset bounding " "box do not intersect"), extra=bar_msg( tr( "You might want to change your extent. {}", extent_msg, )), ) continue row_idx += 1 widget: QWidget = widget_for_field(parameter.type) # type: ignore if (isinstance(widget, QComboBox) or isinstance(widget, QSpinBox) or isinstance(widget, QgsDoubleSpinBox)): widget = QLineEdit() if possible_values: if len(possible_values) == 1: widget.setText(possible_values[0]) else: widget = QComboBox() widget.addItems(possible_values) widget.setEditable(True) if isinstance(widget, QgsDateTimeEdit) and possible_values: widget.setDateTimeRange(min(possible_values), max(possible_values)) if param_name.startswith("end"): widget.setDateTime(max(possible_values)) else: widget.setDateTime(min(possible_values)) if len(possible_values) == 1: widget.setEnabled(False) widget.setToolTip(parameter.abstract) if parameter.type == QVariant.StringList: if parameter.has_variables(): widget = QVBoxLayout() widget.addStretch(1) for variable in parameter.variables: box = QCheckBox(text=variable.alias) box.setToolTip(variable.label) widgets.add(box) widget.addWidget(box) LOGGER.info(tr("Variables: {}", variable.alias)) # TODO: all others if widget is None: LOGGER.error( tr("Unknown parameter type"), extra=bar_msg( tr('With parameter"{}": {}', param_name, parameter.type)), ) return label = QLabel(text=parameter.name) label.setToolTip(parameter.abstract) widgets.update({label, widget}) self.grid.addWidget(label, row_idx, 1) if isinstance(widget, QVBoxLayout): self.grid.addLayout(widget, row_idx, 2) else: self.grid.addWidget(widget, row_idx, 2) self.parameter_rows[param_name] = widgets
def __update_available_error_data(self): self.tbw_errors.setUpdatesEnabled( False) # Don't render until we're ready # Save selection before clearing table to restate it later (if needed) self.__update_selected_item() self.tbw_errors.blockSignals( True) # We don't want to get itemSelectionChanged here self.tbw_errors.clear() self.tbw_errors.blockSignals(False) self.tbw_errors.setHorizontalHeaderLabels(self.__column_labels) # Filter by search text list_errors = self.__filter_by_search_text(self.txt_search.text()) self.tbw_errors.setRowCount(len(list_errors)) row = 0 for feature in list_errors: # 1) Fixed error checkbox widget = QWidget() checkbox = QCheckBox() checkbox.setCheckState(Qt.Checked if self.__controller. is_fixed_error(feature) else Qt.Unchecked) checkbox.setStyleSheet('background: white;') checkbox.setEnabled(not self.__controller.is_exception(feature) ) # Exceptions cannot be fixed checkbox.setToolTip( QCoreApplication.translate( "QualityRulesErrorResultsPanelWidget", "Is the error fixed?")) layout = QHBoxLayout(widget) layout.addWidget(checkbox) layout.setAlignment(Qt.AlignCenter) layout.setContentsMargins(0, 0, 0, 0) checkbox.stateChanged.connect( partial(self.__error_state_changed, row)) self.tbw_errors.setCellWidget(row, CHECK_COLUMN, widget) # 2) Object UUIDs uuids = self.__controller.uuid_objs(feature) uuid_item = QTableWidgetItem(uuids) uuid_item.setData(Qt.UserRole, self.__controller.error_t_id(feature)) ili_name = self.__controller.ili_obj_name(feature) uuid_item.setData( Qt.ToolTipRole, "UUIDs ({}):\n{}".format(ili_name, uuids) if ili_name else "UUIDs:\n{}".format(uuids)) self.tbw_errors.setItem(row, UUIDS_COLUMN, uuid_item) # 3) Error type code error_type_code, error_type_display = self.__controller.error_type_code_and_display( feature) error_type_item = QTableWidgetItem(error_type_code) error_type_item.setData( Qt.ToolTipRole, "{}\n({})".format(error_type_display, error_type_code)) self.tbw_errors.setItem(row, QRE_COLUMN, error_type_item) # 4) Details + Values details = self.__controller.error_details_and_values(feature) error_details_item = QTableWidgetItem(details) error_details_item.setData(Qt.ToolTipRole, details) self.tbw_errors.setItem(row, DETAILS_COLUMN, error_details_item) self.__set_row_color_by_state( row, self.__controller.error_state(feature)) row += 1 # Set selection self.tbw_errors.blockSignals( True) # We don't want to get itemSelectionChanged here item = self.__get_item_by_t_id(self.__selected_item) if item: item.setSelected(True) self.tbw_errors.blockSignals(False) self.tbw_errors.setUpdatesEnabled(True) # Now render!