Пример #1
0
class SchemaDialog(gtk.Window):
    ftypes = ('string','integer','float')
    def __init__(self, shapes, shapesgridtool=None):
        gtk.Window.__init__(self)
        self.set_title(_("Schema"))
        self.ftype = 'string'
        vbox = gtk.VBox(spacing=5)
        vbox.set_border_width(5)
        self.add(vbox)

        self.grid = SimpleGrid()
        self.grid.set_size_request(257,200)
        self.grid.sortable = False
        self.shapes = shapes
        self.shapesgridtool = shapesgridtool
        vbox.pack_start(self.grid)

        # New field
        frame = gtk.Frame(_("Add Field"))
        vbox.pack_start(frame, expand=False)

        table = gtk.Table(rows=5, columns=3)
        table.set_row_spacings(5)
        table.set_col_spacings(5)
        table.set_border_width(10)
        frame.add(table)

        table.attach(gtk.Label(_("Name")),0,1,0,1)
        self.new_field_name_entry = gtk.Entry(10)
        self.new_field_name_entry.set_text('')
        self.new_field_name_entry.set_editable(True)
        table.attach(self.new_field_name_entry,1,2,0,1)

        table.attach(gtk.Label(_("Type")),0,1,2,3)
        self.new_field_width_entry = gtk.Entry(2)
        self.new_field_width_entry.set_text('20')
        self.new_field_width_entry.set_editable(True)
        table.attach(self.new_field_width_entry,1,2,2,3)

        table.attach(gtk.Label(_("Width")),0,1,3,4)
        self.new_field_precision_entry = gtk.Entry(2)
        self.new_field_precision_entry.set_text('0')
        self.new_field_precision_entry.set_editable(False)
        self.new_field_precision_entry.set_sensitive(False)
        table.attach(self.new_field_precision_entry,1,2,3,4)

        table.attach(gtk.Label(_("Precision")),0,1,1,2)
        self.new_field_type_menu = pgu.ComboText(strings=self.ftypes, action=self.new_field_precision_cb)
        self.new_field_type_menu.set_size_request(-1,24)
        table.attach(self.new_field_type_menu,1,2,1,2)

        button = gtk.Button(stock=gtk.STOCK_ADD)
        table.attach(button,0,2,4,5)
        button.connect("clicked", self.add_field)

        # Ability to delete fields?
        self.fill_grid()
##        self.grid.resize_to_default()
        hbox = gtk.HButtonBox()
        vbox.pack_end(hbox, expand=False)
        button = gtk.Button(stock=gtk.STOCK_CLOSE)
        button.connect("clicked", self.close)
        hbox.pack_start(button)
        self.show_all()

    def fill_grid(self):
        """ Get the schema and fill the grid """
        data = FieldsSource(self.shapes)
        types = [str]*4
        self.grid.set_data_source(data, data.fields, types)
        # name and type are not editable
        for col in self.grid.get_columns()[:2]:
            rend = col.get_cell_renderers()[0]
            rend.set_property('editable', False)
        self.grid.model.connect('row-changed', self.changed_field)

    def add_field(self, *args):
        """ Add field """
        sch = self.shapes.get_schema()
        name = self.new_field_name_entry.get_text()

        for item in sch:
            if item[0].lower() == name.lower():
                error(_("cm_editgrid56811109949513") % name)
                return

        ftype = self.ftype

        try:
            fwidth = int(self.new_field_width_entry.get_text())
        except:
            error(_("cm_editgrid56821109949513"))
            return

        if ftype == 'float':
            try:
                fprec = int(self.new_field_precision_entry.get_text())
            except:
                error(_("cm_editgrid56831109949513"))
                return
        else:
            fprec = 0

        self.shapes.add_field(name.upper(), ftype, fwidth, fprec)
        self.fill_grid()
        if self.shapesgridtool is not None:
            self.shapesgridtool.grid.add_column(name.upper(), ftype, fwidth)

    def changed_field(self, lst, path, iter):
        """ User changed a field """
        idx = path[0]
        n,t,w,p = lst[idx]
        self.shapes.set_property('_field_width_%s' % (idx+1), w)
        if lst.get_value(iter,1) == 'float':
            self.shapes.set_property('_field_precision_%s' % (idx+1), p)
        if self.shapesgridtool is not None:
            self.shapesgridtool.layer_update()

    def new_field_precision_cb(self, widget, *args):
        self.ftype = self.ftypes[widget.get_active()]
        if self.ftype == 'float':
            # precision is only relevant for float
            self.new_field_precision_entry.set_editable(True)
            self.new_field_precision_entry.set_sensitive(True)
        else:
            self.new_field_precision_entry.set_text('0')
            self.new_field_precision_entry.set_editable(False)
            self.new_field_precision_entry.set_sensitive(False)

    def close(self, *args):
        self.hide()
##        self.shapesgridtool.set_keep_above(True)
        self.destroy()
Пример #2
0
class AttributeEditor(gtk.Window, Signaler):
    def __init__(self, app=None):
        gtk.Window.__init__(self)
        self.set_title(_("Edit Vector Attributes"))

        self.app = app
        self.layer = None
        self.shapes = None
        self.viewarea = None
        self.layer_teardown_id = None
        self.selecting = False

        self.init_dialog()
        # popup menu items
        entries = ["Set subset/Selected","Set subset/Unselected",
                    "Set subset/All","New layer/Selected","New layer/Unselected"]

        self.grid.make_menu(entries, self.menu_clicked)

    def init_dialog(self):
        vbox = gtk.VBox(spacing=5)
        vbox.set_border_width(10)
        self.add(vbox)

        self.grid = SimpleGrid()
        self.grid.set_size_request(450,398)
        vbox.pack_start(self.grid)

        hbox = gtk.HButtonBox()
        vbox.pack_start(hbox, expand=False)
        self.schema_button = gtk.Button(_("Edit Columns"))
        self.schema_button.connect("clicked", self.edit_schema)
        hbox.pack_start(self.schema_button)

        rbutton = gtk.Button(_("Refresh Columns"))
##        rbutton.connect("clicked", self.refresh_columns)
        hbox.pack_start(rbutton, expand=False)
        rbutton.set_sensitive(False)

        hbox = gtk.HButtonBox()
        vbox.pack_start(hbox, expand=False)
        button = gtk.Button(stock=gtk.STOCK_CLOSE)
        button.connect("clicked", self.close)
        hbox.pack_start(button, expand=False)

        # Trap window close event
        self.connect('delete-event', self.close)

        self.app.sel_manager.subscribe('active-layer-changed', self.layer_update)
        self.grid.subscribe('selected-changed', self.selected_cb)
        self.show_all()
        # Only do actions when grid is visible
        self.active = False

    def show_cb(self, *args):
        # Activate the view that the grid was launched from
        # (confusing for user if launching the grid from
        # one view shows the vectors for another)
        for view in self.app.view_manager.view_list:
            if view == args[0]:
                self.app.view_manager.set_active_view(view)

        self.active = True
        self.show_all()
        self.present()
        self.layer_update()

    def close(self, *args):
        self.active = False
        self.layer_teardown_cb()
        self.hide()
        return True

    def layer_update(self, *args):
        # Disconnect from the old layer
        if not self.active:
            return

        self.layer_teardown_cb()

        layer = self.app.sel_manager.get_active_layer()
        if layer is None or isinstance(layer, gview.GvRasterLayer):
            return

        try:
            self.layer = layer
            self.viewarea = self.app.sel_manager.get_active_view()
            self.shapes = self.layer.get_parent()
            self.set_source(self.shapes)
            self.layer_teardown_id = self.layer.connect('teardown', self.layer_teardown_cb)
            self.app.sel_manager.subscribe('selection-changed', self.selection_update)
            self.selection_update()
        except:
            import sys, traceback
            last_type, last_value, exc_traceback = sys.exc_info()
            exp = traceback.format_exception(last_type, last_value, exc_traceback)
            for line in exp:
                print line

#            error(_('cm-editgrid-err-load'))

    def selection_update(self, *args):
        if self.selecting:
            return
        self.grid.set_selected(self.layer.get_selected())

    def selected_cb(self, *args):
        self.selecting = True
        self.layer.clear_selection()
        for selected in self.grid.get_selected():
            self.layer.select_shape(selected)
        self.layer.display_change()
        self.selecting = False

    def layer_teardown_cb(self, *args):
        self.grid.clear()
        if self.layer_teardown_id is not None:
            self.layer.disconnect(self.layer_teardown_id)
            self.layer_teardown_id = None
            self.app.sel_manager.unsubscribe('selection-changed', self.selection_update)
        self.viewarea = None
        self.layer = None
        self.shapes = None

    def set_source(self, source, titles=None, hidden=None):
        #trap setting to None or an invalid shapes object       
        if not source:
            return

        if not titles:
            titles = source.get_fieldnames()
        data = ShapesSource(source, titles)
        schema = source.get_schema()
        parms = self.grid.calculate_widths(titles, [f[2] for f in schema])
        types = [str]*len(titles)
        self.grid.set_data_source(data, titles, types, parms)

    def edit_schema(self, *args):
        """ Edit the shapes schema. """
        if self.shapes is None:
            return

        sch = SchemaDialog(self.shapes, self)

    def menu_clicked(self, text, row):
        rows = self.grid.get_selected()
        if not rows:
            return

        if "Unselected" in text:
            rows = filter(lambda i: i not in rows, range(len(self.shapes)))

        if text == "Set subset/All":
            self.grid.set_subset(None)
        elif "Set subset" in text:
            self.grid.set_subset(rows)
        elif "New layer" in text:
            name = text.split('/')[1]
            self.new_layer_selected(rows, name)

    def new_layer_selected(self, rows, name):
        """ Create new layer of only selected shapes """
        if not rows:
            warning('No rows selected- ignoring!')
            return

        newshps = gview.GvShapes(name=name)
        src = self.shapes
        if src is None:
            warning('No source layer found- ignoring!')
            return
        
        newshps.copy_fields(src.get_schema())

        for idx in rows:
            if src[idx] is not None:
                newshps.append(src[idx].copy())

        gview.undo_register(newshps)
        clayer = gview.GvShapesLayer(newshps)

        cview = self.app.new_view()
        cview.viewarea.add_layer(clayer)
        cview.viewarea.set_active_layer(clayer)