3 # www13.py -- display the contents of a URL in a Text widget
5 # - make window resizable
6 # - update display while reading
7 # - vertical scroll bar
9 # - editable url entry and reload button
11 # - menu bar; added 'master' option to constructor
22 if len(sys
.argv
) != 2 or sys
.argv
[1][:1] == '-':
23 print "Usage:", sys
.argv
[0], "url"
34 def __init__(self
, master
= None):
37 self
.root
= self
.master
= Tk()
40 self
.root
= Toplevel(self
.master
)
41 self
.root
.minsize(1, 1)
44 self
.mbar
= Frame(self
.root
,
47 self
.mbar
.pack({'fill': 'x'})
50 self
.filebutton
= Menubutton(self
.mbar
, {'text': 'File'})
51 self
.filebutton
.pack({'side': 'left'})
53 self
.filemenu
= Menu(self
.filebutton
)
54 self
.filebutton
['menu'] = self
.filemenu
57 self
.editbutton
= Menubutton(self
.mbar
, {'text': 'Edit'})
58 self
.editbutton
.pack({'side': 'left'})
60 self
.editmenu
= Menu(self
.editbutton
)
61 self
.editbutton
['menu'] = self
.editmenu
63 # Magic so you can swipe from one button to the next
64 self
.mbar
.tk_menuBar(self
.filebutton
, self
.editbutton
)
67 self
.filemenu
.add('command', {'label': 'New',
68 'command': self
.new_command
})
69 self
.filemenu
.add('command', {'label': 'Open...',
70 'command': self
.open_command
})
71 self
.filemenu
.add('command', {'label': 'Clone',
72 'command': self
.clone_command
})
73 self
.filemenu
.add('separator')
74 self
.filemenu
.add('command', {'label': 'Close',
75 'command': self
.close_command
})
76 self
.filemenu
.add('command', {'label': 'Quit',
77 'command': self
.quit_command
})
82 # Create topframe for the entry and button
83 self
.topframe
= Frame(self
.root
)
84 self
.topframe
.pack({'fill': 'x'})
86 # Create a label in front of the entry
87 self
.urllabel
= Label(self
.topframe
, {'text': 'URL:'})
88 self
.urllabel
.pack({'side': 'left'})
90 # Create the entry containing the URL
91 self
.entry
= Entry(self
.topframe
,
92 {'relief': 'sunken', 'border': 2})
93 self
.entry
.pack({'side': 'left', 'fill': 'x', 'expand': 1})
94 self
.entry
.bind('<Return>', self
.loadit
)
97 self
.reload = Button(self
.topframe
,
99 'command': self
.reload})
100 self
.reload.pack({'side': 'right'})
102 # Create botframe for the text and scrollbar
103 self
.botframe
= Frame(self
.root
)
104 self
.botframe
.pack({'fill': 'both', 'expand': 1})
106 # The Scrollbar *must* be created first
107 self
.vbar
= Scrollbar(self
.botframe
)
108 self
.vbar
.pack({'fill': 'y', 'side': 'right'})
109 self
.text
= Text(self
.botframe
)
110 self
.text
.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
112 # Link Text widget and Scrollbar
113 self
.text
['yscrollcommand'] = (self
.vbar
, 'set')
114 self
.vbar
['command'] = (self
.text
, 'yview')
119 # Load a new URL into the window
120 fp
, url
= self
.urlopen(url
)
128 self
.entry
.delete('0', 'end')
129 self
.entry
.insert('end', url
)
131 self
.text
.delete('0.0', 'end')
133 f
= tkfmt
.TkFormatter(self
.text
)
134 p
= htmllib
.FormattingParser(f
, htmllib
.X11Stylesheet
)
139 if line
[-2:] == '\r\n': line
= line
[:-2] + '\n'
141 self
.root
.update_idletasks()
147 def urlopen(self
, url
):
149 # return (fp, url) if successful
150 # display dialog and return (None, url) for errors
152 fp
= urllib
.urlopen(url
)
155 if type(msg
) == types
.TupleType
and len(msg
) == 4:
158 if m
.has_key('location'):
160 return self
.urlopen(url
)
161 elif m
.has_key('uri'):
163 return self
.urlopen(url
)
164 self
.errordialog(IOError, msg
)
168 def errordialog(self
, exc
, msg
):
169 # Display an error dialog -- return when the user clicks OK
170 Dialog
.Dialog(self
.root
, {
182 def reload(self
, *args
):
183 # Callback for Reload button
187 def loadit(self
, *args
):
188 # Callback for <Return> event in entry
189 self
.load(self
.entry
.get())
191 def new_command(self
):
195 def clone_command(self
):
197 v
= Viewer(self
.master
)
200 def open_command(self
):
202 print "File/Open...: Not implemented"
204 def close_command(self
):
208 def quit_command(self
):
213 # Destroy this window
215 if self
.master
is not self
.root
and not self
.master
.children
: