gnome-schedule r1125 - in trunk: . po src



Author: gauteh
Date: Sat Feb 14 21:20:56 2009
New Revision: 1125
URL: http://svn.gnome.org/viewvc/gnome-schedule?rev=1125&view=rev

Log:

	* X support ready for testing
	* xwrapper.py: checks for X connection in both crontab and at
	* xwrapper.py: works for at
	* Merged x-output-support onto trunk


Added:
   trunk/src/xwrapper.py
      - copied unchanged from r1124, /branches/x-output-support/src/xwrapper.py
Modified:
   trunk/   (props changed)
   trunk/ChangeLog
   trunk/HACKING
   trunk/NEWS
   trunk/README
   trunk/po/POTFILES.in
   trunk/src/Makefile.am
   trunk/src/addWindow.py
   trunk/src/at.py
   trunk/src/atEditor.py
   trunk/src/config.py.in
   trunk/src/crontab.py
   trunk/src/crontabEditor.py
   trunk/src/crontabEditorHelper.py
   trunk/src/data.py
   trunk/src/gnome-schedule.glade
   trunk/src/gnome-schedule.py
   trunk/src/lang.py
   trunk/src/mainWindow.py
   trunk/src/scheduleapplet.py
   trunk/src/setuserWindow.py
   trunk/src/template.py
   trunk/src/template_chooser.py
   trunk/src/template_manager.py

Modified: trunk/HACKING
==============================================================================
--- trunk/HACKING	(original)
+++ trunk/HACKING	Sat Feb 14 21:20:56 2009
@@ -12,3 +12,6 @@
 
 Major changes should be submitted for approval to the maintainer(s).
 
+Coding style:
+    Use expanded tabs, 4 of them, on all *.py files.
+

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Sat Feb 14 21:20:56 2009
@@ -1,3 +1,6 @@
+2009-02-14:
+  X output support ready for testing, merged onto trunk/
+
 2008-02-08:
   Releasing 2.0.2 to with a new at parser.
 

Modified: trunk/README
==============================================================================
--- trunk/README	(original)
+++ trunk/README	Sat Feb 14 21:20:56 2009
@@ -87,6 +87,7 @@
 
 	This will use images and datafiles from the current directory. Remember this is only for debugging and might not always work as expected.
 
+
   To make contributions you should first read
 
 	o. HACKING

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Sat Feb 14 21:20:56 2009
@@ -24,4 +24,4 @@
 src/template.py
 src/template_chooser.py
 src/template_manager.py
-
+src/xwrapper.py.in

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sat Feb 14 21:20:56 2009
@@ -17,7 +17,8 @@
 	scheduleapplet.py \
 	template.py \
 	template_chooser.py \
-	template_manager.py
+	template_manager.py \
+	xwrapper.py
 
 
 uidir = $(datadir)/gnome-schedule
@@ -31,7 +32,7 @@
 	config.py \
 	gnome-schedule.glade.bak \
 	gnome-schedule.gladep.bak \
-	gnome-schedule.gladep
+	gnome-schedule.gladep 
 
 EXTRA_DIST =  \
 	$(bin_SCRIPTS) \

Modified: trunk/src/addWindow.py
==============================================================================
--- trunk/src/addWindow.py	(original)
+++ trunk/src/addWindow.py	Sat Feb 14 21:20:56 2009
@@ -21,101 +21,101 @@
 import gtk
 
 class AddWindow:
-	def __init__(self, parent):
-		self.ParentClass = parent
-		self.transient = self.ParentClass.widget
-		self.xml = self.ParentClass.xml
-		self.widget = self.xml.get_widget ("addWindow")
-		self.widget.connect("delete-event", self.widget.hide_on_delete)
-
-		self.mode = 0
-		
-		self.cancel_button = self.xml.get_widget ("select_cancel_button")
-		self.ok_button = self.xml.get_widget ("select_ok_button")
-
-		self.xml.signal_connect("on_select_cancel_button_clicked", self.on_cancel_button_clicked)
-		
-		self.xml.signal_connect("on_button_at_clicked", self.on_button_at_clicked)
-		self.xml.signal_connect("on_button_crontab_clicked", self.on_button_crontab_clicked)
-		self.xml.signal_connect("on_button_templates_clicked", self.on_button_template_clicked)
-
-		self.button_at = self.xml.get_widget ("button_at")
-		self.button_crontab = self.xml.get_widget ("button_crontab")
-		self.button_template = self.xml.get_widget ("button_templates")
-
-		self.chbox = gtk.HBox (False, 5)
-		self.cicon = gtk.Image ()
-		self.cicon.set_from_pixbuf (self.ParentClass.bigiconcrontab)
-		self.cicon.set_alignment (0, 0.5)
-		self.chbox.pack_start (self.cicon, False, False, 5)
-		self.clabel = gtk.Label (_("A task that launches recurrently"))
-		self.clabel.set_justify (gtk.JUSTIFY_LEFT)
-		self.clabel.set_alignment (0, 0.5)
-		self.chbox.pack_start (self.clabel, True, True, 5)
-		
-		self.button_crontab.add (self.chbox)
-		self.button_crontab.show_all ()
-		
-		self.ahbox = gtk.HBox (False, 5)
-		self.aicon = gtk.Image ()
-		self.aicon.set_from_pixbuf (self.ParentClass.bigiconat)
-		self.aicon.set_alignment (0, 0.5)
-		self.ahbox.pack_start (self.aicon, False, False, 5)
-		self.alabel = gtk.Label (_("A task that launches one time"))
-		self.alabel.set_justify (gtk.JUSTIFY_LEFT)
-		self.alabel.set_alignment (0, 0.5)
-		self.ahbox.pack_start (self.alabel, True, True, 5)
-		
-		self.button_at.add (self.ahbox)
-		self.button_at.show_all ()
-		
-		self.thbox = gtk.HBox (False, 5)
-		self.ticon = gtk.Image ()
-		self.ticon.set_from_pixbuf (self.ParentClass.bigicontemplate)
-		self.ticon.set_alignment (0, 0.5)
-		self.thbox.pack_start (self.ticon, False, False, 5)
-		self.tlabel = gtk.Label (_("A task from a predefined template"))
-		self.tlabel.set_justify (gtk.JUSTIFY_LEFT)
-		self.tlabel.set_alignment (0, 0.5)
-		self.thbox.pack_start (self.tlabel, True, True, 5)
-		
-		self.button_template.add (self.thbox)
-		self.button_template.show_all ()
-
-
-	# mode: 0 = normal add, 1 = new template
-	def ShowAddWindow (self, transient, mode = 0):
-		self.mode = mode
-		self.transient = transient
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.widget.show_all()
-		if (mode == 1):
-			self.button_template.hide ()
-		elif (mode == 0):
-			self.button_template.show_all ()
-		
-
-	def on_cancel_button_clicked (self, *args):
-		self.widget.hide()
-		
-	def on_button_template_clicked (self, *args):
-		self.widget.hide ()
-		self.ParentClass.template_chooser.show (self.transient)
-				
-	def on_button_crontab_clicked (self, *args):
-		self.widget.hide ()
-		self.ParentClass.editor = self.ParentClass.crontab_editor
-		if (self.mode == 1):
-			self.ParentClass.editor.shownew_template (self.transient)
-		elif (self.mode == 0):
-			self.ParentClass.editor.showadd (self.transient)
-		
-	def on_button_at_clicked (self, *args):
-		self.widget.hide ()
-		self.ParentClass.editor = self.ParentClass.at_editor
-		if (self.mode == 1):
-			self.ParentClass.editor.shownew_template (self.transient)
-		elif (self.mode == 0):
-			self.ParentClass.editor.showadd (self.transient)	
-		
+    def __init__(self, parent):
+        self.ParentClass = parent
+        self.transient = self.ParentClass.widget
+        self.xml = self.ParentClass.xml
+        self.widget = self.xml.get_widget ("addWindow")
+        self.widget.connect("delete-event", self.widget.hide_on_delete)
+
+        self.mode = 0
+        
+        self.cancel_button = self.xml.get_widget ("select_cancel_button")
+        self.ok_button = self.xml.get_widget ("select_ok_button")
+
+        self.xml.signal_connect("on_select_cancel_button_clicked", self.on_cancel_button_clicked)
+        
+        self.xml.signal_connect("on_button_at_clicked", self.on_button_at_clicked)
+        self.xml.signal_connect("on_button_crontab_clicked", self.on_button_crontab_clicked)
+        self.xml.signal_connect("on_button_templates_clicked", self.on_button_template_clicked)
+
+        self.button_at = self.xml.get_widget ("button_at")
+        self.button_crontab = self.xml.get_widget ("button_crontab")
+        self.button_template = self.xml.get_widget ("button_templates")
+
+        self.chbox = gtk.HBox (False, 5)
+        self.cicon = gtk.Image ()
+        self.cicon.set_from_pixbuf (self.ParentClass.bigiconcrontab)
+        self.cicon.set_alignment (0, 0.5)
+        self.chbox.pack_start (self.cicon, False, False, 5)
+        self.clabel = gtk.Label (_("A task that launches recurrently"))
+        self.clabel.set_justify (gtk.JUSTIFY_LEFT)
+        self.clabel.set_alignment (0, 0.5)
+        self.chbox.pack_start (self.clabel, True, True, 5)
+        
+        self.button_crontab.add (self.chbox)
+        self.button_crontab.show_all ()
+        
+        self.ahbox = gtk.HBox (False, 5)
+        self.aicon = gtk.Image ()
+        self.aicon.set_from_pixbuf (self.ParentClass.bigiconat)
+        self.aicon.set_alignment (0, 0.5)
+        self.ahbox.pack_start (self.aicon, False, False, 5)
+        self.alabel = gtk.Label (_("A task that launches one time"))
+        self.alabel.set_justify (gtk.JUSTIFY_LEFT)
+        self.alabel.set_alignment (0, 0.5)
+        self.ahbox.pack_start (self.alabel, True, True, 5)
+        
+        self.button_at.add (self.ahbox)
+        self.button_at.show_all ()
+        
+        self.thbox = gtk.HBox (False, 5)
+        self.ticon = gtk.Image ()
+        self.ticon.set_from_pixbuf (self.ParentClass.bigicontemplate)
+        self.ticon.set_alignment (0, 0.5)
+        self.thbox.pack_start (self.ticon, False, False, 5)
+        self.tlabel = gtk.Label (_("A task from a predefined template"))
+        self.tlabel.set_justify (gtk.JUSTIFY_LEFT)
+        self.tlabel.set_alignment (0, 0.5)
+        self.thbox.pack_start (self.tlabel, True, True, 5)
+        
+        self.button_template.add (self.thbox)
+        self.button_template.show_all ()
+
+
+    # mode: 0 = normal add, 1 = new template
+    def ShowAddWindow (self, transient, mode = 0):
+        self.mode = mode
+        self.transient = transient
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.widget.show_all()
+        if (mode == 1):
+            self.button_template.hide ()
+        elif (mode == 0):
+            self.button_template.show_all ()
+        
+
+    def on_cancel_button_clicked (self, *args):
+        self.widget.hide()
+        
+    def on_button_template_clicked (self, *args):
+        self.widget.hide ()
+        self.ParentClass.template_chooser.show (self.transient)
+                
+    def on_button_crontab_clicked (self, *args):
+        self.widget.hide ()
+        self.ParentClass.editor = self.ParentClass.crontab_editor
+        if (self.mode == 1):
+            self.ParentClass.editor.shownew_template (self.transient)
+        elif (self.mode == 0):
+            self.ParentClass.editor.showadd (self.transient)
+        
+    def on_button_at_clicked (self, *args):
+        self.widget.hide ()
+        self.ParentClass.editor = self.ParentClass.at_editor
+        if (self.mode == 1):
+            self.ParentClass.editor.shownew_template (self.transient)
+        elif (self.mode == 0):
+            self.ParentClass.editor.showadd (self.transient)    
+        

Modified: trunk/src/at.py
==============================================================================
--- trunk/src/at.py	(original)
+++ trunk/src/at.py	Sat Feb 14 21:20:56 2009
@@ -30,575 +30,618 @@
 
 
 class At:
-	def __init__(self,root,user,uid,gid,user_home_dir,manual_poscorrect):
-	
-		#default preview length
-		self.preview_len = 50
-		self.root =	root
-		self.set_rights(user,uid,gid, user_home_dir)
-		self.user_home_dir = user_home_dir
-		self.manual_poscorrect = manual_poscorrect
-
-
-		# 16       2006-01-08 13:01 a gaute
-		# 7       Sun Jan  8 13:01:00 2006 a pvanhoof
-		# 1	2006-04-26 08:54 a gaute
-		# 14	2006-09-21 10:54 a gaute
-		# 3	Tue May  8 01:01:00 2007 a gaute
-
-		self.atRecordRegex = re.compile('^([\d]+)[\t]([\w]{3,3})[\s]([\w]{3,3})[\s]*([\d]+)[\s]([\d]{2,2}[:][\d]{2,2}[:][\d]{2,2})[\s]([\d]{4,4})[\s]([\w])[\s]([\w]+)')
-			
-
-		# after you add a job, this line is printed to stderr
-		# job 10 at 2006-09-18 12:38
-		self.atRecordRegexAdd = re.compile('^job\s([0-9]+)\sat')
-		
-		self.atRecordRegexAdded = re.compile('[^\s]+\s([0-9]+)\sat')
-		self.nooutput = 0
-		self.SCRIPT_DELIMITER = "###### ---- GNOME_SCHEDULE_SCRIPT_DELIMITER #####"
-		
-		# If normally this variable is unset the user would not expect it 
-		# to be set, which it will be because Gnome Schedule needs it.
-		# Therefore we unset it in the script.
-		self.POSIXLY_CORRECT_UNSET = "unset POSIXLY_CORRECT\n"
-		
-		self.atdatafileversion = 3
-		self.atdata = self.user_home_dir + "/.gnome/gnome-schedule/at"
-		if os.path.exists (self.user_home_dir + "/.gnome") != True:
-			os.mkdir (self.user_home_dir + "/.gnome", 0700)
-			os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
-		if os.path.exists(self.atdata) != True:
-			try:
-				os.makedirs(self.atdata, 0700)
-				if self.root == 1:
-					os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
-					os.chown (self.atdata, self.uid, self.gid)
-			except:
-				print _("Failed to create data dir! Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.")
-				
-		self.months = {
-			'Jan' : '1',
-			'Feb' : '2',
-			'Mar' : '3',
-			'Apr' : '4',
-			'May' : '5',
-			'Jun' : '6',
-			'Jul' : '7',
-			'Aug' : '8',
-			'Sep' : '9',
-			'Oct' : '10',
-			'Nov' : '11',
-			'Dec' : '12'
-		}
-		
-	def set_rights(self,user,uid,gid, ud):
-		self.user = user
-		self.uid = uid
-		self.gid = gid
-		self.user_home_dir = ud
-		self.atdata = self.user_home_dir + "/.gnome/gnome-schedule/at"
-		if os.path.exists (self.user_home_dir + "/.gnome") != True:
-			os.mkdir (self.user_home_dir + "/.gnome", 0700)
-			os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
-		if os.path.exists(self.atdata) != True:
-			try:
-				os.makedirs(self.atdata, 0700)
-				if self.root == 1:
-					os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
-					os.chown (self.atdata, self.uid, self.gid)
-			except:
-				print (_("Failed to create data dir: %s. Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.") % (self.atdata))
-
-	
-	def get_type (self):
-		return "at"
-		
-	def parse (self, line, output = True):
-		if (output == True):
-			if len (line) > 1 and line[0] != '#':
-				m = self.atRecordRegex.match(line)
-				if m != None:			
-					# Time
-					time = m.groups ()[4][:-3]
-					
-					# Date
-					day = m.groups ()[3]
-					month = m.groups ()[2]
-					
-					for monthname in self.months:
-						month = month.replace (monthname, self.months[monthname])
-						
-					if int (day) < 10:
-						day = "0" + day
-					if int (month) < 10:
-						month = "0" + month
-						
-					date = day + "." + month + "." + m.groups ()[5]
-
-					job_id = m.groups ()[0]
-					class_id = m.groups ()[6]
-					user = m.groups ()[7]
-						
-					title, desc, manual_poscorrect = self.get_job_data (int (job_id))
-					# manual_poscorrect is only used during preparation of script
-
-					execute = config.getAtbin() + " -c " + job_id
-					# read lines and detect starter
-					script = os.popen(execute).read()
-					script, prelen, dangerous = self.__prepare_script__ (script, manual_poscorrect)
-										
-					#removing ending newlines, but keep one
-					#if a date in the past is selected the record is removed by at, this creates an error, and generally if the script is of zero length
-					# TODO: complain about it as well
-					
-					if len(script) < 2:
-						done = 1
-					else:
-						done = 0
-
-					while done == 0:
-						if script[-1] == "\n":
-							script = script[0:-1]
-						else:
-							done = 1
-
-					return job_id, date, time, class_id, user, script, title, prelen, dangerous
-					
-		elif (output == False):
-			if len (line) > 1 and line[0] != '#':
-				m = self.atRecordRegexAdd.search(line)
-				#print "Parsing line: " + line
-				if m != None:
-					#print "Parse successfull, groups: "
-					#print m.groups()
-					job_id = m.groups ()[0]
-					return int(job_id)
-				else:
-					return False
-
-		return False
-		# TODO: throw exception
-
-	def get_job_data (self, job_id):
-		f = os.path.join (self.atdata, str (job_id))
-		if os.access (f, os.R_OK):
-			fh = open (f, 'r')
-			d = fh.read ()
-			
-			ver_p = d.find ("ver=")
-			if ver_p == -1:
-				ver = 1
-			else:
-				ver_s = d[ver_p + 4:d.find ("\n")]
-				d = d[d.find ("\n") + 1:]
-				ver = int (ver_s)
-				
-			title = d[6:d.find ("\n")]
-			d = d[d.find ("\n") + 1:]
-			
-			# icons out
-			if ver < 2:
-				icon = d[5:d.find ("\n")]
-				d = d[d.find ("\n") + 1:]
-			
-			desc = d[5:d.find ("\n")]
-			d = d[d.find ("\n") + 1:]
-			
-			manual_poscorrect_b = False
-			if ver > 2:
-				manual_poscorrect = d[18:d.find ("\n")]
-				d = d[d.find ("\n") + 1:]
-				if manual_poscorrect == "true":
-					manual_poscorrect_b = True
-				elif manual_poscorrect == "false":
-					manual_poscorrect_b = False
-			fh.close ()
-			
-			return title, desc, manual_poscorrect_b
-			
-		else: 
-			return "", "", False
-			
-	def write_job_data (self, job_id, title, desc):
-		# Create and write data file
-		f = os.path.join (self.atdata, str(job_id))
-		#print f
-		fh = open (f, 'w')
-		fh.truncate (1)
-		fh.seek (0)
-		fh.write ("ver=" + str(self.atdatafileversion) + "\n")
-		fh.write ("title=" + title + "\n")
-		fh.write ("desc=" + desc + "\n")
-		
-		# This one doesn't need to be passed independently for each job since the job data is only updated together with a task being appended or updated (also new added), and the variable depends on each session. Not job.
-		if self.manual_poscorrect == True:
-			fh.write ("manual_poscorrect=true\n")
-		else:
-			fh.write ("manual_poscorrect=false\n")
-		fh.close ()
-		os.chown (f, self.uid, self.gid)
-		os.chmod (f, 0600)
-			
-	def checkfield (self, runat):
-		#TODO: fix bug $0:19 2004-12-8$ not valid by regexp
-		# print "$" + runat + "$"
-		#regexp1 = re.compile("([0-9][0-9]):([0-9][0-9])\ ([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
-		#print "Testing: " + runat
-		regexp1 = re.compile ("([0-9][0-9])([0-9][0-9])\ ([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
-		regexp2 = re.compile("([0-9][0-9])([0-9][0-9])")
-		regexp3 = re.compile("([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
-		
-		runat_g1 = regexp1.match(runat)
-		runat_g2 = regexp2.match(runat)
-		runat_g3 = regexp3.match(runat)
-		ctime = time.localtime()
-		cyear = ctime[0]
-		cmonth = ctime[1]
-		cday = ctime[2]
-		chour = ctime[3]
-		cminute = ctime[4]
-	
-		if runat_g1:
-			(hour, minute, day, month, year) =  runat_g1.groups()
-			hour = int(hour)
-			minute = int(minute)
-			year = int(year)
-			month = int(month)
-			day = int(day)
-
-			if hour > 24 or hour < 0:
-				return False, "hour"
-			
-			if minute > 60 or minute < 0:
-				return False, "minute"
-			
-			if month > 12 or month < 0:
-				return False, "month"
-				
-			if day > 31 or day < 0:
-				return False, "day"
-				
-			if year < 0:
-				return False, "year"
-				
-			if year >= cyear: 
-				if year == cyear:
-					syear = True
-					if (month >= cmonth):
-						if month == cmonth:
-							smonth = True
-							if day >= cday:
-								if day == cday:
-									sday = True
-									if hour >= chour:
-										if hour == chour:
-											shour = True
-											if minute <= cminute:
-												return False, "minute"
-										else:
-											shour = False
-									else:
-										return False, "hour"
-								else:
-									sday = False
-							else:
-								return False, "day"
-						else:
-							smonth = False
-					else:
-						return False, "month"
-				else:
-					syear = False
-			else:
-				return False, "year"
-
-		elif runat_g2:
-
-			(hour, minute) =  runat_g2.groups()
-			hour = int(hour)
-			minute = int(minute)
-			if hour > 24 or hour < 0:
-				return False, "hour"
-	
-			if minute > 60 or minute < 0:
-				return False, "minute"
-
-
-		elif runat_g3:
-
-			(day, month, year) =  runat_g3.groups()
-			year = int(year)
-			month = int(month)
-			day = int(day)
-			if year < cyear:
-				return False, "year"
-			if month < cmonth:
-				return False, "month"
-			if day < cday:
-				return False, "day"
-
-		else:
-			#lowercase
-			runat = runat.lower()
-		
-			#some timespecs:
-			days = ['sun','mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sunday','monday','tuesday','wednesday','thursday','friday','saturday']
-			relative_days = ['tomorrow','next week','today']
-			relative_hour = ['noon','teatime','midnight','next hour']
-			relative_minute = ['next minute']
-			relative_month = ['next month']
-			
-			if runat in days:
-				pass
-			elif runat in relative_days:
-				pass
-			elif runat in relative_hour:
-				pass
-			elif runat in relative_minute:
-				pass
-			elif runat in relative_month:
-				pass
-			else:
-				return False, "other"
-
-		return True, "ok"
-
-		
-	def append (self, runat, command, title):
-		tmpfile = tempfile.mkstemp ()
-		fd, path = tmpfile
-		tmp = os.fdopen(fd, 'w')
-		tmp.write (self.SCRIPT_DELIMITER + "\n")
-		if self.manual_poscorrect:
-			tmp.write (self.POSIXLY_CORRECT_UNSET)
-		tmp.write (command + "\n")
-		tmp.close ()
-		
-		temp = None
-
-		if self.root == 1:
-			if self.user != "root":
-				#changes the ownership
-				os.chown(path, self.uid, self.gid)
-				execute = config.getSubin() + " " + self.user + " -c \"" + config.getAtbin() +  " -f " + path + " " + runat + " && exit\""
-				child_stdin, child_stdout, child_stderr = os.popen3(execute)
-			else:
-				execute = config.getAtbin() + " -f " + path + " " + runat
-				child_stdin, child_stdout, child_stderr = os.popen3(execute)
-		else:
-			execute = config.getAtbin() + " -f " + path + " " + runat
-			child_stdin, child_stdout, child_stderr = os.popen3(execute)
-
-
-		err = child_stderr.readlines ()
-		job_id = 0
-		for line in err:
-			t = self.parse (line, False)
-			if t != False:
-				job_id = t
-		
-		#print job_id
-		
-		desc = ""
-		self.write_job_data (job_id, title, desc)
-		
-		os.unlink (path)
-
-
-	def update (self, job_id, runat, command, title):
-		#print "update" + str (job_id) + runat + command + title
-		#remove old
-		f = os.path.join (self.atdata, str (job_id))
-		if os.access (f, os.F_OK):
-			os.unlink (f)
-		execute = config.getAtrmbin()+ " " + str(job_id)
-		commands.getoutput(execute)
-		
-		#add new
-		tmpfile = tempfile.mkstemp ()
-		fd, path = tmpfile
-		tmp = os.fdopen(fd, 'w')
-
-		tmp.write (self.SCRIPT_DELIMITER + "\n")
-		if self.manual_poscorrect:
-			tmp.write (self.POSIXLY_CORRECT_UNSET)
-		tmp.write (command + "\n")
-		tmp.close ()
-
-		if self.root == 1:
-			if self.user != "root":
-				#changes the ownership
-				os.chown(path, self.uid, self.gid)
-				execute = config.getSubin() + " " + self.user + " -c \"" + config.getAtbin() +  " -f " + path + " " + runat + " && exit\""
-				child_stdin, child_stdout, child_stderr = os.popen3(execute)
-			else:
-				execute = config.getAtbin() + " -f " + path + " " + runat
-				child_stdin, child_stdout, child_stderr = os.popen3(execute)
-		else:
-			execute = config.getAtbin() + " -f " + path + " " + runat
-			child_stdin, child_stdout, child_stderr = os.popen3(execute)
-
-		err = child_stderr.readlines ()
-		job_id = 0
-		for line in err:
-			t = self.parse (line, False)
-			if t != False:
-				job_id = t
-		
-		#print job_id
-		
-		desc = ""
-		self.write_job_data (job_id, title, desc)
-		
-		os.unlink (path)
-		
-
-	def delete (self, job_id, iter):
-		if job_id:
-			# delete file
-			f = os.path.join (self.atdata, str(job_id))
-			if os.access(f, os.F_OK):
-				os.unlink (f)
-			execute = config.getAtrmbin()+ " " + str(job_id)
-			commands.getoutput(execute)
-			
-				
-	def read (self):
-		data = []
-		#do 'atq'
-		execute = config.getAtqbin ()
-		self.lines = os.popen(execute).readlines()
-		for line in self.lines:
-			
-			array_or_false = self.parse (line)
-			#print array_or_false
-			if array_or_false != False:
-				(job_id, date, time, class_id, user, lines, title, prelen, dangerous) = array_or_false
-
-			
-				preview = self.__make_preview__ (lines, prelen)
-				if dangerous == 1:
-						preview = _("DANGEROUS PARSE: %(preview)s") % {'preview':  preview}
-				#chopping of script delimiter
-				lines = lines[prelen:]
-				lines.strip ()
-					
-				timestring = "%s %s" % (date, time)
-				# TODO: localize time and date formats
-				timestring_show = _("On %(date)s at %(time)s") % {'date': date, 'time': time}
-				
-				# TODO: looks like it could be one append
-				if self.root == 1:
-					if self.user == user:
-						data.append([title, timestring_show, preview, lines, int(job_id), timestring, self, None, date, class_id, user, time, _("Once"), "at", self.nooutput, timestring])
-					else: 
-						#print "Record omitted, not current user"
-						pass
-				else:
-					data.append([title, timestring_show, preview, lines, int(job_id), timestring, self, None, date, class_id, user, time, _("Once"), "at", self.nooutput, timestring])
-
-				#print _("added %(id)s") % { "id": job_id	}
-			else:
-				print _("Warning: a line in atq's output didn't parse")	
-		return data
-
-	
-	def __prepare_script__ (self, script, manual_poscorrect):
-	
-		# It looks like at prepends a bunch of stuff to each script
-		# Luckily it delimits that using two newlines
-		# So assuming that at never prepends two newlines unless
-		# it's done prepending, we will start recording the custom commands
-		# once the first two lines have been found
-
-		# Later: It now seems like this is incorrect, and may vary upon distribution. I therefore determine the prepended stuff by making a test job and then removing the length of it. in gentoo it adds to newlines at the end of the script
-		
-		# If the script is created by Gnome Schedule the script is seperated by a delimiter.
-
-		dangerous = 0
-		prelen = 0
-		string = self.SCRIPT_DELIMITER
-		scriptstart = script.find(string)
-
-		if scriptstart != -1:
-			script = script[scriptstart:]
-			if manual_poscorrect == True:
-				scriptstart = script.find (self.POSIXLY_CORRECT_UNSET)
-				if scriptstart != -1:
-					script = script[scriptstart:]
-					prelen = len (self.POSIXLY_CORRECT_UNSET)
-			else:
-				prelen = len(self.SCRIPT_DELIMITER) + 1
-
-		else:
-			dangerous = 1
-
-			string = " || {\n	 echo 'Execution directory inaccessible' >&2\n	 exit 1\n}\n"
-			string_len = len(string)
-			start = script.find(string)
-			start = start + string_len
-			script = script[start:]
-			prelen = 0
-			# If the string contains TITLE=
-			titlestart = script.find ("TITLE=")
-			if titlestart != -1:
-				titleend = script.find("\n", titlestart)
-				title = script[(titlestart + 6):titleend]
-				#remeber the length to remove this from the preview
-				prelen = len(title) + 7
-			else:
-				title = "Untitled"
-			# If the string contains ICON=
-			iconstart = script.find ("ICON=") 
-			if iconstart != -1:
-				iconend = script.find ("\n", iconstart)
-				icon = script[(iconstart + 5):iconend]
-			
-				prelen = prelen + len(icon) + 6
-		
-			else:
-				icon = None 
-
-		return script, prelen, dangerous
-
-
-	def __make_preview__ (self, lines, prelen, preview_len = 0):
-		if preview_len == 0:
-			preview_len = self.preview_len
-		try:
-			if prelen:
-				result = lines[(0 + prelen):(preview_len + prelen)]
-			else:
-				result = lines[0:preview_len]
-		except:
-			#print "short preview"
-			result = lines[prelen:(-1 - prelen)]
-
-		result = result.replace("\n",";")
-		result = result.replace ("&", "&amp;")
-		#remove ending newlines, not if result len = 0
-		if len(result) < 2:
-			done = 1
-		else:
-			done = 0
-		while done == 0:
-			if result[-1] == ";":
-				result = result[0:-1]
-			else:
-				done = 1
-		#remove beginning newlines
-		if len(result) < 2:
-			done = 1
-		else:
-			done = 0
-		while done == 0:
-			if result[0] == ";":
-				result = result[1:]
-			else:
-				done = 1
+    def __init__(self,root,user,uid,gid,user_home_dir,manual_poscorrect):
+    
+        #default preview length
+        self.preview_len = 50
+        self.root = root
+        self.set_rights(user,uid,gid, user_home_dir)
+        self.user_home_dir = user_home_dir
+        self.manual_poscorrect = manual_poscorrect
+
+
+        # 16       2006-01-08 13:01 a gaute
+        # 7       Sun Jan  8 13:01:00 2006 a pvanhoof
+        # 1 2006-04-26 08:54 a gaute
+        # 14    2006-09-21 10:54 a gaute
+        # 3 Tue May  8 01:01:00 2007 a gaute
+
+        self.atRecordRegex = re.compile('^([\d]+)[\t]([\w]{3,3})[\s]([\w]{3,3})[\s]*([\d]+)[\s]([\d]{2,2}[:][\d]{2,2}[:][\d]{2,2})[\s]([\d]{4,4})[\s]([\w])[\s]([\w]+)')
+            
+
+        # after you add a job, this line is printed to stderr
+        # job 10 at 2006-09-18 12:38
+        self.atRecordRegexAdd = re.compile('^job\s([0-9]+)\sat')
+        
+        self.atRecordRegexAdded = re.compile('[^\s]+\s([0-9]+)\sat')
+        self.SCRIPT_DELIMITER = "###### ---- GNOME_SCHEDULE_SCRIPT_DELIMITER #####"
+        
+        self.DISPLAY = "DISPLAY=%s; export DISPLAY;\n"
+        self.DISPLAY = self.DISPLAY + config.xwrapper_exec + " a\n"
+        self.DISPLAY = self.DISPLAY + """
+xwrapper=$?;
+if [ $xwrapper -eq 0 ]; then
+    echo "all fine";
+else
+    echo "xwrapper failed.";
+    exit;
+fi
+"""
+
+        # If normally this variable is unset the user would not expect it 
+        # to be set, which it will be because Gnome Schedule needs it.
+        # Therefore we unset it in the script. 
+        self.POSIXLY_CORRECT_UNSET = "unset POSIXLY_CORRECT\n"
+        
+        self.atdatafileversion = 5
+        self.atdata = self.user_home_dir + "/.gnome/gnome-schedule/at"
+        if os.path.exists (self.user_home_dir + "/.gnome") != True:
+            os.mkdir (self.user_home_dir + "/.gnome", 0700)
+            os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
+        if os.path.exists(self.atdata) != True:
+            try:
+                os.makedirs(self.atdata, 0700)
+                if self.root == 1:
+                    os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
+                    os.chown (self.atdata, self.uid, self.gid)
+            except:
+                print _("Failed to create data dir! Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.")
+                
+        self.months = {
+            'Jan' : '1',
+            'Feb' : '2',
+            'Mar' : '3',
+            'Apr' : '4',
+            'May' : '5',
+            'Jun' : '6',
+            'Jul' : '7',
+            'Aug' : '8',
+            'Sep' : '9',
+            'Oct' : '10',
+            'Nov' : '11',
+            'Dec' : '12'
+        }
+        
+    def set_rights(self,user,uid,gid, ud):
+        self.user = user
+        self.uid = uid
+        self.gid = gid
+        self.user_home_dir = ud
+        self.atdata = self.user_home_dir + "/.gnome/gnome-schedule/at"
+        if os.path.exists (self.user_home_dir + "/.gnome") != True:
+            os.mkdir (self.user_home_dir + "/.gnome", 0700)
+            os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
+        if os.path.exists(self.atdata) != True:
+            try:
+                os.makedirs(self.atdata, 0700)
+                if self.root == 1:
+                    os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
+                    os.chown (self.atdata, self.uid, self.gid)
+            except:
+                print (_("Failed to create data dir: %s. Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.") % (self.atdata))
+
+    
+    def get_type (self):
+        return "at"
+        
+    def parse (self, line, output = True):
+        if (output == True):
+            if len (line) > 1 and line[0] != '#':
+                m = self.atRecordRegex.match(line)
+                if m != None:           
+                    # Time
+                    time = m.groups ()[4][:-3]
+                    
+                    # Date
+                    day = m.groups ()[3]
+                    month = m.groups ()[2]
+                    
+                    for monthname in self.months:
+                        month = month.replace (monthname, self.months[monthname])
+                        
+                    if int (day) < 10:
+                        day = "0" + day
+                    if int (month) < 10:
+                        month = "0" + month
+                        
+                    date = day + "." + month + "." + m.groups ()[5]
+
+                    job_id = m.groups ()[0]
+                    class_id = m.groups ()[6]
+                    user = m.groups ()[7]
+                        
+                    success, title, desc, manual_poscorrect, output, display = self.get_job_data (int (job_id))
+                    # manual_poscorrect is only used during preparation of script
+
+                    execute = config.getAtbin() + " -c " + job_id
+                    # read lines and detect starter
+                    script = os.popen(execute).read()
+                    script,  dangerous = self.__prepare_script__ (script, manual_poscorrect, output, display)
+                                        
+                    #removing ending newlines, but keep one
+                    #if a date in the past is selected the record is removed by at, this creates an error, and generally if the script is of zero length
+                    # TODO: complain about it as well
+                    
+                    if len(script) < 2:
+                        done = 1
+                    else:
+                        done = 0
+
+                    while done == 0:
+                        if script[-1] == "\n":
+                            script = script[0:-1]
+                        else:
+                            done = 1
+
+                    return job_id, date, time, class_id, user, script, title, dangerous, output
+                    
+        elif (output == False):
+            if len (line) > 1 and line[0] != '#':
+                m = self.atRecordRegexAdd.search(line)
+                #print "Parsing line: " + line
+                if m != None:
+                    #print "Parse successfull, groups: "
+                    #print m.groups()
+                    job_id = m.groups ()[0]
+                    return int(job_id)
+                else:
+                    return False
+
+        return False
+        # TODO: throw exception
+
+    def get_job_data (self, job_id):
+        f = os.path.join (self.atdata, str (job_id))
+        if os.access (f, os.R_OK):
+            fh = open (f, 'r')
+            d = fh.read ()
+            
+            ver_p = d.find ("ver=")
+            if ver_p == -1:
+                ver = 1
+            else:
+                ver_s = d[ver_p + 4:d.find ("\n")]
+                d = d[d.find ("\n") + 1:]
+                ver = int (ver_s)
+                
+            title = d[6:d.find ("\n")]
+            d = d[d.find ("\n") + 1:]
+            
+            # icons out
+            if ver < 2:
+                icon = d[5:d.find ("\n")]
+                d = d[d.find ("\n") + 1:]
+            
+            desc = d[5:d.find ("\n")]
+            d = d[d.find ("\n") + 1:]
+            
+            manual_poscorrect_b = False
+            if ver > 2:
+                manual_poscorrect = d[18:d.find ("\n")]
+                d = d[d.find ("\n") + 1:]
+                if manual_poscorrect == "true":
+                    manual_poscorrect_b = True
+                elif manual_poscorrect == "false":
+                    manual_poscorrect_b = False
+            
+            if ver >= 5:
+                output_str = d[7:d.find ("\n")]
+                output = int (output_str)
+                d = d[d.find("\n") + 1:]
+            else:
+                output = 0
+
+            if ver >= 5:
+                display = d[8:d.find ("\n")]
+                d = d[d.find ("\n") + 1:]
+                if (len (display) < 1) or (output == 0):
+                    display = ""
+            else:
+                display = ""
+
+            fh.close ()
+            
+            return True, title, desc, manual_poscorrect_b, output, display
+            
+        else: 
+            return False, "", "", False, 0, ""
+            
+    def write_job_data (self, job_id, title, desc, output, display):
+        # Create and write data file
+        f = os.path.join (self.atdata, str(job_id))
+        #print f
+        fh = open (f, 'w')
+        fh.truncate (1)
+        fh.seek (0)
+        fh.write ("ver=" + str(self.atdatafileversion) + "\n")
+        fh.write ("title=" + title + "\n")
+        fh.write ("desc=" + desc + "\n")
+        
+        # This one doesn't need to be passed independently for each job since the job data is only updated together with a task being appended or updated (also new added), and the variable depends on each session. Not job.
+        if self.manual_poscorrect == True:
+            fh.write ("manual_poscorrect=true\n")
+        else:
+            fh.write ("manual_poscorrect=false\n")
+
+        fh.write ("output=" + str (output) + "\n")
+        fh.write ("display=" + display + "\n")
+
+        fh.close ()
+        os.chown (f, self.uid, self.gid)
+        os.chmod (f, 0600)
+            
+    def checkfield (self, runat):
+        #TODO: fix bug $0:19 2004-12-8$ not valid by regexp
+        # print "$" + runat + "$"
+        #regexp1 = re.compile("([0-9][0-9]):([0-9][0-9])\ ([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
+        #print "Testing: " + runat
+        regexp1 = re.compile ("([0-9][0-9])([0-9][0-9])\ ([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
+        regexp2 = re.compile("([0-9][0-9])([0-9][0-9])")
+        regexp3 = re.compile("([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
+        
+        runat_g1 = regexp1.match(runat)
+        runat_g2 = regexp2.match(runat)
+        runat_g3 = regexp3.match(runat)
+        ctime = time.localtime()
+        cyear = ctime[0]
+        cmonth = ctime[1]
+        cday = ctime[2]
+        chour = ctime[3]
+        cminute = ctime[4]
+    
+        if runat_g1:
+            (hour, minute, day, month, year) =  runat_g1.groups()
+            hour = int(hour)
+            minute = int(minute)
+            year = int(year)
+            month = int(month)
+            day = int(day)
+
+            if hour > 24 or hour < 0:
+                return False, "hour"
+            
+            if minute > 60 or minute < 0:
+                return False, "minute"
+            
+            if month > 12 or month < 0:
+                return False, "month"
+                
+            if day > 31 or day < 0:
+                return False, "day"
+                
+            if year < 0:
+                return False, "year"
+                
+            if year >= cyear: 
+                if year == cyear:
+                    syear = True
+                    if (month >= cmonth):
+                        if month == cmonth:
+                            smonth = True
+                            if day >= cday:
+                                if day == cday:
+                                    sday = True
+                                    if hour >= chour:
+                                        if hour == chour:
+                                            shour = True
+                                            if minute <= cminute:
+                                                return False, "minute"
+                                        else:
+                                            shour = False
+                                    else:
+                                        return False, "hour"
+                                else:
+                                    sday = False
+                            else:
+                                return False, "day"
+                        else:
+                            smonth = False
+                    else:
+                        return False, "month"
+                else:
+                    syear = False
+            else:
+                return False, "year"
+
+        elif runat_g2:
+
+            (hour, minute) =  runat_g2.groups()
+            hour = int(hour)
+            minute = int(minute)
+            if hour > 24 or hour < 0:
+                return False, "hour"
+    
+            if minute > 60 or minute < 0:
+                return False, "minute"
+
+
+        elif runat_g3:
+
+            (day, month, year) =  runat_g3.groups()
+            year = int(year)
+            month = int(month)
+            day = int(day)
+            if year < cyear:
+                return False, "year"
+            if month < cmonth:
+                return False, "month"
+            if day < cday:
+                return False, "day"
+
+        else:
+            #lowercase
+            runat = runat.lower()
+        
+            #some timespecs:
+            days = ['sun','mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sunday','monday','tuesday','wednesday','thursday','friday','saturday']
+            relative_days = ['tomorrow','next week','today']
+            relative_hour = ['noon','teatime','midnight','next hour']
+            relative_minute = ['next minute']
+            relative_month = ['next month']
+            
+            if runat in days:
+                pass
+            elif runat in relative_days:
+                pass
+            elif runat in relative_hour:
+                pass
+            elif runat in relative_minute:
+                pass
+            elif runat in relative_month:
+                pass
+            else:
+                return False, "other"
+
+        return True, "ok"
+
+        
+    def append (self, runat, command, title, output):
+        tmpfile = tempfile.mkstemp ()
+        fd, path = tmpfile
+        tmp = os.fdopen(fd, 'w')
+        tmp.write (self.SCRIPT_DELIMITER + "\n")
+        if self.manual_poscorrect:
+            tmp.write (self.POSIXLY_CORRECT_UNSET)
+
+        display = ""
+        if output > 0:
+            display = os.getenv ('DISPLAY')
+            tmp.write (self.DISPLAY %  display )
+            
+        tmp.write (command + "\n")
+        tmp.close ()
+        
+        temp = None
+
+        if self.root == 1:
+            if self.user != "root":
+                #changes the ownership
+                os.chown(path, self.uid, self.gid)
+                execute = config.getSubin() + " " + self.user + " -c \"" + config.getAtbin() +  " -f " + path + " " + runat + " && exit\""
+                child_stdin, child_stdout, child_stderr = os.popen3(execute)
+            else:
+                execute = config.getAtbin() + " -f " + path + " " + runat
+                child_stdin, child_stdout, child_stderr = os.popen3(execute)
+        else:
+            execute = config.getAtbin() + " -f " + path + " " + runat
+            child_stdin, child_stdout, child_stderr = os.popen3(execute)
+
+
+        err = child_stderr.readlines ()
+        job_id = 0
+        for line in err:
+            t = self.parse (line, False)
+            if t != False:
+                job_id = t
+        
+        #print job_id
+        
+        desc = ""
+        self.write_job_data (job_id, title, desc, output, display)
+        
+        os.unlink (path)
+
+
+    def update (self, job_id, runat, command, title, output):
+        #print "update" + str (job_id) + runat + command + title
+        #remove old
+        f = os.path.join (self.atdata, str (job_id))
+        if os.access (f, os.F_OK):
+            os.unlink (f)
+        execute = config.getAtrmbin()+ " " + str(job_id)
+        commands.getoutput(execute)
+        
+        #add new
+        tmpfile = tempfile.mkstemp ()
+        fd, path = tmpfile
+        tmp = os.fdopen(fd, 'w')
+
+        tmp.write (self.SCRIPT_DELIMITER + "\n")
+        if self.manual_poscorrect:
+            tmp.write (self.POSIXLY_CORRECT_UNSET)
+
+        display = ""
+        if output > 0:
+            display = os.getenv ('DISPLAY')
+            tmp.write (self.DISPLAY %  display )
+
+        tmp.write (command + "\n")
+        tmp.close ()
+
+        if self.root == 1:
+            if self.user != "root":
+                #changes the ownership
+                os.chown(path, self.uid, self.gid)
+                execute = config.getSubin() + " " + self.user + " -c \"" + config.getAtbin() +  " -f " + path + " " + runat + " && exit\""
+                child_stdin, child_stdout, child_stderr = os.popen3(execute)
+            else:
+                execute = config.getAtbin() + " -f " + path + " " + runat
+                child_stdin, child_stdout, child_stderr = os.popen3(execute)
+        else:
+            execute = config.getAtbin() + " -f " + path + " " + runat
+            child_stdin, child_stdout, child_stderr = os.popen3(execute)
+
+        err = child_stderr.readlines ()
+        job_id = 0
+        for line in err:
+            t = self.parse (line, False)
+            if t != False:
+                job_id = t
+        
+        #print job_id
+        
+        desc = ""
+        self.write_job_data (job_id, title, desc, output, display)
+        
+        os.unlink (path)
+        
+
+    def delete (self, job_id, iter):
+        if job_id:
+            # delete file
+            f = os.path.join (self.atdata, str(job_id))
+            if os.access(f, os.F_OK):
+                os.unlink (f)
+            execute = config.getAtrmbin()+ " " + str(job_id)
+            commands.getoutput(execute)
+            
+                
+    def read (self):
+        data = []
+        #do 'atq'
+        execute = config.getAtqbin ()
+        self.lines = os.popen(execute).readlines()
+        for line in self.lines:
+            
+            array_or_false = self.parse (line)
+            #print array_or_false
+            if array_or_false != False:
+                (job_id, date, time, class_id, user, lines, title, dangerous, output) = array_or_false
+
+            
+                preview = self.__make_preview__ (lines)
+                if dangerous == 1:
+                        preview = _("DANGEROUS PARSE: %(preview)s") % {'preview':  preview}
+                #chopping of script delimiter
+                lines.strip ()
+                    
+                timestring = "%s %s" % (date, time)
+                # TODO: localize time and date formats
+                timestring_show = _("On %(date)s at %(time)s") % {'date': date, 'time': time}
+                
+                # TODO: looks like it could be one append
+                if self.root == 1:
+                    if self.user == user:
+                        data.append([title, timestring_show, preview, lines, int(job_id), timestring, self, None, date, class_id, user, time, _("Once"), "at", output, timestring])
+                    else: 
+                        #print "Record omitted, not current user"
+                        pass
+                else:
+                    data.append([title, timestring_show, preview, lines, int(job_id), timestring, self, None, date, class_id, user, time, _("Once"), "at", output, timestring])
+
+                #print _("added %(id)s") % { "id": job_id   }
+            else:
+                print _("Warning: a line in atq's output didn't parse") 
+        return data
+
+    
+    def __prepare_script__ (self, script, manual_poscorrect, output, display):
+    
+        # It looks like at prepends a bunch of stuff to each script
+        # Luckily it delimits that using two newlines
+        # So assuming that at never prepends two newlines unless
+        # it's done prepending, we will start recording the custom commands
+        # once the first two lines have been found
+
+        # Later: It now seems like this is incorrect, and may vary upon distribution. I therefore determine the prepended stuff by making a test job and then removing the length of it. in gentoo it adds to newlines at the end of the script
+        
+        # If the script is created by Gnome Schedule the script is seperated by a delimiter.
+
+        dangerous = 0
+        scriptstart = script.find(self.SCRIPT_DELIMITER)
+
+        if scriptstart != -1:
+            script = script[scriptstart:]
+            if manual_poscorrect == True:
+                scriptstart = script.find (self.POSIXLY_CORRECT_UNSET)
+                if scriptstart != -1:
+                    script = script[scriptstart + len(self.POSIXLY_CORRECT_UNSET):]
+            else:
+                script = script[len(self.SCRIPT_DELIMITER) + 1:]
+
+            if output > 0:
+                scriptstart = script.find (self.DISPLAY % display)
+                if scriptstart != -1:
+                    script = script [scriptstart + len (self.DISPLAY % display):]
+
+        else:
+            dangerous = 1
+
+            string = " || {\n    echo 'Execution directory inaccessible' >&2\n   exit 1\n}\n"
+            string_len = len(string)
+            start = script.find(string)
+            start = start + string_len
+            script = script[start:]
+            prelen = 0
+            # If the string contains TITLE=
+            titlestart = script.find ("TITLE=")
+            if titlestart != -1:
+                titleend = script.find("\n", titlestart)
+                title = script[(titlestart + 6):titleend]
+                #remeber the length to remove this from the preview
+                prelen = len(title) + 7
+            else:
+                title = "Untitled"
+            # If the string contains ICON=
+            iconstart = script.find ("ICON=") 
+            if iconstart != -1:
+                iconend = script.find ("\n", iconstart)
+                icon = script[(iconstart + 5):iconend]
+            
+                prelen = prelen + len(icon) + 6
+        
+            else:
+                icon = None 
+
+            script = script[prelen:]
+
+        return script, dangerous
+
+
+    def __make_preview__ (self, lines, preview_len = 0):
+        if preview_len == 0:
+            preview_len = self.preview_len
+
+        if len (lines) > preview_len:
+            result = lines[0:preview_len]
+        else:
+            result = lines
+
+        result = result.replace("\n",";")
+        result = result.replace ("&", "&amp;")
+        #remove ending newlines, not if result len = 0
+        if len(result) < 2:
+            done = 1
+        else:
+            done = 0
+        while done == 0:
+            if result[-1] == ";":
+                result = result[0:-1]
+            else:
+                done = 1
+        #remove beginning newlines
+        if len(result) < 2:
+            done = 1
+        else:
+            done = 0
+        while done == 0:
+            if result[0] == ";":
+                result = result[1:]
+            else:
+                done = 1
 
-		if len(result) >= preview_len :
-			result = result + "..."
+        if len(result) >= preview_len :
+            result = result + "..."
 
-		return result
-		
+        return result
+        

Modified: trunk/src/atEditor.py
==============================================================================
--- trunk/src/atEditor.py	(original)
+++ trunk/src/atEditor.py	Sat Feb 14 21:20:56 2009
@@ -33,565 +33,583 @@
 
 
 class AtEditor:
-	def __init__(self, parent, backend, scheduler, template):
-		self.ParentClass = parent
-		self.xml = self.ParentClass.xml
-		self.backend = backend
-		self.scheduler = scheduler
-		self.template = template
-		
-
-		self.widget = self.xml.get_widget("at_editor")
-		self.xml.signal_connect("on_at_editor_delete", self.on_button_cancel_clicked)
-		
-		self.mode = 0 # 0 = add, 1 = edit, 2 = template
-
-		self.button_save = self.xml.get_widget ("at_button_save")
-		self.button_cancel = self.xml.get_widget ("at_button_cancel")
-		self.entry_title = self.xml.get_widget ("at_entry_title")
-		self.text_task = self.xml.get_widget ("at_text_task")
-		self.text_task_buffer = self.text_task.get_buffer()
-		self.button_add_template = self.xml.get_widget ("at_button_template")
-		self.at_vbox_time = self.xml.get_widget ("at_vbox_time")
-		
-
-		self.spin_hour = self.xml.get_widget ("at_spin_hour")
-		self.spin_minute = self.xml.get_widget ("at_spin_minute")
-		self.spin_year = self.xml.get_widget ("at_spin_year")
-		self.spin_month = self.xml.get_widget ("at_spin_month")
-		self.spin_day = self.xml.get_widget ("at_spin_day")
-		
-		self.title_box = self.xml.get_widget ("title_box")
-		
-		self.image_icon = gtk.Image ()
-		self.image_icon.set_from_pixbuf (self.ParentClass.bigiconat)
-		self.title_box.pack_start (self.image_icon, False, False, 0)
-		self.title_box.reorder_child (self.image_icon, 0)
-		self.image_icon.show ()
-		
-		self.cal_button = self.xml.get_widget ("cal_button")
-		self.cal_hbox = gtk.HBox ()
-		self.calicon = gtk.Image ()
-		self.calicon.set_from_pixbuf (self.ParentClass.iconcalendar)
-		self.arrow = gtk.Arrow (gtk.ARROW_DOWN, gtk.SHADOW_OUT)
-		self.cal_label = gtk.Label (_("Calendar"))
-		self.cal_hbox.add (self.calicon)
-		self.cal_hbox.add (self.cal_label)
-		self.cal_hbox.add (self.arrow)
-		self.cal_button.add (self.cal_hbox)
-		self.cal_button.show_all ()
-		
-		self.xml.signal_connect ("on_cal_button_toggled", self.on_cal_button_toggled)
-		
-		self.cal_loaded = False
-		self.x, self.y = self.widget.get_position ()
-		self.height, self.wid9847th = self.widget.get_size ()
-		self.cal_active = True
-		
-		self.xml.signal_connect ("on_at_editor_size_changed", self.on_at_editor_size_changed)
-		
-		self.xml.signal_connect("on_at_button_cancel_clicked", self.on_button_cancel_clicked)
-		self.xml.signal_connect("on_at_button_save_clicked", self.on_button_save_clicked)
-
-		self.xml.signal_connect("on_at_text_task_popup_menu", self.on_text_task_popup_menu)
-		self.xml.signal_connect("on_at_text_task_key_release_event", self.on_text_task_change)
-
-		self.xml.signal_connect("on_at_entry_title_changed", self.on_entry_title_changed)
-
-		self.xml.signal_connect("on_at_button_cancel_clicked", self.on_button_cancel_clicked)
-		self.xml.signal_connect ("on_at_button_template_clicked", self.on_button_template_clicked)
-		
-		self.check_spin_running = False
-		
-		self.xml.signal_connect("on_at_spin_hour_changed", self.on_spin_hour_changed)
-		self.xml.signal_connect("on_at_spin_minute_changed", self.on_spin_minute_changed)
-		self.xml.signal_connect ("on_at_spin_year_changed", self.on_spin_year_changed)
-		self.xml.signal_connect ("on_at_spin_month_changed", self.on_spin_month_changed)
-		self.xml.signal_connect ("on_at_spin_day_changed", self.on_spin_day_changed)
-		
-		ctime = time.localtime()
-		year = ctime[0]
-		self.spin_year.set_range (year, year + 5847) # TODO: Year +5847 compatability
-		self.timeout_handler_id = gobject.timeout_add(60 * 1000, self.__check_spins__)
-		
-		
-	def showadd (self, transient):
-		self.button_save.set_label (gtk.STOCK_ADD)
-		self.__reset__ ()
-		self.title = _("Untitled")
-		self.mode = 0 # add new task
-		self.widget.set_title(_("Create a New Scheduled Task"))
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.__setup_calendar__ ()
-		self.button_add_template.show ()
-		self.widget.show_all ()
-		
-		self.__update_textboxes__()
-	
-	def showadd_template (self, transient, title, command):
-		self.button_save.set_label (gtk.STOCK_ADD)
-		self.__reset__ ()
-		self.title = title
-		self.command = command
-		self.mode = 0 # add new task
-		self.widget.set_title(_("Create a New Scheduled Task"))
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.__setup_calendar__ ()
-		self.button_add_template.show ()
-		self.widget.show_all ()
-		
-		self.__update_textboxes__()
-	
-	def showedit_template (self, transient, id, title, command):
-		self.button_save.set_label (gtk.STOCK_ADD)
-		self.__reset__ ()
-		self.tid = id
-		self.title = title
-		self.command = command
-		self.mode = 2 # edit template
-		
-		self.widget.set_title(_("Edit template"))
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.__setup_calendar__ ()
-		self.widget.show_all ()
-		
-		# hide time settings
-		self.at_vbox_time.hide ()
-		
-		# save and cancel buttons
-		self.button_save.set_label (gtk.STOCK_SAVE)
-		self.button_add_template.hide ()
-		
-		self.__update_textboxes__()
-	
-	def shownew_template (self, transient):
-		self.button_save.set_label (gtk.STOCK_ADD)
-		self.__reset__ ()
-		self.tid = 0
-		self.mode = 2 # edit template
-		
-		self.widget.set_title(_("New template"))
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.__setup_calendar__ ()
-		self.widget.show_all ()
-		
-		# hide time settings
-		self.at_vbox_time.hide ()
-		
-		# save and cancel buttons
-		self.button_save.set_label (gtk.STOCK_ADD)
-		self.button_add_template.hide ()
-		
-		self.__update_textboxes__()
-		
-	def showedit (self, transient, record, job_id, iter):
-		self.button_save.set_label (gtk.STOCK_APPLY)
-		self.mode = 1 # edit task
-		self.job_id = job_id
-		self.date = self.ParentClass.treemodel.get_value(iter, 9)
-		self.time = self.ParentClass.treemodel.get_value(iter, 12)
-		self.title = self.ParentClass.treemodel.get_value(iter, 0)
-		self.class_id = self.ParentClass.treemodel.get_value(iter, 9)
-		self.user = self.ParentClass.treemodel.get_value(iter, 10)
-		self.command = self.ParentClass.treemodel.get_value(iter, 3)
-		# removing beginning newlines.. wherever they come from..
-		i = self.command.find ('\n', 0)
-		while i == 0:
-			self.command = self.command[1:]
-			i = self.command.find ('\n', 0)
-			
-		#parse 	
-		(hour, minute, day, month, year) = self.__parse_time__(self.time, self.date)
-		self.runat = hour + minute  + " " + day + "." + month + "." + year
-		self.spin_year.set_value (int (year))
-		self.spin_month.set_value (int (month))
-		self.spin_day.set_value (int (day))
-
-		self.spin_hour.set_value(int(hour))
-		self.spin_minute.set_value(int(minute))
-		self.widget.set_title(_("Edit a Scheduled Task"))
-		
-		self.__update_textboxes__ ()
-		self.parentiter = iter
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.__setup_calendar__ ()
-		self.button_add_template.show ()
-		self.widget.show_all ()
-
-		
-
-	def on_cal_lost_focus (self, *args):
-		self.__hide_calendar__ ()
-		
-	def on_at_editor_size_changed (self, *args):
-		if self.cal_button.get_active ():
-			x, y = self.widget.get_position ()
-			height, width = self.widget.get_size ()
-			if ((x != self.x) or (y != self.y) or (height != self.height) or (width != self.width)):
-				self.__hide_calendar__ ()
-				
-	def on_cal_button_toggled (self, *args):
-		if self.cal_button.get_active ():
-			self.__show_calendar__ ()
-		else:
-			self.__hide_calendar__ ()
-	
-	
-	def __setup_calendar__ (self):
-		if self.cal_loaded == False:
-			self.xml.signal_connect ("on_cal_lost_focus", self.on_cal_lost_focus)
-			self.xml.signal_connect ("on_cal_window_destroy", self.__destroy_calendar__) # its actually not destroyed, but deleted
-		
-			self.xml.signal_connect ("on_cal_day_selected_dc", self.on_cal_day_selected_dc)
-			self.xml.signal_connect ("on_cal_day_selected", self.on_cal_day_selected)
-		
-			self.cal_window = self.xml.get_widget ("cal_window")
-			self.calendar = self.xml.get_widget ("calendar")
-			self.cal_window.hide_all ()
-			self.cal_loaded = True
-		
-	def __destroy_calendar__ (self):
-		self.cal_window.hide_all ()
-		return True
-
-	def on_cal_day_selected (self, *args):
-		if self.cal_active:
-			year, month, day = self.calendar.get_date ()
-			self.spin_year.set_value (int (year))
-			self.spin_month.set_value (int (month) + 1)
-			self.spin_day.set_value (int (day))
-		
-	def on_cal_day_selected_dc (self, *args):
-		self.__hide_calendar__ ()
-				
-	def __show_calendar__ (self):
-		x, y = self.widget.window.get_origin ()
-		button_rect = self.cal_button.get_allocation ()
-		x = x + button_rect.x
-		y = y + button_rect.y + button_rect.height
-		self.cal_window.move (x, y)
-		self.widget.set_modal (False)
-		self.x, self.y = self.widget.get_position ()
-		self.height, self.width = self.widget.get_size ()
-		self.cal_active = False
-		self.calendar.select_month (self.spin_month.get_value_as_int () -1 , self.spin_year.get_value_as_int ())
-		self.calendar.select_day (self.spin_day.get_value_as_int ())
-		self.cal_active = True
-		self.cal_window.show_all ()
-		
-	def __hide_calendar__ (self):
-		self.cal_window.hide_all ()
-		self.cal_button.set_active (False)
-		self.widget.set_modal (True)
-		
-		
-	def on_worded_label_event (self, *args):
-		#TODO highlight on mouseover
-		pass
-
-	def on_defined_label_event (self, *args):
-		#TODO highlight on mouseover
-		# enable control_option on click
-		pass
-
-	def on_text_task_popup_menu (self, *args):
-		#TODO show at_script_menuons: install t
-		# don't forget to attach eventhandling to this popup
-		pass
-		
-
-	
-	def on_text_task_change (self, *args):
-		start = self.text_task_buffer.get_start_iter()
-		end = self.text_task_buffer.get_end_iter()
-		self.command = self.text_task_buffer.get_text(start, end)
-
-
-	def on_entry_title_changed (self, *args):
-		self.title = self.entry_title.get_text()
-
-	def on_spin_day_changed (self, *args):	
-		self.__check_spins__ ()	
-		self.__update_time_cal__()
-
-	def on_spin_month_changed (self, *args):
-		self.__check_spins__ ()
-		self.__update_time_cal__()
-	
-	def on_spin_year_changed (self, *args):
-		self.__check_spins__ ()
-		self.__update_time_cal__()
-
-	def on_spin_hour_changed (self, *args):
-		self.__check_spins__ ()
-		self.__update_time_cal__()
-
-	def on_spin_minute_changed (self, *args):
-		self.__check_spins__ ()
-		self.__update_time_cal__()
-
-	def __check_spins__ (self):
-		# Is additionally run every minute
-		if self.check_spin_running != True:
-			self.check_spin_running = True
-			
-			ctime = time.localtime()
-			year = ctime[0]
-			month = ctime[1]
-			day = ctime[2]
-			hour = ctime[3]
-			minute = ctime[4]
-			
-			cyear = False
-			cmonth = False
-			cday = False
-			chour = False
-			
-			syear = self.spin_year.get_value_as_int ()
-			if (syear == year):
-				cyear = True
-			
-			smonth = self.spin_month.get_value_as_int ()
-			mi, ma = self.spin_month.get_range ()
-			if cyear:
-				if (mi != month):
-					self.spin_month.set_range (month, 12)
-					mi = month
-			else: 
-				if ((mi != 1) or (ma != 12)):
-					self.spin_month.set_range (1, 12)
-			if (mi <= smonth <= ma):
-				self.spin_month.set_value (smonth)
-			else:
-				if (smonth > ma):
-					self.spin_month.set_value (ma)
-				else:
-					self.spin_month.set_value (mi)
-			smonth = self.spin_month.get_value_as_int ()
-			if (smonth == month):
-				cmonth = True
-			
-			sday = self.spin_day.get_value_as_int ()		
-			mi, ma = self.spin_day.get_range ()
-			w, days = calendar.monthrange (syear, smonth)
-			if (cmonth and cyear):
-				if (mi != day):
-					self.spin_day.set_range (day, days)
-					mi = day
-			else:
-				if ((mi != 1) or (ma != days)):
-					self.spin_day.set_range (1, days)
-			if (mi <= sday <= days):
-				self.spin_day.set_value (sday)
-			else:
-				if (sday > days):
-					self.spin_day.set_value (days)
-				else:
-					self.spin_day.set_value (mi)
-			sday = self.spin_day.get_value_as_int ()
-			if (sday == day):
-				cday = True
-			
-			shour = self.spin_hour.get_value_as_int ()
-			mi, ma = self.spin_hour.get_range ()
-			if (cyear and cmonth and cday):
-				if (mi != hour):
-					self.spin_hour.set_range (hour, 24)
-					mi = hour
-			else:
-				if ((mi != 0) or (ma != 24)):
-					self.spin_hour.set_range (0, 24)
-			if (mi <= shour <= ma):
-				self.spin_hour.set_value (shour)
-			else:
-				if (shour > ma):
-					self.spin_hour.set_value (ma)
-				else:
-					self.spin_hour.set_value (mi)
-			shour = self.spin_hour.get_value_as_int ()
-			if (shour == hour):
-				chour = True
-			
-			sminute = self.spin_minute.get_value_as_int ()
-			mi, ma = self.spin_minute.get_range ()
-			if (cyear and cmonth and cday and chour):
-				if (mi != minute):
-					self.spin_minute.set_range (minute, 59)
-					mi = minute
-			else:
-				if ((mi != 0) or (ma != 59)):
-					self.spin_minute.set_range (0, 59)
-			if (mi <= sminute <= ma):
-				self.spin_minute.set_value (sminute)
-			else:
-				if (sminute > ma):
-					self.spin_minute.set_value (ma)
-				else:
-					self.spin_minute.set_value (mi)	
-			self.check_spin_running = False
-		
-	
-	def __update_time_cal__ (self):
-		year = self.spin_year.get_text ()
-		month = self.spin_month.get_text ()
-		day = self.spin_day.get_text ()
-		hour = self.spin_hour.get_text()
-		minute = self.spin_minute.get_text()
-
-		year = str(year)
-		
-		if hour.isdigit():
-			hour = int(hour)
-		else:
-			return False
-			
-		if minute.isdigit():
-			minute = int(minute)
-		else:
-			return False
-			
-		if day.isdigit ():
-			day = int (day)
-		else:
-			return False
-		
-		if month.isdigit ():
-			month = int (month)
-		else:
-			return False
-		
-		if year.isdigit () == False:
-			return False
-			
-		if hour < 10:
-			hour = "0" + str(hour)
-		else:
-			hour = str(hour)
-	
-		if minute < 10:
-			minute = "0" + str(minute)
-		else:
-			minute = str(minute)
-		
-		if month < 10:
-			month = "0" + str(month)
-		else:
-			month = str(month)
-
-		if day < 10:
-			day = "0" + str(day)
-		else:
-			day = str(day)
-
-		self.runat = hour + minute + " " + day + "." + month + "." + year
-
-
-	def popup_error_no_digit (self, field):
-		box_popup = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("In one or both of the fields hour and minute there was entered a letter, or a number out of range. Remember an hour only has 60 minutes and a day only 24 hours."))
-		box_popup.set_response_sensitive(gtk.RESPONSE_OK, True)
-		run = box_popup.run ()
-		box_popup.hide ()
-		field.set_text ("0")
-
-
-	def __reset__ (self):
-		self.title = _("Untitled")
-		self.command = ""
-
-		ctime = time.localtime()
-		year = ctime[0]
-		month = ctime[1]
-		day = ctime[2]
-		hour = ctime[3]
-		minute = ctime[4]
-		
-		self.runat = str(hour) + str(minute) + " " + str(day) + "." + str(month) + "." + str (year)
-
-		self.spin_hour.set_value(int(hour))
-		self.spin_minute.set_value(int(minute))
-		self.spin_year.set_value (int (year))
-		self.spin_month.set_value (int (month))
-		self.spin_day.set_value (int (day))
-
-		self.__update_textboxes__ ()
-		
-
-	def __update_textboxes__(self, update_runat = 1):
-
-		if self.title == None:
-			self.title = _("Untitled")
-
-		self.entry_title.set_text(self.title)
-		self.text_task_buffer.set_text(self.command)
-
-	def __parse_time__ (self, time, date):
-		regexp_date = re.compile("([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
-		regexp_time = re.compile("([0-9][0-9]):([0-9][0-9])")
-
-		time_g = regexp_time.match(time)
-		if time_g:
-			(hour, minute) = time_g.groups()
-
-		date_g = regexp_date.match(date)
-		if date_g:
-			(day, month, year) = date_g.groups()	
-		
-		return hour, minute, day, month, year
-
-
-	def on_button_cancel_clicked (self, *args):
-		self.__destroy_calendar__ ()
-		self.widget.hide()
-		return True
-		
-
-	def __WrongRecordDialog__ (self, x):
-		self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is an invalid record! The problem could be: %s") % (x)))
-		self.wrongdialog.run()
-		self.wrongdialog.destroy()
-
-	def on_button_template_clicked (self, *args):
-		self.template.savetemplate_at (0, self.title, self.command)
-		self.widget.hide ()
-
-	def on_button_save_clicked (self, *args):
-		if self.mode == 2:
-			self.template.savetemplate_at (self.tid, self.title, self.command)
-			self.widget.hide ()
-			return
-			
-		(validate, reason) = self.scheduler.checkfield(self.runat)
-		if validate == False:
-			self.__WrongRecordDialog__ (reason)
-			return
-		
-		if (self.backend.get_not_inform_working_dir_at() != True):
-			dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nOne-time tasks will be run from the directory where Gnome schedule is run from (normally the home directory)."))
-			dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
-			dia2.set_title (_("Warning: Working directory of executed tasks"))
-			response = dia2.run ()
-			if response == gtk.RESPONSE_CANCEL:
-				dia2.destroy ()
-				del dia2
-				return
-			elif response == gtk.RESPONSE_CLOSE:
-				self.backend.set_not_inform_working_dir_at (True)
-			else:
-				pass
-			dia2.destroy ()
-			del dia2
-		
-		if self.mode == 1:
-			self.scheduler.update (self.job_id, self.runat, self.command, self.title)
-		else:
-			self.scheduler.append (self.runat, self.command, self.title)
-		
-		self.ParentClass.schedule_reload ()
-			
-		self.widget.hide ()
-		
+    def __init__(self, parent, backend, scheduler, template):
+        self.ParentClass = parent
+        self.xml = self.ParentClass.xml
+        self.backend = backend
+        self.scheduler = scheduler
+        self.template = template
+        
+
+        self.widget = self.xml.get_widget("at_editor")
+        self.xml.signal_connect("on_at_editor_delete", self.on_button_cancel_clicked)
+        
+        self.mode = 0 # 0 = add, 1 = edit, 2 = template
+
+        self.button_save = self.xml.get_widget ("at_button_save")
+        self.button_cancel = self.xml.get_widget ("at_button_cancel")
+        self.entry_title = self.xml.get_widget ("at_entry_title")
+        self.text_task = self.xml.get_widget ("at_text_task")
+        self.text_task_buffer = self.text_task.get_buffer()
+        self.button_add_template = self.xml.get_widget ("at_button_template")
+        self.at_vbox_time = self.xml.get_widget ("at_vbox_time")
+
+        self.cb_xoutput = self.xml.get_widget ("cb_xoutput")
+
+        self.spin_hour = self.xml.get_widget ("at_spin_hour")
+        self.spin_minute = self.xml.get_widget ("at_spin_minute")
+        self.spin_year = self.xml.get_widget ("at_spin_year")
+        self.spin_month = self.xml.get_widget ("at_spin_month")
+        self.spin_day = self.xml.get_widget ("at_spin_day")
+        
+        self.title_box = self.xml.get_widget ("title_box")
+        
+        self.image_icon = gtk.Image ()
+        self.image_icon.set_from_pixbuf (self.ParentClass.bigiconat)
+        self.title_box.pack_start (self.image_icon, False, False, 0)
+        self.title_box.reorder_child (self.image_icon, 0)
+        self.image_icon.show ()
+        
+        self.cal_button = self.xml.get_widget ("cal_button")
+        self.cal_hbox = gtk.HBox ()
+        self.calicon = gtk.Image ()
+        self.calicon.set_from_pixbuf (self.ParentClass.iconcalendar)
+        self.arrow = gtk.Arrow (gtk.ARROW_DOWN, gtk.SHADOW_OUT)
+        self.cal_label = gtk.Label (_("Calendar"))
+        self.cal_hbox.add (self.calicon)
+        self.cal_hbox.add (self.cal_label)
+        self.cal_hbox.add (self.arrow)
+        self.cal_button.add (self.cal_hbox)
+        self.cal_button.show_all ()
+        
+        self.xml.signal_connect ("on_cal_button_toggled", self.on_cal_button_toggled)
+        self.xml.signal_connect ("on_cb_xoutput_toggled", self.on_cb_xoutput_toggled)
+        
+        self.cal_loaded = False
+        self.x, self.y = self.widget.get_position ()
+        self.height, self.width = self.widget.get_size ()
+        self.cal_active = True
+        
+        self.xml.signal_connect ("on_at_editor_size_changed", self.on_at_editor_size_changed)
+        
+        self.xml.signal_connect("on_at_button_cancel_clicked", self.on_button_cancel_clicked)
+        self.xml.signal_connect("on_at_button_save_clicked", self.on_button_save_clicked)
+
+        self.xml.signal_connect("on_at_text_task_popup_menu", self.on_text_task_popup_menu)
+        self.xml.signal_connect("on_at_text_task_key_release_event", self.on_text_task_change)
+
+        self.xml.signal_connect("on_at_entry_title_changed", self.on_entry_title_changed)
+
+        self.xml.signal_connect("on_at_button_cancel_clicked", self.on_button_cancel_clicked)
+        self.xml.signal_connect ("on_at_button_template_clicked", self.on_button_template_clicked)
+        
+        self.check_spin_running = False
+        
+        self.xml.signal_connect("on_at_spin_hour_changed", self.on_spin_hour_changed)
+        self.xml.signal_connect("on_at_spin_minute_changed", self.on_spin_minute_changed)
+        self.xml.signal_connect ("on_at_spin_year_changed", self.on_spin_year_changed)
+        self.xml.signal_connect ("on_at_spin_month_changed", self.on_spin_month_changed)
+        self.xml.signal_connect ("on_at_spin_day_changed", self.on_spin_day_changed)
+        
+        ctime = time.localtime()
+        year = ctime[0]
+        self.spin_year.set_range (year, year + 5847) # TODO: Year +5847 compatability
+        self.timeout_handler_id = gobject.timeout_add(60 * 1000, self.__check_spins__)
+        
+        
+    def showadd (self, transient):
+        self.button_save.set_label (gtk.STOCK_ADD)
+        self.__reset__ ()
+        self.title = _("Untitled")
+        self.mode = 0 # add new task
+        self.widget.set_title(_("Create a New Scheduled Task"))
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.__setup_calendar__ ()
+        self.button_add_template.show ()
+        self.widget.show_all ()
+        self.output = 0
+        self.cb_xoutput.set_active (0)
+        
+        self.__update_textboxes__()
+    
+    def showadd_template (self, transient, title, command, output):
+        self.button_save.set_label (gtk.STOCK_ADD)
+        self.__reset__ ()
+        self.title = title
+        self.command = command
+        self.mode = 0 # add new task
+        self.output = output 
+        self.cb_xoutput.set_active (output)
+        self.widget.set_title(_("Create a New Scheduled Task"))
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.__setup_calendar__ ()
+        self.button_add_template.show ()
+        self.widget.show_all ()
+        
+        self.__update_textboxes__()
+    
+    def showedit_template (self, transient, id, title, command, output):
+        self.button_save.set_label (gtk.STOCK_ADD)
+        self.__reset__ ()
+        self.tid = id
+        self.title = title
+        self.command = command
+        self.mode = 2 # edit template
+        self.output = output    
+        self.cb_xoutput.set_active (output)
+        self.widget.set_title(_("Edit template"))
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.__setup_calendar__ ()
+        self.widget.show_all ()
+        
+        # hide time settings
+        self.at_vbox_time.hide ()
+        
+        # save and cancel buttons
+        self.button_save.set_label (gtk.STOCK_SAVE)
+        self.button_add_template.hide ()
+        
+        self.__update_textboxes__()
+    
+    def shownew_template (self, transient):
+        self.button_save.set_label (gtk.STOCK_ADD)
+        self.__reset__ ()
+        self.tid = 0
+        self.mode = 2 # edit template
+        self.output = 0 
+        self.cb_xoutput.set_active (0)
+        self.widget.set_title(_("New template"))
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.__setup_calendar__ ()
+        self.widget.show_all ()
+        
+        # hide time settings
+        self.at_vbox_time.hide ()
+        
+        # save and cancel buttons
+        self.button_save.set_label (gtk.STOCK_ADD)
+        self.button_add_template.hide ()
+        
+        self.__update_textboxes__()
+        
+    def showedit (self, transient, record, job_id, iter):
+        self.button_save.set_label (gtk.STOCK_APPLY)
+        self.mode = 1 # edit task
+        self.job_id = job_id
+        self.date = self.ParentClass.treemodel.get_value(iter, 9)
+        self.time = self.ParentClass.treemodel.get_value(iter, 12)
+        self.title = self.ParentClass.treemodel.get_value(iter, 0)
+        self.class_id = self.ParentClass.treemodel.get_value(iter, 10)
+        self.user = self.ParentClass.treemodel.get_value(iter, 11)
+        self.command = self.ParentClass.treemodel.get_value(iter, 3)
+        self.output = self.ParentClass.treemodel.get_value (iter, 15)
+        self.cb_xoutput.set_active (self.output)
+        # removing beginning newlines.. wherever they come from..
+        i = self.command.find ('\n', 0)
+        while i == 0:
+            self.command = self.command[1:]
+            i = self.command.find ('\n', 0)
+            
+        #parse  
+        (hour, minute, day, month, year) = self.__parse_time__(self.time, self.date)
+        self.runat = hour + minute  + " " + day + "." + month + "." + year
+        self.spin_year.set_value (int (year))
+        self.spin_month.set_value (int (month))
+        self.spin_day.set_value (int (day))
+
+        self.spin_hour.set_value(int(hour))
+        self.spin_minute.set_value(int(minute))
+        self.widget.set_title(_("Edit a Scheduled Task"))
+        
+        self.__update_textboxes__ ()
+        self.parentiter = iter
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.__setup_calendar__ ()
+        self.button_add_template.show ()
+        self.widget.show_all ()
+
+        
+
+    def on_cal_lost_focus (self, *args):
+        self.__hide_calendar__ ()
+        
+    def on_at_editor_size_changed (self, *args):
+        if self.cal_button.get_active ():
+            x, y = self.widget.get_position ()
+            height, width = self.widget.get_size ()
+            if ((x != self.x) or (y != self.y) or (height != self.height) or (width != self.width)):
+                self.__hide_calendar__ ()
+                
+    def on_cb_xoutput_toggled (self, *args):
+        if self.cb_xoutput.get_active ():
+            self.output = 1
+        else:
+            self.output = 0
+
+    def on_cal_button_toggled (self, *args):
+        if self.cal_button.get_active ():
+            self.__show_calendar__ ()
+        else:
+            self.__hide_calendar__ ()
+    
+    
+    def __setup_calendar__ (self):
+        if self.cal_loaded == False:
+            self.xml.signal_connect ("on_cal_lost_focus", self.on_cal_lost_focus)
+            self.xml.signal_connect ("on_cal_window_destroy", self.__destroy_calendar__) # its actually not destroyed, but deleted
+        
+            self.xml.signal_connect ("on_cal_day_selected_dc", self.on_cal_day_selected_dc)
+            self.xml.signal_connect ("on_cal_day_selected", self.on_cal_day_selected)
+        
+            self.cal_window = self.xml.get_widget ("cal_window")
+            self.calendar = self.xml.get_widget ("calendar")
+            self.cal_window.hide_all ()
+            self.cal_loaded = True
+        
+    def __destroy_calendar__ (self):
+        self.cal_window.hide_all ()
+        return True
+
+    def on_cal_day_selected (self, *args):
+        if self.cal_active:
+            year, month, day = self.calendar.get_date ()
+            self.spin_year.set_value (int (year))
+            self.spin_month.set_value (int (month) + 1)
+            self.spin_day.set_value (int (day))
+        
+    def on_cal_day_selected_dc (self, *args):
+        self.__hide_calendar__ ()
+                
+    def __show_calendar__ (self):
+        x, y = self.widget.window.get_origin ()
+        button_rect = self.cal_button.get_allocation ()
+        x = x + button_rect.x
+        y = y + button_rect.y + button_rect.height
+        self.cal_window.move (x, y)
+        self.widget.set_modal (False)
+        self.x, self.y = self.widget.get_position ()
+        self.height, self.width = self.widget.get_size ()
+        self.cal_active = False
+        self.calendar.select_month (self.spin_month.get_value_as_int () -1 , self.spin_year.get_value_as_int ())
+        self.calendar.select_day (self.spin_day.get_value_as_int ())
+        self.cal_active = True
+        self.cal_window.show_all ()
+        
+    def __hide_calendar__ (self):
+        self.cal_window.hide_all ()
+        self.cal_button.set_active (False)
+        self.widget.set_modal (True)
+        
+        
+    def on_worded_label_event (self, *args):
+        #TODO highlight on mouseover
+        pass
+
+    def on_defined_label_event (self, *args):
+        #TODO highlight on mouseover
+        # enable control_option on click
+        pass
+
+    def on_text_task_popup_menu (self, *args):
+        #TODO show at_script_menuons: install t
+        # don't forget to attach eventhandling to this popup
+        pass
+        
+
+    
+    def on_text_task_change (self, *args):
+        start = self.text_task_buffer.get_start_iter()
+        end = self.text_task_buffer.get_end_iter()
+        self.command = self.text_task_buffer.get_text(start, end)
+
+
+    def on_entry_title_changed (self, *args):
+        self.title = self.entry_title.get_text()
+
+    def on_spin_day_changed (self, *args):  
+        self.__check_spins__ () 
+        self.__update_time_cal__()
+
+    def on_spin_month_changed (self, *args):
+        self.__check_spins__ ()
+        self.__update_time_cal__()
+    
+    def on_spin_year_changed (self, *args):
+        self.__check_spins__ ()
+        self.__update_time_cal__()
+
+    def on_spin_hour_changed (self, *args):
+        self.__check_spins__ ()
+        self.__update_time_cal__()
+
+    def on_spin_minute_changed (self, *args):
+        self.__check_spins__ ()
+        self.__update_time_cal__()
+
+    def __check_spins__ (self):
+        # Is additionally run every minute
+        if self.check_spin_running != True:
+            self.check_spin_running = True
+            
+            ctime = time.localtime()
+            year = ctime[0]
+            month = ctime[1]
+            day = ctime[2]
+            hour = ctime[3]
+            minute = ctime[4]
+            
+            cyear = False
+            cmonth = False
+            cday = False
+            chour = False
+            
+            syear = self.spin_year.get_value_as_int ()
+            if (syear == year):
+                cyear = True
+            
+            smonth = self.spin_month.get_value_as_int ()
+            mi, ma = self.spin_month.get_range ()
+            if cyear:
+                if (mi != month):
+                    self.spin_month.set_range (month, 12)
+                    mi = month
+            else: 
+                if ((mi != 1) or (ma != 12)):
+                    self.spin_month.set_range (1, 12)
+            if (mi <= smonth <= ma):
+                self.spin_month.set_value (smonth)
+            else:
+                if (smonth > ma):
+                    self.spin_month.set_value (ma)
+                else:
+                    self.spin_month.set_value (mi)
+            smonth = self.spin_month.get_value_as_int ()
+            if (smonth == month):
+                cmonth = True
+            
+            sday = self.spin_day.get_value_as_int ()        
+            mi, ma = self.spin_day.get_range ()
+            w, days = calendar.monthrange (syear, smonth)
+            if (cmonth and cyear):
+                if (mi != day):
+                    self.spin_day.set_range (day, days)
+                    mi = day
+            else:
+                if ((mi != 1) or (ma != days)):
+                    self.spin_day.set_range (1, days)
+            if (mi <= sday <= days):
+                self.spin_day.set_value (sday)
+            else:
+                if (sday > days):
+                    self.spin_day.set_value (days)
+                else:
+                    self.spin_day.set_value (mi)
+            sday = self.spin_day.get_value_as_int ()
+            if (sday == day):
+                cday = True
+            
+            shour = self.spin_hour.get_value_as_int ()
+            mi, ma = self.spin_hour.get_range ()
+            if (cyear and cmonth and cday):
+                if (mi != hour):
+                    self.spin_hour.set_range (hour, 24)
+                    mi = hour
+            else:
+                if ((mi != 0) or (ma != 24)):
+                    self.spin_hour.set_range (0, 24)
+            if (mi <= shour <= ma):
+                self.spin_hour.set_value (shour)
+            else:
+                if (shour > ma):
+                    self.spin_hour.set_value (ma)
+                else:
+                    self.spin_hour.set_value (mi)
+            shour = self.spin_hour.get_value_as_int ()
+            if (shour == hour):
+                chour = True
+            
+            sminute = self.spin_minute.get_value_as_int ()
+            mi, ma = self.spin_minute.get_range ()
+            if (cyear and cmonth and cday and chour):
+                if (mi != minute):
+                    self.spin_minute.set_range (minute, 59)
+                    mi = minute
+            else:
+                if ((mi != 0) or (ma != 59)):
+                    self.spin_minute.set_range (0, 59)
+            if (mi <= sminute <= ma):
+                self.spin_minute.set_value (sminute)
+            else:
+                if (sminute > ma):
+                    self.spin_minute.set_value (ma)
+                else:
+                    self.spin_minute.set_value (mi) 
+            self.check_spin_running = False
+        
+    
+    def __update_time_cal__ (self):
+        year = self.spin_year.get_text ()
+        month = self.spin_month.get_text ()
+        day = self.spin_day.get_text ()
+        hour = self.spin_hour.get_text()
+        minute = self.spin_minute.get_text()
+
+        year = str(year)
+        
+        if hour.isdigit():
+            hour = int(hour)
+        else:
+            return False
+            
+        if minute.isdigit():
+            minute = int(minute)
+        else:
+            return False
+            
+        if day.isdigit ():
+            day = int (day)
+        else:
+            return False
+        
+        if month.isdigit ():
+            month = int (month)
+        else:
+            return False
+        
+        if year.isdigit () == False:
+            return False
+            
+        if hour < 10:
+            hour = "0" + str(hour)
+        else:
+            hour = str(hour)
+    
+        if minute < 10:
+            minute = "0" + str(minute)
+        else:
+            minute = str(minute)
+        
+        if month < 10:
+            month = "0" + str(month)
+        else:
+            month = str(month)
+
+        if day < 10:
+            day = "0" + str(day)
+        else:
+            day = str(day)
+
+        self.runat = hour + minute + " " + day + "." + month + "." + year
+
+
+    def popup_error_no_digit (self, field):
+        box_popup = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("In one or both of the fields hour and minute there was entered a letter, or a number out of range. Remember an hour only has 60 minutes and a day only 24 hours."))
+        box_popup.set_response_sensitive(gtk.RESPONSE_OK, True)
+        run = box_popup.run ()
+        box_popup.hide ()
+        field.set_text ("0")
+
+
+    def __reset__ (self):
+        self.title = _("Untitled")
+        self.command = ""
+
+        ctime = time.localtime()
+        year = ctime[0]
+        month = ctime[1]
+        day = ctime[2]
+        hour = ctime[3]
+        minute = ctime[4]
+
+        self.output = 0
+        
+        self.runat = str(hour) + str(minute) + " " + str(day) + "." + str(month) + "." + str (year)
+
+        self.spin_hour.set_value(int(hour))
+        self.spin_minute.set_value(int(minute))
+        self.spin_year.set_value (int (year))
+        self.spin_month.set_value (int (month))
+        self.spin_day.set_value (int (day))
+
+        self.__update_textboxes__ ()
+        
+
+    def __update_textboxes__(self, update_runat = 1):
+
+        if self.title == None:
+            self.title = _("Untitled")
+
+        self.entry_title.set_text(self.title)
+        self.text_task_buffer.set_text(self.command)
+
+    def __parse_time__ (self, time, date):
+        regexp_date = re.compile("([0-9][0-9])\.([0-9][0-9])\.([0-9][0-9][0-9][0-9])")
+        regexp_time = re.compile("([0-9][0-9]):([0-9][0-9])")
+
+        time_g = regexp_time.match(time)
+        if time_g:
+            (hour, minute) = time_g.groups()
+
+        date_g = regexp_date.match(date)
+        if date_g:
+            (day, month, year) = date_g.groups()    
+        
+        return hour, minute, day, month, year
+
+
+    def on_button_cancel_clicked (self, *args):
+        self.__destroy_calendar__ ()
+        self.widget.hide()
+        return True
+        
+
+    def __WrongRecordDialog__ (self, x):
+        self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is an invalid record! The problem could be: %s") % (x)))
+        self.wrongdialog.run()
+        self.wrongdialog.destroy()
+
+    def on_button_template_clicked (self, *args):
+        self.template.savetemplate_at (0, self.title, self.command, self.output)
+        self.widget.hide ()
+
+    def on_button_save_clicked (self, *args):
+        if self.mode == 2:
+            self.template.savetemplate_at (self.tid, self.title, self.command, self.output)
+            self.widget.hide ()
+            return
+            
+        (validate, reason) = self.scheduler.checkfield(self.runat)
+        if validate == False:
+            self.__WrongRecordDialog__ (reason)
+            return
+        
+        if (self.backend.get_not_inform_working_dir_at() != True):
+            dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nOne-time tasks will be run from the directory where Gnome schedule is run from (normally the home directory)."))
+            dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+            dia2.set_title (_("Warning: Working directory of executed tasks"))
+            response = dia2.run ()
+            if response == gtk.RESPONSE_CANCEL:
+                dia2.destroy ()
+                del dia2
+                return
+            elif response == gtk.RESPONSE_CLOSE:
+                self.backend.set_not_inform_working_dir_at (True)
+            else:
+                pass
+            dia2.destroy ()
+            del dia2
+        
+        if self.mode == 1:
+            self.scheduler.update (self.job_id, self.runat, self.command, self.title, self.output)
+        else:
+            self.scheduler.append (self.runat, self.command, self.title, self.output)
+        
+        self.ParentClass.schedule_reload ()
+            
+        self.widget.hide ()
+        

Modified: trunk/src/config.py.in
==============================================================================
--- trunk/src/config.py.in	(original)
+++ trunk/src/config.py.in	Sat Feb 14 21:20:56 2009
@@ -1,6 +1,8 @@
 version = "@VERSION@"
 image_dir = "@prefix@/share/pixmaps/gnome-schedule"
-glade_dir = "@prefix@/share/gnome-schedule"
+gs_dir = "@prefix@/share/gnome-schedule"
+glade_dir = gs_dir
+xwrapper_exec = "PYTHONPATH= PYTHONPATH@/gtk-2.0/:$PYTHONPATH @PYTHON@ @prefix@/share/gnome-schedule/xwrapper.py"
 locale_dir = "@prefix@/share/locale"
 crontabbin = "@CRONTAB_CONFIG@"
 atbin = "@AT_CONFIG@"

Modified: trunk/src/crontab.py
==============================================================================
--- trunk/src/crontab.py	(original)
+++ trunk/src/crontab.py	Sat Feb 14 21:20:56 2009
@@ -29,709 +29,734 @@
 
 
 class Crontab:
-	def __init__(self,root,user,uid,gid, user_home_dir):
-		#default preview length
-		self.preview_len = 50
-		self.root = root
-		self.set_rights(user,uid,gid, user_home_dir)
-		self.user_home_dir = user_home_dir
-		
-		self.nooutputtag = ">/dev/null 2>&1"
-		self.crontabRecordRegex = re.compile('([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^#\n$]*)(\s#\s([^\n$]*)|$)')
-		self.__setup_timespec__()
-		self.env_vars = [ ]
-		
-		self.crontabdata = self.user_home_dir + "/.gnome/gnome-schedule/crontab"
-		self.crontabdatafileversion = 3
-		
-		if os.path.exists (self.user_home_dir + "/.gnome") != True:
-			os.mkdir (self.user_home_dir + "/.gnome", 0700)
-			os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
-		if os.path.exists(self.crontabdata) != True:
-			try:
-				os.makedirs(self.crontabdata, 0700)
-				if self.root == 1:
-					os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
-					os.chown (self.crontabdata, self.uid, self.gid)
-			except:
-				print _("Failed to create data dir! Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.")
-			
-		
-		
-	def __setup_timespec__ (self):
-		self.special = {
-			"@reboot"  : '@reboot',
-			"@hourly"  : '0 * * * *',
-			"@daily"   : '0 0 * * *',
-			"@weekly"  : '0 0 * * 0',
-			"@monthly" : '0 0 1 * *',
-			"@yearly"  : '0 0 1 1 *',
-			"@annually": '0 0 1 1 *',
-			"@midnight": '0 0 * * *'
-			}
-				
-		self.timeranges = { 
-			"minute"   : range(0,60), 
-			"hour"     : range(0,24),
-			"day"      : range(1,32),
-			"month"    : range(1,13),
-			"weekday"  : range(0,8)
-			}
-
-		self.timenames = {
-			"minute"   : _("Minute"),
-			"hour"     : _("Hour"),
-			"day"      : _("Day of Month"),
-			"month"    : _("Month"),
-			"weekday"  : _("Weekday")
-			}
-	
-		self.monthnames = {
-			"1"        : "jan",
-			"2"        : "feb",
-			"3"        : "mar",
-			"4"        : "apr",
-			"5"        : "may",
-			"6"        : "jun",
-			"7"        : "jul",
-			"8"        : "aug",
-			"9"        : "sep",
-			"10"       : "oct",
-			"11"       : "nov",
-			"12"       : "dec"
-			}
-		self.monthnumbers = {
-			"jan"	: "1",
-			"feb"	: "2",
-			"mar"	: "3",
-			"apr"	: "4",
-			"may"	: "5",
-			"jun"	: "6",
-			"jul"	: "7",
-			"aug"	: "8",
-			"sep"	: "9",
-			"oct"	: "10",
-			"nov"	: "11",
-			"dec"	: "12"
-			}
-			
-		self.downames = {
-			"0"        : "sun",
-			"1"        : "mon",
-			"2"        : "tue",
-			"3"        : "wed",
-			"4"        : "thu",
-			"5"        : "fri",
-			"6"        : "sat",
-			"7"        : "sun"
-			}
-		
-		self.downumbers = {
-			"sun"	: "0",
-			"mon"	: "1",
-			"tue"	: "2",
-			"wed"	: "3",
-			"thu"	: "4",
-			"fri"	: "5",
-			"sat"	: "6",
-			"sun"	: "7"
-			}
-		
-
-	def set_rights(self,user,uid,gid, ud):
-		self.user = user
-		self.uid = uid
-		self.gid = gid
-		self.user_home_dir = ud
-		self.crontabdata = self.user_home_dir + "/.gnome/gnome-schedule/crontab"
-		if os.path.exists (self.user_home_dir + "/.gnome") != True:
-			os.mkdir (self.user_home_dir + "/.gnome", 0700)
-			os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
-		if os.path.exists(self.crontabdata) != True:
-			try:
-				os.makedirs(self.crontabdata, 0700)
-				if self.root == 1:
-					os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
-					os.chown (self.crontabdata, self.uid, self.gid)
-			except:
-				print (_("Failed to create data dir: %s. Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.") % (self.crontabdata))
-
-	def get_type (self):
-		return "crontab"
-	
-	def checkfield (self, expr, type):
-		"""Verifies format of Crontab timefields
-
-		Checks a single Crontab time expression.
-		At first possibly contained alias names will be replaced by their
-		corresponding numbers. After that every asterisk will be replaced by
-		a "first to last" expression. Then the expression will be splitted
-		into the comma separated subexpressions.
-
-		Each subexpression will run through: 
-		1. Check for stepwidth in range (if it has one)
-		2. Check for validness of range-expression (if it is one)
-		3. If it is no range: Check for simple numeric
-		4. If it is numeric: Check if it's in range
-
-		If one of this checks failed, an exception is raised. Otherwise it will
-		do nothing. Therefore this function should be used with 
-		a try/except construct.  
-		"""
-
-		# reboot?
-		if type == "special":
-			if expr in self.special:
-				pass
-			else:
-				raise ValueError ("special", _("Basic"), _("This is not a valid special record: %(record)s") % {"record": expr})
-		else:
-			timerange = self.timeranges[type]
-
-			# Replace alias names only if no leading and following alphanumeric and 
-			# no leading slash is present. Otherwise terms like "JanJan" or 
-			# "1Feb" would give a valid check. Values after a slash are stepwidths
-			# and shouldn't have an alias.
- 			if type == "month": alias = self.monthnames.copy()
-			elif type == "weekday": alias = self.downames.copy()
-			else: alias = None
-			if alias != None:
-				while True:
-					try: key,value = alias.popitem()
-					except KeyError: break
-					expr = re.sub("(?<!\w|/)" + value + "(?!\w)", key, expr)
-
-			expr = expr.replace("*", str(min(timerange)) + "-" + str(max(timerange)) )
- 		
-			list = expr.split(",")
-			rexp_step = re.compile("^(\d+-\d+)/(\d+)$")
-			rexp_range = re.compile("^(\d+)-(\d+)$")
-
-			for field in list:
-				result = rexp_step.match(field)
-				if  result != None:
-					field = result.groups()[0]
-					if int(result.groups()[1]) not in timerange:
-						raise ValueError("stepwidth", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
-	
-				result = rexp_range.match(field)
-				if (result != None): 
-					if (int(result.groups()[0]) not in timerange) or (int(result.groups()[1]) not in timerange):
-						raise ValueError("range", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
-				elif field.isdigit() != True:
-					raise ValueError("fixed", self.timenames[type], _("%s is not a number") % ( field ) )
-				elif int(field) not in timerange:
-					raise ValueError("fixed", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
-	
-
-	def update (self, minute, hour, day, month, weekday, command, linenumber, parentiter, nooutput, job_id, comment, title, desc):
-		if self.check_command (command) == False:
-			return False
-			
-		# update crontab
-		if minute == "@reboot":
-			record = "@reboot " + command
-		else:
-			record = minute + " " + hour + " " + day + " " + month + " " + weekday + " " + command
-		#print "crontab:update:record=" + record
-		
-		easystring = self.__easy__ (minute, hour, day, month, weekday)
-
-		if nooutput:
-			record = record + " " + self.nooutputtag
-		
-		if comment:
-			record = record + " #" + comment
-		
-		if job_id == False:
-			## Create a job_id for an existing task
-			f = os.path.join (self.crontabdata, "last_id")
-			if os.access (f, os.R_OK):
-				fh = open (f, 'r+')
-				r = fh.read ()
-				if r == "":
-					last_id = 1
-				else:
-					last_id = int (r)
-					
-				#print "last_id" + str (last_id)
-				job_id = last_id + 1
-				#print "job_id" + str (job_id)
-				fh.seek (0)
-				fh.truncate (1)
-				fh.write ( str(job_id))
-				fh.close ()
-			else:
-				job_id = 1
-				fh = open (f, 'w')
-				fh.write ('1')
-				fh.close ()
-
-			os.chown (f, self.uid, self.gid)
-			os.chmod (f, 0600)					
-			
-			record = record + " # JOB_ID_" + str (job_id)
-			
-			
-		if title == None:
-			title = _("Untitled")
-	
-		f = os.path.join (self.crontabdata, str(job_id))
-		#print f
-		fh = open (f, 'w')
-		fh.truncate (1)
-		fh.seek (0)
-		fh.write ("ver=" + str(self.crontabdatafileversion) + "\n")
-		fh.write ("title=" + title + "\n")
-		fh.write ("desc=" + desc + "\n")
-		if nooutput:
-			fh.write ("nooutput=1\n")
-		else:
-			fh.write ("nooutput=0\n")
-		fh.close ()	
-		os.chown (f, self.uid, self.gid)
-		os.chmod (f, 0600)
-		
-		self.lines[linenumber] = record
-		
-		# TODO: let write trow an exception if failed
-		self.__write__ ()
-	
-	
-	def delete (self, linenumber, iter, job_id):
-		# delete file
-		f = os.path.join (self.crontabdata, job_id)
-		if os.access(f, os.F_OK):
-			os.unlink (f)
-		
-		number = 0
-		newlines = list ()
-		for line in self.lines:
-			if number != linenumber:
-				newlines.append (line)
-			number = number + 1
-
-		self.lines = newlines
-		# TODO: let write trow an exception if failed
-		self.__write__ ()
-		
-		
-	def append (self, minute, hour, day, month, weekday, command, nooutput, title, desc = None):
-		if self.check_command (command) == False:
-			return False
-			
-		if minute == "@reboot":
-			record = "@reboot " + command
-		else:
-			record = minute + " " + hour + " " + day + " " + month + " " + weekday + " " + command
-
-		if nooutput:
-			space = " "
-			if record[len(record)-1] == " ":
-				space = ""
-			record = record + space + self.nooutputtag
-			
-		if title == None:
-			title = _("Untitled")
-			
-		if desc == None:
-			desc = ""
-				
-		# Create and write data file
-		f = os.path.join (self.crontabdata, "last_id")
-		if os.access (f, os.R_OK):
-			fh = open (f, 'r+')
-			r = fh.read ()
-			if r == "":
-				last_id = 1
-			else:
-				last_id = int (r)
-				
-			
-			job_id = last_id + 1
-			
-			fh.seek (0)
-			fh.truncate (1)
-			fh.write ( str(job_id))
-			fh.close ()	
-		else:
-			job_id = 1
-			fh = open (f, 'w')
-			fh.write ('1')
-			fh.close ()
-			
-		os.chown (f, self.uid, self.gid)
-		os.chmod (f, 0600)
-		
-		f = os.path.join (self.crontabdata, str(job_id))
-			
-		fh = open (f, 'w')
-		fh.truncate (1)
-		fh.seek (0)
-		fh.write ("ver=" + str(self.crontabdatafileversion) + "\n")
-		fh.write ("title=" + title + "\n")
-		fh.write ("desc=" + desc + "\n")
-		if nooutput:
-			fh.write ("nooutput=1\n")
-		else:
-			fh.write ("nooutput=0\n")
-		
-		fh.close ()
-		os.chown (f, self.uid, self.gid)
-		os.chmod (f, 0600)
-				
-		record = record + " # JOB_ID_" + str (job_id)
-			
-		self.lines.append (record)
-		
-		# TODO: let write trow an exception if failed
-		self.__write__ ()
-		
-
-	#check command for problems
-	def check_command (self, command):
-		# check if % is part of the command and if it is escaped, and the escapor not escaped.
-		i = command.find ("%")
-		while i != -1:
-			escaped = 0
-			part = command[0:i]
-			command = command[i + 1:]
-			e = part.rfind ("\\")
-			while (e != -1) and (e == len(part) - 1):
-				escaped = escaped + 1
-				part = part[0:len(part) - 1]
-				e = part.rfind ("\\")
-				
-			if (escaped % 2 == 0):
-				return False
-				
-			i = command.find ("%")
-		return True
-		
-	#read tasks in crontab
-	def read (self):
-		
-		data = []
-
-		if self.root:
-			execute = config.getCrontabbin () + " -l -u " + self.user
-		else:
-			execute = config.getCrontabbin () + " -l"
-		
-		linecount = 0
-		self.lines = os.popen(execute).readlines()
-		for line in self.lines:
-			#read line and get info
-			array_or_false = self.parse (line)
-			if array_or_false != False:
-				if array_or_false[0] == 2:
-					(minute, hour, day, month, weekday, command, comment, job_id, title, desc, nooutput) = array_or_false[1]
-					
-					time = minute + " " + hour + " " + day + " " + month + " " + weekday
-
-					#make the command smaller if the lenght is to long
-					preview = self.__make_preview__ (command)
-				
-					#add task to treemodel in mainWindow
-					if minute == "@reboot":
-						data.append([title, self.__easy__ (minute, hour, day, month, weekday), preview, line, linecount, time, self, None, job_id, "", "","", _("Recurrent"), "crontab", nooutput, _("At reboot")])
-					else:
-						data.append([title, self.__easy__ (minute, hour, day, month, weekday), preview, line, linecount, time, self, None, job_id, "", "","", _("Recurrent"), "crontab", nooutput, time])
-				
-				
-			linecount = linecount + 1	
-		
-		
-		return data
-
-
-	def translate_frequency (self, frequency):
-
-		if frequency == "minute":
-			return _("minute")
-		if frequency == "hour":
-			return _("hour")
-		if frequency == "day":
-			return _("day")
-		if frequency == "month":
-			return _("month")
-		if frequency == "weekday":
-			return _("weekday")
-
-		return frequency
-	
-	
-	#get info out of task line
-	def parse (self, line, nofile = False):
-		# nofile: no datafile for title and icon available
-		
-		# Format of gnome-schedule job line
-		# * * * * * ls -l >/dev/null >2&1 # JOB_ID_1
-		
-		# Return types
-		# 0: Special expression
-		# 1: Enivornment variable
-		# 2: Standard expression
-		# 3: Comment
-		
-		origline = line
-		line = line.lstrip()
-		comment = ""
-		
-		
-		if line	!= "":
-			#print "Parsing line: " + line
-			if line[0] == "#":
-				comment = line[1:]
-				line = ""
-				return [3, comment]
-			else:
-				if (line.find ('#') != -1):
-					line, comment = line.rsplit('#', 1)
-				
-			comment = comment.strip ()
-			line = line.strip ()
-		
-		if line == "":
-			#Empty
-			if comment != "":
-				return [3, comment]
-			else:
-				return False
-		#special expressions		
-		elif line[0] == "@":
-			special_expression, line = self.get_exp_sec (line)
-								
-			if special_expression == "@reboot":
-				minute = "@reboot"
-				hour = "@reboot"
-				dom = "@reboot"
-				moy = "@reboot"
-				dow = "@reboot"
-			else:
-
-				if special_expression in self.special:
-					expr = self.special[special_expression]
-					line = expr + " " + line
-
-					# Minute
-					minute, line = self.get_exp_sec (line)
-			
-					# Hour
-					hour, line = self.get_exp_sec (line)
-				
-					# Day of Month
-					dom, line = self.get_exp_sec (line)
-			
-					# Month of Year
-					moy, line = self.get_exp_sec (line)
-			
-					# Day of Week
-					dow, line = self.get_exp_sec (line)
-						
-	
-		elif (line[0].isalpha()):
-			if line[0] != '*':
-				#ENVIRONMENT VARIABLE
-				return [1, line]
-		else:
-			# Minute
-			minute, line = self.get_exp_sec (line)
-			
-			# Hour
-			hour, line = self.get_exp_sec (line)
-		
-			# Day of Month
-			dom, line = self.get_exp_sec (line)
-			# Crontab bug? Let's not support
-			# dom behaves like minute
-			"""
-			dom = self.day
-			if dom.isdigit() == False:
-				dom = dom.lower ()
-				for day in self.scheduler.downumbers:
-					dom = dom.replace (day, self.scheduler.downumbers[day])
-			"""
-			try:
-				self.checkfield (dom, "day")
-			except ValueError, ex:
-				print _("Failed to parse the Day of Month field, possibly due to a bug in crontab.")
-				return
-					
-			# Month of Year
-			moy, line = self.get_exp_sec (line)
-			if moy.isdigit () == False:
-				moy = moy.lower ()
-				for m in self.monthnumbers:
-					moy = moy.replace (m, self.monthnumbers[m])
-					
-			
-			# Day of Week
-			dow, line = self.get_exp_sec (line)
-			if dow.isdigit() == False:
-				dow = dow.lower ()
-				for day in self.downumbers:
-					dow = dow.replace (day, self.downumbers[day])
-			
-			
-		
-		command = line.strip ()
-		
-		# Retrive jobid
-		i = comment.find ('JOB_ID_')
-		if (i != -1):			
-			job_id = int (comment[i + 7:].rstrip ())
-		else:
-			job_id = False
-		
-		# Retrive title and icon data
-		if nofile == False:
-			if job_id:
-				ver, title, desc, nooutput = self.get_job_data (job_id)
-			else:
-				ver = 1
-				title = ""
-				desc = ""
-				nooutput = 0
-			
-			if nooutput != 0:
-				# remove devnull part of command
-				# searching reverse, and only if nooutput is saved in the datafile
-				pos = command.rfind (self.nooutputtag)
-				if pos != -1:
-					command = command[:pos]
-			
-			# support older datafiles/entries without removing the no output tag	
-			if ver <= 1:
-				# old version, no output declaration in datafile, migration
-				pos = command.rfind (self.nooutputtag)
-				if pos != -1:
-					command = command[:pos]
-					nooutput = 1
-				else:
-					nooutput = 0
-			
-			command = command.strip ()	
-				
-				
-			return [2, [minute, hour, dom, moy, dow, command, comment, job_id, title, desc, nooutput]]
-		else:
-			return minute, hour, dom, moy, dow, command
-		
-	def get_job_data (self, job_id):
-		f = os.path.join (self.crontabdata, str (job_id))
-		if os.access (f, os.R_OK):
-			fh = open (f, 'r')
-			d = fh.read ()
-				
-			ver_p = d.find ("ver=")
-			if ver_p == -1:
-				ver = 1
-			else:
-				ver_s = d[ver_p + 4:d.find ("\n")]
-				d = d[d.find ("\n") + 1:]
-				ver = int (ver_s)
-				
-			title = d[6:d.find ("\n")]
-			d = d[d.find ("\n") + 1:]
-			
-			if ver < 3:
-				# not in use
-				icon = d[5:d.find ("\n")]
-				d = d[d.find ("\n") + 1:]
-			
-			desc = d[5:d.find ("\n")]
-			d = d[d.find ("\n") + 1:]
-			
-			if ver >= 2:
-				nooutput_str = d[9:d.find ("\n")]
-				if (nooutput_str == "0") or (nooutput_str == "1"):
-					nooutput = int (nooutput_str)
-				else:
-					nooutput = 0
-			else:
-				nooutput = 0
-			
-			fh.close ()
-
-			return ver, title, desc, nooutput
-			
-			
-		else: 
-			return "", "", "", 0
-			
-			
-		
-				
-	def get_exp_sec (self, line):
-		line = line.lstrip ()
-		#print "line: \"" + line + "\""
-		
-		## find next whitespace
-		i = 0
-		found = False
-		while (i <= len(line)) and (found == False):
-			if line[i] in string.whitespace:
-				found = True
-				#print "found: " + str (i)
-			else:
-				i = i + 1
-		sec = line[0:i]
-		#print "sec: \"" + sec + "\""
-		line = line[i + 1:]
-		return sec, line
-		
-	def __easy__ (self, minute, hour, day, month, weekday):
-		return lang.translate_crontab_easy (minute, hour, day, month, weekday)
-
-
-	#create temp file with old tasks and new ones and then update crontab
-	def __write__ (self):
-		tmpfile = tempfile.mkstemp ()
-		fd, path = tmpfile
-		tmp = os.fdopen(fd, 'w')
-		count = 0
-		for line in self.lines:
-
-			## Ignore the first three comments:
-
-			## DO NOT EDIT THIS FILE - edit the master and reinstall.
-			## (/tmp/crontab.XXXXXX installed on Xxx Xxx  x xx:xx:xx xxxx)
-			## (Cron version -- $Id$)
-
-			if not (count < 3 and len(line) > 1 and line[0] == "#"):
-				tmp.write (line)
-				if line[len(line)-1] != '\n':
-					tmp.write ("\n")
-			count = count + 1
-
-		tmp.close ()
-
-		#replace crontab config with new one in file
-		if self.root:
-			# print config.getCrontabbin () + " -u " + self.ParentClass.user + " " + path
-			os.system (config.getCrontabbin () + " " + path + " -u " + self.user)
-		else:
-			# print config.getCrontabbin () + " " + path
-			os.system (config.getCrontabbin () + " " + path)
-
-		os.unlink (path)
-		
-		
-	#TODO: check into
-	#if a command his lenght is to long the last part is removed 
-	def __make_preview__ (self, str, preview_len = 0):
-		if preview_len == 0:
-			preview_len = self.preview_len
-		cnt = 0
-		result = ""
-		for a in str:
-			if cnt <= preview_len:
-				result = result + a
-			cnt = cnt + 1
-		if cnt > preview_len:
-			result = result + "..."
+    def __init__(self,root,user,uid,gid, user_home_dir):
+        #default preview length
+        self.preview_len = 50
+        self.root = root
+        self.set_rights(user,uid,gid, user_home_dir)
+        self.user_home_dir = user_home_dir
+        
+        self.output = ["",
+                        ">/dev/null 2>&1",
+                        config.gs_dir + "/xwrapper.py",
+                        ">/dev/null 2>&1",
+                      ]
+
+        self.crontabRecordRegex = re.compile('([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^\s]+)\s([^#\n$]*)(\s#\s([^\n$]*)|$)')
+        self.__setup_timespec__()
+        self.env_vars = [ ]
+        
+        self.crontabdata = self.user_home_dir + "/.gnome/gnome-schedule/crontab"
+        self.crontabdatafileversion = 5
+        
+        if os.path.exists (self.user_home_dir + "/.gnome") != True:
+            os.mkdir (self.user_home_dir + "/.gnome", 0700)
+            os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
+        if os.path.exists(self.crontabdata) != True:
+            try:
+                os.makedirs(self.crontabdata, 0700)
+                if self.root == 1:
+                    os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
+                    os.chown (self.crontabdata, self.uid, self.gid)
+            except:
+                print _("Failed to create data dir! Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.")
+            
+        
+        
+    def __setup_timespec__ (self):
+        self.special = {
+            "@reboot"  : '@reboot',
+            "@hourly"  : '0 * * * *',
+            "@daily"   : '0 0 * * *',
+            "@weekly"  : '0 0 * * 0',
+            "@monthly" : '0 0 1 * *',
+            "@yearly"  : '0 0 1 1 *',
+            "@annually": '0 0 1 1 *',
+            "@midnight": '0 0 * * *'
+            }
+                
+        self.timeranges = { 
+            "minute"   : range(0,60), 
+            "hour"     : range(0,24),
+            "day"      : range(1,32),
+            "month"    : range(1,13),
+            "weekday"  : range(0,8)
+            }
+
+        self.timenames = {
+            "minute"   : _("Minute"),
+            "hour"     : _("Hour"),
+            "day"      : _("Day of Month"),
+            "month"    : _("Month"),
+            "weekday"  : _("Weekday")
+            }
+    
+        self.monthnames = {
+            "1"        : "jan",
+            "2"        : "feb",
+            "3"        : "mar",
+            "4"        : "apr",
+            "5"        : "may",
+            "6"        : "jun",
+            "7"        : "jul",
+            "8"        : "aug",
+            "9"        : "sep",
+            "10"       : "oct",
+            "11"       : "nov",
+            "12"       : "dec"
+            }
+        self.monthnumbers = {
+            "jan"   : "1",
+            "feb"   : "2",
+            "mar"   : "3",
+            "apr"   : "4",
+            "may"   : "5",
+            "jun"   : "6",
+            "jul"   : "7",
+            "aug"   : "8",
+            "sep"   : "9",
+            "oct"   : "10",
+            "nov"   : "11",
+            "dec"   : "12"
+            }
+            
+        self.downames = {
+            "0"        : "sun",
+            "1"        : "mon",
+            "2"        : "tue",
+            "3"        : "wed",
+            "4"        : "thu",
+            "5"        : "fri",
+            "6"        : "sat",
+            "7"        : "sun"
+            }
+        
+        self.downumbers = {
+            "sun"   : "0",
+            "mon"   : "1",
+            "tue"   : "2",
+            "wed"   : "3",
+            "thu"   : "4",
+            "fri"   : "5",
+            "sat"   : "6",
+            "sun"   : "7"
+            }
+        
+
+    def set_rights(self,user,uid,gid, ud):
+        self.user = user
+        self.uid = uid
+        self.gid = gid
+        self.user_home_dir = ud
+        self.crontabdata = self.user_home_dir + "/.gnome/gnome-schedule/crontab"
+        if os.path.exists (self.user_home_dir + "/.gnome") != True:
+            os.mkdir (self.user_home_dir + "/.gnome", 0700)
+            os.chown (self.user_home_dir + "/.gnome", self.uid, self.gid)
+        if os.path.exists(self.crontabdata) != True:
+            try:
+                os.makedirs(self.crontabdata, 0700)
+                if self.root == 1:
+                    os.chown (self.user_home_dir + "/.gnome/gnome-schedule", self.uid, self.gid)
+                    os.chown (self.crontabdata, self.uid, self.gid)
+            except:
+                print (_("Failed to create data dir: %s. Make sure ~/.gnome and ~/.gnome/gnome-schedule are writable.") % (self.crontabdata))
+
+    def get_type (self):
+        return "crontab"
+    
+    def checkfield (self, expr, type):
+        """Verifies format of Crontab timefields
+
+        Checks a single Crontab time expression.
+        At first possibly contained alias names will be replaced by their
+        corresponding numbers. After that every asterisk will be replaced by
+        a "first to last" expression. Then the expression will be splitted
+        into the comma separated subexpressions.
+
+        Each subexpression will run through: 
+        1. Check for stepwidth in range (if it has one)
+        2. Check for validness of range-expression (if it is one)
+        3. If it is no range: Check for simple numeric
+        4. If it is numeric: Check if it's in range
+
+        If one of this checks failed, an exception is raised. Otherwise it will
+        do nothing. Therefore this function should be used with 
+        a try/except construct.  
+        """
+
+        # reboot?
+        if type == "special":
+            if expr in self.special:
+                pass
+            else:
+                raise ValueError ("special", _("Basic"), _("This is not a valid special record: %(record)s") % {"record": expr})
+        else:
+            timerange = self.timeranges[type]
+
+            # Replace alias names only if no leading and following alphanumeric and 
+            # no leading slash is present. Otherwise terms like "JanJan" or 
+            # "1Feb" would give a valid check. Values after a slash are stepwidths
+            # and shouldn't have an alias.
+            if type == "month": alias = self.monthnames.copy()
+            elif type == "weekday": alias = self.downames.copy()
+            else: alias = None
+            if alias != None:
+                while True:
+                    try: key,value = alias.popitem()
+                    except KeyError: break
+                    expr = re.sub("(?<!\w|/)" + value + "(?!\w)", key, expr)
+
+            expr = expr.replace("*", str(min(timerange)) + "-" + str(max(timerange)) )
+        
+            list = expr.split(",")
+            rexp_step = re.compile("^(\d+-\d+)/(\d+)$")
+            rexp_range = re.compile("^(\d+)-(\d+)$")
+
+            for field in list:
+                result = rexp_step.match(field)
+                if  result != None:
+                    field = result.groups()[0]
+                    if int(result.groups()[1]) not in timerange:
+                        raise ValueError("stepwidth", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
+    
+                result = rexp_range.match(field)
+                if (result != None): 
+                    if (int(result.groups()[0]) not in timerange) or (int(result.groups()[1]) not in timerange):
+                        raise ValueError("range", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
+                elif field.isdigit() != True:
+                    raise ValueError("fixed", self.timenames[type], _("%s is not a number") % ( field ) )
+                elif int(field) not in timerange:
+                    raise ValueError("fixed", self.timenames[type], _("Must be between %(min)s and %(max)s") % { "min": min(timerange), "max": max(timerange) } )
+    
+
+    def update (self, minute, hour, day, month, weekday, command, linenumber, parentiter, output, job_id, comment, title, desc):
+        if self.check_command (command) == False:
+            return False
+            
+        # update crontab
+        
+        easystring = self.__easy__ (minute, hour, day, month, weekday)
+
+        if job_id == False:
+            ## Create a job_id for an existing task
+            f = os.path.join (self.crontabdata, "last_id")
+            if os.access (f, os.R_OK):
+                fh = open (f, 'r+')
+                r = fh.read ()
+                if r == "":
+                    last_id = 1
+                else:
+                    last_id = int (r)
+                    
+                #print "last_id" + str (last_id)
+                job_id = last_id + 1
+                #print "job_id" + str (job_id)
+                fh.seek (0)
+                fh.truncate (1)
+                fh.write ( str(job_id))
+                fh.close ()
+            else:
+                job_id = 1
+                fh = open (f, 'w')
+                fh.write ('1')
+                fh.close ()
+
+            os.chown (f, self.uid, self.gid)
+            os.chmod (f, 0600)                  
+            
+        record = command
+        display = "0"
+        if output == 1:
+            space = " "
+            if record[len(record)-1] == " ":
+                space = ""
+            record = record + space + self.output[1]
+        elif (output == 2) or (output == 3):
+            display = os.getenv ('DISPLAY')
+            record = config.xwrapper_exec + " c " + str (job_id)
+            if output == 3:
+                record = record + " " + self.output [3]
+
+        if minute == "@reboot":
+            record = "@reboot " + record 
+        else:
+            record = minute + " " + hour + " " + day + " " + month + " " + weekday + " " + record 
+
+        record = record + " # JOB_ID_" + str (job_id)
+            
+        if title == None:
+            title = _("Untitled")
+    
+        f = os.path.join (self.crontabdata, str(job_id))
+        #print f
+        fh = open (f, 'w')
+        fh.truncate (1)
+        fh.seek (0)
+        fh.write ("ver=" + str(self.crontabdatafileversion) + "\n")
+        fh.write ("title=" + title + "\n")
+        fh.write ("desc=" + desc + "\n")
+        fh.write ("output=" + str (output) + "\n")
+        fh.write ("display=" + display + "\n")  
+        fh.write ("command_d=" + command + "\n")
+        fh.close () 
+        os.chown (f, self.uid, self.gid)
+        os.chmod (f, 0600)
+        
+        self.lines[linenumber] = record
+        
+        # TODO: let write trow an exception if failed
+        self.__write__ ()
+    
+    
+    def delete (self, linenumber, iter, job_id):
+        # delete file
+        f = os.path.join (self.crontabdata, job_id)
+        if os.access(f, os.F_OK):
+            os.unlink (f)
+        
+        number = 0
+        newlines = list ()
+        for line in self.lines:
+            if number != linenumber:
+                newlines.append (line)
+            number = number + 1
+
+        self.lines = newlines
+        # TODO: let write trow an exception if failed
+        self.__write__ ()
+        
+        
+    def append (self, minute, hour, day, month, weekday, command, output, title, desc = None):
+        if self.check_command (command) == False:
+            return False
+            
+        if title == None:
+            title = _("Untitled")
+            
+        if desc == None:
+            desc = ""
+                
+        # Create and write data file
+        f = os.path.join (self.crontabdata, "last_id")
+        if os.access (f, os.R_OK):
+            fh = open (f, 'r+')
+            r = fh.read ()
+            if r == "":
+                last_id = 1
+            else:
+                last_id = int (r)
+                
+            
+            job_id = last_id + 1
+            
+            fh.seek (0)
+            fh.truncate (1)
+            fh.write ( str(job_id))
+            fh.close () 
+        else:
+            job_id = 1
+            fh = open (f, 'w')
+            fh.write ('1')
+            fh.close ()
+            
+        os.chown (f, self.uid, self.gid)
+        os.chmod (f, 0600)
+        
+        record = command
+        display = "0"
+        if output == 1:
+            space = " "
+            if record[len(record)-1] == " ":
+                space = ""
+            record = record + space + self.output[1]
+        elif (output == 2) or (output == 3):
+            display = os.getenv ('DISPLAY')
+            record = config.xwrapper_exec + " c " + str (job_id)
+            if output == 3:
+                record = record + " " + self.output [3]
+
+        if minute == "@reboot":
+            record = "@reboot " + record
+        else:
+            record = minute + " " + hour + " " + day + " " + month + " " + weekday + " " + record 
+
+        record = record + " # JOB_ID_" + str (job_id)
+
+        self.lines.append (record)
+        
+        f = os.path.join (self.crontabdata, str(job_id))
+        fh = open (f, 'w')
+        fh.truncate (1)
+        fh.seek (0)
+        fh.write ("ver=" + str(self.crontabdatafileversion) + "\n")
+        fh.write ("title=" + title + "\n")
+        fh.write ("desc=" + desc + "\n")
+        fh.write ("output=" + str(output) + "\n")
+        fh.write ("display=" + display + "\n")      
+        fh.write ("command_d=" + command + "\n")
+        fh.close ()
+        os.chown (f, self.uid, self.gid)
+        os.chmod (f, 0600)
+        # TODO: let write trow an exception if failed
+        self.__write__ ()
+        
+
+    #check command for problems
+    def check_command (self, command):
+        # check if % is part of the command and if it is escaped, and the escapor not escaped.
+        i = command.find ("%")
+        while i != -1:
+            escaped = 0
+            part = command[0:i]
+            command = command[i + 1:]
+            e = part.rfind ("\\")
+            while (e != -1) and (e == len(part) - 1):
+                escaped = escaped + 1
+                part = part[0:len(part) - 1]
+                e = part.rfind ("\\")
+                
+            if (escaped % 2 == 0):
+                return False
+                
+            i = command.find ("%")
+        return True
+        
+    #read tasks in crontab
+    def read (self):
+        
+        data = []
+
+        if self.root:
+            execute = config.getCrontabbin () + " -l -u " + self.user
+        else:
+            execute = config.getCrontabbin () + " -l"
+        
+        linecount = 0
+        self.lines = os.popen(execute).readlines()
+        for line in self.lines:
+            #read line and get info
+            array_or_false = self.parse (line)
+            if array_or_false != False:
+                if array_or_false[0] == 2:
+                    (minute, hour, day, month, weekday, command, comment, job_id, title, desc, output, display) = array_or_false[1]
+                    
+                    time = minute + " " + hour + " " + day + " " + month + " " + weekday
+
+                    #make the command smaller if the lenght is to long
+                    preview = self.__make_preview__ (command)
+                
+                    #add task to treemodel in mainWindow
+                    if minute == "@reboot":
+                        data.append([title, self.__easy__ (minute, hour, day, month, weekday), preview, line, linecount, time, self, None, job_id, "", "","", _("Recurrent"), "crontab", output, _("At reboot")])
+                    else:
+                        data.append([title, self.__easy__ (minute, hour, day, month, weekday), preview, line, linecount, time, self, None, job_id, "", "","", _("Recurrent"), "crontab", output, time])
+                
+                
+            linecount = linecount + 1   
+        
+        
+        return data
+
+
+    def translate_frequency (self, frequency):
+
+        if frequency == "minute":
+            return _("minute")
+        if frequency == "hour":
+            return _("hour")
+        if frequency == "day":
+            return _("day")
+        if frequency == "month":
+            return _("month")
+        if frequency == "weekday":
+            return _("weekday")
+
+        return frequency
+    
+    
+    #get info out of task line
+    def parse (self, line, nofile = False):
+        # nofile: no datafile for title and icon available
+        
+        # Format of gnome-schedule job line
+        # * * * * * ls -l >/dev/null >2&1 # JOB_ID_1
+        
+        # Return types
+        # 0: Special expression
+        # 1: Enivornment variable
+        # 2: Standard expression
+        # 3: Comment
+        
+        origline = line
+        line = line.lstrip()
+        comment = ""
+        
+        
+        if line != "":
+            #print "Parsing line: " + line
+            if line[0] == "#":
+                comment = line[1:]
+                line = ""
+                return [3, comment]
+            else:
+                if (line.find ('#') != -1):
+                    line, comment = line.rsplit('#', 1)
+                
+            comment = comment.strip ()
+            line = line.strip ()
+        
+        if line == "":
+            #Empty
+            if comment != "":
+                return [3, comment]
+            else:
+                return False
+        #special expressions        
+        elif line[0] == "@":
+            special_expression, line = self.get_exp_sec (line)
+                                
+            if special_expression == "@reboot":
+                minute = "@reboot"
+                hour = "@reboot"
+                dom = "@reboot"
+                moy = "@reboot"
+                dow = "@reboot"
+            else:
+
+                if special_expression in self.special:
+                    expr = self.special[special_expression]
+                    line = expr + " " + line
+
+                    # Minute
+                    minute, line = self.get_exp_sec (line)
+            
+                    # Hour
+                    hour, line = self.get_exp_sec (line)
+                
+                    # Day of Month
+                    dom, line = self.get_exp_sec (line)
+            
+                    # Month of Year
+                    moy, line = self.get_exp_sec (line)
+            
+                    # Day of Week
+                    dow, line = self.get_exp_sec (line)
+                        
+    
+        elif (line[0].isalpha()):
+            if line[0] != '*':
+                #ENVIRONMENT VARIABLE
+                return [1, line]
+        else:
+            # Minute
+            minute, line = self.get_exp_sec (line)
+            
+            # Hour
+            hour, line = self.get_exp_sec (line)
+        
+            # Day of Month
+            dom, line = self.get_exp_sec (line)
+            # Crontab bug? Let's not support
+            # dom behaves like minute
+            """
+            dom = self.day
+            if dom.isdigit() == False:
+                dom = dom.lower ()
+                for day in self.scheduler.downumbers:
+                    dom = dom.replace (day, self.scheduler.downumbers[day])
+            """
+            try:
+                self.checkfield (dom, "day")
+            except ValueError, ex:
+                print _("Failed to parse the Day of Month field, possibly due to a bug in crontab.")
+                return
+                    
+            # Month of Year
+            moy, line = self.get_exp_sec (line)
+            if moy.isdigit () == False:
+                moy = moy.lower ()
+                for m in self.monthnumbers:
+                    moy = moy.replace (m, self.monthnumbers[m])
+                    
+            
+            # Day of Week
+            dow, line = self.get_exp_sec (line)
+            if dow.isdigit() == False:
+                dow = dow.lower ()
+                for day in self.downumbers:
+                    dow = dow.replace (day, self.downumbers[day])
+            
+            
+        
+        command = line.strip ()
+        
+        # Retrive jobid
+        i = comment.find ('JOB_ID_')
+        if (i != -1):           
+            job_id = int (comment[i + 7:].rstrip ())
+        else:
+            job_id = False
+
+        
+        # Retrive title and icon data
+        if nofile == False:
+            if job_id:
+                success, ver, title, desc, output, display, command_d = self.get_job_data (job_id)
+            else:
+                success = True
+                ver = 1
+                title = ""
+                desc = ""
+                output = 0
+                display = ""
+                command_d = ""
+            
+            if (output == 0) or (output == 3):
+                # remove devnull part of command
+                # searching reverse, and only if output is saved in the datafile
+                pos = command.rfind (self.output[1])
+                if pos != -1:
+                    command = command[:pos]
+            if output >= 2:
+                # rely on command from datafile, command from crontab line only contains xwrapper stuff
+                command = command_d            
+
+            # support older datafiles/entries without removing the no output tag    
+            if ver <= 1:
+                # old version, no output declaration in datafile, migration
+                pos = command.rfind (self.output[1])
+                if pos != -1:
+                    command = command[:pos]
+                    output = 1
+                else:
+                    output = 0
+            
+            command = command.strip ()  
+                
+                
+            return [2, [minute, hour, dom, moy, dow, command, comment, job_id, title, desc, output, display]]
+        else:
+            return minute, hour, dom, moy, dow, command
+        
+    def get_job_data (self, job_id):
+        f = os.path.join (self.crontabdata, str (job_id))
+        if os.access (f, os.R_OK):
+            fh = open (f, 'r')
+            d = fh.read ()
+                
+            ver_p = d.find ("ver=")
+            if ver_p == -1:
+                ver = 1
+            else:
+                ver_s = d[ver_p + 4:d.find ("\n")]
+                d = d[d.find ("\n") + 1:]
+                ver = int (ver_s)
+                
+            title = d[6:d.find ("\n")]
+            d = d[d.find ("\n") + 1:]
+            
+            if ver < 3:
+                # not in use
+                icon = d[5:d.find ("\n")]
+                d = d[d.find ("\n") + 1:]
+            
+            desc = d[5:d.find ("\n")]
+            d = d[d.find ("\n") + 1:]
+            
+            if (ver >= 2) and (ver < 4):
+                output_str = d[9:d.find ("\n")]
+                output = int (output_str)
+                d = d[d.find("\n")]
+
+            if ver >= 4:
+                output_str = d[7:d.find ("\n")]
+                output = int (output_str)
+                d = d[d.find ("\n") + 1:]
+                
+            if ver >= 4:
+                display = d[8:d.find ("\n")]
+                d = d[d.find ("\n") + 1:]
+                if (len (display) < 1) or (output < 2):
+                    display = ""
+
+            if ver >= 5:
+                command_d = d[10:d.find ("\n")]
+                d = d[d.find ("\n") + 1:]
+                if (len (command_d) < 1) or (output < 2):
+                    command_d = ""
+            
+            fh.close ()
+
+            return True, ver, title, desc, output, display, command_d
+            
+            
+        else: 
+            return False, "", "", "", 0, 0, ""
+                
+    def get_exp_sec (self, line):
+        line = line.lstrip ()
+        #print "line: \"" + line + "\""
+        
+        ## find next whitespace
+        i = 0
+        found = False
+        while (i <= len(line)) and (found == False):
+            if line[i] in string.whitespace:
+                found = True
+                #print "found: " + str (i)
+            else:
+                i = i + 1
+        sec = line[0:i]
+        #print "sec: \"" + sec + "\""
+        line = line[i + 1:]
+        return sec, line
+        
+    def __easy__ (self, minute, hour, day, month, weekday):
+        return lang.translate_crontab_easy (minute, hour, day, month, weekday)
+
+
+    #create temp file with old tasks and new ones and then update crontab
+    def __write__ (self):
+        tmpfile = tempfile.mkstemp ()
+        fd, path = tmpfile
+        tmp = os.fdopen(fd, 'w')
+        count = 0
+        for line in self.lines:
+
+            ## Ignore the first three comments:
+
+            ## DO NOT EDIT THIS FILE - edit the master and reinstall.
+            ## (/tmp/crontab.XXXXXX installed on Xxx Xxx  x xx:xx:xx xxxx)
+            ## (Cron version -- $Id$)
+
+            if not (count < 3 and len(line) > 1 and line[0] == "#"):
+                tmp.write (line)
+                if line[len(line)-1] != '\n':
+                    tmp.write ("\n")
+            count = count + 1
+
+        tmp.close ()
+
+        #replace crontab config with new one in file
+        if self.root:
+            # print config.getCrontabbin () + " -u " + self.ParentClass.user + " " + path
+            os.system (config.getCrontabbin () + " " + path + " -u " + self.user)
+        else:
+            # print config.getCrontabbin () + " " + path
+            os.system (config.getCrontabbin () + " " + path)
+
+        os.unlink (path)
+        
+        
+    def __make_preview__ (self, str, preview_len = 0):
+        if preview_len == 0:
+            preview_len = self.preview_len
+    
+        str = str.replace ("&", "&amp")
+
+        if len (str) <= preview_len:
+            return str
+        else:
+            return str[:preview_len] + "..."
 
-		result = result.replace ("&", "&amp;")
-		return result
 

Modified: trunk/src/crontabEditor.py
==============================================================================
--- trunk/src/crontabEditor.py	(original)
+++ trunk/src/crontabEditor.py	Sat Feb 14 21:20:56 2009
@@ -32,673 +32,640 @@
 
 
 class CrontabEditor:
-	def __init__(self, parent, backend, scheduler, template):
+    def __init__(self, parent, backend, scheduler, template):
 
-		self.ParentClass = parent
-		self.backend = backend
-		self.scheduler = scheduler
-		self.template = template
-		
-		self.xml = self.ParentClass.xml
-		self.widget = self.xml.get_widget("crontab_editor")
-		self.widget.connect("delete-event", self.widget.hide_on_delete)
-		
-		
-		# TODO: move to crontab?
-		self.fieldRegex = re.compile('^(\*)$|^([0-9]+)$|^\*\/([0-9]+)$|^([0-9]+)-([0-9]+)$|(^([0-9]+[,])+([0-9]+)$)')
-		self.nooutputRegex = re.compile('([^#\n$]*)>(\s|)/dev/null\s2>&1')
-		
-		
-		self.title_box = self.xml.get_widget ("crontab_title_box")
-		
-		self.image_icon = gtk.Image ()
-		self.image_icon.set_from_pixbuf (self.ParentClass.bigiconcrontab)
-		self.title_box.pack_start (self.image_icon, False, False, 0)
-		self.title_box.reorder_child (self.image_icon, 0)
-		self.image_icon.show ()
-		
-		self.noevents = False
-		
-		
-		##simple tab	
-		self.entry_title = self.xml.get_widget ("entry_title")
-		self.entry_task = self.xml.get_widget ("entry_task")
-		
-		self.frequency_combobox = self.xml.get_widget ("frequency_combobox")
-		self.frequency_combobox_model = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
-		self.frequency_combobox_model.append([_("Every minute"), ["*", "*", "*", "*", "*", ""]])
-		self.frequency_combobox_model.append([_("Every hour"), ["0", "*", "*", "*", "*", ""]])
-		self.frequency_combobox_model.append([_("Every day"), ["0", "0", "*", "*", "*", ""]])
-		self.frequency_combobox_model.append([_("Every month"), ["0", "0", "1", "*", "*", ""]])
-		self.frequency_combobox_model.append([_("Every week"), ["0", "0", "*", "*", "1", ""]])
-		self.frequency_combobox_model.append([_("At reboot"), ["", "", "", "", "", "@reboot"]])
-		self.frequency_combobox.set_model (self.frequency_combobox_model)
-		
-		self.cb_nooutput = self.xml.get_widget("cb_nooutput")
-				
-		#self.help_button = self.xml.get_widget ("cron_help_button")
-		
-		self.button_cancel = self.xml.get_widget ("button_cancel")
-		self.button_apply = self.xml.get_widget ("button_apply")
-		self.button_template = self.xml.get_widget ("button_template")
-		self.rb_advanced = self.xml.get_widget ("rb_advanced")
-		self.rb_basic = self.xml.get_widget ("rb_basic")
-		
-		self.label_preview = self.xml.get_widget ("label_preview")
-		
-		self.xml.signal_connect("on_button_cancel_clicked", self.on_button_cancel_clicked)
-		self.xml.signal_connect("on_button_apply_clicked", self.on_button_apply_clicked)
-		self.xml.signal_connect("on_anyadvanced_entry_changed", self.on_anyadvanced_entry_changed)
-		self.xml.signal_connect("on_anybasic_entry_changed", self.on_anybasic_entry_changed)
-		self.xml.signal_connect("on_frequency_combobox_changed", self.on_frequency_combobox_changed)
-		self.xml.signal_connect("on_cb_nooutput_toggeled", self.on_anybasic_entry_changed)
-
-		self.xml.signal_connect("on_help_clicked", self.on_fieldHelp_clicked)
-		
-		self.xml.signal_connect("on_rb_advanced_toggled", self.on_editmode_toggled)
-		self.xml.signal_connect("on_rb_basic_toggled", self.on_editmode_toggled)
-		
-		self.xml.signal_connect ("on_button_template_clicked", self.on_template_clicked)
-		
-		
-		##
-		
-		##advanced
-		self.minute_entry = self.xml.get_widget ("minute_entry")
-		self.hour_entry = self.xml.get_widget ("hour_entry")
-		self.day_entry = self.xml.get_widget ("day_entry")
-		self.month_entry = self.xml.get_widget ("month_entry")
-		self.weekday_entry = self.xml.get_widget ("weekday_entry")
-		
-		self.help_minute = self.xml.get_widget ("help_minute")
-		self.help_hour = self.xml.get_widget ("help_hour")
-		self.help_day = self.xml.get_widget ("help_day")
-		self.help_month = self.xml.get_widget ("help_month")
-		self.help_weekday = self.xml.get_widget ("help_weekday")
-		##
-		
-		
-		self.editorhelper = crontabEditorHelper.CrontabEditorHelper(self)
-		
-			
-		
-	def showadd (self, transient):
-		self.button_apply.set_label (gtk.STOCK_ADD)
-		self.__reset__ ()
-		self.mode = 0
-		self.widget.set_title(_("Create a New Scheduled Task"))
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.button_template.show ()
-		self.widget.show ()
-		self.cb_nooutput.set_active (True)
-
-	def showadd_template (self, transient, title, command, nooutput,timeexpression):
-		self.button_apply.set_label (gtk.STOCK_ADD)
-		self.__reset__ ()
-		self.mode = 0
-		self.widget.set_title(_("Create a New Scheduled Task"))
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.button_template.show ()
-		self.widget.show ()
-		
-		self.nooutput = nooutput
-		# hehe again, why make it less complicated..
-		timeexpression = timeexpression + " echo hehe"
-		self.minute, self.hour, self.day, self.month, self.weekday, hehe = self.scheduler.parse (timeexpression, True)
-		self.special = ""
-		if self.minute == "@reboot":
-			self.special = "@reboot"
-			self.minute = ""
-			self.day = ""
-			self.hour = ""
-			self.month = ""
-			self.weekday = ""
-		self.command = command
-		self.title = title
-		
-		self.__update_textboxes__ ()
-
-		i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
-		if i == -1:
-			# advanced
-			self.rb_advanced.set_active (True)
-		else:
-			self.rb_basic.set_active (True)
-			self.frequency_combobox.set_active (i)
-
-		if self.nooutput:
-			self.entry_task.set_text (self.command)
-			self.cb_nooutput.set_active (True)
-			
-		else:
-			self.cb_nooutput.set_active (False)
-			
-			
-	def showedit_template (self, transient, id, title, command, nooutput, timeexpression):
-		self.button_apply.set_label (gtk.STOCK_SAVE)
-		
-		self.mode = 2
-		self.tid = id
-		self.__reset__ ()
-		
-		self.command = command
-		self.title = title
-		self.nooutput = nooutput
-		
-		timeexpression = timeexpression + " echo hehe"
-		self.minute, self.hour, self.day, self.month, self.weekday, hehe = self.scheduler.parse (timeexpression, True)
-		self.special = ""
-		if self.minute == "@reboot":
-			self.special = "@reboot"
-			self.minute = ""
-			self.day = ""
-			self.hour = ""
-			self.month = ""
-			self.weekday = ""
-			
-		self.widget.set_title(_("Edit template"))		
-		self.__update_textboxes__ ()
-		
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.widget.show ()
-		self.button_template.hide ()
-		i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
-		if i == -1:
-			# advanced
-			self.rb_advanced.set_active (True)
-		else:
-			self.rb_basic.set_active (True)
-			self.frequency_combobox.set_active (i)
-
-		if self.nooutput:
-			self.entry_task.set_text (self.command)
-			self.cb_nooutput.set_active (True)
-			
-		else:
-			self.cb_nooutput.set_active (False)
-			
-	def shownew_template (self, transient):
-		self.button_apply.set_label (gtk.STOCK_ADD)
-		
-		self.mode = 2
-		self.tid = 0
-		self.__reset__ ()
-
-			
-		self.widget.set_title(_("New template"))		
-		self.__update_textboxes__ ()
-		
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.widget.show ()
-		self.button_template.hide ()
-
-				
-	def showedit (self, transient, record, job_id, linenumber, iter):
-		self.button_apply.set_label (gtk.STOCK_APPLY)
-		self.mode = 1
-		self.linenumber = linenumber
-		self.record = record
-		self.job_id = job_id
-		self.__reset__ ()
-		(self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.comment, self.job_id, self.title, self.desc, self.nooutput) = self.scheduler.parse (record)[1]
-		self.special = ""
-		if self.minute == "@reboot":
-			self.special = "@reboot"
-			self.minute = ""
-			self.day = ""
-			self.hour = ""
-			self.month = ""
-			self.weekday = ""
-			
-		self.widget.set_title(_("Edit a Scheduled Task"))		
-		self.__update_textboxes__ ()
-		self.parentiter = iter
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.button_template.show ()
-		self.widget.show ()
-		i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
-		if i == -1:
-			# advanced
-			self.rb_advanced.set_active (True)
-		else:
-			self.rb_basic.set_active (True)
-			self.frequency_combobox.set_active (i)
-
-		if self.nooutput:
-			self.entry_task.set_text (self.command)
-			self.cb_nooutput.set_active (True)
-			
-		else:
-			self.cb_nooutput.set_active (False)
-			
-
-	def __reset__ (self):
-		self.noevents = True
-		self.minute = "0"
-		self.hour = "*"
-		self.day = "*"
-		self.month = "*"
-		self.weekday = "*"
-		self.special = ""
-		self.command = "ls"
-		self.title = _("Untitled")
-		self.nooutput = 1
-		self.frequency_combobox.set_active (1)
-		self.rb_basic.set_active (True)
-		self.minute_entry.set_editable (False)
-		self.minute_entry.set_sensitive (False)
-		self.hour_entry.set_editable (False)
-		self.hour_entry.set_sensitive (False)
-		self.day_entry.set_editable (False)
-		self.day_entry.set_sensitive (False)
-		self.month_entry.set_editable (False)
-		self.month_entry.set_sensitive (False)
-		self.weekday_entry.set_editable (False)			
-		self.weekday_entry.set_sensitive (False)
-		self.help_minute.set_sensitive (False)
-		self.help_hour.set_sensitive (False)
-		self.help_day.set_sensitive (False)
-		self.help_month.set_sensitive (False)
-		self.help_weekday.set_sensitive (False)
-		self.cb_nooutput.set_active (True)
-		self.frequency_combobox.set_sensitive (True)
-		self.__update_textboxes__ ()
-		self.noevents = False
-
-
-	#error dialog box 
-	def __WrongRecordDialog__ (self, x, y, z):
-		self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % (y, z)))
-		self.wrongdialog.run()
-		self.wrongdialog.destroy()
-
-	def __dialog_command_failed__ (self):
-		self.wrongdialog2 = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("Your command contains one or more of the character %, this is special for cron and cannot be used with Gnome-schedule because of the format it uses to store extra information on the crontab line. Please use the | redirector character to achieve the same functionality. Refer to the crontab manual for more information about the % character. If you don not want to use it for redirection it must be properly escaped with the \ letter.")))
-		self.wrongdialog2.run()
-		self.wrongdialog2.destroy()
-			
-	def __check_field_format__ (self, field, type):
-		try:
-			# Type should not be translatable!
-			self.scheduler.checkfield (field, type)
-		except ValueError, ex:
-			raise ex
-
-	#TODO: Help button?
-	"""
-	def on_cron_help_button_clicked (self, *args):
-		try:
-			gnome.help_display_with_doc_id (
-					self.ParentClass.gprogram, '',
-					'gnome-schedule.xml',
-					'myapp-adding-recurrent')
-		except gobject.GError, error:
-			dialog = gtk.MessageDialog (
-					self.widget,
-					gtk.DIALOG_DESTROY_WITH_PARENT,
-					gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE)
-			dialog.set_markup ("<b>" + _("Could not display help") + "</b>")
-			dialog.format_secondary_text ("%s" % error)
-			dialog.run ()
-			dialog.destroy ()
-
-	"""
-	def on_editmode_toggled (self, widget, *args):
-		if widget.get_active() == True:
-			if self.noevents == False:
-				self.noevents = True
-				if widget.get_name () == self.rb_advanced.get_name ():
-					self.rb_basic.set_active (False)
-					if (self.frequency_combobox.get_active () == 5):
-						# reboot, standard every hour
-						self.special = ""
-						self.minute_entry.set_text ("0")
-						self.hour_entry.set_text ("*")
-						self.day_entry.set_text ("*")
-						self.month_entry.set_text ("*")
-						self.weekday_entry.set_text ("*")
-						self.minute = "0"
-						self.hour = "*"
-						self.day = "*"
-						self.month = "*"
-						self.weekday = "*"
-						
-						self.update_preview ()
-						
-					self.rb_advanced.set_active (True)
-					self.minute_entry.set_editable (True)
-					self.minute_entry.set_sensitive (True)
-					self.hour_entry.set_editable (True)
-					self.hour_entry.set_sensitive (True)
-					self.day_entry.set_editable (True)
-					self.day_entry.set_sensitive (True)
-					self.month_entry.set_editable (True)
-					self.month_entry.set_sensitive (True)
-					self.weekday_entry.set_editable (True)
-					self.weekday_entry.set_sensitive (True)
-					self.help_minute.set_sensitive (True)
-					self.help_hour.set_sensitive (True)
-					self.help_day.set_sensitive (True)
-					self.help_month.set_sensitive (True)
-					self.help_weekday.set_sensitive (True)
-					self.frequency_combobox.set_sensitive (False)
-				else:
-					self.rb_basic.set_active (True)
-					self.rb_advanced.set_active (False)
-					self.minute_entry.set_editable (False)
-					self.minute_entry.set_sensitive (False)
-					self.hour_entry.set_editable (False)
-					self.hour_entry.set_sensitive (False)
-					self.day_entry.set_editable (False)
-					self.day_entry.set_sensitive (False)
-					self.month_entry.set_editable (False)
-					self.month_entry.set_sensitive (False)
-					self.weekday_entry.set_editable (False)			
-					self.weekday_entry.set_sensitive (False)
-					self.help_minute.set_sensitive (False)
-					self.help_hour.set_sensitive (False)
-					self.help_day.set_sensitive (False)
-					self.help_month.set_sensitive (False)
-					self.help_weekday.set_sensitive (False)
-					self.frequency_combobox.set_sensitive (True)
-					self.on_frequency_combobox_changed (self.frequency_combobox)
-				self.noevents = False
-			
-		
-	def on_button_cancel_clicked (self, *args):
-		self.widget.hide()
-
-	def on_template_clicked (self, *args):
-		if self.special != "":
-			try:
-				self.__check_field_format__ (self.special, "special")
-				record = self.special + " " + self.command
-				self.minute = "@reboot"
-				self.hour = "@reboot"
-				self.day = "@reboot"
-				self.month = "@reboot"
-				self.weekday = "@reboot"
-			except ValueError, ex:
-				x, y, z = ex
-				self.__WrongRecordDialog__ (x, y, z)
-				return
-		else:
-			try:
-				# Type should not be translatable!
-				self.__check_field_format__ (self.minute, "minute")
-				self.__check_field_format__ (self.hour, "hour")
-				self.__check_field_format__ (self.day, "day")
-				self.__check_field_format__ (self.month, "month")
-				self.__check_field_format__ (self.weekday, "weekday")
-				record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
-			except ValueError, ex:
-				x, y, z = ex
-				self.__WrongRecordDialog__ (x, y, z)
-				return
-
-		if self.scheduler.check_command (self.command) == False:
-			self.__dialog_command_failed__ ()
-			return	False
-			
-		if self.special != "":
-			self.template.savetemplate_crontab (0, self.title, self.command, self.nooutput, self.special)
-		else:
-			self.template.savetemplate_crontab (0, self.title, self.command, self.nooutput, self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday)
-		
-		self.widget.hide ()
-		
-	def on_button_apply_clicked (self, *args):
-		if self.special != "":
-			try:
-				self.__check_field_format__ (self.special, "special")
-				record = self.special + " " + self.command
-				self.minute = "@reboot"
-				self.hour = "@reboot"
-				self.day = "@reboot"
-				self.month = "@reboot"
-				self.weekday = "@reboot"
-			except ValueError, ex:
-				x, y, z = ex
-				self.__WrongRecordDialog__ (x, y, z)
-				return
-		else:
-			try:
-				# Type should not be translatable!
-				self.__check_field_format__ (self.minute, "minute")
-				self.__check_field_format__ (self.hour, "hour")
-				self.__check_field_format__ (self.day, "day")
-				self.__check_field_format__ (self.month, "month")
-				self.__check_field_format__ (self.weekday, "weekday")
-				record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
-			except ValueError, ex:
-				x, y, z = ex
-				self.__WrongRecordDialog__ (x, y, z)
-				return
-
-		if self.scheduler.check_command (self.command) == False:
-			self.__dialog_command_failed__ ()
-			return	False
-		
-		
-		if (self.backend.get_not_inform_working_dir_crontab() != True):
-			dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nRecurrent tasks will be run from the home directory."))
-			dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
-			dia2.set_title (_("Warning: Working directory of executed tasks"))
-			response = dia2.run ()
-			if response == gtk.RESPONSE_CANCEL:
-				dia2.destroy ()
-				del dia2
-				return
-			elif response == gtk.RESPONSE_CLOSE:
-				self.backend.set_not_inform_working_dir_crontab (True)
-			else:
-				pass
-			dia2.destroy ()
-			del dia2
-			
-		if self.mode == 1:
-			self.scheduler.update (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.linenumber, self.parentiter, self.nooutput, self.job_id, self.comment, self.title, self.desc)
-			
-		elif self.mode == 0:
-			self.scheduler.append (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.nooutput, self.title)
-			
-		elif self.mode == 2:
-			if self.special != "":
-				try:
-					self.__check_field_format__ (self.special, "special")
-					record = self.special + " " + self.command	
-					self.minute = "@reboot"
-					self.hour = "@reboot"
-					self.day = "@reboot"
-					self.month = "@reboot"
-					self.weekday = "@reboot"
-				except ValueError, ex:
-					x, y, z = ex
-					self.__WrongRecordDialog__ (x, y, z)
-					return
-			else:
-				try:
-					# Type should not be translatable!
-					self.__check_field_format__ (self.minute, "minute")
-					self.__check_field_format__ (self.hour, "hour")
-					self.__check_field_format__ (self.day, "day")
-					self.__check_field_format__ (self.month, "month")
-					self.__check_field_format__ (self.weekday, "weekday")
-					record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
-				except ValueError, ex:
-					x, y, z = ex
-					self.__WrongRecordDialog__ (x, y, z)
-					return
-
-			if self.scheduler.check_command (self.command) == False:
-				self.__dialog_command_failed__ ()
-				return	False
-			
-			if self.special != "":
-				self.template.savetemplate_crontab (self.tid, self.title, self.command, self.nooutput, self.special)
-			else:
-				self.template.savetemplate_crontab (self.tid, self.title, self.command, self.nooutput, self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday)
-	
-			self.widget.hide ()
-			return
-			
-		self.ParentClass.schedule_reload ()
-		self.widget.hide ()
-
-
-	def __set_frequency_combo__ (self):
-		if self.noevents == False:
-			index = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
-			if index != -1:
-				self.frequency_combobox.set_active (index)
-			else:
-				self.rb_advanced.set_active (True)
-
-		
-	def __getfrequency__ (self, minute, hour, day, month, weekday, special):
-		index = -1
-		
-		if minute == "*" and hour == "*" and month == "*" and day == "*" and weekday == "*":
-			index = 0
-		if minute == "0" and hour == "*" and month == "*" and day == "*" and weekday == "*":
-			index = 1
-		if minute == "0" and hour == "0" and month == "*" and day == "*" and weekday == "*":
-			index = 2
-		if minute == "0" and hour == "0" and month == "*" and day == "1" and weekday == "*":
-			index = 3
-		if minute == "0" and hour == "0" and month == "*" and day == "*" and weekday == "1":
-			index = 4
-		if special != "":
-			index = 5
-			
-
-		return index
-
-		
-	def __update_textboxes__ (self):
-		self.noevents = True
-		self.cb_nooutput.set_active (self.nooutput)
-		self.entry_task.set_text (self.command)
-		self.entry_title.set_text (self.title)
-		self.minute_entry.set_text (self.minute)
-		self.hour_entry.set_text (self.hour)
-		self.day_entry.set_text (self.day)
-		self.month_entry.set_text (self.month)
-		self.weekday_entry.set_text (self.weekday)
-		self.update_preview ()
-		#self.__set_frequency_combo__()
-		self.noevents = False
-
-	def update_preview (self):
-		if self.special != "":
-			try:
-				self.__check_field_format__ (self.special, "special")
-				record = self.special + " " + self.command
-				minute = "@reboot"
-				hour = "@reboot"
-				day = "@reboot"
-				month = "@reboot"
-				weekday = "@reboot"
-				self.label_preview.set_text ("<b>" + self.scheduler.__easy__ (minute, hour, day, month, weekday) + "</b>")
-				
-			except ValueError, ex:
-				x, y, z = ex
-				self.label_preview.set_text (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % ({'field' : y, 'reason' : z}))
-				
-				
-		else:
-			try:
-				# Type should not be translatable!
-				self.__check_field_format__ (self.minute, "minute")
-				self.__check_field_format__ (self.hour, "hour")
-				self.__check_field_format__ (self.day, "day")
-				self.__check_field_format__ (self.month, "month")
-				self.__check_field_format__ (self.weekday, "weekday")
-				
-				# Day of Month
-				# Crontab bug? Let's not support
-				# dom behaves like minute
-				"""
-				dom = self.day
-				if dom.isdigit() == False:
-					dom = dom.lower ()
-					for day in self.scheduler.downumbers:
-						dom = dom.replace (day, self.scheduler.downumbers[day])
-				"""
-						
-				# Month of Year
-				moy = self.month
-				if moy.isdigit () == False:
-					moy = moy.lower ()
-					for m in self.scheduler.monthnumbers:
-						moy = moy.replace (m, self.scheduler.monthnumbers[m])
-					
-			
-				# Day of Week
-				dow = self.weekday
-				if dow.isdigit() == False:
-					dow = dow.lower ()
-					for day in self.scheduler.downumbers:
-						dow = dow.replace (day, self.scheduler.downumbers[day])
-				self.label_preview.set_text ("<b>" + self.scheduler.__easy__ (self.minute, self.hour, self.day, moy, dow) + "</b>")
-			except ValueError, ex:
-				x, y, z = ex
-				self.label_preview.set_text (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % ({'field' : y, 'reason' : z}))
-
-		self.label_preview.set_use_markup (True)
-			
-			
-	def on_anyadvanced_entry_changed (self, *args):
-		if self.noevents == False:
-			self.minute = self.minute_entry.get_text ()
-			self.hour = self.hour_entry.get_text ()
-			self.day = self.day_entry.get_text ()
-			self.month = self.month_entry.get_text ()
-			self.weekday = self.weekday_entry.get_text ()
-			self.nooutput = self.cb_nooutput.get_active()
-			
-			self.__update_textboxes__ ()
-
-
-	def on_anybasic_entry_changed (self, *args):
-		if self.noevents == False:
-			self.command = self.entry_task.get_text ()
-			self.title = self.entry_title.get_text ()
-			self.nooutput = self.cb_nooutput.get_active()
-			self.__update_textboxes__ ()
-
-
-	def on_frequency_combobox_changed (self, bin):
-		iter = self.frequency_combobox.get_active_iter ()
-		frequency = self.frequency_combobox_model.get_value(iter, 1)
-		if frequency != None:
-			self.minute, self.hour, self.day, self.month, self.weekday, self.special = frequency
-			self.__update_textboxes__()
-		
-	
-	def on_fieldHelp_clicked(self, widget, *args):
-		name = widget.get_name()
-		field = "minute"
-		if name == "help_minute" :
-			field = "minute"
-			expression = self.minute_entry.get_text()
-		if name == "help_hour" :
-			field = "hour"
-			expression = self.hour_entry.get_text()
-		if name == "help_day" :
-			field = "day"
-			expression = self.day_entry.get_text()
-		if name == "help_month" :
-			field = "month"
-			expression = self.month_entry.get_text()
-		if name == "help_weekday" :
-			field = "weekday"
-			expression = self.weekday_entry.get_text()
+        self.ParentClass = parent
+        self.backend = backend
+        self.scheduler = scheduler
+        self.template = template
+        
+        self.xml = self.ParentClass.xml
+        self.widget = self.xml.get_widget("crontab_editor")
+        self.widget.connect("delete-event", self.widget.hide_on_delete)
+        
+        
+        # TODO: move to crontab?
+        self.fieldRegex = re.compile('^(\*)$|^([0-9]+)$|^\*\/([0-9]+)$|^([0-9]+)-([0-9]+)$|(^([0-9]+[,])+([0-9]+)$)')
+        self.nooutputRegex = re.compile('([^#\n$]*)>(\s|)/dev/null\s2>&1')
+        
+        
+        self.title_box = self.xml.get_widget ("crontab_title_box")
+        
+        self.image_icon = gtk.Image ()
+        self.image_icon.set_from_pixbuf (self.ParentClass.bigiconcrontab)
+        self.title_box.pack_start (self.image_icon, False, False, 0)
+        self.title_box.reorder_child (self.image_icon, 0)
+        self.image_icon.show ()
+        
+        self.noevents = False
+        
+        
+        ##simple tab    
+        self.entry_title = self.xml.get_widget ("entry_title")
+        self.entry_task = self.xml.get_widget ("entry_task")
+        
+        self.frequency_combobox = self.xml.get_widget ("frequency_combobox")
+        self.frequency_combobox_model = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
+        self.frequency_combobox_model.append([_("Every minute"), ["*", "*", "*", "*", "*", ""]])
+        self.frequency_combobox_model.append([_("Every hour"), ["0", "*", "*", "*", "*", ""]])
+        self.frequency_combobox_model.append([_("Every day"), ["0", "0", "*", "*", "*", ""]])
+        self.frequency_combobox_model.append([_("Every month"), ["0", "0", "1", "*", "*", ""]])
+        self.frequency_combobox_model.append([_("Every week"), ["0", "0", "*", "*", "1", ""]])
+        self.frequency_combobox_model.append([_("At reboot"), ["", "", "", "", "", "@reboot"]])
+        self.frequency_combobox.set_model (self.frequency_combobox_model)
+        
+        self.cb_output = self.xml.get_widget ("combo_output")
+        self.cb_o_model = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_INT)
+        self.cb_o_model.append ([self.ParentClass.output_strings[0], 0])
+        self.cb_o_model.append ([self.ParentClass.output_strings[1], 1])
+        self.cb_o_model.append ([self.ParentClass.output_strings[2], 2])
+        self.cb_o_model.append ([self.ParentClass.output_strings[3], 3])
+        self.cb_output.set_model (self.cb_o_model)
+        cell = gtk.CellRendererText ()
+        self.cb_output.pack_start (cell, True)
+        self.cb_output.add_attribute (cell, "text", 0)
+
+        self.button_cancel = self.xml.get_widget ("button_cancel")
+        self.button_apply = self.xml.get_widget ("button_apply")
+        self.button_template = self.xml.get_widget ("button_template")
+        self.rb_advanced = self.xml.get_widget ("rb_advanced")
+        self.rb_basic = self.xml.get_widget ("rb_basic")
+        
+        self.label_preview = self.xml.get_widget ("label_preview")
+        
+        self.xml.signal_connect("on_button_cancel_clicked", self.on_button_cancel_clicked)
+        self.xml.signal_connect("on_button_apply_clicked", self.on_button_apply_clicked)
+        self.xml.signal_connect("on_anyadvanced_entry_changed", self.on_anyadvanced_entry_changed)
+        self.xml.signal_connect("on_anybasic_entry_changed", self.on_anybasic_entry_changed)
+        self.xml.signal_connect("on_frequency_combobox_changed", self.on_frequency_combobox_changed)
+        self.xml.signal_connect ("on_combo_output_changed", self.on_anybasic_entry_changed)
+
+        self.xml.signal_connect("on_help_clicked", self.on_fieldHelp_clicked)
+        
+        self.xml.signal_connect("on_rb_advanced_toggled", self.on_editmode_toggled)
+        self.xml.signal_connect("on_rb_basic_toggled", self.on_editmode_toggled)
+        
+        self.xml.signal_connect ("on_button_template_clicked", self.on_template_clicked)
+        
+        ##advanced
+        self.minute_entry = self.xml.get_widget ("minute_entry")
+        self.hour_entry = self.xml.get_widget ("hour_entry")
+        self.day_entry = self.xml.get_widget ("day_entry")
+        self.month_entry = self.xml.get_widget ("month_entry")
+        self.weekday_entry = self.xml.get_widget ("weekday_entry")
+        
+        self.help_minute = self.xml.get_widget ("help_minute")
+        self.help_hour = self.xml.get_widget ("help_hour")
+        self.help_day = self.xml.get_widget ("help_day")
+        self.help_month = self.xml.get_widget ("help_month")
+        self.help_weekday = self.xml.get_widget ("help_weekday")
+        
+        self.editorhelper = crontabEditorHelper.CrontabEditorHelper(self)
+        
+            
+        
+    def showadd (self, transient):
+        self.button_apply.set_label (gtk.STOCK_ADD)
+        self.__reset__ ()
+        self.mode = 0
+        self.widget.set_title(_("Create a New Scheduled Task"))
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.button_template.show ()
+        self.widget.show ()
+        self.cb_output.set_active (0)
+
+    def showadd_template (self, transient, title, command, output,timeexpression):
+        self.button_apply.set_label (gtk.STOCK_ADD)
+        self.__reset__ ()
+        self.mode = 0
+        self.widget.set_title(_("Create a New Scheduled Task"))
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.button_template.show ()
+        self.widget.show ()
+        
+        self.output = output 
+        # hehe again, why make it less complicated..
+        timeexpression = timeexpression + " echo hehe"
+        self.minute, self.hour, self.day, self.month, self.weekday, hehe = self.scheduler.parse (timeexpression, True)
+        self.special = ""
+        if self.minute == "@reboot":
+            self.special = "@reboot"
+            self.minute = ""
+            self.day = ""
+            self.hour = ""
+            self.month = ""
+            self.weekday = ""
+        self.command = command
+        self.title = title
+        
+        self.__update_textboxes__ ()
+
+        i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
+        if i == -1:
+            # advanced
+            self.rb_advanced.set_active (True)
+        else:
+            self.rb_basic.set_active (True)
+            self.frequency_combobox.set_active (i)
+
+        self.cb_output.set_active (self.output)
+            
+            
+    def showedit_template (self, transient, id, title, command, output, timeexpression):
+        self.button_apply.set_label (gtk.STOCK_SAVE)
+        
+        self.mode = 2
+        self.tid = id
+        self.__reset__ ()
+        
+        self.command = command
+        self.title = title
+        self.output = output
+        
+        timeexpression = timeexpression + " echo hehe"
+        self.minute, self.hour, self.day, self.month, self.weekday, hehe = self.scheduler.parse (timeexpression, True)
+        self.special = ""
+        if self.minute == "@reboot":
+            self.special = "@reboot"
+            self.minute = ""
+            self.day = ""
+            self.hour = ""
+            self.month = ""
+            self.weekday = ""
+            
+        self.widget.set_title(_("Edit template"))       
+        self.__update_textboxes__ ()
+        
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.widget.show ()
+        self.button_template.hide ()
+        i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
+        if i == -1:
+            # advanced
+            self.rb_advanced.set_active (True)
+        else:
+            self.rb_basic.set_active (True)
+            self.frequency_combobox.set_active (i)
+
+        self.cb_output.set_active (self.output)
+
+    def shownew_template (self, transient):
+        self.button_apply.set_label (gtk.STOCK_ADD)
+        
+        self.mode = 2
+        self.tid = 0
+        self.__reset__ ()
+
+            
+        self.widget.set_title(_("New template"))        
+        self.__update_textboxes__ ()
+        
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.widget.show ()
+        self.button_template.hide ()
+
+                
+    def showedit (self, transient, record, job_id, linenumber, iter):
+        self.button_apply.set_label (gtk.STOCK_APPLY)
+        self.mode = 1
+        self.linenumber = linenumber
+        self.record = record
+        self.job_id = job_id
+        self.__reset__ ()
+        (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.comment, self.job_id, self.title, self.desc, self.output, display) = self.scheduler.parse (record)[1]
+        self.special = ""
+        if self.minute == "@reboot":
+            self.special = "@reboot"
+            self.minute = ""
+            self.day = ""
+            self.hour = ""
+            self.month = ""
+            self.weekday = ""
+            
+        self.widget.set_title(_("Edit a Scheduled Task"))       
+        self.__update_textboxes__ ()
+        self.parentiter = iter
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.button_template.show ()
+        self.widget.show ()
+        i = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
+        if i == -1:
+            # advanced
+            self.rb_advanced.set_active (True)
+        else:
+            self.rb_basic.set_active (True)
+            self.frequency_combobox.set_active (i)
+
+        self.cb_output.set_active (self.output)     
+
+    def __reset__ (self):
+        self.noevents = True
+        self.minute = "0"
+        self.hour = "*"
+        self.day = "*"
+        self.month = "*"
+        self.weekday = "*"
+        self.special = ""
+        self.command = "ls"
+        self.title = _("Untitled")
+        self.output = 0
+        self.frequency_combobox.set_active (1)
+        self.rb_basic.set_active (True)
+        self.minute_entry.set_editable (False)
+        self.minute_entry.set_sensitive (False)
+        self.hour_entry.set_editable (False)
+        self.hour_entry.set_sensitive (False)
+        self.day_entry.set_editable (False)
+        self.day_entry.set_sensitive (False)
+        self.month_entry.set_editable (False)
+        self.month_entry.set_sensitive (False)
+        self.weekday_entry.set_editable (False)         
+        self.weekday_entry.set_sensitive (False)
+        self.help_minute.set_sensitive (False)
+        self.help_hour.set_sensitive (False)
+        self.help_day.set_sensitive (False)
+        self.help_month.set_sensitive (False)
+        self.help_weekday.set_sensitive (False)
+        self.cb_output.set_active (0)
+        self.frequency_combobox.set_sensitive (True)
+        self.__update_textboxes__ ()
+        self.noevents = False
+
+
+    #error dialog box 
+    def __WrongRecordDialog__ (self, x, y, z):
+        self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % (y, z)))
+        self.wrongdialog.run()
+        self.wrongdialog.destroy()
+
+    def __dialog_command_failed__ (self):
+        self.wrongdialog2 = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("Your command contains one or more of the character %, this is special for cron and cannot be used with Gnome-schedule because of the format it uses to store extra information on the crontab line. Please use the | redirector character to achieve the same functionality. Refer to the crontab manual for more information about the % character. If you don not want to use it for redirection it must be properly escaped with the \ letter.")))
+        self.wrongdialog2.run()
+        self.wrongdialog2.destroy()
+            
+    def __check_field_format__ (self, field, type):
+        try:
+            # Type should not be translatable!
+            self.scheduler.checkfield (field, type)
+        except ValueError, ex:
+            raise ex
+
+    def on_editmode_toggled (self, widget, *args):
+        if widget.get_active() == True:
+            if self.noevents == False:
+                self.noevents = True
+                if widget.get_name () == self.rb_advanced.get_name ():
+                    self.rb_basic.set_active (False)
+                    if (self.frequency_combobox.get_active () == 5):
+                        # reboot, standard every hour
+                        self.special = ""
+                        self.minute_entry.set_text ("0")
+                        self.hour_entry.set_text ("*")
+                        self.day_entry.set_text ("*")
+                        self.month_entry.set_text ("*")
+                        self.weekday_entry.set_text ("*")
+                        self.minute = "0"
+                        self.hour = "*"
+                        self.day = "*"
+                        self.month = "*"
+                        self.weekday = "*"
+                        
+                        self.update_preview ()
+                        
+                    self.rb_advanced.set_active (True)
+                    self.minute_entry.set_editable (True)
+                    self.minute_entry.set_sensitive (True)
+                    self.hour_entry.set_editable (True)
+                    self.hour_entry.set_sensitive (True)
+                    self.day_entry.set_editable (True)
+                    self.day_entry.set_sensitive (True)
+                    self.month_entry.set_editable (True)
+                    self.month_entry.set_sensitive (True)
+                    self.weekday_entry.set_editable (True)
+                    self.weekday_entry.set_sensitive (True)
+                    self.help_minute.set_sensitive (True)
+                    self.help_hour.set_sensitive (True)
+                    self.help_day.set_sensitive (True)
+                    self.help_month.set_sensitive (True)
+                    self.help_weekday.set_sensitive (True)
+                    self.frequency_combobox.set_sensitive (False)
+                else:
+                    self.rb_basic.set_active (True)
+                    self.rb_advanced.set_active (False)
+                    self.minute_entry.set_editable (False)
+                    self.minute_entry.set_sensitive (False)
+                    self.hour_entry.set_editable (False)
+                    self.hour_entry.set_sensitive (False)
+                    self.day_entry.set_editable (False)
+                    self.day_entry.set_sensitive (False)
+                    self.month_entry.set_editable (False)
+                    self.month_entry.set_sensitive (False)
+                    self.weekday_entry.set_editable (False)         
+                    self.weekday_entry.set_sensitive (False)
+                    self.help_minute.set_sensitive (False)
+                    self.help_hour.set_sensitive (False)
+                    self.help_day.set_sensitive (False)
+                    self.help_month.set_sensitive (False)
+                    self.help_weekday.set_sensitive (False)
+                    self.frequency_combobox.set_sensitive (True)
+                    self.on_frequency_combobox_changed (self.frequency_combobox)
+                self.noevents = False
+            
+        
+    def on_button_cancel_clicked (self, *args):
+        self.widget.hide()
+
+    def on_template_clicked (self, *args):
+        if self.special != "":
+            try:
+                self.__check_field_format__ (self.special, "special")
+                record = self.special + " " + self.command
+                self.minute = "@reboot"
+                self.hour = "@reboot"
+                self.day = "@reboot"
+                self.month = "@reboot"
+                self.weekday = "@reboot"
+            except ValueError, ex:
+                x, y, z = ex
+                self.__WrongRecordDialog__ (x, y, z)
+                return
+        else:
+            try:
+                # Type should not be translatable!
+                self.__check_field_format__ (self.minute, "minute")
+                self.__check_field_format__ (self.hour, "hour")
+                self.__check_field_format__ (self.day, "day")
+                self.__check_field_format__ (self.month, "month")
+                self.__check_field_format__ (self.weekday, "weekday")
+                record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
+            except ValueError, ex:
+                x, y, z = ex
+                self.__WrongRecordDialog__ (x, y, z)
+                return
+
+        if self.scheduler.check_command (self.command) == False:
+            self.__dialog_command_failed__ ()
+            return  False
+            
+        if self.special != "":
+            self.template.savetemplate_crontab (0, self.title, self.command, self.output, self.special)
+        else:
+            self.template.savetemplate_crontab (0, self.title, self.command, self.output, self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday)
+        
+        self.widget.hide ()
+        
+    def on_button_apply_clicked (self, *args):
+        if self.special != "":
+            try:
+                self.__check_field_format__ (self.special, "special")
+                record = self.special + " " + self.command
+                self.minute = "@reboot"
+                self.hour = "@reboot"
+                self.day = "@reboot"
+                self.month = "@reboot"
+                self.weekday = "@reboot"
+            except ValueError, ex:
+                x, y, z = ex
+                self.__WrongRecordDialog__ (x, y, z)
+                return
+        else:
+            try:
+                # Type should not be translatable!
+                self.__check_field_format__ (self.minute, "minute")
+                self.__check_field_format__ (self.hour, "hour")
+                self.__check_field_format__ (self.day, "day")
+                self.__check_field_format__ (self.month, "month")
+                self.__check_field_format__ (self.weekday, "weekday")
+                record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
+            except ValueError, ex:
+                x, y, z = ex
+                self.__WrongRecordDialog__ (x, y, z)
+                return
+
+        if self.scheduler.check_command (self.command) == False:
+            self.__dialog_command_failed__ ()
+            return  False
+        
+        
+        if (self.backend.get_not_inform_working_dir_crontab() != True):
+            dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nRecurrent tasks will be run from the home directory."))
+            dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+            dia2.set_title (_("Warning: Working directory of executed tasks"))
+            response = dia2.run ()
+            if response == gtk.RESPONSE_CANCEL:
+                dia2.destroy ()
+                del dia2
+                return
+            elif response == gtk.RESPONSE_CLOSE:
+                self.backend.set_not_inform_working_dir_crontab (True)
+            else:
+                pass
+            dia2.destroy ()
+            del dia2
+            
+        if self.mode == 1:
+            self.scheduler.update (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.linenumber, self.parentiter, self.output, self.job_id, self.comment, self.title, self.desc)
+            
+        elif self.mode == 0:
+            self.scheduler.append (self.minute, self.hour, self.day, self.month, self.weekday, self.command, self.output, self.title)
+            
+        elif self.mode == 2:
+            if self.special != "":
+                try:
+                    self.__check_field_format__ (self.special, "special")
+                    record = self.special + " " + self.command  
+                    self.minute = "@reboot"
+                    self.hour = "@reboot"
+                    self.day = "@reboot"
+                    self.month = "@reboot"
+                    self.weekday = "@reboot"
+                except ValueError, ex:
+                    x, y, z = ex
+                    self.__WrongRecordDialog__ (x, y, z)
+                    return
+            else:
+                try:
+                    # Type should not be translatable!
+                    self.__check_field_format__ (self.minute, "minute")
+                    self.__check_field_format__ (self.hour, "hour")
+                    self.__check_field_format__ (self.day, "day")
+                    self.__check_field_format__ (self.month, "month")
+                    self.__check_field_format__ (self.weekday, "weekday")
+                    record = self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday + " " + self.command
+                except ValueError, ex:
+                    x, y, z = ex
+                    self.__WrongRecordDialog__ (x, y, z)
+                    return
+
+            if self.scheduler.check_command (self.command) == False:
+                self.__dialog_command_failed__ ()
+                return  False
+            
+            if self.special != "":
+                self.template.savetemplate_crontab (self.tid, self.title, self.command, self.output, self.special)
+            else:
+                self.template.savetemplate_crontab (self.tid, self.title, self.command, self.output, self.minute + " " + self.hour + " " + self.day + " " + self.month + " " + self.weekday)
+    
+            self.widget.hide ()
+            return
+            
+        self.ParentClass.schedule_reload ()
+        self.widget.hide ()
+
+
+    def __set_frequency_combo__ (self):
+        if self.noevents == False:
+            index = self.__getfrequency__ (self.minute, self.hour, self.day, self.month, self.weekday, self.special)
+            if index != -1:
+                self.frequency_combobox.set_active (index)
+            else:
+                self.rb_advanced.set_active (True)
+
+        
+    def __getfrequency__ (self, minute, hour, day, month, weekday, special):
+        index = -1
+        
+        if minute == "*" and hour == "*" and month == "*" and day == "*" and weekday == "*":
+            index = 0
+        if minute == "0" and hour == "*" and month == "*" and day == "*" and weekday == "*":
+            index = 1
+        if minute == "0" and hour == "0" and month == "*" and day == "*" and weekday == "*":
+            index = 2
+        if minute == "0" and hour == "0" and month == "*" and day == "1" and weekday == "*":
+            index = 3
+        if minute == "0" and hour == "0" and month == "*" and day == "*" and weekday == "1":
+            index = 4
+        if special != "":
+            index = 5
+            
+
+        return index
+
+        
+    def __update_textboxes__ (self):
+        self.noevents = True
+        self.cb_output.set_active (self.output)
+        self.entry_task.set_text (self.command)
+        self.entry_title.set_text (self.title)
+        self.minute_entry.set_text (self.minute)
+        self.hour_entry.set_text (self.hour)
+        self.day_entry.set_text (self.day)
+        self.month_entry.set_text (self.month)
+        self.weekday_entry.set_text (self.weekday)
+        self.update_preview ()
+        #self.__set_frequency_combo__()
+        self.noevents = False
+
+    def update_preview (self):
+        if self.special != "":
+            try:
+                self.__check_field_format__ (self.special, "special")
+                record = self.special + " " + self.command
+                minute = "@reboot"
+                hour = "@reboot"
+                day = "@reboot"
+                month = "@reboot"
+                weekday = "@reboot"
+                self.label_preview.set_text ("<b>" + self.scheduler.__easy__ (minute, hour, day, month, weekday) + "</b>")
+                
+            except ValueError, ex:
+                x, y, z = ex
+                self.label_preview.set_text (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % ({'field' : y, 'reason' : z}))
+                
+                
+        else:
+            try:
+                # Type should not be translatable!
+                self.__check_field_format__ (self.minute, "minute")
+                self.__check_field_format__ (self.hour, "hour")
+                self.__check_field_format__ (self.day, "day")
+                self.__check_field_format__ (self.month, "month")
+                self.__check_field_format__ (self.weekday, "weekday")
+                
+                # Day of Month
+                # Crontab bug? Let's not support
+                # dom behaves like minute
+                """
+                dom = self.day
+                if dom.isdigit() == False:
+                    dom = dom.lower ()
+                    for day in self.scheduler.downumbers:
+                        dom = dom.replace (day, self.scheduler.downumbers[day])
+                """
+                        
+                # Month of Year
+                moy = self.month
+                if moy.isdigit () == False:
+                    moy = moy.lower ()
+                    for m in self.scheduler.monthnumbers:
+                        moy = moy.replace (m, self.scheduler.monthnumbers[m])
+                    
+            
+                # Day of Week
+                dow = self.weekday
+                if dow.isdigit() == False:
+                    dow = dow.lower ()
+                    for day in self.scheduler.downumbers:
+                        dow = dow.replace (day, self.scheduler.downumbers[day])
+                self.label_preview.set_text ("<b>" + self.scheduler.__easy__ (self.minute, self.hour, self.day, moy, dow) + "</b>")
+            except ValueError, ex:
+                x, y, z = ex
+                self.label_preview.set_text (_("This is an invalid record! The problem could be in the %(field)s field. Reason: %(reason)s") % ({'field' : y, 'reason' : z}))
+
+        self.label_preview.set_use_markup (True)
+            
+            
+    def on_anyadvanced_entry_changed (self, *args):
+        if self.noevents == False:
+            self.minute = self.minute_entry.get_text ()
+            self.hour = self.hour_entry.get_text ()
+            self.day = self.day_entry.get_text ()
+            self.month = self.month_entry.get_text ()
+            self.weekday = self.weekday_entry.get_text ()
+            self.output = self.cb_output.get_active()
+            
+            self.__update_textboxes__ ()
+
+
+    def on_anybasic_entry_changed (self, *args):
+        if self.noevents == False:
+            self.command = self.entry_task.get_text ()
+            self.title = self.entry_title.get_text ()
+            self.output = self.cb_output.get_active()
+            self.__update_textboxes__ ()
+
+
+    def on_frequency_combobox_changed (self, bin):
+        iter = self.frequency_combobox.get_active_iter ()
+        frequency = self.frequency_combobox_model.get_value(iter, 1)
+        if frequency != None:
+            self.minute, self.hour, self.day, self.month, self.weekday, self.special = frequency
+            self.__update_textboxes__()
+        
+    
+    def on_fieldHelp_clicked(self, widget, *args):
+        name = widget.get_name()
+        field = "minute"
+        if name == "help_minute" :
+            field = "minute"
+            expression = self.minute_entry.get_text()
+        if name == "help_hour" :
+            field = "hour"
+            expression = self.hour_entry.get_text()
+        if name == "help_day" :
+            field = "day"
+            expression = self.day_entry.get_text()
+        if name == "help_month" :
+            field = "month"
+            expression = self.month_entry.get_text()
+        if name == "help_weekday" :
+            field = "weekday"
+            expression = self.weekday_entry.get_text()
 
-		self.editorhelper.show (field, expression)
-		
+        self.editorhelper.show (field, expression)
+        

Modified: trunk/src/crontabEditorHelper.py
==============================================================================
--- trunk/src/crontabEditorHelper.py	(original)
+++ trunk/src/crontabEditorHelper.py	Sat Feb 14 21:20:56 2009
@@ -24,263 +24,263 @@
 
 
 class CrontabEditorHelper:
-	def __init__(self, parent):
-		self.ParentClass = parent
-			
-		self.xml = self.ParentClass.xml
-		
-		self.NoExpressionEvents = False
-		self.fieldRegex = self.ParentClass.fieldRegex
-		
-		self.widget = self.xml.get_widget("crontabEditorHelper")
-		self.widget.connect("delete-event", self.widget.hide_on_delete)
-		
-		self.radAll = self.xml.get_widget("radAll")
-		self.radEvery = self.xml.get_widget("radEvery")
-		self.radRange = self.xml.get_widget("radRange")
-		self.radFix = self.xml.get_widget("radFix")
-		self.radOth = self.xml.get_widget ("radOth")
-
-		self.entExpression = self.xml.get_widget("entExpression")
-		self.entEvery = self.xml.get_widget("entEvery")
-		self.entFix = self.xml.get_widget("entFix")
-		self.entRangeStart = self.xml.get_widget("entRangeStart")
-		self.entRangeEnd = self.xml.get_widget("entRangeEnd")
-	
-		self.header = self.xml.get_widget("label_crontab_editor_title")
-
-		self.lblEveryEntity = self.xml.get_widget("lblEveryEntity")
-		self.lblFixEntity = self.xml.get_widget("lblFixEntity")
-
-		#connect the radiobuttons toggle
-		self.xml.signal_connect("on_btnCancel_clicked", self.btnCancel_clicked)
-		self.xml.signal_connect("on_btnOk_clicked", self.btnOk_clicked)
-		self.xml.signal_connect("on_radAll_toggled", self.RadioButtonChange)
-		self.xml.signal_connect("on_radEvery_toggled", self.RadioButtonChange)
-		self.xml.signal_connect("on_radRange_toggled", self.RadioButtonChange)
-		self.xml.signal_connect("on_radFix_toggled", self.RadioButtonChange)
-		self.xml.signal_connect("on_radOth_toggled", self.RadioButtonChange)
-
-		#connect the changes of a combo or entry
-		self.xml.signal_connect("on_entFix_changed", self.anyEntryChanged)
-		self.xml.signal_connect("on_entEvery_changed", self.anyEntryChanged)
-		self.xml.signal_connect("on_entRangeStart_changed", self.anyEntryChanged)
-		self.xml.signal_connect("on_entRangeEnd_changed", self.anyEntryChanged)
-		self.xml.signal_connect("on_entExpression_changed", self.entExpressionChanged)
-
-		self.widgetgroups = { "radAll":  [],
-				      "radEvery":["entEvery", "lblEveryEntity"],
-				      "radRange":["entRangeStart", "entRangeEnd",
-						  "lblRangeStart", "lblRangeEnd"],
-				      "radFix":  ["entFix", "lblFixEntity"],
-				      "radOth":  ["entExpression",
-						  "lblExpression"] }
-
-
-	def populateLabels(self, field):
-		#put the apropiate values in the labels describing entitys, and the 'at' combobox
-
-		if field == "minute":
-			self.entRangeEnd.set_text ("59")
-			self.entRangeStart.set_text ("0")
-			self.entFix.set_text("0")
-			self.radAll.set_label(_("Every minute"))
-
-		if field == "hour":
-			self.entRangeEnd.set_text ("23")
-			self.entRangeStart.set_text ("0")
-			self.entFix.set_text("0")
-			self.radAll.set_label(_("Every hour"))
-
-		if field == "day":
-			self.entRangeEnd.set_text ("31")
-			self.entRangeStart.set_text ("1")
-			self.entFix.set_text("1")
-			self.radAll.set_label(_("Every day"))
-			
-		if field == "month":
-			self.entRangeEnd.set_text ("12")
-			self.entRangeStart.set_text ("1")
-			self.entFix.set_text("1")
-			self.radAll.set_label(_("Every month"))
-
-		if field == "weekday":
-			self.entRangeEnd.set_text ("7")
-			self.entRangeStart.set_text ("0")
-			self.entFix.set_text("0")
-			self.radAll.set_label(_("Every weekday"))
-
-
-		self.entEvery.set_text("2")
-		self.entExpression.set_text ("*")
-
-		self.trans_field = self.ParentClass.scheduler.translate_frequency (field)
-		
-		
-		
-		self.do_label_magic ()
-
-
-	def show (self, field, expression):
-		self.field = field
-		self.populateLabels(field)
-
-		m = self.fieldRegex.match (expression)
-		self.radOth.set_active (True)
-
-		self.NoExpressionEvents = True
-		self.entExpression.set_text (expression)
-
-		if m != None:
-			if m.groups()[0] != None:
-				self.radAll.set_active (True)
-			# 10 * * * * command
-			# */2 * * * * command
-			if m.groups()[1] != None or m.groups()[2] != None:
-				if m.groups()[1] != None:
-					self.radFix.set_active (True)
-					self.entFix.set_text (m.groups()[1])
-				else:
-					self.radEvery.set_active (True)
-					self.entEvery.set_text (m.groups()[2])
-
-			# 1-10 * * * * command
-			if m.groups()[3] != None and m.groups()[4] != None:
-				self.radRange.set_active (True)
-				self.entRangeStart.set_text(m.groups()[3])
-				self.entRangeEnd.set_text (m.groups()[4])
-
-			# Unused
-			# 1,2,3,4 * * * * command
-			# if m.groups()[5] != None:
-				# self.radOth.set_active (True)
-				# fields = m.groups()[5].split (",")
-
-		self.NoExpressionEvents = False
-
-		#show the form
-		if field == "minute":
-			self.widget.set_title(_("Edit minute"))
-		elif field == "hour":
-			self.widget.set_title(_("Edit hour"))
-		elif field == "day":
-			self.widget.set_title(_("Edit day"))
-		elif field == "month":
-			self.widget.set_title(_("Edit month"))
-		elif field == "weekday":
-			self.widget.set_title(_("Edit weekday"))
-			
-		self.widget.set_transient_for(self.ParentClass.widget)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.widget.show_all()
-
-
-	def btnOk_clicked(self, *args):
-		#move expression to field in editor and hide
-		expression = self.entExpression.get_text()
-		try:
-			self.ParentClass.scheduler.checkfield (expression, self.field)
-		except ValueError, ex:
-			x, y, z = ex
-			self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is invalid. Reason: %s") % (z)))
-			self.wrongdialog.run()
-			self.wrongdialog.destroy()
-			return
-
-		if self.field == "minute": self.ParentClass.minute_entry.set_text(expression)
-		if self.field == "hour": self.ParentClass.hour_entry.set_text(expression)
-		if self.field == "day": self.ParentClass.day_entry.set_text(expression)
-		if self.field == "month": self.ParentClass.month_entry.set_text(expression)
-		if self.field == "weekday": self.ParentClass.weekday_entry.set_text(expression)
-		
-		self.widget.hide()
-
-
-	def btnCancel_clicked(self, *args):
-		#hide
-		self.widget.hide()
-		#return True
-
-
-	def RadioButtonChange(self, widget):
-		self.NoExpressionEvents = True
-		self.do_label_magic ()
-		name = widget.get_name()
-		if widget.get_active():
-			if name == "radAll":
-				self.entExpression.set_text("*")
-			elif name == "radEvery":
-				self.entExpression.set_text("*/" + self.entEvery.get_text())
-			elif name == "radRange":
-				self.entExpression.set_text(self.entRangeStart.get_text() + "-" + self.entRangeEnd.get_text())
-			elif name == "radFix":
-				self.entExpression.set_text(self.entFix.get_text())
-		self.NoExpressionEvents = False
-
-		for groupname, widgetlist in self.widgetgroups.iteritems():
-			state = groupname == name
-			for widgetname in widgetlist:
-				widget = self.xml.get_widget(widgetname)
-				widget.set_sensitive(state)
-
-
-	def do_label_magic (self):
-		translated = ["", ""]
-		if self.field == "minute":
-			#minute
-			translated[0] = _("At an exact minute")
-			translated[1] = _("Minute:")
-		elif self.field == "hour":
-			#hour
-			translated[0] = _("At an exact hour")
-			translated[1] = _("Hour:")
-		elif self.field == "day":
-			#day
-			translated[0] = _("On a day")
-			translated[1] = _("Day:")
-		elif self.field == "month":
-			#month
-			translated[0] = _("In a month")
-			translated[1] = _("Month:")
-		elif self.field == "weekday":
-			#weekday
-			translated[0] = _("On a weekday")
-			translated[1] = _("Weekday:")
-
-		self.radFix.set_label (translated[0])
-		self.lblFixEntity.set_label (translated[1])
-		
-		translated[0] = _("In a step width")
-		if self.field == "minute":
-			translated[1] = _("Minutes:")
-		elif self.field == "hour":
-			translated[1] = _("Hours:")
-		elif self.field == "day":
-			translated[1] = _("Days:")
-		elif self.field == "month":
-			translated[1] = _("Months:")
-		elif self.field == "weekday":
-			translated[1] = _("Weekdays:")
-			
-		self.radEvery.set_label (translated[0])
-		self.lblEveryEntity.set_label (translated[1])
-					
-
-	def entExpressionChanged(self, *args):
-		if self.NoExpressionEvents == False:
-			self.radOth.set_active (True)
-
-
-	def anyEntryChanged(self, *args):
-		self.NoExpressionEvents = True
-		self.do_label_magic ()
-		#create a easy read line for the expression view, put the command into the edit box
-		if self.radAll.get_active():
-				self.entExpression.set_text("*")
-		if self.radEvery.get_active():
-				self.entExpression.set_text("*/" + self.entEvery.get_text())
-		if self.radRange.get_active():
-				self.entExpression.set_text(self.entRangeStart.get_text() + "-" + self.entRangeEnd.get_text())
-		if self.radFix.get_active ():
-				self.entExpression.set_text(self.entFix.get_text())
-		self.NoExpressionEvents = False
+    def __init__(self, parent):
+        self.ParentClass = parent
+            
+        self.xml = self.ParentClass.xml
+        
+        self.NoExpressionEvents = False
+        self.fieldRegex = self.ParentClass.fieldRegex
+        
+        self.widget = self.xml.get_widget("crontabEditorHelper")
+        self.widget.connect("delete-event", self.widget.hide_on_delete)
+        
+        self.radAll = self.xml.get_widget("radAll")
+        self.radEvery = self.xml.get_widget("radEvery")
+        self.radRange = self.xml.get_widget("radRange")
+        self.radFix = self.xml.get_widget("radFix")
+        self.radOth = self.xml.get_widget ("radOth")
+
+        self.entExpression = self.xml.get_widget("entExpression")
+        self.entEvery = self.xml.get_widget("entEvery")
+        self.entFix = self.xml.get_widget("entFix")
+        self.entRangeStart = self.xml.get_widget("entRangeStart")
+        self.entRangeEnd = self.xml.get_widget("entRangeEnd")
+    
+        self.header = self.xml.get_widget("label_crontab_editor_title")
+
+        self.lblEveryEntity = self.xml.get_widget("lblEveryEntity")
+        self.lblFixEntity = self.xml.get_widget("lblFixEntity")
+
+        #connect the radiobuttons toggle
+        self.xml.signal_connect("on_btnCancel_clicked", self.btnCancel_clicked)
+        self.xml.signal_connect("on_btnOk_clicked", self.btnOk_clicked)
+        self.xml.signal_connect("on_radAll_toggled", self.RadioButtonChange)
+        self.xml.signal_connect("on_radEvery_toggled", self.RadioButtonChange)
+        self.xml.signal_connect("on_radRange_toggled", self.RadioButtonChange)
+        self.xml.signal_connect("on_radFix_toggled", self.RadioButtonChange)
+        self.xml.signal_connect("on_radOth_toggled", self.RadioButtonChange)
+
+        #connect the changes of a combo or entry
+        self.xml.signal_connect("on_entFix_changed", self.anyEntryChanged)
+        self.xml.signal_connect("on_entEvery_changed", self.anyEntryChanged)
+        self.xml.signal_connect("on_entRangeStart_changed", self.anyEntryChanged)
+        self.xml.signal_connect("on_entRangeEnd_changed", self.anyEntryChanged)
+        self.xml.signal_connect("on_entExpression_changed", self.entExpressionChanged)
+
+        self.widgetgroups = { "radAll":  [],
+                      "radEvery":["entEvery", "lblEveryEntity"],
+                      "radRange":["entRangeStart", "entRangeEnd",
+                          "lblRangeStart", "lblRangeEnd"],
+                      "radFix":  ["entFix", "lblFixEntity"],
+                      "radOth":  ["entExpression",
+                          "lblExpression"] }
+
+
+    def populateLabels(self, field):
+        #put the apropiate values in the labels describing entitys, and the 'at' combobox
+
+        if field == "minute":
+            self.entRangeEnd.set_text ("59")
+            self.entRangeStart.set_text ("0")
+            self.entFix.set_text("0")
+            self.radAll.set_label(_("Every minute"))
+
+        if field == "hour":
+            self.entRangeEnd.set_text ("23")
+            self.entRangeStart.set_text ("0")
+            self.entFix.set_text("0")
+            self.radAll.set_label(_("Every hour"))
+
+        if field == "day":
+            self.entRangeEnd.set_text ("31")
+            self.entRangeStart.set_text ("1")
+            self.entFix.set_text("1")
+            self.radAll.set_label(_("Every day"))
+            
+        if field == "month":
+            self.entRangeEnd.set_text ("12")
+            self.entRangeStart.set_text ("1")
+            self.entFix.set_text("1")
+            self.radAll.set_label(_("Every month"))
+
+        if field == "weekday":
+            self.entRangeEnd.set_text ("7")
+            self.entRangeStart.set_text ("0")
+            self.entFix.set_text("0")
+            self.radAll.set_label(_("Every weekday"))
+
+
+        self.entEvery.set_text("2")
+        self.entExpression.set_text ("*")
+
+        self.trans_field = self.ParentClass.scheduler.translate_frequency (field)
+        
+        
+        
+        self.do_label_magic ()
+
+
+    def show (self, field, expression):
+        self.field = field
+        self.populateLabels(field)
+
+        m = self.fieldRegex.match (expression)
+        self.radOth.set_active (True)
+
+        self.NoExpressionEvents = True
+        self.entExpression.set_text (expression)
+
+        if m != None:
+            if m.groups()[0] != None:
+                self.radAll.set_active (True)
+            # 10 * * * * command
+            # */2 * * * * command
+            if m.groups()[1] != None or m.groups()[2] != None:
+                if m.groups()[1] != None:
+                    self.radFix.set_active (True)
+                    self.entFix.set_text (m.groups()[1])
+                else:
+                    self.radEvery.set_active (True)
+                    self.entEvery.set_text (m.groups()[2])
+
+            # 1-10 * * * * command
+            if m.groups()[3] != None and m.groups()[4] != None:
+                self.radRange.set_active (True)
+                self.entRangeStart.set_text(m.groups()[3])
+                self.entRangeEnd.set_text (m.groups()[4])
+
+            # Unused
+            # 1,2,3,4 * * * * command
+            # if m.groups()[5] != None:
+                # self.radOth.set_active (True)
+                # fields = m.groups()[5].split (",")
+
+        self.NoExpressionEvents = False
+
+        #show the form
+        if field == "minute":
+            self.widget.set_title(_("Edit minute"))
+        elif field == "hour":
+            self.widget.set_title(_("Edit hour"))
+        elif field == "day":
+            self.widget.set_title(_("Edit day"))
+        elif field == "month":
+            self.widget.set_title(_("Edit month"))
+        elif field == "weekday":
+            self.widget.set_title(_("Edit weekday"))
+            
+        self.widget.set_transient_for(self.ParentClass.widget)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.widget.show_all()
+
+
+    def btnOk_clicked(self, *args):
+        #move expression to field in editor and hide
+        expression = self.entExpression.get_text()
+        try:
+            self.ParentClass.scheduler.checkfield (expression, self.field)
+        except ValueError, ex:
+            x, y, z = ex
+            self.wrongdialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, (_("This is invalid. Reason: %s") % (z)))
+            self.wrongdialog.run()
+            self.wrongdialog.destroy()
+            return
+
+        if self.field == "minute": self.ParentClass.minute_entry.set_text(expression)
+        if self.field == "hour": self.ParentClass.hour_entry.set_text(expression)
+        if self.field == "day": self.ParentClass.day_entry.set_text(expression)
+        if self.field == "month": self.ParentClass.month_entry.set_text(expression)
+        if self.field == "weekday": self.ParentClass.weekday_entry.set_text(expression)
+        
+        self.widget.hide()
+
+
+    def btnCancel_clicked(self, *args):
+        #hide
+        self.widget.hide()
+        #return True
+
+
+    def RadioButtonChange(self, widget):
+        self.NoExpressionEvents = True
+        self.do_label_magic ()
+        name = widget.get_name()
+        if widget.get_active():
+            if name == "radAll":
+                self.entExpression.set_text("*")
+            elif name == "radEvery":
+                self.entExpression.set_text("*/" + self.entEvery.get_text())
+            elif name == "radRange":
+                self.entExpression.set_text(self.entRangeStart.get_text() + "-" + self.entRangeEnd.get_text())
+            elif name == "radFix":
+                self.entExpression.set_text(self.entFix.get_text())
+        self.NoExpressionEvents = False
+
+        for groupname, widgetlist in self.widgetgroups.iteritems():
+            state = groupname == name
+            for widgetname in widgetlist:
+                widget = self.xml.get_widget(widgetname)
+                widget.set_sensitive(state)
+
+
+    def do_label_magic (self):
+        translated = ["", ""]
+        if self.field == "minute":
+            #minute
+            translated[0] = _("At an exact minute")
+            translated[1] = _("Minute:")
+        elif self.field == "hour":
+            #hour
+            translated[0] = _("At an exact hour")
+            translated[1] = _("Hour:")
+        elif self.field == "day":
+            #day
+            translated[0] = _("On a day")
+            translated[1] = _("Day:")
+        elif self.field == "month":
+            #month
+            translated[0] = _("In a month")
+            translated[1] = _("Month:")
+        elif self.field == "weekday":
+            #weekday
+            translated[0] = _("On a weekday")
+            translated[1] = _("Weekday:")
+
+        self.radFix.set_label (translated[0])
+        self.lblFixEntity.set_label (translated[1])
+        
+        translated[0] = _("In a step width")
+        if self.field == "minute":
+            translated[1] = _("Minutes:")
+        elif self.field == "hour":
+            translated[1] = _("Hours:")
+        elif self.field == "day":
+            translated[1] = _("Days:")
+        elif self.field == "month":
+            translated[1] = _("Months:")
+        elif self.field == "weekday":
+            translated[1] = _("Weekdays:")
+            
+        self.radEvery.set_label (translated[0])
+        self.lblEveryEntity.set_label (translated[1])
+                    
+
+    def entExpressionChanged(self, *args):
+        if self.NoExpressionEvents == False:
+            self.radOth.set_active (True)
+
+
+    def anyEntryChanged(self, *args):
+        self.NoExpressionEvents = True
+        self.do_label_magic ()
+        #create a easy read line for the expression view, put the command into the edit box
+        if self.radAll.get_active():
+                self.entExpression.set_text("*")
+        if self.radEvery.get_active():
+                self.entExpression.set_text("*/" + self.entEvery.get_text())
+        if self.radRange.get_active():
+                self.entExpression.set_text(self.entRangeStart.get_text() + "-" + self.entRangeEnd.get_text())
+        if self.radFix.get_active ():
+                self.entExpression.set_text(self.entFix.get_text())
+        self.NoExpressionEvents = False

Modified: trunk/src/data.py
==============================================================================
--- trunk/src/data.py	(original)
+++ trunk/src/data.py	Sat Feb 14 21:20:56 2009
@@ -27,66 +27,66 @@
 import config
 
 class ConfigBackend:
-	
-	def __init__(self, parent, type):
-		
-		self.parent = parent
-		self.type = "gconf"
-		
-		self.gconf_client = gconf.client_get_default()
-		self.gconf_client.add_dir ("/apps/gnome-schedule", gconf.CLIENT_PRELOAD_NONE)	
-		self.gconf_client.notify_add ("/apps/gnome-schedule/advanced", self.on_gconfkey_advanced_changed)
-
-	def get_not_inform_working_dir (self):
-		if ((self.get_not_inform_working_dir_crontab () and self.get_not_inform_working_dir_at ()) or self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir")):
-			return True
-		else:
-			return False
-			
-	
-	def set_not_inform_working_dir (self, value):
-		self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir", value)
-	
-	def get_not_inform_working_dir_crontab (self):
-		return self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir_crontab")
-	
-	def set_not_inform_working_dir_crontab (self, value):
-		self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir_crontab", value)
-		
-	def get_not_inform_working_dir_at (self):
-		return self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir_at")
-	
-	def set_not_inform_working_dir_at (self, value):
-		self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir_at", value)
-		
-		
-	def set_window_state (self, x, y, height, width):
-		self.gconf_client.set_int ("/apps/gnome-schedule/x", x)
-		self.gconf_client.set_int ("/apps/gnome-schedule/y", y)
-		self.gconf_client.set_int ("/apps/gnome-schedule/height", height)
-		self.gconf_client.set_int ("/apps/gnome-schedule/width", width)
-	
-	def get_window_state (self):
-		h = self.gconf_client.get_int ("/apps/gnome-schedule/height")
-		w = self.gconf_client.get_int ("/apps/gnome-schedule/width")
-		x = self.gconf_client.get_int ("/apps/gnome-schedule/x")
-		y = self.gconf_client.get_int ("/apps/gnome-schedule/y")
-		return x, y, h, w
-		
-	def get_advanced_option(self):
-		return self.gconf_client.get_bool ("/apps/gnome-schedule/advanced")
-
-		
-	def set_advanced_option(self,value):
-		self.gconf_client.set_bool ("/apps/gnome-schedule/advanced", value)
-
-
-	def on_gconfkey_advanced_changed (self, client, connection_id, entry, args):
-		val = self.gconf_client.get_bool ("/apps/gnome-schedule/advanced")
-		if val:
-			self.parent.switchView("advanced")
-		else:
-			self.parent.switchView("simple")
+    
+    def __init__(self, parent, type):
+        
+        self.parent = parent
+        self.type = "gconf"
+        
+        self.gconf_client = gconf.client_get_default()
+        self.gconf_client.add_dir ("/apps/gnome-schedule", gconf.CLIENT_PRELOAD_NONE)   
+        self.gconf_client.notify_add ("/apps/gnome-schedule/advanced", self.on_gconfkey_advanced_changed)
+
+    def get_not_inform_working_dir (self):
+        if ((self.get_not_inform_working_dir_crontab () and self.get_not_inform_working_dir_at ()) or self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir")):
+            return True
+        else:
+            return False
+            
+    
+    def set_not_inform_working_dir (self, value):
+        self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir", value)
+    
+    def get_not_inform_working_dir_crontab (self):
+        return self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir_crontab")
+    
+    def set_not_inform_working_dir_crontab (self, value):
+        self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir_crontab", value)
+        
+    def get_not_inform_working_dir_at (self):
+        return self.gconf_client.get_bool ("/apps/gnome-schedule/inform_working_dir_at")
+    
+    def set_not_inform_working_dir_at (self, value):
+        self.gconf_client.set_bool ("/apps/gnome-schedule/inform_working_dir_at", value)
+        
+        
+    def set_window_state (self, x, y, height, width):
+        self.gconf_client.set_int ("/apps/gnome-schedule/x", x)
+        self.gconf_client.set_int ("/apps/gnome-schedule/y", y)
+        self.gconf_client.set_int ("/apps/gnome-schedule/height", height)
+        self.gconf_client.set_int ("/apps/gnome-schedule/width", width)
+    
+    def get_window_state (self):
+        h = self.gconf_client.get_int ("/apps/gnome-schedule/height")
+        w = self.gconf_client.get_int ("/apps/gnome-schedule/width")
+        x = self.gconf_client.get_int ("/apps/gnome-schedule/x")
+        y = self.gconf_client.get_int ("/apps/gnome-schedule/y")
+        return x, y, h, w
+        
+    def get_advanced_option(self):
+        return self.gconf_client.get_bool ("/apps/gnome-schedule/advanced")
+
+        
+    def set_advanced_option(self,value):
+        self.gconf_client.set_bool ("/apps/gnome-schedule/advanced", value)
+
+
+    def on_gconfkey_advanced_changed (self, client, connection_id, entry, args):
+        val = self.gconf_client.get_bool ("/apps/gnome-schedule/advanced")
+        if val:
+            self.parent.switchView("advanced")
+        else:
+            self.parent.switchView("simple")
 
 
 

Modified: trunk/src/gnome-schedule.glade
==============================================================================
--- trunk/src/gnome-schedule.glade	(original)
+++ trunk/src/gnome-schedule.glade	Sat Feb 14 21:20:56 2009
@@ -268,6 +268,19 @@
                         <property name="position">1</property>
                       </packing>
                     </child>
+                    <child>
+                      <widget class="GtkCheckButton" id="cb_xoutput">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="label" translatable="yes">X application</property>
+                        <property name="response_id">0</property>
+                        <property name="draw_indicator">True</property>
+                        <signal name="toggled" handler="on_cb_xoutput_toggled"/>
+                      </widget>
+                      <packing>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
                   </widget>
                   <packing>
                     <property name="padding">5</property>
@@ -629,25 +642,6 @@
                   <placeholder/>
                 </child>
                 <child>
-                  <widget class="GtkCheckButton" id="cb_nooutput">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="label" translatable="yes">_No output (&gt;/dev/null 2&gt;&amp;1)</property>
-                    <property name="use_underline">True</property>
-                    <property name="response_id">0</property>
-                    <property name="draw_indicator">True</property>
-                    <signal name="toggled" handler="on_anybasic_entry_changed"/>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="top_attach">2</property>
-                    <property name="bottom_attach">3</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
                   <widget class="GtkEntry" id="entry_task">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
@@ -696,6 +690,18 @@
                     <property name="x_options">GTK_FILL</property>
                   </packing>
                 </child>
+                <child>
+                  <widget class="GtkComboBox" id="combo_output">
+                    <property name="visible">True</property>
+                    <signal name="changed" handler="on_combo_output_changed"/>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
               </widget>
               <packing>
                 <property name="position">1</property>
@@ -1435,6 +1441,60 @@
             <property name="column_spacing">5</property>
             <property name="row_spacing">1</property>
             <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+            <child>
               <widget class="GtkAlignment" id="alignment4">
                 <property name="visible">True</property>
                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>

Modified: trunk/src/gnome-schedule.py
==============================================================================
--- trunk/src/gnome-schedule.py	(original)
+++ trunk/src/gnome-schedule.py	Sat Feb 14 21:20:56 2009
@@ -36,20 +36,20 @@
 poscorrect_isset = os.getenv ("POSIXLY_CORRECT", False)
 manual_poscorrect = False
 if poscorrect_isset == False:
-	os.putenv ("POSIXLY_CORRECT", "enabled")
-	manual_poscorrect = True
+    os.putenv ("POSIXLY_CORRECT", "enabled")
+    manual_poscorrect = True
 
 if __name__ == "__main__":
-	signal.signal (signal.SIGINT, signal.SIG_DFL)
+    signal.signal (signal.SIGINT, signal.SIG_DFL)
 
 debug_flag = None
 if '--debug' in sys.argv:
-	debug_flag = 1
+    debug_flag = 1
 
 try:
-	import pygtk
-  	#tell pyGTK, if possible, that we want GTKv2
-  	pygtk.require("2.0")
+    import pygtk
+    #tell pyGTK, if possible, that we want GTKv2
+    pygtk.require("2.0")
   
 except:
   #Some distributions come with GTK2, but not pyGTK
@@ -61,7 +61,7 @@
   # TODO: Gnome specific
   import gnome
   import gnome.ui
-	
+    
 except:
   print _("You need to install pyGTK or GTKv2,\n"
           "or set your PYTHONPATH correctly.\n"

Modified: trunk/src/lang.py
==============================================================================
--- trunk/src/lang.py	(original)
+++ trunk/src/lang.py	Sat Feb 14 21:20:56 2009
@@ -63,68 +63,68 @@
 # Fallback to english if locale setting is unknown
 # or translation for this locale is not available
 if gettext.find(domain) == None:
-	language = "C"
+    language = "C"
 else:
-	language = ""
+    language = ""
 try:
-	locale.setlocale(locale.LC_ALL, language)
+    locale.setlocale(locale.LC_ALL, language)
 except:
-	warnings.warn_explicit("Locale not supported by Python. Using the fallback 'C' locale.", Warning, "lang.py", "68")
+    warnings.warn_explicit("Locale not supported by Python. Using the fallback 'C' locale.", Warning, "lang.py", "68")
 
 encoding = locale.getpreferredencoding(False)
 language = locale.getlocale()[0]
 if language == None:
-	language = "C"
+    language = "C"
 
 # Some locale stuff in this section to get 
 # translated time expressions out of system. 
 # Don't touch this. Change settings through gettext (po files) 
 def lc_weekday (weekday):
-	weekday = int(weekday)
-	if weekday >= 0 and weekday < 7:
-		weekday = str(weekday)
-	else: 
-		weekday = "0"
-	timevalue = time.strptime(weekday, "%w")
-	expression = time.strftime("%A", timevalue)
-	return unicode(expression, encoding, 'ignore')
+    weekday = int(weekday)
+    if weekday >= 0 and weekday < 7:
+        weekday = str(weekday)
+    else: 
+        weekday = "0"
+    timevalue = time.strptime(weekday, "%w")
+    expression = time.strftime("%A", timevalue)
+    return unicode(expression, encoding, 'ignore')
 
 def lc_month (month):
-	month = "%02d" % int(month)
-	timevalue = time.strptime(month, "%m")
-	expression = time.strftime("%B", timevalue)
-	return unicode(expression, encoding, 'ignore')
+    month = "%02d" % int(month)
+    timevalue = time.strptime(month, "%m")
+    expression = time.strftime("%B", timevalue)
+    return unicode(expression, encoding, 'ignore')
 
 def lc_date (day,month,year = None):
-	day = "%02d" % int(day)
-	month = "%02d" % int(month)
-	if year == None:
-		timevalue = time.strptime(("%s.%s" % (day, month)), "%d.%m")
-		# Translators: Date format for expressions like 'January 21'. %B is month, %d is day number. 
-		# Run the command 'man strftime' to read more about these and other available specifiers.
-		expression = time.strftime(_("%B %d"), timevalue)
-	else:
-		year = str(year)[-2:]
-		year = "%02d" % int(year)
-		timevalue = time.strptime(("%s.%s.%s" % (day, month, year)), "%d.%m.%y")
-		# Translators: Date format for expressions like 'January 21, 2005'. %B is month, %d is day number, %Y is year with century. 
-		# Run the command 'man strftime' to read more about these and other available specifiers.
-		expression = time.strftime(_("%B %d, %Y"), timevalue)
-	return unicode(expression, encoding, 'ignore')
+    day = "%02d" % int(day)
+    month = "%02d" % int(month)
+    if year == None:
+        timevalue = time.strptime(("%s.%s" % (day, month)), "%d.%m")
+        # Translators: Date format for expressions like 'January 21'. %B is month, %d is day number. 
+        # Run the command 'man strftime' to read more about these and other available specifiers.
+        expression = time.strftime(_("%B %d"), timevalue)
+    else:
+        year = str(year)[-2:]
+        year = "%02d" % int(year)
+        timevalue = time.strptime(("%s.%s.%s" % (day, month, year)), "%d.%m.%y")
+        # Translators: Date format for expressions like 'January 21, 2005'. %B is month, %d is day number, %Y is year with century. 
+        # Run the command 'man strftime' to read more about these and other available specifiers.
+        expression = time.strftime(_("%B %d, %Y"), timevalue)
+    return unicode(expression, encoding, 'ignore')
 
 def lc_time (hour,minute,second = None):
-	hour = "%02d" % int(hour)
-	minute = "%02d" % int(minute)
-	if second == None:
-		timevalue = time.strptime(("%s:%s" % (hour, minute)), "%H:%M")
-		# Translators: Time without seconds. %H is hour, %M is minute. 
-		# Run the command 'man strftime' to read more about these and other available specifiers.
-		expression = time.strftime(_("%H:%M"), timevalue)
-	else:
-		second = "%02d" % int(second)
-		timevalue = time.strptime(("%s:%s:%s" % (hour, minute, second)), "%H:%M:%S")
-		expression = time.strftime("%X", timevalue)
-	return unicode(expression, encoding, 'ignore')
+    hour = "%02d" % int(hour)
+    minute = "%02d" % int(minute)
+    if second == None:
+        timevalue = time.strptime(("%s:%s" % (hour, minute)), "%H:%M")
+        # Translators: Time without seconds. %H is hour, %M is minute. 
+        # Run the command 'man strftime' to read more about these and other available specifiers.
+        expression = time.strftime(_("%H:%M"), timevalue)
+    else:
+        second = "%02d" % int(second)
+        timevalue = time.strptime(("%s:%s:%s" % (hour, minute, second)), "%H:%M:%S")
+        expression = time.strftime("%X", timevalue)
+    return unicode(expression, encoding, 'ignore')
 
 
 # So this is for the really really hard languages that have changing
@@ -133,162 +133,162 @@
 # language. If you need assistance, read the AUTHORS file and try to
 # contact us or use the mailinglists.
 def translate_crontab_easy (minute, hour, day, month, weekday):
-#	Add support for your language here
-#	if language.find ("whatever") != -1:
-#		return translate_crontab_easy_whatever (minute, hour, day, month, weekday)
-#	else:	
-		return translate_crontab_easy_common (minute, hour, day, month, weekday)
+#   Add support for your language here
+#   if language.find ("whatever") != -1:
+#       return translate_crontab_easy_whatever (minute, hour, day, month, weekday)
+#   else:   
+        return translate_crontab_easy_common (minute, hour, day, month, weekday)
 
 # Translate Crontab expressions to human readable ones.
 # Don't touch this function. Copy and modify it to create a special translation.
 # Changes on this function affects all translations made through po files.  
 def translate_crontab_easy_common (minute, hour, day, month, weekday):
 
-	# reboot
-	if minute == "@reboot":
-		return _("At reboot")
-		
-	# These are unsupported cases
-	if minute.find ("/") != -1 or hour.find ("/") != -1 or day.find ("/") != -1 or month.find ("/") != -1 or weekday.find ("/") != -1:
-		return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
-	if minute.find ("-") != -1 or hour.find ("-") != -1 or day.find ("-") != -1 or month.find ("-") != -1 or weekday.find ("-") != -1:
-		return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
-	if minute.find (",") != -1 or hour.find (",") != -1 or day.find (",") != -1 or month.find (",") != -1 or weekday.find (",") != -1:
-		return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
-		
-	# So if our case is supported:
-
-	# Minute and hour cases
-	if month == "*" and day == "*" and weekday == "*":
-		if minute == "0" and hour == "*":
-			return _("At every full hour")
-		elif minute == "*" and hour == "*":
-			return _("At every minute")
-		elif minute != "*" and hour == "*":
-			return (_("At minute %(minute)s of every hour") % { "minute": str(minute) } )
-		elif minute == "*" and hour != "*":
-			return (_("At every minute between %(time_from)s and %(time_to)s") % { "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
-		elif hour != "*" and minute != "*":
-			return (_("On every day at %(time)s") % { "time": lc_time(hour, minute) } )
-
-	# Day cases
-	if month == "*" and day != "*" and weekday == "*":
-		if minute == "0" and hour == "*":
-			return (_("On day %(monthday)s of every month at every full hour") % { "monthday": str(day) } )
-		elif minute == "*" and hour == "*":
-			return (_("On day %(monthday)s of every month at every minute") % { "monthday": str(day) } )
-		elif minute != "*" and hour == "*":
-			return (_("On day %(monthday)s of every month at minute %(minute)s of every hour") % { "monthday": str(day), "minute": str(minute) } )
-		elif minute == "*" and hour != "*":
-			return (_("On day %(monthday)s of every month at every minute between %(time_from)s and %(time_to)s") % { "monthday": str(day), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
-		elif minute != "*" and hour != "*":
-			return (_("On day %(monthday)s of every month at %(time)s") % { "monthday": str(day), "time": lc_time(hour, minute) } )
-
-	# Month cases
-	if month != "*" and weekday == "*" and day == "*":
-		if minute == "0" and hour == "*":
-			return (_("On every day in %(month)s at every full hour") % { "month": lc_month(month) } )
-		elif minute == "*" and hour == "*":
-			return (_("On every day in %(month)s at every minute") % { "month": lc_month(month) } )
-		elif minute != "*" and hour == "*":
-			return (_("On every day in %(month)s at minute %(minute)s of every hour") % { "month": lc_month(month), "minute": str(minute) } )
-		elif minute == "*" and hour != "*":
-			return (_("On every day in %(month)s at every minute between %(time_from)s and %(time_to)s") % { "month": lc_month(month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
-		elif minute != "*" and hour != "*":
-			return (_("On every day in %(month)s at %(time)s") % { "month": lc_month(month), "time": lc_time(hour, minute) } )
-
-	# Day and month cases
-	if month != "*" and weekday == "*" and day != "*":
-		if minute == "0" and hour == "*":
-			return (_("Every year on %(date)s at every full hour") % { "date": lc_date(day,month) } )
-		elif minute == "*" and hour == "*":
-			return (_("Every year on %(date)s at every minute") % { "date": lc_date(day,month) } )
-		elif minute != "*" and hour == "*":
-			return (_("Every year on %(date)s at minute %(minute)s of every hour") % { "date": lc_date(day,month), "minute": str(minute) } )
-		elif minute == "*" and hour != "*":
-			return (_("Every year on %(date)s at every minute between %(time_from)s and %(time_to)s") % { "date": lc_date(day,month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
-		elif minute != "*" and hour != "*":
-			return (_("Every year on %(date)s at %(time)s") % { "date": lc_date(day,month), "time": lc_time(hour, minute) } )
-
-	# Weekday cases
-	if month == "*" and day == "*" and weekday != "*":
-		if minute == "0" and hour == "*":
-			return (_("On every weekday: %(weekday)s at every full hour") % { "weekday": lc_weekday(weekday) } )
-		elif minute == "*" and hour == "*":
-			return (_("On every weekday: %(weekday)s at every minute") % { "weekday": lc_weekday(weekday) } )
-		elif minute != "*" and hour == "*":
-			return (_("On every weekday: %(weekday)s at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "minute": str(minute) } )
-		elif minute == "*" and hour != "*":
-			return (_("On every weekday: %(weekday)s at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
-		elif minute != "*" and hour != "*":
-			return (_("On every weekday: %(weekday)s at %(time)s") % { "weekday": lc_weekday(weekday), "time": lc_time(hour, minute) } )
-
-	# Day and weekday cases
-	if day != "*" and month == "*" and weekday != "*":
-		if minute == "0" and hour == "*":
-			return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every full hour") % { "monthday": str(day), "weekday": lc_weekday(weekday) } )
-		elif minute == "*" and hour == "*":
-			return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every minute") % { "monthday": str(day), "weekday": lc_weekday(weekday) } )
-		elif minute != "*" and hour == "*":
-			return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at minute %(minute)s of every hour") % { "monthday": str(day), "weekday": lc_weekday(weekday), "minute": str(minute) } )
-		elif minute == "*" and hour != "*":
-			return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every minute between %(time_from)s and %(time_to)s") % { "monthday": str(day), "weekday": lc_weekday(weekday), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
-		elif minute != "*" and hour != "*":
-			return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at %(time)s") % { "monthday": str(day), "weekday": lc_weekday(weekday), "time": lc_time(hour, minute) } )
-
-	# Month and weekday cases
-	if day == "*" and month != "*" and weekday != "*":
-		if minute == "0" and hour == "*":
-			return (_("On every weekday: %(weekday)s in %(month)s at every full hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month) } )
-		elif minute == "*" and hour == "*":
-			return (_("On every weekday: %(weekday)s in %(month)s at every minute") % { "weekday": lc_weekday(weekday), "month": lc_month(month) } )
-		elif minute != "*" and hour == "*":
-			return (_("On every weekday: %(weekday)s in %(month)s at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "minute": str(minute) } )
-		elif minute == "*" and hour != "*":
-			return (_("On every weekday: %(weekday)s in %(month)s at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
-		elif minute != "*" and hour != "*":
-			return (_("On every weekday: %(weekday)s in %(month)s at %(time)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "time": lc_time(hour, minute) } )
-
-	# Day, month and weekday cases
-	if day != "*" and month != "*" and weekday != "*":
-		if minute == "0" and hour == "*":
-			return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every full hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month) } )
-		elif minute == "*" and hour == "*":
-			return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every minute") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month) } )
-		elif minute != "*" and hour == "*":
-			return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "minute": str(minute) } )
-		elif minute == "*" and hour != "*":
-			return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
-		elif minute != "*" and hour != "*":
-			return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at %(time)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "time": lc_time(hour, minute) } )
+    # reboot
+    if minute == "@reboot":
+        return _("At reboot")
+        
+    # These are unsupported cases
+    if minute.find ("/") != -1 or hour.find ("/") != -1 or day.find ("/") != -1 or month.find ("/") != -1 or weekday.find ("/") != -1:
+        return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
+    if minute.find ("-") != -1 or hour.find ("-") != -1 or day.find ("-") != -1 or month.find ("-") != -1 or weekday.find ("-") != -1:
+        return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
+    if minute.find (",") != -1 or hour.find (",") != -1 or day.find (",") != -1 or month.find (",") != -1 or weekday.find (",") != -1:
+        return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
+        
+    # So if our case is supported:
+
+    # Minute and hour cases
+    if month == "*" and day == "*" and weekday == "*":
+        if minute == "0" and hour == "*":
+            return _("At every full hour")
+        elif minute == "*" and hour == "*":
+            return _("At every minute")
+        elif minute != "*" and hour == "*":
+            return (_("At minute %(minute)s of every hour") % { "minute": str(minute) } )
+        elif minute == "*" and hour != "*":
+            return (_("At every minute between %(time_from)s and %(time_to)s") % { "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+        elif hour != "*" and minute != "*":
+            return (_("On every day at %(time)s") % { "time": lc_time(hour, minute) } )
+
+    # Day cases
+    if month == "*" and day != "*" and weekday == "*":
+        if minute == "0" and hour == "*":
+            return (_("On day %(monthday)s of every month at every full hour") % { "monthday": str(day) } )
+        elif minute == "*" and hour == "*":
+            return (_("On day %(monthday)s of every month at every minute") % { "monthday": str(day) } )
+        elif minute != "*" and hour == "*":
+            return (_("On day %(monthday)s of every month at minute %(minute)s of every hour") % { "monthday": str(day), "minute": str(minute) } )
+        elif minute == "*" and hour != "*":
+            return (_("On day %(monthday)s of every month at every minute between %(time_from)s and %(time_to)s") % { "monthday": str(day), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+        elif minute != "*" and hour != "*":
+            return (_("On day %(monthday)s of every month at %(time)s") % { "monthday": str(day), "time": lc_time(hour, minute) } )
+
+    # Month cases
+    if month != "*" and weekday == "*" and day == "*":
+        if minute == "0" and hour == "*":
+            return (_("On every day in %(month)s at every full hour") % { "month": lc_month(month) } )
+        elif minute == "*" and hour == "*":
+            return (_("On every day in %(month)s at every minute") % { "month": lc_month(month) } )
+        elif minute != "*" and hour == "*":
+            return (_("On every day in %(month)s at minute %(minute)s of every hour") % { "month": lc_month(month), "minute": str(minute) } )
+        elif minute == "*" and hour != "*":
+            return (_("On every day in %(month)s at every minute between %(time_from)s and %(time_to)s") % { "month": lc_month(month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+        elif minute != "*" and hour != "*":
+            return (_("On every day in %(month)s at %(time)s") % { "month": lc_month(month), "time": lc_time(hour, minute) } )
+
+    # Day and month cases
+    if month != "*" and weekday == "*" and day != "*":
+        if minute == "0" and hour == "*":
+            return (_("Every year on %(date)s at every full hour") % { "date": lc_date(day,month) } )
+        elif minute == "*" and hour == "*":
+            return (_("Every year on %(date)s at every minute") % { "date": lc_date(day,month) } )
+        elif minute != "*" and hour == "*":
+            return (_("Every year on %(date)s at minute %(minute)s of every hour") % { "date": lc_date(day,month), "minute": str(minute) } )
+        elif minute == "*" and hour != "*":
+            return (_("Every year on %(date)s at every minute between %(time_from)s and %(time_to)s") % { "date": lc_date(day,month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+        elif minute != "*" and hour != "*":
+            return (_("Every year on %(date)s at %(time)s") % { "date": lc_date(day,month), "time": lc_time(hour, minute) } )
+
+    # Weekday cases
+    if month == "*" and day == "*" and weekday != "*":
+        if minute == "0" and hour == "*":
+            return (_("On every weekday: %(weekday)s at every full hour") % { "weekday": lc_weekday(weekday) } )
+        elif minute == "*" and hour == "*":
+            return (_("On every weekday: %(weekday)s at every minute") % { "weekday": lc_weekday(weekday) } )
+        elif minute != "*" and hour == "*":
+            return (_("On every weekday: %(weekday)s at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "minute": str(minute) } )
+        elif minute == "*" and hour != "*":
+            return (_("On every weekday: %(weekday)s at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+        elif minute != "*" and hour != "*":
+            return (_("On every weekday: %(weekday)s at %(time)s") % { "weekday": lc_weekday(weekday), "time": lc_time(hour, minute) } )
+
+    # Day and weekday cases
+    if day != "*" and month == "*" and weekday != "*":
+        if minute == "0" and hour == "*":
+            return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every full hour") % { "monthday": str(day), "weekday": lc_weekday(weekday) } )
+        elif minute == "*" and hour == "*":
+            return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every minute") % { "monthday": str(day), "weekday": lc_weekday(weekday) } )
+        elif minute != "*" and hour == "*":
+            return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at minute %(minute)s of every hour") % { "monthday": str(day), "weekday": lc_weekday(weekday), "minute": str(minute) } )
+        elif minute == "*" and hour != "*":
+            return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at every minute between %(time_from)s and %(time_to)s") % { "monthday": str(day), "weekday": lc_weekday(weekday), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+        elif minute != "*" and hour != "*":
+            return (_("On day %(monthday)s of every month and every weekday: %(weekday)s at %(time)s") % { "monthday": str(day), "weekday": lc_weekday(weekday), "time": lc_time(hour, minute) } )
+
+    # Month and weekday cases
+    if day == "*" and month != "*" and weekday != "*":
+        if minute == "0" and hour == "*":
+            return (_("On every weekday: %(weekday)s in %(month)s at every full hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month) } )
+        elif minute == "*" and hour == "*":
+            return (_("On every weekday: %(weekday)s in %(month)s at every minute") % { "weekday": lc_weekday(weekday), "month": lc_month(month) } )
+        elif minute != "*" and hour == "*":
+            return (_("On every weekday: %(weekday)s in %(month)s at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "minute": str(minute) } )
+        elif minute == "*" and hour != "*":
+            return (_("On every weekday: %(weekday)s in %(month)s at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+        elif minute != "*" and hour != "*":
+            return (_("On every weekday: %(weekday)s in %(month)s at %(time)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "time": lc_time(hour, minute) } )
+
+    # Day, month and weekday cases
+    if day != "*" and month != "*" and weekday != "*":
+        if minute == "0" and hour == "*":
+            return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every full hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month) } )
+        elif minute == "*" and hour == "*":
+            return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every minute") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month) } )
+        elif minute != "*" and hour == "*":
+            return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at minute %(minute)s of every hour") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "minute": str(minute) } )
+        elif minute == "*" and hour != "*":
+            return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at every minute between %(time_from)s and %(time_to)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "time_from": lc_time(hour, 0), "time_to": lc_time(hour, 59) } )
+        elif minute != "*" and hour != "*":
+            return (_("On every weekday: %(weekday)s in %(month)s and on %(date)s every year at %(time)s") % { "weekday": lc_weekday(weekday), "month": lc_month(month), "date": lc_date(day,month), "time": lc_time(hour, minute) } )
 
-	# If nothing got translated, we fall back to ...
-	return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
+    # If nothing got translated, we fall back to ...
+    return translate_crontab_easy_fallback (minute, hour, day, month, weekday)
 
 # This is for cases that don't be covered by translate_crontab_easy
 def translate_crontab_easy_fallback (minute, hour, day, month, weekday):
-	if minute == "*":
-		minute = _("every minute")
-	else:
-		minute = _("minute: %s") % (minute)
-
-	if hour == "*":
-		hour = _("every hour")
-	else:
-		hour = _("hour: %s") % (hour)
-
-	if day == "*":
-		day = _("every day of month")
-	else:
-		day = _("day of month: %s") % (day)
-
-	if month == "*":
-		month = _("every month")
-	else:
-		month = _("month: %s") % (month)
-
-	if weekday == "*":
-		return _("At %(minute)s, %(hour)s, %(monthday)s, %(month)s") % { "minute": minute, "hour": hour, "monthday": day, "month": month }
-	else:
-		weekday = _("weekday: %s") % (weekday)
-		return _("At %(minute)s, %(hour)s, %(monthday)s, %(month)s, %(weekday)s") % { "minute": minute, "hour": hour, "monthday": day, "month": month, "weekday": weekday }
+    if minute == "*":
+        minute = _("every minute")
+    else:
+        minute = _("minute: %s") % (minute)
+
+    if hour == "*":
+        hour = _("every hour")
+    else:
+        hour = _("hour: %s") % (hour)
+
+    if day == "*":
+        day = _("every day of month")
+    else:
+        day = _("day of month: %s") % (day)
+
+    if month == "*":
+        month = _("every month")
+    else:
+        month = _("month: %s") % (month)
+
+    if weekday == "*":
+        return _("At %(minute)s, %(hour)s, %(monthday)s, %(month)s") % { "minute": minute, "hour": hour, "monthday": day, "month": month }
+    else:
+        weekday = _("weekday: %s") % (weekday)
+        return _("At %(minute)s, %(hour)s, %(monthday)s, %(month)s, %(weekday)s") % { "minute": minute, "hour": hour, "monthday": day, "month": month, "weekday": weekday }

Modified: trunk/src/mainWindow.py
==============================================================================
--- trunk/src/mainWindow.py	(original)
+++ trunk/src/mainWindow.py	Sat Feb 14 21:20:56 2009
@@ -22,7 +22,7 @@
 import gtk.glade
 import gobject
 
-# TODO: gnome specific
+# gnome specific
 import gnome
 from gnome import url_show
 
@@ -52,732 +52,740 @@
 ## The MainWindow class
 ##
 class main:
-	def __init__(self, debug_flag=None, inapplet=False, gprogram = None, manual_poscorrect=False):
-		self.debug_flag = debug_flag
-		self.inapplet = inapplet
-		self.gprogram = gprogram
-		self.manual_poscorrect = manual_poscorrect
-		
-		self.__loadIcon__()
-		self.__loadGlade__()
-		
-		self.editor = None
-		self.schedule = None
-		
-		self.noevents = False
-					
-		#start the backend where all the user configuration is stored
-		self.backend = data.ConfigBackend(self, "gconf")
-		self.template = template.Template (self, self.backend)
-		
-		
-		##configure the window
-		self.widget = self.xml.get_widget("mainWindow")
-
-		self.widget.connect("delete_event", self.__quit__)
-		self.widget.connect("destroy_event", self.__quit__)
-		
-		self.widget.set_icon(self.iconPixbuf)
-		
-		#load state
-		(x, y, h, w) = self.backend.get_window_state ()
-		if (x and y):
-	 		self.widget.move (x, y)
-	 	if (h and w):
-	 		self.widget.resize (h, w)
-
-		self.widget.set_resizable (True)
-
-		##		
-
-
-		##configure statusbar
-		self.statusbar = self.xml.get_widget("statusbar")
-		
-		self.statusbarUser = self.statusbar.get_context_id("user")
-		##
-		
-		##configure the toolbar	
-		self.toolbar = self.xml.get_widget ("toolbar")
-		self.add_button = gtk.MenuToolButton (gtk.STOCK_NEW)
-		
-		self.add_button_menu = gtk.Menu ()
-		self.add_button_menu_add_crontab = gtk.MenuItem ()
-		self.add_button_menu_add_at = gtk.MenuItem ()
-		self.add_button_menu_add_template = gtk.MenuItem ()
-
-		self.recurrenthbox = gtk.HBox ()
-		icon = gtk.Image ()
-		icon.set_from_pixbuf (self.iconcrontab)
-		label = gtk.Label (_("Recurrent task"))
-		icon.set_alignment (0, 0.5)
-		label.set_justify (gtk.JUSTIFY_LEFT)
-		label.set_alignment (0, 0.5)
-		self.recurrenthbox.pack_start (icon, False, False, 2)
-		self.recurrenthbox.pack_start (label, True, True, 2)
-		self.add_button_menu_add_crontab.add (self.recurrenthbox)
-		
-		self.onetimehbox = gtk.HBox ()
-		icon = gtk.Image ()
-		icon.set_from_pixbuf (self.iconat)
-		label = gtk.Label (_("One-time task"))
-		icon.set_alignment (0, 0.5)
-		label.set_justify (gtk.JUSTIFY_LEFT)
-		label.set_alignment (0, 0.5)
-		self.onetimehbox.pack_start (icon, False, False, 2)
-		self.onetimehbox.pack_start (label, True, True, 2)
-		self.add_button_menu_add_at.add (self.onetimehbox)
-		
-		self.templatehbox = gtk.HBox ()
-		icon = gtk.Image ()
-		icon.set_from_pixbuf (self.icontemplate)
-		label = gtk.Label (_("From template"))
-		icon.set_alignment (0, 0.5)
-		label.set_justify (gtk.JUSTIFY_LEFT)
-		label.set_alignment (0, 0.5)
-		self.templatehbox.pack_start (icon, False, False, 2)
-		self.templatehbox.pack_start (label, True, True, 2)
-		self.add_button_menu_add_template.add (self.templatehbox)
-		
-		self.add_button_menu.append (self.add_button_menu_add_crontab)
-		self.add_button_menu.append (self.add_button_menu_add_at)
-		self.add_button_menu.append (self.add_button_menu_add_template)
-		
-		self.add_button.set_menu (self.add_button_menu)
-
-		self.toolbar.insert (self.add_button, 0)
-		self.add_button.set_is_important (True)
-		tip = gtk.Tooltips ()
-		tip.enable ()
-		
-		self.add_button.set_tooltip (tip, _("Add a new task"), tip_private=None)
-		self.add_button.show_all ()
-		self.add_button_menu.show_all ()
-		self.add_button_menu_add_crontab.show_all ()
-		self.add_button_menu_add_at.show_all ()
-
-		self.add_button.connect ("clicked", self.on_add_button_clicked)
-		self.add_button_menu_add_crontab.connect ("activate", self.on_add_crontab_task)
-		self.add_button_menu_add_at.connect ("activate", self.on_add_at_task)
-		self.add_button_menu_add_template.connect ("activate", self.on_add_from_template)
-
-		
-		self.prop_button = self.xml.get_widget ("prop_button")
-		self.del_button = self.xml.get_widget ("del_button")
-		self.run_button = self.xml.get_widget ("run_button")
-		self.help_button = self.xml.get_widget ("help_button")
-		self.btnSetUser = self.xml.get_widget("btnSetUser")
-		self.btnExit = self.xml.get_widget("btnExit")
-		self.about_button = self.xml.get_widget ("about_button")
-		self.edit_mode_button = self.xml.get_widget ("edit_mode_button")
-		self.button_template = self.xml.get_widget ("button_m_template")
-
-		icon = gtk.Image()
-		icon.set_from_pixbuf (self.normalicontemplate)
-		self.button_template.set_icon_widget (icon)
-		icon.show ()
-
-		self.prop_button.set_sensitive (False)
-		self.del_button.set_sensitive (False)
-		self.run_button.set_sensitive (False)
-	
-		self.xml.signal_connect("on_prop_button_clicked", self.on_prop_button_clicked)
-		self.xml.signal_connect("on_del_button_clicked", self.on_del_button_clicked)
-		self.xml.signal_connect("on_help_button_clicked", self.on_help_button_clicked)
-		self.xml.signal_connect("on_btnSetUser_clicked", self.on_btnSetUser_clicked)
-		self.xml.signal_connect("on_about_menu_activate", self.on_about_menu_activate)
-		self.xml.signal_connect("on_edit_mode_button_clicked", self.on_advanced_menu_activate)
-		self.xml.signal_connect("on_btnExit_clicked", self.__quit__)
-		self.xml.signal_connect("on_mainWindow_delete_event", self.__quit__)
-		self.xml.signal_connect("on_run_button_clicked", self.on_run_button_clicked)
-		
-		self.xml.signal_connect ("on_button_m_template_clicked", self.on_template_manager_button)
-				
-		##inittializing the treeview and treemodel
-		## somethins not rite here..:
-		## [0 Title, 1 Frequency, 2 Command, 3 Crontab record, 4 ID, 5 Time, 6 Icon, 7 scheduled instance, 8 icon path, 9 date, 10 class_id, 11 user, 12 time, 13 type, 14 crontab/at, 15 advanced time string]
-		##for at this would be like: 
-		
+    def __init__(self, debug_flag=None, inapplet=False, gprogram = None, manual_poscorrect=False):
+        self.debug_flag = debug_flag
+        self.inapplet = inapplet
+        self.gprogram = gprogram
+        self.manual_poscorrect = manual_poscorrect
+        
+        self.__loadIcon__()
+        self.__loadGlade__()
+        
+        self.editor = None
+        self.schedule = None
+        
+        self.noevents = False
+                    
+        # Common string representation for the different output modes
+        self.output_strings = [
+                                _("Default behaviour"),
+                                _("Supress output"), 
+                                _("X application"), 
+                                _("X application: supress output"),
+                        ]
+
+        #start the backend where all the user configuration is stored
+        self.backend = data.ConfigBackend(self, "gconf")
+        self.template = template.Template (self, self.backend)
+        
+        
+        ##configure the window
+        self.widget = self.xml.get_widget("mainWindow")
+
+        self.widget.connect("delete_event", self.__quit__)
+        self.widget.connect("destroy_event", self.__quit__)
+        
+        self.widget.set_icon(self.iconPixbuf)
+        
+        #load state
+        (x, y, h, w) = self.backend.get_window_state ()
+        if (x and y):
+            self.widget.move (x, y)
+        if (h and w):
+            self.widget.resize (h, w)
+
+        self.widget.set_resizable (True)
+
+        ##      
+
+
+        ##configure statusbar
+        self.statusbar = self.xml.get_widget("statusbar")
+        
+        self.statusbarUser = self.statusbar.get_context_id("user")
+        ##
+        
+        ##configure the toolbar 
+        self.toolbar = self.xml.get_widget ("toolbar")
+        self.add_button = gtk.MenuToolButton (gtk.STOCK_NEW)
+        
+        self.add_button_menu = gtk.Menu ()
+        self.add_button_menu_add_crontab = gtk.MenuItem ()
+        self.add_button_menu_add_at = gtk.MenuItem ()
+        self.add_button_menu_add_template = gtk.MenuItem ()
+
+        self.recurrenthbox = gtk.HBox ()
+        icon = gtk.Image ()
+        icon.set_from_pixbuf (self.iconcrontab)
+        label = gtk.Label (_("Recurrent task"))
+        icon.set_alignment (0, 0.5)
+        label.set_justify (gtk.JUSTIFY_LEFT)
+        label.set_alignment (0, 0.5)
+        self.recurrenthbox.pack_start (icon, False, False, 2)
+        self.recurrenthbox.pack_start (label, True, True, 2)
+        self.add_button_menu_add_crontab.add (self.recurrenthbox)
+        
+        self.onetimehbox = gtk.HBox ()
+        icon = gtk.Image ()
+        icon.set_from_pixbuf (self.iconat)
+        label = gtk.Label (_("One-time task"))
+        icon.set_alignment (0, 0.5)
+        label.set_justify (gtk.JUSTIFY_LEFT)
+        label.set_alignment (0, 0.5)
+        self.onetimehbox.pack_start (icon, False, False, 2)
+        self.onetimehbox.pack_start (label, True, True, 2)
+        self.add_button_menu_add_at.add (self.onetimehbox)
+        
+        self.templatehbox = gtk.HBox ()
+        icon = gtk.Image ()
+        icon.set_from_pixbuf (self.icontemplate)
+        label = gtk.Label (_("From template"))
+        icon.set_alignment (0, 0.5)
+        label.set_justify (gtk.JUSTIFY_LEFT)
+        label.set_alignment (0, 0.5)
+        self.templatehbox.pack_start (icon, False, False, 2)
+        self.templatehbox.pack_start (label, True, True, 2)
+        self.add_button_menu_add_template.add (self.templatehbox)
+        
+        self.add_button_menu.append (self.add_button_menu_add_crontab)
+        self.add_button_menu.append (self.add_button_menu_add_at)
+        self.add_button_menu.append (self.add_button_menu_add_template)
+        
+        self.add_button.set_menu (self.add_button_menu)
+
+        self.toolbar.insert (self.add_button, 0)
+        self.add_button.set_is_important (True)
+        tip = gtk.Tooltips ()
+        tip.enable ()
+        
+        self.add_button.set_tooltip (tip, _("Add a new task"), tip_private=None)
+        self.add_button.show_all ()
+        self.add_button_menu.show_all ()
+        self.add_button_menu_add_crontab.show_all ()
+        self.add_button_menu_add_at.show_all ()
+
+        self.add_button.connect ("clicked", self.on_add_button_clicked)
+        self.add_button_menu_add_crontab.connect ("activate", self.on_add_crontab_task)
+        self.add_button_menu_add_at.connect ("activate", self.on_add_at_task)
+        self.add_button_menu_add_template.connect ("activate", self.on_add_from_template)
+
+        
+        self.prop_button = self.xml.get_widget ("prop_button")
+        self.del_button = self.xml.get_widget ("del_button")
+        self.run_button = self.xml.get_widget ("run_button")
+        self.help_button = self.xml.get_widget ("help_button")
+        self.btnSetUser = self.xml.get_widget("btnSetUser")
+        self.btnExit = self.xml.get_widget("btnExit")
+        self.about_button = self.xml.get_widget ("about_button")
+        self.edit_mode_button = self.xml.get_widget ("edit_mode_button")
+        self.button_template = self.xml.get_widget ("button_m_template")
+
+        icon = gtk.Image ()
+        icon.set_from_pixbuf (self.normalicontemplate)
+        self.button_template.set_icon_widget (icon)
+        icon.show ()
+
+        self.prop_button.set_sensitive (False)
+        self.del_button.set_sensitive (False)
+        self.run_button.set_sensitive (False)
+
+        self.xml.signal_connect("on_prop_button_clicked", self.on_prop_button_clicked)
+        self.xml.signal_connect("on_del_button_clicked", self.on_del_button_clicked)
+        self.xml.signal_connect("on_help_button_clicked", self.on_help_button_clicked)
+        self.xml.signal_connect("on_btnSetUser_clicked", self.on_btnSetUser_clicked)
+        self.xml.signal_connect("on_about_menu_activate", self.on_about_menu_activate)
+        self.xml.signal_connect("on_edit_mode_button_clicked", self.on_advanced_menu_activate)
+        self.xml.signal_connect("on_btnExit_clicked", self.__quit__)
+        self.xml.signal_connect("on_mainWindow_delete_event", self.__quit__)
+        self.xml.signal_connect("on_run_button_clicked", self.on_run_button_clicked)
+        
+        self.xml.signal_connect ("on_button_m_template_clicked", self.on_template_manager_button)
+                
+        ##inittializing the treeview and treemodel
+        ## somethins not rite here..:
+        ## [0 Title, 1 Frequency, 2 Command, 3 Crontab record, 4 ID, 5 Time, 6 Icon, 7 scheduled instance, 8 icon path, 9 date, 10 class_id, 11 user, 12 time, 13 type, 14 crontab/at, 15 advanced time string]
+        ##for at this would be like: 
+        
 # ["untitled", "12:50 2004-06-25", "preview", "script", "job_id", "12:50", icon, at instance, icon_path, "2004-06-25", "a", "drzap", "at"]
 
-		##for crontab it would be: 
-		
+        ##for crontab it would be: 
+        
 # ["untitled", "every hour", "ls /", "0 * * * * ls / # untitled", "5", "0 * * * *", icon, crontab instance,icon_path, 1(job_id), "", "", "crontab"]
-		self.treemodel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING, gtk.gdk.Pixbuf, gobject.TYPE_PYOBJECT, gobject.TYPE_STRING , gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING)
-		
-		self.treeview = self.xml.get_widget("treeview")
-		
-		self.xml.signal_connect("on_treeview_button_press_event", self.on_treeview_button_press_event)
-		self.xml.signal_connect("on_treeview_key_press_event", self.on_treeview_key_pressed)
-		
-		self.treeview.set_model (self.treemodel)
-		self.treeview.get_selection().connect("changed", self.on_TreeViewSelectRow)
-
-		#enable or disable advanced depending on user config
-		self.noevents = True
-		if self.backend.get_advanced_option():
-			self.switchView("advanced")
-			self.edit_mode_button.set_active (True)
-		else:
-			self.switchView("simple")
-			self.edit_mode_button.set_active (False)
-		self.noevents = False
-		
-		
-		self.__initUser__()
-		
-		##create crontab
-		self.crontab = crontab.Crontab(self.root, self.user, self.uid, self.gid, self.user_home_dir)
-		self.crontab_editor = crontabEditor.CrontabEditor(self, self.backend, self.crontab, self.template)
-		##
-		
-		##create at
-		self.at = at.At(self.root, self.user, self.uid, self.gid, self.user_home_dir, self.manual_poscorrect)
-		self.at_editor = atEditor.AtEditor (self, self.backend, self.at, self.template)
-		##
-		
-		#set user window
-		self.setuserWindow = setuserWindow.SetuserWindow (self)
-		
-		#set add window
-		self.addWindow = addWindow.AddWindow (self)
-		
-		# template windows
-		self.template_chooser = template_chooser.TemplateChooser (self, self.template)
-		self.template_manager = template_manager.TemplateManager (self, self.template)
-
-		self.schedule_reload ()
-
-		self.timeout_handler_id = gobject.timeout_add(9000, self.update_schedule)
-
-		# temporary files to be deleted
-		self.temp_files = []
-		
-		if inapplet == False:
-			gtk.main()
-		
-	
-	def update_schedule(self):
-		selection = self.treeview.get_selection()
-		model, iter, = selection.get_selected()
-		if iter:
-			path = model.get_path(iter)
-		self.schedule_reload ()
-		if iter:
-			 selection.select_path(path)	
-		return True
-
-	def changeUser(self,user):
-		if user != self.user:
-			self.__setUser__(user)
-			#change user for the schedulers
-			self.crontab.set_rights(self.user, self.uid, self.gid, self.user_home_dir)
-			self.at.set_rights(self.user, self.uid, self.gid, self.user_home_dir)
-			#adjust statusbar
-			if self.root == 1:
-				self.statusbar.push(self.statusbarUser, (_("Editing user: %s") % (self.user)))
-		
-			self.schedule_reload ()
-	
-	
-	def __setUser__(self,user):
-		userdb = pwd.getpwnam(user)
-		self.user = user
-		self.uid = userdb[2]
-		self.gid = userdb[3]
-		self.user_home_dir = userdb[5]
-		self.user_shell = userdb[6]
-		
-						
-	## TODO: 2 times a loop looks to mutch
-	def schedule_reload (self):
-		self.treemodel.clear ()
-
-		data = self.crontab.read ()
-		if data != None:
-			self.__fill__ (data)
-			
-		data = self.at.read ()
-		if data != None:
-			self.__fill__ (data)
-						
-
-
-
-	def __fill__ (self, records):
-		for title, timestring_show, preview, lines, job_id, timestring, scheduler, icon, date, class_id, user, time, typetext, type, nooutput, timestring_advanced in records:
-					
-			if scheduler.get_type() == "crontab":
-				iter = self.treemodel.append([title, timestring_show, preview, lines, job_id, timestring, self.iconcrontab, scheduler, icon, date, class_id, user, time, typetext, type, nooutput, timestring_advanced])
-			elif scheduler.get_type() == "at":
-				iter = self.treemodel.append([title, timestring_show, preview, lines, job_id, timestring, self.iconat, scheduler, icon, date, class_id, user, time, typetext, type, nooutput, timestring_advanced])
-
-			
-		
-	def __loadIcon__(self):
-		if self.debug_flag:
-			if os.access("../icons/gnome-schedule.svg", os.F_OK):
-				self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/gnome-schedule.svg", 52, 52)
-		else:
-			try:
-				self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/gnome-schedule.svg", 52, 52)
-			except:
-				print _("ERROR: Could not load icon")
-
-		if self.debug_flag:
-			if os.access ("../icons/crontab.svg", os.F_OK):
-				self.iconcrontab = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/crontab.svg", 19, 19)
-				self.bigiconcrontab = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/crontab.svg", 49, 49)
-		else:
-			try:
-				self.iconcrontab = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/crontab.svg", 19, 19)
-				self.bigiconcrontab = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/crontab.svg", 49, 49)
-			except:
-				print _("ERROR: Could not load icon")		
-			
-		if self.debug_flag:				
-			if os.access ("../icons/calendar.svg", os.F_OK):
-				self.iconcalendar = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/calendar.svg", 19, 19)
-				self.bigiconcalendar = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/calendar.svg", 49, 49)
-		else:
-			try:
-				self.iconcalendar = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/calendar.svg", 19, 19)
-				self.bigiconcalendar = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/calendar.svg", 49, 49)
-			except:
-				print _("ERROR: Could not load icon")
-		
-		if self.debug_flag:		
-			if os.access ("../icons/template.svg", os.F_OK):
-				self.icontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 19, 19)
-				self.normalicontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 25, 25)
-				self.bigicontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 49, 49)
-				self.pathicontemplate = "../icons/template.svg"
-		else:
-			try:
-				self.icontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 19, 19)
-				self.normalicontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 25, 25)
-				self.bigicontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 49, 49)
-				self.pathicontemplate = config.getImagedir() + "/template.svg"
-			except:
-				print _("ERROR: Could not load icon")
-		
-		if self.debug_flag:		
-			if os.access ("../icons/at.svg", os.F_OK):
-				self.iconat = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/at.svg", 19, 19)
-				self.bigiconat = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/at.svg", 49, 49)
-		else:
-			try:
-				self.iconat = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/at.svg", 19, 19)
-				self.bigiconat = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/at.svg", 49, 49)
-			except:
-				print _("ERROR: Could not load icon")
-				
-		
-	def __loadGlade__(self):
-		if self.debug_flag:
-			if os.access("gnome-schedule.glade", os.F_OK):
-				try:
-					self.xml = gtk.glade.XML ("gnome-schedule.glade", domain="gnome-schedule")
-				except:
-					print _("ERROR: Could not load glade file")
-					quit ()
-		else:
-			try:
-				self.xml = gtk.glade.XML (config.getGladedir() + "/gnome-schedule.glade", domain="gnome-schedule")
-			except:
-				print _("ERROR: Could not load glade file")
-				quit ()
-
-	
-	
-	def __initUser__(self):
-		self.uid = os.geteuid() 
-		self.gid = os.getegid()
-		self.user = pwd.getpwuid(self.uid)[0]
-		self.user_home_dir = pwd.getpwuid(self.uid)[5]
-		self.user_shell = pwd.getpwuid(self.uid)[6]
-		
-		if self.uid != 0:
-			self.btnSetUser.hide()
-			self.statusbar.hide()	
-			self.root = 0
-		else:
-			self.root = 1
-			self.btnSetUser.show()
-			self.statusbar.show()
-			self.statusbar.push(self.statusbarUser, (_("Editing user: %s") % (self.user)))
-				
-
-	#when the user selects a task, buttons get enabled
-	def on_TreeViewSelectRow (self, *args):
-		if self.treeview.get_selection().count_selected_rows() > 0 :
-			value = True
-		else:
-			value = False
-			
-		self.prop_button.set_sensitive (value)
-		self.del_button.set_sensitive (value)
-		self.run_button.set_sensitive (value)
-
-		
-	
-	#clean existing columns
-	def __cleancolumns__ (self):
-		columns = len(self.treeview.get_columns()) -1
-		while columns > -1:
-			temp = self.treeview.get_column(columns)
-			self.treeview.remove_column(temp)
-			columns = columns - 1
-		 
-	
-	#switch between advanced and simple mode			
-	def switchView(self, mode = "simple"):
-		self.__cleancolumns__ ()
-		
-		self.treeview.get_selection().unselect_all()
-		self.edit_mode = mode
-		
-		cell = gtk.CellRendererPixbuf()
-		cell.set_fixed_size(21,21)
-		cell2 = gtk.CellRendererText ()	
-		col = gtk.TreeViewColumn (_("Task"), None)
-		col.pack_start (cell, True)
-		col.pack_end (cell2, True)
-		col.add_attribute (cell, "pixbuf", 6)
-		if mode == "simple":
-			col.add_attribute (cell2, "text", 13)
-		else:
-			col.add_attribute (cell2, "text", 14)
-			
-		self.treeview.append_column(col)
-		
-		if mode == "simple":
-			
-			col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=0)
-			col.set_resizable (True)
-			self.treeview.append_column(col)
-
-			col = gtk.TreeViewColumn(_("Date and Time"), gtk.CellRendererText(), text=1)
-			col.set_resizable (True)
-			self.treeview.append_column(col)
-
-			col = gtk.TreeViewColumn(_("Command preview"), gtk.CellRendererText(), text=2)
-			col.set_resizable (True)
-			col.set_expand (True)
-			self.treeview.append_column(col)
-
-
-
-		elif mode == "advanced":
-	
-			col = gtk.TreeViewColumn(_("Date and Time"), gtk.CellRendererText(), text=16)
-			col.set_resizable (True)
-			self.treeview.append_column(col)
-
-			col = gtk.TreeViewColumn(_("Command preview"), gtk.CellRendererText(), text=2)
-			col.set_resizable (True)
-			col.set_expand (True)
-			self.treeview.append_column(col)
-
-			col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=0)
-			col.set_resizable (True)
-			self.treeview.append_column(col)
-
-
-
-	def on_advanced_menu_activate (self, widget):
-		if self.noevents == False:
-			if self.backend.get_advanced_option():
-				self.backend.set_advanced_option(0)
-			else:
-				self.backend.set_advanced_option(1)
-
-	def on_add_at_task (self, *args):
-		self.addWindow.mode = 0
-		self.addWindow.on_button_at_clicked (*args)
-		
-	def on_add_crontab_task (self, *args):
-		self.addWindow.mode = 0
-		self.addWindow.on_button_crontab_clicked  (*args)
-	
-	def on_add_from_template (self, *args):
-		self.addWindow.mode = 0
-		self.addWindow.on_button_template_clicked  (*args)
-
-	def on_template_manager_button (self, *args):
-		self.template_manager.show (self.widget)
-		
-	def on_add_scheduled_task_menu_activate (self, *args):
-		self.addWindow.ShowAddWindow (self.widget)
-
-	def on_properties_menu_activate (self, *args):
-		store, iter = self.treeview.get_selection().get_selected()
-		
-		try:
-			#see what scheduler (at, crontab or ...)
-			self.schedule = self.treemodel.get_value(iter, 7)
-			
-			
-		
-			record = self.treemodel.get_value(iter, 3)
-			linenumber = self.treemodel.get_value(iter, 4)
-			
-			# TODO: dirty hacky 
-			if self.schedule.get_type() == "crontab":
-				self.editor = self.crontab_editor
-				job_id = self.treemodel.get_value (iter, 9)
-				self.editor.showedit (self.widget, record, job_id, linenumber, iter)
-			else:
-				self.editor = self.at_editor
-				self.editor.showedit (self.widget, record, linenumber, iter)
-
-		except Exception, ex:
-			#print ex
-			self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task"))
-			self.dialog.run ()
-			self.dialog.destroy ()			
-			
-
-	# TODO: looks not that clean (is broken)
-	def on_delete_menu_activate (self, *args):
-		dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("Do you want to delete this task?"))
-		if (dialog.run() != gtk.RESPONSE_YES):
-			dialog.destroy()
-			del dialog
-			return
-		dialog.destroy()
-		del dialog
-		
-		store, iter = self.treeview.get_selection().get_selected()
-	
-		try:
-			#see what scheduler (at, crontab or ...)
-			self.schedule = self.treemodel.get_value(iter, 7)
-			
-			# TODO: dirty hacky 
-			if self.schedule.get_type() == "crontab":
-				self.editor = self.crontab_editor
-			elif self.schedule.get_type() == "at":
-				self.editor = self.at_editor
-
-			record = self.treemodel.get_value(iter, 3)
-			linenumber = self.treemodel.get_value(iter, 4)
-
-			path = self.treemodel.get_path(iter)
-			pathint = path[0]
-			backpath = (pathint - 1,)
-			
-			if self.schedule.get_type() == "crontab":
-				self.schedule.delete (linenumber, iter, self.treemodel.get_value(iter, 9))
-			elif self.schedule.get_type() == "at":
-				self.schedule.delete (linenumber, iter)
-			
-			self.schedule_reload()
-			
-			firstiter = self.treemodel.get_iter_first()
-			try:
-				nextiter = self.treemodel.get_iter(path)
-				#go next
-				selection = self.treeview.get_selection()
-				selection.select_iter(nextiter)
-
-			except:
-				if backpath[0] > 0:
-					nextiter = self.treemodel.get_iter(backpath)
-					#go back
-					selection = self.treeview.get_selection()
-					selection.select_iter(nextiter)
-
-				else:
-					if firstiter:
-						#go first
-						selection = self.treeview.get_selection()
-						selection.select_iter(firstiter)
-						
-		except Exception, ex:
-			#print ex
-			self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task"))
-			self.dialog.run ()
-			self.dialog.destroy ()
-
-	def on_set_user_menu_activate(self, *args):
-		self.setuserWindow.ShowSetuserWindow()
-
-
-	def on_btnSetUser_clicked(self, *args):
-		self.on_set_user_menu_activate(self, args)
-			
-	def on_add_button_clicked (self, *args):
-		self.on_add_scheduled_task_menu_activate (self, args)
-
-	def on_prop_button_clicked (self, *args):
-		self.on_properties_menu_activate (self, args)
-
-	def on_del_button_clicked (self, *args):
-		self.on_delete_menu_activate (self, args)
-
-	def on_help_button_clicked (self, *args):
-		self.on_manual_menu_activate (self, args)
-
-
-	def on_treeview_key_pressed (self, widget, event):
-		key = gtk.gdk.keyval_name(event.keyval)
-		#remove task from list with DEL key
-		if key == "Delete" or key == "KP_Delete":
-			self.on_delete_menu_activate()
-		#display properties with ENTER key
-		if (key == "Return" or key == "KP_Return"):
- 			self.on_properties_menu_activate(self, widget)
-
-	
-	#double click on task to get properties
-	def on_treeview_button_press_event (self, widget, event):
-		if event.type == gtk.gdk._2BUTTON_PRESS:
-			self.on_properties_menu_activate(self, widget)
-
-
- 	#about box
- 	def open_url (self, *args):
- 		url_show("http://gnome-schedule.sourceforge.net";)
- 	
-
- 	
- 	def on_run_button_clicked (self, *args):
-		dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE, _("Are you sure you want to run this task now?\n\nThis is used to preview the task and initiates a one-time run, this does not affect the normal scheduled run times."))
-		dialog.add_buttons (gtk.STOCK_EXECUTE, gtk.RESPONSE_YES, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
-		dialog.set_title (_("Are you sure you want to run this task?"))
-		if (dialog.run() != gtk.RESPONSE_YES):
-			dialog.destroy()
-			del dialog
-			return
-		dialog.destroy()
-		del dialog
-		
-		if (self.backend.get_not_inform_working_dir() != True):
-			dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nRecurrent tasks will be run from the home directory, one-time tasks from the directory where Gnome schedule was run from at the time of task creation (normally the home directory)."))
-			dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
-			dia2.set_title (_("Warning: Working directory of executed tasks"))
-			response = dia2.run ()
-			if response == gtk.RESPONSE_CANCEL:
-				dia2.destroy ()
-				del dia2
-				return
-			elif response == gtk.RESPONSE_CLOSE:
-				self.backend.set_not_inform_working_dir (True)
-			else:
-				pass
-			dia2.destroy ()
-			del dia2
-		
-		store, iter = self.treeview.get_selection().get_selected()
-	
-		try:
-			# commands are at model[3]
-			
-			#see what scheduler (at, crontab or ...)		
-			self.schedule = self.treemodel.get_value(iter, 7)
-			
-			tmpfile = tempfile.mkstemp ()
-			fd, path = tmpfile
-			tmp = os.fdopen (fd, 'w')
-			
-			commands = self.treemodel.get_value(iter, 3)
-			linenumber = self.treemodel.get_value(iter, 4)
-			
-			
-			if self.schedule.get_type () == "at":
-				script = os.popen (config.getAtbin () + " -c " + str (linenumber)).read ()
-			elif self.schedule.get_type () == "crontab":
-				script = self.schedule.parse (commands)[1][5]
-			
-			# left untranslated to protect against any 'translation attacks'..
-			script = script + "\necho " + "Press ENTER to continue and close this window." + "\n"
-			script = script + "read\nexit\n"
-			tmp.write (script)
-			tmp.flush ()
-			self.temp_files.append ((tmp, path))
-			
-			
-			execute = self.user_shell + " " + path
-			
-			if self.root == 1:
-				if self.user != "root":
-					execute = "su " + self.user + " -c \"" + self.user_shell + " " + path
-					os.chown (path, self.uid, self.gid)
-			os.chmod (path, stat.S_IEXEC | stat.S_IREAD)
-			
-			
-			gnome.execute_terminal_shell (self.user_home_dir, execute)
-			
-			
-				
-		except Exception, ex:
-			print ex
-			self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task!"))
-			self.dialog.run ()
-			self.dialog.destroy ()
- 			
- 	def on_about_menu_activate (self, *args):
- 	
-		gtk.about_dialog_set_url_hook(self.open_url, "bogusbar")
-	 	dlg = gtk.AboutDialog ()
- 		dlg.set_title (_("About Gnome Schedule"))
- 		dlg.set_name (_("Gnome Schedule"))
- 		dlg.set_version (config.getVersion())
- 		dlg.set_copyright (_("Copyright (c) %(year)s %(name)s.") % ({ 'year' : "2004-2008", 'name' : "Gaute Hope"}))
- 		#dlg.set_comments ()
- 		#dlg.set_license ()
- 		dlg.set_website ("http://gnome-schedule.sourceforge.net";)
- 		dlg.set_website_label("http://gnome-schedule.sourceforge.net";)
- 		dlg.set_authors (
- 			["Gaute Hope <eg gaute vetsj com>",
+        self.treemodel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING, gtk.gdk.Pixbuf, gobject.TYPE_PYOBJECT, gobject.TYPE_STRING , gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_INT, gobject.TYPE_STRING)
+        
+        self.treeview = self.xml.get_widget("treeview")
+        
+        self.xml.signal_connect("on_treeview_button_press_event", self.on_treeview_button_press_event)
+        self.xml.signal_connect("on_treeview_key_press_event", self.on_treeview_key_pressed)
+        
+        self.treeview.set_model (self.treemodel)
+        self.treeview.get_selection().connect("changed", self.on_TreeViewSelectRow)
+
+        #enable or disable advanced depending on user config
+        self.noevents = True
+        if self.backend.get_advanced_option():
+            self.switchView("advanced")
+            self.edit_mode_button.set_active (True)
+        else:
+            self.switchView("simple")
+            self.edit_mode_button.set_active (False)
+        self.noevents = False
+        
+        
+        self.__initUser__()
+        
+        ##create crontab
+        self.crontab = crontab.Crontab(self.root, self.user, self.uid, self.gid, self.user_home_dir)
+        self.crontab_editor = crontabEditor.CrontabEditor(self, self.backend, self.crontab, self.template)
+        ##
+        
+        ##create at
+        self.at = at.At(self.root, self.user, self.uid, self.gid, self.user_home_dir, self.manual_poscorrect)
+        self.at_editor = atEditor.AtEditor (self, self.backend, self.at, self.template)
+        ##
+        
+        #set user window
+        self.setuserWindow = setuserWindow.SetuserWindow (self)
+        
+        #set add window
+        self.addWindow = addWindow.AddWindow (self)
+        
+        # template windows
+        self.template_chooser = template_chooser.TemplateChooser (self, self.template)
+        self.template_manager = template_manager.TemplateManager (self, self.template)
+
+        self.schedule_reload ()
+
+        self.timeout_handler_id = gobject.timeout_add(9000, self.update_schedule)
+
+        # temporary files to be deleted
+        self.temp_files = []
+        
+        if inapplet == False:
+            gtk.main()
+        
+    
+    def update_schedule(self):
+        selection = self.treeview.get_selection()
+        model, iter, = selection.get_selected()
+        if iter:
+            path = model.get_path(iter)
+        self.schedule_reload ()
+        if iter:
+             selection.select_path(path)    
+        return True
+
+    def changeUser(self,user):
+        if user != self.user:
+            self.__setUser__(user)
+            #change user for the schedulers
+            self.crontab.set_rights(self.user, self.uid, self.gid, self.user_home_dir)
+            self.at.set_rights(self.user, self.uid, self.gid, self.user_home_dir)
+            #adjust statusbar
+            if self.root == 1:
+                self.statusbar.push(self.statusbarUser, (_("Editing user: %s") % (self.user)))
+        
+            self.schedule_reload ()
+    
+    
+    def __setUser__(self,user):
+        userdb = pwd.getpwnam(user)
+        self.user = user
+        self.uid = userdb[2]
+        self.gid = userdb[3]
+        self.user_home_dir = userdb[5]
+        self.user_shell = userdb[6]
+        
+                        
+    ## TODO: 2 times a loop looks to mutch
+    def schedule_reload (self):
+        self.treemodel.clear ()
+
+        data = self.crontab.read ()
+        if data != None:
+            self.__fill__ (data)
+            
+        data = self.at.read ()
+        if data != None:
+            self.__fill__ (data)
+                        
+
+
+
+    def __fill__ (self, records):
+        for title, timestring_show, preview, lines, job_id, timestring, scheduler, icon, date, class_id, user, time, typetext, type, output, timestring_advanced in records:
+                    
+            if scheduler.get_type() == "crontab":
+                iter = self.treemodel.append([title, timestring_show, preview, lines, job_id, timestring, self.iconcrontab, scheduler, icon, date, class_id, user, time, typetext, type, output, timestring_advanced])
+            elif scheduler.get_type() == "at":
+                iter = self.treemodel.append([title, timestring_show, preview, lines, job_id, timestring, self.iconat, scheduler, icon, date, class_id, user, time, typetext, type, output, timestring_advanced])
+
+            
+        
+    def __loadIcon__(self):
+        if self.debug_flag:
+            if os.access("../icons/gnome-schedule.svg", os.F_OK):
+                self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/gnome-schedule.svg", 52, 52)
+        else:
+            try:
+                self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/gnome-schedule.svg", 52, 52)
+            except:
+                print _("ERROR: Could not load icon")
+
+        if self.debug_flag:
+            if os.access ("../icons/crontab.svg", os.F_OK):
+                self.iconcrontab = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/crontab.svg", 19, 19)
+                self.bigiconcrontab = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/crontab.svg", 49, 49)
+        else:
+            try:
+                self.iconcrontab = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/crontab.svg", 19, 19)
+                self.bigiconcrontab = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/crontab.svg", 49, 49)
+            except:
+                print _("ERROR: Could not load icon")       
+            
+        if self.debug_flag:             
+            if os.access ("../icons/calendar.svg", os.F_OK):
+                self.iconcalendar = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/calendar.svg", 19, 19)
+                self.bigiconcalendar = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/calendar.svg", 49, 49)
+        else:
+            try:
+                self.iconcalendar = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/calendar.svg", 19, 19)
+                self.bigiconcalendar = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/calendar.svg", 49, 49)
+            except:
+                print _("ERROR: Could not load icon")
+        
+        if self.debug_flag:     
+            if os.access ("../icons/template.svg", os.F_OK):
+                self.icontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 19, 19)
+                self.normalicontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 25, 25)
+                self.bigicontemplate = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/template.svg", 49, 49)
+                self.pathicontemplate = "../icons/template.svg"
+        else:
+            try:
+                self.icontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 19, 19)
+                self.normalicontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 25, 25)
+                self.bigicontemplate = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/template.svg", 49, 49)
+                self.pathicontemplate = config.getImagedir() + "/template.svg"
+            except:
+                print _("ERROR: Could not load icon")
+        
+        if self.debug_flag:     
+            if os.access ("../icons/at.svg", os.F_OK):
+                self.iconat = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/at.svg", 19, 19)
+                self.bigiconat = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/at.svg", 49, 49)
+        else:
+            try:
+                self.iconat = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/at.svg", 19, 19)
+                self.bigiconat = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/at.svg", 49, 49)
+            except:
+                print _("ERROR: Could not load icon")
+                
+        
+    def __loadGlade__(self):
+        if self.debug_flag:
+            if os.access("gnome-schedule.glade", os.F_OK):
+                try:
+                    self.xml = gtk.glade.XML ("gnome-schedule.glade", domain="gnome-schedule")
+                except:
+                    print _("ERROR: Could not load glade file")
+                    quit ()
+        else:
+            try:
+                self.xml = gtk.glade.XML (config.getGladedir() + "/gnome-schedule.glade", domain="gnome-schedule")
+            except:
+                print _("ERROR: Could not load glade file")
+                quit ()
+
+    
+    
+    def __initUser__(self):
+        self.uid = os.geteuid() 
+        self.gid = os.getegid()
+        self.user = pwd.getpwuid(self.uid)[0]
+        self.user_home_dir = pwd.getpwuid(self.uid)[5]
+        self.user_shell = pwd.getpwuid(self.uid)[6]
+        
+        if self.uid != 0:
+            self.btnSetUser.hide()
+            self.statusbar.hide()   
+            self.root = 0
+        else:
+            self.root = 1
+            self.btnSetUser.show()
+            self.statusbar.show()
+            self.statusbar.push(self.statusbarUser, (_("Editing user: %s") % (self.user)))
+                
+
+    #when the user selects a task, buttons get enabled
+    def on_TreeViewSelectRow (self, *args):
+        if self.treeview.get_selection().count_selected_rows() > 0 :
+            value = True
+        else:
+            value = False
+            
+        self.prop_button.set_sensitive (value)
+        self.del_button.set_sensitive (value)
+        self.run_button.set_sensitive (value)
+
+        
+    
+    #clean existing columns
+    def __cleancolumns__ (self):
+        columns = len(self.treeview.get_columns()) -1
+        while columns > -1:
+            temp = self.treeview.get_column(columns)
+            self.treeview.remove_column(temp)
+            columns = columns - 1
+         
+    
+    #switch between advanced and simple mode            
+    def switchView(self, mode = "simple"):
+        self.__cleancolumns__ ()
+        
+        self.treeview.get_selection().unselect_all()
+        self.edit_mode = mode
+        
+        cell = gtk.CellRendererPixbuf()
+        cell.set_fixed_size(21,21)
+        cell2 = gtk.CellRendererText () 
+        col = gtk.TreeViewColumn (_("Task"), None)
+        col.pack_start (cell, True)
+        col.pack_end (cell2, True)
+        col.add_attribute (cell, "pixbuf", 6)
+        if mode == "simple":
+            col.add_attribute (cell2, "text", 13)
+        else:
+            col.add_attribute (cell2, "text", 14)
+            
+        self.treeview.append_column(col)
+        
+        if mode == "simple":
+            
+            col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=0)
+            col.set_resizable (True)
+            self.treeview.append_column(col)
+
+            col = gtk.TreeViewColumn(_("Date and Time"), gtk.CellRendererText(), text=1)
+            col.set_resizable (True)
+            self.treeview.append_column(col)
+
+            col = gtk.TreeViewColumn(_("Command preview"), gtk.CellRendererText(), text=2)
+            col.set_resizable (True)
+            col.set_expand (True)
+            self.treeview.append_column(col)
+
+
+
+        elif mode == "advanced":
+    
+            col = gtk.TreeViewColumn(_("Date and Time"), gtk.CellRendererText(), text=16)
+            col.set_resizable (True)
+            self.treeview.append_column(col)
+
+            col = gtk.TreeViewColumn(_("Command preview"), gtk.CellRendererText(), text=2)
+            col.set_resizable (True)
+            col.set_expand (True)
+            self.treeview.append_column(col)
+
+            col = gtk.TreeViewColumn(_("Description"), gtk.CellRendererText(), text=0)
+            col.set_resizable (True)
+            self.treeview.append_column(col)
+
+
+
+    def on_advanced_menu_activate (self, widget):
+        if self.noevents == False:
+            if self.backend.get_advanced_option():
+                self.backend.set_advanced_option(0)
+            else:
+                self.backend.set_advanced_option(1)
+
+    def on_add_at_task (self, *args):
+        self.addWindow.mode = 0
+        self.addWindow.on_button_at_clicked (*args)
+        
+    def on_add_crontab_task (self, *args):
+        self.addWindow.mode = 0
+        self.addWindow.on_button_crontab_clicked  (*args)
+    
+    def on_add_from_template (self, *args):
+        self.addWindow.mode = 0
+        self.addWindow.on_button_template_clicked  (*args)
+
+    def on_template_manager_button (self, *args):
+        self.template_manager.show (self.widget)
+        
+    def on_add_scheduled_task_menu_activate (self, *args):
+        self.addWindow.ShowAddWindow (self.widget)
+
+    def on_properties_menu_activate (self, *args):
+        store, iter = self.treeview.get_selection().get_selected()
+        
+        try:
+            #see what scheduler (at, crontab or ...)
+            self.schedule = self.treemodel.get_value(iter, 7)
+            
+            
+        
+            record = self.treemodel.get_value(iter, 3)
+            linenumber = self.treemodel.get_value(iter, 4)
+            
+            # TODO: dirty hacky 
+            if self.schedule.get_type() == "crontab":
+                self.editor = self.crontab_editor
+                job_id = self.treemodel.get_value (iter, 9)
+                self.editor.showedit (self.widget, record, job_id, linenumber, iter)
+            else:
+                self.editor = self.at_editor
+                self.editor.showedit (self.widget, record, linenumber, iter)
+
+        except Exception, ex:
+            print ex
+            self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task"))
+            self.dialog.run ()
+            self.dialog.destroy ()          
+            
+
+    # TODO: looks not that clean (is broken)
+    def on_delete_menu_activate (self, *args):
+        dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("Do you want to delete this task?"))
+        if (dialog.run() != gtk.RESPONSE_YES):
+            dialog.destroy()
+            del dialog
+            return
+        dialog.destroy()
+        del dialog
+        
+        store, iter = self.treeview.get_selection().get_selected()
+    
+        try:
+            #see what scheduler (at, crontab or ...)
+            self.schedule = self.treemodel.get_value(iter, 7)
+            
+            # TODO: dirty hacky 
+            if self.schedule.get_type() == "crontab":
+                self.editor = self.crontab_editor
+            elif self.schedule.get_type() == "at":
+                self.editor = self.at_editor
+
+            record = self.treemodel.get_value(iter, 3)
+            linenumber = self.treemodel.get_value(iter, 4)
+
+            path = self.treemodel.get_path(iter)
+            pathint = path[0]
+            backpath = (pathint - 1,)
+            
+            if self.schedule.get_type() == "crontab":
+                self.schedule.delete (linenumber, iter, self.treemodel.get_value(iter, 9))
+            elif self.schedule.get_type() == "at":
+                self.schedule.delete (linenumber, iter)
+            
+            self.schedule_reload()
+            
+            firstiter = self.treemodel.get_iter_first()
+            try:
+                nextiter = self.treemodel.get_iter(path)
+                #go next
+                selection = self.treeview.get_selection()
+                selection.select_iter(nextiter)
+
+            except:
+                if backpath[0] > 0:
+                    nextiter = self.treemodel.get_iter(backpath)
+                    #go back
+                    selection = self.treeview.get_selection()
+                    selection.select_iter(nextiter)
+
+                else:
+                    if firstiter:
+                        #go first
+                        selection = self.treeview.get_selection()
+                        selection.select_iter(firstiter)
+                        
+        except Exception, ex:
+            #print ex
+            self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task"))
+            self.dialog.run ()
+            self.dialog.destroy ()
+
+    def on_set_user_menu_activate(self, *args):
+        self.setuserWindow.ShowSetuserWindow()
+
+
+    def on_btnSetUser_clicked(self, *args):
+        self.on_set_user_menu_activate(self, args)
+            
+    def on_add_button_clicked (self, *args):
+        self.on_add_scheduled_task_menu_activate (self, args)
+
+    def on_prop_button_clicked (self, *args):
+        self.on_properties_menu_activate (self, args)
+
+    def on_del_button_clicked (self, *args):
+        self.on_delete_menu_activate (self, args)
+
+    def on_help_button_clicked (self, *args):
+        self.on_manual_menu_activate (self, args)
+
+
+    def on_treeview_key_pressed (self, widget, event):
+        key = gtk.gdk.keyval_name(event.keyval)
+        #remove task from list with DEL key
+        if key == "Delete" or key == "KP_Delete":
+            self.on_delete_menu_activate()
+        #display properties with ENTER key
+        if (key == "Return" or key == "KP_Return"):
+            self.on_properties_menu_activate(self, widget)
+
+    
+    #double click on task to get properties
+    def on_treeview_button_press_event (self, widget, event):
+        if event.type == gtk.gdk._2BUTTON_PRESS:
+            self.on_properties_menu_activate(self, widget)
+
+
+    #about box
+    def open_url (self, *args):
+        url_show("http://gnome-schedule.sourceforge.net";)
+    
+
+    
+    def on_run_button_clicked (self, *args):
+        dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE, _("Are you sure you want to run this task now?\n\nThis is used to preview the task and initiates a one-time run, this does not affect the normal scheduled run times."))
+        dialog.add_buttons (gtk.STOCK_EXECUTE, gtk.RESPONSE_YES, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+        dialog.set_title (_("Are you sure you want to run this task?"))
+        if (dialog.run() != gtk.RESPONSE_YES):
+            dialog.destroy()
+            del dialog
+            return
+        dialog.destroy()
+        del dialog
+        
+        if (self.backend.get_not_inform_working_dir() != True):
+            dia2 = gtk.MessageDialog (self.widget, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_NONE, _("Note about working directory of executed tasks:\n\nRecurrent tasks will be run from the home directory, one-time tasks from the directory where Gnome schedule was run from at the time of task creation (normally the home directory)."))
+            dia2.add_buttons (_("_Don't show again"), gtk.RESPONSE_CLOSE, gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+            dia2.set_title (_("Warning: Working directory of executed tasks"))
+            response = dia2.run ()
+            if response == gtk.RESPONSE_CANCEL:
+                dia2.destroy ()
+                del dia2
+                return
+            elif response == gtk.RESPONSE_CLOSE:
+                self.backend.set_not_inform_working_dir (True)
+            else:
+                pass
+            dia2.destroy ()
+            del dia2
+        
+        store, iter = self.treeview.get_selection().get_selected()
+    
+        try:
+            # commands are at model[3]
+            
+            #see what scheduler (at, crontab or ...)        
+            self.schedule = self.treemodel.get_value(iter, 7)
+            
+            tmpfile = tempfile.mkstemp ()
+            fd, path = tmpfile
+            tmp = os.fdopen (fd, 'w')
+            
+            commands = self.treemodel.get_value(iter, 3)
+            linenumber = self.treemodel.get_value(iter, 4)
+            
+            
+            if self.schedule.get_type () == "at":
+                script = os.popen (config.getAtbin () + " -c " + str (linenumber)).read ()
+            elif self.schedule.get_type () == "crontab":
+                script = self.schedule.parse (commands)[1][5]
+            
+            # left untranslated to protect against any 'translation attacks'..
+            script = script + "\necho " + "Press ENTER to continue and close this window." + "\n"
+            script = script + "read\nexit\n"
+            tmp.write (script)
+            tmp.flush ()
+            self.temp_files.append ((tmp, path))
+            
+            
+            execute = self.user_shell + " " + path
+            
+            if self.root == 1:
+                if self.user != "root":
+                    execute = "su " + self.user + " -c \"" + self.user_shell + " " + path
+                    os.chown (path, self.uid, self.gid)
+            os.chmod (path, stat.S_IEXEC | stat.S_IREAD)
+            
+            
+            gnome.execute_terminal_shell (self.user_home_dir, execute)
+            
+            
+                
+        except Exception, ex:
+            print ex
+            self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Please select a task!"))
+            self.dialog.run ()
+            self.dialog.destroy ()
+            
+    def on_about_menu_activate (self, *args):
+    
+        gtk.about_dialog_set_url_hook(self.open_url, "bogusbar")
+        dlg = gtk.AboutDialog ()
+        dlg.set_title (_("About Gnome Schedule"))
+        dlg.set_name (_("Gnome Schedule"))
+        dlg.set_version (config.getVersion())
+        dlg.set_copyright (_("Copyright (c) %(year)s %(name)s.") % ({ 'year' : "2004-2008", 'name' : "Gaute Hope"}))
+        #dlg.set_comments ()
+        #dlg.set_license ()
+        dlg.set_website ("http://gnome-schedule.sourceforge.net";)
+        dlg.set_website_label("http://gnome-schedule.sourceforge.net";)
+        dlg.set_authors (
+            ["Gaute Hope <eg gaute vetsj com>",
                          "Philip Van Hoof <pvanhoof at gnome dot org>",
- 			 "Kristof Vansant <de_lupus at pandora dot be>"]
- 			)
- 		dlg.set_documenters (
- 			["Rodrigo Marcos Fombellida <rmarcos_geo yahoo es>"]
- 			)
- 		dlg.set_translator_credits (_("translator-credits"))
- 		dlg.set_logo (self.iconPixbuf)
- 		
-		if (dlg.run() != gtk.RESPONSE_YES):
-			dlg.destroy()
-			del dlg
-			return
-		dlg.destroy()
-		del dlg
- 		 	
- 	#open help
-  	def on_manual_menu_activate (self, *args):
-		try:
-			gnome.help_display (
-					'gnome-schedule', 
-					None)
-		except gobject.GError, error:
-			dialog = gtk.MessageDialog (
-					self.widget,
-					gtk.DIALOG_DESTROY_WITH_PARENT,
-					gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE)
-			dialog.set_markup ("<b>" + _("Could not display help") + "</b>")
-			dialog.format_secondary_text ("%s" % error)
-			dialog.run ()
-			dialog.destroy ()
-
-
- 	#quit program
- 	def __quit__(self, *args):
- 		for t in self.temp_files:
- 			f, p = t
- 			f.close ()
- 			os.remove (p)
- 			
-  		# save state
- 		x,y = self.widget.get_position ()
- 		h, w = self.widget.get_size ()
- 		self.backend.set_window_state(x, y, h, w)
- 		if self.inapplet:
-			self.widget.hide ()
-		else:
-			gtk.main_quit ()
-		return True
-		
+             "Kristof Vansant <de_lupus at pandora dot be>"]
+            )
+        dlg.set_documenters (
+            ["Rodrigo Marcos Fombellida <rmarcos_geo yahoo es>"]
+            )
+        dlg.set_translator_credits (_("translator-credits"))
+        dlg.set_logo (self.iconPixbuf)
+        
+        if (dlg.run() != gtk.RESPONSE_YES):
+            dlg.destroy()
+            del dlg
+            return
+        dlg.destroy()
+        del dlg
+            
+    #open help
+    def on_manual_menu_activate (self, *args):
+        try:
+            gnome.help_display (
+                    'gnome-schedule', 
+                    None)
+        except gobject.GError, error:
+            dialog = gtk.MessageDialog (
+                    self.widget,
+                    gtk.DIALOG_DESTROY_WITH_PARENT,
+                    gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE)
+            dialog.set_markup ("<b>" + _("Could not display help") + "</b>")
+            dialog.format_secondary_text ("%s" % error)
+            dialog.run ()
+            dialog.destroy ()
+
+
+    #quit program
+    def __quit__(self, *args):
+        for t in self.temp_files:
+            f, p = t
+            f.close ()
+            os.remove (p)
+            
+        # save state
+        x,y = self.widget.get_position ()
+        h, w = self.widget.get_size ()
+        self.backend.set_window_state(x, y, h, w)
+        if self.inapplet:
+            self.widget.hide ()
+        else:
+            gtk.main_quit ()
+        return True
+        

Modified: trunk/src/scheduleapplet.py
==============================================================================
--- trunk/src/scheduleapplet.py	(original)
+++ trunk/src/scheduleapplet.py	Sat Feb 14 21:20:56 2009
@@ -28,8 +28,8 @@
 poscorrect_isset = os.getenv ("POSIXLY_CORRECT", False)
 manual_poscorrect = False
 if poscorrect_isset == False:
-	os.putenv ("POSIXLY_CORRECT", "enabled")
-	manual_poscorrect = True
+    os.putenv ("POSIXLY_CORRECT", "enabled")
+    manual_poscorrect = True
 
 ##
 ## I18N
@@ -39,16 +39,16 @@
 gettext.install(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR(), unicode=1)
 
 if __name__ == "__main__":
-	signal.signal (signal.SIGINT, signal.SIG_DFL)
+    signal.signal (signal.SIGINT, signal.SIG_DFL)
 
 debug_flag = None
 if '--debug' in sys.argv:
-	debug_flag = 1
+    debug_flag = 1
 
 try:
-	import pygtk
-  	#tell pyGTK, if possible, that we want GTKv2
-  	pygtk.require("2.0")
+    import pygtk
+    #tell pyGTK, if possible, that we want GTKv2
+    pygtk.require("2.0")
   
 except:
   #Some distributions come with GTK2, but not pyGTK
@@ -62,7 +62,7 @@
   import gnome.ui
   import gnomeapplet
   import gobject
-	
+    
 except:
   print _("You need to install pyGTK or GTKv2,\n"
           "or set your PYTHONPATH correctly.\n"
@@ -75,105 +75,105 @@
 
 
 class ScheduleApplet(gnomeapplet.Applet):
-	def __init__(self, applet, iid, gprogram, debug_flag, manual_poscorrect):
-		self.__gobject_init__()
-		self.debug_flag = debug_flag
-		self.manual_poscorrect = manual_poscorrect
-		
-		gettext.bindtextdomain(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR())
-		gettext.textdomain(config.GETTEXT_PACKAGE())
-
-		locale.bindtextdomain(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR())
-		locale.textdomain(config.GETTEXT_PACKAGE())
-		
-		
-		self.applet = applet
-		self.gprogram = gprogram
-		self.__loadIcon__()
-		
-
-		self.ev_box = gtk.EventBox()
-		
-		self.image = gtk.Image()
-		self.image.set_from_pixbuf(self.iconPixbuf)
-		
-		self.main_loaded = False
-		
-		self.ev_box.add(self.image)
-		self.ev_box.show()
-		self.ev_box.set_events(gtk.gdk.BUTTON_PRESS_MASK)
-		self.ev_box.connect("button_press_event", self.event_box_clicked)
-		self.applet.add(self.ev_box)
-		
-		self.create_menu()
-		self.applet.show_all()
-
-		
-
-	
-	def __loadIcon__(self):
-		if self.debug_flag:
-			if os.access("../icons/gnome-schedule.svg", os.F_OK):
-				self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/gnome-schedule.svg", 18, 18)
-		else:
-			try:
-				self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/gnome-schedule.svg", 24, 24)
-			except:
-				print _("ERROR: Could not load icon")
-
-	def create_menu(self):
-		self.verbs = 	[ 		("show_main", self.show_main_window), 
-						("add", self.add_task),
-						("help", self.show_help),
-						("about", self.show_about)
-				]
-		
-		#check for file in current dir
-		if self.debug_flag:
-			if os.access ("gnome-schedule-applet.xml", os.F_OK):
-				datadir = './'
-		else:
-			if os.access (config.getGladedir() + "/gnome-schedule-applet.xml", os.F_OK):
-				datadir = config.getGladedir()
-			else:
-				print _("ERROR: Could not load menu xml file")
-				datadir = ''
-				quit ()
-				
-		self.applet.setup_menu_from_file(datadir,  "gnome-schedule-applet.xml", "gnome-schedule", self.verbs)
-			
-
-	def event_box_clicked (self, widget, event):
-		if event.type == gtk.gdk._2BUTTON_PRESS:
-			self.show_main_window()
-		
-	def show_main_window(self, *args):
-		if self.main_loaded == False:
-			self.main_loaded = True
-			self.main_window = mainWindow.main(None, True, self.gprogram, self.manual_poscorrect)
-		else:
-			self.main_window.widget.show ()
-			self.main_window.schedule_reload()
-		
-
-	def add_task(self, *args):
-		if self.main_loaded == False:
-			self.show_main_window()
-			self.main_window.widget.hide()
-		self.main_window.on_add_scheduled_task_menu_activate()
-
-		
-	def show_help(self, *args):
-		if self.main_loaded == False:
-			self.show_main_window()
-			self.main_window.widget.hide()
-		self.main_window.on_manual_menu_activate()
-
-	def show_about(self, *args):
-		if self.main_loaded == False:
-			self.show_main_window()
-			self.main_window.widget.hide()
-		self.main_window.on_about_menu_activate()
+    def __init__(self, applet, iid, gprogram, debug_flag, manual_poscorrect):
+        self.__gobject_init__()
+        self.debug_flag = debug_flag
+        self.manual_poscorrect = manual_poscorrect
+        
+        gettext.bindtextdomain(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR())
+        gettext.textdomain(config.GETTEXT_PACKAGE())
+
+        locale.bindtextdomain(config.GETTEXT_PACKAGE(), config.GNOMELOCALEDIR())
+        locale.textdomain(config.GETTEXT_PACKAGE())
+        
+        
+        self.applet = applet
+        self.gprogram = gprogram
+        self.__loadIcon__()
+        
+
+        self.ev_box = gtk.EventBox()
+        
+        self.image = gtk.Image()
+        self.image.set_from_pixbuf(self.iconPixbuf)
+        
+        self.main_loaded = False
+        
+        self.ev_box.add(self.image)
+        self.ev_box.show()
+        self.ev_box.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+        self.ev_box.connect("button_press_event", self.event_box_clicked)
+        self.applet.add(self.ev_box)
+        
+        self.create_menu()
+        self.applet.show_all()
+
+        
+
+    
+    def __loadIcon__(self):
+        if self.debug_flag:
+            if os.access("../icons/gnome-schedule.svg", os.F_OK):
+                self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size ("../icons/gnome-schedule.svg", 18, 18)
+        else:
+            try:
+                self.iconPixbuf = gtk.gdk.pixbuf_new_from_file_at_size (config.getImagedir() + "/gnome-schedule.svg", 24, 24)
+            except:
+                print _("ERROR: Could not load icon")
+
+    def create_menu(self):
+        self.verbs =    [       ("show_main", self.show_main_window), 
+                        ("add", self.add_task),
+                        ("help", self.show_help),
+                        ("about", self.show_about)
+                ]
+        
+        #check for file in current dir
+        if self.debug_flag:
+            if os.access ("gnome-schedule-applet.xml", os.F_OK):
+                datadir = './'
+        else:
+            if os.access (config.getGladedir() + "/gnome-schedule-applet.xml", os.F_OK):
+                datadir = config.getGladedir()
+            else:
+                print _("ERROR: Could not load menu xml file")
+                datadir = ''
+                quit ()
+                
+        self.applet.setup_menu_from_file(datadir,  "gnome-schedule-applet.xml", "gnome-schedule", self.verbs)
+            
+
+    def event_box_clicked (self, widget, event):
+        if event.type == gtk.gdk._2BUTTON_PRESS:
+            self.show_main_window()
+        
+    def show_main_window(self, *args):
+        if self.main_loaded == False:
+            self.main_loaded = True
+            self.main_window = mainWindow.main(None, True, self.gprogram, self.manual_poscorrect)
+        else:
+            self.main_window.widget.show ()
+            self.main_window.schedule_reload()
+        
+
+    def add_task(self, *args):
+        if self.main_loaded == False:
+            self.show_main_window()
+            self.main_window.widget.hide()
+        self.main_window.on_add_scheduled_task_menu_activate()
+
+        
+    def show_help(self, *args):
+        if self.main_loaded == False:
+            self.show_main_window()
+            self.main_window.widget.hide()
+        self.main_window.on_manual_menu_activate()
+
+    def show_about(self, *args):
+        if self.main_loaded == False:
+            self.show_main_window()
+            self.main_window.widget.hide()
+        self.main_window.on_about_menu_activate()
 
 gobject.type_register(ScheduleApplet)
 

Modified: trunk/src/setuserWindow.py
==============================================================================
--- trunk/src/setuserWindow.py	(original)
+++ trunk/src/setuserWindow.py	Sat Feb 14 21:20:56 2009
@@ -26,62 +26,62 @@
 
 
 class SetuserWindow:
-	def __init__(self, parent):
-		self.ParentClass = parent
-		self.xml = self.ParentClass.xml
-		self.widget = self.xml.get_widget("setuserWindow")
-		self.widget.connect("delete-event", self.widget.hide_on_delete)
-
-		##comboxEntry
-		self.entUser = self.xml.get_widget("entUser")
-		
-		liststore = gtk.ListStore(gobject.TYPE_STRING)
-		self.entUser.set_model(liststore)
-		self.entUser.set_text_column(0)
-		
-		#entryCompletion
-		# TODO: make it only possible for the user to type something that is in the list
-		self.entry = self.entUser.child
-		self.entry.set_text(self.ParentClass.user)
-  		completion = gtk.EntryCompletion()
-  		self.entry.set_completion(completion)
-   		completion.set_model(liststore)
-  		completion.set_text_column(0)
-  			
-		#fill combox with all the users
-		pwd_info = pwd.getpwall()
-		
-		for info in pwd_info:
-			self.entUser.append_text(info[0])
-		##
-		
-		self.cancel_button = self.xml.get_widget ("setuser_cancel_button")
-		self.ok_button = self.xml.get_widget ("setuser_ok_button")
-		self.xml.signal_connect("on_setuser_cancel_button_clicked", self.on_cancel_button_clicked)
-		self.xml.signal_connect("on_setuser_ok_button_clicked", self.on_ok_button_clicked)
-		
-		
-	#public function
-	def ShowSetuserWindow (self):
-		self.widget.set_transient_for(self.ParentClass.widget)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.widget.show_all()
-
-
-	def on_cancel_button_clicked (self, *args):
-		self.widget.hide()
-
-
-	def on_ok_button_clicked (self, *args):
-		
-		user = self.entry.get_text()
-		try:
-			self.ParentClass.changeUser(user)						
-			self.widget.hide()
-			
-		except Exception, ex:
-			print ex
-			self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("No such user"))
-			self.dialog.run ()
-			self.dialog.destroy ()
-		
+    def __init__(self, parent):
+        self.ParentClass = parent
+        self.xml = self.ParentClass.xml
+        self.widget = self.xml.get_widget("setuserWindow")
+        self.widget.connect("delete-event", self.widget.hide_on_delete)
+
+        ##comboxEntry
+        self.entUser = self.xml.get_widget("entUser")
+        
+        liststore = gtk.ListStore(gobject.TYPE_STRING)
+        self.entUser.set_model(liststore)
+        self.entUser.set_text_column(0)
+        
+        #entryCompletion
+        # TODO: make it only possible for the user to type something that is in the list
+        self.entry = self.entUser.child
+        self.entry.set_text(self.ParentClass.user)
+        completion = gtk.EntryCompletion()
+        self.entry.set_completion(completion)
+        completion.set_model(liststore)
+        completion.set_text_column(0)
+            
+        #fill combox with all the users
+        pwd_info = pwd.getpwall()
+        
+        for info in pwd_info:
+            self.entUser.append_text(info[0])
+        ##
+        
+        self.cancel_button = self.xml.get_widget ("setuser_cancel_button")
+        self.ok_button = self.xml.get_widget ("setuser_ok_button")
+        self.xml.signal_connect("on_setuser_cancel_button_clicked", self.on_cancel_button_clicked)
+        self.xml.signal_connect("on_setuser_ok_button_clicked", self.on_ok_button_clicked)
+        
+        
+    #public function
+    def ShowSetuserWindow (self):
+        self.widget.set_transient_for(self.ParentClass.widget)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.widget.show_all()
+
+
+    def on_cancel_button_clicked (self, *args):
+        self.widget.hide()
+
+
+    def on_ok_button_clicked (self, *args):
+        
+        user = self.entry.get_text()
+        try:
+            self.ParentClass.changeUser(user)                       
+            self.widget.hide()
+            
+        except Exception, ex:
+            print ex
+            self.dialog = gtk.MessageDialog(self.widget, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("No such user"))
+            self.dialog.run ()
+            self.dialog.destroy ()
+        

Modified: trunk/src/template.py
==============================================================================
--- trunk/src/template.py	(original)
+++ trunk/src/template.py	Sat Feb 14 21:20:56 2009
@@ -25,182 +25,193 @@
 import config
 
 class Template:
-	def __init__ (self, parent, configbackend):
-		self.parent = parent
-		self.configbackend = configbackend
-		self.gconf_client = self.configbackend.gconf_client
-		
-
-	def removetemplate_at (self, template_id):
-		installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/installed")
-		newstring = installed
-		if installed != None:
-			first = True
-			newstring = "   "
-
-			for t in installed.split (", "):
-				if t != str (template_id):
-					if first == True:
-						newstring = t
-						first = False
-					else:
-						newstring = newstring + ", " + t
-		
-		self.gconf_client.unset("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)))
-		self.gconf_client.unset("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)))
-			
-		if newstring == "   ":
-			self.gconf_client.unset ("/apps/gnome-schedule/templates/at/installed")
-		else:
-			self.gconf_client.set_string("/apps/gnome-schedule/templates/at/installed", newstring)
-			
-	def removetemplate_crontab (self, template_id):	
-		installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/installed")
-		newstring = installed
-		if installed != None:
-			first = True
-			newstring = "   "
-
-			for t in installed.split (", "):
-				if t != str (template_id):
-					if first == True:
-						newstring = t
-						first = False
-					else:
-						newstring = newstring + ", " + t
-		
-		self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)))
-		self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)))
-		self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/timeexpression" % (str (template_id)))
-		self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/nooutput" % (str (template_id)))
-			
-		if newstring == "   ":
-			self.gconf_client.unset ("/apps/gnome-schedule/templates/crontab/installed")
-		else:
-			self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/installed", newstring)
-		
-	
-	def create_new_id_crontab (self):
-		i = self.gconf_client.get_int ("/apps/gnome-schedule/templates/crontab/last_id")
-		if i == None:
-			self.gconf_client.set_int ("/apps/gnome-schedule/templates/crontab/last_id", 1)
-			return 1
-		else:
-			i = i + 1
-			self.gconf_client.set_int ("/apps/gnome-schedule/templates/crontab/last_id", i)
-			return i
-			
-	def savetemplate_crontab (self, template_id, title, command, nooutput, timeexpression):	
-
-		if (template_id == 0):
-			template_id = self.create_new_id_crontab ()
-			
-		self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/timeexpression" % (str (template_id)), timeexpression)
-		self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)), title)
-		self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)), command)
-		self.gconf_client.set_bool("/apps/gnome-schedule/templates/crontab/%s/nooutput" % (str (template_id)), nooutput)
-		
-		installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/installed")
-		if installed == None:
-			installed = str(template_id)
-		else:
-			found = False
-
-			for t in installed.split (", "):
-				if t == str (template_id):
-					found = True
-		
-			if found == False:
-				installed = installed + ", " + str (template_id)
-				
-		self.gconf_client.unset ("/apps/gnome-schedule/templates/crontab/installed")
-		self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/installed", installed)
-		self.parent.template_manager.reload_tv ()
-		self.parent.template_chooser.reload_tv ()
-		
-		
-	def gettemplateids (self, type):
-		strlist = self.gconf_client.get_string("/apps/gnome-schedule/templates/" + type + "/installed")
-		if strlist != None:
-
-			list = strlist.split (", ")
-			return list
-		else:
-			return None
-
-
-	def gettemplate (self, type, template_id):
-		if type == "crontab":
-			try:
-				command = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)))
-				title = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)))
-				nooutput = self.gconf_client.get_bool("/apps/gnome-schedule/templates/" + type + "/%s/nooutput" % (template_id))
-				timeexpression = self.gconf_client.get_string("/apps/gnome-schedule/templates/" + type + "/%s/timeexpression" % (template_id))
-				return template_id, title, command, nooutput, timeexpression
-	
-			except Exception, ex:
-				return False
-				
-		elif type == "at":
-			try:
-				command = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)))
-				title = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)))
-				return template_id, title, command
-	
-			except Exception, ex:
-				return False
-
-	def create_new_id_at (self):
-		i = self.gconf_client.get_int ("/apps/gnome-schedule/templates/at/last_id")
-		if i == 0:
-			self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/last_id", 1)
-			return 1
-		else:
-			i = i + 1
-			self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/last_id", i)
-			return i	
-
-	def savetemplate_at (self, template_id, title, command):
-
-		if (template_id == 0):
-			template_id = self.create_new_id_at ()
-			
-		self.gconf_client.set_string("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)), title)
-		self.gconf_client.set_string("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)), command)
-
-		
-		installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/installed")
-		if installed == None:
-			installed = str(template_id)
-		else:
-			found = False
-
-			for t in installed.split (", "):
-				if t == str (template_id):
-					found = True
-		
-			if found == False:
-				installed = installed + ", " + str (template_id)
-				
-		self.gconf_client.unset ("/apps/gnome-schedule/templates/at/installed")
-		self.gconf_client.set_string("/apps/gnome-schedule/templates/at/installed", installed)
-		self.parent.template_manager.reload_tv ()
-		self.parent.template_chooser.reload_tv ()
-		
-	def format_at (self, title, command):
-		command = self.parent.at.__make_preview__ (command, 0)
-		s = "<b>" + _("Title:") + "</b> " + title + "\n<b>" + _("Command:") + "</b> " + command
-		return s
-		
-	def format_crontab (self, title, command, nooutput, timeexpression):
-		command = self.parent.crontab.__make_preview__ (command)
-		if self.parent.edit_mode == "simple":
-			# hehe.. :)
-			timeexpression = timeexpression + " echo hehe"
-			minute, hour, dom, moy, dow, hehe = self.parent.crontab.parse (timeexpression, True)
-			timeexpression = self.parent.crontab.__easy__ (minute, hour, dom, moy, dow)
-		s = "<b>" + _("Title:") + "</b> " + title + "\n<b>" + _("Run:") + "</b> " + timeexpression + "\n<b>" + _("Command:") + "</b> " + command
-		if nooutput:
-			s = s + " <i>(" + _("No output") + ")</i>"
-		
-		return s
+    def __init__ (self, parent, configbackend):
+        self.parent = parent
+        self.configbackend = configbackend
+        self.gconf_client = self.configbackend.gconf_client
+        
+
+    def removetemplate_at (self, template_id):
+        installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/installed")
+        newstring = installed
+        if installed != None:
+            first = True
+            newstring = "   "
+
+            for t in installed.split (", "):
+                if t != str (template_id):
+                    if first == True:
+                        newstring = t
+                        first = False
+                    else:
+                        newstring = newstring + ", " + t
+        
+        self.gconf_client.unset("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)))
+        self.gconf_client.unset("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)))
+        self.gconf_client.unset ("/apps/gnome-schedule/templates/at/%s/output" % (str (template_id)))
+            
+        if newstring == "   ":
+            self.gconf_client.unset ("/apps/gnome-schedule/templates/at/installed")
+        else:
+            self.gconf_client.set_string("/apps/gnome-schedule/templates/at/installed", newstring)
+            
+    def removetemplate_crontab (self, template_id): 
+        installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/installed")
+        newstring = installed
+        if installed != None:
+            first = True
+            newstring = "   "
+
+            for t in installed.split (", "):
+                if t != str (template_id):
+                    if first == True:
+                        newstring = t
+                        first = False
+                    else:
+                        newstring = newstring + ", " + t
+        
+        self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)))
+        self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)))
+        self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/timeexpression" % (str (template_id)))
+        self.gconf_client.unset("/apps/gnome-schedule/templates/crontab/%s/output" % (str (template_id)))
+            
+        if newstring == "   ":
+            self.gconf_client.unset ("/apps/gnome-schedule/templates/crontab/installed")
+        else:
+            self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/installed", newstring)
+        
+    
+    def create_new_id_crontab (self):
+        i = self.gconf_client.get_int ("/apps/gnome-schedule/templates/crontab/last_id")
+        if i == None:
+            self.gconf_client.set_int ("/apps/gnome-schedule/templates/crontab/last_id", 1)
+            return 1
+        else:
+            i = i + 1
+            self.gconf_client.set_int ("/apps/gnome-schedule/templates/crontab/last_id", i)
+            return i
+            
+    def savetemplate_crontab (self, template_id, title, command, output, timeexpression):   
+
+        if (template_id == 0):
+            template_id = self.create_new_id_crontab ()
+            
+        self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/timeexpression" % (str (template_id)), timeexpression)
+        self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)), title)
+        self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)), command)
+        self.gconf_client.set_int("/apps/gnome-schedule/templates/crontab/%s/output" % (str (template_id)), output)
+        
+        installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/installed")
+        if installed == None:
+            installed = str(template_id)
+        else:
+            found = False
+
+            for t in installed.split (", "):
+                if t == str (template_id):
+                    found = True
+        
+            if found == False:
+                installed = installed + ", " + str (template_id)
+                
+        self.gconf_client.unset ("/apps/gnome-schedule/templates/crontab/installed")
+        self.gconf_client.set_string("/apps/gnome-schedule/templates/crontab/installed", installed)
+        self.parent.template_manager.reload_tv ()
+        self.parent.template_chooser.reload_tv ()
+        
+        
+    def gettemplateids (self, type):
+        strlist = self.gconf_client.get_string("/apps/gnome-schedule/templates/" + type + "/installed")
+        if strlist != None:
+
+            list = strlist.split (", ")
+            return list
+        else:
+            return None
+
+
+    def gettemplate (self, type, template_id):
+        if type == "crontab":
+            try:
+                command = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/%s/command" % (str (template_id)))
+                title = self.gconf_client.get_string("/apps/gnome-schedule/templates/crontab/%s/title" % (str (template_id)))
+                output = self.gconf_client.get_int("/apps/gnome-schedule/templates/" + type + "/%s/output" % (str (template_id)))
+                timeexpression = self.gconf_client.get_string("/apps/gnome-schedule/templates/" + type + "/%s/timeexpression" % (template_id))
+                return template_id, title, command, output, timeexpression
+    
+            except Exception, ex:
+                return False
+                
+        elif type == "at":
+            try:
+                command = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)))
+                title = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)))
+                output = self.gconf_client.get_int ("/apps/gnome-schedule/templates/at/%s/output" % (str (template_id)))
+                return template_id, title, command, output
+    
+            except Exception, ex:
+                return False
+
+    def create_new_id_at (self):
+        i = self.gconf_client.get_int ("/apps/gnome-schedule/templates/at/last_id")
+        if i == 0:
+            self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/last_id", 1)
+            return 1
+        else:
+            i = i + 1
+            self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/last_id", i)
+            return i    
+
+    def savetemplate_at (self, template_id, title, command, output):
+        print "savetemplate"
+
+        if (template_id == 0):
+            template_id = self.create_new_id_at ()
+            print "got new id"
+            
+        self.gconf_client.set_string("/apps/gnome-schedule/templates/at/%s/title" % (str (template_id)), title)
+        self.gconf_client.set_string("/apps/gnome-schedule/templates/at/%s/command" % (str (template_id)), command)
+        self.gconf_client.set_int ("/apps/gnome-schedule/templates/at/%s/output" % ( str(template_id)), output)
+
+        
+        installed = self.gconf_client.get_string("/apps/gnome-schedule/templates/at/installed")
+        if installed == None:
+            installed = str(template_id)
+        else:
+            found = False
+
+            for t in installed.split (", "):
+                if t == str (template_id):
+                    found = True
+        
+            if found == False:
+                installed = installed + ", " + str (template_id)
+                
+        self.gconf_client.unset ("/apps/gnome-schedule/templates/at/installed")
+        self.gconf_client.set_string("/apps/gnome-schedule/templates/at/installed", installed)
+        self.parent.template_manager.reload_tv ()
+        self.parent.template_chooser.reload_tv ()
+        
+    # TODO: output
+    def format_at (self, title, command, output):
+        command = self.parent.at.__make_preview__ (command, 0)
+        s = "<b>" + _("Title:") + "</b> " + title + "\n<b>" + _("Command:") + "</b> " + command
+        if output > 0:
+            s = (s + " <i>(%s)</i>") % (str (self.parent.output_strings [2]))
+
+        return s
+        
+    def format_crontab (self, title, command, output, timeexpression):
+        command = self.parent.crontab.__make_preview__ (command)
+        if self.parent.edit_mode == "simple":
+            # hehe.. :)
+            timeexpression = timeexpression + " echo hehe"
+            minute, hour, dom, moy, dow, hehe = self.parent.crontab.parse (timeexpression, True)
+            timeexpression = self.parent.crontab.__easy__ (minute, hour, dom, moy, dow)
+
+        s = "<b>" + _("Title:") + "</b> " + title + "\n<b>" + _("Run:") + "</b> " + timeexpression + "\n<b>" + _("Command:") + "</b> " + command
+
+        if output > 0:
+            s = (s + " <i>(%s)</i>") % (str (self.parent.output_strings[output]))
+        
+        return s

Modified: trunk/src/template_chooser.py
==============================================================================
--- trunk/src/template_chooser.py	(original)
+++ trunk/src/template_chooser.py	Sat Feb 14 21:20:56 2009
@@ -21,122 +21,122 @@
 
 
 class TemplateChooser:
-	def __init__ (self, parent, template):
-		self.parent = parent
-		self.template = template
-		self.transient = self.parent.widget
-
-		# setup window
-		self.xml = self.parent.xml
-		self.widget = self.xml.get_widget ("template_chooser")
-		self.widget.connect("delete-event", self.widget.hide_on_delete)
-		
-		
-		self.treeview = self.xml.get_widget ("tc_treeview")
-		self.button_use = self.xml.get_widget ("tc_button_use")
-		hbox = gtk.HBox ()
-		icon = gtk.Image ()
-		icon.set_from_pixbuf (self.parent.normalicontemplate)
-		label = gtk.Label (_("Use template"))
-		icon.set_alignment (0.5, 0.5)
-		label.set_justify (gtk.JUSTIFY_CENTER)
-		label.set_alignment (0.5, 0.5)
-		hbox.pack_start (icon, True, True, 0)
-		hbox.pack_start (label, True, True, 0)
-		self.button_use.add (hbox)
-		self.button_use.show_all ()
-		
-		self.button_cancel = self.xml.get_widget ("tc_button_cancel")
-	
-		self.xml.signal_connect ("on_tc_button_use_clicked", self.on_use_clicked)
-		self.xml.signal_connect ("on_tc_button_cancel_clicked", self.on_cancel_clicked)
-		self.xml.signal_connect ("on_tc_treeview_button_press_event", self.on_tv_pressed)
-		
-		self.treeview.get_selection().connect("changed", self.on_tv_changed)
-				
-		# setup liststore
-		# [template id, type, type-string, formatted text, icon/pixbuf]
-		self.treemodel = gtk.ListStore (gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gtk.gdk.Pixbuf)
-		
-		# setup treeview
-		self.treeview.set_model (self.treemodel)
-		self.treeview.set_headers_visible (True)
-		
-		
-		rend1 = gtk.CellRendererPixbuf ()
-		rend2 = gtk.CellRendererText ()
-		
-        	column = gtk.TreeViewColumn(_("Task"))
-        	column.pack_start (rend1, True)
-        	column.pack_end (rend2, True)
-        	column.add_attribute (rend1, "pixbuf", 4)
-        	column.add_attribute (rend2, "text", 2)
-        	self.treeview.append_column(column)
-		 
-        			
-        	rend = gtk.CellRendererText ()
-        	column = gtk.TreeViewColumn(_("Description"), rend, markup=3)
-        	self.treeview.append_column(column)  
-
-	def on_tv_changed (self, *args):
-		if self.treeview.get_selection().count_selected_rows() > 0 :
-			value = True
-		else:
-			value = False
-		self.button_use.set_sensitive (value)
-		
-	def reload_tv (self):
-		self.treemodel.clear ()
-		at = self.template.gettemplateids ("at")
-		if at != None:
-			for id in at:
-				t = self.template.gettemplate ("at", int (id))
-				if t != False:
-					id2, title, command = t
-					formatted = self.template.format_at (title, command)
-					iter = self.treemodel.append ([int (id), "at", _("One-time"), formatted, self.parent.bigiconat])
-
-		crontab = self.template.gettemplateids ("crontab")
-		if crontab != None:
-			for id in crontab:
-				t = self.template.gettemplate ("crontab", int (id))
-				if t != False:
-					id2, title, command, nooutput, timeexpression = t
-					formatted = self.template.format_crontab (title, command, nooutput, timeexpression)
-					iter = self.treemodel.append ([int (id), "crontab", _("Recurrent"), formatted, self.parent.bigiconcrontab])
-					
-					
-	def show (self, transient):
-		# populate treeview
-		self.reload_tv ()
-		self.transient = transient
-		self.widget.set_transient_for (transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.widget.show_all ()
-	
-	def on_tv_pressed (self, widget, event):
-		if event.type == gtk.gdk._2BUTTON_PRESS:
-			self.on_use_clicked(self, widget)
-			
-	def on_use_clicked (self, *args):
-		store, iter = self.treeview.get_selection().get_selected()
-		if iter != None:
-			type = self.treemodel.get_value(iter, 1)
-			id = self.treemodel.get_value(iter, 0)
-			if type == "at":
-				t = self.template.gettemplate ("at", int (id))	
-				if t != False:
-					id2, title, command = t
-					self.parent.at_editor.showadd_template (self.transient, title, command)
-			elif type == "crontab":
-				t = self.template.gettemplate ("crontab", int (id))
-				if t != False:
-					id2, title, command, nooutput, timeexpression = t
-					self.parent.crontab_editor.showadd_template (self.transient, title, command, nooutput, timeexpression)
-			
-			self.widget.hide ()
-		
-	def on_cancel_clicked (self, *args):
-		self.widget.hide ()
-	
+    def __init__ (self, parent, template):
+        self.parent = parent
+        self.template = template
+        self.transient = self.parent.widget
+
+        # setup window
+        self.xml = self.parent.xml
+        self.widget = self.xml.get_widget ("template_chooser")
+        self.widget.connect("delete-event", self.widget.hide_on_delete)
+        
+        
+        self.treeview = self.xml.get_widget ("tc_treeview")
+        self.button_use = self.xml.get_widget ("tc_button_use")
+        hbox = gtk.HBox ()
+        icon = gtk.Image ()
+        icon.set_from_pixbuf (self.parent.normalicontemplate)
+        label = gtk.Label (_("Use template"))
+        icon.set_alignment (0.5, 0.5)
+        label.set_justify (gtk.JUSTIFY_CENTER)
+        label.set_alignment (0.5, 0.5)
+        hbox.pack_start (icon, True, True, 0)
+        hbox.pack_start (label, True, True, 0)
+        self.button_use.add (hbox)
+        self.button_use.show_all ()
+        
+        self.button_cancel = self.xml.get_widget ("tc_button_cancel")
+    
+        self.xml.signal_connect ("on_tc_button_use_clicked", self.on_use_clicked)
+        self.xml.signal_connect ("on_tc_button_cancel_clicked", self.on_cancel_clicked)
+        self.xml.signal_connect ("on_tc_treeview_button_press_event", self.on_tv_pressed)
+        
+        self.treeview.get_selection().connect("changed", self.on_tv_changed)
+                
+        # setup liststore
+        # [template id, type, type-string, formatted text, icon/pixbuf]
+        self.treemodel = gtk.ListStore (gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gtk.gdk.Pixbuf)
+        
+        # setup treeview
+        self.treeview.set_model (self.treemodel)
+        self.treeview.set_headers_visible (True)
+        
+        
+        rend1 = gtk.CellRendererPixbuf ()
+        rend2 = gtk.CellRendererText ()
+        
+        column = gtk.TreeViewColumn(_("Task"))
+        column.pack_start (rend1, True)
+        column.pack_end (rend2, True)
+        column.add_attribute (rend1, "pixbuf", 4)
+        column.add_attribute (rend2, "text", 2)
+        self.treeview.append_column(column)
+     
+                
+        rend = gtk.CellRendererText ()
+        column = gtk.TreeViewColumn(_("Description"), rend, markup=3)
+        self.treeview.append_column(column)  
+
+    def on_tv_changed (self, *args):
+        if self.treeview.get_selection().count_selected_rows() > 0 :
+            value = True
+        else:
+            value = False
+        self.button_use.set_sensitive (value)
+        
+    def reload_tv (self):
+        self.treemodel.clear ()
+        at = self.template.gettemplateids ("at")
+        if at != None:
+            for id in at:
+                t = self.template.gettemplate ("at", int (id))
+                if t != False:
+                    id2, title, command, output = t
+                    formatted = self.template.format_at (title, command, output)
+                    iter = self.treemodel.append ([int (id), "at", _("One-time"), formatted, self.parent.bigiconat])
+
+        crontab = self.template.gettemplateids ("crontab")
+        if crontab != None:
+            for id in crontab:
+                t = self.template.gettemplate ("crontab", int (id))
+                if t != False:
+                    id2, title, command, output, timeexpression = t
+                    formatted = self.template.format_crontab (title, command, output, timeexpression)
+                    iter = self.treemodel.append ([int (id), "crontab", _("Recurrent"), formatted, self.parent.bigiconcrontab])
+                    
+                    
+    def show (self, transient):
+        # populate treeview
+        self.reload_tv ()
+        self.transient = transient
+        self.widget.set_transient_for (transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.widget.show_all ()
+    
+    def on_tv_pressed (self, widget, event):
+        if event.type == gtk.gdk._2BUTTON_PRESS:
+            self.on_use_clicked(self, widget)
+            
+    def on_use_clicked (self, *args):
+        store, iter = self.treeview.get_selection().get_selected()
+        if iter != None:
+            type = self.treemodel.get_value(iter, 1)
+            id = self.treemodel.get_value(iter, 0)
+            if type == "at":
+                t = self.template.gettemplate ("at", int (id))  
+                if t != False:
+                    id2, title, command, output = t
+                    self.parent.at_editor.showadd_template (self.transient, title, command, output)
+            elif type == "crontab":
+                t = self.template.gettemplate ("crontab", int (id))
+                if t != False:
+                    id2, title, command, output, timeexpression = t
+                    self.parent.crontab_editor.showadd_template (self.transient, title, command, output, timeexpression)
+            
+            self.widget.hide ()
+        
+    def on_cancel_clicked (self, *args):
+        self.widget.hide ()
+    
 

Modified: trunk/src/template_manager.py
==============================================================================
--- trunk/src/template_manager.py	(original)
+++ trunk/src/template_manager.py	Sat Feb 14 21:20:56 2009
@@ -20,164 +20,164 @@
 import gobject
 
 class TemplateManager:
-	def __init__ (self, parent, template):
-		self.parent = parent
-		self.template = template
+    def __init__ (self, parent, template):
+        self.parent = parent
+        self.template = template
 
-		# setup window
-		self.xml = self.parent.xml
-		self.widget = self.xml.get_widget ("template_manager")
-		self.widget.connect("delete-event", self.widget.hide_on_delete)
-		
-		self.treeview = self.xml.get_widget ("tm_treeview")
-		self.button_use = self.xml.get_widget ("tm_button_use")
-		hbox = gtk.HBox ()
-		icon = gtk.Image ()
-		icon.set_from_pixbuf (self.parent.normalicontemplate)
-		label = gtk.Label (_("Use template"))
-		icon.set_alignment (0.5, 0.5)
-		label.set_justify (gtk.JUSTIFY_CENTER)
-		label.set_alignment (0.5, 0.5)
-		hbox.pack_start (icon, True, True, 0)
-		hbox.pack_start (label, True, True, 0)
-		self.button_use.add (hbox)
-		self.button_use.show_all ()
-		
-		self.button_cancel = self.xml.get_widget ("tm_button_cancel")
-		
-		self.xml.signal_connect ("on_tm_button_new_clicked", self.on_new_clicked)
-		self.xml.signal_connect ("on_tm_button_use_clicked", self.on_use_clicked)
-		self.xml.signal_connect ("on_tm_button_cancel_clicked", self.on_cancel_clicked)
-		self.xml.signal_connect ("on_tm_button_edit_clicked", self.on_edit_clicked)
-		self.xml.signal_connect ("on_tm_button_delete_clicked", self.on_delete_clicked)
-		self.xml.signal_connect ("on_tm_treeview_button_press_event", self.on_tv_pressed)
-		
-		self.button_edit = self.xml.get_widget ("tm_button_edit")
-		self.button_delete = self.xml.get_widget ("tm_button_delete")
-		
-		self.treeview.get_selection().connect("changed", self.on_tv_changed)
-				
-		# setup liststore
-		# [template id, type, type-string, formatted text, icon/pixbuf]
-		self.treemodel = gtk.ListStore (gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gtk.gdk.Pixbuf)
-		
-		# setup treeview
-		self.treeview.set_model (self.treemodel)
-		self.treeview.set_headers_visible (True)
-		
-		
-		rend1 = gtk.CellRendererPixbuf ()
-		rend2 = gtk.CellRendererText ()
-		
-        	column = gtk.TreeViewColumn(_("Task"))
-        	column.pack_start (rend1, True)
-        	column.pack_end (rend2, True)
-        	column.add_attribute (rend1, "pixbuf", 4)
-        	column.add_attribute (rend2, "text", 2)
-        	self.treeview.append_column(column)
-		 
-        			
-        	rend = gtk.CellRendererText ()
-        	column = gtk.TreeViewColumn(_("Description"), rend, markup=3)
-        	self.treeview.append_column(column)  
+        # setup window
+        self.xml = self.parent.xml
+        self.widget = self.xml.get_widget ("template_manager")
+        self.widget.connect("delete-event", self.widget.hide_on_delete)
+        
+        self.treeview = self.xml.get_widget ("tm_treeview")
+        self.button_use = self.xml.get_widget ("tm_button_use")
+        hbox = gtk.HBox ()
+        icon = gtk.Image ()
+        icon.set_from_pixbuf (self.parent.normalicontemplate)
+        label = gtk.Label (_("Use template"))
+        icon.set_alignment (0.5, 0.5)
+        label.set_justify (gtk.JUSTIFY_CENTER)
+        label.set_alignment (0.5, 0.5)
+        hbox.pack_start (icon, True, True, 0)
+        hbox.pack_start (label, True, True, 0)
+        self.button_use.add (hbox)
+        self.button_use.show_all ()
+        
+        self.button_cancel = self.xml.get_widget ("tm_button_cancel")
+        
+        self.xml.signal_connect ("on_tm_button_new_clicked", self.on_new_clicked)
+        self.xml.signal_connect ("on_tm_button_use_clicked", self.on_use_clicked)
+        self.xml.signal_connect ("on_tm_button_cancel_clicked", self.on_cancel_clicked)
+        self.xml.signal_connect ("on_tm_button_edit_clicked", self.on_edit_clicked)
+        self.xml.signal_connect ("on_tm_button_delete_clicked", self.on_delete_clicked)
+        self.xml.signal_connect ("on_tm_treeview_button_press_event", self.on_tv_pressed)
+        
+        self.button_edit = self.xml.get_widget ("tm_button_edit")
+        self.button_delete = self.xml.get_widget ("tm_button_delete")
+        
+        self.treeview.get_selection().connect("changed", self.on_tv_changed)
+                
+        # setup liststore
+        # [template id, type, type-string, formatted text, icon/pixbuf]
+        self.treemodel = gtk.ListStore (gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gtk.gdk.Pixbuf)
+        
+        # setup treeview
+        self.treeview.set_model (self.treemodel)
+        self.treeview.set_headers_visible (True)
+        
+        
+        rend1 = gtk.CellRendererPixbuf ()
+        rend2 = gtk.CellRendererText ()
+        
+        column = gtk.TreeViewColumn(_("Task"))
+        column.pack_start (rend1, True)
+        column.pack_end (rend2, True)
+        column.add_attribute (rend1, "pixbuf", 4)
+        column.add_attribute (rend2, "text", 2)
+        self.treeview.append_column(column)
+     
+                
+        rend = gtk.CellRendererText ()
+        column = gtk.TreeViewColumn(_("Description"), rend, markup=3)
+        self.treeview.append_column(column)  
 
-	def on_tv_changed (self, *args):
-		if self.treeview.get_selection().count_selected_rows() > 0 :
-			value = True
-		else:
-			value = False
-		self.button_use.set_sensitive (value)
-		self.button_edit.set_sensitive (value)
-		self.button_delete.set_sensitive (value)
-		
-	def reload_tv (self):
-		self.treemodel.clear ()
-		at = self.template.gettemplateids ("at")
-		if at != None:
-			for id in at:
-				t = self.template.gettemplate ("at", int (id))
-				if t != False:
-					id2, title, command = t
-					formatted = self.template.format_at (title, command)
-					iter = self.treemodel.append ([int (id), "at", _("One-time"), formatted, self.parent.bigiconat])
+    def on_tv_changed (self, *args):
+        if self.treeview.get_selection().count_selected_rows() > 0 :
+            value = True
+        else:
+            value = False
+        self.button_use.set_sensitive (value)
+        self.button_edit.set_sensitive (value)
+        self.button_delete.set_sensitive (value)
+        
+    def reload_tv (self):
+        self.treemodel.clear ()
+        at = self.template.gettemplateids ("at")
+        if at != None:
+            for id in at:
+                t = self.template.gettemplate ("at", int (id))
+                if t != False:
+                    id2, title, command, output = t
+                    formatted = self.template.format_at (title, command, output)
+                    iter = self.treemodel.append ([int (id), "at", _("One-time"), formatted, self.parent.bigiconat])
 
-		crontab = self.template.gettemplateids ("crontab")
-		if crontab != None:
-			for id in crontab:
-				t = self.template.gettemplate ("crontab", int (id))
-				if t != False:
-					id2, title, command, nooutput, timeexpression = t
-					formatted = self.template.format_crontab (title, command, nooutput, timeexpression)
-					iter = self.treemodel.append ([int (id), "crontab", _("Recurrent"), formatted, self.parent.bigiconcrontab])
-					
-	def on_edit_clicked (self, *args):
-		store, iter = self.treeview.get_selection().get_selected()
-		if iter != None:
-			type = self.treemodel.get_value(iter, 1)
-			id = self.treemodel.get_value(iter, 0)
-			if type == "at":
-				t = self.template.gettemplate ("at", int (id))	
-				if t != False:
-					id2, title, command = t
-					self.parent.at_editor.showedit_template (self.widget, id2, title, command)
-					
-			elif type == "crontab":
-				t = self.template.gettemplate ("crontab", int (id)	)
-				if t != False:
-					id2, title, command, nooutput, timeexpression = t
-					self.parent.crontab_editor.showedit_template (self.widget, id2, title, command, nooutput, timeexpression)
-		self.reload_tv ()
-		
-	def on_new_clicked (self, *args):
-		self.parent.addWindow.ShowAddWindow (self.widget, 1)
-	
-	def on_delete_clicked (self, *args):
-		store, iter = self.treeview.get_selection().get_selected()
-		if iter != None:
-			type = self.treemodel.get_value(iter, 1)
-			id = self.treemodel.get_value(iter, 0)
-			if type == "at":
-				self.template.removetemplate_at (id)
-			elif type == "crontab":
-				self.template.removetemplate_crontab (id)
-			
-		self.reload_tv ()
-		
-		
-				
-	def show (self, transient):
-		# populate treeview
-		self.reload_tv ()
-		
-		self.widget.set_transient_for(transient)
-		self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-		self.widget.show_all ()
-		
-	def on_tv_pressed (self, widget, event):
-		if event.type == gtk.gdk._2BUTTON_PRESS:
-			self.on_edit_clicked(self, widget)
-			
-	def on_use_clicked (self, *args):
-		store, iter = self.treeview.get_selection().get_selected()
-		if iter != None:
-			type = self.treemodel.get_value(iter, 1)
-			id = self.treemodel.get_value(iter, 0)
-			if type == "at":
-				t = self.template.gettemplate ("at", int (id))	
-				if t != False:
-					id2, title, command = t
-					self.parent.at_editor.showadd_template (self.widget, title, command)
-			elif type == "crontab":
-				t = self.template.gettemplate ("crontab", int (id)	)
-				if t != False:
-					id2, title, command, nooutput, timeexpression = t
-					self.parent.crontab_editor.showadd_template (self.widget, title, command, nooutput, timeexpression)
-		
-			self.widget.hide ()
-		
-	def on_cancel_clicked (self, *args):
-		self.widget.hide ()
-	
+        crontab = self.template.gettemplateids ("crontab")
+        if crontab != None:
+            for id in crontab:
+                t = self.template.gettemplate ("crontab", int (id))
+                if t != False:
+                    id2, title, command, output, timeexpression = t
+                    formatted = self.template.format_crontab (title, command, output, timeexpression)
+                    iter = self.treemodel.append ([int (id), "crontab", _("Recurrent"), formatted, self.parent.bigiconcrontab])
+                    
+    def on_edit_clicked (self, *args):
+        store, iter = self.treeview.get_selection().get_selected()
+        if iter != None:
+            type = self.treemodel.get_value(iter, 1)
+            id = self.treemodel.get_value(iter, 0)
+            if type == "at":
+                t = self.template.gettemplate ("at", int (id))  
+                if t != False:
+                    id2, title, command = t
+                    self.parent.at_editor.showedit_template (self.widget, id2, title, command)
+                    
+            elif type == "crontab":
+                t = self.template.gettemplate ("crontab", int (id)  )
+                if t != False:
+                    id2, title, command, output, timeexpression = t
+                    self.parent.crontab_editor.showedit_template (self.widget, id2, title, command, output, timeexpression)
+        self.reload_tv ()
+        
+    def on_new_clicked (self, *args):
+        self.parent.addWindow.ShowAddWindow (self.widget, 1)
+    
+    def on_delete_clicked (self, *args):
+        store, iter = self.treeview.get_selection().get_selected()
+        if iter != None:
+            type = self.treemodel.get_value(iter, 1)
+            id = self.treemodel.get_value(iter, 0)
+            if type == "at":
+                self.template.removetemplate_at (id)
+            elif type == "crontab":
+                self.template.removetemplate_crontab (id)
+            
+        self.reload_tv ()
+        
+        
+                
+    def show (self, transient):
+        # populate treeview
+        self.reload_tv ()
+        
+        self.widget.set_transient_for(transient)
+        self.widget.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.widget.show_all ()
+        
+    def on_tv_pressed (self, widget, event):
+        if event.type == gtk.gdk._2BUTTON_PRESS:
+            self.on_edit_clicked(self, widget)
+            
+    def on_use_clicked (self, *args):
+        store, iter = self.treeview.get_selection().get_selected()
+        if iter != None:
+            type = self.treemodel.get_value(iter, 1)
+            id = self.treemodel.get_value(iter, 0)
+            if type == "at":
+                t = self.template.gettemplate ("at", int (id))  
+                if t != False:
+                    id2, title, command, output = t
+                    self.parent.at_editor.showadd_template (self.widget, title, command, output)
+            elif type == "crontab":
+                t = self.template.gettemplate ("crontab", int (id)  )
+                if t != False:
+                    id2, title, command, output, timeexpression = t
+                    self.parent.crontab_editor.showadd_template (self.widget, title, command, output, timeexpression)
+        
+            self.widget.hide ()
+        
+    def on_cancel_clicked (self, *args):
+        self.widget.hide ()
+    
 
-		
-		
+        
+        



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]