def __init__(self):
        toolbox.Tool.__init__(self)
        
        # create gui (a treeview in a scrolled window with a
        # buttonbox underneath)
        treeview = ProjectTreeView()
        scrollwindow = uihelper.add_scrollbars(treeview)
        
        buttons = [(gtk.STOCK_ADD, lambda sender: None),
                   (gtk.STOCK_REMOVE, lambda sender: None)]
        buttonbox = uihelper.construct_hbuttonbox(buttons, labels=False)

        self.pack_start(scrollwindow, True, True)
        #self.pack_start(buttonbox, False, True)        
        self.show_all()
        
        self.buttonbox = buttonbox
        self.treeview = treeview
        self.scrollwindow = scrollwindow

        # connect to callbacks
        treeview.connect( "row-activated", self.on_row_activated )
        treeview.connect( "button-press-event", self.on_button_press_event )
        treeview.connect( "popup-menu", self.on_popup_menu, 3, 0 )

        # create actions for ui manager
        uimanager = globals.app.window.uimanager
        uihelper.add_actions(uimanager, "ProjectView", self.actions, self)
        uimanager.add_ui_from_string(globals.app.get_uistring('project_explorer'))
    def __init__(self, project, dataset, colnr):
        gtk.Window.__init__(self)
        self.set_title("Cool Column Calculator")
        self.set_size_request(width=-1, height=200)
        
        self.project = project
        self.dataset = dataset
        self.colnr = colnr    

        vbox = gtk.VBox()

        self.label = gtk.Label("col(%d) = " % self.colnr)       

        self.textview = gtk.TextView()
        self.scrolled_window = uihelper.add_scrollbars(self.textview)

        btn1 = gtk.Button(stock=gtk.STOCK_APPLY)
        btn1.connect('clicked', self.on_apply)
        btn2 = gtk.Button(stock=gtk.STOCK_CLOSE)
        btn2.connect('clicked', (lambda sender: self.destroy()))
        
        self.btnbox = gtk.HButtonBox()
        self.btnbox.pack_end(btn2)
        self.btnbox.pack_end(btn1)

        vbox.pack_start(self.label, False)
        vbox.pack_start(self.scrolled_window, True, True)
        vbox.pack_end(self.btnbox, False)
        self.add(vbox)
        self.show_all()
    def construct_preview(self, filename):
        if filename is None:
            return gtk.Label()           
        
        view = gtk.TextView()
        buffer = view.get_buffer()
        view.set_editable(False)
        view.show()
        
        tag_main = buffer.create_tag(family="Courier")
        tag_linenr = buffer.create_tag(family="Courier", weight=pango.WEIGHT_HEAVY)

        # fill preview buffer with at most 100 lines
        try:
            fd = open(filename, 'r')
        except IOError:
            raise RuntimeError("Could not open file %s for preview!" % filename)

        iter = buffer.get_start_iter()        
        try:
            for j in range(1,100):
                line = fd.readline()
                if len(line) == 0:
                    break
                buffer.insert_with_tags(iter, u"%3d\t" % j, tag_linenr)
                try:
                    buffer.insert_with_tags(iter, unicode(line), tag_main)
                except UnicodeDecodeError:
                    buffer.insert_with_tags(iter, u"<unreadable line>\n", tag_main)
        finally:
            fd.close()

        return uihelper.new_section("Preview", uihelper.add_scrollbars(view))
    def __init__(self, project, dataset=None):
        gtk.Window.__init__(self)
	self.set_size_request(280,320)
        self.set_transient_for(globals.app.window)
        
        self.cblist = []

        # GUI elements
        self.uimanager = self._construct_uimanager()

        self.menubar = self.uimanager.get_widget('/MainMenu')

        self.toolbar = self.uimanager.get_widget('/Toolbar')
        self.toolbar.set_style(gtk.TOOLBAR_ICONS)

        self.popup = self.uimanager.get_widget('/popup_column')

        self.statusbar = gtk.Statusbar()
        self.statusbar.set_has_resize_grip(True)        

        self.dataview = self._construct_dataview()
        sw = uihelper.add_scrollbars(self.dataview)
                
        hpaned = gtk.HPaned()
        hpaned.pack1( sw )
#        hpaned.pack2( self._construct_metadata_widget() )
        self.hpaned = hpaned
        
        vbox = gtk.VBox()

        vbox.pack_start( self.menubar, expand=False, fill=True )
        # toolbar disabled right now -- it clutters and is not so useful
#        vbox.pack_start( self.toolbar, expand=False, fill=True )
        vbox.pack_start( self.hpaned, expand=True, fill=True )
        vbox.pack_start( self.statusbar, expand=False, fill=True )

        self.add(vbox)

        self.project = project  # immutable
        self._dataset = None

        self.set_dataset(dataset)        
        self.project.sig_connect("close", (lambda sender: self.destroy()))

        self.dataview.emit('cursor_changed')

        self.show_all()
    def edit(self, obj):

        # create new widget (unless we don't have a SPObject, e.g. a List)
        if self.edit_cache.has_key(obj.__class__) is False:
            # create factory
            factory = checkwidgets.DisplayFactory(obj)
            try:
                #keys = KLASS_KEYS[obj.__class__]
                keys = KLASS_DESCR[obj.__class__]['attrs']
            except KeyError:
                keys = [key for key, check in obj._checks.iteritems() if not isinstance(check, (List,Dict))]                
            factory.add_keys(keys)

            # create widget and add it to the edit area
            tbl = factory.create_table()
            widget = uihelper.add_scrollbars(tbl, viewport=True)
            self.paned.pack2(widget)

            # set up undo hooks (needs to be after creation of table, because
            # otherwise there are no displays!)
            undo_hook = lambda obj, key, value: uwrap.set(obj, key, value, undolist=globals.app.project.journal)
            for display in factory.displays.itervalues():
                display.set_value = undo_hook

            self.add_to_cache(obj, widget, factory)           

        # show widget
        widget, factory = self.edit_cache[obj.__class__]
        if factory is not None:
            factory.connect(obj)
        child = self.paned.get_child2()
        if child is not None and child is not widget:
            self.paned.remove(child)
            self.paned.pack2(widget)
        widget.show_all()

        self.obj = obj        
    def __init__(self):
        toolbox.Tool.__init__(self)

        self.depends_on(globals.app, 'active_backend')
        self.popup_info = None
        
        #
        # Treeview
        #
        
        # model (object)
        model = gtk.TreeStore(object, str)

        self.treeview = treeview = gtk.TreeView(model)
        treeview.set_headers_visible(False)
        treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
        
        column = gtk.TreeViewColumn('label')

        cell = gtk.CellRendererPixbuf()                        
        column.pack_start(cell,expand=False)
        def render_icon(column, cell, model, iter):
            obj = model.get_value(iter, 0)
            key = model.get_value(iter, 1)
            if key is not None:
                stock_id = 'sloppy-%s'%key.lower()
            else:
                stock_id = 'sloppy-%s'%obj.__class__.__name__.lower()
            cell.set_property('stock_id', stock_id)        
        column.set_cell_data_func(cell, render_icon)
        treeview.append_column(column)
        
        cell = gtk.CellRendererText()
        column.pack_start(cell)
        def render_label(column, cell, model, iter):
            obj = model.get_value(iter, 0)
            key = model.get_value(iter, 1)

            if key is None:
                for attr in ['label', 'title', 'key']:
                    if hasattr(obj, attr):
                        key = getattr(obj, attr)

            label = key
            cell.set_property('text', label)

            
            label = None
            if key is not None:
                label = key
            else:
                try:
                    label = obj.get_description()
                except:
                    for attr in ['label', 'title', 'key']:
                        if hasattr(obj, attr):
                            label = getattr(obj, attr)
                            break
                    else:
                        label = "<%s>" % obj.__class__.__name__                        

            cell.set_property('text', label)
            
        column.set_cell_data_func(cell, render_label)
        treeview.append_column(column)

        treeview.connect("button-press-event", self.on_button_press_event)
        treeview.connect("cursor-changed", self.on_cursor_changed)
        treeview.connect("popup-menu", self.on_popup_menu, 3, 0)
        treeview.show()    

        # The edit_cache is a dict where the keys are the classes
        # of the objects that can be edited and the values are
        # tuples (widget, factory), which are the edit widget for this
        # class and the corresponding DisplayFactory object to make 
        # the connection to actual objects. The factory may be None.
        self.edit_cache = {}

        # The currently edited object. Use edit_cache[self.obj.__class__]
        # to get the currently active widget and its factory
        self.obj = None

        #
        # Both the treeview and the table are stuffed into
        # a vbox; but there is no no table to begin with.
        # It is created in the on_cursor_changed event.
        #
        self.paned = gtk.VPaned()
        self.paned.pack1(uihelper.add_scrollbars(treeview),True,True)
        self.add(self.paned)
               
        #self.vbox = vbox = gtk.VBox()
        #vbox.add(uihelper.add_scrollbars(treeview))
        #self.add(vbox)
        
        # Connect to Backend.
        self.backend = -1
        #self.dock.connect('backend', ...)
        sender = globals.app
        sender.sig_connect('update::active_backend', self.on_update_backend)
        self.on_update_backend(sender, 'backend', sender.active_backend)

        # ui manager
        uimanager = globals.app.window.uimanager        
        uihelper.add_actions(uimanager, "PropertyEditor", self.actions, self)
        uimanager.add_ui_from_string(globals.app.get_uistring('property_editor'))              
    def __init__(self, layer):
        AbstractTab.__init__(self)
        self.layer = layer

        #
        # Construct TreeView and ButtonBox
        #

        keys = ['visible', 'label', 'style', 'width', 'color', 'marker', 'marker_color', 'marker_size', 'source', 'cx', 'cy', 'row_first', 'row_last']
        self.factory = widget_factory.CTreeViewFactory(layer, 'lines')
        self.factory.add_columns(keys, source=self.create_source_column)
        self.treeview = self.factory.create_treeview()
        sw = uihelper.add_scrollbars(self.treeview)

        #
        # keybox = label + key_combo 
        #
        model = gtk.ListStore(str, object)
        key_combo = gtk.ComboBox(model)
        cell = gtk.CellRendererText()
        key_combo.pack_start(cell, True)
        key_combo.add_attribute(cell, 'text', 0)
        key_combo.connect('changed', lambda cb: self.limit_columns())
        self.key_combo = key_combo # for use in limit_columns()
        
        viewdict = {'all' : ['_all'],
                    'style' : ['visible', 'label', 'style', 'width', 'color', 'marker', 'marker_color', 'marker_size'],
                    'data' : ['visible', 'label', 'source', 'cx', 'cy', 'row_first', 'row_last']}
        for key, alist in viewdict.iteritems():
            model.append((key, alist))

        keybox = gtk.HBox(False, 5)
        keybox.pack_start(gtk.Label("Display:"), False, False)
        keybox.pack_start(key_combo, False, False)
        keybox.pack_start(gtk.Label(), True, True)

        self.key_combo.set_active(0)
        self.limit_columns()
        
        buttons = [(gtk.STOCK_ADD, self.on_insert_new),
                   (gtk.STOCK_REMOVE, self.on_remove_selection),
                   (gtk.STOCK_GO_UP, self.on_move_selection, -1),
                   (gtk.STOCK_GO_DOWN, self.on_move_selection, +1)]        
        buttonbox = uihelper.construct_vbuttonbox(buttons, labels=False)
        
        hbox = gtk.HBox(False, 5)
        hbox.pack_start(sw, True, True)
        hbox.pack_start(buttonbox, False, True)

        vbox = gtk.VBox(False, 5)
        vbox.pack_start(keybox, False, False)
        vbox.pack_start(hbox)
        
        frame1 = uihelper.new_section('Lines', vbox)
        
        #
        # Construct Group Boxes
        #
        #self.gblist = [GroupBox(self.layer, 'group_linestyle'),
        #               GroupBox(self.layer, 'group_linemarker'),
        #               GroupBox(self.layer, 'group_linewidth'),
        #               GroupBox(self.layer, 'group_linecolor')]
        self.gblist = []

        # DISABLE GROUP BOXES RIGHT NOW!
        self.gblist = []

#         # Wrap group boxes into a table       
#         table = gtk.Table(rows=len(self.gblist), columns=3)

#         n = 0
#         for widget in self.gblist:
#             # label (put into an event box to display the tooltip)
#             label = gtk.Label(widget.prop.blurb or widget.propname)
#             ebox = gtk.EventBox()
#             ebox.add(label)
#             if widget.prop.doc is not None:
#                 tooltips.set_tip(ebox, widget.prop.doc)
            
#             table.attach(ebox, 0, 1, n, n+1,
#                          xoptions=gtk.FILL, yoptions=0,
#                          xpadding=5, ypadding=1)            
#             table.attach(widget, 1, 2, n, n+1,
#                          xoptions=gtk.EXPAND|gtk.FILL, yoptions=0,
#                          xpadding=5, ypadding=1)
#             n += 1       

#         frame2 = uihelper.new_section('Group Properties', table)

        #
        # Put everything together!
        #
        self.pack_start(frame1,True,True)

        # DISABLE GROUP BOXES RIGHT NOW
        #self.pack_start(frame2,False,True)

        self.show_all()
    def __init__(self):
        gtk.VBox.__init__(self)
    
        # We create copies of all templates and put these into the
        # treeview.  This allows the user to reject the modifications
        # (RESPONSE_REJECT).  If however he wishes to use the
        # modifications (RESPONSE_ACCEPT), then we simply need to
        # replace the current templates with these temporary ones.

        # check in
        self.model = gtk.ListStore(str, object) # key, object
        model = self.model # TBR

        #
        # create gui
        #
        # columns should be created in the order given by COLUMN_xxx
        # definitions above.
        tv = gtk.TreeView(model)

        tv.set_headers_visible(False)

        cell = gtk.CellRendererText()
        column = gtk.TreeViewColumn()
        column.pack_start(cell)

        def render(column, cell, model, iter):
            object = model.get_value(iter, self.MODEL_OBJECT)
            key = model.get_value(iter, self.MODEL_KEY)

            key = "<big><b>%s</b></big>" % key

            if object.blurb is not None:
                blurb = "<i>%s</i>" % object.blurb
            else:
                blurb = "<i>no description</i>"

            if object.immutable is True:
                blurb += " <i>(immutable)</i>"

            text = "%s\n%s" % (key, blurb)

            cell.set_property('markup', text)

        column.set_cell_data_func(cell, render)
        tv.append_column(column)
            
        self.treeview = tv
        sw = uihelper.add_scrollbars(tv)

        tv.connect("row-activated", (lambda a,b,c: self.on_edit_item(a,c)))
                    
        buttons=[(gtk.STOCK_EDIT, self.on_edit_item),
                 (gtk.STOCK_ADD, self.on_add_item),
                 (gtk.STOCK_COPY, self.on_copy_item),
                 (gtk.STOCK_DELETE, self.on_delete_item)]

        btnbox = uihelper.construct_vbuttonbox(buttons)
        btnbox.set_spacing(uihelper.SECTION_SPACING)
        btnbox.set_border_width(uihelper.SECTION_SPACING)

        sw.set_border_width(uihelper.SECTION_SPACING)


        hbox = gtk.HBox()
        hbox.pack_start(sw,True,True)
        hbox.pack_start(btnbox,False,True)
        
        frame = uihelper.new_section("Import Templates", hbox)
        self.add(frame)
        self.show_all()
def test():
    
    class TestObject(HasChecks):
        is_valid = Bool(init=True)
        is_valid_or_none = Bool(init=None)
        choices = Choice(['One', 'Two', 'Three'], init='Two')

        an_integer = Integer(init=0)
        a_float = Float(init=3.14)
        another_float = Float(init=-7892, max=27.0)
        a_third_float = Float(init=7.0, min=-5, max=12.874)
        what_an_integer = Integer(init=19, max=20)

        a_color = RGBColor(raw=True, init="lightgreen", doc="A color")

        a_mapping = Mapping({'One':1, 'Two':2, 'Three':3}, init='Three')

        a_string = String(init=None)

        def __init__(self, **kwargs):
            HasChecks.__init__(self, **kwargs)

            # set up available Signals
            self.signals = {}            
            self.signals['update'] = Signal()
            for key in self._checks.keys():                
                self.signals['update::%s'%key] = Signal()

            # trigger Signals on attribute update
            def dispatch(sender, key, value):
                sender.signals['update::%s'%key].call(sender, value)
            self.signals['update'].connect(dispatch)

            def on_update(sender, key, value):
                sender.signals['update'].call(sender, key,value)
            self.on_update = on_update
                             


    class MainObject(HasChecks):
        obj_list = List(Instance(TestObject))


    obj = TestObject(a_string="object ONE", is_valid=False, a_mapping='One')
    obj2 = TestObject(a_string="object TWO", an_integer=5, a_mapping=1)
    main = MainObject(obj_list=[obj, obj2])

    # This is how the notification works:

    # The object has an on_update function.
    # This function is set to emit a signal 'update'.
    # If you want to be informed of changes to the object,
    # just connect to this signal.

    # Each display should connect to the 'update' signal
    # of the object and call set_widget_data whenever
    # the value changes.

    df = DisplayFactory(obj)    
    df.add_keys(obj._checks.keys())
    tv = df.create_sections( ['Section One', 'a_string'],
                             ['Section Two', 'an_integer', 'a_string'] )
    df.check_in(obj)

    def quit(sender):
        df.check_out()
        print
        print "Obj1 ===>", obj._values
        gtk.main_quit()

    
    win = gtk.Window()
    win.set_size_request(640,480)
    win.connect('destroy', quit)

    hbox = gtk.HBox()
    hbox.add(tv)
    
    vbox = gtk.VBox()
    vbox.add(uihelper.add_scrollbars(hbox, viewport=True))
    win.add(vbox)
    win.show_all()

    gtk.main()
    def __init__(self):
        toolbox.Tool.__init__(self)
        self.settings = settings = Settings()
        
        self.depends_on(globals.app, 'active_backend')

        #
        # find button
        #
        self.btn_find = btn_find = gtk.Button('Find')
        btn_find.connect('clicked', self.on_btn_find_clicked)

        #
        # Settings
        #
        df = checkwidgets.DisplayFactory(Settings)
        ##self.display_line = DisplayLine()
        ##df.add_keys(self.settings._checks.keys(), line=self.display_line)
        df.add_keys(self.settings._checks.keys())
        self.table = table = df.create_sections(['Settings', 'line','threshold','accuracy'])
        df.connect(self.settings)
            
        #
        # Treeview (displaying the found peaks)
        #
        
        # model: (float, float, str) = (x,y, symobl)
        model = gtk.ListStore(float, float, str)        
        self.treeview = treeview = gtk.TreeView(model)
        treeview.set_headers_visible(False)

        cell = gtk.CellRendererText()        
        column = gtk.TreeViewColumn('X', cell)
        column.set_attributes(cell, text=0)
        cell = gtk.CellRendererText()
        treeview.append_column(column)
        
        cell = gtk.CellRendererText()        
        column = gtk.TreeViewColumn('Y', cell)
        column.set_attributes(cell, text=1)
        cell = gtk.CellRendererText()
        treeview.append_column(column)

        cell = gtk.CellRendererText()        
        column = gtk.TreeViewColumn('Symbol', cell)
        column.set_attributes(cell, text=2)
        cell = gtk.CellRendererText()
        treeview.append_column(column)

        #treeview.connect("row-activated", self.on_row_activated)
        #treeview.connect("cursor-changed", self.on_cursor_changed)

        # results is the section containing the treeview
        results = uihelper.new_section('Results:', uihelper.add_scrollbars(treeview))

        #
        # pack everything in a vbox
        #
        vbox = gtk.VBox()
        vbox.pack_start(results, True, True)
        vbox.pack_start(table, False, False)
        vbox.pack_start(btn_find, False, True)
        
        vbox.show_all()
        
        self.add(vbox)