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

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

Fix setup.py files

File size: 14.5 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(_("Exporting bells configuration. Wait a moment..."))                       
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
227        #def export_clicked     
228
229        def pulsate_export_bells(self):
230
231                if self.export_bells_t.is_alive():
232                        self.waiting_pbar.pulse()
233                        return True
234
235                else:
236                        self.waiting_window.hide()
237                        if self.export_result['status']:
238                                self.manage_message(False,self.export_result['code'])
239                        else:
240                                self.manage_message(True,self.export_result['code'])
241
242                return False
243
244        #def pulsate_export_bell       
245
246        def export_bells(self):
247
248                self.export_result=self.core.bellmanager.export_bells_conf(self.dest)                           
249       
250        #def export_bells
251
252        def import_clicked(self,widget):
253
254                self.loading_errors=False
255                self.backup=True
256
257                dialog = Gtk.MessageDialog(None,0,Gtk.MessageType.WARNING, Gtk.ButtonsType.YES_NO, "BELL SCHEDULER")
258                dialog.format_secondary_text(_("New bells configurarion will be loaded and replace the existing configutarion. Do you want to continue?"))
259                response=dialog.run()
260                dialog.destroy()
261                if response == Gtk.ResponseType.YES:
262                        dialog = Gtk.FileChooserDialog(_("Please choose a file to load bells list"), None,
263                        Gtk.FileChooserAction.OPEN,(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
264                        Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
265                        response = dialog.run()
266                        if response == Gtk.ResponseType.OK:
267                                self.orig=dialog.get_filename()
268                                dialog.destroy()
269                                self.waiting_label.set_text(_("Importing bells configuration. Wait a moment..."))                       
270                                self.waiting_window.show_all()
271                                self.init_threads()
272                                self.import_bells_t.start()
273                                GLib.timeout_add(100,self.pulsate_import_bells)
274
275                dialog.destroy()
276                               
277        #def import_clicked
278
279        def pulsate_import_bells(self):
280
281                if self.import_bells_t.is_alive():
282                        self.waiting_pbar.pulse()
283                        return True
284
285                else:
286                        self.waiting_window.hide()
287                        if self.import_result['status']:
288                                self.load_info()
289                                if self.read_conf['status']:
290                                        try:
291                                                self.core.bellBox.draw_bell(False)
292                                                if not self.loading_errors:
293                                                        self.manage_message(False,self.import_result['code'])
294                                                else:
295                                                        self.manage_message(True,13)   
296                                        except:
297                                                self.backup=False
298                                                self.orig=self.import_result['data']+".zip"
299                                                self.init_threads()
300                                                self.recovery_bells_t.start()
301                                                self.waiting_label.set_text(_("Revovering previous bells configuration. Wait a moment..."))
302                                                GLib.timeout_add(100,self.pulsate_recovery_bells)
303                                                return False   
304                                else:
305                                        self.manage_message(True,self.read_conf['code'])       
306                                        self.cont=0
307                                        return False
308
309                        else:
310                                self.manage_message(True,self.import_result['code'])   
311                                self.cont=0
312                                return False
313
314        #def pulsate_import_bells
315
316        def import_bells(self):
317
318                self.import_result=self.core.bellmanager.import_bells_conf(self.orig,self.backup)
319
320        #def import_bells               
321
322
323        def pulsate_recovery_bells(self):
324
325                if self.recovery_bells_t.is_alive():
326                        self.waiting_pbar.pulse()
327                        return True
328
329                else:
330                        self.waiting_window.hide()
331                        self.load_info()
332                        try:
333                                self.core.bellBox.draw_bell(False)
334                                if not self.loading_errors:
335                                        self.manage_message(True,9)
336                                else:
337                                        self.manage_message(True,9)     
338                        except:
339                                self.manage_message(True,self.recovery_result['code']) 
340                                return False   
341
342                return False
343       
344        #def pulsate_recovery_bells             
345       
346       
347        def recovery_bells(self):
348
349                self.recovery_result=self.core.bellmanager.recovery_bells_conf(self.orig,self.backup)           
350
351        #def recovery_bells
352
353        def search_entry_changed(self,widget):
354
355                self.core.bellBox.init_bell_list() 
356                self.load_info()
357                self.search_list=self.bells_info.copy()
358
359                search=self.search_entry.get_text().lower()
360                if search=="":
361                        self.core.bellBox.draw_bell(False)
362                else:
363                        for item in self.bells_info:
364                                time=self.core.bellmanager.format_time(item)
365                                hour=str(time[0])
366                                minute=str(time[1])
367                                cron=str(time[2])
368                                name=self.bells_info[item]["name"].lower()
369                                days=[]
370                                if self.bells_info[item]["weekdays"]["0"]:
371                                        days.append(_("Monday"))
372                                        days.append(_("M"))
373                                        days.append(_("Mon"))
374                                if self.bells_info[item]["weekdays"]["1"]:
375                                        days.append(_("Thuesday"))
376                                        days.append(_("T"))
377                                        days.append(_("Thue"))
378                                if self.bells_info[item]["weekdays"]["2"]:
379                                        days.append(_("Wednesday"))     
380                                        days.append(_("W"))
381                                        days.append(_("Wed"))
382                                if self.bells_info[item]["weekdays"]["3"]:
383                                        days.append(_("Thursday"))
384                                        days.append(_("R"))
385                                        days.append(_("Thur"))
386                                if self.bells_info[item]["weekdays"]["4"]:
387                                        days.append(_("Friday"))
388                                        days.append(_("F"))     
389                                        days.append(_("Fri"))
390
391                               
392                                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]:
393                                        pass
394                                else:
395                                        self.search_list.pop(item)
396
397                        if len(self.search_list)>0:
398                                        self.search_order=self.core.bellmanager.get_order_bell(self.search_list)               
399                                        self.core.bellBox.draw_bell(True)
400                       
401        #def search_entry_changed                               
402
403        def manage_menubar(self,active,hide=None):
404       
405                if hide:
406                        self.add_button.hide()
407                        self.import_button.hide()
408                        self.export_button.hide()
409                        self.search_entry.hide()
410                else:
411                        self.add_button.show()
412                        self.import_button.show()
413                        self.export_button.show()
414                        self.search_entry.show()
415
416                if active:
417                        self.add_button.set_sensitive(True)
418                        self.import_button.set_sensitive(True)
419                        self.export_button.set_sensitive(True)
420                        self.search_entry.set_sensitive(True)
421                else:
422                        self.add_button.set_sensitive(False)
423                        self.import_button.set_sensitive(False)
424                        self.export_button.set_sensitive(False)
425                        self.search_entry.set_sensitive(False)
426
427        #def manage_menubar             
428
429       
430        def manage_down_buttons(self,show):
431       
432                if show:
433                        self.cancel_button.show()
434                        self.save_button.show()
435                        self.msg_label.hide()
436                else:
437                        self.cancel_button.hide()
438                        self.save_button.hide()
439                        self.msg_label.hide()
440
441        #def manage_down_buttons                                       
442
443                       
444        def manage_message(self,error,code):
445
446                msg=self.get_msg(code)
447               
448                if error:
449                        self.msg_label.set_name("MSG_ERROR_LABEL")
450                else:
451                        self.msg_label.set_name("MSG_CORRECT_LABEL")   
452
453                self.msg_label.set_text(msg)
454                self.msg_label.show()
455
456        #def manage_message             
457
458
459        def get_msg(self,code):
460
461                if      code==1:
462                        msg_text=_("You must indicate a name for the alarm")
463                elif code==2:
464                        msg_text=_("Sound file is not correct")
465                elif code==3:
466                        msg_text=_("You must indicate sound file")
467                elif code==4:
468                        msg_text=_("Image file is not correct")
469                elif code==5:
470                        msg_text=_("You must indicate a image file")
471                elif code==6:
472                        msg_text=_("You must indicate a url")
473                elif code==7:
474                        msg_text=_("You must indicate a directory")     
475                elif code==8:
476                        msg_text=_("Max durartion must be major than 0")
477                elif code==9:
478                        msg_text=_("File has errors. Unabled to load it")
479                elif code==10:
480                        msg_text=_("File loaded succesfully")
481                elif code==11:
482                        msg_text=_("File saved succcesfully")
483                elif code==12:
484                        msg_text=_("Unable to save file")       
485                elif code==13:
486                        msg_text=_("File loaded with errors")   
487                elif code==14:
488                        msg_text=_("Bell deleted successfully") 
489                elif code==15:
490                        msg_text=_("Bell edited successfully")
491                elif code==16:
492                        msg_text=_("Bell activated successfully")
493                elif code==17:
494                        msg_text=_("Bell deactivated successfully")
495                elif code==18:
496                        msg_text=_("Bell created successfully")         
497                elif code==19:
498                        msg_text=_("Unabled to edit the Bell due to problems with cron sync")   
499                elif code==20:
500                        msg_text=_("Unabled to create the Bell due to problems with cron sync")
501                elif code==21:
502                        msg_text=_("Unabled to delete the Bell due to problems with cron sync") 
503                elif code==22:
504                        msg_text=_("Unabled to activate the Bell due to problems with cron sync")       
505                elif code==23:
506                        msg_text=_("Unabled to deactivate the Bell due to problems with cron sync")     
507                elif code==24:
508                        msg_text=_("Unabled to copy image and/or sound file to work directory") 
509                elif code==25:
510                        msg_text=_("Unabled to read bells configuration file")         
511                               
512                       
513                return msg_text
514
515        #def get_msg   
516                       
517
518        def quit(self,widget):
519
520                Gtk.main_quit() 
521
522        #def quit       
523
524        def start_gui(self):
525               
526                GObject.threads_init()
527                Gtk.main()
528               
529        #def start_gui
530
531
532       
533#class MainWindow
534
535from . import Core
Note: See TracBrowser for help on using the repository browser.