Anonymous avatar Anonymous committed 6c002c3

context: add 'native' commit support with simple dialog

Comments (0)

Files changed (2)

tortoise/commitdialog.py

+"""
+commitdialog.py - a simple commit dialog for TortoiseHg
+
+ Copyright (C) 2007 TK Soh <teekaysoh@gmail.com>
+
+This software may be used and distributed according to the terms
+of the GNU General Public License, incorporated herein by reference.
+"""
+
+import os, tempfile, re
+import win32ui
+import win32con
+from pywin.mfc import dialog
+from mercurial import hg, repo, ui, cmdutil, util
+import gpopen
+import util
+
+def get_changes_text(filenames):
+    root = util.find_root(filenames[0])
+    u = ui.ui()
+    try:
+        repo = hg.repository(u, path=root)
+    except repo.RepoError:
+        return None
+    
+    # get file status
+    try:
+        files, matchfn, anypats = cmdutil.matchpats(repo, filenames)
+        modified, added, removed, deleted, unknown, ignored, clean = [
+                n for n in repo.status(files=files, list_clean=False)]
+    except util.Abort, inst:
+        return None
+
+    if not (modified + added + removed):
+        return None
+    
+    edittext = []
+    edittext.append("")
+    edittext.append("HG: user: %s" % u.username())
+    edittext.extend(["HG: changed %s" % f for f in modified])
+    edittext.extend(["HG: removed %s" % f for f in removed])
+    edittext.extend(["HG: Added %s" % f for f in added])
+    edittext.append("")
+
+    return "\n".join(edittext)
+
+class SimpleCommitDialog(dialog.Dialog):
+    def __init__(self, defmsg="", title="Mercurial: commit"):
+        self.title = title
+        dialog.Dialog.__init__(self, win32ui.IDD_LARGE_EDIT)
+        self.AddDDX(win32ui.IDC_EDIT1, 'msg')
+        self.data['msg']=defmsg
+
+    def OnInitDialog(self):
+        self.SetWindowText(self.title)
+
+        cancel=self.GetDlgItem(win32con.IDCANCEL)
+        cancel.ShowWindow(win32con.SW_SHOW)
+        
+        okBtn = self.GetDlgItem(win32con.IDOK)
+        okBtn.SetWindowText("Commit")
+
+        self.font = win32ui.CreateFont({'name': "Courier New", 'height': 14})
+        edit = self.GetDlgItem(win32ui.IDC_EDIT1)
+        edit.SetFont(self.font)
+
+        edit.SetWindowText(self.data['msg'])
+                        
+def do_commit(files):
+    """
+    show a simple editor dialog for enter log message,
+    and commit the list of files.
+    """
+    # get the list of changes to present at the editor
+    text = get_changes_text(files)
+    if text is None:
+        return
+
+    # show commit dialog
+    text = text.replace("\n", "\r\n")
+    dlg = SimpleCommitDialog(defmsg=text)
+
+    if dlg.DoModal() == win32con.IDOK:
+        # strip log message of lines with HG: prefix
+        text = dlg['msg']
+        text = re.sub("(?m)^HG:.*\r\n", "", text)
+        lines = [line.rstrip() for line in text.rstrip().splitlines()]
+        while lines and not lines[0]:
+            del lines[0]
+        if not lines:
+            win32ui.MessageBox("Commit message is empty!", "Mercurial",
+                               win32con.MB_OK | win32con.MB_ICONERROR)
+            return False
+        
+        # save log message to a temp file        
+        text = '\n'.join(lines)
+        logfd, logpath = tempfile.mkstemp(prefix="tortoisehg_")
+        os.write(logfd, text)
+        os.close(logfd)
+
+        # commit file with log message        
+        root = util.find_root(files[0])
+        quoted_files = [util.shellquote(s) for s in files]
+        cmdline = "hg --repository %s commit --verbose --logfile %s %s" % (
+                        util.shellquote(root),
+                        util.shellquote(logpath),
+                        " ".join(quoted_files))
+        gpopen.run(cmdline, modal=True)
+        os.unlink(logpath)
+
+if __name__ == "__main__":
+    files = ["D:\\Profiles\\r28629\\My Documents\\Mercurial\\repos\\c1\\"]
+    do_commit(files)

tortoise/contextmenu.py

     # CREATE_NO_WINDOW flag to suppress the terminal window
 
     print "run_program: %s, %s" % (appName, cmdline)
-    flags = win32con.CREATE_NO_WINDOW
+    flags = win32con.CREATE_NO_WINDOW
     startupInfo = win32process.STARTUPINFO()
-    
-    handlers = win32process.CreateProcess(appName, 
-                                            cmdline,
-                                            None,
-                                            None,
-                                            1,
-                                            flags,
-                                            os.environ,
+    
+    handlers = win32process.CreateProcess(appName, 
+                                            cmdline,
+                                            None,
+                                            None,
+                                            1,
+                                            flags,
+                                            os.environ,
                                             os.getcwd(),
                                             startupInfo)
     hProcess, hThread, PId, TId = handlers
-    win32event.WaitForSingleObject(hProcess, 500)
+    win32event.WaitForSingleObject(hProcess, 500)
     exitcode = win32process.GetExitCodeProcess(hProcess)
     if exitcode < 0:
         msg = "Error when starting external command: \n%s " % cmdline
             return 0
 
         # only support Overlays In Explorer
-        print "QueryContextMenu: checking if in explorer"
+        print "QueryContextMenu: checking if in explorer"
         modname = win32api.GetModuleFileName(win32api.GetModuleHandle(None))
         print "modname = %s" % modname
         if not modname.lower().endswith("\\explorer.exe"):
                 self._handlers[id] = (help_text, command)
 
             # add Hg submenu to context menu
-            item, extras = win32gui_struct.PackMENUITEMINFO(text="TortoiseHg",
-                                                            hSubMenu=submenu)
+            item, extras = win32gui_struct.PackMENUITEMINFO(text="TortoiseHg",
+                                                            hSubMenu=submenu)
             win32gui.InsertMenuItem(hMenu, indexMenu, 1, item)
             indexMenu += 1
 
             u = ui.ui()
             root = find_root(path)
             if root:
-                try:
+                try:
                     repo = hg.repository(u, path=root)
                     return repo
                 except repo.RepoError:
 
         print "file = %s\nroot = %s" % (rpath, root)
         
-        try:
+        try:
             tree = hg.repository(u, path=root)
         except repo.RepoError:
             print "%s: can't repo" % dir
                            status))
                            
             result.append([])   # separator
-            
+
             # Mercurial standard commands
             result.append((_("Status"),
                            _("Repository status"),
             result.append((_("Diff"),
                            _("View changes"),
                            self._diff))
+            result.append((_("Commit"),
+                           _("Commit changes"),
+                           self._commit_simple))
             result.append((_("Add"),
                            _("Add files to Hg repository"),
                            self._add))
         if rv == 1:
             self._run_dialog('rollback', True)
 
+    def _commit_simple(self, parent_window):
+        import commitdialog
+        targets = self._filenames or [self._folder]
+        #quoted_files = [shellquote(s) for s in targets]
+        commitdialog.do_commit(targets)
+        
     def _run_program_with_guishell(self, hgcmd, noargs=False):
         exepath = find_path(GUI_SHELL)
         if exepath:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.