1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2014 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4#
5
6"""
7Module implementing the Git version control plugin.
8"""
9
10import os
11import contextlib
12
13from PyQt5.QtCore import QObject, QCoreApplication, QByteArray
14
15from E5Gui.E5Application import e5App
16
17import Preferences
18from Preferences.Shortcuts import readShortcuts
19
20from VcsPlugins.vcsGit.GitUtilities import getConfigPath
21
22import Utilities
23import UI.Info
24
25# Start-Of-Header
26name = "Git Plugin"
27author = "Detlev Offenbach <detlev@die-offenbachs.de>"
28autoactivate = False
29deactivateable = True
30version = UI.Info.VersionOnly
31pluginType = "version_control"
32pluginTypename = "Git"
33className = "VcsGitPlugin"
34packageName = "__core__"
35shortDescription = "Implements the Git version control interface."
36longDescription = (
37    """This plugin provides the Git version control interface."""
38)
39pyqtApi = 2
40# End-Of-Header
41
42error = ""
43
44
45def exeDisplayData():
46    """
47    Public method to support the display of some executable info.
48
49    @return dictionary containing the data to query the presence of
50        the executable
51    """
52    exe = 'git'
53    if Utilities.isWindowsPlatform():
54        exe += '.exe'
55
56    data = {
57        "programEntry": True,
58        "header": QCoreApplication.translate(
59            "VcsGitPlugin", "Version Control - Git"),
60        "exe": exe,
61        "versionCommand": 'version',
62        "versionStartsWith": 'git',
63        "versionPosition": 2,
64        "version": "",
65        "versionCleanup": None,
66    }
67
68    return data
69
70
71def getVcsSystemIndicator():
72    """
73    Public function to get the indicators for this version control system.
74
75    @return dictionary with indicator as key and a tuple with the vcs name
76        (string) and vcs display string (string)
77    """
78    global pluginTypename
79    data = {}
80    exe = 'git'
81    if Utilities.isWindowsPlatform():
82        exe += '.exe'
83    if Utilities.isinpath(exe):
84        data[".git"] = (pluginTypename, displayString())
85        data["_git"] = (pluginTypename, displayString())
86    return data
87
88
89def displayString():
90    """
91    Public function to get the display string.
92
93    @return display string (string)
94    """
95    exe = 'git'
96    if Utilities.isWindowsPlatform():
97        exe += '.exe'
98    if Utilities.isinpath(exe):
99        return QCoreApplication.translate('VcsGitPlugin', 'Git')
100    else:
101        return ""
102
103
104gitCfgPluginObject = None
105
106
107def createConfigurationPage(configDlg):
108    """
109    Module function to create the configuration page.
110
111    @param configDlg reference to the configuration dialog (QDialog)
112    @return reference to the configuration page
113    """
114    global gitCfgPluginObject
115    from VcsPlugins.vcsGit.ConfigurationPage.GitPage import (
116        GitPage
117    )
118    if gitCfgPluginObject is None:
119        gitCfgPluginObject = VcsGitPlugin(None)
120    page = GitPage(gitCfgPluginObject)
121    return page
122
123
124def getConfigData():
125    """
126    Module function returning data as required by the configuration dialog.
127
128    @return dictionary with key "zzz_gitPage" containing the relevant
129        data
130    """
131    return {
132        "zzz_gitPage":
133        [QCoreApplication.translate("VcsGitPlugin", "Git"),
134            os.path.join("VcsPlugins", "vcsGit", "icons",
135                         "preferences-git.svg"),
136            createConfigurationPage, "vcsPage", None],
137    }
138
139
140def prepareUninstall():
141    """
142    Module function to prepare for an uninstallation.
143    """
144    if not e5App().getObject("PluginManager").isPluginLoaded(
145            "PluginVcsGit"):
146        Preferences.Prefs.settings.remove("Git")
147
148
149def clearPrivateData():
150    """
151    Module function to clear the private data of the plug-in.
152    """
153    for key in ["RepositoryUrlHistory"]:
154        VcsGitPlugin.setPreferences(key, [])
155
156
157class VcsGitPlugin(QObject):
158    """
159    Class implementing the Git version control plugin.
160    """
161    GitDefaults = {
162        "StopLogOnCopy": True,          # used in log browser
163        "ShowAuthorColumns": True,      # used in log browser
164        "ShowCommitterColumns": True,   # used in log browser
165        "ShowCommitIdColumn": True,     # used in log browser
166        "ShowBranchesColumn": True,     # used in log browser
167        "ShowTagsColumn": True,         # used in log browser
168        "FindCopiesHarder": False,      # used in log browser
169        "LogLimit": 20,
170        "LogSubjectColumnWidth": 30,
171        "LogBrowserGeometry": QByteArray(),
172        "LogBrowserSplitterStates": [QByteArray(), QByteArray(),
173                                     QByteArray()],
174        # mainSplitter, detailsSplitter, diffSplitter
175        "StatusDialogGeometry": QByteArray(),
176        "StatusDialogSplitterStates": [QByteArray(), QByteArray()],
177        # vertical splitter, horizontal splitter
178        "CommitMessages": 20,
179        "Commits": [],
180        "CommitIdLength": 10,
181        "CleanupPatterns": "*.orig *.rej *~",
182        "AggressiveGC": True,
183        "RepositoryUrlHistory": [],
184    }
185
186    def __init__(self, ui):
187        """
188        Constructor
189
190        @param ui reference to the user interface object (UI.UserInterface)
191        """
192        super().__init__(ui)
193        self.__ui = ui
194
195        from VcsPlugins.vcsGit.ProjectHelper import GitProjectHelper
196        self.__projectHelperObject = GitProjectHelper(None, None)
197        with contextlib.suppress(KeyError):
198            e5App().registerPluginObject(
199                pluginTypename, self.__projectHelperObject, pluginType)
200
201        readShortcuts(pluginName=pluginTypename)
202
203    def getProjectHelper(self):
204        """
205        Public method to get a reference to the project helper object.
206
207        @return reference to the project helper object
208        """
209        return self.__projectHelperObject
210
211    def initToolbar(self, ui, toolbarManager):
212        """
213        Public slot to initialize the VCS toolbar.
214
215        @param ui reference to the main window (UserInterface)
216        @param toolbarManager reference to a toolbar manager object
217            (E5ToolBarManager)
218        """
219        if self.__projectHelperObject:
220            self.__projectHelperObject.initToolbar(ui, toolbarManager)
221
222    def activate(self):
223        """
224        Public method to activate this plugin.
225
226        @return tuple of reference to instantiated viewmanager and
227            activation status (boolean)
228        """
229        from VcsPlugins.vcsGit.git import Git
230        self.__object = Git(self, self.__ui)
231
232        tb = self.__ui.getToolbar("vcs")[1]
233        tb.setVisible(False)
234        tb.setEnabled(False)
235
236        tb = self.__ui.getToolbar("git")[1]
237        tb.setVisible(Preferences.getVCS("ShowVcsToolbar"))
238        tb.setEnabled(True)
239
240        return self.__object, True
241
242    def deactivate(self):
243        """
244        Public method to deactivate this plugin.
245        """
246        self.__object = None
247
248        tb = self.__ui.getToolbar("git")[1]
249        tb.setVisible(False)
250        tb.setEnabled(False)
251
252        tb = self.__ui.getToolbar("vcs")[1]
253        tb.setVisible(Preferences.getVCS("ShowVcsToolbar"))
254        tb.setEnabled(True)
255
256    @classmethod
257    def getPreferences(cls, key):
258        """
259        Class method to retrieve the various settings.
260
261        @param key the key of the value to get
262        @return the requested setting
263        """
264        if key in ["StopLogOnCopy", "ShowReflogInfo", "ShowAuthorColumns",
265                   "ShowCommitterColumns", "ShowCommitIdColumn",
266                   "ShowBranchesColumn", "ShowTagsColumn", "FindCopiesHarder",
267                   "AggressiveGC"]:
268            return Preferences.toBool(Preferences.Prefs.settings.value(
269                "Git/" + key, cls.GitDefaults[key]))
270        elif key in ["LogLimit", "CommitMessages", "CommitIdLength",
271                     "LogSubjectColumnWidth"]:
272            return int(Preferences.Prefs.settings.value(
273                "Git/" + key, cls.GitDefaults[key]))
274        elif key in ["Commits", "RepositoryUrlHistory"]:
275            return Preferences.toList(Preferences.Prefs.settings.value(
276                "Git/" + key))
277        elif key in ["LogBrowserGeometry", "StatusDialogGeometry"]:
278            v = Preferences.Prefs.settings.value("Git/" + key)
279            if v is not None:
280                return v
281            else:
282                return cls.GitDefaults[key]
283        elif key in ["LogBrowserSplitterStates", "StatusDialogSplitterStates"]:
284            states = Preferences.Prefs.settings.value("Git/" + key)
285            if states is not None:
286                return states
287            else:
288                return cls.GitDefaults[key]
289        else:
290            return Preferences.Prefs.settings.value(
291                "Git/" + key, cls.GitDefaults[key])
292
293    @classmethod
294    def setPreferences(cls, key, value):
295        """
296        Class method to store the various settings.
297
298        @param key the key of the setting to be set
299        @param value the value to be set
300        """
301        Preferences.Prefs.settings.setValue("Git/" + key, value)
302
303    def getConfigPath(self):
304        """
305        Public method to get the filename of the config file.
306
307        @return filename of the config file (string)
308        """
309        return getConfigPath()
310
311    def prepareUninstall(self):
312        """
313        Public method to prepare for an uninstallation.
314        """
315        e5App().unregisterPluginObject(pluginTypename)
316
317    def prepareUnload(self):
318        """
319        Public method to prepare for an unload.
320        """
321        if self.__projectHelperObject:
322            self.__projectHelperObject.removeToolbar(
323                self.__ui, e5App().getObject("ToolbarManager"))
324        e5App().unregisterPluginObject(pluginTypename)
325
326#
327# eflag: noqa = M801
328