Edit File by line
/home/barbar84/public_h.../wp-conte.../plugins/sujqvwi/ShExBy/shex_roo.../lib64/python2..../idlelib
File: UndoDelegator.py
import string
[0] Fix | Delete
from Tkinter import *
[1] Fix | Delete
[2] Fix | Delete
from idlelib.Delegator import Delegator
[3] Fix | Delete
[4] Fix | Delete
#$ event <<redo>>
[5] Fix | Delete
#$ win <Control-y>
[6] Fix | Delete
#$ unix <Alt-z>
[7] Fix | Delete
[8] Fix | Delete
#$ event <<undo>>
[9] Fix | Delete
#$ win <Control-z>
[10] Fix | Delete
#$ unix <Control-z>
[11] Fix | Delete
[12] Fix | Delete
#$ event <<dump-undo-state>>
[13] Fix | Delete
#$ win <Control-backslash>
[14] Fix | Delete
#$ unix <Control-backslash>
[15] Fix | Delete
[16] Fix | Delete
[17] Fix | Delete
class UndoDelegator(Delegator):
[18] Fix | Delete
[19] Fix | Delete
max_undo = 1000
[20] Fix | Delete
[21] Fix | Delete
def __init__(self):
[22] Fix | Delete
Delegator.__init__(self)
[23] Fix | Delete
self.reset_undo()
[24] Fix | Delete
[25] Fix | Delete
def setdelegate(self, delegate):
[26] Fix | Delete
if self.delegate is not None:
[27] Fix | Delete
self.unbind("<<undo>>")
[28] Fix | Delete
self.unbind("<<redo>>")
[29] Fix | Delete
self.unbind("<<dump-undo-state>>")
[30] Fix | Delete
Delegator.setdelegate(self, delegate)
[31] Fix | Delete
if delegate is not None:
[32] Fix | Delete
self.bind("<<undo>>", self.undo_event)
[33] Fix | Delete
self.bind("<<redo>>", self.redo_event)
[34] Fix | Delete
self.bind("<<dump-undo-state>>", self.dump_event)
[35] Fix | Delete
[36] Fix | Delete
def dump_event(self, event):
[37] Fix | Delete
from pprint import pprint
[38] Fix | Delete
pprint(self.undolist[:self.pointer])
[39] Fix | Delete
print "pointer:", self.pointer,
[40] Fix | Delete
print "saved:", self.saved,
[41] Fix | Delete
print "can_merge:", self.can_merge,
[42] Fix | Delete
print "get_saved():", self.get_saved()
[43] Fix | Delete
pprint(self.undolist[self.pointer:])
[44] Fix | Delete
return "break"
[45] Fix | Delete
[46] Fix | Delete
def reset_undo(self):
[47] Fix | Delete
self.was_saved = -1
[48] Fix | Delete
self.pointer = 0
[49] Fix | Delete
self.undolist = []
[50] Fix | Delete
self.undoblock = 0 # or a CommandSequence instance
[51] Fix | Delete
self.set_saved(1)
[52] Fix | Delete
[53] Fix | Delete
def set_saved(self, flag):
[54] Fix | Delete
if flag:
[55] Fix | Delete
self.saved = self.pointer
[56] Fix | Delete
else:
[57] Fix | Delete
self.saved = -1
[58] Fix | Delete
self.can_merge = False
[59] Fix | Delete
self.check_saved()
[60] Fix | Delete
[61] Fix | Delete
def get_saved(self):
[62] Fix | Delete
return self.saved == self.pointer
[63] Fix | Delete
[64] Fix | Delete
saved_change_hook = None
[65] Fix | Delete
[66] Fix | Delete
def set_saved_change_hook(self, hook):
[67] Fix | Delete
self.saved_change_hook = hook
[68] Fix | Delete
[69] Fix | Delete
was_saved = -1
[70] Fix | Delete
[71] Fix | Delete
def check_saved(self):
[72] Fix | Delete
is_saved = self.get_saved()
[73] Fix | Delete
if is_saved != self.was_saved:
[74] Fix | Delete
self.was_saved = is_saved
[75] Fix | Delete
if self.saved_change_hook:
[76] Fix | Delete
self.saved_change_hook()
[77] Fix | Delete
[78] Fix | Delete
def insert(self, index, chars, tags=None):
[79] Fix | Delete
self.addcmd(InsertCommand(index, chars, tags))
[80] Fix | Delete
[81] Fix | Delete
def delete(self, index1, index2=None):
[82] Fix | Delete
self.addcmd(DeleteCommand(index1, index2))
[83] Fix | Delete
[84] Fix | Delete
# Clients should call undo_block_start() and undo_block_stop()
[85] Fix | Delete
# around a sequence of editing cmds to be treated as a unit by
[86] Fix | Delete
# undo & redo. Nested matching calls are OK, and the inner calls
[87] Fix | Delete
# then act like nops. OK too if no editing cmds, or only one
[88] Fix | Delete
# editing cmd, is issued in between: if no cmds, the whole
[89] Fix | Delete
# sequence has no effect; and if only one cmd, that cmd is entered
[90] Fix | Delete
# directly into the undo list, as if undo_block_xxx hadn't been
[91] Fix | Delete
# called. The intent of all that is to make this scheme easy
[92] Fix | Delete
# to use: all the client has to worry about is making sure each
[93] Fix | Delete
# _start() call is matched by a _stop() call.
[94] Fix | Delete
[95] Fix | Delete
def undo_block_start(self):
[96] Fix | Delete
if self.undoblock == 0:
[97] Fix | Delete
self.undoblock = CommandSequence()
[98] Fix | Delete
self.undoblock.bump_depth()
[99] Fix | Delete
[100] Fix | Delete
def undo_block_stop(self):
[101] Fix | Delete
if self.undoblock.bump_depth(-1) == 0:
[102] Fix | Delete
cmd = self.undoblock
[103] Fix | Delete
self.undoblock = 0
[104] Fix | Delete
if len(cmd) > 0:
[105] Fix | Delete
if len(cmd) == 1:
[106] Fix | Delete
# no need to wrap a single cmd
[107] Fix | Delete
cmd = cmd.getcmd(0)
[108] Fix | Delete
# this blk of cmds, or single cmd, has already
[109] Fix | Delete
# been done, so don't execute it again
[110] Fix | Delete
self.addcmd(cmd, 0)
[111] Fix | Delete
[112] Fix | Delete
def addcmd(self, cmd, execute=True):
[113] Fix | Delete
if execute:
[114] Fix | Delete
cmd.do(self.delegate)
[115] Fix | Delete
if self.undoblock != 0:
[116] Fix | Delete
self.undoblock.append(cmd)
[117] Fix | Delete
return
[118] Fix | Delete
if self.can_merge and self.pointer > 0:
[119] Fix | Delete
lastcmd = self.undolist[self.pointer-1]
[120] Fix | Delete
if lastcmd.merge(cmd):
[121] Fix | Delete
return
[122] Fix | Delete
self.undolist[self.pointer:] = [cmd]
[123] Fix | Delete
if self.saved > self.pointer:
[124] Fix | Delete
self.saved = -1
[125] Fix | Delete
self.pointer = self.pointer + 1
[126] Fix | Delete
if len(self.undolist) > self.max_undo:
[127] Fix | Delete
##print "truncating undo list"
[128] Fix | Delete
del self.undolist[0]
[129] Fix | Delete
self.pointer = self.pointer - 1
[130] Fix | Delete
if self.saved >= 0:
[131] Fix | Delete
self.saved = self.saved - 1
[132] Fix | Delete
self.can_merge = True
[133] Fix | Delete
self.check_saved()
[134] Fix | Delete
[135] Fix | Delete
def undo_event(self, event):
[136] Fix | Delete
if self.pointer == 0:
[137] Fix | Delete
self.bell()
[138] Fix | Delete
return "break"
[139] Fix | Delete
cmd = self.undolist[self.pointer - 1]
[140] Fix | Delete
cmd.undo(self.delegate)
[141] Fix | Delete
self.pointer = self.pointer - 1
[142] Fix | Delete
self.can_merge = False
[143] Fix | Delete
self.check_saved()
[144] Fix | Delete
return "break"
[145] Fix | Delete
[146] Fix | Delete
def redo_event(self, event):
[147] Fix | Delete
if self.pointer >= len(self.undolist):
[148] Fix | Delete
self.bell()
[149] Fix | Delete
return "break"
[150] Fix | Delete
cmd = self.undolist[self.pointer]
[151] Fix | Delete
cmd.redo(self.delegate)
[152] Fix | Delete
self.pointer = self.pointer + 1
[153] Fix | Delete
self.can_merge = False
[154] Fix | Delete
self.check_saved()
[155] Fix | Delete
return "break"
[156] Fix | Delete
[157] Fix | Delete
[158] Fix | Delete
class Command:
[159] Fix | Delete
[160] Fix | Delete
# Base class for Undoable commands
[161] Fix | Delete
[162] Fix | Delete
tags = None
[163] Fix | Delete
[164] Fix | Delete
def __init__(self, index1, index2, chars, tags=None):
[165] Fix | Delete
self.marks_before = {}
[166] Fix | Delete
self.marks_after = {}
[167] Fix | Delete
self.index1 = index1
[168] Fix | Delete
self.index2 = index2
[169] Fix | Delete
self.chars = chars
[170] Fix | Delete
if tags:
[171] Fix | Delete
self.tags = tags
[172] Fix | Delete
[173] Fix | Delete
def __repr__(self):
[174] Fix | Delete
s = self.__class__.__name__
[175] Fix | Delete
t = (self.index1, self.index2, self.chars, self.tags)
[176] Fix | Delete
if self.tags is None:
[177] Fix | Delete
t = t[:-1]
[178] Fix | Delete
return s + repr(t)
[179] Fix | Delete
[180] Fix | Delete
def do(self, text):
[181] Fix | Delete
pass
[182] Fix | Delete
[183] Fix | Delete
def redo(self, text):
[184] Fix | Delete
pass
[185] Fix | Delete
[186] Fix | Delete
def undo(self, text):
[187] Fix | Delete
pass
[188] Fix | Delete
[189] Fix | Delete
def merge(self, cmd):
[190] Fix | Delete
return 0
[191] Fix | Delete
[192] Fix | Delete
def save_marks(self, text):
[193] Fix | Delete
marks = {}
[194] Fix | Delete
for name in text.mark_names():
[195] Fix | Delete
if name != "insert" and name != "current":
[196] Fix | Delete
marks[name] = text.index(name)
[197] Fix | Delete
return marks
[198] Fix | Delete
[199] Fix | Delete
def set_marks(self, text, marks):
[200] Fix | Delete
for name, index in marks.items():
[201] Fix | Delete
text.mark_set(name, index)
[202] Fix | Delete
[203] Fix | Delete
[204] Fix | Delete
class InsertCommand(Command):
[205] Fix | Delete
[206] Fix | Delete
# Undoable insert command
[207] Fix | Delete
[208] Fix | Delete
def __init__(self, index1, chars, tags=None):
[209] Fix | Delete
Command.__init__(self, index1, None, chars, tags)
[210] Fix | Delete
[211] Fix | Delete
def do(self, text):
[212] Fix | Delete
self.marks_before = self.save_marks(text)
[213] Fix | Delete
self.index1 = text.index(self.index1)
[214] Fix | Delete
if text.compare(self.index1, ">", "end-1c"):
[215] Fix | Delete
# Insert before the final newline
[216] Fix | Delete
self.index1 = text.index("end-1c")
[217] Fix | Delete
text.insert(self.index1, self.chars, self.tags)
[218] Fix | Delete
self.index2 = text.index("%s+%dc" % (self.index1, len(self.chars)))
[219] Fix | Delete
self.marks_after = self.save_marks(text)
[220] Fix | Delete
##sys.__stderr__.write("do: %s\n" % self)
[221] Fix | Delete
[222] Fix | Delete
def redo(self, text):
[223] Fix | Delete
text.mark_set('insert', self.index1)
[224] Fix | Delete
text.insert(self.index1, self.chars, self.tags)
[225] Fix | Delete
self.set_marks(text, self.marks_after)
[226] Fix | Delete
text.see('insert')
[227] Fix | Delete
##sys.__stderr__.write("redo: %s\n" % self)
[228] Fix | Delete
[229] Fix | Delete
def undo(self, text):
[230] Fix | Delete
text.mark_set('insert', self.index1)
[231] Fix | Delete
text.delete(self.index1, self.index2)
[232] Fix | Delete
self.set_marks(text, self.marks_before)
[233] Fix | Delete
text.see('insert')
[234] Fix | Delete
##sys.__stderr__.write("undo: %s\n" % self)
[235] Fix | Delete
[236] Fix | Delete
def merge(self, cmd):
[237] Fix | Delete
if self.__class__ is not cmd.__class__:
[238] Fix | Delete
return False
[239] Fix | Delete
if self.index2 != cmd.index1:
[240] Fix | Delete
return False
[241] Fix | Delete
if self.tags != cmd.tags:
[242] Fix | Delete
return False
[243] Fix | Delete
if len(cmd.chars) != 1:
[244] Fix | Delete
return False
[245] Fix | Delete
if self.chars and \
[246] Fix | Delete
self.classify(self.chars[-1]) != self.classify(cmd.chars):
[247] Fix | Delete
return False
[248] Fix | Delete
self.index2 = cmd.index2
[249] Fix | Delete
self.chars = self.chars + cmd.chars
[250] Fix | Delete
return True
[251] Fix | Delete
[252] Fix | Delete
alphanumeric = string.ascii_letters + string.digits + "_"
[253] Fix | Delete
[254] Fix | Delete
def classify(self, c):
[255] Fix | Delete
if c in self.alphanumeric:
[256] Fix | Delete
return "alphanumeric"
[257] Fix | Delete
if c == "\n":
[258] Fix | Delete
return "newline"
[259] Fix | Delete
return "punctuation"
[260] Fix | Delete
[261] Fix | Delete
[262] Fix | Delete
class DeleteCommand(Command):
[263] Fix | Delete
[264] Fix | Delete
# Undoable delete command
[265] Fix | Delete
[266] Fix | Delete
def __init__(self, index1, index2=None):
[267] Fix | Delete
Command.__init__(self, index1, index2, None, None)
[268] Fix | Delete
[269] Fix | Delete
def do(self, text):
[270] Fix | Delete
self.marks_before = self.save_marks(text)
[271] Fix | Delete
self.index1 = text.index(self.index1)
[272] Fix | Delete
if self.index2:
[273] Fix | Delete
self.index2 = text.index(self.index2)
[274] Fix | Delete
else:
[275] Fix | Delete
self.index2 = text.index(self.index1 + " +1c")
[276] Fix | Delete
if text.compare(self.index2, ">", "end-1c"):
[277] Fix | Delete
# Don't delete the final newline
[278] Fix | Delete
self.index2 = text.index("end-1c")
[279] Fix | Delete
self.chars = text.get(self.index1, self.index2)
[280] Fix | Delete
text.delete(self.index1, self.index2)
[281] Fix | Delete
self.marks_after = self.save_marks(text)
[282] Fix | Delete
##sys.__stderr__.write("do: %s\n" % self)
[283] Fix | Delete
[284] Fix | Delete
def redo(self, text):
[285] Fix | Delete
text.mark_set('insert', self.index1)
[286] Fix | Delete
text.delete(self.index1, self.index2)
[287] Fix | Delete
self.set_marks(text, self.marks_after)
[288] Fix | Delete
text.see('insert')
[289] Fix | Delete
##sys.__stderr__.write("redo: %s\n" % self)
[290] Fix | Delete
[291] Fix | Delete
def undo(self, text):
[292] Fix | Delete
text.mark_set('insert', self.index1)
[293] Fix | Delete
text.insert(self.index1, self.chars)
[294] Fix | Delete
self.set_marks(text, self.marks_before)
[295] Fix | Delete
text.see('insert')
[296] Fix | Delete
##sys.__stderr__.write("undo: %s\n" % self)
[297] Fix | Delete
[298] Fix | Delete
class CommandSequence(Command):
[299] Fix | Delete
[300] Fix | Delete
# Wrapper for a sequence of undoable cmds to be undone/redone
[301] Fix | Delete
# as a unit
[302] Fix | Delete
[303] Fix | Delete
def __init__(self):
[304] Fix | Delete
self.cmds = []
[305] Fix | Delete
self.depth = 0
[306] Fix | Delete
[307] Fix | Delete
def __repr__(self):
[308] Fix | Delete
s = self.__class__.__name__
[309] Fix | Delete
strs = []
[310] Fix | Delete
for cmd in self.cmds:
[311] Fix | Delete
strs.append(" %r" % (cmd,))
[312] Fix | Delete
return s + "(\n" + ",\n".join(strs) + "\n)"
[313] Fix | Delete
[314] Fix | Delete
def __len__(self):
[315] Fix | Delete
return len(self.cmds)
[316] Fix | Delete
[317] Fix | Delete
def append(self, cmd):
[318] Fix | Delete
self.cmds.append(cmd)
[319] Fix | Delete
[320] Fix | Delete
def getcmd(self, i):
[321] Fix | Delete
return self.cmds[i]
[322] Fix | Delete
[323] Fix | Delete
def redo(self, text):
[324] Fix | Delete
for cmd in self.cmds:
[325] Fix | Delete
cmd.redo(text)
[326] Fix | Delete
[327] Fix | Delete
def undo(self, text):
[328] Fix | Delete
cmds = self.cmds[:]
[329] Fix | Delete
cmds.reverse()
[330] Fix | Delete
for cmd in cmds:
[331] Fix | Delete
cmd.undo(text)
[332] Fix | Delete
[333] Fix | Delete
def bump_depth(self, incr=1):
[334] Fix | Delete
self.depth = self.depth + incr
[335] Fix | Delete
return self.depth
[336] Fix | Delete
[337] Fix | Delete
def _undo_delegator(parent):
[338] Fix | Delete
from idlelib.Percolator import Percolator
[339] Fix | Delete
root = Tk()
[340] Fix | Delete
root.title("Test UndoDelegator")
[341] Fix | Delete
width, height, x, y = list(map(int, re.split('[x+]', parent.geometry())))
[342] Fix | Delete
root.geometry("+%d+%d"%(x, y + 150))
[343] Fix | Delete
[344] Fix | Delete
text = Text(root)
[345] Fix | Delete
text.config(height=10)
[346] Fix | Delete
text.pack()
[347] Fix | Delete
text.focus_set()
[348] Fix | Delete
p = Percolator(text)
[349] Fix | Delete
d = UndoDelegator()
[350] Fix | Delete
p.insertfilter(d)
[351] Fix | Delete
[352] Fix | Delete
undo = Button(root, text="Undo", command=lambda:d.undo_event(None))
[353] Fix | Delete
undo.pack(side='left')
[354] Fix | Delete
redo = Button(root, text="Redo", command=lambda:d.redo_event(None))
[355] Fix | Delete
redo.pack(side='left')
[356] Fix | Delete
dump = Button(root, text="Dump", command=lambda:d.dump_event(None))
[357] Fix | Delete
dump.pack(side='left')
[358] Fix | Delete
[359] Fix | Delete
root.mainloop()
[360] Fix | Delete
[361] Fix | Delete
if __name__ == "__main__":
[362] Fix | Delete
from idlelib.idle_test.htest import run
[363] Fix | Delete
run(_undo_delegator)
[364] Fix | Delete
[365] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function