Coverage for C:\Repos\leo-editor\leo\commands\baseCommands.py: 91%

65 statements  

« prev     ^ index     » next       coverage.py v6.4, created at 2022-05-24 10:21 -0500

1# -*- coding: utf-8 -*- 

2#@+leo-ver=5-thin 

3#@+node:ekr.20150514035943.1: * @file ../commands/baseCommands.py 

4#@@first 

5"""The base class for all of Leo's user commands.""" 

6from leo.core import leoGlobals as g 

7#@+others 

8#@+node:ekr.20160514095639.1: ** class BaseEditCommandsClass 

9class BaseEditCommandsClass: 

10 """The base class for all edit command classes""" 

11 #@+others 

12 #@+node:ekr.20150516040334.1: *3* BaseEdit.ctor 

13 def __init__(self, c): 

14 """ 

15 Ctor for the BaseEditCommandsClass class. 

16 

17 Subclasses with ctors set self.c instead of calling this ctor. 

18 Subclasses without ctors call this ctor implicitly. 

19 """ 

20 self.c = c 

21 #@+node:ekr.20150514043714.3: *3* BaseEdit.begin/endCommand (handles undo) 

22 #@+node:ekr.20150514043714.4: *4* BaseEdit.beginCommand 

23 def beginCommand(self, w, undoType='Typing'): 

24 """Do the common processing at the start of each command.""" 

25 c, p, u = self.c, self.c.p, self.c.undoer 

26 name = c.widget_name(w) 

27 if name.startswith('body'): 

28 self.undoData = b = g.Bunch() 

29 # To keep pylint happy. 

30 b.ch = '' 

31 b.name = name 

32 b.oldSel = w.getSelectionRange() 

33 b.oldText = p.b 

34 b.w = w 

35 b.undoType = undoType 

36 b.undoer_bunch = u.beforeChangeBody(p) # #1733. 

37 else: 

38 self.undoData = None 

39 return w 

40 #@+node:ekr.20150514043714.6: *4* BaseEdit.endCommand 

41 def endCommand(self, label=None, changed=True, setLabel=True): 

42 """ 

43 Do the common processing at the end of each command. 

44 Handles undo only if we are in the body pane. 

45 """ 

46 k, p, u = self.c.k, self.c.p, self.c.undoer 

47 w = self.editWidget(event=None) 

48 bunch = self.undoData 

49 if bunch and bunch.name.startswith('body') and changed: 

50 newText = w.getAllText() 

51 if bunch.undoType.capitalize() == 'Typing': 

52 u.doTyping(p, 'Typing', 

53 oldText=bunch.oldText, 

54 newText=newText, 

55 oldSel=bunch.oldSel) 

56 else: 

57 p.v.b = newText # p.b would cause a redraw. 

58 u.afterChangeBody(p, bunch.undoType, bunch.undoer_bunch) 

59 self.undoData = None 

60 k.clearState() 

61 # Warning: basic editing commands **must not** set the label. 

62 if setLabel: 

63 if label: 

64 k.setLabelGrey(label) 

65 else: 

66 k.resetLabel() 

67 #@+node:ekr.20150514043714.7: *3* BaseEdit.editWidget 

68 def editWidget(self, event, forceFocus=True): 

69 """Return the edit widget for the event. Also sets self.w""" 

70 c = self.c 

71 w = event and event.widget 

72 # wname = c.widget_name(w) if w else '<no widget>' 

73 if w and g.isTextWrapper(w): 

74 pass 

75 else: 

76 w = c.frame.body and c.frame.body.wrapper 

77 if w and forceFocus: 

78 c.widgetWantsFocusNow(w) 

79 self.w = w 

80 return w 

81 #@+node:ekr.20150514043714.8: *3* BaseEdit.getWSString 

82 def getWSString(self, s): 

83 """Return s with all characters replaced by tab or space.""" 

84 return ''.join([ch if ch == '\t' else ' ' for ch in s]) 

85 #@+node:ekr.20150514043714.9: *3* BaseEdit.oops 

86 def oops(self): 

87 """Return a "must be overridden" message""" 

88 g.pr("BaseEditCommandsClass oops:", 

89 g.callers(), 

90 "must be overridden in subclass") 

91 #@+node:ekr.20150514043714.10: *3* BaseEdit.Helpers 

92 #@+node:ekr.20150514043714.11: *4* BaseEdit._chckSel 

93 def _chckSel(self, event, warning='no selection'): 

94 """Return True if there is a selection in the edit widget.""" 

95 w = self.editWidget(event) 

96 val = w and w.hasSelection() 

97 if warning and not val: 

98 # k.setLabelGrey(warning) 

99 g.es(warning, color='red') 

100 return val 

101 #@+node:ekr.20150514043714.13: *4* BaseEdit.getRectanglePoints 

102 def getRectanglePoints(self, w): 

103 """Return the rectangle corresponding to the selection range.""" 

104 c = self.c 

105 c.widgetWantsFocusNow(w) 

106 s = w.getAllText() 

107 i, j = w.getSelectionRange() 

108 r1, r2 = g.convertPythonIndexToRowCol(s, i) 

109 r3, r4 = g.convertPythonIndexToRowCol(s, j) 

110 return r1 + 1, r2, r3 + 1, r4 

111 #@+node:ekr.20150514043714.14: *4* BaseEdit.keyboardQuit 

112 def keyboardQuit(self, event=None): 

113 """Clear the state and the minibuffer label.""" 

114 return self.c.k.keyboardQuit() 

115 #@-others 

116#@-others 

117#@-leo