source: repoman/trunk/fuentes/src/repoman.py @ 7873

Last change on this file since 7873 was 7873, checked in by Juanma, 16 months ago

add educational resources.

  • Property svn:executable set to *
File size: 18.9 KB
Line 
1#! /usr/bin/python3
2# -*- coding: utf-8 -*-
3
4import os
5import gi
6gi.require_version('Gtk', '3.0')
7from gi.repository import Gtk,Gdk,GdkPixbuf,GObject,GLib
8gi.require_version('PangoCairo', '1.0')
9import json
10#from edupals.ui.n4dgtklogin import *
11import repomanager.RepoManager as RepoManager
12import threading
13import time
14import subprocess
15
16import gettext
17gettext.textdomain('repoman')
18_ = gettext.gettext
19
20RSRC_DIR='/usr/share/repoman/rsrc'
21#RSRC_DIR='/home/lliurex/trabajo/repoman/rsrc'
22JSON_SRC_DIR='/usr/share/repoman/sources.d'
23APT_SRC_DIR='/etc/apt/sources.list.d'
24
25SPACING=6
26MARGIN=6
27
28class main:
29
30        def __init__(self):
31                self.dbg=True
32                self.err_msg={1:_("Invalid Url"),
33                                                2:_("Can't add repository information.\nCheck your permissions"),
34                                                3:_("Can't write sources file.\nCheck your permissions"),
35                                                4:_("Repository not found at given Url"),
36                                                5:_("Repositories failed to update"),
37                                                6:_("Mirror not availabe")
38                                                }
39                self.result={}         
40                self._set_css_info()
41                self.stack_dir=Gtk.StackTransitionType.SLIDE_LEFT
42                self.sources=RepoManager.manager()
43                self.repos={}
44                self._render_gui()
45        #def __init__
46
47        def _debug(self,msg):
48                if self.dbg:
49                        print("repoman: %s"%msg)
50
51        def _render_gui(self):
52                self.mw=Gtk.Window()
53                self.mw.set_title("RepoMan")
54                self.mw.set_hexpand(True)
55                self.mw.connect("destroy",self._on_destroy)
56                self.mw.set_resizable(False)
57                vbox=Gtk.VBox(False,True)
58                self.mw.add(vbox)
59                pb=GdkPixbuf.Pixbuf.new_from_file("%s/repoman.png"%RSRC_DIR)
60                img_banner=Gtk.Image.new_from_pixbuf(pb)
61                img_banner.props.halign=Gtk.Align.CENTER
62                img_banner.set_margin_left(MARGIN*2)
63                vbox.add(img_banner)
64                toolbarbox=self._render_toolbar()
65                vbox.add(toolbarbox)
66                self.rev_question=Gtk.InfoBar()
67                lbl_question=Gtk.Label()
68                lbl_question.set_name("NOTIF_LABEL")
69                lbl_question.set_halign(Gtk.Align.START)
70                self.rev_question.props.no_show_all=True
71                self.rev_question.get_content_area().add(lbl_question)
72                img_cancel=Gtk.Image()
73                img_cancel.set_from_icon_name(Gtk.STOCK_CANCEL,Gtk.IconSize.BUTTON)
74                btn_cancel=Gtk.Button()
75                btn_cancel.add(img_cancel)
76                btn_cancel.set_halign(Gtk.Align.END)
77                btn_cancel.props.no_show_all=False
78                self.rev_question.add_action_widget(btn_cancel,Gtk.ResponseType.CANCEL)
79                img_ok=Gtk.Image()
80                img_ok.set_from_icon_name(Gtk.STOCK_OK,Gtk.IconSize.BUTTON)
81                btn_ok=Gtk.Button()
82                btn_ok.props.no_show_all=False
83                btn_ok.set_halign(Gtk.Align.START)
84                btn_ok.add(img_ok)
85                self.rev_question.add_action_widget(btn_ok,Gtk.ResponseType.OK)
86                self.rev_question.connect('response',self._manage_response)
87                vbox.add(self.rev_question)
88                self.stack = Gtk.Stack()
89                self.stack.set_hexpand(True)
90                self.stack.set_transition_duration(1000)
91                self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT)
92#               self.stack.add_titled(self._render_login(), "login", "Login")
93                self.stack.add_titled(self._render_sources(), "sources", "Sources")
94                self.stack.add_titled(self._render_newrepo(), "newrepo", "Newrepo")
95                self.stack.add_titled(self._render_repolist(), "repolist", "Repolist")
96                self.stack.set_visible_child_name("sources")
97                vbox.add(self.stack)
98                self.rev_info=Gtk.Revealer()
99                vbox.add(self.rev_info)
100                lbl_update=Gtk.Label()
101                lbl_update.set_name("NOTIF_LABEL")
102                self.rev_info.add(lbl_update)
103                self.rev_info.set_transition_duration(1000)
104                self.mw.show_all()
105                self.rev_info.set_reveal_child(False)
106#               toolbarbox.hide()
107#               img_banner.hide()
108                self.box_info=Gtk.Grid()
109                self.box_info.set_margin_bottom(MARGIN)
110                self.box_info.set_margin_left(MARGIN)
111                self.box_info.set_column_spacing(MARGIN)
112                lbl_info=Gtk.Label()
113                info=_("Repositories must be updated. Update now?")
114                lbl_info.set_markup('<span color="grey">%s</span>'%info)
115#               img_info=Gtk.Image().new_from_icon_name(Gtk.STOCK_REFRESH,Gtk.IconSize.BUTTON)
116                pb_info=GdkPixbuf.Pixbuf.new_from_file_at_scale("%s/stock_refresh.png"%RSRC_DIR,16,16,True)
117                img_info=Gtk.Image().new_from_pixbuf(pb_info)
118                btn_info=Gtk.Button()
119                btn_info.set_name("BLUEBUTTON")
120                btn_info.set_tooltip_text(_("Update repositories"))
121                btn_info.add(img_info)
122                spn_info=Gtk.Spinner()
123                self.box_info.attach(lbl_info,0,0,1,1)
124                self.box_info.attach(btn_info,1,0,1,1)
125                self.box_info.attach(spn_info,0,0,2,1)
126                btn_info.connect("clicked",self._begin_update_repos,spn_info)
127                vbox.add(self.box_info)
128                Gtk.main()
129        #def _render_gui
130
131        def _render_toolbar(self):
132                self.toolbar=Gtk.Box()
133                self.toolbar=Gtk.Box(spacing=SPACING)
134                self.toolbar.set_margin_top(MARGIN)
135                self.toolbar.set_margin_bottom(MARGIN)
136                self.toolbar.set_margin_left(MARGIN)
137               
138                btn_return=Gtk.Button()#.new_from_stock(Gtk.STOCK_GO_BACK)
139                btn_return.add(Gtk.Image().new_from_icon_name(Gtk.STOCK_HOME,Gtk.IconSize.BUTTON))
140                btn_return.connect("clicked",self._load_screen,"sources")
141                btn_return.props.halign=Gtk.Align.START
142                btn_return.set_tooltip_text(_("Default repositories"))
143                self.toolbar.add(btn_return)
144
145                btn_manage=Gtk.Button()
146                btn_manage.props.halign=Gtk.Align.START
147                btn_manage.add(Gtk.Image().new_from_icon_name(Gtk.STOCK_PROPERTIES,Gtk.IconSize.BUTTON))
148                btn_manage.connect("clicked",self._load_screen,"repolist")
149                btn_manage.set_tooltip_text(_("External repositories"))
150                self.toolbar.add(btn_manage)
151               
152                btn_add=Gtk.Button()#.new_from_stock(Gtk.STOCK_ADD)
153                btn_add.props.halign=Gtk.Align.START
154                btn_add.add(Gtk.Image().new_from_icon_name(Gtk.STOCK_ADD,Gtk.IconSize.BUTTON))
155                btn_add.connect("clicked",self._load_screen,"newrepo")
156                btn_add.set_tooltip_text(_("Add external repository"))
157                self.toolbar.add(btn_add)
158               
159                return(self.toolbar)
160        #def _render_toolbar
161
162        def _render_login(self):
163                login=N4dGtkLogin()
164                login.set_allowed_groups(['adm','teachers'])
165                desc=_("Welcome to RepoMan.\nFrom here you can invoke RepoMan's mighty powers to manage your repositories.")
166                login.set_info_text("<span foreground='black'>RepoMan</span>",_("Repositories Manager"),"<span foreground='black'>"+desc+"</span>\n")
167#               self.login.set_info_background(image='taskscheduler',cover=True)
168#               login.set_info_background(image=LOGIN_IMG,cover=False)
169                login.after_validation_goto(self._signin)
170                login.hide_server_entry()
171#               login.show_all()
172                return (login)
173
174        def _signin(self,user=None,pwd=None,server=None,data=None):
175#               self.scheduler.set_credentials(user,pwd,server)
176                self.stack.set_visible_child_name("sources")
177                self.mw.show_all()
178        #def _signin
179
180        def _render_sources(self):
181                gridbox=Gtk.Grid()
182                gridbox.set_column_homogeneous(False)
183                gridbox.set_column_spacing(MARGIN)
184                gridbox.set_name("WHITE_BACKGROUND")
185                gridbox.set_margin_top(MARGIN)
186                gridbox.set_margin_left(MARGIN)
187                gridbox.set_margin_right(MARGIN)
188                gridbox.set_margin_bottom(MARGIN)
189                self.repos=self.sources.list_default_repos()
190                row=0
191                for source,sourcedata in self.repos.items():
192                        desc=''
193                        if sourcedata['desc']:
194                                desc=_(sourcedata['desc'])
195                        self._insert_sourceslist_item(gridbox,source,desc,'',sourcedata['enabled'],row)
196                        row+=1
197                gridbox.set_margin_top(MARGIN)
198                gridbox.set_margin_bottom(MARGIN*2)
199                return(gridbox)
200        #def _render_sources
201
202        def _repo_state_changed(self,*args):
203                reponame=args[-1]
204                state=args[-2]
205                widget=args[0]
206                err=0
207                if reponame.lower()=="lliurex mirror":
208                        ret=subprocess.run(["lliurex-version","-m"],universal_newlines=True,stdout=subprocess.PIPE)
209                        if ret.stdout.strip()=="False":
210                                err=6
211                if err==0:
212                        self.repos[reponame].update({'enabled':str(state)})
213                        repo={}
214                        repo={reponame:self.repos[reponame]}
215                        self._debug("New state: %s"%repo)
216                        self._debug("Saving repo json: %s"%repo)
217                        if self.sources.write_repo_json(repo):
218                                if self.sources.write_repo(repo)!=True:
219                                        err=3
220                        else:
221                                err=2
222                if err:
223                        self.stack.set_sensitive(False)
224                        self.toolbar.set_sensitive(False)
225                        GLib.timeout_add(3000,self.show_info,(self.err_msg[err]),"ERROR_LABEL")
226                        widget.set_state(not(state))
227                        return True
228                else:
229                        self.box_info.show_all()
230        #def _repo_state_changed
231
232        def _render_repolist(self):
233                scrollbox=Gtk.ScrolledWindow()
234                scrollbox.set_min_content_height(280)
235                scrollbox.set_min_content_width(280)
236                self.repobox=Gtk.Grid()
237                self.repobox.set_hexpand(True)
238                self.repobox.set_row_spacing(MARGIN)
239                self.repobox.set_margin_left(MARGIN)
240                self.repobox.set_margin_right(MARGIN)
241                self.repobox.set_margin_top(MARGIN)
242                self.repobox.set_row_spacing(0)
243                self.repobox.set_name("WHITE_BACKGROUND")
244                sourcefiles=self.sources.list_sources()
245                self.repos.update(sourcefiles)
246                row=0
247                for sourcefile,sourcedata in sourcefiles.items():
248                        desc=''
249                        if sourcedata['desc']:
250                                desc=_(sourcedata['desc'])
251                        edit=True
252                        if 'protected' in sourcedata.keys():
253                                if sourcedata['protected'].lower()=='true':
254                                        edit=False
255                        self._insert_sourceslist_item(self.repobox,sourcefile,desc,'',sourcedata['enabled'],row,edit)
256                        row+=1
257                scrollbox.add(self.repobox)
258                return scrollbox
259        #def _render_repolist
260
261        def _render_newrepo(self):
262                def del_icon(*args):
263                        args[-1].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,None)
264                        args[-1].set_placeholder_text("")
265
266                gridbox=Gtk.Grid()
267                gridbox.set_hexpand(True)
268                gridbox.set_row_spacing(MARGIN)
269                gridbox.set_margin_left(MARGIN)
270                gridbox.set_margin_right(MARGIN)
271                gridbox.set_margin_top(MARGIN)
272                boxname=Gtk.VBox(True,True)
273                boxname.set_name("WHITE_BACKGROUND")
274                boxname.set_hexpand(True)
275                lbl_name=Gtk.Label()
276                lbl_name.set_name("ENTRY_LABEL")
277                lbl_name.set_halign(Gtk.Align.START)
278                lbl_name.set_markup("<sup>%s</sup>"%_("Name for the repo"))
279                boxname.add(lbl_name)
280                inp_name=Gtk.Entry()
281                inp_name.connect("focus-in-event",del_icon,inp_name)
282                boxname.add(inp_name)
283                gridbox.add(boxname)
284                boxdesc=Gtk.VBox(True,True)
285                boxdesc.set_name("WHITE_BACKGROUND")
286                lbl_desc=Gtk.Label()
287                lbl_desc.set_name("ENTRY_LABEL")
288                lbl_desc.set_halign(Gtk.Align.START)
289                lbl_desc.set_markup("<sup>%s</sup>"%_("Description"))
290                boxdesc.add(lbl_desc)
291                inp_desc=Gtk.Entry()
292                boxdesc.add(inp_desc)
293                gridbox.attach_next_to(boxdesc,boxname,Gtk.PositionType.BOTTOM,1,1)
294                boxurl=Gtk.VBox(True,True)
295                boxurl.set_name("WHITE_BACKGROUND")
296                lbl_url=Gtk.Label()
297                lbl_url.set_name("ENTRY_LABEL")
298                lbl_url.set_halign(Gtk.Align.START)
299                lbl_url.set_markup("<sup>%s</sup>"%_("Url"))
300                boxurl.add(lbl_url)
301                inp_url=Gtk.Entry()
302                inp_url.connect("focus-in-event",del_icon,inp_url)
303                inp_url.connect("activate",self._begin_add_repo,inp_name,inp_desc,inp_url)
304                boxurl.add(inp_url)
305                gridbox.attach_next_to(boxurl,boxdesc,Gtk.PositionType.BOTTOM,1,1)
306                boxbtn=Gtk.Box()
307                btn_add=Gtk.Button.new_from_stock(Gtk.STOCK_APPLY)
308                btn_add.connect("clicked",self._begin_add_repo,inp_name,inp_desc,inp_url)
309#               btn_add.connect("clicked",self._add_repo,inp_name,inp_desc,inp_url)
310                boxbtn.set_halign(Gtk.Align.END)
311                boxbtn.add(btn_add)
312               
313                gridbox.attach_next_to(boxbtn,boxurl,Gtk.PositionType.BOTTOM,1,1)
314                return(gridbox)
315        #def _render_newrepo
316
317        def _begin_add_repo(self,*args):
318                name=args[-3].get_text()
319                desc=args[-2].get_text()
320                url=args[-1].get_text()
321                sw_err=False
322                name=args[-3].get_text()
323                desc=args[-2].get_text()
324                url=args[-1].get_text()
325                if not name:
326                        args[-3].set_placeholder_text(_("Name is mandatory"))
327                        args[-3].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,Gtk.STOCK_DIALOG_ERROR)
328                        sw_err=True
329                elif len(name)>40:
330                        args[-3].set_placeholder_text(_("Name is too long"))
331                        args[-3].set_text("")
332                        args[-3].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,Gtk.STOCK_DIALOG_ERROR)
333                        sw_err=True
334
335                desc_array=desc.split(' ')
336                for element in desc_array:
337                        if len(element)>40:
338                                args[-2].set_placeholder_text(_("Description is too long"))
339                                args[-2].set_text("")
340                                args[-2].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,Gtk.STOCK_DIALOG_ERROR)
341                                sw_err=True
342
343                if not url:
344                        args[-1].set_placeholder_text(_("Url is mandatory"))
345                        args[-1].set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,Gtk.STOCK_DIALOG_ERROR)
346                        sw_err=True
347                if not sw_err:
348                        if os.path.isfile('%s/%s.json'%(JSON_SRC_DIR,name.replace(' ','_'))):
349                                self.result.pop('response',None)
350                                try:
351                                        self.rev_question.disconnect_by_func(self._manage_response)
352                                except:
353                                        pass
354                                self.rev_question.grab_add()
355                                self.rev_question.connect('response',self._manage_response,self._add_repo,*args)
356                                self.show_question(_("%s already exists. Overwrite it?"%name))
357                        else:
358                                self._add_repo(*args)
359
360        def _add_repo(self,*args):
361                name=args[-3].get_text()
362                desc=args[-2].get_text()
363                url=args[-1].get_text()
364                self.stack.set_sensitive(False)
365                self.toolbar.set_sensitive(False)
366                err=self.sources.add_repo(name,desc,url)
367                if err==0:
368                        row=(len(self.repos.keys())*2)
369                        sourcefiles=self.sources.list_sources()
370                        self.repos.update(sourcefiles)
371                        self._insert_sourceslist_item(self.repobox,name,desc,url,'true',"false",row,True)
372                        GLib.timeout_add(2000,self.show_info,(_("Added repository %s"%name)),"NOTIF_LABEL",True)
373                else:
374                        #err=1 -> Bad url
375                        #err=2 -> Can't write json
376                        #err=3 -> Can't write sources
377                        #err=4 -> Repository not found at given url
378                        GLib.timeout_add(3000,self.show_info,(self.err_msg[err]),"ERROR_LABEL")
379        #def _add_repo
380
381        def _insert_sourceslist_item(self,sourcebox,name,desc,url,enabled='false',index=0,edit=False):
382                index*=2
383                repobox=Gtk.VBox(True,True)
384                repobox.set_margin_left(MARGIN)
385                repobox.set_margin_right(MARGIN)
386                repobox.set_margin_bottom(MARGIN)
387                repobox.set_margin_top(MARGIN)
388                lbl_source=Gtk.Label()
389                lbl_source.set_markup('<span size="larger">%s</span>'%name)
390                lbl_source.set_halign(Gtk.Align.START)
391                lbl_source.set_hexpand(True)
392                lbl_source.set_margin_left(MARGIN)
393                lbl_source.set_margin_bottom(MARGIN)
394                lbl_source.set_margin_top(MARGIN)
395                lbl_source.props.halign=Gtk.Align.START
396                repobox.add(lbl_source)
397                lbl_desc=Gtk.Label()
398                lbl_desc.set_ellipsize(3)
399                lbl_desc.set_markup('<span size="medium">%s</span>'%desc)
400                lbl_desc.set_tooltip_text('%s'%desc)
401                lbl_desc.set_halign(Gtk.Align.START)
402                repobox.add(lbl_desc)
403                if edit:
404                        img_edit=Gtk.Image.new_from_icon_name(Gtk.STOCK_EDIT,Gtk.IconSize.BUTTON)
405                        btn_edit=Gtk.Button()
406                        btn_edit.add(img_edit)
407                        btn_edit.set_tooltip_text(_("Edit sources file"))
408                        btn_edit.set_valign(Gtk.Align.CENTER)
409                        btn_edit.connect("clicked",self._edit_source_file,name)
410                        sourcebox.attach(btn_edit,1,index,1,1)
411                swt_repo=Gtk.Switch()
412                swt_repo.set_halign(Gtk.Align.END)
413                if enabled.lower()=="true":
414                        swt_repo.set_active(True)
415                else:
416                        swt_repo.set_active(False)
417                swt_repo.connect("state_set",self._repo_state_changed,name)
418                sourcebox.attach(repobox,0,index,1,1)
419                sourcebox.attach(swt_repo,2,index,1,1)
420                sourcebox.attach(Gtk.Separator(),0,index+1,1,1)
421                sourcebox.show_all()
422        #def _insert_sourceslist_item
423
424        def _load_screen(self,*args):
425                self.stack.set_transition_type(self.stack_dir)
426                if self.stack_dir==Gtk.StackTransitionType.SLIDE_RIGHT:
427                        self.stack_dir=Gtk.StackTransitionType.SLIDE_LEFT
428                else:
429                        self.stack_dir=Gtk.StackTransitionType.SLIDE_RIGHT
430                screen=args[-1]
431                self.stack.set_visible_child_name(screen)
432        #def _load_screen
433
434        def _begin_update_repos(self,*args):
435                spinner=args[-1]
436                spinner.show()
437                spinner.start()
438                self.stack.set_sensitive(False)
439                self.toolbar.set_sensitive(False)
440                th=threading.Thread(target=self._update_repos,args=[spinner])
441                th.start()
442                GLib.timeout_add(1500,self._check_update,th,spinner)
443        #def _begin_update_repos
444
445        def _update_repos(self,spinner):
446                self.result['update']=self.sources.update_repos()
447        #def _update_repos
448
449        def _check_update(self,th,spinner):
450                if th.is_alive():
451                        return True
452                spinner.stop()
453                self.stack.set_sensitive(True)
454                self.toolbar.set_sensitive(True)
455                self.box_info.hide()
456                if self.result['update']:
457                        return(self.show_info(_("Repositories updated")))
458                else:
459                        return(self.show_info(self.err_msg[5],"ERROR_LABEL"))
460        #def _check_update
461
462        def _edit_source_file(self,*args):
463                sfile=args[-1].replace(' ','_')
464                self._debug("Editing %s.list"%sfile)
465                if os.path.isfile("%s/%s.list"%(APT_SRC_DIR,sfile)):
466                        edit=True
467                        try:
468                                subprocess.run(["pluma","%s/%s.list"%(APT_SRC_DIR,sfile)],check=True)
469                        except:
470                                edit=False
471                        if edit:
472                                newrepos=[]
473                                try:
474                                        with open("%s/%s.list"%(APT_SRC_DIR,sfile),'r') as f:
475                                                for line in f:
476                                                        newrepos.append(line.strip())
477                                except Exception as e:
478                                        self._debug("_edit_source_file failed: %s"%e)
479                                if sorted(self.repos[args[-1]]['repos'])!=sorted(newrepos):
480                                        self.repos[args[-1]]['repos']=newrepos
481                                        self.sources.write_repo_json({args[-1]:self.repos[args[-1]]})
482                                        self.box_info.show_all()
483        #def _edit_source_file
484
485        def show_info(self,msg='',style="NOTIF_LABEL",show_info=False):
486                if self.rev_info.get_reveal_child():
487                        self.rev_info.set_reveal_child(False)
488                        self.stack.set_sensitive(True)
489                        self.toolbar.set_sensitive(True)
490                        if show_info:
491                                self.box_info.show_all()
492                        return False
493                lbl=None
494                for child in self.rev_info.get_children():
495                        if type(child)==type(Gtk.Label()):
496                                lbl=child
497                if lbl:
498                        lbl.set_name(style)
499                        lbl.set_markup(msg)
500                        self.rev_info.set_reveal_child(True)
501                return True
502        #def show_info
503       
504        def show_question(self,msg='',style="NOTIF_LABEL"):
505                self.rev_question.grab_add()
506                for child in self.rev_question.get_content_area():
507                        if type(child)==type(Gtk.Label()):
508                                lbl=child
509                for child in self.rev_question.get_action_area():
510                        if type(child)==type(Gtk.Button()):
511                                child.show_all()
512
513                lbl.set_markup(msg)
514                lbl.show()
515                self.rev_question.show()
516        #def show_question
517
518        def _manage_response(self,*args):
519                self.rev_question.grab_remove()
520                response=args[1]
521                self.rev_question.hide()
522                if response==Gtk.ResponseType.OK:
523                        args[2](args[-3],args[-2],args[-1])
524                else:
525                        return False
526
527        def _on_destroy(self,*args):
528                Gtk.main_quit()
529
530        def _set_css_info(self):
531       
532                css = b"""
533
534                GtkEntry{
535                        font-family: Roboto;
536                        border:0px;
537                        border-bottom:1px grey solid;
538                        margin-top:0px;
539                        padding-top:0px;
540                }
541
542                GtkLabel {
543                        font-family: Roboto;
544                }
545
546                #NOTIF_LABEL{
547                        background-color: #3366cc;
548                        font: 11px Roboto;
549                        color:white;
550                        border: dashed 1px silver;
551                        padding:6px;
552                }
553
554                #ERROR_LABEL{
555                        background-color: red;
556                        font: 11px Roboto;
557                        color:white;
558                        border: dashed 1px silver;
559                        padding:6px;
560                }
561
562                #ENTRY_LABEL{
563                        color:grey;
564                        padding:6px;
565                        padding-bottom:0px;
566                }
567
568                #PLAIN_BTN,#PLAIN_BTN:active{
569                        border:0px;
570                        padding:0px;
571                        background:white;
572                }
573               
574                #PLAIN_BTN_DISABLED,#PLAIN_BTN_DISABLED:active{
575                        border:0px;
576                        padding:0px;
577                        background:white;
578                        font:grey;
579                }
580
581                #COMPONENT{
582                        padding:3px;
583                        border: dashed 1px silver;
584
585                }
586
587                #WHITE_BACKGROUND {
588                        background:white;
589               
590                }
591
592                #BLUE_FONT {
593                        color: #3366cc;
594                        font: Roboto Bold 11;
595                       
596                }       
597               
598
599                #TASKGRID_FONT {
600                        color: #3366cc;
601                        font: Roboto 11;
602                       
603                }
604
605                #LABEL #LABEL_INSTALL{
606                        padding: 6px;
607                        margin:6px;
608                        font: 12px Roboto;
609                }
610
611                #LABEL_OPTION{
612               
613                        font: 48px Roboto;
614                        padding: 6px;
615                        margin:6px;
616                        font-weight:bold;
617                }
618
619                #ERROR_FONT {
620                        color: #CC0000;
621                        font: Roboto Bold 11;
622                }
623
624                #MENUITEM {
625                        padding: 12px;
626                        margin:6px;
627                        font: 24px Roboto;
628                        background:white;
629                }
630
631                #BLUEBUTTON {
632                        background-color: #3366cc;
633                        color:white;
634                        font: 11px Roboto Bold;
635                }
636
637                """
638                self.style_provider=Gtk.CssProvider()
639                self.style_provider.load_from_data(css)
640                Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),self.style_provider,Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
641        #def set_css_info       
642
643GObject.threads_init()
644main()
Note: See TracBrowser for help on using the repository browser.