Commit 6f77039d authored by Gaute Hope's avatar Gaute Hope

X support ready for testing checks for X connection in both crontab and at


	* 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

svn path=/trunk/; revision=1125
parent 23a6e7bd
2008-12-07 Gaute Hope <eg@gaute.vetsj.com>
2009-02-14 Gaute Hope <eg@gaute.vetsj.com>
* 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
2009-01-14 Gaute Hope <eg@gaute.vetsj.com>
* Expanded tabs (4) in *.py
2008-12-14 Gaute Hope <eg@gaute.vetsj.com>
* X support for at tasks and at templates
* New option ui and new variable in gconf
* xwrapper.py: Still needs some more failchecking - is only run by cron
tasks. Perhaps it could serve as a test in the at script..
* at.py: removed all the prelen stuff - not useful, only storing the unique script
2008-12-13 Gaute Hope <eg@gaute.vetsj.com>
* Bug 563600: Fixed text position on template ToolButton in mainWindow.
* Experimental X support for crontab now working.
* xwrapper.py.in -> xwrapper.py - no need for a shebang
* Expect /bin/sh to be present
* crontab: Template saving and editing respects output setting
2008-12-07 Gaute Hope <eg@gaute.vetsj.com>
* Bug 563600: Fixed text position on template ToolButton in mainWindow
* Bug 563618: Escape &
2008-10-21 Gaute Hope <eg@gaute.vetsj.com>
* xwrapper.py: Wrapper around crontab commands running in X
* Added xoutput, display to datafile, popped to version 4
* new x-output-support branch: broken at the moment
2008-10-01 Gaute Hope <eg@gaute.vetsj.com>
* Cleaned up the run function a bit more.. problem persists - can't take care of differencies between shells that don't act like they should.
......
......@@ -12,3 +12,6 @@ entry.
Major changes should be submitted for approval to the maintainer(s).
Coding style:
Use expanded tabs, 4 of them, on all *.py files.
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.
......
......@@ -87,6 +87,7 @@ Compiling and HACKING
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
......
......@@ -24,4 +24,4 @@ src/atEditor.py
src/template.py
src/template_chooser.py
src/template_manager.py
src/xwrapper.py.in
......@@ -17,7 +17,8 @@ gnomeschedule_PYTHON = \
scheduleapplet.py \
template.py \
template_chooser.py \
template_manager.py
template_manager.py \
xwrapper.py
uidir = $(datadir)/gnome-schedule
......@@ -31,7 +32,7 @@ DISTCLEANFILES = \
config.py \
gnome-schedule.glade.bak \
gnome-schedule.gladep.bak \
gnome-schedule.gladep
gnome-schedule.gladep
EXTRA_DIST = \
$(bin_SCRIPTS) \
......
......@@ -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)
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.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.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.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 ()
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 ()
# 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 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)
This diff is collapsed.
This diff is collapsed.
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@"
......
This diff is collapsed.
This diff is collapsed.
......@@ -24,263 +24,263 @@ import re
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])