#!/usr/bin/env python 

#    Copyright (C) 2006 Pete Savage & Jordan Mantha
#    This file is part of gisomount.

#    gisomount 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.

#    gisomount 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 gisomount; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import sys 
import os
import subprocess
import string
import gisomount.config

try: 
   import pygtk 
   pygtk.require("2.0") 

except: 
   pass 

try: 
   import gtk 
   import gtk.glade 
   import gobject

except: 
   print "GTK is not installed" 
   sys.exit(1) 

#Checks to see if program has been run with setuid of 0, if not shout at user
if os.geteuid() != 0:
   dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,"You need to be root to run this program")
   dialog.run()
   dialog.destroy()
   sys.exit(1)

#GUI initialisation script
class gui: 
   
   def __init__(self):
      #Main initialisation script for the application 
      self.isos=[info() for x in range(5)]
      self.treestore=[0 for x in range(5)]
      if os.path.isfile("gisomount.glade"):
	useglade="gisomount.glade"
      else:
	useglade="/usr/share/gisomount/gisomount.glade"
      self.wTree=gtk.glade.XML (useglade)
      self.win=self.wTree.get_widget("window1")
      self.about=self.wTree.get_widget("about")
      self.notebook=self.wTree.get_widget("notebook2")
      dic = {"on_add_fav":
	 self.on_add_fav,
	 "on_menu_help" :
	 self.on_menu_help,
	 "on_menu_browse" :
	 self.on_menu_browse,
	 "on_menu_open" :
	 self.on_menu_open,
	 "on_menu_burn" :
	 self.on_menu_burn,
	 "on_menu_summer" :
	 self.on_menu_summer,
	 "on_browse" :
	 self.on_browse,
	 "on_summer" :
         self.on_summer,
	 "on_progress_destroy" :
         self.on_progress_destroy,
	 "about_delete_event" :
	 self.on_about_ok,
	 "on_info" :
         self.on_info,
	 "on_mmount" :
         self.on_mmount,
	 "on_burn" :
	 self.on_burn,
	 "on_open" :
	 self.on_open,
         "on_exit" : 
         (gtk.main_quit) } 
      
      for x in range (5):
       self.on_info(x)
      self.wTree.signal_autoconnect(dic)
      self.win.connect("delete_event", self.delete_event)
      self.about.connect("delete_event", self.about_delete_event)
      for x in range (1,5):
       self.hide_tab(x)
      self.reconnect()

	#Setup main menus
      self.vbox1=self.wTree.get_widget("vbox1")
      self.menu_items = '''<ui>
    <menubar name="MenuBar">
      <menu action="File">
	<menuitem action="Open"/>
        <menuitem action="Quit"/>
      </menu>
      <menu action="Actions">
        <menuitem action="Calculate md5"/>
        <menuitem action="Burn"/>
        <menuitem action="Browse"/>
      </menu>
      <menu action="Favorites">
        <menuitem action="Add to Favorites"/>
	<separator name="sep1"/>
      </menu>
      <menu action="Help">
        <menuitem action="About"/>
      </menu>
    </menubar>
    </ui>'''

      self.actiongroup = gtk.ActionGroup('UIManagerExample')
      self.actiongroup.add_actions([('File', None, '_File'),
				('Open', None, '_Open', None,
				'Open an ISO', self.on_menu_open),
				('Quit', None, '_Quit', None,
				'Quit', gtk.main_quit),
				('Calculate md5', None, '_Calculate md5sum', None,
				'Calculate', self.on_menu_summer),
				('Burn', None, '_Burn', None,
				'Burn', self.on_menu_burn),
				('About', None, '_About', None,
				'About', self.on_menu_help),
				('Browse', None, 'B_rowse', None,
				'Browse', self.on_menu_browse),
				('Add to Favorites', None, 'Add to Favorites', None,
				'Add to Favorites', self.on_add_fav),
				('Actions', None, '_Actions'),
				('Favorites', None, '_Favorites'),
				('Help', None, '_Help')])

      self.uimanager=gtk.UIManager()
      self.uimanager.insert_action_group(self.actiongroup, 0)
      self.uimanager.add_ui_from_string(self.menu_items)
      menubar = self.uimanager.get_widget('/MenuBar')
      self.vbox1.pack_start(menubar,False,True,0)
      self.vbox1.reorder_child(menubar,0)
      self.rebuildFav()
      self.mtabpollerobj=gobject.timeout_add (1000, self.mtabPoller)

   def rebuildFav(self):
      #Rebuild the favorites from the config file
      self.config=gisomount.config.configFile()
      self.fav=[]
      cnt=0
      while self.config.getValue("fav"+str(cnt))!=None:
	tempFav=self.config.getValue("fav"+str(cnt))
	self.fav.append(tempFav)
	tempAction=gtk.Action(tempFav, tempFav, tempFav, None)
	if tempFav.rfind('/')!= -1:	
		tempFav=tempFav[tempFav.rfind('/')+1:]
	tempFav=str(cnt+1)+". "+tempFav
      	
	self.uimanager.add_ui(self.uimanager.new_merge_id(),'/MenuBar/Favorites', tempFav, tempFav, 'menuitem',False)
	self.actiongroup.add_action(gtk.Action(tempFav, tempFav, tempFav, None))
      	self.uimanager.get_widget('/MenuBar/Favorites/'+tempFav).connect("activate", self.on_chooseFav,cnt)
	cnt=cnt+1

   def on_add_fav(self,widget):
	#######TO DO CHECK IF REAL ISO#######
	cnt=len(self.fav)
	entry=self.wTree.get_widget("entry"+str(self.notebook.get_current_page()))
	tempFav=entry.get_text()
	self.config.setValue("fav"+str(len(self.fav)),tempFav)
	if tempFav.rfind('/')!= -1:	
		tempFav=tempFav[tempFav.rfind('/')+1:]
	tempFav=str(cnt+1)+". "+tempFav
	self.uimanager.add_ui(self.uimanager.new_merge_id(),'/MenuBar/Favorites', tempFav, tempFav, 'menuitem',False)
	self.actiongroup.add_action(gtk.Action(tempFav, tempFav, tempFav, None))
      	self.uimanager.get_widget('/MenuBar/Favorites/'+tempFav).connect("activate", self.on_chooseFav,cnt)
	self.fav.append(entry.get_text())

   def on_chooseFav(self,widget,cnt):
	#######TO DO CHECK IF REAL ISO#######
	entry=self.wTree.get_widget("entry"+str(self.notebook.get_current_page()))
	entry.set_text(self.fav[cnt])
	self.get_cd_info(self.notebook.get_current_page())
	self.on_info(self.notebook.get_current_page())

   def about_delete_event(self,widget,event):
	self.about.hide_all()
	return True

   def on_about_ok(self,widget):
	self.about.hide_all()

   def mtabPoller(self):
	#Function to continually monitor the mtab and unmount when an iso has been unmounted
	existISO=open('/etc/mtab','r')
	existISOArr=[]
	output=existISO.readline()
	while output!="":
		mark1=output.find("(vcd)")
		mark2=output.find("/media/")
		if (mark1 != -1) & (mark2 != -1):
			splitISO=output.split(" ")
			existISOArr.append(splitISO[1].decode('string-escape'))
		output=existISO.readline()
	for i in range(0,4):
          	if self.isos[i].mounted==True:
			flag=0
			for j in existISOArr:
				if j==self.isos[i].mntpoint:
					flag=1
			if flag==0:
				self.on_umount(i,1)
	return True



   def reconnect(self):
	#This reconnects iso mount points that have been previously mounted with gismount
	existISO=open('/etc/mtab','r')
	output=existISO.readline()
	while output!="":
	  mark1=output.find("(vcd)")
	  mark2=output.find("/media/")
	  if (mark1 != -1) & (mark2 != -1):
	    splitISO=output.split(" ")
	    isoFile=splitISO[0].decode('string-escape')
	    isoMount=splitISO[1].decode('string-escape')
	    free=self.find_free_slot()
	    self.show_tab(free)
	    self.isos[free].mounted=True
	    self.isos[free].mntpoint=isoMount
	    self.isos[free].filename=isoFile
	    
	    entry=self.wTree.get_widget("entry"+str(free))
	    entry.set_text(isoFile)
	    self.lock_slot(free)
	    self.get_cd_info(free)
	    self.on_info(free)
	    self.notebook.set_tab_label_text(self.notebook.get_nth_page(free),self.isos[free].info.vollabel[:7]+"...")
	    button=self.wTree.get_widget("mmount"+str(free))
	    button.set_label("Unmount")

	  output=existISO.readline()
	existISO.close()
	self.unlock_slot(self.find_free_slot())

   def on_mmount(self,widget):
	widgetName=widget.get_name()
	partial=widgetName[6:]
	pRef=int(partial)

	if self.isos[pRef].mounted==False:
		self.on_mount(pRef)
	else:
		self.on_umount(pRef)

   def on_menu_help(self,widget):
	self.about=self.wTree.get_widget("about")
	self.about.show_all()

   def on_info(self,index):
	#Possibly this should be a class of it's own
	tabswin=self.wTree.get_widget("window1")
	tabs=self.wTree.get_widget("treeview"+str(index))

	if not tabs.get_model():
	#Create the model if it doesn't already exist
		self.treestore[index]=gtk.TreeStore(str,str)
		column = gtk.TreeViewColumn("Key", gtk.CellRendererText(), text=0)
		column.set_resizable(True)		
		column.set_sort_column_id(0)
		column2 = gtk.TreeViewColumn("Info", gtk.CellRendererText(), text=1)
		column2.set_resizable(True)		
		column2.set_sort_column_id(1)
		tabs.append_column(column)
		tabs.append_column(column2)
		tabs.set_model(self.treestore[index])
	
	#Clear the model so we can add new information in
	self.treestore[index].clear()
	self.treeRefBasic=self.treestore[index].append(None, ("File Information",""))
	self.treeRefAdv=self.treestore[index].append(None, ("ISO Information",""))
	self.treeRefMount=self.treestore[index].append(None, ("Mount Information",""))
	#Name Size md5 DVD
	basicInfo=[
		("Filename",self.isos[index].filename),
		("Size",self.isos[index].size),
		("MD5 sum",self.isos[index].md5),
		("ISO type",self.isos[index].itype)
		]
	advancedInfo=[
		("Volume Label",self.isos[index].info.vollabel),
		("Publisher ID",self.isos[index].info.publishid),
		("Creation Date",self.isos[index].info.volcreate),
		("Data Preparer",self.isos[index].info.datprepareid),
		("Volume Set Identifier",self.isos[index].info.volsetident),
		("Standard ID",self.isos[index].info.standardid),
		("System ID",self.isos[index].info.systemid),
		("Volume Set Size",self.isos[index].info.volsetsize),
		("Application ID",self.isos[index].info.applicid)
		]
	mountInfo=[
		("Mount Point",self.isos[index].mntpoint)
		]
	
	for dataTuple in basicInfo:
		if dataTuple[1]!="":
			self.treestore[index].append(self.treeRefBasic, dataTuple)
	for dataTuple in advancedInfo:
		if dataTuple[1]!="":
			self.treestore[index].append(self.treeRefAdv, dataTuple)
	for dataTuple in mountInfo:
		if dataTuple[1]!="":
			self.treestore[index].append(self.treeRefMount, dataTuple)

   def on_progress_destroy(self, widget):
	#Kill the md5sum process if the user cancels the progress bar
	gobject.source_remove(self.progresstimer)
	gobject.source_remove(self.progressbartimer)
	self.progress.hide_all()
	mountproc=subprocess.Popen("kill "+str(self.md5proc.pid), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

   def md5sum_dead(self):
	#Polls to check if the md5sum has finished it's operation, and then destroy
	#progress bar window.  Tied to a gobject timer.
	mountoutput=self.md5proc.poll()
	if mountoutput==None:
		return True
	else:
		gobject.source_remove(self.progresstimer)
		gobject.source_remove(self.progressbartimer)
		self.progress.hide_all()
		md5info=self.md5proc.stdout.read()
		md5split=md5info.split(" ")
		displayMessage(self,'md5sum is: <big><b>'+md5split[0]+'</b></big>',gtk.MESSAGE_INFO)
		return False

   def progress_update(self):
	#Pulse the progress bar, needed cos eith gobject it stupid, or I am!
	self.progressbar.pulse()
	return True
	
   def delete_event(self,widget,event):
	#Interrupt the closing of the main gtk window and prompt the 
	#user if they wish to unmount all of the vcds.  
	if self.find_free_slot()==0:
	  return False
	self.win.set_sensitive(False)
        dialog = gtk.MessageDialog(self.win,
        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
        gtk.MESSAGE_INFO, gtk.BUTTONS_YES_NO, None)
	dialog.add_button("Cancel",-10)
        dialog.set_markup('<big><b>Do you want to unmount all vcds now?</b></big>')
        dialog.connect("destroy", lambda w: self.win.set_sensitive(True))
        resp = dialog.run()
        if resp==-8:
	  #Close gISOMount and unmount all volumes mounted
          dialog.destroy()
	  for i in range(len(self.isos)):
	    if self.isos[i].mounted==True:
	      umount=self.ac_umount(self.isos[i].mntpoint)
	      if umount==True:
		mountproc=subprocess.Popen("rmdir \""+self.isos[i].mntpoint+"\"", shell=True)
	  return False
	elif resp==-9:
	  #Close gISOMount and leave all volumes mounted
	  dialog.destroy()
	  return False
	else:
	  #Just cancel
          dialog.destroy()
	  return True

   def get_cd_info(self,index):
	#Adds the cd info into the iso info class
	entry=self.wTree.get_widget("entry"+str(index))
	cdinfo=isoinfo(entry.get_text())
	entry=self.wTree.get_widget("entry"+str(index))
	info=os.stat(entry.get_text())
	self.isos[index].size=info.st_size
        self.isos[index].filename=entry.get_text()
	self.isos[index].info.vollabel=cdinfo.vollabel()
	self.isos[index].info.volcreate=cdinfo.volcreate()
	self.isos[index].info.volsetident=cdinfo.volsetident()
	self.isos[index].info.standardid=cdinfo.standardid()
	self.isos[index].info.systemid=cdinfo.systemid()
	self.isos[index].info.volsetsize=cdinfo.volsetsize()
	self.isos[index].info.volseqnum=cdinfo.volseqnum()
	self.isos[index].info.publishid=cdinfo.publishid()
	self.isos[index].info.datprepareid=cdinfo.datprepareid()
	self.isos[index].info.applicid=cdinfo.applicid()

   def on_menu_browse(self,widget):
	self.on_browse(self.wTree.get_widget("browse"+str(self.notebook.get_current_page())))
   def on_menu_burn(self,widget):
	self.on_burn(self.wTree.get_widget("burn"+str(self.notebook.get_current_page())))
   def on_menu_summer(self,widget):
	self.on_summer(self.wTree.get_widget("summer"+str(self.notebook.get_current_page())))
   def on_menu_open(self,widget):
	self.on_open(self.wTree.get_widget("open"+str(self.notebook.get_current_page())))

   def on_browse(self,widget):
      #Opens the iso chooser window
      widgetName=widget.get_name()
      partial=widgetName[6:]
      filew = gtk.FileChooserDialog(title="Open ISO image...",action=gtk.FILE_CHOOSER_ACTION_OPEN,buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
      response=filew.run()
      if response == gtk.RESPONSE_OK:
          entry=self.wTree.get_widget("entry"+str(partial))
          entry.set_text(filew.get_filename())
	  filew.destroy()
	  self.get_cd_info(int(partial))
	  self.on_info(int(partial))
      elif response == gtk.RESPONSE_CANCEL:
          filew.destroy()

   def on_mount(self,index):
      #Handler: Mount button is pushed, which button has been pressed is
      #picked up by the widget's name
      entry=self.wTree.get_widget("entry"+str(index))
      is_valid=self.is_iso_valid(entry.get_text())
      if is_valid==True:
	  #Try mounting it now, cos all appears gooooooood
	  self.get_cd_info(index)
	  if os.path.isdir("/media/"+self.isos[index].info.vollabel.strip()+"(vcd)"):
	   j=0
	   while os.path.isdir("/media/"+self.isos[index].info.vollabel.strip()+"("+str(j)+")(vcd)"):
	     j=j+1
	   fileMount="/media/"+self.isos[index].info.vollabel.strip()+"("+str(j)+")(vcd)"
	  else: 
	   fileMount="/media/"+self.isos[index].info.vollabel.strip()+"(vcd)"
	  #fileMount=fileMount.strip()
	  self.isos[index].mntpoint=fileMount
	  makeDir=subprocess.Popen("mkdir \""+fileMount+"\"", shell=True)
	  makeDir.wait()

	  mount=self.ac_mount(entry.get_text(),fileMount)

	  #If the mount was successful, get on with updating the UI
	  if mount==True:
	   info=os.stat(entry.get_text())
	   icon=self.wTree.get_widget("icon"+str(index))
	   if info.st_size<729217000:
		icon.set_from_file("cd.png")
		self.isos[index].itype="CD-ROM"
	   else:
	   	icon.set_from_file("dvd.png")
		self.isos[index].itype="DVD-ROM"
	   self.lock_slot(index)
	   self.isos[index].mounted=True
	   self.isos[index].filename=entry.get_text()
	   if self.find_free_slot()<5:
	    self.show_tab(self.find_free_slot())
	    self.unlock_slot(self.find_free_slot())
	   self.notebook.set_tab_label_text(self.notebook.get_nth_page(self.notebook.get_current_page()),self.isos[index].info.vollabel[:7]+"...")
	   button=self.wTree.get_widget("mmount"+str(index))
	   button.set_label("Unmount")
      self.on_info(self.notebook.get_current_page())


   def on_umount(self,index,poll=0):
      #Handler: Unmount 
      if poll==0:
         umount=self.ac_umount(self.isos[index].mntpoint)
      else:
	 umount=True
      self.notebook.set_tab_label_text(self.notebook.get_nth_page(index),"<untitled>")
      icon=self.wTree.get_widget("icon"+str(index))
      icon.set_from_file("cdicon.png")

      if umount==True:
        mountproc=subprocess.Popen("rmdir \""+self.isos[index].mntpoint+"\"", shell=True)
	self.unlock_slot(index)
	#Re-initialise the iso infor class
	self.isos[index]=info()
	button=self.wTree.get_widget("mmount"+str(index))
	button.set_label("Mount")

   def on_exit(obj): 
      mainquit()

   def find_free_slot(self):
	#Nicer version of the old find_Free(), returns the next free ie. uninitialised slot
	free=-1
	for i in range(0,4):
          if self.isos[i].mounted==False:
	    free=i
	    return free

   def lock_slot(self,slot):
	#Locks a mount slot on the gui
	entry=self.wTree.get_widget("entry"+str(slot))
	entry.set_sensitive(False)
	browse=self.wTree.get_widget("browse"+str(slot))
	browse.set_sensitive(False)

   def unlock_slot(self,slot):
	#Unlocks a mount slot on the gui
	entry=self.wTree.get_widget("entry"+str(slot))
	entry.set_sensitive(True)
	browse=self.wTree.get_widget("browse"+str(slot))
	browse.set_sensitive(True)

   def ac_mount(self,filename,mountpoint):
	mountproc=subprocess.Popen("mount -o loop,ro -t iso9660 "+filename+" \""+mountpoint+"\"", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
	mountoutput=mountproc.stderr.read()
	if mountoutput != "":
	  displayMessage(self,'<big><b>'+mountoutput+'</b></big>',gtk.MESSAGE_ERROR)
	  return False
	else:
	  return True

   def ac_umount(self,mountpoint):
      mountproc=subprocess.Popen("umount \""+mountpoint+"\"", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      mountoutput=mountproc.stderr.read()
      if mountoutput != "":
	  displayMessage(self,'<big><b>'+mountoutput+'</b></big>',gtk.MESSAGE_ERROR)
	  return False
      else:
	return True

   def on_summer(self,widget):
	widgetName=widget.get_name()
	partial=widgetName[6:]
	pRef=int(partial)
	#Handler: If summer button is pressed, start the md5sum process
	entry=self.wTree.get_widget("entry"+partial)
        self.progress=self.wTree.get_widget("progress")
        self.progress.show_all()
	self.progressbar=self.wTree.get_widget("progressbar1")
	self.progressbartimer=gobject.timeout_add (100, self.progress_update)
	self.md5proc=subprocess.Popen("md5sum "+entry.get_text(), shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
	self.progresstimer=gobject.timeout_add (100, self.md5sum_dead)

   def on_open(self,widget):
	widgetName=widget.get_name()
	partial=widgetName[4:]
	pRef=int(partial)
	mountproc=subprocess.Popen("nautilus \""+self.isos[pRef].mntpoint+"\"", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

   def on_burn(self,widget):
	widgetName=widget.get_name()
	partial=widgetName[4:]
	pRef=int(partial)
	mountproc=subprocess.Popen("/usr/bin/nautilus-cd-burner --source-iso=\""+self.isos[pRef].filename+"\"", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

   def is_iso_valid(self,filename):
	#Checks to see if an iso is valid
      if filename == "":
	#Dude, select a file first you idiot
	displayMessage(self,'<big><b>You must input an iso image</b></big>',gtk.MESSAGE_ERROR)
	return False
      process=subprocess.Popen("file "+filename, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      output=process.stdout.read()
      if output.find("ISO") == -1:
	  #File is clearly not an iso, dummy :p
	  displayMessage(self,'<big><b>File selected is not an ISO</b></big>',gtk.MESSAGE_ERROR)
	  return False
      return True

   def hide_tab(self,index):
	test=self.wTree.get_widget("tabwrap"+str(index))
	test.hide_all()
	
   def show_tab(self,index):
	test=self.wTree.get_widget("tabwrap"+str(index))
	test.show_all()

class isoinfo:
   #Class for providing the volume label etc of an iso
   def __init__(self,filename):
      self.isoimage=file(filename,'r')

   def standardid(self):
      self.isoimage.seek(32767+2)
      return self.isoimage.read(5)

   def systemid(self):
      self.isoimage.seek(32767+9)
      return self.isoimage.read(32)

   def vollabel(self):
      self.isoimage.seek(32767+41)
      return self.isoimage.read(32)

   def volsetsize(self):
      self.isoimage.seek(32767+121)
      return self.isoimage.read(4)

   def volseqnum(self):
      self.isoimage.seek(32767+125)
      return self.isoimage.read(4)

   def volsetident(self):
      self.isoimage.seek(32767+191)
      return self.isoimage.read(128)

   def publishid(self):
      self.isoimage.seek(32767+319)
      return self.isoimage.read(128)

   def datprepareid(self):
      self.isoimage.seek(32767+447)
      return self.isoimage.read(128)

   def applicid(self):
      self.isoimage.seek(32767+575)
      return self.isoimage.read(128)

   def volcreate(self):
      self.isoimage.seek(32767+814)
      return self.isoimage.read(16)

class info:
	#Class for holding vcd info
	def __init__(self):
		self.info=self.iso()
		self.mounted=False
		self.filename=""
		self.mntpoint=""
		self.size=""
		self.md5=""
		self.itype=""
	
	class iso:
		def __init__(self):
			self.vollabel=""
			self.volcreate=""
			self.volsetident=""
			self.standardid=""
			self.systemid=""
			self.volsetsize=""
			self.volseqnum=""
			self.publishid=""
			self.datprepareid=""
			self.applicid=""

def displayMessage(mclass,mtext,mtype):
  mclass.win.set_sensitive(False)
  dialog = gtk.MessageDialog(mclass.win,
  gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
  mtype, gtk.BUTTONS_OK, None)
  dialog.set_markup(mtext)
  dialog.connect("destroy", lambda w: mclass.win.set_sensitive(True))
  resp = dialog.run()
  if resp:
    dialog.destroy()


app=gui()
gtk.main()

#dir(gtk.Entry()) - Very useful
