blob: 1091676a49205ff8065fad42e98c091d7dc66563 [file] [log] [blame]
Guido van Rossumf06ee5f1996-11-27 19:52:01 +00001#! /usr/bin/env python
Guido van Rossum9cf8f331992-03-30 10:54:51 +00002
3# A minimal single-window text editor using STDWIN's text objects.
4#
5# Usage: microedit file
6#
7# This is not intended as a real application but as an introduction
8# to STDWIN programming in Python, especially text objects.
9# Once you understand microedit.py, study miniedit.py to learn
10# about multiple windows and menus, cut and paste, etc.
11
12
13import sys
14import stdwin
15from stdwinevents import *
16
17
18# Main program
19#
20def main():
21 #
22 # Get the filename argument and read its contents as one very
23 # large string.
24 # An exception will terminate the program if there is no argument
25 # or if the file could not be read...
26 #
27 filename = sys.argv[1]
28 fp = open(filename, 'r')
29 contents = fp.read()
30 del fp # Close the file
31 #
32 # Create the window, using the filename as window title
33 #
34 window = stdwin.open(filename)
35 #
36 # Add a simple File menu to the window with two items
37 #
38 filemenu = window.menucreate('File')
39 filemenu.additem('Save', 'S') # Item 0 (shortcut Meta-S)
40 filemenu.additem('Save As...') # Item 1
41 #
42 # Create a text object occupying the entire window
43 # and fill it with the file's contents
44 #
45 corner = window.getwinsize() # (width, height)
46 area = (0, 0), corner # Rectangle as large as the window
47 text = window.textcreate(area)
48 text.settext(contents)
49 del contents # Get rid of contents object
50 fix_textsize(window, text) # Set document size accordingly
51 #
52 # Main event loop -- stop if a close request comes in.
53 #
54 # STDWIN applications should regularly call stdwin.getevent()
55 # otherwise the windows won't function as expected.
56 #
57 while 1:
58 #
59 # Get the next event
60 #
61 type, w, detail = e = stdwin.getevent()
62 #
63 # Event decoding switch
64 #
65 if type == WE_CLOSE:
66 break # Stop (no check for saved file!)
67 elif type == WE_SIZE:
68 #
69 # The window was resized --
70 # let the text object recompute the line breaks
71 # and change the document size accordingly,
72 # so scroll bars will work
73 #
74 fix_textsize(window, text)
75 elif type == WE_MENU:
76 #
77 # Execute a file menu request (our only menu)
78 #
79 menu, item = detail
80 if item == 0:
81 #
82 # "Save": save to the current filename
83 #
84 dummy = save_file(window, text, filename)
85 elif item == 1:
86 #
87 # "Save As": ask a new filename, save to it,
88 # and make it the current filename
89 #
90 # NB: askfile raises KeyboardInterrupt
91 # if the user cancels the dialog, hence
92 # the try statement
93 #
94 try:
95 newfile = stdwin.askfile( \
96 'Save as:', filename, 1)
97 except KeyboardInterrupt:
98 newfile = ''
99 if newfile:
100 if save_file(window, text, newfile):
101 filename = newfile
102 window.settitle(filename)
103 elif text.event(e):
104 #
105 # The text object has handled the event.
106 # Fix the document size if necessary.
107 # Note: this sometimes fixes the size
108 # unnecessarily, e.g., for arrow keys.
109 #
110 if type in (WE_CHAR, WE_COMMAND):
111 fix_docsize(window, text)
112
113
114# Save the window's contents to the filename.
115# If the open() fails, put up a warning message and return 0;
116# if the save succeeds, return 1.
117#
118def save_file(window, text, filename):
119 #
120 # Open the file for writing, handling exceptions
121 #
122 try:
123 fp = open(filename, 'w')
124 except RuntimeError:
125 stdwin.message('Cannot create ' + filename)
126 return 0
127 #
128 # Get the contents of the text object as one very long string
129 #
130 contents = text.gettext()
131 #
132 # Write the contents to the file
133 #
134 fp.write(contents)
135 #
136 # The file is automatically closed when this routine returns
137 #
138 return 1
139
140
141# Change the size of the text object to fit in the window,
142# and then fix the window's document size to fit around the text object.
143#
144def fix_textsize(window, text):
145 #
146 # Compute a rectangle as large as the window
147 #
148 corner = window.getwinsize() # (width, height)
149 area = (0, 0), (corner)
150 #
151 # Move the text object to this rectangle.
152 # Note: text.move() ignores the bottom coordinate!
153 #
154 text.move(area)
155 #
156 # Now fix the document size accordingly
157 #
158 fix_docsize(window, text)
159
160
161# Fix the document size, after the text has changed
162#
163def fix_docsize(window, text):
164 #
165 # Get the actual rectangle occupied by the text object.
166 # This has the same left, top and right, but a different bottom.
167 #
168 area = text.getrect()
169 #
170 # Compute the true height of the text object
171 #
172 origin, corner = area
173 width, height = corner
174 #
175 # Set the document height to the text object's height.
176 # The width is zero since we don't want a horizontal scroll bar.
177 #
178 window.setdocsize(0, height)
179
180
181# Once all functions are defined, call main()
182#
183main()