1# -*- coding: utf-8 -*- 2 3# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> 4# 5 6""" 7Module implementing the Mercurial 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.vcsMercurial.HgUtilities import getConfigPath, getHgExecutable 21 22import Utilities 23import UI.Info 24 25# Start-Of-Header 26name = "Mercurial Plugin" 27author = "Detlev Offenbach <detlev@die-offenbachs.de>" 28autoactivate = False 29deactivateable = True 30version = UI.Info.VersionOnly 31pluginType = "version_control" 32pluginTypename = "Mercurial" 33className = "VcsMercurialPlugin" 34packageName = "__core__" 35shortDescription = "Implements the Mercurial version control interface." 36longDescription = ( 37 """This plugin provides the Mercurial 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 data = { 53 "programEntry": True, 54 "header": QCoreApplication.translate( 55 "VcsMercurialPlugin", "Version Control - Mercurial"), 56 "exe": getHgExecutable(), 57 "versionCommand": 'version', 58 "versionStartsWith": 'Mercurial', 59 "versionPosition": -1, 60 "version": "", 61 "versionCleanup": (0, -1), 62 } 63 64 return data 65 66 67def getVcsSystemIndicator(): 68 """ 69 Public function to get the indicators for this version control system. 70 71 @return dictionary with indicator as key and a tuple with the vcs name 72 (string) and vcs display string (string) 73 """ 74 global pluginTypename 75 data = {} 76 exe = getHgExecutable() 77 if Utilities.isinpath(exe): 78 data[".hg"] = (pluginTypename, displayString()) 79 data["_hg"] = (pluginTypename, displayString()) 80 return data 81 82 83def displayString(): 84 """ 85 Public function to get the display string. 86 87 @return display string (string) 88 """ 89 exe = getHgExecutable() 90 if Utilities.isinpath(exe): 91 return QCoreApplication.translate('VcsMercurialPlugin', 'Mercurial') 92 else: 93 return "" 94 95mercurialCfgPluginObject = None 96 97 98def createConfigurationPage(configDlg): 99 """ 100 Module function to create the configuration page. 101 102 @param configDlg reference to the configuration dialog (QDialog) 103 @return reference to the configuration page 104 """ 105 global mercurialCfgPluginObject 106 from VcsPlugins.vcsMercurial.ConfigurationPage.MercurialPage import ( 107 MercurialPage 108 ) 109 if mercurialCfgPluginObject is None: 110 mercurialCfgPluginObject = VcsMercurialPlugin(None) 111 page = MercurialPage(mercurialCfgPluginObject) 112 return page 113 114 115def getConfigData(): 116 """ 117 Module function returning data as required by the configuration dialog. 118 119 @return dictionary with key "zzz_mercurialPage" containing the relevant 120 data 121 """ 122 return { 123 "zzz_mercurialPage": 124 [QCoreApplication.translate("VcsMercurialPlugin", "Mercurial"), 125 os.path.join("VcsPlugins", "vcsMercurial", "icons", 126 "preferences-mercurial.svg"), 127 createConfigurationPage, "vcsPage", None], 128 } 129 130 131def prepareUninstall(): 132 """ 133 Module function to prepare for an uninstallation. 134 """ 135 if not e5App().getObject("PluginManager").isPluginLoaded( 136 "PluginVcsMercurial"): 137 Preferences.Prefs.settings.remove("Mercurial") 138 139 140def clearPrivateData(): 141 """ 142 Module function to clear the private data of the plug-in. 143 """ 144 for key in ["RepositoryUrlHistory"]: 145 VcsMercurialPlugin.setPreferences(key, []) 146 147 148class VcsMercurialPlugin(QObject): 149 """ 150 Class implementing the Mercurial version control plugin. 151 """ 152 MercurialDefaults = { 153 "StopLogOnCopy": True, # used in log browser 154 "LogLimit": 20, 155 "CommitMessages": 20, 156 "Commits": [], 157 "CommitAuthorsLimit": 20, 158 "CommitAuthors": [], 159 "PullUpdate": False, 160 "PreferUnbundle": False, 161 "ServerPort": 8000, 162 "ServerStyle": "", 163 "CleanupPatterns": "*.orig *.rej *~", 164 "CreateBackup": False, 165 "InternalMerge": False, 166 "Encoding": "utf-8", 167 "EncodingMode": "strict", 168 "ConsiderHidden": False, 169 "LogMessageColumnWidth": 30, 170 "LogBrowserShowFullLog": True, 171 "LogBrowserGeometry": QByteArray(), 172 "LogBrowserSplitterStates": [QByteArray(), QByteArray(), 173 QByteArray()], 174 # mainSplitter, detailsSplitter, diffSplitter 175 "StatusDialogGeometry": QByteArray(), 176 "StatusDialogSplitterState": QByteArray(), 177 "MqStatusDialogGeometry": QByteArray(), 178 "MqStatusDialogSplitterState": QByteArray(), 179 "RepositoryUrlHistory": [], 180 } 181 182 def __init__(self, ui): 183 """ 184 Constructor 185 186 @param ui reference to the user interface object (UI.UserInterface) 187 """ 188 super().__init__(ui) 189 self.__ui = ui 190 191 from VcsPlugins.vcsMercurial.ProjectHelper import HgProjectHelper 192 self.__projectHelperObject = HgProjectHelper(None, None) 193 with contextlib.suppress(KeyError): 194 e5App().registerPluginObject( 195 pluginTypename, self.__projectHelperObject, pluginType) 196 readShortcuts(pluginName=pluginTypename) 197 198 def getProjectHelper(self): 199 """ 200 Public method to get a reference to the project helper object. 201 202 @return reference to the project helper object 203 """ 204 return self.__projectHelperObject 205 206 def initToolbar(self, ui, toolbarManager): 207 """ 208 Public slot to initialize the VCS toolbar. 209 210 @param ui reference to the main window (UserInterface) 211 @param toolbarManager reference to a toolbar manager object 212 (E5ToolBarManager) 213 """ 214 if self.__projectHelperObject: 215 self.__projectHelperObject.initToolbar(ui, toolbarManager) 216 217 def activate(self): 218 """ 219 Public method to activate this plugin. 220 221 @return tuple of reference to instantiated viewmanager and 222 activation status (boolean) 223 """ 224 from VcsPlugins.vcsMercurial.hg import Hg 225 self.__object = Hg(self, self.__ui) 226 227 tb = self.__ui.getToolbar("vcs")[1] 228 tb.setVisible(False) 229 tb.setEnabled(False) 230 231 tb = self.__ui.getToolbar("mercurial")[1] 232 tb.setVisible(Preferences.getVCS("ShowVcsToolbar")) 233 tb.setEnabled(True) 234 235 return self.__object, True 236 237 def deactivate(self): 238 """ 239 Public method to deactivate this plugin. 240 """ 241 self.__object = None 242 243 tb = self.__ui.getToolbar("mercurial")[1] 244 tb.setVisible(False) 245 tb.setEnabled(False) 246 247 tb = self.__ui.getToolbar("vcs")[1] 248 tb.setVisible(Preferences.getVCS("ShowVcsToolbar")) 249 tb.setEnabled(True) 250 251 @classmethod 252 def getPreferences(cls, key): 253 """ 254 Class method to retrieve the various settings. 255 256 @param key the key of the value to get 257 @return the requested setting 258 """ 259 if key in ["StopLogOnCopy", "PullUpdate", "PreferUnbundle", 260 "CreateBackup", "InternalMerge", "ConsiderHidden", 261 "LogBrowserShowFullLog"]: 262 return Preferences.toBool(Preferences.Prefs.settings.value( 263 "Mercurial/" + key, cls.MercurialDefaults[key])) 264 elif key in ["LogLimit", "CommitMessages", "CommitAuthorsLimit", 265 "ServerPort", "LogMessageColumnWidth"]: 266 return int(Preferences.Prefs.settings.value( 267 "Mercurial/" + key, cls.MercurialDefaults[key])) 268 elif key in ["Commits", "CommitAuthors", "RepositoryUrlHistory"]: 269 return Preferences.toList(Preferences.Prefs.settings.value( 270 "Mercurial/" + key, cls.MercurialDefaults[key])) 271 elif key in ["LogBrowserGeometry", "StatusDialogGeometry", 272 "StatusDialogSplitterState", "MqStatusDialogGeometry", 273 "MqStatusDialogSplitterState"]: 274 # QByteArray values 275 v = Preferences.Prefs.settings.value("Mercurial/" + key) 276 if v is not None: 277 return v 278 else: 279 return cls.MercurialDefaults[key] 280 elif key in ["LogBrowserSplitterStates"]: 281 # list of QByteArray values 282 states = Preferences.Prefs.settings.value("Mercurial/" + key) 283 if states is not None: 284 return states 285 else: 286 return cls.MercurialDefaults[key] 287 else: 288 return Preferences.Prefs.settings.value( 289 "Mercurial/" + key, cls.MercurialDefaults[key]) 290 291 @classmethod 292 def setPreferences(cls, key, value): 293 """ 294 Class method to store the various settings. 295 296 @param key the key of the setting to be set 297 @param value the value to be set 298 """ 299 Preferences.Prefs.settings.setValue("Mercurial/" + key, value) 300 301 def getGlobalOptions(self): 302 """ 303 Public method to build a list of global options. 304 305 @return list of global options (list of string) 306 """ 307 args = [] 308 if ( 309 self.getPreferences("Encoding") != 310 self.MercurialDefaults["Encoding"] 311 ): 312 args.append("--encoding") 313 args.append(self.getPreferences("Encoding")) 314 if ( 315 self.getPreferences("EncodingMode") != 316 self.MercurialDefaults["EncodingMode"] 317 ): 318 args.append("--encodingmode") 319 args.append(self.getPreferences("EncodingMode")) 320 if self.getPreferences("ConsiderHidden"): 321 args.append("--hidden") 322 return args 323 324 def getConfigPath(self): 325 """ 326 Public method to get the filename of the config file. 327 328 @return filename of the config file (string) 329 """ 330 return getConfigPath() 331 332 def prepareUninstall(self): 333 """ 334 Public method to prepare for an uninstallation. 335 """ 336 e5App().unregisterPluginObject(pluginTypename) 337 338 def prepareUnload(self): 339 """ 340 Public method to prepare for an unload. 341 """ 342 if self.__projectHelperObject: 343 self.__projectHelperObject.removeToolbar( 344 self.__ui, e5App().getObject("ToolbarManager")) 345 e5App().unregisterPluginObject(pluginTypename) 346