# -*- coding: utf-8 -*-
"""
/***************************************************************************
 QGisImajnetPlugin
                                 Imajnet QGIS plugin
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2018-06-20
        git sha              : $Format:%H$
        copyright            : (C) 2018 by JC
        email                : jchesnel@imajing.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

# Uncomment to test if QtWebEngine is usable
# from PyQt5 import QtWebEngine, QtWebEngineWidgets
# from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage


from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QUrl,QObject
from PyQt5.QtGui import QIcon, QKeySequence,QDesktopServices
from PyQt5.QtWidgets import QAction
# Initialize Qt resources from file resources.py
from .resources import *

# Import the code for the DockWidget
from .QGisImajnetPlugin_dockwidget import QGisImajnetPluginDockWidget
from .QGisImajnetPlugin_debugwindow import QGisImajnetPluginDebugWindow
import os.path

from qgis import *
from qgis.core import *

from .ImajnetMapTool import  ImajnetMapTool
from .ImajnetLog import ImajnetLog
from .QGisImajnetPluginAboutWindow import QGisImajnetPluginAboutWindow
from .PyImajnet import PyImajnet
from .openlayers.openlayers_layer import ImajnetOpenlayersLayer


class ImajnetPluginLayerType(QgsPluginLayerType):

  def __init__(self, iface, plugin):
    QgsPluginLayerType.__init__(self, ImajnetOpenlayersLayer.LAYER_TYPE)
    self.iface = iface
    self.plugin = plugin

  def createLayer(self):
    #ImajnetLog.error("ImajnetPluginLayerType createLayer called")
    if not self.plugin.pluginIsActive:
        self.plugin.run()
    return ImajnetOpenlayersLayer(self.iface,PyImajnet.instance)

  def showLayerProperties(self, layer):
     return False
 
class QGisImajnetPlugin:
    """QGIS Plugin Implementation."""
    autoInitDebugWindow = False
    imajnetMapTool = None
    
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        ImajnetLog.init()
        # Save reference to the QGIS interface
        self.iface = iface
        
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        self.locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'QGisImajnetPlugin_{}.qm'.format(self.locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'Imajnet')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(self.tr(u'Imajnet'))
        self.toolbar.setObjectName(self.tr(u'Imajnet'))

        #print "** INITIALIZING QGisImajnetPlugin"

        self.pluginIsActive = False
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
        self.imajnetMapTool = None
        self.aboutDialog = None
        self.pluginLayerRegistry = QgsApplication.pluginLayerRegistry()
        
        # Register plugin layer type
        res = self.pluginLayerRegistry.addPluginLayerType(ImajnetPluginLayerType(self.iface,self))
        #ImajnetLog.error("ImajnetPluginLayerType: {}".format(res))
        
        self.manager = QgsNetworkAccessManager.instance() #QNetworkAccessManager()
        self.cookieJar = self.manager.cookieJar()
        if self.cookieJar is None:
            self.cookieJar = QNetworkCookieJar()
            #QgsNetworkAccessManager.instance().setCookieJar(self.cookieJar)
            self.manager.setCookieJar(self.cookieJar)
        
         
    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('@QGisImajnetPlugin', message)


    def add_action(
        self,
        icon_path,
        text,
        callback,
        checkable_flag=False,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool
        
        :param checkable_flag: A flag indicating if the action should be checkable. 
            Defaults to False.
        :type checkable_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        action.setCheckable(checkable_flag)
        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToWebMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action


    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        #icon_path = ':/plugins/QGisImajnetPlugin/icon.png'
        icon_path = ':/plugins/imajnet-qgis-plugin/resources/img/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Imajnet plugin'),
            callback=self.run,
            parent=self.iface.mainWindow())
            
        self._closestImageAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/closestImageMode.png',
            text=self.tr(u'Closest image'),
            callback=self.on_closestImage_click,
            checkable_flag=True,
            enabled_flag=False,
            add_to_menu=False,
            add_to_toolbar=True,
            status_tip=self.tr(u'Click on the map and get the closest image'),
            whats_this=self.tr(u'Imajnet closest image tool'),
            parent=self.iface.mainWindow())
        
        self._clickModeAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/clickMode.png',
            text=self.tr(u'Click mode'),
            callback=self.on_clickMode_click,
            checkable_flag=True,
            enabled_flag=False,
            add_to_menu=False,
            add_to_toolbar=True,
            status_tip=self.tr(u'Click on an object and get an image oriented towards that object'),
            whats_this=self.tr(u'Imajnet click mode tool'),
            parent=self.iface.mainWindow())
        
        
        self._aboutAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/about.png',
            text=self.tr(u'About'),
            callback=self.on_about_click,
            enabled_flag=True,
            add_to_menu=True,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        
        self._helpAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/help.png',
            text=self.tr(u'Help'),
            callback=self.on_help_click,
            enabled_flag=True,
            add_to_menu=True,
            add_to_toolbar=True,
            parent=self.iface.mainWindow())
        
        self._disconnectAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/logout.png',
            text=self.tr(u'Disconnect'),
            callback=self.on_disconnect_click,
            enabled_flag=False,
            add_to_menu=True,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        
        self._debugModeAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/debug.png',
            text=self.tr(u'Debug'),
            callback=self.on_debug_click,
            enabled_flag=False,
            add_to_menu=self.isDevMode(),
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        debugShortcutKeys = QKeySequence("Ctrl+I")
        self._debugModeAction.setShortcut(debugShortcutKeys)
        #self._debugModeAction.setVisible(False)
        
                
        self._jumpForwardAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png',
            text=self.tr(u'jump forward'),
            callback=self.jumpForward,
            enabled_flag=True,
            add_to_menu=False,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpForwardShortcutKeys = QKeySequence("PgUp")
        self._jumpForwardAction.setShortcut(jumpForwardShortcutKeys)
        
        self._jumpBackwardAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png',
            text=self.tr(u'jump backward'),
            callback=self.jumpBackward,
            enabled_flag=True,
            add_to_menu=False,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())                
        jumpBackwardShortcutKeys = QKeySequence("PgDown")
        self._jumpBackwardAction.setShortcut(jumpBackwardShortcutKeys)
        
        
        self._jumpForwardShortAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png',
            text=self.tr(u'jump forward short'),
            callback=self.jumpForwardShort,
            enabled_flag=True,
            add_to_menu=False,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpForwardShortShortcutKeys = QKeySequence("Shift+PgUp")
        self._jumpForwardShortAction.setShortcut(jumpForwardShortShortcutKeys)
        
        self._jumpBackwardShortAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png',
            text=self.tr(u'jump backward short'),
            callback=self.jumpBackwardShort,
            enabled_flag=True,
            add_to_menu=False,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())                
        jumpBackwardShortShortcutKeys = QKeySequence("Shift+PgDown")
        self._jumpBackwardShortAction.setShortcut(jumpBackwardShortShortcutKeys)
        
    #--------------------------------------------------------------------------
        
    def onClosePlugin(self, isUserAction = False):
        """Cleanup necessary items here when plugin dockwidget is closed"""
        ImajnetLog.info("** CLOSING QGisImajnetPlugin")
        
        if self.debugWidget != None:
            self.debugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.debugWidget.hide()
        if self.mapDebugWidget != None:
            self.mapDebugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.mapDebugWidget.hide()
            
        if (self.dockwidget is not None):
            self.dockwidget.cleanup(isUserAction)
            #disconnects
            self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
            self.dockwidget.hide()
            self.iface.removeDockWidget(self.dockwidget)
            self.dockwidget = None
            
            
        # remove this statement if dockwidget is to remain
        # for reuse if plugin is reopened
        # Commented next statement since it causes QGIS crashe
        # when closing the docked window:
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
                
        
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)
        self.imajnetMapTool = None

        self.pluginIsActive = False

        #self.iface.unregisterMainWindowAction(self._jumpForwardAction)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        
        ImajnetLog.info("** UNLOAD QGisImajnetPlugin")

        if self.pluginIsActive:
            self.onClosePlugin(False)
            
        for action in self.actions:
            self.iface.removePluginWebMenu(
                self.tr(u'&Imajnet'),
                action)
            self.iface.removeToolBarIcon(action)
            
        
        # remove the toolbar
        del self.toolbar
        
        if self.aboutDialog :
            self.aboutDialog = None
            #del self.aboutDialog
        
        self.pluginLayerRegistry.removePluginLayerType(ImajnetOpenlayersLayer.LAYER_TYPE)
        #ImajnetLog.error("** UNLOADED")
        ImajnetLog.close()
        

    #--------------------------------------------------------------------------

    def run(self):
        """Run method that loads and starts the plugin"""
        
        # IF SOMETHING SHALL BE MODIFIED BY USER THIS MUST BE HERE
        
        if self.pluginIsActive:
            self.onClosePlugin(True)
        else:
            self.pluginIsActive = True

            ImajnetLog.info("** STARTING QGisImajnetPlugin")


            # Create the dockwidget (after translation) and keep reference
            self.dockwidget = QGisImajnetPluginDockWidget(self.iface, self)
            
            #enable the map tool
            self.imajnetMapTool = ImajnetMapTool(self)
            self.imajnetMapTool.setClickMode(False)
            
            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)

            # show the dockwidget
            # TODO: fix to allow choice of dock location
            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget)
            self.dockwidget.show()
            self._debugModeAction.setEnabled(True)
            
            if QGisImajnetPlugin.autoInitDebugWindow ==  True:
                self.showOrHideDebugWindow()
            
            
        
    #--------------------------------------------------------------------------
            
            
    def showOrHideDebugWindow(self):
        """Shows the imajnet debug window"""
        firstLoad = False
              
        if self.debugWidget == None:   
                self.debugWidget = QGisImajnetPluginDebugWindow(self.iface,self.dockwidget.m_view)
                self.debugWidget.closingPlugin.connect(self.onClosePlugin)
                self.iface.addDockWidget(Qt.NoDockWidgetArea, self.debugWidget)
                firstLoad=True
                
        if self.debugWidget.isVisible() and not(firstLoad):         
                self.debugWidget.hide()
        else:
                self.debugWidget.show()
                
        if self.mapDebugWidget == None:   
                self.mapDebugWidget = QGisImajnetPluginDebugWindow(self.iface,None)
                self.mapDebugWidget.closingPlugin.connect(self.onClosePlugin)
                self.iface.addDockWidget(Qt.NoDockWidgetArea, self.mapDebugWidget)
                firstLoad=True
        if self.mapDebugWidget.isVisible() and not(firstLoad):         
                self.mapDebugWidget.hide()
        else:
                self.mapDebugWidget.show()
    #-------------------------------------------------------------------------
    
    def on_closestImage_click(self):
        self.enableImajnetMapTool(False);
        self._closestImageAction.setChecked(True)
        self._clickModeAction.setChecked(False)
        return True
    
    def on_clickMode_click(self):
        self.enableImajnetMapTool(True);
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(True)
        return False
    
    def enableImajnetMapTool(self, clickMode):
        ImajnetLog.info('enableImajnetMapTool')
        if self.imajnetMapTool is not None:
             self.imajnetMapTool.setClickMode(clickMode)
             self.iface.mapCanvas().setMapTool(self.imajnetMapTool)
        
    def on_debug_click(self):
        self.showOrHideDebugWindow()
    
    def on_disconnect_click(self):
        self.disableImajnetActions()

        # due to issue #34, logout is not working properly as qgis gets stuck. We replace the call with the cleanup 
        # code + page reload which triggers the unload event that does the actual logout         
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("cleanupForLogout()")
        self.dockwidget.m_view.reload()
        #self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("doLogout()")
        
    def on_help_click(self):
        QDesktopServices.openUrl(QUrl("https://imajnet.net/userguide/qgis/UG_IMAJNET_QGIS_{}.pdf".format(self.locale.upper()), QUrl.TolerantMode));
        
    def on_about_click(self):
        if not self.aboutDialog :
            self.aboutDialog = QGisImajnetPluginAboutWindow(self)
        self._debugModeAction.setEnabled(True)
        
        # show the dialog
        self.aboutDialog.show()
        #self.aboutDialog.raise()
        self.aboutDialog.activateWindow()
            
        #    # Run the dialog event loop
        #result = self.aboutDialog.exec_()
        #self._debugModeAction.setEnabled(False)
        ## See if OK was pressed
        #if result:
        #    # Do something useful here - delete the line containing pass and
        #    # substitute with your code.
        #    pass
        
    def enableImajnetActions(self):
        self._closestImageAction.setEnabled(True)
        self._clickModeAction.setEnabled(True)
        self._debugModeAction.setEnabled(True)
        self._disconnectAction.setEnabled(True)
        self.on_closestImage_click()
        
    def disableImajnetActions(self):     
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)   
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(False)
        
        self._closestImageAction.setEnabled(False)
        self._clickModeAction.setEnabled(False)
        self._debugModeAction.setEnabled(False)
        self._disconnectAction.setEnabled(False)
        
    def uncheckImajnetActions(self):
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(False) 
    
    def isDevMode(self):
        s = QSettings()
        return s.value("imajnet/devMode",False)
    
    def toggleDevMode(self):        
        s = QSettings()
        s.setValue("imajnet/devMode", not self.isDevMode())
        if self.isDevMode():            
            self.iface.addPluginToWebMenu(self.menu,self._debugModeAction)
        else:
            self.iface.removePluginWebMenu(self.menu,self._debugModeAction)
        self.iface.messageBar().pushMessage("Imajnet", "Dev mode toggled", level=Qgis.Info, duration=3)
    
    def enableAdvancedFeatures(self):
        self.iface.addPluginToWebMenu(self.menu,self._jumpForwardAction)
        self.iface.addPluginToWebMenu(self.menu,self._jumpBackwardAction)
        self.iface.addPluginToWebMenu(self.menu,self._jumpForwardShortAction)
        self.iface.addPluginToWebMenu(self.menu,self._jumpBackwardShortAction)
        
    def disableAdvancedFeatures(self):
        self.iface.removePluginWebMenu(self.menu,self._jumpForwardAction)
        self.iface.removePluginWebMenu(self.menu,self._jumpBackwardAction)
        self.iface.removePluginWebMenu(self.menu,self._jumpForwardShortAction)
        self.iface.removePluginWebMenu(self.menu,self._jumpBackwardShortAction)
        
    def jumpForward(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("ImajnetAPI.jumpForward()")
             
    def jumpBackward(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("ImajnetAPI.jumpBackwards()")    
    
    def jumpForwardShort(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("ImajnetAPI.jumpForwardShort()")
             
    def jumpBackwardShort(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("ImajnetAPI.jumpBackwardsShort()")

4db2540d5aed1a39e8638bcf3bc40f84d08b5eaa
<mask token>


class QGisImajnetPlugin:
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>
    <mask token>

    def onClosePlugin(self, isUserAction=False):
        """Cleanup necessary items here when plugin dockwidget is closed"""
        ImajnetLog.info('** CLOSING QGisImajnetPlugin')
        if self.debugWidget != None:
            self.debugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.debugWidget.hide()
        if self.mapDebugWidget != None:
            self.mapDebugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.mapDebugWidget.hide()
        if self.dockwidget is not None:
            self.dockwidget.cleanup(isUserAction)
            self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
            self.dockwidget.hide()
            self.iface.removeDockWidget(self.dockwidget)
            self.dockwidget = None
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)
        self.imajnetMapTool = None
        self.pluginIsActive = False

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        ImajnetLog.info('** UNLOAD QGisImajnetPlugin')
        if self.pluginIsActive:
            self.onClosePlugin(False)
        for action in self.actions:
            self.iface.removePluginWebMenu(self.tr(u'&Imajnet'), action)
            self.iface.removeToolBarIcon(action)
        del self.toolbar
        if self.aboutDialog:
            self.aboutDialog = None
        self.pluginLayerRegistry.removePluginLayerType(ImajnetOpenlayersLayer
            .LAYER_TYPE)
        ImajnetLog.close()
    <mask token>
    <mask token>

    def on_closestImage_click(self):
        self.enableImajnetMapTool(False)
        self._closestImageAction.setChecked(True)
        self._clickModeAction.setChecked(False)
        return True
    <mask token>

    def enableImajnetMapTool(self, clickMode):
        ImajnetLog.info('enableImajnetMapTool')
        if self.imajnetMapTool is not None:
            self.imajnetMapTool.setClickMode(clickMode)
            self.iface.mapCanvas().setMapTool(self.imajnetMapTool)

    def on_debug_click(self):
        self.showOrHideDebugWindow()

    def on_disconnect_click(self):
        self.disableImajnetActions()
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'cleanupForLogout()')
        self.dockwidget.m_view.reload()
    <mask token>
    <mask token>

    def enableImajnetActions(self):
        self._closestImageAction.setEnabled(True)
        self._clickModeAction.setEnabled(True)
        self._debugModeAction.setEnabled(True)
        self._disconnectAction.setEnabled(True)
        self.on_closestImage_click()
    <mask token>
    <mask token>
    <mask token>

    def toggleDevMode(self):
        s = QSettings()
        s.setValue('imajnet/devMode', not self.isDevMode())
        if self.isDevMode():
            self.iface.addPluginToWebMenu(self.menu, self._debugModeAction)
        else:
            self.iface.removePluginWebMenu(self.menu, self._debugModeAction)
        self.iface.messageBar().pushMessage('Imajnet', 'Dev mode toggled',
            level=Qgis.Info, duration=3)

    def enableAdvancedFeatures(self):
        self.iface.addPluginToWebMenu(self.menu, self._jumpForwardAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpBackwardAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpForwardShortAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpBackwardShortAction)
    <mask token>
    <mask token>
    <mask token>
    <mask token>

    def jumpBackwardShort(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpBackwardsShort()')

<mask token>


class QGisImajnetPlugin:
    <mask token>
    <mask token>
    <mask token>
    <mask token>

    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        return QCoreApplication.translate('@QGisImajnetPlugin', message)

    def add_action(self, icon_path, text, callback, checkable_flag=False,
        enabled_flag=True, add_to_menu=True, add_to_toolbar=True,
        status_tip=None, whats_this=None, parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool
        
        :param checkable_flag: A flag indicating if the action should be checkable. 
            Defaults to False.
        :type checkable_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """
        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        action.setCheckable(checkable_flag)
        if status_tip is not None:
            action.setStatusTip(status_tip)
        if whats_this is not None:
            action.setWhatsThis(whats_this)
        if add_to_toolbar:
            self.toolbar.addAction(action)
        if add_to_menu:
            self.iface.addPluginToWebMenu(self.menu, action)
        self.actions.append(action)
        return action
    <mask token>

    def onClosePlugin(self, isUserAction=False):
        """Cleanup necessary items here when plugin dockwidget is closed"""
        ImajnetLog.info('** CLOSING QGisImajnetPlugin')
        if self.debugWidget != None:
            self.debugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.debugWidget.hide()
        if self.mapDebugWidget != None:
            self.mapDebugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.mapDebugWidget.hide()
        if self.dockwidget is not None:
            self.dockwidget.cleanup(isUserAction)
            self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
            self.dockwidget.hide()
            self.iface.removeDockWidget(self.dockwidget)
            self.dockwidget = None
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)
        self.imajnetMapTool = None
        self.pluginIsActive = False

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        ImajnetLog.info('** UNLOAD QGisImajnetPlugin')
        if self.pluginIsActive:
            self.onClosePlugin(False)
        for action in self.actions:
            self.iface.removePluginWebMenu(self.tr(u'&Imajnet'), action)
            self.iface.removeToolBarIcon(action)
        del self.toolbar
        if self.aboutDialog:
            self.aboutDialog = None
        self.pluginLayerRegistry.removePluginLayerType(ImajnetOpenlayersLayer
            .LAYER_TYPE)
        ImajnetLog.close()

    def run(self):
        """Run method that loads and starts the plugin"""
        if self.pluginIsActive:
            self.onClosePlugin(True)
        else:
            self.pluginIsActive = True
            ImajnetLog.info('** STARTING QGisImajnetPlugin')
            self.dockwidget = QGisImajnetPluginDockWidget(self.iface, self)
            self.imajnetMapTool = ImajnetMapTool(self)
            self.imajnetMapTool.setClickMode(False)
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)
            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget)
            self.dockwidget.show()
            self._debugModeAction.setEnabled(True)
            if QGisImajnetPlugin.autoInitDebugWindow == True:
                self.showOrHideDebugWindow()
    <mask token>

    def on_closestImage_click(self):
        self.enableImajnetMapTool(False)
        self._closestImageAction.setChecked(True)
        self._clickModeAction.setChecked(False)
        return True
    <mask token>

    def enableImajnetMapTool(self, clickMode):
        ImajnetLog.info('enableImajnetMapTool')
        if self.imajnetMapTool is not None:
            self.imajnetMapTool.setClickMode(clickMode)
            self.iface.mapCanvas().setMapTool(self.imajnetMapTool)

    def on_debug_click(self):
        self.showOrHideDebugWindow()

    def on_disconnect_click(self):
        self.disableImajnetActions()
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'cleanupForLogout()')
        self.dockwidget.m_view.reload()
    <mask token>
    <mask token>

    def enableImajnetActions(self):
        self._closestImageAction.setEnabled(True)
        self._clickModeAction.setEnabled(True)
        self._debugModeAction.setEnabled(True)
        self._disconnectAction.setEnabled(True)
        self.on_closestImage_click()

    def disableImajnetActions(self):
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(False)
        self._closestImageAction.setEnabled(False)
        self._clickModeAction.setEnabled(False)
        self._debugModeAction.setEnabled(False)
        self._disconnectAction.setEnabled(False)
    <mask token>
    <mask token>

    def toggleDevMode(self):
        s = QSettings()
        s.setValue('imajnet/devMode', not self.isDevMode())
        if self.isDevMode():
            self.iface.addPluginToWebMenu(self.menu, self._debugModeAction)
        else:
            self.iface.removePluginWebMenu(self.menu, self._debugModeAction)
        self.iface.messageBar().pushMessage('Imajnet', 'Dev mode toggled',
            level=Qgis.Info, duration=3)

    def enableAdvancedFeatures(self):
        self.iface.addPluginToWebMenu(self.menu, self._jumpForwardAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpBackwardAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpForwardShortAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpBackwardShortAction)
    <mask token>

    def jumpForward(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpForward()')
    <mask token>
    <mask token>

    def jumpBackwardShort(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpBackwardsShort()')

<mask token>


class QGisImajnetPlugin:
    <mask token>
    <mask token>
    <mask token>

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        ImajnetLog.init()
        self.iface = iface
        self.plugin_dir = os.path.dirname(__file__)
        self.locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
            'QGisImajnetPlugin_{}.qm'.format(self.locale))
        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)
        self.actions = []
        self.menu = self.tr(u'Imajnet')
        self.toolbar = self.iface.addToolBar(self.tr(u'Imajnet'))
        self.toolbar.setObjectName(self.tr(u'Imajnet'))
        self.pluginIsActive = False
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
        self.imajnetMapTool = None
        self.aboutDialog = None
        self.pluginLayerRegistry = QgsApplication.pluginLayerRegistry()
        res = self.pluginLayerRegistry.addPluginLayerType(
            ImajnetPluginLayerType(self.iface, self))
        self.manager = QgsNetworkAccessManager.instance()
        self.cookieJar = self.manager.cookieJar()
        if self.cookieJar is None:
            self.cookieJar = QNetworkCookieJar()
            self.manager.setCookieJar(self.cookieJar)

    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        return QCoreApplication.translate('@QGisImajnetPlugin', message)

    def add_action(self, icon_path, text, callback, checkable_flag=False,
        enabled_flag=True, add_to_menu=True, add_to_toolbar=True,
        status_tip=None, whats_this=None, parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool
        
        :param checkable_flag: A flag indicating if the action should be checkable. 
            Defaults to False.
        :type checkable_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """
        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        action.setCheckable(checkable_flag)
        if status_tip is not None:
            action.setStatusTip(status_tip)
        if whats_this is not None:
            action.setWhatsThis(whats_this)
        if add_to_toolbar:
            self.toolbar.addAction(action)
        if add_to_menu:
            self.iface.addPluginToWebMenu(self.menu, action)
        self.actions.append(action)
        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        icon_path = ':/plugins/imajnet-qgis-plugin/resources/img/icon.png'
        self.add_action(icon_path, text=self.tr(u'Imajnet plugin'),
            callback=self.run, parent=self.iface.mainWindow())
        self._closestImageAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/closestImageMode.png',
            text=self.tr(u'Closest image'), callback=self.
            on_closestImage_click, checkable_flag=True, enabled_flag=False,
            add_to_menu=False, add_to_toolbar=True, status_tip=self.tr(
            u'Click on the map and get the closest image'), whats_this=self
            .tr(u'Imajnet closest image tool'), parent=self.iface.mainWindow())
        self._clickModeAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/clickMode.png',
            text=self.tr(u'Click mode'), callback=self.on_clickMode_click,
            checkable_flag=True, enabled_flag=False, add_to_menu=False,
            add_to_toolbar=True, status_tip=self.tr(
            u'Click on an object and get an image oriented towards that object'
            ), whats_this=self.tr(u'Imajnet click mode tool'), parent=self.
            iface.mainWindow())
        self._aboutAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/about.png', text=
            self.tr(u'About'), callback=self.on_about_click, enabled_flag=
            True, add_to_menu=True, add_to_toolbar=False, parent=self.iface
            .mainWindow())
        self._helpAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/help.png', text=
            self.tr(u'Help'), callback=self.on_help_click, enabled_flag=
            True, add_to_menu=True, add_to_toolbar=True, parent=self.iface.
            mainWindow())
        self._disconnectAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/logout.png', text=
            self.tr(u'Disconnect'), callback=self.on_disconnect_click,
            enabled_flag=False, add_to_menu=True, add_to_toolbar=False,
            parent=self.iface.mainWindow())
        self._debugModeAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/debug.png', text=
            self.tr(u'Debug'), callback=self.on_debug_click, enabled_flag=
            False, add_to_menu=self.isDevMode(), add_to_toolbar=False,
            parent=self.iface.mainWindow())
        debugShortcutKeys = QKeySequence('Ctrl+I')
        self._debugModeAction.setShortcut(debugShortcutKeys)
        self._jumpForwardAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png', text=
            self.tr(u'jump forward'), callback=self.jumpForward,
            enabled_flag=True, add_to_menu=False, add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpForwardShortcutKeys = QKeySequence('PgUp')
        self._jumpForwardAction.setShortcut(jumpForwardShortcutKeys)
        self._jumpBackwardAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png', text=
            self.tr(u'jump backward'), callback=self.jumpBackward,
            enabled_flag=True, add_to_menu=False, add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpBackwardShortcutKeys = QKeySequence('PgDown')
        self._jumpBackwardAction.setShortcut(jumpBackwardShortcutKeys)
        self._jumpForwardShortAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png', text=
            self.tr(u'jump forward short'), callback=self.jumpForwardShort,
            enabled_flag=True, add_to_menu=False, add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpForwardShortShortcutKeys = QKeySequence('Shift+PgUp')
        self._jumpForwardShortAction.setShortcut(jumpForwardShortShortcutKeys)
        self._jumpBackwardShortAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png', text=
            self.tr(u'jump backward short'), callback=self.
            jumpBackwardShort, enabled_flag=True, add_to_menu=False,
            add_to_toolbar=False, parent=self.iface.mainWindow())
        jumpBackwardShortShortcutKeys = QKeySequence('Shift+PgDown')
        self._jumpBackwardShortAction.setShortcut(jumpBackwardShortShortcutKeys
            )

    def onClosePlugin(self, isUserAction=False):
        """Cleanup necessary items here when plugin dockwidget is closed"""
        ImajnetLog.info('** CLOSING QGisImajnetPlugin')
        if self.debugWidget != None:
            self.debugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.debugWidget.hide()
        if self.mapDebugWidget != None:
            self.mapDebugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.mapDebugWidget.hide()
        if self.dockwidget is not None:
            self.dockwidget.cleanup(isUserAction)
            self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
            self.dockwidget.hide()
            self.iface.removeDockWidget(self.dockwidget)
            self.dockwidget = None
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)
        self.imajnetMapTool = None
        self.pluginIsActive = False

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        ImajnetLog.info('** UNLOAD QGisImajnetPlugin')
        if self.pluginIsActive:
            self.onClosePlugin(False)
        for action in self.actions:
            self.iface.removePluginWebMenu(self.tr(u'&Imajnet'), action)
            self.iface.removeToolBarIcon(action)
        del self.toolbar
        if self.aboutDialog:
            self.aboutDialog = None
        self.pluginLayerRegistry.removePluginLayerType(ImajnetOpenlayersLayer
            .LAYER_TYPE)
        ImajnetLog.close()

    def run(self):
        """Run method that loads and starts the plugin"""
        if self.pluginIsActive:
            self.onClosePlugin(True)
        else:
            self.pluginIsActive = True
            ImajnetLog.info('** STARTING QGisImajnetPlugin')
            self.dockwidget = QGisImajnetPluginDockWidget(self.iface, self)
            self.imajnetMapTool = ImajnetMapTool(self)
            self.imajnetMapTool.setClickMode(False)
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)
            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget)
            self.dockwidget.show()
            self._debugModeAction.setEnabled(True)
            if QGisImajnetPlugin.autoInitDebugWindow == True:
                self.showOrHideDebugWindow()

    def showOrHideDebugWindow(self):
        """Shows the imajnet debug window"""
        firstLoad = False
        if self.debugWidget == None:
            self.debugWidget = QGisImajnetPluginDebugWindow(self.iface,
                self.dockwidget.m_view)
            self.debugWidget.closingPlugin.connect(self.onClosePlugin)
            self.iface.addDockWidget(Qt.NoDockWidgetArea, self.debugWidget)
            firstLoad = True
        if self.debugWidget.isVisible() and not firstLoad:
            self.debugWidget.hide()
        else:
            self.debugWidget.show()
        if self.mapDebugWidget == None:
            self.mapDebugWidget = QGisImajnetPluginDebugWindow(self.iface, None
                )
            self.mapDebugWidget.closingPlugin.connect(self.onClosePlugin)
            self.iface.addDockWidget(Qt.NoDockWidgetArea, self.mapDebugWidget)
            firstLoad = True
        if self.mapDebugWidget.isVisible() and not firstLoad:
            self.mapDebugWidget.hide()
        else:
            self.mapDebugWidget.show()

    def on_closestImage_click(self):
        self.enableImajnetMapTool(False)
        self._closestImageAction.setChecked(True)
        self._clickModeAction.setChecked(False)
        return True
    <mask token>

    def enableImajnetMapTool(self, clickMode):
        ImajnetLog.info('enableImajnetMapTool')
        if self.imajnetMapTool is not None:
            self.imajnetMapTool.setClickMode(clickMode)
            self.iface.mapCanvas().setMapTool(self.imajnetMapTool)

    def on_debug_click(self):
        self.showOrHideDebugWindow()

    def on_disconnect_click(self):
        self.disableImajnetActions()
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'cleanupForLogout()')
        self.dockwidget.m_view.reload()

    def on_help_click(self):
        QDesktopServices.openUrl(QUrl(
            'https://imajnet.net/userguide/qgis/UG_IMAJNET_QGIS_{}.pdf'.
            format(self.locale.upper()), QUrl.TolerantMode))
    <mask token>

    def enableImajnetActions(self):
        self._closestImageAction.setEnabled(True)
        self._clickModeAction.setEnabled(True)
        self._debugModeAction.setEnabled(True)
        self._disconnectAction.setEnabled(True)
        self.on_closestImage_click()

    def disableImajnetActions(self):
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(False)
        self._closestImageAction.setEnabled(False)
        self._clickModeAction.setEnabled(False)
        self._debugModeAction.setEnabled(False)
        self._disconnectAction.setEnabled(False)
    <mask token>

    def isDevMode(self):
        s = QSettings()
        return s.value('imajnet/devMode', False)

    def toggleDevMode(self):
        s = QSettings()
        s.setValue('imajnet/devMode', not self.isDevMode())
        if self.isDevMode():
            self.iface.addPluginToWebMenu(self.menu, self._debugModeAction)
        else:
            self.iface.removePluginWebMenu(self.menu, self._debugModeAction)
        self.iface.messageBar().pushMessage('Imajnet', 'Dev mode toggled',
            level=Qgis.Info, duration=3)

    def enableAdvancedFeatures(self):
        self.iface.addPluginToWebMenu(self.menu, self._jumpForwardAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpBackwardAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpForwardShortAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpBackwardShortAction)

    def disableAdvancedFeatures(self):
        self.iface.removePluginWebMenu(self.menu, self._jumpForwardAction)
        self.iface.removePluginWebMenu(self.menu, self._jumpBackwardAction)
        self.iface.removePluginWebMenu(self.menu, self._jumpForwardShortAction)
        self.iface.removePluginWebMenu(self.menu, self._jumpBackwardShortAction
            )

    def jumpForward(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpForward()')

    def jumpBackward(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpBackwards()')
    <mask token>

    def jumpBackwardShort(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpBackwardsShort()')

<mask token>


class ImajnetPluginLayerType(QgsPluginLayerType):

    def __init__(self, iface, plugin):
        QgsPluginLayerType.__init__(self, ImajnetOpenlayersLayer.LAYER_TYPE)
        self.iface = iface
        self.plugin = plugin

    def createLayer(self):
        if not self.plugin.pluginIsActive:
            self.plugin.run()
        return ImajnetOpenlayersLayer(self.iface, PyImajnet.instance)

    def showLayerProperties(self, layer):
        return False


class QGisImajnetPlugin:
    """QGIS Plugin Implementation."""
    autoInitDebugWindow = False
    imajnetMapTool = None

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        ImajnetLog.init()
        self.iface = iface
        self.plugin_dir = os.path.dirname(__file__)
        self.locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
            'QGisImajnetPlugin_{}.qm'.format(self.locale))
        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)
        self.actions = []
        self.menu = self.tr(u'Imajnet')
        self.toolbar = self.iface.addToolBar(self.tr(u'Imajnet'))
        self.toolbar.setObjectName(self.tr(u'Imajnet'))
        self.pluginIsActive = False
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
        self.imajnetMapTool = None
        self.aboutDialog = None
        self.pluginLayerRegistry = QgsApplication.pluginLayerRegistry()
        res = self.pluginLayerRegistry.addPluginLayerType(
            ImajnetPluginLayerType(self.iface, self))
        self.manager = QgsNetworkAccessManager.instance()
        self.cookieJar = self.manager.cookieJar()
        if self.cookieJar is None:
            self.cookieJar = QNetworkCookieJar()
            self.manager.setCookieJar(self.cookieJar)

    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        return QCoreApplication.translate('@QGisImajnetPlugin', message)

    def add_action(self, icon_path, text, callback, checkable_flag=False,
        enabled_flag=True, add_to_menu=True, add_to_toolbar=True,
        status_tip=None, whats_this=None, parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool
        
        :param checkable_flag: A flag indicating if the action should be checkable. 
            Defaults to False.
        :type checkable_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """
        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        action.setCheckable(checkable_flag)
        if status_tip is not None:
            action.setStatusTip(status_tip)
        if whats_this is not None:
            action.setWhatsThis(whats_this)
        if add_to_toolbar:
            self.toolbar.addAction(action)
        if add_to_menu:
            self.iface.addPluginToWebMenu(self.menu, action)
        self.actions.append(action)
        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        icon_path = ':/plugins/imajnet-qgis-plugin/resources/img/icon.png'
        self.add_action(icon_path, text=self.tr(u'Imajnet plugin'),
            callback=self.run, parent=self.iface.mainWindow())
        self._closestImageAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/closestImageMode.png',
            text=self.tr(u'Closest image'), callback=self.
            on_closestImage_click, checkable_flag=True, enabled_flag=False,
            add_to_menu=False, add_to_toolbar=True, status_tip=self.tr(
            u'Click on the map and get the closest image'), whats_this=self
            .tr(u'Imajnet closest image tool'), parent=self.iface.mainWindow())
        self._clickModeAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/clickMode.png',
            text=self.tr(u'Click mode'), callback=self.on_clickMode_click,
            checkable_flag=True, enabled_flag=False, add_to_menu=False,
            add_to_toolbar=True, status_tip=self.tr(
            u'Click on an object and get an image oriented towards that object'
            ), whats_this=self.tr(u'Imajnet click mode tool'), parent=self.
            iface.mainWindow())
        self._aboutAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/about.png', text=
            self.tr(u'About'), callback=self.on_about_click, enabled_flag=
            True, add_to_menu=True, add_to_toolbar=False, parent=self.iface
            .mainWindow())
        self._helpAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/help.png', text=
            self.tr(u'Help'), callback=self.on_help_click, enabled_flag=
            True, add_to_menu=True, add_to_toolbar=True, parent=self.iface.
            mainWindow())
        self._disconnectAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/logout.png', text=
            self.tr(u'Disconnect'), callback=self.on_disconnect_click,
            enabled_flag=False, add_to_menu=True, add_to_toolbar=False,
            parent=self.iface.mainWindow())
        self._debugModeAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/debug.png', text=
            self.tr(u'Debug'), callback=self.on_debug_click, enabled_flag=
            False, add_to_menu=self.isDevMode(), add_to_toolbar=False,
            parent=self.iface.mainWindow())
        debugShortcutKeys = QKeySequence('Ctrl+I')
        self._debugModeAction.setShortcut(debugShortcutKeys)
        self._jumpForwardAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png', text=
            self.tr(u'jump forward'), callback=self.jumpForward,
            enabled_flag=True, add_to_menu=False, add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpForwardShortcutKeys = QKeySequence('PgUp')
        self._jumpForwardAction.setShortcut(jumpForwardShortcutKeys)
        self._jumpBackwardAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png', text=
            self.tr(u'jump backward'), callback=self.jumpBackward,
            enabled_flag=True, add_to_menu=False, add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpBackwardShortcutKeys = QKeySequence('PgDown')
        self._jumpBackwardAction.setShortcut(jumpBackwardShortcutKeys)
        self._jumpForwardShortAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png', text=
            self.tr(u'jump forward short'), callback=self.jumpForwardShort,
            enabled_flag=True, add_to_menu=False, add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpForwardShortShortcutKeys = QKeySequence('Shift+PgUp')
        self._jumpForwardShortAction.setShortcut(jumpForwardShortShortcutKeys)
        self._jumpBackwardShortAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png', text=
            self.tr(u'jump backward short'), callback=self.
            jumpBackwardShort, enabled_flag=True, add_to_menu=False,
            add_to_toolbar=False, parent=self.iface.mainWindow())
        jumpBackwardShortShortcutKeys = QKeySequence('Shift+PgDown')
        self._jumpBackwardShortAction.setShortcut(jumpBackwardShortShortcutKeys
            )

    def onClosePlugin(self, isUserAction=False):
        """Cleanup necessary items here when plugin dockwidget is closed"""
        ImajnetLog.info('** CLOSING QGisImajnetPlugin')
        if self.debugWidget != None:
            self.debugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.debugWidget.hide()
        if self.mapDebugWidget != None:
            self.mapDebugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.mapDebugWidget.hide()
        if self.dockwidget is not None:
            self.dockwidget.cleanup(isUserAction)
            self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
            self.dockwidget.hide()
            self.iface.removeDockWidget(self.dockwidget)
            self.dockwidget = None
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)
        self.imajnetMapTool = None
        self.pluginIsActive = False

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        ImajnetLog.info('** UNLOAD QGisImajnetPlugin')
        if self.pluginIsActive:
            self.onClosePlugin(False)
        for action in self.actions:
            self.iface.removePluginWebMenu(self.tr(u'&Imajnet'), action)
            self.iface.removeToolBarIcon(action)
        del self.toolbar
        if self.aboutDialog:
            self.aboutDialog = None
        self.pluginLayerRegistry.removePluginLayerType(ImajnetOpenlayersLayer
            .LAYER_TYPE)
        ImajnetLog.close()

    def run(self):
        """Run method that loads and starts the plugin"""
        if self.pluginIsActive:
            self.onClosePlugin(True)
        else:
            self.pluginIsActive = True
            ImajnetLog.info('** STARTING QGisImajnetPlugin')
            self.dockwidget = QGisImajnetPluginDockWidget(self.iface, self)
            self.imajnetMapTool = ImajnetMapTool(self)
            self.imajnetMapTool.setClickMode(False)
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)
            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget)
            self.dockwidget.show()
            self._debugModeAction.setEnabled(True)
            if QGisImajnetPlugin.autoInitDebugWindow == True:
                self.showOrHideDebugWindow()

    def showOrHideDebugWindow(self):
        """Shows the imajnet debug window"""
        firstLoad = False
        if self.debugWidget == None:
            self.debugWidget = QGisImajnetPluginDebugWindow(self.iface,
                self.dockwidget.m_view)
            self.debugWidget.closingPlugin.connect(self.onClosePlugin)
            self.iface.addDockWidget(Qt.NoDockWidgetArea, self.debugWidget)
            firstLoad = True
        if self.debugWidget.isVisible() and not firstLoad:
            self.debugWidget.hide()
        else:
            self.debugWidget.show()
        if self.mapDebugWidget == None:
            self.mapDebugWidget = QGisImajnetPluginDebugWindow(self.iface, None
                )
            self.mapDebugWidget.closingPlugin.connect(self.onClosePlugin)
            self.iface.addDockWidget(Qt.NoDockWidgetArea, self.mapDebugWidget)
            firstLoad = True
        if self.mapDebugWidget.isVisible() and not firstLoad:
            self.mapDebugWidget.hide()
        else:
            self.mapDebugWidget.show()

    def on_closestImage_click(self):
        self.enableImajnetMapTool(False)
        self._closestImageAction.setChecked(True)
        self._clickModeAction.setChecked(False)
        return True

    def on_clickMode_click(self):
        self.enableImajnetMapTool(True)
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(True)
        return False

    def enableImajnetMapTool(self, clickMode):
        ImajnetLog.info('enableImajnetMapTool')
        if self.imajnetMapTool is not None:
            self.imajnetMapTool.setClickMode(clickMode)
            self.iface.mapCanvas().setMapTool(self.imajnetMapTool)

    def on_debug_click(self):
        self.showOrHideDebugWindow()

    def on_disconnect_click(self):
        self.disableImajnetActions()
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'cleanupForLogout()')
        self.dockwidget.m_view.reload()

    def on_help_click(self):
        QDesktopServices.openUrl(QUrl(
            'https://imajnet.net/userguide/qgis/UG_IMAJNET_QGIS_{}.pdf'.
            format(self.locale.upper()), QUrl.TolerantMode))

    def on_about_click(self):
        if not self.aboutDialog:
            self.aboutDialog = QGisImajnetPluginAboutWindow(self)
        self._debugModeAction.setEnabled(True)
        self.aboutDialog.show()
        self.aboutDialog.activateWindow()

    def enableImajnetActions(self):
        self._closestImageAction.setEnabled(True)
        self._clickModeAction.setEnabled(True)
        self._debugModeAction.setEnabled(True)
        self._disconnectAction.setEnabled(True)
        self.on_closestImage_click()

    def disableImajnetActions(self):
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(False)
        self._closestImageAction.setEnabled(False)
        self._clickModeAction.setEnabled(False)
        self._debugModeAction.setEnabled(False)
        self._disconnectAction.setEnabled(False)

    def uncheckImajnetActions(self):
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(False)

    def isDevMode(self):
        s = QSettings()
        return s.value('imajnet/devMode', False)

    def toggleDevMode(self):
        s = QSettings()
        s.setValue('imajnet/devMode', not self.isDevMode())
        if self.isDevMode():
            self.iface.addPluginToWebMenu(self.menu, self._debugModeAction)
        else:
            self.iface.removePluginWebMenu(self.menu, self._debugModeAction)
        self.iface.messageBar().pushMessage('Imajnet', 'Dev mode toggled',
            level=Qgis.Info, duration=3)

    def enableAdvancedFeatures(self):
        self.iface.addPluginToWebMenu(self.menu, self._jumpForwardAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpBackwardAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpForwardShortAction)
        self.iface.addPluginToWebMenu(self.menu, self._jumpBackwardShortAction)

    def disableAdvancedFeatures(self):
        self.iface.removePluginWebMenu(self.menu, self._jumpForwardAction)
        self.iface.removePluginWebMenu(self.menu, self._jumpBackwardAction)
        self.iface.removePluginWebMenu(self.menu, self._jumpForwardShortAction)
        self.iface.removePluginWebMenu(self.menu, self._jumpBackwardShortAction
            )

    def jumpForward(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpForward()')

    def jumpBackward(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpBackwards()')

    def jumpForwardShort(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpForwardShort()')

    def jumpBackwardShort(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript(
            'ImajnetAPI.jumpBackwardsShort()')

# -*- coding: utf-8 -*-
"""
/***************************************************************************
 QGisImajnetPlugin
                                 Imajnet QGIS plugin
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2018-06-20
        git sha              : $Format:%H$
        copyright            : (C) 2018 by JC
        email                : jchesnel@imajing.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

# Uncomment to test if QtWebEngine is usable
# from PyQt5 import QtWebEngine, QtWebEngineWidgets
# from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage


from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QUrl,QObject
from PyQt5.QtGui import QIcon, QKeySequence,QDesktopServices
from PyQt5.QtWidgets import QAction
# Initialize Qt resources from file resources.py
from .resources import *

# Import the code for the DockWidget
from .QGisImajnetPlugin_dockwidget import QGisImajnetPluginDockWidget
from .QGisImajnetPlugin_debugwindow import QGisImajnetPluginDebugWindow
import os.path

from qgis import *
from qgis.core import *

from .ImajnetMapTool import  ImajnetMapTool
from .ImajnetLog import ImajnetLog
from .QGisImajnetPluginAboutWindow import QGisImajnetPluginAboutWindow
from .PyImajnet import PyImajnet
from .openlayers.openlayers_layer import ImajnetOpenlayersLayer


class ImajnetPluginLayerType(QgsPluginLayerType):

  def __init__(self, iface, plugin):
    QgsPluginLayerType.__init__(self, ImajnetOpenlayersLayer.LAYER_TYPE)
    self.iface = iface
    self.plugin = plugin

  def createLayer(self):
    #ImajnetLog.error("ImajnetPluginLayerType createLayer called")
    if not self.plugin.pluginIsActive:
        self.plugin.run()
    return ImajnetOpenlayersLayer(self.iface,PyImajnet.instance)

  def showLayerProperties(self, layer):
     return False
 
class QGisImajnetPlugin:
    """QGIS Plugin Implementation."""
    autoInitDebugWindow = False
    imajnetMapTool = None
    
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        ImajnetLog.init()
        # Save reference to the QGIS interface
        self.iface = iface
        
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        self.locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'QGisImajnetPlugin_{}.qm'.format(self.locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'Imajnet')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(self.tr(u'Imajnet'))
        self.toolbar.setObjectName(self.tr(u'Imajnet'))

        #print "** INITIALIZING QGisImajnetPlugin"

        self.pluginIsActive = False
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
        self.imajnetMapTool = None
        self.aboutDialog = None
        self.pluginLayerRegistry = QgsApplication.pluginLayerRegistry()
        
        # Register plugin layer type
        res = self.pluginLayerRegistry.addPluginLayerType(ImajnetPluginLayerType(self.iface,self))
        #ImajnetLog.error("ImajnetPluginLayerType: {}".format(res))
        
        self.manager = QgsNetworkAccessManager.instance() #QNetworkAccessManager()
        self.cookieJar = self.manager.cookieJar()
        if self.cookieJar is None:
            self.cookieJar = QNetworkCookieJar()
            #QgsNetworkAccessManager.instance().setCookieJar(self.cookieJar)
            self.manager.setCookieJar(self.cookieJar)
        
         
    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('@QGisImajnetPlugin', message)


    def add_action(
        self,
        icon_path,
        text,
        callback,
        checkable_flag=False,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool
        
        :param checkable_flag: A flag indicating if the action should be checkable. 
            Defaults to False.
        :type checkable_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        action.setCheckable(checkable_flag)
        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToWebMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action


    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        #icon_path = ':/plugins/QGisImajnetPlugin/icon.png'
        icon_path = ':/plugins/imajnet-qgis-plugin/resources/img/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Imajnet plugin'),
            callback=self.run,
            parent=self.iface.mainWindow())
            
        self._closestImageAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/closestImageMode.png',
            text=self.tr(u'Closest image'),
            callback=self.on_closestImage_click,
            checkable_flag=True,
            enabled_flag=False,
            add_to_menu=False,
            add_to_toolbar=True,
            status_tip=self.tr(u'Click on the map and get the closest image'),
            whats_this=self.tr(u'Imajnet closest image tool'),
            parent=self.iface.mainWindow())
        
        self._clickModeAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/clickMode.png',
            text=self.tr(u'Click mode'),
            callback=self.on_clickMode_click,
            checkable_flag=True,
            enabled_flag=False,
            add_to_menu=False,
            add_to_toolbar=True,
            status_tip=self.tr(u'Click on an object and get an image oriented towards that object'),
            whats_this=self.tr(u'Imajnet click mode tool'),
            parent=self.iface.mainWindow())
        
        
        self._aboutAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/about.png',
            text=self.tr(u'About'),
            callback=self.on_about_click,
            enabled_flag=True,
            add_to_menu=True,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        
        self._helpAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/help.png',
            text=self.tr(u'Help'),
            callback=self.on_help_click,
            enabled_flag=True,
            add_to_menu=True,
            add_to_toolbar=True,
            parent=self.iface.mainWindow())
        
        self._disconnectAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/logout.png',
            text=self.tr(u'Disconnect'),
            callback=self.on_disconnect_click,
            enabled_flag=False,
            add_to_menu=True,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        
        self._debugModeAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/debug.png',
            text=self.tr(u'Debug'),
            callback=self.on_debug_click,
            enabled_flag=False,
            add_to_menu=self.isDevMode(),
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        debugShortcutKeys = QKeySequence("Ctrl+I")
        self._debugModeAction.setShortcut(debugShortcutKeys)
        #self._debugModeAction.setVisible(False)
        
                
        self._jumpForwardAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png',
            text=self.tr(u'jump forward'),
            callback=self.jumpForward,
            enabled_flag=True,
            add_to_menu=False,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpForwardShortcutKeys = QKeySequence("PgUp")
        self._jumpForwardAction.setShortcut(jumpForwardShortcutKeys)
        
        self._jumpBackwardAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png',
            text=self.tr(u'jump backward'),
            callback=self.jumpBackward,
            enabled_flag=True,
            add_to_menu=False,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())                
        jumpBackwardShortcutKeys = QKeySequence("PgDown")
        self._jumpBackwardAction.setShortcut(jumpBackwardShortcutKeys)
        
        
        self._jumpForwardShortAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png',
            text=self.tr(u'jump forward short'),
            callback=self.jumpForwardShort,
            enabled_flag=True,
            add_to_menu=False,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())
        jumpForwardShortShortcutKeys = QKeySequence("Shift+PgUp")
        self._jumpForwardShortAction.setShortcut(jumpForwardShortShortcutKeys)
        
        self._jumpBackwardShortAction = self.add_action(
            ':/plugins/imajnet-qgis-plugin/resources/img/icon.png',
            text=self.tr(u'jump backward short'),
            callback=self.jumpBackwardShort,
            enabled_flag=True,
            add_to_menu=False,
            add_to_toolbar=False,
            parent=self.iface.mainWindow())                
        jumpBackwardShortShortcutKeys = QKeySequence("Shift+PgDown")
        self._jumpBackwardShortAction.setShortcut(jumpBackwardShortShortcutKeys)
        
    #--------------------------------------------------------------------------
        
    def onClosePlugin(self, isUserAction = False):
        """Cleanup necessary items here when plugin dockwidget is closed"""
        ImajnetLog.info("** CLOSING QGisImajnetPlugin")
        
        if self.debugWidget != None:
            self.debugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.debugWidget.hide()
        if self.mapDebugWidget != None:
            self.mapDebugWidget.closingPlugin.disconnect(self.onClosePlugin)
            self.mapDebugWidget.hide()
            
        if (self.dockwidget is not None):
            self.dockwidget.cleanup(isUserAction)
            #disconnects
            self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
            self.dockwidget.hide()
            self.iface.removeDockWidget(self.dockwidget)
            self.dockwidget = None
            
            
        # remove this statement if dockwidget is to remain
        # for reuse if plugin is reopened
        # Commented next statement since it causes QGIS crashe
        # when closing the docked window:
        self.dockwidget = None
        self.debugWidget = None
        self.mapDebugWidget = None
                
        
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)
        self.imajnetMapTool = None

        self.pluginIsActive = False

        #self.iface.unregisterMainWindowAction(self._jumpForwardAction)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        
        ImajnetLog.info("** UNLOAD QGisImajnetPlugin")

        if self.pluginIsActive:
            self.onClosePlugin(False)
            
        for action in self.actions:
            self.iface.removePluginWebMenu(
                self.tr(u'&Imajnet'),
                action)
            self.iface.removeToolBarIcon(action)
            
        
        # remove the toolbar
        del self.toolbar
        
        if self.aboutDialog :
            self.aboutDialog = None
            #del self.aboutDialog
        
        self.pluginLayerRegistry.removePluginLayerType(ImajnetOpenlayersLayer.LAYER_TYPE)
        #ImajnetLog.error("** UNLOADED")
        ImajnetLog.close()
        

    #--------------------------------------------------------------------------

    def run(self):
        """Run method that loads and starts the plugin"""
        
        # IF SOMETHING SHALL BE MODIFIED BY USER THIS MUST BE HERE
        
        if self.pluginIsActive:
            self.onClosePlugin(True)
        else:
            self.pluginIsActive = True

            ImajnetLog.info("** STARTING QGisImajnetPlugin")


            # Create the dockwidget (after translation) and keep reference
            self.dockwidget = QGisImajnetPluginDockWidget(self.iface, self)
            
            #enable the map tool
            self.imajnetMapTool = ImajnetMapTool(self)
            self.imajnetMapTool.setClickMode(False)
            
            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)

            # show the dockwidget
            # TODO: fix to allow choice of dock location
            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget)
            self.dockwidget.show()
            self._debugModeAction.setEnabled(True)
            
            if QGisImajnetPlugin.autoInitDebugWindow ==  True:
                self.showOrHideDebugWindow()
            
            
        
    #--------------------------------------------------------------------------
            
            
    def showOrHideDebugWindow(self):
        """Shows the imajnet debug window"""
        firstLoad = False
              
        if self.debugWidget == None:   
                self.debugWidget = QGisImajnetPluginDebugWindow(self.iface,self.dockwidget.m_view)
                self.debugWidget.closingPlugin.connect(self.onClosePlugin)
                self.iface.addDockWidget(Qt.NoDockWidgetArea, self.debugWidget)
                firstLoad=True
                
        if self.debugWidget.isVisible() and not(firstLoad):         
                self.debugWidget.hide()
        else:
                self.debugWidget.show()
                
        if self.mapDebugWidget == None:   
                self.mapDebugWidget = QGisImajnetPluginDebugWindow(self.iface,None)
                self.mapDebugWidget.closingPlugin.connect(self.onClosePlugin)
                self.iface.addDockWidget(Qt.NoDockWidgetArea, self.mapDebugWidget)
                firstLoad=True
        if self.mapDebugWidget.isVisible() and not(firstLoad):         
                self.mapDebugWidget.hide()
        else:
                self.mapDebugWidget.show()
    #-------------------------------------------------------------------------
    
    def on_closestImage_click(self):
        self.enableImajnetMapTool(False);
        self._closestImageAction.setChecked(True)
        self._clickModeAction.setChecked(False)
        return True
    
    def on_clickMode_click(self):
        self.enableImajnetMapTool(True);
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(True)
        return False
    
    def enableImajnetMapTool(self, clickMode):
        ImajnetLog.info('enableImajnetMapTool')
        if self.imajnetMapTool is not None:
             self.imajnetMapTool.setClickMode(clickMode)
             self.iface.mapCanvas().setMapTool(self.imajnetMapTool)
        
    def on_debug_click(self):
        self.showOrHideDebugWindow()
    
    def on_disconnect_click(self):
        self.disableImajnetActions()

        # due to issue #34, logout is not working properly as qgis gets stuck. We replace the call with the cleanup 
        # code + page reload which triggers the unload event that does the actual logout         
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("cleanupForLogout()")
        self.dockwidget.m_view.reload()
        #self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("doLogout()")
        
    def on_help_click(self):
        QDesktopServices.openUrl(QUrl("https://imajnet.net/userguide/qgis/UG_IMAJNET_QGIS_{}.pdf".format(self.locale.upper()), QUrl.TolerantMode));
        
    def on_about_click(self):
        if not self.aboutDialog :
            self.aboutDialog = QGisImajnetPluginAboutWindow(self)
        self._debugModeAction.setEnabled(True)
        
        # show the dialog
        self.aboutDialog.show()
        #self.aboutDialog.raise()
        self.aboutDialog.activateWindow()
            
        #    # Run the dialog event loop
        #result = self.aboutDialog.exec_()
        #self._debugModeAction.setEnabled(False)
        ## See if OK was pressed
        #if result:
        #    # Do something useful here - delete the line containing pass and
        #    # substitute with your code.
        #    pass
        
    def enableImajnetActions(self):
        self._closestImageAction.setEnabled(True)
        self._clickModeAction.setEnabled(True)
        self._debugModeAction.setEnabled(True)
        self._disconnectAction.setEnabled(True)
        self.on_closestImage_click()
        
    def disableImajnetActions(self):     
        self.iface.mapCanvas().unsetMapTool(self.imajnetMapTool)   
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(False)
        
        self._closestImageAction.setEnabled(False)
        self._clickModeAction.setEnabled(False)
        self._debugModeAction.setEnabled(False)
        self._disconnectAction.setEnabled(False)
        
    def uncheckImajnetActions(self):
        self._closestImageAction.setChecked(False)
        self._clickModeAction.setChecked(False) 
    
    def isDevMode(self):
        s = QSettings()
        return s.value("imajnet/devMode",False)
    
    def toggleDevMode(self):        
        s = QSettings()
        s.setValue("imajnet/devMode", not self.isDevMode())
        if self.isDevMode():            
            self.iface.addPluginToWebMenu(self.menu,self._debugModeAction)
        else:
            self.iface.removePluginWebMenu(self.menu,self._debugModeAction)
        self.iface.messageBar().pushMessage("Imajnet", "Dev mode toggled", level=Qgis.Info, duration=3)
    
    def enableAdvancedFeatures(self):
        self.iface.addPluginToWebMenu(self.menu,self._jumpForwardAction)
        self.iface.addPluginToWebMenu(self.menu,self._jumpBackwardAction)
        self.iface.addPluginToWebMenu(self.menu,self._jumpForwardShortAction)
        self.iface.addPluginToWebMenu(self.menu,self._jumpBackwardShortAction)
        
    def disableAdvancedFeatures(self):
        self.iface.removePluginWebMenu(self.menu,self._jumpForwardAction)
        self.iface.removePluginWebMenu(self.menu,self._jumpBackwardAction)
        self.iface.removePluginWebMenu(self.menu,self._jumpForwardShortAction)
        self.iface.removePluginWebMenu(self.menu,self._jumpBackwardShortAction)
        
    def jumpForward(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("ImajnetAPI.jumpForward()")
             
    def jumpBackward(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("ImajnetAPI.jumpBackwards()")    
    
    def jumpForwardShort(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("ImajnetAPI.jumpForwardShort()")
             
    def jumpBackwardShort(self):
        self.dockwidget.m_view.page().currentFrame().evaluateJavaScript("ImajnetAPI.jumpBackwardsShort()")
