Started implementing a 'Quick Commit' function for the new VCS Status List widget. eric7

Thu, 23 Sep 2021 18:20:31 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 23 Sep 2021 18:20:31 +0200
branch
eric7
changeset 8624
5192a2592324
parent 8623
fced5aa98d41
child 8625
d52ae1294878

Started implementing a 'Quick Commit' function for the new VCS Status List widget.

eric7/Plugins/PluginVcsGit.py file | annotate | diff | comparison | revisions
eric7/Plugins/PluginVcsMercurial.py file | annotate | diff | comparison | revisions
eric7/Plugins/PluginVcsPySvn.py file | annotate | diff | comparison | revisions
eric7/Plugins/PluginVcsSubversion.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsGit/ConfigurationPage/GitPage.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsGit/ConfigurationPage/GitPage.ui file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsGit/GitCommitDialog.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsGit/git.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.ui file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsMercurial/hg.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.ui file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsPySvn/SvnCommitDialog.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsPySvn/subversion.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.ui file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsSubversion/SvnCommitDialog.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsSubversion/subversion.py file | annotate | diff | comparison | revisions
eric7/Preferences/ConfigurationPages/VcsPage.ui file | annotate | diff | comparison | revisions
eric7/Preferences/__init__.py file | annotate | diff | comparison | revisions
eric7/VCS/StatusWidget.py file | annotate | diff | comparison | revisions
eric7/VCS/VersionControl.py file | annotate | diff | comparison | revisions
--- a/eric7/Plugins/PluginVcsGit.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/PluginVcsGit.py	Thu Sep 23 18:20:31 2021 +0200
@@ -175,7 +175,6 @@
         "StatusDialogGeometry": QByteArray(),
         "StatusDialogSplitterStates": [QByteArray(), QByteArray()],
         # vertical splitter, horizontal splitter
-        "CommitMessages": 20,
         "Commits": [],
         "CommitIdLength": 10,
         "CleanupPatterns": "*.orig *.rej *~",
@@ -267,8 +266,7 @@
                    "AggressiveGC"]:
             return Preferences.toBool(Preferences.Prefs.settings.value(
                 "Git/" + key, cls.GitDefaults[key]))
-        elif key in ["LogLimit", "CommitMessages", "CommitIdLength",
-                     "LogSubjectColumnWidth"]:
+        elif key in ["LogLimit", "CommitIdLength", "LogSubjectColumnWidth"]:
             return int(Preferences.Prefs.settings.value(
                 "Git/" + key, cls.GitDefaults[key]))
         elif key in ["Commits", "RepositoryUrlHistory"]:
--- a/eric7/Plugins/PluginVcsMercurial.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/PluginVcsMercurial.py	Thu Sep 23 18:20:31 2021 +0200
@@ -152,7 +152,6 @@
     MercurialDefaults = {
         "StopLogOnCopy": True,  # used in log browser
         "LogLimit": 20,
-        "CommitMessages": 20,
         "Commits": [],
         "CommitAuthorsLimit": 20,
         "CommitAuthors": [],
@@ -261,8 +260,8 @@
                    "LogBrowserShowFullLog"]:
             return Preferences.toBool(Preferences.Prefs.settings.value(
                 "Mercurial/" + key, cls.MercurialDefaults[key]))
-        elif key in ["LogLimit", "CommitMessages", "CommitAuthorsLimit",
-                     "ServerPort", "LogMessageColumnWidth"]:
+        elif key in ["LogLimit", "CommitAuthorsLimit", "ServerPort",
+                     "LogMessageColumnWidth"]:
             return int(Preferences.Prefs.settings.value(
                 "Mercurial/" + key, cls.MercurialDefaults[key]))
         elif key in ["Commits", "CommitAuthors", "RepositoryUrlHistory"]:
--- a/eric7/Plugins/PluginVcsPySvn.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/PluginVcsPySvn.py	Thu Sep 23 18:20:31 2021 +0200
@@ -156,7 +156,6 @@
         self.__subversionDefaults = {
             "StopLogOnCopy": 1,
             "LogLimit": 20,
-            "CommitMessages": 20,
         }
         
         from VcsPlugins.vcsPySvn.ProjectHelper import PySvnProjectHelper
@@ -229,7 +228,7 @@
         if key in ["StopLogOnCopy"]:
             return Preferences.toBool(Preferences.Prefs.settings.value(
                 "Subversion/" + key, self.__subversionDefaults[key]))
-        elif key in ["LogLimit", "CommitMessages"]:
+        elif key in ["LogLimit"]:
             return int(Preferences.Prefs.settings.value(
                 "Subversion/" + key,
                 self.__subversionDefaults[key]))
--- a/eric7/Plugins/PluginVcsSubversion.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/PluginVcsSubversion.py	Thu Sep 23 18:20:31 2021 +0200
@@ -162,7 +162,6 @@
         self.__subversionDefaults = {
             "StopLogOnCopy": True,
             "LogLimit": 20,
-            "CommitMessages": 20,
         }
         
         from VcsPlugins.vcsSubversion.ProjectHelper import SvnProjectHelper
@@ -235,7 +234,7 @@
         if key in ["StopLogOnCopy"]:
             return Preferences.toBool(Preferences.Prefs.settings.value(
                 "Subversion/" + key, self.__subversionDefaults[key]))
-        elif key in ["LogLimit", "CommitMessages"]:
+        elif key in ["LogLimit"]:
             return int(Preferences.Prefs.settings.value(
                 "Subversion/" + key,
                 self.__subversionDefaults[key]))
--- a/eric7/Plugins/VcsPlugins/vcsGit/ConfigurationPage/GitPage.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsGit/ConfigurationPage/GitPage.py	Thu Sep 23 18:20:31 2021 +0200
@@ -45,8 +45,6 @@
         self.findHarderCheckBox.setChecked(
             self.__plugin.getPreferences("FindCopiesHarder"))
         # commit
-        self.commitSpinBox.setValue(
-            self.__plugin.getPreferences("CommitMessages"))
         self.commitIdSpinBox.setValue(
             self.__plugin.getPreferences("CommitIdLength"))
         # cleanup
@@ -69,9 +67,7 @@
             "FindCopiesHarder", self.findHarderCheckBox.isChecked())
         # commit
         self.__plugin.setPreferences(
-            "CommitMessages", self.commitSpinBox.value())
-        self.__plugin.setPreferences(
-            "CommitMessages", self.commitIdSpinBox.value())
+            "CommitIdLength", self.commitIdSpinBox.value())
         # cleanup
         self.__plugin.setPreferences(
             "CleanupPatterns", self.cleanupPatternEdit.text())
--- a/eric7/Plugins/VcsPlugins/vcsGit/ConfigurationPage/GitPage.ui	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsGit/ConfigurationPage/GitPage.ui	Thu Sep 23 18:20:31 2021 +0200
@@ -118,50 +118,7 @@
       <string>Commit</string>
      </property>
      <layout class="QGridLayout" name="gridLayout_2">
-      <item row="0" column="0">
-       <widget class="QLabel" name="label_2">
-        <property name="text">
-         <string>No. of commit messages to remember:</string>
-        </property>
-       </widget>
-      </item>
       <item row="0" column="1">
-       <widget class="QSpinBox" name="commitSpinBox">
-        <property name="toolTip">
-         <string>Enter the number of commit messages to remember</string>
-        </property>
-        <property name="alignment">
-         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-        </property>
-        <property name="minimum">
-         <number>1</number>
-        </property>
-        <property name="maximum">
-         <number>100</number>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="2">
-       <spacer>
-        <property name="orientation">
-         <enum>Qt::Horizontal</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>40</width>
-          <height>20</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="label_4">
-        <property name="text">
-         <string>Commit ID length:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
        <widget class="QSpinBox" name="commitIdSpinBox">
         <property name="toolTip">
          <string>Enter the number of character to show for the commit ID</string>
@@ -177,7 +134,7 @@
         </property>
        </widget>
       </item>
-      <item row="1" column="2">
+      <item row="0" column="2">
        <spacer name="horizontalSpacer">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
@@ -190,6 +147,13 @@
         </property>
        </spacer>
       </item>
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_4">
+        <property name="text">
+         <string>Commit ID length:</string>
+        </property>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>
@@ -264,7 +228,6 @@
   <tabstop>logSpinBox</tabstop>
   <tabstop>logWidthSpinBox</tabstop>
   <tabstop>findHarderCheckBox</tabstop>
-  <tabstop>commitSpinBox</tabstop>
   <tabstop>commitIdSpinBox</tabstop>
   <tabstop>cleanupPatternEdit</tabstop>
   <tabstop>aggressiveCheckBox</tabstop>
--- a/eric7/Plugins/VcsPlugins/vcsGit/GitCommitDialog.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsGit/GitCommitDialog.py	Thu Sep 23 18:20:31 2021 +0200
@@ -48,7 +48,7 @@
         
         @param evt the event (QShowEvent)
         """
-        commitMessages = self.__vcs.getPlugin().getPreferences('Commits')
+        commitMessages = self.__vcs.vcsCommitMessages()
         self.recentComboBox.clear()
         self.recentComboBox.addItem("")
         for message in commitMessages:
@@ -67,14 +67,7 @@
         """
         msg = self.logEdit.toPlainText()
         if msg:
-            commitMessages = self.__vcs.getPlugin().getPreferences('Commits')
-            if msg in commitMessages:
-                commitMessages.remove(msg)
-            commitMessages.insert(0, msg)
-            no = self.__vcs.getPlugin().getPreferences("CommitMessages")
-            del commitMessages[no:]
-            self.__vcs.getPlugin().setPreferences(
-                'Commits', commitMessages)
+            self.__vcs.vcsAddCommitMessage(msg)
         
         return msg
     
--- a/eric7/Plugins/VcsPlugins/vcsGit/git.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsGit/git.py	Thu Sep 23 18:20:31 2021 +0200
@@ -491,6 +491,44 @@
         self.committed.emit()
         self.checkVCSStatus()
     
+    def vcsCommitMessages(self):
+        """
+        Public method to get the list of saved commit messages.
+        
+        @return list of saved commit messages
+        @rtype list of str
+        """
+        # try per project commit history first
+        messages = self._vcsProjectCommitMessages()
+        if not messages:
+            # empty list returned, try the vcs specific one
+            messages = self.getPlugin().getPreferences('Commits')
+        
+        return messages
+    
+    def vcsAddCommitMessage(self, message):
+        """
+        Public method to add a commit message to the list of saved messages.
+        
+        @param message message to be added
+        @type str
+        """
+        if not self._vcsAddProjectCommitMessage(message):
+            commitMessages = self.vcsCommitMessages()
+            if message in commitMessages:
+                commitMessages.remove(message)
+            commitMessages.insert(0, message)
+            no = Preferences.getVCS("CommitMessages")
+            del commitMessages[no:]
+            self.getPlugin().setPreferences('Commits', commitMessages)
+    
+    def vcsClearCommitMessages(self):
+        """
+        Public method to clear the list of saved messages.
+        """
+        if not self._vcsClearProjectCommitMessages():
+            self.getPlugin().setPreferences('Commits', [])
+    
     def vcsUpdate(self, name, noDialog=False, revision=None):
         """
         Public method used to update a file/directory with the Git
--- a/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py	Thu Sep 23 18:20:31 2021 +0200
@@ -62,8 +62,6 @@
         self.startFullLogCheckBox.setChecked(
             self.__plugin.getPreferences("LogBrowserShowFullLog"))
         # commit
-        self.commitSpinBox.setValue(
-            self.__plugin.getPreferences("CommitMessages"))
         self.commitAuthorsSpinBox.setValue(
             self.__plugin.getPreferences("CommitAuthorsLimit"))
         # pull
@@ -101,8 +99,6 @@
             "LogBrowserShowFullLog", self.startFullLogCheckBox.isChecked())
         # commit
         self.__plugin.setPreferences(
-            "CommitMessages", self.commitSpinBox.value())
-        self.__plugin.setPreferences(
             "CommitAuthorsLimit", self.commitAuthorsSpinBox.value())
         # pull
         self.__plugin.setPreferences(
--- a/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.ui	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.ui	Thu Sep 23 18:20:31 2021 +0200
@@ -165,50 +165,7 @@
       <string>Commit</string>
      </property>
      <layout class="QGridLayout" name="gridLayout_2">
-      <item row="0" column="0">
-       <widget class="QLabel" name="label_2">
-        <property name="text">
-         <string>No. of commit messages to remember:</string>
-        </property>
-       </widget>
-      </item>
       <item row="0" column="1">
-       <widget class="QSpinBox" name="commitSpinBox">
-        <property name="toolTip">
-         <string>Enter the number of commit messages to remember</string>
-        </property>
-        <property name="alignment">
-         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-        </property>
-        <property name="minimum">
-         <number>1</number>
-        </property>
-        <property name="maximum">
-         <number>100</number>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="2">
-       <spacer>
-        <property name="orientation">
-         <enum>Qt::Horizontal</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>40</width>
-          <height>20</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="label_6">
-        <property name="text">
-         <string>No. of commit authors to remember:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
        <widget class="QSpinBox" name="commitAuthorsSpinBox">
         <property name="toolTip">
          <string>Enter the number of commit authors to remember</string>
@@ -224,7 +181,14 @@
         </property>
        </widget>
       </item>
-      <item row="1" column="2">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_6">
+        <property name="text">
+         <string>No. of commit authors to remember:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="2">
        <spacer name="spacer">
         <property name="orientation">
          <enum>Qt::Horizontal</enum>
@@ -393,7 +357,6 @@
   <tabstop>logSpinBox</tabstop>
   <tabstop>logWidthSpinBox</tabstop>
   <tabstop>startFullLogCheckBox</tabstop>
-  <tabstop>commitSpinBox</tabstop>
   <tabstop>commitAuthorsSpinBox</tabstop>
   <tabstop>pullUpdateCheckBox</tabstop>
   <tabstop>preferUnbundleCheckBox</tabstop>
--- a/eric7/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsMercurial/HgCommitDialog.py	Thu Sep 23 18:20:31 2021 +0200
@@ -52,7 +52,7 @@
         
         @param evt the event (QShowEvent)
         """
-        commitMessages = self.__vcs.getPlugin().getPreferences('Commits')
+        commitMessages = self.__vcs.vcsCommitMessages()
         self.recentComboBox.clear()
         self.recentComboBox.addItem("")
         for message in commitMessages:
@@ -118,14 +118,7 @@
         """
         msg = self.logEdit.toPlainText()
         if msg:
-            commitMessages = self.__vcs.getPlugin().getPreferences('Commits')
-            if msg in commitMessages:
-                commitMessages.remove(msg)
-            commitMessages.insert(0, msg)
-            no = self.__vcs.getPlugin().getPreferences("CommitMessages")
-            del commitMessages[no:]
-            self.__vcs.getPlugin().setPreferences(
-                'Commits', commitMessages)
+            self.__vcs.vcsAddCommitMessage(msg)
         
         author = self.authorComboBox.currentText()
         if author:
--- a/eric7/Plugins/VcsPlugins/vcsMercurial/hg.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsMercurial/hg.py	Thu Sep 23 18:20:31 2021 +0200
@@ -27,6 +27,7 @@
 from .HgDialog import HgDialog
 from .HgClient import HgClient
 
+import Preferences
 import Utilities
 
 
@@ -542,6 +543,44 @@
             self.__forgotNames = []
         self.checkVCSStatus()
     
+    def vcsCommitMessages(self):
+        """
+        Public method to get the list of saved commit messages.
+        
+        @return list of saved commit messages
+        @rtype list of str
+        """
+        # try per project commit history first
+        messages = self._vcsProjectCommitMessages()
+        if not messages:
+            # empty list returned, try the vcs specific one
+            messages = self.getPlugin().getPreferences('Commits')
+        
+        return messages
+    
+    def vcsAddCommitMessage(self, message):
+        """
+        Public method to add a commit message to the list of saved messages.
+        
+        @param message message to be added
+        @type str
+        """
+        if not self._vcsAddProjectCommitMessage(message):
+            commitMessages = self.vcsCommitMessages()
+            if message in commitMessages:
+                commitMessages.remove(message)
+            commitMessages.insert(0, message)
+            no = Preferences.getVCS("CommitMessages")
+            del commitMessages[no:]
+            self.getPlugin().setPreferences('Commits', commitMessages)
+    
+    def vcsClearCommitMessages(self):
+        """
+        Public method to clear the list of saved messages.
+        """
+        if not self._vcsClearProjectCommitMessages():
+            self.getPlugin().setPreferences('Commits', [])
+    
     def __getMostRecentCommitMessage(self):
         """
         Private method to get the most recent commit message.
--- a/eric7/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.py	Thu Sep 23 18:20:31 2021 +0200
@@ -33,16 +33,12 @@
         
         # set initial values
         self.logSpinBox.setValue(self.__plugin.getPreferences("LogLimit"))
-        self.commitSpinBox.setValue(
-            self.__plugin.getPreferences("CommitMessages"))
         
     def save(self):
         """
         Public slot to save the Subversion configuration.
         """
         self.__plugin.setPreferences("LogLimit", self.logSpinBox.value())
-        self.__plugin.setPreferences(
-            "CommitMessages", self.commitSpinBox.value())
     
     @pyqtSlot()
     def on_configButton_clicked(self):
--- a/eric7/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.ui	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsPySvn/ConfigurationPage/SubversionPage.ui	Thu Sep 23 18:20:31 2021 +0200
@@ -1,67 +1,68 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>SubversionPage</class>
- <widget class="QWidget" name="SubversionPage" >
-  <property name="geometry" >
+ <widget class="QWidget" name="SubversionPage">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>402</width>
+    <width>406</width>
     <height>354</height>
    </rect>
   </property>
-  <layout class="QVBoxLayout" >
+  <layout class="QVBoxLayout">
    <item>
-    <widget class="QLabel" name="headerLabel" >
-     <property name="text" >
-      <string>&lt;b>Configure Subversion Interface&lt;/b></string>
+    <widget class="QLabel" name="headerLabel">
+     <property name="text">
+      <string>&lt;b&gt;Configure Subversion Interface&lt;/b&gt;</string>
      </property>
     </widget>
    </item>
    <item>
-    <widget class="Line" name="line15" >
-     <property name="frameShape" >
+    <widget class="Line" name="line15">
+     <property name="frameShape">
       <enum>QFrame::HLine</enum>
      </property>
-     <property name="frameShadow" >
+     <property name="frameShadow">
       <enum>QFrame::Sunken</enum>
      </property>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
     </widget>
    </item>
    <item>
-    <widget class="QGroupBox" name="groupBox" >
-     <property name="title" >
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
       <string>Log</string>
      </property>
-     <layout class="QHBoxLayout" >
+     <layout class="QHBoxLayout">
       <item>
-       <widget class="QLabel" name="label" >
-        <property name="text" >
+       <widget class="QLabel" name="label">
+        <property name="text">
          <string>No. of log messages shown:</string>
         </property>
        </widget>
       </item>
       <item>
-       <widget class="QSpinBox" name="logSpinBox" >
-        <property name="toolTip" >
+       <widget class="QSpinBox" name="logSpinBox">
+        <property name="toolTip">
          <string>Enter the number of log messages to be shown</string>
         </property>
-        <property name="alignment" >
+        <property name="alignment">
          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
         </property>
-        <property name="maximum" >
+        <property name="maximum">
          <number>999999</number>
         </property>
        </widget>
       </item>
       <item>
        <spacer>
-        <property name="orientation" >
+        <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
-        <property name="sizeHint" stdset="0" >
+        <property name="sizeHint" stdset="0">
          <size>
           <width>41</width>
           <height>20</height>
@@ -73,76 +74,31 @@
     </widget>
    </item>
    <item>
-    <widget class="QGroupBox" name="groupBox_2" >
-     <property name="title" >
-      <string>Commit</string>
-     </property>
-     <layout class="QHBoxLayout" >
-      <item>
-       <widget class="QLabel" name="label_2" >
-        <property name="text" >
-         <string>No. of commit messages to remember:</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QSpinBox" name="commitSpinBox" >
-        <property name="toolTip" >
-         <string>Enter the number of commit messages to remember</string>
-        </property>
-        <property name="alignment" >
-         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-        </property>
-        <property name="minimum" >
-         <number>1</number>
-        </property>
-        <property name="maximum" >
-         <number>100</number>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <spacer>
-        <property name="orientation" >
-         <enum>Qt::Horizontal</enum>
-        </property>
-        <property name="sizeHint" stdset="0" >
-         <size>
-          <width>40</width>
-          <height>20</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QPushButton" name="configButton" >
-     <property name="toolTip" >
+    <widget class="QPushButton" name="configButton">
+     <property name="toolTip">
       <string>Edit the subversion config file</string>
      </property>
-     <property name="text" >
+     <property name="text">
       <string>Edit config file</string>
      </property>
     </widget>
    </item>
    <item>
-    <widget class="QPushButton" name="serversButton" >
-     <property name="toolTip" >
+    <widget class="QPushButton" name="serversButton">
+     <property name="toolTip">
       <string>Edit the subversion servers file</string>
      </property>
-     <property name="text" >
+     <property name="text">
       <string>Edit servers file</string>
      </property>
     </widget>
    </item>
    <item>
     <spacer>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeHint" stdset="0" >
+     <property name="sizeHint" stdset="0">
       <size>
        <width>388</width>
        <height>31</height>
--- a/eric7/Plugins/VcsPlugins/vcsPySvn/SvnCommitDialog.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsPySvn/SvnCommitDialog.py	Thu Sep 23 18:20:31 2021 +0200
@@ -14,8 +14,6 @@
 
 from .Ui_SvnCommitDialog import Ui_SvnCommitDialog
 
-import Preferences
-
 
 class SvnCommitDialog(QWidget, Ui_SvnCommitDialog):
     """
@@ -27,20 +25,22 @@
     accepted = pyqtSignal()
     rejected = pyqtSignal()
     
-    def __init__(self, changelists, parent=None):
+    def __init__(self, vcs, parent=None):
         """
         Constructor
         
-        @param changelists list of available change lists (list of strings)
+        @param vcs reference to the vcs object
         @param parent parent widget (QWidget)
         """
         super().__init__(parent, Qt.WindowType.Window)
         self.setupUi(self)
         
+        self.__vcs = vcs
+        
         if pysvn.svn_version < (1, 5, 0) or pysvn.version < (1, 6, 0):
             self.changeListsGroup.hide()
         else:
-            self.changeLists.addItems(sorted(changelists))
+            self.changeLists.addItems(sorted(vcs.svnGetChangelists()))
         
     def showEvent(self, evt):
         """
@@ -48,11 +48,10 @@
         
         @param evt the event (QShowEvent)
         """
-        self.recentCommitMessages = Preferences.toList(
-            Preferences.Prefs.settings.value('Subversion/Commits'))
+        commitMessages = self.__vcs.vcsCommitMessages()
         self.recentComboBox.clear()
         self.recentComboBox.addItem("")
-        self.recentComboBox.addItems(self.recentCommitMessages)
+        self.recentComboBox.addItems(commitMessages)
         
         self.logEdit.setFocus(Qt.FocusReason.OtherFocusReason)
         
@@ -67,14 +66,7 @@
         """
         msg = self.logEdit.toPlainText()
         if msg:
-            if msg in self.recentCommitMessages:
-                self.recentCommitMessages.remove(msg)
-            self.recentCommitMessages.insert(0, msg)
-            no = int(Preferences.Prefs.settings.value(
-                'Subversion/CommitMessages', 20))
-            del self.recentCommitMessages[no:]
-            Preferences.Prefs.settings.setValue(
-                'Subversion/Commits', self.recentCommitMessages)
+            self.__vcs.vcsAddCommitMessage(msg)
         return msg
         
     def hasChangelists(self):
--- a/eric7/Plugins/VcsPlugins/vcsPySvn/subversion.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsPySvn/subversion.py	Thu Sep 23 18:20:31 2021 +0200
@@ -29,6 +29,7 @@
 from .SvnDialog import SvnDialog
 from .SvnUtilities import getConfigPath, amendConfig, createDefaultConfig
 
+import Preferences
 import Utilities
 
 
@@ -481,8 +482,7 @@
             # call CommitDialog and get message from there
             if self.__commitDialog is None:
                 from .SvnCommitDialog import SvnCommitDialog
-                self.__commitDialog = SvnCommitDialog(
-                    self.svnGetChangelists(), self.__ui)
+                self.__commitDialog = SvnCommitDialog(self, self.__ui)
                 self.__commitDialog.accepted.connect(self.__vcsCommit_Step2)
             self.__commitDialog.show()
             self.__commitDialog.raise_()
@@ -606,7 +606,45 @@
         os.chdir(cwd)
         self.committed.emit()
         self.checkVCSStatus()
+    
+    def vcsCommitMessages(self):
+        """
+        Public method to get the list of saved commit messages.
         
+        @return list of saved commit messages
+        @rtype list of str
+        """
+        # try per project commit history first
+        messages = self._vcsProjectCommitMessages()
+        if not messages:
+            # empty list returned, try the vcs specific one
+            messages = self.getPlugin().getPreferences("Commits")
+        
+        return messages
+    
+    def vcsAddCommitMessage(self, message):
+        """
+        Public method to add a commit message to the list of saved messages.
+        
+        @param message message to be added
+        @type str
+        """
+        if not self._vcsAddProjectCommitMessage(message):
+            commitMessages = self.vcsCommitMessages()
+            if message in commitMessages:
+                commitMessages.remove(message)
+            commitMessages.insert(0, message)
+            no = Preferences.getVCS("CommitMessages")
+            del commitMessages[no:]
+            self.getPlugin().setPreferences("Commits", commitMessages)
+    
+    def vcsClearCommitMessages(self):
+        """
+        Public method to clear the list of saved messages.
+        """
+        if not self._vcsClearProjectCommitMessages():
+            self.getPlugin().setPreferences('Commits', [])
+    
     def vcsUpdate(self, name, noDialog=False):
         """
         Public method used to update a file/directory with the Subversion
--- a/eric7/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.py	Thu Sep 23 18:20:31 2021 +0200
@@ -33,16 +33,12 @@
         
         # set initial values
         self.logSpinBox.setValue(self.__plugin.getPreferences("LogLimit"))
-        self.commitSpinBox.setValue(
-            self.__plugin.getPreferences("CommitMessages"))
         
     def save(self):
         """
         Public slot to save the Subversion configuration.
         """
         self.__plugin.setPreferences("LogLimit", self.logSpinBox.value())
-        self.__plugin.setPreferences(
-            "CommitMessages", self.commitSpinBox.value())
     
     @pyqtSlot()
     def on_configButton_clicked(self):
--- a/eric7/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.ui	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsSubversion/ConfigurationPage/SubversionPage.ui	Thu Sep 23 18:20:31 2021 +0200
@@ -1,67 +1,68 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>SubversionPage</class>
- <widget class="QWidget" name="SubversionPage" >
-  <property name="geometry" >
+ <widget class="QWidget" name="SubversionPage">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>402</width>
+    <width>406</width>
     <height>384</height>
    </rect>
   </property>
-  <layout class="QVBoxLayout" >
+  <layout class="QVBoxLayout">
    <item>
-    <widget class="QLabel" name="headerLabel" >
-     <property name="text" >
-      <string>&lt;b>Configure Subversion Interface&lt;/b></string>
+    <widget class="QLabel" name="headerLabel">
+     <property name="text">
+      <string>&lt;b&gt;Configure Subversion Interface&lt;/b&gt;</string>
      </property>
     </widget>
    </item>
    <item>
-    <widget class="Line" name="line15" >
-     <property name="frameShape" >
+    <widget class="Line" name="line15">
+     <property name="frameShape">
       <enum>QFrame::HLine</enum>
      </property>
-     <property name="frameShadow" >
+     <property name="frameShadow">
       <enum>QFrame::Sunken</enum>
      </property>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
     </widget>
    </item>
    <item>
-    <widget class="QGroupBox" name="groupBox" >
-     <property name="title" >
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
       <string>Log</string>
      </property>
-     <layout class="QHBoxLayout" >
+     <layout class="QHBoxLayout">
       <item>
-       <widget class="QLabel" name="label" >
-        <property name="text" >
+       <widget class="QLabel" name="label">
+        <property name="text">
          <string>No. of log messages shown:</string>
         </property>
        </widget>
       </item>
       <item>
-       <widget class="QSpinBox" name="logSpinBox" >
-        <property name="toolTip" >
+       <widget class="QSpinBox" name="logSpinBox">
+        <property name="toolTip">
          <string>Enter the number of log messages to be shown</string>
         </property>
-        <property name="alignment" >
+        <property name="alignment">
          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
         </property>
-        <property name="maximum" >
+        <property name="maximum">
          <number>999999</number>
         </property>
        </widget>
       </item>
       <item>
        <spacer>
-        <property name="orientation" >
+        <property name="orientation">
          <enum>Qt::Horizontal</enum>
         </property>
-        <property name="sizeHint" stdset="0" >
+        <property name="sizeHint" stdset="0">
          <size>
           <width>41</width>
           <height>20</height>
@@ -73,76 +74,31 @@
     </widget>
    </item>
    <item>
-    <widget class="QGroupBox" name="groupBox_2" >
-     <property name="title" >
-      <string>Commit</string>
-     </property>
-     <layout class="QHBoxLayout" >
-      <item>
-       <widget class="QLabel" name="label_2" >
-        <property name="text" >
-         <string>No. of commit messages to remember:</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QSpinBox" name="commitSpinBox" >
-        <property name="toolTip" >
-         <string>Enter the number of commit messages to remember</string>
-        </property>
-        <property name="alignment" >
-         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-        </property>
-        <property name="minimum" >
-         <number>1</number>
-        </property>
-        <property name="maximum" >
-         <number>100</number>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <spacer>
-        <property name="orientation" >
-         <enum>Qt::Horizontal</enum>
-        </property>
-        <property name="sizeHint" stdset="0" >
-         <size>
-          <width>40</width>
-          <height>20</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QPushButton" name="configButton" >
-     <property name="toolTip" >
+    <widget class="QPushButton" name="configButton">
+     <property name="toolTip">
       <string>Edit the subversion config file</string>
      </property>
-     <property name="text" >
+     <property name="text">
       <string>Edit config file</string>
      </property>
     </widget>
    </item>
    <item>
-    <widget class="QPushButton" name="serversButton" >
-     <property name="toolTip" >
+    <widget class="QPushButton" name="serversButton">
+     <property name="toolTip">
       <string>Edit the subversion servers file</string>
      </property>
-     <property name="text" >
+     <property name="text">
       <string>Edit servers file</string>
      </property>
     </widget>
    </item>
    <item>
     <spacer>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeHint" stdset="0" >
+     <property name="sizeHint" stdset="0">
       <size>
        <width>388</width>
        <height>21</height>
--- a/eric7/Plugins/VcsPlugins/vcsSubversion/SvnCommitDialog.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsSubversion/SvnCommitDialog.py	Thu Sep 23 18:20:31 2021 +0200
@@ -12,8 +12,6 @@
 
 from .Ui_SvnCommitDialog import Ui_SvnCommitDialog
 
-import Preferences
-
 
 class SvnCommitDialog(QWidget, Ui_SvnCommitDialog):
     """
@@ -35,6 +33,8 @@
         super().__init__(parent, Qt.WindowType.Window)
         self.setupUi(self)
         
+        self.__vcs = vcs
+        
         if vcs.version < (1, 5, 0):
             self.changeListsGroup.hide()
         else:
@@ -46,11 +46,10 @@
         
         @param evt the event (QShowEvent)
         """
-        self.recentCommitMessages = Preferences.toList(
-            Preferences.Prefs.settings.value('Subversion/Commits'))
+        commitMessages = self.__vcs.vcsCommitMessages()
         self.recentComboBox.clear()
         self.recentComboBox.addItem("")
-        self.recentComboBox.addItems(self.recentCommitMessages)
+        self.recentComboBox.addItems(commitMessages)
         
         self.logEdit.setFocus(Qt.FocusReason.OtherFocusReason)
         
@@ -62,14 +61,7 @@
         """
         msg = self.logEdit.toPlainText()
         if msg:
-            if msg in self.recentCommitMessages:
-                self.recentCommitMessages.remove(msg)
-            self.recentCommitMessages.insert(0, msg)
-            no = int(Preferences.Prefs.settings
-                     .value('Subversion/CommitMessages', 20))
-            del self.recentCommitMessages[no:]
-            Preferences.Prefs.settings.setValue(
-                'Subversion/Commits', self.recentCommitMessages)
+            self.__vcs.vcsAddCommitMessage(msg)
         return msg
         
     def hasChangelists(self):
--- a/eric7/Plugins/VcsPlugins/vcsSubversion/subversion.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsSubversion/subversion.py	Thu Sep 23 18:20:31 2021 +0200
@@ -570,7 +570,45 @@
                 dia.exec()
         self.committed.emit()
         self.checkVCSStatus()
+    
+    def vcsCommitMessages(self):
+        """
+        Public method to get the list of saved commit messages.
         
+        @return list of saved commit messages
+        @rtype list of str
+        """
+        # try per project commit history first
+        messages = self._vcsProjectCommitMessages()
+        if not messages:
+            # empty list returned, try the vcs specific one
+            messages = self.getPlugin().getPreferences("Commits")
+        
+        return messages
+    
+    def vcsAddCommitMessage(self, message):
+        """
+        Public method to add a commit message to the list of saved messages.
+        
+        @param message message to be added
+        @type str
+        """
+        if not self._vcsAddProjectCommitMessage(message):
+            commitMessages = self.vcsCommitMessages()
+            if message in commitMessages:
+                commitMessages.remove(message)
+            commitMessages.insert(0, message)
+            no = Preferences.getVCS("CommitMessages")
+            del commitMessages[no:]
+            self.getPlugin().setPreferences("Commits", commitMessages)
+    
+    def vcsClearCommitMessages(self):
+        """
+        Public method to clear the list of saved messages.
+        """
+        if not self._vcsClearProjectCommitMessages():
+            self.getPlugin().setPreferences('Commits', [])
+    
     def vcsUpdate(self, name, noDialog=False):
         """
         Public method used to update a file/directory with the Subversion
--- a/eric7/Preferences/ConfigurationPages/VcsPage.ui	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Preferences/ConfigurationPages/VcsPage.ui	Thu Sep 23 18:20:31 2021 +0200
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>576</width>
-    <height>554</height>
+    <height>596</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_2">
@@ -43,8 +43,8 @@
      <property name="title">
       <string>Commit</string>
      </property>
-     <layout class="QVBoxLayout">
-      <item>
+     <layout class="QGridLayout" name="gridLayout_3">
+      <item row="0" column="0">
        <widget class="QCheckBox" name="vcsAutoSaveCheckBox">
         <property name="toolTip">
          <string>Select, if files should be saved before a commit</string>
@@ -54,7 +54,7 @@
         </property>
        </widget>
       </item>
-      <item>
+      <item row="0" column="1">
        <widget class="QCheckBox" name="vcsAutoSaveProjectCheckBox">
         <property name="toolTip">
          <string>Select, if project should be saved before a commit</string>
@@ -64,6 +64,56 @@
         </property>
        </widget>
       </item>
+      <item row="1" column="0" colspan="2">
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <widget class="QLabel" name="label_8">
+          <property name="text">
+           <string>No. of commit messages to remember:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="commitSpinBox">
+          <property name="toolTip">
+           <string>Enter the number of commit messages to remember</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="minimum">
+           <number>1</number>
+          </property>
+          <property name="maximum">
+           <number>100</number>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="spacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item row="2" column="0" colspan="2">
+       <widget class="QCheckBox" name="checkBox">
+        <property name="toolTip">
+         <string>Select to use one commit messages history per project</string>
+        </property>
+        <property name="text">
+         <string>Remember commit messages per project</string>
+        </property>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>
@@ -320,14 +370,18 @@
   <tabstop>vcsAutoCloseCheckBox</tabstop>
   <tabstop>vcsAutoSaveCheckBox</tabstop>
   <tabstop>vcsAutoSaveProjectCheckBox</tabstop>
+  <tabstop>commitSpinBox</tabstop>
+  <tabstop>checkBox</tabstop>
   <tabstop>vcsStatusMonitorIntervalSpinBox</tabstop>
   <tabstop>vcsMonitorLocalStatusCheckBox</tabstop>
   <tabstop>autoUpdateCheckBox</tabstop>
   <tabstop>pbVcsAddedButton</tabstop>
+  <tabstop>pbVcsConflictButton</tabstop>
   <tabstop>pbVcsModifiedButton</tabstop>
+  <tabstop>pbVcsReplacedButton</tabstop>
   <tabstop>pbVcsUpdateButton</tabstop>
-  <tabstop>pbVcsConflictButton</tabstop>
-  <tabstop>pbVcsReplacedButton</tabstop>
+  <tabstop>pbVcsRemovedButton</tabstop>
+  <tabstop>vcsToolbarCheckBox</tabstop>
  </tabstops>
  <resources/>
  <connections/>
--- a/eric7/Preferences/__init__.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/Preferences/__init__.py	Thu Sep 23 18:20:31 2021 +0200
@@ -1248,6 +1248,8 @@
         "StatusMonitorInterval": 30,
         "MonitorLocalStatus": False,
         "ShowVcsToolbar": True,
+        "PerProjectCommitHistory": True,
+        "CommitMessages": 20,
     }
     
     # defaults for tasks related stuff
@@ -3053,7 +3055,7 @@
     @param key the key of the value to get
     @return the requested user setting
     """
-    if key in ["StatusMonitorInterval"]:
+    if key in ["StatusMonitorInterval", "CommitMessages"]:
         return int(Prefs.settings.value(
             "VCS/" + key, Prefs.vcsDefaults[key]))
     else:
--- a/eric7/VCS/StatusWidget.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/VCS/StatusWidget.py	Thu Sep 23 18:20:31 2021 +0200
@@ -13,11 +13,14 @@
 from PyQt6.QtCore import pyqtSlot, Qt
 from PyQt6.QtWidgets import (
     QWidget, QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy, QListView,
-    QListWidget, QListWidgetItem, QToolButton, QAbstractItemView, QMenu
+    QListWidget, QListWidgetItem, QToolButton, QAbstractItemView, QMenu,
+    QGroupBox, QDialog
 )
 
 from EricWidgets.EricApplication import ericApp
 from EricWidgets import EricMessageBox
+from EricWidgets.EricSpellCheckedTextEdit import EricSpellCheckedTextEdit
+from EricWidgets.EricListSelectionDialog import EricListSelectionDialog
 
 import Preferences
 import UI.PixmapCache
@@ -53,7 +56,7 @@
         self.__topLayout = QHBoxLayout()
         self.__topLayout.setObjectName("topLayout")
         
-        # Create the top row
+        # Create the top area
         self.__infoLabel = QLabel(self)
         self.__infoLabel.setSizePolicy(
             QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
@@ -69,7 +72,7 @@
         self.__commitButton = QToolButton(self)
         self.__commitButton.setIcon(UI.PixmapCache.getIcon("vcsCommit"))
         self.__commitButton.setToolTip(
-            self.tr("Press to commit the marked entries"))
+            self.tr("Press to commit the marked entries with options"))
         self.__commitButton.clicked.connect(self.__commit)
         self.__topLayout.addWidget(self.__commitButton)
         
@@ -97,7 +100,9 @@
         self.__topLayout.addWidget(self.__actionsButton)
         
         self.__layout.addLayout(self.__topLayout)
+        ###################################################################
         
+        # Create the middle part
         self.__statusList = QListWidget(self)
         self.__statusList.setAlternatingRowColors(True)
         self.__statusList.setSortingEnabled(True)
@@ -106,9 +111,58 @@
         self.__statusList.setSelectionMode(
             QAbstractItemView.SelectionMode.ExtendedSelection)
         self.__statusList.itemSelectionChanged.connect(
-            self.__updateButtonStates)
+            self.__updateEnabledStates)
         self.__statusList.itemDoubleClicked.connect(self.__itemDoubleClicked)
         self.__layout.addWidget(self.__statusList)
+        ###################################################################
+        
+        # create the Quick Commit area
+        self.__quickCommitGroup = QGroupBox(self.tr("Quick Commit"), self)
+        self.__quickCommitLayout = QVBoxLayout()
+        self.__quickCommitEdit = EricSpellCheckedTextEdit(self)
+        self.__quickCommitEdit.setSizePolicy(
+            QSizePolicy.Policy.Expanding,
+            QSizePolicy.Policy.Preferred)
+        self.__quickCommitEdit.setMaximumHeight(100)
+        self.__quickCommitEdit.textChanged.connect(
+            self.__quickCommitEditTextChanged)
+        self.__quickCommitLayout.addWidget(self.__quickCommitEdit)
+        
+        self.__quickCommitLayout2 = QHBoxLayout()
+        self.__quickCommitLayout2.addStretch()
+        
+        self.__quickCommitHistoryButton = QToolButton(self)
+        self.__quickCommitHistoryButton.setIcon(
+            UI.PixmapCache.getIcon("history"))
+        self.__quickCommitHistoryButton.setToolTip(
+            self.tr("Select commit message from previous commits"))
+        self.__quickCommitHistoryButton.clicked.connect(
+            self.__selectQuickCommitMessage)
+        self.__quickCommitLayout2.addWidget(self.__quickCommitHistoryButton)
+        
+        self.__quickCommitHistoryClearButton = QToolButton(self)
+        self.__quickCommitHistoryClearButton.setIcon(
+            UI.PixmapCache.getIcon("historyClear"))
+        self.__quickCommitHistoryClearButton.setToolTip(
+            self.tr("Clear the list of saved commit messages"))
+        self.__quickCommitHistoryClearButton.clicked.connect(
+            self.__clearCommitMessages)
+        self.__quickCommitLayout2.addWidget(
+            self.__quickCommitHistoryClearButton)
+        
+        self.__quickCommitButton = QToolButton(self)
+        self.__quickCommitButton.setIcon(
+            UI.PixmapCache.getIcon("vcsCommit"))
+        self.__quickCommitButton.setToolTip(
+            self.tr("Press to commit the marked entries"))
+        self.__quickCommitButton.clicked.connect(
+            self.__quickCommit)
+        self.__quickCommitLayout2.addWidget(self.__quickCommitButton)
+        
+        self.__quickCommitLayout.addLayout(self.__quickCommitLayout2)
+        self.__quickCommitGroup.setLayout(self.__quickCommitLayout)
+        self.__layout.addWidget(self.__quickCommitGroup)
+        ###################################################################
         
         self.setLayout(self.__layout)
         
@@ -161,7 +215,7 @@
             UI.PixmapCache.getIcon("vcsCommit"),
             self.tr("Commit"), self.__commit)
         self.__commitAct.setToolTip(self.tr(
-            "Commit the selected changes"))
+            "Commit the marked entries with options"))
         self.__commitSelectAct = self.__actionsMenu.addAction(
             self.tr("Select all for commit"), self.__commitSelectAll)
         self.__commitDeselectAct = self.__actionsMenu.addAction(
@@ -275,10 +329,13 @@
         self.__commitToggleButton.setEnabled(False)
         self.__commitButton.setEnabled(False)
         self.__addButton.setEnabled(False)
+        
+        self.__quickCommitEdit.clear()
+        self.__quickCommitGroup.setEnabled(False)
     
-    def __updateButtonStates(self):
+    def __updateEnabledStates(self):
         """
-        Private method to set the button states depending on the list state.
+        Private method to set the enabled states depending on the list state.
         """
         modified = len(self.__getModifiedItems())
         unversioned = len(self.__getSelectedUnversionedItems())
@@ -287,6 +344,8 @@
         self.__commitToggleButton.setEnabled(modified)
         self.__commitButton.setEnabled(commitable)
         self.__addButton.setEnabled(unversioned)
+        
+        self.__quickCommitGroup.setEnabled(True)
     
     @pyqtSlot(dict)
     def __processStatusData(self, data):
@@ -331,7 +390,7 @@
         
         self.__statusList.sortItems(Qt.SortOrder.AscendingOrder)
         
-        self.__updateButtonStates()
+        self.__updateEnabledStates()
     
     @pyqtSlot()
     def __toggleCheckMark(self):
@@ -766,3 +825,77 @@
         vcs = self.__project.getVcs()
         vcs and vcs.vcsResolved(names)
         self.__reload()
+    
+    #######################################################################
+    ## Quick Commit handling methods
+    #######################################################################
+    
+    @pyqtSlot()
+    def __selectQuickCommitMessage(self):
+        """
+        Private slot to select a commit message from the list of
+        saved messages.
+        """
+        vcs = self.__project.getVcs()
+        if vcs:
+            commitMessages = vcs.vcsCommitMessages()
+            dlg = EricListSelectionDialog(
+                commitMessages,
+                selectionMode=QAbstractItemView.SelectionMode.SingleSelection,
+                title=self.tr("Quick Commit"),
+                message=self.tr("Select your commit message:"),
+                parent=self
+            )
+            if dlg.exec() == QDialog.DialogCode.Accepted:
+                selection = dlg.getSelection()
+                if selection:
+                    self.__quickCommitEdit.setPlainText(selection[0])
+    
+    @pyqtSlot()
+    def __clearCommitMessages(self):
+        """
+        Private slot to clear the list of saved commit messages.
+        """
+        vcs = self.__project.getVcs()
+        vcs and vcs.vcsClearCommitMessages()
+    
+    @pyqtSlot()
+    def __quickCommit(self):
+        """
+        Private slot to commit all marked entries with the entered
+        commit message.
+        """
+        projectPath = self.__project.getProjectPath()
+        names = []
+        
+        for row in range(self.__statusList.count()):
+            itm = self.__statusList.item(row)
+            if itm.checkState() == Qt.CheckState.Checked:
+                names.append(os.path.join(projectPath, itm.text()))
+        
+        if not names:
+            EricMessageBox.information(
+                self,
+                self.tr("Commit"),
+                self.tr("""There are no entries selected to be"""
+                        """ committed."""))
+            return
+        
+        if Preferences.getVCS("AutoSaveFiles"):
+            vm = ericApp().getObject("ViewManager")
+            for name in names:
+                vm.saveEditor(name)
+        
+        commitMessage = self.__quickCommitEdit.toPlainText()
+        vcs = self.__project.getVcs()
+        if vcs:
+            vcs.vcsCommit(names, commitMessage, noDialog=True)
+            vcs.vcsAddCommitMessage(commitMessage)
+    
+    @pyqtSlot()
+    def __quickCommitEditTextChanged(self):
+        """
+        Private slot to react upon changes of the quick commit text.
+        """
+        self.__quickCommitButton.setEnabled(bool(
+            self.__quickCommitEdit.toPlainText()))
--- a/eric7/VCS/VersionControl.py	Wed Sep 22 19:52:28 2021 +0200
+++ b/eric7/VCS/VersionControl.py	Thu Sep 23 18:20:31 2021 +0200
@@ -8,15 +8,18 @@
 VCS interfaces.
 """
 
+import contextlib
+import json
 import os
-import contextlib
 
 from PyQt6.QtCore import (
-    QObject, QThread, QMutex, QProcess, Qt, pyqtSignal, QCoreApplication
+    QObject, QThread, QMutex, QProcess, Qt, pyqtSignal, QCoreApplication,
+    QLockFile
 )
 from PyQt6.QtWidgets import QApplication
 
 from EricWidgets import EricMessageBox
+from EricWidgets.EricApplication import ericApp
 
 import Preferences
 
@@ -50,6 +53,9 @@
     canBeCommitted = 1  # Indicates that a file/directory is in the vcs.
     canBeAdded = 2      # Indicates that a file/directory is not in vcs.
     
+    commitHistoryLock = "commitHistory.lock"
+    commitHistoryData = "commitHistory.json"
+    
     def __init__(self, parent=None, name=None):
         """
         Constructor
@@ -200,7 +206,121 @@
         raise RuntimeError('Not implemented')
         
         return False
+    
+    def vcsCommitMessages(self):
+        """
+        Public method to get the list of saved commit messages.
         
+        @return list of saved commit messages
+        @rtype list of str
+        @exception RuntimeError to indicate that this method must be
+            implemented by a subclass
+        """
+        raise RuntimeError('Not implemented')
+        
+        return []
+    
+    def _vcsProjectCommitMessages(self):
+        """
+        Protected method to get the list of saved commit messages.
+        
+        @return list of saved commit messages
+        @rtype list of str
+        """
+        messages = []
+        if Preferences.getVCS("PerProjectCommitHistory"):
+            projectMgmtDir = (
+                ericApp().getObject("Project").getProjectManagementDir
+            )
+            with contextlib.suppress(OSError, json.JSONDecodeError):
+                with open(os.path.join(projectMgmtDir,
+                                       VersionControl.commitHistoryData),
+                          "r") as f:
+                    jsonString = f.read()
+                messages = json.loads(jsonString)
+        
+        return messages
+    
+    def vcsAddCommitMessage(self, message):
+        """
+        Public method to add a commit message to the list of saved messages.
+        
+        @param message message to be added
+        @type str
+        @exception RuntimeError to indicate that this method must be
+            implemented by a subclass
+        """
+        raise RuntimeError('Not implemented')
+    
+    def _vcsAddProjectCommitMessage(self, message):
+        """
+        Protected method to add a commit message to the list of project
+        specific saved messages.
+        
+        @param message message to be added
+        @type str
+        @return flag indicating success
+        @rtype bool
+        """
+        if Preferences.getVCS("PerProjectCommitHistory"):
+            projectMgmtDir = (
+                ericApp().getObject("Project").getProjectManagementDir
+            )
+            lockFile = QLockFile(
+                os.path.join(projectMgmtDir, VersionControl.commitHistoryLock))
+            if lockFile.lock():
+                noMessages = Preferences.getVCS("CommitMessages")
+                messages = self.vcsCommitMessages()
+                if message in messages:
+                    messages.remove(message)
+                messages.insert(0, message)
+                del messages[noMessages:]
+                
+                with contextlib.suppress(TypeError, OSError):
+                    jsonString = json.dumps(messages, indent=2)
+                    with open(os.path.join(projectMgmtDir,
+                                           VersionControl.commitHistoryData),
+                              "w") as f:
+                        f.write(jsonString)
+                lockFile.unlock()
+                return True
+        
+        return False
+    
+    def vcsClearCommitMessages(self):
+        """
+        Public method to clear the list of saved messages.
+        
+        @exception RuntimeError to indicate that this method must be
+            implemented by a subclass
+        """
+        raise RuntimeError('Not implemented')
+    
+    def _vcsClearProjectCommitMessages(self):
+        """
+        Protected method to clear the list of project specific saved messages.
+        
+        @return flag indicating success
+        @rtype bool
+        """
+        if Preferences.getVCS("PerProjectCommitHistory"):
+            projectMgmtDir = (
+                ericApp().getObject("Project").getProjectManagementDir
+            )
+            lockFile = QLockFile(
+                os.path.join(projectMgmtDir, VersionControl.commitHistoryLock))
+            if lockFile.lock():
+                with contextlib.suppress(TypeError, OSError):
+                    jsonString = json.dumps([], indent=2)
+                    with open(os.path.join(projectMgmtDir,
+                                           VersionControl.commitHistoryData),
+                              "w") as f:
+                        f.write(jsonString)
+                lockFile.unlock()
+                return True
+        
+        return False
+    
     def vcsUpdate(self, name, noDialog=False):
         """
         Public method used to update a file/directory in the vcs.

eric ide

mercurial