def __init__(self, parent=None): super(_CameraWidget, self).__init__(parent) self.setLayout(QGridLayout()) self.toolbar = QToolBar() spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.toolbar.setIconSize(QSize(48, 48)) self.toolbar.addWidget(spacer) self.swapaction = self.toolbar.addAction(QIcon(":/widgets/cameraswap"), "Swap Camera") self.swapaction.triggered.connect(self.swapcamera) self.current_camera_index = 0 self.camera = None self.viewfinder = QCameraViewfinder() self.viewfinder.mousePressEvent = self.capture self.viewfinder.setAspectRatioMode(Qt.KeepAspectRatioByExpanding) self.update_camera_buttons() self.capturebutton = QPushButton("Capture", self) self.capturebutton.pressed.connect(self.capture) self.actionCancel = self.toolbar.addAction(QIcon(":/icons/cancel"), "Cancel") self.actionCancel.triggered.connect(self._cancel) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self.toolbar) self.layout().addWidget(self.viewfinder) self.layout().addWidget(self.capturebutton) self.viewfinder.show()
def __init__(self, parent): super(HtmlViewerWidget, self).__init__(parent) self.setLayout(QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.view = QWebView() self.view.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) self.frame = QFrame() self.frame.setLayout(QGridLayout()) self.frame.layout().setContentsMargins(0, 0, 0, 0) self.toolbar = QToolBar() self.spacer = QWidget() self.spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.copyAction = self.toolbar.addAction(QIcon(":/icons/clipboard"), "Copy Text") self.label = QLabel() self.closeAction = QPushButton(QIcon(":/icons/cancel"), "Close", self) self.spaceraction = self.toolbar.insertWidget(None, self.spacer) self.labelaction = self.toolbar.insertWidget(self.spaceraction, self.label) self.closeAction.pressed.connect(self.close) self.copyAction.triggered.connect(self.copy_text) self.layout().addWidget(self.frame) self.frame.layout().addWidget(self.toolbar) self.frame.layout().addWidget(self.view) self.frame.layout().addWidget(self.closeAction) self.effect = QGraphicsOpacityEffect() self.label.setGraphicsEffect(self.effect) self.anim = QPropertyAnimation(self.effect, "opacity".encode("utf-8")) self.anim.setDuration(2000) self.anim.setStartValue(1.0) self.anim.setEndValue(0.0) self.anim.setEasingCurve(QEasingCurve.OutQuad)
def initGui(self): """Creates application GUI widgets""" self.initProcessing() self.dock = VertexDockWidget(self.iface.mapCanvas()) self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock) self.dock.setUserVisible(False) self.toolbar = QToolBar(self.tr('Vertex Compare Toolbar')) self.toolbar.setObjectName('vertexCompareToolbar') self.iface.addToolBar(self.toolbar) self.layer_combo = QgsMapLayerComboBox() self.layer_combo.setAllowEmptyLayer(True, self.tr('Disabled')) self.layer_combo.setFilters(QgsMapLayerProxyModel.PolygonLayer | QgsMapLayerProxyModel.LineLayer) self.layer_combo.setMinimumWidth( QFontMetrics(self.layer_combo.font()).width('x') * 40) self.layer_combo.setCurrentIndex(0) self.layer_combo.layerChanged.connect(self._set_layer) self.toolbar.addWidget(self.layer_combo) self.show_vertices_action = QAction(self.tr("Show Vertex Numbers"), self) self.show_vertices_action.setIcon( GuiUtils.get_icon('show_vertex_numbers.svg')) self.show_vertices_action.setCheckable(True) self.show_vertices_action.setEnabled(False) self.actions.append(self.show_vertices_action) self.toolbar.addAction(self.show_vertices_action) self.show_vertices_action.toggled.connect( self.vertex_highlighter.set_visible) self.show_topology_action = QAction(self.tr("Compare Vertices"), self) self.show_topology_action.setIcon(GuiUtils.get_icon('topology.svg')) self.show_topology_action.setCheckable(True) self.actions.append(self.show_topology_action) self.toolbar.addAction(self.show_topology_action) self.show_topology_action.toggled.connect( self.vertex_highlighter.set_topological) self.show_dock_action = QAction(self.tr('Show Vertices'), parent=self.toolbar) self.show_dock_action.setIcon(GuiUtils.get_icon('vertex_table.svg')) self.toolbar.addAction(self.show_dock_action) self.actions.append(self.show_dock_action) self.dock.setToggleVisibilityAction(self.show_dock_action) self.selection_handler.selection_changed.connect( self._selection_changed) self.dock.label_filter_changed.connect(self.vertex_highlighter.redraw) self.dock.vertex_symbol_changed.connect(self.vertex_highlighter.redraw) self.dock.vertex_text_format_changed.connect( self.vertex_highlighter.redraw) self.dock.selected_vertex_changed.connect( self.vertex_highlighter.set_selected_vertex)
def __init__(self, name, parent): """ parent: The parent of this toolbar. Should be another toolbar """ QToolBar.__init__(self, name, parent) self.setMovable(False) self.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint | Qt.X11BypassWindowManagerHint) self.setAllowedAreas(Qt.NoToolBarArea) self.actiongroup = QActionGroup(self)
class NetworkActivityDock(QgsDockWidget): """ The Dock holding the actual treeview. Also having some buttons to clear/pause and filter the requests. """ def __init__(self, logger): super().__init__() self.setWindowTitle('Network Activity') self.view = ActivityView(logger) font = QFont() font.setFamily('Courier') font.setPointSize(font.pointSize() - 1) self.view.setFont(font) self.logger = logger self.l = QVBoxLayout() self.l.setContentsMargins(0, 0, 0, 0) self.clear_action = QAction('Clear') self.pause_action = QAction('Pause') self.pause_action.setCheckable(True) self.toolbar = QToolBar() self.toolbar.setIconSize(iface.iconSize(True)) self.toolbar.addAction(self.clear_action) self.toolbar.addAction(self.pause_action) self.clear_action.triggered.connect(self.view.clear) self.pause_action.toggled.connect(self.view.pause) self.show_success_action = QAction('Show successful requests') self.show_success_action.setCheckable(True) self.show_success_action.setChecked(True) self.show_success_action.toggled.connect(self.view.show_successful) self.show_timeouts_action = QAction('Show timeouts') self.show_timeouts_action.setCheckable(True) self.show_timeouts_action.setChecked(True) self.show_timeouts_action.toggled.connect(self.view.show_timeouts) self.toolbar.addSeparator() self.toolbar.addAction(self.show_success_action) self.toolbar.addAction(self.show_timeouts_action) self.filter_line_edit = QgsFilterLineEdit() self.filter_line_edit.setShowSearchIcon(True) self.filter_line_edit.setPlaceholderText('Filter requests') self.filter_line_edit.textChanged.connect(self.view.set_filter_string) self.l.addWidget(self.toolbar) self.l.addWidget(self.filter_line_edit) self.l.addWidget(self.view) self.w = QWidget() self.w.setLayout(self.l) self.setWidget(self.w)
class RedistrictingDockWidget(QgsDockWidget): """ Dock widget for display of redistricting statistics and operations """ def __init__(self, _iface: QgisInterface = None): super().__init__() if _iface is not None: self.iface = _iface else: self.iface = iface dock_contents = QWidget() grid = QGridLayout(dock_contents) grid.setContentsMargins(0, 0, 0, 0) self._dock_toolbar = QToolBar(dock_contents) self._dock_toolbar.setFloatable(False) grid.addWidget(self._dock_toolbar, 0, 0, 1, 1) self._dock_toolbar.setIconSize(self.iface.iconSize(True)) self.frame = QTextBrowser() self.frame.setOpenLinks(False) self.frame.anchorClicked.connect(self.anchor_clicked) grid.addWidget(self.frame, 1, 0, 1, 1) self.setWidget(dock_contents) def dock_toolbar(self): """ Returns the dock toolbar """ return self._dock_toolbar def show_message(self, html): """ Shows a HTML formatted message in the dock, replacing its current contents :param html: HTML to show """ self.frame.setHtml(html) self.setUserVisible(True) def anchor_clicked(self, link: QUrl): """ Called on clicking an anchor link in the dock frame :param link: link clicked """ pass # pylint: disable=unnecessary-pass
def initGui(self): """Creates application GUI widgets""" self.initProcessing() self.toolbar = QToolBar(self.tr('Cartography Tools')) self.toolbar.setObjectName('cartographyTools') self.iface.addToolBar(self.toolbar) self.create_tools() self.iface.currentLayerChanged.connect(self.current_layer_changed) self.iface.actionToggleEditing().toggled.connect(self.editing_toggled) self.layout_hooks.init_gui(self.iface)
class HtmlViewerWidget(QWidget): def __init__(self, parent): super(HtmlViewerWidget, self).__init__(parent) self.setLayout(QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.view = QWebView() self.view.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) self.frame = QFrame() self.frame.setLayout(QGridLayout()) self.frame.layout().setContentsMargins(0, 0, 0, 0) self.toolbar = QToolBar() self.spacer = QWidget() self.spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.copyAction = self.toolbar.addAction(QIcon(":/icons/clipboard"), "Copy Text") self.label = QLabel() self.closeAction = QPushButton(QIcon(":/icons/cancel"), "Close", self) self.spaceraction = self.toolbar.insertWidget(None, self.spacer) self.labelaction = self.toolbar.insertWidget(self.spaceraction, self.label) self.closeAction.pressed.connect(self.close) self.copyAction.triggered.connect(self.copy_text) self.layout().addWidget(self.frame) self.frame.layout().addWidget(self.toolbar) self.frame.layout().addWidget(self.view) self.frame.layout().addWidget(self.closeAction) self.effect = QGraphicsOpacityEffect() self.label.setGraphicsEffect(self.effect) self.anim = QPropertyAnimation(self.effect, "opacity".encode("utf-8")) self.anim.setDuration(2000) self.anim.setStartValue(1.0) self.anim.setEndValue(0.0) self.anim.setEasingCurve(QEasingCurve.OutQuad) def copy_text(self): self.label.setText("Copied to clipboard") text = self.view.page().mainFrame().toPlainText() QApplication.clipboard().setText(text) self.anim.stop() self.anim.start() def showHTML(self, template, level, **data): html = templates.render_tample(template, **data) self.view.setHtml(html, templates.baseurl)
def __init__(self, _iface: QgisInterface = None): super().__init__() if _iface is not None: self.iface = _iface else: self.iface = iface dock_contents = QWidget() grid = QGridLayout(dock_contents) grid.setContentsMargins(0, 0, 0, 0) self._dock_toolbar = QToolBar(dock_contents) self._dock_toolbar.setFloatable(False) grid.addWidget(self._dock_toolbar, 0, 0, 1, 1) self._dock_toolbar.setIconSize(self.iface.iconSize(True)) self.frame = QTextBrowser() self.frame.setOpenLinks(False) self.frame.anchorClicked.connect(self.anchor_clicked) grid.addWidget(self.frame, 1, 0, 1, 1) self.setWidget(dock_contents)
class CartographyToolsPlugin: """QGIS Plugin Implementation.""" def __init__(self, iface: QgisInterface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ super().__init__() # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QgsApplication.locale() locale_path = os.path.join(self.plugin_dir, 'i18n', '{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # processing framework self.provider = CartographyToolsProvider() self.toolbar = None self.actions = [] self.tools = {} self.active_tool = None self.layout_hooks = LayoutDesignerHooks() @staticmethod def tr(message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('CartographyTools', message) def initProcessing(self): """Create the Processing provider""" QgsApplication.processingRegistry().addProvider(self.provider) def initGui(self): """Creates application GUI widgets""" self.initProcessing() self.toolbar = QToolBar(self.tr('Cartography Tools')) self.toolbar.setObjectName('cartographyTools') self.iface.addToolBar(self.toolbar) self.create_tools() self.iface.currentLayerChanged.connect(self.current_layer_changed) self.iface.actionToggleEditing().toggled.connect(self.editing_toggled) self.layout_hooks.init_gui(self.iface) def get_map_tool_action_group(self): try: return self.iface.mapToolActionGroup() except AttributeError: return \ [o for o in self.iface.mainWindow().findChildren(QActionGroup) if self.iface.actionPan() in o.actions()][0] def create_tools(self): """ Creates all map tools ands add them to the QGIS interface """ action_single_point_templated_marker = QAction( GuiUtils.get_icon('single_point_templated_marker.svg'), self.tr('Single Point Templated Marker')) action_single_point_templated_marker.setCheckable(True) self.tools[SinglePointTemplatedMarkerTool. ID] = SinglePointTemplatedMarkerTool( self.iface.mapCanvas(), self.iface.cadDockWidget(), self.iface, action_single_point_templated_marker) self.tools[SinglePointTemplatedMarkerTool.ID].setAction( action_single_point_templated_marker) action_single_point_templated_marker.triggered.connect( partial(self.switch_tool, SinglePointTemplatedMarkerTool.ID)) action_single_point_templated_marker.setData( SinglePointTemplatedMarkerTool.ID) self.toolbar.addAction(action_single_point_templated_marker) self.actions.append(action_single_point_templated_marker) self.get_map_tool_action_group().addAction( action_single_point_templated_marker) # single point at center of line tool action_single_point_at_center_of_line = QAction( GuiUtils.get_icon('marker_at_center_of_line.svg'), self.tr('Single Point Templated Marker Via Two Points')) action_single_point_at_center_of_line.setCheckable(True) self.tools[ TwoPointTemplatedMarkerTool.ID] = TwoPointTemplatedMarkerTool( self.iface.mapCanvas(), self.iface.cadDockWidget(), self.iface, action_single_point_at_center_of_line) self.tools[TwoPointTemplatedMarkerTool.ID].setAction( action_single_point_at_center_of_line) action_single_point_at_center_of_line.triggered.connect( partial(self.switch_tool, TwoPointTemplatedMarkerTool.ID)) action_single_point_at_center_of_line.setData( TwoPointTemplatedMarkerTool.ID) self.toolbar.addAction(action_single_point_at_center_of_line) self.actions.append(action_single_point_at_center_of_line) self.get_map_tool_action_group().addAction( action_single_point_at_center_of_line) # multi point tool action_multi_point_templated_marker = QAction( GuiUtils.get_icon('multi_point_templated_marker.svg'), self.tr('Multiple Point Templated Marker Along LineString')) action_multi_point_templated_marker.setCheckable(True) self.tools[ MultiPointTemplatedMarkerTool.ID] = MultiPointTemplatedMarkerTool( self.iface.mapCanvas(), self.iface.cadDockWidget(), self.iface, action_multi_point_templated_marker) self.tools[MultiPointTemplatedMarkerTool.ID].setAction( action_multi_point_templated_marker) action_multi_point_templated_marker.triggered.connect( partial(self.switch_tool, MultiPointTemplatedMarkerTool.ID)) action_multi_point_templated_marker.setData( MultiPointTemplatedMarkerTool.ID) self.toolbar.addAction(action_multi_point_templated_marker) self.actions.append(action_multi_point_templated_marker) self.get_map_tool_action_group().addAction( action_single_point_templated_marker) # multi at center of segment point tool action_multi_point_center_segment_templated_marker = QAction( GuiUtils.get_icon('multi_point_templated_marker_at_center.svg'), self.tr('Multiple Point Templated Marker At Center Of Segments')) action_multi_point_center_segment_templated_marker.setCheckable(True) self.tools[MultiPointSegmentCenterTemplatedMarkerTool. ID] = MultiPointSegmentCenterTemplatedMarkerTool( self.iface.mapCanvas(), self.iface.cadDockWidget(), self.iface, action_multi_point_center_segment_templated_marker) self.tools[MultiPointSegmentCenterTemplatedMarkerTool.ID].setAction( action_multi_point_center_segment_templated_marker) action_multi_point_center_segment_templated_marker.triggered.connect( partial(self.switch_tool, MultiPointSegmentCenterTemplatedMarkerTool.ID)) action_multi_point_center_segment_templated_marker.setData( MultiPointSegmentCenterTemplatedMarkerTool.ID) self.toolbar.addAction( action_multi_point_center_segment_templated_marker) self.actions.append(action_multi_point_center_segment_templated_marker) self.get_map_tool_action_group().addAction( action_single_point_templated_marker) self.enable_actions_for_layer(self.iface.activeLayer()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" QgsApplication.processingRegistry().removeProvider(self.provider) if self.toolbar is not None: self.toolbar.deleteLater() for action in self.actions: if action is not None: action.deleteLater() self.iface.currentLayerChanged.disconnect(self.current_layer_changed) self.layout_hooks.unload(self.iface) def switch_tool(self, tool_id: str): """ Switches to the tool with the specified tool_id """ tool = self.tools[tool_id] if self.iface.mapCanvas().mapTool() == tool: return self.iface.mapCanvas().setMapTool(tool) self.active_tool = tool self.active_tool.set_layer(self.iface.activeLayer()) def current_layer_changed(self, layer: QgsMapLayer): """ Called when the current layer changes """ self.enable_actions_for_layer(layer) if self.active_tool: self.active_tool.set_layer(layer) def editing_toggled(self, enabled: bool): """ Called when editing mode is toggled """ QTimer.singleShot( 0, partial(self.enable_actions_for_layer, self.iface.activeLayer(), enabled)) def enable_actions_for_layer(self, layer: QgsMapLayer, forced_edit_state=None): """ Toggles whether actions should be enabled for the specified layer """ is_editable = forced_edit_state if is_editable is None: if isinstance(layer, QgsVectorLayer): is_editable = layer.isEditable() else: is_editable = False for action in self.actions: if sip.isdeleted(action): continue if self.tools.get(action.data()): tool = self.tools[action.data()] action.setEnabled( tool.is_compatible_with_layer(layer, is_editable)) if tool == self.active_tool and not action.isEnabled(): self.iface.mapCanvas().unsetMapTool(tool) self.iface.actionPan().trigger()
class WellLogView(QWidget): DEFAULT_COLUMN_WIDTH = 150 # Emitted when some styles have been updated styles_updated = pyqtSignal() def __init__(self, title=None,image_dir=None, parent=None): QWidget.__init__(self, parent) self.toolbar = QToolBar() self.__log_scene = MyScene(0, 0, 600, 600) self.__log_view = LogGraphicsView(self.__log_scene) self.__log_view.setAlignment(Qt.AlignLeft|Qt.AlignTop) self.__log_scene.sceneRectChanged.connect(self.on_rect_changed) if image_dir is None: image_dir = os.path.join(os.path.dirname(__file__), "img") self.__action_move_column_left = QAction(QIcon(os.path.join(image_dir, "left.svg")), "Move the column to the left", self.toolbar) self.__action_move_column_left.triggered.connect(self.on_move_column_left) self.__action_move_column_right = QAction(QIcon(os.path.join(image_dir, "right.svg")), "Move the column to the right", self.toolbar) self.__action_move_column_right.triggered.connect(self.on_move_column_right) self.__action_edit_style = QAction(QIcon(os.path.join(image_dir, "symbology.svg")), "Edit column style", self.toolbar) self.__action_edit_style.triggered.connect(self.on_edit_style) self.__action_add_column = QAction(QIcon(os.path.join(image_dir, "add.svg")), "Add a data column from configured ones", self.toolbar) self.__action_add_column.triggered.connect(self.on_add_column) self.__action_remove_column = QAction(QIcon(os.path.join(image_dir, "remove.svg")), "Remove the column", self.toolbar) self.__action_remove_column.triggered.connect(self.on_remove_column) #self.__action_move_content_right = QAction("Move content right", self.toolbar) #self.__action_move_content_left = QAction("Move content left", self.toolbar) #self.__action_move_content_left.triggered.connect(self.on_move_content_left) #self.__action_move_content_right.triggered.connect(self.on_move_content_right) self.toolbar.addAction(self.__action_move_column_left) self.toolbar.addAction(self.__action_move_column_right) self.toolbar.addAction(self.__action_edit_style) self.toolbar.addAction(self.__action_add_column) self.toolbar.addAction(self.__action_remove_column) #self.__toolbar.addAction(self.__action_move_content_left) #self.__toolbar.addAction(self.__action_move_content_right) self.__title_label = QLabel() if title is not None: self.set_title(title) self.__status_bar = QStatusBar() vbox = QVBoxLayout() vbox.addWidget(self.__title_label) vbox.addWidget(self.toolbar) vbox.addWidget(self.__log_view) vbox.addWidget(self.__status_bar) self.setLayout(vbox) self.__station_id = None # (log_item, legend_item) for each column self.__columns = [] # { layer : (log_item, legend_item) } self.__data2logitems = {} self.__column_widths = [] self._min_z = 0 self._max_z = 40 self.__allow_mouse_translation = True self.__translation_orig = None self.__style_dir = os.path.join(os.path.dirname(__file__), 'styles') self.select_column(-1) # by default we have a Z scale self.add_z_scale() def on_rect_changed(self, rect): for item, _ in self.__columns: item.set_height(rect.height()) def set_title(self, title): self.__title_label.setText(title) def _place_items(self): x = 0 for i, c in enumerate(self.__columns): item, legend = c width = self.__column_widths[i] legend.setPos(x, 0) item.setPos(x, legend.boundingRect().height()) x += width rect = self.__log_scene.sceneRect() rect.setWidth(x) self.__log_scene.setSceneRect(rect) def _add_column(self, log_item, legend_item): self.__log_scene.addItem(log_item) self.__log_scene.addItem(legend_item) log_item.set_min_depth(self._min_z) log_item.set_max_depth(self._max_z) self.__columns.append((log_item, legend_item)) self.__column_widths.append(log_item.boundingRect().width()) self._place_items() def _fit_to_max_depth(self): self._min_z = min([i.min_depth() for i, _ in self.__columns if i.min_depth() is not None]) self._max_z = max([i.max_depth() for i, _ in self.__columns if i.max_depth() is not None]) # if we have only one value, center it on a 2 meters range if self._min_z == self._max_z: self._min_z -= 1.0 self._max_z += 1.0 def _update_column_depths(self): for item, _ in self.__columns: item.set_min_depth(self._min_z) item.set_max_depth(self._max_z) item.update() def add_z_scale(self, title="Depth"): scale_item = ZScaleItem(self.DEFAULT_COLUMN_WIDTH / 2, self.__log_scene.height(), self._min_z, self._max_z) legend_item = LegendItem(self.DEFAULT_COLUMN_WIDTH / 2, title, unit_of_measure="m") self._add_column(scale_item, legend_item) def remove_data_column(self, data): """Remove data column from widget :param data: data to be removed """ # Column doesn't exist if data not in self.__data2logitems: raise ValueError("Impossible to remove data column : given data" " object doesn't exist") log_item, legend_item = self.__data2logitems[data] for i, (pitem, litem) in enumerate(self.__columns): if pitem == log_item and litem == legend_item: self.__columns.pop(i) self.__column_widths.pop(i) del self.__data2logitems[data] self.__log_scene.removeItem(log_item) self.__log_scene.removeItem(legend_item) return # Columns not found assert False def clear_data_columns(self): # remove item from scenes for (item, legend) in self.__columns: self.__log_scene.removeItem(legend) self.__log_scene.removeItem(item) # remove from internal lists self.__columns = [] self.__column_widths = [] self.__data2logitems = {} self.__selected_column = -1 self._place_items() self._update_button_visibility() # still add z scale self.add_z_scale() def on_plot_tooltip(self, txt, station_name = None): if station_name is not None: self.__status_bar.showMessage(u"Station: {} ".format(station_name) + txt) else: self.__status_bar.showMessage(txt) def add_data_column(self, data, title, uom, station_name = None, config = None): """ Parameters ---------- data: ?? title: str uom: str Unit of measure station_name: str Station name config: PlotConfig """ symbology, symbology_type = config.get_symbology() plot_item = PlotItem(size=QSizeF(self.DEFAULT_COLUMN_WIDTH, self.__log_scene.height()), render_type = POLYGON_RENDERER if symbology_type is None else symbology_type, symbology = symbology, x_orientation = ORIENTATION_DOWNWARD, y_orientation = ORIENTATION_LEFT_TO_RIGHT) plot_item.style_updated.connect(self.styles_updated) plot_item.set_layer(data.get_layer()) plot_item.tooltipRequested.connect(lambda txt: self.on_plot_tooltip(txt, station_name)) legend_item = LegendItem(self.DEFAULT_COLUMN_WIDTH, title, unit_of_measure=uom) data.data_modified.connect(lambda data=data : self._update_data_column(data, config)) self.__data2logitems[data] = (plot_item, legend_item) self._add_column(plot_item, legend_item) self._update_data_column(data, config) self._update_column_depths() def _update_data_column(self, data, config): plot_item, legend_item = self.__data2logitems[data] y_values = data.get_y_values() x_values = data.get_x_values() if y_values is None or x_values is None: plot_item.set_data_window(None) return plot_item.set_data(data.get_x_values(), data.get_y_values()) win = plot_item.data_window() min_x, min_y, max_x, max_y = win.left(), win.top(), win.right(), win.bottom() if config and config.get('min') is not None: min_y = float(config['min']) if config and config.get('max') is not None: max_y = float(config['max']) # legend legend_item.set_scale(min_y, max_y) plot_item.set_data_window(QRectF(min_x, min_y, max_x-min_x, max_y-min_y)) self.__log_scene.update() def add_stratigraphy(self, layer, filter_expression, column_mapping, title, style_file=None, config=None): """Add stratigraphy data Parameters ---------- layer: QgsVectorLayer The layer where stratigraphic data are stored filter_expression: str A QGIS expression to filter the vector layer column_mapping: dict Dictionary of column names title: str Title of the graph style_file: str Name of the style file to use config: PlotConfig """ symbology = config.get_symbology()[0] if config else None item = StratigraphyItem(self.DEFAULT_COLUMN_WIDTH, self.__log_scene.height(), style_file=style_file if not symbology else None, symbology=symbology, column_mapping=column_mapping ) item.style_updated.connect(self.styles_updated) legend_item = LegendItem(self.DEFAULT_COLUMN_WIDTH, title) item.set_layer(layer) item.tooltipRequested.connect(self.on_plot_tooltip) req = QgsFeatureRequest() req.setFilterExpression(filter_expression) item.set_data(list(layer.getFeatures(req))) self._add_column(item, legend_item) def add_imagery(self, image_filename, title, depth_from, depth_to): item = ImageryDataItem(self.DEFAULT_COLUMN_WIDTH, self.__log_scene.height(), image_filename, depth_from, depth_to) legend_item = LegendItem(self.DEFAULT_COLUMN_WIDTH, title) self._add_column(item, legend_item) def select_column_at(self, pos): x = pos.x() c = 0 selected = -1 for i, width in enumerate(self.__column_widths): if x >= c and x < c + width: selected = i break c += width self.select_column(selected) def select_column(self, idx): self.__selected_column = idx for i, p in enumerate(self.__columns): item, legend = p item.set_selected(idx == i) legend.set_selected(idx == i) item.update() legend.update() self._update_button_visibility() def selected_column(self): return self.__selected_column def _update_button_visibility(self): idx = self.__selected_column self.__action_move_column_left.setEnabled(idx != -1 and idx > 0) self.__action_move_column_right.setEnabled(idx != -1 and idx < len(self.__columns) - 1) item = self.__columns[idx][0] if idx > 0 else None self.__action_edit_style.setEnabled(bool(item and not isinstance(item, ImageryDataItem))) self.__action_remove_column.setEnabled(idx != -1) def on_move_column_left(self): if self.__selected_column < 1: return sel = self.__selected_column self.__columns[sel-1], self.__columns[sel] = self.__columns[sel], self.__columns[sel-1] self.__column_widths[sel-1], self.__column_widths[sel] = self.__column_widths[sel], self.__column_widths[sel-1] self.__selected_column -= 1 self._place_items() self._update_button_visibility() def on_move_column_right(self): if self.__selected_column == -1 or self.__selected_column >= len(self.__columns) - 1: return sel = self.__selected_column self.__columns[sel+1], self.__columns[sel] = self.__columns[sel], self.__columns[sel+1] self.__column_widths[sel+1], self.__column_widths[sel] = self.__column_widths[sel], self.__column_widths[sel+1] self.__selected_column += 1 self._place_items() self._update_button_visibility() def on_remove_column(self): if self.__selected_column == -1: return sel = self.__selected_column # remove item from scenes item, legend = self.__columns[sel] self.__log_scene.removeItem(legend) self.__log_scene.removeItem(item) # remove from internal list del self.__columns[sel] del self.__column_widths[sel] self.__selected_column = -1 self._place_items() self._update_button_visibility() def on_edit_style(self): if self.__selected_column == -1: return item = self.__columns[self.__selected_column][0] item.edit_style() def on_add_column(self): # to be overridden by subclasses pass def styles(self): """Return the current style of each item""" return dict([(item.layer().id(), item.qgis_style()) for item, legend in self.__columns if hasattr(item, "qgis_style")])
def initGui(self): """ Called to setup the plugin GUI """ self.network_layer_notifier = QgepLayerNotifier( self.iface.mainWindow(), ['vw_network_node', 'vw_network_segment']) self.wastewater_networkelement_layer_notifier = QgepLayerNotifier( self.iface.mainWindow(), ['vw_wastewater_node', 'vw_qgep_reach']) self.toolbarButtons = [] # Create toolbar button self.profileAction = QAction( QIcon( os.path.join(plugin_root_path(), "icons/wastewater-profile.svg")), self.tr("Profile"), self.iface.mainWindow()) self.profileAction.setWhatsThis(self.tr("Reach trace")) self.profileAction.setEnabled(False) self.profileAction.setCheckable(True) self.profileAction.triggered.connect(self.profileToolClicked) self.downstreamAction = QAction( QIcon( os.path.join(plugin_root_path(), "icons/wastewater-downstream.svg")), self.tr("Downstream"), self.iface.mainWindow()) self.downstreamAction.setWhatsThis(self.tr("Downstream reaches")) self.downstreamAction.setEnabled(False) self.downstreamAction.setCheckable(True) self.downstreamAction.triggered.connect(self.downstreamToolClicked) self.upstreamAction = QAction( QIcon( os.path.join(plugin_root_path(), "icons/wastewater-upstream.svg")), self.tr("Upstream"), self.iface.mainWindow()) self.upstreamAction.setWhatsThis(self.tr("Upstream reaches")) self.upstreamAction.setEnabled(False) self.upstreamAction.setCheckable(True) self.upstreamAction.triggered.connect(self.upstreamToolClicked) self.wizardAction = QAction( QIcon(os.path.join(plugin_root_path(), "icons/wizard.svg")), "Wizard", self.iface.mainWindow()) self.wizardAction.setWhatsThis( self.tr("Create new manholes and reaches")) self.wizardAction.setEnabled(False) self.wizardAction.setCheckable(True) self.wizardAction.triggered.connect(self.wizard) self.connectNetworkElementsAction = QAction( QIcon( os.path.join(plugin_root_path(), "icons/link-wastewater-networkelement.svg")), QApplication.translate('qgepplugin', 'Connect wastewater networkelements'), self.iface.mainWindow()) self.connectNetworkElementsAction.setEnabled(False) self.connectNetworkElementsAction.setCheckable(True) self.connectNetworkElementsAction.triggered.connect( self.connectNetworkElements) self.refreshNetworkTopologyAction = QAction( QIcon(os.path.join(plugin_root_path(), "icons/refresh-network.svg")), "Refresh network topology", self.iface.mainWindow()) self.refreshNetworkTopologyAction.setWhatsThis( self.tr("Refresh network topology")) self.refreshNetworkTopologyAction.setEnabled(False) self.refreshNetworkTopologyAction.setCheckable(False) self.refreshNetworkTopologyAction.triggered.connect( self.refreshNetworkTopologyActionClicked) self.aboutAction = QAction(self.tr('About'), self.iface.mainWindow()) self.aboutAction.triggered.connect(self.about) self.settingsAction = QAction(self.tr('Settings'), self.iface.mainWindow()) self.settingsAction.triggered.connect(self.showSettings) # Add toolbar button and menu item self.toolbar = QToolBar(QApplication.translate('qgepplugin', 'QGEP')) self.toolbar.addAction(self.profileAction) self.toolbar.addAction(self.upstreamAction) self.toolbar.addAction(self.downstreamAction) self.toolbar.addAction(self.wizardAction) self.toolbar.addAction(self.refreshNetworkTopologyAction) self.toolbar.addAction(self.connectNetworkElementsAction) self.iface.addPluginToMenu("&QGEP", self.profileAction) self.iface.addPluginToMenu("&QGEP", self.settingsAction) self.iface.addPluginToMenu("&QGEP", self.aboutAction) self.iface.addToolBar(self.toolbar) # Local array of buttons to enable / disable based on context self.toolbarButtons.append(self.profileAction) self.toolbarButtons.append(self.upstreamAction) self.toolbarButtons.append(self.downstreamAction) self.toolbarButtons.append(self.wizardAction) self.toolbarButtons.append(self.refreshNetworkTopologyAction) self.network_layer_notifier.layersAvailable.connect( self.onLayersAvailable) self.network_layer_notifier.layersUnavailable.connect( self.onLayersUnavailable) # Init the object maintaining the network self.network_analyzer = QgepGraphManager() self.network_analyzer.message_emitted.connect( self.iface.messageBar().pushMessage) # Create the map tool for profile selection self.profile_tool = QgepProfileMapTool(self.iface, self.profileAction, self.network_analyzer) self.profile_tool.profileChanged.connect(self.onProfileChanged) self.upstream_tree_tool = QgepTreeMapTool(self.iface, self.upstreamAction, self.network_analyzer) self.upstream_tree_tool.setDirection("upstream") self.upstream_tree_tool.treeChanged.connect(self.onTreeChanged) self.downstream_tree_tool = QgepTreeMapTool(self.iface, self.downstreamAction, self.network_analyzer) self.downstream_tree_tool.setDirection("downstream") self.downstream_tree_tool.treeChanged.connect(self.onTreeChanged) self.maptool_connect_networkelements = QgepMapToolConnectNetworkElements( self.iface, self.connectNetworkElementsAction) self.wastewater_networkelement_layer_notifier.layersAvailableChanged.connect( self.connectNetworkElementsAction.setEnabled) self.processing_provider = QgepProcessingProvider() QgsApplication.processingRegistry().addProvider( self.processing_provider) self.network_layer_notifier.layersAdded([])
class QgepPlugin(object): """ A plugin for wastewater management http://www.github.com/qgep/QGEP """ # The networkAnalyzer will manage the networklayers and pathfinding network_analyzer = None # Remember not to reopen the dock if there's already one opened profile_dock = None # Wizard wizarddock = None # The layer ids the plugin will need edgeLayer = None nodeLayer = None specialStructureLayer = None networkElementLayer = None profile = None def __init__(self, iface): self.iface = iface self.canvas = iface.mapCanvas() self.nodes = None self.edges = None self.initLogger() setup_i18n() def tr(self, source_text): """ This does not inherit from QObject but for the translation to work (in particular to have translatable strings picked up) we need a tr method. :rtype : unicode :param source_text: The text to translate :return: The translated text """ return QApplication.translate('QgepPlugin', source_text) def initLogger(self): """ Initializes the logger """ self.logger = logging.getLogger(__package__) settings = QSettings() loglevel = settings.value("/QGEP/LogLevel", 'Warning') logfile = settings.value("/QGEP/LogFile", None) if hasattr(self.logger, 'qgepFileHandler'): self.logger.removeHandler(self.logger.qgepFileHandler) del self.logger.qgepFileHandler current_handlers = [h.__class__.__name__ for h in self.logger.handlers] if self.__class__.__name__ not in current_handlers: self.logger.addHandler(QgepQgsLogHandler()) if logfile: log_handler = logging.FileHandler(logfile) fmt = logging.Formatter(LOGFORMAT) log_handler.setFormatter(fmt) self.logger.addHandler(log_handler) self.logger.fileHandler = log_handler if 'Debug' == loglevel: self.logger.setLevel(logging.DEBUG) elif 'Info' == loglevel: self.logger.setLevel(logging.INFO) elif 'Warning' == loglevel: self.logger.setLevel(logging.WARNING) elif 'Error' == loglevel: self.logger.setLevel(logging.ERROR) fp = os.path.join(os.path.abspath(os.path.dirname(__file__)), "metadata.txt") ini_text = QSettings(fp, QSettings.IniFormat) verno = ini_text.value("version") self.logger.info('QGEP plugin version ' + verno + ' started') def initGui(self): """ Called to setup the plugin GUI """ self.network_layer_notifier = QgepLayerNotifier( self.iface.mainWindow(), ['vw_network_node', 'vw_network_segment']) self.wastewater_networkelement_layer_notifier = QgepLayerNotifier( self.iface.mainWindow(), ['vw_wastewater_node', 'vw_qgep_reach']) self.toolbarButtons = [] # Create toolbar button self.profileAction = QAction( QIcon( os.path.join(plugin_root_path(), "icons/wastewater-profile.svg")), self.tr("Profile"), self.iface.mainWindow()) self.profileAction.setWhatsThis(self.tr("Reach trace")) self.profileAction.setEnabled(False) self.profileAction.setCheckable(True) self.profileAction.triggered.connect(self.profileToolClicked) self.downstreamAction = QAction( QIcon( os.path.join(plugin_root_path(), "icons/wastewater-downstream.svg")), self.tr("Downstream"), self.iface.mainWindow()) self.downstreamAction.setWhatsThis(self.tr("Downstream reaches")) self.downstreamAction.setEnabled(False) self.downstreamAction.setCheckable(True) self.downstreamAction.triggered.connect(self.downstreamToolClicked) self.upstreamAction = QAction( QIcon( os.path.join(plugin_root_path(), "icons/wastewater-upstream.svg")), self.tr("Upstream"), self.iface.mainWindow()) self.upstreamAction.setWhatsThis(self.tr("Upstream reaches")) self.upstreamAction.setEnabled(False) self.upstreamAction.setCheckable(True) self.upstreamAction.triggered.connect(self.upstreamToolClicked) self.wizardAction = QAction( QIcon(os.path.join(plugin_root_path(), "icons/wizard.svg")), "Wizard", self.iface.mainWindow()) self.wizardAction.setWhatsThis( self.tr("Create new manholes and reaches")) self.wizardAction.setEnabled(False) self.wizardAction.setCheckable(True) self.wizardAction.triggered.connect(self.wizard) self.connectNetworkElementsAction = QAction( QIcon( os.path.join(plugin_root_path(), "icons/link-wastewater-networkelement.svg")), QApplication.translate('qgepplugin', 'Connect wastewater networkelements'), self.iface.mainWindow()) self.connectNetworkElementsAction.setEnabled(False) self.connectNetworkElementsAction.setCheckable(True) self.connectNetworkElementsAction.triggered.connect( self.connectNetworkElements) self.refreshNetworkTopologyAction = QAction( QIcon(os.path.join(plugin_root_path(), "icons/refresh-network.svg")), "Refresh network topology", self.iface.mainWindow()) self.refreshNetworkTopologyAction.setWhatsThis( self.tr("Refresh network topology")) self.refreshNetworkTopologyAction.setEnabled(False) self.refreshNetworkTopologyAction.setCheckable(False) self.refreshNetworkTopologyAction.triggered.connect( self.refreshNetworkTopologyActionClicked) self.aboutAction = QAction(self.tr('About'), self.iface.mainWindow()) self.aboutAction.triggered.connect(self.about) self.settingsAction = QAction(self.tr('Settings'), self.iface.mainWindow()) self.settingsAction.triggered.connect(self.showSettings) # Add toolbar button and menu item self.toolbar = QToolBar(QApplication.translate('qgepplugin', 'QGEP')) self.toolbar.addAction(self.profileAction) self.toolbar.addAction(self.upstreamAction) self.toolbar.addAction(self.downstreamAction) self.toolbar.addAction(self.wizardAction) self.toolbar.addAction(self.refreshNetworkTopologyAction) self.toolbar.addAction(self.connectNetworkElementsAction) self.iface.addPluginToMenu("&QGEP", self.profileAction) self.iface.addPluginToMenu("&QGEP", self.settingsAction) self.iface.addPluginToMenu("&QGEP", self.aboutAction) self.iface.addToolBar(self.toolbar) # Local array of buttons to enable / disable based on context self.toolbarButtons.append(self.profileAction) self.toolbarButtons.append(self.upstreamAction) self.toolbarButtons.append(self.downstreamAction) self.toolbarButtons.append(self.wizardAction) self.toolbarButtons.append(self.refreshNetworkTopologyAction) self.network_layer_notifier.layersAvailable.connect( self.onLayersAvailable) self.network_layer_notifier.layersUnavailable.connect( self.onLayersUnavailable) # Init the object maintaining the network self.network_analyzer = QgepGraphManager() self.network_analyzer.message_emitted.connect( self.iface.messageBar().pushMessage) # Create the map tool for profile selection self.profile_tool = QgepProfileMapTool(self.iface, self.profileAction, self.network_analyzer) self.profile_tool.profileChanged.connect(self.onProfileChanged) self.upstream_tree_tool = QgepTreeMapTool(self.iface, self.upstreamAction, self.network_analyzer) self.upstream_tree_tool.setDirection("upstream") self.upstream_tree_tool.treeChanged.connect(self.onTreeChanged) self.downstream_tree_tool = QgepTreeMapTool(self.iface, self.downstreamAction, self.network_analyzer) self.downstream_tree_tool.setDirection("downstream") self.downstream_tree_tool.treeChanged.connect(self.onTreeChanged) self.maptool_connect_networkelements = QgepMapToolConnectNetworkElements( self.iface, self.connectNetworkElementsAction) self.wastewater_networkelement_layer_notifier.layersAvailableChanged.connect( self.connectNetworkElementsAction.setEnabled) self.processing_provider = QgepProcessingProvider() QgsApplication.processingRegistry().addProvider( self.processing_provider) self.network_layer_notifier.layersAdded([]) def unload(self): """ Called when unloading """ self.toolbar.removeAction(self.profileAction) self.toolbar.removeAction(self.upstreamAction) self.toolbar.removeAction(self.downstreamAction) self.toolbar.removeAction(self.wizardAction) self.toolbar.removeAction(self.refreshNetworkTopologyAction) self.toolbar.removeAction(self.connectNetworkElementsAction) self.toolbar.deleteLater() self.iface.removePluginMenu("&QGEP", self.profileAction) self.iface.removePluginMenu("&QGEP", self.aboutAction) QgsApplication.processingRegistry().removeProvider( self.processing_provider) def onLayersAvailable(self, layers): for b in self.toolbarButtons: b.setEnabled(True) self.network_analyzer.setReachLayer(layers['vw_network_segment']) self.network_analyzer.setNodeLayer(layers['vw_network_node']) def onLayersUnavailable(self): for b in self.toolbarButtons: b.setEnabled(False) def profileToolClicked(self): """ Is executed when the profile button is clicked """ self.openDock() # Set the profile map tool self.profile_tool.setActive() def upstreamToolClicked(self): """ Is executed when the user clicks the upstream search tool """ self.openDock() self.upstream_tree_tool.setActive() def downstreamToolClicked(self): """ Is executed when the user clicks the downstream search tool """ self.openDock() self.downstream_tree_tool.setActive() def refreshNetworkTopologyActionClicked(self): """ Is executed when the user clicks the refreshNetworkTopologyAction tool """ self.network_analyzer.refresh() def wizard(self): """ """ if not self.wizarddock: self.wizarddock = QgepWizard(self.iface.mainWindow(), self.iface) self.logger.debug('Opening Wizard') self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.wizarddock) self.wizarddock.show() def connectNetworkElements(self, checked): self.iface.mapCanvas().setMapTool(self.maptool_connect_networkelements) def openDock(self): """ Opens the dock """ if self.profile_dock is None: self.logger.debug('Open dock') self.profile_dock = QgepProfileDockWidget(self.iface.mainWindow(), self.iface.mapCanvas(), self.iface.addDockWidget) self.profile_dock.closed.connect(self.onDockClosed) self.profile_dock.showIt() self.plotWidget = QgepPlotSVGWidget(self.profile_dock, self.network_analyzer) self.plotWidget.specialStructureMouseOver.connect( self.highlightProfileElement) self.plotWidget.specialStructureMouseOut.connect( self.unhighlightProfileElement) self.plotWidget.reachMouseOver.connect( self.highlightProfileElement) self.plotWidget.reachMouseOut.connect( self.unhighlightProfileElement) self.profile_dock.addPlotWidget(self.plotWidget) self.profile_dock.setTree(self.nodes, self.edges) def onDockClosed(self): # used when Dock dialog is closed """ Gets called when the dock is closed All the cleanup of the dock has to be done here """ self.profile_dock = None def onProfileChanged(self, profile): """ The profile changed: update the plot @param profile: The profile to plot """ self.profile = profile.copy() if self.plotWidget: self.plotWidget.setProfile(profile) def onTreeChanged(self, nodes, edges): if self.profile_dock: self.profile_dock.setTree(nodes, edges) self.nodes = nodes self.edges = edges def highlightProfileElement(self, obj_id): if self.profile is not None: self.profile.highlight(str(obj_id)) def unhighlightProfileElement(self): if self.profile is not None: self.profile.highlight(None) def about(self): from .gui.dlgabout import DlgAbout DlgAbout(self.iface.mainWindow()).exec_() def showSettings(self): settings_dlg = QgepSettingsDialog(self.iface.mainWindow()) settings_dlg.exec_()
class _CameraWidget(QWidget): imagecaptured = pyqtSignal(QPixmap) cancel = pyqtSignal() def __init__(self, parent=None): super(_CameraWidget, self).__init__(parent) self.setLayout(QGridLayout()) self.toolbar = QToolBar() spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.toolbar.setIconSize(QSize(48, 48)) self.toolbar.addWidget(spacer) self.swapaction = self.toolbar.addAction(QIcon(":/widgets/cameraswap"), "Swap Camera") self.swapaction.triggered.connect(self.swapcamera) self.current_camera_index = 0 self.camera = None self.viewfinder = QCameraViewfinder() self.viewfinder.mousePressEvent = self.capture self.viewfinder.setAspectRatioMode(Qt.KeepAspectRatioByExpanding) self.update_camera_buttons() self.capturebutton = QPushButton("Capture", self) self.capturebutton.pressed.connect(self.capture) self.actionCancel = self.toolbar.addAction(QIcon(":/icons/cancel"), "Cancel") self.actionCancel.triggered.connect(self._cancel) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self.toolbar) self.layout().addWidget(self.viewfinder) self.layout().addWidget(self.capturebutton) self.viewfinder.show() def __del__(self): if self.camera: self.camera.unload() def _cancel(self): if self.camera: self.camera.unload() self.cancel.emit() @property def list_of_cameras(self): return QCameraInfo.availableCameras() def update_camera_buttons(self): if len(self.list_of_cameras) <= 1: self.swapaction.setVisible(False) def capture(self, *args): self.camera.searchAndLock() self.camera_capture.capture() self.camera.unlock() def swapcamera(self): cameras = QCameraInfo.availableCameras() if self.current_camera_index + 1 == len(cameras): self.current_camera_index = 0 else: self.current_camera_index += 1 self.start(self.current_camera_index) @property def camera_res(self): width, height = tuple(roam.config.settings['camera_res'].split(',')) return width, height def imageCaptured(self, frameid, image): # TODO Doing a pixmap convert here is a waste but downstream needs a qpixmap for now # refactor later if self.camera: self.camera.unload() self.imagecaptured.emit(QPixmap.fromImage(image)) def start(self, dev=1): if self.camera: self.camera.unload() cameras = QCameraInfo.availableCameras() self.camera = QCamera(cameras[dev]) self.camera.setViewfinder(self.viewfinder) self.camera.setCaptureMode(QCamera.CaptureStillImage) self.camera.start() self.camera_capture = QCameraImageCapture(self.camera) self.camera_capture.setCaptureDestination( QCameraImageCapture.CaptureToBuffer) self.camera_capture.imageCaptured.connect(self.imageCaptured)
def initGui(self): for keyseq, slot in ( (Qt.CTRL + Qt.ALT + Qt.Key_K, self.__create_group), # (Qt.CTRL + Qt.ALT + Qt.Key_S, self.__select_next_group), (Qt.CTRL + Qt.ALT + Qt.Key_N, self.__next_section), (Qt.CTRL + Qt.ALT + Qt.Key_B, self.__previous_section), (Qt.CTRL + Qt.ALT + Qt.Key_J, self.__add_section_from_selection), ): short = QShortcut(QKeySequence(keyseq), self.__iface.mainWindow()) short.setContext(Qt.ApplicationShortcut) short.activated.connect(slot) self.__shortcuts.append(short) self.__menu = QMenu("Albion") self.__menu.aboutToShow.connect(self.__create_menu_entries) self.__iface.mainWindow().menuBar().addMenu(self.__menu) self.__toolbar = QToolBar("Albion") self.__iface.addToolBar(self.__toolbar) #self.__toolbar.addAction( # icon("log_strati.svg"), "stratigraphic log" #).triggered.connect(self.__log_strati_clicked) self.__toolbar.addWidget(self.__current_graph) self.__current_graph.currentIndexChanged[str].connect( self.__current_graph_changed ) self.__toolbar.addWidget(self.__current_section) self.__current_section.currentIndexChanged[str].connect( self.__current_section_changed ) self.__toolbar.addAction( icon("previous_line_big.svg"), "previous section (Ctrl+Alt+b)" ).triggered.connect(self.__previous_section) self.__toolbar.addAction( icon("previous_line.svg"), "previous sub section" ).triggered.connect(self.__previous_subsection) self.__toolbar.addAction( icon("next_line.svg"), "next sub section" ).triggered.connect(self.__next_subsection) self.__toolbar.addAction( icon("next_line_big.svg"), "next section (Ctrl+Alt+n)" ).triggered.connect(self.__next_section) self.__toolbar.addAction( icon("line_from_selected.svg"), "create temporary section" ).triggered.connect(self.__section_from_selection) self.__viewer3d = QDockWidget("3D") self.__viewer3d.setWidget(Viewer3d()) self.__iface.addDockWidget(Qt.LeftDockWidgetArea, self.__viewer3d) self.__iface.mainWindow().tabifyDockWidget( self.__iface.mainWindow().findChild(QDockWidget, "Layers"), self.__viewer3d ) self.__viewer3d_ctrl = QToolBar("3D controls") self.__viewer3d_ctrl.addWidget(ViewerControls(self.__viewer3d.widget())) self.__iface.addToolBar(self.__viewer3d_ctrl) QgsProject.instance().readProject.connect(self.__qgis__project__loaded) self.__qgis__project__loaded() # case of reload
def __init__(self, parent=None): QWidget.__init__(self, parent) self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console")) self.settings = QgsSettings() self.shell = ShellScintilla(self) self.setFocusProxy(self.shell) self.shellOut = ShellOutputScintilla(self) self.tabEditorWidget = EditorTabWidget(self) # ------------ UI ------------------------------- self.splitterEditor = QSplitter(self) self.splitterEditor.setOrientation(Qt.Horizontal) self.splitterEditor.setHandleWidth(6) self.splitterEditor.setChildrenCollapsible(True) self.shellOutWidget = QWidget(self) self.shellOutWidget.setLayout(QVBoxLayout()) self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0) self.shellOutWidget.layout().addWidget(self.shellOut) self.splitter = QSplitter(self.splitterEditor) self.splitter.setOrientation(Qt.Vertical) self.splitter.setHandleWidth(3) self.splitter.setChildrenCollapsible(False) self.splitter.addWidget(self.shellOutWidget) self.splitter.addWidget(self.shell) # self.splitterEditor.addWidget(self.tabEditorWidget) self.splitterObj = QSplitter(self.splitterEditor) self.splitterObj.setHandleWidth(3) self.splitterObj.setOrientation(Qt.Horizontal) # self.splitterObj.setSizes([0, 0]) # self.splitterObj.setStretchFactor(0, 1) self.widgetEditor = QWidget(self.splitterObj) self.widgetFind = QWidget(self) self.listClassMethod = QTreeWidget(self.splitterObj) self.listClassMethod.setColumnCount(2) objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector") self.listClassMethod.setHeaderLabels([objInspLabel, '']) self.listClassMethod.setColumnHidden(1, True) self.listClassMethod.setAlternatingRowColors(True) # self.splitterEditor.addWidget(self.widgetEditor) # self.splitterObj.addWidget(self.listClassMethod) # self.splitterObj.addWidget(self.widgetEditor) # Hide side editor on start up self.splitterObj.hide() self.listClassMethod.hide() # Hide search widget on start up self.widgetFind.hide() icon_size = iface.iconSize(dockedToolbar=True) if iface else QSize(16, 16) sizes = self.splitter.sizes() self.splitter.setSizes(sizes) # ----------------Restore Settings------------------------------------ self.restoreSettingsConsole() # ------------------Toolbar Editor------------------------------------- # Action for Open File openFileBt = QCoreApplication.translate("PythonConsole", "Open Script…") self.openFileButton = QAction(self) self.openFileButton.setCheckable(False) self.openFileButton.setEnabled(True) self.openFileButton.setIcon(QgsApplication.getThemeIcon("console/iconOpenConsole.svg")) self.openFileButton.setMenuRole(QAction.PreferencesRole) self.openFileButton.setIconVisibleInMenu(True) self.openFileButton.setToolTip(openFileBt) self.openFileButton.setText(openFileBt) openExtEditorBt = QCoreApplication.translate("PythonConsole", "Open in External Editor") self.openInEditorButton = QAction(self) self.openInEditorButton.setCheckable(False) self.openInEditorButton.setEnabled(True) self.openInEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg")) self.openInEditorButton.setMenuRole(QAction.PreferencesRole) self.openInEditorButton.setIconVisibleInMenu(True) self.openInEditorButton.setToolTip(openExtEditorBt) self.openInEditorButton.setText(openExtEditorBt) # Action for Save File saveFileBt = QCoreApplication.translate("PythonConsole", "Save") self.saveFileButton = QAction(self) self.saveFileButton.setCheckable(False) self.saveFileButton.setEnabled(False) self.saveFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveConsole.svg")) self.saveFileButton.setMenuRole(QAction.PreferencesRole) self.saveFileButton.setIconVisibleInMenu(True) self.saveFileButton.setToolTip(saveFileBt) self.saveFileButton.setText(saveFileBt) # Action for Save File As saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As…") self.saveAsFileButton = QAction(self) self.saveAsFileButton.setCheckable(False) self.saveAsFileButton.setEnabled(True) self.saveAsFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveAsConsole.svg")) self.saveAsFileButton.setMenuRole(QAction.PreferencesRole) self.saveAsFileButton.setIconVisibleInMenu(True) self.saveAsFileButton.setToolTip(saveAsFileBt) self.saveAsFileButton.setText(saveAsFileBt) # Action Cut cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut") self.cutEditorButton = QAction(self) self.cutEditorButton.setCheckable(False) self.cutEditorButton.setEnabled(True) self.cutEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCut.svg")) self.cutEditorButton.setMenuRole(QAction.PreferencesRole) self.cutEditorButton.setIconVisibleInMenu(True) self.cutEditorButton.setToolTip(cutEditorBt) self.cutEditorButton.setText(cutEditorBt) # Action Copy copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy") self.copyEditorButton = QAction(self) self.copyEditorButton.setCheckable(False) self.copyEditorButton.setEnabled(True) self.copyEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCopy.svg")) self.copyEditorButton.setMenuRole(QAction.PreferencesRole) self.copyEditorButton.setIconVisibleInMenu(True) self.copyEditorButton.setToolTip(copyEditorBt) self.copyEditorButton.setText(copyEditorBt) # Action Paste pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste") self.pasteEditorButton = QAction(self) self.pasteEditorButton.setCheckable(False) self.pasteEditorButton.setEnabled(True) self.pasteEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditPaste.svg")) self.pasteEditorButton.setMenuRole(QAction.PreferencesRole) self.pasteEditorButton.setIconVisibleInMenu(True) self.pasteEditorButton.setToolTip(pasteEditorBt) self.pasteEditorButton.setText(pasteEditorBt) # Action Run Script (subprocess) runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run Script") self.runScriptEditorButton = QAction(self) self.runScriptEditorButton.setCheckable(False) self.runScriptEditorButton.setEnabled(True) self.runScriptEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconRunScriptConsole.svg")) self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole) self.runScriptEditorButton.setIconVisibleInMenu(True) self.runScriptEditorButton.setToolTip(runScriptEditorBt) self.runScriptEditorButton.setText(runScriptEditorBt) # Action Run Script (subprocess) commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment") self.commentEditorButton = QAction(self) self.commentEditorButton.setCheckable(False) self.commentEditorButton.setEnabled(True) self.commentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCommentEditorConsole.svg")) self.commentEditorButton.setMenuRole(QAction.PreferencesRole) self.commentEditorButton.setIconVisibleInMenu(True) self.commentEditorButton.setToolTip(commentEditorBt) self.commentEditorButton.setText(commentEditorBt) # Action Run Script (subprocess) uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment") self.uncommentEditorButton = QAction(self) self.uncommentEditorButton.setCheckable(False) self.uncommentEditorButton.setEnabled(True) self.uncommentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.svg")) self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole) self.uncommentEditorButton.setIconVisibleInMenu(True) self.uncommentEditorButton.setToolTip(uncommentEditorBt) self.uncommentEditorButton.setText(uncommentEditorBt) # Action for Object browser objList = QCoreApplication.translate("PythonConsole", "Object Inspector…") self.objectListButton = QAction(self) self.objectListButton.setCheckable(True) self.objectListButton.setEnabled(self.settings.value("pythonConsole/enableObjectInsp", False, type=bool)) self.objectListButton.setIcon(QgsApplication.getThemeIcon("console/iconClassBrowserConsole.svg")) self.objectListButton.setMenuRole(QAction.PreferencesRole) self.objectListButton.setIconVisibleInMenu(True) self.objectListButton.setToolTip(objList) self.objectListButton.setText(objList) # Action for Find text findText = QCoreApplication.translate("PythonConsole", "Find Text") self.findTextButton = QAction(self) self.findTextButton.setCheckable(True) self.findTextButton.setEnabled(True) self.findTextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchEditorConsole.svg")) self.findTextButton.setMenuRole(QAction.PreferencesRole) self.findTextButton.setIconVisibleInMenu(True) self.findTextButton.setToolTip(findText) self.findTextButton.setText(findText) # ----------------Toolbar Console------------------------------------- # Action Show Editor showEditor = QCoreApplication.translate("PythonConsole", "Show Editor") self.showEditorButton = QAction(self) self.showEditorButton.setEnabled(True) self.showEditorButton.setCheckable(True) self.showEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg")) self.showEditorButton.setMenuRole(QAction.PreferencesRole) self.showEditorButton.setIconVisibleInMenu(True) self.showEditorButton.setToolTip(showEditor) self.showEditorButton.setText(showEditor) # Action for Clear button clearBt = QCoreApplication.translate("PythonConsole", "Clear Console") self.clearButton = QAction(self) self.clearButton.setCheckable(False) self.clearButton.setEnabled(True) self.clearButton.setIcon(QgsApplication.getThemeIcon("console/iconClearConsole.svg")) self.clearButton.setMenuRole(QAction.PreferencesRole) self.clearButton.setIconVisibleInMenu(True) self.clearButton.setToolTip(clearBt) self.clearButton.setText(clearBt) # Action for settings optionsBt = QCoreApplication.translate("PythonConsole", "Options…") self.optionsButton = QAction(self) self.optionsButton.setCheckable(False) self.optionsButton.setEnabled(True) self.optionsButton.setIcon(QgsApplication.getThemeIcon("console/iconSettingsConsole.svg")) self.optionsButton.setMenuRole(QAction.PreferencesRole) self.optionsButton.setIconVisibleInMenu(True) self.optionsButton.setToolTip(optionsBt) self.optionsButton.setText(optionsBt) # Action for Run script runBt = QCoreApplication.translate("PythonConsole", "Run Command") self.runButton = QAction(self) self.runButton.setCheckable(False) self.runButton.setEnabled(True) self.runButton.setIcon(QgsApplication.getThemeIcon("console/mIconRunConsole.svg")) self.runButton.setMenuRole(QAction.PreferencesRole) self.runButton.setIconVisibleInMenu(True) self.runButton.setToolTip(runBt) self.runButton.setText(runBt) # Help action helpBt = QCoreApplication.translate("PythonConsole", "Help…") self.helpButton = QAction(self) self.helpButton.setCheckable(False) self.helpButton.setEnabled(True) self.helpButton.setIcon(QgsApplication.getThemeIcon("console/iconHelpConsole.svg")) self.helpButton.setMenuRole(QAction.PreferencesRole) self.helpButton.setIconVisibleInMenu(True) self.helpButton.setToolTip(helpBt) self.helpButton.setText(helpBt) self.toolBar = QToolBar() self.toolBar.setEnabled(True) self.toolBar.setFocusPolicy(Qt.NoFocus) self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBar.setLayoutDirection(Qt.LeftToRight) self.toolBar.setIconSize(icon_size) self.toolBar.setMovable(False) self.toolBar.setFloatable(False) self.toolBar.addAction(self.clearButton) self.toolBar.addAction(self.runButton) self.toolBar.addSeparator() self.toolBar.addAction(self.showEditorButton) self.toolBar.addSeparator() self.toolBar.addAction(self.optionsButton) self.toolBar.addAction(self.helpButton) self.toolBarEditor = QToolBar() self.toolBarEditor.setEnabled(False) self.toolBarEditor.setFocusPolicy(Qt.NoFocus) self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBarEditor.setLayoutDirection(Qt.LeftToRight) self.toolBarEditor.setIconSize(icon_size) self.toolBarEditor.setMovable(False) self.toolBarEditor.setFloatable(False) self.toolBarEditor.addAction(self.openFileButton) self.toolBarEditor.addAction(self.openInEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.saveFileButton) self.toolBarEditor.addAction(self.saveAsFileButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.runScriptEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.findTextButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.cutEditorButton) self.toolBarEditor.addAction(self.copyEditorButton) self.toolBarEditor.addAction(self.pasteEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.commentEditorButton) self.toolBarEditor.addAction(self.uncommentEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.objectListButton) self.widgetButton = QWidget() sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth()) self.widgetButton.setSizePolicy(sizePolicy) self.widgetButtonEditor = QWidget(self.widgetEditor) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widgetButtonEditor.sizePolicy().hasHeightForWidth()) self.widgetButtonEditor.setSizePolicy(sizePolicy) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.shellOut.sizePolicy().hasHeightForWidth()) self.shellOut.setSizePolicy(sizePolicy) self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # ------------ Layout ------------------------------- self.mainLayout = QGridLayout(self) self.mainLayout.setMargin(0) self.mainLayout.setSpacing(0) self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1) self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1) self.shellOutWidget.layout().insertWidget(0, self.toolBar) self.layoutEditor = QGridLayout(self.widgetEditor) self.layoutEditor.setMargin(0) self.layoutEditor.setSpacing(0) self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1) self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1) self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1) self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1) # Layout for the find widget self.layoutFind = QGridLayout(self.widgetFind) self.layoutFind.setContentsMargins(0, 0, 0, 0) self.lineEditFind = QgsFilterLineEdit() placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find…") self.lineEditFind.setPlaceholderText(placeHolderTxt) self.toolBarFindText = QToolBar() self.toolBarFindText.setIconSize(icon_size) self.findNextButton = QAction(self) self.findNextButton.setEnabled(False) toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next") self.findNextButton.setToolTip(toolTipfindNext) self.findNextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchNextEditorConsole.svg")) self.findPrevButton = QAction(self) self.findPrevButton.setEnabled(False) toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous") self.findPrevButton.setToolTip(toolTipfindPrev) self.findPrevButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchPrevEditorConsole.svg")) self.caseSensitive = QCheckBox() caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive") self.caseSensitive.setText(caseSensTr) self.wholeWord = QCheckBox() wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word") self.wholeWord.setText(wholeWordTr) self.wrapAround = QCheckBox() self.wrapAround.setChecked(True) wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around") self.wrapAround.setText(wrapAroundTr) self.toolBarFindText.addWidget(self.lineEditFind) self.toolBarFindText.addAction(self.findPrevButton) self.toolBarFindText.addAction(self.findNextButton) self.toolBarFindText.addWidget(self.caseSensitive) self.toolBarFindText.addWidget(self.wholeWord) self.toolBarFindText.addWidget(self.wrapAround) self.layoutFind.addWidget(self.toolBarFindText, 0, 1, 1, 1) # ------------ Add first Tab in Editor ------------------------------- # self.tabEditorWidget.newTabEditor(tabName='first', filename=None) # ------------ Signal ------------------------------- self.findTextButton.triggered.connect(self._toggleFind) self.objectListButton.toggled.connect(self.toggleObjectListWidget) self.commentEditorButton.triggered.connect(self.commentCode) self.uncommentEditorButton.triggered.connect(self.uncommentCode) self.runScriptEditorButton.triggered.connect(self.runScriptEditor) self.cutEditorButton.triggered.connect(self.cutEditor) self.copyEditorButton.triggered.connect(self.copyEditor) self.pasteEditorButton.triggered.connect(self.pasteEditor) self.showEditorButton.toggled.connect(self.toggleEditor) self.clearButton.triggered.connect(self.shellOut.clearConsole) self.optionsButton.triggered.connect(self.openSettings) self.runButton.triggered.connect(self.shell.entered) self.openFileButton.triggered.connect(self.openScriptFile) self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor) self.saveFileButton.triggered.connect(self.saveScriptFile) self.saveAsFileButton.triggered.connect(self.saveAsScriptFile) self.helpButton.triggered.connect(self.openHelp) self.listClassMethod.itemClicked.connect(self.onClickGoToLine) self.lineEditFind.returnPressed.connect(self._findNext) self.findNextButton.triggered.connect(self._findNext) self.findPrevButton.triggered.connect(self._findPrev) self.lineEditFind.textChanged.connect(self._textFindChanged) self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor) self.findScut.setContext(Qt.WidgetWithChildrenShortcut) self.findScut.activated.connect(self._openFind) self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor) self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut) self.findNextScut.activated.connect(self._findNext) self.findPreviousScut = QShortcut(QKeySequence.FindPrevious, self.widgetEditor) self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut) self.findPreviousScut.activated.connect(self._findPrev) # Escape on editor hides the find bar self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor) self.findScut.setContext(Qt.WidgetWithChildrenShortcut) self.findScut.activated.connect(self._closeFind)
class TimeSeriesView(QWidget): DEFAULT_ROW_HEIGHT = 150 # Emitted when some styles have been updated styles_updated = pyqtSignal() def __init__(self, title=None, image_dir=None, parent=None): QWidget.__init__(self, parent) self.__toolbar = QToolBar() self.__scene = MyScene(0, 0, 600, 400) self.__view = TimeSeriesGraphicsView(self.__scene) self.__view.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.__scene.sceneRectChanged.connect(self.on_rect_changed) if image_dir is None: image_dir = os.path.join(os.path.dirname(__file__), "img") self.__action_move_row_up = QAction( QIcon(os.path.join(image_dir, "up.svg")), "Move the row up", self.__toolbar) self.__action_move_row_up.triggered.connect(self.on_move_row_up) self.__action_move_row_down = QAction( QIcon(os.path.join(image_dir, "down.svg")), "Move the row down", self.__toolbar) self.__action_move_row_down.triggered.connect(self.on_move_row_down) self.__action_edit_style = QAction( QIcon(os.path.join(image_dir, "symbology.svg")), "Edit row style", self.__toolbar) self.__action_edit_style.triggered.connect(self.on_edit_style) self.__action_add_row = QAction( QIcon(os.path.join(image_dir, "add.svg")), "Add a data row", self.__toolbar) self.__action_add_row.triggered.connect(self.on_add_row) self.__action_remove_row = QAction( QIcon(os.path.join(image_dir, "remove.svg")), "Remove the row", self.__toolbar) self.__action_remove_row.triggered.connect(self.on_remove_row) self.__toolbar.addAction(self.__action_move_row_up) self.__toolbar.addAction(self.__action_move_row_down) self.__toolbar.addAction(self.__action_edit_style) self.__toolbar.addAction(self.__action_add_row) self.__toolbar.addAction(self.__action_remove_row) self.__title_label = QLabel() if title is not None: self.set_title(title) self.__status_bar = QStatusBar() vbox = QVBoxLayout() vbox.addWidget(self.__title_label) vbox.addWidget(self.__toolbar) vbox.addWidget(self.__view) vbox.addWidget(self.__status_bar) self.setLayout(vbox) self.__station_id = None # (log_item, legend_item) for each row self.__rows = [] # { layer : (log_item, legend_item) } self.__data2logitems = {} self.__row_heights = [] self._min_x = None self._max_x = None self.__allow_mouse_translation = True self.__translation_orig = None self.__style_dir = os.path.join(os.path.dirname(__file__), 'styles') self.select_row(-1) self._update_row_depths() def on_rect_changed(self, rect): for item, _ in self.__rows: item.set_width(rect.width()) def set_title(self, title): self.__title_label.setText(title) def _place_items(self): y = 0 for i, r in enumerate(self.__rows): item, legend = r height = self.__row_heights[i] legend.setPos(0, y) item.setPos(legend.boundingRect().width(), y) y += height rect = self.__scene.sceneRect() rect.setHeight(y) self.__scene.setSceneRect(rect) def _add_row(self, log_item, legend_item): self.__scene.addItem(log_item) self.__scene.addItem(legend_item) log_item.set_min_depth(self._min_x) log_item.set_max_depth(self._max_x) self.__rows.insert(0, (log_item, legend_item)) self.__row_heights.insert(0, log_item.boundingRect().height()) self._place_items() def set_x_range(self, min_x, max_x): self._min_x, self._max_x = min_x, max_x self._update_row_depths() def _update_row_depths(self): if self._min_x is None: return for item, _ in self.__rows: item.set_min_depth(self._min_x) item.set_max_depth(self._max_x) item.update() def remove_data_row(self, data): """Remove data row from widget :param data: data to be removed """ # Row doesn't exist if data not in self.__data2logitems: raise ValueError("Impossible to remove data row : given data" " object doesn't exist") log_item, legend_item = self.__data2logitems[data] for i, (pitem, litem) in enumerate(self.__rows): if pitem == log_item and litem == legend_item: self.__rows.pop(i) self.__row_widths.pop(i) del self.__data2logitems[data] self.__scene.removeItem(log_item) self.__scene.removeItem(legend_item) return # Rows not found assert False def clear_data_rows(self): # remove item from scenes for (item, legend) in self.__rows: self.__scene.removeItem(legend) self.__scene.removeItem(item) # remove from internal lists self.__rows = [] self.__rows_widths = [] self.__data2logitems = {} self.select_row(-1) self._place_items() self._update_button_visibility() self.add_time_scale() def on_plot_tooltip(self, station_name, txt): if station_name is not None: self.__status_bar.showMessage( u"Station: {} ".format(station_name) + txt) else: self.__status_bar.showMessage(txt) def add_data_row(self, data, title, uom, station_name=None, config=None): """ Parameters ---------- data: ?? title: str uom: str Unit of measure station_name: str Station name config: PlotConfig """ symbology, symbology_type = config.get_symbology() plot_item = PlotItem(size=QSizeF(self.__scene.width(), self.DEFAULT_ROW_HEIGHT), render_type=POINT_RENDERER if not symbology_type else symbology_type, symbology=symbology, x_orientation=ORIENTATION_LEFT_TO_RIGHT, y_orientation=ORIENTATION_UPWARD) plot_item.style_updated.connect(self.styles_updated) plot_item.set_layer(data.get_layer()) plot_item.tooltipRequested.connect( lambda txt: self.on_plot_tooltip(station_name, txt)) legend_item = LegendItem(self.DEFAULT_ROW_HEIGHT, title, unit_of_measure=uom, is_vertical=True) data.data_modified.connect( lambda data=data: self._update_data_row(data, config)) # center on new data self._min_x, self._max_x = data.get_x_min(), data.get_x_max() # if we have only one value, center it on a 2 minutes range if self._min_x and self._min_x == self._max_x: self._min_x -= 60 self._max_x += 60 self.__data2logitems[data] = (plot_item, legend_item) self._add_row(plot_item, legend_item) self._update_data_row(data, config) self._update_row_depths() def add_time_scale(self, title="Time"): scale_item = TimeScaleItem(self.__scene.width(), self.DEFAULT_ROW_HEIGHT * 3 / 4, self._min_x, self._max_x) legend_item = LegendItem(self.DEFAULT_ROW_HEIGHT * 3 / 4, title, is_vertical=True) self._add_row(scale_item, legend_item) def _update_data_row(self, data, config): plot_item, legend_item = self.__data2logitems[data] y_values = data.get_y_values() x_values = data.get_x_values() if y_values is None or x_values is None: plot_item.set_data_window(None) return plot_item.set_data(data.get_x_values(), data.get_y_values()) win = plot_item.data_window() min_x, min_y, max_x, max_y = win.left(), win.top(), win.right( ), win.bottom() if config and config.get("min") is not None: min_y = float(config['min']) if config and config.get("max") is not None: max_y = float(config['max']) # legend legend_item.set_scale(min_y, max_y) plot_item.set_data_window( QRectF(min_x, min_y, max_x - min_x, max_y - min_y)) self.__scene.update() def select_row_at(self, pos): y = pos.y() r = 0 selected = -1 for i, height in enumerate(self.__row_heights): if y >= r and y < r + height: selected = i break r += height self.select_row(selected) def select_row(self, idx): self.__selected_row = idx for i, p in enumerate(self.__rows): item, legend = p item.set_selected(idx == i) legend.set_selected(idx == i) item.update() legend.update() self._update_button_visibility() def _update_button_visibility(self): idx = self.__selected_row self.__action_move_row_up.setEnabled(idx != -1 and idx > 0) self.__action_move_row_down.setEnabled(idx != -1 and idx < len(self.__rows) - 1) self.__action_edit_style.setEnabled(idx != -1) self.__action_remove_row.setEnabled(idx != -1) def on_move_row_up(self): if self.__selected_row < 1: return sel = self.__selected_row self.__rows[sel - 1], self.__rows[sel] = self.__rows[sel], self.__rows[sel - 1] self.__row_heights[sel - 1], self.__row_heights[ sel] = self.__row_heights[sel], self.__row_heights[sel - 1] self.__selected_row -= 1 self._place_items() self._update_button_visibility() def on_move_row_down(self): if self.__selected_row == -1 or self.__selected_row >= len( self.__rows) - 1: return sel = self.__selected_row self.__rows[sel + 1], self.__rows[sel] = self.__rows[sel], self.__rows[sel + 1] self.__row_heights[sel + 1], self.__row_heights[ sel] = self.__row_heights[sel], self.__row_heights[sel + 1] self.__selected_row += 1 self._place_items() self._update_button_visibility() def on_remove_row(self): if self.__selected_row == -1: return sel = self.__selected_row # remove item from scenes item, legend = self.__rows[sel] self.__scene.removeItem(legend) self.__scene.removeItem(item) # remove from internal list del self.__rows[sel] del self.__row_heights[sel] self.__selected_row = -1 self._place_items() self._update_button_visibility() def on_edit_style(self): if self.__selected_row == -1: return item = self.__rows[self.__selected_row][0] item.edit_style() def on_add_row(self): # to be overridden by subclasses pass
class PythonConsoleWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setWindowTitle( QCoreApplication.translate("PythonConsole", "Python Console")) self.settings = QgsSettings() self.shell = ShellScintilla(self) self.setFocusProxy(self.shell) self.shellOut = ShellOutputScintilla(self) self.tabEditorWidget = EditorTabWidget(self) # ------------ UI ------------------------------- self.splitterEditor = QSplitter(self) self.splitterEditor.setOrientation(Qt.Horizontal) self.splitterEditor.setHandleWidth(6) self.splitterEditor.setChildrenCollapsible(True) self.shellOutWidget = QWidget(self) self.shellOutWidget.setLayout(QVBoxLayout()) self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0) self.shellOutWidget.layout().addWidget(self.shellOut) self.splitter = QSplitter(self.splitterEditor) self.splitter.setOrientation(Qt.Vertical) self.splitter.setHandleWidth(3) self.splitter.setChildrenCollapsible(False) self.splitter.addWidget(self.shellOutWidget) self.splitter.addWidget(self.shell) # self.splitterEditor.addWidget(self.tabEditorWidget) self.splitterObj = QSplitter(self.splitterEditor) self.splitterObj.setHandleWidth(3) self.splitterObj.setOrientation(Qt.Horizontal) # self.splitterObj.setSizes([0, 0]) # self.splitterObj.setStretchFactor(0, 1) self.widgetEditor = QWidget(self.splitterObj) self.widgetFind = QWidget(self) self.listClassMethod = QTreeWidget(self.splitterObj) self.listClassMethod.setColumnCount(2) objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector") self.listClassMethod.setHeaderLabels([objInspLabel, '']) self.listClassMethod.setColumnHidden(1, True) self.listClassMethod.setAlternatingRowColors(True) # self.splitterEditor.addWidget(self.widgetEditor) # self.splitterObj.addWidget(self.listClassMethod) # self.splitterObj.addWidget(self.widgetEditor) # Hide side editor on start up self.splitterObj.hide() self.listClassMethod.hide() # Hide search widget on start up self.widgetFind.hide() icon_size = iface.iconSize( dockedToolbar=True) if iface else QSize(16, 16) sizes = self.splitter.sizes() self.splitter.setSizes(sizes) # ----------------Restore Settings------------------------------------ self.restoreSettingsConsole() # ------------------Toolbar Editor------------------------------------- # Action for Open File openFileBt = QCoreApplication.translate("PythonConsole", "Open Script...") self.openFileButton = QAction(self) self.openFileButton.setCheckable(False) self.openFileButton.setEnabled(True) self.openFileButton.setIcon( QgsApplication.getThemeIcon("console/iconOpenConsole.png")) self.openFileButton.setMenuRole(QAction.PreferencesRole) self.openFileButton.setIconVisibleInMenu(True) self.openFileButton.setToolTip(openFileBt) self.openFileButton.setText(openFileBt) openExtEditorBt = QCoreApplication.translate( "PythonConsole", "Open in External Editor") self.openInEditorButton = QAction(self) self.openInEditorButton.setCheckable(False) self.openInEditorButton.setEnabled(True) self.openInEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconShowEditorConsole.png")) self.openInEditorButton.setMenuRole(QAction.PreferencesRole) self.openInEditorButton.setIconVisibleInMenu(True) self.openInEditorButton.setToolTip(openExtEditorBt) self.openInEditorButton.setText(openExtEditorBt) # Action for Save File saveFileBt = QCoreApplication.translate("PythonConsole", "Save") self.saveFileButton = QAction(self) self.saveFileButton.setCheckable(False) self.saveFileButton.setEnabled(False) self.saveFileButton.setIcon( QgsApplication.getThemeIcon("console/iconSaveConsole.png")) self.saveFileButton.setMenuRole(QAction.PreferencesRole) self.saveFileButton.setIconVisibleInMenu(True) self.saveFileButton.setToolTip(saveFileBt) self.saveFileButton.setText(saveFileBt) # Action for Save File As saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As...") self.saveAsFileButton = QAction(self) self.saveAsFileButton.setCheckable(False) self.saveAsFileButton.setEnabled(True) self.saveAsFileButton.setIcon( QgsApplication.getThemeIcon("console/iconSaveAsConsole.png")) self.saveAsFileButton.setMenuRole(QAction.PreferencesRole) self.saveAsFileButton.setIconVisibleInMenu(True) self.saveAsFileButton.setToolTip(saveAsFileBt) self.saveAsFileButton.setText(saveAsFileBt) # Action Cut cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut") self.cutEditorButton = QAction(self) self.cutEditorButton.setCheckable(False) self.cutEditorButton.setEnabled(True) self.cutEditorButton.setIcon( QgsApplication.getThemeIcon("mActionEditCut.svg")) self.cutEditorButton.setMenuRole(QAction.PreferencesRole) self.cutEditorButton.setIconVisibleInMenu(True) self.cutEditorButton.setToolTip(cutEditorBt) self.cutEditorButton.setText(cutEditorBt) # Action Copy copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy") self.copyEditorButton = QAction(self) self.copyEditorButton.setCheckable(False) self.copyEditorButton.setEnabled(True) self.copyEditorButton.setIcon( QgsApplication.getThemeIcon("mActionEditCopy.svg")) self.copyEditorButton.setMenuRole(QAction.PreferencesRole) self.copyEditorButton.setIconVisibleInMenu(True) self.copyEditorButton.setToolTip(copyEditorBt) self.copyEditorButton.setText(copyEditorBt) # Action Paste pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste") self.pasteEditorButton = QAction(self) self.pasteEditorButton.setCheckable(False) self.pasteEditorButton.setEnabled(True) self.pasteEditorButton.setIcon( QgsApplication.getThemeIcon("mActionEditPaste.svg")) self.pasteEditorButton.setMenuRole(QAction.PreferencesRole) self.pasteEditorButton.setIconVisibleInMenu(True) self.pasteEditorButton.setToolTip(pasteEditorBt) self.pasteEditorButton.setText(pasteEditorBt) # Action Run Script (subprocess) runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run script") self.runScriptEditorButton = QAction(self) self.runScriptEditorButton.setCheckable(False) self.runScriptEditorButton.setEnabled(True) self.runScriptEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconRunScriptConsole.png")) self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole) self.runScriptEditorButton.setIconVisibleInMenu(True) self.runScriptEditorButton.setToolTip(runScriptEditorBt) self.runScriptEditorButton.setText(runScriptEditorBt) # Action Run Script (subprocess) commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment") self.commentEditorButton = QAction(self) self.commentEditorButton.setCheckable(False) self.commentEditorButton.setEnabled(True) self.commentEditorButton.setIcon( QgsApplication.getThemeIcon( "console/iconCommentEditorConsole.png")) self.commentEditorButton.setMenuRole(QAction.PreferencesRole) self.commentEditorButton.setIconVisibleInMenu(True) self.commentEditorButton.setToolTip(commentEditorBt) self.commentEditorButton.setText(commentEditorBt) # Action Run Script (subprocess) uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment") self.uncommentEditorButton = QAction(self) self.uncommentEditorButton.setCheckable(False) self.uncommentEditorButton.setEnabled(True) self.uncommentEditorButton.setIcon( QgsApplication.getThemeIcon( "console/iconUncommentEditorConsole.png")) self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole) self.uncommentEditorButton.setIconVisibleInMenu(True) self.uncommentEditorButton.setToolTip(uncommentEditorBt) self.uncommentEditorButton.setText(uncommentEditorBt) # Action for Object browser objList = QCoreApplication.translate("PythonConsole", "Object Inspector...") self.objectListButton = QAction(self) self.objectListButton.setCheckable(True) self.objectListButton.setEnabled( self.settings.value("pythonConsole/enableObjectInsp", False, type=bool)) self.objectListButton.setIcon( QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png")) self.objectListButton.setMenuRole(QAction.PreferencesRole) self.objectListButton.setIconVisibleInMenu(True) self.objectListButton.setToolTip(objList) self.objectListButton.setText(objList) # Action for Find text findText = QCoreApplication.translate("PythonConsole", "Find Text") self.findTextButton = QAction(self) self.findTextButton.setCheckable(True) self.findTextButton.setEnabled(True) self.findTextButton.setIcon( QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png")) self.findTextButton.setMenuRole(QAction.PreferencesRole) self.findTextButton.setIconVisibleInMenu(True) self.findTextButton.setToolTip(findText) self.findTextButton.setText(findText) # ----------------Toolbar Console------------------------------------- # Action Show Editor showEditor = QCoreApplication.translate("PythonConsole", "Show Editor") self.showEditorButton = QAction(self) self.showEditorButton.setEnabled(True) self.showEditorButton.setCheckable(True) self.showEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconShowEditorConsole.png")) self.showEditorButton.setMenuRole(QAction.PreferencesRole) self.showEditorButton.setIconVisibleInMenu(True) self.showEditorButton.setToolTip(showEditor) self.showEditorButton.setText(showEditor) # Action for Clear button clearBt = QCoreApplication.translate("PythonConsole", "Clear Console") self.clearButton = QAction(self) self.clearButton.setCheckable(False) self.clearButton.setEnabled(True) self.clearButton.setIcon( QgsApplication.getThemeIcon("console/iconClearConsole.png")) self.clearButton.setMenuRole(QAction.PreferencesRole) self.clearButton.setIconVisibleInMenu(True) self.clearButton.setToolTip(clearBt) self.clearButton.setText(clearBt) # Action for settings optionsBt = QCoreApplication.translate("PythonConsole", "Options...") self.optionsButton = QAction(self) self.optionsButton.setCheckable(False) self.optionsButton.setEnabled(True) self.optionsButton.setIcon( QgsApplication.getThemeIcon("console/iconSettingsConsole.png")) self.optionsButton.setMenuRole(QAction.PreferencesRole) self.optionsButton.setIconVisibleInMenu(True) self.optionsButton.setToolTip(optionsBt) self.optionsButton.setText(optionsBt) # Action for Run script runBt = QCoreApplication.translate("PythonConsole", "Run Command") self.runButton = QAction(self) self.runButton.setCheckable(False) self.runButton.setEnabled(True) self.runButton.setIcon( QgsApplication.getThemeIcon("console/iconRunConsole.png")) self.runButton.setMenuRole(QAction.PreferencesRole) self.runButton.setIconVisibleInMenu(True) self.runButton.setToolTip(runBt) self.runButton.setText(runBt) # Help action helpBt = QCoreApplication.translate("PythonConsole", "Help...") self.helpButton = QAction(self) self.helpButton.setCheckable(False) self.helpButton.setEnabled(True) self.helpButton.setIcon( QgsApplication.getThemeIcon("console/iconHelpConsole.png")) self.helpButton.setMenuRole(QAction.PreferencesRole) self.helpButton.setIconVisibleInMenu(True) self.helpButton.setToolTip(helpBt) self.helpButton.setText(helpBt) self.toolBar = QToolBar() self.toolBar.setEnabled(True) self.toolBar.setFocusPolicy(Qt.NoFocus) self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBar.setLayoutDirection(Qt.LeftToRight) self.toolBar.setIconSize(icon_size) self.toolBar.setMovable(False) self.toolBar.setFloatable(False) self.toolBar.addAction(self.clearButton) self.toolBar.addAction(self.runButton) self.toolBar.addSeparator() self.toolBar.addAction(self.showEditorButton) self.toolBar.addSeparator() self.toolBar.addAction(self.optionsButton) self.toolBar.addAction(self.helpButton) self.toolBarEditor = QToolBar() self.toolBarEditor.setEnabled(False) self.toolBarEditor.setFocusPolicy(Qt.NoFocus) self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBarEditor.setLayoutDirection(Qt.LeftToRight) self.toolBarEditor.setIconSize(icon_size) self.toolBarEditor.setMovable(False) self.toolBarEditor.setFloatable(False) self.toolBarEditor.addAction(self.openFileButton) self.toolBarEditor.addAction(self.openInEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.saveFileButton) self.toolBarEditor.addAction(self.saveAsFileButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.runScriptEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.findTextButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.cutEditorButton) self.toolBarEditor.addAction(self.copyEditorButton) self.toolBarEditor.addAction(self.pasteEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.commentEditorButton) self.toolBarEditor.addAction(self.uncommentEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.objectListButton) self.widgetButton = QWidget() sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.widgetButton.sizePolicy().hasHeightForWidth()) self.widgetButton.setSizePolicy(sizePolicy) self.widgetButtonEditor = QWidget(self.widgetEditor) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.widgetButtonEditor.sizePolicy().hasHeightForWidth()) self.widgetButtonEditor.setSizePolicy(sizePolicy) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.shellOut.sizePolicy().hasHeightForWidth()) self.shellOut.setSizePolicy(sizePolicy) self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # ------------ Layout ------------------------------- self.mainLayout = QGridLayout(self) self.mainLayout.setMargin(0) self.mainLayout.setSpacing(0) self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1) self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1) self.shellOutWidget.layout().insertWidget(0, self.toolBar) self.layoutEditor = QGridLayout(self.widgetEditor) self.layoutEditor.setMargin(0) self.layoutEditor.setSpacing(0) self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1) self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1) self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1) self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1) # Layout for the find widget self.layoutFind = QGridLayout(self.widgetFind) self.layoutFind.setContentsMargins(0, 0, 0, 0) self.lineEditFind = QgsFilterLineEdit() placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find...") self.lineEditFind.setPlaceholderText(placeHolderTxt) self.findNextButton = QToolButton() self.findNextButton.setEnabled(False) toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next") self.findNextButton.setToolTip(toolTipfindNext) self.findNextButton.setIcon( QgsApplication.getThemeIcon( "console/iconSearchNextEditorConsole.png")) self.findNextButton.setIconSize(QSize(24, 24)) self.findNextButton.setAutoRaise(True) self.findPrevButton = QToolButton() self.findPrevButton.setEnabled(False) toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous") self.findPrevButton.setToolTip(toolTipfindPrev) self.findPrevButton.setIcon( QgsApplication.getThemeIcon( "console/iconSearchPrevEditorConsole.png")) self.findPrevButton.setIconSize(QSize(24, 24)) self.findPrevButton.setAutoRaise(True) self.caseSensitive = QCheckBox() caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive") self.caseSensitive.setText(caseSensTr) self.wholeWord = QCheckBox() wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word") self.wholeWord.setText(wholeWordTr) self.wrapAround = QCheckBox() self.wrapAround.setChecked(True) wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around") self.wrapAround.setText(wrapAroundTr) self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1) self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1) self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1) self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1) self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1) self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1) # ------------ Add first Tab in Editor ------------------------------- # self.tabEditorWidget.newTabEditor(tabName='first', filename=None) # ------------ Signal ------------------------------- self.findTextButton.triggered.connect(self._toggleFind) self.objectListButton.toggled.connect(self.toggleObjectListWidget) self.commentEditorButton.triggered.connect(self.commentCode) self.uncommentEditorButton.triggered.connect(self.uncommentCode) self.runScriptEditorButton.triggered.connect(self.runScriptEditor) self.cutEditorButton.triggered.connect(self.cutEditor) self.copyEditorButton.triggered.connect(self.copyEditor) self.pasteEditorButton.triggered.connect(self.pasteEditor) self.showEditorButton.toggled.connect(self.toggleEditor) self.clearButton.triggered.connect(self.shellOut.clearConsole) self.optionsButton.triggered.connect(self.openSettings) self.runButton.triggered.connect(self.shell.entered) self.openFileButton.triggered.connect(self.openScriptFile) self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor) self.saveFileButton.triggered.connect(self.saveScriptFile) self.saveAsFileButton.triggered.connect(self.saveAsScriptFile) self.helpButton.triggered.connect(self.openHelp) self.listClassMethod.itemClicked.connect(self.onClickGoToLine) self.lineEditFind.returnPressed.connect(self._findNext) self.findNextButton.clicked.connect(self._findNext) self.findPrevButton.clicked.connect(self._findPrev) self.lineEditFind.textChanged.connect(self._textFindChanged) self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor) self.findScut.setContext(Qt.WidgetWithChildrenShortcut) self.findScut.activated.connect(self._openFind) self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor) self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut) self.findNextScut.activated.connect(self._findNext) self.findPreviousScut = QShortcut(QKeySequence.FindPrevious, self.widgetEditor) self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut) self.findPreviousScut.activated.connect(self._findPrev) # Escape on editor hides the find bar self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor) self.findScut.setContext(Qt.WidgetWithChildrenShortcut) self.findScut.activated.connect(self._closeFind) def _toggleFind(self): self.tabEditorWidget.currentWidget().newEditor.toggleFindWidget() def _openFind(self): self.tabEditorWidget.currentWidget().newEditor.openFindWidget() def _closeFind(self): self.tabEditorWidget.currentWidget().newEditor.closeFindWidget() def _findNext(self): self.tabEditorWidget.currentWidget().newEditor.findText(True) def _findPrev(self): self.tabEditorWidget.currentWidget().newEditor.findText(False) def _textFindChanged(self): if self.lineEditFind.text(): self.findNextButton.setEnabled(True) self.findPrevButton.setEnabled(True) self.tabEditorWidget.currentWidget().newEditor.findText( True, showMessage=False, findFirst=True) else: self.lineEditFind.setStyleSheet('') self.findNextButton.setEnabled(False) self.findPrevButton.setEnabled(False) def onClickGoToLine(self, item, column): tabEditor = self.tabEditorWidget.currentWidget().newEditor if item.text(1) == 'syntaxError': check = tabEditor.syntaxCheck(fromContextMenu=False) if check and not tabEditor.isReadOnly(): self.tabEditorWidget.currentWidget().save() return linenr = int(item.text(1)) itemName = str(item.text(0)) charPos = itemName.find(' ') if charPos != -1: objName = itemName[0:charPos] else: objName = itemName tabEditor.goToLine(objName, linenr) def toggleEditor(self, checked): self.splitterObj.show() if checked else self.splitterObj.hide() if not self.tabEditorWidget: self.tabEditorWidget.enableToolBarEditor(checked) self.tabEditorWidget.restoreTabsOrAddNew() def toggleObjectListWidget(self, checked): self.listClassMethod.show() if checked else self.listClassMethod.hide() def pasteEditor(self): self.tabEditorWidget.currentWidget().newEditor.paste() def cutEditor(self): self.tabEditorWidget.currentWidget().newEditor.cut() def copyEditor(self): self.tabEditorWidget.currentWidget().newEditor.copy() def runScriptEditor(self): self.tabEditorWidget.currentWidget().newEditor.runScriptCode() def commentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True) def uncommentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False) def openScriptFileExtEditor(self): tabWidget = self.tabEditorWidget.currentWidget() path = tabWidget.path import subprocess try: subprocess.Popen([os.environ['EDITOR'], path]) except KeyError: QDesktopServices.openUrl(QUrl.fromLocalFile(path)) def openScriptFile(self): lastDirPath = self.settings.value("pythonConsole/lastDirPath", QDir.homePath()) openFileTr = QCoreApplication.translate("PythonConsole", "Open File") fileList, selected_filter = QFileDialog.getOpenFileNames( self, openFileTr, lastDirPath, "Script file (*.py)") if fileList: for pyFile in fileList: for i in range(self.tabEditorWidget.count()): tabWidget = self.tabEditorWidget.widget(i) if tabWidget.path == pyFile: self.tabEditorWidget.setCurrentWidget(tabWidget) break else: tabName = QFileInfo(pyFile).fileName() self.tabEditorWidget.newTabEditor(tabName, pyFile) lastDirPath = QFileInfo(pyFile).path() self.settings.setValue("pythonConsole/lastDirPath", pyFile) self.updateTabListScript(pyFile, action='append') def saveScriptFile(self): tabWidget = self.tabEditorWidget.currentWidget() try: tabWidget.save() except (IOError, OSError) as error: msgText = QCoreApplication.translate( 'PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}').format( tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False) def saveAsScriptFile(self, index=None): tabWidget = self.tabEditorWidget.currentWidget() if not index: index = self.tabEditorWidget.currentIndex() if not tabWidget.path: fileName = self.tabEditorWidget.tabText(index) + '.py' folder = self.settings.value("pythonConsole/lastDirPath", QDir.home()) pathFileName = os.path.join(folder, fileName) fileNone = True else: pathFileName = tabWidget.path fileNone = False saveAsFileTr = QCoreApplication.translate("PythonConsole", "Save File As") filename, filter = QFileDialog.getSaveFileName(self, saveAsFileTr, pathFileName, "Script file (*.py)") if filename: try: tabWidget.save(filename) except (IOError, OSError) as error: msgText = QCoreApplication.translate( 'PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}' ).format(tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False) if fileNone: tabWidget.path = None else: tabWidget.path = pathFileName return if not fileNone: self.updateTabListScript(pathFileName, action='remove') def openHelp(self): QgsHelp.openHelp("plugins/python_console.html") def openSettings(self): if optionsDialog(self).exec_(): self.shell.refreshSettingsShell() self.shellOut.refreshSettingsOutput() self.tabEditorWidget.refreshSettingsEditor() def callWidgetMessageBar(self, text): self.shellOut.widgetMessageBar(iface, text) def callWidgetMessageBarEditor(self, text, level, timed): self.tabEditorWidget.widgetMessageBar(iface, text, level, timed) def updateTabListScript(self, script, action=None): if action == 'remove': self.tabListScript.remove(script) elif action == 'append': if not self.tabListScript: self.tabListScript = [] if script not in self.tabListScript: self.tabListScript.append(script) else: self.tabListScript = [] self.settings.setValue("pythonConsole/tabScripts", self.tabListScript) def saveSettingsConsole(self): self.settings.setValue("pythonConsole/splitterConsole", self.splitter.saveState()) self.settings.setValue("pythonConsole/splitterObj", self.splitterObj.saveState()) self.settings.setValue("pythonConsole/splitterEditor", self.splitterEditor.saveState()) self.shell.writeHistoryFile(True) def restoreSettingsConsole(self): storedTabScripts = self.settings.value("pythonConsole/tabScripts", []) self.tabListScript = storedTabScripts self.splitter.restoreState( self.settings.value("pythonConsole/splitterConsole", QByteArray())) self.splitterEditor.restoreState( self.settings.value("pythonConsole/splitterEditor", QByteArray())) self.splitterObj.restoreState( self.settings.value("pythonConsole/splitterObj", QByteArray()))
def setupUi(self): self.setWindowTitle(self.tr("DB Manager")) self.setWindowIcon(QIcon(":/db_manager/icon")) self.resize(QSize(700, 500).expandedTo(self.minimumSizeHint())) # create central tab widget and add the first 3 tabs: info, table and preview self.tabs = QTabWidget() self.info = InfoViewer(self) self.tabs.addTab(self.info, self.tr("Info")) self.table = TableViewer(self) self.tabs.addTab(self.table, self.tr("Table")) self.preview = LayerPreview(self) self.tabs.addTab(self.preview, self.tr("Preview")) self.setCentralWidget(self.tabs) # display close button for all tabs but the first 3 ones, i.e. # HACK: just hide the close button where not needed (GS) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_tab) tabbar = self.tabs.tabBar() for i in range(3): btn = tabbar.tabButton(i, QTabBar.RightSide) if tabbar.tabButton(i, QTabBar.RightSide) else tabbar.tabButton(i, QTabBar.LeftSide) btn.resize(0, 0) btn.hide() # Creates layout for message bar self.layout = QGridLayout(self.info) self.layout.setContentsMargins(0, 0, 0, 0) spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.layout.addItem(spacerItem, 1, 0, 1, 1) # init messageBar instance self.infoBar = QgsMessageBar(self.info) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.infoBar.setSizePolicy(sizePolicy) self.layout.addWidget(self.infoBar, 0, 0, 1, 1) # create database tree self.dock = QDockWidget("Tree", self) self.dock.setObjectName("DB_Manager_DBView") self.dock.setFeatures(QDockWidget.DockWidgetMovable) self.tree = DBTree(self) self.dock.setWidget(self.tree) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock) # create status bar self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) # create menus self.menuBar = QMenuBar(self) self.menuDb = QMenu(self.tr("&Database"), self) self.menuBar.addMenu(self.menuDb) self.menuSchema = QMenu(self.tr("&Schema"), self) actionMenuSchema = self.menuBar.addMenu(self.menuSchema) self.menuTable = QMenu(self.tr("&Table"), self) actionMenuTable = self.menuBar.addMenu(self.menuTable) self.menuHelp = None # QMenu(self.tr("&Help"), self) # actionMenuHelp = self.menuBar.addMenu(self.menuHelp) self.setMenuBar(self.menuBar) # create toolbar self.toolBar = QToolBar("Default", self) self.toolBar.setObjectName("DB_Manager_ToolBar") self.addToolBar(self.toolBar) # create menus' actions # menu DATABASE sep = self.menuDb.addSeparator() sep.setObjectName("DB_Manager_DbMenu_placeholder") sep.setVisible(False) self.actionRefresh = self.menuDb.addAction(QIcon(":/db_manager/actions/refresh"), self.tr("&Refresh"), self.refreshActionSlot, QKeySequence("F5")) self.actionSqlWindow = self.menuDb.addAction(QIcon(":/db_manager/actions/sql_window"), self.tr("&SQL window"), self.runSqlWindow, QKeySequence("F2")) self.menuDb.addSeparator() self.actionClose = self.menuDb.addAction(QIcon(), self.tr("&Exit"), self.close, QKeySequence("CTRL+Q")) # menu SCHEMA sep = self.menuSchema.addSeparator() sep.setObjectName("DB_Manager_SchemaMenu_placeholder") sep.setVisible(False) actionMenuSchema.setVisible(False) # menu TABLE sep = self.menuTable.addSeparator() sep.setObjectName("DB_Manager_TableMenu_placeholder") sep.setVisible(False) self.actionImport = self.menuTable.addAction(QIcon(":/db_manager/actions/import"), self.tr("&Import layer/file"), self.importActionSlot) self.actionExport = self.menuTable.addAction(QIcon(":/db_manager/actions/export"), self.tr("&Export to file"), self.exportActionSlot) self.menuTable.addSeparator() #self.actionShowSystemTables = self.menuTable.addAction(self.tr("Show system tables/views"), self.showSystemTables) #self.actionShowSystemTables.setCheckable(True) #self.actionShowSystemTables.setChecked(True) actionMenuTable.setVisible(False) # add actions to the toolbar self.toolBar.addAction(self.actionRefresh) self.toolBar.addAction(self.actionSqlWindow) self.toolBar.addAction(self.actionImport) self.toolBar.addAction(self.actionExport)
def __init__(self, parent=None): super(FeatureFormWidget, self).__init__(parent) self.setupUi(self) utils.install_touch_scroll(self.scrollArea) toolbar = QToolBar() size = QSize(48, 48) toolbar.setIconSize(size) style = Qt.ToolButtonTextUnderIcon toolbar.setToolButtonStyle(style) self.actionDelete = toolbar.addAction(QIcon(":/icons/delete"), "Delete") self.actionDelete.triggered.connect(self.delete_feature) label = '<b style="color:red">*</b> Required fields' self.missingfieldsLabel = QLabel(label) self.missingfieldsLabel.hide() self.missingfieldaction = toolbar.addWidget(self.missingfieldsLabel) titlespacer = QWidget() titlespacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(titlespacer) self.titlellabel = QLabel(label) self.titlellabel.setProperty("headerlabel", True) self.titlelabelaction = toolbar.addWidget(self.titlellabel) spacer = QWidget() spacer2 = QWidget() spacer2.setMinimumWidth(40) spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) spacer2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) toolbar.addWidget(spacer) self.actionCancel = toolbar.addAction(QIcon(":/icons/cancel"), "Cancel") toolbar.addWidget(spacer2) self.actionSave = toolbar.addAction(QIcon(":/icons/save"), "Save") self.actionSave.triggered.connect(self.save_feature) self.layout().setContentsMargins(0, 3, 0, 3) self.layout().insertWidget(0, toolbar) self.actiontoolbar = QToolBar() self.actiontoolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.actiontoolbar.addWidget(spacer) self.layout().insertWidget(1, self.actiontoolbar) self.featureform = None self.values = {} self.config = {} self.feature = None
class FeatureFormWidget(Ui_Form, QWidget): # Raise the cancel event, takes a reason and a level canceled = pyqtSignal(str, int) featuresaved = pyqtSignal() featuredeleted = pyqtSignal() def __init__(self, parent=None): super(FeatureFormWidget, self).__init__(parent) self.setupUi(self) utils.install_touch_scroll(self.scrollArea) toolbar = QToolBar() size = QSize(48, 48) toolbar.setIconSize(size) style = Qt.ToolButtonTextUnderIcon toolbar.setToolButtonStyle(style) self.actionDelete = toolbar.addAction(QIcon(":/icons/delete"), "Delete") self.actionDelete.triggered.connect(self.delete_feature) label = '<b style="color:red">*</b> Required fields' self.missingfieldsLabel = QLabel(label) self.missingfieldsLabel.hide() self.missingfieldaction = toolbar.addWidget(self.missingfieldsLabel) titlespacer = QWidget() titlespacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar.addWidget(titlespacer) self.titlellabel = QLabel(label) self.titlellabel.setProperty("headerlabel", True) self.titlelabelaction = toolbar.addWidget(self.titlellabel) spacer = QWidget() spacer2 = QWidget() spacer2.setMinimumWidth(40) spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) spacer2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) toolbar.addWidget(spacer) self.actionCancel = toolbar.addAction(QIcon(":/icons/cancel"), "Cancel") toolbar.addWidget(spacer2) self.actionSave = toolbar.addAction(QIcon(":/icons/save"), "Save") self.actionSave.triggered.connect(self.save_feature) self.layout().setContentsMargins(0, 3, 0, 3) self.layout().insertWidget(0, toolbar) self.actiontoolbar = QToolBar() self.actiontoolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.actiontoolbar.addWidget(spacer) self.layout().insertWidget(1, self.actiontoolbar) self.featureform = None self.values = {} self.config = {} self.feature = None def set_featureform(self, featureform): """ Note: There can only be one feature form. If you need to show another one make a new FeatureFormWidget """ self.featureform = featureform self.titlellabel.setText(self.featureform.windowTitle()) self.featureform.formvalidation.connect(self._update_validation) self.featureform.helprequest.connect( functools.partial(RoamEvents.helprequest.emit, self)) self.featureform.showlargewidget.connect(RoamEvents.show_widget.emit) self.featureform.enablesave.connect(self.actionSave.setEnabled) self.featureform.enablesave.connect(self.actionSave.setVisible) self.featureform.rejected.connect(self.canceled.emit) self.featureform.accepted.connect(self.featuresaved) actions = self.featureform.form_actions() if actions: for action in actions: self.actiontoolbar.addAction(action) else: self.actiontoolbar.hide() self.featureform.setContentsMargins(0, 0, 0, 0) self.featureformarea.layout().addWidget(self.featureform) def delete_feature(self): try: msg = self.featureform.deletemessage except AttributeError: msg = 'Do you really want to delete this feature?' box = DeleteFeatureDialog(msg) if not box.exec_(): return try: self.featureform.delete() except featureform.DeleteFeatureException as ex: RoamEvents.raisemessage(*ex.error) self.featureform.featuredeleted(self.feature) self.featuredeleted.emit() def feature_saved(self): self.featuresaved.emit() RoamEvents.featuresaved.emit() def save_feature(self): try: self.featureform.save() except featureform.MissingValuesException as ex: RoamEvents.raisemessage(*ex.error) return except featureform.FeatureSaveException as ex: RoamEvents.raisemessage(*ex.error) self.feature_saved() def set_config(self, config): self.config = config editmode = config['editmode'] allowsave = config.get('allowsave', True) self.feature = config.get('feature', None) tools = config.get('tools', []) candelete = True if tools: candelete = "delete" in tools self.featureform.feature = self.feature self.featureform.editingmode = editmode self.actionDelete.setVisible(editmode and candelete) self.actionSave.setEnabled(allowsave) def _update_validation(self, passed): # Show the error if there is missing fields self.missingfieldaction.setVisible(not passed) def bind_values(self, values): self.values = values self.featureform.bindvalues(values) def after_load(self): self.featureform.loaded() def before_load(self): self.featureform.load(self.config['feature'], self.config['layers'], self.values)
def __init__(self, iface): locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(os.path.dirname(__file__), 'i18n', 'annotationManager_{}.qm'.format(locale)) self.translator = None if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.iface = iface self.iface.projectRead.connect(self.projectOpen) self.dock = QDockWidget(self.tr('Annotations')) self.manager = QWidget() toolbar = QToolBar() self.annotationList = QListWidget() self.annotationList.setSelectionMode( QAbstractItemView.ExtendedSelection) self.annotationList.itemSelectionChanged.connect(self.selectAnnotation) self.annotationList.itemChanged.connect(self.checkItem) action_refresh = QAction( QIcon(':/plugins/annotationManager/resources/mActionDraw.png'), self.tr('Refresh the annotations list'), self.manager) action_refresh.triggered.connect(self.refreshAnnotations) action_remove = QAction( QIcon( ':/plugins/annotationManager/resources/mActionRemoveAnnotation.png' ), self.tr('Remove the selected annotation'), self.manager) action_remove.triggered.connect(self.removeAnnotation) viewMenu = QMenu() action_showAll = QAction( QIcon(':/plugins/annotationManager/resources/mActionShowAll.png'), self.tr('Show all annotations'), self.manager) action_showAll.triggered.connect(self.showAll) action_hideAll = QAction( QIcon(':/plugins/annotationManager/resources/mActionHideAll.png'), self.tr('Hide all annotations'), self.manager) action_hideAll.triggered.connect(self.hideAll) action_showAllSelected = QAction( QIcon(':/plugins/annotationManager/resources/mActionShowAll.png'), self.tr('Show all selected annotations'), self.manager) action_showAllSelected.triggered.connect(self.showAllSelected) action_hideAllSelected = QAction( QIcon(':/plugins/annotationManager/resources/mActionHideAll.png'), self.tr('Hide all selected annotations'), self.manager) action_hideAllSelected.triggered.connect(self.hideAllSelected) viewMenu.addAction(action_showAll) viewMenu.addAction(action_hideAll) viewMenu.addAction(action_showAllSelected) viewMenu.addAction(action_hideAllSelected) viewButton = QToolButton() viewButton.setIcon( QIcon(':/plugins/annotationManager/resources/mActionShowAll.png')) viewButton.setPopupMode(2) viewButton.setMenu(viewMenu) toolbar.addAction(action_refresh) toolbar.addAction(action_remove) toolbar.addWidget(viewButton) toolbar.setIconSize(QSize(16, 16)) p1_vertical = QVBoxLayout() p1_vertical.setContentsMargins(0, 0, 0, 0) p1_vertical.addWidget(toolbar) p1_vertical.addWidget(self.annotationList) self.manager.setLayout(p1_vertical) self.dock.setWidget(self.manager) self.dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dock) self.rb = QgsRubberBand(self.iface.mapCanvas(), QgsWkbTypes.PolygonGeometry) self.project = QgsProject.instance() self.annotationManager = self.project.annotationManager() self.annotationManager.annotationAdded.connect(self.refreshAnnotations) self.annotationManager.annotationRemoved.connect( self.refreshAnnotations)
class MainApp(QDockWidget, QMainWindow, Ui_MainApp): # signals goBack = pyqtSignal() searchOpsubByName = pyqtSignal(str) enableSearch = pyqtSignal(bool) refreshLegend = pyqtSignal(QgsMapLayer) ogrDatasourceLoaded = pyqtSignal(bool) class VfkLayer(object): Par = 0 Bud = 1 def __init__(self, iface): QDockWidget.__init__(self, iface.mainWindow()) self.setupUi(self) self.iface = iface # variables self.__mLastVfkFile = [] self.__mOgrDataSource = None self.__mDataSourceName = '' self.__fileName = [] self.__mLoadedLayers = {} self.__mDefaultPalette = self.vfkFileLineEdit.palette() # new lineEdits variables self.lineEditsCount = 1 self.__browseButtons = {} self.__vfkLineEdits = {} # data will be load from source according to checked radiobox self.__source_for_data = 'file' # apply changes into main database self.__databases = {} # self.pb_applyChanges.setEnabled(False) self.changes_instance = ApplyChanges() # Connect ui with functions self.__createToolbarsAndConnect() # check GDAL version self.__gdal_version = int(gdal.VersionInfo()) if self.__gdal_version < 2020000: self.actionZpracujZmeny.setEnabled(False) self.pb_nextFile.setEnabled(False) self.pb_nextFile.setToolTip( u'Není možné načíst více souborů, verze GDAL je nižší než 2.2.0.' ) self.actionZpracujZmeny.setToolTip( u'Zpracování změn není povoleno, verze GDAL je nižší než 2.2.0.' ) self.groupBox.setEnabled(False) # settings self.loadVfkButton.setDisabled(True) self.searchFormMainControls = SearchFormController.MainControls() self.searchFormMainControls.formCombobox = self.searchCombo self.searchFormMainControls.searchForms = self.searchForms self.searchFormMainControls.searchButton = self.searchButton self.searchForms = SearchFormController.SearchForms() self.searchForms.vlastnici = self.vlastniciSearchForm self.searchForms.parcely = self.parcelySearchForm self.searchForms.budovy = self.budovySearchForm self.searchForms.jednotky = self.jednotkySearchForm # search form controller self.__mSearchController = SearchFormController( self.searchFormMainControls, self.searchForms, self) self.__mSearchController.actionTriggered.connect( self.vfkBrowser.processAction) self.enableSearch.connect(self.searchButton.setEnabled) self.vfkBrowser.showParcely.connect(self.showParInMap) self.vfkBrowser.showBudovy.connect(self.showBudInMap) # connect lineEdits and returnPressed action self.vfkFileLineEdit.returnPressed.connect(self.loadVfkButton_clicked) self.vlastniciSearchForm.ui.jmenoLineEdit.returnPressed.connect( self.__mSearchController.search) self.vlastniciSearchForm.ui.rcIcoLineEdit.returnPressed.connect( self.__mSearchController.search) self.vlastniciSearchForm.ui.lvVlastniciLineEdit.returnPressed.connect( self.__mSearchController.search) self.parcelySearchForm.ui.parCisloLineEdit.returnPressed.connect( self.__mSearchController.search) self.parcelySearchForm.ui.lvParcelyLineEdit.returnPressed.connect( self.__mSearchController.search) self.budovySearchForm.ui.cisloDomovniLineEdit.returnPressed.connect( self.__mSearchController.search) self.budovySearchForm.ui.naParceleLineEdit.returnPressed.connect( self.__mSearchController.search) self.budovySearchForm.ui.lvBudovyLineEdit.returnPressed.connect( self.__mSearchController.search) self.jednotkySearchForm.ui.mCisloJednotkyLineEdit.returnPressed.connect( self.__mSearchController.search) self.jednotkySearchForm.ui.mCisloDomovniLineEdit.returnPressed.connect( self.__mSearchController.search) self.jednotkySearchForm.ui.mNaParceleLineEdit.returnPressed.connect( self.__mSearchController.search) self.jednotkySearchForm.ui.mLvJednotkyLineEdit.returnPressed.connect( self.__mSearchController.search) self.vfkBrowser.showHelpPage() # settings self.settings = QtCore.QSettings() def browseButton_clicked(self, browseButton_id=1): """ :param browseButton_id: ID of clicked browse button. :return: """ sender = '{}-lastUsedDir'.format(self.sender().objectName()) lastUsedDir = self.settings.value(sender, '') if self.__source_for_data == 'file': ext = '*.vfk' if self.__gdal_version >= 2020000: ext += ' *.db' loaded_file, __ = QFileDialog.getOpenFileName( self, u'Načti soubor VFK', lastUsedDir, u'Soubory podporované ovladačem VFK GDAL ({})'.format(ext)) if not loaded_file: return self.__fileName.append(loaded_file) if browseButton_id == 1: self.vfkFileLineEdit.setText(self.__fileName[0]) else: self.__vfkLineEdits['vfkL1ineEdit_{}'.format( len(self.__vfkLineEdits))].setText( self.__fileName[browseButton_id - 1]) self.settings.setValue(sender, os.path.dirname(loaded_file)) elif self.__source_for_data == 'directory': loaded_file = QFileDialog.getExistingDirectory( self, u"Vyberte adresář s daty VFK", lastUsedDir) if not loaded_file: return self.__fileName = [] self.__fileName.append(loaded_file) self.vfkFileLineEdit.setText(self.__fileName[0]) self.settings.setValue(sender, loaded_file) else: iface.messageBar().pushWarning(u'ERROR', u'Not valid data source') self.loadVfkButton.setEnabled(True) def browserGoBack(self): self.vfkBrowser.goBack() def browserGoForward(self): self.vfkBrowser.goForth() def selectParInMap(self): self.showInMap(self.vfkBrowser.currentParIds(), "PAR") def selectBudInMap(self): self.showInMap(self.vfkBrowser.currentBudIds(), "BUD") def latexExport(self): fileName, __ = QFileDialog.getSaveFileName( self, u"Jméno exportovaného souboru", ".tex", "LaTeX (*.tex)") if fileName: export_succesfull = self.vfkBrowser.exportDocument( self.vfkBrowser.currentUrl(), fileName, self.vfkBrowser.ExportFormat.Latex) if export_succesfull: self.succesfullExport("LaTeX") def htmlExport(self): fileName, __ = QFileDialog.getSaveFileName( self, u"Jméno exportovaného souboru", ".html", "HTML (*.html)") if fileName: export_succesfull = self.vfkBrowser.exportDocument( self.vfkBrowser.currentUrl(), fileName, self.vfkBrowser.ExportFormat.Html) if export_succesfull: self.succesfullExport("HTML") def setSelectionChangedConnected(self, connected): """ :type connected: bool :return: """ for layer in self.__mLoadedLayers: id = self.__mLoadedLayers[layer] vectorLayer = QgsProject.instance().mapLayer(id) if connected: vectorLayer.selectionChanged.connect( self.showInfoAboutSelection) else: vectorLayer.selectionChanged.disconnect( self.showInfoAboutSelection) def showInMap(self, ids, layerName): """ :type ids: list :type layerName: str :return: """ if layerName in self.__mLoadedLayers: id = self.__mLoadedLayers[layerName] vectorLayer = QgsProject.instance().mapLayer(id) searchString = "ID IN ({})".format(", ".join(ids)) error = '' fIds = self.__search(vectorLayer, searchString, error) if error: iface.messageBar().pushWarning( u'ERROR', u'In showInMap: {}'.format(error)) return else: vectorLayer.setSelectedFeatures(fIds) def __search(self, layer, searchString, error): """ :type layer: QgsVectorLayer :type searchString: str :type error: str :return: """ # parse search string and build parsed tree search = QgsExpression(searchString) rect = QgsRectangle() fIds = [] if search.hasParserError(): error += "Parsing error:" + search.parserErrorString() return fIds if not search.prepare(layer.fields()): error + "Evaluation error:" + search.evalErrorString() layer.select(rect, False) fit = QgsFeatureIterator(layer.getFeatures()) f = QgsFeature() while fit.nextFeature(f): if search.evaluate(f): fIds.append(f.id()) # check if there were errors during evaluating if search.hasEvalError(): iface.messageBar().pushWarning( u'ERROR', u'Evaluate error: {}'.format(error)) break return fIds def loadVfkButton_clicked(self): """ After click method starts loading all inserted files """ # check the source of data if self.__source_for_data == 'directory': dir_path = self.__fileName[0] self.__fileName = self.__findVFKFilesInDirectory(dir_path) # check if first file is amendment amendment_file = self.__checkIfAmendmentFile(self.__fileName[0]) # prepare name for database if amendment_file: new_database_name = '{}_zmeny.db'.format( os.path.basename(self.__fileName[0]).split('.')[0]) else: new_database_name = '{}_stav.db'.format( os.path.basename(self.__fileName[0]).split('.')[0]) gdal.SetConfigOption( 'OGR_VFK_DB_NAME', str( os.path.join(os.path.dirname(self.__fileName[0]), new_database_name))) self.__mDataSourceName = self.__fileName[0] QgsApplication.processEvents() self.importThread = OpenThread(self.__fileName) self.importThread.working.connect(self.runLoadingLayer) if not self.importThread.isRunning(): self.importThread.start() def runLoadingLayer(self, fileName): """ :return: """ if fileName not in self.__mLastVfkFile: self.labelLoading.setText( u'Načítám data do SQLite databáze (může nějaký čas trvat...)') try: self.loadVfkFile(fileName) except VFKError as e: QMessageBox.critical(self, u'Chyba', u'{}'.format(e), QMessageBox.Ok) self.enableSearch.emit(False) return self.__mLastVfkFile.append(fileName) self.importThread.nextLayer = False if fileName == self.__fileName[-1]: self.loadingLayersFinished() def loadingLayersFinished(self): """ :return: """ try: self.__openDatabase(gdal.GetConfigOption('OGR_VFK_DB_NAME')) except VFKError as e: QMessageBox.critical(self, u'Chyba', u'{}'.format(e), QMessageBox.Ok) self.enableSearch.emit(False) return self.vfkBrowser.setConnectionName(self.property("connectionName")) self.__mSearchController.setConnectionName( self.property("connectionName")) self.enableSearch.emit(True) self.__mLoadedLayers.clear() if self.parCheckBox.isChecked(): self.__loadVfkLayer('PAR') else: self.__unLoadVfkLayer('PAR') if self.budCheckBox.isChecked(): self.__loadVfkLayer('BUD') else: self.__unLoadVfkLayer('BUD') self.labelLoading.setText(u'Načítání souborů VFK bylo dokončeno.') def vfkFileLineEdit_textChanged(self, arg1): """ :type arg1: str :return: """ info = QFileInfo(arg1) if info.isFile(): self.loadVfkButton.setEnabled(True) self.vfkFileLineEdit.setPalette(self.__mDefaultPalette) else: self.loadVfkButton.setEnabled(False) pal = QPalette(self.vfkFileLineEdit.palette()) pal.setColor(QPalette.text(), Qt.red) self.vfkFileLineEdit.setPalette(pal) def __loadVfkLayer(self, vfkLayerName): """ :type vfkLayerName: str :return: """ # QgsMessageLog.logMessage(u"(VFK) Loading vfk layer {}".format(vfkLayerName)) if vfkLayerName in self.__mLoadedLayers: # QgsMessageLog.logMessage( # "(VFK) Vfk layer {} is already loaded".format(vfkLayerName) # ) return composedURI = self.__mDataSourceName + "|layername=" + vfkLayerName layer = QgsVectorLayer(composedURI, vfkLayerName, "ogr") if not layer.isValid(): iface.messageBar().pushWarning(u'ERROR', u"Layer failed to load!") self.__mLoadedLayers[vfkLayerName] = layer.id() try: self.__setSymbology(layer) except VFKWarning as e: QMessageBox.information(self, 'Load Style', e, QMessageBox.Ok) QgsProject.instance().addMapLayer(layer) def __unLoadVfkLayer(self, vfkLayerName): """ :type vfkLayerName: str :return: """ # QgsMessageLog.logMessage("(VFK) Unloading vfk layer {}".format(vfkLayerName)) if vfkLayerName not in self.__mLoadedLayers: # QgsMessageLog.logMessage( # "(VFK) Vfk layer {} is already unloaded".format(vfkLayerName) # ) return QgsProject.instance().removeMapLayer( self.__mLoadedLayers[vfkLayerName]) del self.__mLoadedLayers[vfkLayerName] def __setSymbology(self, layer): """ :type layer: QgsVectorLayer :return: """ name = layer.name() symbologyFile = '' if name == 'PAR': symbologyFile = ':/parStyle.qml' elif name == 'BUD': symbologyFile = ':/budStyle.qml' errorMsg, resultFlag = layer.loadNamedStyle(symbologyFile) if not resultFlag: raise VFKWarning(u'Load style: {}'.format(errorMsg)) layer.triggerRepaint() self.refreshLegend.emit(layer) def __openDatabase(self, dbPath): """ :type dbPath: str :return: """ # QgsMessageLog.logMessage("(VFK) Open DB: {}".format(dbPath)) if not QSqlDatabase.isDriverAvailable('QSQLITE'): raise VFKError(u'Databázový ovladač QSQLITE není dostupný.') connectionName = QUuid.createUuid().toString() db = QSqlDatabase.addDatabase("QSQLITE", connectionName) db.setDatabaseName(dbPath) if not db.open(): raise VFKError(u'Nepodařilo se otevřít databázi. ') self.setProperty("connectionName", connectionName) def loadVfkFile(self, fileName): """ :type fileName: str :return: """ label_text = fileName.split('/') label_text = '...' + label_text[-2] + '/' + label_text[-1] # overwrite database if fileName == self.__fileName[0]: if self.overwriteCheckBox.isChecked(): # QgsMessageLog.logMessage(u'(VFK) Database will be overwritten') gdal.SetConfigOption('OGR_VFK_DB_OVERWRITE', 'YES') if self.__mOgrDataSource: self.__mOgrDataSource.Destroy() self.__mOgrDataSource = None QgsApplication.registerOgrDrivers() self.progressBar.setRange(0, 1) self.progressBar.setValue(0) QgsApplication.processEvents() self.labelLoading.setText( u'Načítám soubor {} (může nějaký čas trvat...)'.format(label_text)) QgsApplication.processEvents() self.__mOgrDataSource = ogr.Open( fileName, 0) # 0 - datasource is open in read-only mode if not self.__mOgrDataSource: raise VFKError( u"Nelze otevřít VFK soubor '{}' jako platný OGR datasource.". format(fileName)) layerCount = self.__mOgrDataSource.GetLayerCount() layers_names = [] for i in range(layerCount): layers_names.append( self.__mOgrDataSource.GetLayer(i).GetLayerDefn().GetName()) if ('PAR' not in layers_names or 'BUD' not in layers_names) and len( self.__vfkLineEdits) == 1: self.__dataWithoutParBud() self.labelLoading.setText( u'Data nemohla být načtena. Vstupní soubor neobsahuje bloky PAR a BUD.' ) QgsApplication.processEvents() return # load all layers self.progressBar.setRange(0, layerCount - 1) for i in range(layerCount): self.progressBar.setValue(i) theLayerName = self.__mOgrDataSource.GetLayer( i).GetLayerDefn().GetName() self.labelLoading.setText(u"VFK data {}/{}: {}".format( i + 1, layerCount, theLayerName)) QgsApplication.processEvents() self.__mOgrDataSource.GetLayer(i).GetFeatureCount(True) time.sleep(0.02) self.labelLoading.setText( u'Soubor {} úspěšně načten.'.format(label_text)) gdal.SetConfigOption('OGR_VFK_DB_OVERWRITE', 'NO') self.__mOgrDataSource.Destroy() self.__mOgrDataSource = None def __selectedIds(self, layer): """ :type layer: QgsVectorLayer :return: """ ids = [] flist = layer.selectedFeatures() for it in flist: f = QgsFeature(it) ids.append(str(f.attribute("ID"))) return ids def showInfoAboutSelection(self): layers = ["PAR", "BUD"] layerIds = {} for layer in layers: if layer in self.__mLoadedLayers: id = str(self.__mLoadedLayers[layer]) vectorLayer = QgsProject.instance().mapLayer(id) layerIds[layer] = self.__selectedIds(vectorLayer) self.vfkBrowser.showInfoAboutSelection(layerIds["PAR"], layerIds["BUD"]) def showParInMap(self, ids): """ :type ids: list :return: """ if self.actionShowInfoaboutSelection.isChecked(): self.setSelectionChangedConnected(False) self.showInMap(ids, "PAR") self.setSelectionChangedConnected(True) else: self.showInMap(ids, "PAR") def showBudInMap(self, ids): """ :type ids: list :return: """ if self.actionShowInfoaboutSelection.isChecked(): self.setSelectionChangedConnected(False) self.showInMap(ids, "BUD") self.setSelectionChangedConnected(True) else: self.showInMap(ids, "BUD") def showOnCuzk(self): x = self.vfkBrowser.currentDefinitionPoint().first.split(".")[0] y = self.vfkBrowser.currentDefinitionPoint().second.split(".")[0] url = "http://nahlizenidokn.cuzk.cz/MapaIdentifikace.aspx?&x=-{}&y=-{}".format( y, x) QDesktopServices.openUrl(QUrl(url, QUrl.TolerantMode)) def switchToImport(self): self.actionImport.trigger() def switchToSearch(self, searchType): """ :type searchType: int """ self.actionVyhledavani.trigger() self.searchCombo.setCurrentIndex(searchType) self.searchFormMainControls.searchForms.setCurrentIndex(searchType) def switchToChanges(self): """ """ self.actionZpracujZmeny.trigger() def succesfullExport(self, export_format): """ :type export_format: str :return: """ QMessageBox.information( self, u'Export', u"Export do formátu {} proběhl úspěšně.".format(export_format), QMessageBox.Ok) def __dataWithoutParBud(self): """ :type export_format: str :return: """ QMessageBox.warning( self, u'Upozornění', u"Zvolený VFK soubor neobsahuje vrstvy s geometrií (PAR, BUD), proto nemohou " u"být pomocí VFK Pluginu načtena. Data je možné načíst v QGIS pomocí volby " u"'Načíst vektorovou vrstvu.'", QMessageBox.Ok) def __addRowToGridLayout(self): if len(self.__vfkLineEdits) >= 5: self.__maximumLineEditsReached() return # update label self.label.setText('VFK soubory:') # new layout horizontalLayout = QtWidgets.QHBoxLayout() # create new objects self.__browseButtons['browseButton_{}'.format( len(self.__vfkLineEdits) + 1)] = QtWidgets.QPushButton(u"Procházet") self.__vfkLineEdits['vfkLineEdit_{}'.format( len(self.__vfkLineEdits) + 1)] = QtWidgets.QLineEdit() horizontalLayout.addWidget(self.__vfkLineEdits['vfkLineEdit_{}'.format( len(self.__vfkLineEdits))]) horizontalLayout.addWidget( self.__browseButtons['browseButton_{}'.format( len(self.__vfkLineEdits))]) # number of lines in gridLayout rows_count = self.gridLayout_12.rowCount( ) # count of rows in gridLayout # export objects from gridLayout item_label = self.gridLayout_12.itemAtPosition(rows_count - 3, 0) item_par = self.gridLayout_12.itemAtPosition(rows_count - 3, 1) item_bud = self.gridLayout_12.itemAtPosition(rows_count - 2, 1) item_settings = self.gridLayout_12.itemAtPosition(rows_count - 1, 0) item_rewrite_db = self.gridLayout_12.itemAtPosition(rows_count - 1, 1) # remove objects from gridLayout self.gridLayout_12.removeItem( self.gridLayout_12.itemAtPosition(rows_count - 3, 0)) self.gridLayout_12.removeItem( self.gridLayout_12.itemAtPosition(rows_count - 3, 1)) self.gridLayout_12.removeItem( self.gridLayout_12.itemAtPosition(rows_count - 2, 1)) self.gridLayout_12.removeItem( self.gridLayout_12.itemAtPosition(rows_count - 1, 0)) self.gridLayout_12.removeItem( self.gridLayout_12.itemAtPosition(rows_count - 1, 1)) # re-build gridLayout self.gridLayout_12.addLayout(horizontalLayout, rows_count - 3, 1) self.gridLayout_12.addItem(item_label, rows_count - 2, 0) self.gridLayout_12.addItem(item_par, rows_count - 2, 1) self.gridLayout_12.addItem(item_bud, rows_count - 1, 1) self.gridLayout_12.addItem(item_settings, rows_count, 0) self.gridLayout_12.addItem(item_rewrite_db, rows_count, 1) self.__browseButtons['browseButton_{}'.format(len(self.__vfkLineEdits))].clicked.\ connect(lambda: self.browseButton_clicked( int('{}'.format(len(self.__vfkLineEdits))))) def __maximumLineEditsReached(self): QMessageBox.information( self, u'Upozornění', u"Byl dosažen maximální počet ({}) VFK souboru pro zpracování." u"\nNačítání dalších souborů není povoleno!".format( self.lineEditsCount), QMessageBox.Ok) def browseDb_clicked(self, database_type): """ Method run dialog for select database in widget with changes. According to pushButton name will fill in relevant lineEdit. :type database_type: str """ title = u'Vyber databázi' settings = QSettings() lastUsedDir = str( settings.value('/UI/' + "lastVectorFileFilter" + "Dir", ".")) if database_type == 'mainDb': self.__databases[database_type] = QFileDialog.getOpenFileName( self, title, lastUsedDir, u'Datábaze (*.db)') if not self.__databases[database_type]: return self.le_mainDb.setText(str(self.__databases[database_type])) elif database_type == 'amendmentDb': self.__databases[database_type] = QFileDialog.getOpenFileName( self, title, lastUsedDir, u'Datábaze (*.db)') if not self.__databases[database_type]: return self.le_amendmentDb.setText(str(self.__databases[database_type])) elif database_type == 'exportDb': title = u'Zadej jméno výstupní databáze' self.__databases[database_type] = QFileDialog.getSaveFileName( self, u"Jméno výstupní databáze", ".db", u"Databáze (*.db)") if not self.__databases[database_type]: return self.le_exportDb.setText(str(self.__databases[database_type])) if len(self.__databases) == 3: self.pb_applyChanges.setEnabled(True) def applyChanges(self): """ Method :return: """ self.changes_instance.run(self.__databases['mainDb'], self.__databases['amendmentDb'], self.__databases['exportDb']) def __updateProgressBarChanges(self, iteration, table_name): """ :type iteration: int :type table_name: str """ self.progressBar_changes.setValue(iteration) self.l_status.setText( u'Aplikuji změny na tabulku {}...'.format(table_name)) QgsApplication.processEvents() def __setRangeProgressBarChanges(self, max_range): """ :type max_range: int """ self.progressBar_changes.setRange(0, max_range) self.progressBar_changes.setValue(0) def __changesApplied(self): """ """ time.sleep(1) self.l_status.setText(u'Změny byly úspěšně aplikovány.') QgsApplication.processEvents() def __changesPreprocessingDatabase(self): """ """ self.l_status.setText(u'Připravuji výstupní databázi...') QgsApplication.processEvents() def __checkIfAmendmentFile(self, file_name): """ :param file_name: Name of the input file :type file_name: str :return: bool """ if file_name.endswith(".vfk"): with open(file_name, 'rb') as f: for line in f: line_splited = str(line).split(';') if line_splited[0] == '&HZMENY': if line_splited[1] == '1': return True else: return False else: # fix_print_with_import print('database') # TODO: dopsat kontrolu, zda se jedna o stavovou, nebo zmenovou databazi def radioButtonValue(self): """ Check which radio button is checked """ self.vfkFileLineEdit.setText('') self.__fileName = [] self.loadVfkButton.setEnabled(False) if self.rb_file.isChecked(): self.__source_for_data = 'file' self.pb_nextFile.show() self.label.setText('VFK soubor:') elif self.rb_directory.isChecked(): self.__source_for_data = 'directory' self.pb_nextFile.hide() self.label.setText(u'Adresář:') # delete if len(self.__browseButtons) > 1: for i, button in enumerate(self.__browseButtons): if i > 0: self.__browseButtons[button].hide() if len(self.__vfkLineEdits) > 1: for i, le in enumerate(self.__vfkLineEdits): if i > 0: self.__vfkLineEdits[le].hide() def __findVFKFilesInDirectory(self, dir_path): """ Finds all files with extension '.vfk' in given directory including subdirectories :param dir_path: Path to directory. :type dir_path: str :return: List of VFK files """ file_paths = [] for root, dirs, files in os.walk(dir_path): for file in files: if file.endswith(".vfk"): file_paths.append(os.path.join(root, file)) return file_paths def __createToolbarsAndConnect(self): actionGroup = QActionGroup(self) actionGroup.addAction(self.actionImport) actionGroup.addAction(self.actionVyhledavani) actionGroup.addAction(self.actionZpracujZmeny) # QSignalMapper self.signalMapper = QtCore.QSignalMapper(self) self.actionImport.triggered.connect(self.signalMapper.map) self.actionVyhledavani.triggered.connect(self.signalMapper.map) self.actionZpracujZmeny.triggered.connect(self.signalMapper.map) # setMapping on each button to the QStackedWidget index we'd like to # switch to self.signalMapper.setMapping(self.actionImport, 0) self.signalMapper.setMapping(self.actionVyhledavani, 2) self.signalMapper.setMapping(self.actionZpracujZmeny, 1) # connect mapper to stackedWidget self.signalMapper.mapped.connect(self.stackedWidget.setCurrentIndex) self.vfkBrowser.switchToPanelImport.connect(self.switchToImport) self.vfkBrowser.switchToPanelSearch.connect(self.switchToSearch) self.vfkBrowser.switchToPanelChanges.connect(self.switchToChanges) # Browser toolbar # --------------- self.__mBrowserToolbar = QToolBar(self) self.actionBack.triggered.connect(self.vfkBrowser.goBack) self.actionForward.triggered.connect(self.vfkBrowser.goForth) self.actionSelectBudInMap.triggered.connect(self.selectBudInMap) self.actionSelectParInMap.triggered.connect(self.selectParInMap) self.actionCuzkPage.triggered.connect(self.showOnCuzk) self.actionExportLatex.triggered.connect(self.latexExport) self.actionExportHtml.triggered.connect(self.htmlExport) self.actionShowInfoaboutSelection.toggled.connect( self.setSelectionChangedConnected) self.actionShowHelpPage.triggered.connect(self.vfkBrowser.showHelpPage) self.loadVfkButton.clicked.connect(self.loadVfkButton_clicked) self.__browseButtons['browseButton_1'] = self.browseButton self.__browseButtons['browseButton_1'].clicked.connect( lambda: self.browseButton_clicked( int('{}'.format(len(self.__vfkLineEdits))))) self.__vfkLineEdits['vfkLineEdit_1'] = self.vfkFileLineEdit bt = QToolButton(self.__mBrowserToolbar) bt.setPopupMode(QToolButton.InstantPopup) bt.setText("Export ") menu = QMenu(bt) menu.addAction(self.actionExportLatex) menu.addAction(self.actionExportHtml) bt.setMenu(menu) # add actions to toolbar icons self.__mBrowserToolbar.addAction(self.actionImport) self.__mBrowserToolbar.addAction(self.actionVyhledavani) self.__mBrowserToolbar.addAction(self.actionZpracujZmeny) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addAction(self.actionBack) self.__mBrowserToolbar.addAction(self.actionForward) self.__mBrowserToolbar.addAction(self.actionSelectParInMap) self.__mBrowserToolbar.addAction(self.actionSelectBudInMap) self.__mBrowserToolbar.addAction(self.actionCuzkPage) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addAction(self.actionShowInfoaboutSelection) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addWidget(bt) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addAction(self.actionShowHelpPage) self.rightWidgetLayout.insertWidget(0, self.__mBrowserToolbar) # connect signals from vfkbrowser when changing history self.vfkBrowser.currentParIdsChanged.connect( self.actionSelectParInMap.setEnabled) self.vfkBrowser.currentBudIdsChanged.connect( self.actionSelectBudInMap.setEnabled) self.vfkBrowser.historyBefore.connect(self.actionBack.setEnabled) self.vfkBrowser.historyAfter.connect(self.actionForward.setEnabled) self.vfkBrowser.definitionPointAvailable.connect( self.actionCuzkPage.setEnabled) # add toolTips self.pb_nextFile.setToolTip(u'Přidej další soubor VFK') self.parCheckBox.setToolTip(u'Načti vrstvu parcel') self.budCheckBox.setToolTip(u'Načti vrstvu budov') # add new VFK file self.pb_nextFile.clicked.connect(self.__addRowToGridLayout) # widget apply changes self.pb_mainDb.clicked.connect(lambda: self.browseDb_clicked('mainDb')) self.pb_amendmentDb.clicked.connect( lambda: self.browseDb_clicked('amendmentDb')) self.pb_exportDb.clicked.connect( lambda: self.browseDb_clicked('exportDb')) self.pb_applyChanges.clicked.connect(self.applyChanges) self.pb_applyChanges.setEnabled(False) self.changes_instance.maxRangeProgressBar.connect( self.__setRangeProgressBarChanges) self.changes_instance.updateStatus.connect( self.__updateProgressBarChanges) self.changes_instance.finishedStatus.connect(self.__changesApplied) self.changes_instance.preprocessingDatabase.connect( self.__changesPreprocessingDatabase) # connect radio boxes self.rb_file.clicked.connect(self.radioButtonValue) self.rb_directory.clicked.connect(self.radioButtonValue)
def __createToolbarsAndConnect(self): actionGroup = QActionGroup(self) actionGroup.addAction(self.actionImport) actionGroup.addAction(self.actionVyhledavani) actionGroup.addAction(self.actionZpracujZmeny) # QSignalMapper self.signalMapper = QtCore.QSignalMapper(self) self.actionImport.triggered.connect(self.signalMapper.map) self.actionVyhledavani.triggered.connect(self.signalMapper.map) self.actionZpracujZmeny.triggered.connect(self.signalMapper.map) # setMapping on each button to the QStackedWidget index we'd like to # switch to self.signalMapper.setMapping(self.actionImport, 0) self.signalMapper.setMapping(self.actionVyhledavani, 2) self.signalMapper.setMapping(self.actionZpracujZmeny, 1) # connect mapper to stackedWidget self.signalMapper.mapped.connect(self.stackedWidget.setCurrentIndex) self.vfkBrowser.switchToPanelImport.connect(self.switchToImport) self.vfkBrowser.switchToPanelSearch.connect(self.switchToSearch) self.vfkBrowser.switchToPanelChanges.connect(self.switchToChanges) # Browser toolbar # --------------- self.__mBrowserToolbar = QToolBar(self) self.actionBack.triggered.connect(self.vfkBrowser.goBack) self.actionForward.triggered.connect(self.vfkBrowser.goForth) self.actionSelectBudInMap.triggered.connect(self.selectBudInMap) self.actionSelectParInMap.triggered.connect(self.selectParInMap) self.actionCuzkPage.triggered.connect(self.showOnCuzk) self.actionExportLatex.triggered.connect(self.latexExport) self.actionExportHtml.triggered.connect(self.htmlExport) self.actionShowInfoaboutSelection.toggled.connect( self.setSelectionChangedConnected) self.actionShowHelpPage.triggered.connect(self.vfkBrowser.showHelpPage) self.loadVfkButton.clicked.connect(self.loadVfkButton_clicked) self.__browseButtons['browseButton_1'] = self.browseButton self.__browseButtons['browseButton_1'].clicked.connect( lambda: self.browseButton_clicked( int('{}'.format(len(self.__vfkLineEdits))))) self.__vfkLineEdits['vfkLineEdit_1'] = self.vfkFileLineEdit bt = QToolButton(self.__mBrowserToolbar) bt.setPopupMode(QToolButton.InstantPopup) bt.setText("Export ") menu = QMenu(bt) menu.addAction(self.actionExportLatex) menu.addAction(self.actionExportHtml) bt.setMenu(menu) # add actions to toolbar icons self.__mBrowserToolbar.addAction(self.actionImport) self.__mBrowserToolbar.addAction(self.actionVyhledavani) self.__mBrowserToolbar.addAction(self.actionZpracujZmeny) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addAction(self.actionBack) self.__mBrowserToolbar.addAction(self.actionForward) self.__mBrowserToolbar.addAction(self.actionSelectParInMap) self.__mBrowserToolbar.addAction(self.actionSelectBudInMap) self.__mBrowserToolbar.addAction(self.actionCuzkPage) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addAction(self.actionShowInfoaboutSelection) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addWidget(bt) self.__mBrowserToolbar.addSeparator() self.__mBrowserToolbar.addAction(self.actionShowHelpPage) self.rightWidgetLayout.insertWidget(0, self.__mBrowserToolbar) # connect signals from vfkbrowser when changing history self.vfkBrowser.currentParIdsChanged.connect( self.actionSelectParInMap.setEnabled) self.vfkBrowser.currentBudIdsChanged.connect( self.actionSelectBudInMap.setEnabled) self.vfkBrowser.historyBefore.connect(self.actionBack.setEnabled) self.vfkBrowser.historyAfter.connect(self.actionForward.setEnabled) self.vfkBrowser.definitionPointAvailable.connect( self.actionCuzkPage.setEnabled) # add toolTips self.pb_nextFile.setToolTip(u'Přidej další soubor VFK') self.parCheckBox.setToolTip(u'Načti vrstvu parcel') self.budCheckBox.setToolTip(u'Načti vrstvu budov') # add new VFK file self.pb_nextFile.clicked.connect(self.__addRowToGridLayout) # widget apply changes self.pb_mainDb.clicked.connect(lambda: self.browseDb_clicked('mainDb')) self.pb_amendmentDb.clicked.connect( lambda: self.browseDb_clicked('amendmentDb')) self.pb_exportDb.clicked.connect( lambda: self.browseDb_clicked('exportDb')) self.pb_applyChanges.clicked.connect(self.applyChanges) self.pb_applyChanges.setEnabled(False) self.changes_instance.maxRangeProgressBar.connect( self.__setRangeProgressBarChanges) self.changes_instance.updateStatus.connect( self.__updateProgressBarChanges) self.changes_instance.finishedStatus.connect(self.__changesApplied) self.changes_instance.preprocessingDatabase.connect( self.__changesPreprocessingDatabase) # connect radio boxes self.rb_file.clicked.connect(self.radioButtonValue) self.rb_directory.clicked.connect(self.radioButtonValue)
def __init__(self, parent=None): QWidget.__init__(self, parent) self.setWindowTitle( QCoreApplication.translate("PythonConsole", "Python Console")) self.settings = QgsSettings() self.shell = ShellScintilla(self) self.setFocusProxy(self.shell) self.shellOut = ShellOutputScintilla(self) self.tabEditorWidget = EditorTabWidget(self) # ------------ UI ------------------------------- self.splitterEditor = QSplitter(self) self.splitterEditor.setOrientation(Qt.Horizontal) self.splitterEditor.setHandleWidth(6) self.splitterEditor.setChildrenCollapsible(True) self.shellOutWidget = QWidget(self) self.shellOutWidget.setLayout(QVBoxLayout()) self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0) self.shellOutWidget.layout().addWidget(self.shellOut) self.splitter = QSplitter(self.splitterEditor) self.splitter.setOrientation(Qt.Vertical) self.splitter.setHandleWidth(3) self.splitter.setChildrenCollapsible(False) self.splitter.addWidget(self.shellOutWidget) self.splitter.addWidget(self.shell) # self.splitterEditor.addWidget(self.tabEditorWidget) self.splitterObj = QSplitter(self.splitterEditor) self.splitterObj.setHandleWidth(3) self.splitterObj.setOrientation(Qt.Horizontal) # self.splitterObj.setSizes([0, 0]) # self.splitterObj.setStretchFactor(0, 1) self.widgetEditor = QWidget(self.splitterObj) self.widgetFind = QWidget(self) self.listClassMethod = QTreeWidget(self.splitterObj) self.listClassMethod.setColumnCount(2) objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector") self.listClassMethod.setHeaderLabels([objInspLabel, '']) self.listClassMethod.setColumnHidden(1, True) self.listClassMethod.setAlternatingRowColors(True) # self.splitterEditor.addWidget(self.widgetEditor) # self.splitterObj.addWidget(self.listClassMethod) # self.splitterObj.addWidget(self.widgetEditor) # Hide side editor on start up self.splitterObj.hide() self.listClassMethod.hide() # Hide search widget on start up self.widgetFind.hide() icon_size = iface.iconSize( dockedToolbar=True) if iface else QSize(16, 16) sizes = self.splitter.sizes() self.splitter.setSizes(sizes) # ----------------Restore Settings------------------------------------ self.restoreSettingsConsole() # ------------------Toolbar Editor------------------------------------- # Action for Open File openFileBt = QCoreApplication.translate("PythonConsole", "Open Script...") self.openFileButton = QAction(self) self.openFileButton.setCheckable(False) self.openFileButton.setEnabled(True) self.openFileButton.setIcon( QgsApplication.getThemeIcon("console/iconOpenConsole.png")) self.openFileButton.setMenuRole(QAction.PreferencesRole) self.openFileButton.setIconVisibleInMenu(True) self.openFileButton.setToolTip(openFileBt) self.openFileButton.setText(openFileBt) openExtEditorBt = QCoreApplication.translate( "PythonConsole", "Open in External Editor") self.openInEditorButton = QAction(self) self.openInEditorButton.setCheckable(False) self.openInEditorButton.setEnabled(True) self.openInEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconShowEditorConsole.png")) self.openInEditorButton.setMenuRole(QAction.PreferencesRole) self.openInEditorButton.setIconVisibleInMenu(True) self.openInEditorButton.setToolTip(openExtEditorBt) self.openInEditorButton.setText(openExtEditorBt) # Action for Save File saveFileBt = QCoreApplication.translate("PythonConsole", "Save") self.saveFileButton = QAction(self) self.saveFileButton.setCheckable(False) self.saveFileButton.setEnabled(False) self.saveFileButton.setIcon( QgsApplication.getThemeIcon("console/iconSaveConsole.png")) self.saveFileButton.setMenuRole(QAction.PreferencesRole) self.saveFileButton.setIconVisibleInMenu(True) self.saveFileButton.setToolTip(saveFileBt) self.saveFileButton.setText(saveFileBt) # Action for Save File As saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As...") self.saveAsFileButton = QAction(self) self.saveAsFileButton.setCheckable(False) self.saveAsFileButton.setEnabled(True) self.saveAsFileButton.setIcon( QgsApplication.getThemeIcon("console/iconSaveAsConsole.png")) self.saveAsFileButton.setMenuRole(QAction.PreferencesRole) self.saveAsFileButton.setIconVisibleInMenu(True) self.saveAsFileButton.setToolTip(saveAsFileBt) self.saveAsFileButton.setText(saveAsFileBt) # Action Cut cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut") self.cutEditorButton = QAction(self) self.cutEditorButton.setCheckable(False) self.cutEditorButton.setEnabled(True) self.cutEditorButton.setIcon( QgsApplication.getThemeIcon("mActionEditCut.svg")) self.cutEditorButton.setMenuRole(QAction.PreferencesRole) self.cutEditorButton.setIconVisibleInMenu(True) self.cutEditorButton.setToolTip(cutEditorBt) self.cutEditorButton.setText(cutEditorBt) # Action Copy copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy") self.copyEditorButton = QAction(self) self.copyEditorButton.setCheckable(False) self.copyEditorButton.setEnabled(True) self.copyEditorButton.setIcon( QgsApplication.getThemeIcon("mActionEditCopy.svg")) self.copyEditorButton.setMenuRole(QAction.PreferencesRole) self.copyEditorButton.setIconVisibleInMenu(True) self.copyEditorButton.setToolTip(copyEditorBt) self.copyEditorButton.setText(copyEditorBt) # Action Paste pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste") self.pasteEditorButton = QAction(self) self.pasteEditorButton.setCheckable(False) self.pasteEditorButton.setEnabled(True) self.pasteEditorButton.setIcon( QgsApplication.getThemeIcon("mActionEditPaste.svg")) self.pasteEditorButton.setMenuRole(QAction.PreferencesRole) self.pasteEditorButton.setIconVisibleInMenu(True) self.pasteEditorButton.setToolTip(pasteEditorBt) self.pasteEditorButton.setText(pasteEditorBt) # Action Run Script (subprocess) runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run script") self.runScriptEditorButton = QAction(self) self.runScriptEditorButton.setCheckable(False) self.runScriptEditorButton.setEnabled(True) self.runScriptEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconRunScriptConsole.png")) self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole) self.runScriptEditorButton.setIconVisibleInMenu(True) self.runScriptEditorButton.setToolTip(runScriptEditorBt) self.runScriptEditorButton.setText(runScriptEditorBt) # Action Run Script (subprocess) commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment") self.commentEditorButton = QAction(self) self.commentEditorButton.setCheckable(False) self.commentEditorButton.setEnabled(True) self.commentEditorButton.setIcon( QgsApplication.getThemeIcon( "console/iconCommentEditorConsole.png")) self.commentEditorButton.setMenuRole(QAction.PreferencesRole) self.commentEditorButton.setIconVisibleInMenu(True) self.commentEditorButton.setToolTip(commentEditorBt) self.commentEditorButton.setText(commentEditorBt) # Action Run Script (subprocess) uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment") self.uncommentEditorButton = QAction(self) self.uncommentEditorButton.setCheckable(False) self.uncommentEditorButton.setEnabled(True) self.uncommentEditorButton.setIcon( QgsApplication.getThemeIcon( "console/iconUncommentEditorConsole.png")) self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole) self.uncommentEditorButton.setIconVisibleInMenu(True) self.uncommentEditorButton.setToolTip(uncommentEditorBt) self.uncommentEditorButton.setText(uncommentEditorBt) # Action for Object browser objList = QCoreApplication.translate("PythonConsole", "Object Inspector...") self.objectListButton = QAction(self) self.objectListButton.setCheckable(True) self.objectListButton.setEnabled( self.settings.value("pythonConsole/enableObjectInsp", False, type=bool)) self.objectListButton.setIcon( QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png")) self.objectListButton.setMenuRole(QAction.PreferencesRole) self.objectListButton.setIconVisibleInMenu(True) self.objectListButton.setToolTip(objList) self.objectListButton.setText(objList) # Action for Find text findText = QCoreApplication.translate("PythonConsole", "Find Text") self.findTextButton = QAction(self) self.findTextButton.setCheckable(True) self.findTextButton.setEnabled(True) self.findTextButton.setIcon( QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png")) self.findTextButton.setMenuRole(QAction.PreferencesRole) self.findTextButton.setIconVisibleInMenu(True) self.findTextButton.setToolTip(findText) self.findTextButton.setText(findText) # ----------------Toolbar Console------------------------------------- # Action Show Editor showEditor = QCoreApplication.translate("PythonConsole", "Show Editor") self.showEditorButton = QAction(self) self.showEditorButton.setEnabled(True) self.showEditorButton.setCheckable(True) self.showEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconShowEditorConsole.png")) self.showEditorButton.setMenuRole(QAction.PreferencesRole) self.showEditorButton.setIconVisibleInMenu(True) self.showEditorButton.setToolTip(showEditor) self.showEditorButton.setText(showEditor) # Action for Clear button clearBt = QCoreApplication.translate("PythonConsole", "Clear Console") self.clearButton = QAction(self) self.clearButton.setCheckable(False) self.clearButton.setEnabled(True) self.clearButton.setIcon( QgsApplication.getThemeIcon("console/iconClearConsole.png")) self.clearButton.setMenuRole(QAction.PreferencesRole) self.clearButton.setIconVisibleInMenu(True) self.clearButton.setToolTip(clearBt) self.clearButton.setText(clearBt) # Action for settings optionsBt = QCoreApplication.translate("PythonConsole", "Options...") self.optionsButton = QAction(self) self.optionsButton.setCheckable(False) self.optionsButton.setEnabled(True) self.optionsButton.setIcon( QgsApplication.getThemeIcon("console/iconSettingsConsole.png")) self.optionsButton.setMenuRole(QAction.PreferencesRole) self.optionsButton.setIconVisibleInMenu(True) self.optionsButton.setToolTip(optionsBt) self.optionsButton.setText(optionsBt) # Action for Run script runBt = QCoreApplication.translate("PythonConsole", "Run Command") self.runButton = QAction(self) self.runButton.setCheckable(False) self.runButton.setEnabled(True) self.runButton.setIcon( QgsApplication.getThemeIcon("console/iconRunConsole.png")) self.runButton.setMenuRole(QAction.PreferencesRole) self.runButton.setIconVisibleInMenu(True) self.runButton.setToolTip(runBt) self.runButton.setText(runBt) # Help action helpBt = QCoreApplication.translate("PythonConsole", "Help...") self.helpButton = QAction(self) self.helpButton.setCheckable(False) self.helpButton.setEnabled(True) self.helpButton.setIcon( QgsApplication.getThemeIcon("console/iconHelpConsole.png")) self.helpButton.setMenuRole(QAction.PreferencesRole) self.helpButton.setIconVisibleInMenu(True) self.helpButton.setToolTip(helpBt) self.helpButton.setText(helpBt) self.toolBar = QToolBar() self.toolBar.setEnabled(True) self.toolBar.setFocusPolicy(Qt.NoFocus) self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBar.setLayoutDirection(Qt.LeftToRight) self.toolBar.setIconSize(icon_size) self.toolBar.setMovable(False) self.toolBar.setFloatable(False) self.toolBar.addAction(self.clearButton) self.toolBar.addAction(self.runButton) self.toolBar.addSeparator() self.toolBar.addAction(self.showEditorButton) self.toolBar.addSeparator() self.toolBar.addAction(self.optionsButton) self.toolBar.addAction(self.helpButton) self.toolBarEditor = QToolBar() self.toolBarEditor.setEnabled(False) self.toolBarEditor.setFocusPolicy(Qt.NoFocus) self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBarEditor.setLayoutDirection(Qt.LeftToRight) self.toolBarEditor.setIconSize(icon_size) self.toolBarEditor.setMovable(False) self.toolBarEditor.setFloatable(False) self.toolBarEditor.addAction(self.openFileButton) self.toolBarEditor.addAction(self.openInEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.saveFileButton) self.toolBarEditor.addAction(self.saveAsFileButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.runScriptEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.findTextButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.cutEditorButton) self.toolBarEditor.addAction(self.copyEditorButton) self.toolBarEditor.addAction(self.pasteEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.commentEditorButton) self.toolBarEditor.addAction(self.uncommentEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.objectListButton) self.widgetButton = QWidget() sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.widgetButton.sizePolicy().hasHeightForWidth()) self.widgetButton.setSizePolicy(sizePolicy) self.widgetButtonEditor = QWidget(self.widgetEditor) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.widgetButtonEditor.sizePolicy().hasHeightForWidth()) self.widgetButtonEditor.setSizePolicy(sizePolicy) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.shellOut.sizePolicy().hasHeightForWidth()) self.shellOut.setSizePolicy(sizePolicy) self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # ------------ Layout ------------------------------- self.mainLayout = QGridLayout(self) self.mainLayout.setMargin(0) self.mainLayout.setSpacing(0) self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1) self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1) self.shellOutWidget.layout().insertWidget(0, self.toolBar) self.layoutEditor = QGridLayout(self.widgetEditor) self.layoutEditor.setMargin(0) self.layoutEditor.setSpacing(0) self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1) self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1) self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1) self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1) # Layout for the find widget self.layoutFind = QGridLayout(self.widgetFind) self.layoutFind.setContentsMargins(0, 0, 0, 0) self.lineEditFind = QgsFilterLineEdit() placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find...") self.lineEditFind.setPlaceholderText(placeHolderTxt) self.findNextButton = QToolButton() self.findNextButton.setEnabled(False) toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next") self.findNextButton.setToolTip(toolTipfindNext) self.findNextButton.setIcon( QgsApplication.getThemeIcon( "console/iconSearchNextEditorConsole.png")) self.findNextButton.setIconSize(QSize(24, 24)) self.findNextButton.setAutoRaise(True) self.findPrevButton = QToolButton() self.findPrevButton.setEnabled(False) toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous") self.findPrevButton.setToolTip(toolTipfindPrev) self.findPrevButton.setIcon( QgsApplication.getThemeIcon( "console/iconSearchPrevEditorConsole.png")) self.findPrevButton.setIconSize(QSize(24, 24)) self.findPrevButton.setAutoRaise(True) self.caseSensitive = QCheckBox() caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive") self.caseSensitive.setText(caseSensTr) self.wholeWord = QCheckBox() wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word") self.wholeWord.setText(wholeWordTr) self.wrapAround = QCheckBox() self.wrapAround.setChecked(True) wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around") self.wrapAround.setText(wrapAroundTr) self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1) self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1) self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1) self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1) self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1) self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1) # ------------ Add first Tab in Editor ------------------------------- # self.tabEditorWidget.newTabEditor(tabName='first', filename=None) # ------------ Signal ------------------------------- self.findTextButton.triggered.connect(self._toggleFind) self.objectListButton.toggled.connect(self.toggleObjectListWidget) self.commentEditorButton.triggered.connect(self.commentCode) self.uncommentEditorButton.triggered.connect(self.uncommentCode) self.runScriptEditorButton.triggered.connect(self.runScriptEditor) self.cutEditorButton.triggered.connect(self.cutEditor) self.copyEditorButton.triggered.connect(self.copyEditor) self.pasteEditorButton.triggered.connect(self.pasteEditor) self.showEditorButton.toggled.connect(self.toggleEditor) self.clearButton.triggered.connect(self.shellOut.clearConsole) self.optionsButton.triggered.connect(self.openSettings) self.runButton.triggered.connect(self.shell.entered) self.openFileButton.triggered.connect(self.openScriptFile) self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor) self.saveFileButton.triggered.connect(self.saveScriptFile) self.saveAsFileButton.triggered.connect(self.saveAsScriptFile) self.helpButton.triggered.connect(self.openHelp) self.listClassMethod.itemClicked.connect(self.onClickGoToLine) self.lineEditFind.returnPressed.connect(self._findNext) self.findNextButton.clicked.connect(self._findNext) self.findPrevButton.clicked.connect(self._findPrev) self.lineEditFind.textChanged.connect(self._textFindChanged) self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor) self.findScut.setContext(Qt.WidgetWithChildrenShortcut) self.findScut.activated.connect(self._openFind) self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor) self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut) self.findNextScut.activated.connect(self._findNext) self.findPreviousScut = QShortcut(QKeySequence.FindPrevious, self.widgetEditor) self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut) self.findPreviousScut.activated.connect(self._findPrev) # Escape on editor hides the find bar self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor) self.findScut.setContext(Qt.WidgetWithChildrenShortcut) self.findScut.activated.connect(self._closeFind)
def __init__(self, title=None,image_dir=None, parent=None): QWidget.__init__(self, parent) self.toolbar = QToolBar() self.__log_scene = MyScene(0, 0, 600, 600) self.__log_view = LogGraphicsView(self.__log_scene) self.__log_view.setAlignment(Qt.AlignLeft|Qt.AlignTop) self.__log_scene.sceneRectChanged.connect(self.on_rect_changed) if image_dir is None: image_dir = os.path.join(os.path.dirname(__file__), "img") self.__action_move_column_left = QAction(QIcon(os.path.join(image_dir, "left.svg")), "Move the column to the left", self.toolbar) self.__action_move_column_left.triggered.connect(self.on_move_column_left) self.__action_move_column_right = QAction(QIcon(os.path.join(image_dir, "right.svg")), "Move the column to the right", self.toolbar) self.__action_move_column_right.triggered.connect(self.on_move_column_right) self.__action_edit_style = QAction(QIcon(os.path.join(image_dir, "symbology.svg")), "Edit column style", self.toolbar) self.__action_edit_style.triggered.connect(self.on_edit_style) self.__action_add_column = QAction(QIcon(os.path.join(image_dir, "add.svg")), "Add a data column from configured ones", self.toolbar) self.__action_add_column.triggered.connect(self.on_add_column) self.__action_remove_column = QAction(QIcon(os.path.join(image_dir, "remove.svg")), "Remove the column", self.toolbar) self.__action_remove_column.triggered.connect(self.on_remove_column) #self.__action_move_content_right = QAction("Move content right", self.toolbar) #self.__action_move_content_left = QAction("Move content left", self.toolbar) #self.__action_move_content_left.triggered.connect(self.on_move_content_left) #self.__action_move_content_right.triggered.connect(self.on_move_content_right) self.toolbar.addAction(self.__action_move_column_left) self.toolbar.addAction(self.__action_move_column_right) self.toolbar.addAction(self.__action_edit_style) self.toolbar.addAction(self.__action_add_column) self.toolbar.addAction(self.__action_remove_column) #self.__toolbar.addAction(self.__action_move_content_left) #self.__toolbar.addAction(self.__action_move_content_right) self.__title_label = QLabel() if title is not None: self.set_title(title) self.__status_bar = QStatusBar() vbox = QVBoxLayout() vbox.addWidget(self.__title_label) vbox.addWidget(self.toolbar) vbox.addWidget(self.__log_view) vbox.addWidget(self.__status_bar) self.setLayout(vbox) self.__station_id = None # (log_item, legend_item) for each column self.__columns = [] # { layer : (log_item, legend_item) } self.__data2logitems = {} self.__column_widths = [] self._min_z = 0 self._max_z = 40 self.__allow_mouse_translation = True self.__translation_orig = None self.__style_dir = os.path.join(os.path.dirname(__file__), 'styles') self.select_column(-1) # by default we have a Z scale self.add_z_scale()
class DBManager(QMainWindow): def __init__(self, iface, parent=None): QMainWindow.__init__(self, parent) self.setAttribute(Qt.WA_DeleteOnClose) self.setupUi() self.iface = iface # restore the window state settings = QgsSettings() self.restoreGeometry(settings.value("/DB_Manager/mainWindow/geometry", QByteArray(), type=QByteArray)) self.restoreState(settings.value("/DB_Manager/mainWindow/windowState", QByteArray(), type=QByteArray)) self.tabs.currentChanged.connect(self.tabChanged) self.tree.selectedItemChanged.connect(self.itemChanged) self.tree.model().dataChanged.connect(self.iface.reloadConnections) self.itemChanged(None) def closeEvent(self, e): self.unregisterAllActions() # clear preview, this will delete the layer in preview tab self.preview.loadPreview(None) # save the window state settings = QgsSettings() settings.setValue("/DB_Manager/mainWindow/windowState", self.saveState()) settings.setValue("/DB_Manager/mainWindow/geometry", self.saveGeometry()) QMainWindow.closeEvent(self, e) def refreshItem(self, item=None): with OverrideCursor(Qt.WaitCursor): try: if item is None: item = self.tree.currentItem() self.tree.refreshItem(item) # refresh item children in the db tree except BaseError as e: DlgDbError.showError(e, self) def itemChanged(self, item): with OverrideCursor(Qt.WaitCursor): try: self.reloadButtons() # clear preview, this will delete the layer in preview tab self.preview.loadPreview(None) self.refreshTabs() except BaseError as e: DlgDbError.showError(e, self) def reloadButtons(self): db = self.tree.currentDatabase() if not hasattr(self, '_lastDb'): self._lastDb = db elif db == self._lastDb: return # remove old actions if self._lastDb is not None: self.unregisterAllActions() # add actions of the selected database self._lastDb = db if self._lastDb is not None: self._lastDb.registerAllActions(self) def tabChanged(self, index): with OverrideCursor(Qt.WaitCursor): try: self.refreshTabs() except BaseError as e: DlgDbError.showError(e, self) def refreshTabs(self): index = self.tabs.currentIndex() item = self.tree.currentItem() table = self.tree.currentTable() # enable/disable tabs self.tabs.setTabEnabled(self.tabs.indexOf(self.table), table is not None) self.tabs.setTabEnabled(self.tabs.indexOf(self.preview), table is not None and table.type in [table.VectorType, table.RasterType] and table.geomColumn is not None) # show the info tab if the current tab is disabled if not self.tabs.isTabEnabled(index): self.tabs.setCurrentWidget(self.info) current_tab = self.tabs.currentWidget() if current_tab == self.info: self.info.showInfo(item) elif current_tab == self.table: self.table.loadData(item) elif current_tab == self.preview: self.preview.loadPreview(item) def refreshActionSlot(self): self.info.setDirty() self.table.setDirty() self.preview.setDirty() self.refreshItem() def importActionSlot(self): db = self.tree.currentDatabase() if db is None: self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."), Qgis.Info, self.iface.messageTimeout()) return outUri = db.uri() schema = self.tree.currentSchema() if schema: outUri.setDataSource(schema.name, "", "", "") from .dlg_import_vector import DlgImportVector dlg = DlgImportVector(None, db, outUri, self) dlg.exec_() def exportActionSlot(self): table = self.tree.currentTable() if table is None: self.infoBar.pushMessage(self.tr("Select the table you want export to file."), Qgis.Info, self.iface.messageTimeout()) return inLayer = table.toMapLayer() if inLayer.type() != QgsMapLayer.VectorLayer: self.infoBar.pushMessage( self.tr("Select a vector or a tabular layer you want export."), Qgis.Warning, self.iface.messageTimeout()) return from .dlg_export_vector import DlgExportVector dlg = DlgExportVector(inLayer, table.database(), self) dlg.exec_() inLayer.deleteLater() def runSqlWindow(self): db = self.tree.currentDatabase() if db is None: self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."), Qgis.Info, self.iface.messageTimeout()) # force displaying of the message, it appears on the first tab (i.e. Info) self.tabs.setCurrentIndex(0) return from .dlg_sql_window import DlgSqlWindow query = DlgSqlWindow(self.iface, db, self) dbname = db.connection().connectionName() tabname = self.tr("Query ({0})").format(dbname) index = self.tabs.addTab(query, tabname) self.tabs.setTabIcon(index, db.connection().icon()) self.tabs.setCurrentIndex(index) query.nameChanged.connect(functools.partial(self.update_query_tab_name, index, dbname)) def runSqlLayerWindow(self, layer): from .dlg_sql_layer_window import DlgSqlLayerWindow query = DlgSqlLayerWindow(self.iface, layer, self) lname = layer.name() tabname = self.tr("Layer ({0})").format(lname) index = self.tabs.addTab(query, tabname) # self.tabs.setTabIcon(index, db.connection().icon()) self.tabs.setCurrentIndex(index) def update_query_tab_name(self, index, dbname, queryname): if not queryname: queryname = self.tr("Query") tabname = u"%s (%s)" % (queryname, dbname) self.tabs.setTabText(index, tabname) def showSystemTables(self): self.tree.showSystemTables(self.actionShowSystemTables.isChecked()) def registerAction(self, action, menuName, callback=None): """ register an action to the manager's main menu """ if not hasattr(self, '_registeredDbActions'): self._registeredDbActions = {} if callback is not None: def invoke_callback(x): return self.invokeCallback(callback) if menuName is None or menuName == "": self.addAction(action) if menuName not in self._registeredDbActions: self._registeredDbActions[menuName] = list() self._registeredDbActions[menuName].append(action) if callback is not None: action.triggered.connect(invoke_callback) return True # search for the menu actionMenu = None helpMenuAction = None for a in self.menuBar.actions(): if not a.menu() or a.menu().title() != menuName: continue if a.menu() != self.menuHelp: helpMenuAction = a actionMenu = a break # not found, add a new menu before the help menu if actionMenu is None: menu = QMenu(menuName, self) if helpMenuAction is not None: actionMenu = self.menuBar.insertMenu(helpMenuAction, menu) else: actionMenu = self.menuBar.addMenu(menu) menu = actionMenu.menu() menuActions = menu.actions() # get the placeholder's position to insert before it pos = 0 for pos in range(len(menuActions)): if menuActions[pos].isSeparator() and menuActions[pos].objectName().endswith("_placeholder"): menuActions[pos].setVisible(True) break if pos < len(menuActions): before = menuActions[pos] menu.insertAction(before, action) else: menu.addAction(action) actionMenu.setVisible(True) # show the menu if menuName not in self._registeredDbActions: self._registeredDbActions[menuName] = list() self._registeredDbActions[menuName].append(action) if callback is not None: action.triggered.connect(invoke_callback) return True def invokeCallback(self, callback, *params): """ Call a method passing the selected item in the database tree, the sender (usually a QAction), the plugin mainWindow and optionally additional parameters. This method takes care to override and restore the cursor, but also catches exceptions and displays the error dialog. """ with OverrideCursor(Qt.WaitCursor): try: callback(self.tree.currentItem(), self.sender(), self, *params) except BaseError as e: # catch database errors and display the error dialog DlgDbError.showError(e, self) def unregisterAction(self, action, menuName): if not hasattr(self, '_registeredDbActions'): return if menuName is None or menuName == "": self.removeAction(action) if menuName in self._registeredDbActions: if self._registeredDbActions[menuName].count(action) > 0: self._registeredDbActions[menuName].remove(action) action.deleteLater() return True for a in self.menuBar.actions(): if not a.menu() or a.menu().title() != menuName: continue menu = a.menu() menuActions = menu.actions() menu.removeAction(action) if menu.isEmpty(): # hide the menu a.setVisible(False) if menuName in self._registeredDbActions: if self._registeredDbActions[menuName].count(action) > 0: self._registeredDbActions[menuName].remove(action) # hide the placeholder if there're no other registered actions if len(self._registeredDbActions[menuName]) <= 0: for i in range(len(menuActions)): if menuActions[i].isSeparator() and menuActions[i].objectName().endswith("_placeholder"): menuActions[i].setVisible(False) break action.deleteLater() return True return False def unregisterAllActions(self): if not hasattr(self, '_registeredDbActions'): return for menuName in self._registeredDbActions: for action in list(self._registeredDbActions[menuName]): self.unregisterAction(action, menuName) del self._registeredDbActions def close_tab(self, index): widget = self.tabs.widget(index) if widget not in [self.info, self.table, self.preview]: self.tabs.removeTab(index) widget.deleteLater() def setupUi(self): self.setWindowTitle(self.tr("DB Manager")) self.setWindowIcon(QIcon(":/db_manager/icon")) self.resize(QSize(700, 500).expandedTo(self.minimumSizeHint())) # create central tab widget and add the first 3 tabs: info, table and preview self.tabs = QTabWidget() self.info = InfoViewer(self) self.tabs.addTab(self.info, self.tr("Info")) self.table = TableViewer(self) self.tabs.addTab(self.table, self.tr("Table")) self.preview = LayerPreview(self) self.tabs.addTab(self.preview, self.tr("Preview")) self.setCentralWidget(self.tabs) # display close button for all tabs but the first 3 ones, i.e. # HACK: just hide the close button where not needed (GS) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_tab) tabbar = self.tabs.tabBar() for i in range(3): btn = tabbar.tabButton(i, QTabBar.RightSide) if tabbar.tabButton(i, QTabBar.RightSide) else tabbar.tabButton(i, QTabBar.LeftSide) btn.resize(0, 0) btn.hide() # Creates layout for message bar self.layout = QGridLayout(self.info) self.layout.setContentsMargins(0, 0, 0, 0) spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.layout.addItem(spacerItem, 1, 0, 1, 1) # init messageBar instance self.infoBar = QgsMessageBar(self.info) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.infoBar.setSizePolicy(sizePolicy) self.layout.addWidget(self.infoBar, 0, 0, 1, 1) # create database tree self.dock = QDockWidget("Tree", self) self.dock.setObjectName("DB_Manager_DBView") self.dock.setFeatures(QDockWidget.DockWidgetMovable) self.tree = DBTree(self) self.dock.setWidget(self.tree) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock) # create status bar self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) # create menus self.menuBar = QMenuBar(self) self.menuDb = QMenu(self.tr("&Database"), self) self.menuBar.addMenu(self.menuDb) self.menuSchema = QMenu(self.tr("&Schema"), self) actionMenuSchema = self.menuBar.addMenu(self.menuSchema) self.menuTable = QMenu(self.tr("&Table"), self) actionMenuTable = self.menuBar.addMenu(self.menuTable) self.menuHelp = None # QMenu(self.tr("&Help"), self) # actionMenuHelp = self.menuBar.addMenu(self.menuHelp) self.setMenuBar(self.menuBar) # create toolbar self.toolBar = QToolBar("Default", self) self.toolBar.setObjectName("DB_Manager_ToolBar") self.addToolBar(self.toolBar) # create menus' actions # menu DATABASE sep = self.menuDb.addSeparator() sep.setObjectName("DB_Manager_DbMenu_placeholder") sep.setVisible(False) self.actionRefresh = self.menuDb.addAction(QIcon(":/db_manager/actions/refresh"), self.tr("&Refresh"), self.refreshActionSlot, QKeySequence("F5")) self.actionSqlWindow = self.menuDb.addAction(QIcon(":/db_manager/actions/sql_window"), self.tr("&SQL window"), self.runSqlWindow, QKeySequence("F2")) self.menuDb.addSeparator() self.actionClose = self.menuDb.addAction(QIcon(), self.tr("&Exit"), self.close, QKeySequence("CTRL+Q")) # menu SCHEMA sep = self.menuSchema.addSeparator() sep.setObjectName("DB_Manager_SchemaMenu_placeholder") sep.setVisible(False) actionMenuSchema.setVisible(False) # menu TABLE sep = self.menuTable.addSeparator() sep.setObjectName("DB_Manager_TableMenu_placeholder") sep.setVisible(False) self.actionImport = self.menuTable.addAction(QIcon(":/db_manager/actions/import"), self.tr("&Import layer/file"), self.importActionSlot) self.actionExport = self.menuTable.addAction(QIcon(":/db_manager/actions/export"), self.tr("&Export to file"), self.exportActionSlot) self.menuTable.addSeparator() #self.actionShowSystemTables = self.menuTable.addAction(self.tr("Show system tables/views"), self.showSystemTables) #self.actionShowSystemTables.setCheckable(True) #self.actionShowSystemTables.setChecked(True) actionMenuTable.setVisible(False) # add actions to the toolbar self.toolBar.addAction(self.actionRefresh) self.toolBar.addAction(self.actionSqlWindow) self.toolBar.addAction(self.actionImport) self.toolBar.addAction(self.actionExport)
class PythonConsoleWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console")) self.settings = QgsSettings() self.shell = ShellScintilla(self) self.setFocusProxy(self.shell) self.shellOut = ShellOutputScintilla(self) self.tabEditorWidget = EditorTabWidget(self) # ------------ UI ------------------------------- self.splitterEditor = QSplitter(self) self.splitterEditor.setOrientation(Qt.Horizontal) self.splitterEditor.setHandleWidth(6) self.splitterEditor.setChildrenCollapsible(True) self.shellOutWidget = QWidget(self) self.shellOutWidget.setLayout(QVBoxLayout()) self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0) self.shellOutWidget.layout().addWidget(self.shellOut) self.splitter = QSplitter(self.splitterEditor) self.splitter.setOrientation(Qt.Vertical) self.splitter.setHandleWidth(3) self.splitter.setChildrenCollapsible(False) self.splitter.addWidget(self.shellOutWidget) self.splitter.addWidget(self.shell) # self.splitterEditor.addWidget(self.tabEditorWidget) self.splitterObj = QSplitter(self.splitterEditor) self.splitterObj.setHandleWidth(3) self.splitterObj.setOrientation(Qt.Horizontal) # self.splitterObj.setSizes([0, 0]) # self.splitterObj.setStretchFactor(0, 1) self.widgetEditor = QWidget(self.splitterObj) self.widgetFind = QWidget(self) self.listClassMethod = QTreeWidget(self.splitterObj) self.listClassMethod.setColumnCount(2) objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector") self.listClassMethod.setHeaderLabels([objInspLabel, '']) self.listClassMethod.setColumnHidden(1, True) self.listClassMethod.setAlternatingRowColors(True) # self.splitterEditor.addWidget(self.widgetEditor) # self.splitterObj.addWidget(self.listClassMethod) # self.splitterObj.addWidget(self.widgetEditor) # Hide side editor on start up self.splitterObj.hide() self.listClassMethod.hide() # Hide search widget on start up self.widgetFind.hide() icon_size = iface.iconSize(dockedToolbar=True) if iface else QSize(16, 16) sizes = self.splitter.sizes() self.splitter.setSizes(sizes) # ----------------Restore Settings------------------------------------ self.restoreSettingsConsole() # ------------------Toolbar Editor------------------------------------- # Action for Open File openFileBt = QCoreApplication.translate("PythonConsole", "Open Script…") self.openFileButton = QAction(self) self.openFileButton.setCheckable(False) self.openFileButton.setEnabled(True) self.openFileButton.setIcon(QgsApplication.getThemeIcon("console/iconOpenConsole.svg")) self.openFileButton.setMenuRole(QAction.PreferencesRole) self.openFileButton.setIconVisibleInMenu(True) self.openFileButton.setToolTip(openFileBt) self.openFileButton.setText(openFileBt) openExtEditorBt = QCoreApplication.translate("PythonConsole", "Open in External Editor") self.openInEditorButton = QAction(self) self.openInEditorButton.setCheckable(False) self.openInEditorButton.setEnabled(True) self.openInEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg")) self.openInEditorButton.setMenuRole(QAction.PreferencesRole) self.openInEditorButton.setIconVisibleInMenu(True) self.openInEditorButton.setToolTip(openExtEditorBt) self.openInEditorButton.setText(openExtEditorBt) # Action for Save File saveFileBt = QCoreApplication.translate("PythonConsole", "Save") self.saveFileButton = QAction(self) self.saveFileButton.setCheckable(False) self.saveFileButton.setEnabled(False) self.saveFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveConsole.svg")) self.saveFileButton.setMenuRole(QAction.PreferencesRole) self.saveFileButton.setIconVisibleInMenu(True) self.saveFileButton.setToolTip(saveFileBt) self.saveFileButton.setText(saveFileBt) # Action for Save File As saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As…") self.saveAsFileButton = QAction(self) self.saveAsFileButton.setCheckable(False) self.saveAsFileButton.setEnabled(True) self.saveAsFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveAsConsole.svg")) self.saveAsFileButton.setMenuRole(QAction.PreferencesRole) self.saveAsFileButton.setIconVisibleInMenu(True) self.saveAsFileButton.setToolTip(saveAsFileBt) self.saveAsFileButton.setText(saveAsFileBt) # Action Cut cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut") self.cutEditorButton = QAction(self) self.cutEditorButton.setCheckable(False) self.cutEditorButton.setEnabled(True) self.cutEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCut.svg")) self.cutEditorButton.setMenuRole(QAction.PreferencesRole) self.cutEditorButton.setIconVisibleInMenu(True) self.cutEditorButton.setToolTip(cutEditorBt) self.cutEditorButton.setText(cutEditorBt) # Action Copy copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy") self.copyEditorButton = QAction(self) self.copyEditorButton.setCheckable(False) self.copyEditorButton.setEnabled(True) self.copyEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditCopy.svg")) self.copyEditorButton.setMenuRole(QAction.PreferencesRole) self.copyEditorButton.setIconVisibleInMenu(True) self.copyEditorButton.setToolTip(copyEditorBt) self.copyEditorButton.setText(copyEditorBt) # Action Paste pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste") self.pasteEditorButton = QAction(self) self.pasteEditorButton.setCheckable(False) self.pasteEditorButton.setEnabled(True) self.pasteEditorButton.setIcon(QgsApplication.getThemeIcon("mActionEditPaste.svg")) self.pasteEditorButton.setMenuRole(QAction.PreferencesRole) self.pasteEditorButton.setIconVisibleInMenu(True) self.pasteEditorButton.setToolTip(pasteEditorBt) self.pasteEditorButton.setText(pasteEditorBt) # Action Run Script (subprocess) runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run Script") self.runScriptEditorButton = QAction(self) self.runScriptEditorButton.setCheckable(False) self.runScriptEditorButton.setEnabled(True) self.runScriptEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconRunScriptConsole.svg")) self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole) self.runScriptEditorButton.setIconVisibleInMenu(True) self.runScriptEditorButton.setToolTip(runScriptEditorBt) self.runScriptEditorButton.setText(runScriptEditorBt) # Action Run Script (subprocess) commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment") self.commentEditorButton = QAction(self) self.commentEditorButton.setCheckable(False) self.commentEditorButton.setEnabled(True) self.commentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCommentEditorConsole.svg")) self.commentEditorButton.setMenuRole(QAction.PreferencesRole) self.commentEditorButton.setIconVisibleInMenu(True) self.commentEditorButton.setToolTip(commentEditorBt) self.commentEditorButton.setText(commentEditorBt) # Action Run Script (subprocess) uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment") self.uncommentEditorButton = QAction(self) self.uncommentEditorButton.setCheckable(False) self.uncommentEditorButton.setEnabled(True) self.uncommentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.svg")) self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole) self.uncommentEditorButton.setIconVisibleInMenu(True) self.uncommentEditorButton.setToolTip(uncommentEditorBt) self.uncommentEditorButton.setText(uncommentEditorBt) # Action for Object browser objList = QCoreApplication.translate("PythonConsole", "Object Inspector…") self.objectListButton = QAction(self) self.objectListButton.setCheckable(True) self.objectListButton.setEnabled(self.settings.value("pythonConsole/enableObjectInsp", False, type=bool)) self.objectListButton.setIcon(QgsApplication.getThemeIcon("console/iconClassBrowserConsole.svg")) self.objectListButton.setMenuRole(QAction.PreferencesRole) self.objectListButton.setIconVisibleInMenu(True) self.objectListButton.setToolTip(objList) self.objectListButton.setText(objList) # Action for Find text findText = QCoreApplication.translate("PythonConsole", "Find Text") self.findTextButton = QAction(self) self.findTextButton.setCheckable(True) self.findTextButton.setEnabled(True) self.findTextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchEditorConsole.svg")) self.findTextButton.setMenuRole(QAction.PreferencesRole) self.findTextButton.setIconVisibleInMenu(True) self.findTextButton.setToolTip(findText) self.findTextButton.setText(findText) # ----------------Toolbar Console------------------------------------- # Action Show Editor showEditor = QCoreApplication.translate("PythonConsole", "Show Editor") self.showEditorButton = QAction(self) self.showEditorButton.setEnabled(True) self.showEditorButton.setCheckable(True) self.showEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.svg")) self.showEditorButton.setMenuRole(QAction.PreferencesRole) self.showEditorButton.setIconVisibleInMenu(True) self.showEditorButton.setToolTip(showEditor) self.showEditorButton.setText(showEditor) # Action for Clear button clearBt = QCoreApplication.translate("PythonConsole", "Clear Console") self.clearButton = QAction(self) self.clearButton.setCheckable(False) self.clearButton.setEnabled(True) self.clearButton.setIcon(QgsApplication.getThemeIcon("console/iconClearConsole.svg")) self.clearButton.setMenuRole(QAction.PreferencesRole) self.clearButton.setIconVisibleInMenu(True) self.clearButton.setToolTip(clearBt) self.clearButton.setText(clearBt) # Action for settings optionsBt = QCoreApplication.translate("PythonConsole", "Options…") self.optionsButton = QAction(self) self.optionsButton.setCheckable(False) self.optionsButton.setEnabled(True) self.optionsButton.setIcon(QgsApplication.getThemeIcon("console/iconSettingsConsole.svg")) self.optionsButton.setMenuRole(QAction.PreferencesRole) self.optionsButton.setIconVisibleInMenu(True) self.optionsButton.setToolTip(optionsBt) self.optionsButton.setText(optionsBt) # Action for Run script runBt = QCoreApplication.translate("PythonConsole", "Run Command") self.runButton = QAction(self) self.runButton.setCheckable(False) self.runButton.setEnabled(True) self.runButton.setIcon(QgsApplication.getThemeIcon("console/mIconRunConsole.svg")) self.runButton.setMenuRole(QAction.PreferencesRole) self.runButton.setIconVisibleInMenu(True) self.runButton.setToolTip(runBt) self.runButton.setText(runBt) # Help action helpBt = QCoreApplication.translate("PythonConsole", "Help…") self.helpButton = QAction(self) self.helpButton.setCheckable(False) self.helpButton.setEnabled(True) self.helpButton.setIcon(QgsApplication.getThemeIcon("console/iconHelpConsole.svg")) self.helpButton.setMenuRole(QAction.PreferencesRole) self.helpButton.setIconVisibleInMenu(True) self.helpButton.setToolTip(helpBt) self.helpButton.setText(helpBt) self.toolBar = QToolBar() self.toolBar.setEnabled(True) self.toolBar.setFocusPolicy(Qt.NoFocus) self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBar.setLayoutDirection(Qt.LeftToRight) self.toolBar.setIconSize(icon_size) self.toolBar.setMovable(False) self.toolBar.setFloatable(False) self.toolBar.addAction(self.clearButton) self.toolBar.addAction(self.runButton) self.toolBar.addSeparator() self.toolBar.addAction(self.showEditorButton) self.toolBar.addSeparator() self.toolBar.addAction(self.optionsButton) self.toolBar.addAction(self.helpButton) self.toolBarEditor = QToolBar() self.toolBarEditor.setEnabled(False) self.toolBarEditor.setFocusPolicy(Qt.NoFocus) self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBarEditor.setLayoutDirection(Qt.LeftToRight) self.toolBarEditor.setIconSize(icon_size) self.toolBarEditor.setMovable(False) self.toolBarEditor.setFloatable(False) self.toolBarEditor.addAction(self.openFileButton) self.toolBarEditor.addAction(self.openInEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.saveFileButton) self.toolBarEditor.addAction(self.saveAsFileButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.runScriptEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.findTextButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.cutEditorButton) self.toolBarEditor.addAction(self.copyEditorButton) self.toolBarEditor.addAction(self.pasteEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.commentEditorButton) self.toolBarEditor.addAction(self.uncommentEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.objectListButton) self.widgetButton = QWidget() sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth()) self.widgetButton.setSizePolicy(sizePolicy) self.widgetButtonEditor = QWidget(self.widgetEditor) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widgetButtonEditor.sizePolicy().hasHeightForWidth()) self.widgetButtonEditor.setSizePolicy(sizePolicy) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.shellOut.sizePolicy().hasHeightForWidth()) self.shellOut.setSizePolicy(sizePolicy) self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # ------------ Layout ------------------------------- self.mainLayout = QGridLayout(self) self.mainLayout.setMargin(0) self.mainLayout.setSpacing(0) self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1) self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1) self.shellOutWidget.layout().insertWidget(0, self.toolBar) self.layoutEditor = QGridLayout(self.widgetEditor) self.layoutEditor.setMargin(0) self.layoutEditor.setSpacing(0) self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1) self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1) self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1) self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1) # Layout for the find widget self.layoutFind = QGridLayout(self.widgetFind) self.layoutFind.setContentsMargins(0, 0, 0, 0) self.lineEditFind = QgsFilterLineEdit() placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find…") self.lineEditFind.setPlaceholderText(placeHolderTxt) self.toolBarFindText = QToolBar() self.toolBarFindText.setIconSize(icon_size) self.findNextButton = QAction(self) self.findNextButton.setEnabled(False) toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next") self.findNextButton.setToolTip(toolTipfindNext) self.findNextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchNextEditorConsole.svg")) self.findPrevButton = QAction(self) self.findPrevButton.setEnabled(False) toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous") self.findPrevButton.setToolTip(toolTipfindPrev) self.findPrevButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchPrevEditorConsole.svg")) self.caseSensitive = QCheckBox() caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive") self.caseSensitive.setText(caseSensTr) self.wholeWord = QCheckBox() wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word") self.wholeWord.setText(wholeWordTr) self.wrapAround = QCheckBox() self.wrapAround.setChecked(True) wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around") self.wrapAround.setText(wrapAroundTr) self.toolBarFindText.addWidget(self.lineEditFind) self.toolBarFindText.addAction(self.findPrevButton) self.toolBarFindText.addAction(self.findNextButton) self.toolBarFindText.addWidget(self.caseSensitive) self.toolBarFindText.addWidget(self.wholeWord) self.toolBarFindText.addWidget(self.wrapAround) self.layoutFind.addWidget(self.toolBarFindText, 0, 1, 1, 1) # ------------ Add first Tab in Editor ------------------------------- # self.tabEditorWidget.newTabEditor(tabName='first', filename=None) # ------------ Signal ------------------------------- self.findTextButton.triggered.connect(self._toggleFind) self.objectListButton.toggled.connect(self.toggleObjectListWidget) self.commentEditorButton.triggered.connect(self.commentCode) self.uncommentEditorButton.triggered.connect(self.uncommentCode) self.runScriptEditorButton.triggered.connect(self.runScriptEditor) self.cutEditorButton.triggered.connect(self.cutEditor) self.copyEditorButton.triggered.connect(self.copyEditor) self.pasteEditorButton.triggered.connect(self.pasteEditor) self.showEditorButton.toggled.connect(self.toggleEditor) self.clearButton.triggered.connect(self.shellOut.clearConsole) self.optionsButton.triggered.connect(self.openSettings) self.runButton.triggered.connect(self.shell.entered) self.openFileButton.triggered.connect(self.openScriptFile) self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor) self.saveFileButton.triggered.connect(self.saveScriptFile) self.saveAsFileButton.triggered.connect(self.saveAsScriptFile) self.helpButton.triggered.connect(self.openHelp) self.listClassMethod.itemClicked.connect(self.onClickGoToLine) self.lineEditFind.returnPressed.connect(self._findNext) self.findNextButton.triggered.connect(self._findNext) self.findPrevButton.triggered.connect(self._findPrev) self.lineEditFind.textChanged.connect(self._textFindChanged) self.findScut = QShortcut(QKeySequence.Find, self.widgetEditor) self.findScut.setContext(Qt.WidgetWithChildrenShortcut) self.findScut.activated.connect(self._openFind) self.findNextScut = QShortcut(QKeySequence.FindNext, self.widgetEditor) self.findNextScut.setContext(Qt.WidgetWithChildrenShortcut) self.findNextScut.activated.connect(self._findNext) self.findPreviousScut = QShortcut(QKeySequence.FindPrevious, self.widgetEditor) self.findPreviousScut.setContext(Qt.WidgetWithChildrenShortcut) self.findPreviousScut.activated.connect(self._findPrev) # Escape on editor hides the find bar self.findScut = QShortcut(Qt.Key_Escape, self.widgetEditor) self.findScut.setContext(Qt.WidgetWithChildrenShortcut) self.findScut.activated.connect(self._closeFind) def _toggleFind(self): self.tabEditorWidget.currentWidget().newEditor.toggleFindWidget() def _openFind(self): self.tabEditorWidget.currentWidget().newEditor.openFindWidget() def _closeFind(self): self.tabEditorWidget.currentWidget().newEditor.closeFindWidget() def _findNext(self): self.tabEditorWidget.currentWidget().newEditor.findText(True) def _findPrev(self): self.tabEditorWidget.currentWidget().newEditor.findText(False) def _textFindChanged(self): if self.lineEditFind.text(): self.findNextButton.setEnabled(True) self.findPrevButton.setEnabled(True) self.tabEditorWidget.currentWidget().newEditor.findText(True, showMessage=False, findFirst=True) else: self.lineEditFind.setStyleSheet('') self.findNextButton.setEnabled(False) self.findPrevButton.setEnabled(False) def onClickGoToLine(self, item, column): tabEditor = self.tabEditorWidget.currentWidget().newEditor if item.text(1) == 'syntaxError': check = tabEditor.syntaxCheck(fromContextMenu=False) if check and not tabEditor.isReadOnly(): self.tabEditorWidget.currentWidget().save() return linenr = int(item.text(1)) itemName = str(item.text(0)) charPos = itemName.find(' ') if charPos != -1: objName = itemName[0:charPos] else: objName = itemName tabEditor.goToLine(objName, linenr) def toggleEditor(self, checked): self.splitterObj.show() if checked else self.splitterObj.hide() if not self.tabEditorWidget: self.tabEditorWidget.enableToolBarEditor(checked) self.tabEditorWidget.restoreTabsOrAddNew() def toggleObjectListWidget(self, checked): self.listClassMethod.show() if checked else self.listClassMethod.hide() def pasteEditor(self): self.tabEditorWidget.currentWidget().newEditor.paste() def cutEditor(self): self.tabEditorWidget.currentWidget().newEditor.cut() def copyEditor(self): self.tabEditorWidget.currentWidget().newEditor.copy() def runScriptEditor(self): self.tabEditorWidget.currentWidget().newEditor.runScriptCode() def commentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True) def uncommentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False) def openScriptFileExtEditor(self): tabWidget = self.tabEditorWidget.currentWidget() path = tabWidget.path import subprocess try: subprocess.Popen([os.environ['EDITOR'], path]) except KeyError: QDesktopServices.openUrl(QUrl.fromLocalFile(path)) def openScriptFile(self): lastDirPath = self.settings.value("pythonConsole/lastDirPath", QDir.homePath()) openFileTr = QCoreApplication.translate("PythonConsole", "Open File") fileList, selected_filter = QFileDialog.getOpenFileNames( self, openFileTr, lastDirPath, "Script file (*.py)") if fileList: for pyFile in fileList: for i in range(self.tabEditorWidget.count()): tabWidget = self.tabEditorWidget.widget(i) if tabWidget.path == pyFile: self.tabEditorWidget.setCurrentWidget(tabWidget) break else: tabName = QFileInfo(pyFile).fileName() self.tabEditorWidget.newTabEditor(tabName, pyFile) lastDirPath = QFileInfo(pyFile).path() self.settings.setValue("pythonConsole/lastDirPath", pyFile) self.updateTabListScript(pyFile, action='append') def saveScriptFile(self): tabWidget = self.tabEditorWidget.currentWidget() try: tabWidget.save() except (IOError, OSError) as error: msgText = QCoreApplication.translate('PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False) def saveAsScriptFile(self, index=None): tabWidget = self.tabEditorWidget.currentWidget() if not index: index = self.tabEditorWidget.currentIndex() if not tabWidget.path: fileName = self.tabEditorWidget.tabText(index) + '.py' folder = self.settings.value("pythonConsole/lastDirPath", QDir.homePath()) pathFileName = os.path.join(folder, fileName) fileNone = True else: pathFileName = tabWidget.path fileNone = False saveAsFileTr = QCoreApplication.translate("PythonConsole", "Save File As") filename, filter = QFileDialog.getSaveFileName(self, saveAsFileTr, pathFileName, "Script file (*.py)") if filename: try: tabWidget.save(filename) except (IOError, OSError) as error: msgText = QCoreApplication.translate('PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False) if fileNone: tabWidget.path = None else: tabWidget.path = pathFileName return if not fileNone: self.updateTabListScript(pathFileName, action='remove') def openHelp(self): QgsHelp.openHelp("plugins/python_console.html") def openSettings(self): if optionsDialog(self).exec_(): self.shell.refreshSettingsShell() self.shellOut.refreshSettingsOutput() self.tabEditorWidget.refreshSettingsEditor() def callWidgetMessageBar(self, text): self.shellOut.widgetMessageBar(iface, text) def callWidgetMessageBarEditor(self, text, level, timed): self.tabEditorWidget.widgetMessageBar(iface, text, level, timed) def updateTabListScript(self, script, action=None): if action == 'remove': self.tabListScript.remove(script) elif action == 'append': if not self.tabListScript: self.tabListScript = [] if script not in self.tabListScript: self.tabListScript.append(script) else: self.tabListScript = [] self.settings.setValue("pythonConsole/tabScripts", self.tabListScript) def saveSettingsConsole(self): self.settings.setValue("pythonConsole/splitterConsole", self.splitter.saveState()) self.settings.setValue("pythonConsole/splitterObj", self.splitterObj.saveState()) self.settings.setValue("pythonConsole/splitterEditor", self.splitterEditor.saveState()) self.shell.writeHistoryFile(True) def restoreSettingsConsole(self): storedTabScripts = self.settings.value("pythonConsole/tabScripts", []) self.tabListScript = storedTabScripts self.splitter.restoreState(self.settings.value("pythonConsole/splitterConsole", QByteArray())) self.splitterEditor.restoreState(self.settings.value("pythonConsole/splitterEditor", QByteArray())) self.splitterObj.restoreState(self.settings.value("pythonConsole/splitterObj", QByteArray()))
def __init__(self, raster_layer, iface=None): super().__init__(None, Qt.Dialog) # Set up the user interface from Designer. ui_path = os.path.join(os.path.dirname( __file__), 'Ui_RasterAttributeTableDialog.ui') uic.loadUi(ui_path, self) self.setWindowTitle(raster_layer.name() + ' — ' + self.windowTitle()) self.raster_layer = raster_layer self.iface = iface self.editable = False self.is_dirty = False # Get band from renderer or data provider try: self.band = raster_layer.renderer().band() self.loadRat(self.band) except AttributeError: for band in range(1, raster_layer.dataProvider().bandCount() + 1): if self.loadRat(band): self.band = band self.mRasterBandsComboBox.addItems( [raster_layer.bandName(bn) for bn in range(1, raster_layer.bandCount() + 1)]) self.mRasterBandsComboBox.setCurrentIndex(self.band - 1) # Setup edit menu actions self.mActionToggleEditing = QAction( QgsApplication.getThemeIcon("/mActionEditTable.svg"), QCoreApplication.translate("RAT", "&Edit Attribute Table")) self.mActionToggleEditing.setCheckable(True) self.mActionNewColumn = QAction( QgsApplication.getThemeIcon("/mActionNewAttribute.svg"), QCoreApplication.translate("RAT", "New &Column")) self.mActionNewRow = QAction( QgsApplication.getThemeIcon("/mActionNewTableRow.svg"), QCoreApplication.translate("RAT", "New &Row")) self.mActionRemoveRow = QAction( QgsApplication.getThemeIcon("/mActionRemoveSelectedFeature.svg"), QCoreApplication.translate("RAT", "Remove Row")) self.mActionRemoveColumn = QAction( QgsApplication.getThemeIcon("/mActionDeleteAttribute.svg"), QCoreApplication.translate("RAT", "Remove Column")) self.mActionSaveChanges = QAction( QgsApplication.getThemeIcon("/mActionSaveAllEdits.svg"), QCoreApplication.translate("RAT", "&Save Changes")) self.mEditToolBar = QToolBar() self.mEditToolBar.addAction(self.mActionToggleEditing) self.mEditToolBar.addAction(self.mActionNewColumn) self.mEditToolBar.addAction(self.mActionNewRow) self.mEditToolBar.addAction(self.mActionRemoveColumn) self.mEditToolBar.addAction(self.mActionRemoveRow) self.mEditToolBar.addAction(self.mActionSaveChanges) self.layout().setMenuBar(self.mEditToolBar) self.setEditable(False) # Connections self.mClassifyButton.clicked.connect(self.classify) self.mButtonBox.accepted.connect(self.accept) self.mButtonBox.rejected.connect(self.reject) self.mActionToggleEditing.triggered.connect(self.setEditable) self.mActionSaveChanges.triggered.connect(self.saveChanges) self.mActionNewColumn.triggered.connect(self.addColumn) self.mActionRemoveColumn.triggered.connect(self.removeColumn) self.mActionNewRow.triggered.connect(self.addRow) self.mActionRemoveRow.triggered.connect(self.removeRow) self.mRasterBandsComboBox.currentIndexChanged.connect( self.bandChanged) try: self.restoreGeometry(QgsSettings().value( "RasterAttributeTable/geometry", None, QByteArray, QgsSettings.Plugins)) except: pass self.updateButtons()
def __init__(self, title=None, image_dir=None, parent=None): QWidget.__init__(self, parent) self.__toolbar = QToolBar() self.__scene = MyScene(0, 0, 600, 400) self.__view = TimeSeriesGraphicsView(self.__scene) self.__view.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.__scene.sceneRectChanged.connect(self.on_rect_changed) if image_dir is None: image_dir = os.path.join(os.path.dirname(__file__), "img") self.__action_move_row_up = QAction( QIcon(os.path.join(image_dir, "up.svg")), "Move the row up", self.__toolbar) self.__action_move_row_up.triggered.connect(self.on_move_row_up) self.__action_move_row_down = QAction( QIcon(os.path.join(image_dir, "down.svg")), "Move the row down", self.__toolbar) self.__action_move_row_down.triggered.connect(self.on_move_row_down) self.__action_edit_style = QAction( QIcon(os.path.join(image_dir, "symbology.svg")), "Edit row style", self.__toolbar) self.__action_edit_style.triggered.connect(self.on_edit_style) self.__action_add_row = QAction( QIcon(os.path.join(image_dir, "add.svg")), "Add a data row", self.__toolbar) self.__action_add_row.triggered.connect(self.on_add_row) self.__action_remove_row = QAction( QIcon(os.path.join(image_dir, "remove.svg")), "Remove the row", self.__toolbar) self.__action_remove_row.triggered.connect(self.on_remove_row) self.__toolbar.addAction(self.__action_move_row_up) self.__toolbar.addAction(self.__action_move_row_down) self.__toolbar.addAction(self.__action_edit_style) self.__toolbar.addAction(self.__action_add_row) self.__toolbar.addAction(self.__action_remove_row) self.__title_label = QLabel() if title is not None: self.set_title(title) self.__status_bar = QStatusBar() vbox = QVBoxLayout() vbox.addWidget(self.__title_label) vbox.addWidget(self.__toolbar) vbox.addWidget(self.__view) vbox.addWidget(self.__status_bar) self.setLayout(vbox) self.__station_id = None # (log_item, legend_item) for each row self.__rows = [] # { layer : (log_item, legend_item) } self.__data2logitems = {} self.__row_heights = [] self._min_x = None self._max_x = None self.__allow_mouse_translation = True self.__translation_orig = None self.__style_dir = os.path.join(os.path.dirname(__file__), 'styles') self.select_row(-1) self._update_row_depths()
class Plugin(QObject): def __init__(self, iface): QObject.__init__(self) self.__iface = iface self.__shortcuts = [] self.__current_section = QComboBox() self.__current_section.setMinimumWidth(150) self.__current_graph = QComboBox() self.__current_graph.setMinimumWidth(150) self.__toolbar = None self.__menu = None self.__log_strati = None def initGui(self): for keyseq, slot in ( (Qt.CTRL + Qt.ALT + Qt.Key_K, self.__create_group), # (Qt.CTRL + Qt.ALT + Qt.Key_S, self.__select_next_group), (Qt.CTRL + Qt.ALT + Qt.Key_N, self.__next_section), (Qt.CTRL + Qt.ALT + Qt.Key_B, self.__previous_section), (Qt.CTRL + Qt.ALT + Qt.Key_J, self.__add_section_from_selection), ): short = QShortcut(QKeySequence(keyseq), self.__iface.mainWindow()) short.setContext(Qt.ApplicationShortcut) short.activated.connect(slot) self.__shortcuts.append(short) self.__menu = QMenu("Albion") self.__menu.aboutToShow.connect(self.__create_menu_entries) self.__iface.mainWindow().menuBar().addMenu(self.__menu) self.__toolbar = QToolBar("Albion") self.__iface.addToolBar(self.__toolbar) #self.__toolbar.addAction( # icon("log_strati.svg"), "stratigraphic log" #).triggered.connect(self.__log_strati_clicked) self.__toolbar.addWidget(self.__current_graph) self.__current_graph.currentIndexChanged[str].connect( self.__current_graph_changed ) self.__toolbar.addWidget(self.__current_section) self.__current_section.currentIndexChanged[str].connect( self.__current_section_changed ) self.__toolbar.addAction( icon("previous_line_big.svg"), "previous section (Ctrl+Alt+b)" ).triggered.connect(self.__previous_section) self.__toolbar.addAction( icon("previous_line.svg"), "previous sub section" ).triggered.connect(self.__previous_subsection) self.__toolbar.addAction( icon("next_line.svg"), "next sub section" ).triggered.connect(self.__next_subsection) self.__toolbar.addAction( icon("next_line_big.svg"), "next section (Ctrl+Alt+n)" ).triggered.connect(self.__next_section) self.__toolbar.addAction( icon("line_from_selected.svg"), "create temporary section" ).triggered.connect(self.__section_from_selection) self.__viewer3d = QDockWidget("3D") self.__viewer3d.setWidget(Viewer3d()) self.__iface.addDockWidget(Qt.LeftDockWidgetArea, self.__viewer3d) self.__iface.mainWindow().tabifyDockWidget( self.__iface.mainWindow().findChild(QDockWidget, "Layers"), self.__viewer3d ) self.__viewer3d_ctrl = QToolBar("3D controls") self.__viewer3d_ctrl.addWidget(ViewerControls(self.__viewer3d.widget())) self.__iface.addToolBar(self.__viewer3d_ctrl) QgsProject.instance().readProject.connect(self.__qgis__project__loaded) self.__qgis__project__loaded() # case of reload def unload(self): for s in self.__shortcuts: s.setParent(None) self.__toolbar and self.__toolbar.setParent(None) self.__menu and self.__menu.setParent(None) self.__viewer3d and self.__viewer3d.setParent(None) self.__viewer3d_ctrl and self.__viewer3d_ctrl.setParent(None) def __add_menu_entry(self, name, callback, enabled=True, help_str=""): act = self.__menu.addAction(name) if callback is not None: act.triggered.connect(callback) act.setEnabled(enabled) act.setToolTip(help_str) else: act.setEnabled(False) act.setToolTip("NOT INMPLEMENTED " + help_str) return act def __create_menu_entries(self): self.__menu.clear() self.__add_menu_entry("New &Project", self.__new_project) self.__add_menu_entry("Import Project", self.__import_project) self.__add_menu_entry("Export Project", self.__export_project, self.project is not None) self.__add_menu_entry("Upgrade Project", self.__upgrade_project) self.__menu.addSeparator() self.__add_menu_entry( "&Import directory", self.__import_data, self.project is not None, "Import data from directory" ) self.__add_menu_entry( "&Import holes", None, #self.__import_holes, self.project is not None and False, "Import hole data from directory" ) self.__add_menu_entry( "Export holes", self.__export_holes, self.project is not None and self.project.has_hole, "Export hole trace in .vtk or .dxf format", ) self.__add_menu_entry( "Import layer", self.__import_layer, self.project is not None, "Import data from selected layer." ) self.__add_menu_entry( "Export layer", self.__export_layer, self.project is not None ) self.__add_menu_entry( "Compute &Mineralization", self.__compute_mineralization, self.project is not None and self.project.has_radiometry, "", ) self.__menu.addSeparator() self.__menu.addSeparator() self.__add_menu_entry( "Create cells", self.__create_cells, self.project is not None and self.project.has_hole, "Create Delaunay triangulation of collar layer.", ) self.__add_menu_entry( "Create subsections", self.__create_sections, self.project is not None and self.project.has_group_cell, "Once cell groups have been defined, create section lines.", ) self.__add_menu_entry( "Refresh selected layers sections", self.__refresh_selected_layers_sections, self.project is not None, "" ) self.__menu.addSeparator() self.__add_menu_entry( "New &Graph", self.__new_graph, self.project is not None, "Create a new graph", ) self.__add_menu_entry( "Delete Graph", self.__delete_graph, self.project is not None and self.project.has_graph ) self.__add_menu_entry( "Add selection to graph nodes", self.__add_selection_to_graph_node, self.project is not None and self.project.has_graph ) self.__add_menu_entry( "Accept graph possible edges", self.__accept_possible_edge, self.project is not None and self.project.has_graph ) self.__add_menu_entry( "Create terminations", self.__create_terminations, self.project is not None and bool(self.__current_graph.currentText()), "Create terminations associated with current graph.", ) self.__menu.addSeparator() self.__add_menu_entry( "Create volumes", self.__create_volumes, self.project is not None and bool(self.__current_graph.currentText()), "Create volumes associated with current graph.", ) self.__add_menu_entry( "Export Volume", self.__export_volume, self.project is not None and bool(self.__current_graph.currentText()), "Export volume of current graph in .obj or .dxf format", ) self.__add_menu_entry( "Export Elementary Volume", self.__export_elementary_volume, self.project is not None and bool(self.__current_graph.currentText()), "Export an elementary volume of current graph in .obj or .dxf format", ) self.__add_menu_entry( "Export Sections", self.__export_sections, self.project is not None and bool(self.__current_graph.currentText()) and self.project.has_section and self.project.has_volume, "Export triangulated section in .obj or .dxf format", ) self.__add_menu_entry( "Export rasters from formation", self.__export_raster_formation, self.project is not None and self.project.has_cell, "Export rasters (DEM, aspect, slope, ruggedness index) from formation", ) self.__add_menu_entry( "Export rasters from collar", self.__export_raster_collar, self.project is not None and self.project.has_cell, "Export rasters (DEM, aspect, slope, ruggedness index) from collar", ) self.__menu.addSeparator() self.__menu.addAction("Help").triggered.connect(self.open_help) def __current_graph_changed(self, graph_id): if self.project is None: return self.__viewer3d.widget().set_graph(graph_id) def __getattr__(self, name): if name == "project": project_name = QgsProject.instance().readEntry( "albion", "project_name", "" )[0] return Project(project_name) if project_name else None else: raise AttributeError(name) def __create_terminations(self): self.project.create_terminations(self.__current_graph.currentText()) self.__viewer3d.widget().refresh_data() self.__refresh_layers("section") def __create_volumes(self): self.project.create_volumes(self.__current_graph.currentText()) self.__viewer3d.widget().refresh_data() def __next_section(self): self.project.next_section(self.__current_section.currentText()) self.__refresh_layers("section") self.__viewer3d.widget().scene.update("section") self.__viewer3d.widget().scene.update("volume_section") self.__viewer3d.widget().update() def __previous_section(self): self.project.previous_section(self.__current_section.currentText()) self.__refresh_layers("section") self.__viewer3d.widget().scene.update("section") self.__viewer3d.widget().scene.update("volume_section") self.__viewer3d.widget().update() def __next_subsection(self): self.project.next_subsection(self.__current_section.currentText()) print("refresh") self.__refresh_layers("section") print("section") self.__viewer3d.widget().scene.update("section") print("volume section") self.__viewer3d.widget().scene.update("volume_section") print("3D update") self.__viewer3d.widget().update() print("done done") def __previous_subsection(self): self.project.previous_subsection(self.__current_section.currentText()) self.__refresh_layers("section") self.__viewer3d.widget().scene.update("section") self.__viewer3d.widget().scene.update("volume_section") self.__viewer3d.widget().update() def __refresh_layers(self, name=None, updateExtent=False): for layer in self.__iface.mapCanvas().layers(): if name is None or layer.name().find(name) != -1: layer.triggerRepaint() def __layer(self, name): lay = None for layer in self.__iface.mapCanvas().layers(): if name is None or layer.name() == name: lay = layer return lay def __current_section_changed(self, section_id): layers = QgsProject.instance().mapLayersByName(u"group_cell") if len(layers): layers[0].setSubsetString("section_id='{}'".format(section_id)) self.__refresh_layers("section") # def __select_next_group(self): # if ( # self.__iface.activeLayer() # and self.__iface.activeLayer().name() == u"cell" # ): # self.__iface.activeLayer().removeSelection() # self.__iface.activeLayer().selectByExpression( # "id in ({})".format(",".join(project.next_group_ids())) # ) # def __create_group(self): if ( self.__iface.activeLayer() and self.__iface.activeLayer().name() == u"cell" ): if self.__iface.activeLayer().selectedFeatureCount(): section = self.__current_section.currentText() self.project.create_group( section, [f["id"] for f in self.__iface.activeLayer().selectedFeatures()], ) self.__iface.activeLayer().removeSelection() self.__refresh_layers("group_cell") def __qgis__project__loaded(self): if self.project is None: return self.__current_graph.clear() self.__current_section.clear() self.__current_section.addItems(self.project.sections()) self.__current_graph.addItems(self.project.graphs()) layers = QgsProject.instance().mapLayersByName("section.anchor") if len(layers): layers[0].editingStopped.connect(self.__update_section_list) self.__viewer3d.widget().resetScene(self.project) # We make sure that corresponding extents are valid when the project # is loaded cell = QgsProject.instance().mapLayersByName("cell") if len(cell): cell[0].updateExtents() section_geom = QgsProject.instance().mapLayersByName("section.geom") if section_geom: section_geom[0].updateExtents() def __update_section_list(self): self.__current_section.clear() self.__current_section.addItems(self.project.sections()) def __upgrade_project(self): project_name, ok = QInputDialog.getText( self.__iface.mainWindow(), "Database name", "Database name:", QLineEdit.Normal, "", ) if not ok: return project = Project(project_name) project.update() QgsProject.instance().writeEntry("albion", "project_name", project.name) QgsProject.instance().writeEntry("albion", "srid", project.srid) self.__qgis__project__loaded() def __new_project(self): fil, __ = QFileDialog.getSaveFileName( None, u"New project name (no space, plain ascii)", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "QGIS poject file (*.qgs)", ) if not fil: return fil = fil if len(fil) > 4 and fil[-4:] == ".qgs" else fil + ".qgs" fil = fil.replace(" ", "_") if len(fil) != len(fil.encode()): self.__iface.messageBar().pushError( "Albion:", "project name may only contain asci character (no accent)" ) return srid, ok = QInputDialog.getText( self.__iface.mainWindow(), "Project SRID", "Project SRID EPSG:", QLineEdit.Normal, "32632", ) if not ok: return srid = int(srid) project_name = str(os.path.split(fil)[1][:-4]) if Project.exists(project_name): if ( QMessageBox.Yes != QMessageBox( QMessageBox.Information, "Delete existing DB", "Database {} exits, do you want to delete it ?".format( project_name ), QMessageBox.Yes | QMessageBox.No, ).exec_() ): self.__iface.messageBar().pushInfo("Albion:", "keeping existing database...") else: Project.delete(project_name) self.__iface.messageBar().pushInfo("Albion:", "creating project...") Project.create(project_name, srid) else: self.__iface.messageBar().pushInfo("Albion:", "creating project...") Project.create(project_name, srid) if os.path.exists(fil): os.remove(fil) # load template open(fil, "w").write( open(resource("template_project.qgs")) .read() .replace("template_project", project_name) .replace("32632", str(srid)) ) self.__iface.newProject() QgsProject.instance().setFileName(fil) QgsProject.instance().read() QgsProject.instance().writeEntry("albion", "project_name", project_name) QgsProject.instance().writeEntry("albion", "srid", srid) QgsProject.instance().write() self.__qgis__project__loaded() def __import_data(self): assert(self.project) dir_ = QFileDialog.getExistingDirectory( None, u"Data directory", QgsProject.instance().readEntry("albion", "last_dir", "")[0], QFileDialog.ShowDirsOnly | QFileDialog.DontUseNativeDialog ) if not dir_: return QgsProject.instance().writeEntry("albion", "last_dir", dir_), progressMessageBar = self.__iface.messageBar().createMessage( "Loading {}...".format(dir_) ) progress = QProgressBar() progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.__iface.messageBar().pushWidget(progressMessageBar) self.project.import_data(dir_, ProgressBar(progress)) #self.project.triangulate() self.project.create_section_view_0_90(4) self.__iface.messageBar().clearWidgets() collar = QgsProject.instance().mapLayersByName("collar") if len(collar): collar[0].reload() collar[0].updateExtents() self.__iface.setActiveLayer(collar[0]) QApplication.instance().processEvents() while self.__iface.mapCanvas().isDrawing(): QApplication.instance().processEvents() self.__iface.zoomToActiveLayer() self.__iface.actionSaveProject().trigger() self.__viewer3d.widget().resetScene(self.project) self.__current_section.clear() self.__current_section.addItems(self.project.sections()) def __import_layer(self): assert(self.project) if self.__iface.activeLayer(): from_idx = None to_idx = None hole_id_idx= None other_idx = [] definitions = [] fields = [] for idx, f in enumerate(self.__iface.activeLayer().fields()): if f.name().lower() == 'from' or f.name().lower() == 'from_': from_idx = idx elif f.name().lower() == 'to' or f.name().lower() == 'to_': to_idx = idx elif f.name().lower() == 'hole_id' or f.name().lower() == 'holeid': hole_id_idx = idx else: other_idx.append(idx) name = f.name().lower().replace(' ', '_') fields.append(name) type_ = 'varchar' if f.typeName() == 'double': type_ = 'double precision' elif f.typeName() == 'integer': type_ = 'integer' definitions.append(name + ' ' + type_) table = { 'NAME': self.__iface.activeLayer().name().lower().replace(' ', '_'), 'FIELDS_DEFINITION': ', '.join(definitions), 'FIELDS': ', '.join(fields), 'SRID': self.project.srid } if from_idx is None or to_idx is None or hole_id_idx is None: self.__iface.messageBar().pushCritical( "Albion", "imported layer must have 'to', 'from' and 'hole_id' fields") return values = [] for f in self.__iface.activeLayer().getFeatures(): values.append((f[hole_id_idx], f[from_idx], f[to_idx]) + tuple((f[i] for i in other_idx))) self.project.add_table(table, values) def __new_graph(self): graph, ok = QInputDialog.getText( self.__iface.mainWindow(), "Graph", "Graph name:", QLineEdit.Normal, "test_graph", ) if not ok: return parent, ok = QInputDialog.getText( self.__iface.mainWindow(), "Parent Graph", "Parent Graph name:", QLineEdit.Normal, "", ) if not ok: return self.project.new_graph(graph, parent) self.__current_graph.addItem(graph) self.__current_graph.setCurrentIndex(self.__current_graph.findText(graph)) def __delete_graph(self): graph, ok = QInputDialog.getText( self.__iface.mainWindow(), "Graph", "Graph name:", QLineEdit.Normal, self.__current_graph.currentText(), ) if not ok: return self.__current_graph.removeItem(self.__current_graph.findText(graph)) self.project.delete_graph(graph) def __add_selection_to_graph_node(self): assert(self.project) #TODO ADD DIALOG TO REMIND USER THE CURRENT GRAPH if ( self.__iface.activeLayer() and self.__iface.activeLayer().selectedFeatures() ): selection = self.__iface.activeLayer().selectedFeatures() graph = self.__current_graph.currentText() if ( QMessageBox.Yes != QMessageBox( QMessageBox.Information, "Adding selected edges", "Do you want to add {} selected edges to {} ?".format( len(selection), graph ), QMessageBox.Yes | QMessageBox.No, ).exec_() ): return self.project.add_to_graph_node(graph, selection) self.__refresh_layers() def __accept_possible_edge(self): assert(self.project) self.project.accept_possible_edge(self.__current_graph.currentText()) def __create_cells(self): assert(self.project) createAlbionRaster = True if self.project.has_cell: createAlbionRaster = False if ( QMessageBox.Yes != QMessageBox( QMessageBox.Information, "Creating cells", "Do you want to replace project cells (your graphs will become invalid) ?", QMessageBox.Yes | QMessageBox.No, ).exec_() ): return self.project.triangulate(createAlbionRaster) self.__refresh_layers() def __create_sections(self): assert(self.project) self.project.create_sections() def __refresh_selected_layers_sections(self): assert(self.project) for l in self.__iface.layerTreeView().selectedLayers(): uri = QgsDataSourceUri(l.dataProvider().dataSourceUri()) table = uri.table() if table.endswith('_section'): table = table[:-8] self.project.refresh_section_geom(table) self.__refresh_layers(table+'_section') def __compute_mineralization(self): MineralizationDialog(self.project).exec_() def __export_volume(self): assert(self.project) fil, __ = QFileDialog.getSaveFileName( None, u"Export volume for current graph", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "File formats (*.dxf *.obj)", ) if not fil: return QgsProject.instance().writeEntry("albion", "last_dir", os.path.dirname(fil)) if fil[-4:] == ".obj": self.project.export_obj(self.__current_graph.currentText(), fil) elif fil[-4:] == ".dxf": self.project.export_dxf(self.__current_graph.currentText(), fil) else: self.__iface.messageBar().pushWarning( "Albion", "unsupported extension for volume export" ) def __export_elementary_volume(self): assert(self.project) layer = self.__layer("cell") if not layer: self.__iface.messageBar().pushWarning( "Albion", "cell layer must be selected" ) return graph = self.__current_graph.currentText() export_widget = ExportElementaryVolume(layer, self.project, graph) export_widget.show() export_widget.exec_() def __export_sections(self): assert(self.project) fil, __ = QFileDialog.getSaveFileName( None, u"Export named sections for current graph", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "File formats (*.dxf *.obj)", ) if not fil: return QgsProject.instance().writeEntry("albion", "last_dir", os.path.dirname(fil)) if fil[-4:] == ".obj": self.project.export_sections_obj(self.__current_graph.currentText(), fil) elif fil[-4:] == ".dxf": self.project.export_sections_dxf(self.__current_graph.currentText(), fil) else: self.__iface.messageBar().pushWarning( "Albion", "unsupported extension for section export" ) def __export_holes(self): assert(self.project) fil, __ = QFileDialog.getSaveFileName( None, u"Export holes", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "File formats (*.dxf *.vtk)", ) if not fil: return QgsProject.instance().writeEntry("albion", "last_dir", os.path.dirname(fil)) if fil[-4:] == ".vtk": self.project.export_holes_vtk(fil) elif fil[-4:] == ".dxf": self.project.export_holes_dxf(fil) else: self.__iface.messageBar().pushWarning("Albion", "unsupported extension for hole export") def __export_layer(self): assert(self.project) table = None for l in self.__iface.layerTreeView().selectedLayers(): uri = QgsDataSourceUri(l.dataProvider().dataSourceUri()) table = uri.table() if table.endswith('_section'): table = table[:-8] break if table is None: self.__iface.messageBar().pushWarning("Albion", "you must select a layer") return fil, __ = QFileDialog.getSaveFileName( None, u"Export layer", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "File formats (*.dxf *.vtk)", ) if not fil: return QgsProject.instance().writeEntry("albion", "last_dir", os.path.dirname(fil)) if fil.endswith('.vtk'): self.project.export_layer_vtk(table, fil) elif fil.endswith('.dxf'): self.project.export_layer_dxf(table, fil) else: self.__iface.messageBar().pushWarning("Albion", "unsupported extension for hole export") def __import_project(self): fil, __ = QFileDialog.getOpenFileName( None, u"Import project from file", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "File formats (*.zip)", ) if not fil: return QgsProject.instance().writeEntry("albion", "last_dir", os.path.dirname(fil)), if fil[-4:] != ".zip": self.__iface.messageBar().pushWarning( "Albion", "unsupported extension for import" ) project_name = os.path.split(fil)[1][:-4] dir_ = tempfile.mkdtemp() with zipfile.ZipFile(fil, "r") as z: z.extractall(dir_) dump = find_in_dir(dir_, ".dump") prj = find_in_dir(dir_, ".qgs") self.__iface.messageBar().pushInfo( "Albion", "loading {} from {}".format(project_name, dump) ) dbname = os.path.splitext(os.path.basename(dump))[0] if Project.exists(dbname): if ( QMessageBox.Yes != QMessageBox( QMessageBox.Information, "Delete existing DB", "Database {} exits, to you want to delete it ?".format( dbname ), QMessageBox.Yes | QMessageBox.No, ).exec_() ): return Project.delete(dbname) project = Project.import_(dbname, dump) QgsProject.instance().read(prj) def __export_project(self): if self.project is None: return fil, __ = QFileDialog.getSaveFileName( None, u"Export project", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "Data files(*.zip)", ) if not fil: return QgsProject.instance().writeEntry("albion", "last_dir", os.path.dirname(fil)), if os.path.exists(fil): os.remove(fil) with zipfile.ZipFile(fil, "w") as project: dump = tempfile.mkstemp()[1] self.project.export(dump) project.write(dump, self.project.name + ".dump") project.write( QgsProject.instance().fileName(), os.path.split(QgsProject.instance().fileName())[1], ) def __export_raster_formation(self): ret = ExportRasterFormationDialog(self.project).exec_() def __export_raster_collar(self): ret = ExportRasterCollarDialog(self.project).exec_() #def __log_strati_clicked(self): # # @todo switch behavior when in section view -> ortho # self.__click_tool = QgsMapToolEmitPoint(self.__iface.mapCanvas()) # self.__iface.mapCanvas().setMapTool(self.__click_tool) # self.__click_tool.canvasClicked.connect(self.__map_log_clicked) #def __map_log_clicked(self, point, button): # self.__click_tool.setParent(None) # self.__click_tool = None # if self.project is None: # self.__log_strati and self.__log_strati.setParent(None) # self.__log_strati = None # return # if self.__log_strati is None: # self.__log_strati = QDockWidget("Stratigraphic Log") # self.__log_strati.setWidget(BoreHoleWindow(self.project)) # self.__iface.addDockWidget(Qt.LeftDockWidgetArea, self.__log_strati) # self.__iface.mainWindow().tabifyDockWidget( # self.__iface.mainWindow().findChild(QDockWidget, "Layers"), # self.__log_strati, # ) # res = self.project.closest_hole_id(point.x(), point.y()) # if res: # self.__log_strati.widget().scene.set_current_id(res) # self.__log_strati.show() # self.__log_strati.raise_() def __line_from_selection(self): if ( self.__iface.activeLayer() and self.__iface.activeLayer().name() == u"collar" and self.__iface.activeLayer().selectedFeatures() ): collar = self.__iface.activeLayer() selection = collar.selectedFeatures() if len(selection) < 2: return def align(l): assert len(l) >= 2 res = numpy.array(l[:2]) for p in l[2:]: u, v = res[0] - res[1], p - res[1] if numpy.dot(u, v) < 0: res[1] = p elif numpy.dot(u, u) < numpy.dot(v, v): res[0] = p # align with ref direction sqrt2 = math.sqrt(2.0) / 2 l = l[numpy.argsort(numpy.dot(l - res[0], res[1] - res[0]))] d = numpy.array(l[-1] - l[0]) dr = numpy.array([(0, 1), (sqrt2, sqrt2), (1, 0), (sqrt2, -sqrt2)]) i = numpy.argmax(numpy.abs(dr.dot(d))) return l if (dr.dot(d))[i] > 0 else l[::-1] line = LineString( align(numpy.array([f.geometry().asPoint() for f in selection])) ) collar.removeSelection() return line else: return None def __add_section_from_selection(self): assert(self.project) line = self.__line_from_selection() if line: self.project.add_named_section(self.__current_section.currentText(), line) self.__refresh_layers("named_section") def __section_from_selection(self): assert(self.project) line = self.__line_from_selection() if line: self.project.set_section_geom(self.__current_section.currentText(), line) self.__refresh_layers("section") self.__viewer3d.widget().scene.update("section") self.__viewer3d.widget().scene.update("volume_section") self.__viewer3d.widget().update() def open_help(self): QDesktopServices.openUrl( QUrl.fromLocalFile( os.path.join( os.path.dirname(__file__), "doc", "build", "html", "index.html" ) ) )
class DBManager(QMainWindow): def __init__(self, iface, parent=None): QMainWindow.__init__(self, parent) self.setAttribute(Qt.WA_DeleteOnClose) self.setupUi() self.iface = iface # restore the window state settings = QgsSettings() self.restoreGeometry(settings.value("/DB_Manager/mainWindow/geometry", QByteArray(), type=QByteArray)) self.restoreState(settings.value("/DB_Manager/mainWindow/windowState", QByteArray(), type=QByteArray)) self.tabs.currentChanged.connect(self.tabChanged) self.tree.selectedItemChanged.connect(self.itemChanged) self.itemChanged(None) def closeEvent(self, e): self.unregisterAllActions() # clear preview, this will delete the layer in preview tab self.preview.loadPreview(None) # save the window state settings = QgsSettings() settings.setValue("/DB_Manager/mainWindow/windowState", self.saveState()) settings.setValue("/DB_Manager/mainWindow/geometry", self.saveGeometry()) QMainWindow.closeEvent(self, e) def refreshItem(self, item=None): with OverrideCursor(Qt.WaitCursor): try: if item is None: item = self.tree.currentItem() self.tree.refreshItem(item) # refresh item children in the db tree except BaseError as e: DlgDbError.showError(e, self) def itemChanged(self, item): with OverrideCursor(Qt.WaitCursor): try: self.reloadButtons() # clear preview, this will delete the layer in preview tab self.preview.loadPreview(None) self.refreshTabs() except BaseError as e: DlgDbError.showError(e, self) def reloadButtons(self): db = self.tree.currentDatabase() if not hasattr(self, '_lastDb'): self._lastDb = db elif db == self._lastDb: return # remove old actions if self._lastDb is not None: self.unregisterAllActions() # add actions of the selected database self._lastDb = db if self._lastDb is not None: self._lastDb.registerAllActions(self) def tabChanged(self, index): with OverrideCursor(Qt.WaitCursor): try: self.refreshTabs() except BaseError as e: DlgDbError.showError(e, self) def refreshTabs(self): index = self.tabs.currentIndex() item = self.tree.currentItem() table = self.tree.currentTable() # enable/disable tabs self.tabs.setTabEnabled(self.tabs.indexOf(self.table), table is not None) self.tabs.setTabEnabled(self.tabs.indexOf(self.preview), table is not None and table.type in [table.VectorType, table.RasterType] and table.geomColumn is not None) # show the info tab if the current tab is disabled if not self.tabs.isTabEnabled(index): self.tabs.setCurrentWidget(self.info) current_tab = self.tabs.currentWidget() if current_tab == self.info: self.info.showInfo(item) elif current_tab == self.table: self.table.loadData(item) elif current_tab == self.preview: self.preview.loadPreview(item) def refreshActionSlot(self): self.info.setDirty() self.table.setDirty() self.preview.setDirty() self.refreshItem() def importActionSlot(self): db = self.tree.currentDatabase() if db is None: self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."), QgsMessageBar.INFO, self.iface.messageTimeout()) return outUri = db.uri() schema = self.tree.currentSchema() if schema: outUri.setDataSource(schema.name, "", "", "") from .dlg_import_vector import DlgImportVector dlg = DlgImportVector(None, db, outUri, self) dlg.exec_() def exportActionSlot(self): table = self.tree.currentTable() if table is None: self.infoBar.pushMessage(self.tr("Select the table you want export to file."), QgsMessageBar.INFO, self.iface.messageTimeout()) return inLayer = table.toMapLayer() if inLayer.type() != QgsMapLayer.VectorLayer: self.infoBar.pushMessage( self.tr("Select a vector or a tabular layer you want export."), QgsMessageBar.WARNING, self.iface.messageTimeout()) return from .dlg_export_vector import DlgExportVector dlg = DlgExportVector(inLayer, table.database(), self) dlg.exec_() inLayer.deleteLater() def runSqlWindow(self): db = self.tree.currentDatabase() if db is None: self.infoBar.pushMessage(self.tr("No database selected or you are not connected to it."), QgsMessageBar.INFO, self.iface.messageTimeout()) # force displaying of the message, it appears on the first tab (i.e. Info) self.tabs.setCurrentIndex(0) return from .dlg_sql_window import DlgSqlWindow query = DlgSqlWindow(self.iface, db, self) dbname = db.connection().connectionName() tabname = self.tr("Query ({0})").format(dbname) index = self.tabs.addTab(query, tabname) self.tabs.setTabIcon(index, db.connection().icon()) self.tabs.setCurrentIndex(index) query.nameChanged.connect(functools.partial(self.update_query_tab_name, index, dbname)) def runSqlLayerWindow(self, layer): from .dlg_sql_layer_window import DlgSqlLayerWindow query = DlgSqlLayerWindow(self.iface, layer, self) lname = layer.name() tabname = self.tr("Layer ({0})").format(lname) index = self.tabs.addTab(query, tabname) # self.tabs.setTabIcon(index, db.connection().icon()) self.tabs.setCurrentIndex(index) def update_query_tab_name(self, index, dbname, queryname): if not queryname: queryname = self.tr("Query") tabname = u"%s (%s)" % (queryname, dbname) self.tabs.setTabText(index, tabname) def showSystemTables(self): self.tree.showSystemTables(self.actionShowSystemTables.isChecked()) def registerAction(self, action, menuName, callback=None): """ register an action to the manager's main menu """ if not hasattr(self, '_registeredDbActions'): self._registeredDbActions = {} if callback is not None: def invoke_callback(x): return self.invokeCallback(callback) if menuName is None or menuName == "": self.addAction(action) if menuName not in self._registeredDbActions: self._registeredDbActions[menuName] = list() self._registeredDbActions[menuName].append(action) if callback is not None: action.triggered.connect(invoke_callback) return True # search for the menu actionMenu = None helpMenuAction = None for a in self.menuBar.actions(): if not a.menu() or a.menu().title() != menuName: continue if a.menu() != self.menuHelp: helpMenuAction = a actionMenu = a break # not found, add a new menu before the help menu if actionMenu is None: menu = QMenu(menuName, self) if helpMenuAction is not None: actionMenu = self.menuBar.insertMenu(helpMenuAction, menu) else: actionMenu = self.menuBar.addMenu(menu) menu = actionMenu.menu() menuActions = menu.actions() # get the placeholder's position to insert before it pos = 0 for pos in range(len(menuActions)): if menuActions[pos].isSeparator() and menuActions[pos].objectName().endswith("_placeholder"): menuActions[pos].setVisible(True) break if pos < len(menuActions): before = menuActions[pos] menu.insertAction(before, action) else: menu.addAction(action) actionMenu.setVisible(True) # show the menu if menuName not in self._registeredDbActions: self._registeredDbActions[menuName] = list() self._registeredDbActions[menuName].append(action) if callback is not None: action.triggered.connect(invoke_callback) return True def invokeCallback(self, callback, *params): """ Call a method passing the selected item in the database tree, the sender (usually a QAction), the plugin mainWindow and optionally additional parameters. This method takes care to override and restore the cursor, but also catches exceptions and displays the error dialog. """ with OverrideCursor(Qt.WaitCursor): try: callback(self.tree.currentItem(), self.sender(), self, *params) except BaseError as e: # catch database errors and display the error dialog DlgDbError.showError(e, self) def unregisterAction(self, action, menuName): if not hasattr(self, '_registeredDbActions'): return if menuName is None or menuName == "": self.removeAction(action) if menuName in self._registeredDbActions: if self._registeredDbActions[menuName].count(action) > 0: self._registeredDbActions[menuName].remove(action) action.deleteLater() return True for a in self.menuBar.actions(): if not a.menu() or a.menu().title() != menuName: continue menu = a.menu() menuActions = menu.actions() menu.removeAction(action) if menu.isEmpty(): # hide the menu a.setVisible(False) if menuName in self._registeredDbActions: if self._registeredDbActions[menuName].count(action) > 0: self._registeredDbActions[menuName].remove(action) # hide the placeholder if there're no other registered actions if len(self._registeredDbActions[menuName]) <= 0: for i in range(len(menuActions)): if menuActions[i].isSeparator() and menuActions[i].objectName().endswith("_placeholder"): menuActions[i].setVisible(False) break action.deleteLater() return True return False def unregisterAllActions(self): if not hasattr(self, '_registeredDbActions'): return for menuName in self._registeredDbActions: for action in list(self._registeredDbActions[menuName]): self.unregisterAction(action, menuName) del self._registeredDbActions def close_tab(self, index): widget = self.tabs.widget(index) if widget not in [self.info, self.table, self.preview]: self.tabs.removeTab(index) widget.deleteLater() def setupUi(self): self.setWindowTitle(self.tr("DB Manager")) self.setWindowIcon(QIcon(":/db_manager/icon")) self.resize(QSize(700, 500).expandedTo(self.minimumSizeHint())) # create central tab widget and add the first 3 tabs: info, table and preview self.tabs = QTabWidget() self.info = InfoViewer(self) self.tabs.addTab(self.info, self.tr("Info")) self.table = TableViewer(self) self.tabs.addTab(self.table, self.tr("Table")) self.preview = LayerPreview(self) self.tabs.addTab(self.preview, self.tr("Preview")) self.setCentralWidget(self.tabs) # display close button for all tabs but the first 3 ones, i.e. # HACK: just hide the close button where not needed (GS) self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_tab) tabbar = self.tabs.tabBar() for i in range(3): btn = tabbar.tabButton(i, QTabBar.RightSide) if tabbar.tabButton(i, QTabBar.RightSide) else tabbar.tabButton(i, QTabBar.LeftSide) btn.resize(0, 0) btn.hide() # Creates layout for message bar self.layout = QGridLayout(self.info) self.layout.setContentsMargins(0, 0, 0, 0) spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.layout.addItem(spacerItem, 1, 0, 1, 1) # init messageBar instance self.infoBar = QgsMessageBar(self.info) sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.infoBar.setSizePolicy(sizePolicy) self.layout.addWidget(self.infoBar, 0, 0, 1, 1) # create database tree self.dock = QDockWidget("Tree", self) self.dock.setObjectName("DB_Manager_DBView") self.dock.setFeatures(QDockWidget.DockWidgetMovable) self.tree = DBTree(self) self.dock.setWidget(self.tree) self.addDockWidget(Qt.LeftDockWidgetArea, self.dock) # create status bar self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) # create menus self.menuBar = QMenuBar(self) self.menuDb = QMenu(self.tr("&Database"), self) self.menuBar.addMenu(self.menuDb) self.menuSchema = QMenu(self.tr("&Schema"), self) actionMenuSchema = self.menuBar.addMenu(self.menuSchema) self.menuTable = QMenu(self.tr("&Table"), self) actionMenuTable = self.menuBar.addMenu(self.menuTable) self.menuHelp = None # QMenu(self.tr("&Help"), self) # actionMenuHelp = self.menuBar.addMenu(self.menuHelp) self.setMenuBar(self.menuBar) # create toolbar self.toolBar = QToolBar("Default", self) self.toolBar.setObjectName("DB_Manager_ToolBar") self.addToolBar(self.toolBar) # create menus' actions # menu DATABASE sep = self.menuDb.addSeparator() sep.setObjectName("DB_Manager_DbMenu_placeholder") sep.setVisible(False) self.actionRefresh = self.menuDb.addAction(QIcon(":/db_manager/actions/refresh"), self.tr("&Refresh"), self.refreshActionSlot, QKeySequence("F5")) self.actionSqlWindow = self.menuDb.addAction(QIcon(":/db_manager/actions/sql_window"), self.tr("&SQL window"), self.runSqlWindow, QKeySequence("F2")) self.menuDb.addSeparator() self.actionClose = self.menuDb.addAction(QIcon(), self.tr("&Exit"), self.close, QKeySequence("CTRL+Q")) # menu SCHEMA sep = self.menuSchema.addSeparator() sep.setObjectName("DB_Manager_SchemaMenu_placeholder") sep.setVisible(False) actionMenuSchema.setVisible(False) # menu TABLE sep = self.menuTable.addSeparator() sep.setObjectName("DB_Manager_TableMenu_placeholder") sep.setVisible(False) self.actionImport = self.menuTable.addAction(QIcon(":/db_manager/actions/import"), self.tr("&Import layer/file"), self.importActionSlot) self.actionExport = self.menuTable.addAction(QIcon(":/db_manager/actions/export"), self.tr("&Export to file"), self.exportActionSlot) self.menuTable.addSeparator() #self.actionShowSystemTables = self.menuTable.addAction(self.tr("Show system tables/views"), self.showSystemTables) #self.actionShowSystemTables.setCheckable(True) #self.actionShowSystemTables.setChecked(True) actionMenuTable.setVisible(False) # add actions to the toolbar self.toolBar.addAction(self.actionRefresh) self.toolBar.addAction(self.actionSqlWindow) self.toolBar.addAction(self.actionImport) self.toolBar.addAction(self.actionExport)
def add_tool_buttons(self): """ Add toolbar buttons of add, edit and delete buttons. :return: None :rtype: NoneType """ tool_buttons = QToolBar() tool_buttons.setObjectName('form_toolbar') tool_buttons.setIconSize(QSize(16, 16)) self.addSTR = QAction(GuiUtils.get_icon('add.png'), QApplication.translate('ViewSTRWidget', 'Add'), self) self.editSTR = QAction(GuiUtils.get_icon('edit.png'), QApplication.translate('ViewSTRWidget', 'Edit'), self) self.deleteSTR = QAction( GuiUtils.get_icon('remove.png'), QApplication.translate('ViewSTRWidget', 'Remove'), self) tool_buttons.addAction(self.addSTR) tool_buttons.addAction(self.editSTR) tool_buttons.addAction(self.deleteSTR) self.toolbarVBox.addWidget(tool_buttons)