ยปCore Development>Code coverage>Mac/Demo/mlte/mlted.py

Python code coverage for Mac/Demo/mlte/mlted.py

#countcontent
1n/a# A minimal text editor using MLTE. Based on wed.py.
2n/a#
3n/a# To be done:
4n/a# - Functionality: find, etc.
5n/a
6n/afrom Menu import DrawMenuBar
7n/afrom FrameWork import *
8n/afrom Carbon import Win
9n/afrom Carbon import Ctl
10n/afrom Carbon import Qd
11n/afrom Carbon import Res
12n/afrom Carbon import Scrap
13n/aimport os
14n/afrom Carbon import MacTextEditor
15n/afrom Carbon import Mlte
16n/a
17n/aUNDOLABELS = [ # Indexed by MLTECanUndo() value
18n/a "Typing", "Cut", "Paste", "Clear", "Font Change", "Color Change", "Size Change",
19n/a "Style Change", "Align Left", "Align Center", "Align Right", "Drop", "Move"]
20n/a
21n/aclass MlteWindow(Window):
22n/a def open(self, path, name, data):
23n/a self.path = path
24n/a self.name = name
25n/a r = windowbounds(400, 400)
26n/a w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
27n/a self.wid = w
28n/a flags = MacTextEditor.kTXNDrawGrowIconMask|MacTextEditor.kTXNWantHScrollBarMask| \
29n/a MacTextEditor.kTXNWantVScrollBarMask
30n/a self.ted, self.frameid = Mlte.TXNNewObject(None, w, None, flags, MacTextEditor.kTXNTextEditStyleFrameType,
31n/a MacTextEditor.kTXNTextFile, MacTextEditor.kTXNMacOSEncoding)
32n/a self.ted.TXNSetData(MacTextEditor.kTXNTextData, data, 0, 0x7fffffff)
33n/a self.changed = 0
34n/a self.do_postopen()
35n/a self.do_activate(1, None)
36n/a
37n/a def do_idle(self, event):
38n/a self.ted.TXNIdle()
39n/a self.ted.TXNAdjustCursor(None)
40n/a
41n/a
42n/a
43n/a def do_activate(self, onoff, evt):
44n/a if onoff:
45n/a## self.ted.TXNActivate(self.frameid, 0)
46n/a self.ted.TXNFocus(1)
47n/a self.parent.active = self
48n/a else:
49n/a self.ted.TXNFocus(0)
50n/a self.parent.active = None
51n/a self.parent.updatemenubar()
52n/a
53n/a def do_update(self, wid, event):
54n/a self.ted.TXNDraw(None)
55n/a
56n/a def do_postresize(self, width, height, window):
57n/a self.ted.TXNResizeFrame(width, height, self.frameid)
58n/a
59n/a def do_contentclick(self, local, modifiers, evt):
60n/a self.ted.TXNClick(evt)
61n/a self.parent.updatemenubar()
62n/a
63n/a def do_char(self, ch, event):
64n/a self.ted.TXNKeyDown(event)
65n/a self.parent.updatemenubar()
66n/a
67n/a def close(self):
68n/a if self.changed:
69n/a save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
70n/a if save > 0:
71n/a self.menu_save()
72n/a elif save < 0:
73n/a return
74n/a if self.parent.active == self:
75n/a self.parent.active = None
76n/a self.ted.TXNDeleteObject()
77n/a del self.ted
78n/a## del self.tedtexthandle
79n/a self.do_postclose()
80n/a
81n/a def menu_save(self):
82n/a if not self.path:
83n/a self.menu_save_as()
84n/a return # Will call us recursively
85n/a dhandle = self.ted.TXNGetData(0, 0x7fffffff)
86n/a data = dhandle.data
87n/a fp = open(self.path, 'wb') # NOTE: wb, because data has CR for end-of-line
88n/a fp.write(data)
89n/a if data[-1] <> '\r': fp.write('\r')
90n/a fp.close()
91n/a self.changed = 0
92n/a
93n/a def menu_save_as(self):
94n/a path = EasyDialogs.AskFileForSave(message='Save as:')
95n/a if not path: return
96n/a self.path = path
97n/a self.name = os.path.split(self.path)[-1]
98n/a self.wid.SetWTitle(self.name)
99n/a self.menu_save()
100n/a
101n/a def menu_cut(self):
102n/a## self.ted.WESelView()
103n/a self.ted.TXNCut()
104n/a### Mlte.ConvertToPublicScrap()
105n/a## Scrap.ZeroScrap()
106n/a## self.ted.WECut()
107n/a## self.updatescrollbars()
108n/a self.parent.updatemenubar()
109n/a self.changed = 1
110n/a
111n/a def menu_copy(self):
112n/a## Scrap.ZeroScrap()
113n/a self.ted.TXNCopy()
114n/a### Mlte.ConvertToPublicScrap()
115n/a## self.updatescrollbars()
116n/a self.parent.updatemenubar()
117n/a
118n/a def menu_paste(self):
119n/a### Mlte.ConvertFromPublicScrap()
120n/a self.ted.TXNPaste()
121n/a## self.updatescrollbars()
122n/a self.parent.updatemenubar()
123n/a self.changed = 1
124n/a
125n/a def menu_clear(self):
126n/a## self.ted.WESelView()
127n/a self.ted.TXNClear()
128n/a## self.updatescrollbars()
129n/a self.parent.updatemenubar()
130n/a self.changed = 1
131n/a
132n/a def menu_undo(self):
133n/a self.ted.TXNUndo()
134n/a## self.updatescrollbars()
135n/a self.parent.updatemenubar()
136n/a
137n/a def menu_redo(self):
138n/a self.ted.TXNRedo()
139n/a## self.updatescrollbars()
140n/a self.parent.updatemenubar()
141n/a
142n/a def have_selection(self):
143n/a start, stop = self.ted.TXNGetSelection()
144n/a return start < stop
145n/a
146n/a def can_paste(self):
147n/a return Mlte.TXNIsScrapPastable()
148n/a
149n/a def can_undo(self):
150n/a can, which = self.ted.TXNCanUndo()
151n/a if not can:
152n/a return None
153n/a if which >= len(UNDOLABELS):
154n/a # Unspecified undo
155n/a return "Undo"
156n/a which = UNDOLABELS[which]
157n/a
158n/a return "Undo "+which
159n/a
160n/a def can_redo(self):
161n/a can, which = self.ted.TXNCanRedo()
162n/a if not can:
163n/a return None
164n/a if which >= len(UNDOLABELS):
165n/a # Unspecified undo
166n/a return "Redo"
167n/a which = UNDOLABELS[which]
168n/a
169n/a return "Redo "+which
170n/a
171n/aclass Mlted(Application):
172n/a def __init__(self):
173n/a Application.__init__(self)
174n/a self.num = 0
175n/a self.active = None
176n/a self.updatemenubar()
177n/a
178n/a def makeusermenus(self):
179n/a self.filemenu = m = Menu(self.menubar, "File")
180n/a self.newitem = MenuItem(m, "New window", "N", self.open)
181n/a self.openitem = MenuItem(m, "Open...", "O", self.openfile)
182n/a self.closeitem = MenuItem(m, "Close", "W", self.closewin)
183n/a m.addseparator()
184n/a self.saveitem = MenuItem(m, "Save", "S", self.save)
185n/a self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
186n/a m.addseparator()
187n/a self.quititem = MenuItem(m, "Quit", "Q", self.quit)
188n/a
189n/a self.editmenu = m = Menu(self.menubar, "Edit")
190n/a self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
191n/a self.redoitem = MenuItem(m, "Redo", None, self.redo)
192n/a m.addseparator()
193n/a self.cutitem = MenuItem(m, "Cut", "X", self.cut)
194n/a self.copyitem = MenuItem(m, "Copy", "C", self.copy)
195n/a self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
196n/a self.clearitem = MenuItem(m, "Clear", "", self.clear)
197n/a
198n/a # Groups of items enabled together:
199n/a self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem, self.editmenu]
200n/a self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
201n/a self.windowgroup_on = -1
202n/a self.focusgroup_on = -1
203n/a self.pastegroup_on = -1
204n/a self.undo_label = "never"
205n/a self.redo_label = "never"
206n/a
207n/a def updatemenubar(self):
208n/a changed = 0
209n/a on = (self.active <> None)
210n/a if on <> self.windowgroup_on:
211n/a for m in self.windowgroup:
212n/a m.enable(on)
213n/a self.windowgroup_on = on
214n/a changed = 1
215n/a if on:
216n/a # only if we have an edit menu
217n/a on = self.active.have_selection()
218n/a if on <> self.focusgroup_on:
219n/a for m in self.focusgroup:
220n/a m.enable(on)
221n/a self.focusgroup_on = on
222n/a changed = 1
223n/a on = self.active.can_paste()
224n/a if on <> self.pastegroup_on:
225n/a self.pasteitem.enable(on)
226n/a self.pastegroup_on = on
227n/a changed = 1
228n/a on = self.active.can_undo()
229n/a if on <> self.undo_label:
230n/a if on:
231n/a self.undoitem.enable(1)
232n/a self.undoitem.settext(on)
233n/a self.undo_label = on
234n/a else:
235n/a self.undoitem.settext("Nothing to undo")
236n/a self.undoitem.enable(0)
237n/a changed = 1
238n/a on = self.active.can_redo()
239n/a if on <> self.redo_label:
240n/a if on:
241n/a self.redoitem.enable(1)
242n/a self.redoitem.settext(on)
243n/a self.redo_label = on
244n/a else:
245n/a self.redoitem.settext("Nothing to redo")
246n/a self.redoitem.enable(0)
247n/a changed = 1
248n/a if changed:
249n/a DrawMenuBar()
250n/a
251n/a #
252n/a # Apple menu
253n/a #
254n/a
255n/a def do_about(self, id, item, window, event):
256n/a EasyDialogs.Message("A simple single-font text editor based on MacTextEditor")
257n/a
258n/a #
259n/a # File menu
260n/a #
261n/a
262n/a def open(self, *args):
263n/a self._open(0)
264n/a
265n/a def openfile(self, *args):
266n/a self._open(1)
267n/a
268n/a def _open(self, askfile):
269n/a if askfile:
270n/a path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
271n/a if not path:
272n/a return
273n/a name = os.path.split(path)[-1]
274n/a try:
275n/a fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
276n/a data = fp.read()
277n/a fp.close()
278n/a except IOError, arg:
279n/a EasyDialogs.Message("IOERROR: %r" % (arg,))
280n/a return
281n/a else:
282n/a path = None
283n/a name = "Untitled %d"%self.num
284n/a data = ''
285n/a w = MlteWindow(self)
286n/a w.open(path, name, data)
287n/a self.num = self.num + 1
288n/a
289n/a def closewin(self, *args):
290n/a if self.active:
291n/a self.active.close()
292n/a else:
293n/a EasyDialogs.Message("No active window?")
294n/a
295n/a def save(self, *args):
296n/a if self.active:
297n/a self.active.menu_save()
298n/a else:
299n/a EasyDialogs.Message("No active window?")
300n/a
301n/a def saveas(self, *args):
302n/a if self.active:
303n/a self.active.menu_save_as()
304n/a else:
305n/a EasyDialogs.Message("No active window?")
306n/a
307n/a
308n/a def quit(self, *args):
309n/a for w in self._windows.values():
310n/a w.close()
311n/a if self._windows:
312n/a return
313n/a self._quit()
314n/a
315n/a #
316n/a # Edit menu
317n/a #
318n/a
319n/a def undo(self, *args):
320n/a if self.active:
321n/a self.active.menu_undo()
322n/a else:
323n/a EasyDialogs.Message("No active window?")
324n/a
325n/a def redo(self, *args):
326n/a if self.active:
327n/a self.active.menu_redo()
328n/a else:
329n/a EasyDialogs.Message("No active window?")
330n/a
331n/a def cut(self, *args):
332n/a if self.active:
333n/a self.active.menu_cut()
334n/a else:
335n/a EasyDialogs.Message("No active window?")
336n/a
337n/a def copy(self, *args):
338n/a if self.active:
339n/a self.active.menu_copy()
340n/a else:
341n/a EasyDialogs.Message("No active window?")
342n/a
343n/a def paste(self, *args):
344n/a if self.active:
345n/a self.active.menu_paste()
346n/a else:
347n/a EasyDialogs.Message("No active window?")
348n/a
349n/a def clear(self, *args):
350n/a if self.active:
351n/a self.active.menu_clear()
352n/a else:
353n/a EasyDialogs.Message("No active window?")
354n/a
355n/a #
356n/a # Other stuff
357n/a #
358n/a
359n/a def idle(self, event):
360n/a if self.active:
361n/a self.active.do_idle(event)
362n/a else:
363n/a Qd.SetCursor(Qd.GetQDGlobalsArrow())
364n/a
365n/adef main():
366n/a Mlte.TXNInitTextension(0)
367n/a try:
368n/a App = Mlted()
369n/a App.mainloop()
370n/a finally:
371n/a Mlte.TXNTerminateTextension()
372n/a
373n/aif __name__ == '__main__':
374n/a main()