Exemple #1
0
def add_widget_into_main(parent):
    """add a widget into the main window of LabGuiMain
    
    create a QDock widget and store a reference to the widget
    """
    


            
    

    mywidget = SimpleConnectWidget(parent = parent)
    
    #create a QDockWidget
    simpleconnectDockWidget = QDockWidget("Simple instrument console",
                                                parent)
    simpleconnectDockWidget.setObjectName("simpleConnectWidgetDockWidget")
    simpleconnectDockWidget.setAllowedAreas(
            Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        
    #fill the dictionnary with the widgets added into LabGuiMain
    parent.widgets['ConnectTerminalWidget'] = mywidget
    
    simpleconnectDockWidget.setWidget(mywidget)
    parent.addDockWidget(Qt.RightDockWidgetArea, simpleconnectDockWidget)
    
    #Enable the toggle view action
    parent.windowMenu.addAction(simpleconnectDockWidget.toggleViewAction())
    simpleconnectDockWidget.hide()      
class SideBar(QToolBar):
    def __init__(self, parent):
        self.parent = parent
        QToolBar.__init__(self)
        self.setObjectName('sideBar')
        self.parent.addToolBar(Qt.LeftToolBarArea, self)

        self.setIconSize(
            QSize(48, 48))
        self.setMovable(False)

        self.dock = QDockWidget()
        self.dock.setObjectName('sideBarDock')
        self.dock.stack = QStackedWidget()
        self.stack = self.dock.stack
        self.dock.setWidget(self.stack)
        self.parent.addDockWidget(Qt.LeftDockWidgetArea, self.dock)

        self.dock.hide()
class MainWindow(KXmlGuiWindow):

    "Class which displays the main Danbooru Client window."

    def __init__(self, *args):

        "Initialize a new main window."

        super(MainWindow, self).__init__(*args)
        self.cache = KPixmapCache("danbooru")
        self.preferences = preferences.Preferences()
        self.api = None
        self.__ratings = None
        self.__step = 0

        self.url_list = self.preferences.boards_list
        self.max_retrieve = self.preferences.thumbnail_no

        self.statusbar = self.statusBar()
        self.progress = QProgressBar()
        self.thumbnailarea = None
        self.tag_dock = None
        self.pool_dock = None
        self.first_fetch_widget = None

        self.progress.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)

        # FIXME: Hackish, but how to make it small otherwise?
        self.progress.setMinimumSize(100, 1)
        self.statusbar.addPermanentWidget(self.progress)
        self.progress.hide()

        self.setup_welcome_widget()
        self.setup_actions()

    def reload_config(self):
        """Reload configuration after a change"""

        urls = self.preferences.boards_list

        if self.first_fetch_widget is not None:
            self.first_fetch_widget.setup_urls(urls)

        if self.thumbnailarea is not None:

            max_thumbnail = self.preferences.thumbnail_no
            max_rating = self.preferences.max_allowed_rating

            self.thumbnailarea.fetchwidget.limit = max_thumbnail
            self.thumbnailarea.fetchwidget.rating = max_rating
            self.thumbnailarea.fetchwidget.update_values()

            self.thumbnailarea.connectwidget.setup_urls(urls)

        self.url_list = self.preferences.boards_list
        self.max_retrieve = self.preferences.thumbnail_no

    def setup_welcome_widget(self):
        """Load the welcome widget at startup."""

        widget = QWidget()
        layout = QVBoxLayout()

        welcome = QLabel(parent=self)
        pix = QPixmap(KStandardDirs.locate("appdata", "logo.png"))

        welcome.setPixmap(pix)
        welcome.setAlignment(Qt.AlignCenter)

        self.first_fetch_widget = connectwidget.ConnectWidget(
            self.preferences.boards_list, self)

        self.statusbar.addPermanentWidget(self.first_fetch_widget, 300)

        self.first_fetch_widget.connectionEstablished.connect(
            self.handle_connection)
        self.first_fetch_widget.rejected.connect(self.first_fetch_widget.hide)

        self.first_fetch_widget.hide()

        self.first_fetch_widget.setSizePolicy(QSizePolicy.Preferred,
                                              QSizePolicy.Fixed)

        layout.addWidget(self.first_fetch_widget)
        layout.addWidget(welcome)
        widget.setLayout(layout)

        self.setCentralWidget(widget)

    def setup_tooltips(self):
        """Set tooltips for the actions."""

        self.connect_action.setToolTip(i18n("Connect to a Danbooru board"))
        self.fetch_action.setToolTip(
            i18n("Fetch thumbnails from a Danbooru board"))
        self.batch_download_action.setToolTip(i18n("Batch download images"))

    def create_actions(self):
        """Create actions for the main window."""

        self.connect_action = KAction(KIcon("document-open-remote"),
                                      i18n("Connect"), self)
        self.fetch_action = KAction(KIcon("download"), i18n("Download"), self)
        self.clean_action = KAction(KIcon("trash-empty"),
                                    i18n("Clear thumbnail cache"), self)
        self.batch_download_action = KAction(KIcon("download"),
                                             i18n("Batch download"), self)
        self.pool_toggle_action = KToggleAction(KIcon("image-x-generic"),
                                                i18n("Pools"), self)
        self.tag_display_action = KDualAction(i18n("Show tags"),
                                              i18n("Hide tags"), self)
        self.tag_display_action.setIconForStates(KIcon("image-x-generic"))
        self.tag_display_action.setEnabled(False)

        # Shortcuts
        connect_default = KAction.ShortcutTypes(KAction.DefaultShortcut)
        connect_active = KAction.ShortcutTypes(KAction.ActiveShortcut)

        self.connect_action.setShortcut(KStandardShortcut.open())
        self.fetch_action.setShortcut(KStandardShortcut.find())

        self.fetch_action.setEnabled(False)
        self.batch_download_action.setEnabled(False)
        self.pool_toggle_action.setEnabled(False)

    def setup_action_collection(self):
        """Set up the action collection by adding the actions."""

        action_collection = self.actionCollection()

        # Addition to the action collection
        action_collection.addAction("connect", self.connect_action)
        action_collection.addAction("fetch", self.fetch_action)
        action_collection.addAction("clean", self.clean_action)
        action_collection.addAction("batchDownload",
                                    self.batch_download_action)
        action_collection.addAction("poolDownload", self.pool_toggle_action)
        action_collection.addAction("tagDisplay", self.tag_display_action)

        KStandardAction.quit(self.close, action_collection)
        KStandardAction.preferences(self.show_preferences, action_collection)

        action_collection.removeAction(
            action_collection.action("help_contents"))
        action_collection.actionHovered.connect(self.setup_action_tooltip)

    def setup_actions(self):
        """Set up the relevant actions, tooltips, and load the RC file."""

        self.create_actions()
        self.setup_tooltips()
        self.setup_action_collection()

        # Connect signals
        self.connect_action.triggered.connect(self.connect)
        self.fetch_action.triggered.connect(self.get_posts)
        self.clean_action.triggered.connect(self.clean_cache)
        self.batch_download_action.triggered.connect(self.batch_download)
        self.pool_toggle_action.toggled.connect(self.pool_toggle)
        self.tag_display_action.activeChanged.connect(self.tag_display)

        window_options = self.StandardWindowOption(self.ToolBar | self.Keys
                                                   | self.Create | self.Save
                                                   | self.StatusBar)

        setupGUI_args = [
            QSize(500, 400),
            self.StandardWindowOption(window_options)
        ]

        #Check first in standard locations for danbooruui.rc

        rc_file = KStandardDirs.locate("appdata", "danbooruui.rc")

        if rc_file.isEmpty():
            setupGUI_args.append(os.path.join(sys.path[0], "danbooruui.rc"))
        else:
            setupGUI_args.append(rc_file)

        self.setupGUI(*setupGUI_args)

    def setup_action_tooltip(self, action):

        "Show statusbar help when actions are hovered."

        if action.isEnabled():
            self.statusBar().showMessage(action.toolTip(), 2000)

    def setup_connections(self):
        """Set up connections for post and tag retrieval."""

        if self.api is None:
            return

        self.api.postRetrieved.connect(self.update_progress)
        self.api.postDownloadFinished.connect(self.download_finished)
        self.api.tagRetrieved.connect(self.tag_dock.widget().add_tags)
        self.tag_dock.widget().itemDoubleClicked.connect(
            self.fetch_tagged_items)

    def show_preferences(self):

        "Show the preferences dialog."

        if KConfigDialog.showDialog("Preferences dialog"):
            return
        else:
            dialog = preferences.PreferencesDialog(self, "Preferences dialog",
                                                   self.preferences)
            dialog.show()
            dialog.settingsChanged.connect(self.reload_config)

    def connect(self, ok):

        "Connect to a Danbooru board."

        if self.thumbnailarea is None:
            self.first_fetch_widget.show()
        else:
            self.thumbnailarea.connectwidget.show()

    def restore(self):

        self.statusbar.removeWidget(self.connect_widget)

    def handle_connection(self, connection):

        self.api = None
        self.api = connection
        self.api.cache = self.cache

        if self.pool_dock is not None:
            self.pool_dock.hide()
            self.pool_dock.widget().clear()
            self.pool_toggle_action.setChecked(False)

        if self.thumbnailarea is not None:
            #TODO: Investigate usability
            self.clear(clear_pool=True)
            self.thumbnailarea.clear()
            self.thumbnailarea.api_data = self.api
            self.setup_connections()

        else:
            self.first_fetch_widget.connectionEstablished.disconnect()
            self.first_fetch_widget.rejected.disconnect()
            self.statusbar.removeWidget(self.first_fetch_widget)
            self.setup_area()

        self.api.cache = self.cache

        self.statusBar().showMessage(i18n("Connected to %s" % self.api.url),
                                     3000)
        self.fetch_action.setEnabled(True)

        # Set up pool widget

        pool_widget = poolwidget.DanbooruPoolWidget(self.api)
        self.pool_dock = QDockWidget("Pools", self)
        self.pool_dock.setObjectName("PoolDock")
        self.pool_dock.setAllowedAreas(Qt.BottomDockWidgetArea)
        self.pool_dock.setWidget(pool_widget)
        #self.pool_dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.pool_dock)
        self.pool_dock.widget().poolDownloadRequested.connect(
            self.pool_prepare)
        self.pool_dock.hide()

        self.pool_toggle_action.setEnabled(True)
        self.clear()  # Needed to show properly the stuff after connecting

        self.api.get_post_list(tags="",
                               limit=self.thumbnailarea.post_limit,
                               rating=self.preferences.max_allowed_rating,
                               blacklist=list(self.preferences.tag_blacklist))
        self.api.get_tag_list(name="",
                              blacklist=list(self.preferences.tag_blacklist),
                              limit=20)

    def get_posts(self, ok):

        "Get posts from the connected Danbooru board."

        if not self.api:
            return

        self.thumbnailarea.fetchwidget.show()

    def handle_fetching(self, tags, max_rating, limit):
        """Slot connected to the dataSent signal of the fetch widget.

        The widgets are set up if they don't exist, and the API is queried
        to do the actual downloading of tags and

        """

        self.clear()

        self.thumbnailarea.fetchwidget.hide()

        if self.tag_dock is not None:
            self.tag_dock.widget().clear()

        self.thumbnailarea.post_limit = limit
        blacklist = list(self.preferences.tag_blacklist)
        self.api.get_post_list(tags=tags,
                               limit=limit,
                               rating=max_rating,
                               blacklist=blacklist)

        tags = [item for item in tags if item]

        if not tags:
            # No related tags, fetch the most recent 20
            tags = ""
            self.api.get_tag_list(name=tags, blacklist=blacklist, limit=20)
        else:
            self.api.get_related_tags(tags=tags, blacklist=blacklist)

    def fetch_tagged_items(self, item):
        """Fetch items found in the tag list widget."""

        tag_name = unicode(item.text())
        self.clear()

        blacklist = self.preferences.tag_blacklist
        limit = self.preferences.thumbnail_no
        rating = self.preferences.max_allowed_rating

        self.api.get_post_list(page=1,
                               tags=[tag_name],
                               blacklist=blacklist,
                               limit=limit,
                               rating=rating)
        self.api.get_related_tags(tags=[tag_name], blacklist=blacklist)

    def pool_toggle(self, checked):

        "Toggle the presence/absence of the pool dock."

        if not self.api:
            return

        if not checked:
            self.pool_dock.hide()
        else:
            self.pool_dock.show()

    def pool_prepare(self, pool_id):
        """Prepare the central area for pool image loading."""

        if self.thumbnailarea is None:
            self.setup_area()
        else:
            self.clear(clear_pool=False)

        self.api.get_pool(pool_id,
                          blacklist=self.preferences.tag_blacklist,
                          rating=self.preferences.max_allowed_rating)

    def batch_download(self, ok):

        "Download images in batch."

        selected_items = self.thumbnailarea.selected_images()

        if not selected_items:
            return

        start_url = KUrl("kfiledialog:///danbooru")
        caption = i18n("Select a directory to save the images to")
        directory = KFileDialog.getExistingDirectoryUrl(
            start_url, self, caption)

        if directory.isEmpty():
            return

        for item in selected_items:

            file_url = item.url_label.url()
            tags = item.data.tags

            # Make a local copy to append paths as addPath works in-place
            destination = KUrl(directory)

            file_name = KUrl(file_url).fileName()
            destination.addPath(file_name)

            job = KIO.file_copy(KUrl(file_url), destination, -1)
            job.setProperty("tags", QVariant(tags))
            job.result.connect(self.batch_download_slot)

    def setup_area(self):

        "Set up the central widget to display thumbnails."

        self.thumbnailarea = thumbnailarea.DanbooruTabWidget(
            self.api, self.preferences, self.preferences.thumbnail_no, self)

        self.setCentralWidget(self.thumbnailarea)

        self.thumbnailarea.connectwidget.connectionEstablished.connect(
            self.handle_connection, type=Qt.UniqueConnection)
        self.thumbnailarea.connectwidget.rejected.connect(
            self.thumbnailarea.connectwidget.hide, type=Qt.UniqueConnection)

        self.thumbnailarea.fetchwidget.dataSent.connect(
            self.handle_fetching, type=Qt.UniqueConnection)
        self.thumbnailarea.fetchwidget.rejected.connect(
            self.thumbnailarea.fetchwidget.hide, type=Qt.UniqueConnection)

        # Set up tag widget

        blacklist = self.preferences.tag_blacklist
        tag_widget = tagwidget.DanbooruTagWidget(blacklist, self)
        self.tag_display_action.setActive(True)
        self.tag_display_action.setEnabled(True)
        self.tag_dock = QDockWidget("Similar tags", self)
        self.tag_dock.setObjectName("TagDock")
        self.tag_dock.setAllowedAreas(Qt.RightDockWidgetArea)
        self.tag_dock.setWidget(tag_widget)
        #self.tag_dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.addDockWidget(Qt.RightDockWidgetArea, self.tag_dock)
        self.tag_dock.hide()

        # Container signal-slot connections

        self.setup_connections()

    def download_finished(self):
        """Slot called when all the data has been completed. Clears the progress
        bar and resets it to 0."""

        if not self.batch_download_action.isEnabled():
            self.batch_download_action.setEnabled(True)

        self.__step = 0
        self.progress.hide()

    def update_progress(self):

        "Update the progress bar."

        if not self.progress.isVisible():
            self.progress.show()

        self.__step += 1
        self.progress.setValue(self.__step)

    def clear(self, clear_pool=True):

        "Clear the central widget."

        if self.thumbnailarea is None:
            return

        self.thumbnailarea.clear()
        self.tag_dock.widget().clear()
        if clear_pool:
            self.pool_dock.widget().clear()
        self.batch_download_action.setEnabled(False)

    def clean_cache(self):

        "Purge the thumbnail cache."

        self.cache.discard()
        self.statusBar().showMessage(i18n("Thumbnail cache cleared."))

    def batch_download_slot(self, job):
        """Slot called when doing batch download, for each file retrieved.

        If Nepomuk tagging is enabled, each file is tagged using the item's
        respective tags.

        """

        if job.error():
            job.ui().showErrorMessage()
        else:
            if self.preferences.nepomuk_enabled:
                tags = job.property("tags").toPyObject()
                #danbooru2nepomuk.tag_danbooru_item(job.destUrl().path(),
                #                                   tags)

    def tag_display(self, state):
        """Display or hide the tag dock."""

        if self.tag_dock is None:
            self.tag_display_action.setActive(False)
            return

        if state:
            self.tag_dock.show()
        else:
            self.tag_dock.hide()
Exemple #4
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """The Main window of Luma.
    """

    logger = logging.getLogger(__name__)
    languages = {}
    translator = None
    languageHandler = None
    currentLanguage = ''

    def __init__(self, parent=None):
        """The constructor sets up the MainWindow widget, and connects
        all necessary signals and slots
        """
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        # We store the window size to make sure the previous window size
        # is restored when leaving fullscreen mode. This varible is used
        # in the toggleFullscreen slot.
        self.__tmpWinSize = self.size()
        self.eventFilter = LumaEventFilter(self)

        self.mainTabs.installEventFilter(self.eventFilter)

        self.translator = QTranslator()
        self.languageHandler = LanguageHandler()
        self.languages = self.languageHandler.availableLanguages

        #self.__createPluginToolBar()
        self.__createLoggerWidget()
        self.__loadSettings()
        self.__createLanguageOptions()

        self.setStatusBar(self.statusBar)

        self.mainTabs.setTabsClosable(True)
        self.mainTabs.setContextMenuPolicy(Qt.CustomContextMenu)
        self.mainTabs.customContextMenuRequested.connect(
            self.__mainTabsContextMenu)

        self.defaultTabStyle = ''
        self.lumaHeadStyle = 'background: url(:/icons/luma-gray);\n' + \
                     'background-position: bottom right;\n' + \
                     'background-attachment: fixed;\n' + \
                     'background-repeat:  no-repeat;'

        #Sets up pluginWidget
        #self in parameter is used to call pluginSelected here...
        self.pluginWidget = PluginListWidget(self)
        self.showPlugins()

        self.welcomeTab = WelcomeTab()
        self.welcomeTab.textBrowser.setStyleSheet(self.lumaHeadStyle)

        #This value comes from __loadSettings()
        #Its a checkbox set in WelcomeTab
        if self.showWelcomeSettings == 2:
            self.showWelcome()
        else:
            # Let's do some styling of the tab widget when no tabs are opened
            if self.mainTabs.currentIndex() == -1:
                self.__setTabWidgetStyle(self.lumaHeadStyle)

            self.actionShowWelcomeTab.setEnabled(True)

        self.serversChangedMessage = QErrorMessage(self)

    def __mainTabsContextMenu(self, pos):
        menu = QMenu()
        if self.mainTabs.count() > 0:
            return
            # The menu is displayed even when the rightclick is not
            # done over the actual tabs so to avoid confusion the
            # function is disabled entirey
            #menu.addAction(QApplication.translate(
            #    "MainWindow", "Close all plugin-tabs"), self.tabCloseAll)
        else:
            # If there's no tabs, offer to display the pluginlist
            menu.addAction(self.actionShowPluginList)
        menu.exec_(self.mainTabs.mapToGlobal(pos))

    def __createPluginToolBar(self):
        """Creates the pluign toolbar.
        """
        self.pluginToolBar = PluginToolBar(self)
        self.pluginToolBar.setWindowTitle(
            QApplication.translate('MainWindow', 'Plugintoolbar', None,
                                   QApplication.UnicodeUTF8))
        self.pluginToolBar.setObjectName('pluginToolBar')
        self.addToolBar(self.pluginToolBar)
        self.pluginToolBar.hide()

    def __createLoggerWidget(self):
        """Creates the logger widget.
        """
        self.loggerDockWindow = QDockWidget(self)
        self.loggerDockWindow.setObjectName('loggerDockWindow')
        self.loggerDockWindow.visibilityChanged[bool].connect(
            self.actionShowLogger.setChecked)
        self.loggerDockWindow.setWindowTitle(
            QApplication.translate('MainWindow', 'Logger', None,
                                   QApplication.UnicodeUTF8))
        self.loggerWidget = LoggerWidget(self.loggerDockWindow)
        self.loggerDockWindow.setWidget(self.loggerWidget)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.loggerDockWindow)
        self.loggerDockWindow.hide()

    def __createLanguageOptions(self):
        """Creates the language selection in the menubar.
        """
        self.langGroup = QActionGroup(self)
        self.langGroup.setExclusive(True)
        self.langGroup.triggered['QAction*'].connect(self.languageChanged)

        for key, name in self.languages.iteritems():
            action = QAction(self)
            action.setCheckable(True)
            action.setData(key)
            action.setText(name[0])
            action.setStatusTip(name[1])
            action.setActionGroup(self.langGroup)
            self.menuLanguage.addAction(action)
            if key == self.currentLanguage:
                action.setChecked(True)

    def __loadSettings(self, mainWin=True):
        """Loads settings from file.

        :param mainWin: If set to ``False``, neither the values for the
         window size or the window position will be loaded. This is
         i.e done when the settings dialog returns 1.
        :type mainWin: bool
        """
        settings = Settings()
        # We might want to use these methods to restore the
        # application state and geometry.
        if mainWin:
            self.restoreGeometry(settings.geometry)
        #self.restoreState(settings.state)

        # If the geometry saved inticates fullscreen mode,
        # we need to explicitly set the fullscreen menuaction checkbox
        if self.isFullScreen():
            self.actionFullscreen.setChecked(True)

        # Logger

        # Logger
        # The `allwaysShowLoggerOnStart` a precedence on the
        # `showLogger` value.
        if settings.showLoggerOnStart:
            self.actionShowLogger.setChecked(True)
        else:
            self.actionShowLogger.setChecked(settings.showLogger)

        self.loggerWidget.errorBox.setChecked(settings.showErrors)
        self.loggerWidget.debugBox.setChecked(settings.showDebug)
        self.loggerWidget.infoBox.setChecked(settings.showInfo)

        self.toggleLoggerWindow(self.actionShowLogger.isChecked())

        # Language
        self.loadLanguage(settings.language)

        #Tabs
        self.showWelcomeSettings = settings.value("showWelcome", 2).toInt()[0]

    def __writeSettings(self):
        """Save settings to file.
        """
        settings = Settings()
        # We might want to use these methods to restore the
        # application state and geometry.
        settings.geometry = self.saveGeometry()
        #settings.state = self.saveState()

        # Mainwin
        #max = self.isMaximized()
        #settings.maximize = max
        #if not max:
        #    settings.size = self.size()
        #    settings.position = self.pos()

        # The global logger settings is managed from the settings dialog.
        # Logger
        settings.showLogger = self.actionShowLogger.isChecked()
        settings.showErrors = self.loggerWidget.errorBox.isChecked()
        settings.showDebug = self.loggerWidget.debugBox.isChecked()
        settings.showInfo = self.loggerWidget.infoBox.isChecked()

        # Language
        settings.language = self.currentLanguage

    def __switchTranslator(self, translator, qmFile):
        """Called when a new language is loaded.

        :param translator: The translator object to install.
        :type translator: QTranslator
        :qmFile: The translation file for the loaded language.
        :type qmFile: string
        """
        qApp.removeTranslator(translator)
        if translator.load(qmFile):
            qApp.installTranslator(translator)

    def __setTabWidgetStyle(self, stylesheet):
        self.mainTabs.setStyleSheet(stylesheet)

    @pyqtSlot('QAction*')
    @pyqtSlot(int)
    def languageChanged(self, value):
        """This slot is called by actions and signals related to
        application translations. The slot contains validation for
        those parameters defined by the pyqtSlot meta info in the
        method header.

        :param value: Can be either a ``QAction`` or an integer value.
         I.e. menu actions provide ``QActions`` but a ``QCombobox``
         might send it's index.
        :type value: QAction/int
        """
        locale = None
        if isinstance(value, int):
            locale = self.languageSelector.itemData(value).toString()
        elif isinstance(value, QAction):
            locale = value.data().toString()
        #else:
        #    locale = value
        if locale:
            self.loadLanguage(locale)

    def loadLanguage(self, locale):
        """Loads a language by the given language iso code.

        :param locale: A twoletter lowercase ISO 639 language code and
         possibly a twoletter uppercase ISO 3166 country code separeted
         by a underscore.
        :type locale: string
        """
        if self.currentLanguage != locale:
            self.currentLanguage = locale
            qmFile = self.languageHandler.getQmFile(locale)
            self.__switchTranslator(self.translator, qmFile)

    def changeEvent(self, event):
        """This event is called when a new translator is loaded or the
        system language (locale) is changed.

        :param event: The event that generated the `changeEvent`.
        :type event: QEvent
        """
        if None != event:
            type = event.type()
            if QEvent.LanguageChange == type or QEvent.LocaleChange == type:
                self.retranslateUi(self)
                self.loggerWidget.retranslateUi(self.loggerWidget)

    def showAboutLuma(self):
        """Slot for displaying the about dialog.
        """
        AboutDialog().exec_()

    @pyqtSlot(bool)
    def toggleLoggerWindow(self, show):
        """Slot for toggling the logger window.

        :param show: a boolean value indicating whether the logger window
         should be shown or not.
        :type show: bool
        """
        if show:
            self.loggerDockWindow.show()
        else:
            self.loggerDockWindow.hide()

    @pyqtSlot(bool)
    def toggleStatusbar(self, show):
        """Slot for toggling the logger window.

        :param show: a boolean value indicating whether the statusbar
         should be shown or not.
        :type show: bool
        """
        if show:
            self.statusBar.show()
        else:
            self.statusBar.hide()

    @pyqtSlot(bool)
    def toggleFullscreen(self, fullscreen):
        """Slot for toggling the logger window.

        :param fullscreen: a boolean value indicating whether to enter
         fullscreenmode or not.
        :type fullcreen: bool
        """
        if fullscreen:
            self.__tmpWinSize = self.size()
            self.showFullScreen()
        else:
            self.showNormal()
            self.resize(self.__tmpWinSize)

    def showServerEditor(self):
        """Slot to display the server editor dialog.
        """
        serverEditor = ServerDialog()
        r = serverEditor.exec_()
        if r:
            #TODO -- only display if plugins open:
            self.serversChangedMessage.showMessage(
                QApplication.translate(
                    "MainWindow",
                    "You may need to restart plugins for changes to take effect."
                ))

    def showTempPasswordDialog(self):
        """ Sets overridePassword for a server.
        Using this one doesn't actually have to enter the password
        in the ServerDialog (and by extension save to disk).
        """
        serverList = ServerList()

        # Create a stringlist to be used by the qinputdialog
        stringList = []
        for server in serverList.getTable():
            stringList.append(server.name)

        # Display list of servers
        (serverString, ok) = QInputDialog.getItem(
            self,
            QApplication.translate("MainWindow", "Select server"),
            QApplication.translate("MainWindow", "Server:"),
            stringList,
            editable=False)
        if ok:
            server = serverList.getServerObjectByName(serverString)
            if server != None:
                # Ask for password
                (value, ok) = QInputDialog.getText(
                    self,
                    QApplication.translate("MainWindow", "Temporary password"),
                    QApplication.translate("MainWindow", "Enter password:"******"""Slot to display the settings dialog. If the settings dialog
        returns 1, i.e. the user has clicked the ok button, the
        loadSettings method is called with mainWin=False, to load the
        (assumed) newly changed settings.

        :param tab: The index of the tab to display in the settings
         dialog.
        :type tab: int
        """
        #settingsDialog = SettingsDialog(self.currentLanguage, self.languages)
        settingsDialog = SettingsDialog()
        if tab < 0:
            tab = 0
        settingsDialog.tabWidget.setCurrentIndex(tab)
        if settingsDialog.exec_():
            self.reloadPlugins()


#            # We assume that some settings is changed
#            # if the user clicked the ok button, and
#            # reloads the application settings
#            self.__loadSettings(mainWin=False)
#            # A Hack but it'll do for now
#            for a in self.langGroup.actions():
#                if a.data().toString() == self.currentLanguage:
#                    a.setChecked(True)

    def configurePlugins(self):
        """Slot to display the plugins configuration. This currently
        calls `showSettingsDialog` with tab index set to 2.
        """
        self.showSettingsDialog(1)

    def reloadPlugins(self):
        """Slot to reload plugins.
        """
        self.pluginWidget.updatePlugins()

    def pluginSelected(self, item):
        """This method will be called from the `PluginListWidget`.
        """
        # Clear the stylesheet when a tab is opened
        self.__setTabWidgetStyle(self.defaultTabStyle)

        widget = item.plugin.getPluginWidget(None, self)

        if platform.system() == "Windows":
            scroll = QScrollArea()
            scroll.setWidget(widget)
            scroll.setWidgetResizable(True)
            index = self.mainTabs.addTab(scroll, item.icon(),
                                         item.plugin.pluginUserString)
        else:
            index = self.mainTabs.addTab(widget, item.icon(),
                                         item.plugin.pluginUserString)

        self.mainTabs.setCurrentIndex(index)

    def tabClose(self, index):
        """Slot for the signal `tabCloseRequest(int)` for the tabMains.
        """

        widget = self.mainTabs.widget(index)

        # If the tab closed is one of these, enable the toggle-action
        if widget == self.pluginWidget:
            self.actionShowPluginList.setEnabled(True)
        if widget == self.welcomeTab:
            self.actionShowWelcomeTab.setEnabled(True)

        self.mainTabs.removeTab(index)

        # Unparent the widget since it was reparented by the QTabWidget
        # so it's garbage collected
        widget.setParent(None)

        # In case the widget contained circular references
        # -- force GC to take care of the objects since there can be
        #    quite many if it was BrowserWidget that was closed.
        # Can't call it directly since that'll be too soon
        QTimer.singleShot(1000, self.gc)

        # Let's do some styling of the tab widget when no tabs are opened
        if self.mainTabs.currentIndex() == -1:
            self.__setTabWidgetStyle(self.lumaHeadStyle)

    def gc(self):
        """Runs Python's garbage-collection manually.
        Used to make sure circular references are taken care of *now*.
        """
        gc.collect()

    def showWelcome(self):
        """Shows the Welcome-tab
        """
        self.__setTabWidgetStyle(self.defaultTabStyle)
        index = self.mainTabs.addTab(
            self.welcomeTab, QApplication.translate("MainWindow", "Welcome"))

        self.mainTabs.setCurrentIndex(index)
        self.actionShowWelcomeTab.setEnabled(False)

    def showPlugins(self):
        """Will show the pluginlistwidget-tab
        """
        self.__setTabWidgetStyle(self.defaultTabStyle)
        if self.mainTabs.indexOf(self.pluginWidget) == -1:
            index = self.mainTabs.addTab(
                self.pluginWidget,
                QApplication.translate("MainWindow", "Plugins"))
            self.mainTabs.setCurrentIndex(index)
            self.actionShowPluginList.setEnabled(False)

    def closeEvent(self, e):
        """Overrides the ``QMainWindow.closeEvent`` slot to save
        settings before we tear down the application.
        """
        self.__writeSettings()
        QMainWindow.closeEvent(self, e)
Exemple #5
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """The Main window of Luma.
    """

    logger = logging.getLogger(__name__)
    languages = {}
    translator = None
    languageHandler = None
    currentLanguage = ''

    def __init__(self, parent=None):
        """The constructor sets up the MainWindow widget, and connects
        all necessary signals and slots
        """
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        # We store the window size to make sure the previous window size
        # is restored when leaving fullscreen mode. This varible is used
        # in the toggleFullscreen slot.
        self.__tmpWinSize = self.size()
        self.eventFilter = LumaEventFilter(self)

        self.mainTabs.installEventFilter(self.eventFilter)

        self.translator = QTranslator()
        self.languageHandler = LanguageHandler()
        self.languages = self.languageHandler.availableLanguages

        #self.__createPluginToolBar()
        self.__createLoggerWidget()
        self.__loadSettings()
        self.__createLanguageOptions()

        self.setStatusBar(self.statusBar)

        self.mainTabs.setTabsClosable(True)
        self.mainTabs.setContextMenuPolicy(Qt.CustomContextMenu)
        self.mainTabs.customContextMenuRequested.connect(
            self.__mainTabsContextMenu)

        self.defaultTabStyle = ''
        self.lumaHeadStyle = 'background: url(:/icons/luma-gray);\n' + \
                     'background-position: bottom right;\n' + \
                     'background-attachment: fixed;\n' + \
                     'background-repeat:  no-repeat;'

        #Sets up pluginWidget
        #self in parameter is used to call pluginSelected here...
        self.pluginWidget = PluginListWidget(self)
        self.showPlugins()

        self.welcomeTab = WelcomeTab()
        self.welcomeTab.textBrowser.setStyleSheet(self.lumaHeadStyle)

        #This value comes from __loadSettings()
        #Its a checkbox set in WelcomeTab
        if self.showWelcomeSettings == 2:
            self.showWelcome()
        else:
            # Let's do some styling of the tab widget when no tabs are opened
            if self.mainTabs.currentIndex() == -1:
                self.__setTabWidgetStyle(self.lumaHeadStyle)

            self.actionShowWelcomeTab.setEnabled(True)

        self.serversChangedMessage = QErrorMessage(self)

    def __mainTabsContextMenu(self, pos):
        menu = QMenu()
        if self.mainTabs.count() > 0:
            return
            # The menu is displayed even when the rightclick is not
            # done over the actual tabs so to avoid confusion the
            # function is disabled entirey
            #menu.addAction(QApplication.translate(
            #    "MainWindow", "Close all plugin-tabs"), self.tabCloseAll)
        else:
            # If there's no tabs, offer to display the pluginlist
            menu.addAction(self.actionShowPluginList)
        menu.exec_(self.mainTabs.mapToGlobal(pos))

    def __createPluginToolBar(self):
        """Creates the pluign toolbar.
        """
        self.pluginToolBar = PluginToolBar(self)
        self.pluginToolBar.setWindowTitle(QApplication.translate(
            'MainWindow', 'Plugintoolbar', None, QApplication.UnicodeUTF8))
        self.pluginToolBar.setObjectName('pluginToolBar')
        self.addToolBar(self.pluginToolBar)
        self.pluginToolBar.hide()

    def __createLoggerWidget(self):
        """Creates the logger widget.
        """
        self.loggerDockWindow = QDockWidget(self)
        self.loggerDockWindow.setObjectName('loggerDockWindow')
        self.loggerDockWindow.visibilityChanged[bool].connect(
            self.actionShowLogger.setChecked)
        self.loggerDockWindow.setWindowTitle(QApplication.translate(
            'MainWindow', 'Logger', None, QApplication.UnicodeUTF8))
        self.loggerWidget = LoggerWidget(self.loggerDockWindow)
        self.loggerDockWindow.setWidget(self.loggerWidget)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.loggerDockWindow)
        self.loggerDockWindow.hide()

    def __createLanguageOptions(self):
        """Creates the language selection in the menubar.
        """
        self.langGroup = QActionGroup(self)
        self.langGroup.setExclusive(True)
        self.langGroup.triggered['QAction*'].connect(self.languageChanged)

        for key, name in self.languages.iteritems():
            action = QAction(self)
            action.setCheckable(True)
            action.setData(key)
            action.setText(name[0])
            action.setStatusTip(name[1])
            action.setActionGroup(self.langGroup)
            self.menuLanguage.addAction(action)
            if key == self.currentLanguage:
                action.setChecked(True)

    def __loadSettings(self, mainWin=True):
        """Loads settings from file.

        :param mainWin: If set to ``False``, neither the values for the
         window size or the window position will be loaded. This is
         i.e done when the settings dialog returns 1.
        :type mainWin: bool
        """
        settings = Settings()
        # We might want to use these methods to restore the
        # application state and geometry.
        if mainWin:
            self.restoreGeometry(settings.geometry)
        #self.restoreState(settings.state)

        # If the geometry saved inticates fullscreen mode,
        # we need to explicitly set the fullscreen menuaction checkbox
        if self.isFullScreen():
            self.actionFullscreen.setChecked(True)

        # Logger

        # Logger
        # The `allwaysShowLoggerOnStart` a precedence on the
        # `showLogger` value.
        if settings.showLoggerOnStart:
            self.actionShowLogger.setChecked(True)
        else:
            self.actionShowLogger.setChecked(settings.showLogger)

        self.loggerWidget.errorBox.setChecked(settings.showErrors)
        self.loggerWidget.debugBox.setChecked(settings.showDebug)
        self.loggerWidget.infoBox.setChecked(settings.showInfo)

        self.toggleLoggerWindow(self.actionShowLogger.isChecked())

        # Language
        self.loadLanguage(settings.language)

        #Tabs
        self.showWelcomeSettings = settings.value("showWelcome", 2).toInt()[0]

    def __writeSettings(self):
        """Save settings to file.
        """
        settings = Settings()
        # We might want to use these methods to restore the
        # application state and geometry.
        settings.geometry = self.saveGeometry()
        #settings.state = self.saveState()

        # Mainwin
        #max = self.isMaximized()
        #settings.maximize = max
        #if not max:
        #    settings.size = self.size()
        #    settings.position = self.pos()

        # The global logger settings is managed from the settings dialog.
        # Logger
        settings.showLogger = self.actionShowLogger.isChecked()
        settings.showErrors = self.loggerWidget.errorBox.isChecked()
        settings.showDebug = self.loggerWidget.debugBox.isChecked()
        settings.showInfo = self.loggerWidget.infoBox.isChecked()

        # Language
        settings.language = self.currentLanguage

    def __switchTranslator(self, translator, qmFile):
        """Called when a new language is loaded.

        :param translator: The translator object to install.
        :type translator: QTranslator
        :qmFile: The translation file for the loaded language.
        :type qmFile: string
        """
        qApp.removeTranslator(translator)
        if translator.load(qmFile):
            qApp.installTranslator(translator)

    def __setTabWidgetStyle(self, stylesheet):
        self.mainTabs.setStyleSheet(stylesheet)

    @pyqtSlot('QAction*')
    @pyqtSlot(int)
    def languageChanged(self, value):
        """This slot is called by actions and signals related to
        application translations. The slot contains validation for
        those parameters defined by the pyqtSlot meta info in the
        method header.

        :param value: Can be either a ``QAction`` or an integer value.
         I.e. menu actions provide ``QActions`` but a ``QCombobox``
         might send it's index.
        :type value: QAction/int
        """
        locale = None
        if isinstance(value, int):
            locale = self.languageSelector.itemData(value).toString()
        elif isinstance(value, QAction):
            locale = value.data().toString()
        #else:
        #    locale = value
        if locale:
            self.loadLanguage(locale)

    def loadLanguage(self, locale):
        """Loads a language by the given language iso code.

        :param locale: A twoletter lowercase ISO 639 language code and
         possibly a twoletter uppercase ISO 3166 country code separeted
         by a underscore.
        :type locale: string
        """
        if self.currentLanguage != locale:
            self.currentLanguage = locale
            qmFile = self.languageHandler.getQmFile(locale)
            self.__switchTranslator(self.translator, qmFile)

    def changeEvent(self, event):
        """This event is called when a new translator is loaded or the
        system language (locale) is changed.

        :param event: The event that generated the `changeEvent`.
        :type event: QEvent
        """
        if None != event:
            type = event.type()
            if QEvent.LanguageChange == type or QEvent.LocaleChange == type:
                self.retranslateUi(self)
                self.loggerWidget.retranslateUi(self.loggerWidget)

    def showAboutLuma(self):
        """Slot for displaying the about dialog.
        """
        AboutDialog().exec_()

    @pyqtSlot(bool)
    def toggleLoggerWindow(self, show):
        """Slot for toggling the logger window.

        :param show: a boolean value indicating whether the logger window
         should be shown or not.
        :type show: bool
        """
        if show:
            self.loggerDockWindow.show()
        else:
            self.loggerDockWindow.hide()

    @pyqtSlot(bool)
    def toggleStatusbar(self, show):
        """Slot for toggling the logger window.

        :param show: a boolean value indicating whether the statusbar
         should be shown or not.
        :type show: bool
        """
        if show:
            self.statusBar.show()
        else:
            self.statusBar.hide()

    @pyqtSlot(bool)
    def toggleFullscreen(self, fullscreen):
        """Slot for toggling the logger window.

        :param fullscreen: a boolean value indicating whether to enter
         fullscreenmode or not.
        :type fullcreen: bool
        """
        if fullscreen:
            self.__tmpWinSize = self.size()
            self.showFullScreen()
        else:
            self.showNormal()
            self.resize(self.__tmpWinSize)

    def showServerEditor(self):
        """Slot to display the server editor dialog.
        """
        serverEditor = ServerDialog()
        r = serverEditor.exec_()
        if r:
            #TODO -- only display if plugins open:
            self.serversChangedMessage.showMessage(QApplication.translate(
                "MainWindow",
                "You may need to restart plugins for changes to take effect."))

    def showTempPasswordDialog(self):
        """ Sets overridePassword for a server.
        Using this one doesn't actually have to enter the password
        in the ServerDialog (and by extension save to disk).
        """
        serverList = ServerList()

        # Create a stringlist to be used by the qinputdialog
        stringList = []
        for server in serverList.getTable():
            stringList.append(server.name)

        # Display list of servers
        (serverString, ok) = QInputDialog.getItem(
            self,
            QApplication.translate("MainWindow", "Select server"),
            QApplication.translate("MainWindow", "Server:"),
            stringList,
            editable=False
        )
        if ok:
            server = serverList.getServerObjectByName(serverString)
            if server != None:
                # Ask for password
                (value, ok) = QInputDialog.getText(
                    self,
                    QApplication.translate("MainWindow", "Temporary password"),
                    QApplication.translate("MainWindow", "Enter password:"******"""Slot to display the settings dialog. If the settings dialog
        returns 1, i.e. the user has clicked the ok button, the
        loadSettings method is called with mainWin=False, to load the
        (assumed) newly changed settings.

        :param tab: The index of the tab to display in the settings
         dialog.
        :type tab: int
        """
        #settingsDialog = SettingsDialog(self.currentLanguage, self.languages)
        settingsDialog = SettingsDialog()
        if tab < 0:
            tab = 0
        settingsDialog.tabWidget.setCurrentIndex(tab)
        if settingsDialog.exec_():
            self.reloadPlugins()
#            # We assume that some settings is changed
#            # if the user clicked the ok button, and
#            # reloads the application settings
#            self.__loadSettings(mainWin=False)
#            # A Hack but it'll do for now
#            for a in self.langGroup.actions():
#                if a.data().toString() == self.currentLanguage:
#                    a.setChecked(True)

    def configurePlugins(self):
        """Slot to display the plugins configuration. This currently
        calls `showSettingsDialog` with tab index set to 2.
        """
        self.showSettingsDialog(1)

    def reloadPlugins(self):
        """Slot to reload plugins.
        """
        self.pluginWidget.updatePlugins()

    def pluginSelected(self, item):
        """This method will be called from the `PluginListWidget`.
        """
        # Clear the stylesheet when a tab is opened
        self.__setTabWidgetStyle(self.defaultTabStyle)

        widget = item.plugin.getPluginWidget(None, self)

        if platform.system() == "Windows":
            scroll = QScrollArea()
            scroll.setWidget(widget)
            scroll.setWidgetResizable(True)
            index = self.mainTabs.addTab(
                scroll, item.icon(), item.plugin.pluginUserString)
        else:
            index = self.mainTabs.addTab(
                widget, item.icon(), item.plugin.pluginUserString)

        self.mainTabs.setCurrentIndex(index)

    def tabClose(self, index):
        """Slot for the signal `tabCloseRequest(int)` for the tabMains.
        """

        widget = self.mainTabs.widget(index)

        # If the tab closed is one of these, enable the toggle-action
        if widget == self.pluginWidget:
            self.actionShowPluginList.setEnabled(True)
        if widget == self.welcomeTab:
            self.actionShowWelcomeTab.setEnabled(True)

        self.mainTabs.removeTab(index)

        # Unparent the widget since it was reparented by the QTabWidget
        # so it's garbage collected
        widget.setParent(None)

        # In case the widget contained circular references
        # -- force GC to take care of the objects since there can be
        #    quite many if it was BrowserWidget that was closed.
        # Can't call it directly since that'll be too soon
        QTimer.singleShot(1000, self.gc)

        # Let's do some styling of the tab widget when no tabs are opened
        if self.mainTabs.currentIndex() == -1:
            self.__setTabWidgetStyle(self.lumaHeadStyle)

    def gc(self):
        """Runs Python's garbage-collection manually.
        Used to make sure circular references are taken care of *now*.
        """
        gc.collect()

    def showWelcome(self):
        """Shows the Welcome-tab
        """
        self.__setTabWidgetStyle(self.defaultTabStyle)
        index = self.mainTabs.addTab(self.welcomeTab,
        QApplication.translate("MainWindow", "Welcome"))

        self.mainTabs.setCurrentIndex(index)
        self.actionShowWelcomeTab.setEnabled(False)

    def showPlugins(self):
        """Will show the pluginlistwidget-tab
        """
        self.__setTabWidgetStyle(self.defaultTabStyle)
        if self.mainTabs.indexOf(self.pluginWidget) == -1:
            index = self.mainTabs.addTab(
                self.pluginWidget, QApplication.translate(
                    "MainWindow", "Plugins"))
            self.mainTabs.setCurrentIndex(index)
            self.actionShowPluginList.setEnabled(False)

    def closeEvent(self, e):
        """Overrides the ``QMainWindow.closeEvent`` slot to save
        settings before we tear down the application.
        """
        self.__writeSettings()
        QMainWindow.closeEvent(self, e)
class MainWindow(KXmlGuiWindow):

    "Class which displays the main Danbooru Client window."

    def __init__(self,  *args):

        "Initialize a new main window."

        super(MainWindow,  self).__init__(*args)
        self.cache = KPixmapCache("danbooru")
        self.preferences = preferences.Preferences()
        self.api = None
        self.__ratings = None
        self.__step = 0

        self.url_list = self.preferences.boards_list
        self.max_retrieve = self.preferences.thumbnail_no

        self.statusbar = self.statusBar()
        self.progress = QProgressBar()
        self.thumbnailarea = None
        self.tag_dock = None
        self.pool_dock = None
        self.first_fetch_widget = None

        self.progress.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)

        # FIXME: Hackish, but how to make it small otherwise?
        self.progress.setMinimumSize(100, 1)
        self.statusbar.addPermanentWidget(self.progress)
        self.progress.hide()

        self.setup_welcome_widget()
        self.setup_actions()

    def reload_config(self):

        """Reload configuration after a change"""

        urls = self.preferences.boards_list

        if self.first_fetch_widget is not None:
            self.first_fetch_widget.setup_urls(urls)

        if self.thumbnailarea is not None:

            max_thumbnail = self.preferences.thumbnail_no
            max_rating = self.preferences.max_allowed_rating

            self.thumbnailarea.fetchwidget.limit = max_thumbnail
            self.thumbnailarea.fetchwidget.rating = max_rating
            self.thumbnailarea.fetchwidget.update_values()

            self.thumbnailarea.connectwidget.setup_urls(urls)

        self.url_list = self.preferences.boards_list
        self.max_retrieve = self.preferences.thumbnail_no




    def setup_welcome_widget(self):

        """Load the welcome widget at startup."""

        widget = QWidget()
        layout = QVBoxLayout()

        welcome = QLabel(parent=self)
        pix = QPixmap(KStandardDirs.locate("appdata","logo.png"))

        welcome.setPixmap(pix)
        welcome.setAlignment(Qt.AlignCenter)

        self.first_fetch_widget = connectwidget.ConnectWidget(
        self.preferences.boards_list, self)

        self.statusbar.addPermanentWidget(self.first_fetch_widget, 300)

        self.first_fetch_widget.connectionEstablished.connect(
            self.handle_connection)
        self.first_fetch_widget.rejected.connect(
            self.first_fetch_widget.hide)

        self.first_fetch_widget.hide()

        self.first_fetch_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)

        layout.addWidget(self.first_fetch_widget)
        layout.addWidget(welcome)
        widget.setLayout(layout)

        self.setCentralWidget(widget)

    def setup_tooltips(self):

        """Set tooltips for the actions."""

        self.connect_action.setToolTip(i18n("Connect to a Danbooru board"))
        self.fetch_action.setToolTip(
            i18n("Fetch thumbnails from a Danbooru board")
        )
        self.batch_download_action.setToolTip(i18n("Batch download images"))

    def create_actions(self):

        """Create actions for the main window."""

        self.connect_action = KAction(KIcon("document-open-remote"),
                                 i18n("Connect"), self)
        self.fetch_action = KAction(KIcon("download"), i18n("Download"),
                                    self)
        self.clean_action = KAction(KIcon("trash-empty"),
                               i18n("Clear thumbnail cache"),
                               self)
        self.batch_download_action = KAction(KIcon("download"),
                                             i18n("Batch download"), self)
        self.pool_toggle_action = KToggleAction(KIcon("image-x-generic"),
                                            i18n("Pools"), self)
        self.tag_display_action = KDualAction(i18n("Show tags"),
                                              i18n("Hide tags"),
                                              self)
        self.tag_display_action.setIconForStates(KIcon("image-x-generic"))
        self.tag_display_action.setEnabled(False)

        # Shortcuts
        connect_default = KAction.ShortcutTypes(KAction.DefaultShortcut)
        connect_active = KAction.ShortcutTypes(KAction.ActiveShortcut)

        self.connect_action.setShortcut(KStandardShortcut.open())
        self.fetch_action.setShortcut(KStandardShortcut.find())

        self.fetch_action.setEnabled(False)
        self.batch_download_action.setEnabled(False)
        self.pool_toggle_action.setEnabled(False)

    def setup_action_collection(self):

        """Set up the action collection by adding the actions."""

        action_collection = self.actionCollection()

        # Addition to the action collection
        action_collection.addAction("connect", self.connect_action)
        action_collection.addAction("fetch", self.fetch_action)
        action_collection.addAction("clean", self.clean_action)
        action_collection.addAction("batchDownload", self.batch_download_action)
        action_collection.addAction("poolDownload", self.pool_toggle_action)
        action_collection.addAction("tagDisplay", self.tag_display_action)

        KStandardAction.quit (self.close, action_collection)
        KStandardAction.preferences(self.show_preferences,
                                    action_collection)

        action_collection.removeAction(
            action_collection.action("help_contents"))
        action_collection.actionHovered.connect(self.setup_action_tooltip)

    def setup_actions(self):

        """Set up the relevant actions, tooltips, and load the RC file."""

        self.create_actions()
        self.setup_tooltips()
        self.setup_action_collection()

        # Connect signals
        self.connect_action.triggered.connect(self.connect)
        self.fetch_action.triggered.connect(self.get_posts)
        self.clean_action.triggered.connect(self.clean_cache)
        self.batch_download_action.triggered.connect(self.batch_download)
        self.pool_toggle_action.toggled.connect(self.pool_toggle)
        self.tag_display_action.activeChanged.connect(self.tag_display)

        window_options = self.StandardWindowOption(self.ToolBar| self.Keys |
                                                   self.Create | self.Save |
                                                   self.StatusBar)

        setupGUI_args = [
            QSize(500, 400), self.StandardWindowOption(window_options)
        ]

        #Check first in standard locations for danbooruui.rc

        rc_file = KStandardDirs.locate("appdata", "danbooruui.rc")

        if rc_file.isEmpty():
            setupGUI_args.append(os.path.join(sys.path [0],
                                              "danbooruui.rc"))
        else:
            setupGUI_args.append(rc_file)

        self.setupGUI(*setupGUI_args)

    def setup_action_tooltip(self, action):

        "Show statusbar help when actions are hovered."

        if action.isEnabled():
            self.statusBar().showMessage(action.toolTip(), 2000)

    def setup_connections(self):

        """Set up connections for post and tag retrieval."""

        if self.api is None:
            return

        self.api.postRetrieved.connect(self.update_progress)
        self.api.postDownloadFinished.connect(self.download_finished)
        self.api.tagRetrieved.connect(self.tag_dock.widget().add_tags)
        self.tag_dock.widget().itemDoubleClicked.connect(
            self.fetch_tagged_items)

    def show_preferences(self):

        "Show the preferences dialog."

        if KConfigDialog.showDialog("Preferences dialog"):
            return
        else:
            dialog = preferences.PreferencesDialog(self, "Preferences dialog",
                                                   self.preferences)
            dialog.show()
            dialog.settingsChanged.connect(self.reload_config)

    def connect(self, ok):

        "Connect to a Danbooru board."

        if self.thumbnailarea is None:
            self.first_fetch_widget.show()
        else:
            self.thumbnailarea.connectwidget.show()


    def restore(self):

        self.statusbar.removeWidget(self.connect_widget)

    def handle_connection(self, connection):

        self.api = None
        self.api = connection
        self.api.cache = self.cache

        if self.pool_dock is not None:
            self.pool_dock.hide()
            self.pool_dock.widget().clear()
            self.pool_toggle_action.setChecked(False)

        if self.thumbnailarea is not None:
            #TODO: Investigate usability
            self.clear(clear_pool=True)
            self.thumbnailarea.clear()
            self.thumbnailarea.api_data = self.api
            self.setup_connections()

        else:
            self.first_fetch_widget.connectionEstablished.disconnect()
            self.first_fetch_widget.rejected.disconnect()
            self.statusbar.removeWidget(self.first_fetch_widget)
            self.setup_area()

        self.api.cache = self.cache

        self.statusBar().showMessage(i18n("Connected to %s" % self.api.url),
                                     3000)
        self.fetch_action.setEnabled(True)

        # Set up pool widget

        pool_widget = poolwidget.DanbooruPoolWidget(self.api)
        self.pool_dock = QDockWidget("Pools", self)
        self.pool_dock.setObjectName("PoolDock")
        self.pool_dock.setAllowedAreas(Qt.BottomDockWidgetArea)
        self.pool_dock.setWidget(pool_widget)
        #self.pool_dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.pool_dock)
        self.pool_dock.widget().poolDownloadRequested.connect(
            self.pool_prepare)
        self.pool_dock.hide()

        self.pool_toggle_action.setEnabled(True)
        self.clear() # Needed to show properly the stuff after connecting

        self.api.get_post_list(tags="", limit=self.thumbnailarea.post_limit,
                               rating=self.preferences.max_allowed_rating,
                               blacklist=list(self.preferences.tag_blacklist))
        self.api.get_tag_list(name="",blacklist=list(self.preferences.tag_blacklist),
                              limit=20)

    def get_posts(self, ok):

        "Get posts from the connected Danbooru board."

        if not self.api:
            return

        self.thumbnailarea.fetchwidget.show()



    def handle_fetching(self, tags, max_rating, limit):

        """Slot connected to the dataSent signal of the fetch widget.

        The widgets are set up if they don't exist, and the API is queried
        to do the actual downloading of tags and

        """

        self.clear()

        self.thumbnailarea.fetchwidget.hide()

        if self.tag_dock is not None:
            self.tag_dock.widget().clear()

        self.thumbnailarea.post_limit = limit
        blacklist= list(self.preferences.tag_blacklist)
        self.api.get_post_list(tags=tags, limit=limit,
                               rating=max_rating,
                               blacklist=blacklist)

        tags = [item for item in tags if item]

        if not tags:
            # No related tags, fetch the most recent 20
            tags = ""
            self.api.get_tag_list(name=tags,blacklist=blacklist,
                                  limit=20)
        else:
            self.api.get_related_tags(tags=tags, blacklist=blacklist)

    def fetch_tagged_items(self, item):

        """Fetch items found in the tag list widget."""

        tag_name = unicode(item.text())
        self.clear()

        blacklist = self.preferences.tag_blacklist
        limit = self.preferences.thumbnail_no
        rating = self.preferences.max_allowed_rating

        self.api.get_post_list(page=1, tags=[tag_name],
                                blacklist=blacklist,
                                limit=limit,
                                rating=rating)
        self.api.get_related_tags(tags=[tag_name], blacklist=blacklist)

    def pool_toggle(self, checked):

        "Toggle the presence/absence of the pool dock."

        if not self.api:
            return

        if not checked:
            self.pool_dock.hide()
        else:
            self.pool_dock.show()

    def pool_prepare(self, pool_id):

        """Prepare the central area for pool image loading."""

        if self.thumbnailarea is None:
            self.setup_area()
        else:
            self.clear(clear_pool=False)

        self.api.get_pool(pool_id, blacklist=self.preferences.tag_blacklist,
                          rating=self.preferences.max_allowed_rating)

    def batch_download(self, ok):

        "Download images in batch."

        selected_items = self.thumbnailarea.selected_images()

        if not selected_items:
            return

        start_url = KUrl("kfiledialog:///danbooru")
        caption = i18n("Select a directory to save the images to")
        directory = KFileDialog.getExistingDirectoryUrl(start_url, self,
                                                        caption)

        if directory.isEmpty():
            return

        for item in selected_items:

            file_url = item.url_label.url()
            tags = item.data.tags

            # Make a local copy to append paths as addPath works in-place
            destination = KUrl(directory)

            file_name = KUrl(file_url).fileName()
            destination.addPath(file_name)

            job = KIO.file_copy(KUrl(file_url), destination, -1)
            job.setProperty("tags", QVariant(tags))
            job.result.connect(self.batch_download_slot)

    def setup_area(self):

        "Set up the central widget to display thumbnails."

        self.thumbnailarea = thumbnailarea.DanbooruTabWidget(self.api,
            self.preferences, self.preferences.thumbnail_no, self)

        self.setCentralWidget(self.thumbnailarea)

        self.thumbnailarea.connectwidget.connectionEstablished.connect(
                    self.handle_connection, type=Qt.UniqueConnection)
        self.thumbnailarea.connectwidget.rejected.connect(
            self.thumbnailarea.connectwidget.hide, type=Qt.UniqueConnection)

        self.thumbnailarea.fetchwidget.dataSent.connect(
            self.handle_fetching, type=Qt.UniqueConnection)
        self.thumbnailarea.fetchwidget.rejected.connect(
            self.thumbnailarea.fetchwidget.hide, type=Qt.UniqueConnection)

        # Set up tag widget

        blacklist = self.preferences.tag_blacklist
        tag_widget = tagwidget.DanbooruTagWidget(blacklist, self)
        self.tag_display_action.setActive(True)
        self.tag_display_action.setEnabled(True)
        self.tag_dock = QDockWidget("Similar tags", self)
        self.tag_dock.setObjectName("TagDock")
        self.tag_dock.setAllowedAreas(Qt.RightDockWidgetArea)
        self.tag_dock.setWidget(tag_widget)
        #self.tag_dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.addDockWidget(Qt.RightDockWidgetArea, self.tag_dock)
        self.tag_dock.hide()

        # Container signal-slot connections

        self.setup_connections()

    def download_finished(self):

        """Slot called when all the data has been completed. Clears the progress
        bar and resets it to 0."""

        if not self.batch_download_action.isEnabled():
            self.batch_download_action.setEnabled(True)

        self.__step = 0
        self.progress.hide()

    def update_progress(self):

        "Update the progress bar."

        if not self.progress.isVisible():
            self.progress.show()

        self.__step += 1
        self.progress.setValue(self.__step)

    def clear(self, clear_pool=True):

        "Clear the central widget."

        if self.thumbnailarea is None:
            return

        self.thumbnailarea.clear()
        self.tag_dock.widget().clear()
        if clear_pool:
            self.pool_dock.widget().clear()
        self.batch_download_action.setEnabled(False)

    def clean_cache(self):

        "Purge the thumbnail cache."

        self.cache.discard()
        self.statusBar().showMessage(i18n("Thumbnail cache cleared."))

    def batch_download_slot(self, job):

        """Slot called when doing batch download, for each file retrieved.

        If Nepomuk tagging is enabled, each file is tagged using the item's
        respective tags.

        """

        if job.error():
            job.ui().showErrorMessage()
        else:
            if self.preferences.nepomuk_enabled:
                tags = job.property("tags").toPyObject()
                #danbooru2nepomuk.tag_danbooru_item(job.destUrl().path(),
                #                                   tags)

    def tag_display(self, state):

        """Display or hide the tag dock."""

        if self.tag_dock is None:
            self.tag_display_action.setActive(False)
            return

        if state:
            self.tag_dock.show()
        else:
            self.tag_dock.hide()
Exemple #7
0
class fdtm:
    """QGIS Plugin Implementation."""
    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
        """
        # Save reference to the QGIS interface
        self.iface = iface

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'fdtm_{}.qm'.format(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'&fdtm')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'fdtm')
        self.toolbar.setObjectName(u'fdtm')

        self.pluginIsActive = False

    # 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('fdtm', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu='toolbar',
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   isMenu=None,
                   checkable=None,
                   checked=None,
                   parent=None):

        if not parent:
            parent = self.iface.mainWindow()

        icon = QIcon(icon_path)
        if add_to_menu == 'toolbar':
            action = QAction(icon, text, parent)
        else:
            action = self.tools[add_to_menu].menu().addAction(text)
            action.setActionGroup(self.tools[add_to_menu].actionGroup)
            add_to_toolbar = False

        if checkable:
            action.setCheckable(True)
            if checked:
                action.setChecked(True)
            if callback:
                action.toggled.connect(callback)
        else:
            if callback:
                action.triggered.connect(callback)
        action.setEnabled(enabled_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 isMenu:
            newMenu = QMenu()
            action.setMenu(newMenu)
            newActionGroup = QActionGroup(newMenu)
            action.actionGroup = newActionGroup

        if add_to_menu == 'toolbar':
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        self.tools = {
            'about':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_00_about.png'),
                text=self.tr(u'about FDTM plugin'),
                callback=self.run_about,
            ),
            'settings':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_01_settings.png'),
                text=self.tr(u'settings'),
                callback=self.run_settings,
            ),
            'print':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_07_print.png'),
                text=self.tr(u'print'),
                callback=self.run_print,
                enabled_flag=False,
                isMenu=True,
            ),
            'summary':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_08_summary.png'),
                text=self.tr(u'summary'),
                callback=self.toggle_summary,
                enabled_flag=False,
            ),
            'info':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_06_info.png'),
                text=self.tr(u'info summary'),
                callback=self.run_info,
                enabled_flag=False,
                checkable=True,
            ),
            'EP':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_02_EP.png'),
                text=self.tr(u'input/edit strategies'),
                callback=self.run_EP,
                enabled_flag=False,
                checkable=True,
            ),
            'EA':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_03_EA.png'),
                text=self.tr(u'input/edit strategies'),
                callback=self.run_EA,
                enabled_flag=False,
                checkable=True,
            ),
            'WR':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_04_WR.png'),
                text=self.tr(u'input/edit water_rec'),
                callback=self.run_WR,
                enabled_flag=False,
                checkable=True,
                isMenu=True,
            ),
            'WDS':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_05_WDS.png'),
                text=self.tr(u'input/edit water_ds'),
                callback=self.run_WDS,
                enabled_flag=False,
                checkable=True,
            ),
            'DSV':
            self.add_action(
                os.path.join(self.plugin_dir, 'res', 'icon_09_DSV.png'),
                text=self.tr(u'rebuild dranaige system valve'),
                callback=self.run_DSV,
                enabled_flag=False,
                checkable=False,
            ),
        }

        self.tools['WRp'] = self.add_action(
            os.path.join(self.plugin_dir, 'res', 'icon_04_WR.png'),
            text=self.tr(u'point water_rec'),
            callback=None,  #self.check_WR,
            enabled_flag=True,
            checkable=True,
            add_to_menu='WR',
        )

        self.tools['WRg'] = self.add_action(
            os.path.join(self.plugin_dir, 'res', 'icon_04_WR.png'),
            text=self.tr(u'green roof water_rec'),
            callback=None,  #self.check_WR,
            enabled_flag=True,
            checkable=True,
            add_to_menu='WR')

        self.tools['WRl'] = self.add_action(
            os.path.join(self.plugin_dir, 'res', 'icon_04_WR.png'),
            text=self.tr(u'limited water_rec'),
            callback=None,  #self.check_WR,
            enabled_flag=True,
            checked=True,
            checkable=True,
            add_to_menu='WR')

        self.tools['Print project report'] = self.add_action(
            os.path.join(self.plugin_dir, 'res', 'icon_04_WR.png'),
            text=self.tr(u'print global report'),
            callback=self.print_global,
            enabled_flag=True,
            add_to_menu='print')

        self.tools['Print EP report'] = self.add_action(
            os.path.join(self.plugin_dir, 'res', 'icon_04_WR.png'),
            text=self.tr(u'print EP report'),
            callback=self.print_EP,
            enabled_flag=True,
            add_to_menu='print')

        self.tools['Print EA report'] = self.add_action(
            os.path.join(self.plugin_dir, 'res', 'icon_04_WR.png'),
            text=self.tr(u'print EA report'),
            callback=self.print_EA,
            enabled_flag=True,
            add_to_menu='print')

        self.tools['Print WR report'] = self.add_action(
            os.path.join(self.plugin_dir, 'res', 'icon_04_WR.png'),
            text=self.tr(u'print WR report'),
            callback=self.print_WR,
            enabled_flag=True,
            add_to_menu='print')

        self.tools['Print WDS report'] = self.add_action(
            os.path.join(self.plugin_dir, 'res', 'icon_04_WR.png'),
            text=self.tr(u'print WDS report'),
            callback=self.print_WDS,
            enabled_flag=True,
            add_to_menu='print')

        self.dlg_EA = fdtmEADialog()
        self.dlg_EP = fdtmEPDialog()
        self.dlg_WR = fdtmWRDialog()
        self.dlg_WDS = fdtmWDSDialog()
        self.dlg_info = fdtmInfoDialog()
        self.dlg_print = fdtmPrintDialog()
        self.dlg_settings = fdtmSettingsDialog(self)
        self.dlg_about = fdtmAboutDialog()
        self.dlg_about.webView.page().setNetworkAccessManager(
            QgsNetworkAccessManager.instance())
        # ---------------------------------------------------------------------

        self.dlg_settings.validated.connect(self.enableTools)

        self.dlg_summary = self.dlg_settings.getSummaryWidget()
        self.fdtmDockwidget = QDockWidget("FDTM summary",
                                          self.iface.mainWindow())
        self.fdtmDockwidget.setObjectName("fdtmSummary")
        self.fdtmDockwidget.setWidget(self.dlg_summary)
        self.iface.addDockWidget(Qt.BottomDockWidgetArea, self.fdtmDockwidget)
        self.fdtmDockwidget.hide()

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

    def enableTools(self, validated):
        tool_set = {
            'print': 'icon_07_print',
            'EP': 'icon_02_EP',
            'EA': 'icon_03_EA',
            'info': 'icon_06_info',
            'WR': 'icon_04_WR',
            'WDS': 'icon_05_WDS',
            'DSV': 'icon_09_DSV',
            'summary': 'icon_08_summary'
        }  #'print':'icon_07_print','WR':'icon_04_WR','WDS':'icon_05_WDS'
        if validated:
            disabled_sufx = ''
            self.fdtmDockwidget.show()
        else:
            disabled_sufx = '_disabled'
            self.fdtmDockwidget.hide()
        for t, f in tool_set.items():
            self.tools[t].setEnabled(validated)
            icon = QIcon(
                os.path.join(self.plugin_dir, 'res',
                             f + disabled_sufx + '.png'))
            self.tools[t].setIcon(icon)
        if self.dlg_settings.optionalDrainageSystemLayer.isChecked(
        ) and self.dlg_settings.optionalDrainageSystemLayer.DSVLayer():
            self.tools['DSV'].setEnabled(True)
            self.tools['DSV'].setIcon(
                QIcon(os.path.join(self.plugin_dir, 'res', 'icon_09_DSV.png')))
        else:
            self.tools['DSV'].setEnabled(False)
            self.tools['DSV'].setIcon(
                QIcon(
                    os.path.join(self.plugin_dir, 'res',
                                 'icon_09_DSV_disabled.png')))

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""

        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&fdtm'), action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        self.dlg_settings.deactivate()
        self.iface.removeDockWidget(self.fdtmDockwidget)
        del self.toolbar

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

    def setUncheckedActions(self, uncheckedActions):
        for action in uncheckedActions:
            self.tools[action].setChecked(False)

    def run_EP(self, checked):
        if checked:
            self.setUncheckedActions(['EA', 'WR', 'WDS'])
            self.dlg_settings.datasetWrapper.EPpWrapper.fdtm_startEditing()
        else:
            self.dlg_settings.datasetWrapper.EPpWrapper.confirmEdits()

    def run_EA(self, checked):
        if checked:
            self.setUncheckedActions(['EP', 'WR', 'WDS'])
            self.dlg_settings.datasetWrapper.EApWrapper.fdtm_startEditing()
        else:
            self.dlg_settings.datasetWrapper.EApWrapper.confirmEdits()

    def check_WR(self):
        self.tools['WR'].setChecked(True)

    def run_WR(self, checked):
        if checked:
            self.setUncheckedActions(['EA', 'EP', 'WDS'])
            if self.tools['WR'].actionGroup.checkedAction(
            ) == self.tools['WRp']:
                WRType = 'point'
            elif self.tools['WR'].actionGroup.checkedAction(
            ) == self.tools['WRl']:
                WRType = 'limited'
            elif self.tools['WR'].actionGroup.checkedAction(
            ) == self.tools['WRg']:
                WRType = 'greenroof'
            self.dlg_settings.datasetWrapper.WRWrapper.fdtm_startEditing(
                WRType)
            self.tools['WR'].actionGroup.setEnabled(False)
        else:
            self.dlg_settings.datasetWrapper.WRWrapper.confirmEdits()
            self.tools['WR'].actionGroup.setEnabled(True)

    def run_WDS(self, checked):
        if checked:
            self.setUncheckedActions(['EA', 'WR', 'EP'])
            self.dlg_settings.datasetWrapper.WDSWrapper.fdtm_startEditing()
        else:
            self.dlg_settings.datasetWrapper.WDSWrapper.confirmEdits()

    def toggle_summary(self):
        if self.fdtmDockwidget.isVisible():
            self.fdtmDockwidget.hide()
        else:
            self.fdtmDockwidget.show()

    def run_info(self, checked):
        if checked:
            self.backupMapTool = self.iface.mapCanvas().mapTool()
            layerList = [
                self.dlg_settings.EApLayer, self.dlg_settings.EPpLayer,
                self.dlg_settings.EPlLayer, self.dlg_settings.WRLayer,
                self.dlg_settings.WDSLayer
            ]
            if self.dlg_settings.optionalDrainageSystemLayer.DSVLayer():
                self.drainageSystemLayerManagement = True
                layerList.append(
                    self.dlg_settings.datasetWrapper.DSVWrapper.lyr)
            else:
                self.drainageSystemLayerManagement = False
            #print layerList
            self.fdtm_infoMapTool = IdentifyGeometry(
                self.iface.mapCanvas(), layerList, self.dlg_settings.DEMLayer)
            self.fdtm_infoMapTool.geomIdentified.connect(self.editFeature)
            self.iface.mapCanvas().setMapTool(self.fdtm_infoMapTool)
            self.iface.mapCanvas().mapToolSet.connect(self.restoreInfoAction)
        else:
            if self.backupMapTool:
                self.iface.mapCanvas().mapToolSet.disconnect(
                    self.restoreInfoAction)
                self.iface.mapCanvas().setMapTool(self.backupMapTool)

    def restoreInfoAction(self, MT):
        self.iface.mapCanvas().mapToolSet.disconnect(self.restoreInfoAction)
        self.backupMapTool = None
        self.tools['info'].setChecked(False)

    def editFeature(self, selLayer, selFeature, identifyPoint):
        if selLayer == self.dlg_settings.DEMLayer:
            if self.dlg_settings.datasetWrapper.DEMWrapper.contains(
                    identifyPoint):
                self.dlg_settings.datasetWrapper.DEMWrapper.viewSample(
                    identifyPoint)
            else:
                self.iface.messageBar().pushMessage(
                    "Info tool error",
                    "Sampling outside digital elevation model boundary",
                    level=1,
                    duration=3)  # QgsMessageBar.Warning
        elif self.drainageSystemLayerManagement and selLayer == self.dlg_settings.datasetWrapper.DSVWrapper.lyr:
            self.dlg_settings.datasetWrapper.DSVWrapper.fdtm_startEditing(
                changeActiveLayer=False)
            self.dlg_settings.datasetWrapper.DSVWrapper.editAttributes(
                selFeature)
            self.dlg_settings.datasetWrapper.DSVWrapper.fdtm_commitChanges()
        else:
            selLayer.fdtm_wrapper.editAttributes(selFeature)

    def run_settings(self):
        """Run method that loads and starts the plugin"""
        self.dlg_settings.show()

    def run_about(self):
        """Run method that loads and starts the plugin"""
        self.dlg_about.webView.load(QUrl("http://brigaid.eu/"))
        self.dlg_about.show()

    def run_print(self):
        """Run method that loads and starts the plugin"""
        self.tools['print'].menu().exec_(
            self.toolbar.mapToGlobal(QPoint(0, self.toolbar.height())))

    def print_global(self):
        fdtmPrint.exportGlobalReport(self.dlg_settings)

    def print_EP(self):
        fdtmPrint.exportEP(self.dlg_settings)

    def print_EA(self):
        fdtmPrint.exportEA(self.dlg_settings)

    def print_WR(self):
        fdtmPrint.exportWR(self.dlg_settings)

    def print_WDS(self):
        fdtmPrint.exportWDS(self.dlg_settings)

    def undef(self):
        pass

    def run_DSV(self):
        self.dlg_settings.datasetWrapper.DSVWrapper.rebuildLayer()