source: bell-scheduler/trunk/fuentes/bell-scheduler/python3-bellscheduler/MainWindow.py @ 6871

Last change on this file since 6871 was 6871, checked in by jrpelegrina, 19 months ago

Fix files and added translations

File size: 14.7 KB
Line 
1#!/usr/bin/env python3
2
3import gi
4gi.require_version('Gtk', '3.0')
5from gi.repository import Gtk, Pango, GdkPixbuf, Gdk, Gio, GObject,GLib
6
7
8
9import signal
10import os
11import subprocess
12import json
13import sys
14import syslog
15import time
16import threading
17import tempfile
18from shutil import copyfile
19
20from edupals.ui.n4dgtklogin import *
21import signal
22signal.signal(signal.SIGINT, signal.SIG_DFL)
23
24
25from . import settings
26import gettext
27gettext.textdomain(settings.TEXT_DOMAIN)
28_ = gettext.gettext
29
30class MainWindow:
31       
32        def __init__(self):
33
34                self.core=Core.Core.get_core()
35
36        #def init
37
38       
39        def load_gui(self):
40               
41                builder=Gtk.Builder()
42                builder.set_translation_domain(settings.TEXT_DOMAIN)
43                ui_path=self.core.ui_path
44                builder.add_from_file(ui_path)
45
46                self.css_file=self.core.rsrc_dir+"bell-scheduler.css"
47                               
48                self.stack_window= Gtk.Stack()
49                self.stack_window.set_transition_duration(1500)
50                self.stack_window.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
51                self.stack_window.set_margin_top(0)
52                self.stack_window.set_margin_bottom(0)
53               
54                self.main_window=builder.get_object("main_window")
55                self.main_window.set_title("Bell Scheduler")
56                self.main_box=builder.get_object("main_box")
57                self.login=N4dGtkLogin()
58                self.login.set_allowed_groups(['adm','teachers'])
59                self.login.hide_server_entry()
60                desc=_("Welcome to the Bell Scheduler.\nFrom here you can program multiple alarms for entry, exit, recess or any other event")
61                self.login.set_info_text("<span foreground='black'>Bell Scheduler</span>",_("Bell Scheduler"),"<span foreground='black'>"+desc+"</span>\n")
62                image=os.path.join(self.core.rsrc_dir,"bell.png")
63                self.login.set_info_background(image=image,cover=True)
64                self.login.after_validation_goto(self._signin)
65
66                self.option_box=builder.get_object("options_box")
67                self.add_button=builder.get_object("add_button")
68                self.export_button=builder.get_object("export_button")
69                self.import_button=builder.get_object("import_button")
70                self.search_entry=builder.get_object("search_entry")
71                self.msg_label=builder.get_object("msg_label")
72                self.save_button=builder.get_object("save_button")
73                self.cancel_button=builder.get_object("cancel_button")
74                #self.banner_box=builder.get_object("banner_box")
75
76                self.waiting_window=builder.get_object("waiting_window")
77                self.waiting_label=builder.get_object("waiting_plabel")
78                self.waiting_pbar=builder.get_object("waiting_pbar")
79                self.waiting_window.set_transient_for(self.main_window)
80
81                self.bellBox=self.core.bellBox
82                self.editBox=self.core.editBox
83
84                self.stack_window.add_titled(self.login, "login", "Login")
85                self.stack_window.add_titled(self.option_box,"optionBox", "Option Box")
86                self.stack_window.show_all()
87                self.main_box.pack_start(self.stack_window,True,True,0)
88
89                self.stack_opt= Gtk.Stack()
90                self.stack_opt.set_transition_duration(1500)
91                self.stack_opt.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
92
93                self.stack_opt.add_titled(self.bellBox,"bellBox", "Bell Box")
94                self.stack_opt.add_titled(self.editBox,"editBox", "Edit Box")
95               
96                self.stack_opt.show_all()
97
98                self.option_box.pack_start(self.stack_opt,True,True,5)
99               
100                self.set_css_info()
101                self.init_threads()
102                self.connect_signals()
103                self.manage_menubar(True,True)
104                self.manage_down_buttons(False)
105                self.cont=0
106                self.main_window.show()
107                self.stack_window.set_transition_type(Gtk.StackTransitionType.NONE)
108                self.stack_window.set_visible_child_name("login")
109               
110                '''
111                self.manage_down_buttons(False)
112                self.load_info()
113                self.core.bellBox.draw_bell(False)
114                '''
115               
116        #def load_gui
117
118
119        def init_threads(self):
120
121                self.export_bells_t=threading.Thread(target=self.export_bells)
122                self.import_bells_t=threading.Thread(target=self.import_bells)
123                self.recovery_bells_t=threading.Thread(target=self.recovery_bells)
124
125                self.export_bells_t.daemon=True
126                self.import_bells_t.daemon=True
127                self.recovery_bells_t.daemon=True
128
129                self.export_bells_t.launched=False
130                self.import_bells_t.launched=False
131                self.recovery_bells_t.launched=False
132
133                GObject.threads_init()
134
135        #def init_threads       
136
137        def set_css_info(self):
138               
139               
140                self.style_provider=Gtk.CssProvider()
141                f=Gio.File.new_for_path(self.css_file)
142                self.style_provider.load_from_file(f)
143                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
144                self.main_window.set_name("WINDOW")
145                self.waiting_label.set_name("WAITING_LABEL")
146                #self.banner_box.set_name("BANNER_BOX")
147
148        #def set_css_info       
149                               
150                       
151        def connect_signals(self):
152               
153                self.main_window.connect("destroy",self.quit)
154                self.add_button.connect("clicked",self.add_bell)
155                self.save_button.connect("clicked",self.core.editBox.gather_values)
156                self.cancel_button.connect("clicked",self.cancel_clicked)
157                self.export_button.connect("clicked",self.export_clicked)
158                self.import_button.connect("clicked",self.import_clicked)
159                self.search_entry.connect("changed",self.search_entry_changed)
160
161        #def connect_signals   
162
163                               
164        def _signin(self,user,pwd,server):
165
166                self.core.bellmanager.credentials=[user,pwd]
167                self.manage_down_buttons(False)
168                self.manage_menubar(True)
169                self.core.bellmanager.sync_with_cron()
170                self.load_info()
171                self.core.bellBox.draw_bell(False)
172                self.stack_window.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
173                self.stack_window.set_visible_child_name("optionBox")
174
175        #def _signin   
176
177        def load_info(self):
178       
179                self.read_conf=self.core.bellmanager.read_conf()
180                self.bells_info=self.core.bellmanager.bells_config.copy()
181                self.order_bells=self.core.bellmanager.get_order_bell() 
182                if not self.read_conf['status']:
183                        if self.cont==0:
184                                self.manage_message(True,self.read_conf['code'])
185       
186        #def load_info 
187
188        def add_bell(self,widget):
189
190                self.manage_menubar(False)
191                self.manage_down_buttons(True)
192                self.core.editBox.init_form()
193                self.core.editBox.render_form()
194                self.stack_opt.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
195                self.stack_opt.set_visible_child_name("editBox")
196
197        #def add_bell   
198
199
200        def cancel_clicked(self,widget):
201
202                self.manage_menubar(True)
203                self.manage_down_buttons(False)
204                self.core.editBox.remove(self.core.editBox.main_box)
205                self.stack_opt.set_transition_type(Gtk.StackTransitionType.SLIDE_RIGHT)
206                self.stack_opt.set_visible_child_name("bellBox")
207               
208        #def cancel_clicked     
209
210        def export_clicked(self,widget):
211
212                dialog = Gtk.FileChooserDialog(_("Please choose a file to save bells list"), None,
213                Gtk.FileChooserAction.SAVE,(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
214                Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
215                dialog.set_do_overwrite_confirmation(True)
216                response = dialog.run()
217               
218                if response == Gtk.ResponseType.OK:
219                        self.dest=dialog.get_filename()
220                        dialog.destroy()
221                        self.waiting_label.set_text(self.get_msg(26))                   
222                        self.waiting_window.show_all()
223                        self.init_threads()
224                        self.export_bells_t.start()
225                        GLib.timeout_add(100,self.pulsate_export_bells)
226                dialog.destroy()       
227
228        #def export_clicked     
229
230        def pulsate_export_bells(self):
231
232                if self.export_bells_t.is_alive():
233                        self.waiting_pbar.pulse()
234                        return True
235
236                else:
237                        self.waiting_window.hide()
238                        if self.export_result['status']:
239                                self.manage_message(False,self.export_result['code'])
240                        else:
241                                self.manage_message(True,self.export_result['code'])
242
243                return False
244
245        #def pulsate_export_bell       
246
247        def export_bells(self):
248
249                self.export_result=self.core.bellmanager.export_bells_conf(self.dest)                           
250       
251        #def export_bells
252
253        def import_clicked(self,widget):
254
255                self.loading_errors=False
256                self.backup=True
257
258                dialog = Gtk.MessageDialog(None,0,Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, "BELL SCHEDULER")
259                dialog.format_secondary_text(_("New bells configurarion will be loaded and replace the existing configutarion. Do you want to continue?"))
260                response=dialog.run()
261                dialog.destroy()
262                if response == Gtk.ResponseType.YES:
263                        dialog = Gtk.FileChooserDialog(_("Please choose a file to load bells list"), None,
264                        Gtk.FileChooserAction.OPEN,(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
265                        Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
266                        response = dialog.run()
267                        if response == Gtk.ResponseType.OK:
268                                self.orig=dialog.get_filename()
269                                dialog.destroy()
270                                self.waiting_label.set_text(self.get_msg(27))                   
271                                self.waiting_window.show_all()
272                                self.init_threads()
273                                self.import_bells_t.start()
274                                GLib.timeout_add(100,self.pulsate_import_bells)
275
276                dialog.destroy()
277                               
278        #def import_clicked
279
280        def pulsate_import_bells(self):
281
282                if self.import_bells_t.is_alive():
283                        self.waiting_pbar.pulse()
284                        return True
285
286                else:
287                        self.waiting_window.hide()
288                        if self.import_result['status']:
289                                self.load_info()
290                                if self.read_conf['status']:
291                                        try:
292                                                self.core.bellBox.draw_bell(False)
293                                                if not self.loading_errors:
294                                                        self.manage_message(False,self.import_result['code'])
295                                                else:
296                                                        self.manage_message(True,13)   
297                                        except:
298                                                self.backup=False
299                                                self.orig=self.import_result['data']+".zip"
300                                                self.init_threads()
301                                                self.recovery_bells_t.start()
302                                                self.waiting_label.set_text(self.get_msg(28))
303                                                GLib.timeout_add(100,self.pulsate_recovery_bells)
304                                                return False   
305                                else:
306                                        self.manage_message(True,self.read_conf['code'])       
307                                        self.cont=0
308                                        return False
309
310                        else:
311                                self.manage_message(True,self.import_result['code'])   
312                                self.cont=0
313                                return False
314
315        #def pulsate_import_bells
316
317        def import_bells(self):
318
319                self.import_result=self.core.bellmanager.import_bells_conf(self.orig,self.backup)
320
321        #def import_bells               
322
323
324        def pulsate_recovery_bells(self):
325
326                if self.recovery_bells_t.is_alive():
327                        self.waiting_pbar.pulse()
328                        return True
329
330                else:
331                        self.waiting_window.hide()
332                        self.load_info()
333                        try:
334                                self.core.bellBox.draw_bell(False)
335                                if not self.loading_errors:
336                                        self.manage_message(True,9)
337                                else:
338                                        self.manage_message(True,9)     
339                        except:
340                                self.manage_message(True,self.recovery_result['code']) 
341                                return False   
342
343                return False
344       
345        #def pulsate_recovery_bells             
346       
347       
348        def recovery_bells(self):
349
350                self.recovery_result=self.core.bellmanager.recovery_bells_conf(self.orig,self.backup)           
351
352        #def recovery_bells
353
354        def search_entry_changed(self,widget):
355
356                self.core.bellBox.init_bell_list() 
357                self.load_info()
358                self.search_list=self.bells_info.copy()
359
360                search=self.search_entry.get_text().lower()
361                if search=="":
362                        self.core.bellBox.draw_bell(False)
363                else:
364                        for item in self.bells_info:
365                                time=self.core.bellmanager.format_time(item)
366                                hour=str(time[0])
367                                minute=str(time[1])
368                                cron=str(time[2])
369                                name=self.bells_info[item]["name"].lower()
370                                days=[]
371                                if self.bells_info[item]["weekdays"]["0"]:
372                                        days.append(_("Monday"))
373                                        days.append(_("M"))
374                                        days.append(_("Mon"))
375                                if self.bells_info[item]["weekdays"]["1"]:
376                                        days.append(_("Tuesday"))
377                                        days.append(_("T"))
378                                        days.append(_("Tue"))
379                                if self.bells_info[item]["weekdays"]["2"]:
380                                        days.append(_("Wednesday"))     
381                                        days.append(_("W"))
382                                        days.append(_("Wed"))
383                                if self.bells_info[item]["weekdays"]["3"]:
384                                        days.append(_("Thursday"))
385                                        days.append(_("R"))
386                                        days.append(_("Thu"))
387                                if self.bells_info[item]["weekdays"]["4"]:
388                                        days.append(_("Friday"))
389                                        days.append(_("F"))     
390                                        days.append(_("Fri"))
391
392                               
393                                if search in hour or search in minute or search in name or search in cron or search in [ x.lower() for x in days]:
394                                        pass
395                                else:
396                                        self.search_list.pop(item)
397
398                        if len(self.search_list)>0:
399                                        self.search_order=self.core.bellmanager.get_order_bell(self.search_list)               
400                                        self.core.bellBox.draw_bell(True)
401                       
402        #def search_entry_changed                               
403
404        def manage_menubar(self,active,hide=None):
405       
406                if hide:
407                        self.add_button.hide()
408                        self.import_button.hide()
409                        self.export_button.hide()
410                        self.search_entry.hide()
411                else:
412                        self.add_button.show()
413                        self.import_button.show()
414                        self.export_button.show()
415                        self.search_entry.show()
416
417                if active:
418                        self.add_button.set_sensitive(True)
419                        self.import_button.set_sensitive(True)
420                        self.export_button.set_sensitive(True)
421                        self.search_entry.set_sensitive(True)
422                else:
423                        self.add_button.set_sensitive(False)
424                        self.import_button.set_sensitive(False)
425                        self.export_button.set_sensitive(False)
426                        self.search_entry.set_sensitive(False)
427
428        #def manage_menubar             
429
430       
431        def manage_down_buttons(self,show):
432       
433                if show:
434                        self.cancel_button.show()
435                        self.save_button.show()
436                        self.msg_label.hide()
437                else:
438                        self.cancel_button.hide()
439                        self.save_button.hide()
440                        self.msg_label.hide()
441
442        #def manage_down_buttons                                       
443
444                       
445        def manage_message(self,error,code):
446
447                msg=self.get_msg(code)
448               
449                if error:
450                        self.msg_label.set_name("MSG_ERROR_LABEL")
451                else:
452                        self.msg_label.set_name("MSG_CORRECT_LABEL")   
453
454                self.msg_label.set_text(msg)
455                self.msg_label.show()
456
457        #def manage_message             
458
459
460        def get_msg(self,code):
461
462                if      code==1:
463                        msg_text=_("You must indicate a name for the alarm")
464                elif code==2:
465                        msg_text=_("Sound file is not correct")
466                elif code==3:
467                        msg_text=_("You must indicate sound file")
468                elif code==4:
469                        msg_text=_("Image file is not correct")
470                elif code==5:
471                        msg_text=_("You must indicate a image file")
472                elif code==6:
473                        msg_text=_("You must indicate a url")
474                elif code==7:
475                        msg_text=_("You must indicate a directory")     
476                elif code==8:
477                        msg_text=_("Max durartion must be major than 0")
478                elif code==9:
479                        msg_text=_("File has errors. Unabled to load it")
480                elif code==10:
481                        msg_text=_("File loaded succesfully")
482                elif code==11:
483                        msg_text=_("File saved succcesfully")
484                elif code==12:
485                        msg_text=_("Unable to save file")       
486                elif code==13:
487                        msg_text=_("File loaded with errors")   
488                elif code==14:
489                        msg_text=_("Bell deleted successfully") 
490                elif code==15:
491                        msg_text=_("Bell edited successfully")
492                elif code==16:
493                        msg_text=_("Bell activated successfully")
494                elif code==17:
495                        msg_text=_("Bell deactivated successfully")
496                elif code==18:
497                        msg_text=_("Bell created successfully")         
498                elif code==19:
499                        msg_text=_("Unabled to edit the Bell due to problems with cron sync")   
500                elif code==20:
501                        msg_text=_("Unabled to create the Bell due to problems with cron sync")
502                elif code==21:
503                        msg_text=_("Unabled to delete the Bell due to problems with cron sync") 
504                elif code==22:
505                        msg_text=_("Unabled to activate the Bell due to problems with cron sync")       
506                elif code==23:
507                        msg_text=_("Unabled to deactivate the Bell due to problems with cron sync")     
508                elif code==24:
509                        msg_text=_("Unabled to copy image and/or sound file to work directory") 
510                elif code==25:
511                        msg_text=_("Unabled to read bells configuration file") 
512                elif code==26:
513                        msg_text=_("Exporting bells configuration. Wait a moment...")   
514                elif code==27:
515                        msg_text=_("Importing bells configuration. Wait a moment...")
516                elif code==28:
517                        msg_text=_("Revovering previous bells configuration. Wait a moment...") 
518                elif code==29:
519                        msg_text=("ERROR: File or directory not available")                             
520                               
521                       
522                return msg_text
523
524        #def get_msg   
525                       
526
527        def quit(self,widget):
528
529                Gtk.main_quit() 
530
531        #def quit       
532
533        def start_gui(self):
534               
535                GObject.threads_init()
536                Gtk.main()
537               
538        #def start_gui
539
540
541       
542#class MainWindow
543
544from . import Core
Note: See TracBrowser for help on using the repository browser.