Add some nice colors to the patch viewer
[hgct.git] / citool.py
blob94b1deb95b5172da2d6069f4bc538a6eb10eb5a4
1 #!/usr/bin/env python
3 import sys, math, random, qt, os, re
5 qconnect = qt.QObject.connect
7 #class MyListBoxItem(qt.QListBoxItem):
8 # def __init__(self, listbox = None):
9 # qt.QListBoxItem.__init__(self, listbox)
10 # self.setSelectable(false)
12 # def paint(p):
14 class MainWidget(qt.QMainWindow):
15 def __init__(self, parent=None, name=None):
16 qt.QMainWindow.__init__(self, parent, name)
17 l = qt.QVBox(self)
19 fW = qt.QListBox(l)
20 fW.setFocus()
21 fW.setSelectionMode(qt.QListBox.Multi)
23 text = qt.QTextEdit(l)
24 text.setTextFormat(qt.QTextEdit.PlainText)
26 self.setCentralWidget(l)
27 self.setCaption('Main Window')
29 self.newSelLambda = lambda i: self.newSelection(i)
30 qconnect(fW, qt.SIGNAL("highlighted(int)"), self.newSelLambda)
32 ops = qt.QPopupMenu(self)
33 ops.insertItem("Commit", self.commit)
34 ops.insertItem("Refresh", self.refreshFiles)
36 m = self.menuBar()
37 m.insertItem("&Operations", ops)
39 self.diffNew = qt.QColor(0, 150, 0)
40 self.diffRemove = qt.QColor(200, 0, 0)
41 self.diffHead = qt.QColor(200, 0, 200)
42 self.diffStd = qt.QColor(0, 0, 0)
44 self.filesW = fW
45 self.layout = l
46 self.text = text
48 def newSelection(self, index):
49 if self.prevCur == 0:
50 self.files[0].patch = self.text.text()
52 if index == 0:
53 self.text.setText(self.files[index].patch)
54 else:
55 self.setColorPatch(self.files[index].patch)
57 self.prevCur = index
59 def setColorPatch(self, patch):
60 t = self.text
61 t.setText('')
62 for l in patch.split('\n'):
63 if len(l) > 0:
64 c = l[0]
65 else:
66 c = ''
68 if c == '+': t.setColor(self.diffNew)
69 elif c == '-': t.setColor(self.diffRemove)
70 elif c == '@': t.setColor(self.diffHead)
71 else: t.setColor(self.diffStd)
72 t.append(l + '\n')
74 def commit(self, id):
75 if self.prevCur == 0:
76 self.files[0].patch = self.text.text()
78 selFiles = [x for x in range(1, len(self.files)) if self.filesW.isSelected(x)]
79 print "selFiles: " + str(selFiles) + "\n"
80 fileStr = ' '.join([self.files[x].name for x in selFiles])
81 print "Files: " + fileStr + "\n"
82 commitMsg = str(self.files[0].patch)
83 print "Message: " + commitMsg + "\n"
84 fout = os.popen('citool-commit ' + fileStr, 'w')
85 fout.write(commitMsg)
86 fout.close()
87 print "Commit!\n"
89 def setFiles(self, files):
90 self.filesW.clear()
91 f = File()
92 f.name = "Commit message"
93 f.patch = ""
94 self.files = [f]
95 for x in files:
96 self.files.append(x)
97 self.filesW.insertStrList([x.name for x in self.files])
98 self.prevCur = 0
99 self.filesW.setCurrentItem(0)
100 self.filesW.item(0).setSelectable(False)
102 def refreshFiles(self, ignored=None):
103 files = getFiles()
104 self.setFiles(files)
106 class File:
107 pass
109 def getFiles():
110 fin = os.popen('git-diff-cache -M --cached HEAD', 'r')
111 r = re.compile(':([0-9]+) ([0-9]+) ([0-9a-f]{40}) ([0-9a-f]{40}) ([MCRNDUT][0-9]*)\t([^\t]+)(?:\t([^\t]+))?\n')
113 ret = []
114 for l in fin:
115 m = r.match(l)
116 if not m:
117 print "Unknown output from git-diff-cache!: " + l + "\n"
118 continue
120 f = File()
121 f.name = m.group(6)
122 f.change = m.group(5)
123 if f.change[0] == 'C' or f.change[0] == 'R':
124 f.oldName = m.group(6)
125 f.newName = m.group(7)
126 f.name = "Rename from " + f.oldName + " to " + f.newName
127 f.patch = getPatch(f.name, f.newName)
128 else:
129 f.patch = getPatch(f.name)
130 ret.append(f)
131 fin.close()
132 return ret
134 def getPatch(file, otherFile = None):
135 # FIXME Use the popen2 module instead
136 if otherFile:
137 f = file + ' ' + otherFile
138 else:
139 f = file
140 fin = os.popen('git-diff-cache -p -M --cached HEAD ' + f, 'r')
141 ret = fin.read()
142 fin.close()
143 return ret
146 app = qt.QApplication(sys.argv)
147 mw = MainWidget()
148 app.setMainWidget(mw)
150 mw.refreshFiles()
151 mw.setGeometry(100, 100, 500, 600)
152 mw.show()
153 sys.exit(app.exec_loop())