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

Last change on this file since 4618 was 4618, checked in by daduve, 2 years ago

Updating gui to block LliureX and Mirror options in APT

File size: 14.3 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.current_id in ['LliureX', 'Mirror']:
284                        return
285               
286                if self.delete_apt_dialog(self.current_id):
287                        for apt_button in self.list_box.get_children():
288                               
289                                if apt_button.get_tooltip_text() == self.current_id:
290                                        self.list_box.remove(apt_button)
291                                        self.stack.set_visible_child_name("empty")
292                                        self.core.var["apt"].pop(self.current_id)
293                                        self.current_id=None
294                                        self.core.current_var=None
295                                        self.core.n4d.set_variable(self.core.var)
296               
297        #def add_button_clicked
298       
299        def accept_apt_button_clicked(self,widget):
300               
301               
302                name=self.apt_name_entry.get_text()
303                source=self.apt_url_entry.get_text()
304               
305                if len(name) < 1 or len(source) < 8:
306                        self.apt_msg_label.set_markup("<span foreground='red'>"+"Invalid values"+"</span>")
307                        return
308                if name in self.core.var["apt"]:
309                        self.apt_msg_label.set_markup("<span foreground='red'>"+"Apt name already exists"+"</span>")
310                        return
311               
312                if len(name) > 0 and len(source)>0 and name not in self.core.var:
313                        name=(name.lower())
314                        b=self.new_apt_button(name)
315                       
316                        if self.core.current_var ==None:
317                                self.core.current_var=copy.deepcopy(self.core.var)
318                               
319                        self.core.current_var["apt"][name]={}
320                        self.core.current_var["apt"][name]["packages"]=[]
321                        self.core.current_var["apt"][name]["url"]=source
322                        self.new_apt_window.hide()
323                       
324                        self.core.var=copy.deepcopy(self.core.current_var)
325                        self.core.n4d.set_variable(self.core.var)
326                       
327                        self.apt_clicked(b,name,True)
328                       
329
330               
331        #def accept_apt_button_clicked
332       
333       
334        def cancel_apt_button_clicked(self,widget):
335               
336                self.new_apt_window.hide()
337               
338        #def cancel_apt_button_clicked
339       
340        # #################################################### #####
341       
342       
343       
344        # #### PACKAGE CHANGES ################### #
345       
346       
347        def add_package_clicked(self,widget):
348               
349                self.package_list_entry.set_text("")
350                self.new_package_window.show()
351               
352        #def add_package_clicked
353       
354       
355        def delete_package_clicked(self,button,hbox):
356               
357                pkg=hbox.get_children()[0].get_text()
358               
359                if self.delete_package_dialog(pkg):
360               
361                        self.package_list_box.remove(hbox)
362                               
363                        for p in range(len(self.core.current_var["apt"][self.current_id]["packages"])-1,-1,-1):
364                                if self.core.current_var["apt"][self.current_id]["packages"][p]==pkg:
365                                        self.core.current_var["apt"][self.current_id]["packages"].pop(p)
366                                        self.core.var=self.core.current_var
367                                        self.core.n4d.set_variable(self.core.var)
368                                       
369                        # STORE VALUE IN N4D HERE IF NEEDED
370                       
371                        # ######### #
372       
373        #def delete_package_clicked
374       
375       
376        def url_entry_changed(self,widget):
377               
378                if self.current_id in ['LliureX', 'Mirror']:
379                        return
380               
381                if self.core.current_var !=None:
382                        txt=widget.get_text()
383                        if len(txt)>6:
384                                self.core.current_var["apt"][self.current_id]["url"]=txt
385
386        #def url_entry_changed 
387       
388       
389        def accept_add_package_button_clicked(self,widget):
390               
391               
392                self.package_list_entry.grab_focus()
393                txt=self.package_list_entry.get_text()
394               
395                for pkg in txt.split(","):
396                       
397                        pkg=pkg.strip(" ")
398                        if pkg not in self.core.current_var["apt"][self.current_id]["packages"]:
399                                self.core.current_var["apt"][self.current_id]["packages"].append(pkg)
400                        self.new_package_button(pkg)
401                       
402                self.new_package_window.hide()
403               
404        #def accept_add_package_button_clicked
405       
406       
407        def cancel_add_package_button_clicked(self,widget):
408               
409                self.new_package_window.hide()
410               
411        #def cancel_add_package_button_clicked
412       
413       
414        def apply_changes_button_clicked(self,widget):
415               
416                self.thread=threading.Thread(target=self.apply_changes_thread)
417                self.thread.daemon=True
418                self.thread.start()
419               
420                main_window=self.core.lri.main_window
421                dialog=Dialog.ApplyingChangesDialog(main_window,"Lliurex Remote installer",_(u"Updating repositories and testing packages..."))
422                dialog.show()
423                GLib.timeout_add(500,self.check_apply_thread,dialog)
424               
425        #def apply_changes_button_clicked
426       
427       
428        def apply_changes_thread(self):
429               
430                try:
431                        self.core.dprint("Updating repositories and testing packages...")
432               
433                        # SAMPLE CODE
434                       
435                        #self.core.n4d.lliurex_version()
436                        #print "testeando....."
437                        #time.sleep(1.5)
438                        # ######### #
439                        #self.core.current_var=copy.deepcopy(self.core.var)
440                        self.core.var=copy.deepcopy(self.core.current_var)
441                        self.test_apt=self.core.n4d.test_apt_list(self.core.var)
442                        self.thread_ret={"status":True,"msg":"BROKEN"}
443       
444                        # store return value here
445                       
446                       
447                       
448                except Exception as e:
449                        print e
450                        return False
451               
452               
453        #def apply_changes_thread
454       
455        def check_apply_thread(self,dialog):
456               
457               
458                if self.thread.is_alive():
459                        return True
460               
461                dialog.destroy()
462               
463                #self.test_apt=[True,False, n4d_var, listado_apt_accesibles, listado_apt_no_instalbles, comentario]
464                if self.test_apt[0]:
465                        if self.test_apt[3] not in [None,"","[]",[]]:
466                                if self.delete_test_apt_dialog(self.test_apt[3]):
467                                        self.core.n4d.set_variable(self.test_apt[1])
468                                        self.core.var=copy.deepcopy(self.test_apt[1])
469                                        self.core.current_var=copy.deepcopy(self.test_apt[1])
470                                else:
471                                        self.core.n4d.set_variable(self.core.var)
472                        else:
473                                self.core.n4d.set_variable(self.core.var)
474                        self.core.dprint("Done")
475                else:
476                        self.core.dprint("Test Error: variable remains unset")
477               
478               
479                for b in self.list_box:
480                        if b.get_tooltip_text()==self.current_id:
481                                break
482               
483               
484                self.apt_clicked(b,self.current_id)
485               
486               
487               
488                if not self.thread_ret["status"]:
489                        mw=self.core.lri.main_window
490                        d=Dialog.ErrorDialog(mw,"",self.thread_ret["msg"])
491                        d.run()
492                        d.destroy()
493               
494
495                return False
496               
497        #def check_thread
498       
499       
500        # ######################################################### #
501       
502
503        # ### DIALOGS ##### ##################
504       
505        def delete_apt_dialog(self,pkg_name):
506               
507                main_window=self.core.lri.main_window
508               
509                dialog=Dialog.QuestionDialog(main_window,_(u"Delete apt list"),_(u"Do you want to delete '%s' packages list?")%pkg_name)
510                response=dialog.run()
511                dialog.destroy()
512               
513                if response== Gtk.ResponseType.OK:
514                        return True
515               
516                return False
517               
518        #def delete_package_dialog
519       
520        def delete_test_apt_dialog(self,pkg_name_orig):
521               
522                main_window=self.core.lri.main_window
523                pkg_name='\n'.join(pkg_name_orig)
524                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)
525                response=dialog.run()
526                dialog.destroy()
527               
528                if response== Gtk.ResponseType.OK:
529                        return True
530               
531                return False
532               
533        #def delete_package_dialog
534       
535        def delete_package_dialog(self,pkg_name):
536               
537                main_window=self.core.lri.main_window
538                dialog=Dialog.QuestionDialog(main_window,_(u"Delete package"),_(u"Do you want to delete '%s'?")%pkg_name)
539                response=dialog.run()
540                dialog.destroy()
541               
542                if response== Gtk.ResponseType.OK:
543                        return True
544               
545                return False
546               
547        #def delete_package_dialog
548       
549        def changes_detected_dialog(self,force_exit=False):
550               
551                main_window=self.core.lri.main_window
552               
553                dialog=Dialog.QuestionDialog(main_window,_(u"Changes detected"),_(u"There are unsaved changes. Do you want to discard them?"))
554                response=dialog.run()
555                dialog.destroy()
556               
557                if response== Gtk.ResponseType.OK:
558                        if force_exit:
559                                sys.exit(0)
560                               
561                        return True
562               
563                return False
564               
565        #def changes_detected_dialog
566       
567        # #####################################################
568               
569       
570       
571       
572#class aptbox
Note: See TracBrowser for help on using the repository browser.