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

Last change on this file since 6764 was 6764, checked in by Juanma, 20 months ago

WIP on expert mode

  • Property svn:executable set to *
File size: 24.3 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 fixedDateBox import DetailBox as fixedDateTask
22from intervalDateBox import DetailBox as intervalDateTask
23from dailyDateBox import DetailBox as dailyDateTask
24from edupals.ui.n4dgtklogin import *
25import signal
26signal.signal(signal.SIGINT, signal.SIG_DFL)
27
28import gettext
29gettext.textdomain('taskscheduler')
30_ = gettext.gettext
31
32BASE_DIR="/usr/share/taskscheduler/"
33#BASE_DIR="../share/taskscheduler/"
34GLADE_FILE=BASE_DIR+"rsrc/taskScheduler.ui"
35REMOVE_ICON=BASE_DIR+"rsrc/trash.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                self.types={'fix':fixedDateTask,'repeat':'TaskRepeat','days':fixedDateTask}
51                       
52        #def __init__           
53
54        def _debug(self,msg):
55                if DBG:
56                        print("taskScheduler: %s"%msg)
57        #def _debug
58
59        def is_scheduler_running(self):
60                if os.path.exists(LOCK_PATH):
61                        dialog = Gtk.MessageDialog(None,0,Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "Task Scheduler")
62                        dialog.format_secondary_text(_("There's another instance of Task Scheduler running."))
63                        dialog.run()
64                        sys.exit(1)
65        #def is_scheduler_running
66
67        def start_gui(self):
68                self.scheduler=scheduler()
69                builder=Gtk.Builder()
70                builder.set_translation_domain('taskscheduler')
71
72                self.stack = Gtk.Stack()
73                self.stack.set_transition_duration(1000)
74                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
75
76                glade_path=GLADE_FILE
77                builder.add_from_file(glade_path)
78
79                self.window=builder.get_object("main_window")
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.btn_remote_tasks=builder.get_object("btn_remote_tasks")
122                self.btn_local_tasks=builder.get_object("btn_local_tasks")
123                self.handler_remote=self.btn_remote_tasks.connect("clicked",self.view_tasks_clicked,True)
124                self.handler_local=self.btn_local_tasks.connect("clicked",self.view_tasks_clicked,False)
125                self.txt_search=builder.get_object("txt_search")
126                self.txt_search.connect('changed',self.match_tasks)
127                #tasks list
128                self._load_task_list_gui(builder)
129                #Manage tasks
130                self._load_manage_tasks(builder)
131                #Icons
132                image=Gtk.Image()
133                image.set_from_file(REMOVE_ICON)               
134                self.remove_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.loginBox, "login", "Login")
140                self.stack.add_titled(self.login, "login", "Login")
141                #Packing
142                self.main_box.pack_start(self.stack,True,False,5)
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.task_details_grid=fixedDateTask(self.scheduler)
164#               self.task_details_grid=DetailBox.DetailBox(self.scheduler)
165                td_grid=self.task_details_grid.render_form(builder.get_object("task_details_grid"))
166                self.detailGrid=builder.get_object("task_details_grid")
167
168                self.task_details_grid.btn_apply.set_sensitive(True)
169                self.task_details_grid.btn_apply.connect("clicked",self.update_task)
170                self.task_details_grid.chk_node.connect("toggled",self._reload_grid)
171                self.tasks_store=Gtk.ListStore(str,str,str,GdkPixbuf.Pixbuf,str,str,str)
172                self.tasks_store_filter=self.tasks_store.filter_new()
173                self.tasks_store_filter.set_visible_func(self.filter_tasklist)
174                self.tasks_tv.set_model(self.tasks_store_filter)
175                self.tasks_tv.connect("button-release-event",self.task_clicked)
176                self.tasks_tv.connect("cursor-changed",self.task_clicked)
177
178                column=Gtk.TreeViewColumn(_("Task"))
179                cell=Gtk.CellRendererText()
180                column.pack_start(cell,True)
181                column.add_attribute(cell,"markup",0)
182                column.add_attribute(cell,"cell_background",6)
183                column.set_expand(True)
184                self.tasks_tv.append_column(column)
185               
186                column=Gtk.TreeViewColumn(_("Serial"))
187                cell=Gtk.CellRendererText()
188                column.pack_start(cell,True)
189                column.add_attribute(cell,"markup",1)
190                column.add_attribute(cell,"cell_background",6)
191                column.set_expand(True)
192                column.set_visible(False)
193                self.tasks_tv.append_column(column)
194               
195                column=Gtk.TreeViewColumn(_("When"))
196                cell=Gtk.CellRendererText()
197                cell.set_property("alignment",Pango.Alignment.CENTER)
198                column.pack_start(cell,False)
199                column.add_attribute(cell,"markup",2)
200                column.add_attribute(cell,"cell_background",6)
201                column.set_expand(True)
202                self.tasks_tv.append_column(column)             
203
204                column=Gtk.TreeViewColumn(_("Remove"))
205                cell=Gtk.CellRendererPixbuf()
206#               cell.set_property('cell_background','red')
207                column.pack_start(cell,True)
208                column.add_attribute(cell,"pixbuf",3)
209                column.add_attribute(cell,"cell_background",6)
210                self.col_remove=column
211                self.tasks_tv.append_column(column)
212               
213                column=Gtk.TreeViewColumn(_("Command"))
214                cell=Gtk.CellRendererText()
215                column.pack_start(cell,True)
216                column.add_attribute(cell,"markup",4)
217                column.set_expand(True)
218                column.set_visible(False)
219                self.tasks_tv.append_column(column)
220               
221                column=Gtk.TreeViewColumn(_("Type"))
222                cell=Gtk.CellRendererText()
223                column.pack_start(cell,True)
224                column.add_attribute(cell,"markup",5)
225                column.set_expand(True)
226                column.set_visible(False)
227                self.tasks_tv.append_column(column)
228
229                self.tasks_tv.set_search_column(2)
230                self.tasks_tv.set_search_entry(self.txt_search)
231
232                #Add tasks
233                self.add_task_box=builder.get_object("add_task_box")
234                self.add_task_grid=fixedDateTask(self.scheduler)
235#               self.add_task_grid=DetailBox(self.scheduler)
236                at_grid=self.add_task_grid.render_form(builder.get_object("add_task_grid"),False)
237                at_grid=builder.get_object("add_task_grid")
238                self.cmb_task_names=builder.get_object("cmb_task_names")
239                self.cmb_task_cmds=builder.get_object("cmb_task_cmds")
240                builder.get_object("btn_back_add").connect("clicked", self.cancel_add_clicked)
241                builder.get_object("btn_cancel_add").connect("clicked", self.cancel_add_clicked)
242                builder.get_object("btn_confirm_add").connect("clicked", self.save_task_details)
243                self.chk_remote=builder.get_object("swt_remote")
244                self.chk_local=builder.get_object("swt_local")
245        #def _load_task_list_gui
246
247        def _load_manage_tasks(self,builder):
248                self.manage_box=builder.get_object("manage_box")
249                custom_grid=builder.get_object("custom_grid")
250                custom_grid.set_margin_left(12)
251                custom_grid.set_margin_top(12)
252                txt_taskname=Gtk.Entry()
253                txt_taskname.set_tooltip_text(_("A descriptive name for the command"))
254                txt_taskname.set_placeholder_text(_("Task name"))
255                lbl_name=Gtk.Label(_("Task name"))
256                lbl_name.set_halign(Gtk.Align.END)
257                custom_grid.attach(lbl_name,0,0,1,1)
258                custom_grid.attach(txt_taskname,1,0,1,1)
259                cmb_cmds=Gtk.ComboBoxText()
260                cmds=self.scheduler.get_commands()
261                i18n_cmd={}
262                for cmd in cmds.keys():
263                        i18n_cmd[_(cmd)]=cmd
264                        cmb_cmds.append_text(_(cmd))
265
266                lbl_cmd=Gtk.Label(_("Command"))
267                lbl_cmd.set_halign(Gtk.Align.END)
268                custom_grid.attach(lbl_cmd,0,1,1,1)
269                custom_grid.attach(cmb_cmds,1,1,1,1)
270                chk_parm_is_file=Gtk.CheckButton(_("Needs a file"))
271                chk_parm_is_file.set_tooltip_text(_("Mark if the command will launch a file"))
272                btn_file=Gtk.FileChooserButton()
273                chk_parm_is_file.set_tooltip_text(_("Select the file that will be launched"))
274                chk_parm_is_file.connect('toggled',self._enable_filechooser,btn_file)
275                txt_params=Gtk.Entry()
276                txt_params.set_placeholder_text(_("Needed arguments"))
277                txt_params.set_tooltip_text(_("Put here the arguments for the command (if any)"))
278                lbl_arg=Gtk.Label(_("Arguments"))
279                lbl_arg.set_halign(Gtk.Align.END)
280                custom_grid.attach(lbl_arg,2,1,1,1)
281                custom_grid.attach(txt_params,3,1,1,1)
282                custom_grid.attach(chk_parm_is_file,2,0,1,1)
283                custom_grid.attach(btn_file,3,0,1,1)
284                btn_file.set_sensitive(False)
285                self.btn_apply_manage=builder.get_object("btn_apply_manage")
286                self.btn_apply_manage.connect("clicked",self._add_custom_task,txt_taskname,cmb_cmds,txt_params,chk_parm_is_file,btn_file,i18n_cmd)
287                self.btn_back_manage=builder.get_object("btn_back_manage")
288                self.btn_back_manage.connect("clicked",self._cancel_manage_clicked)
289                self.btn_cancel_manage=builder.get_object("btn_cancel_manage")
290                self.btn_cancel_manage.connect("clicked",self._cancel_manage_clicked)
291        #def _load_manage_tasks
292       
293        def _enable_filechooser(self,widget,filechooser):
294                if widget.get_active():
295                        filechooser.set_sensitive(True)
296                else:
297                        filechooser.set_sensitive(False)
298        #def _enable_filechooser
299
300        def _add_custom_task(self,widget,w_name,w_cmd,w_parms,w_chk,w_file,i18n_cmd):
301                name=w_name.get_text()
302                cmd=w_cmd.get_active_text()
303                cmd_desc=i18n_cmd[cmd]
304                parms=w_parms.get_text()
305                cmd=self.scheduler.get_command_cmd(cmd_desc)
306                if w_chk.get_active():
307                        parms=parms+' '+w_file.get_uri().replace('file://','')
308                if self.scheduler.write_custom_task(name,cmd,parms):
309                        self._show_info(_("Task saved"))
310                else:
311                        self._show_info(_("Permission denied"))
312        #def _add_custom_task
313
314        def _signin(self,user=None,pwd=None,server=None,data=None):
315                self.scheduler.set_credentials(user,pwd,server)
316                if server=='localhost':
317                        self.btn_local_tasks.set_active(True)
318                        self.btn_remote_tasks.set_visible(False)
319                        self.btn_local_tasks.set_visible(False)
320                else:
321                        self.btn_remote_tasks.set_active(True)
322                self.toolbar.show()
323        #def _signin
324
325        def populate_tasks_tv(self,sw_remote=False):
326                self._debug("Populating task list")
327                self.task_details_grid.btn_apply.set_sensitive(False)
328                self.scheduled_tasks={}
329                tasks=[]
330                sw_tasks=False
331                tasks=self.scheduler.get_scheduled_tasks(sw_remote)
332                self.tasks_store.clear()
333                if type(tasks)==type({}):       
334                        parser=cronParser()
335                        for task_name in tasks.keys():
336                                for serial in tasks[task_name].keys():
337                                        task=tasks[task_name][serial]
338                                        task['sw_remote']=''
339                                        color='silver'
340                                        if 'sched' in task.keys():
341                                                task['sched']==task['sched']
342                                                color='orange'
343                                        else:
344                                                task['sched']=''
345#                                       self.scheduled_tasks[task_name]=tasks[task_name][serial]
346                                        self.scheduled_tasks[task_name]=tasks[task_name]
347#                                       for task in tasks[task_name][serial]:
348                                        sw_tasks=True
349                                        parsed_calendar=''
350                                        parsed_calendar=parser.parse_taskData(task)
351                                        task['cmd']=task['cmd'].replace(self.ldm_helper+' ','')
352                                        task['action']=self.scheduler.get_task_description(task['cmd'])
353                                        self.i18n['cmd']={_(task['action']):task['action']}
354                                        self.i18n['name']={_(task_name):task_name}
355                                        row=self.tasks_store.append(("<span font='Roboto'><b>"+_(task['action'])+"</b></span>\n"+\
356                                                                "<span font='Roboto' size='small'><i>"+\
357                                                                _(task_name)+"</i></span>",serial,"<span font='Roboto' size='small'>"+\
358                                                                parsed_calendar+"</span>",self.remove_icon,task['sw_remote'],task['sched'],color))
359                if sw_tasks:
360                        self.task_details_grid.btn_apply.set_sensitive(True)
361        #def populate_tasks_tv
362       
363        def filter_tasklist(self,model,iterr,data):
364                sw_match=True
365                match=self.txt_search.get_text().lower()
366                task_data=model.get_value(iterr,0).split('\n')
367                task_sched_data=model.get_value(iterr,2).split('\n')
368                task_cmd=task_data[0][task_data[0].find("<b>")+3:task_data[0].find("</b>")]
369                task_name=task_data[1][task_data[1].find("<i>")+3:task_data[1].find("</i>")]
370                task_sched=task_sched_data[0][task_sched_data[0].find("ll'>")+4:task_sched_data[0].find("</span>")]
371
372                task_text=task_cmd+' '+task_name+' '+task_sched
373                if match and match not in task_text.lower():
374                        sw_match=False
375                return sw_match
376        #def filter_tasklist
377
378        def match_tasks(self,widget):
379                self.tasks_store_filter.refilter()
380                GObject.timeout_add(100,self.tasks_tv.set_cursor,0)
381        #def match_tasks
382
383        def _process_model(self,model,data):
384                task={}
385                task['data']=model[data][0].split('\n')
386                task['serial']=model[data][1].split('\n')[0]
387                cmd=task['data'][0][task['data'][0].find("<b>")+3:task['data'][0].find("</b>")]
388                if cmd in self.i18n['cmd'].keys():
389                        task['cmd']=self.i18n['cmd'][cmd]
390                else:
391                        task['cmd']=cmd
392
393                name=task['data'][1][task['data'][1].find("<i>")+3:task['data'][1].find("</i>")]
394                if name in self.i18n['name'].keys():
395                        task['name']=self.i18n['name'][name]
396                else:
397                        task['name']=name
398
399                task['serial']=model[data][1]
400                if self.btn_remote_tasks.get_active():
401                        task['type']='remote'
402                        task['sw_remote']=True
403                else:
404                        task['type']='local'
405                        task['sw_remote']=False
406                return(task)
407
408        def _click_on_delete(self,event):
409                sw_show=True
410                try:
411                        row=self.tasks_tv.get_path_at_pos(int(event.x),int(event.y))
412                except Exception as e:
413                        self._debug(e)
414                if row:
415                        if row[1]==self.col_remove:
416                                sw_show=False
417                return sw_show
418
419        def task_clicked(self,treeview,event=None):
420                self._debug("task clicked %s"%event)
421                if self.task_details_grid:
422                        self.task_details_grid.clear_screen()
423                selection=self.tasks_tv.get_selection()
424                model,data=selection.get_selected()
425                if not data:
426                        return
427                task={}
428                sw_show=True
429                if event!=None:
430                        sw_show=self._click_on_delete(event)
431                task=self._process_model(model,data)
432                if sw_show:
433                        if task['name'] in self.scheduled_tasks.keys():
434                                if task['serial'] in self.scheduled_tasks[task['name']].keys():
435                                        task['data']=self.scheduled_tasks[task['name']][task['serial']]
436                                        self._debug("Loading details of task %s of group %s remote %s"% (task['serial'],task['name'],task['sw_remote']))
437                                        self.task_details_grid.set_task_data(task)
438                                        self.task_details_grid.load_task_details()
439                else:
440                        self.lbl_question.set_text(_("Are you sure to delete this task?"))
441                        for widget in self.main_box.get_children():
442                                widget.set_sensitive(False)
443                        self.inf_question.set_sensitive(True)
444                        self.inf_question.show_all()
445                        try:
446                                self.inf_question.disconnect_by_func(self.manage_remove_responses)
447                        except:
448                                pass
449                        self.inf_question.connect('response',self.manage_remove_responses,model,task['name'],task['serial'],task['cmd'],task['type'],data)
450        #def task_clicked                       
451
452        def save_task_details(self,widget):
453                task={}
454                name=self.cmb_task_names.get_active_text()
455#               task_name=self.orig_tasks[name]
456                task['name']=self.i18n['name'][name]
457                action=self.cmb_task_cmds.get_active_text()
458                i18n_action=self.i18n['cmd'][action]
459                tasks=self.scheduler.get_available_tasks()
460                task['cmd']=tasks[task['name']][i18n_action]
461                task['sw_remote']=False
462#               task_type='local'
463                if self.btn_remote_tasks.get_active():
464                        task['sw_remote']=True
465#                       task_type='remote'
466                self.add_task_grid.set_task_data(task)
467                task=self.add_task_grid.get_task_details()
468
469                self._debug("Writing task info...")
470                if self.chk_remote.get_active():
471                        status=self.scheduler.write_tasks(task,'remote')
472                if self.chk_local.get_active():
473                        status=self.scheduler.write_tasks(task,'local')
474                if status:
475                        self._show_info(_("Task saved"))
476                else:
477                        self._show_info(_("Permission denied"))
478                return()
479        #def save_task_details
480
481        def view_tasks_clicked(self,widget,sw_remote):
482                if widget:
483                        if not widget.get_active():
484                                if sw_remote:
485                                        self._block_widget_state(True,widget,self.handler_remote)
486                                else:                                   
487                                        self._block_widget_state(True,widget,self.handler_local)
488                                return True
489                self._debug("loading tasks (remote: %s)" % sw_remote)
490                if sw_remote:
491                        self.btn_local_tasks.set_active(False)
492                        self.btn_local_tasks.props.active=False
493                        self.last_task_type='remote'
494                else:
495                        self.btn_remote_tasks.set_active(False)
496                        self.btn_remote_tasks.props.active=False
497                        self.last_task_type='local'
498                self._debug("Task clicked")
499                self.populate_tasks_tv(sw_remote)
500                self.tasks_tv.set_model(self.tasks_store_filter)
501                self.tasks_tv.set_cursor(0)
502                if self.stack.get_visible_child_name!='tasks':
503                        self.stack.set_visible_child_name("tasks")
504        #def view_tasks_clicked
505
506        def load_add_task_details(self):
507                if not self.btn_remote_tasks.get_visible():
508                        self.chk_remote.set_visible(False)
509                        self.chk_local.set_active(1)
510                        self.chk_remote.set_active(0)
511                        self.chk_local.set_sensitive(False)
512                else:
513                        if self.btn_remote_tasks.get_active():
514                                self.chk_remote.set_active(1)
515                                self.chk_local.set_active(0)
516                        else:
517                                self.chk_local.set_active(1)
518                                self.chk_remote.set_active(0)
519
520                self._block_widget_state(False,self.btn_remote_tasks,self.handler_remote)
521                self._block_widget_state(False,self.btn_local_tasks,self.handler_local)
522                tasks=[]
523                names=[]
524#               self.orig_tasks={}
525                self.cmb_task_names.remove_all()
526                tasks=self.scheduler.get_available_tasks()
527                for name in tasks.keys():
528                        print("APPEND: %s"%name)
529                        if name not in names:
530                                names.append(name)
531                                self.i18n['name'].update({_(name):name})
532#                               self.orig_tasks[_(name)]=name
533                                print("PROCESS %s"%name)
534                                self.cmb_task_names.append_text(_(name))
535               
536                self.cmb_task_names.connect('changed',self.load_add_task_details_cmds,tasks)
537                self.cmb_task_names.set_active(0)
538        #def load_add_task_details
539
540        def load_add_task_details_cmds(self,widget,tasks):
541                actions=[]
542                self.i18n['cmd']={}
543                self.cmb_task_cmds.remove_all()
544                task_name=self.cmb_task_names.get_active_text()
545                if task_name:
546#                       orig_name=self.orig_tasks[task_name]
547                        orig_name=self.i18n['name'][task_name]
548                        print(tasks)
549                        for action in tasks[orig_name].keys():
550                                if action not in actions:
551                                        self.i18n['cmd'].update({_(action):action})
552                                        actions.append(action)
553                                        self.cmb_task_cmds.append_text(_(action))
554                self.cmb_task_cmds.set_active(0)
555        #def load_add_task_details_cmds
556       
557        def update_task(self,widget,data=None):
558                self._debug("Updating task")
559                if self.task_details_grid.update_task_details():
560                        self._show_info(_('Task updated'))
561                        self._reload_grid()
562                else:
563                        self._show_info(_('Permission denied'))
564               
565        #def update_task
566
567        def add_task_clicked(self,widget,event):
568                self._debug("Loading new task form")
569                self.add_task_grid.clear_screen()
570                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
571                self.stack.set_visible_child_name("add")
572                if self.btn_remote_tasks.get_active():
573                        self.last_task_type='remote'
574                else:
575                        self.last_task_type='local'
576                self.load_add_task_details()
577        #def add_task_clicked   
578
579        def cancel_add_clicked(self,widget,event=None):
580                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
581                self.stack.set_visible_child_name("tasks")     
582                if self.last_task_type=='remote':
583                        self._block_widget_state(True,self.btn_remote_tasks,self.handler_remote)
584                else:
585                        self._block_widget_state(True,self.btn_local_tasks,self.handler_local)
586                self._debug("Cancel add clicked")
587                self._reload_grid()
588        #def cancel_add_clicked
589
590        def _reload_grid(self,widget=None,data=None):
591                cursor=self.tasks_tv.get_cursor()[0]
592                self._debug("CURSOR %s"%widget)
593                if self.btn_remote_tasks.get_active():
594#                       task_type='remote'
595                        sw_remote=True
596                else:
597#                       task_type='local'
598                        sw_remote=False
599                self._debug("Reload grid")
600                self.populate_tasks_tv(sw_remote)
601                if cursor:
602                        self._debug("Restoring cursor")
603                        self.tasks_tv.set_cursor(cursor)
604
605                if type(widget)==type(Gtk.CheckButton()):
606                        self.task_details_grid.chk_node.connect("toggled",self._reload_grid)
607        #def _reload_grid
608
609        def manage_remove_responses(self,widget,response,model,task_name,task_serial,task_cmd,task_type,data):
610                self.inf_question.hide()
611                if response==Gtk.ResponseType.OK:
612                        self._debug("Removing task %s - %s - %s"%(task_name,task_serial,task_cmd))
613                        if task_name in self.i18n['name'].keys():
614                                name=self.i18n['name'][task_name]
615                        else:
616                                name=task_name
617                        if task_cmd in self.i18n['cmd'].keys():
618                                cmd=self.i18n['cmd'][task_cmd]
619                        else:
620                                cmd=task_cmd
621                        if self.scheduler.remove_task(name,task_serial,cmd,task_type):
622                                self.populate_tasks_tv(task_type)
623                                self.tasks_tv.set_cursor(0)
624                        else:
625                                self._show_info(_("Permission denied"))
626                for widget in self.main_box.get_children():
627                        widget.set_sensitive(True)
628        #def manage_remove_responses
629
630        def _show_info(self,msg):
631                self.lbl_message.set_text(_(msg))
632                self.inf_message.show_all()
633                GObject.timeout_add(5000,self.inf_message.hide)
634        #def _show_info
635       
636        def _manage_tasks(self,widget,event):
637                self._debug("Loading manage tasks form")
638                if self.btn_remote_tasks.get_active():
639                        self.last_task_type='remote'
640                else:
641                        self.last_task_type='local'
642                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
643                self.stack.set_visible_child_name("manage")
644                self._block_widget_state(False,self.btn_remote_tasks,self.handler_remote)
645                self._block_widget_state(False,self.btn_local_tasks,self.handler_local)
646        #def _manage_tasks     
647
648        def _cancel_manage_clicked(self,widget):
649                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
650                self.stack.set_visible_child_name("tasks")     
651                if self.last_task_type=='remote':
652                        self._block_widget_state(True,self.btn_remote_tasks,self.handler_remote)
653                else:
654                        self._block_widget_state(True,self.btn_local_tasks,self.handler_local)
655
656        ###
657        #Changes the state of a widget blocking the signals
658        ###
659        def _block_widget_state(self,state,widget,handler):
660                widget.handler_block(handler)
661                widget.set_active(state)
662                GObject.timeout_add(100,widget.handler_unblock,handler)
663        #def _block_widget_state
664       
665        def set_css_info(self):
666       
667                css = b"""
668                #WHITE_BACKGROUND {
669                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ffffff),  to (#ffffff));;
670               
671                }
672
673                #BLUE_FONT {
674                        color: #3366cc;
675                        font: Roboto Bold 11;
676                       
677                }       
678               
679
680                #TASKGRID_FONT {
681                        color: #3366cc;
682                        font: Roboto 11;
683                       
684                }
685
686                #LABEL_OPTION{
687               
688                        color: #808080;
689                        font: Roboto 11;
690                }
691
692                #ERROR_FONT {
693                        color: #CC0000;
694                        font: Roboto Bold 11;
695                }
696                """
697                self.style_provider=Gtk.CssProvider()
698                self.style_provider.load_from_data(css)
699                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
700               
701                self.window.set_name("WHITE_BACKGROUND")
702                self.tasks_box.set_name("WHITE_BACKGROUND")
703        #def set_css_info       
704
705        def quit(self,widget,event=None):
706                Gtk.main_quit() 
707        #def quit       
708
709#class TaskScheduler
710
711GObject.threads_init()
712t=TaskScheduler()
713t.start_gui()           
Note: See TracBrowser for help on using the repository browser.