def update_model(self, model, schema, profile): """ Update the model by retrieving the profile given in database """ menudict = {} with self.transaction(): cur = self.connection.cursor() select = """ select name, profile, model_index, datasource_uri from {}.{} where profile = '{}' """.format(schema, self.table, profile) cur.execute(select) rows = cur.fetchall() model.clear() for name, profile, model_index, datasource_uri in self.sortby_modelindex( rows): menu = model.invisibleRootItem() indexes = json.loads(model_index) parent = '' for idx, subname in indexes[:-1]: parent += '{}-{}/'.format(idx, subname) if parent in menudict: # already created entry menu = menudict[parent] continue # create menu item = QStandardItem(subname) uri_struct = QgsMimeDataUtils.Uri(datasource_uri) item.setData(uri_struct) item.setIcon( QIcon(':/plugins/MenuBuilder/resources/menu.svg')) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled | Qt.ItemIsEditable) item.setWhatsThis("menu") menu.appendRow(item) menudict[parent] = item # set current menu to the new created item menu = item # add leaf (layer item) item = QStandardItem(name) uri_struct = QgsMimeDataUtils.Uri(datasource_uri) # fix layer name instead of table name # usefull when the layer has been renamed in menu uri_struct.name = name if uri_struct.providerKey in ICON_MAPPER: item.setIcon(QIcon(ICON_MAPPER[uri_struct.providerKey])) item.setData(uri_struct) # avoid placing dragged layers on it item.setDropEnabled(False) if uri_struct.providerKey == 'postgres': # set tooltip to postgres comment comment = self.get_table_comment(uri_struct.uri) item.setToolTip(comment) menudict[parent].appendRow(item)
def mimeData(self, indexes): lst = QgsMimeDataUtils.UriList for index in indexes: if index.isValid(): if index.type() == QgsDataItem.Project: mimeData = QMimeData() url = QUrl.fromLocalFile(index.path()) mimeData.setUrls([url]) return mimeData if index.type() == QgsDataItem.Layer: lst.append(QgsMimeDataUtils.Uri(index)) return QgsMimeDataUtils.encodeUriList(lst)
def mimeUri(self): u = QgsMimeDataUtils.Uri() u.layerType = "custom" u.providerKey = "processing" u.name = self.name() u.uri = self.path() return u
def dropMimeData(self, mimedata, action, row, column, parentIndex): """ Handles the dropping of an item onto the model. De-serializes the data and inserts it into the model. """ # decode data using qgis helpers uri_list = QgsMimeDataUtils.decodeUriList(mimedata) if not uri_list: return False # find parent item dropParent = self.itemFromIndex(parentIndex) if not dropParent: return False # each uri will become a new item for uri in uri_list: item = QStandardItem(uri.name) item.setData(uri) # avoid placing dragged layers on it item.setDropEnabled(False) if uri.providerKey in ICON_MAPPER: item.setIcon(QIcon(ICON_MAPPER[uri.providerKey])) dropParent.appendRow(item) dropParent.emitDataChanged() return True
def mimeUri(self): # pylint: disable=missing-docstring u = QgsMimeDataUtils.Uri() u.layerType = "custom" u.providerKey = "esri_mxd" u.name = self.name() u.uri = self.path() return u
def mimeUri(self): # pylint: disable=missing-docstring if not self.bookmark: u = QgsMimeDataUtils.Uri() u.layerType = "custom" u.providerKey = "esri_dat" u.name = self.name() u.uri = self.path() return u else: u = QgsMimeDataUtils.Uri() u.layerType = "custom" u.providerKey = "bookmark" u.name = self.name() doc = QDomDocument() doc.appendChild(self.bookmark.writeXml(doc)) u.uri = doc.toString() return u
def dropMimeData(self, data, action, row, column, parent): global isImportVectorAvail if action == Qt.IgnoreAction: return True # vectors/tables to be imported must be dropped on connected db, schema or table canImportLayer = isImportVectorAvail and parent.isValid() and \ (isinstance(parent.internalPointer(), (SchemaItem, TableItem)) or (isinstance(parent.internalPointer(), ConnectionItem) and parent.internalPointer().populated)) added = 0 if data.hasUrls(): for u in data.urls(): filename = u.toLocalFile() if filename == "": continue if self.hasSpatialiteSupport: from .db_plugins.spatialite.connector import SpatiaLiteDBConnector if SpatiaLiteDBConnector.isValidDatabase(filename): # retrieve the SL plugin tree item using its path index = self._rPath2Index(["spatialite"]) if not index.isValid(): continue item = index.internalPointer() conn_name = QFileInfo(filename).fileName() uri = QgsDataSourceURI() uri.setDatabase(filename) item.getItemData().addConnection(conn_name, uri) item.changed.emit() added += 1 continue if canImportLayer: if QgsRasterLayer.isValidRasterFileName(filename): layerType = 'raster' providerKey = 'gdal' else: layerType = 'vector' providerKey = 'ogr' layerName = QFileInfo(filename).completeBaseName() if self.importLayer(layerType, providerKey, layerName, filename, parent): added += 1 if data.hasFormat(self.QGIS_URI_MIME): for uri in QgsMimeDataUtils.decodeUriList(data): if canImportLayer: if self.importLayer(uri.layerType, uri.providerKey, uri.name, uri.uri, parent): added += 1 return added > 0
def dropMimeData(self, data, action, row, column, parent): global isImportVectorAvail if action == Qt.IgnoreAction: return True # vectors/tables to be imported must be dropped on connected db, schema or table canImportLayer = isImportVectorAvail and parent.isValid() and \ (isinstance(parent.internalPointer(), (SchemaItem, TableItem)) or (isinstance(parent.internalPointer(), ConnectionItem) and parent.internalPointer().populated)) added = 0 if data.hasUrls(): for u in data.urls(): filename = u.toLocalFile() if filename == "": continue if self.hasSpatialiteSupport: from .db_plugins.spatialite.connector import SpatiaLiteDBConnector if SpatiaLiteDBConnector.isValidDatabase(filename): # retrieve the SL plugin tree item using its path index = self._rPath2Index(["spatialite"]) if not index.isValid(): continue item = index.internalPointer() conn_name = QFileInfo(filename).fileName() uri = QgsDataSourceUri() uri.setDatabase(filename) item.getItemData().addConnection(conn_name, uri) item.changed.emit() added += 1 continue if canImportLayer: if QgsRasterLayer.isValidRasterFileName(filename): layerType = 'raster' providerKey = 'gdal' else: layerType = 'vector' providerKey = 'ogr' layerName = QFileInfo(filename).completeBaseName() if self.importLayer(layerType, providerKey, layerName, filename, parent): added += 1 if data.hasFormat(self.QGIS_URI_MIME): for uri in QgsMimeDataUtils.decodeUriList(data): if canImportLayer: if self.importLayer(uri.layerType, uri.providerKey, uri.name, uri.uri, parent): added += 1 return added > 0
def getUriFromBrowser(self,index): uriItem = self.browserModel.dataItem(index) uri_list = QgsMimeDataUtils.decodeUriList(self.browserModel.mimeData([index])) try: #print uri_list[0].providerKey,uri_list[0].uri self.result = (uri_list[0].layerType,uri_list[0].providerKey,uri_list[0].uri) self.close() self.acceptedFlag = True except: #print "NO VALID URI" self.result = (None,None,None)
def mimeData(self, indexes): """ Used to serialize data """ if not indexes: return items = [self.itemFromIndex(idx) for idx in indexes] if not items: return if not all(it.data() for it in items): return # reencode items mimedata = QgsMimeDataUtils.encodeUriList([item.data() for item in items]) return mimedata
def on_layer_selected(self, index): """ Triggered on selecting a layer """ is_layer_compatible = False self.uri = QgsMimeDataUtils.Uri() if index.isValid(): item = self.browser_proxy_model.dataItem(index) if item: if issubclass(item.__class__, QgsLayerItem): is_layer_compatible = True self.uri = item.mimeUri() self.buttonBox.button( QDialogButtonBox.Ok).setEnabled(is_layer_compatible)
def get_valid_mime_uri(layer_name, uri, wkb_type): """ Gross method to force a valid layer path, only used for very old QGIS versions """ if QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.NullGeometry: layer_type = QgsMapLayer.RasterLayer else: layer_type = QgsMapLayer.VectorLayer if QThread.currentThread() == QCoreApplication.instance().thread(): from .datasourceselectdialog import DataSourceSelectDialog # pylint: disable=import-outside-toplevel dlg = DataSourceSelectDialog(layer_name=layer_name, original_uri=uri, layer_type=layer_type) if dlg.exec_(): return dlg.uri # use default dummy path - QGIS 3.4 will crash on invalid layer sources otherwise uri = QgsMimeDataUtils.Uri() if QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.PointGeometry: file = 'dummy_points.shp' elif QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.LineGeometry: file = 'dummy_lines.shp' elif QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.PolygonGeometry: file = 'dummy_polygon.shp' elif QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.NullGeometry: file = 'dummy_raster.tif' else: # ??? file = 'dummy_points.shp' path = os.path.dirname(os.path.abspath(__file__)) uri.uri = os.path.realpath(os.path.join(path, '..', '..', file)).replace('\\', '/') uri.providerKey = 'ogr' return uri
def testQgsMimeDataUri(self): d = QgsMimeDataUtils.Uri() d.uri = 'my_uri' d.providerKey = 'my_provider' self.assertEqual(d.__repr__(), "<QgsMimeDataUtils::Uri (my_provider): my_uri>")
def load_menus(self, profile=None, schema=None): """ Load menus in the main windows qgis bar """ if not schema: schema = self.combo_schema.currentText() if not profile: profile = self.combo_profile.currentText() # remove previous menus for menu in self.uiparent.menus: self.uiparent.iface.mainWindow().menuBar().removeAction( menu.menuAction()) with self.transaction(): cur = self.connection.cursor() select = """ select name, profile, model_index, datasource_uri from {}.{} where profile = '{}' """.format(schema, self.table, profile) cur.execute(select) rows = cur.fetchall() # item accessor ex: '0-menu/0-submenu/1-item/' menudict = {} # reference to parent item parent = '' # reference to qgis main menu bar menubar = self.uiparent.iface.mainWindow().menuBar() for name, profile, model_index, datasource_uri in self.sortby_modelindex( rows): uri_struct = QgsMimeDataUtils.Uri(datasource_uri) indexes = json.loads(model_index) # root menu parent = '{}-{}/'.format(indexes[0][0], indexes[0][1]) if parent not in menudict: menu = QMenu(self.uiparent.iface.mainWindow()) self.uiparent.menus.append(menu) menu.setObjectName(indexes[0][1]) menu.setTitle(indexes[0][1]) menubar.insertMenu( self.uiparent.iface.firstRightStandardMenu().menuAction(), menu) menudict[parent] = menu else: # menu already there menu = menudict[parent] for idx, subname in indexes[1:-1]: # intermediate submenus parent += '{}-{}/'.format(idx, subname) if parent not in menudict: submenu = menu.addMenu(subname) submenu.setObjectName(subname) submenu.setTitle(subname) menu = submenu # store it for later use menudict[parent] = menu continue # already treated menu = menudict[parent] # last item = layer layer = QAction(name, self.uiparent.iface.mainWindow()) if uri_struct.providerKey in ICON_MAPPER: layer.setIcon(QIcon(ICON_MAPPER[uri_struct.providerKey])) if uri_struct.providerKey == 'postgres': # set tooltip to postgres comment comment = self.get_table_comment(uri_struct.uri) layer.setStatusTip(comment) layer.setToolTip(comment) layer.setData(uri_struct.uri) layer.setWhatsThis(uri_struct.providerKey) layer.triggered.connect(self.layer_handler[uri_struct.layerType]) menu.addAction(layer)