home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyos2bin.zip / Demo / tkinter / www / www12.py < prev    next >
Text File  |  1996-11-27  |  5KB  |  211 lines

  1. #! /usr/bin/env python
  2.  
  3. # www12.py -- display the contents of a URL in a Text widget
  4. # - set window title
  5. # - make window resizable
  6. # - update display while reading
  7. # - vertical scroll bar
  8. # - rewritten as class
  9. # - editable url entry and reload button
  10. # - error dialog
  11. # - menu bar; added 'master' option to constructor
  12.  
  13. import sys
  14. import urllib
  15. from Tkinter import *
  16. import Dialog
  17.  
  18. def main():
  19.     if len(sys.argv) != 2 or sys.argv[1][:1] == '-':
  20.         print "Usage:", sys.argv[0], "url"
  21.         sys.exit(2)
  22.     url = sys.argv[1]
  23.     tk = Tk()
  24.     tk.withdraw()
  25.     viewer = Viewer(tk)
  26.     viewer.load(url)
  27.     viewer.go()
  28.  
  29. class Viewer:
  30.  
  31.     def __init__(self, master = None):
  32.         # Create root window
  33.         if master is None:
  34.             self.root = self.master = Tk()
  35.         else:
  36.             self.master = master
  37.             self.root = Toplevel(self.master)
  38.         self.root.minsize(1, 1)
  39.  
  40.         # Create menu bar
  41.         self.mbar = Frame(self.root,
  42.                   {'relief': 'raised',
  43.                    'border': 2})
  44.         self.mbar.pack({'fill': 'x'})
  45.  
  46.         # Create File menu
  47.         self.filebutton = Menubutton(self.mbar, {'text': 'File'})
  48.         self.filebutton.pack({'side': 'left'})
  49.  
  50.         self.filemenu = Menu(self.filebutton)
  51.         self.filebutton['menu'] = self.filemenu
  52.  
  53.         # Create Edit menu
  54.         self.editbutton = Menubutton(self.mbar, {'text': 'Edit'})
  55.         self.editbutton.pack({'side': 'left'})
  56.  
  57.         self.editmenu = Menu(self.editbutton)
  58.         self.editbutton['menu'] = self.editmenu
  59.  
  60.         # Magic so you can swipe from one button to the next
  61.         self.mbar.tk_menuBar(self.filebutton, self.editbutton)
  62.  
  63.         # Populate File menu
  64.         self.filemenu.add('command', {'label': 'New',
  65.                           'command': self.new_command})
  66.         self.filemenu.add('command', {'label': 'Open...',
  67.                           'command': self.open_command})
  68.         self.filemenu.add('command', {'label': 'Clone',
  69.                           'command': self.clone_command})
  70.         self.filemenu.add('separator')
  71.         self.filemenu.add('command', {'label': 'Close',
  72.                           'command': self.close_command})
  73.         self.filemenu.add('command', {'label': 'Quit',
  74.                           'command': self.quit_command})
  75.  
  76.         # Populate Edit menu
  77.         pass
  78.  
  79.         # Create topframe for the entry and button
  80.         self.topframe = Frame(self.root)
  81.         self.topframe.pack({'fill': 'x'})
  82.  
  83.         # Create a label in front of the entry
  84.         self.urllabel = Label(self.topframe, {'text': 'URL:'})
  85.         self.urllabel.pack({'side': 'left'})
  86.  
  87.         # Create the entry containing the URL
  88.         self.entry = Entry(self.topframe,
  89.                    {'relief': 'sunken', 'border': 2})
  90.         self.entry.pack({'side': 'left', 'fill': 'x', 'expand': 1})
  91.         self.entry.bind('<Return>', self.loadit)
  92.  
  93.         # Create the button
  94.         self.reload = Button(self.topframe,
  95.                      {'text': 'Reload',
  96.                       'command': self.reload})
  97.         self.reload.pack({'side': 'right'})
  98.  
  99.         # Create botframe for the text and scrollbar
  100.         self.botframe = Frame(self.root)
  101.         self.botframe.pack({'fill': 'both', 'expand': 1})
  102.  
  103.         # The Scrollbar *must* be created first
  104.         self.vbar = Scrollbar(self.botframe)
  105.         self.vbar.pack({'fill': 'y', 'side': 'right'})
  106.         self.text = Text(self.botframe)
  107.         self.text.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
  108.  
  109.         # Link Text widget and Scrollbar
  110.         self.text['yscrollcommand'] = (self.vbar, 'set')
  111.         self.vbar['command'] = (self.text, 'yview')
  112.  
  113.         self.url = None
  114.  
  115.     def load(self, url):
  116.         # Load a new URL into the window
  117.         fp, url = self.urlopen(url)
  118.         if not fp:
  119.             return
  120.  
  121.         self.url = url
  122.  
  123.         self.root.title(url)
  124.  
  125.         self.entry.delete('0', 'end')
  126.         self.entry.insert('end', url)
  127.  
  128.         self.text.delete('0.0', 'end')
  129.  
  130.         while 1:
  131.             line = fp.readline()
  132.             if not line: break
  133.             if line[-2:] == '\r\n': line = line[:-2] + '\n'
  134.             self.text.insert('end', line)
  135.             self.root.update_idletasks()
  136.  
  137.         fp.close()
  138.  
  139.     def urlopen(self, url):
  140.         # Open a URL --
  141.         # return (fp, url) if successful
  142.         # display dialog and return (None, url) for errors
  143.         try:
  144.             fp = urllib.urlopen(url)
  145.         except IOError, msg:
  146.             import types
  147.             if type(msg) == types.TupleType and len(msg) == 4:
  148.                 if msg[1] == 302:
  149.                     m = msg[3]
  150.                     if m.has_key('location'):
  151.                         url = m['location']
  152.                         return self.urlopen(url)
  153.                     elif m.has_key('uri'):
  154.                         url = m['uri']
  155.                         return self.urlopen(url)
  156.             self.errordialog(IOError, msg)
  157.             fp = None
  158.         return fp, url
  159.  
  160.     def errordialog(self, exc, msg):
  161.         # Display an error dialog -- return when the user clicks OK
  162.         Dialog.Dialog(self.root, {
  163.             'text': str(msg),
  164.             'title': exc,
  165.             'bitmap': 'error',
  166.             'default': 0,
  167.             'strings': ('OK',),
  168.             })
  169.  
  170.     def go(self):
  171.         # Start Tk main loop
  172.         self.root.mainloop()
  173.  
  174.     def reload(self, *args):
  175.         # Callback for Reload button
  176.         if self.url:
  177.             self.load(self.url)
  178.  
  179.     def loadit(self, *args):
  180.         # Callback for <Return> event in entry
  181.         self.load(self.entry.get())
  182.  
  183.     def new_command(self):
  184.         # File/New...
  185.         Viewer(self.master)
  186.  
  187.     def clone_command(self):
  188.         # File/Clone
  189.         v = Viewer(self.master)
  190.         v.load(self.url)
  191.  
  192.     def open_command(self):
  193.         # File/Open...
  194.         print "File/Open...: Not implemented"
  195.  
  196.     def close_command(self):
  197.         # File/Close
  198.         self.destroy()
  199.  
  200.     def quit_command(self):
  201.         # File/Quit
  202.         self.root.quit()
  203.  
  204.     def destroy(self):
  205.         # Destroy this window
  206.         self.root.destroy()
  207.         if self.master is not self.root and not self.master.children:
  208.             self.master.quit()
  209.  
  210. main()
  211.