def do_aeag_menu(self,
                     fileName,
                     who,
                     menu=None,
                     visible=None,
                     expanded=None):
        self.canvas.freeze(True)
        self.canvas.setRenderFlag(False)
        group = None
        theLayer = None
        groupName = None
        QgsApplication.setOverrideCursor(Qt.WaitCursor)

        try:
            if (type(menu.parentWidget()) == QMenu or type(menu.parentWidget())
                    == QWidget) and self.optionCreateGroup:
                groupName = menu.title().replace("&", "")
                group = QgsProject.instance().layerTreeRoot().findGroup(
                    groupName)
                if group is None:
                    group = QgsProject.instance().layerTreeRoot().addGroup(
                        groupName)

            # load all layers
            if fileName is None and who is None and self.optionLoadAll:
                for action in menu.actions():
                    if ((action.text() != self.tr("&Load all"))
                            and (action.text() != "Load all")):
                        action.trigger()
            else:
                # read QGis project
                doc = QtXml.QDomDocument()
                xml = QFile(fileName)
                if xml.open(QIODevice.ReadOnly | QIODevice.Text):
                    doc.setContent(xml)

                # is project in relative path ?
                absolute = self.isAbsolute(doc)

                node = getFirstChildByTagNameValue(doc.documentElement(),
                                                   "maplayer", "id", who)
                if node:
                    idNode = node.namedItem("id")
                    layerType = node.toElement().attribute("type", "vector")
                    # give it a new id (for multiple import)
                    import re
                    newLayerId = "L%s" % re.sub("[{}-]", "",
                                                QUuid.createUuid().toString())
                    try:
                        idNode.firstChild().toText().setData(newLayerId)
                    except:
                        pass

                    # if relative path, adapt datasource
                    if not absolute:
                        try:
                            datasourceNode = node.namedItem("datasource")
                            ds = datasourceNode.firstChild().toText().data()
                            providerNode = node.namedItem("provider")
                            provider = providerNode.firstChild().toText().data(
                            )

                            if provider == "ogr" and (ds.find(".") == 0):
                                projectpath = QFileInfo(
                                    os.path.realpath(fileName)).path()
                                newlayerpath = projectpath + "/" + ds
                                datasourceNode.firstChild().toText().setData(
                                    newlayerpath)
                        except:
                            pass

                    # read modified layer node
                    if self.optionCreateGroup and group is not None:
                        """# sol 1 bug : layer incomplete
                        # because of API strange behaviour, we clone the layer... 
                        theLayer = QgsProject.instance().mapLayer(newLayerId)
                        cloneLayer = theLayer.clone()
                        # removing the first
                        QgsProject.instance().removeMapLayer(newLayerId)
                        # adding the clone...
                        treeNode = group.addLayer(cloneLayer)
                        treeNode.setExpanded(expanded)
                        treeNode.setItemVisibilityChecked(visible)"""

                        # solution 2, ok !
                        if layerType == "raster":
                            theLayer = QgsRasterLayer()
                        else:
                            theLayer = QgsVectorLayer()

                        theLayer.readLayerXml(node.toElement(),
                                              QgsReadWriteContext())
                        # needed
                        QgsProject.instance().addMapLayer(theLayer, False)
                        # add to group
                        treeNode = group.addLayer(theLayer)
                        treeNode.setExpanded(expanded)
                        treeNode.setItemVisibilityChecked(visible)
                    else:
                        # create layer
                        QgsProject.instance().readLayer(node)

        except Exception as e:
            QgsMessageLog.logMessage(
                'Menu from layer: Invalid ' +
                (fileName if fileName is not None else ""), 'Extensions')
            for m in e.args:
                QgsMessageLog.logMessage(m, 'Extensions')

        self.canvas.freeze(False)
        self.canvas.setRenderFlag(True)
        self.canvas.refresh()
        QgsApplication.restoreOverrideCursor()
    def addLayer(self,
                 uri,
                 fileName,
                 layerId,
                 group=None,
                 visible=False,
                 expanded=False):
        theLayer = None

        # read QGIS project
        doc, _ = self.getQgsDoc(fileName)

        # is project in relative path ?
        absolute = is_absolute(doc)
        trusted = project_trusted(doc)

        node = getFirstChildByTagNameValue(doc.documentElement(), "maplayer",
                                           "id", layerId)
        node = node.cloneNode()
        if node:
            idNode = node.namedItem("id")
            layerType = node.toElement().attribute("type", "vector")
            # give it a new id (for multiple import)
            newLayerId = "L%s" % re.sub("[{}-]", "",
                                        QUuid.createUuid().toString())
            try:
                idNode.firstChild().toText().setData(newLayerId)
            except Exception:
                pass

            # if relative path, adapt datasource
            if not absolute:
                try:
                    datasourceNode = node.namedItem("datasource")
                    ds = datasourceNode.firstChild().toText().data()
                    providerNode = node.namedItem("provider")
                    provider = providerNode.firstChild().toText().data()

                    if provider in ["ogr", "gdal"] and (ds.find(".") == 0):
                        projectpath = QFileInfo(uri).path()
                        newlayerpath = projectpath + "/" + ds
                        datasourceNode.firstChild().toText().setData(
                            newlayerpath)
                except Exception:
                    pass

            # read modified layer node
            if self.optionCreateGroup and group is not None:
                if layerType == "raster":
                    theLayer = QgsRasterLayer()
                else:
                    theLayer = QgsVectorLayer()
                    theLayer.setReadExtentFromXml(trusted)

                theLayer.readLayerXml(node.toElement(), QgsReadWriteContext())

                # Special process if the plugin "DB Style Manager" is installed
                flag = "use_db_style_manager_in_custom_menu" in os.environ
                if flag and "db-style-manager" in plugins:
                    try:
                        plugins["db-style-manager"].load_style_from_database(
                            theLayer)
                    except Exception:
                        self.log("DB-Style-Manager failed to load the style.")

                # needed
                QgsProject.instance().addMapLayer(theLayer, False)

                # add to group
                treeNode = group.insertLayer(0, theLayer)
                treeNode.setExpanded(expanded)
                treeNode.setItemVisibilityChecked(visible)
            else:
                # create layer
                theLayer = QgsProject.instance().readLayer(node)

            return QgsProject.instance().mapLayer(newLayerId)

        else:
            self.log("{} not found".format(layerId))

        return None