1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4#
5
6"""
7Module implementing the Plugin Info Dialog.
8"""
9
10from PyQt5.QtCore import pyqtSlot, Qt
11from PyQt5.QtGui import QBrush
12from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QHeaderView, QMenu
13
14from .Ui_PluginInfoDialog import Ui_PluginInfoDialog
15
16
17class PluginInfoDialog(QDialog, Ui_PluginInfoDialog):
18    """
19    Class implementing the Plugin Info Dialog.
20    """
21    def __init__(self, pluginManager, parent=None):
22        """
23        Constructor
24
25        @param pluginManager reference to the plugin manager object
26        @param parent parent of this dialog (QWidget)
27        """
28        super().__init__(parent)
29        self.setupUi(self)
30        self.setWindowFlags(Qt.WindowType.Window)
31
32        self.pm = pluginManager
33
34        self.__autoActivateColumn = 3
35        self.__activeColumn = 4
36
37        self.pluginList.headerItem().setText(self.pluginList.columnCount(), "")
38
39        # populate the list
40        self.__populateList()
41        self.pluginList.sortByColumn(0, Qt.SortOrder.AscendingOrder)
42
43        self.__menu = QMenu(self)
44        self.__menu.addAction(self.tr('Show details'), self.__showDetails)
45        self.__activateAct = self.__menu.addAction(
46            self.tr('Activate'), self.__activatePlugin)
47        self.__deactivateAct = self.__menu.addAction(
48            self.tr('Deactivate'), self.__deactivatePlugin)
49        self.pluginList.setContextMenuPolicy(
50            Qt.ContextMenuPolicy.CustomContextMenu)
51        self.pluginList.customContextMenuRequested.connect(
52            self.__showContextMenu)
53
54    def __populateList(self):
55        """
56        Private method to (re)populate the list of plugins.
57        """
58        self.pluginList.clear()
59        for info in self.pm.getPluginInfos():
60            self.__createEntry(info)
61        self.pluginList.sortItems(
62            self.pluginList.sortColumn(),
63            self.pluginList.header().sortIndicatorOrder())
64
65    def __createEntry(self, info):
66        """
67        Private method to create a list entry based on the provided info.
68
69        @param info dictionary giving the info for the entry (as returned by
70            PluginManager.getPluginInfos())
71        @type dict
72        """
73        infoList = [
74            info["module_name"],
75            info["plugin_name"],
76            info["version"],
77            (info["auto_activate"] and self.tr("Yes") or self.tr("On-Demand")),
78            (info["active"] and self.tr("Yes") or self.tr("No")),
79            info["short_desc"]
80        ]
81        itm = QTreeWidgetItem(self.pluginList, infoList)
82        if info["error"]:
83            # plugin error
84            for col in range(self.pluginList.columnCount()):
85                itm.setForeground(col, QBrush(Qt.GlobalColor.red))
86        itm.setTextAlignment(self.__autoActivateColumn,
87                             Qt.AlignmentFlag.AlignHCenter)
88        itm.setTextAlignment(self.__activeColumn,
89                             Qt.AlignmentFlag.AlignHCenter)
90
91        self.pluginList.header().resizeSections(
92            QHeaderView.ResizeMode.ResizeToContents)
93        self.pluginList.header().setStretchLastSection(True)
94
95    def __showContextMenu(self, coord):
96        """
97        Private slot to show the context menu of the listview.
98
99        @param coord the position of the mouse pointer (QPoint)
100        """
101        itm = self.pluginList.itemAt(coord)
102        if itm is not None:
103            autoactivate = (itm.text(self.__autoActivateColumn) ==
104                            self.tr("Yes"))
105            if itm.text(self.__activeColumn) == self.tr("Yes"):
106                self.__activateAct.setEnabled(False)
107                self.__deactivateAct.setEnabled(autoactivate)
108            else:
109                self.__activateAct.setEnabled(autoactivate)
110                self.__deactivateAct.setEnabled(False)
111            self.__menu.popup(self.mapToGlobal(coord))
112
113    @pyqtSlot(QTreeWidgetItem, int)
114    def on_pluginList_itemActivated(self, item, column):
115        """
116        Private slot to show details about a plugin.
117
118        @param item reference to the selected item (QTreeWidgetItem)
119        @param column column number (integer)
120        """
121        moduleName = item.text(0)
122        details = self.pm.getPluginDetails(moduleName)
123        if details is None:
124            pass
125        else:
126            from .PluginDetailsDialog import PluginDetailsDialog
127            dlg = PluginDetailsDialog(details, self)
128            dlg.show()
129
130    def __showDetails(self):
131        """
132        Private slot to handle the "Show details" context menu action.
133        """
134        itm = self.pluginList.currentItem()
135        self.on_pluginList_itemActivated(itm, 0)
136
137    def __activatePlugin(self):
138        """
139        Private slot to handle the "Deactivate" context menu action.
140        """
141        itm = self.pluginList.currentItem()
142        moduleName = itm.text(0)
143        self.pm.activatePlugin(moduleName)
144        # repopulate the list
145        self.__populateList()
146
147    def __deactivatePlugin(self):
148        """
149        Private slot to handle the "Activate" context menu action.
150        """
151        itm = self.pluginList.currentItem()
152        moduleName = itm.text(0)
153        self.pm.deactivatePlugin(moduleName)
154        # repopulate the list
155        self.__populateList()
156