1 # A minimal text editor.
4 # - Update viewrect after resize
5 # - Handle horizontal scrollbar correctly
6 # - Functionality: find, etc.
8 from Carbon
.Menu
import DrawMenuBar
9 from FrameWork
import *
10 from Carbon
import Win
13 from Carbon
import Scrap
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, 0)
24 x0
, y0
, x1
, y1
= self
.wid
.GetWindowPort().GetPortBounds()
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().GetPortBounds())
91 self
.ted
.TEUpdate(wid
.GetWindowPort().GetPortBounds())
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 path
= EasyDialogs
.AskFileForSave(message
='Save as:')
137 self
.name
= os
.path
.split(self
.path
)[-1]
138 self
.wid
.SetWTitle(self
.name
)
144 if hasattr(Scrap
, 'ZeroScrap'):
147 Scrap
.ClearCurrentScrap()
149 self
.updatescrollbars()
150 self
.parent
.updatemenubar()
155 if hasattr(Scrap
, 'ZeroScrap'):
158 Scrap
.ClearCurrentScrap()
160 self
.updatescrollbars()
161 self
.parent
.updatemenubar()
163 def menu_paste(self
):
167 self
.updatescrollbars()
168 self
.parent
.updatemenubar()
171 def menu_clear(self
):
174 self
.updatescrollbars()
175 self
.parent
.updatemenubar()
178 def have_selection(self
):
179 return (self
.ted
.selStart
< self
.ted
.selEnd
)
181 class Ped(Application
):
183 Application
.__init
__(self
)
188 def makeusermenus(self
):
189 self
.filemenu
= m
= Menu(self
.menubar
, "File")
190 self
.newitem
= MenuItem(m
, "New window", "N", self
.open)
191 self
.openitem
= MenuItem(m
, "Open...", "O", self
.openfile
)
192 self
.closeitem
= MenuItem(m
, "Close", "W", self
.closewin
)
194 self
.saveitem
= MenuItem(m
, "Save", "S", self
.save
)
195 self
.saveasitem
= MenuItem(m
, "Save as...", "", self
.saveas
)
197 self
.quititem
= MenuItem(m
, "Quit", "Q", self
.quit
)
199 self
.editmenu
= m
= Menu(self
.menubar
, "Edit")
200 self
.undoitem
= MenuItem(m
, "Undo", "Z", self
.undo
)
201 self
.cutitem
= MenuItem(m
, "Cut", "X", self
.cut
)
202 self
.copyitem
= MenuItem(m
, "Copy", "C", self
.copy
)
203 self
.pasteitem
= MenuItem(m
, "Paste", "V", self
.paste
)
204 self
.clearitem
= MenuItem(m
, "Clear", "", self
.clear
)
206 # Not yet implemented:
207 self
.undoitem
.enable(0)
209 # Groups of items enabled together:
210 self
.windowgroup
= [self
.closeitem
, self
.saveitem
, self
.saveasitem
, self
.editmenu
]
211 self
.focusgroup
= [self
.cutitem
, self
.copyitem
, self
.clearitem
]
212 self
.windowgroup_on
= -1
213 self
.focusgroup_on
= -1
214 self
.pastegroup_on
= -1
216 def updatemenubar(self
):
218 on
= (self
.active
<> None)
219 if on
<> self
.windowgroup_on
:
220 for m
in self
.windowgroup
:
222 self
.windowgroup_on
= on
225 # only if we have an edit menu
226 on
= self
.active
.have_selection()
227 if on
<> self
.focusgroup_on
:
228 for m
in self
.focusgroup
:
230 self
.focusgroup_on
= on
232 if hasattr(Scrap
, 'InfoScrap'):
233 on
= (Scrap
.InfoScrap()[0] <> 0)
235 flavors
= Scrap
.GetCurrentScrap().GetScrapFlavorInfoList()
236 for tp
, info
in flavors
:
242 if on
<> self
.pastegroup_on
:
243 self
.pasteitem
.enable(on
)
244 self
.pastegroup_on
= on
253 def do_about(self
, id, item
, window
, event
):
254 EasyDialogs
.Message("A simple single-font text editor")
260 def open(self
, *args
):
263 def openfile(self
, *args
):
266 def _open(self
, askfile
):
268 path
= EasyDialogs
.AskFileForOpen(typeList
=('TEXT',))
271 name
= os
.path
.split(path
)[-1]
273 fp
= open(path
, 'rb') # NOTE binary, we need cr as end-of-line
277 EasyDialogs
.Message("IOERROR: "+`arg`
)
281 name
= "Untitled %d"%self
.num
284 w
.open(path
, name
, data
)
285 self
.num
= self
.num
+ 1
287 def closewin(self
, *args
):
291 EasyDialogs
.Message("No active window?")
293 def save(self
, *args
):
295 self
.active
.menu_save()
297 EasyDialogs
.Message("No active window?")
299 def saveas(self
, *args
):
301 self
.active
.menu_save_as()
303 EasyDialogs
.Message("No active window?")
306 def quit(self
, *args
):
307 for w
in self
._windows
.values():
317 def undo(self
, *args
):
320 def cut(self
, *args
):
322 self
.active
.menu_cut()
324 EasyDialogs
.Message("No active window?")
326 def copy(self
, *args
):
328 self
.active
.menu_copy()
330 EasyDialogs
.Message("No active window?")
332 def paste(self
, *args
):
334 self
.active
.menu_paste()
336 EasyDialogs
.Message("No active window?")
338 def clear(self
, *args
):
340 self
.active
.menu_clear()
342 EasyDialogs
.Message("No active window?")
348 def idle(self
, *args
):
350 self
.active
.do_idle()
352 Qd
.SetCursor(Qd
.GetQDGlobalsArrow())
358 if __name__
== '__main__':