#!/usr/bin/env python
#-*- coding: UTF-8 -*-

import wx
import wx.calendar
import wx.lib.masked as masked
import stomatasksman
from   stomamisc import *
  
class EditJobDialog(wx.Dialog):

    ID_TC_NAME = wx.NewId()
    ID_TC_COUNT = wx.NewId()
    ID_LISTBOX = wx.NewId()
    
    def __init__(self, parent, updateJobwin, config, jobtimer, jobname = '', clone = False):        
        """  as """
        wx.Dialog.__init__(self, parent, -1, TITLE + ' - New / Edit backup job')
        self.parent = parent
        self.updateJobwin = updateJobwin
        self.config = config
        self.config.write()
        self.jobtimer = jobtimer
        self.timerstate = jobtimer.IsRunning()
        jobtimer.Stop()
        background_color = wx.SystemSettings_GetColour(wx.SYS_COLOUR_BACKGROUND)
        self.jobname = jobname       
        
        self.edit = len(jobname)
        # new   ::= edit == 0, clone == False
        # clone ::= edit != 0, clone == True
        # edit  ::= edit != 0, clone == False
        if self.edit:
            if clone:
                self.jobdata = self.config['Jobs'][jobname].dict()
                self.jobname = 'clone_of_job-' + jobname
            else:
                self.jobdata = self.config['Jobs'][jobname]
            dts = self.jobdata['nextrun']
            self.datetime = wx.DateTimeFromDMY(int(dts[8:10]), int(dts[5:7]), int(dts[:4]), int(dts[11:13]), int(dts[14:]))
            self.datetime.SetMonth(int(dts[5:7]) - 1)     # fix DateTimeFromDMY error
        else:
            self.datetime = wx.DateTime_Now() 
            self.jobname = 'job-' + self.datetime.Format('%Y%m%d%H%M')
            self.jobdata = initJobExample()['Example']

        sizer = wx.BoxSizer(wx.VERTICAL)        
        row1 = wx.BoxSizer(wx.HORIZONTAL)        
        self.nb = wx.Notebook(self, -1)
        self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onPageChanged)
        row1.Add(self.nb) #, 0, wx.GROW | wx.ALL, 0)        
     
        # tab 1
        page1 = wx.Panel(self.nb, -1)
        p1sizer = wx.BoxSizer(wx.VERTICAL)  
        fgsz = wx.FlexGridSizer(4, 2, 0, 0)
        fgsz.AddGrowableCol(1)
        st = wx.StaticText(page1, -1, 'Job name:')
        fgsz.Add(st, 0, wx.ALL, GAP)
        if self.edit and not clone:
            self.tcname = wx.TextCtrl(page1, self.ID_TC_NAME, self.jobname, style = wx.TE_READONLY)
            self.tcname.SetBackgroundColour(background_color)
        else:
            self.tcname = wx.TextCtrl(page1, self.ID_TC_NAME, self.jobname)
        fgsz.Add(self.tcname, 0, wx.GROW | wx.ALL, GAP)
        st = wx.StaticText(page1, -1, 'Tasks count:')
        fgsz.Add(st, 0, wx.ALL, GAP)
        self.tccount = wx.TextCtrl(page1, self.ID_TC_COUNT, self.jobdata['taskcount'], style = wx.TE_READONLY)
        self.tccount.SetBackgroundColour(background_color)
        fgsz.Add(self.tccount, 0, wx.GROW | wx.ALL, GAP)        

        st = wx.StaticText(page1, -1, 'Immediate exec:')
        fgsz.Add(st, 0, wx.ALL, GAP)        
        self.cbi = wx.CheckBox(page1, -1, ' (if checked - user start mode)')
        self.Bind(wx.EVT_CHECKBOX, self.onCheckImmediate, self.cbi)
        self.cbi.SetValue(self.jobdata['immediate'] == 'True')
        fgsz.Add(self.cbi, 0, wx.GROW | wx.ALL, GAP)

        st = wx.StaticText(page1, -1, 'Scheduled exec:')
        fgsz.Add(st, 0, wx.ALL, GAP)        
        self.cbb = wx.CheckBox(page1, -1, ' (if checked - unattended mode)')
        self.Bind(wx.EVT_CHECKBOX, self.onCheckBackground, self.cbb)
        self.cbb.SetValue(self.jobdata['background'] == 'True')
        fgsz.Add(self.cbb, 0, wx.GROW | wx.ALL, GAP)
        p1sizer.Add(fgsz, 0, wx.GROW | LRT, BORDER)
        page1.SetSizer(p1sizer)
        self.nb.AddPage(page1, ' Job info ')

        # tab 2
        page2 = wx.Panel(self.nb, -1)
        p2sizer = wx.BoxSizer(wx.VERTICAL)  

        sb = wx.StaticBox(page2, -1, ' Next execution at ')
        sbz = wx.StaticBoxSizer(sb, wx.VERTICAL)
        gbsz = wx.GridBagSizer(BORDER, BORDER)
        gbsz.AddGrowableCol(0)
        st = wx.StaticText(page2, -1, 'Start date:')
        gbsz.Add(st, wx.GBPosition(0, 0), wx.GBSpan(1, 1), wx.GROW)

        cal = wx.calendar.CalendarCtrl(page2, -1, self.datetime,
                                       style = wx.calendar.CAL_SHOW_HOLIDAYS
                                             | wx.calendar.CAL_SUNDAY_FIRST
                                             | wx.calendar.CAL_SEQUENTIAL_MONTH_SELECTION)
        self.Bind(wx.calendar.EVT_CALENDAR, self.onCalSelected)
        gbsz.Add(cal, wx.GBPosition(0, 1), wx.GBSpan(1, 1), wx.GROW)        
        
        st = wx.StaticText(page2, -1, 'Start time:')
        gbsz.Add(st, wx.GBPosition(1, 0), wx.GBSpan(1, 1), wx.GROW)

        bsz = wx.BoxSizer(wx.HORIZONTAL)
        spin24 = wx.SpinButton(page2, -1, style = wx.SP_VERTICAL)
        time24 = masked.TimeCtrl(page2, -1, self.datetime.Format('%H:%M:%S'),
                                 fmt24hr = True, display_seconds = False, spinButton = spin24)
        self.Bind(masked.EVT_TIMEUPDATE, self.onTimeChange)
        bsz.Add(time24, 0, wx.LEFT, GAP)
        bsz.Add(spin24, 0, wx.LEFT, GAP)
        gbsz.Add(bsz, wx.GBPosition(1, 1), wx.GBSpan(1, 1), wx.GROW)
        st = wx.StaticText(page2, -1, 'Execution at:')
        gbsz.Add(st, wx.GBPosition(2, 0), wx.GBSpan(1, 1), wx.GROW)
        
        self.tcdatetime = wx.TextCtrl(page2, -1, self.jobdata['nextrun'], style = wx.TE_READONLY)
        self.tcdatetime.SetBackgroundColour(background_color)
        gbsz.Add(self.tcdatetime, wx.GBPosition(2, 1), wx.GBSpan(1, 1), wx.GROW)
        gbsz.AddGrowableCol(1)
        sbz.Add(gbsz, 0, wx.GROW | wx.ALL, GAP) 
        p2sizer.Add(sbz, 0, wx.GROW | LRT, GAP) 

        sb = wx.StaticBox(page2, -1, ' Repeat credentials ')
        sbz = wx.StaticBoxSizer(sb, wx.VERTICAL)
        fgsz = wx.FlexGridSizer(2, 2, 0, 0)
        fgsz.AddGrowableCol(1)
        st = wx.StaticText(page2, -1, 'Delayed exec:')
        fgsz.Add(st, 0, wx.ALL, GAP)        
        self.cbd = wx.CheckBox(page2, -1, ' (if checked - time shift execution)')
        self.Bind(wx.EVT_CHECKBOX, self.onCheckDelayed, self.cbd)
        self.cbd.SetValue(self.jobdata['delayed'] == 'True')
        
        fgsz.Add(self.cbd, 0, wx.ALL, GAP) 
        st = wx.StaticText(page2, -1, 'Interval (days):')
        fgsz.Add(st, 0, wx.ALL, GAP)                
        self.sc = wx.SpinCtrl(page2, -1)
        self.sc.SetRange(0, 365)
        self.sc.SetValue(int(self.jobdata['interval']))
        self.Bind(wx.EVT_SPINCTRL, self.onInterval)
        fgsz.Add(self.sc, 0, wx.GROW | wx.ALL, GAP)
        
        sbz.Add(fgsz, 0, wx.GROW | wx.ALL, GAP)
        p2sizer.Add(sbz, 0, wx.GROW | LRT, GAP)
        page2.SetSizer(p2sizer)
        self.nb.AddPage(page2, ' Scheduler ')

        # tab 3    
        page3 = wx.Panel(self.nb, -1)    
        p3sizer = wx.BoxSizer(wx.VERTICAL)
        tasknames = self.config['Tasks'].keys()
        tasknames.sort()
        self.clb = wx.CheckListBox(page3, self.ID_LISTBOX, choices = tasknames)
        self.Bind(wx.EVT_CHECKLISTBOX, self.onCheckListBox, id = self.ID_LISTBOX)
        self.Bind(wx.EVT_LISTBOX_DCLICK, self.onListBoxClicked, id = self.ID_LISTBOX)
        for index, taskname in enumerate(tasknames):
            if taskname in self.jobdata['tasklist']:
                self.clb.Check(index, True)
        p3sizer.Add(self.clb, 1, wx.GROW | wx.ALL, BORDER)
                
        msgtext = wx.StaticText(page3, -1, '  checked tasks are associated with this job')
        font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
        msgtext.SetFont(font)
        p3sizer.Add(msgtext, 0, wx.GROW | wx.ALL, GAP)
        
        page3.SetSizer(p3sizer)   
        self.nb.AddPage(page3, ' Task list ')
   
        butok = wx.Button(self, wx.ID_OK, '&OK')
        self.Bind(wx.EVT_BUTTON, self.onOk, id = wx.ID_OK)
        self.buttask = wx.Button(self, wx.ID_NEW)
        self.Bind(wx.EVT_BUTTON, self.onAddTask, id = wx.ID_NEW)
        self.buttask.Enable(False)
        butcancel = wx.Button(self, wx.ID_CANCEL, '&Cancel')
        self.Bind(wx.EVT_BUTTON, self.onCancel, id = wx.ID_CANCEL)        
        
        row2 = wx.BoxSizer(wx.HORIZONTAL)
        row2.AddStretchSpacer()
        row2.Add(butok, 0, wx.GROW | wx.ALL, BORDER)
        row2.Add(self.buttask, 0, wx.GROW | wx.ALL, BORDER)
        row2.Add(butcancel, 0, wx.GROW | wx.ALL, BORDER)
        row2.AddStretchSpacer()
    
        sizer.Add(row1, 0, wx.GROW | LRT, BORDER)
        sizer.Add(row2, 0, wx.GROW | wx.LEFT | wx.RIGHT, BORDER)
        self.SetSizer(sizer)
        self.Fit()
        self.Centre()
    #-------------------------------------------------------------------------------------------

    def onPageChanged(self, event):
        try:
            if event.GetSelection() == 2:
                self.buttask.Enable(True)
            else:
                self.buttask.Enable(False)
        except:
            pass
    #-------------------------------------------------------------------------------------------

    def onListBoxClicked(self, event):
        dlg = stomatasksman.EditTaskDialog(self, self.config, self.jobtimer, event.GetString())
        if dlg.ShowModal() == wx.ID_OK:
            task, taskname = dlg.getValues()
            self.config['Tasks'][taskname] = task
        dlg.Destroy()
    #-------------------------------------------------------------------------------------------

    def onCheckImmediate(self, event):
        bstatus = event.IsChecked()                
        self.jobdata['immediate'] = str(bstatus)
        self.updateJobwin(True)
    #-------------------------------------------------------------------------------------------

    def onCheckBackground(self, event):
        bstatus = event.IsChecked()                
        self.jobdata['background'] = str(bstatus)
        self.updateJobwin(True)
#        if bstatus:
#            self.jobdata['nextrun'] = strftime('%Y-%m-%d %H:%M')
    #-------------------------------------------------------------------------------------------

    def onCalSelected(self, event):
        wxdate = event.Date
        datestr = wxdate.Format('%Y-%m-%d')
        self.jobdata['nextrun'] = datestr + self.jobdata['nextrun'][10:]
        self.tcdatetime.SetValue(self.jobdata['nextrun'])
    #-------------------------------------------------------------------------------------------

    def onTimeChange(self, event):
        self.jobdata['nextrun'] = self.jobdata['nextrun'][:11] + event.GetValue()
        self.tcdatetime.SetValue(self.jobdata['nextrun'])
    #-------------------------------------------------------------------------------------------

    def onCheckDelayed(self, event):
        self.jobdata['delayed'] = str(event.IsChecked())
    #-------------------------------------------------------------------------------------------

    def onInterval(self, event):
        self.jobdata['interval'] = str(event.GetInt())
    #-------------------------------------------------------------------------------------------

    def onCheckListBox(self, event = None):
        tasklist = []
        for index in range(self.clb.GetCount()):
            if self.clb.IsChecked(index):
                tasklist.append(self.clb.GetString(index))
        self.jobdata['taskcount'] = str(len(tasklist))
        self.tccount.SetValue(self.jobdata['taskcount'])
        self.jobdata['tasklist'] = tasklist
        self.updateJobwin()
    #-------------------------------------------------------------------------------------------

    def restoreTimer(self):
        if self.timerstate:
            self.jobtimer.Start(JOB_TIME_SLICE)
    #-------------------------------------------------------------------------------------------
    
    def onOk(self, event):
        if self.parent.config['Jobs'].has_key(self.tcname.GetValue()) and not self.edit:
            dlg = wx.MessageDialog(self, "The choosen jobname already exists!\nPlease use a different jobname.",
                                   TITLE + ' - New / Edit backup job', wx.OK | wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()
            self.restoreTimer()
            return
        else:
            if self.jobdata['taskcount'] == '0':
                dlg = wx.MessageDialog(self, "This job seems to be useless, because no task\nis associated with it.\nLeave 'Add / Edit backup job' anyway?",
                                   TITLE + ' - Job without task', wx.YES_NO | wx.ICON_WARNING)
                if dlg.ShowModal() == wx.ID_NO:
                    dlg.Destroy() 
                    return
                dlg.Destroy()               
            self.restoreTimer()
            event.Skip()
    #-------------------------------------------------------------------------------------------

    def onCancel(self, event):
        self.config.reload()      # read old values
        self.restoreTimer()
        self.updateJobwin()
        event.Skip()
    #-------------------------------------------------------------------------------------------

    def onAddTask(self, event):
        dlg = stomatasksman.EditTaskDialog(self, self.config, self.jobtimer)
        if dlg.ShowModal() == wx.ID_OK:
            task, newtaskname = dlg.getValues()
            self.config['Tasks'][str(newtaskname)] = task
            self.updateJobwin()
            tasknames = self.config['Tasks'].keys()
            tasknames.sort()
            self.clb.Set(tasknames)
            for index, taskname in enumerate(tasknames):
                if taskname in self.jobdata['tasklist'] or taskname == str(newtaskname):
                    self.clb.Check(index, True)
            self.onCheckListBox()
        dlg.Destroy()
    #-------------------------------------------------------------------------------------------

    def getValues(self):
        return self.jobdata, self.tcname.GetValue()
# - class EditJobDialog(wx.Dialog):---------------------------------------------------------------

  
class JobsManDialog(wx.Dialog):
    
    ID_CLONE = wx.NewId()
    
    def __init__(self, parent, updateJobwin, writeToLogwin, config, jobtimer, index = 0):        
        """  add, edit or remove backup jobs """
        wx.Dialog.__init__(self, parent, -1, TITLE + ' - Manage backup jobs',                           
                           style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
        self.Bind(wx.EVT_CLOSE, self.onButtonClose)
        self.Bind(wx.EVT_RIGHT_DOWN, self.onContext)
        self.config = config
        self.jobtimer = jobtimer
        self.timerstate = jobtimer.IsRunning()
        jobtimer.Stop()        
        self.parent = parent
        self.updateJobwin = updateJobwin
        self.writeToLogwin = writeToLogwin
        sizer = wx.BoxSizer(wx.VERTICAL)
        gbsz = wx.GridBagSizer(BORDER, BORDER)      
        
        sb = wx.StaticBox(self, -1, ' Existing backup jobs ')
        col1 = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
        self.joblist = wx.ListBox(self, -1, size = wx.Size(155, -1),
                                  style = wx.LB_SINGLE | wx.LB_HSCROLL)
        col1.Add(self.joblist, 1, wx.GROW | wx.ALL, GAP)
        self.Bind(wx.EVT_LISTBOX, self.onClickJob)
        self.Bind(wx.EVT_LISTBOX_DCLICK, self.onButtonEdit)
        self.Bind(wx.EVT_CHECKLISTBOX, self.onChecked)
        self.joblist.Bind(wx.EVT_RIGHT_DOWN, self.onContext)
        gbsz.Add(col1, wx.GBPosition(0, 0), wx.GBSpan(1, 1), wx.GROW)

        sb = wx.StaticBox(self, -1, ' Job info ')
        col2 = wx.StaticBoxSizer(sb, wx.HORIZONTAL)
        self.ji = wx.ListCtrl(self, -1, style = wx.LC_REPORT | wx.LC_NO_HEADER | \
                              wx.LC_SINGLE_SEL | wx.LC_HRULES | wx.BORDER_SUNKEN)
        self.ji.Bind(wx.EVT_RIGHT_DOWN, self.onContext)
        self.ji.InsertColumn(0, '')
        self.ji.InsertColumn(1, '')
        col2.Add(self.ji, 1, wx.GROW | wx.ALL, GAP)
        gbsz.Add(col2, wx.GBPosition(0, 1), wx.GBSpan(1, 2), wx.GROW)
                
        butnew = wx.Button(self, wx.ID_NEW)
        butedit = wx.Button(self, wx.ID_EDIT)
        butclone = wx.Button(self, self.ID_CLONE, 'C&lone')
        butrem = wx.Button(self, wx.ID_REMOVE)
        butclear = wx.Button(self, wx.ID_CLEAR)
        butclose = wx.Button(self, wx.ID_CLOSE)
        self.Bind(wx.EVT_BUTTON, self.onButtonClose, id = wx.ID_CLOSE)
        self.Bind(wx.EVT_BUTTON, self.onButtonNew, id = wx.ID_NEW)
        self.Bind(wx.EVT_BUTTON, self.onButtonClone, id = self.ID_CLONE)
        self.Bind(wx.EVT_BUTTON, self.onButtonRem, id = wx.ID_REMOVE)
        self.Bind(wx.EVT_BUTTON, self.onButtonEdit, id = wx.ID_EDIT)
        self.Bind(wx.EVT_BUTTON, self.onButtonClear, id = wx.ID_CLEAR)
        row2 = wx.BoxSizer(wx.HORIZONTAL)
        row2.Add(butnew, 1, wx.GROW | wx.RIGHT, GAP)
        row2.Add(butedit, 1, wx.GROW | wx.LEFT | wx.RIGHT, GAP)
        row2.Add(butclone, 1, wx.GROW | wx.LEFT | wx.RIGHT, GAP)
        row2.Add(butrem, 1, wx.GROW | wx.LEFT | wx.RIGHT, GAP)
        row2.Add(butclear, 1, wx.GROW | wx.LEFT | wx.RIGHT, GAP)
        row2.Add(butclose, 1, wx.GROW | wx.LEFT, GAP)
        gbsz.Add(row2, wx.GBPosition(1, 0), wx.GBSpan(1, 3), wx.GROW)

        self.initContextMenu()
        self.updateKeys()
        try:
            self.joblist.Select(index)
            self.onClickJob(None, self.jobnames[index])   
        except:
            pass

        gbsz.AddGrowableCol(0)
        gbsz.AddGrowableCol(1)
        gbsz.AddGrowableRow(0)

        sizer.Add(gbsz, 1, wx.GROW | wx.ALL, BORDER)
        self.SetSizer(sizer)
        self.SetMinSize(wx.Size(640, 480))
        self.Fit()
        self.Centre()        
    #-------------------------------------------------------------------------------------------

    def initContextMenu(self):
        self.popupID0 = wx.NewId()  
        self.popupID1 = wx.NewId()          
        self.popupID2 = wx.NewId()
        self.popupID3 = wx.NewId()
        self.popupID4 = wx.NewId()
        self.popupID5 = wx.NewId()
        
        self.Bind(wx.EVT_MENU, self.onButtonNew, id = self.popupID0)
        self.Bind(wx.EVT_MENU, self.onButtonEdit, id = self.popupID1)
        self.Bind(wx.EVT_MENU, self.onButtonClone, id = self.popupID2)
        self.Bind(wx.EVT_MENU, self.onButtonRem, id = self.popupID3)
        self.Bind(wx.EVT_MENU, self.onButtonClear, id = self.popupID4)
        self.Bind(wx.EVT_MENU, self.onButtonClose, id = self.popupID5)
    #-------------------------------------------------------------------------------------------

    def onContext(self, event):
        """ context menu handler """
        menu = wx.Menu()
        menu.Append(self.popupID0, 'New job')
        menu.Append(self.popupID1, 'Edit job')
        menu.Append(self.popupID2, 'Clone job')
        menu.Append(self.popupID3, 'Remove job')
        menu.Append(self.popupID4, 'Clear jobs')
        menu.AppendSeparator()
        menu.Append(self.popupID5, 'Close dialog')
        self.PopupMenu(menu)
        menu.Destroy()
    #-------------------------------------------------------------------------------------------      

    def onChecked(self, event):
        index = event.GetSelection()
        jobname = self.joblist.GetString(index)
        self.onClickJob(jobname = jobname)
    #-------------------------------------------------------------------------------------------        

    def onClickJob(self, event = None, jobname = ''):
        self.ji.DeleteAllItems()
        
        if len(self.config['Jobs']) == 0: return
        if event != None:
            jobname = event.GetString()
        if (len(jobname) == 0):
            jobname = self.jobnames[0]
        
        jobdata = self.config['Jobs'][jobname]
        
        self.ji.InsertStringItem(0, 'Job name:')
        self.ji.InsertStringItem(1, '')
        self.ji.InsertStringItem(2, 'Immediate execution:')
        self.ji.InsertStringItem(3, 'Scheduled execution:')
        self.ji.InsertStringItem(4, 'Delayed execution:')
        self.ji.InsertStringItem(5, '')        
        self.ji.InsertStringItem(6, 'Last time executed at:')
        self.ji.InsertStringItem(7, 'Next time executed at:')
        self.ji.InsertStringItem(8, 'Repeat interval (days):')
        self.ji.InsertStringItem(9, '')        
        self.ji.InsertStringItem(10, 'Task count:')
        self.ji.InsertStringItem(11, 'Task list:')
        self.ji.SetColumnWidth(0, wx.LIST_AUTOSIZE)
        
        self.ji.SetStringItem(0, 1, jobname)
        self.ji.SetStringItem(2, 1, jobdata['immediate'])
        self.ji.SetStringItem(3, 1, jobdata['background'])
        self.ji.SetStringItem(4, 1, jobdata['delayed'])
        if jobdata['lastrun'].startswith('2000'):
            self.ji.SetStringItem(6, 1, 'never')
        else:
            self.ji.SetStringItem(6, 1, jobdata['lastrun'])
        self.ji.SetStringItem(7, 1, jobdata['nextrun'])
        if (jobdata['background'] == 'False') or \
           (jobdata['delayed'] == 'True' and int(jobdata['interval']) == 0): 
            self.ji.SetItemTextColour(7, GREY)
        self.ji.SetStringItem(8, 1, jobdata['interval'])
        self.ji.SetStringItem(10, 1, jobdata['taskcount'])
        
        line = 11
        for task in jobdata['tasklist']:
            self.ji.SetStringItem(line, 1, task)
            line += 1
            self.ji.InsertStringItem(line, '')
        self.ji.SetColumnWidth(1, wx.LIST_AUTOSIZE)
    #-------------------------------------------------------------------------------------------

    def onButtonClone(self, event):
        jobids = self.joblist.GetSelections()       
        if len(jobids):
            jobname = self.joblist.GetString(jobids[0])                       
            dlg = EditJobDialog(self, self.updateJobwin, self.config, self.jobtimer, jobname, True)
            if dlg.ShowModal() == wx.ID_OK:
                job, jobname = dlg.getValues()
                self.config['Jobs'][jobname] = job
                self.writeToLogwin('Backup jobs - 1 job (%s) added to list' % (jobname))
                self.updateKeys()
                self.onClickJob(jobname = jobname)            
            dlg.Destroy()
            self.joblist.Select(self.jobnames.index(jobname))
        else:
            try:
                self.joblist.Select(0)
            except:
                pass            
        self.Layout()        
    #-------------------------------------------------------------------------------------------

    def onButtonClear(self, event):
        self.config['Jobs'] = {}
        self.updateKeys()
        self.onClickJob()   
        self.writeToLogwin('Backup jobs - all jobs removed from list', RED)
        self.Layout()
    #-------------------------------------------------------------------------------------------

    def onButtonClose(self, event):
        if self.timerstate:
            self.jobtimer.Start(JOB_TIME_SLICE)        
        self.Destroy()
    #-------------------------------------------------------------------------------------------
        
    def onButtonNew(self, event):    
        dlg = EditJobDialog(self, self.updateJobwin, self.config, self.jobtimer)
        jobname = ''
        if dlg.ShowModal() == wx.ID_OK:
            job, jobname = dlg.getValues()
            self.config['Jobs'][jobname] = job
            self.writeToLogwin('Backup jobs - 1 job (%s) added to list' % (jobname))
            self.updateKeys()
            self.onClickJob(jobname = jobname)            
        dlg.Destroy()
        if jobname:
            self.joblist.Select(self.jobnames.index(jobname))
        else:
            try:
                self.joblist.Select(0)
            except:
                pass            
        self.Layout()
    #-------------------------------------------------------------------------------------------

    def onButtonRem(self, event = None):
        jobids = self.joblist.GetSelections() 
        if len(jobids):
            jobname = self.joblist.GetString(jobids[0])
            del self.config['Jobs'][jobname]      
            self.writeToLogwin("Backup jobs - job '%s' removed from list" % (jobname))
        else:
            self.writeToLogwin('Backup jobs - there is no job to remove')
        self.updateKeys()
        self.ji.DeleteAllItems()
        self.onClickJob()
        try:
            self.joblist.Select(0)
        except:
            pass            
        self.Layout()
    #-------------------------------------------------------------------------------------------

    def onButtonEdit(self, event):
        jobids = self.joblist.GetSelections()        
        if len(jobids):
            jobname = self.joblist.GetString(jobids[0])
            dlg = EditJobDialog(self, self.updateJobwin, self.config, self.jobtimer, jobname)
            if dlg.ShowModal() == wx.ID_OK:
                job, jobname = dlg.getValues()
                self.config['Jobs'][jobname] = job
            dlg.Destroy()
            self.updateKeys()
            self.onClickJob(jobname = jobname)
            self.joblist.Select(self.jobnames.index(jobname))
        self.Layout()
    #-------------------------------------------------------------------------------------------

    def updateKeys(self):
        self.jobnames = self.config['Jobs'].keys()
        self.jobnames.sort()
        self.joblist.Set(self.jobnames)
        self.updateJobwin()     
# - class JobsDialog(wx.Dialog):----------------------------------------------------------------

