#
# $Header: /usr/local/cvsroot/pythondoc/gui.py,v 1.4 1999/05/01 01:03:40 daniel Exp $
#
# Copyright (C) Daniel Larsson
# All Rights Reserved.
#
# See copyright notice in the file 'LICENSE.TXT', which should have accompanied
# this distribution.
#

"""Tkinter based GUI for pythondoc.

Requires pmw!
"""

__author__ = "Daniel Larsson, Daniel.Larsson@telia.com"

DOWNLOAD_INFO = """
pythondoc GUI needs the following components to work:

tkFileDialog - Fetch it from Fredrik Lundh's home page at
               http://starship.skyport.net/crew/fredrik

Pmw -          Peter Munnings' and Greg McFarlane's Python megawidgets.
               http://www.dscpl.com.au/pmw
"""

COPYRIGHT = "Copyright 1998 %s" % __author__

CONTACT = """
Email: Daniel.Larsson@telia.com
WWW: http://starship.python.net/crew/danilo/pythondoc
"""

import Tkinter, threading

try:
    import Pmw
    import tkFileDialog
except ImportError:
    print DOWNLOAD_INFO
    import sys
    sys.exit(-1)

# pythondoc modules
import pythondoc, version, options, geninfo

Pmw.aboutversion(version.__version__)
Pmw.aboutcopyright(COPYRIGHT)
Pmw.aboutcontact(CONTACT)

class _Struct:
    pass

class MainWindow(Tkinter.Toplevel):

    def __init__(self, master, startup_display=None):
	Tkinter.Toplevel.__init__(self, master)
	self.withdraw()

	self.startup_display = startup_display

	self.__title = "%s, %s" % ("pythondoc", version.__version__)
	self.title(self.__title)
	
	self.__menubar()
	self.__bindings()
	self.__make_children()

	# The about dialog
	self.__about_dlg = Pmw.AboutDialog(master,
					   applicationname="pythondoc")
	self.__about_dlg.withdraw()
	self.deiconify()

    def __make_children(self):
	# Used to store references to GUI controls
	self.__settings = {}

	self.__notebook = Pmw.NoteBookR(self)
	self.__notebook.add("main", label="Main")
	page = self.__notebook.main
	self.__setup_formatter_page(page)
	self.__notebook.pack(expand=1, fill='both')

	import formatters.format_init
	for formatter in formatters.format_init.formatters.keys():
	    if formatter[0] != "_":
		self.__notebook.add(formatter, label=formatter)
	        page = getattr(self.__notebook, formatter)
	        self.__setup_formatter_page(page)

	self.__notebook.add('modules', label="Modules")
	self.__setup_modules_page(self.__notebook.modules)

    def __setup_formatter_page(self, page):
        frame = page.interior()
        boolframe = Tkinter.Frame(frame)
        boolframe.pack(expand=1, fill='x')
        dirframe = Tkinter.Frame(frame)
        dirframe.pack(expand=1, fill='x')
        stringframe = Tkinter.Frame(frame)
        stringframe.pack(expand=1, fill='x')
        enumframe = Tkinter.Frame(frame)
        enumframe.pack(expand=1, fill='x')
        intframe = Tkinter.Frame(frame)
        intframe.pack(expand=1, fill='x')

	# Store settings for this page
	self.__settings[page.pagename] = settings = {}

        if page.pagename != 'main':
	    var = Tkinter.IntVar()
	    check = Tkinter.Checkbutton(boolframe,
					text="Generate %s" % page.pagename,
					variable=var)
	    check.pack(anchor='w')
	    settings['check'] = var.get

	opts = options.options().options.get(page.pagename, {})
	for key, (type, description, default, values) in opts.items():
	    if type == options.Options.BOOL:
		var = Tkinter.IntVar()
	        w = Tkinter.Checkbutton(boolframe,
					text=description,
					variable=var)
	        if default:
	            w.select()
		w.get = var.get
	    elif type in (options.Options.STRING, options.Options.URL):
	        w = Pmw.EntryField(stringframe, labelpos='w',
	                           label_text=description, value=default)
	    elif type == options.Options.INT:
	        w = Pmw.EntryField(intframe,
	        		   labelpos='w',
	                           label_text=description,
	                           value=default,
	                           validate=Pmw.integervalidator)
	    elif type in (options.Options.FILE, options.Options.DIR):
	        w = Tkinter.Frame(dirframe)
	        entry = Pmw.EntryField(w, labelpos='w', value=default, label_text=description)
	        entry.pack(side='left')
	        button = Tkinter.Button(w, text="...")
	        button.pack(side='left')
		w.get = entry.get
	    elif type == options.Options.ENUM:
	        w = Pmw.OptionMenu(enumframe, labelpos='w',
	                           label_text=description,
	                           items=values,
	                           initialitem=list(values).index(default))
	    else:
	        w = Tkinter.Label(frame, text=description)

	    settings[key] = w.get
	    w.pack(anchor="w")

    def __setup_modules_page(self, page):
        frame = page.interior()
	lframe = Tkinter.Frame(frame)
	lframe.pack(side='left')
	self.modules = Pmw.ScrolledListBox(lframe)
	self.modules.pack(anchor="w")
	w = Tkinter.Frame(lframe)
	w.pack(anchor="w")
	self.module = entry = Pmw.EntryField(w, labelpos='w',
					     command=self.__add_module_cmd)
	entry.pack(side='left', anchor='w')
	button = Tkinter.Button(w, text="...", command=self.__open_cmd)
	button.pack(side='left')

	rframe = Tkinter.Frame(frame)
	rframe.pack(side='left', anchor='nw')
	Tkinter.Label(rframe, justify='left', text="Enter module/package\nnames, or file paths\nfor the modules you\nwant to document").pack()

    def __menubar(self):
	menub = Tkinter.Menu(self, tearoff=Tkinter.NO)
	menu = Tkinter.Menu(menub, tearoff=Tkinter.NO)
	menub.add_cascade(label='File', underline=0, menu=menu)

	menu.add_command(label='Make docs',
			 command=self.__makedocs_cmd,
			 accelerator='Ctrl+M')
	menu.add_separator()
	menu.add_command(label='Exit',
			 command=self.__exit_cmd,
			 accel='Ctrl+X')

	menu = Tkinter.Menu(menub, tearoff=Tkinter.NO)
	menub.add_cascade(label='Help', underline=0, menu=menu)

	menu.add_command(label='About...', command=self.__about)

	self.configure(menu=menub)

    def __bindings(self):
	self.bind('<Control-m>',self.__makedocs_cmd)
	self.bind_all('<Control-x>',self.__exit_cmd)

    def __about(self):
	self.__about_dlg.activate()

    def __open_cmd(self, event=None):
	from tkFileDialog import askopenfilename
	filename = askopenfilename(defaultextension='.py',
				   filetypes=(('Python file', '.py'),),
				   parent = self,
				   title = "Open File")

	if not filename: return
	self.module.setentry(filename)

    def __add_module_cmd(self, event=None):
	self.modules.insert('end', self.module.get())
	self.module.setentry('')

    def __makedocs_cmd(self, event=None):
	formats = []
	for extension, settings in self.__settings.items():
	    for key, value in settings.items():
		if key == 'check':
		    pythondoc.add_formatter(extension, formats)
		else:
		    options.options().add_value('%s_%s' % (extension, key),
						value())

	modules = map(pythondoc.path2module, self.modules.get())
	

	self.genthread = threading.Thread(target=pythondoc.generate_pages,
					  args=(modules, formats),
					  verbose=1)
	self.dialog = d = Pmw.TextDialog(self, title="Document generation status",
					 text_width=70, text_height=1,
					 buttons=('Cancel',),
					 command=self.__stop_gen_cmd)
	d.insert('end', "Starting doc generation")
	d.configure(text_state='disabled')
	self.genthread.start()
	d.after(200, self.__update_info_cmd)

    def __stop_gen_cmd(self, button):
	geninfo.stop()

    def __update_info_cmd(self):
	if not self.genthread.isAlive():
	    self.dialog.destroy()
	else:
	    self.dialog.settext(geninfo.get_message())
	    self.dialog.after(200, self.__update_info_cmd)

    def __exit_cmd(self, event=None):
	self.tk.quit()


def run(formatters=None):
    root = Tkinter.Tk(className='pythondoc')
    root.withdraw()

    m = MainWindow(root)
    root.mainloop()

#
# $Log: gui.py,v $
# Revision 1.4  1999/05/01 01:03:40  daniel
# New file. Implements the Tkinter GUI.
#
# 
