1 # A minimal text editor using MLTE. Based on wed.py.
4 # - Functionality: find, etc.
6 from Menu
import DrawMenuBar
7 from FrameWork
import *
11 from Carbon
import Res
12 from Carbon
import Scrap
15 from Carbon
import MacTextEditor
16 from Carbon
import Mlte
18 UNDOLABELS
= [ # Indexed by MLTECanUndo() value
19 "Typing", "Cut", "Paste", "Clear", "Font Change", "Color Change", "Size Change",
20 "Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"]
22 class MlteWindow(Window
):
23 def open(self
, path
, name
, data
):
26 r
= windowbounds(400, 400)
27 w
= Win
.NewWindow(r
, name
, 1, 0, -1, 1, 0)
29 flags
= MacTextEditor
.kTXNDrawGrowIconMask|MacTextEditor
.kTXNWantHScrollBarMask| \
30 MacTextEditor
.kTXNWantVScrollBarMask
31 self
.ted
, self
.frameid
= Mlte
.TXNNewObject(None, w
, None, flags
, MacTextEditor
.kTXNTextEditStyleFrameType
,
32 MacTextEditor
.kTXNTextFile
, MacTextEditor
.kTXNMacOSEncoding
)
33 self
.ted
.TXNSetData(MacTextEditor
.kTXNTextData
, data
, 0, 0x7fffffff)
36 self
.do_activate(1, None)
38 def do_idle(self
, event
):
40 self
.ted
.TXNAdjustCursor(None)
44 def do_activate(self
, onoff
, evt
):
46 ## self.ted.TXNActivate(self.frameid, 0)
48 self
.parent
.active
= self
51 self
.parent
.active
= None
52 self
.parent
.updatemenubar()
54 def do_update(self
, wid
, event
):
55 self
.ted
.TXNDraw(None)
57 def do_postresize(self
, width
, height
, window
):
58 self
.ted
.TXNResizeFrame(width
, height
, self
.frameid
)
60 def do_contentclick(self
, local
, modifiers
, evt
):
61 self
.ted
.TXNClick(evt
)
62 self
.parent
.updatemenubar()
64 def do_char(self
, ch
, event
):
65 self
.ted
.TXNKeyDown(event
)
66 self
.parent
.updatemenubar()
70 save
= EasyDialogs
.AskYesNoCancel('Save window "%s" before closing?'%self
.name
, 1)
75 if self
.parent
.active
== self
:
76 self
.parent
.active
= None
77 self
.ted
.TXNDeleteObject()
79 ## del self.tedtexthandle
85 return # Will call us recursively
86 dhandle
= self
.ted
.TXNGetData(0, 0x7fffffff)
88 fp
= open(self
.path
, 'wb') # NOTE: wb, because data has CR for end-of-line
90 if data
[-1] <> '\r': fp
.write('\r')
94 def menu_save_as(self
):
95 fss
, ok
= macfs
.StandardPutFile('Save as:')
97 self
.path
= fss
.as_pathname()
98 self
.name
= os
.path
.split(self
.path
)[-1]
99 self
.wid
.SetWTitle(self
.name
)
103 ## self.ted.WESelView()
105 ### Mlte.ConvertToPublicScrap()
108 ## self.updatescrollbars()
109 self
.parent
.updatemenubar()
115 ### Mlte.ConvertToPublicScrap()
116 ## self.updatescrollbars()
117 self
.parent
.updatemenubar()
119 def menu_paste(self
):
120 ### Mlte.ConvertFromPublicScrap()
122 ## self.updatescrollbars()
123 self
.parent
.updatemenubar()
126 def menu_clear(self
):
127 ## self.ted.WESelView()
129 ## self.updatescrollbars()
130 self
.parent
.updatemenubar()
135 ## self.updatescrollbars()
136 self
.parent
.updatemenubar()
140 ## self.updatescrollbars()
141 self
.parent
.updatemenubar()
143 def have_selection(self
):
144 start
, stop
= self
.ted
.TXNGetSelection()
148 return Mlte
.TXNIsScrapPastable()
151 can
, which
= self
.ted
.TXNCanUndo()
154 if which
>= len(UNDOLABELS
):
157 which
= UNDOLABELS
[which
]
162 can
, which
= self
.ted
.TXNCanRedo()
165 if which
>= len(UNDOLABELS
):
168 which
= UNDOLABELS
[which
]
172 class Mlted(Application
):
174 Application
.__init
__(self
)
179 def makeusermenus(self
):
180 self
.filemenu
= m
= Menu(self
.menubar
, "File")
181 self
.newitem
= MenuItem(m
, "New window", "N", self
.open)
182 self
.openitem
= MenuItem(m
, "Open...", "O", self
.openfile
)
183 self
.closeitem
= MenuItem(m
, "Close", "W", self
.closewin
)
185 self
.saveitem
= MenuItem(m
, "Save", "S", self
.save
)
186 self
.saveasitem
= MenuItem(m
, "Save as...", "", self
.saveas
)
188 self
.quititem
= MenuItem(m
, "Quit", "Q", self
.quit
)
190 self
.editmenu
= m
= Menu(self
.menubar
, "Edit")
191 self
.undoitem
= MenuItem(m
, "Undo", "Z", self
.undo
)
192 self
.redoitem
= MenuItem(m
, "Redo", None, self
.redo
)
194 self
.cutitem
= MenuItem(m
, "Cut", "X", self
.cut
)
195 self
.copyitem
= MenuItem(m
, "Copy", "C", self
.copy
)
196 self
.pasteitem
= MenuItem(m
, "Paste", "V", self
.paste
)
197 self
.clearitem
= MenuItem(m
, "Clear", "", self
.clear
)
199 # Groups of items enabled together:
200 self
.windowgroup
= [self
.closeitem
, self
.saveitem
, self
.saveasitem
, self
.editmenu
]
201 self
.focusgroup
= [self
.cutitem
, self
.copyitem
, self
.clearitem
]
202 self
.windowgroup_on
= -1
203 self
.focusgroup_on
= -1
204 self
.pastegroup_on
= -1
205 self
.undo_label
= "never"
206 self
.redo_label
= "never"
208 def updatemenubar(self
):
210 on
= (self
.active
<> None)
211 if on
<> self
.windowgroup_on
:
212 for m
in self
.windowgroup
:
214 self
.windowgroup_on
= on
217 # only if we have an edit menu
218 on
= self
.active
.have_selection()
219 if on
<> self
.focusgroup_on
:
220 for m
in self
.focusgroup
:
222 self
.focusgroup_on
= on
224 on
= self
.active
.can_paste()
225 if on
<> self
.pastegroup_on
:
226 self
.pasteitem
.enable(on
)
227 self
.pastegroup_on
= on
229 on
= self
.active
.can_undo()
230 if on
<> self
.undo_label
:
232 self
.undoitem
.enable(1)
233 self
.undoitem
.settext(on
)
236 self
.undoitem
.settext("Nothing to undo")
237 self
.undoitem
.enable(0)
239 on
= self
.active
.can_redo()
240 if on
<> self
.redo_label
:
242 self
.redoitem
.enable(1)
243 self
.redoitem
.settext(on
)
246 self
.redoitem
.settext("Nothing to redo")
247 self
.redoitem
.enable(0)
256 def do_about(self
, id, item
, window
, event
):
257 EasyDialogs
.Message("A simple single-font text editor based on MacTextEditor")
263 def open(self
, *args
):
266 def openfile(self
, *args
):
269 def _open(self
, askfile
):
271 fss
, ok
= macfs
.StandardGetFile('TEXT')
274 path
= fss
.as_pathname()
275 name
= os
.path
.split(path
)[-1]
277 fp
= open(path
, 'rb') # NOTE binary, we need cr as end-of-line
281 EasyDialogs
.Message("IOERROR: "+`arg`
)
285 name
= "Untitled %d"%self
.num
288 w
.open(path
, name
, data
)
289 self
.num
= self
.num
+ 1
291 def closewin(self
, *args
):
295 EasyDialogs
.Message("No active window?")
297 def save(self
, *args
):
299 self
.active
.menu_save()
301 EasyDialogs
.Message("No active window?")
303 def saveas(self
, *args
):
305 self
.active
.menu_save_as()
307 EasyDialogs
.Message("No active window?")
310 def quit(self
, *args
):
311 for w
in self
._windows
.values():
321 def undo(self
, *args
):
323 self
.active
.menu_undo()
325 EasyDialogs
.Message("No active window?")
327 def redo(self
, *args
):
329 self
.active
.menu_redo()
331 EasyDialogs
.Message("No active window?")
333 def cut(self
, *args
):
335 self
.active
.menu_cut()
337 EasyDialogs
.Message("No active window?")
339 def copy(self
, *args
):
341 self
.active
.menu_copy()
343 EasyDialogs
.Message("No active window?")
345 def paste(self
, *args
):
347 self
.active
.menu_paste()
349 EasyDialogs
.Message("No active window?")
351 def clear(self
, *args
):
353 self
.active
.menu_clear()
355 EasyDialogs
.Message("No active window?")
361 def idle(self
, event
):
363 self
.active
.do_idle(event
)
365 Qd
.SetCursor(Qd
.qd
.arrow
)
368 Mlte
.TXNInitTextension(0)
373 Mlte
.TXNTerminateTextension()
375 if __name__
== '__main__':