from qgis.PyQt.QtCore import (QCoreApplication, QEvent, QFileInfo, QItemSelectionModel, QObject, QSettings, QSize, QSizeF, Qt, QTimer, pyqtSignal)
from qgis.PyQt.QtWidgets import (QAbstractItemView, QAction, QApplication, QButtonGroup, QCheckBox, QComboBox, QDialog, QDialogButtonBox, QFileDialog,
                                 QGraphicsScene, QGraphicsView, QGroupBox, QInputDialog, QLabel, QListView, QMdiSubWindow, QMenu, QPushButton, QSizePolicy,
                                 QScrollArea, QSlider, QTabWidget, QTableView, QToolBar, QToolTip, QVBoxLayout, QTreeWidget, QTreeWidgetItem, QWidget)

from qgis.PyQt.QtGui import (QColor, QCursor, QIcon, QImage, QKeySequence, QPixmap, QStandardItemModel, QTextDocument)
from qgis.PyQt.QtPrintSupport import (QPrintPreviewDialog, QPrinter)

from qgis.core import (QgsApplication, Qgis, QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsGeometry, QgsLayerTree, QgsLayerTreeLayer,
                       QgsLayerTreeGroup,  QgsLayerTreeModel, QgsPointXY, QgsProject, QgsRasterLayer, QgsRectangle, QgsSpatialIndex, QgsStyle, QgsVectorLayer)

from qgis.core import (QgsLayerTreeNode, QgsMapLayerProxyModel, QgsUnitTypes)
from qgis.gui import (QgsCollapsibleGroupBox, QgsColorWheel, QgsMapLayerComboBox, QgsLayerTreeMapCanvasBridge, QgsLayerTreeView,
                      QgsMapCanvas, QgsMapTool, QgsMapToolPan,  QgsMapToolZoom, QgsMessageBar, QgsRasterTransparencyWidget,
                      QgsRendererPropertiesDialog, QgsRendererRasterPropertiesWidget, QgsRubberBand )


from os.path import (basename, dirname, exists, isfile, join, splitext)
from autoLoaderRaster.utils import (changeButtonIcon, cleanPath, convertSize, fixeLabelsFileDialog, fixeMaxDim, funnyPushButton,
                                    getComboLayer, getComboLayerIndex, getListLayers, getThemeIcon, GroupComboBox,
                                    iff, layersComboBox, myPushButton, printerDlg, saveDlg, textForMenu, translateMsg,
                                    windowIcon, zoomNextExtent, zoomPreviousExtent) #NEW 3.6.4


from collections import OrderedDict
from datetime import datetime as thedatetime
from math import ceil


class legendTreeWidget( QTreeWidget ):
    def __init__(self, settings, parent=None, masterDialog=None):
        QTreeWidget.__init__(self, parent)

        self.vectors, self.rasters, self.alrRasters = None, None, None
        self.parent = parent
        self.masterDialog = masterDialog
        self.ihmWindow = self.parent.parent().parent()
        
        self.setItemsExpandable(True)
        self.setAnimated(True)
        self.setDragEnabled(True)
        self.setDropIndicatorShown(True)
        self.setDragDropMode(QAbstractItemView.InternalMove)
        self.header().setDefaultSectionSize(150)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setMinimumWidth(300)
        self.setGeometry(500, 200, 300, 400)
        self.settings = settings

        root=self.invisibleRootItem()
        root.setData(0, Qt.ToolTipRole,"root")
        self.setRootIsDecorated( False )
        self.setHeaderLabels([translateMsg("Groups and Layers"), translateMsg("Opacity")])

        styleSheet = "QTreeWidget { border: 1px solid;  border-radius: 5px; opacity: 0.5; background-color: rgba(255, 255, 255, 50);}"
        styleSheet+= "QTreeWidget::item:selected {background-color: #5D5D5D; color: rgb(255,255,255); }"

        self.imgChecked = getThemeIcon("checked.png").replace("\\","/")
        self.imgUnChecked = getThemeIcon("unchecked.png").replace("\\","/")

        styleSheet+= "QTreeWidget {opacity: 0.5;  background-color: rgba(255, 255, 255, 210);}"
        styleSheet+= "QTreeWidget::indicator:checked {image: url(%s);}" % self.imgChecked
        styleSheet+= "QTreeWidget::indicator:unchecked  {image: url(%s);}" % self.imgUnChecked


        self.setStyleSheet(styleSheet)
        
        self.setColumnWidth(0, 200)
        self.setColumnWidth(1, 80)
        
        
        self.setColumnCount(2)
        
        self.styleSlider = """
        QSlider::groove:horizontal {border: 1px solid #bbb; background: white; height: 10px; border-radius: 4px;}
        QSlider::sub-page:horizontal {background: qlineargradient(x1: 0, y1: 0,    x2: 0, y2: 1,  stop: 0 #66e, stop: 1 #bbf); background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,  stop: 0 #bbf, stop: 1 #55f);border: 1px solid #777;height: 10px;border-radius: 4px;}
        QSlider::add-page:horizontal {background: #fff; border: 1px solid #777; height: 10px; border-radius: 4px;}
        QSlider::handle:horizontal {background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #eee, stop:1 #ccc); border: 1px solid #777; width: 13px; margin-top: -2px; margin-bottom: -2px; border-radius: 4px;}
        QSlider::handle:horizontal:hover {background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #fff, stop:1 #ddd); border: 1px solid #444; border-radius: 4px;}
        QSlider::sub-page:horizontal:disabled {background: #bbb; border-color: #999;}
        QSlider::add-page:horizontal:disabled {background: #eee; border-color: #999;}
        QSlider::handle:horizontal:disabled {background: #eee; border: 1px solid #aaa; border-radius: 4px;}
        """

        self.itemChanged.connect(self.treeWidgetItemChanged)
        self.currentItemChanged.connect(self.updateIhmButtonsUpDown)
        self.parent.installEventFilter(self)

    def eventFilter(self, obj, event):
        if obj is self.parent:
           if event.type() == event.Resize: self.resizeObjects()
        return QObject.eventFilter(self, obj, event)
           
    def expandTreeWidget(self):
        if self.sender().objectName() == "buttonExpandAllNodes" : self.expandAll()
        else : self.collapseAll()

    def resizeObjects(self):
        self.setGeometry(10, 30, self.parent.width()-30, self.parent.height()-40) 
        self.setColumnWidth(0, self.parent.width()-150)
        self.setColumnWidth(1, 80)
        self.ihmWindow.buttonExpandAllNodes.setGeometry(self.parent.width()-60, 5, 15, 15)
        self.ihmWindow.buttonReduceAllNodes.setGeometry(self.parent.width()-40, 5, 15, 15)
        self.ihmWindow.closeLegend.setGeometry(self.parent.width()-20, 5, 15, 15)
        self.ihmWindow.butMoveUp.setGeometry(self.parent.width()-18, 100, 15, 15)
        self.ihmWindow.butMoveDown.setGeometry(self.parent.width()-18, 120, 15, 15)

    def getGroupParent(self, nameGroup): 
        results = self.findItems(nameGroup, Qt.MatchContains|Qt.MatchRecursive, 0)
        for item in results :
            return item
        return None

    def removeAllLayers(self):
        root = self.invisibleRootItem()
        for i in range(root.childCount()):
            group = root.child(i)
            if group :
               for j in range(group.childCount()-1, -1, -1,) : group.removeChild(group.child(j))

    def setMapLayers(self):
        layersMap1, layersMap2 = [], []
        root = self.invisibleRootItem()

        layersMap1.insert(0, self.ihmWindow.listLayers1.layer)

        for i in range(root.childCount()-1, -1, -1):
            group = root.child(i)
            if group :
               if group.text(0).find(self.ihmWindow.txtMap) == -1 :
                  for j in range(group.childCount()-1, -1, -1):
                      item = group.child(j)
                      if item :
                         layer = self.layerItem(item.whatsThis(0))
                         if layer :
                              layersMap1.insert(0, layer)
                              layersMap2.insert(0, layer)



        if self.ihmWindow.listLayers1.layer :
            self.ihmWindow.refCrs = self.ihmWindow.listLayers1.layer.crs()
            self.ihmWindow.mapCanvas1.setDestinationCrs(self.ihmWindow.refCrs)
        if self.ihmWindow.listLayers2.layer :
            try :
                refCrsB = self.ihmWindow.listLayers2.layer.crs()
                self.ihmWindow.mapCanvas2.setDestinationCrs(refCrsB)
            except : pass

        try :
            self.ihmWindow.mapCanvas1.setLayers(layersMap1)
            self.ihmWindow.mapCanvas2.setLayers(layersMap2 + self.masterDialog.refLayers2)
        except : pass    

        try :
            index = len(self.ihmWindow.mapCanvas1.layers())-1
            self.ihmWindow.mapCanvas1.setDestinationCrs(self.ihmWindow.mapCanvas1.layers()[index].crs())
            index = len(self.ihmWindow.mapCanvas2.layers())-1
            self.ihmWindow.mapCanvas2.setDestinationCrs(self.ihmWindow.mapCanvas2.layers()[index].crs())
        except : pass    

        if self.ihmWindow.listLayers1.layer : self.ihmWindow.mapCanvas1.setExtent(self.ihmWindow.listLayers1.layer.extent())


    def layerItem(self, whatsThis):
        try : infos = whatsThis.split("|")
        except : return None

        findLayer = None
      
        layerId = infos[1]
        root = self.ihmWindow.project.layerTreeRoot()
        allLayers = root.layerOrder()
        for layer in allLayers:
            mapLayer = root.findLayer(layerId)
            if mapLayer : return mapLayer.layer()

        if not findLayer :
            root = QgsProject.instance().layerTreeRoot()
            allLayers = root.layerOrder()
            for layer in allLayers:
                mapLayer = root.findLayer(layerId)
                if mapLayer : return mapLayer.layer()
        
        return findLayer        


    def updateValueSlider(self, value):
        layer = self.layerItem(self.sender().toolTip())
        if layer :
           opacity = 1.00-(value/100.00)            
           layer.renderer().setOpacity(opacity) if type(layer) == QgsRasterLayer else layer.setOpacity(opacity)
           self.ihmWindow.mapCanvas1.refresh()
           self.ihmWindow.mapCanvas2.refresh()

        item = self.currentItem()
        if not item : return
        item.setData(1, Qt.ToolTipRole, value)
    
    def treeWidgetItemChanged(self, item, column):
        if item : 
            infos = item.whatsThis(0)
            if infos == "" : return
            if item.childCount() > 0 : return
            infos = infos.split("|")
            if infos[1] == "-1" : self.ihmWindow.updateMoveButtons(False, False); return
            if not infos[0] in ("groups", "alrgroup1", "alrgroup2") :
               self.updateIhmButtonsUpDown(item, item) 
               self.setItemVisibility(item)
            else :
               self.ihmWindow.updateMoveButtons(False, False)
               for i in range(item.childCount()): self.setItemVisibility(item.child(i))

    def updateIhmButtonsUpDown(self, item, itemprev) :
        if not item : return
        if not itemprev : return
        infos = item.whatsThis(0).split("|")
        if (infos[0] in ("groups", "alrgroup1") and infos[1] == "-1") or infos[0] in ("alr1", "alr2") :
           self.ihmWindow.updateMoveButtons(False, False)
           return
        itemAbove, itemBelow = self.itemAbove(item), self.itemBelow(item)
        if not itemAbove :
           condAbove = False
        else :
           condAbove = (itemAbove and itemAbove.childCount() == 0) if itemAbove else False
           
        if not itemBelow : 
           condBelow = False
        else :
           condBelow = (itemBelow and itemBelow.childCount() == 0) if itemBelow else False
        self.ihmWindow.updateMoveButtons(condAbove, condBelow)

    def setItemVisibility(self, item):
        layer = self.layerItem(item.whatsThis(0))
        if layer :
            visibility = (item.checkState(0) == Qt.Checked)
            groupSlider = self.itemWidget(item, 1)
            slider = None
            value = 1
            if groupSlider :
                for child in groupSlider.children() :
                    if type(child) == QSlider : slider = child ; break ;
            if slider : value = 1.00-(slider.value()/100.00)            
            opacity = 0 if not visibility else value
            layer.renderer().setOpacity(opacity) if type(layer) == QgsRasterLayer else layer.setOpacity(opacity)
            self.ihmWindow.mapCanvas1.refresh()
            self.ihmWindow.mapCanvas2.refresh()


    def mouseDoubleClickEvent(self, event): 
        item = self.currentItem()
        if not item : return
        layer = self.layerItem(item.whatsThis(0))        
        if layer :
           self.ihmWindow.setPropertiesLayer(layer, item)

           if type(layer) == QgsVectorLayer :
              renderer = layer.renderer() 
              icon = None              
              for symbolItem in renderer.legendSymbolItems() :
                  image = symbolItem.symbol().asImage(QSize(32, 32))
                  pix = QPixmap.fromImage(image)
                  icon = QIcon()
                  icon.addPixmap(pix)
                  break
              if icon : item.setIcon(0, icon)   

    def moveUp(self) :
        if self.currentItem().childCount() > 0 : return
        
        role = Qt.ToolTipRole
        itemBeingDragged = self.currentItem()
        valueSliderItemBeingDragged = itemBeingDragged.data(1, role)

        modelIndex = self.currentIndex()
        row  = modelIndex.row()

        if row > 0 :

           itemBeingReplaced = self.itemAbove(itemBeingDragged)
           
           if itemBeingReplaced :
              valueSliderItemBeingReplaced = itemBeingReplaced.data(1, role)    

              parent = itemBeingDragged.parent()
              index = parent.indexOfChild(itemBeingDragged)
              child = parent.takeChild(index)
              parent.insertChild(index-1, itemBeingDragged)

              self.setCurrentItem(itemBeingDragged)
              self.setSlider(itemBeingDragged, valueSliderItemBeingDragged)
              
              self.setCurrentItem(itemBeingReplaced)
              self.setSlider(itemBeingReplaced, valueSliderItemBeingReplaced)

              self.setCurrentItem(itemBeingDragged)
           
        
    def moveDown(self):
        if self.currentItem().childCount() > 0 : return
        
        role = Qt.ToolTipRole
        itemBeingDragged = self.currentItem()
        valueSliderItemBeingDragged = itemBeingDragged.data(1, role)

        modelIndex = self.currentIndex()
        row  = modelIndex.row()

        itemBeingReplaced = self.itemBelow(itemBeingDragged)

        if row < itemBeingDragged.parent().childCount()-1 :
            
            if itemBeingReplaced :
                  valueSliderItemBeingReplaced = itemBeingReplaced.data(1, role)    

                  parent = itemBeingDragged.parent()
                  index = parent.indexOfChild(itemBeingDragged)
                  child = parent.takeChild(index)
                  parent.insertChild(index+1, itemBeingDragged)

                  self.setCurrentItem(itemBeingDragged)
                  self.setSlider(itemBeingDragged, valueSliderItemBeingDragged)
                  
                  self.setCurrentItem(itemBeingReplaced)
                  self.setSlider(itemBeingReplaced, valueSliderItemBeingReplaced)

                  self.setCurrentItem(itemBeingDragged)

            
    def setSlider(self, item, value):
        group = QGroupBox(self)
        group.setGeometry(0, 0, 140, 25)
        
        slider = QSlider(group)
        slider.setMinimumSize(80, 20)
        slider.setMaximumSize(80, 20)
        slider.setGeometry(2, 0, 80, 20)
        slider.setOrientation(Qt.Horizontal)
        slider.setMinimum(0)
        slider.setMaximum(100)
        slider.setValue(value)
        slider.setPageStep(10)
        slider.setSingleStep(1)
        slider.setInvertedAppearance(True)
        slider.setStyleSheet(self.styleSlider)

        zoomButton = QPushButton(group)
        zoomButton.setMinimumSize(20, 20)
        zoomButton.setMaximumSize(20, 20)        
        zoomButton.setIcon(QIcon(getThemeIcon("zoomtolayer.png")))
        zoomButton.setGeometry(85, 0, 20, 20)
        zoomButton.clicked.connect(self.zoomToLayerExtent)
        zoomButton.setToolTip(item.whatsThis(0))
        
        self.setItemWidget(item, 1, group)
        item.setData(1, Qt.ToolTipRole, slider.value())
        slider.setToolTip(item.whatsThis(0))
        slider.valueChanged.connect(self.updateValueSlider)

    def zoomToLayerExtent(self):
        layer = self.layerItem(self.sender().toolTip())
        if layer :
           extent = layer.extent()
           if self.ihmWindow.listLayers1.layer.crs() != layer.crs() :
               transformer = QgsCoordinateTransform()
               transformer.setSourceCrs(self.ihmWindow.listLayers1.layer.crs()) 
               transformer.setDestinationCrs(layer.crs())
               extent = transformer.transform(extent, QgsCoordinateTransform.ReverseTransform)               
           self.ihmWindow.mapCanvas1.setExtent(extent)
    
    def setDataItem(self, groupText, findText, itemText, layerId, itemIcon, groupKey, category, group):
        group = self.getGroupParent(groupText)
        item = None
        if group :
           for i in range(group.childCount()):
               if group.child(i).text(0).startswith(findText) :
                  group.child(i).setData(0, Qt.DisplayRole, itemText)
                  group.child(i).setWhatsThis(0, "%s|%s" % (category, layerId))
                  item = group.child(i) 
                  if category.find("group") == -1 :  self.setSlider(group.child(i), 0)
                  break

           if not item :
              try :
                 layer = self.addItem([itemText], groupKey, layerId, itemIcon, category, group)
                 layer.setCheckState(0, Qt.Checked)
              except : pass               


    def addItem(self, strings, category, fileId, iconlayer, parentname=None, parent=None):
        if category not in self.settings:  return False
        if parent is None : parent = self.invisibleRootItem()
        
        item = QTreeWidgetItem(parent, strings)
        item.setData(0, Qt.ToolTipRole, category)
        item.setWhatsThis(0, "%s|%s" % (category, fileId)) if parent else item.setWhatsThis(0, "%s|%s" % (category, parentname))
        item.setStatusTip(0, parentname) 
        item.setExpanded(True)
        item.setFlags(self.settings[category][1])
        if type(iconlayer) == str : iconlayer = QIcon(iconlayer)
        item.setIcon(0, iconlayer)
        
        if category.find("group") == -1 : self.setSlider(item, 0)
        if category == "groups" : self.setButtons(item) 
    
        return item

    def setButtons(self, item):
        group = QGroupBox(self)
        group.setGeometry(0, 0, 50, 25)
        
        addButton = QPushButton(group)
        addButton.setMinimumSize(20, 20)
        addButton.setMaximumSize(20, 20)        
        addButton.setIcon(QIcon(getThemeIcon("add.png")))
        addButton.setGeometry(2, 0, 20, 20)
        addButton.setWhatsThis(item.statusTip(0))
        addButton.clicked.connect(self.ihmWindow.addLayersToMapCanvas)

        delButton = QPushButton(group)
        delButton.setMinimumSize(20, 20)
        delButton.setMaximumSize(20, 20)        
        delButton.setIcon(QIcon(getThemeIcon("del.png")))
        delButton.setGeometry(20, 0, 20, 20)
        delButton.setWhatsThis(item.statusTip(0))
        delButton.clicked.connect(self.ihmWindow.delLayersFromMapCanvas)

        self.setItemWidget(item, 1, group)
       

    def removeItemWithId(self, groupText, layerId):
        group = self.getGroupParent(groupText)
        if group :
           for i in range(group.childCount()):
               item = group.child(i)
               infos = item.whatsThis(0).split("|")
               if layerId == infos[1] :
                  group.removeChild(item)
                  break


#---------------------------------------------------------------------------
# (c) Christophe MASSE 2013 - 2024
# revision code : 15-12-2023
# CLASS uiDoubleFocusGlassesPlugin - AUTOLOADERRASTER PLUGIN
#---------------------------------------------------------------------------
class uiDoubleFocusGlassesPlugin(QDialog):
    
    def __init__(self, parent):
        super(uiDoubleFocusGlassesPlugin, self).__init__()
        self.setObjectName("uiDoubleFocusGlassesPlugin")
        self.parent = parent
        self.styleSheetPushButton = self.parent.styleSheetPushButton
        self.styleComboBox = self.parent.styleComboBox
        self.resize(1000, 680)
        self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint)
        self.setWindowTitle(translateMsg("Double glass viewer"))
        windowIcon(self, "checkdoubleglasses.png")

        self.iface = self.parent.iface
        self.saveFolder = join(dirname(__file__),"works")
        self.layers, self.currentLayers = [], []

        self.refLayers2 = []
        self.transformer = QgsCoordinateTransform()
       
        self.canvas = self.parent.canvas
        self.rasterIcon = QIcon(getThemeIcon("raster.png"))
        self.vectorIcon = QIcon(getThemeIcon("vector.png"))
        self.groupIcon = QIcon(getThemeIcon("group.png"))
        self.imgChecked = getThemeIcon("checked.png").replace("\\","/")
        self.imgUnChecked = getThemeIcon("unchecked.png").replace("\\","/")        

        self.printMapview = QTextDocument()

        self.tableListLayers, self.comboLayersCurrentLayerId = {}, 0

        self.model = QStandardItemModel()
        self.view = QTableView()
        self.view.setModel( self.model )
        self.view.horizontalHeader().setVisible(False)
        self.view.verticalHeader().setVisible(False)
        self.view.setColumnHidden(1, True)
        self.view.verticalHeader().setDefaultSectionSize(20)
        self.view.setStyleSheet("QTableView {min-width: 800px; max-width: 1500px; selection-background-color: qlineargradient(x1: 0, y1: 0, x2: 0.5, y2: 0.5, stop: 0 #FFFFFF, stop: 1 #000000);}")
        self.view.setShowGrid(False)


        self.buttonToolBarNav = funnyPushButton(self) 
        self.buttonToolBarNav.initPushButton(25, 25, 40, 90, "buttonToolBarNav", "", translateMsg("Show/Hide navigation toolbar"), True, getThemeIcon("navigation_on.png"), 25, 25, True)
        self.buttonToolBarNav.setShortcut(QKeySequence("Ctrl+N"))
        
        self.buttonToolBarLegend = funnyPushButton(self) 
        self.buttonToolBarLegend.initPushButton(25, 25, 40, 90, "buttonToolBarLegend", "", translateMsg("Show/Hide legend toolbar"), True, getThemeIcon("legend_off.png"), 25, 25, True)
        self.buttonToolBarLegend.setShortcut(QKeySequence("Ctrl+L"))

        self.initDir = join(dirname(__file__), "works")
        
        self.showGrids = False
        
        self.buttonToolBarGrid = funnyPushButton(self) 
        self.buttonToolBarGrid.initPushButton(25, 25, 40, 90, "buttonToolBarGrid", "", translateMsg("Show/Hide Grid Maps"), True, getThemeIcon("grid_off.png"), 25, 25, True)
        self.buttonToolBarGrid.setShortcut(QKeySequence("Ctrl+G"))

        toolTip = translateMsg("Actions ...")
        self.buttonActions = funnyPushButton(self) 
        self.buttonActions.initPushButton(40, 25, 40, 90, "buttonActions", "", toolTip, True, getThemeIcon("actions.png"), 40, 25, True)
 
        self.buttonReverse = funnyPushButton(self) 
        self.buttonReverse.initPushButton(25, 25, 40, 90, "buttonReverse", "", translateMsg("Swap members"), True, getThemeIcon("reverse.png"), 25, 25, False)        
        self.buttonReverse.setShortcut(QKeySequence("Ctrl+R"))
        self.buttonReverse.clicked.connect(self.swapListMember)

        self.buttonToolBarNav.clicked.connect(self.getToolBarNav)
        self.buttonToolBarLegend.clicked.connect(self.getToolBarLegend)
        self.buttonToolBarGrid.clicked.connect(self.getGridMaps)

        self.mapCanvas1 = QgsMapCanvas(self)
        self.mapCanvas1.setObjectName("1")
        self.listLayers1 = layersComboBox(self, "listLayers1", self.mapCanvas1, False)
        
        self.refCrs = self.parent.projectAlr.crs()
        self.barInfo = QgsMessageBar(self.mapCanvas1)
        self.barInfo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) 

        self.labelScale = QLabel(self)
        self.labelScale.setStyleSheet("QLabel { font-size: 11px; border: 1px solid white; border-radius: 5px;  background-color: rgba(255, 255, 255, 50);}")
        self.labelScale.setAlignment(Qt.AlignCenter)
        
        self.widgetmapViewerLayerGridParams = actionsWindows(self.mapCanvas1, "widgetmapViewerLayerGridParams", "%s ...:" % translateMsg("Params"), 130, 200, False)

        self.closeGridParams = funnyPushButton(self.widgetmapViewerLayerGridParams) 
        self.closeGridParams.initPushButton(15, 15, 110, 5, "closeGridParams", "", translateMsg("Close"), True, getThemeIcon("closenb.png"), 15, 15, True)
        self.closeGridParams.clicked.connect(self.getGridParams)

        self.lblListParamsGrid = QLabel(self.widgetmapViewerLayerGridParams)
        self.lblListParamsGrid.setObjectName("lblListParamsGrid")
        self.lblListParamsGrid.setText("%s :" % translateMsg("Grid"))
        self.lblListParamsGrid.setAlignment(Qt.AlignRight)
        self.lblListParamsGrid.setGeometry(10, 35, 50, 25)


        styleComboBox = """
                          QComboBox { border-style: outset; border-radius: 3px;  selection-color: black; selection-background-color: lightgray;}
                          QComboBox:editable {  background-color: white; }
                          QComboBox:!editable, QComboBox::drop-down:editable { font-color: black; color : black; border-left-width: 1px; border-left-color: black; border-left-style: solid; border-top-right-radius: 3px; border-right-color: black;}
                          QComboBox:!editable:on, QComboBox::drop-down:editable:on {color : black; font-color: black;  }
                          QComboBox:on { padding-top: 3px; padding-left: 4px; }
                          QComboBox::drop-down {color: black; subcontrol-origin: padding; subcontrol-position: top right; width: 15px; border-left-width: 1px; border-left-color: darkgray; border-left-style: solid; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}
                          QComboBox::down-arrow { image: url(%s); }
                          QComboBox::down-arrow:on {top: 1px; left: 1px; }
                          QComboBox QAbstractItemView { border: 2px solid darkgray;  selection-background-color: lightgray; color: black; font-color: black;}
                        """ % getThemeIcon("nodes_expand.png").replace("\\","/") 


        self.listParamsGrid = QComboBox(self.widgetmapViewerLayerGridParams)
        self.listParamsGrid.setObjectName("listParamsGrid")
        self.listParamsGrid.setStyleSheet(styleComboBox)
        self.listParamsGrid.addItems([ "2", "4", "5", "6", "8", "10", "12", "14", "16", "18", "20"])
        self.listParamsGrid.setCurrentIndex(1)
        self.listParamsGrid.setGeometry(65, 30, 50, 25)
        self.listParamsGrid.currentIndexChanged.connect(self.updateGridMaps)

        self.lblMireColor = QLabel(self.widgetmapViewerLayerGridParams)
        self.lblMireColor.setObjectName("lblMireColor")
        self.lblMireColor.setText("%s :" % translateMsg("Colors"))
        self.lblMireColor.setAlignment(Qt.AlignCenter)
        self.lblMireColor.setGeometry(10, 60, 110, 25)


        self.mireColor = QgsColorWheel(self.widgetmapViewerLayerGridParams) 
        self.mireColor.setObjectName("mireColor")
        self.mireColor.setStyleSheet("{ border: 1px solid; border-radius: 5px;  opacity: 0.5; background-color: rgba(255, 255, 255, 50);}")
        self.mireColor.setGeometry(10, 85, 110, 110)
        self.mireColor.setBaseSize(24,24)
        self.mireColor.setToolTip(translateMsg("Color used for the extent"))
        self.mireColor.setColor(Qt.blue)
        self.mireColor.colorChanged.connect(self.setColors)

        self.widgetmapViewerLayerGridParams.setVisible(False)

        self.contextMnuActions(self.buttonActions)

        #NEW 3.6.0
        self.rbDynaMire = QgsRubberBand(self.mapCanvas1, Qgis.GeometryType.Polygon)
        self.rb = QgsRubberBand(self.mapCanvas1, Qgis.GeometryType.Polygon)
        self.rbaxesh = QgsRubberBand(self.mapCanvas1, Qgis.GeometryType.Line)
        self.rbaxesv = QgsRubberBand(self.mapCanvas1, Qgis.GeometryType.Line)

        self.rbDynaMire.setColor(Qt.blue)
        self.rbDynaMire.setWidth(1)
        self.rbDynaMire.setLineStyle(Qt.DashDotLine)         

        self.rb.setColor(Qt.blue)
        self.rb.setWidth(2)
        self.rbaxesh.setColor(Qt.blue)
        self.rbaxesv.setColor(Qt.blue)

        self.legende = actionsWindows(self.mapCanvas1, "widgetConsole", "%s ..." % translateMsg("Legende"), 340, 450, True )
        #NEW 3.6.4    
        self.widgetMapView = actionsWindows(self.mapCanvas1, "widgetConsole", "%s ..." % translateMsg("Actions"), 370, 65, False)
        ctrlMap(self, self.widgetMapView, True, False, False, 5, 0, 350, 30, False)

        #NEW 3.6.4
        self.widgetMapView.setGeometry(0, 0, 370, 65)
        self.widgetmapViewerLayerGridParams.setGeometry(371, 0, 120, 150) 
        self.legende.setGeometry(0, 65, 340, 450)

        self.toolPan = QgsMapToolPan(self.mapCanvas1)
        self.toolZoomIn = QgsMapToolZoom(self.mapCanvas1, False) 
        self.toolZoomOut = QgsMapToolZoom(self.mapCanvas1, True)

        self.buttonCatchExtent.clicked.connect(self.catchExtent)
        self.buttonPan.clicked.connect(self.pan)
        self.buttonZoomIn.clicked.connect(self.zoomIn)
        self.buttonZoomOut.clicked.connect(self.zoomOut)

        self.contextMnuZoomAll(self.buttonZoomAll)
        self.buttonZoomPrevious.clicked.connect(self.zoomPrevious)
        self.buttonZoomNext.clicked.connect(self.zoomNext)
        self.buttonSendExtent.clicked.connect(self.sendExtentToMapCanvas)

        self.model2 = QStandardItemModel()
        self.view2 = QTableView()
        self.view2.setModel( self.model2 )
        self.view2.horizontalHeader().setVisible(False)
        self.view2.verticalHeader().setVisible(False)
        self.view2.setColumnHidden(1, True)
        self.view2.verticalHeader().setDefaultSectionSize(20)
        self.view2.setStyleSheet("QTableView {min-width: 800px; max-width: 1500px; selection-background-color: qlineargradient(x1: 0, y1: 0, x2: 0.5, y2: 0.5, stop: 0 #FFFFFF, stop: 1 #000000);}")
        self.view2.setShowGrid(False)

        self.mapCanvas2 = QgsMapCanvas(self)
        self.mapCanvas2.setObjectName("2")
        self.mapCanvas2.setEnabled(False)

        self.listLayers2 = layersComboBox(self, "listLayers2", self.mapCanvas2, True)

        self.initProject()
        self.setBrigeForMapViewer()

        self.txtMap = translateMsg("Map")
        
        self.txtGroupVectors = translateMsg("Group vectors")
        self.txtGroupRasters = translateMsg("Group rasters")
        self.txtGroupMap1 = "%s 1" % self.txtMap
        self.txtGroupMap2 = "%s 2" % self.txtMap        
        
        default = Qt.ItemIsSelectable| Qt.ItemIsEnabled | Qt.ItemIsTristate | Qt.ItemIsUserCheckable 
        defaultalr = Qt.ItemIsSelectable | Qt.ItemIsTristate 
        checkebable = Qt.ItemIsUserCheckable
        drag = Qt.ItemIsDragEnabled
        drop = Qt.ItemIsDropEnabled

        """
                    "vectors":(["root"], default|drag|drop),
                    "rasters":(["root"], default|drag|drop),
        """            
        settings = {"groups":(["root"], default|drop),
                    "alrgroup1":(["root"], default|drop),
                    "alrgroup2":(["root"], defaultalr),
                    "layers":(["groups"], default),
                    "alr1": (["groups"], default),
                    "alr2":(["groups"], defaultalr)
                    }
            
        iconVector = None

        self.treeLegend = legendTreeWidget(settings, self.legende, self)
        self.treeLegend.vectors = self.treeLegend.addItem([self.txtGroupVectors], "groups", -1, self.groupIcon, "VECTOR") 
        self.treeLegend.vectors.setCheckState(0, Qt.Unchecked)
        self.treeLegend.rasters = self.treeLegend.addItem([self.txtGroupRasters], "groups", -1, self.groupIcon, "RASTER") 
        self.treeLegend.rasters.setCheckState(0, Qt.Unchecked)
        self.treeLegend.alrLayers1 = self.treeLegend.addItem([self.txtGroupMap1], "alrgroup1", -1, self.groupIcon) 
        self.treeLegend.alrLayers1.setCheckState(0, Qt.Checked)
        self.treeLegend.alrLayers2 = self.treeLegend.addItem([self.txtGroupMap2], "alrgroup2", -1, self.groupIcon) 
        self.treeLegend.alrLayers2.setCheckState(0, Qt.Checked)        
        
        cartes = ['1', '2']
        for carte in cartes :
            if carte == "1" : layer = self.treeLegend.addItem(["%s %s :" % (self.txtMap, carte)], "alr1" , -1, self.rasterIcon, "alrRasters", self.treeLegend.alrLayers1)
            else : layer = self.treeLegend.addItem(["%s %s :" % (self.txtMap, carte)], "alr2" , -1, self.rasterIcon, "alrRasters", self.treeLegend.alrLayers2)
            layer.setCheckState(0, Qt.Checked)
 
        self.buttonExpandAllNodes = funnyPushButton(self.legende) 
        self.buttonExpandAllNodes.initPushButton(15, 15, self.legende.width()-80, 5, "buttonExpandAllNodes", "", translateMsg("Expand all nodes"), True, getThemeIcon("nodes_expand.png"), 15, 15, True)

        self.buttonReduceAllNodes = funnyPushButton(self.legende) 
        self.buttonReduceAllNodes.initPushButton(15, 15, self.legende.width()-60, 5, "buttonReduceAllNodes", "", translateMsg("Close all nodes"), True, getThemeIcon("nodes_reduce.png"), 15, 15, True)

        self.closeLegend = funnyPushButton(self.legende) 
        self.closeLegend.initPushButton(15, 15, self.legende.width()-40, 5, "closeLegend", "", translateMsg("Close"), True, getThemeIcon("closenb.png"), 15, 15, True)

        self.butMoveUp = funnyPushButton(self.legende) 
        self.butMoveUp.initPushButton(15, 15, self.legende.width()-40, 100, "butMoveUp", "", translateMsg("Move up"), True, getThemeIcon("moveup.png"), 15, 15, True)
        self.butMoveUp.setEnabled(False)
                
        self.butMoveDown = funnyPushButton(self.legende) 
        self.butMoveDown.initPushButton(15, 15, self.legende.width()-40, 120, "butMoveDown", "", translateMsg("Move down"), True, getThemeIcon("movedown.png"), 15, 15, True)
        self.butMoveDown.setEnabled(False)
        
        self.buttonExpandAllNodes.clicked.connect(self.treeLegend.expandTreeWidget)
        self.buttonReduceAllNodes.clicked.connect(self.treeLegend.expandTreeWidget)

        self.butMoveUp.clicked.connect(self.treeLegend.moveUp)
        self.butMoveDown.clicked.connect(self.treeLegend.moveDown)

        self.closeLegend.clicked.connect(self.getToolBarLegend)
        
        self.legende.setVisible(False)


        try :
            self.rb2 = QgsRubberBand(self.mapCanvas2, True)
            self.rbaxesh2 = QgsRubberBand(self.mapCanvas2, True)
            self.rbaxesv2 = QgsRubberBand(self.mapCanvas2, True)
            self.rbDynaMire2 = QgsRubberBand(self.mapCanvas2, True)
        except :
            self.rb2 = QgsRubberBand(self.mapCanvas2)
            self.rbaxesh2 = QgsRubberBand(self.mapCanvas2)
            self.rbaxesv2 = QgsRubberBand(self.mapCanvas2)
            self.rbDynaMire2 = QgsRubberBand(self.mapCanvas2)            
        
        self.rb2.setColor(Qt.blue)
        self.rb2.setWidth(4)
        self.rbaxesh2.setColor(Qt.blue)
        self.rbaxesv2.setColor(Qt.blue)

        self.rbDynaMire2.setColor(Qt.blue)
        self.rbDynaMire2.setWidth(1)
        self.rbDynaMire2.setLineStyle(Qt.DashDotLine) 

        self.labelCoordCursorPos = QLabel(self)
        self.labelCoordCursorPos.setStyleSheet("QLabel { font-size: 11px;  color : white; background-color: rgba(160, 160, 160, 125); border: 2px solid cyan;  border-radius: 4px;  padding: 2px;}")
        self.labelCoordCursorPos.setAlignment(Qt.AlignCenter)
        self.labelCoordCursorPos.setVisible(False)

        self.imgMagnify = QgsMapCanvas(self) 
        self.imgMagnify.setStyleSheet("QgsMapCanvas { border-width: 5px; border-radius: 10px;   border:2px solid #000000 ; background-color: rgba(255, 255, 255, 210);}")
        self.imgMagnify.setVisible(False)
        self.toolMagnifyImage = toolMagnify(self, self.mapCanvas1, self.mapCanvas2, False)
        self.boutonMagnify.setShortcut(QKeySequence("Ctrl+M"))
        self.boutonMagnify.clicked.connect(self.setMagnify)
               

        self.mapCanvas1.setMapTool(self.toolZoomIn)
        contextMnu = self.setContextMenu(True)
        self.mapCanvas1.setContextMenuPolicy(Qt.CustomContextMenu)
        self.mapCanvas1.customContextMenuRequested.connect(self.contextMnuShortCut)

        try : self.mapCanvas1.contextMenuAboutToShow.connect(self.addContextMnu)
        except : pass
        
        self.buttonAddPermanentLayers.clicked.connect(self.addLayersToMapCanvas)
        self.buttonDelPermanentLayers.clicked.connect(self.delLayersFromMapCanvas) 


        self.iface.newProjectCreated.connect(self.initContextProject) 
        self.iface.projectRead.connect(self.initContextProject) 

        QgsProject(self.iface).instance().layerRemoved.connect(self.onLayerRemoved)
        QgsProject(self.iface).instance().layersWillBeRemoved.connect(self.clearProject) 
        
        self.mapCanvas1.extentsChanged.connect(self.synchronizeExtent)
        self.mapCanvas1.keyPressed.connect(self.updateMagnify)

        self.listLayers1.layerLabel.textChanged.connect(self.getUpdateMapViewers)
        self.listLayers2.layerLabel.textChanged.connect(self.getUpdateMapViewers)

        self.initContextProject()
        self.resizeListLayers()

        #NEW 3.6.4
        self.extents = []
        self.currentExtent = -1
        self.mapCanvas1.extentsChanged.connect(self.storeExtent)
        self.buttonClearExtents.clicked.connect(self.clearHistory)
        self.updateButtonZoomNextPrevious()

    #NEW 3.6.4
    def clearHistory(self):
        self.extents, self.currentExtent = [], -1
        self.updateButtonZoomNextPrevious()
        
    def storeExtent(self):
        self.extents.append(self.mapCanvas1.extent())
        self.currentExtent = len(self.extents)-1
        self.updateButtonZoomNextPrevious()


    def updateMoveButtons(self, above, below):
        try :
            self.butMoveUp.setEnabled(above)
            self.butMoveDown.setEnabled(below)
        except : pass
        
    def initContextProject(self):
        self.clearProject([])
        self.getUpdateMapViewers()
        self.synchronizeExtent()        
        self.setRefLayerForMapViewer2()
        self.zoomAllLayerRaster()
        
    def onLayerRemoved(self, layer): self.getUpdateMapViewers()        
        
    def swapListMember(self):
        layer1 = self.listLayers1.layer
        layer2 = self.listLayers2.layer
        
        extent1 = self.mapCanvas1.extent()
        extent2 = self.mapCanvas2.extent()

        self.listLayers1.blockSignals(True)
        self.listLayers2.blockSignals(True)

        removeLayers = []
        if self.listLayers1.layer : removeLayers.append(self.listLayers1.layer.id())
        self.initMaps()
        
        self.project.removeMapLayers(removeLayers)

        self.listLayers1.layer = layer2
        self.listLayers2.layer = layer1
        self.listLayers1.setLayer()
        self.listLayers2.setLayer()

        ready, sameCrs = self.setTransformerCrs()
       
        self.updateMapViewers(self.listLayers1)
        self.setRefLayerForMapViewer2()

        self.synchronizeExtent()
        self.mapCanvas1.refreshAllLayers()

        self.mapCanvas1.blockSignals(True)
        self.mapCanvas2.blockSignals(True)

        self.mapCanvas1.setExtent(extent2)
        self.mapCanvas2.setExtent(extent1)        
 
        self.mapCanvas1.blockSignals(False)
        self.mapCanvas2.blockSignals(False)
        self.listLayers1.blockSignals(False)
        self.listLayers2.blockSignals(False)
        
        self.synchronizeMap(0)
        self.updateMire()
       
        
    def updateMagnify(self, event) :
        if event.key() in (Qt.Key_Left, Qt.Key_Right, Qt.Key_Up, Qt.Key_Down) :
             cp = self.mapCanvas1.mapTool().toMapCoordinates(self.toolMagnifyImage.mapViewer.mouseLastXY())
             self.toolMagnifyImage.imgMagnify.setCenter(QgsPointXY(cp))
             self.toolMagnifyImage.imgMagnify.refresh()
             self.toolMagnifyImage.updateRb()
        elif event.key() == Qt.Key_Escape :
             self.buttonZoomIn.clicked.emit()
             self.buttonZoomIn.setChecked(True)
             self.toolMagnifyImage.deactivate()
             self.mapCanvas1.setMapTool(self.toolZoomIn)

        
    def keyPressEvent(self, event) :
        if self.boutonMagnify.isChecked() :
            if event.key() == Qt.Key_Tab :
                self.toolMagnifyImage.firstMapViewer = not (self.toolMagnifyImage.firstMapViewer)
                self.toolMagnifyImage.updateMapViewer()
            elif event.key() == Qt.Key_Plus : self.toolMagnifyImage.zoomInMg()
            elif event.key() == Qt.Key_Minus : self.toolMagnifyImage.zoomOutMg()

            
    def setMagnify(self) : self.mapCanvas1.setMapTool(self.toolMagnifyImage)

    def getGridParams(self):
        sender = self.sender() 
        if sender == self.closeGridParams : sender = self.paramsGridBut
        self.setVisibility(self.widgetmapViewerLayerGridParams, sender, "gridparams_%s.png")
        if sender == self.paramsGridBut : self.paramsGrid.setIcon(self.paramsGridBut.icon())
        else : self.paramsGridBut.setIcon(self.paramsGrid.icon())
        
    def setColors(self):
        color = self.mireColor.color()

        self.rbDynaMire.setColor(color)
        self.rbDynaMire2.setColor(color)

        self.rb.setColor(color)
        self.rbaxesh.setColor(color)
        self.rbaxesv.setColor(color)
        
        self.rb2.setColor(color)
        self.rbaxesh2.setColor(color)
        self.rbaxesv2.setColor(color)

        if self.showGrids : self.refreshMaps()    

    
    def setTransformerCrs(self):
        if self.mapCanvas1.layers() == [] : return False, True
        if self.mapCanvas2.layers() == [] : return False, True
        try :
            index1 = len(self.mapCanvas1.layers())-1
            index2 = len(self.mapCanvas2.layers())-1
            self.transformer.setSourceCrs(self.mapCanvas1.layers()[index].crs()) 
            sameCrs = (self.mapCanvas1.layers()[index1].crs() == self.mapCanvas2.layers()[index2].crs()) 
        except : return False, True 
        try :
            index1 = len(self.mapCanvas1.layers())-1
            index2 = len(self.mapCanvas2.layers())-1
            self.transformer.setDestinationCrs(self.mapCanvas2.layers()[index2].crs()) 
            sameCrs = (self.mapCanvas1.layers()[index1].crs() == self.mapCanvas2.layers()[index2].crs()) 
        except : return False, True     
        return True, sameCrs

    def matchTransformer(self, extent, sourceCrs, destinationCrs, orderCrs):
        try : 
            if sourceCrs != destinationCrs :
               self.transformer.setSourceCrs(sourceCrs)
               self.transformer.setDestinationCrs(destinationCrs)
               extent = self.transformer.transform(extent, orderCrs)
        except : pass    
        return extent

    
    def updateMire(self) :
        self.lastExtent = self.mapCanvas1.extent()
        layer = self.listLayers1.layer
        if layer :
           try : self.getMire(layer)
           except : return

    def resetMire(self):
        self.rb.reset()
        self.rb2.reset()           
        self.rbaxesh.reset()
        self.rbaxesv.reset()
        self.rbaxesh2.reset()
        self.rbaxesv2.reset()

    def getMire(self, layer):
        self.resetMire()
        if self.showGrids :
           index1 = len(self.mapCanvas1.layers())-1
           index2 = len(self.mapCanvas2.layers())-1
           if self.mapCanvas1.layers() != [] : self.drawGrids(self.mapCanvas1.extent(), self.rbaxesh, self.rbaxesv, self.mapCanvas1.layers()[index1].crs())
           if self.mapCanvas2.layers() != [] : self.drawGrids(self.mapCanvas2.extent(), self.rbaxesh2, self.rbaxesv2, self.mapCanvas2.layers()[index2].crs()) 

    def drawGrids(self, extent, rbAxesX, rbAxesY, crs): 
        nRange = int(self.listParamsGrid.currentText())
        coeff = 1 / nRange
        xMin, xMax = extent.xMinimum(), extent.xMaximum()
        yMin, yMax = extent.yMinimum(),extent.yMaximum()
      
        for i in range(1, nRange, 1) :
            meanX = extent.xMinimum() + abs(coeff * i * (extent.xMaximum()-extent.xMinimum())) 
            meanY = extent.yMinimum() + abs(coeff * i * (extent.yMinimum()-extent.yMaximum()))
            point1, point2, point3, point4 = QgsPointXY(xMin, meanY), QgsPointXY(xMax, meanY), QgsPointXY(meanX, yMin), QgsPointXY(meanX, yMax)                  
            geometry = QgsGeometry().fromPolylineXY([point1, point2])
            rbAxesX.addGeometry(geometry, crs) 
            geometry = QgsGeometry().fromPolylineXY([point3, point4])
            rbAxesY.addGeometry(geometry, crs) 
             

    def getToolBarNav(self): self.setVisibility(self.widgetMapView, self.buttonToolBarNav, "navigation_%s.png")
    def getToolBarLegend(self): self.setVisibility(self.legende, self.buttonToolBarLegend, "legend_%s.png")
    
    def updateGridMaps(self, index):
        if self.showGrids : self.updateMire()
        if self.boutonMagnify.isChecked() : self.boutonMagnify.setFocus()
        
    def getGridMaps(self):
        self.showGrids = not( self.showGrids)
        self.buttonToolBarGrid.setIcon(QIcon(getThemeIcon("grid_%s.png" % iff(self.showGrids, "on", "off"))))
        self.updateMire()
        
    
    def setVisibility(self, widget, actionTool, icon):
        if widget :
           widget.setVisible(not widget.isVisible ())
           cond = "on" if widget.isVisible() else "off"
        else : cond = "off"
        actionTool.setIcon(QIcon(getThemeIcon(icon % cond)))


    def resizeListLayers(self):
        centerX = int(self.width()/2)        
        
        self.listLayers1.setGeometry(5, 0, centerX-5-140, 28)
        self.listLayers2.setGeometry(centerX+15, 0, centerX-20, 25)
                
        dim = max(self.listLayers1.width(), self.listLayers2.width())
        
        self.view.horizontalHeader().setDefaultSectionSize(dim)
        self.view.setStyleSheet("QTableView {min-width: %spx; max-width: %spx; selection-background-color: qlineargradient(x1: 0, y1: 0, x2: 0.5, y2: 0.5, stop: 0 #FFFFFF, stop: 1 #000000);}" % (dim, dim))

        self.view2.horizontalHeader().setDefaultSectionSize(dim)
        self.view2.setStyleSheet("QTableView {min-width: %spx; max-width: %spx; selection-background-color: qlineargradient(x1: 0, y1: 0, x2: 0.5, y2: 0.5, stop: 0 #FFFFFF, stop: 1 #000000);}" % (dim, dim))


    def resizeEvent(self, event):
        centerX = int(self.width()/2)
        self.resizeListLayers()

        self.buttonToolBarNav.setGeometry(centerX-130, 5, 25, 25) 
        self.buttonToolBarLegend.setGeometry(centerX-100, 5, 25, 25) 
        self.buttonToolBarGrid.setGeometry(centerX-75, 5, 25, 25) 
        self.buttonActions.setGeometry(centerX-55, 5, 25, 25)         
        self.buttonReverse.setGeometry(centerX-10, 5, centerX-5, 25)
        
        self.mapCanvas1.setGeometry(5, 30, centerX-5, self.height()-40)
        self.barInfo.setGeometry(0, self.mapCanvas1.height()-90, self.mapCanvas1.width(), 70)
        self.barInfo.resize(self.mapCanvas1.width(), 70)
        
        self.labelScale.setGeometry(self.mapCanvas1.width()-110, self.height()-35, 100, 20)
        self.mapCanvas2.setGeometry(centerX, 30, centerX-5, self.height()-40)

        self.updateMire()


    def setPropertiesLayer(self, layer, item): 

        self.mapCanvas1.setCurrentLayer(layer)
        
        if not layer : return
        
        if type(layer) == QgsVectorLayer :
            dlg = QgsRendererPropertiesDialog(layer, QgsStyle.defaultStyle(), False)
            dlg.item = item
            dlg.layer = layer

            groupBox = dlg.findChild(QGroupBox, "mLayerRenderingGroupBox")
            if groupBox :
               opacityWidget = groupBox.findChild(QWidget, "mOpacityWidget")
               if opacityWidget :
                  for child in opacityWidget.children() :
                      if type(child) == QSlider : dlg.slider = child  ; break
               
                            
            
        elif type(layer) == QgsRasterLayer : 
            dlg = QDialog()
            dlg.item = item
            dlg.layer = layer
            dlg.setMaximumWidth(800)
            dlg.setMaximumHeight(800)
            dlg.setWindowFlags(Qt.WindowMaximizeButtonHint | Qt.WindowStaysOnTopHint | Qt.WindowCloseButtonHint)
            dlg.setWindowTitle(translateMsg("Properties for the layer"))
            dlg.setGeometry(200, 200, 600, 600)
            layout = QVBoxLayout(dlg)

            tabs = QTabWidget(dlg) 
            tabs.setTabsClosable(False)
            tabs.setDocumentMode(True)
            tabs.setTabShape(QTabWidget.Rounded)

            icon = getThemeIcon("raster.png")

            scrollAreaA = QScrollArea(dlg)
            dlg.widgetproperties = QgsRendererRasterPropertiesWidget(layer, self.mapCanvas1, dlg)
            dlg.widgetproperties.setGeometry(10, 10, 580, 580)
            scrollAreaA.setWidget(dlg.widgetproperties)
            
            tabs.addTab(scrollAreaA, QIcon(icon), translateMsg("Renderer's params"))

            dlg.slider = None
            scrollAreaB = QScrollArea(dlg)
            dlg.transparencyProperties = QgsRasterTransparencyWidget(layer, self.mapCanvas1, dlg)

            dlg.slider = None
            opacityWidget = dlg.findChild(QWidget, "mOpacityWidget")
            if opacityWidget :
               for child in opacityWidget.children() :
                   if type(child) == QSlider : dlg.slider = child ; break
                               
            dlg.transparencyProperties.setGeometry(10, 10, 560, 580)
            scrollAreaB.setWidget(dlg.transparencyProperties)
            
            tabs.addTab(scrollAreaB, QIcon(icon), translateMsg("Opacity and Transparency"))

            layout.addWidget(tabs)
           
        
        else : return
        
        windowIcon(dlg , "layers.png")
        dlg.setWindowTitle("%s : %s" % (dlg.windowTitle(), layer.name()))
        buttonBox = None
        for conteneur in dlg.children():
                if conteneur.children()!= []:
                   for child in conteneur.children():
                          for elt in child.children():
                                  if type(elt) == QDialogButtonBox :
                                             buttonBox = elt
                                             break

        
        if buttonBox and layer.type() == 0 :
                self.applystyle = buttonBox.addButton(translateMsg("Apply style"), QDialogButtonBox.ActionRole)
                self.applystyle.clicked.connect(self.apply_style)
                buttonBox.accepted.connect(self.apply_style_accept)
                buttonBox.rejected.connect(dlg.close)
        else :
           buttonBox = QDialogButtonBox()
           self.quitButton = buttonBox.addButton(translateMsg("Cancel"), QDialogButtonBox.RejectRole)
           self.applystyle = buttonBox.addButton(translateMsg("Apply style"), QDialogButtonBox.ActionRole)
           self.acceptButton = buttonBox.addButton(translateMsg("Validate"), QDialogButtonBox.AcceptRole)
           buttonBox.accepted.connect(self.apply_style_accept)
           buttonBox.rejected.connect(dlg.reject)
           layout.addWidget(buttonBox)
           self.applystyle.clicked.connect(self.apply_style)

        self.styleDlg = dlg                          
        dlg.exec_()
        self.mapCanvas1.refresh()


    def setSliderValue(self):
        if self.styleDlg :
            item = self.styleDlg.item
            if self.styleDlg.slider :
               self.treeLegend.setSlider(item, 100- (self.styleDlg.slider.value()/10))

    
    def apply_style_accept(self) :
        self.apply_style()
        self.styleDlg.accept()
          

    def apply_style(self):
        if self.styleDlg:
           if self.mapCanvas1.currentLayer().type()==0 :
              self.styleDlg.apply()
              self.setSliderValue()
           else :
              self.styleDlg.widgetproperties.apply()
              self.styleDlg.transparencyProperties.apply()
              self.setSliderValue()
           self.refreshMaps()

    def reinitListLayers(self, listLayers1):
        listLayers1.layer = None
        listLayers1.layerLabel.setText("%s !" % translateMsg("Please select a layer"))        


    def clearProject(self, layers=[]):
        for layer in layers :
            if self.listLayers1.layer :
               if self.listLayers1.layer.id() == layer: self.reinitListLayers(self.listLayers1)
            if self.listLayers2.layer :
               if self.listLayers2.layer.id() == layer : self.reinitListLayers(self.listLayers2)            
        self.layers, self.currentLayers = [], []
        if layers == [] : self.treeLegend.removeAllLayers() 
        self.mapCanvas1.blockSignals(True)
        if self.project : self.project.addMapLayers([])
        self.initProject()
        self.resetMire()
        self.initMaps()
        
        self.mapCanvas1.blockSignals(False)
        
    def initProject(self):
        self.project = QgsProject(self)
        crs = QSettings().value("Projections/layerDefaultCrs")
        self.crs = QgsCoordinateReferenceSystem(crs)
        if self.mapCanvas1.layers() != [] :
           index1 = len(self.mapCanvas1.layers())-1
           self.crs = self.mapCanvas1.layers()[index1].crs()
        self.project.setCrs(self.crs)
        self.project.addMapLayers([])

    def setBrigeForMapViewer(self) :  self.bridgeA = QgsLayerTreeMapCanvasBridge(self.project.layerTreeRoot(), self.mapCanvas1)

    def contextMnuZoomAll(self, button):
        contextMenu = QMenu()

        action = QAction(QIcon(getThemeIcon("zoomtolayer.png")), "%s...%s 1" % (translateMsg("Zoom to raster layer extent"), translateMsg("Map")), self)
        action.setObjectName("zoomallrasterlayer1")
        contextMenu.addAction(action)
        setattr(self, "zoomallrasterlayer1", action)
        action.triggered.connect(self.zoomAllLayerRaster)
        
        action = QAction(QIcon(getThemeIcon("zoomtolayer.png")), "%s...%s 2" % (translateMsg("Zoom to raster layer extent"), translateMsg("Map")), self)
        action.setObjectName("zoomallrasterlayer2")
        contextMenu.addAction(action)
        setattr(self, "zoomallrasterlayer2", action)
        action.triggered.connect(self.zoomAllLayerRaster)

        contextMenu.addSeparator()

        action = QAction(QIcon(getThemeIcon("zoommap.png")), "%s 1" % translateMsg("Zoom all the map window"), self)
        action.setObjectName("zoomallmap1")
        contextMenu.addAction(action)
        setattr(self, "zoomallmap1", action)
        action.triggered.connect(self.zoomAllMap)

        action = QAction(QIcon(getThemeIcon("zoommap.png")), "%s 2" % translateMsg("Zoom all the map window"), self)
        action.setObjectName("zoomallmap2")
        contextMenu.addAction(action)
        setattr(self, "zoomallmap2", action)
        action.triggered.connect(self.zoomAllMap)         

        button.setMenu(contextMenu)
        

    def refreshContext(self):
        self.treeLegend.removeAllLayers()
        self.initProject()
        self.updateMapViewers(self.listLayers1)
        self.setBrigeForMapViewer()
        self.synchronizeExtent()

        
    def contextMnuActions(self, button):  self.getContextMnu(self.sender(), None, button)
    def contextMnuShortCut(self, point): self.getContextMnu(self.sender(), point, None)
    def getContextMnu(self, sender, point, button):  
        if point :
          if not (sender == self.mapCanvas1) : return
        contextMnu = self.setContextMenu(False) if button else self.setContextMenu(True)
        if point : contextMnu.exec_(self.sender().mapToGlobal(point))
        else : button.setMenu(contextMnu) 
         
    def setContextMenu(self, fromMap):
        if fromMap == True :
            
            self.toolMagnifyImage.deactivate()
            self.mapCanvas1.setMapTool(self.toolZoomIn)
            self.buttonZoomIn.setChecked(True)
            
            actions = {"paramsGrid" : ("gridparams_%s.png", "Parameters for the grid", "" , self.getGridParams, True, "Ctrl+O"),
                       "~0" : (),  
                       "prinMapAsImages" : ("print.png", "Print the maps", "" , self.printMaps, True, "Ctrl+P"),
                       "saveMapAsImages" : ("savefile.png", "Save maps as images", "" , self.saveMapsAsImage, True, "Ctrl+S"),
                       "~1" : (),
                       "reloadContextAction" : ("reload.png", "Reload QGIS context", "" , self.refreshContext, True, "Ctrl+Q")
                       }
        else :
            actions = {"paramsGridBut" : ("gridparams_off.png", "Parameters for the grid", "" , self.getGridParams, True, "Ctrl+O"),
                       "~0" : (),  
                       "prinMapAsImages" : ("print.png", "Print the maps", "" , self.printMaps, True, "Ctrl+P"),
                       "saveMapAsImages" : ("savefile.png", "Save maps as images", "" , self.saveMapsAsImage, True, "Ctrl+S"),
                       "~1" : (),
                       "reloadContext" : ("reload.png", "Reload QGIS context", "" , self.refreshContext, True, "Ctrl+Q")
                       }          
         
        listItems = []
        for key in actions.keys() :
            if not key.startswith("~") : listItems.append(translateMsg(actions[key][1]).replace(":",""))
        maxDim = fixeMaxDim(listItems)

        contextMnu = QMenu() 
        for key in actions :
            if key.startswith("~") : contextMnu.addSeparator()
            else :
                  icon = actions[key][0]
                  if key == "paramsGrid" :
                     cond = "on" if self.widgetmapViewerLayerGridParams.isVisible() else "off"
                     icon = getThemeIcon(icon % cond)
                  else : icon = getThemeIcon(icon)

                  text = textForMenu("%s...%s", translateMsg(actions[key][1]).replace(":",""), maxDim, actions[key][5])
                  action = QAction(QIcon(icon), text, self)
                  
                  if actions[key][2] != "" : action.setShortcut(QKeySequence(actions[key][2]))
                  action.setEnabled(actions[key][4])
                  action.setObjectName(key)
                  action.setShortcut(QKeySequence(actions[key][5]))
                  contextMnu.addAction(action)
                  action.triggered.connect(actions[key][3])

                  setattr(self, key, action)

        return contextMnu


    def addContextMnu(self, mapCanvasContextMnu) :
        contextMnu = self.setContextMenu(True)
        mapCanvasContextMnu.addMenu(contextMnu)
        
    def saveMapsAsImage(self):
        dlgFile = saveDlg(self, self.initDir)
        dlgFile.exec_()

    def createFilesImages(self, folder):
        fileName = join(folder, "mapviewer1.png") 
        self.mapCanvas1.saveAsImage(fileName, None, "PNG")

        fileNameDouble = join(folder ,"mapviewer2.png") 
        self.mapCanvas2.saveAsImage(fileNameDouble, None, "PNG")

        return fileName, fileNameDouble
       
    def printMaps(self):
        printer = QPrinter(); printer.setPageSize(QPrinter.A4); printer.setOrientation(QPrinter.Landscape);
        printer.setPageMargins(5, 5, 5, 5, QPrinter.Millimeter); printer.setOutputFormat(QPrinter.NativeFormat);

        fileName, fileNameDouble = self.createFilesImages(join(dirname(__file__), "works"))
       
        self.printMapview.clear()
        self.printMapview.setPageSize(QSizeF(printer.pageRect().size()))
       

        try:
            from osgeo.gdal import Open as gdalopen
            from osgeo.gdal import GA_ReadOnly
        except:
            from gdal import Open as gdalopen
            from gdal import GA_ReadOnly

        sourceWidth, sourceHeight = printer.pageRect().width(), printer.pageRect().height()
        dataset = gdalopen( fileName, GA_ReadOnly )
        orientation = QPrinter.Landscape
        
        if dataset :
            imgWidth, imgHeight = dataset.RasterXSize, dataset.RasterYSize
            if imgHeight > (imgWidth*1.1) : orientation = QPrinter.Portrait


        if orientation == QPrinter.Portrait :  scale = sourceHeight*0.8 / float(imgHeight)
        else :  scale = sourceWidth / float(imgWidth*2)

        
        imgWidth, imgHeight = int(imgWidth*scale), int(imgHeight*scale)

        orientation = QPrinter.Landscape
       
        title = "%s : " % translateMsg("Print")
        html = """
        <head><title>Report</title></head>
        <body>
            <table width="100%">
                <tr><td><span style='font-size:1.2em'>{}</span><br><small>{} [{}]<br>{} [{}]</small></td></tr>
            </table>
          <hr>
          <table width="100%">
          <tr>
            <td><img src="{}" width="{}" height="{}"></td>
            <td><img src="{}" width="{}" height="{}"></td>
          </tr>
          </table>
          <hr>
          <p align=right>AutoLaoderRaster, le {}</p>
        </body>
        """.format(title, fileName, self.listLayers1.layerLabel.toPlainText(), fileNameDouble, self.listLayers2.layerLabel.toPlainText(), fileName, imgWidth, imgHeight, fileNameDouble, imgWidth, imgHeight, thedatetime.now().strftime("%d/%m/%Y à %Hh%M"))
       
        self.printMapview.setHtml(html)        
        dlgPrint = printerDlg(self, self.printMapview, "%s : " % translateMsg("Print"), orientation)


    def catchExtent(self):
        extent = self.canvas.extent()
        if self.mapCanvas1.layers() :
            index1 = len(self.mapCanvas1.layers())-1
            if self.mapCanvas1.layers()[index1].crs() != QgsProject(self.iface).instance().crs() :
               transformer = QgsCoordinateTransform()
               transformer.setSourceCrs(QgsProject(self.iface).instance().crs()) 
               transformer.setDestinationCrs(self.mapCanvas1.layers()[index1].crs())
               extent = transformer.transform(extent, QgsCoordinateTransform.ForwardTransform)               
            self.mapCanvas1.setExtent(extent)

  
    def sendExtentToMapCanvas(self):
        if self.mapCanvas1.layers() == [] : return
        try :
            extent = self.mapCanvas1.extent()
            index1 = len(self.mapCanvas1.layers())-1           
            if self.mapCanvas1.layers()[index1].crs() != QgsProject(self.iface).instance().crs() :
               transformer = QgsCoordinateTransform()
               transformer.setSourceCrs(self.mapCanvas1.layers()[index1].crs())
               transformer.setDestinationCrs(QgsProject(self.iface).instance().crs())
               extent = transformer.transform(extent, QgsCoordinateTransform.ForwardTransform)            
            self.canvas.setExtent(extent)
            self.canvas.refresh()
        except : pass

    def initMaps(self):
        self.mapCanvas1.setLayers([])
        self.mapCanvas2.setLayers([])
        self.mapCanvas1.clearCache()
        self.mapCanvas2.clearCache()
        self.refreshMaps() 
    
    def refreshMaps(self) :
        self.mapCanvas1.refresh()
        self.mapCanvas2.refresh()   

    def zoomIn(self): self.mapCanvas1.setMapTool(self.toolZoomIn) 
    def zoomOut(self): self.mapCanvas1.setMapTool(self.toolZoomOut) 

    def zoomAndSaveContext(self):
        if self.mapCanvas1.layers() == [] : return None
        if not self.listLayers1.layer : return None

        oldExtent = self.mapCanvas1.extent()

        index1 = len(self.mapCanvas1.layers())-1 
        crs = self.mapCanvas1.layers()[index1].crs()
        layer = self.listLayers1.layer
         
        if layer :
           if layer.crs() != crs :
              transformer = QgsCoordinateTransform()
              transformer.setSourceCrs(crs)
              transformer.setDestinationCrs(layer.crs())
              oldExtentProj = transformer.transform(oldExtent, QgsCoordinateTransform.ForwardTransform)
           else : oldExtentProj = oldExtent
        else : oldExtentProj = oldExtent  

        if layer :
           oldGeomExtent = QgsGeometry().fromRect(oldExtentProj) if layer.crs() != crs else QgsGeometry().fromRect(oldExtent)
        else : oldGeomExtent = QgsGeometry().fromRect(oldExtent)    
        newGeomExtent = QgsGeometry().fromRect(layer.extent())    

        if newGeomExtent.intersects(oldGeomExtent): return oldExtentProj
        else : return layer.extent()

        return oldExtentProj

    def zoomAllLayerRaster(self):
        if self.sender() == self.zoomallrasterlayer2 :
           self.mapCanvas1.blockSignals(True) 
           self.setMaps2Extent()
           self.mapCanvas1.blockSignals(False)
           self.synchronizeExtent()
        else :
           if self.listLayers1.layer :
              layer = self.listLayers1.layer
              self.mapCanvas1.setExtent(layer.extent())
           
        self.updateMire()
        self.updateLabelScale()

    def setMaps2Extent(self):
        ready, sameCrs = self.setTransformerCrs()
        if self.listLayers2.layer :
           extent = self.listLayers2.layer.extent()
           self.mapCanvas2.setExtent(extent)
        else : return
        
        checking, index1, index2, crs1, crs2 = self.getInfosForCoordinateTransform()
        if checking :
           if crs1 != crs2 : 
                transformer = QgsCoordinateTransform() 
                transformer.setSourceCrs(crs1)
                transformer.setDestinationCrs(crs2)
                extent = transformer.transform(extent, QgsCoordinateTransform.ReverseTransform)

        self.mapCanvas1.setExtent(extent)
        self.refreshMaps()
        self.updateLabelScale()     


    def zoomAllMap(self):        
        if self.sender()== self.zoomallmap2 :
           if self.mapCanvas2.layers() == [] : return
           self.mapCanvas1.blockSignals(True)
           self.mapCanvas2.zoomToFullExtent()           
           extent = self.mapCanvas2.extent()
            
           checking, index1, index2, crs1, crs2 = self.getInfosForCoordinateTransform()
           if checking :
              if crs1 != crs2 :
                   transformer = QgsCoordinateTransform() 
                   transformer.setSourceCrs(crs1)
                   transformer.setDestinationCrs(crs2)
                   extent = transformer.transform(extent, QgsCoordinateTransform.ReverseTransform)
           
           self.mapCanvas1.setExtent(extent)
           self.refreshMaps()
           self.updateLabelScale()
           self.mapCanvas1.blockSignals(False)
        else :
           if self.mapCanvas1.layers() == [] : return
           index1 = len(self.mapCanvas1.layers())-1
           index2 = len(self.mapCanvas2.layers())-1
           crs1 = self.mapCanvas1.layers()[index1].crs()
           crs2 = self.mapCanvas2.layers()[index2].crs()          
           self.mapCanvas2.blockSignals(True) 
           self.mapCanvas1.zoomToFullExtent()
           self.mapCanvas2.blockSignals(False)             
        self.updateMire()
          
    #NEW 3.6.4
    def zoomPrevious(self):
        self.currentExtent = zoomPreviousExtent(self.currentExtent, self.extents, self.mapCanvas1); self.synchronizeExtent()
        self.updateButtonZoomNextPrevious()
    def zoomNext(self):
        self.currentExtent = zoomNextExtent(self.currentExtent, self.extents, self.mapCanvas1) ; self.synchronizeExtent()
        self.updateButtonZoomNextPrevious()
    def updateButtonZoomNextPrevious(self):
        self.buttonZoomPrevious.setEnabled(self.currentExtent > 0)
        self.buttonZoomNext.setEnabled(self.currentExtent < len(self.extents)-1)

    def pan(self): self.mapCanvas1.setMapTool(self.toolPan)         

    
    def getInfosForCoordinateTransform(self):
        index1, index2, crs1, crs2 = None, None, None, None
        if not self.listLayers1.layer and not self.listLayers2.layer : return False, index1, index2, crs1, crs2
        if self.mapCanvas1.layers() == [] : return False, index1, index2, crs1, crs2
        if self.mapCanvas2.layers() == [] : return False, index1, index2, crs1, crs2        
        index1 = len(self.mapCanvas1.layers())-1
        index2 = len(self.mapCanvas2.layers())-1
        crs1 = self.mapCanvas1.layers()[index1].crs()
        crs2 = self.mapCanvas2.layers()[index2].crs()
        return True, index1, index2, crs1, crs2
  
    def setMapsExtent(self):        
        ready, sameCrs = self.setTransformerCrs()
        extent = self.mapCanvas1.extent()

        if not self.listLayers1.layer and not self.listLayers2.layer : return
        if self.mapCanvas1.layers() == [] : return
        if self.mapCanvas2.layers() == [] : return

        checking, index1, index2, crs1, crs2 = self.getInfosForCoordinateTransform()
        if checking :
           if crs1 != crs2 : 
              transformer = QgsCoordinateTransform()
              transformer.setSourceCrs(crs1)
              transformer.setDestinationCrs(crs2)
              extent = transformer.transform(extent, QgsCoordinateTransform.ForwardTransform)
           
        self.mapCanvas2.blockSignals(True)
        self.mapCanvas2.setExtent(extent)
        self.mapCanvas2.refresh()
        self.mapCanvas2.blockSignals(False)

    def updateLabelScale(self):
        widthMap = convertSize(round(self.mapCanvas1.extent().xMaximum() - self.mapCanvas1.extent().xMinimum(), 2))        
        self.labelScale.setText("%s%s" % (widthMap, QgsUnitTypes.toString(self.refCrs.mapUnits()))) 

    def synchronizeExtent(self):
        self.mapCanvas1.refresh()
        self.setMapsExtent()
        self.synchronizeMap(0)
        self.updateLabelScale()
        self.updateMire()
        if self.mapCanvas1.mapTool() == self.toolMagnifyImage : self.toolMagnifyImage.updateRb()
   
    def getUpdateMapViewers(self):
        extent = self.zoomAndSaveContext()
        self.updateMapViewers(self.sender())              

        if not extent : self.zoomAllLayerRaster()
        else : self.mapCanvas1.setExtent(extent)

        ready, sameCrs = self.setTransformerCrs()
        self.setRefLayerForMapViewer2()
        self.setMapsExtent()


    def updateMapViewers(self, mapLayerComboBox):
        if mapLayerComboBox in (self.listLayers2, self.listLayers2.layerLabel) : target, carte = self.mapCanvas2, "2"  
        else : mapLayerComboBox in (self.listLayers1, self.listLayers1.layerLabel) ; target, carte = self.mapCanvas1, "1"
        if not target : return

        if not self.listLayers1.layer : return

        layer = self.listLayers1.layer
        clayer = None
        
        if not layer in self.mapCanvas1.layers() :
           if isinstance(layer, QgsRasterLayer) :
              try : 
                  clayer = layer.clone()     
                  self.project.addMapLayer(clayer)
              except : return    
        else : clayer = layer    

        group = self.treeLegend.getGroupParent("%s 1" % self.txtMap)        
        if group.childCount() > 0 :
           item = group.child(0)
           oldRefLayer = self.treeLegend.layerItem(item.whatsThis(0))
           if oldRefLayer : self.project.removeMapLayers( [oldRefLayer.id()] )

        if not clayer : return   
        
        if clayer :
            self.setLayers(clayer)
            self.treeLegend.setDataItem(self.txtGroupMap1, "%s 1" % self.txtMap, "%s 1 : %s" % (self.txtMap, clayer.name()), clayer.id(), self.rasterIcon, "alr1" , "alrRasters", self.treeLegend.alrLayers1)

        self.treeLegend.setMapLayers()

        self.setBrigeForMapViewer()
      
   
    def setRefLayerForMapViewer2(self):
        if not self.listLayers2.layer : return
        layer = self.listLayers2.layer
                
        if layer :

            self.setLayers(layer)
            groupForTheLayer = self.getGroupForTheLayer(layer)
            self.treeLegend.setDataItem(self.txtGroupMap2, "%s 2" % self.txtMap, "%s 2 : %s" % (self.txtMap, layer.name()), layer.id(), self.rasterIcon, "alr2" , "alrRasters", self.treeLegend.alrLayers2)
            self.treeLegend.setMapLayers()
            self.setMapsExtent()
            ready, sameCrs = self.setTransformerCrs()
            self.updateMire()
            self.synchronizeMap(0)


    def getGeomFromExtent(self, extent):
        coords = [[ QgsPointXY(extent.xMinimum(),extent.yMaximum()), QgsPointXY(extent.xMaximum(),extent.yMaximum()),
                    QgsPointXY(extent.xMaximum(),extent.yMinimum()), QgsPointXY(extent.xMinimum(),extent.yMinimum()),
                    QgsPointXY(extent.xMinimum(),extent.yMaximum()), ]]  
        geomTargetExtent = QgsGeometry().fromPolygonXY(coords)
        return geomTargetExtent
  
    def synchronizeMap(self, indexTarget):
          if not self.listLayers1.layer : return
          if self.mapCanvas1.layers() == [] : return                
          
          layer1 = self.listLayers1.layer 
          geomTargetExtent = self.mapCanvas1.extent() 

          layer2 = self.listLayers2.layer 
          if not layer2 : return
          self.refLayers2 = []  

          self.refLayers2.append(layer2)  
          groupForTheLayer = self.getGroupForTheLayer(layer2)
          extent = self.mapCanvas2.extent()

          if groupForTheLayer :
             if self.listLayers2.includeGroup :
                 for layer in groupForTheLayer.findLayers() :
                     if layer.layer().source() != layer2.source() :
                        if layer.layer().extent().intersects(extent) : self.refLayers2.append(layer.layer())


    def getVectorLayer(self, contexte):
        root = QgsProject.instance().layerTreeRoot()
        dicLayers, allLayers, allLayersIcon = {}, [], []
        iconVector, iconRaster = QIcon(getThemeIcon("vector.png")),  QIcon(getThemeIcon("raster.png"))
        if contexte == "RASTER" : listTypes = (QgsRasterLayer,)
        elif contexte == "VECTOR" : listTypes = (QgsVectorLayer,)
        else : listTypes = (QgsVectorLayer, QgsRasterLayer)
        for layer in root.findLayers() : 
            if type(layer.layer()) in listTypes :
               key = layer.layer().name()
               if not key in dicLayers.keys() :
                   icon = iconVector if layer.layer().type() == 0 else iconRaster
                   dicLayers[key] = icon

        for key in OrderedDict(sorted(dicLayers.items(), key=lambda i: i[0].lower())) :
            allLayers.append(key)
            allLayersIcon.append(dicLayers[key])
               
        return allLayers, allLayersIcon


    def delLayersFromMapCanvas(self):
        if not self.listLayers1.layer : return
        frozenLayer = self.listLayers1.layer
        
        allLayers, allLayersIcon = [], []
        iconVector, iconRaster = QIcon(getThemeIcon("vector.png")),  QIcon(getThemeIcon("raster.png"))

        for layer in self.mapCanvas1.layers() : 
            if type(layer) in (QgsVectorLayer, QgsRasterLayer) :
               if not layer.name() in allLayers :
                  allLayers.append(layer.name())
                  allLayersIcon.append(iconVector if layer.type() == 0 else iconRaster)
        if allLayers == [] : return
        
        self.dialogInput = QInputDialog(self) 
        self.dialogInput.setWindowTitle(translateMsg("Delete"))
        self.dialogInput.setLabelText("%s :" % translateMsg("Layers"))
        self.dialogInput.setOptions(QInputDialog.UseListViewForComboBoxItems)
        windowIcon(self.dialogInput, "del.png")

        self.dialogInput.resize(600, 500)
        self.dialogInput.setComboBoxItems(allLayers) 

        child = None
        for child in self.dialogInput.children():
            if type(child) == QListView :
                child.setIconSize(QSize(18, 18))
                child.setSelectionMode( QAbstractItemView.ExtendedSelection )

                child.doubleClicked.connect(self.dialogInput.accept)                

                model = child.model()
                for index in range(model.rowCount()):
                    listViewItem = model.item(index)
                    listViewItem.setData( allLayersIcon[index], Qt.DecorationRole)
                    if frozenLayer :
                       if listViewItem.text() == frozenLayer.name() : listViewItem.setEnabled(False)
       

        if self.dialogInput.exec_() :
            if child :
               instance = self.project
               layersMapView = self.mapCanvas1.layers()
               layersMapViewDouble = self.mapCanvas2.layers()
               
               for index in child.selectionModel().selectedIndexes() :
                   nameLayer = child.model().itemFromIndex(index).text()
                   layers = instance.mapLayersByName(nameLayer)
                   
                   for layer in layers :
                      self.treeLegend.removeItemWithId(self.txtGroupRasters, layer.id())
                      self.treeLegend.removeItemWithId(self.txtGroupVectors, layer.id())
                       
                      if layer in layersMapView : layersMapView.remove(layer)
                      if layer in layersMapViewDouble :  layersMapViewDouble.remove(layer)
                                            
                      self.project.removeMapLayers( [layer.id()] )

               self.afterAddOrDelLayers()
   
    def addLayersToMapCanvas(self):
       
        if not self.listLayers1.layer : return
        frozenLayer = self.listLayers1.layer

        try : contexte = self.sender().whatsThis()
        except : contexte = "ALL"

        allLayers, allLayersIcon = self.getVectorLayer(contexte)
        if allLayers == [] : return
     
        self.dialogInput = QInputDialog(self)

        if contexte == "VECTOR" : self.dialogInput.setWindowTitle("%s - %s" % (translateMsg("Add"), translateMsg("Vector layers")))
        elif contexte == "RASTER" : self.dialogInput.setWindowTitle("%s - %s" % (translateMsg("Add"), translateMsg("Raster layers")))
        else : self.dialogInput.setWindowTitle("%s - %s" % (translateMsg("Add"), translateMsg("Layers")))
        
        self.dialogInput.setLabelText("%s %s :" % (len(allLayers), translateMsg("Layers")))
        self.dialogInput.setOptions(QInputDialog.UseListViewForComboBoxItems)
        windowIcon(self.dialogInput, "add.png")

        self.dialogInput.resize(600, 500)
        
        self.dialogInput.setComboBoxItems(allLayers) 
        icon = QIcon(getThemeIcon("vector.png"))

        child = None
        for child in self.dialogInput.children():
            if type(child) == QListView : 
                child.doubleClicked.connect(self.dialogInput.accept)                
                child.setIconSize(QSize(18, 18))
                child.setSelectionMode( QAbstractItemView.ExtendedSelection )
                model = child.model()
                for index in range(model.rowCount()):
                    listViewItem = model.item(index)
                    listViewItem.setData( allLayersIcon[index], Qt.DecorationRole)
                    if frozenLayer :
                       if listViewItem.text() == frozenLayer.name() : listViewItem.setEnabled(False)


        if self.dialogInput.exec_() :
            if child :
               instance = QgsProject.instance()
               for index in child.selectionModel().selectedIndexes() :
                   nameLayer = child.model().itemFromIndex(index).text()
                   layer = instance.mapLayersByName(nameLayer)
                   if layer : 
                      if type(layer)== list : layer = layer[0]
                      if  not layer in self.mapCanvas1.layers() :
                          clayer = layer.clone()  
                          if layer.hasScaleBasedVisibility() : clayer.setScaleBasedVisibility(False)
                          self.project.addMapLayer(clayer)
                          layer = self.treeLegend.addItem([clayer.name()], "layers", clayer.id(), self.rasterIcon, "layers", self.treeLegend.rasters) if type(clayer) == QgsRasterLayer else  self.treeLegend.addItem([clayer.name()],  "layers", clayer.id(), self.vectorIcon, "layers", self.treeLegend.vectors)
                          layer.setCheckState(0, Qt.Checked)
               self.afterAddOrDelLayers()

    def afterAddOrDelLayers(self):                          
        extent = self.zoomAndSaveContext() 
        self.mapCanvas1.blockSignals(True)
        self.setBrigeForMapViewer()               
        self.setRefLayerForMapViewer2() 
        self.mapCanvas1.blockSignals(False)
        if self.mapCanvas1.mapTool() == self.toolMagnifyImage : self.toolMagnifyImage.updateMapViewer()
        self.mapCanvas1.setExtent(extent)
                   
    def setLayers(self, refLayer):
        self.currentLayers = []
        groupRefLayer = self.getGroupForTheLayer(refLayer)
        for layer in self.layers :
            group = self.getGroupForTheLayer(layer)            
            if group == groupRefLayer : self.currentLayers.append(layer)              
        if groupRefLayer == None : groupRefLayer = refLayer


    def getGroupForTheLayer(self, mapCanvasLayer):      
        root = QgsProject.instance().layerTreeRoot()
        groupLayer = None
        if not mapCanvasLayer : return None
        if not isinstance(mapCanvasLayer, QgsRasterLayer) : return None
        for layer in root.findLayers() :
            if isinstance(layer.layer(), QgsRasterLayer) :
               if layer.layer().id() == mapCanvasLayer.id() :
                  if type(layer.parent()) == QgsLayerTreeGroup : groupLayer = layer.parent() ; break
        return groupLayer
          

    def zoomToLayerExtent(self, layer, target):
        try : 
            ds = gdal.Open(layer.source())        
            minX, maxX = ds.GetGeoTransform()[0], (ds.RasterXSize*ds.GetGeoTransform()[1])+ds.GetGeoTransform()[0] 
            maxY, minY = ds.GetGeoTransform()[3], ds.GetGeoTransform()[3]+(ds.RasterYSize*ds.GetGeoTransform()[5])
            ds = None
            target.setExtent(QgsRectangle(minX, minY, maxX, maxY))
            target.refresh()            
        except : return           


def actionsWindows(parent, name, title, width, height, isLegende):
        self = QMdiSubWindow(parent)
        self.setObjectName(name)
        self.setWindowTitle(title)

        if isLegende :
           self.setWindowFlags(Qt.WindowTitleHint | Qt.WindowStaysOnTopHint)
           self.setStyleSheet("QMdiSubWindow { border: 1px solid;    border-radius: 5px;   background-color: rgba(255, 255, 255, 210);}"
                              "QMdiSubWindow QWidget { background-color: transparent; border:1px;}"
                              "QMdiSubWindow:title { height: 18px; background-color: rgba(255, 255, 255, 210);}")           
        else :
           self.setWindowFlags(Qt.WindowTitleHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint)
           self.setStyleSheet("QMdiSubWindow { border: 1px solid;    border-radius: 5px;   background-color: rgba(255, 255, 255, 210);}"
                              "QMdiSubWindow QWidget { background-color: transparent; border:1px;}"
                              "QMdiSubWindow:title { height: 18px; background-color: rgba(255, 255, 255, 210);}")
           self.setFixedSize(width, height)

        self.setGeometry(10, 10, width, height)
        
        self.oldPos = self.pos()

        return self

def ctrlMap(self, conteneur, complete, getPointsForExtent, simply, iX, iY, iW, iH, allActions):
        
         self.groupMap = QGroupBox(conteneur)

         self.actionsMapCanvas = QButtonGroup(conteneur) 
         self.actionsMapCanvas.setExclusive(True)

         if allActions :

             dicoCtrls = {"buttonCatchExtent" : ("catchextent.png", "Get extent for QGIS mapcanvas", 10, 20),
                          "buttonZoomIn" : ("zoomin.png", "Zoom in the map window", 40, 20),
                          "buttonZoomOut" : ("zoomout.png", "Zoom out the map window", 70, 20),
                          "buttonZoomAll" : ("zoomall.png", "Zoom all the map window", 100, 20),
                          "buttonZoomCurrentLayer" : ("zoomcurrentlayer.png", "Zoom to grid layer", 130, 20),
                          "buttonZoomPrevious" : ("zoomprev.png", "Previous zoom", 160, 20),
                          "buttonZoomNext" : ("zoomnext.png", "Next zoom", 190, 20),
                          "buttonSendExtent" : ("sendextent.png", "Send extent to Qgis mapcanvas", 220, 20),
                          "buttonPan" : ("pan.png", "Move the map window", 250, 20),
                          "buttonHotlink" : ("hotlink.png", "Load a raster file", 280, 20),
                          "buttonLoadExtent" : ("hotlinkextent.png", "Load the raster files for extent", 310, 20),
                          "buttonLoadSelected" : ("hotlinkselected.png", "Load the raster files for selected objects", 340, 20)
                          }
             

         else :
             #NEW 3.6.4
             dicoCtrls = {"buttonCatchExtent" : ("catchextent.png", "Get extent for QGIS mapcanvas", 10, 20),
                          "buttonZoomIn" : ("zoomin.png", "Zoom in the map window", 40, 20),
                          "buttonZoomOut" : ("zoomout.png", "Zoom out the map window", 70, 20),
                          "buttonZoomAll" : ("zoomall.png", "Zoom to all ...", 100, 20),
                          "buttonZoomPrevious" : ("zoomprev.png", "Previous zoom", 130, 20),
                          "buttonZoomNext" : ("zoomnext.png", "Next zoom", 160, 20),
                          "buttonSendExtent" : ("sendextent.png", "Send extent to Qgis mapcanvas", 190, 20),
                          "buttonClearExtents" : ("clearextents.png", "Clear zoom history", 220, 20),
                          "buttonPan" : ("pan.png", "Move the map window", 250, 20),
                          "boutonMagnify" : ("magnifycross.png", "Magnify particulat extent (CTRL+TAB to switch map)", 280, 20),
                          "buttonAddPermanentLayers" : ("add.png", "Add layers", 310, 20),
                          "buttonDelPermanentLayers" : ("del.png", "Delete layers", 340, 20)
                      }


         pos = 5

       
         for key in dicoCtrls :
      
                   icon = getThemeIcon(dicoCtrls[key][0])
                   toolTip = translateMsg(dicoCtrls[key][1])

                   button = myPushButton(self.groupMap)
                   
                   if key!= "buttonHotlink" : button.initPushButton(25, 25, pos, dicoCtrls[key][3], key, "", toolTip, True, icon, 25, 25, True)
                   else :  button.initPushButton(50, 25, pos, dicoCtrls[key][3], key, "", toolTip, True, icon, 50, 25, True)

                   if key in ("buttonZoomIn", "buttonZoomOut", "boutonMagnify", "buttonPan") : 

                      button.setStyleSheet(self.styleSheetPushButton)
                      button.setCheckable(True)

                      if key == "buttonZoomIn" : button.setChecked(True)
 
                      index = ("buttonZoomIn", "buttonZoomOut", "boutonMagnify", "buttonPan").index(key)
                      self.actionsMapCanvas.addButton(button, index)
                      

                   if key == "buttonHotlink" :
                      button.setStyleSheet(self.styleSheetPushButtonWithMenu)
                      button.setCheckable(True)

                      self.contextMnuToolsHotlink(button)

                   if key in ("buttonAddPermanentLayers", "buttonDelPermanentLayers") : button.setWhatsThis("ALL")   
                   setattr(self, key, button)
                   
                   if key == "buttonHotlink" : pos+= 50
                   else : pos+= 30 
                   

         sizeWidth = len(self.groupMap.children())*30
         self.groupMap.setGeometry(5, 10, sizeWidth+20, 50)           

         return sizeWidth



class toolMagnify(QgsMapTool):
    def __init__(self, parent, mapViewer, mapViewerBis, uiAlr):
        QgsMapTool.__init__(self, mapViewer)
        self.parent = parent
        self.imgMagnify = self.parent.imgMagnify
        self.labelCoordCursorPos = self.parent.labelCoordCursorPos
        self.delta = None
       
        self.mapViewer, self.mapViewerBis = mapViewer, mapViewerBis

        self.transformer = QgsCoordinateTransform()
        
        self.firstMapViewer = True
        self.status = 0
        self.cp = None
        self.cursor = QCursor(QPixmap(getThemeIcon("magnifycross.png")))
        self.timerMapTips = QTimer( self.mapViewer )

    def setTransformerCrs(self):
        if not self.mapViewer.layers() : return False, True
        if not self.mapViewerBis.layers() : return False, True
        index = len(self.mapViewer.layers())-1
        self.transformer.setSourceCrs(self.mapViewer.layers()[index].crs())
        try :
            index = len(self.mapViewer.layers())-1
            indexBis = len(self.mapViewerBis.layers())-1
            self.transformer.setDestinationCrs(self.mapViewerBis.layers()[indexBis].crs()) 
            sameCrs = (self.mapViewer.layers()[index].crs() == self.mapViewerBis.layers()[indexBis].crs()) 
        except : return False, True     
        return True, sameCrs

    def getDelta(self):
        delta = int(ceil(self.mapViewer.scale()) * 0.000000050) 
        return iff(delta < 10, 10, delta)

    def updateMapViewer(self) :
        if self.firstMapViewer : self.imgMagnify.setLayers(self.mapViewer.layers())        
        else : self.imgMagnify.setLayers(self.mapViewerBis.layers())
        if self.imgMagnify.layers() :
           index = len(self.imgMagnify.layers())-1
           self.imgMagnify.setDestinationCrs(self.imgMagnify.layers()[index].crs())
        if self.cp : self.updateCP(None, self.cp)

    def resetRb(self) :
        self.parent.rbDynaMire.reset()
        self.parent.rbDynaMire2.reset()
        self.parent.rb.reset()
        self.parent.rb2.reset()
        
    def updateRb(self):
        self.resetRb()        
        extent = self.imgMagnify.extent()
        
        if self.firstMapViewer :

            if self.mapViewerBis.layers() == [] : return

            index = len(self.mapViewer.layers())-1
            indexBis = len(self.mapViewerBis.layers())-1
            crs1 = self.mapViewer.layers()[index].crs() 
            crs2 = self.mapViewerBis.layers()[indexBis].crs() 

            self.parent.rb.addGeometry(QgsGeometry().fromRect(extent))
            if crs2 != crs1 : extent2 = self.transformer.transform(extent, QgsCoordinateTransform.ForwardTransform)
            else : extent2 = extent
            self.parent.rb2.addGeometry(QgsGeometry().fromRect(extent2), crs2)

            if self.cp :
                if crs2 != crs1 : cp2 = self.transformer.transform(self.cp, QgsCoordinateTransform.ForwardTransform)
                else : cp2 = self.cp
                self.drawAxes(self.mapViewer.extent(), crs1, self.cp, self.parent.rbDynaMire)                 
                self.drawAxes(self.mapViewerBis.extent(), crs2, cp2, self.parent.rbDynaMire2)
        else :

            if self.mapViewer.layers() == [] : return            

            index = len(self.mapViewer.layers())-1
            indexBis = len(self.mapViewerBis.layers())-1
            crs1 = self.mapViewerBis.layers()[indexBis].crs() 
            crs2 = self.mapViewer.layers()[index].crs() 

            if crs2 != crs1 : extent1 = self.transformer.transform(extent, QgsCoordinateTransform.ReverseTransform)
            else : extent1 = extent
            
            self.parent.rb.addGeometry(QgsGeometry().fromRect(extent1), crs2)
            self.parent.rb2.addGeometry(QgsGeometry().fromRect(extent), crs1)
            
            if self.cp :
                if crs2 != crs1 : cp1 = self.transformer.transform(self.cp, QgsCoordinateTransform.ReverseTransform)
                else : cp1 = self.cp
                self.drawAxes(self.mapViewer.extent(), crs2, cp1, self.parent.rbDynaMire)
                self.drawAxes(self.mapViewerBis.extent(), crs1, self.cp, self.parent.rbDynaMire2)
            
        
    def drawAxes(self, extent, crs, cp, rbDyna):
        if not cp : return
        if not extent : return
         
        point1, point2  = QgsPointXY(extent.xMinimum(), cp.y()), QgsPointXY(extent.xMaximum(), cp.y())
        geometry = QgsGeometry().fromPolylineXY([point1, point2])
        rbDyna.addGeometry(geometry, crs)

        point1, point2  = QgsPointXY(cp.x(), extent.yMaximum()), QgsPointXY(cp.x(), extent.yMinimum())
        geometry = QgsGeometry().fromPolylineXY([point1, point2])
        rbDyna.addGeometry(geometry, crs)        

    def zoomInMg(self): self.resetRb(); self.imgMagnify.zoomIn(); self.updateRb();
    def zoomOutMg(self): self.resetRb(); self.imgMagnify.zoomOut(); self.updateRb();

    def setVisibleCtrl(self, cond):
        self.imgMagnify.setVisible(cond)
        self.labelCoordCursorPos.setVisible(cond)
        
    def deactivate(self) :
        self.cp = None
        self.resetRb()
        self.setVisibleCtrl(False)
        self.firstMapViewer = True
           
    def activate(self) :
        self.updateMapViewer()
        self.setCursor(self.cursor)
        self.setVisibleCtrl(True)
        self.firstMapViewer = True
        
    def keyPressEvent(self, event) :
        if event.key() == Qt.Key_Tab :
           self.firstMapViewer = not (self.firstMapViewer)
           self.updateMapViewer()
           self.updateRb()
        elif event.key() == Qt.Key_Plus : self.zoomInMg()
        elif event.key() == Qt.Key_Minus : self.zoomOutMg()

    def canvasMoveEvent(self, e): self.updateCP(e.pos(), None)
    
    def updateCP(self, e, point):

        ready, cond = self.setTransformerCrs()
        
        if not e :
           if not self.firstMapViewer :
              pos = self.toCanvasCoordinates(point)
           else :
              tPoint = self.transformer.transform(point, QgsCoordinateTransform.ReverseTransform) if not cond else point
              pos = self.toCanvasCoordinates(QgsPointXY(tPoint.x(), tPoint.y()))
        else : pos = e
        
        point = QgsPointXY(pos.x(), pos.y())
        

        self.cp = self.toMapCoordinates(pos) 
        self.labelCoordCursorPos.setText("x : %s, y : %s" % (round(self.cp.x(), 4), round(self.cp.y(), 4)))
        self.resetRb()

        if not self.delta :        
            delta = self.getDelta()            
            minX, maxX = self.cp.x() - delta, self.cp.x() + delta
            minY, maxY = self.cp.y() - delta, self.cp.y() + delta
            extent = QgsRectangle(minX, minY, maxX, maxY)
            self.delta = delta

            if not self.firstMapViewer :
               extent1 = self.transformer.transform(extent, QgsCoordinateTransform.ForwardTransform) if not cond else extent
            else : extent1 = extent
            
            self.imgMagnify.setExtent(extent1)
            
        else :
            if not self.firstMapViewer :
               self.cp = self.transformer.transform(self.cp, QgsCoordinateTransform.ForwardTransform) if not cond else self.cp
            self.imgMagnify.setCenter(self.cp) ; extent = self.imgMagnify.extent()

        self.imgMagnify.refresh()

       
        if pos.y()+345 < self.mapViewer.height() : self.imgMagnify.setGeometry(pos.x()+25, pos.y()+25, 320, 320)
        else : self.imgMagnify.setGeometry(pos.x()+25, pos.y()-305, 320, 320)
        self.labelCoordCursorPos.setGeometry(self.imgMagnify.x(), self.imgMagnify.y()-25, 320, 25)


        self.updateRb()
        
