530 lines
18 KiB
Python
530 lines
18 KiB
Python
#SGrepMDI is by Gordon McMillan (gmcm@hypernet.com)
|
|
#It does basically what Find In Files does in MSVC with a couple enhancements.
|
|
# - It saves any directories in the app's ini file (if you want to get rid
|
|
# of them you'll have to edit the file)
|
|
# - "Directories" can be directories,
|
|
# - semicolon separated lists of "directories",
|
|
# - environment variables that evaluate to "directories",
|
|
# - registry path names that evaluate to "directories",
|
|
# - all of which is recursive, so you can mix them all up.
|
|
# - It is MDI, so you can 'nest' greps and return to earlier ones,
|
|
# (ie, have multiple results open at the same time)
|
|
# - Like FIF, double clicking a line opens an editor and takes you to the line.
|
|
# - You can highlight text, right click and start a new grep with the selected
|
|
# text as search pattern and same directories etc as before.
|
|
# - You can save grep parameters (so you don't lose your hardearned pattern)
|
|
# from File|Save
|
|
# - You can save grep results by right clicking in the result window.
|
|
# Hats off to Mark Hammond for providing an environment where I could cobble
|
|
# something like this together in a couple evenings!
|
|
|
|
import win32ui
|
|
import win32api
|
|
from pywin.mfc import docview, dialog, window
|
|
import win32con
|
|
import string
|
|
import re
|
|
import glob
|
|
import os
|
|
import stat
|
|
import glob
|
|
from . import scriptutils
|
|
|
|
def getsubdirs(d):
|
|
dlist = []
|
|
flist = glob.glob(d+'\\*')
|
|
for f in flist:
|
|
if os.path.isdir(f):
|
|
dlist.append(f)
|
|
dlist = dlist + getsubdirs(f)
|
|
return dlist
|
|
|
|
class dirpath:
|
|
def __init__(self, str, recurse=0):
|
|
dp = str.split(';')
|
|
dirs = {}
|
|
for d in dp:
|
|
if os.path.isdir(d):
|
|
d = d.lower()
|
|
if d not in dirs:
|
|
dirs[d] = None
|
|
if recurse:
|
|
subdirs = getsubdirs(d)
|
|
for sd in subdirs:
|
|
sd = sd.lower()
|
|
if sd not in dirs:
|
|
dirs[sd] = None
|
|
elif os.path.isfile(d):
|
|
pass
|
|
else:
|
|
x = None
|
|
if d in os.environ:
|
|
x = dirpath(os.environ[d])
|
|
elif d[:5] == 'HKEY_':
|
|
keystr = d.split('\\')
|
|
try:
|
|
root = eval('win32con.'+keystr[0])
|
|
except:
|
|
win32ui.MessageBox("Can't interpret registry key name '%s'" % keystr[0])
|
|
try:
|
|
subkey = '\\'.join(keystr[1:])
|
|
val = win32api.RegQueryValue(root, subkey)
|
|
if val:
|
|
x = dirpath(val)
|
|
else:
|
|
win32ui.MessageBox("Registry path '%s' did not return a path entry" % d)
|
|
except:
|
|
win32ui.MessageBox("Can't interpret registry key value: %s" % keystr[1:])
|
|
else:
|
|
win32ui.MessageBox("Directory '%s' not found" % d)
|
|
if x:
|
|
for xd in x:
|
|
if xd not in dirs:
|
|
dirs[xd] = None
|
|
if recurse:
|
|
subdirs = getsubdirs(xd)
|
|
for sd in subdirs:
|
|
sd = sd.lower()
|
|
if sd not in dirs:
|
|
dirs[sd] = None
|
|
self.dirs = []
|
|
for d in list(dirs.keys()):
|
|
self.dirs.append(d)
|
|
|
|
def __getitem__(self, key):
|
|
return self.dirs[key]
|
|
def __len__(self):
|
|
return len(self.dirs)
|
|
def __setitem__(self, key, value):
|
|
self.dirs[key] = value
|
|
def __delitem__(self, key):
|
|
del self.dirs[key]
|
|
def __getslice__(self, lo, hi):
|
|
return self.dirs[lo:hi]
|
|
def __setslice__(self, lo, hi, seq):
|
|
self.dirs[lo:hi] = seq
|
|
def __delslice__(self, lo, hi):
|
|
del self.dirs[lo:hi]
|
|
def __add__(self, other):
|
|
if type(other) == type(self) or type(other) == type([]):
|
|
return self.dirs + other.dirs
|
|
def __radd__(self, other):
|
|
if type(other) == type(self) or type(other) == type([]):
|
|
return other.dirs + self.dirs
|
|
|
|
# Group(1) is the filename, group(2) is the lineno.
|
|
#regexGrepResult=regex.compile("^\\([a-zA-Z]:.*\\)(\\([0-9]+\\))")
|
|
|
|
regexGrep=re.compile(r"^([a-zA-Z]:[^(]*)\(([0-9]+)\)")
|
|
|
|
#these are the atom numbers defined by Windows for basic dialog controls
|
|
|
|
BUTTON = 0x80
|
|
EDIT = 0x81
|
|
STATIC = 0x82
|
|
LISTBOX = 0x83
|
|
SCROLLBAR = 0x84
|
|
COMBOBOX = 0x85
|
|
|
|
class GrepTemplate(docview.RichEditDocTemplate):
|
|
def __init__(self):
|
|
docview.RichEditDocTemplate.__init__(self, win32ui.IDR_TEXTTYPE, GrepDocument, GrepFrame, GrepView)
|
|
self.SetDocStrings("\nGrep\nGrep\nGrep params (*.grep)\n.grep\n\n\n")
|
|
win32ui.GetApp().AddDocTemplate(self)
|
|
self.docparams = None
|
|
|
|
def MatchDocType(self, fileName, fileType):
|
|
doc = self.FindOpenDocument(fileName)
|
|
if doc: return doc
|
|
ext = os.path.splitext(fileName)[1].lower()
|
|
if ext =='.grep':
|
|
return win32ui.CDocTemplate_Confidence_yesAttemptNative
|
|
return win32ui.CDocTemplate_Confidence_noAttempt
|
|
|
|
def setParams(self, params):
|
|
self.docparams = params
|
|
|
|
def readParams(self):
|
|
tmp = self.docparams
|
|
self.docparams = None
|
|
return tmp
|
|
|
|
class GrepFrame(window.MDIChildWnd):
|
|
# The template and doc params will one day be removed.
|
|
def __init__(self, wnd = None):
|
|
window.MDIChildWnd.__init__(self, wnd)
|
|
|
|
class GrepDocument(docview.RichEditDoc):
|
|
def __init__(self, template):
|
|
docview.RichEditDoc.__init__(self, template)
|
|
self.dirpattern = ''
|
|
self.filpattern = ''
|
|
self.greppattern = ''
|
|
self.casesensitive = 1
|
|
self.recurse = 1
|
|
self.verbose = 0
|
|
|
|
def OnOpenDocument(self, fnm):
|
|
#this bizarre stuff with params is so right clicking in a result window
|
|
#and starting a new grep can communicate the default parameters to the
|
|
#new grep.
|
|
try:
|
|
params = open(fnm,'r').read()
|
|
except:
|
|
params = None
|
|
self.setInitParams(params)
|
|
return self.OnNewDocument()
|
|
|
|
def OnCloseDocument(self):
|
|
try:
|
|
win32ui.GetApp().DeleteIdleHandler(self.SearchFile)
|
|
except:
|
|
pass
|
|
return self._obj_.OnCloseDocument()
|
|
|
|
def saveInitParams(self):
|
|
# Only save the flags, not the text boxes.
|
|
paramstr = "\t%s\t\t%d\t%d" % (self.filpattern, self.casesensitive, self.recurse)
|
|
win32ui.WriteProfileVal("Grep", "Params", paramstr)
|
|
|
|
def setInitParams(self, paramstr):
|
|
if paramstr is None:
|
|
paramstr = win32ui.GetProfileVal("Grep", "Params", '\t\t\t1\t0\t0')
|
|
params = paramstr.split('\t')
|
|
if len(params) < 3:
|
|
params = params + ['']*(3-len(params))
|
|
if len(params) < 6:
|
|
params = params + [0]*(6-len(params))
|
|
self.dirpattern = params[0]
|
|
self.filpattern = params[1]
|
|
self.greppattern = params[2]
|
|
self.casesensitive = int(params[3])
|
|
self.recurse = int(params[4])
|
|
self.verbose = int(params[5])
|
|
# setup some reasonable defaults.
|
|
if not self.dirpattern:
|
|
try:
|
|
editor=win32ui.GetMainFrame().MDIGetActive()[0].GetEditorView()
|
|
self.dirpattern=os.path.abspath(os.path.dirname(editor.GetDocument().GetPathName()))
|
|
except (AttributeError, win32ui.error):
|
|
self.dirpattern = os.getcwd()
|
|
if not self.filpattern:
|
|
self.filpattern = "*.py"
|
|
|
|
def OnNewDocument(self):
|
|
if self.dirpattern == '':
|
|
self.setInitParams(greptemplate.readParams())
|
|
d = GrepDialog(self.dirpattern, self.filpattern, self.greppattern, self.casesensitive, self.recurse, self.verbose)
|
|
if d.DoModal() == win32con.IDOK:
|
|
self.dirpattern = d['dirpattern']
|
|
self.filpattern = d['filpattern']
|
|
self.greppattern = d['greppattern']
|
|
self.casesensitive = d['casesensitive']
|
|
self.recurse = d['recursive']
|
|
self.verbose = d['verbose']
|
|
self.doSearch()
|
|
self.saveInitParams()
|
|
return 1
|
|
return 0 # cancelled - return zero to stop frame creation.
|
|
|
|
def doSearch(self):
|
|
self.dp = dirpath(self.dirpattern, self.recurse)
|
|
self.SetTitle("Grep for %s in %s" % (self.greppattern, self.filpattern))
|
|
#self.text = []
|
|
self.GetFirstView().Append('#Search '+self.dirpattern+'\n')
|
|
if self.verbose:
|
|
self.GetFirstView().Append('# ='+repr(self.dp.dirs)+'\n')
|
|
self.GetFirstView().Append('# Files '+self.filpattern+'\n')
|
|
self.GetFirstView().Append('# For '+self.greppattern+'\n')
|
|
self.fplist = self.filpattern.split(';')
|
|
if self.casesensitive:
|
|
self.pat = re.compile(self.greppattern)
|
|
else:
|
|
self.pat = re.compile(self.greppattern, re.IGNORECASE)
|
|
win32ui.SetStatusText("Searching. Please wait...", 0)
|
|
self.dpndx = self.fpndx = 0
|
|
self.fndx = -1
|
|
if not self.dp:
|
|
self.GetFirstView().Append("# ERROR: '%s' does not resolve to any search locations" % self.dirpattern)
|
|
self.SetModifiedFlag(0)
|
|
else:
|
|
self.flist = glob.glob(self.dp[0]+'\\'+self.fplist[0])
|
|
win32ui.GetApp().AddIdleHandler(self.SearchFile)
|
|
|
|
def SearchFile(self, handler, count):
|
|
self.fndx = self.fndx + 1
|
|
if self.fndx < len(self.flist):
|
|
f = self.flist[self.fndx]
|
|
if self.verbose:
|
|
self.GetFirstView().Append('# ..'+f+'\n')
|
|
# Directories may match the file type pattern, and files may be removed
|
|
# while grep is running
|
|
if os.path.isfile(f):
|
|
win32ui.SetStatusText("Searching "+f, 0)
|
|
lines = open(f, 'r').readlines()
|
|
for i in range(len(lines)):
|
|
line = lines[i]
|
|
if self.pat.search(line) != None:
|
|
self.GetFirstView().Append(f+'('+repr(i+1) + ') '+line)
|
|
else:
|
|
self.fndx = -1
|
|
self.fpndx = self.fpndx + 1
|
|
if self.fpndx < len(self.fplist):
|
|
self.flist = glob.glob(self.dp[self.dpndx] + '\\' + self.fplist[self.fpndx])
|
|
else:
|
|
self.fpndx = 0
|
|
self.dpndx = self.dpndx + 1
|
|
if self.dpndx < len(self.dp):
|
|
self.flist = glob.glob(self.dp[self.dpndx] + '\\' + self.fplist[self.fpndx])
|
|
else:
|
|
win32ui.SetStatusText("Search complete.", 0)
|
|
self.SetModifiedFlag(0) # default to not modified.
|
|
try:
|
|
win32ui.GetApp().DeleteIdleHandler(self.SearchFile)
|
|
except:
|
|
pass
|
|
return 0
|
|
return 1
|
|
|
|
def GetParams(self):
|
|
return self.dirpattern+'\t'+self.filpattern+'\t'+self.greppattern+'\t'+repr(self.casesensitive)+'\t'+repr(self.recurse)+'\t'+repr(self.verbose)
|
|
|
|
def OnSaveDocument(self, filename):
|
|
# print 'OnSaveDocument() filename=',filename
|
|
savefile = open(filename,"wb")
|
|
txt = self.GetParams()+'\n'
|
|
# print 'writing',txt
|
|
savefile.write(txt)
|
|
savefile.close()
|
|
self.SetModifiedFlag(0)
|
|
return 1
|
|
|
|
ID_OPEN_FILE = 0xe400
|
|
ID_GREP = 0xe401
|
|
ID_SAVERESULTS = 0x402
|
|
ID_TRYAGAIN = 0x403
|
|
|
|
class GrepView(docview.RichEditView):
|
|
def __init__(self, doc):
|
|
docview.RichEditView.__init__(self, doc)
|
|
self.SetWordWrap(win32ui.CRichEditView_WrapNone)
|
|
self.HookHandlers()
|
|
|
|
def OnInitialUpdate(self):
|
|
rc = self._obj_.OnInitialUpdate()
|
|
format = (-402653169, 0, 200, 0, 0, 0, 49, 'Courier New')
|
|
self.SetDefaultCharFormat(format)
|
|
return rc
|
|
|
|
def HookHandlers(self):
|
|
self.HookMessage(self.OnRClick, win32con.WM_RBUTTONDOWN)
|
|
self.HookCommand(self.OnCmdOpenFile, ID_OPEN_FILE)
|
|
self.HookCommand(self.OnCmdGrep, ID_GREP)
|
|
self.HookCommand(self.OnCmdSave, ID_SAVERESULTS)
|
|
self.HookCommand(self.OnTryAgain, ID_TRYAGAIN)
|
|
self.HookMessage(self.OnLDblClick,win32con.WM_LBUTTONDBLCLK)
|
|
|
|
def OnLDblClick(self,params):
|
|
line = self.GetLine()
|
|
regexGrepResult = regexGrep.match(line)
|
|
if regexGrepResult:
|
|
fname = regexGrepResult.group(1)
|
|
line = int(regexGrepResult.group(2))
|
|
scriptutils.JumpToDocument(fname, line)
|
|
return 0 # dont pass on
|
|
return 1 # pass it on by default.
|
|
|
|
def OnRClick(self, params):
|
|
menu = win32ui.CreatePopupMenu()
|
|
flags=win32con.MF_STRING|win32con.MF_ENABLED
|
|
lineno = self._obj_.LineFromChar(-1) #selection or current line
|
|
line = self._obj_.GetLine(lineno)
|
|
regexGrepResult = regexGrep.match(line)
|
|
if regexGrepResult:
|
|
self.fnm = regexGrepResult.group(1)
|
|
self.lnnum = int(regexGrepResult.group(2))
|
|
menu.AppendMenu(flags, ID_OPEN_FILE, "&Open "+self.fnm)
|
|
menu.AppendMenu(win32con.MF_SEPARATOR)
|
|
menu.AppendMenu(flags, ID_TRYAGAIN, "&Try Again")
|
|
charstart, charend = self._obj_.GetSel()
|
|
if charstart != charend:
|
|
linestart = self._obj_.LineIndex(lineno)
|
|
self.sel = line[charstart-linestart:charend-linestart]
|
|
menu.AppendMenu(flags, ID_GREP, "&Grep for "+self.sel)
|
|
menu.AppendMenu(win32con.MF_SEPARATOR)
|
|
menu.AppendMenu(flags, win32ui.ID_EDIT_CUT, 'Cu&t')
|
|
menu.AppendMenu(flags, win32ui.ID_EDIT_COPY, '&Copy')
|
|
menu.AppendMenu(flags, win32ui.ID_EDIT_PASTE, '&Paste')
|
|
menu.AppendMenu(flags, win32con.MF_SEPARATOR);
|
|
menu.AppendMenu(flags, win32ui.ID_EDIT_SELECT_ALL, '&Select all')
|
|
menu.AppendMenu(flags, win32con.MF_SEPARATOR);
|
|
menu.AppendMenu(flags, ID_SAVERESULTS, 'Sa&ve results')
|
|
menu.TrackPopupMenu(params[5])
|
|
return 0
|
|
|
|
def OnCmdOpenFile(self, cmd, code):
|
|
doc = win32ui.GetApp().OpenDocumentFile(self.fnm)
|
|
if doc:
|
|
vw = doc.GetFirstView()
|
|
#hope you have an editor that implements GotoLine()!
|
|
try:
|
|
vw.GotoLine(int(self.lnnum))
|
|
except:
|
|
pass
|
|
return 0
|
|
|
|
def OnCmdGrep(self, cmd, code):
|
|
curparamsstr = self.GetDocument().GetParams()
|
|
params = curparamsstr.split('\t')
|
|
params[2] = self.sel
|
|
greptemplate.setParams('\t'.join(params))
|
|
greptemplate.OpenDocumentFile()
|
|
return 0
|
|
|
|
def OnTryAgain(self, cmd, code):
|
|
greptemplate.setParams(self.GetDocument().GetParams())
|
|
greptemplate.OpenDocumentFile()
|
|
return 0
|
|
|
|
def OnCmdSave(self, cmd, code):
|
|
flags = win32con.OFN_OVERWRITEPROMPT
|
|
dlg = win32ui.CreateFileDialog(0, None, None, flags, "Text Files (*.txt)|*.txt||", self)
|
|
dlg.SetOFNTitle("Save Results As")
|
|
if dlg.DoModal() == win32con.IDOK:
|
|
pn = dlg.GetPathName()
|
|
self._obj_.SaveTextFile(pn)
|
|
return 0
|
|
|
|
def Append(self, strng):
|
|
numlines = self.GetLineCount()
|
|
endpos = self.LineIndex(numlines-1) + len(self.GetLine(numlines-1))
|
|
self.SetSel(endpos, endpos)
|
|
self.ReplaceSel(strng)
|
|
|
|
|
|
class GrepDialog(dialog.Dialog):
|
|
def __init__(self, dp, fp, gp, cs, r, v):
|
|
style = win32con.DS_MODALFRAME | win32con.WS_POPUP | win32con.WS_VISIBLE | win32con.WS_CAPTION | win32con.WS_SYSMENU | win32con.DS_SETFONT
|
|
CS = win32con.WS_CHILD | win32con.WS_VISIBLE
|
|
tmp = [ ["Grep", (0, 0, 210, 90), style, None, (8, "MS Sans Serif")], ]
|
|
tmp.append([STATIC, "Grep For:", -1, (7, 7, 50, 9), CS ])
|
|
tmp.append([EDIT, gp, 101, (52, 7, 144, 11), CS | win32con.WS_TABSTOP | win32con.ES_AUTOHSCROLL | win32con.WS_BORDER])
|
|
tmp.append([STATIC, "Directories:", -1, (7, 20, 50, 9), CS ])
|
|
tmp.append([EDIT, dp, 102, (52, 20, 128, 11), CS | win32con.WS_TABSTOP | win32con.ES_AUTOHSCROLL | win32con.WS_BORDER])
|
|
tmp.append([BUTTON, '...', 110, (182,20, 16, 11), CS | win32con.BS_PUSHBUTTON | win32con.WS_TABSTOP])
|
|
tmp.append([STATIC, "File types:", -1, (7, 33, 50, 9), CS ])
|
|
tmp.append([EDIT, fp, 103, (52, 33, 128, 11), CS | win32con.WS_TABSTOP | win32con.ES_AUTOHSCROLL | win32con.WS_BORDER ])
|
|
tmp.append([BUTTON, '...', 111, (182,33, 16, 11), CS | win32con.BS_PUSHBUTTON | win32con.WS_TABSTOP])
|
|
tmp.append([BUTTON,'Case sensitive', 104, (7, 45, 72, 9), CS | win32con.BS_AUTOCHECKBOX | win32con.BS_LEFTTEXT| win32con.WS_TABSTOP])
|
|
tmp.append([BUTTON,'Subdirectories', 105, (7, 56, 72, 9), CS | win32con.BS_AUTOCHECKBOX | win32con.BS_LEFTTEXT| win32con.WS_TABSTOP])
|
|
tmp.append([BUTTON,'Verbose', 106, (7, 67, 72, 9), CS | win32con.BS_AUTOCHECKBOX | win32con.BS_LEFTTEXT| win32con.WS_TABSTOP])
|
|
tmp.append([BUTTON,'OK', win32con.IDOK, (166,53, 32, 12), CS | win32con.BS_DEFPUSHBUTTON| win32con.WS_TABSTOP])
|
|
tmp.append([BUTTON,'Cancel', win32con.IDCANCEL, (166,67, 32, 12), CS | win32con.BS_PUSHBUTTON| win32con.WS_TABSTOP])
|
|
dialog.Dialog.__init__(self, tmp)
|
|
self.AddDDX(101,'greppattern')
|
|
self.AddDDX(102,'dirpattern')
|
|
self.AddDDX(103,'filpattern')
|
|
self.AddDDX(104,'casesensitive')
|
|
self.AddDDX(105,'recursive')
|
|
self.AddDDX(106,'verbose')
|
|
self._obj_.data['greppattern'] = gp
|
|
self._obj_.data['dirpattern'] = dp
|
|
self._obj_.data['filpattern'] = fp
|
|
self._obj_.data['casesensitive'] = cs
|
|
self._obj_.data['recursive'] = r
|
|
self._obj_.data['verbose'] = v
|
|
self.HookCommand(self.OnMoreDirectories, 110)
|
|
self.HookCommand(self.OnMoreFiles, 111)
|
|
|
|
def OnMoreDirectories(self, cmd, code):
|
|
self.getMore('Grep\\Directories', 'dirpattern')
|
|
|
|
def OnMoreFiles(self, cmd, code):
|
|
self.getMore('Grep\\File Types', 'filpattern')
|
|
|
|
def getMore(self, section, key):
|
|
self.UpdateData(1)
|
|
#get the items out of the ini file
|
|
ini = win32ui.GetProfileFileName()
|
|
secitems = win32api.GetProfileSection(section, ini)
|
|
items = []
|
|
for secitem in secitems:
|
|
items.append(secitem.split('=')[1])
|
|
dlg = GrepParamsDialog(items)
|
|
if dlg.DoModal() == win32con.IDOK:
|
|
itemstr = ';'.join(dlg.getItems())
|
|
self._obj_.data[key] = itemstr
|
|
#update the ini file with dlg.getNew()
|
|
i = 0
|
|
newitems = dlg.getNew()
|
|
if newitems:
|
|
items = items + newitems
|
|
for item in items:
|
|
win32api.WriteProfileVal(section, repr(i), item, ini)
|
|
i = i + 1
|
|
self.UpdateData(0)
|
|
|
|
def OnOK(self):
|
|
self.UpdateData(1)
|
|
for id, name in [(101,'greppattern'), (102,'dirpattern'), (103,'filpattern')]:
|
|
if not self[name]:
|
|
self.GetDlgItem(id).SetFocus()
|
|
win32api.MessageBeep()
|
|
win32ui.SetStatusText("Please enter a value")
|
|
return
|
|
self._obj_.OnOK()
|
|
|
|
class GrepParamsDialog(dialog.Dialog):
|
|
def __init__(self, items):
|
|
self.items = items
|
|
self.newitems = []
|
|
style = win32con.DS_MODALFRAME | win32con.WS_POPUP | win32con.WS_VISIBLE | win32con.WS_CAPTION | win32con.WS_SYSMENU | win32con.DS_SETFONT
|
|
CS = win32con.WS_CHILD | win32con.WS_VISIBLE
|
|
tmp = [ ["Grep Parameters", (0, 0, 205, 100), style, None, (8, "MS Sans Serif")], ]
|
|
tmp.append([LISTBOX, '', 107, (7, 7, 150, 72), CS | win32con.LBS_MULTIPLESEL| win32con.LBS_STANDARD | win32con.LBS_HASSTRINGS | win32con.WS_TABSTOP | win32con.LBS_NOTIFY])
|
|
tmp.append([BUTTON,'OK', win32con.IDOK, (167, 7, 32, 12), CS | win32con.BS_DEFPUSHBUTTON| win32con.WS_TABSTOP])
|
|
tmp.append([BUTTON,'Cancel', win32con.IDCANCEL, (167,23, 32, 12), CS | win32con.BS_PUSHBUTTON| win32con.WS_TABSTOP])
|
|
tmp.append([STATIC,'New:', -1, (2, 83, 15, 12), CS])
|
|
tmp.append([EDIT, '', 108, (18, 83, 139, 12), CS | win32con.WS_TABSTOP | win32con.ES_AUTOHSCROLL | win32con.WS_BORDER])
|
|
tmp.append([BUTTON,'Add', 109, (167,83, 32, 12), CS | win32con.BS_PUSHBUTTON| win32con.WS_TABSTOP])
|
|
dialog.Dialog.__init__(self, tmp)
|
|
self.HookCommand(self.OnAddItem, 109)
|
|
self.HookCommand(self.OnListDoubleClick, 107)
|
|
|
|
def OnInitDialog(self):
|
|
lb = self.GetDlgItem(107)
|
|
for item in self.items:
|
|
lb.AddString(item)
|
|
return self._obj_.OnInitDialog()
|
|
|
|
def OnAddItem(self, cmd, code):
|
|
eb = self.GetDlgItem(108)
|
|
item = eb.GetLine(0)
|
|
self.newitems.append(item)
|
|
lb = self.GetDlgItem(107)
|
|
i = lb.AddString(item)
|
|
lb.SetSel(i, 1)
|
|
return 1
|
|
|
|
def OnListDoubleClick(self, cmd, code):
|
|
if code == win32con.LBN_DBLCLK:
|
|
self.OnOK()
|
|
return 1
|
|
|
|
def OnOK(self):
|
|
lb = self.GetDlgItem(107)
|
|
self.selections = lb.GetSelTextItems()
|
|
self._obj_.OnOK()
|
|
|
|
def getItems(self):
|
|
return self.selections
|
|
|
|
def getNew(self):
|
|
return self.newitems
|
|
|
|
try:
|
|
win32ui.GetApp().RemoveDocTemplate(greptemplate)
|
|
except NameError:
|
|
pass
|
|
|
|
greptemplate = GrepTemplate()
|