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

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

WIP on expert mode

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