source: zero-lliurex-flavours/trunk/fuentes/install-files/usr/share/lliurex-flavours-selector/lliurex-flavours-selector.py @ 5909

Last change on this file since 5909 was 5909, checked in by jrpelegrina, 3 years ago

Redesign gui. Change to stock buttons

  • Property svn:executable set to *
File size: 23.9 KB
RevLine 
[2134]1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import gi
5gi.require_version('Gtk', '3.0')
6gi.require_version('PangoCairo', '1.0')
7
8import cairo
9import os
[3434]10import glob
[2134]11import threading
12import ConfigParser
13import platform
14import subprocess
15import sys
[2143]16import datetime
[2134]17from math import pi
18
19from gi.repository import Gtk, Gdk, GObject, GLib, PangoCairo, Pango
20
21import signal
22signal.signal(signal.SIGINT, signal.SIG_DFL)
23
24
25import gettext
[2141]26gettext.textdomain('zero-lliurex-flavours')
[2134]27_ = gettext.gettext
28
29
30BASE_DIR="/usr/share/lliurex-flavours-selector/"
31RSRC_DIR=BASE_DIR+"rsrc/"
32SHADOW_BANNER=RSRC_DIR+"shadow.png"
33UNKNOWN_BANNER=RSRC_DIR+"unknown.png"
34BANNERS_PATH=BASE_DIR+"banners/"
35FLAVOURS_CONFIG_PATH=BASE_DIR+"supported-flavours/"
36
37CURRENT_PLATFORM=platform.machine()
38
39class GridButton:
40       
41        def __init__(self,info):
42               
43                self.info=info
44                self.info["installed"]=False
45                self.info["checked"]=False
[2311]46                self.info["incompatible"]=False
[2134]47                self.info["shadow_alpha"]=0.1
48                self.info["animation_active"]=False
49                self.info["shadow_start"]=0
50                self.info["available"]=True
51                self.info["drawingarea"]=None
52               
53                if os.path.exists(BANNERS_PATH+self.info["pkg"]+".png"):
54                        self.info["image"]=BANNERS_PATH+self.info["pkg"]+".png"
55                else:
56                        self.info["image"]=UNKNOWN_BANNER
57               
58        #def init
59       
60       
61#class GridButton
62
63
64class ConfButton:
65       
66        def __init__(self,info):
67               
68                self.txt=info["txt"]
69                self.icon=info["icon"]
70                self.name=info["name"]
71                self.da=None
72                if "active" not in info:
73                        self.active=False
74                else:
75                        self.active=info["active"]
76               
77        #def
78
79#class ConfButton
80       
81       
82class ConfigurationParser:
83       
84        def __init__(self):
85                pass
86       
87        def load_plugin(self,path):
88       
89                try:
90                        config = ConfigParser.ConfigParser()
91                        config.optionxform=str
92                        config.read(path)
93                        if config.has_section("FLAVOUR"):
94                                info={}
95                                info["pkg"]=config.get("FLAVOUR","pkg")
96                                info["name"]=config.get("FLAVOUR","name")
97                               
98                                return GridButton(info)
99                               
100                except Exception as e:
101                        print e
102                        return None
103       
104       
105#class ConfigParser
106
107
108class CustomColor:
109       
110        def __init__(self,r,g,b):
111               
112                self.r=r/255.0
113                self.g=g/255.0
114                self.b=b/255.0
115
116#class CustomColor             
117
118class AwesomeTabs:
119       
120        def __init__(self):
121               
[3181]122                self.check_root()
123
[2134]124                self.configuration_parser=ConfigurationParser()
125               
126                self.current_tab=-1
127                self.current_width=0
128                self.animation_left=False
129                self.animation_right=False
130               
131                self.current_red_width=0
132                self.current_red_pos=0
133                self.configuration_start=0
134               
135                self.current_grid_width=0
136                self.current_grid_height=0
137               
138                self.max_grid_width=2
139               
140                self.dark_gray=CustomColor(130.0,151.0,161.0)
141                self.light_gray=CustomColor(185.0,195.0,195.0)
142               
143                self.green=CustomColor(74.0,166.,69.0)
144                self.light_green=CustomColor(88.0,208.0,86.0)
145               
146                self.conf_light=CustomColor(49.0,55.0,66.0)
147                self.conf_dark=CustomColor(30.0,36.0,42.0)
148               
149                self.conf_light_shadow=CustomColor(107.0,116.0,137.0)
150                self.conf_dark_shadow=CustomColor(0,0,0)
151               
152                self.current_conf_height=0
153                self.conf_buttons=[]
[3181]154                log_msg="---------------------------------------------------------\n"+"LLIUREX FLAVOUR SELECTOR STARTING AT: " + datetime.datetime.today().strftime("%d/%m/%y %H:%M:%S") +"\n---------------------------------------------------------"
155                self.log(log_msg)
[2134]156                self.start_gui()
[3181]157
[2134]158        #def __init__
159       
160       
[3181]161        def check_root(self):
162               
163                try:
164                        f=open("/etc/zero-lliurex-flavours.token","w")
165                        f.close()
166                        os.remove("/etc/zero-lliurex-flavours.token")
167                except:
168                        dialog = Gtk.MessageDialog(None,0,Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL, "Lliurex Flavours Selector")
169                        dialog.format_secondary_text("You need administration privileges to run this application.")
170                        dialog.run()
171                        sys.exit(1)
172
173        #def check_root         
[2134]174       
175        def start_gui(self):
176               
177                builder=Gtk.Builder()
[2141]178                builder.set_translation_domain('zero-lliurex-flavours')
[2134]179                glade_path=RSRC_DIR+"lliurex-flavours-selector.ui"
180                builder.add_from_file(glade_path)
181               
182                self.installers_eb=builder.get_object("installers_eventbox")
183                self.installers_label=builder.get_object("installers_label")
184               
185               
186                self.top_divider_da=builder.get_object("top_divider_drawingarea")
187                self.bottom_divider_da=builder.get_object("bottom_divider_drawingarea")
188                self.top_divider_da.connect("draw",self.draw_top_divider)
189                self.bottom_divider_da.connect("draw",self.draw_bottom_divider)
190               
191                self.button_scroll=builder.get_object("button_scrolledwindow")
192                self.main_box=builder.get_object("main_box")
[5909]193                self.apply_button=builder.get_object("apply_button")
194                self.apply_button.connect("clicked",self.apply_clicked)
195                self.close_button=builder.get_object("close_button")
196                self.close_button.connect("clicked",self.quit)
197                '''
[2134]198                self.apply_eb=builder.get_object("apply_eventbox")
199                self.apply_da=builder.get_object("apply_drawingarea")
200                self.apply_eb.connect("button-press-event",self.accept_clicked)
201                self.apply_da.connect("draw",self.draw_apply_button)
202                self.close_eb=builder.get_object("close_eventbox")
203                self.close_da=builder.get_object("close_drawingarea")
204                self.close_eb.connect("button-press-event",self.quit)
205                self.close_da.connect("draw",self.draw_close_button)
[5909]206                '''
[2134]207                self.msg_label=builder.get_object("msg_label")
208               
209                self.stack = Gtk.Stack()
210                self.stack.set_transition_duration(1000)
211                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
212               
213                self.installers_grid=builder.get_object("button_grid")
214                               
215               
216               
217                self.stack.add_titled(self.button_scroll, "installers", "Installers")
218               
219               
220                self.main_box.add(self.stack)
221               
222                self.main_window=builder.get_object("main_window")
223               
224               
225                self.main_window.connect("destroy",self.quit)
226               
227               
228                self.progress_window=builder.get_object("progress_window")
229                self.pbar=builder.get_object("progressbar")
230                self.progress_window.set_transient_for(self.main_window)
231               
232                self.gather_window=builder.get_object("gather_window")
233                self.gather_pbar=builder.get_object("progressbar1")
234                self.progress_label=builder.get_object("progress_label")
235               
236                       
237                self.set_css_info()
238               
239                self.gather_window.show_all()
[3181]240                log_msg="-Current flavours installed:"
241                self.log(log_msg)
242
[2134]243                GLib.timeout_add(100,self.pulsate_gathering_info)
244               
245                self.t=threading.Thread(target=self.gather_info)
246                self.t.daemon=True
247                self.t.start()
248                self.install_metas=[]
249                self.update_metas=[]
250                GObject.threads_init()         
251                Gtk.main()
252               
253        #def start_gui
254       
255        def gather_info(self):
256               
257                import time
258                base_apt_cmd="apt-cache policy "
259               
260                self.gbs=[]
[2141]261                self.flavours_installed=0
[2134]262               
263                for item in sorted(os.listdir(FLAVOURS_CONFIG_PATH)):
264                        if os.path.isfile(FLAVOURS_CONFIG_PATH+item):
265                                gb=self.configuration_parser.load_plugin(FLAVOURS_CONFIG_PATH+item)
266                                if gb!=None:
267                                        sys.stdout.write("* Checking %s ...\t"%gb.info["pkg"])
268                                        gb.info["installed"]=self.is_installed(gb.info["pkg"])
269                                        sys.stdout.write("%s\n"%gb.info["installed"])
270                                        base_apt_cmd += "%s "%gb.info["pkg"]
271                                        self.gbs.append(gb)
272                                       
273                p=subprocess.Popen([base_apt_cmd],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)     
274                output=p.communicate()
275               
276                for gb in self.gbs:
277                       
278                        if gb.info["pkg"] not in output[0]:
279                                print(" [!] %s not available [!] "%gb.info["pkg"])
280                                gb.info["available"]=False
[2141]281                        else:
282                                if gb.info["installed"]==True:
[2311]283                                        self.check_meta_blocked(gb, self.gbs)
[2141]284                                        self.flavours_installed+=1     
[2134]285                                self.add_grid_button(gb)       
[2311]286                       
[2134]287        #def gather_info
288       
[2311]289        def check_meta_blocked(self, gb, gbs):
290
291                if gb.info["pkg"]=="lliurex-meta-server":
292                        for gb in self.gbs:
293                                if gb.info["pkg"]=="lliurex-meta-client": 
294                                        gb.info["incompatible"]=True
295                                elif gb.info["pkg"]=="lliurex-meta-desktop" and not gb.info["installed"]:
296                                        gb.info["incompatible"]=True   
297                elif gb.info["pkg"]=="lliurex-meta-client":
298                        for gb in self.gbs:
299                                if gb.info["pkg"]=="lliurex-meta-server":
300                                        gb.info["incompatible"]=True                           
301
302        #def check_meta_blocked                         
303
[2134]304        def pulsate_gathering_info(self):
305               
306                self.gather_pbar.pulse()
307               
308                if not self.t.is_alive():
309                       
310                        self.gather_window.hide()
311                        self.main_window.show_all()
312               
[2141]313                        if self.flavours_installed<1:
[3181]314                                log_msg="No flavour detected"
315                                self.log(log_msg)
[2141]316                                msg=_("No flavour detected. Check one at least")
317                                self.msg_label.show()
318                                self.msg_label.set_markup(msg)
[2134]319                return self.t.is_alive()
320               
321        #def pulsate_gathering
322       
323        def set_css_info(self):
324               
325                css = """
326               
327                #BLUE {
328                        background-image:-gtk-gradient (linear, left top, left bottom, from (#0f72ff),  to (#0f72ff));;
329               
330                }
331               
332                #BLACK{
333                        background-image:-gtk-gradient (linear, left top, left bottom, from (#000000),  to (#000000));;
334               
335                }
336               
337               
338                #BACK_GRADIENT{
339                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ffffff), to (#eceff3));;
340                }
341               
342                #WHITE {
343                        color: white;
344                        text-shadow: 0px 1px black;
345                }
346               
347                #MAIN_LABEL_ENABLED{
348                        color: #8297a1;
349                        font: Noto Sans Bold 18;
350                }
351               
352                #ALTERNATIVES_LABEL{
353                        color: #8297a1;
354                        font: Noto Sans Bold 12;               
355                }
356               
[2311]357                #DIALOG_LABEL{
358                        color: #8297a1;
359                        font: Noto Sans Bold 10;               
360                }
361
[2134]362                #MAIN_LABEL_DISABLED{
363                        color: #c9d4e2;
364                        font: Noto Sans Bold 18;
365                }
366               
367                #RED_PROGRESS{
368                       
369                        background-color: #FF0000;
370                        border: 0px;
371
372                }
373               
374                #DARK_BACK{
375                        background-color: #070809;
376                }
377               
378                #GREEN {
379                        background-image:-gtk-gradient (linear, left top, left bottom, from (#41ff70),  to (#41ff70));;
380               
381                }
382               
383                #ORANGE {
384                        background-image:-gtk-gradient (linear, left top, left bottom, from (#ff7f2a),  to (#ff7f2a));;
385               
386                }
387               
388                #LIGHTBLUE {
389                        -unico-border-gradient: -gtk-gradient (linear, left top, left bottom,
390                        from (shade (#ff0000, 0.68)),
391                        to (shade (#ff0000, 0.68)));
392               
393                }
394               
395                #RED_LABEL{
396                       
397                        color: red;
[3181]398                        font: Noto Sans Bold 10;
[2134]399                }
400
401               
402                GtkButton#RED GtkLabel {
403                        color: #8297a1;
404                        font: Noto Sans 11;
405                }
406
407
408                """
409                self.style_provider=Gtk.CssProvider()
410                self.style_provider.load_from_data(css)
411                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
412               
413                self.main_window.set_name("BACK_GRADIENT")
414                self.installers_label.set_name("MAIN_LABEL_ENABLED")
[3181]415                #self.pbar.set_name("RED_PROGRESS")
416                #self.gather_pbar.set_name("RED_PROGRESS")
[2134]417                self.progress_label.set_name("ALTERNATIVES_LABEL")
418                self.msg_label.set_name("RED_LABEL")
419               
420               
421        #def css_info
422
423        def is_installed(self,pkg):
424               
425               
426                p=subprocess.Popen(["dpkg-query -W -f='${db:Status-Status}' %s"%pkg],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
427                output=p.communicate()
428               
429                if output[0]=="installed":
[3181]430                        self.log(pkg)
[2134]431                        return True
432                       
433                return False
434               
435               
436        #def is_installed
437       
438        def quit(self,widget,event=None):
439               
440                Gtk.main_quit()
441               
442        #def quit
443       
444        def execute(self,command):
445               
446                self.thread_ret=-1
[2143]447                p=subprocess.Popen([command],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
448                output=p.communicate()
449                self.thread_ret=p.returncode
450                self.flavour_error=output[1]
[3434]451       
452                #Delete extra sources if music meta is being installed
453                if 'lliurex-meta-music' in command:
454                        sourcesFile=open('/etc/apt/sources.list','r')
455                        repos=sourcesFile.readlines()
456                        repos_orig=[]
457                        for repo in repos:
458                                if 'kxstudio' not in repo:
459                                        repos_orig.append(repo)
460                        sourcesFile.close()
461                        try:
462                                sourcesFile=open('/etc/apt/sources.list','w')
463                                sourcesFile.writelines(repos_orig)
[3437]464                                sourcesFile.close()
[3434]465                        except e as Exception:
466                                msg_log="Couldn't open sources.list fro witting"
467                                self.log(msg_log)
[2134]468        #def execute
469       
470       
471        def pulsate_pbar(self,da):
472               
473                if self.t.is_alive():
474                       
475                        self.pbar.pulse()
476                               
477                if not self.t.is_alive():
478                        self.progress_window.hide()
479                        if self.thread_ret==0:
480                                for item in self.install_metas:
[2142]481                               
[2134]482                                        if item.info["checked"]:
483                                                item.info["checked"]=False
484                                                item.info["drawingarea"].queue_draw()
485                                                self.mouse_left(item.info["drawingarea"],None,item)
[2141]486                                                item.info["installed"]=True
487                                try:
488                                        self.remove_desktop.info["checked"]=False
489                                        self.remove_desktop.info["drawingarea"].queue_draw()
490                                        self.mouse_left(self.remove_desktop.info["drawingarea"],None,self.remove_desktop)
491                                except:
492                                        print "No desktop flavour to remove"
493                                       
[2134]494                                self.install_metas=[]   
495                                self.msg_label.show()
[2141]496                                self.msg_label.set_markup("<span foreground='#4aa645'><b>"+_("Installation succesful. A reboot is required")+"</b></span>")
[3181]497                                log_msg="Installation of new flavour OK"
498                                self.log(log_msg)
[2134]499                        else:
500                                self.msg_label.show()
[3181]501                                msg=_("An error ocurred. See log in /var/log/lliurex-flavours-selector")
[2143]502                                self.msg_label.set_markup(msg)
[3181]503                                log_msg="Error during installation of new flavours. " + self.flavour_error
504                                self.log(log_msg)       
[2134]505                return self.t.is_alive()
506       
507        #def pulsate_pbar
508
509       
510       
511               
512        def add_grid_button(self,grid_button):
513               
514                da=Gtk.DrawingArea()
515                da.set_size_request(140,148)
516                da.add_events(Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK | Gdk.EventMask.BUTTON_PRESS_MASK )
517               
518                da.connect("draw",self.draw_button,grid_button)
519                da.connect("motion-notify-event",self.mouse_over,grid_button)
520                da.connect("leave_notify_event",self.mouse_left,grid_button)
521                da.connect("button-press-event",self.button_clicked,grid_button)
522                grid_button.info["drawingarea"]=da
523               
524                da.show()
525                self.installers_grid.attach(da,self.current_grid_width,self.current_grid_height,1,1)
526               
527                self.current_grid_width+=1
528               
529                if self.current_grid_width > self.max_grid_width:
530                        self.current_grid_width=0
531                        self.current_grid_height+=1
532                       
533                       
534        #def add_grid_button
535       
536       
537        def button_clicked(self,widget,event,grid_button):
538               
[2311]539                if not (grid_button.info["installed"] or grid_button.info["incompatible"]):
[2134]540                        if grid_button.info["checked"]:
541                                self.install_metas.remove(grid_button)
542                                grid_button.info["checked"]=False
[2311]543                                grid_button.info["drawingarea"].queue_draw()
544                                self.mouse_left(grid_button.info["drawingarea"],None,grid_button)
[2134]545                        else:
546                                self.install_metas.append(grid_button)
547                                grid_button.info["checked"]=True
548                                grid_button.info["shadow_alpha"]+=0.1
549                               
550                                widget.queue_draw()
551               
552        #def button_clicked
553       
554       
[5909]555        def apply_clicked(self,widget,even=None):
[2311]556               
[2134]557                ret, msg=self.check_meta_compatibility()
558               
559                if not ret:
560                        self.msg_label.show()
561                        self.msg_label.set_markup(msg)
562                        return
[2311]563                else:
564                        self.msg_label.hide()
565                        self.show_confirm_dialog(widget)
566       
567        # def accept_clicked                   
568       
569        def show_confirm_dialog(self, widget):
570                message=_("The selected flavours will be installed. Do you wish to continue?")
571                label = Gtk.Label(message)
572
[5909]573                dialog = Gtk.Dialog("Warning", None, Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, (Gtk.STOCK_YES, Gtk.ResponseType.YES,Gtk.STOCK_NO, Gtk.ResponseType.NO))
[2311]574                dialog.vbox.pack_start(label,True,True,10)
575
576                label.show()
[2315]577                dialog.set_border_width(6)
[2311]578                dialog.set_name("BACK_GRADIENT")
579                label.set_name("DIALOG_LABEL")
580
581                response = dialog.run()
582
583                if response==Gtk.ResponseType.YES:
584                        self.install_packages(widget)
585                dialog.destroy()               
[2134]586               
[2311]587        # def show_confirm_dialog       
588                               
589        def install_packages(self,widget):
590               
591                       
[3336]592                cmd='lliurex-preseed --update; apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y '
[2134]593                pkg=""
[3181]594                log_pkg=""
[2134]595                for item in self.update_metas:
596                        pkg+=item.info["pkg"] + ' '
597                       
598                for item in self.install_metas:
[3402]599                        if item.info["pkg"]=="lliurex-meta-infantil":
[3418]600                                cmdInfantil=["sudo","/usr/bin/add-apt-repository", "deb http://lliurex.net/xenial xenial preschool"]
[3404]601                                x=subprocess.Popen((cmdInfantil),stdin=subprocess.PIPE,stdout=subprocess.PIPE)
[3401]602                                log_msg="Adding repository recursos"
603                                self.log(log_msg)
[3403]604                                x.communicate("\n")[0]
[3425]605                               
606                        if item.info["pkg"]=="lliurex-meta-musica":
607                                lxRepos=["deb http://ppa.launchpad.net/kxstudio-debian/libs/ubuntu xenial main",
608                                        "deb http://ppa.launchpad.net/kxstudio-debian/music/ubuntu xenial main",
609                                        "deb http://ppa.launchpad.net/kxstudio-debian/plugins/ubuntu xenial main",
610                                        "deb http://ppa.launchpad.net/kxstudio-debian/apps/ubuntu xenial main",
611                                        "deb http://ppa.launchpad.net/kxstudio-debian/kxstudio/ubuntu xenial main"]
[3401]612
[3425]613                                cmdMusica=["sudo","/usr/bin/add-apt-repository"]
614                                for repo in lxRepos:
[3434]615                                        log_msg="Adding repository "+repo
[3425]616                                        self.log(log_msg)
617                                        cmdAux=cmdMusica+[repo]
618                                        x=subprocess.Popen((cmdAux),stdin=subprocess.PIPE,stdout=subprocess.PIPE)
619                                        x.communicate("\n")[0]
620
[2134]621                        pkg+=item.info["pkg"] + ' '
[3181]622                        log_pkg=log_pkg+item.info["pkg"]+ ' '
623
[2134]624                command=cmd+pkg
[2311]625       
[2134]626                self.t=threading.Thread(target=self.execute,args=(command,))
627                self.t.daemon=True
628                self.t.start()
[3181]629                log_msg="-New flavours to install:"
630                self.log(log_msg)
631                log_msg=str(log_pkg)
632                self.log(log_msg)
[2134]633                GLib.timeout_add(100,self.pulsate_pbar,widget)
[2311]634                self.progress_window.show()     
[2134]635               
636               
[2311]637        # def install_packages 
[2145]638               
[2134]639        def check_meta_compatibility(self):
640                               
641                if len(self.install_metas)>0:
642                       
643                        for gb in self.gbs:
644                                if gb.info["available"]:
645                                        if gb.info["installed"]:
646                                                if not gb in self.update_metas:
647                                                        self.update_metas.append(gb)
648                                                       
649                                                if gb.info["pkg"]=="lliurex-meta-server":
650                                                        for item in self.install_metas:
651                                                                if item.info["pkg"]=="lliurex-meta-client":
652                                                                        return [False,_("Incompatibility between Server and Client detected")]
653                                                                                                                                               
654                                                                if item.info["pkg"]=="lliurex-meta-desktop":
655                                                                        return [False, _("Is not possible adding Desktop Flavour in Server")]   
656                                                                       
657                                                if gb.info["pkg"]=="lliurex-meta-client":
658                                                        for item in self.install_metas:
659                                                                if item.info["pkg"]=="lliurex-meta-server":
660                                                                        return [False,_("Incompatibility between Server and Client detected")]
661                                               
662                                                if gb.info["pkg"]=="lliurex-meta-desktop":
663                                                        for item in self.install_metas:
664                                                                if item.info["pkg"]=="lliurex-meta-server":
665                                                                        if  gb in self.update_metas:
[2141]666                                                                                self.update_metas.remove(gb)                   
667                        i=0             
668                       
[2134]669                        for item in self.install_metas:
[2141]670                                if item.info["pkg"]=="lliurex-meta-server":
671                                        i+=1
672                                        for item in self.install_metas:
673                                                if item.info["pkg"]=="lliurex-meta-client":
674                                                        i+=1
675                                                if item.info["pkg"]=="lliurex-meta-desktop":
676                                                        self.install_metas.remove(item)
677                                                        self.remove_desktop=item
678                                                                       
679                        if i>1:
[2134]680                                return [False,_("Incompatibility between Server and Client detected")]
[2141]681                       
[2134]682                        return [True,""]
683                       
684                else:
685                        return [False,_("Choose new flavour to incorporate or close button")]
686                       
687        #def check_meta_compatibility
688                               
689        def draw_button(self,widget,ctx,grid_button):
690               
691                ctx.move_to(0,0)
692                img=cairo.ImageSurface.create_from_png(SHADOW_BANNER)
693                ctx.set_source_surface(img,0,grid_button.info["shadow_start"])
694                ctx.paint_with_alpha(grid_button.info["shadow_alpha"])
695               
696                ctx.move_to(0,0)
697                img=cairo.ImageSurface.create_from_png(grid_button.info["image"])
698                ctx.set_source_surface(img,0,0)
699                ctx.paint()
700               
701                ctx.move_to(0,0)
702                ctx.set_source_rgba(1,1,1,1)
703                ctx.rectangle(0,110,140,30)
704                ctx.fill()
705               
706               
707                ctx.set_source_rgba(self.dark_gray.r,self.dark_gray.g,self.dark_gray.b,1)
708               
709                pctx = PangoCairo.create_layout(ctx)
[2143]710                desc = Pango.font_description_from_string ("Noto Sans Bold 7.5")
[2134]711                pctx.set_font_description(desc)
712                pctx.set_markup(grid_button.info["name"])
713                ctx.move_to(5,118)
714                PangoCairo.show_layout(ctx, pctx)
715                width=pctx.get_pixel_size()[0]
716               
717               
718               
719                if grid_button.info["installed"]:
720               
721                        desc = Pango.font_description_from_string ("Noto Sans Bold 7")
722                        pctx.set_font_description(desc)
723                        ctx.set_source_rgba(self.green.r,self.green.g,self.green.b,1)
724                        txt=_("Installed")
725                        pctx.set_markup(txt)
726                        width=pctx.get_pixel_size()[0]
727                        ctx.move_to(140-width-5,120)
728                        PangoCairo.show_layout(ctx, pctx)
729                       
730                        ctx.rectangle(5,139,130,1)
731                        ctx.fill()
732               
733                if grid_button.info["checked"]:
734               
735                        desc = Pango.font_description_from_string ("Noto Sans Bold 7")
736                        pctx.set_font_description(desc)
737                        ctx.set_source_rgba(self.green.r,self.green.g,self.green.b,1)
738                        txt=_("Install")
739                        pctx.set_markup(txt)
740                        width=pctx.get_pixel_size()[0]
741                        ctx.move_to(140-width-5,120)
742                        PangoCairo.show_layout(ctx, pctx)
743                       
744                        ctx.rectangle(5,139,130,1)
745                        ctx.fill()
746               
[2311]747
748                if grid_button.info["incompatible"]:
749               
750                        desc = Pango.font_description_from_string ("Noto Sans Bold 7")
751                        pctx.set_font_description(desc)
752                        ctx.set_source_rgba(255,0,0,1)
753                        txt=_("Incompatible")
754                        pctx.set_markup(txt)
755                        width=pctx.get_pixel_size()[0]
756                        ctx.move_to(140-width-5,120)
757                        PangoCairo.show_layout(ctx, pctx)
758                       
759                        ctx.rectangle(5,139,130,1)
760                        ctx.fill()
[2134]761        #def draw_button
762       
763       
764        def drawing_label_event(self,widget,ctx,id):
765               
766                if id==self.current_tab:
767
768                        lg1 = cairo.LinearGradient(0.0,0.0, 300.0, 3.0)
769                        lg1.add_color_stop_rgba(0, 0, 1, 1, 0)
770                        lg1.add_color_stop_rgba(0.5, 0, 1, 1, 1)
771                        lg1.add_color_stop_rgba(1, 0, 1, 1, 0)
772                        ctx.rectangle(0, 0, 300, 3)
773                        ctx.set_source(lg1)
774                        ctx.fill()
775                       
776        #drawing_label_event
777       
[5909]778        '''
[2134]779        def draw_apply_button(self,widget,ctx):
780               
781               
782                button_border=22
783               
784                pctx = PangoCairo.create_layout(ctx)
785                desc = Pango.font_description_from_string ("Noto Sans Bold 10")
786                pctx.set_font_description(desc)
787               
788                pctx.set_markup(_("APPLY"))
789                width=pctx.get_pixel_size()[0]
790                widget.set_size_request(width+button_border*2,30)
791               
792                ctx.set_source_rgba(1,1,0,1)
793                xx=0
794                yx=0
795                widthx=width+44
796                heightx=30
797                radius=5
798               
799                r=47.0
800                g=167.0
801                b=223.0
802                alpha=1.0
803               
804                r=r/255.0
805                g=g/255.0
806                b=b/255.0
807               
808                r2=83
809                g2=153
810                b2=252
811               
812                r2=r2/255.0
813                g2=g2/255.0
814                b2=b2/255.0
815               
816               
817                lg1 = cairo.LinearGradient(0.0,0.0, 90.0, 0)
818                lg1.add_color_stop_rgba(0, r, g, b, 1)
819                lg1.add_color_stop_rgba(1, r2, g2, b2, 1)
820                ctx.set_source(lg1)
821               
822               
823                ctx.move_to (xx + radius, yx);
824                ctx.arc (xx + widthx - radius, yx + radius, radius, pi * 1.5, pi * 2);
825                ctx.arc (xx + widthx - radius, yx + heightx - radius, radius, 0, pi * .5);
826                ctx.arc (xx + radius, yx + heightx - radius, radius, pi * .5, pi);
827                ctx.arc (xx + radius, yx + radius, radius, pi , pi * 1.5);
828                ctx.fill ();
829               
830                ctx.set_source_rgb(0.9,0.9,0.9)
831                ctx.move_to(button_border,7)
832                PangoCairo.show_layout(ctx, pctx)
833       
834        #draw_apply_button
835       
836        def draw_close_button(self,widget,ctx):
837               
838               
839                button_border=22
840               
841                pctx = PangoCairo.create_layout(ctx)
842                desc = Pango.font_description_from_string ("Noto Sans Bold 10")
843                pctx.set_font_description(desc)
844               
845                pctx.set_markup(_("CLOSE"))
846                width=pctx.get_pixel_size()[0]
847                widget.set_size_request(width+button_border*2,30)
848               
849                ctx.set_source_rgba(1,1,0,1)
850                xx=0
851                yx=0
852                widthx=width+44
853                heightx=30
854                radius=5
855               
856                r=47.0
857                g=167.0
858                b=223.0
859                alpha=1.0
860               
861                r=r/255.0
862                g=g/255.0
863                b=b/255.0
864               
865                r2=83
866                g2=153
867                b2=252
868               
869                r2=r2/255.0
870                g2=g2/255.0
871                b2=b2/255.0
872               
873               
874                lg1 = cairo.LinearGradient(0.0,0.0, 90.0, 0)
875                lg1.add_color_stop_rgba(0, r, g, b, 1)
876                lg1.add_color_stop_rgba(1, r2, g2, b2, 1)
877                ctx.set_source(lg1)
878               
879               
880                ctx.move_to (xx + radius, yx);
881                ctx.arc (xx + widthx - radius, yx + radius, radius, pi * 1.5, pi * 2);
882                ctx.arc (xx + widthx - radius, yx + heightx - radius, radius, 0, pi * .5);
883                ctx.arc (xx + radius, yx + heightx - radius, radius, pi * .5, pi);
884                ctx.arc (xx + radius, yx + radius, radius, pi , pi * 1.5);
885                ctx.fill ();
886               
887                ctx.set_source_rgb(0.9,0.9,0.9)
888                ctx.move_to(button_border,7)
889                PangoCairo.show_layout(ctx, pctx)
890               
891        #def draw_close_button
[5909]892        '''
[2134]893       
894        def draw_top_divider(self,widget,ctx):
895               
896                r=self.dark_gray.r
897                g=self.dark_gray.g
898                b=self.dark_gray.b
899                alpha=1.0
900               
901                ctx.set_source_rgba(r,g,b,alpha)
902                ctx.rectangle(0,1,500,3)
903                ctx.fill()
904               
905               
906        #def draw_top_divider
907       
908       
909        def draw_bottom_divider(self,widget,ctx):
910               
911                r=self.dark_gray.r
912                g=self.dark_gray.g
913                b=self.dark_gray.b
914                alpha=1.0
915               
916                ctx.set_source_rgba(r,g,b,alpha)
917                ctx.rectangle(0,1,500,3)
918                ctx.fill()
919               
920        #def draw_bottom_divider
921       
922       
923        def mouse_over(self,widget,event,grid_button):
924               
925                grid_button.info["animation_active"]=False
926                if grid_button.info["shadow_alpha"] <0.5 :
927                        grid_button.info["shadow_alpha"]+=0.1
928                        widget.queue_draw()
929                        return True
930                       
931                return False
932               
933        #def mouse_over
934
935        def mouse_left(self,widget,event,grid_button):
936                if not grid_button.info["checked"]:
937                        if not grid_button.info["animation_active"]:
938                       
939                                grid_button.info["animation_active"]=True
940                                GLib.timeout_add(10,self.restore_shadow_alpha,grid_button,widget)
941                       
942        #def mouse_left
943
944       
945        def restore_shadow_alpha(self,grid_button,widget):
946               
947                if grid_button.info["shadow_alpha"] >0.2 :
948                        grid_button.info["shadow_alpha"]-=0.1
949               
950                        widget.queue_draw()
951                        return True
952                       
953                grid_button.info["animation_active"]=False
954                return False
955               
956        # def restore_shadow_alfpha     
957
[3181]958        def log(self,log_msg):
959                log_file="/var/log/lliurex-flavour-selector.log"
960                f=open(log_file,"a+")
961                f.write(log_msg + '\n')
[2143]962                f.close()
[2145]963               
964        # def log               
965               
[2311]966
967                       
[2134]968#awesome tabs
969
970if __name__=="__main__":
971       
972        at=AwesomeTabs()
Note: See TracBrowser for help on using the repository browser.