#! /usr/bin/env python
###############################################################################
#                                                                             #
#   Copyright 2005 University of Cambridge Computer Laboratory.               #
#                                                                             #
#   This file is part of Nprobe.                                              #
#                                                                             #
#   Nprobe is free software; you can redistribute it and/or modify            #
#   it under the terms of the GNU General Public License as published by      #
#   the Free Software Foundation; either version 2 of the License, or         #
#   (at your option) any later version.                                       #
#                                                                             #
#   Nprobe is distributed in the hope that it will be useful,                 #
#   but WITHOUT ANY WARRANTY; without even the implied warranty of            #
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             #
#   GNU General Public License for more details.                              #
#                                                                             #
#   You should have received a copy of the GNU General Public License         #
#   along with Nprobe; if not, write to the Free Software                     #
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA #
#                                                                             #
###############################################################################


##############################################################################
## 
##
## Basic widgets for np use
## 
##
## 

############################################################################

from Tkinter import *
import os
from signal import *
import string

##############################################################################
##############################################################################

#
# Canvas scrollable?
#

NOSCROLL = 0x0
XSCROLL = 0x1
YSCROLL = 0x2
XYSCROLL = 0x3

############################################################################

#
# Scrollable Canvas 
#


class Can(Canvas):

    def wheelscroll(self, ev):
        #print 'scroll button %d' % (ev.num)
        if ev.num == 4:
            self.yview(SCROLL, -1, UNITS)
        else:
            self.yview(SCROLL, 1, UNITS)

    def __init__(self, master, xsize, ysize, xpos, ypos, scroll):
	Canvas.__init__(self, master)
	self.config(width=xsize, height=ysize,
			   background="white")
	if (scroll & XSCROLL):
	    self.scrollX = Scrollbar(self, orient=HORIZONTAL)
	    self['xscrollcommand'] = self.scrollX.set
	    #self.scrollX['command'] = self.xview
	    self.scrollX['command'] = self.xview
	    self.scrollX.pack(side=BOTTOM, fill=X)
	if (scroll & YSCROLL):
	    self.scrollY = Scrollbar(self, orient=VERTICAL)
	    self['yscrollcommand'] = self.scrollY.set
	    self.scrollY['command'] = self.yview
	    self.scrollY.pack(side=RIGHT, fill=Y)

            self.bind("<Button-4>", self.wheelscroll)
            self.bind("<Button-5>", self.wheelscroll)


	#self.place(x=xpos, y=ypos, anchor=NW, width=xsize, height=ysize)
	self.xpos = xpos
	self.ypos = ypos
	self.width = xsize
	self.ht = ysize

############################################################################

#
# Scrollable Canvas for packing
#


class PCan(Canvas):

    def wheelscroll(self, ev):
        #print 'scroll button %d' % (ev.num)
        if ev.num == 4:
            self.yview(SCROLL, -1, UNITS)
        else:
            self.yview(SCROLL, 1, UNITS)

    def __init__(self, master, scroll):
	Canvas.__init__(self, master)
	self.config(background="white")
	if (scroll & XSCROLL):
	    self.scrollX = Scrollbar(self, orient=HORIZONTAL)
	    self['xscrollcommand'] = self.scrollX.set
	    #self.scrollX['command'] = self.xview
	    self.scrollX['command'] = self.xview
	    self.scrollX.pack(side=BOTTOM, fill=X)
	if (scroll & YSCROLL):
	    self.scrollY = Scrollbar(self, orient=VERTICAL)
	    self['yscrollcommand'] = self.scrollY.set
	    self.scrollY['command'] = self.yview
	    self.scrollY.pack(side=RIGHT, fill=Y)

            self.bind("<Button-4>", self.wheelscroll)
            self.bind("<Button-5>", self.wheelscroll)


##############################################################################
##############################################################################

#
# Scrollable List Box for packing
#


class PListB(Listbox):

    def wheelscroll(self, ev):
        #print 'scroll button %d' % (ev.num)
        if ev.num == 4:
            self.yview(SCROLL, -1, UNITS)
        else:
            self.yview(SCROLL, 1, UNITS)

    def __init__(self, master, scroll):
	Listbox.__init__(self, master)
	self.config(background="white")
	if (scroll & XSCROLL):
	    self.scrollX = Scrollbar(self, orient=HORIZONTAL)
	    self['xscrollcommand'] = self.scrollX.set
	    #self.scrollX['command'] = self.xview
	    self.scrollX['command'] = self.xview
	    self.scrollX.pack(side=BOTTOM, fill=X)
	if (scroll & YSCROLL):
	    self.scrollY = Scrollbar(self, orient=VERTICAL)
	    self['yscrollcommand'] = self.scrollY.set
	    self.scrollY['command'] = self.yview
	    self.scrollY.pack(side=RIGHT, fill=Y)

            self.bind("<Button-4>", self.wheelscroll)
            self.bind("<Button-5>", self.wheelscroll)


##############################################################################
##############################################################################

#
# Toolbar Menu button
class BarButton(Menubutton):


    def __init__(self, master=None, **cnf):
	apply(Menubutton.__init__, (self, master), cnf)
	self.pack(side=LEFT, fill=Y)
	self.menu = Menu(self, name='menu')
	
	self.menu.configure(bg='grey')
	
	self['menu'] = self.menu


############################################################################
############################################################################

#
# Standard entry widget behaviour is to repond to <Backspace> by deleting the
# character *following* the cursor - fix this
#

class BetterEntry(Entry):

    def __init__(self, parent):

	Entry.__init__(self, parent)
	self.bind("<Delete>", self.bs_delete)

    def bs_delete(self, e):

	entry = e.widget
	entry.delete(entry.index(INSERT)-1)
	
	return "break" # don't propagate


############################################################################
############################################################################

#
# Dialogue box - underlying class
#



class Dialogue(Toplevel):

    def __init__(self, parent, title = None, msg = None, entries=None,
		 results=None):

	Toplevel.__init__(self, parent)
	self.transient(parent)
	
	if title:
	    self.title(title)

	self.msg = msg
	self.entries = entries
	    
	self.parent = parent
	
	self.results = results
	
	self.configure(bg='grey')
	
	body = Frame(self, bg='grey')
	self.initial_focus = self.body(body)
	body.pack(padx=5, pady=5)
	body.configure(bg='grey')
	
	self.buttonbox()
	
	self.grab_set()
	
	if not self.initial_focus:
	    self.initial_focus = self
	    
	self.protocol("WM_DELETE_WINDOW", self.cancel)

## 	print parent.winfo_rootx()
## 	print parent.winfo_rooty()
	ypos = parent.winfo_rooty()/2
## 	ypos = min([parent.winfo_rooty(), 900])
## 	print ypos
## 	print 'P ' + parent.geometry()
## 	print 'S1 ' + self.geometry()
	
	self.geometry("+%d+%d" % (parent.winfo_rootx(),ypos))
	self.initial_focus.focus_set()
	self.wait_window(self)
	
    #
    # construction hooks

    def body(self, master):
	# create dialog body.  return widget that should have
	# initial focus.  this method should be overridden
	
	pass
    
    def buttonbox(self):
	# add standard button box. override if you don't want the
	# standard buttons
	
	box = Frame(self)
	box.configure(bg='grey')
	
	w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
	w.pack(side=LEFT, padx=5, pady=5)
	w.configure(bg='grey')
	w = Button(box, text="Cancel", width=10, command=self.cancel)
	w.pack(side=LEFT, padx=5, pady=5)
	w.configure(bg='grey')
	
	self.bind("&lt;Return>", self.ok)
	self.bind("&lt;Escape>", self.cancel)
	
	box.pack()
	
    #
    # standard button semantics
    
    def ok(self, event=None):
	
	if not self.validate():
	    self.initial_focus.focus_set() # put focus back
	    return

	self.withdraw()
	self.update_idletasks()
	self.apply()
	
	self.cancel()
	
    def cancel(self, event=None):
	
	# put focus back to the parent window
	self.parent.focus_set()
	self.destroy()
	
    #
    # command hooks
    
    def validate(self):
	
	return 1 # override
    
    def apply(self):
	
	pass # override
	    
	     
##############################################################################
##############################################################################
	
class TwoEntryDialogue(Dialogue):
    
    def body(self, master):
	
	Label(master, text="First:").grid(row=0)
	Label(master, text="Second:").grid(row=1)
	
	self.e1 = BetterEntry(master)
	self.e2 = BetterEntry(master)
	
	self.e1.grid(row=0, column=1)
	self.e2.grid(row=1, column=1)
	return self.e1 # initial focus
    
    def apply(self):
	first = self.e1.get()
	second = self.e2.get()
	print first, second # or something 


#foo.delete(foo.index(INSERT))  
	     
##############################################################################
############################################################################## 

testroot = None

def callback():
    #print "called the callback!"
    global testroot
    d = TwoEntryDialogue(testroot)

def quit():
    sys.exit(0)

def handle_sigint(n, f):
    print 'SIGINT'
    #handle_sigint_def(n, f)
    sys.exit(0)

def main():

    global testroot


    testroot = Tk()



    handle_sigint_def = signal(SIGINT, handle_sigint)

    # create a toolbar
    toolbar = Frame(testroot)

    b = Button(toolbar, text="dialogue", width=6, command=callback)
    b.pack(side=LEFT, padx=2, pady=2)
    
    b = Button(toolbar, text="quit", width=6, command=quit)
    b.pack(side=LEFT, padx=2, pady=2)
    
    toolbar.pack(side=TOP, fill=X)
    
    mainloop()
	    
	     
##############################################################################


# Call main when run as script
if __name__ == '__main__':
        main()
