source: lliurex-remote-installer/trunk/fuentes/lliurex-remote-installer-gui.install/usr/share/lliurex-remote-installer/AptBox.py @ 4473

Last change on this file since 4473 was 4473, checked in by Juanma, 4 years ago

WIP on locale

File size: 14.2 KB
Line 
1import gi
2gi.require_version('Gtk', '3.0')
3from gi.repository import Gtk, Pango, GdkPixbuf, Gdk, Gio, GObject,GLib
4
5import copy
6import gettext
7import Core
8
9import Dialog
10import time
11import threading
12import sys
13
14gettext.textdomain('lliurex-remote-installer-gui')
15_=gettext.gettext
16
17
18RSRC="./"
19
20
21class AptBox(Gtk.VBox):
22       
23        def __init__(self):
24               
25                Gtk.VBox.__init__(self)
26               
27                self.core=Core.Core.get_core()
28               
29                builder=Gtk.Builder()
30                builder.set_translation_domain('lliurex-remote-installer-gui')
31                ui_path=RSRC + "lliurex-remote-installer.ui"
32
33                builder.add_from_file(ui_path)
34                self.main_box=builder.get_object("section_box")
35                self.list_box=builder.get_object("list_box")
36                self.package_list_box=builder.get_object("package_list_box")
37                self.package_list_vp=builder.get_object("package_list_viewport")
38                self.add_package_button=builder.get_object("add_package_button")
39                self.delete_apt_button=builder.get_object("delete_button")
40                self.add_apt_button=builder.get_object("add_button")
41                self.apply_button=builder.get_object("apply_button")
42                self.url_entry=builder.get_object("url_entry")
43                self.data_box=builder.get_object("apt_data_box")
44                self.data_vp=builder.get_object("apt_data_viewport")
45                self.package_label=builder.get_object("package_label")
46                self.url_label=builder.get_object("url_label")
47                self.new_package_window=builder.get_object("new_package_window")
48                self.new_apt_window=builder.get_object("new_apt_window")
49                self.cancel_apt_button=builder.get_object("cancel_apt_button")
50                self.accept_apt_button=builder.get_object("accept_apt_button")
51                self.cancel_add_package_button=builder.get_object("cancel_add_package_button")
52                self.accept_add_package_button=builder.get_object("accept_add_package_button")
53                self.apt_name_entry=builder.get_object("apt_name_entry")
54                self.apt_url_entry=builder.get_object("apt_url_entry")
55                self.apt_msg_label=builder.get_object("apt_msg_label")
56                self.package_msg_label=builder.get_object("package_msg_label")
57                self.apply_changes_button=builder.get_object("apply_changes_button")
58                self.package_list_entry=builder.get_object("package_list_entry")
59               
60               
61                self.stack=Gtk.Stack()
62                self.stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
63                self.stack.set_transition_duration(250)
64                hbox=Gtk.HBox()
65                hbox.show()
66                self.stack.add_titled(hbox,"empty","Empty Box")
67                self.stack.add_titled(self.data_box,"apt_data","Apt Data Box")
68                self.data_vp.add(self.stack)
69               
70                self.pack_start(self.main_box,True,True,0)
71               
72               
73                self.connect_signals()
74                self.set_css_info()
75               
76                self.core.current_var=None
77                self.current_id=None
78               
79                self.thread=threading.Thread()
80                self.thread_ret=None
81               
82               
83               
84        #def __init__
85       
86
87        def set_css_info(self):
88               
89                self.style_provider=Gtk.CssProvider()
90                f=Gio.File.new_for_path("lliurex-remote-installer.css")
91                self.style_provider.load_from_file(f)
92                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
93                self.package_label.set_name("OPTION_LABEL")
94                self.url_label.set_name("OPTION_LABEL")
95               
96                       
97        #def set-css_info
98       
99       
100        def connect_signals(self):
101               
102                self.add_apt_button.connect("clicked",self.add_apt_button_clicked)
103                self.delete_apt_button.connect("clicked",self.delete_apt_button_clicked)
104                self.add_package_button.connect("clicked",self.add_package_clicked)
105               
106                self.accept_add_package_button.connect("clicked",self.accept_add_package_button_clicked)
107                self.cancel_add_package_button.connect("clicked",self.cancel_add_package_button_clicked)
108               
109                self.accept_apt_button.connect("clicked",self.accept_apt_button_clicked)
110                self.cancel_apt_button.connect("clicked",self.cancel_apt_button_clicked)
111               
112                self.apply_changes_button.connect("clicked",self.apply_changes_button_clicked)
113                self.url_entry.connect("changed",self.url_entry_changed)
114               
115                self.new_package_window.connect("delete_event",self.hide_window)
116                self.new_apt_window.connect("delete_event",self.hide_window)
117               
118        #def connect_signals
119       
120       
121        def hide_window(self,widget,event):
122               
123                widget.hide()
124                return True
125               
126        #def new_package_window
127
128
129        def check_changes(self,widget=True,event=True,manage_dialog=False):
130               
131               
132                if not manage_dialog:
133                        if self.core.current_var==None:
134                                return False
135                        return self.core.current_var != self.core.var
136               
137               
138                if self.core.current_var!=None and self.core.current_var != self.core.var:
139                        if not self.changes_detected_dialog(False):
140                                return True
141               
142                sys.exit(0)
143                       
144
145        #def check_changes
146               
147       
148        def set_info(self,info):
149               
150                #Empty list
151                for x in self.list_box.get_children():
152                        self.list_box.remove(x)
153               
154                self.core.var=info
155               
156                times=1
157               
158                for t in range(0,times):
159                        if self.core.var["apt"] not in [{},"",None,'{}']:
160                                for x in self.core.var["apt"]:
161                                        self.new_apt_button(x)
162                       
163                self.core.current_var=copy.deepcopy(self.core.var)
164                self.list_box.show_all()
165               
166
167        #def set_info
168       
169
170        def new_apt_button(self,source_name):
171               
172                new_source_name=source_name
173               
174                if len(source_name) > 8:
175                       
176                        new_source_name=source_name[0:7]+"..."
177               
178                b=Gtk.Button(new_source_name)
179                b.connect("clicked",self.apt_clicked,source_name)
180                b.set_size_request(100,100)
181                b.set_halign(Gtk.Align.START)
182                b.set_name("OPTION_BUTTON")
183                b.show_all()
184                self.list_box.pack_start(b,False,False,5)
185                b.queue_draw()
186                b.set_tooltip_text(source_name)
187               
188                return b
189               
190        #def new_apt_button
191
192       
193        def new_package_button(self,pkg_name):
194               
195                hbox=Gtk.HBox()
196                label=Gtk.Label(pkg_name)
197                b=Gtk.Button()
198                i=Gtk.Image.new_from_file("trash.svg")
199                b.add(i)
200                b.set_halign(Gtk.Align.CENTER)
201                b.set_valign(Gtk.Align.CENTER)
202                b.set_name("DELETE_ITEM_BUTTON")
203                b.connect("clicked",self.delete_package_clicked,hbox)
204                hbox.pack_start(label,False,False,0)
205                hbox.pack_end(b,False,False,10)
206                hbox.show_all()
207                label.set_margin_right(20)
208                label.set_margin_left(20)
209                label.set_margin_top(20)
210                label.set_margin_bottom(20)
211                hbox.set_name("PKG_BOX")
212                self.package_list_box.pack_start(hbox,False,False,5)
213                self.package_list_box.queue_draw()
214                hbox.queue_draw()
215               
216        #def new_package_button
217       
218       
219        # ## APT ### ################################################
220       
221        def apt_clicked(self,widget,apt_id,ignore_changes=False):
222               
223               
224                if not ignore_changes:
225                       
226                        if self.core.current_var!=None:
227                                if self.check_changes():
228                                        if not self.changes_detected_dialog(False):
229                                                return
230                       
231                        if apt_id !=self.current_id:
232                                self.core.current_var=copy.deepcopy(self.core.var)
233                               
234                self.current_id=apt_id
235               
236                self.stack.set_visible_child_name("apt_data")
237
238                for b in self.list_box.get_children():
239                        b.set_name("OPTION_BUTTON")
240                       
241                widget.set_name("SELECTED_OPTION_BUTTON")
242                       
243               
244                for x in self.package_list_box.get_children():
245                        self.package_list_box.remove(x)
246                       
247                self.url_entry.set_text(self.core.current_var["apt"][apt_id]["url"])
248                       
249                for x in self.core.current_var["apt"][apt_id]["packages"]:
250                        self.new_package_button("%s"%x)
251                               
252                               
253                self.package_list_box.show_all()
254               
255                if not ignore_changes:
256               
257                        for apt in self.list_box:
258                                if apt.get_tooltip_text() not in self.core.current_var["apt"]:
259                                        self.list_box.remove(apt)
260                       
261               
262               
263                #self.core.lri.main_window.connect("delete_event",self.check_changes,True)
264               
265               
266        #def apt_clicked
267       
268        def add_apt_button_clicked(self,widget):
269               
270                self.apt_name_entry.set_text("")
271                self.apt_url_entry.set_text("")
272                self.apt_msg_label.set_text("")
273                self.new_apt_window.show()
274               
275        #def add_button_clicked
276       
277       
278        def delete_apt_button_clicked(self,widget):
279               
280                if self.current_id==None:
281                        return
282               
283                if self.delete_apt_dialog(self.current_id):
284                        for apt_button in self.list_box.get_children():
285                               
286                                if apt_button.get_tooltip_text() == self.current_id:
287                                        self.list_box.remove(apt_button)
288                                        self.stack.set_visible_child_name("empty")
289                                        self.core.var["apt"].pop(self.current_id)
290                                        self.current_id=None
291                                        self.core.current_var=None
292                                        self.core.n4d.set_variable(self.core.var)
293               
294        #def add_button_clicked
295       
296        def accept_apt_button_clicked(self,widget):
297               
298               
299                name=self.apt_name_entry.get_text()
300                source=self.apt_url_entry.get_text()
301               
302                if len(name) < 1 or len(source) < 8:
303                        self.apt_msg_label.set_markup("<span foreground='red'>"+"Invalid values"+"</span>")
304                        return
305                if name in self.core.var["apt"]:
306                        self.apt_msg_label.set_markup("<span foreground='red'>"+"Apt name already exists"+"</span>")
307                        return
308               
309                if len(name) > 0 and len(source)>0 and name not in self.core.var:
310                        name=(name.lower())
311                        b=self.new_apt_button(name)
312                       
313                        if self.core.current_var ==None:
314                                self.core.current_var=copy.deepcopy(self.core.var)
315                               
316                        self.core.current_var["apt"][name]={}
317                        self.core.current_var["apt"][name]["packages"]=[]
318                        self.core.current_var["apt"][name]["url"]=source
319                        self.new_apt_window.hide()
320                       
321                        self.core.var=copy.deepcopy(self.core.current_var)
322                        self.core.n4d.set_variable(self.core.var)
323                       
324                        self.apt_clicked(b,name,True)
325                       
326
327               
328        #def accept_apt_button_clicked
329       
330       
331        def cancel_apt_button_clicked(self,widget):
332               
333                self.new_apt_window.hide()
334               
335        #def cancel_apt_button_clicked
336       
337        # #################################################### #####
338       
339       
340       
341        # #### PACKAGE CHANGES ################### #
342       
343       
344        def add_package_clicked(self,widget):
345               
346                self.package_list_entry.set_text("")
347                self.new_package_window.show()
348               
349        #def add_package_clicked
350       
351       
352        def delete_package_clicked(self,button,hbox):
353               
354                pkg=hbox.get_children()[0].get_text()
355               
356                if self.delete_package_dialog(pkg):
357               
358                        self.package_list_box.remove(hbox)
359                               
360                        for p in range(len(self.core.current_var["apt"][self.current_id]["packages"])-1,-1,-1):
361                                if self.core.current_var["apt"][self.current_id]["packages"][p]==pkg:
362                                        self.core.current_var["apt"][self.current_id]["packages"].pop(p)
363                                        self.core.var=self.core.current_var
364                                        self.core.n4d.set_variable(self.core.var)
365                                       
366                        # STORE VALUE IN N4D HERE IF NEEDED
367                       
368                        # ######### #
369       
370        #def delete_package_clicked
371       
372       
373        def url_entry_changed(self,widget):
374               
375                if self.core.current_var !=None:
376                        txt=widget.get_text()
377                        if len(txt)>6:
378                                self.core.current_var["apt"][self.current_id]["url"]=txt
379
380        #def url_entry_changed 
381       
382       
383        def accept_add_package_button_clicked(self,widget):
384               
385               
386                self.package_list_entry.grab_focus()
387                txt=self.package_list_entry.get_text()
388               
389                for pkg in txt.split(","):
390                       
391                        pkg=pkg.strip(" ")
392                        if pkg not in self.core.current_var["apt"][self.current_id]["packages"]:
393                                self.core.current_var["apt"][self.current_id]["packages"].append(pkg)
394                        self.new_package_button(pkg)
395                       
396                self.new_package_window.hide()
397               
398        #def accept_add_package_button_clicked
399       
400       
401        def cancel_add_package_button_clicked(self,widget):
402               
403                self.new_package_window.hide()
404               
405        #def cancel_add_package_button_clicked
406       
407       
408        def apply_changes_button_clicked(self,widget):
409               
410                self.thread=threading.Thread(target=self.apply_changes_thread)
411                self.thread.daemon=True
412                self.thread.start()
413               
414                main_window=self.core.lri.main_window
415                dialog=Dialog.ApplyingChangesDialog(main_window,"Lliurex Remote installer",_(u"Updating repositories and testing packages..."))
416                dialog.show()
417                GLib.timeout_add(500,self.check_apply_thread,dialog)
418               
419        #def apply_changes_button_clicked
420       
421       
422        def apply_changes_thread(self):
423               
424                try:
425                        self.core.dprint("Updating repositories and testing packages...")
426               
427                        # SAMPLE CODE
428                       
429                        #self.core.n4d.lliurex_version()
430                        #print "testeando....."
431                        #time.sleep(1.5)
432                        # ######### #
433                        #self.core.current_var=copy.deepcopy(self.core.var)
434                        self.core.var=copy.deepcopy(self.core.current_var)
435                        self.test_apt=self.core.n4d.test_apt_list(self.core.var)
436                        self.thread_ret={"status":True,"msg":"BROKEN"}
437       
438                        # store return value here
439                       
440                       
441                       
442                except Exception as e:
443                        print e
444                        return False
445               
446               
447        #def apply_changes_thread
448       
449        def check_apply_thread(self,dialog):
450               
451               
452                if self.thread.is_alive():
453                        return True
454               
455                dialog.destroy()
456               
457                #self.test_apt=[True,False, n4d_var, listado_apt_accesibles, listado_apt_no_instalbles, comentario]
458                if self.test_apt[0]:
459                        if self.test_apt[3] not in [None,"","[]",[]]:
460                                if self.delete_test_apt_dialog(self.test_apt[3]):
461                                        self.core.n4d.set_variable(self.test_apt[1])
462                                        self.core.var=copy.deepcopy(self.test_apt[1])
463                                        self.core.current_var=copy.deepcopy(self.test_apt[1])
464                                else:
465                                        self.core.n4d.set_variable(self.core.var)
466                        else:
467                                self.core.n4d.set_variable(self.core.var)
468                        self.core.dprint("Done")
469                else:
470                        self.core.dprint("Test Error: variable remains unset")
471               
472               
473                for b in self.list_box:
474                        if b.get_tooltip_text()==self.current_id:
475                                break
476               
477               
478                self.apt_clicked(b,self.current_id)
479               
480               
481               
482                if not self.thread_ret["status"]:
483                        mw=self.core.lri.main_window
484                        d=Dialog.ErrorDialog(mw,"",self.thread_ret["msg"])
485                        d.run()
486                        d.destroy()
487               
488
489                return False
490               
491        #def check_thread
492       
493       
494        # ######################################################### #
495       
496
497        # ### DIALOGS ##### ##################
498       
499        def delete_apt_dialog(self,pkg_name):
500               
501                main_window=self.core.lri.main_window
502               
503                dialog=Dialog.QuestionDialog(main_window,_(u"Delete apt list"),_(u"Do you want to delete '%s' packages list?")%pkg_name)
504                response=dialog.run()
505                dialog.destroy()
506               
507                if response== Gtk.ResponseType.OK:
508                        return True
509               
510                return False
511               
512        #def delete_package_dialog
513       
514        def delete_test_apt_dialog(self,pkg_name_orig):
515               
516                main_window=self.core.lri.main_window
517                pkg_name='\n'.join(pkg_name_orig)
518                dialog=Dialog.QuestionDialog(main_window,_(u"Delete apt list"),_(u"This pakage list is unavaiable from your repos:\n%s\nDo you want delete it?")%pkg_name)
519                response=dialog.run()
520                dialog.destroy()
521               
522                if response== Gtk.ResponseType.OK:
523                        return True
524               
525                return False
526               
527        #def delete_package_dialog
528       
529        def delete_package_dialog(self,pkg_name):
530               
531                main_window=self.core.lri.main_window
532                dialog=Dialog.QuestionDialog(main_window,_(u"Delete package"),_(u"Do you want to delete '%s'?")%pkg_name)
533                response=dialog.run()
534                dialog.destroy()
535               
536                if response== Gtk.ResponseType.OK:
537                        return True
538               
539                return False
540               
541        #def delete_package_dialog
542       
543        def changes_detected_dialog(self,force_exit=False):
544               
545                main_window=self.core.lri.main_window
546               
547                dialog=Dialog.QuestionDialog(main_window,_(u"Changes detected"),_(u"There are unsaved changes. Do you want to discard them?"))
548                response=dialog.run()
549                dialog.destroy()
550               
551                if response== Gtk.ResponseType.OK:
552                        if force_exit:
553                                sys.exit(0)
554                               
555                        return True
556               
557                return False
558               
559        #def changes_detected_dialog
560       
561        # #####################################################
562               
563       
564       
565       
566#class aptbox
Note: See TracBrowser for help on using the repository browser.