Пример #1
0
class _DownloadStatus(HBox):
    def __init__(self, queue):
        HBox.__init__(self)
        self.thread = DlWorker(queue, self.progress, self.set_url)
        self.label = Label('hello')
        self.pbar = ProgressBar()
        self.pack_start(self.label, FALSE, FALSE, 0)
        self.pack_end(self.pbar, FALSE, FALSE, 0)
        self.label.show()
        self.pbar.show()
        self.show()
        self._done = False
        self._started = False

    def progress(self, dt, dd, ut, ud):
        threads_enter()
        print 'in progress', dt, dd, ut, ud
        if dt == 0:
            self._done += 0.1
            if self._done >= 1:
                self._done = 0
        else:
            self._done = float(dd) / float(dt)
        print '_done', self._done
        self.pbar.set_fraction(self._done)
        threads_leave()

    def set_url(self, url):
        self.label.set_text(url)

    def start(self, *args):
        if not self._started:
            self.thread.start()
            self._started = True
Пример #2
0
class _DownloadStatus(HBox):
    def __init__(self, queue):
        HBox.__init__(self)
        self.thread = DlWorker(queue, self.progress, self.set_url)
        self.label = Label("hello")
        self.pbar = ProgressBar()
        self.pack_start(self.label, FALSE, FALSE, 0)
        self.pack_end(self.pbar, FALSE, FALSE, 0)
        self.label.show()
        self.pbar.show()
        self.show()
        self._done = False
        self._started = False

    def progress(self, dt, dd, ut, ud):
        threads_enter()
        print "in progress", dt, dd, ut, ud
        if dt == 0:
            self._done += 0.1
            if self._done >= 1:
                self._done = 0
        else:
            self._done = float(dd) / float(dt)
        print "_done", self._done
        self.pbar.set_fraction(self._done)
        threads_leave()

    def set_url(self, url):
        self.label.set_text(url)

    def start(self, *args):
        if not self._started:
            self.thread.start()
            self._started = True
Пример #3
0
class PresenceServiceNameWatcher(VBox):
    def __init__(self, bus):
        VBox.__init__(self)

        self.bus = bus

        logger.debug('Running...')
        self.label = Label('Looking for Presence Service...')
        self.errors = ListStore(str)

        errors_tree = TreeView(model=self.errors)
        errors_tree.insert_column_with_attributes(0,
                                                  'Log',
                                                  CellRendererText(),
                                                  text=0)
        scroller = ScrolledWindow()
        scroller.add(errors_tree)

        self.paned = VPaned()
        self.paned.pack1(scroller)

        self.pack_start(self.label, False, False)
        self.pack_end(self.paned)

        bus.watch_name_owner(PS_NAME, self.on_name_owner_change)
        self.ps_watcher = Label('-')
        self.paned.pack2(self.ps_watcher)

        self.show_all()

    def log(self, format, *args):
        self.errors.append((format % args, ))

    def on_name_owner_change(self, owner):
        try:
            if owner:
                self.label.set_text(
                    'Presence Service running: unique name %s' % owner)
                if self.ps_watcher is not None:
                    self.paned.remove(self.ps_watcher)
                self.ps_watcher = PresenceServiceWatcher(
                    self.bus, owner, self.log)
                self.paned.pack2(self.ps_watcher)
                self.show_all()
            else:
                self.label.set_text('Presence Service not running')
                if self.ps_watcher is not None:
                    self.paned.remove(self.ps_watcher)
                self.ps_watcher = Label('-')
                self.paned.pack2(self.ps_watcher)
        except Exception, e:
            self.log('ERROR: %s', e)
class Requeriment(Expander):
    def __init__(self, objectives, new):
        Expander.__init__(self)

        self.connect("enter-notify-event", self.onEnterNotifyEvent)
        self.connect("leave-notify-event", self.onLeaveNotifyEvent)

        vBox = VBox()
        self.add(vBox)

        # Data model
        self.model = ListStore(str, float)

        # Title bar
        hBox = HBox()
        self.set_property("label-widget", hBox)

        self.title = Label()
        hBox.pack_start(self.title)

        # Alternatives
        treeView = TreeView(self.model)
        #		treeView.set_headers_visible(False)
        vBox.pack_start(treeView)

        listStore_objectives = ListStore(str)
        for name in objectives:
            listStore_objectives.append((name, ))

        def combo_changed(_, path, text, model):
            model[path][0] = text

        cellRenderer = CellRendererCombo()
        cellRenderer.connect("edited", combo_changed, self.model)
        cellRenderer.set_property("text-column", 0)
        cellRenderer.set_property("editable", True)
        cellRenderer.set_property("has-entry", True)
        cellRenderer.set_property("model", listStore_objectives)

        treeViewColumn = TreeViewColumn("Alternative", cellRenderer, text=0)
        #		treeViewColumn = TreeViewColumn(None,cellRenderer,text=0)
        treeView.append_column(treeViewColumn)

        def spin_changed(_, path, value, model):
            model[path][1] = float(value.replace(",", "."))

        cellRenderer = CellRendererSpin()
        cellRenderer.connect("edited", spin_changed, self.model)
        cellRenderer.set_property("adjustment",
                                  Adjustment(1, 0, 100, 1, 10, 0))
        cellRenderer.set_property("editable", True)
        cellRenderer.set_property("digits", 2)

        treeViewColumn = TreeViewColumn(None, cellRenderer, text=1)
        treeView.append_column(treeViewColumn)

        # Add/remove alternative button box
        #		hButtonBox = HButtonBox()
        #		vBox.pack_start(hButtonBox, False)

        # Add alternative
        button = Button("gtk-add")
        button.connect("clicked", self.on_btnAdd_Alternative_clicked)
        button.set_use_stock(True)
        #		hButtonBox.pack_start(button)
        vBox.pack_start(button, False)

        #		# Remove alternative
        #		button = Button("gtk-remove")
        #		button.connect("clicked",self.on_btnDel_Alternative_clicked)
        #		button.set_use_stock(True)
        #		hButtonBox.pack_start(button)

        # Expand the requeriment and add an alternative if it's new
        if new:
            self.set_expanded(True)
            self.model.append((None, 1.0))

        # Show requeriment
        self.show_all()

        # Delete requeriment button (default is hidden)
        self.imgRemove = Image()
        self.imgRemove.connect("button-press-event", self.onDelRequeriment)
        self.imgRemove.set_from_stock("gtk-cancel", ICON_SIZE_MENU)
        hBox.pack_start(self.imgRemove)

    def Add(self, alternative):
        self.model.append(alternative)

        names = []
        iter = self.model.get_iter_first()
        while iter:
            alt = self.model.get_value(iter, 0)
            if alt:
                names.append(alt)

            iter = self.model.iter_next(iter)

        self.title.set_text(','.join(names))

    def GetData(self):
        result = OrderedDict()

        iter = self.model.get_iter_first()
        while iter:
            alt = self.model.get_value(iter, 0)
            if alt:
                result[alt] = self.model.get_value(iter, 1)

            iter = self.model.iter_next(iter)

        return result

    def onDelRequeriment(self, widget):
        self.get_parent().remove(self)

    def onEnterNotifyEvent(self, widget, event):
        self.imgRemove.show()

    def onLeaveNotifyEvent(self, widget, event):
        self.imgRemove.hide()

    def __btnDel_Alternative_Sensitivity(self):
        pass
#		self.__btnDel.set_sensitive(len(self.__model.))

    def on_btnAdd_Alternative_clicked(self, widget):
        self.model.append((None, 1.0))

        self.__btnDel_Alternative_Sensitivity()

    def on_btnDel_Alternative_clicked(self, widget):

        self.__btnDel_Alternative_Sensitivity()
class multipage_glade_editor(object):
    def __init__(self,
                 trans, transid, plugin, gui_parent, change_register_function,
                 book, display_mode=TRANSACTION_ALL_EDIT_FIRST_TIME,
                 transaction_edit_finished_function=null_function):
        self.trans = trans
        self.transid = transid
        self.plugin = plugin
        self.gui_parent = gui_parent
        self.change_register_function = change_register_function
        self.book = book
        self.display_mode = display_mode
        self.transaction_edit_finished_function = (
            null_function if display_mode not in HEADLESS_MODES
            else transaction_edit_finished_function )

        self.hide_parent = Window()
        self.hide_parent.hide()
        self.mainvbox = VBox()
        self.hide_parent.add(self.mainvbox)

        config = self.trans.get_configuration_and_provide_on_load_hook()
        config_module_name = self.plugin.config_module_name
        if not config_valid(config):
            # even in the case of a broken config, we should still
            # display all of the data we have available...
            self.mainvbox.pack_start(Label("no configuration"))
        elif not self.trans.can_safely_proceed_with_config_module(config):
            # should display all data that's available instead of just
            # this label
            #
            # and should give
            # user an overide option where they either pick an old config
            # for one time use or just blow out the memory of having used
            # a different config...
            #
            # should also print the checksum itself so they know
            # what they need...
            #
            # perhaps eventually we even put in place some archival support
            # for saving old glade and config files and then code into the
            # the transaction -- hey, code you need to be editable is
            # over here..
            #
            # now hopefully there is no marking of this transaction dirty
            # in this mode and the extra safegaurds we put into
            # MultipageGladeTransaction don't get activated
            self.mainvbox.pack_start(
                Label("out of date configuration. data is read only here for "
                      "the safety of your old information, last adler "
                      "CRC was %s" % self.trans.config_crc_cache ))
        else:
            # if the safety cache was relied on before we need to tell the
            # backend that the transaction is actually dirty,
            # and now that we know that we have a workable config,
            # there's a chance that we'll actually be able to avoid
            # relying on the cache this time
            if self.trans.get_safety_cache_was_used():
                self.change_register_function()

            self.page_label = Label("")
            (x_align, y_align) = self.page_label.get_alignment()
            self.page_label.set_alignment(0.0, y_align)
            self.mainvbox.pack_start(self.page_label, expand=False)

            # establish maincontainer, which is where the actual glade
            # pages are put by attach_current_page
            #
            # The order of placement here is important, we place this
            # after page_label has already been added to main
            # and we also need to do this prior to attach_current_page
            # being called, as it depends on self.maincontainer being
            # there
            #
            # when we're in headless mode the maincontainer can just be
            # the mainvbox itself
            #
            # but, outside headless mode we save screen real-estate and
            # place a scrolled window (which becomes the maincontainer)
            # inside the mainvbox and the glade by glade pages end up
            # in there instead (again, in attach_current_page)
            if display_mode in HEADLESS_MODES:
                self.maincontainer = self.mainvbox
            else:
                self.maincontainer = Viewport()
                sw = ScrolledWindow()
                sw.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
                sw.add( self.maincontainer)
                self.mainvbox.pack_start(sw)

            self.glade_pages = [
                self.__setup_page(glade_file, top_glade_element)
                for glade_file, top_glade_element in config.pages ]
            self.glade_pages_by_ident_index = dict(
                ( (key, self.glade_pages[i])
                  for i, key in enumerate(config.pages)
                  ) # end generator expression
                ) # end dict
            
            self.__setup_auto_widgets()

            self.current_page = 0
            self.attach_current_page()

            button_hbox = HBox()
            self.mainvbox.pack_end(button_hbox, expand=False)
            self.nav_buts = dict( (Button(), i)
                                  for i in range(2) )
            for but, i in self.nav_buts.iteritems():
                but.set_property('use-stock', True)
                but.set_label( STOCK_GO_BACK
                               if i == GLADE_BACK_NAV else STOCK_GO_FORWARD )
                button_hbox.pack_start(but, expand=False)
                but.connect("clicked", self.nav_but_clicked)

            config.gui_initialization_hook(
                self, self.trans, self.plugin, self.book)

        self.mainvbox.show_all()
        self.mainvbox.reparent(self.gui_parent)

    def page_is_current(self, page):
        # assumption is that config is fine and we're on a page
        assert( hasattr(self, 'glade_pages_by_ident_index') and
                True )
        return \
            self.glade_pages_by_ident_index[page] == self.current_widget_dict

    def __setup_page(self, glade_file, top_glade_element):
        widget_dict = {}
        
        # this should come from the config, seeing how we're setting up
        # our stuff manually
        event_handlers_dict = {}
        load_glade_file_get_widgets_and_connect_signals(
            glade_file, top_glade_element,
            widget_dict, event_handlers_dict )
        widget_dict[top_glade_element].hide()
        return widget_dict

    def __setup_auto_widgets(self):
        # go through each page
        for key, widget_dict in self.glade_pages_by_ident_index.iteritems():
            # go through each widget
            for widget_name, widget in widget_dict.iteritems():
                widget_key = (key, widget_name)

                # determine if the current widget is one that we can take
                # care of automatically saving, we do this with a linear
                # search through a table of eligible types,
                # where the first element of each entry is Widget class
                #
                # Once we have a match do one of the following
                #  * Change the widget from the existing stored stage
                #  * Establish new state from some default
                # The next two entries in the table
                # (change_widget_from_state, new_state_from_widget)
                # provide functions to do this
                #
                # Lastly, we establish event handlers for this widget using
                # the last element in the table
                for (cls,
                     change_widget_from_state, new_state_from_widget,
                     establish_event_handlers) in ( # start table

                    (Entry,
                     lambda w, wk: w.set_text(self.trans.get_widget_state(wk)),
                     lambda w: '',
                     lambda w: w.connect("changed", self.entry_changed),
                     ), # Entry

                    (Calendar,
                     self.__change_calendar_from_saved_version,
                     get_current_date_of_gtkcal,
                     lambda w: w.connect( "day_selected",
                                          self.calendar_changed ), 
                     ), # Calendar

                    (CheckButton,
                     lambda w, wk:
                         w.set_active(self.trans.get_widget_state(wk)),
                     get_state_of_checkbutton,
                     lambda w: w.connect("toggled", self.checkbutton_changed),
                     ), # CheckButton

                    ): # end of table and for declartion

                    # does the widget match the type in the current table entry?
                    if isinstance(widget, cls):

                        # use the three remaining functions in the table
                        # as appropriate
                        if self.trans.has_widget_state( widget_key ):
                            change_widget_from_state(widget, widget_key)
                        else:
                            self.trans.update_widget_state(
                                widget_key,
                                new_state_from_widget(widget) )
                        establish_event_handlers(widget)

    def __change_calendar_from_saved_version(self, widget, widget_key):
        set_current_date_of_gtkcal(widget, 
                                   self.trans.get_widget_state( widget_key ) )

    def attach_current_page(self):
        config = self.plugin.get_configuration(allow_reload=False)
        self.current_widget_dict = self.glade_pages[self.current_page] 
        self.current_window = self.current_widget_dict[
            config.pages[self.current_page][TOP_WIDGET] ]
        self.current_top_vbox = self.current_window.child
        self.current_top_vbox.reparent(
            self.maincontainer)
        self.page_label.set_text( "page %s of %s" %( self.current_page + 1,
                                                     len(config.pages) ) )
        self.update_auto_labels()

    def detach_current_page(self):
        # put the spawn back to wence it came
        self.current_top_vbox.reparent(
            self.current_window)

    def detach(self):
        if hasattr(self, 'current_page'):
            self.detach_current_page()
        self.mainvbox.reparent(self.hide_parent)

    def page_change_acceptable_by_input_valid(self):
        bad_fields = ', '.join( widget_name
            for widget_name, widget in self.current_widget_dict.iteritems()
            if not self.widget_valid(widget_name, widget)
            )
        if bad_fields == '':
            return True
        else:
            # this is kind of primiative, it would be better to
            # just highlight them by inserting red lights or something
            gtk_error_message("The following fields are invalid %s" %
                              bad_fields )
            return False
    
    def __current_page_ident(self):
        config = self.plugin.get_configuration(allow_reload=False)
        return config.pages[self.current_page]

    def __entry_widget_is_check_excempt(self, widget_name):
        config = self.plugin.get_configuration(allow_reload=False)
        return (self.__current_page_ident(), widget_name) in \
            config.non_decimal_check_labels

    def widget_valid(self, widget_name, widget):
        config = self.plugin.get_configuration(allow_reload=False)
        if isinstance(widget, Entry) and \
                not self.__entry_widget_is_check_excempt(widget_name):
            try:
                entry_to_decimal_convert(
                    widget.get_text(), widget_name,
                    self.__current_page_ident(),
                    config)
            except EntryTextToDecimalConversionFail:
                return False
        # this covers not only the else case on the first if, but the
        # the case with the above try, except passes without exception
        return True

    def nav_but_clicked(self, but, *args):
        config = self.plugin.get_configuration(allow_reload=False)
        
        old_page = self.current_page
        delta = -1 if self.nav_buts[but] == GLADE_BACK_NAV else 1
        new_page = old_page + delta
        # reject a change outside the acceptable range.. and hmm,
        # perhaps this event handler should never even run under those
        # conditions because we should really just grey the buttons
        if not (new_page < 0 or new_page == len(self.glade_pages)) and \
                self.page_change_acceptable_by_input_valid() and \
                config.page_change_acceptable(self.trans, old_page, new_page):

            # intentionally done before the page is actually attached,
            # that's what we mean by pre
            config.page_pre_change_config_hooks(self.trans, old_page, new_page)

            self.detach_current_page()
            self.current_page = new_page
            self.attach_current_page()
            
            # intentionally done after the page is actually attached,
            # that's what we mean by post
            config.page_post_change_config_hooks(self.trans, old_page, new_page)

    entry_changed = make_widget_changed_func(lambda w: w.get_text() )
    calendar_changed = make_widget_changed_func(get_current_date_of_gtkcal)
    checkbutton_changed = make_widget_changed_func(get_state_of_checkbutton)

    def update_auto_labels(self):
        config = self.plugin.get_configuration(allow_reload=False)
        # this function should never be called if the config hasn't been
        # checked out as okay
        assert( hasattr(config, 'auto_update_labels') )
        for page, label_name, label_source_func in config.auto_update_labels:
            if self.page_is_current(page):
                try:
                    label_text = str(label_source_func(
                            self.trans.widget_states, config))
                except EntryTextToDecimalConversionFail, e:
                    label_text = ''
                except WidgetFindError, no_find_e:
                    label_text = str(no_find_e)
                self.current_widget_dict[label_name].set_text(label_text)