eric7/VCS/ProjectBrowserHelper.py

branch
eric7
changeset 8312
800c432b34c8
parent 8218
7c09585bd960
child 8318
962bce857696
diff -r 4e8b98454baa -r 800c432b34c8 eric7/VCS/ProjectBrowserHelper.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/VCS/ProjectBrowserHelper.py	Sat May 15 18:45:04 2021 +0200
@@ -0,0 +1,416 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2005 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the base class of the VCS project browser helper.
+"""
+
+import os
+
+from PyQt5.QtCore import QObject, QCoreApplication
+from PyQt5.QtWidgets import QDialog
+
+from E5Gui.E5Application import e5App
+
+from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
+
+from Project.ProjectBrowserModel import (
+    ProjectBrowserSimpleDirectoryItem, ProjectBrowserFileItem,
+    ProjectBrowserDirectoryItem
+)
+
+import Preferences
+
+
+class VcsProjectBrowserHelper(QObject):
+    """
+    Class implementing the base class of the VCS project browser helper.
+    """
+    def __init__(self, vcsObject, browserObject, projectObject,
+                 isTranslationsBrowser, parent=None, name=None):
+        """
+        Constructor
+        
+        @param vcsObject reference to the vcs object
+        @param browserObject reference to the project browser object
+        @param projectObject reference to the project object
+        @param isTranslationsBrowser flag indicating, the helper is requested
+            for the translations browser (this needs some special treatment)
+        @param parent parent widget (QWidget)
+        @param name name of this object (string)
+        """
+        super().__init__(parent)
+        if name:
+            self.setObjectName(name)
+        
+        self.vcs = vcsObject
+        self.browser = browserObject
+        self.isTranslationsBrowser = isTranslationsBrowser
+        self.project = projectObject
+    
+    def addVCSMenus(self, mainMenu, multiMenu, backMenu, dirMenu,
+                    dirMultiMenu):
+        """
+        Public method to add the VCS entries to the various project browser
+        menus.
+        
+        @param mainMenu reference to the main menu (QPopupMenu)
+        @param multiMenu reference to the multiple selection menu (QPopupMenu)
+        @param backMenu reference to the background menu (QPopupMenu)
+        @param dirMenu reference to the directory menu (QPopupMenu)
+        @param dirMultiMenu reference to the multiple selection directory
+            menu (QPopupMenu)
+        """
+        self._addVCSMenu(mainMenu)
+        self._addVCSMenuMulti(multiMenu)
+        self._addVCSMenuBack(backMenu)
+        self._addVCSMenuDir(dirMenu)
+        self._addVCSMenuDirMulti(dirMultiMenu)
+    
+    def showContextMenu(self, menu, standardItems):
+        """
+        Public slot called before the context menu is shown.
+        
+        It enables/disables the VCS menu entries depending on the overall
+        VCS status and the file status.
+        
+        @param menu reference to the menu to be shown
+        @param standardItems array of standard items that need
+            activation/deactivation depending on the overall VCS status
+        @exception RuntimeError to indicate that this method must be
+            implemented by a subclass
+        """
+        raise RuntimeError('Not implemented')
+    
+    def showContextMenuMulti(self, menu, standardItems):
+        """
+        Public slot called before the context menu (multiple selections) is
+        shown.
+        
+        It enables/disables the VCS menu entries depending on the overall
+        VCS status and the files status.
+        
+        @param menu reference to the menu to be shown
+        @param standardItems array of standard items that need
+            activation/deactivation depending on the overall VCS status
+        @exception RuntimeError to indicate that this method must be
+            implemented by a subclass
+        """
+        raise RuntimeError('Not implemented')
+    
+    def showContextMenuDir(self, menu, standardItems):
+        """
+        Public slot called before the context menu is shown.
+        
+        It enables/disables the VCS menu entries depending on the overall
+        VCS status and the directory status.
+        
+        @param menu reference to the menu to be shown
+        @param standardItems array of standard items that
+            need activation/deactivation depending on the overall VCS status
+        @exception RuntimeError to indicate that this method must be
+            implemented by a subclass
+        """
+        raise RuntimeError('Not implemented')
+    
+    def showContextMenuDirMulti(self, menu, standardItems):
+        """
+        Public slot called before the context menu is shown.
+        
+        It enables/disables the VCS menu entries depending on the overall
+        VCS status and the directory status.
+        
+        @param menu reference to the menu to be shown
+        @param standardItems array of standard items that need
+            activation/deactivation depending on the overall VCS status
+        @exception RuntimeError to indicate that this method must be
+            implemented by a subclass
+        """
+        raise RuntimeError('Not implemented')
+
+    ###########################################################################
+    ## General menu handling methods below
+    ###########################################################################
+    
+    def _VCSUpdate(self):
+        """
+        Protected slot called by the context menu to update a file from the
+        VCS repository.
+        """
+        if self.isTranslationsBrowser:
+            names = [itm.dirName()
+                     for itm in self.browser.getSelectedItems(
+                         [ProjectBrowserSimpleDirectoryItem])]
+            if not names:
+                names = [itm.fileName()
+                         for itm in self.browser.getSelectedItems(
+                             [ProjectBrowserFileItem])]
+        else:
+            names = []
+            for itm in self.browser.getSelectedItems():
+                try:
+                    name = itm.fileName()
+                except AttributeError:
+                    name = itm.dirName()
+                names.append(name)
+        self.vcs.vcsUpdate(names)
+        
+    def _VCSCommit(self):
+        """
+        Protected slot called by the context menu to commit the changes to the
+        VCS repository.
+        """
+        if self.isTranslationsBrowser:
+            names = [itm.dirName()
+                     for itm in self.browser.getSelectedItems(
+                         [ProjectBrowserSimpleDirectoryItem])]
+            if not names:
+                names = [itm.fileName()
+                         for itm in self.browser.getSelectedItems(
+                             [ProjectBrowserFileItem])]
+        else:
+            names = []
+            for itm in self.browser.getSelectedItems():
+                try:
+                    name = itm.fileName()
+                except AttributeError:
+                    name = itm.dirName()
+                names.append(name)
+        if Preferences.getVCS("AutoSaveFiles"):
+            vm = e5App().getObject("ViewManager")
+            for name in names:
+                vm.saveEditor(name)
+        self.vcs.vcsCommit(names, '')
+        
+    def _VCSAdd(self):
+        """
+        Protected slot called by the context menu to add the selected file to
+        the VCS repository.
+        """
+        if self.isTranslationsBrowser:
+            items = self.browser.getSelectedItems(
+                [ProjectBrowserSimpleDirectoryItem])
+            if items:
+                names = [itm.dirName() for itm in items]
+                qnames = []
+            else:
+                items = self.browser.getSelectedItems([ProjectBrowserFileItem])
+                names = []
+                qnames = []
+                for itm in items:
+                    name = itm.fileName()
+                    if name.endswith('.qm'):
+                        qnames.append(name)
+                    else:
+                        names.append(name)
+        else:
+            names = []
+            for itm in self.browser.getSelectedItems():
+                try:
+                    name = itm.fileName()
+                except AttributeError:
+                    name = itm.dirName()
+                names.append(name)
+            qnames = []
+        
+        if not len(names + qnames):
+            return
+        
+        if len(names + qnames) == 1:
+            if names:
+                self.vcs.vcsAdd(names[0], os.path.isdir(names[0]))
+            else:
+                if self.vcs.canDetectBinaries:
+                    self.vcs.vcsAdd(qnames)
+                else:
+                    self.vcs.vcsAddBinary(qnames)
+        else:
+            if self.vcs.canDetectBinaries:
+                self.vcs.vcsAdd(names + qnames)
+            else:
+                self.vcs.vcsAdd(names)
+                if len(qnames):
+                    self.vcs.vcsAddBinary(qnames)
+        for fn in names + qnames:
+            self._updateVCSStatus(fn)
+        
+    def _VCSAddTree(self):
+        """
+        Protected slot called by the context menu.
+        
+        It is used to add the selected
+        directory tree to the VCS repository.
+        """
+        names = []
+        for itm in self.browser.getSelectedItems():
+            try:
+                name = itm.fileName()
+            except AttributeError:
+                name = itm.dirName()
+            names.append(name)
+        self.vcs.vcsAddTree(names)
+        for fn in names:
+            self._updateVCSStatus(fn)
+        
+    def _VCSRemove(self):
+        """
+        Protected slot called by the context menu to remove the selected file
+        from the VCS repository.
+        """
+        if self.isTranslationsBrowser:
+            items = self.browser.getSelectedItems(
+                [ProjectBrowserSimpleDirectoryItem])
+            if items:
+                return      # not supported
+            
+            isRemoveDirs = False
+            items = self.browser.getSelectedItems([ProjectBrowserFileItem])
+            names = [itm.fileName() for itm in items]
+            
+            dlg = DeleteFilesConfirmationDialog(
+                self.parent(),
+                QCoreApplication.translate(
+                    "VcsProjectBrowserHelper",
+                    "Remove from repository (and disk)"),
+                QCoreApplication.translate(
+                    "VcsProjectBrowserHelper",
+                    "Do you really want to remove these translation files from"
+                    " the repository (and disk)?"),
+                names)
+        else:
+            items = self.browser.getSelectedItems()
+            isRemoveDirs = (
+                len(items) == self.browser.getSelectedItemsCount(
+                    [ProjectBrowserSimpleDirectoryItem,
+                     ProjectBrowserDirectoryItem])
+            )
+            if isRemoveDirs:
+                names = [itm.dirName() for itm in items]
+            else:
+                names = [itm.fileName() for itm in items]
+            files = [self.browser.project.getRelativePath(name)
+                     for name in names]
+            
+            dlg = DeleteFilesConfirmationDialog(
+                self.parent(),
+                QCoreApplication.translate(
+                    "VcsProjectBrowserHelper",
+                    "Remove from repository (and disk)"),
+                QCoreApplication.translate(
+                    "VcsProjectBrowserHelper",
+                    "Do you really want to remove these files/directories"
+                    " from the repository (and disk)?"),
+                files)
+        
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            status = self.vcs.vcsRemove(names)
+            if status:
+                if isRemoveDirs:
+                    self.browser._removeDir()
+                    # remove directories from Project
+                else:
+                    self.browser._removeFile()  # remove file(s) from project
+        
+    def _VCSLog(self):
+        """
+        Protected slot called by the context menu to show the VCS log of a
+        file/directory.
+        """
+        # kept for backward compatibility for plug-ins
+        self._VCSLogBrowser()
+    
+    def _VCSLogBrowser(self):
+        """
+        Protected slot called by the context menu to show the log browser for a
+        file.
+        """
+        itm = self.browser.currentItem()
+        try:
+            fn = itm.fileName()
+            isFile = True
+        except AttributeError:
+            fn = itm.dirName()
+            isFile = False
+        self.vcs.vcsLogBrowser(fn, isFile=isFile)
+        
+    def _VCSDiff(self):
+        """
+        Protected slot called by the context menu to show the difference of a
+        file/directory to the repository.
+        """
+        names = []
+        for itm in self.browser.getSelectedItems():
+            try:
+                name = itm.fileName()
+            except AttributeError:
+                name = itm.dirName()
+            names.append(name)
+        self.vcs.vcsDiff(names)
+        
+    def _VCSStatus(self):
+        """
+        Protected slot called by the context menu to show the status of a file.
+        """
+        if self.isTranslationsBrowser:
+            items = self.browser.getSelectedItems(
+                [ProjectBrowserSimpleDirectoryItem])
+            if items:
+                names = [itm.dirName() for itm in items]
+            else:
+                items = self.browser.getSelectedItems([ProjectBrowserFileItem])
+                names = [itm.fileName() for itm in items]
+        else:
+            names = []
+            for itm in self.browser.getSelectedItems():
+                try:
+                    name = itm.fileName()
+                except AttributeError:
+                    name = itm.dirName()
+                names.append(name)
+        self.vcs.vcsStatus(names)
+
+    def _VCSRevert(self):
+        """
+        Protected slot called by the context menu to revert changes made to a
+        file.
+        """
+        names = []
+        for itm in self.browser.getSelectedItems():
+            try:
+                name = itm.fileName()
+            except AttributeError:
+                name = itm.dirName()
+            names.append(name)
+        self.vcs.vcsRevert(names)
+
+    def _VCSMerge(self):
+        """
+        Protected slot called by the context menu to merge changes into to a
+        file.
+        """
+        itm = self.browser.currentItem()
+        try:
+            name = itm.fileName()
+        except AttributeError:
+            name = itm.dirName()
+        self.vcs.vcsMerge(name)
+    
+    def _VCSInfoDisplay(self):
+        """
+        Protected slot called to show some vcs information.
+        """
+        from .RepositoryInfoDialog import VcsRepositoryInfoDialog
+        info = self.vcs.vcsRepositoryInfos(self.project.ppath)
+        dlg = VcsRepositoryInfoDialog(None, info)
+        dlg.exec()
+
+    def _updateVCSStatus(self, name):
+        """
+        Protected method to update the VCS status of an item.
+        
+        @param name filename or directoryname of the item to be updated
+            (string)
+        """
+        self.project.getModel().updateVCSStatus(name)

eric ide

mercurial