PluginExtensionIrc.py

Wed, 07 May 2025 18:04:16 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 07 May 2025 18:04:16 +0200
changeset 11
d1af35d0bcc6
parent 9
bd9ede602f1c
permissions
-rw-r--r--

Corrected some copy & paste issue in the source code documentation and added code to prevent plug-in activation on eric-ide versions containing the embedded variant.

# -*- coding: utf-8 -*-

# Copyright (c) 2025 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a plug-in providing IRC communication capability.
"""

import logging
import os

from PyQt6.QtCore import QCoreApplication, QObject, Qt, QTranslator
from PyQt6.QtGui import QIcon, QKeySequence, QPixmap

from eric7 import EricUtilities, Preferences
from eric7.EricGui import EricPixmapCache
from eric7.EricGui.EricAction import EricAction
from eric7.EricWidgets import EricMessageBox
from eric7.EricWidgets.EricApplication import ericApp
from eric7.UI.UserInterface import UserInterfaceSide

# Start-Of-Header
__header__ = {
    "name": "IRC Extension Plugin",
    "author": "Detlev Offenbach <detlev@die-offenbachs.de>",
    "autoactivate": True,
    "deactivateable": True,
    "version": "10.0.2",
    "className": "IrcExtensionPlugin",
    "packageName": "ExtensionIrc",
    "shortDescription": "This plug-in adds a widget to communicate via IRC messa",
    "longDescription": (
        "This plug-in adds a widget to communicate via IRC messages. It replaces"
        " the formerly integrated variant."
    ),
    "needsRestart": False,
    "hasCompiledForms": True,
    "pyqtApi": 2,
}
# End-Of-Header

error = ""  # noqa: U-200

ircExtensionPluginObject = None


def createIrcPage(configDlg):  # noqa: U-100
    """
    Function to create the IRC configuration page.

    @param configDlg reference to the configuration dialog
    @type ConfigurationWidget
    @return reference to the configuration page
    @rtype TranslatorPage
    """
    global ircExtensionPluginObject
    from ExtensionIrc.ConfigurationPage.IrcPage import IrcPage  # noqa: I-101, I-102

    page = IrcPage(ircExtensionPluginObject)
    return page


def getConfigData():
    """
    Function returning data as required by the configuration dialog.

    @return dictionary containing the relevant data
    @rtype dict
    """
    return {
        "ircPage": [
            QCoreApplication.translate("IrcExtensionPlugin", "IRC"),
            os.path.join("ExtensionIrc", "icons", "irc"),
            createIrcPage,
            None,
            None,
        ],
    }


def prepareUninstall():
    """
    Function to prepare for an un-installation.
    """
    Preferences.getSettings().remove(IrcExtensionPlugin.PreferencesKey)


class IrcExtensionPlugin(QObject):
    """
    Class implementing a plug-in providing IRC communication capability.
    """

    PreferencesKey = "IRC"

    def __init__(self, ui):
        """
        Constructor

        @param ui reference to the user interface object
        @type UI.UserInterface
        """
        super().__init__(ui)
        self.__ui = ui
        self.__initialize()

        self.__defaults = {
            "ShowTimestamps": True,
            "TimestampIncludeDate": False,
            "TimeFormat": "hh:mm",
            "DateFormat": "yyyy-MM-dd",
            "NetworkMessageColour": "#000055",
            "ServerMessageColour": "#91640A",
            "ErrorMessageColour": "#FF0000",
            "TimestampColour": "#709070",
            "HyperlinkColour": "#0000FF",
            "ChannelMessageColour": "#000000",
            "OwnNickColour": "#000000",
            "NickColour": "#18B33C",
            "JoinChannelColour": "#72D672",
            "LeaveChannelColour": "#B00000",
            "ChannelInfoColour": "#9E54B3",
            "EnableIrcColours": True,
            "IrcColor0": "#FFFF00",
            "IrcColor1": "#000000",
            "IrcColor2": "#000080",
            "IrcColor3": "#008000",
            "IrcColor4": "#FF0000",
            "IrcColor5": "#A52A2A",
            "IrcColor6": "#800080",
            "IrcColor7": "#FF8000",
            "IrcColor8": "#808000",
            "IrcColor9": "#00FF00",
            "IrcColor10": "#008080",
            "IrcColor11": "#00FFFF",
            "IrcColor12": "#0000FF",
            "IrcColor13": "#FFC0CB",
            "IrcColor14": "#A0A0A0",
            "IrcColor15": "#C0C0C0",
            "ShowNotifications": True,
            "NotifyJoinPart": True,
            "NotifyMessage": False,
            "NotifyNick": False,
            "AutoUserInfoLookup": True,
            "AutoUserInfoMax": 200,
            "AutoUserInfoInterval": 90,
            "MarkPositionWhenHidden": True,
            "MarkerLineForegroundColour": "#000000",  # Black on
            "MarkerLineBackgroundColour": "#ffff00",  # Yellow
        }

        self.__translator = None
        self.__loadTranslator()

    def __initialize(self):
        """
        Private slot to (re)initialize the plugin.
        """
        self.__irc = None

    def activate(self):
        """
        Public method to activate this plug-in.

        @return tuple of None and activation status
        @rtype bool
        """
        global error, ircExtensionPluginObject
        error = ""  # clear previous error
        ircExtensionPluginObject = self

        if self.__ui.versionIsNewer("25.4"):
            # Create the IRC user interface
            logging.getLogger(__name__).debug("Creating IRC Widget...")
            from ExtensionIrc.IrcWidget import IrcWidget  # noqa: I-101, I-102

            usesDarkPalette = ericApp().usesDarkPalette()
            self.__iconType = "dark" if usesDarkPalette else "light"

            self.__irc = IrcWidget(plugin=self)
            iconName = "sbIrc96" if self.__ui.getLayoutType() == "Sidebars" else "irc"
            self.__ui.addSideWidget(
                UserInterfaceSide.Right,
                self.__irc,
                self.getIcon(iconName),
                self.tr("IRC"),
            )

            self.__activateAct = EricAction(
                self.tr("IRC"),
                self.tr("&IRC"),
                QKeySequence(self.tr("Ctrl+Alt+Shift+I")),
                0,
                self,
                "irc_widget_activate",
            )
            self.__activateAct.setStatusTip(
                self.tr("Switch the input focus to the IRC window.")
            )
            self.__activateAct.setWhatsThis(
                self.tr(
                    """<b>Activate IRC</b>"""
                    """<p>This switches the input focus to the IRC window.</p>"""
                )
            )
            self.__activateAct.triggered.connect(self.__activateWidget)

            self.__ui.addEricActions([self.__activateAct], "ui")
            menu = self.__ui.getMenu("subwindow")
            menu.addAction(self.__activateAct)

            ericApp().getObject("PluginManager").shutdown.connect(self.__irc.shutdown)

            self.__irc.autoConnected.connect(self.__activateWidget)
            self.__irc.autoConnect()

            return None, True
        else:
            EricMessageBox.warning(
                self.__ui,
                self.tr("IRC Extension"),
                self.tr(
                    "The IRC extension cannot be activated because it requires eric7"
                    " 25.5 or newer."
                ),
            )
            error = self.tr(
                "The IRC extension cannot be activated because it requires eric7 25.5"
                " or newer."
            )

            return None, False

    def deactivate(self):
        """
        Public method to deactivate this plug-in.
        """
        menu = self.__ui.getMenu("subwindow")
        menu.removeAction(self.__activateAct)
        self.__ui.removeEricActions([self.__activateAct], "ui")
        self.__ui.removeSideWidget(self.__irc)

        self.__initialize()

    def __getIconPaths(self, iconName):
        """
        Private method to generate a list of paths to check for the requested icon name.

        @param iconName name of the icon
        @type str
        @return list of icon path names
        @rtype list of str
        """
        return [
            os.path.join("ExtensionIrc", "icons", self.__iconType, iconName),
            os.path.join("ExtensionIrc", "icons", iconName),  # without icon type
        ]

    def getIcon(self, iconName):
        """
        Public method to get a named icon.

        @param iconName name of the icon
        @type str
        @return requested icon
        @rtype QIcon
        """
        icon = QIcon()

        for iconPath in self.__getIconPaths(iconName):
            icon = EricPixmapCache.getIcon(iconPath)
            if not icon.isNull():
                break

        return icon

    def getPixmap(self, pixmapName):
        """
        Public method to get a named pixmap.

        @param pixmapName name of the pixmap
        @type str
        @return requested pixmap
        @rtype QPixmap
        """
        pixmap = QPixmap()

        for pixPath in self.__getIconPaths(pixmapName):
            pixmap = EricPixmapCache.getPixmap(pixPath)
            if not pixmap.isNull():
                break

        return pixmap

    def __loadTranslator(self):
        """
        Private method to load the translation file.
        """
        if self.__ui is not None:
            loc = self.__ui.getLocale()
            if loc and loc != "C":
                locale_dir = os.path.join(
                    os.path.dirname(__file__), "ExtensionIrc", "i18n"
                )
                translation = "irc_{0}".format(loc)
                translator = QTranslator(None)
                loaded = translator.load(translation, locale_dir)
                if loaded:
                    self.__translator = translator
                    ericApp().installTranslator(self.__translator)
                else:
                    print(  # noqa: M-801
                        "Warning: translation file '{0}' could not be"
                        " loaded.".format(translation)
                    )
                    print("Using default.")  # noqa: M-801

    def __activateWidget(self):
        """
        Private slot to handle the activation of the IRC widget.
        """
        uiLayoutType = self.__ui.getLayoutType()

        if uiLayoutType == "Toolboxes":
            self.__ui.rToolboxDock.show()
            self.__ui.rToolbox.setCurrentWidget(self.irc)
        elif uiLayoutType == "Sidebars":
            self.__ui.activateLeftRightSidebarWidget(self.__irc)
        self.__irc.setFocus(Qt.FocusReason.ActiveWindowFocusReason)

    def getPreferences(self, key):
        """
        Public method to retrieve the various settings values.

        @param key the key of the value to get
        @type str
        @return the requested setting value
        @rtype Any
        """
        if key in [
            "TimestampIncludeDate",
            "ShowTimestamps",
            "ShowNotifications",
            "NotifyJoinPart",
            "NotifyMessage",
            "NotifyNick",
            "EnableIrcColours",
            "AutoUserInfoLookup",
            "MarkPositionWhenHidden",
        ]:
            return EricUtilities.toBool(
                Preferences.Prefs.settings.value(
                    self.PreferencesKey + "/" + key, self.__defaults[key]
                )
            )
        elif key in ["AutoUserInfoMax", "AutoUserInfoInterval"]:
            return int(
                Preferences.Prefs.settings.value(
                    self.PreferencesKey + "/" + key, self.__defaults[key]
                )
            )
        else:
            return Preferences.Prefs.settings.value(
                self.PreferencesKey + "/" + key, self.__defaults[key]
            )
        return None

    def setPreferences(self, key, value):
        """
        Public method to store the various settings values.

        @param key the key of the setting to be set
        @type str
        @param value the value to be set
        @type Any
        """
        Preferences.Prefs.settings.setValue(self.PreferencesKey + "/" + key, value)

eric ide

mercurial