1 # A minimal text editor.
4 # - Update viewrect after resize
5 # - Handle horizontal scrollbar correctly
6 # - Functionality: find, etc.
8 from Menu
import DrawMenuBar
9 from FrameWork
import *
17 class TEWindow(ScrolledWindow
):
18 def open(self
, path
, name
, data
):
21 r
= windowbounds(400, 400)
22 w
= Win
.NewWindow(r
, name
, 1, 0, -1, 1, 0x55555555)
24 x0
, y0
, x1
, y1
= self
.wid
.GetWindowPort().portRect
29 vr
= dr
= x0
, y0
, x1
, y1
30 ##vr = 4, 0, r[2]-r[0]-15, r[3]-r[1]-15
31 ##dr = (0, 0, vr[2], 0)
35 self
.ted
= TE
.TENew(dr
, vr
)
36 self
.ted
.TEAutoView(1)
37 self
.ted
.TESetText(data
)
42 self
.do_activate(1, None)
47 def getscrollbarvalues(self
):
48 dr
= self
.ted
.destRect
49 vr
= self
.ted
.viewRect
50 height
= self
.ted
.nLines
* self
.ted
.lineHeight
51 vx
= self
.scalebarvalue(dr
[0], dr
[2]-dr
[0], vr
[0], vr
[2])
52 vy
= self
.scalebarvalue(dr
[1], dr
[1]+height
, vr
[1], vr
[3])
53 print dr
, vr
, height
, vx
, vy
56 def scrollbar_callback(self
, which
, what
, value
):
59 height
= self
.ted
.nLines
* self
.ted
.lineHeight
60 cur
= self
.getscrollbarvalues()[1]
61 delta
= (cur
-value
)*height
/32767
63 delta
= self
.ted
.lineHeight
65 delta
= (self
.ted
.viewRect
[3]-self
.ted
.lineHeight
)
67 delta
= self
.ted
.lineHeight
69 delta
= -self
.ted
.lineHeight
71 delta
= -(self
.ted
.viewRect
[3]-self
.ted
.lineHeight
)
73 delta
= -self
.ted
.lineHeight
74 self
.ted
.TEPinScroll(0, delta
)
75 print 'SCROLL Y', delta
77 pass # No horizontal scrolling
79 def do_activate(self
, onoff
, evt
):
80 print "ACTIVATE", onoff
81 ScrolledWindow
.do_activate(self
, onoff
, evt
)
84 self
.parent
.active
= self
85 self
.parent
.updatemenubar()
87 self
.ted
.TEDeactivate()
89 def do_update(self
, wid
, event
):
90 Qd
.EraseRect(wid
.GetWindowPort().portRect
)
91 self
.ted
.TEUpdate(wid
.GetWindowPort().portRect
)
92 self
.updatescrollbars()
94 def do_contentclick(self
, local
, modifiers
, evt
):
95 shifted
= (modifiers
& 0x200)
96 self
.ted
.TEClick(local
, shifted
)
97 self
.updatescrollbars()
98 self
.parent
.updatemenubar()
100 def do_char(self
, ch
, event
):
102 self
.ted
.TEKey(ord(ch
))
104 self
.updatescrollbars()
105 self
.parent
.updatemenubar()
109 save
= EasyDialogs
.AskYesNoCancel('Save window "%s" before closing?'%self
.name
, 1)
114 if self
.parent
.active
== self
:
115 self
.parent
.active
= None
116 self
.parent
.updatemenubar()
123 return # Will call us recursively
124 print 'Saving to ', self
.path
125 dhandle
= self
.ted
.TEGetText()
127 fp
= open(self
.path
, 'wb') # NOTE: wb, because data has CR for end-of-line
129 if data
[-1] <> '\r': fp
.write('\r')
133 def menu_save_as(self
):
134 fss
, ok
= macfs
.StandardPutFile('Save as:')
136 self
.path
= fss
.as_pathname()
137 self
.name
= os
.path
.split(self
.path
)[-1]
138 self
.wid
.SetWTitle(self
.name
)
146 self
.updatescrollbars()
147 self
.parent
.updatemenubar()
154 self
.updatescrollbars()
155 self
.parent
.updatemenubar()
157 def menu_paste(self
):
158 print 'SCRAP', Scrap
.InfoScrap(), `Scrap
.InfoScrap()[1].data`
162 self
.updatescrollbars()
163 self
.parent
.updatemenubar()
166 def menu_clear(self
):
169 self
.updatescrollbars()
170 self
.parent
.updatemenubar()
173 def have_selection(self
):
174 return (self
.ted
.selStart
< self
.ted
.selEnd
)
176 class Ped(Application
):
178 Application
.__init
__(self
)
183 def makeusermenus(self
):
184 self
.filemenu
= m
= Menu(self
.menubar
, "File")
185 self
.newitem
= MenuItem(m
, "New window", "N", self
.open)
186 self
.openitem
= MenuItem(m
, "Open...", "O", self
.openfile
)
187 self
.closeitem
= MenuItem(m
, "Close", "W", self
.closewin
)
189 self
.saveitem
= MenuItem(m
, "Save", "S", self
.save
)
190 self
.saveasitem
= MenuItem(m
, "Save as...", "", self
.saveas
)
192 self
.quititem
= MenuItem(m
, "Quit", "Q", self
.quit
)
194 self
.editmenu
= m
= Menu(self
.menubar
, "Edit")
195 self
.undoitem
= MenuItem(m
, "Undo", "Z", self
.undo
)
196 self
.cutitem
= MenuItem(m
, "Cut", "X", self
.cut
)
197 self
.copyitem
= MenuItem(m
, "Copy", "C", self
.copy
)
198 self
.pasteitem
= MenuItem(m
, "Paste", "V", self
.paste
)
199 self
.clearitem
= MenuItem(m
, "Clear", "", self
.clear
)
201 # Not yet implemented:
202 self
.undoitem
.enable(0)
204 # Groups of items enabled together:
205 self
.windowgroup
= [self
.closeitem
, self
.saveitem
, self
.saveasitem
, self
.editmenu
]
206 self
.focusgroup
= [self
.cutitem
, self
.copyitem
, self
.clearitem
]
207 self
.windowgroup_on
= -1
208 self
.focusgroup_on
= -1
209 self
.pastegroup_on
= -1
211 def updatemenubar(self
):
213 on
= (self
.active
<> None)
214 if on
<> self
.windowgroup_on
:
215 for m
in self
.windowgroup
:
217 self
.windowgroup_on
= on
220 # only if we have an edit menu
221 on
= self
.active
.have_selection()
222 if on
<> self
.focusgroup_on
:
223 for m
in self
.focusgroup
:
225 self
.focusgroup_on
= on
227 on
= (Scrap
.InfoScrap()[0] <> 0)
228 if on
<> self
.pastegroup_on
:
229 self
.pasteitem
.enable(on
)
230 self
.pastegroup_on
= on
239 def do_about(self
, id, item
, window
, event
):
240 EasyDialogs
.Message("A simple single-font text editor")
246 def open(self
, *args
):
249 def openfile(self
, *args
):
252 def _open(self
, askfile
):
254 fss
, ok
= macfs
.StandardGetFile('TEXT')
257 path
= fss
.as_pathname()
258 name
= os
.path
.split(path
)[-1]
260 fp
= open(path
, 'rb') # NOTE binary, we need cr as end-of-line
264 EasyDialogs
.Message("IOERROR: "+`arg`
)
268 name
= "Untitled %d"%self
.num
271 w
.open(path
, name
, data
)
272 self
.num
= self
.num
+ 1
274 def closewin(self
, *args
):
278 EasyDialogs
.Message("No active window?")
280 def save(self
, *args
):
282 self
.active
.menu_save()
284 EasyDialogs
.Message("No active window?")
286 def saveas(self
, *args
):
288 self
.active
.menu_save_as()
290 EasyDialogs
.Message("No active window?")
293 def quit(self
, *args
):
294 for w
in self
._windows
.values():
304 def undo(self
, *args
):
307 def cut(self
, *args
):
309 self
.active
.menu_cut()
311 EasyDialogs
.Message("No active window?")
313 def copy(self
, *args
):
315 self
.active
.menu_copy()
317 EasyDialogs
.Message("No active window?")
319 def paste(self
, *args
):
321 self
.active
.menu_paste()
323 EasyDialogs
.Message("No active window?")
325 def clear(self
, *args
):
327 self
.active
.menu_clear()
329 EasyDialogs
.Message("No active window?")
335 def idle(self
, *args
):
337 self
.active
.do_idle()
343 if __name__
== '__main__':