Clarify portability and main program.
[python/dscho.git] / Mac / Demo / waste / htmled.py
blob5aa0207267281cfffe87c68ca9e65d5f8faf927b
1 # A minimal text editor.
3 # To be done:
4 # - Functionality: find, etc.
6 from Menu import DrawMenuBar
7 from FrameWork import *
8 import Win
9 import Qd
10 import Res
11 import Fm
12 import waste
13 import WASTEconst
14 import Scrap
15 import os
16 import macfs
17 import regsub
18 import string
19 import htmllib
21 WATCH = Qd.GetCursor(4).data
23 LEFTMARGIN=0
25 UNDOLABELS = [ # Indexed by WEGetUndoInfo() value
26 None, "", "typing", "Cut", "Paste", "Clear", "Drag", "Style"]
28 # Style and size menu. Note that style order is important (tied to bit values)
29 STYLES = [
30 ("Bold", "B"), ("Italic", "I"), ("Underline", "U"), ("Outline", "O"),
31 ("Shadow", ""), ("Condensed", ""), ("Extended", "")
33 SIZES = [ 9, 10, 12, 14, 18, 24]
35 # Sizes for HTML tag types
36 HTML_SIZE={
37 'h1': 18,
38 'h2': 14
41 BIGREGION=Qd.NewRgn()
42 Qd.SetRectRgn(BIGREGION, -16000, -16000, 16000, 16000)
44 class WasteWindow(ScrolledWindow):
45 def open(self, path, name, data):
46 self.path = path
47 self.name = name
48 r = windowbounds(400, 400)
49 w = Win.NewWindow(r, name, 1, 0, -1, 1, 0x55555555)
50 self.wid = w
51 vr = LEFTMARGIN, 0, r[2]-r[0]-15, r[3]-r[1]-15
52 dr = (0, 0, vr[2], 0)
53 Qd.SetPort(w)
54 Qd.TextFont(4)
55 Qd.TextSize(9)
56 flags = WASTEconst.weDoAutoScroll | WASTEconst.weDoOutlineHilite | \
57 WASTEconst.weDoMonoStyled | WASTEconst.weDoUndo
58 self.ted = waste.WENew(dr, vr, flags)
59 self.ted.WEInstallTabHooks()
60 style, soup = self.getstylesoup(self.path)
61 self.ted.WEInsert(data, style, soup)
62 self.ted.WESetSelection(0,0)
63 self.ted.WECalText()
64 self.ted.WEResetModCount()
65 w.DrawGrowIcon()
66 self.scrollbars()
67 self.do_postopen()
68 self.do_activate(1, None)
70 def getstylesoup(self, pathname):
71 if not pathname:
72 return None, None
73 oldrf = Res.CurResFile()
74 try:
75 rf = Res.OpenResFile(self.path)
76 except Res.Error:
77 return None, None
78 try:
79 hstyle = Res.Get1Resource('styl', 128)
80 hstyle.DetachResource()
81 except Res.Error:
82 hstyle = None
83 try:
84 hsoup = Res.Get1Resource('SOUP', 128)
85 hsoup.DetachResource()
86 except Res.Error:
87 hsoup = None
88 Res.CloseResFile(rf)
89 Res.UseResFile(oldrf)
90 return hstyle, hsoup
92 def do_idle(self, event):
93 (what, message, when, where, modifiers) = event
94 Qd.SetPort(self.wid)
95 self.ted.WEIdle()
96 if self.ted.WEAdjustCursor(where, BIGREGION):
97 return
98 Qd.SetCursor(Qd.qd.arrow)
100 def getscrollbarvalues(self):
101 dr = self.ted.WEGetDestRect()
102 vr = self.ted.WEGetViewRect()
103 vx = self.scalebarvalue(dr[0], dr[2], vr[0], vr[2])
104 vy = self.scalebarvalue(dr[1], dr[3], vr[1], vr[3])
105 return vx, vy
107 def scrollbar_callback(self, which, what, value):
108 if which == 'y':
110 # "line" size is minimum of top and bottom line size
112 topline_off,dummy = self.ted.WEGetOffset((1,1))
113 topline_num = self.ted.WEOffsetToLine(topline_off)
114 toplineheight = self.ted.WEGetHeight(topline_num, topline_num+1)
116 botlinepos = self.ted.WEGetViewRect()[3]
117 botline_off, dummy = self.ted.WEGetOffset((1, botlinepos-1))
118 botline_num = self.ted.WEOffsetToLine(botline_off)
119 botlineheight = self.ted.WEGetHeight(botline_num, botline_num+1)
121 if botlineheight == 0:
122 botlineheight = self.ted.WEGetHeight(botline_num-1, botline_num)
123 if botlineheight < toplineheight:
124 lineheight = botlineheight
125 else:
126 lineheight = toplineheight
127 if lineheight <= 0:
128 lineheight = 1
130 # Now do the command.
132 if what == 'set':
133 height = self.ted.WEGetHeight(0, 0x3fffffff)
134 cur = self.getscrollbarvalues()[1]
135 delta = (cur-value)*height/32767
136 if what == '-':
137 delta = lineheight
138 elif what == '--':
139 delta = (self.ted.WEGetViewRect()[3]-lineheight)
140 if delta <= 0:
141 delta = lineheight
142 elif what == '+':
143 delta = -lineheight
144 elif what == '++':
145 delta = -(self.ted.WEGetViewRect()[3]-lineheight)
146 if delta >= 0:
147 delta = -lineheight
148 self.ted.WEScroll(0, delta)
149 else:
150 if what == 'set':
151 return # XXXX
152 vr = self.ted.WEGetViewRect()
153 winwidth = vr[2]-vr[0]
154 if what == '-':
155 delta = winwidth/10
156 elif what == '--':
157 delta = winwidth/2
158 elif what == '+':
159 delta = -winwidth/10
160 elif what == '++':
161 delta = -winwidth/2
162 self.ted.WEScroll(delta, 0)
163 # Pin the scroll
164 l, t, r, b = self.ted.WEGetDestRect()
165 vl, vt, vr, vb = self.ted.WEGetViewRect()
166 if t > 0 or l > 0:
167 dx = dy = 0
168 if t > 0: dy = -t
169 if l > 0: dx = -l
170 self.ted.WEScroll(dx, dy)
171 elif b < vb:
172 self.ted.WEScroll(0, vb-b)
175 def do_activate(self, onoff, evt):
176 Qd.SetPort(self.wid)
177 ScrolledWindow.do_activate(self, onoff, evt)
178 if onoff:
179 self.ted.WEActivate()
180 self.parent.active = self
181 self.parent.updatemenubar()
182 else:
183 self.ted.WEDeactivate()
185 def do_update(self, wid, event):
186 region = wid.GetWindowPort().visRgn
187 if Qd.EmptyRgn(region):
188 return
189 Qd.EraseRgn(region)
190 self.ted.WEUpdate(region)
191 self.updatescrollbars()
193 def do_postresize(self, width, height, window):
194 l, t, r, b = self.ted.WEGetViewRect()
195 vr = (l, t, l+width-15, t+height-15)
196 self.ted.WESetViewRect(vr)
197 Win.InvalRect(vr)
198 ScrolledWindow.do_postresize(self, width, height, window)
200 def do_contentclick(self, local, modifiers, evt):
201 (what, message, when, where, modifiers) = evt
202 self.ted.WEClick(local, modifiers, when)
203 self.updatescrollbars()
204 self.parent.updatemenubar()
206 def do_char(self, ch, event):
207 self.ted.WESelView()
208 (what, message, when, where, modifiers) = event
209 self.ted.WEKey(ord(ch), modifiers)
210 self.updatescrollbars()
211 self.parent.updatemenubar()
213 def close(self):
214 if self.ted.WEGetModCount():
215 save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
216 if save > 0:
217 self.menu_save()
218 elif save < 0:
219 return
220 if self.parent.active == self:
221 self.parent.active = None
222 self.parent.updatemenubar()
223 del self.ted
224 self.do_postclose()
226 def menu_save(self):
227 if not self.path:
228 self.menu_save_as()
229 return # Will call us recursively
231 # First save data
233 dhandle = self.ted.WEGetText()
234 data = dhandle.data
235 fp = open(self.path, 'wb') # NOTE: wb, because data has CR for end-of-line
236 fp.write(data)
237 if data[-1] <> '\r': fp.write('\r')
238 fp.close()
240 # Now save style and soup
242 oldresfile = Res.CurResFile()
243 try:
244 rf = Res.OpenResFile(self.path)
245 except Res.Error:
246 Res.CreateResFile(self.path)
247 rf = Res.OpenResFile(self.path)
248 styles = Res.Resource('')
249 soup = Res.Resource('')
250 self.ted.WECopyRange(0, 0x3fffffff, None, styles, soup)
251 styles.AddResource('styl', 128, '')
252 soup.AddResource('SOUP', 128, '')
253 Res.CloseResFile(rf)
254 Res.UseResFile(oldresfile)
256 self.ted.WEResetModCount()
258 def menu_save_as(self):
259 fss, ok = macfs.StandardPutFile('Save as:')
260 if not ok: return
261 self.path = fss.as_pathname()
262 self.name = os.path.split(self.path)[-1]
263 self.wid.SetWTitle(self.name)
264 self.menu_save()
266 def menu_insert(self, fp):
267 self.ted.WESelView()
268 data = fp.read()
269 self.ted.WEInsert(data, None, None)
270 self.updatescrollbars()
271 self.parent.updatemenubar()
273 def menu_insert_html(self, fp):
274 import htmllib
275 import formatter
276 f = formatter.AbstractFormatter(self)
278 # Remember where we are, and don't update
279 Qd.SetCursor(WATCH)
280 start, dummy = self.ted.WEGetSelection()
281 self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 1)
283 self.html_init()
284 p = MyHTMLParser(f)
285 p.feed(fp.read())
287 # Restore updating, recalc, set focus
288 dummy, end = self.ted.WEGetSelection()
289 self.ted.WECalText()
290 self.ted.WESetSelection(start, end)
291 self.ted.WESelView()
292 self.ted.WEFeatureFlag(WASTEconst.weFInhibitRecal, 0)
293 Win.InvalRect(self.ted.WEGetViewRect())
295 self.updatescrollbars()
296 self.parent.updatemenubar()
298 def menu_cut(self):
299 self.ted.WESelView()
300 self.ted.WECut()
301 Scrap.ZeroScrap()
302 self.ted.WECut()
303 self.updatescrollbars()
304 self.parent.updatemenubar()
306 def menu_copy(self):
307 Scrap.ZeroScrap()
308 self.ted.WECopy()
309 self.updatescrollbars()
310 self.parent.updatemenubar()
312 def menu_paste(self):
313 self.ted.WESelView()
314 self.ted.WEPaste()
315 self.updatescrollbars()
316 self.parent.updatemenubar()
318 def menu_clear(self):
319 self.ted.WESelView()
320 self.ted.WEDelete()
321 self.updatescrollbars()
322 self.parent.updatemenubar()
324 def menu_undo(self):
325 self.ted.WEUndo()
326 self.updatescrollbars()
327 self.parent.updatemenubar()
329 def menu_setfont(self, font):
330 font = Fm.GetFNum(font)
331 self.mysetstyle(WASTEconst.weDoFont, (font, 0, 0, (0,0,0)))
332 self.parent.updatemenubar()
334 def menu_modface(self, face):
335 self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoToggleFace,
336 (0, face, 0, (0,0,0)))
338 def menu_setface(self, face):
339 self.mysetstyle(WASTEconst.weDoFace|WASTEconst.weDoReplaceFace,
340 (0, face, 0, (0,0,0)))
342 def menu_setsize(self, size):
343 self.mysetstyle(WASTEconst.weDoSize, (0, 0, size, (0,0,0)))
345 def menu_incsize(self, size):
346 self.mysetstyle(WASTEconst.weDoAddSize, (0, 0, size, (0,0,0)))
348 def mysetstyle(self, which, how):
349 self.ted.WESelView()
350 self.ted.WESetStyle(which, how)
351 self.parent.updatemenubar()
353 def have_selection(self):
354 start, stop = self.ted.WEGetSelection()
355 return start < stop
357 def can_paste(self):
358 return self.ted.WECanPaste()
360 def can_undo(self):
361 which, redo = self.ted.WEGetUndoInfo()
362 which = UNDOLABELS[which]
363 if which == None: return None
364 if redo:
365 return "Redo "+which
366 else:
367 return "Undo "+which
369 def getruninfo(self):
370 all = (WASTEconst.weDoFont | WASTEconst.weDoFace | WASTEconst.weDoSize)
371 dummy, mode, (font, face, size, color) = self.ted.WEContinuousStyle(all)
372 if not (mode & WASTEconst.weDoFont):
373 font = None
374 else:
375 font = Fm.GetFontName(font)
376 if not (mode & WASTEconst.weDoFace): fact = None
377 if not (mode & WASTEconst.weDoSize): size = None
378 return font, face, size
381 # Methods for writer class for html formatter
384 def html_init(self):
385 self.html_font = [12, 0, 0, 0]
386 self.html_style = 0
387 self.html_color = (0,0,0)
388 self.new_font(self.html_font)
390 def new_font(self, font):
391 if font == None:
392 font = (12, 0, 0, 0)
393 font = map(lambda x:x, font)
394 for i in range(len(font)):
395 if font[i] == None:
396 font[i] = self.html_font[i]
397 [size, italic, bold, tt] = font
398 self.html_font = font[:]
399 if tt:
400 font = Fm.GetFNum('Courier')
401 else:
402 font = Fm.GetFNum('Times')
403 if HTML_SIZE.has_key(size):
404 size = HTML_SIZE[size]
405 else:
406 size = 12
407 face = 0
408 if bold: face = face | 1
409 if italic: face = face | 2
410 face = face | self.html_style
411 self.ted.WESetStyle(WASTEconst.weDoFont | WASTEconst.weDoFace |
412 WASTEconst.weDoSize | WASTEconst.weDoColor,
413 (font, face, size, self.html_color))
415 def new_margin(self, margin, level):
416 self.ted.WEInsert('[Margin %s %s]'%(margin, level), None, None)
418 def new_spacing(self, spacing):
419 self.ted.WEInsert('[spacing %s]'%spacing, None, None)
421 def new_styles(self, styles):
422 self.html_style = 0
423 self.html_color = (0,0,0)
424 if 'anchor' in styles:
425 self.html_style = self.html_style | 4
426 self.html_color = (0xffff, 0, 0)
427 self.new_font(self.html_font)
429 def send_paragraph(self, blankline):
430 self.ted.WEInsert('\r'*(blankline+1), None, None)
432 def send_line_break(self):
433 self.ted.WEInsert('\r', None, None)
435 def send_hor_rule(self, *args, **kw):
436 # Ignore ruler options, for now
437 dummydata = Res.Resource('')
438 self.ted.WEInsertObject('rulr', dummydata, (0,0))
440 def send_label_data(self, data):
441 self.ted.WEInsert(data, None, None)
443 def send_flowing_data(self, data):
444 self.ted.WEInsert(data, None, None)
446 def send_literal_data(self, data):
447 data = regsub.gsub('\n', '\r', data)
448 data = string.expandtabs(data)
449 self.ted.WEInsert(data, None, None)
451 class Wed(Application):
452 def __init__(self):
453 Application.__init__(self)
454 self.num = 0
455 self.active = None
456 self.updatemenubar()
457 waste.STDObjectHandlers()
458 # Handler for horizontal ruler
459 waste.WEInstallObjectHandler('rulr', 'new ', self.newRuler)
460 waste.WEInstallObjectHandler('rulr', 'draw', self.drawRuler)
462 def makeusermenus(self):
463 self.filemenu = m = Menu(self.menubar, "File")
464 self.newitem = MenuItem(m, "New window", "N", self.open)
465 self.openitem = MenuItem(m, "Open...", "O", self.openfile)
466 self.closeitem = MenuItem(m, "Close", "W", self.closewin)
467 m.addseparator()
468 self.saveitem = MenuItem(m, "Save", "S", self.save)
469 self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
470 m.addseparator()
471 self.insertitem = MenuItem(m, "Insert plaintext...", "", self.insertfile)
472 self.htmlitem = MenuItem(m, "Insert HTML...", "", self.inserthtml)
473 m.addseparator()
474 self.quititem = MenuItem(m, "Quit", "Q", self.quit)
476 self.editmenu = m = Menu(self.menubar, "Edit")
477 self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
478 self.cutitem = MenuItem(m, "Cut", "X", self.cut)
479 self.copyitem = MenuItem(m, "Copy", "C", self.copy)
480 self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
481 self.clearitem = MenuItem(m, "Clear", "", self.clear)
483 self.makefontmenu()
485 # Groups of items enabled together:
486 self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem,
487 self.editmenu, self.fontmenu, self.facemenu, self.sizemenu,
488 self.insertitem]
489 self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
490 self.windowgroup_on = -1
491 self.focusgroup_on = -1
492 self.pastegroup_on = -1
493 self.undo_label = "never"
494 self.ffs_values = ()
496 def makefontmenu(self):
497 self.fontmenu = Menu(self.menubar, "Font")
498 self.fontnames = getfontnames()
499 self.fontitems = []
500 for n in self.fontnames:
501 m = MenuItem(self.fontmenu, n, "", self.selfont)
502 self.fontitems.append(m)
503 self.facemenu = Menu(self.menubar, "Style")
504 self.faceitems = []
505 for n, shortcut in STYLES:
506 m = MenuItem(self.facemenu, n, shortcut, self.selface)
507 self.faceitems.append(m)
508 self.facemenu.addseparator()
509 self.faceitem_normal = MenuItem(self.facemenu, "Normal", "N",
510 self.selfacenormal)
511 self.sizemenu = Menu(self.menubar, "Size")
512 self.sizeitems = []
513 for n in SIZES:
514 m = MenuItem(self.sizemenu, `n`, "", self.selsize)
515 self.sizeitems.append(m)
516 self.sizemenu.addseparator()
517 self.sizeitem_bigger = MenuItem(self.sizemenu, "Bigger", "+",
518 self.selsizebigger)
519 self.sizeitem_smaller = MenuItem(self.sizemenu, "Smaller", "-",
520 self.selsizesmaller)
522 def selfont(self, id, item, *rest):
523 if self.active:
524 font = self.fontnames[item-1]
525 self.active.menu_setfont(font)
526 else:
527 EasyDialogs.Message("No active window?")
529 def selface(self, id, item, *rest):
530 if self.active:
531 face = (1<<(item-1))
532 self.active.menu_modface(face)
533 else:
534 EasyDialogs.Message("No active window?")
536 def selfacenormal(self, *rest):
537 if self.active:
538 self.active.menu_setface(0)
539 else:
540 EasyDialogs.Message("No active window?")
542 def selsize(self, id, item, *rest):
543 if self.active:
544 size = SIZES[item-1]
545 self.active.menu_setsize(size)
546 else:
547 EasyDialogs.Message("No active window?")
549 def selsizebigger(self, *rest):
550 if self.active:
551 self.active.menu_incsize(2)
552 else:
553 EasyDialogs.Message("No active window?")
555 def selsizesmaller(self, *rest):
556 if self.active:
557 self.active.menu_incsize(-2)
558 else:
559 EasyDialogs.Message("No active window?")
561 def updatemenubar(self):
562 changed = 0
563 on = (self.active <> None)
564 if on <> self.windowgroup_on:
565 for m in self.windowgroup:
566 m.enable(on)
567 self.windowgroup_on = on
568 changed = 1
569 if on:
570 # only if we have an edit menu
571 on = self.active.have_selection()
572 if on <> self.focusgroup_on:
573 for m in self.focusgroup:
574 m.enable(on)
575 self.focusgroup_on = on
576 changed = 1
577 on = self.active.can_paste()
578 if on <> self.pastegroup_on:
579 self.pasteitem.enable(on)
580 self.pastegroup_on = on
581 changed = 1
582 on = self.active.can_undo()
583 if on <> self.undo_label:
584 if on:
585 self.undoitem.enable(1)
586 self.undoitem.settext(on)
587 self.undo_label = on
588 else:
589 self.undoitem.settext("Nothing to undo")
590 self.undoitem.enable(0)
591 changed = 1
592 if self.updatefontmenus():
593 changed = 1
594 if changed:
595 DrawMenuBar()
597 def updatefontmenus(self):
598 info = self.active.getruninfo()
599 if info == self.ffs_values:
600 return 0
601 # Remove old checkmarks
602 if self.ffs_values == ():
603 self.ffs_values = (None, None, None)
604 font, face, size = self.ffs_values
605 if font <> None:
606 fnum = self.fontnames.index(font)
607 self.fontitems[fnum].check(0)
608 if face <> None:
609 for i in range(len(self.faceitems)):
610 if face & (1<<i):
611 self.faceitems[i].check(0)
612 if size <> None:
613 for i in range(len(self.sizeitems)):
614 if SIZES[i] == size:
615 self.sizeitems[i].check(0)
617 self.ffs_values = info
618 # Set new checkmarks
619 font, face, size = self.ffs_values
620 if font <> None:
621 fnum = self.fontnames.index(font)
622 self.fontitems[fnum].check(1)
623 if face <> None:
624 for i in range(len(self.faceitems)):
625 if face & (1<<i):
626 self.faceitems[i].check(1)
627 if size <> None:
628 for i in range(len(self.sizeitems)):
629 if SIZES[i] == size:
630 self.sizeitems[i].check(1)
631 # Set outline/normal for sizes
632 if font:
633 exists = getfontsizes(font, SIZES)
634 for i in range(len(self.sizeitems)):
635 if exists[i]:
636 self.sizeitems[i].setstyle(0)
637 else:
638 self.sizeitems[i].setstyle(8)
641 # Apple menu
644 def do_about(self, id, item, window, event):
645 EasyDialogs.Message("A simple single-font text editor based on WASTE")
648 # File menu
651 def open(self, *args):
652 self._open(0)
654 def openfile(self, *args):
655 self._open(1)
657 def _open(self, askfile):
658 if askfile:
659 fss, ok = macfs.StandardGetFile('TEXT')
660 if not ok:
661 return
662 path = fss.as_pathname()
663 name = os.path.split(path)[-1]
664 try:
665 fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
666 data = fp.read()
667 fp.close()
668 except IOError, arg:
669 EasyDialogs.Message("IOERROR: "+`arg`)
670 return
671 else:
672 path = None
673 name = "Untitled %d"%self.num
674 data = ''
675 w = WasteWindow(self)
676 w.open(path, name, data)
677 self.num = self.num + 1
679 def insertfile(self, *args):
680 if self.active:
681 fss, ok = macfs.StandardGetFile('TEXT')
682 if not ok:
683 return
684 path = fss.as_pathname()
685 try:
686 fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
687 except IOError, arg:
688 EasyDialogs.Message("IOERROR: "+`arg`)
689 return
690 self.active.menu_insert(fp)
691 else:
692 EasyDialogs.Message("No active window?")
694 def inserthtml(self, *args):
695 if self.active:
696 fss, ok = macfs.StandardGetFile('TEXT')
697 if not ok:
698 return
699 path = fss.as_pathname()
700 try:
701 fp = open(path, 'r')
702 except IOError, arg:
703 EasyDialogs.Message("IOERROR: "+`arg`)
704 return
705 self.active.menu_insert_html(fp)
706 else:
707 EasyDialogs.Message("No active window?")
710 def closewin(self, *args):
711 if self.active:
712 self.active.close()
713 else:
714 EasyDialogs.Message("No active window?")
716 def save(self, *args):
717 if self.active:
718 self.active.menu_save()
719 else:
720 EasyDialogs.Message("No active window?")
722 def saveas(self, *args):
723 if self.active:
724 self.active.menu_save_as()
725 else:
726 EasyDialogs.Message("No active window?")
729 def quit(self, *args):
730 for w in self._windows.values():
731 w.close()
732 if self._windows:
733 return
734 self._quit()
737 # Edit menu
740 def undo(self, *args):
741 if self.active:
742 self.active.menu_undo()
743 else:
744 EasyDialogs.Message("No active window?")
746 def cut(self, *args):
747 if self.active:
748 self.active.menu_cut()
749 else:
750 EasyDialogs.Message("No active window?")
752 def copy(self, *args):
753 if self.active:
754 self.active.menu_copy()
755 else:
756 EasyDialogs.Message("No active window?")
758 def paste(self, *args):
759 if self.active:
760 self.active.menu_paste()
761 else:
762 EasyDialogs.Message("No active window?")
764 def clear(self, *args):
765 if self.active:
766 self.active.menu_clear()
767 else:
768 EasyDialogs.Message("No active window?")
771 # Other stuff
774 def idle(self, event):
775 if self.active:
776 self.active.do_idle(event)
778 def newRuler(self, obj):
779 """Insert a new ruler. Make it as wide as the window minus 2 pxls"""
780 ted = obj.WEGetObjectOwner()
781 l, t, r, b = ted.WEGetDestRect()
782 return r-l, 4
784 def drawRuler(self, (l, t, r, b), obj):
785 y = (t+b)/2
786 Qd.MoveTo(l+2, y)
787 Qd.LineTo(r-2, y)
788 return 0
790 class MyHTMLParser(htmllib.HTMLParser):
792 def anchor_bgn(self, href, name, type):
793 self.anchor = href
794 if self.anchor:
795 self.anchorlist.append(href)
796 self.formatter.push_style('anchor')
798 def anchor_end(self):
799 if self.anchor:
800 self.anchor = None
801 self.formatter.pop_style()
804 def getfontnames():
805 names = []
806 for i in range(256):
807 n = Fm.GetFontName(i)
808 if n: names.append(n)
809 return names
811 def getfontsizes(name, sizes):
812 exist = []
813 num = Fm.GetFNum(name)
814 for sz in sizes:
815 if Fm.RealFont(num, sz):
816 exist.append(1)
817 else:
818 exist.append(0)
819 return exist
821 def main():
822 App = Wed()
823 App.mainloop()
825 if __name__ == '__main__':
826 main()