source: taskscheduler/trunk/fuentes/scheduler-gui.install/usr/share/taskscheduler/bin/taskScheduler.py @ 6822

Last change on this file since 6822 was 6822, checked in by Juanma, 19 months ago

refactorized

  • Property svn:executable set to *
File size: 22.5 KB
Line 
1#! /usr/bin/python3
2# -*- coding: utf-8 -*-
3import gi
4gi.require_version('Gtk', '3.0')
5gi.require_version('PangoCairo', '1.0')
6import json
7import cairo
8import os
9import subprocess
10import shutil
11import threading
12import platform
13import subprocess
14import sys
15import time
16#import commands
17from gi.repository import Gtk, Gdk, GdkPixbuf, GObject, GLib, PangoCairo, Pango
18import time
19from taskscheduler.taskscheduler import TaskScheduler as scheduler
20from taskscheduler.cronParser import cronParser
21from detailDateBox import DetailBox as detailDateBox
22from edupals.ui.n4dgtklogin import *
23import signal
24signal.signal(signal.SIGINT, signal.SIG_DFL)
25
26import gettext
27gettext.textdomain('taskscheduler')
28_ = gettext.gettext
29
30BASE_DIR="/usr/share/taskscheduler/"
31#BASE_DIR="../share/taskscheduler/"
32GLADE_FILE=BASE_DIR+"rsrc/taskScheduler.ui"
33REMOVE_ICON=BASE_DIR+"rsrc/trash.svg"
34EDIT_ICON=BASE_DIR+"rsrc/edit.svg"
35NO_EDIT_ICON=BASE_DIR+"rsrc/no_edit.svg"
36LOCK_PATH="/var/run/taskScheduler.lock"
37WIDGET_MARGIN=6
38DBG=1
39
40class TaskScheduler:
41        def __init__(self):
42                self.is_scheduler_running()
43                try:
44                        self.flavour=subprocess.getoutput("lliurex-version -f")
45                except:
46                        self.flavour="client"
47                self.last_task_type='remote'
48                self.ldm_helper='/usr/sbin/sched-ldm.sh'
49                self.i18n={}
50                       
51        #def __init__           
52
53        def _debug(self,msg):
54                if DBG:
55                        print("taskScheduler: %s"%msg)
56        #def _debug
57
58        def is_scheduler_running(self):
59                if os.path.exists(LOCK_PATH):
60                        dialog = Gtk.MessageDialog(None,0,Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "Task Scheduler")
61                        dialog.format_secondary_text(_("There's another instance of Task Scheduler running."))
62                        dialog.run()
63                        sys.exit(1)
64        #def is_scheduler_running
65
66        def start_gui(self):
67                self.scheduler=scheduler()
68                builder=Gtk.Builder()
69                builder.set_translation_domain('taskscheduler')
70
71                self.stack = Gtk.Stack()
72                self.stack.set_transition_duration(1000)
73                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
74
75                glade_path=GLADE_FILE
76                builder.add_from_file(glade_path)
77
78                self.window=builder.get_object("main_window")
79                self.window.set_resizable(False)
80                self.main_box=builder.get_object("main_box")
81                self.login=N4dGtkLogin()
82                self.login.set_allowed_groups(['adm','teachers'])
83                desc=_("Welcome to the Task Scheduler for Lliurex.\nFrom here you can:\n<sub>* Schedule tasks in the local pc\n* Distribute tasks among all the pcs in the network\n*Show scheduled tasks</sub>")
84                self.login.set_info_text("<span foreground='black'>Task Scheduler</span>",_("Task Scheduler"),"<span foreground='black'>"+desc+"</span>\n")
85                self.login.set_info_background(image='taskscheduler',cover=True)
86                self.login.after_validation_goto(self._signin)
87                self.login.hide_server_entry()
88                self.inf_message=Gtk.InfoBar()
89                self.inf_message.set_show_close_button(True)
90                self.lbl_message=Gtk.Label("")
91                self.inf_message.get_action_area().add(self.lbl_message)
92                self.inf_message.set_halign(Gtk.Align.CENTER)
93                self.inf_message.set_valign(Gtk.Align.CENTER)
94                def hide(widget,response):
95                        self.inf_message.hide()
96                self.inf_message.connect('response',hide)
97#               self.inf_message.props.no_show_all=True
98
99                self.inf_question=Gtk.InfoBar() 
100                self.lbl_question=Gtk.Label("")
101                self.inf_question.get_action_area().add(self.lbl_question)
102                self.inf_question.add_button(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL)
103                self.inf_question.add_button(Gtk.STOCK_OK,Gtk.ResponseType.OK)
104                self.inf_question.set_halign(Gtk.Align.CENTER)
105                self.inf_question.set_valign(Gtk.Align.CENTER)
106#               self.inf_question.props.no_show_all=True
107                self.main_box.pack_start(self.inf_question,False,False,0)
108                self.main_box.pack_start(self.inf_message,False,False,0)
109                self.view_tasks_button_box=builder.get_object("view_tasks_button_box")
110                self.view_tasks_eb=builder.get_object("view_tasks_eventbox")
111                self.btn_signal_id=None
112                #Toolbar
113                self.toolbar=builder.get_object("toolbar")
114                self.toolbar.set_visible(False)
115                self.btn_add_task=builder.get_object("btn_add_task")
116                self.btn_add_task.connect("button-release-event", self.add_task_clicked)
117                self.btn_refresh_tasks=builder.get_object("btn_refresh_tasks")
118                self.btn_refresh_tasks.connect("button-release-event", self._reload_grid)
119                self.btn_manage_tasks=builder.get_object("btn_manage_tasks")
120                self.btn_manage_tasks.connect("button-release-event", self._manage_tasks)
121                self.txt_search=builder.get_object("txt_search")
122                self.txt_search.connect('changed',self.match_tasks)
123                #tasks list
124                self._load_task_list_gui(builder)
125                #Manage tasks
126                self._load_manage_tasks(builder)
127                #Icons
128                image=Gtk.Image()
129                image.set_from_file(REMOVE_ICON)               
130                self.remove_icon=image.get_pixbuf()
131                image.set_from_file(EDIT_ICON)         
132                self.edit_icon=image.get_pixbuf()
133                image.set_from_file(NO_EDIT_ICON)               
134                self.no_edit_icon=image.get_pixbuf()
135
136                self.stack.add_titled(self.tasks_box, "tasks", "Tasks")
137                self.stack.add_titled(self.manage_box, "manage", "Manage")
138                self.stack.add_titled(self.add_task_box, "add", "Add Task")
139                self.stack.add_titled(self.login, "login", "Login")
140                #Packing
141                self.main_box.pack_start(self.stack,True,False,5)
142
143                self.toolbar.props.no_show_all=True
144                self.window.connect("destroy",self.quit)
145                self.window.set_resizable(False)
146                self.window.show_all()
147                self.inf_message.hide()
148                self.inf_question.hide()
149                self.set_css_info()
150                #Load stack
151                self.stack.set_transition_type(Gtk.StackTransitionType.NONE)
152                self.stack.set_visible_child_name("login")
153                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
154
155                Gtk.main()
156
157        #def start_gui
158
159        def _load_task_list_gui(self,builder):
160                self.tasks_box=builder.get_object("tasks_box")
161                self.tasks_label=builder.get_object("tasks_label")
162                self.tasks_tv=builder.get_object("tasks_treeview")
163                self.tasks_store=Gtk.ListStore(str,str,str,GdkPixbuf.Pixbuf,GdkPixbuf.Pixbuf,str,str,str,str)
164                self.tasks_store_filter=self.tasks_store.filter_new()
165                self.tasks_store_filter.set_visible_func(self.filter_tasklist)
166                self.tasks_tv.set_model(self.tasks_store_filter)
167                self.tasks_tv.connect("button-release-event",self.task_clicked)
168                self.tasks_tv.connect("cursor-changed",self.task_clicked)
169
170                column=Gtk.TreeViewColumn(_("Task"))
171                cell=Gtk.CellRendererText()
172                column.pack_start(cell,True)
173                column.add_attribute(cell,"markup",0)
174                column.add_attribute(cell,"cell_background",7)
175                column.add_attribute(cell,"foreground",8)
176                column.set_expand(True)
177                self.tasks_tv.append_column(column)
178               
179                column=Gtk.TreeViewColumn(_("Serial"))
180                cell=Gtk.CellRendererText()
181                column.pack_start(cell,True)
182                column.add_attribute(cell,"markup",1)
183                column.add_attribute(cell,"cell_background",7)
184                column.add_attribute(cell,"foreground",8)
185                column.set_expand(True)
186                column.set_visible(False)
187                self.tasks_tv.append_column(column)
188               
189                column=Gtk.TreeViewColumn(_("When"))
190                cell=Gtk.CellRendererText()
191                cell.set_property("alignment",Pango.Alignment.CENTER)
192                column.pack_start(cell,False)
193                column.add_attribute(cell,"markup",2)
194                column.add_attribute(cell,"cell_background",7)
195                column.add_attribute(cell,"foreground",8)
196                column.set_expand(True)
197                self.tasks_tv.append_column(column)             
198
199                column=Gtk.TreeViewColumn(_("Edit"))
200
201                cell=Gtk.CellRendererPixbuf()
202                column.pack_start(cell,True)
203                column.add_attribute(cell,"pixbuf",3)
204                column.add_attribute(cell,"cell_background",7)
205                self.col_edit=column
206                self.tasks_tv.append_column(column)
207               
208                column=Gtk.TreeViewColumn(_("Remove"))
209                cell=Gtk.CellRendererPixbuf()
210                column.pack_start(cell,True)
211                column.add_attribute(cell,"pixbuf",4)
212                column.add_attribute(cell,"cell_background",7)
213                self.col_remove=column
214                self.tasks_tv.append_column(column)
215
216                column=Gtk.TreeViewColumn(_("Command"))
217                cell=Gtk.CellRendererText()
218                column.pack_start(cell,True)
219                column.add_attribute(cell,"markup",5)
220                column.set_expand(True)
221                column.set_visible(False)
222                self.tasks_tv.append_column(column)
223               
224                column=Gtk.TreeViewColumn(_("Type"))
225                cell=Gtk.CellRendererText()
226                column.pack_start(cell,True)
227                column.add_attribute(cell,"markup",6)
228                column.set_expand(True)
229                column.set_visible(False)
230                self.tasks_tv.append_column(column)
231
232                self.tasks_tv.set_search_column(2)
233                self.tasks_tv.set_search_entry(self.txt_search)
234
235                #Add tasks
236                self.add_task_box=builder.get_object("add_task_box")
237                self.add_task_grid=detailDateBox(self.scheduler)
238                at_grid=self.add_task_grid.render_form(builder.get_object("add_task_grid"))
239                at_grid=builder.get_object("add_task_grid")
240                at_grid.set_hexpand(False)
241                self.cmb_task_names=builder.get_object("cmb_task_names")
242                self.cmb_task_cmds=builder.get_object("cmb_task_cmds")
243                builder.get_object("btn_back_add").connect("clicked", self.cancel_add_clicked)
244                builder.get_object("btn_cancel_add").connect("clicked", self.cancel_add_clicked)
245                self.btn_confirm_add=builder.get_object("btn_confirm_add")
246                self.btn_confirm_add.connect("clicked", self.save_task_details)
247        #def _load_task_list_gui
248
249        def _load_manage_tasks(self,builder):
250                self.manage_box=builder.get_object("manage_box")
251                custom_grid=builder.get_object("custom_grid")
252                custom_grid.set_margin_left(12)
253                custom_grid.set_margin_top(12)
254                txt_taskname=Gtk.Entry()
255                txt_taskname.set_tooltip_text(_("A descriptive name for the command"))
256                txt_taskname.set_placeholder_text(_("Task name"))
257                lbl_name=Gtk.Label(_("Task name"))
258                lbl_name.set_halign(Gtk.Align.END)
259                custom_grid.attach(lbl_name,0,0,1,1)
260                custom_grid.attach(txt_taskname,1,0,1,1)
261                cmb_cmds=Gtk.ComboBoxText()
262                cmds=self.scheduler.get_commands()
263                i18n_cmd={}
264                for cmd in cmds.keys():
265                        i18n_cmd[_(cmd)]=cmd
266                        cmb_cmds.append_text(_(cmd))
267
268                lbl_cmd=Gtk.Label(_("Command"))
269                lbl_cmd.set_halign(Gtk.Align.END)
270                custom_grid.attach(lbl_cmd,0,1,1,1)
271                custom_grid.attach(cmb_cmds,1,1,1,1)
272                chk_parm_is_file=Gtk.CheckButton(_("Needs a file"))
273                chk_parm_is_file.set_tooltip_text(_("Mark if the command will launch a file"))
274                btn_file=Gtk.FileChooserButton()
275                chk_parm_is_file.set_tooltip_text(_("Select the file that will be launched"))
276                chk_parm_is_file.connect('toggled',self._enable_filechooser,btn_file)
277                txt_params=Gtk.Entry()
278                txt_params.set_placeholder_text(_("Needed arguments"))
279                txt_params.set_tooltip_text(_("Put here the arguments for the command (if any)"))
280                lbl_arg=Gtk.Label(_("Arguments"))
281                lbl_arg.set_halign(Gtk.Align.END)
282                custom_grid.attach(lbl_arg,2,1,1,1)
283                custom_grid.attach(txt_params,3,1,1,1)
284                custom_grid.attach(chk_parm_is_file,2,0,1,1)
285                custom_grid.attach(btn_file,3,0,1,1)
286                btn_file.set_sensitive(False)
287                self.btn_apply_manage=builder.get_object("btn_apply_manage")
288                self.btn_apply_manage.connect("clicked",self._add_custom_task,txt_taskname,cmb_cmds,txt_params,chk_parm_is_file,btn_file,i18n_cmd)
289                self.btn_back_manage=builder.get_object("btn_back_manage")
290                self.btn_back_manage.connect("clicked",self._cancel_manage_clicked)
291                self.btn_cancel_manage=builder.get_object("btn_cancel_manage")
292                self.btn_cancel_manage.connect("clicked",self._cancel_manage_clicked)
293        #def _load_manage_tasks
294       
295        def _enable_filechooser(self,widget,filechooser):
296                if widget.get_active():
297                        filechooser.set_sensitive(True)
298                else:
299                        filechooser.set_sensitive(False)
300        #def _enable_filechooser
301
302        def _add_custom_task(self,widget,w_name,w_cmd,w_parms,w_chk,w_file,i18n_cmd):
303                name=w_name.get_text()
304                cmd=w_cmd.get_active_text()
305                cmd_desc=i18n_cmd[cmd]
306                parms=w_parms.get_text()
307                cmd=self.scheduler.get_command_cmd(cmd_desc)
308                if w_chk.get_active():
309                        parms=parms+' '+w_file.get_uri().replace('file://','')
310                if self.scheduler.write_custom_task(name,cmd,parms):
311                        self._show_info(_("Task saved"))
312                else:
313                        self._show_info(_("Permission denied"))
314        #def _add_custom_task
315
316        def _signin(self,user=None,pwd=None,server=None,data=None):
317                self.scheduler.set_credentials(user,pwd,server)
318                self.stack.set_visible_child_name("tasks")
319                self.populate_tasks_tv()
320                self.toolbar.show()
321        #def _signin
322
323        def populate_tasks_tv(self,sw_remote=False):
324                self._debug("Populating task list")
325                self.scheduled_tasks={}
326                tasks=[]
327                sw_tasks=False
328                tasks=self.scheduler.get_scheduled_tasks(sw_remote)
329                self.tasks_store.clear()
330                if type(tasks)==type({}):       
331                        parser=cronParser()
332                        self.i18n['cmd']={}
333                        self.i18n['name']={}
334                        for task_name in tasks.keys():
335                                for serial in tasks[task_name].keys():
336                                        task=tasks[task_name][serial]
337                                        task['sw_remote']=''
338                                        color_palette=['goldenrod','DarkSlateGrey','Burlywood','DarkSlateGrey','DarkSlateBlue','bisque','LightSteelBlue','DarkSlateGrey']
339                                        bg_color=color_palette[0]
340                                        fg_color=color_palette[1]
341                                        if 'kind' in task.keys():
342                                                if 'fixed' in task['kind']:
343                                                        bg_color=color_palette[2]
344                                                        fg_color=color_palette[3]
345                                                elif 'repeat' in task['kind']:
346                                                        bg_color=color_palette[4]
347                                                        fg_color=color_palette[5]
348                                                elif 'daily' in task['kind']:
349                                                        bg_color=color_palette[6]
350                                                        fg_color=color_palette[7]
351                                        else:
352                                                task['kind']=''
353                                        remote='Local task'
354                                        if 'spread' in task.keys():
355                                                if task['spread']==True:
356                                                        remote="Client task"
357                                        else:
358                                                task['spread']=False
359                                        self.scheduled_tasks[task_name]=tasks[task_name]
360                                        sw_tasks=True
361                                        parsed_calendar=''
362                                        parsed_calendar=parser.parse_taskData(task)
363                                        task['cmd']=task['cmd'].replace(self.ldm_helper+' ','')
364                                        task['action']=self.scheduler.get_task_description(task['cmd'])
365                                        if 'name' in task.keys():
366                                                name=task['name']
367                                        else:
368                                                name=_(task['action'])
369                                        self.i18n['cmd'].update({name:task['action']})
370                                        self.i18n['name'].update({_(task_name):task_name})
371                                        img=self.edit_icon
372                                        if 'protected' in task.keys():
373                                                if task['protected']==True:
374                                                        img=self.no_edit_icon
375                                        row=self.tasks_store.append(("<span font='Roboto'><b>"+name+"</b></span>\n"+\
376                                                                "<span font='Roboto' size='small'><i>"+\
377                                                                _(task_name)+"</i></span>",serial,"<span font='Roboto' size='small'>"+\
378                                                                parsed_calendar+"</span>\n"+"<span font='Roboto' size='small'><i>"+remote+"</i></span>",img,self.remove_icon,str(task['spread']),','.join(task['kind']),bg_color,fg_color))
379        #def populate_tasks_tv
380       
381        def filter_tasklist(self,model,iterr,data):
382                sw_match=True
383                match=self.txt_search.get_text().lower()
384                task_data=model.get_value(iterr,0).split('\n')
385                task_sched_data=model.get_value(iterr,2).split('\n')
386                task_cmd=task_data[0][task_data[0].find("<b>")+3:task_data[0].find("</b>")]
387                task_name=task_data[1][task_data[1].find("<i>")+3:task_data[1].find("</i>")]
388                task_sched=task_sched_data[0][task_sched_data[0].find("ll'>")+4:task_sched_data[0].find("</span>")]
389
390                task_text=task_cmd+' '+task_name+' '+task_sched
391                if match and match not in task_text.lower():
392                        sw_match=False
393                return sw_match
394        #def filter_tasklist
395
396        def match_tasks(self,widget):
397                self.tasks_store_filter.refilter()
398                GObject.timeout_add(100,self.tasks_tv.set_cursor,0)
399        #def match_tasks
400
401        def _process_model(self,model,data):
402                task={}
403                task['data']=model[data][0].split('\n')
404                if _("client task") in model[data][2]:
405                        task['spread']=True
406                else:
407                        task['spread']=False
408                task['serial']=model[data][1].split('\n')[0]
409                cmd=task['data'][0][task['data'][0].find("<b>")+3:task['data'][0].find("</b>")]
410                if cmd in self.i18n['cmd'].keys():
411                        task['cmd']=self.i18n['cmd'][cmd]
412                else:
413                        task['cmd']=cmd
414
415                name=task['data'][1][task['data'][1].find("<i>")+3:task['data'][1].find("</i>")]
416                if name in self.i18n['name'].keys():
417                        task['name']=self.i18n['name'][name]
418                else:
419                        task['name']=name
420
421                task['serial']=model[data][1]
422                return(task)
423
424        def _click_on_list(self,event):
425                action=''
426                try:
427                        row=self.tasks_tv.get_path_at_pos(int(event.x),int(event.y))
428                except Exception as e:
429                        self._debug(e)
430                if row:
431                        if row[1]==self.col_remove:
432                                action='remove'
433                        elif row[1]==self.col_edit:
434                                action='edit'
435                self._debug(action)
436                return action
437
438        def task_clicked(self,treeview,event=None):
439                self._debug("task clicked %s"%event)
440                selection=self.tasks_tv.get_selection()
441                model,data=selection.get_selected()
442                if not data:
443                        return
444                task={}
445                action=''
446                if event!=None:
447                        action=self._click_on_list(event)
448                task=self._process_model(model,data)
449                if action=='remove':
450                        self.lbl_question.set_text(_("Are you sure to delete this task?"))
451                        for widget in self.main_box.get_children():
452                                widget.set_sensitive(False)
453                        self.inf_question.set_sensitive(True)
454                        self.inf_question.show_all()
455                        try:
456                                self.inf_question.disconnect_by_func(self.manage_remove_responses)
457                        except:
458                                pass
459                        self.inf_question.connect('response',self.manage_remove_responses,model,task)
460                elif action=='edit':
461                        if task['name'] in self.scheduled_tasks.keys():
462                                if task['serial'] in self.scheduled_tasks[task['name']].keys():
463                                        task['data']=self.scheduled_tasks[task['name']][task['serial']]
464                                        self._debug("Loading details of task %s of group %s"% (task['serial'],task['name']))
465                                        self.add_task_grid.set_task_data(task)
466                                        self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
467                                        self.cmb_task_names.remove_all()
468                                        self.cmb_task_cmds.remove_all()
469                                        self.cmb_task_names.append_text(_(task['name']))
470                                        self.cmb_task_cmds.append_text(_(task['cmd']))
471                                        self.cmb_task_names.set_active(0)
472                                        self.cmb_task_cmds.set_active(0)
473                                        self.add_task_grid.load_task_details()
474                                        if 'protected' in task['data'].keys():
475                                                if task['data']['protected']:
476                                                        self.btn_confirm_add.set_sensitive(False)
477                                        else:
478                                                self.btn_confirm_add.set_sensitive(True)
479                                        self.stack.set_visible_child_name("add")
480        #def task_clicked                       
481
482        def save_task_details(self,widget):
483                task={}
484                name=self.cmb_task_names.get_active_text()
485                task['name']=self.i18n['name'][name]
486                action=self.cmb_task_cmds.get_active_text()
487                i18n_action=self.i18n['cmd'][action]
488                tasks=self.scheduler.get_available_tasks()
489                task['cmd']=tasks[task['name']][i18n_action]
490                self.add_task_grid.update_task_data(task)
491                task=self.add_task_grid.get_task_details()
492
493                self._debug("Writing task info...%s"%task)
494                for key in task.keys():
495                        print(key)
496                        for data in task[key].keys():
497                                if task[key][data]['spread']==False:
498                                        status=self.scheduler.write_tasks(task,'local')
499                                else:
500                                        status=self.scheduler.write_tasks(task,'remote')
501                        break
502                if status:
503                        self._show_info(_("Task saved"))
504                else:
505                        self._show_info(_("Permission denied"))
506                return()
507        #def save_task_details
508
509        def view_tasks_clicked(self,widget,sw_remote):
510                if widget:
511                        if not widget.get_active():
512                                return True
513                self._debug("loading tasks (remote: %s)" % sw_remote)
514                if sw_remote:
515                        self.last_task_type='remote'
516                else:
517                        self.last_task_type='local'
518                self._debug("Task clicked")
519                self.populate_tasks_tv()
520                self.tasks_tv.set_model(self.tasks_store_filter)
521                self.tasks_tv.set_cursor(0)
522                if self.stack.get_visible_child_name!='tasks':
523                        self.stack.set_visible_child_name("tasks")
524        #def view_tasks_clicked
525
526        def load_add_task_details(self):
527                tasks=[]
528                names=[]
529                self.cmb_task_names.remove_all()
530                tasks=self.scheduler.get_available_tasks()
531                for name in tasks.keys():
532                        if name not in names:
533                                names.append(name)
534                                self.i18n['name'].update({_(name):name})
535                                self.cmb_task_names.append_text(_(name))
536               
537                self.cmb_task_names.connect('changed',self.load_add_task_details_cmds,tasks)
538                self.cmb_task_names.set_active(0)
539        #def load_add_task_details
540
541        def load_add_task_details_cmds(self,widget,tasks):
542                actions=[]
543                self.i18n['cmd']={}
544                self.cmb_task_cmds.remove_all()
545                task_name=self.cmb_task_names.get_active_text()
546                if task_name:
547                        orig_name=self.i18n['name'][task_name]
548                        for action in tasks[orig_name].keys():
549                                if action not in actions:
550                                        self.i18n['cmd'].update({_(action):action})
551                                        actions.append(action)
552                                        self.cmb_task_cmds.append_text(_(action))
553                self.cmb_task_cmds.set_active(0)
554        #def load_add_task_details_cmds
555       
556        def update_task(self,widget,data=None):
557                self._debug("Updating task")
558                if self.task_details_grid.update_task_details():
559                        self._show_info(_('Task updated'))
560                        self._reload_grid()
561                else:
562                        self._show_info(_('Permission denied'))
563               
564        #def update_task
565
566        def add_task_clicked(self,widget,event):
567                self._debug("Loading new task form")
568                self.add_task_grid.clear_screen()
569                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
570                self.stack.set_visible_child_name("add")
571                self.load_add_task_details()
572        #def add_task_clicked   
573
574        def cancel_add_clicked(self,widget,event=None):
575                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
576                self.stack.set_visible_child_name("tasks")     
577                self._debug("Cancel add clicked")
578                self._reload_grid()
579        #def cancel_add_clicked
580
581        def _reload_grid(self,widget=None,data=None):
582                cursor=self.tasks_tv.get_cursor()[0]
583                self._debug("CURSOR %s"%widget)
584                self._debug("Reload grid")
585                self.populate_tasks_tv()
586                if cursor:
587                        self._debug("Restoring cursor")
588                        self.tasks_tv.set_cursor(cursor)
589
590                if type(widget)==type(Gtk.CheckButton()):
591                        self.task_details_grid.chk_node.connect("toggled",self._reload_grid)
592        #def _reload_grid
593
594        def manage_remove_responses(self,widget,response,model,task):
595                self.inf_question.hide()
596                if response==Gtk.ResponseType.OK:
597                        self._debug("Removing task %s"%(task))
598                        if task['name'] in self.i18n['name'].keys():
599                                task['name']=self.i18n['name'][task['name']]
600                        if task['cmd'] in self.i18n['cmd'].keys():
601                                task['cmd']=self.i18n['cmd'][task['cmd']]
602                        if self.scheduler.remove_task(task):
603                                self.populate_tasks_tv()
604                                self.tasks_tv.set_cursor(0)
605                        else:
606                                self._show_info(_("Permission denied"))
607                for widget in self.main_box.get_children():
608                        widget.set_sensitive(True)
609        #def manage_remove_responses
610
611        def _show_info(self,msg):
612                self.lbl_message.set_text(_(msg))
613                self.inf_message.show_all()
614                GObject.timeout_add(5000,self.inf_message.hide)
615        #def _show_info
616       
617        def _manage_tasks(self,widget,event):
618                self._debug("Loading manage tasks form")
619                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
620                self.stack.set_visible_child_name("manage")
621        #def _manage_tasks     
622
623        def _cancel_manage_clicked(self,widget):
624                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
625                self.stack.set_visible_child_name("tasks")     
626       
627        def set_css_info(self):
628       
629                css = b"""
630                #WHITE_BACKGROUND {
631                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ffffff),  to (#ffffff));;
632               
633                }
634
635                #BLUE_FONT {
636                        color: #3366cc;
637                        font: Roboto Bold 11;
638                       
639                }       
640               
641
642                #TASKGRID_FONT {
643                        color: #3366cc;
644                        font: Roboto 11;
645                       
646                }
647
648                #LABEL_OPTION{
649               
650                        color: #808080;
651                        font: Roboto 11;
652                }
653
654                #ERROR_FONT {
655                        color: #CC0000;
656                        font: Roboto Bold 11;
657                }
658                """
659                self.style_provider=Gtk.CssProvider()
660                self.style_provider.load_from_data(css)
661                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
662               
663                self.window.set_name("WHITE_BACKGROUND")
664                self.tasks_box.set_name("WHITE_BACKGROUND")
665        #def set_css_info       
666
667        def quit(self,widget,event=None):
668                Gtk.main_quit() 
669        #def quit       
670
671#class TaskScheduler
672
673GObject.threads_init()
674t=TaskScheduler()
675t.start_gui()           
Note: See TracBrowser for help on using the repository browser.