ยปCore Development>Code coverage>Mac/Demo/textedit/ped.py

Python code coverage for Mac/Demo/textedit/ped.py

#countcontent
1n/a# A minimal text editor.
2n/a#
3n/a# To be done:
4n/a# - Update viewrect after resize
5n/a# - Handle horizontal scrollbar correctly
6n/a# - Functionality: find, etc.
7n/a
8n/afrom Carbon.Menu import DrawMenuBar
9n/afrom FrameWork import *
10n/afrom Carbon import Win
11n/afrom Carbon import Qd
12n/afrom Carbon import TE
13n/afrom Carbon import Scrap
14n/aimport os
15n/aimport macfs
16n/a
17n/aclass TEWindow(ScrolledWindow):
18n/a def open(self, path, name, data):
19n/a self.path = path
20n/a self.name = name
21n/a r = windowbounds(400, 400)
22n/a w = Win.NewWindow(r, name, 1, 0, -1, 1, 0)
23n/a self.wid = w
24n/a x0, y0, x1, y1 = self.wid.GetWindowPort().GetPortBounds()
25n/a x0 = x0 + 4
26n/a y0 = y0 + 4
27n/a x1 = x1 - 20
28n/a y1 = y1 - 20
29n/a vr = dr = x0, y0, x1, y1
30n/a ##vr = 4, 0, r[2]-r[0]-15, r[3]-r[1]-15
31n/a ##dr = (0, 0, vr[2], 0)
32n/a Qd.SetPort(w)
33n/a Qd.TextFont(4)
34n/a Qd.TextSize(9)
35n/a self.ted = TE.TENew(dr, vr)
36n/a self.ted.TEAutoView(1)
37n/a self.ted.TESetText(data)
38n/a w.DrawGrowIcon()
39n/a self.scrollbars()
40n/a self.changed = 0
41n/a self.do_postopen()
42n/a self.do_activate(1, None)
43n/a
44n/a def do_idle(self):
45n/a self.ted.TEIdle()
46n/a
47n/a def getscrollbarvalues(self):
48n/a dr = self.ted.destRect
49n/a vr = self.ted.viewRect
50n/a height = self.ted.nLines * self.ted.lineHeight
51n/a vx = self.scalebarvalue(dr[0], dr[2]-dr[0], vr[0], vr[2])
52n/a vy = self.scalebarvalue(dr[1], dr[1]+height, vr[1], vr[3])
53n/a print dr, vr, height, vx, vy
54n/a return None, vy
55n/a
56n/a def scrollbar_callback(self, which, what, value):
57n/a if which == 'y':
58n/a if what == 'set':
59n/a height = self.ted.nLines * self.ted.lineHeight
60n/a cur = self.getscrollbarvalues()[1]
61n/a delta = (cur-value)*height/32767
62n/a if what == '-':
63n/a delta = self.ted.lineHeight
64n/a elif what == '--':
65n/a delta = (self.ted.viewRect[3]-self.ted.lineHeight)
66n/a if delta <= 0:
67n/a delta = self.ted.lineHeight
68n/a elif what == '+':
69n/a delta = -self.ted.lineHeight
70n/a elif what == '++':
71n/a delta = -(self.ted.viewRect[3]-self.ted.lineHeight)
72n/a if delta >= 0:
73n/a delta = -self.ted.lineHeight
74n/a self.ted.TEPinScroll(0, delta)
75n/a print 'SCROLL Y', delta
76n/a else:
77n/a pass # No horizontal scrolling
78n/a
79n/a def do_activate(self, onoff, evt):
80n/a print "ACTIVATE", onoff
81n/a ScrolledWindow.do_activate(self, onoff, evt)
82n/a if onoff:
83n/a self.ted.TEActivate()
84n/a self.parent.active = self
85n/a self.parent.updatemenubar()
86n/a else:
87n/a self.ted.TEDeactivate()
88n/a
89n/a def do_update(self, wid, event):
90n/a Qd.EraseRect(wid.GetWindowPort().GetPortBounds())
91n/a self.ted.TEUpdate(wid.GetWindowPort().GetPortBounds())
92n/a self.updatescrollbars()
93n/a
94n/a def do_contentclick(self, local, modifiers, evt):
95n/a shifted = (modifiers & 0x200)
96n/a self.ted.TEClick(local, shifted)
97n/a self.updatescrollbars()
98n/a self.parent.updatemenubar()
99n/a
100n/a def do_char(self, ch, event):
101n/a self.ted.TESelView()
102n/a self.ted.TEKey(ord(ch))
103n/a self.changed = 1
104n/a self.updatescrollbars()
105n/a self.parent.updatemenubar()
106n/a
107n/a def close(self):
108n/a if self.changed:
109n/a save = EasyDialogs.AskYesNoCancel('Save window "%s" before closing?'%self.name, 1)
110n/a if save > 0:
111n/a self.menu_save()
112n/a elif save < 0:
113n/a return
114n/a if self.parent.active == self:
115n/a self.parent.active = None
116n/a self.parent.updatemenubar()
117n/a del self.ted
118n/a self.do_postclose()
119n/a
120n/a def menu_save(self):
121n/a if not self.path:
122n/a self.menu_save_as()
123n/a return # Will call us recursively
124n/a print 'Saving to ', self.path
125n/a dhandle = self.ted.TEGetText()
126n/a data = dhandle.data
127n/a fp = open(self.path, 'wb') # NOTE: wb, because data has CR for end-of-line
128n/a fp.write(data)
129n/a if data[-1] <> '\r': fp.write('\r')
130n/a fp.close()
131n/a self.changed = 0
132n/a
133n/a def menu_save_as(self):
134n/a path = EasyDialogs.AskFileForSave(message='Save as:')
135n/a if not path: return
136n/a self.path = path
137n/a self.name = os.path.split(self.path)[-1]
138n/a self.wid.SetWTitle(self.name)
139n/a self.menu_save()
140n/a
141n/a def menu_cut(self):
142n/a self.ted.TESelView()
143n/a self.ted.TECut()
144n/a if hasattr(Scrap, 'ZeroScrap'):
145n/a Scrap.ZeroScrap()
146n/a else:
147n/a Scrap.ClearCurrentScrap()
148n/a TE.TEToScrap()
149n/a self.updatescrollbars()
150n/a self.parent.updatemenubar()
151n/a self.changed = 1
152n/a
153n/a def menu_copy(self):
154n/a self.ted.TECopy()
155n/a if hasattr(Scrap, 'ZeroScrap'):
156n/a Scrap.ZeroScrap()
157n/a else:
158n/a Scrap.ClearCurrentScrap()
159n/a TE.TEToScrap()
160n/a self.updatescrollbars()
161n/a self.parent.updatemenubar()
162n/a
163n/a def menu_paste(self):
164n/a TE.TEFromScrap()
165n/a self.ted.TESelView()
166n/a self.ted.TEPaste()
167n/a self.updatescrollbars()
168n/a self.parent.updatemenubar()
169n/a self.changed = 1
170n/a
171n/a def menu_clear(self):
172n/a self.ted.TESelView()
173n/a self.ted.TEDelete()
174n/a self.updatescrollbars()
175n/a self.parent.updatemenubar()
176n/a self.changed = 1
177n/a
178n/a def have_selection(self):
179n/a return (self.ted.selStart < self.ted.selEnd)
180n/a
181n/aclass Ped(Application):
182n/a def __init__(self):
183n/a Application.__init__(self)
184n/a self.num = 0
185n/a self.active = None
186n/a self.updatemenubar()
187n/a
188n/a def makeusermenus(self):
189n/a self.filemenu = m = Menu(self.menubar, "File")
190n/a self.newitem = MenuItem(m, "New window", "N", self.open)
191n/a self.openitem = MenuItem(m, "Open...", "O", self.openfile)
192n/a self.closeitem = MenuItem(m, "Close", "W", self.closewin)
193n/a m.addseparator()
194n/a self.saveitem = MenuItem(m, "Save", "S", self.save)
195n/a self.saveasitem = MenuItem(m, "Save as...", "", self.saveas)
196n/a m.addseparator()
197n/a self.quititem = MenuItem(m, "Quit", "Q", self.quit)
198n/a
199n/a self.editmenu = m = Menu(self.menubar, "Edit")
200n/a self.undoitem = MenuItem(m, "Undo", "Z", self.undo)
201n/a self.cutitem = MenuItem(m, "Cut", "X", self.cut)
202n/a self.copyitem = MenuItem(m, "Copy", "C", self.copy)
203n/a self.pasteitem = MenuItem(m, "Paste", "V", self.paste)
204n/a self.clearitem = MenuItem(m, "Clear", "", self.clear)
205n/a
206n/a # Not yet implemented:
207n/a self.undoitem.enable(0)
208n/a
209n/a # Groups of items enabled together:
210n/a self.windowgroup = [self.closeitem, self.saveitem, self.saveasitem, self.editmenu]
211n/a self.focusgroup = [self.cutitem, self.copyitem, self.clearitem]
212n/a self.windowgroup_on = -1
213n/a self.focusgroup_on = -1
214n/a self.pastegroup_on = -1
215n/a
216n/a def updatemenubar(self):
217n/a changed = 0
218n/a on = (self.active <> None)
219n/a if on <> self.windowgroup_on:
220n/a for m in self.windowgroup:
221n/a m.enable(on)
222n/a self.windowgroup_on = on
223n/a changed = 1
224n/a if on:
225n/a # only if we have an edit menu
226n/a on = self.active.have_selection()
227n/a if on <> self.focusgroup_on:
228n/a for m in self.focusgroup:
229n/a m.enable(on)
230n/a self.focusgroup_on = on
231n/a changed = 1
232n/a if hasattr(Scrap, 'InfoScrap'):
233n/a on = (Scrap.InfoScrap()[0] <> 0)
234n/a else:
235n/a flavors = Scrap.GetCurrentScrap().GetScrapFlavorInfoList()
236n/a for tp, info in flavors:
237n/a if tp == 'TEXT':
238n/a on = 1
239n/a break
240n/a else:
241n/a on = 0
242n/a if on <> self.pastegroup_on:
243n/a self.pasteitem.enable(on)
244n/a self.pastegroup_on = on
245n/a changed = 1
246n/a if changed:
247n/a DrawMenuBar()
248n/a
249n/a #
250n/a # Apple menu
251n/a #
252n/a
253n/a def do_about(self, id, item, window, event):
254n/a EasyDialogs.Message("A simple single-font text editor")
255n/a
256n/a #
257n/a # File menu
258n/a #
259n/a
260n/a def open(self, *args):
261n/a self._open(0)
262n/a
263n/a def openfile(self, *args):
264n/a self._open(1)
265n/a
266n/a def _open(self, askfile):
267n/a if askfile:
268n/a path = EasyDialogs.AskFileForOpen(typeList=('TEXT',))
269n/a if not path:
270n/a return
271n/a name = os.path.split(path)[-1]
272n/a try:
273n/a fp = open(path, 'rb') # NOTE binary, we need cr as end-of-line
274n/a data = fp.read()
275n/a fp.close()
276n/a except IOError, arg:
277n/a EasyDialogs.Message("IOERROR: %r" % (arg,))
278n/a return
279n/a else:
280n/a path = None
281n/a name = "Untitled %d"%self.num
282n/a data = ''
283n/a w = TEWindow(self)
284n/a w.open(path, name, data)
285n/a self.num = self.num + 1
286n/a
287n/a def closewin(self, *args):
288n/a if self.active:
289n/a self.active.close()
290n/a else:
291n/a EasyDialogs.Message("No active window?")
292n/a
293n/a def save(self, *args):
294n/a if self.active:
295n/a self.active.menu_save()
296n/a else:
297n/a EasyDialogs.Message("No active window?")
298n/a
299n/a def saveas(self, *args):
300n/a if self.active:
301n/a self.active.menu_save_as()
302n/a else:
303n/a EasyDialogs.Message("No active window?")
304n/a
305n/a
306n/a def quit(self, *args):
307n/a for w in self._windows.values():
308n/a w.close()
309n/a if self._windows:
310n/a return
311n/a self._quit()
312n/a
313n/a #
314n/a # Edit menu
315n/a #
316n/a
317n/a def undo(self, *args):
318n/a pass
319n/a
320n/a def cut(self, *args):
321n/a if self.active:
322n/a self.active.menu_cut()
323n/a else:
324n/a EasyDialogs.Message("No active window?")
325n/a
326n/a def copy(self, *args):
327n/a if self.active:
328n/a self.active.menu_copy()
329n/a else:
330n/a EasyDialogs.Message("No active window?")
331n/a
332n/a def paste(self, *args):
333n/a if self.active:
334n/a self.active.menu_paste()
335n/a else:
336n/a EasyDialogs.Message("No active window?")
337n/a
338n/a def clear(self, *args):
339n/a if self.active:
340n/a self.active.menu_clear()
341n/a else:
342n/a EasyDialogs.Message("No active window?")
343n/a
344n/a #
345n/a # Other stuff
346n/a #
347n/a
348n/a def idle(self, *args):
349n/a if self.active:
350n/a self.active.do_idle()
351n/a else:
352n/a Qd.SetCursor(Qd.GetQDGlobalsArrow())
353n/a
354n/adef main():
355n/a App = Ped()
356n/a App.mainloop()
357n/a
358n/aif __name__ == '__main__':
359n/a main()