[GRASS-SVN] r47714 - in grass/trunk/gui/wxpython: . gui_modules

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Aug 17 15:31:48 EDT 2011


Author: annakrat
Date: 2011-08-17 12:31:48 -0700 (Wed, 17 Aug 2011)
New Revision: 47714

Modified:
   grass/trunk/gui/wxpython/gui_modules/colorrules.py
   grass/trunk/gui/wxpython/gui_modules/gselect.py
   grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py
   grass/trunk/gui/wxpython/gui_modules/nviz_tools.py
   grass/trunk/gui/wxpython/gui_modules/workspace.py
   grass/trunk/gui/wxpython/gui_modules/wxnviz.py
   grass/trunk/gui/wxpython/wxgui.py
Log:
wxGUI/wxNviz: color rules dialog changed to support both v.colors and attribute columns

Modified: grass/trunk/gui/wxpython/gui_modules/colorrules.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/colorrules.py	2011-08-17 18:38:59 UTC (rev 47713)
+++ grass/trunk/gui/wxpython/gui_modules/colorrules.py	2011-08-17 19:31:48 UTC (rev 47714)
@@ -46,17 +46,17 @@
 
 
 class RulesPanel:
-    def __init__(self, parent, mapType, columnType, properties, panelWidth = 180):
+    def __init__(self, parent, mapType, attributeType, properties, panelWidth = 180):
         """!Create rules panel
         
         @param mapType raster/vector
-        @param columnType color/size for choosing widget type
-        @param properties properties of classes derived from ColorTabel
+        @param attributeType color/size for choosing widget type
+        @param properties properties of classes derived from ColorTable
         @param panelWidth width of scroll panel"""
         
         self.ruleslines = {}
         self.mapType = mapType
-        self.columnType = columnType
+        self.attributeType = attributeType
         self.properties = properties
         self.parent = parent
         
@@ -72,14 +72,6 @@
         self.mainPanel.SetSizer(self.mainSizer)
         self.mainPanel.SetAutoLayout(True)
         
-        if self.mapType == 'vector' and self.columnType == 'color':
-            self.label = wx.StaticText(parent, id = wx.ID_ANY, label =  _("Set color for attribute values:"))
-        elif self.mapType == 'vector' and self.columnType == 'size':
-            if self.parent.GetParent().vectorType == 'points':
-                label = label = _("Set size for attribute values:")
-            else:
-                label = label = _("Set width for attribute values:")                
-            self.label = wx.StaticText(parent, id = wx.ID_ANY, label = label)
         # (un)check all
         self.checkAll = wx.CheckBox(parent, id = wx.ID_ANY, label = _("Check all"))
         self.checkAll.SetValue(True)
@@ -138,11 +130,10 @@
                                    size = (80, -1),
                                    style = wx.TE_NOHIDESEL)
             if self.mapType == 'vector':
-                txt_ctrl.SetToolTipString(_("Enter vector attribute values (e.g. 5) "
-                                            "or ranges (e.g. 5 to 10)"))
+                txt_ctrl.SetToolTipString(_("Enter vector attribute values"))
             txt_ctrl.Bind(wx.EVT_TEXT, self.OnRuleValue)
             txt_ctrl.SetName('source')
-            if self.columnType == 'color':
+            if self.attributeType == 'color':
                 # color
                 columnCtrl = csel.ColourSelect(self.mainPanel, id = 2000 + num,
                                                size  =  globalvar.DIALOG_COLOR_SIZE)
@@ -151,16 +142,20 @@
                 if not start:
                     self.ruleslines[enable.GetId()] = { 'value' : '',
                                                         'color': "0:0:0" }
-            if self.columnType == 'size':
-                # size
+            else:
+                # size or width
+                init = 2
+                if self.attributeType == 'size':
+                    init = 100
                 columnCtrl = wx.SpinCtrl(self.mainPanel, id = 2000 + num,
-                                         size = (50, -1), min = 1, max = 1e3,
-                                         initial = 5)
+                                         size = (50, -1), min = 1, max = 1e4,
+                                         initial = init)
                 columnCtrl.Bind(wx.EVT_SPINCTRL, self.OnRuleSize)
+                columnCtrl.Bind(wx.EVT_TEXT, self.OnRuleSize)
                 columnCtrl.SetName('target')
                 if not start:
                     self.ruleslines[enable.GetId()] = { 'value' : '',
-                                                        'size': 100 }
+                                                        self.attributeType: init }
             
             self.mainSizer.Add(item = enable, proportion = 0,
                               flag = wx.ALIGN_CENTER_VERTICAL)
@@ -180,13 +175,19 @@
         if event.IsChecked():
             self.mainPanel.FindWindowById(id + 1000).Enable()
             self.mainPanel.FindWindowById(id + 2000).Enable()
-            if self.mapType == 'vector':
-                value = self.SQLConvert(self.mainPanel.FindWindowById(id + 1000).GetValue(), self.columnType)
+            if self.mapType == 'vector' and not self.parent.GetParent().colorTable:
+                vals = []
+                vals.append(self.mainPanel.FindWindowById(id + 1000).GetValue())
+                try:
+                    vals.append(self.mainPanel.FindWindowById(id + 1 + 1000).GetValue())
+                except AttributeError:
+                    vals.append(None)
+                value = self.SQLConvert(vals)
             else:
                 value = self.mainPanel.FindWindowById(id + 1000).GetValue()
             color = self.mainPanel.FindWindowById(id + 2000).GetValue()
             
-            if self.columnType == 'color':
+            if self.attributeType == 'color':
             # color
                 color_str = str(color[0]) + ':' \
                           + str(color[1]) + ':' \
@@ -195,9 +196,9 @@
                                        'color' : color_str }
                 
             else:
-            # size
+            # size or width
                 self.ruleslines[id] = {'value' : value,
-                                       'size'  : float(color) }
+                                       self.attributeType  : float(color) }
         
         else:
             self.mainPanel.FindWindowById(id + 1000).Disable()
@@ -221,50 +222,56 @@
         num = event.GetId()
         size = event.GetInt()
         
-        self.ruleslines[num - 2000]['size'] = size
+        self.ruleslines[num - 2000][self.attributeType] = size
         
     def OnRuleValue(self, event):
         """!Rule value changed"""
         num = event.GetId()
-        vals = event.GetString().strip()
+        val = event.GetString().strip()
         
-        if vals == '':
+        if val == '':
             return
-        
-        if self.mapType == 'vector':
-            self.SetVectorRule(num, vals)
+        try:
+            table = self.parent.colorTable
+        except AttributeError:
+            # due to scrollpanel in vector dialog
+            table = self.parent.GetParent().colorTable
+        if table:
+            self.SetRasterRule(num, val)
         else:
-            self.SetRasterRule(num, vals)
+            self.SetVectorRule(num, val)
 
-    def SetRasterRule(self, num, vals): 
+    def SetRasterRule(self, num, val): 
         """!Set raster rule"""       
-        self.ruleslines[num-1000]['value'] = vals
+        self.ruleslines[num - 1000]['value'] = val
 
-    def SetVectorRule(self, num, vals):
+    def SetVectorRule(self, num, val):
         """!Set vector rule"""
-        tc = self.mainPanel.FindWindowById(num)
-        if self.columnType == 'color':
-            source, target = 'source_rgb', 'rgb'
-        else:
-            source, target = 'source_size', 'size'
-        if self.properties[source] == '' or self.properties[target] == '':
-            tc.SetValue('')
-            gcmd.GMessage(parent = self,
-                          message = _("Please select attribute column "
-                                    "and RGB color column first"))
-        else:
-            try:
-                self.ruleslines[num-1000]['value'] = self.SQLConvert(vals, self.columnType)
-            except ValueError:
-                tc.SetValue('')
-                self.ruleslines[num-1000]['value'] = ''
-                
-                return
+##        tc = self.mainPanel.FindWindowById(num)
+##        source, target = 'sourceColumn', 'storeColumn'
+##        if self.properties[source] == '' or self.properties[target] == '':
+##            tc.SetValue('')
+##            gcmd.GMessage(parent = self.parent,
+##                          message = _("Please select attribute column "
+##                                    "and RGB color column first"))
+##        else:
+        vals = []
+        vals.append(val)
+        try:
+            vals.append(self.mainPanel.FindWindowById(num + 1).GetValue())
+        except AttributeError:
+            vals.append(None)
+        self.ruleslines[num - 1000]['value'] = self.SQLConvert(vals)
+##            except ValueError:
+##                tc.SetValue('')
+##                self.ruleslines[num - 1000]['value'] = ''
             
     def Enable(self, enable = True):
         """!Enable/Disable all widgets"""
         for child in self.mainPanel.GetChildren():
             child.Enable(enable)
+        sql = True
+        self.LoadRulesline(sql)# todo
         self.btnAdd.Enable(enable)
         self.numRules.Enable(enable)
         self.checkAll.Enable(enable)
@@ -272,48 +279,42 @@
         
         
     def LoadRules(self):
-        """!Fill rule widgets from ruleslines"""
         message = ""
         for item in range(len(self.ruleslines)):
             self.mainPanel.FindWindowById(item + 1000).SetValue(self.ruleslines[item]['value'])
             r, g, b = (0, 0, 0) # default
-            if self.ruleslines[item][self.columnType] == '':
-                if self.columnType == 'color':
-                    self.ruleslines[item][self.columnType] = '%d:%d:%d' % (r, g, b)
-                elif self.columnType == 'size':
-                    self.ruleslines[item][self.columnType] = 100
+            if not self.ruleslines[item][self.attributeType]:
+                if self.attributeType == 'color':
+                    self.ruleslines[item][self.attributeType] = '%d:%d:%d' % (r, g, b)
+                elif self.attributeType == 'size':
+                    self.ruleslines[item][self.attributeType] = 100                
+                elif self.attributeType == 'width':
+                    self.ruleslines[item][self.attributeType] = 2
                 
-            if self.columnType == 'color':
+            if self.attributeType == 'color':
                 try:
-                    r, g, b = map(int, self.ruleslines[item][self.columnType].split(':'))
+                    r, g, b = map(int, self.ruleslines[item][self.attributeType].split(':'))
                 except ValueError, e:
                     message =  _("Bad color format. Use color format '0:0:0'")
                 self.mainPanel.FindWindowById(item + 2000).SetValue((r, g, b))
             else:
-                value = float(self.ruleslines[item][self.columnType])
+                value = float(self.ruleslines[item][self.attributeType])
                 self.mainPanel.FindWindowById(item + 2000).SetValue(value)
                 
         if message:
             gcmd.GMessage(parent = self.parent, message = message)
             return False
         
-        return True    
-    
-    def SQLConvert(self, vals, type = 'color'):
+        return True
+                
+    def SQLConvert(self, vals):
         """!Prepare value for SQL query"""
-        if type == 'color':
-            source = 'source_rgb'
-        elif type == 'size':
-            source = 'source_size'
-        valslist = []
-        valslist = vals.split('to')
-        if len(valslist) == 1:
-            sqlrule = '%s=%s' % (self.properties[source], valslist[0])
-        elif len(valslist) > 1:
-            sqlrule = '%s>=%s AND %s<=%s' % (self.properties[source], valslist[0],
-                                             self.properties[source], valslist[1])
+        if vals[0].isdigit():
+            sqlrule = '%s>=%s' % (self.properties['sourceColumn'], vals[0])
+            if vals[1]:
+                sqlrule += ' AND %s<%s' % (self.properties['sourceColumn'], vals[1])
         else:
-            return None
+            sqlrule = '%s=%s' % (self.properties['sourceColumn'], vals[0])
         
         return sqlrule  
 
@@ -339,8 +340,7 @@
         # input map to change
         self.inmap = ''
         # reference to layer with preview
-        self.layer = None          
-           
+        self.layer = None     
         # layout
         self._doLayout()
         
@@ -360,10 +360,10 @@
         # if not the right type, than select another
         try:
             sel = self.parent.curr_page.maptree.layer_selected
-            if sel and self.parent.curr_page.maptree.GetPyData(sel)[0]['type'] == self.type:
+            if sel and self.parent.curr_page.maptree.GetPyData(sel)[0]['type'] == self.mapType:
                 layer = sel
             else:
-                layer = self.parent.curr_page.maptree.FindItemByData(key = 'type', value = self.type)
+                layer = self.parent.curr_page.maptree.FindItemByData(key = 'type', value = self.mapType)
         except:
             layer = None
         if layer:
@@ -418,17 +418,13 @@
         row += 1
         
         # color table
-        self.colorRulesPanel = RulesPanel(parent = parent, mapType = self.type,
-                                          columnType = 'color', properties = self.properties)
-        if self.type == 'vector':
-            bodySizer.Add(item = self.colorRulesPanel.label, pos = (row, 0), span = (1, 2),
-                          flag = wx.ALL, border = 5)
-            row += 1
+        self.rulesPanel = RulesPanel(parent = parent, mapType = self.mapType,
+                                          attributeType = self.attributeType, properties = self.properties)
         
-        bodySizer.Add(item = self.colorRulesPanel.mainPanel, pos = (row, 0), span = (1, 2),
+        bodySizer.Add(item = self.rulesPanel.mainPanel, pos = (row, 0), span = (1, 2),
                       flag = wx.ALL, border = 5)
         # add two rules as default
-        self.colorRulesPanel.AddRules(2)
+        self.rulesPanel.AddRules(2)
         
         # preview window
         self._createPreview(parent = parent)
@@ -436,9 +432,9 @@
                       flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 5)
         row += 1
         # add ckeck all and clear all
-        bodySizer.Add(item = self.colorRulesPanel.checkAll, flag = wx.ALIGN_CENTER_VERTICAL, 
+        bodySizer.Add(item = self.rulesPanel.checkAll, flag = wx.ALIGN_CENTER_VERTICAL, 
                       pos = (row, 0))
-        bodySizer.Add(item = self.colorRulesPanel.clearAll, pos = (row, 1))
+        bodySizer.Add(item = self.rulesPanel.clearAll, pos = (row, 1))
         
         # preview button
         self.btnPreview = wx.Button(parent, id = wx.ID_ANY,
@@ -450,9 +446,9 @@
                                            "(current Map Display extent is used)."))
         row +=1
         # add rules button and spin to sizer
-        bodySizer.Add(item = self.colorRulesPanel.numRules, pos = (row, 0),
+        bodySizer.Add(item = self.rulesPanel.numRules, pos = (row, 0),
                       flag = wx.ALIGN_CENTER_VERTICAL)
-        bodySizer.Add(item = self.colorRulesPanel.btnAdd, pos = (row, 1))
+        bodySizer.Add(item = self.rulesPanel.btnAdd, pos = (row, 1))
         
 
        
@@ -479,12 +475,14 @@
 
         @return True on success otherwise False
         """
-        ret = self.CreateColorTable()
+        ret = self.CreateColorTable(mapType = self.mapType)
+        if not self.colorTable:
+            self.UseAttrColumn()
         if ret:
             display = self.parent.GetLayerTree().GetMapDisplay()
             if display and display.IsAutoRendered():
                 display.GetWindow().UpdateMap(render = True)
-            
+           
         return ret
 
     def OnOK(self, event):
@@ -495,7 +493,105 @@
     def OnCancel(self, event):
         """!Do not apply any changes and close the dialog"""
         self.Destroy()
+    
+    def LoadTable(self, mapType = 'raster'):
+        """!Load current color table (using `r.colors.out`)"""
         
+        self.rulesPanel.Clear()
+        if mapType == 'raster':
+            cmd = ['r.colors.out',
+                   'read=True',
+                   'map=%s' % self.inmap,
+                   'rules=-']
+        else:
+            cmd = ['v.colors.out',
+                   'read=True',
+                   'map=%s' % self.inmap,
+                   'rules=-']
+            
+            if self.properties['sourceColumn'] != 'cat':
+                cmd.append('column=%s' % self.properties['sourceColumn'])
+            
+        cmd = utils.CmdToTuple(cmd)
+        
+        if self.inmap:
+            ctable = gcmd.RunCommand(cmd[0], **cmd[1])
+        else:
+            self.OnPreview()
+            return
+        
+        rulesNumber = len(ctable.splitlines())
+        self.rulesPanel.AddRules(rulesNumber)
+        
+        count = 0
+        for line in ctable.splitlines():
+            value, color = map(lambda x: x.strip(), line.split(' '))
+            self.rulesPanel.ruleslines[count]['value'] = value
+            self.rulesPanel.ruleslines[count]['color'] = color
+            self.rulesPanel.mainPanel.FindWindowById(count + 1000).SetValue(value)
+            rgb = list()
+            for c in color.split(':'):
+                rgb.append(int(c))
+            self.rulesPanel.mainPanel.FindWindowById(count + 2000).SetColour(rgb)
+            count += 1
+        
+        self.OnPreview(tmp = True)    
+        
+    def CreateColorTable(self, force = False, mapType = 'raster'):
+        """!Creates color table
+
+        @return True on success
+        @return False on failure
+        """
+        rulestxt = ''
+        
+        for rule in self.rulesPanel.ruleslines.itervalues():
+            if not rule['value']: # skip empty rules
+                continue
+            
+            if rule['value'] not in ('nv', 'default') and \
+                    rule['value'][-1] != '%' and \
+                    not self._IsNumber(rule['value']):
+                gcmd.GError(_("Invalid rule value '%s'. Unable to apply color table.") % rule['value'],
+                            parent = self)
+                return False
+            
+            rulestxt += rule['value'] + ' ' + rule['color'] + '\n'
+           
+        if not rulestxt:
+            gcmd.GMessage(parent = self, message = _("No color rules given."))
+            return False
+        
+        gtemp = utils.GetTempfile()
+        output = open(gtemp, "w")
+        try:
+            output.write(rulestxt)
+        finally:
+            output.close()
+        
+        flags = ''
+        if mapType == 'raster':
+            if not force and not self.ovrwrtcheck.IsChecked():
+                flags = 'w'
+                
+        cmd = ['%s.colors' % mapType[0],#r.colors/v.colors
+                'flags=%s' % flags,
+                'map=%s' % self.inmap,
+                'rules=%s' % gtemp]
+        if mapType == 'vector' and self.properties['sourceColumn']:
+            cmd.append('column=%s' % self.properties['sourceColumn'])
+        cmd = utils.CmdToTuple(cmd)
+        ret = gcmd.RunCommand(cmd[0], **cmd[1])
+                        
+        if ret != 0 and mapType == 'raster':
+            gcmd.GMessage(_("Color table already exists. "
+                            "Check out 'replace existing color table' to "
+                            "overwrite it."),
+                          parent = self)
+            return False
+        
+        return True
+    
     def DoPreview(self, ltype, cmdlist):
         """!Update preview (based on computational region)"""
         
@@ -507,7 +603,7 @@
             self.layer.SetCmd(cmdlist)
         
         # apply new color table and display preview
-        self.CreateColorTable(force = True)
+        self.CreateColorTable(force = True, mapType = self.mapType)
         self.preview.UpdatePreview()
         
     def RunHelp(self, cmd):
@@ -530,8 +626,9 @@
     def __init__(self, parent, **kwargs):
         """!Dialog for interactively entering color rules for raster maps"""
 
-        self.type = 'raster'
-        
+        self.mapType = 'raster'
+        self.attributeType = 'color' 
+        self.colorTable = True 
         # raster properties
         self.properties = {
             # min cat in raster map
@@ -630,7 +727,7 @@
             self.btnPreview.Enable(False)
             self.btnOK.Enable(False)
             self.btnApply.Enable(False)
-            self.OnLoadTable(event)
+            self.LoadTable()
             return
         
         info = grass.raster_info(map = self.inmap)
@@ -638,7 +735,7 @@
         if info:
             self.properties['min'] = info['min']
             self.properties['max'] = info['max']
-            self.OnLoadTable(event)
+            self.LoadTable()
         else:
             self.inmap = ''
             self.properties['min'] = self.properties['max'] = None
@@ -661,41 +758,9 @@
         self.btnPreview.Enable()
         self.btnOK.Enable()
         self.btnApply.Enable()
-    
-    def OnLoadTable(self, event):
-        """!Load current color table (using `r.colors.out`)"""
-        
-        self.colorRulesPanel.Clear()
-        
-        if self.inmap:
-            ctable = gcmd.RunCommand('r.colors.out',
-                                     parent = self,
-                                     read = True,
-                                     map = self.inmap,
-                                     rules = '-')
-        else:
-            self.OnPreview(event)
-            return
-        
-        rulesNumber = len(ctable.splitlines())
-        self.colorRulesPanel.AddRules(rulesNumber)
-        
-        count = 0
-        for line in ctable.splitlines():
-            value, color = map(lambda x: x.strip(), line.split(' '))
-            self.colorRulesPanel.ruleslines[count]['value'] = value
-            self.colorRulesPanel.ruleslines[count]['color'] = color
-            self.colorRulesPanel.mainPanel.FindWindowById(count + 1000).SetValue(value)
-            rgb = list()
-            for c in color.split(':'):
-                rgb.append(int(c))
-            self.colorRulesPanel.mainPanel.FindWindowById(count + 2000).SetColour(rgb)
-            count += 1
-        
-        self.OnPreview(tmp = False)
             
           
-    def OnPreview(self, event = None, tmp = True):
+    def OnPreview(self, tmp = True):
         """!Update preview (based on computational region)"""
         if not self.inmap:
             self.preview.EraseMap()
@@ -739,7 +804,7 @@
     def OnSaveTable(self, event):
         """!Save color table to file"""
         rulestxt = ''   
-        for rule in self.ruleslines.itervalues():
+        for rule in self.rulesPanel.ruleslines.itervalues():
             if not rule['value']:
                 continue
             rulestxt += rule['value'] + ' ' + rule['color'] + '\n'
@@ -763,97 +828,50 @@
         cmd = 'r.colors'
         ColorTable.RunHelp(self, cmd = cmd)
     
-    def CreateColorTable(self, force = False):
-        """!Creates color table
 
-        @return True on success
-        @return False on failure
-        """
-        rulestxt = ''
-        
-        for rule in self.colorRulesPanel.ruleslines.itervalues():
-            if not rule['value']: # skip empty rules
-                continue
-            
-            if rule['value'] not in ('nv', 'default') and \
-                    rule['value'][-1] != '%' and \
-                    not self._IsNumber(rule['value']):
-                gcmd.GError(_("Invalid rule value '%s'. Unable to apply color table.") % rule['value'],
-                            parent = self)
-                return False
-            
-            rulestxt += rule['value'] + ' ' + rule['color'] + '\n'
-           
-        if not rulestxt:
-            gcmd.GMessage(parent = self, message = _("No color rules given."))
-            return False
-        
-        gtemp = utils.GetTempfile()
-        output = open(gtemp, "w")
-        try:
-            output.write(rulestxt)
-        finally:
-            output.close()
-        
-        if not force and not self.ovrwrtcheck.IsChecked():
-            flags = 'w'
-        else:
-            flags = ''
-        
-        ret = gcmd.RunCommand('r.colors',
-                              flags = flags,
-                              map = self.inmap,
-                              rules = gtemp)
-        if ret != 0:
-            gcmd.GMessage(_("Color table already exists. "
-                            "Check out 'replace existing color table' to "
-                            "overwrite it."),
-                          parent = self)
-            return False
-        
-        return True
                       
 class VectorColorTable(ColorTable):
-    def __init__(self, parent, **kwargs):
+    def __init__(self, parent, attributeType, **kwargs):
         """!Dialog for interactively entering color rules for vector maps"""
-        
-        self.type = 'vector'
+        # dialog attributes
+        self.mapType = 'vector'
+        self.attributeType = attributeType # color, size, width
+        # in version 7 v.colors used, otherwise color column only
+        self.version7 = int(grass.version()['version'].split('.')[0]) >= 7
+        self.colorTable = False
         # vector properties
         self.properties = {
-            # list of database layers for vector (minimum of 1)
-            'layers' : [],
-            # list of database columns for vector
-            'columns' : [],
             # vector layer for attribute table to use for setting color
             'layer' : 1, 
             # vector attribute table used for setting color         
             'table' : '',
             # vector attribute column for assigning colors
-            'source_rgb' : '', 
+            'sourceColumn' : '', 
+            # vector attribute column to use for loading colors
+            'loadColumn' : '',
             # vector attribute column to use for storing colors
-            'rgb' : '',    
+            'storeColumn' : '',    
             # vector attribute column for temporary storing colors   
-            'tmp_rgb' : '',
-            # vector attribute column for temporary storing size   
-            'tmp_size' : '',
-            # vector attribute column for assigning size
-            'source_size' : '', 
-            # vector attribute column to use for storing size
-            'size' : '',
-            }         
-        
+            'tmpColumn' : ''
+            }     
+        self.columnsProp = {'color': {'name': 'GRASSRGB', 'type1': 'varchar(11)', 'type2': ['character']},
+                            'size' : {'name': 'GRASSSIZE', 'type1': 'integer', 'type2': ['integer']},
+                            'width': {'name': 'GRASSWIDTH', 'type1': 'integer', 'type2': ['integer']}}
         ColorTable.__init__(self, parent = parent,
-                            title = _('Create new color table for vector map'), **kwargs)   
+                            title = _('Create new color rules for vector map'), **kwargs)   
         
         # additional bindings for vector color management
-        self.Bind(wx.EVT_COMBOBOX, self.OnLayerSelection, self.cb_vlayer)
-        self.Bind(wx.EVT_COMBOBOX, self.OnColumnSelection, self.cb_color_att)
-        self.Bind(wx.EVT_COMBOBOX, self.OnRGBColSelection, self.cb_rgb_col)
-        self.Bind(wx.EVT_BUTTON, self.OnAddColumn, self.btn_add_RGB)    
+        self.Bind(wx.EVT_COMBOBOX, self.OnLayerSelection, self.layerSelect)
+        self.Bind(wx.EVT_COMBOBOX, self.OnSourceColumnSelection, self.sourceColumn)
+        self.Bind(wx.EVT_COMBOBOX, self.OnFromColSelection, self.fromColumn)
+        self.Bind(wx.EVT_COMBOBOX, self.OnToColSelection, self.toColumn)
+        self.Bind(wx.EVT_BUTTON, self.OnAddColumn, self.addColumn)    
         
         self._initLayer()
-        self.cr_label.SetLabel(_("Enter vector attribute values (e.g. 5) "
-                                            "or ranges (e.g. 5 to 10)"))
+        if self.colorTable:
+            self.cr_label.SetLabel(_("Enter vector attribute values or percents:"))
+        else:
+            self.cr_label.SetLabel(_("Enter vector attribute values:"))
         self.SetMinSize(self.GetSize()) 
         self.CentreOnScreen()
         self.Show()
@@ -869,11 +887,9 @@
         self.selectionInput = gselect.Select(parent, id = wx.ID_ANY,
                                              size = globalvar.DIALOG_GSELECT_SIZE,
                                              type = 'vector')
-            
-        # layout
         inputSizer.Add(item = self.selectionInput, proportion = 1,
                        flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, border = 5)
-    
+                    
         return inputSizer
     
     def _createVectorAttrb(self, parent):
@@ -884,38 +900,68 @@
                                              label = _('Layer:'))
         cb_vc_label = wx.StaticText(parent, id = wx.ID_ANY,
                                          label = _('Attribute column:'))
-        cb_vrgb_label = wx.StaticText(parent, id = wx.ID_ANY,
-                                           label = _('RGB color column:'))
+                                        
+        if self.attributeType == 'color':
+            labels =  [_("Load color from column:"), _("Save color to column:")]
+        elif self.attributeType == 'size':
+            labels =  [_("Load size from column:"), _("Save size to column:")]
+        elif self.attributeType == 'width':
+            labels =  [_("Load width from column:"), _("Save width to column:")]
+            
+        if self.version7 and self.attributeType == 'color':
+            self.useColumn = wx.CheckBox(parent, id = wx.ID_ANY,
+                                  label = _("Use color column instead of color table:"))
+            self.useColumn.Bind(wx.EVT_CHECKBOX, self.OnCheckColumn)
+        
+        fromColumnLabel = wx.StaticText(parent, id = wx.ID_ANY,
+                                            label = labels[0])
+        toColumnLabel = wx.StaticText(parent, id = wx.ID_ANY,
+                                            label = labels[1])
+                                                
         self.rgb_range_label = wx.StaticText(parent, id = wx.ID_ANY)
-        self.cb_vlayer = gselect.LayerSelect(parent)
-        self.cb_color_att = gselect.ColumnSelect(parent)
-        self.cb_rgb_col = gselect.ColumnSelect(parent)
-        self.btn_add_RGB = wx.Button(parent, id = wx.ID_ANY,
+        self.layerSelect = gselect.LayerSelect(parent)
+        self.sourceColumn = gselect.ColumnSelect(parent)
+        self.fromColumn = gselect.ColumnSelect(parent)
+        self.toColumn = gselect.ColumnSelect(parent)
+        self.addColumn = wx.Button(parent, id = wx.ID_ANY,
                                              label = _('Add column'))
-        self.btn_add_RGB.SetToolTipString(_("Add GRASSRGB column to current attribute table."))
+        self.addColumn.SetToolTipString(_("Add GRASSRGB column to current attribute table."))
         
         # layout
         inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
         vSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
-        vSizer.Add(cb_vl_label, pos = (0, 0),
+        row = 0
+        vSizer.Add(cb_vl_label, pos = (row, 0),
                    flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.cb_vlayer,  pos = (0, 1),
+        vSizer.Add(self.layerSelect,  pos = (row, 1),
                    flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(cb_vc_label, pos = (1, 0),
+        row += 1
+        vSizer.Add(cb_vc_label, pos = (row, 0),
                    flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.cb_color_att, pos = (1, 1),
+        vSizer.Add(self.sourceColumn, pos = (row, 1),
                    flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.rgb_range_label, pos = (1, 2),
+        vSizer.Add(self.rgb_range_label, pos = (row, 2),
                    flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(cb_vrgb_label, pos = (2, 0),
+        row += 1   
+        if self.version7 and self.attributeType == 'color':
+            vSizer.Add(self.useColumn, pos = (row, 0), span = (1, 2),
+                       flag = wx.ALIGN_CENTER_VERTICAL)
+            row += 1
+            
+        vSizer.Add(fromColumnLabel, pos = (row, 0),
                   flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.cb_rgb_col, pos = (2, 1),
+        vSizer.Add(self.fromColumn, pos = (row, 1),
                    flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.btn_add_RGB, pos = (2, 2),
+        row += 1
+        vSizer.Add(toColumnLabel, pos = (row, 0),
+                  flag = wx.ALIGN_CENTER_VERTICAL)
+        vSizer.Add(self.toColumn, pos = (row, 1),
                    flag = wx.ALIGN_CENTER_VERTICAL)
+        vSizer.Add(self.addColumn, pos = (row, 2),
+                   flag = wx.ALIGN_CENTER_VERTICAL)
         inputSizer.Add(item = vSizer,
                        flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, border = 5)
-                
+        self.colorColumnSizer = vSizer        
         return inputSizer 
        
     def _doLayout(self):
@@ -982,10 +1028,47 @@
         if dlg.ShowModal() == wx.ID_YES:
             dlg.Destroy()
             menuform.GUI(parent = self).ParseCommand(['v.db.addtable', 'map=' + self.inmap], 
-                                                      completed = (self.CreateTable, self.inmap, ''))
+                                                      completed = (self.CreateAttrTable, self.inmap, ''))
         else:
             dlg.Destroy()
+  
+    def OnCheckColumn(self, event):
+        """!Use color column instead of color table"""
+        if self.useColumn.GetValue():
+            self.properties['loadColumn'] = self.fromColumn.GetStringSelection()
+            self.properties['storeColumn'] = self.toColumn.GetStringSelection()
+            self.fromColumn.Enable(True)
+            self.toColumn.Enable(True)
+            self.colorTable = False
             
+            if self.properties['loadColumn']:
+                self.LoadTable()
+            else:
+                self.rulesPanel.Clear()
+        else:
+            self.properties['loadColumn'] = ''
+            self.properties['storeColumn'] = ''
+            self.fromColumn.Enable(False)
+            self.toColumn.Enable(False)
+            self.colorTable = True
+            
+            self.LoadTable()
+        
+            
+    def EnableVectorAttributes(self, enable):
+        """!Enable/disable part of dialog connected with db"""
+        for child in self.colorColumnSizer.GetChildren():
+            child.GetWindow().Enable(enable)
+    
+    def DisableClearAll(self):
+        """!Enable, disable the whole dialog"""
+        self.rulesPanel.Clear()
+        self.EnableVectorAttributes(False)
+        self.btnPreview.Enable(False)
+        self.btnOK.Enable(False)
+        self.btnApply.Enable(False)
+        self.preview.EraseMap()
+        
     def OnSelectionInput(self, event):
         """!Vector map selected"""
         if event:
@@ -998,51 +1081,60 @@
         self.UpdateDialog()
         
     def UpdateDialog(self):
-        """!Update dialog after map selection"""    
+        """!Update dialog after map selection"""  
         if not self.inmap:
-            self.colorRulesPanel.Clear()
-            self.btnPreview.Enable(False)
-            self.btnOK.Enable(False)
-            self.btnApply.Enable(False)
-            self.preview.EraseMap()
+            self.DisableClearAll()
             return
-                               
+        
+        if self.inmap and not self.CheckMapset():
+            # currently v.colors need the map to be in current mapset
+            if self.version7 and self.attributeType == 'color':
+                message = _("Selected map <%s> is not in current mapset <%s>. "
+                            "Color rules cannot be edited.") % \
+                            (self.inmap, grass.gisenv()['MAPSET'])
+            else:
+                message = _("Selected map <%s> is not in current mapset <%s>. "
+                            "Attribute table cannot be edited.") % \
+                            (self.inmap, grass.gisenv()['MAPSET'])
+            wx.CallAfter(gcmd.GMessage, parent = self, message = message)
+            self.DisableClearAll()
+            return
+              
         # check for db connection
         self.dbInfo = gselect.VectorDBInfo(self.inmap)
-        if not len(self.dbInfo.layers):
-            wx.CallAfter(self.NoConnection, self.inmap)
-            for combo in (self.cb_vlayer, self.cb_color_att, self.cb_rgb_col):
+        enable = True
+        if not len(self.dbInfo.layers): # no connection
+            if not (self.version7 and self.attributeType == 'color'): # otherwise it doesn't matter
+                wx.CallAfter(self.NoConnection, self.inmap)
+                enable = False
+            for combo in (self.layerSelect, self.sourceColumn, self.fromColumn, self.toColumn):
                 combo.SetValue("")
-                combo.Disable()
                 combo.Clear()
-            enable = False   
-        else:
+            self.EnableVectorAttributes(False)
+              
+        else: # db connection exist
         # initialize layer selection combobox
-            for combo in (self.cb_vlayer, self.cb_color_att, self.cb_rgb_col):
-                combo.Enable()
-            self.cb_vlayer.InsertLayers(self.inmap)
+            self.EnableVectorAttributes(True)
+            self.layerSelect.InsertLayers(self.inmap)
             # initialize attribute table for layer=1
-            self.properties['layer'] = self.cb_vlayer.GetString(0)
-            self.cb_vlayer.SetStringSelection(self.properties['layer'])
+            self.properties['layer'] = self.layerSelect.GetString(0)
+            self.layerSelect.SetStringSelection(self.properties['layer'])
             layer = int(self.properties['layer'])
             self.properties['table'] = self.dbInfo.layers[layer]['table']
             
-            if self.CheckMapset():
-                enable = True
-                self.btn_add_RGB.Enable(True)
-                self.AddTemporaryColumn(name = 'tmp_rgb', type = 'varchar(20)')
+            if self.attributeType == 'color':
+                self.AddTemporaryColumn(name = 'tmpColumn', type = 'varchar(20)')
             else:
-                enable = False
-                wx.CallAfter(gcmd.GMessage, parent = self, 
-                             message = _("Selected map <%s> is not in current mapset <%s>. "
-                                        "Attribute table cannot be edited. "
-                                        "Color rules will not be saved.") % 
-                                        (self.inmap, grass.gisenv()['MAPSET']))
-                              
-                self.btn_add_RGB.Enable(False)
+                self.AddTemporaryColumn(name = 'tmpColumn', type = 'integer')
             
             # initialize column selection comboboxes 
+            
             self.OnLayerSelection(event = None)
+        if self.version7 and self.attributeType == 'color':
+            self.useColumn.SetValue(False)
+            self.OnCheckColumn(event = None) 
+        
+        self.LoadTable()
             
         self.btnPreview.Enable(enable)
         self.btnOK.Enable(enable)
@@ -1054,7 +1146,7 @@
         ret = gcmd.RunCommand('v.db.addcolumn',
                               map = self.inmap,
                               layer = self.properties['layer'],
-                              columns = '%s %s' % (name, type))
+                              column = '%s %s' % (name, type))
         self.properties[name] = name
         
     def DeleteTemporaryColumn(self, name):
@@ -1066,47 +1158,61 @@
                        
     def OnLayerSelection(self, event):
         # reset choices in column selection comboboxes if layer changes
-        vlayer = int(self.cb_vlayer.GetStringSelection())
-        self.cb_color_att.InsertColumns(vector = self.inmap, layer = vlayer, dbInfo = self.dbInfo)
-        self.cb_color_att.SetSelection(0)
-        self.properties['source_rgb'] = self.cb_color_att.GetString(0)
-        self.cb_rgb_col.InsertColumns(vector = self.inmap, layer = vlayer, type = ["character"], dbInfo = self.dbInfo)
-#        self.cb_rgb_col.Delete(self.cb_rgb_col.FindString(self.properties['source_rgb']))
-        found = self.cb_rgb_col.FindString('GRASSRGB')
+        vlayer = int(self.layerSelect.GetStringSelection())
+        self.sourceColumn.InsertColumns(vector = self.inmap, layer = vlayer,
+                                        type = ['integer', 'double precision'], dbInfo = self.dbInfo,
+                                        excludeCols = ['tmpColumn'])
+        self.sourceColumn.SetStringSelection('cat')
+        self.properties['sourceColumn'] = self.sourceColumn.GetString(0)
+        
+        if self.attributeType == 'color':
+            type = ['character']
+        else:
+            type = ['integer']
+        self.fromColumn.InsertColumns(vector = self.inmap, layer = vlayer, type = type,
+                                      dbInfo = self.dbInfo, excludeCols = ['tmpColumn'])
+        self.toColumn.InsertColumns(vector = self.inmap, layer = vlayer, type = type,
+                                    dbInfo = self.dbInfo, excludeCols = ['tmpColumn'])
+        
+        found = self.fromColumn.FindString(self.columnsProp[self.attributeType]['name'])
         if found != wx.NOT_FOUND:
-            self.cb_rgb_col.SetSelection(found)
-            self.properties['rgb'] = self.cb_rgb_col.GetString(found)
+            self.fromColumn.SetSelection(found)
+            self.toColumn.SetSelection(found)
+            self.properties['loadColumn'] = self.fromColumn.GetString(found)
+            self.properties['storeColumn'] = self.toColumn.GetString(found)
         else:
-            self.properties['rgb'] = ''
+            self.properties['loadColumn'] = ''
+            self.properties['storeColumn'] = ''
         
-        self.LoadTable(attColumn = self.properties['source_rgb'],
-                       rgbColumn = self.properties['rgb'], rulesPanel = self.colorRulesPanel)
+        if event:
+            self.LoadTable()
         self.Update()
         
-    def OnColumnSelection(self, event):
-        self.properties['source_rgb'] = event.GetString()
+    def OnSourceColumnSelection(self, event):
+        self.properties['sourceColumn'] = event.GetString()
         
-        self.LoadTable(attColumn = self.properties['source_rgb'],
-                       rgbColumn = self.properties['rgb'], rulesPanel = self.colorRulesPanel)
+        self.LoadTable()
     
     def OnAddColumn(self, event):
-        """!Add GRASSRGB column if it doesn't exist"""
-        if 'GRASSRGB' not in self.cb_rgb_col.GetItems():
+        """!Add GRASS(RGB,SIZE,WIDTH) column if it doesn't exist"""
+        if self.columnsProp[self.attributeType]['name'] not in self.fromColumn.GetItems():
             ret = gcmd.RunCommand('v.db.addcolumn',
-                                   map = self.inmap,
+                                  map = self.inmap,
                                   layer = self.properties['layer'],
-                                  columns = 'GRASSRGB varchar(20)')
-            self.cb_rgb_col.InsertColumns(self.inmap, self.properties['layer'], type = ["character"])
-            self.cb_rgb_col.SetStringSelection('GRASSRGB')
-            self.properties['rgb'] = self.cb_rgb_col.GetStringSelection()
+                                  columns = '%s %s' % (self.columnsProp[self.attributeType]['name'],
+                                            self.columnsProp[self.attributeType]['type1']))
+            self.toColumn.InsertColumns(self.inmap, self.properties['layer'],
+                                        type = self.columnsProp[self.attributeType]['type2'])
+            self.toColumn.SetStringSelection(self.columnsProp[self.attributeType]['name'])
+            self.properties['storeColumn'] = self.toColumn.GetStringSelection()
             
-            self.LoadTable(attColumn = self.properties['source_rgb'], rgbColumn = self.properties['rgb'],
-                       rulesPanel = self.colorRulesPanel, type = 'color')
+            self.LoadTable()
         else:
             gcmd.GMessage(parent = self,
-                          message = _("GRASSRGB column already exists."))
+                          message = _("%s column already exists.") % \
+                                    self.columnsProp[self.attributeType]['name'])
                         
-    def CreateTable(self, dcmd, layer, params, propwin):
+    def CreateAttrTable(self, dcmd, layer, params, propwin):
         """!Create attribute table"""
         if dcmd:
             cmd = utils.CmdToTuple(dcmd)
@@ -1115,63 +1221,79 @@
                 self.OnSelectionInput(None)
                 return True
             
-        for combo in (self.cb_vlayer, self.cb_color_att, self.cb_rgb_col):
+        for combo in (self.layerSelect, self.sourceColumn, self.fromColumn, self.toColumn):
             combo.SetValue("")
             combo.Disable()
         return False    
     
-    def LoadTable(self, attColumn, rgbColumn, rulesPanel, type = 'color'):
+    def LoadTable(self):
+        """!Load table"""
+        if self.colorTable:
+            ColorTable.LoadTable(self, mapType = 'vector')
+        else:
+            self.LoadRulesFromColumn(sourceColumn = self.properties['sourceColumn'],
+                                     loadColumn = self.properties['loadColumn'],
+                                     rulesPanel = self.rulesPanel, 
+                                     type = self.attributeType)
+            
+    def LoadRulesFromColumn(self, sourceColumn, loadColumn, rulesPanel, type):
         """!Load current column (GRASSRGB, size column)"""
         
         rulesPanel.Clear()
-        if not attColumn or not rgbColumn:
+        if not sourceColumn:
             self.preview.EraseMap()
             return
         
         busy = wx.BusyInfo(message = _("Please wait, loading data from attribute table..."),
                            parent = self)
         wx.Yield()
+        
+        columns = sourceColumn
+        if loadColumn:
+            columns += ',' + loadColumn
+            
         if self.inmap:
-            outFile = tempfile.NamedTemporaryFile(mode='w+b')
+            outFile = tempfile.NamedTemporaryFile(mode = 'w+b')
             sep = '|'
             ret = gcmd.RunCommand('v.db.select',
-                                      quiet = True,
-                                      flags = 'c',
-                                      map = self.inmap,
-                                      layer = self.properties['layer'],
-                                      columns = attColumn + ',' + rgbColumn,
-                                      fs = sep,
-                                      stdout = outFile)
-            
+                                  quiet = True,
+                                  flags = 'c',
+                                  map = self.inmap,
+                                  layer = self.properties['layer'],
+                                  columns = columns,
+                                  fs = sep,
+                                  stdout = outFile)
         else:
-            self.OnPreview(event)
+            self.preview.EraseMap()
             busy.Destroy()
             return
-        if type == 'color':
-            ctype = self.dbInfo.GetTableDesc(self.properties['table'])\
-                                            [self.properties['source_rgb']]['ctype']
-        elif type == 'size':
-            ctype = self.dbInfo.GetTableDesc(self.properties['table'])\
-                                            [self.properties['source_size']]['ctype']
+        
+##        if type == 'color':
+##            ctype = self.dbInfo.GetTableDesc(self.properties['table'])\
+##                                            [sourceColumn]['ctype']
         outFile.seek(0)
         i = 0
         minim = maxim = 0.0
         while True:
             # os.linesep doesn't work here (MSYS)
             record = outFile.readline().replace('\n', '')
-            
             if not record:
                 break
             rulesPanel.ruleslines[i] = {}
             
-            col1, col2 = record.split(sep)
-            if ctype not in (int, float):
-                col1 = "'" + col1 + "'"
+            if not loadColumn:
+                col1 = record
+                col2 = None
             else:
-                if float(col1) < minim:
-                    minim = float(col1)
-                if float(col1) > maxim:
-                    maxim = float(col1)
+                col1, col2 = record.split(sep)
+            
+##            if ctype not in (int, float):
+##                col1 = "'" + col1 + "'"
+##            else:
+            if float(col1) < minim:
+                minim = float(col1)
+            if float(col1) > maxim:
+                maxim = float(col1)
                     
             rulesPanel.ruleslines[i]['value'] = col1
             rulesPanel.ruleslines[i][type] = col2
@@ -1179,10 +1301,10 @@
         
         rulesPanel.AddRules(i, start = True)
         ret = rulesPanel.LoadRules()
-        self.SetRangeLabel(type, ctype, minim, maxim)
+##        self.SetRangeLabel(type, ctype, minim, maxim)
         
         if ret:
-            self.OnPreview()    
+            self.OnPreview()   
         else:
             rulesPanel.Clear()
     
@@ -1207,24 +1329,72 @@
             else:
                 self.size_range_label.SetLabel('')
                 
-                
-    def OnRGBColSelection(self, event):
-        self.properties['rgb'] = event.GetString()
+    def OnFromColSelection(self, event):
+        """!Selection in combobox (for loading values) changed"""
+        self.properties['loadColumn'] = event.GetString()
         
-        self.LoadTable(attColumn = self.properties['source_rgb'],
-                       rgbColumn = self.properties['rgb'], rulesPanel = self.colorRulesPanel)
+        self.LoadTable()
+    
+    def OnToColSelection(self, event):
+        """!Selection in combobox (for storing values) changed"""
+        self.properties['storeColumn'] = event.GetString()
+    
+    def OnPreview(self, event = None, tmp = True):
+        """!Update preview (based on computational region)"""
+        if self.colorTable:
+            self.OnTablePreview(tmp)
+        else:
+            self.OnColumnPreview() 
+                                 
+    def OnTablePreview(self, tmp):
+        """!Update preview (based on computational region)"""
+        if not self.inmap:
+            self.preview.EraseMap()
+            return
+        
+        ltype = 'vector'
+        cmdlist = ['d.vect',
+                   'map=%s' % self.inmap]
+        
+        # find existing color table and copy to temp file
+        old_colrtable = None
+        path = grass.find_file(name = self.inmap, element = 'vector')['file']
+        
+        if os.path.exists(os.path.join(path, 'colr')):
+            old_colrtable = os.path.join(path, 'colr')
+            colrtemp = utils.GetTempfile()
+            shutil.copyfile(old_colrtable, colrtemp)
             
-    def OnPreview(self, event = None):
+        ColorTable.DoPreview(self, ltype, cmdlist)  
+        
+        # restore previous color table
+        if tmp:
+            if old_colrtable:
+                shutil.copyfile(colrtemp, old_colrtable)
+                os.remove(colrtemp)
+            else:
+                gcmd.RunCommand('v.colors',
+                                parent = self,
+                                flags = 'r',
+                                map = self.inmap)
+    def OnColumnPreview(self):
         """!Update preview (based on computational region)"""
-        if not self.inmap or not self.properties["rgb"] or not self.properties["tmp_rgb"]:
+        if not self.inmap or not self.properties['tmpColumn']:
             self.preview.EraseMap()
             return
         
         cmdlist = ['d.vect',
                     '-a',
                    'map=%s' % self.inmap,
-                   'rgb_column=%s' % self.properties['tmp_rgb'],
                    'type=point,line,boundary,area']
+                
+        if self.attributeType == 'color':
+            cmdlist.append('rgb_column=%s' % self.properties['tmpColumn'])
+        elif self.attributeType == 'size':
+            cmdlist.append('size_column=%s' % self.properties['tmpColumn'])
+        elif self.attributeType == 'width':
+            cmdlist.append('width_column=%s' % self.properties['tmpColumn'])
+            
         ltype = 'vector'
         
         ColorTable.DoPreview(self, ltype, cmdlist)
@@ -1234,7 +1404,38 @@
         cmd = 'v.colors'
         ColorTable.RunHelp(self, cmd = cmd)
         
-    def CreateColorTable(self, force = False):
+    def UseAttrColumn(self, useAttrColumn = True):
+        """!Use attribute column to render map"""
+        # TODO switch back to table, not only selected map
+        layer = self.parent.curr_page.maptree.layer_selected
+        if layer and self.parent.curr_page.maptree.GetPyData(layer)[0]['maplayer'].GetName() == self.inmap:
+##            cmd = self.parent.curr_page.maptree.GetPyData(layer)[0]['maplayer'].GetCmd()
+##            if useAttrColumn:
+##                cmd[1].update({'flags': 'a', })
+            cmdlist = ['d.vect',
+                        '-a',
+                       'map=%s' % self.inmap,
+                       'type=point,line,boundary,area']
+                
+            if self.attributeType == 'color':
+                cmdlist.append('rgb_column=%s' % self.properties['storeColumn'])
+            elif self.attributeType == 'size':
+                cmdlist.append('size_column=%s' % self.properties['storeColumn'])
+            elif self.attributeType == 'width':
+                cmdlist.append('width_column=%s' % self.properties['storeColumn'])
+            
+            self.parent.curr_page.maptree.GetPyData(layer)[0]['maplayer'].SetCmd(cmdlist)
+        
+    def CreateColorTable(self, force = False, mapType = 'vector'):
+        """!Create color rules (color table or color column)"""
+        if self.colorTable:
+            ret = ColorTable.CreateColorTable(self, force, mapType)
+        else:
+            ret = self.UpdateColorColumn(force)
+            
+        return ret
+        
+    def UpdateColorColumn(self, force):
         """!Creates color table
 
         @return True on success
@@ -1242,17 +1443,19 @@
         """
         rulestxt = ''
         
-        for rule in self.colorRulesPanel.ruleslines.itervalues():
+        for rule in self.rulesPanel.ruleslines.itervalues():
             if not rule['value']: # skip empty rules
                 continue
-            
             if force:
-                rgb_col = self.properties['tmp_rgb']
+                rgb_col = self.properties['tmpColumn']
             else:
-                rgb_col = self.properties['rgb']
+                rgb_col = self.properties['storeColumn']
+                if not self.properties['storeColumn']:
+                    gcmd.GMessage(self.parent, message = _("Please select column to save values to."))
+                    
             rulestxt += "UPDATE %s SET %s='%s' WHERE %s ;\n" % (self.properties['table'],
                                                                 rgb_col,
-                                                                rule['color'],
+                                                                rule[self.attributeType],
                                                                 rule['value'])
         if not rulestxt:
             return False
@@ -1274,12 +1477,12 @@
             and delete temporary column"""
         if self.OnApply(event):
             self.Destroy()
-            self.DeleteTemporaryColumn(name = self.properties['tmp_rgb'])
+            self.DeleteTemporaryColumn(name = self.properties['tmpColumn'])
     
     def OnCancel(self, event):
         """!Do not apply any changes and close the dialog"""
         self.Destroy()
-        self.DeleteTemporaryColumn(name = self.properties['tmp_rgb'])
+        self.DeleteTemporaryColumn(name = self.properties['tmpColumn'])
         
 class ThematicVectorTable(VectorColorTable):
     def __init__(self, parent, vectorType, **kwargs):
@@ -1288,70 +1491,9 @@
         self.vectorType = vectorType
         VectorColorTable.__init__(self, parent = parent, **kwargs)
         
-        # additional bingings
-        self.Bind(wx.EVT_COMBOBOX, self.OnSizeSourceSelection, self.cb_size_att)
-        self.Bind(wx.EVT_COMBOBOX, self.OnSizeSelection, self.cb_size_col)
-        self.Bind(wx.EVT_BUTTON, self.OnAddSizeColumn, self.btn_add_size)
-        self.Bind(wx.EVT_CHECKBOX, self.OnColorChecked,  self.rgb_check)
-        self.Bind(wx.EVT_CHECKBOX, self.OnSizeChecked,  self.size_check)
         
         self.SetTitle(_("Thematic mapping for vector map in 3D view"))
         
-        
-    def UpdateDialog(self):
-        """!Update dialog according to selected map"""
-        VectorColorTable.UpdateDialog(self)
-        if not self.inmap:
-            self.sizeRulesPanel.Clear()                       
-        if not len(self.dbInfo.layers):
-            for combo in (self.cb_size_att, self.cb_size_col):
-                combo.SetValue("")
-                combo.Disable()
-                combo.Clear()
-            enable = False   
-        else:
-        # initialize layer selection combobox
-            for combo in (self.cb_vlayer, self.cb_size_att, self.cb_size_col):
-                combo.Enable()
-            
-            if self.CheckMapset():
-                self.btn_add_size.Enable(True)
-                self.AddTemporaryColumn(name = 'tmp_size', type = 'integer')
-            else:
-                self.btn_add_RGB.Enable(False)
-                
-    def OnLayerSelection(self, event):
-        VectorColorTable.OnLayerSelection(self, event)
-        # reset choices in column selection comboboxes if layer changes
-        vlayer = int(self.cb_vlayer.GetStringSelection())
-        self.cb_size_att.InsertColumns(vector = self.inmap, layer = vlayer, dbInfo = self.dbInfo)
-        self.cb_size_att.SetSelection(0)
-        self.properties['source_size'] = self.cb_size_att.GetString(0)
-        self.cb_size_col.InsertColumns(vector = self.inmap, layer = vlayer,
-                                       type = ["integer", "double precision"], dbInfo = self.dbInfo)
-        for item in self.cb_size_col.GetItems():
-            if item.lower().find('size') >= 0:
-                self.cb_size_col.SetStringSelection(item)
-                self.properties['size'] = item
-            else:
-                self.properties['size'] = ''
-        
-        self.LoadTable(attColumn = self.properties['source_size'], rgbColumn = self.properties['size'],
-                       rulesPanel = self.sizeRulesPanel, type = 'size')
-        self.Update()  
-        
-    def OnSizeSelection(self, event):
-        self.properties['size'] = event.GetString()
-        
-        self.LoadTable(attColumn = self.properties['source_size'], rgbColumn = self.properties['size'],
-                       rulesPanel = self.sizeRulesPanel, type = 'size')
-    
-    def OnSizeSourceSelection(self, event):
-        self.properties['source_size'] = event.GetString()
-        
-        
-        self.LoadTable(attColumn = self.properties['source_size'], rgbColumn = self.properties['size'],
-                       rulesPanel = self.sizeRulesPanel, type = 'size') 
                     
     def _initLayer(self):
         """!Set initial layer when opening dialog"""
@@ -1359,292 +1501,33 @@
         self.selectionInput.SetValue(self.inmap)
         self.selectionInput.Disable()
         
-    def _doLayout(self):
-        """!Do main layout"""
-        mainsizer = wx.BoxSizer(wx.VERTICAL)
-        # ? size (-1, ...) doesn't work
-        scrollPanel = scrolled.ScrolledPanel(self, id = wx.ID_ANY, size = (870, 600),
-                                             style = wx.TAB_TRAVERSAL)
-        scrollPanel.SetupScrolling()
-        
-        sizer = wx.BoxSizer(wx.VERTICAL)
-        #
-        # map selection
-        #
-        mapSelection = self._createMapSelection(parent = scrollPanel)
-        sizer.Add(item = mapSelection, proportion = 0,
-                  flag = wx.ALL | wx.EXPAND, border = 5)
-        #
-        # set vector attributes
-        #
-        vectorAttrb = self._createVectorAttrb(parent = scrollPanel)
-        sizer.Add(item = vectorAttrb, proportion = 0,
-                  flag = wx.ALL | wx.EXPAND, border = 5)
-        #
-        # body & preview
-        #
-        bodySizer = self._createBody(parent = scrollPanel)
-        sizer.Add(item = bodySizer, proportion = 1,
-                  flag = wx.ALL | wx.EXPAND, border = 5)
-                
-        scrollPanel.SetSizer(sizer)
-        scrollPanel.Fit()        
-        mainsizer.Add(scrollPanel, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
-        #
-        # buttons
-        #
-        btnSizer = self._createButtons()
-        
-        mainsizer.Add(item = wx.StaticLine(parent = self, id = wx.ID_ANY,
-                                       style = wx.LI_HORIZONTAL), proportion = 0,
-                                       flag = wx.EXPAND | wx.ALL, border = 5) 
-        
-        mainsizer.Add(item = btnSizer, proportion = 0,
-                  flag = wx.ALL | wx.ALIGN_RIGHT, border = 5)
-        
-        self.SetSizer(mainsizer)
-        mainsizer.Layout()
-        mainsizer.Fit(self) 
-    
-    def _createBody(self, parent):
-        """!Create dialog body consisting of rules and preview"""
-        bodySizer =  wx.GridBagSizer(hgap = 5, vgap = 5)
-        row = 0
-        
-        # label with instructions - don't want it now
-        self.cr_label = wx.StaticText(parent, id = wx.ID_ANY)
-        self.cr_label.Hide()
-
-        # color table
-        self.colorRulesPanel = RulesPanel(parent = parent, mapType = self.type,
-                                          columnType = 'color', properties = self.properties,
-                                          panelWidth = 200)
-        # size table        
-        self.sizeRulesPanel = RulesPanel(parent = parent, mapType = self.type,
-                                         columnType = 'size', properties = self.properties,
-                                         panelWidth = 200)
-                                        
-        bodySizer.Add(item = self.colorRulesPanel.label, pos = (row, 0), span = (1, 2))
-        bodySizer.Add(item = self.sizeRulesPanel.label, pos = (row, 2), span = (1, 2))
-        row += 1
-        
-        bodySizer.Add(item = self.colorRulesPanel.mainPanel, pos = (row, 0), span = (1, 2))
-        # add two rules as default
-        self.colorRulesPanel.AddRules(2)
-        bodySizer.Add(item = self.sizeRulesPanel.mainPanel, pos = (row, 2), span = (1, 2))
-        # add two rules as default
-        self.sizeRulesPanel.AddRules(2)
-        
-        # preview window
-        self._createPreview(parent = parent)
-        bodySizer.Add(item = self.preview, pos = (row, 4),
-                      flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border = 10)
-        row += 1
-        # add ckeck all and clear all
-        bodySizer.Add(item = self.colorRulesPanel.checkAll, flag = wx.ALIGN_CENTER_VERTICAL, 
-                      pos = (row, 0))
-        bodySizer.Add(item = self.colorRulesPanel.clearAll, pos = (row, 1))
-        
-        bodySizer.Add(item = self.sizeRulesPanel.checkAll, flag = wx.ALIGN_CENTER_VERTICAL, 
-                      pos = (row, 2))
-        bodySizer.Add(item = self.sizeRulesPanel.clearAll, pos = (row, 3))
-        
-        # preview button
-        self.btnPreview = wx.Button(parent, id = wx.ID_ANY,
-                                    label = _("Preview"))
-        bodySizer.Add(item = self.btnPreview, pos = (row, 4),
-                      flag = wx.ALIGN_RIGHT)
-        self.btnPreview.Enable(False)
-        self.btnPreview.SetToolTipString(_("Show preview of map "
-                                           "(current Map Display extent is used)."))
-        row += 1
-        # add rules button and spin to sizer
-        bodySizer.Add(item = self.colorRulesPanel.numRules, pos = (row, 0),
-                      flag = wx.ALIGN_CENTER_VERTICAL)
-        bodySizer.Add(item = self.colorRulesPanel.btnAdd, pos = (row, 1))
-        bodySizer.Add(item = self.sizeRulesPanel.numRules, pos = (row, 2),
-                      flag = wx.ALIGN_CENTER_VERTICAL)
-        bodySizer.Add(item = self.sizeRulesPanel.btnAdd, pos = (row, 3), 
-                        flag = wx.ALIGN_LEFT)
-                
-        return bodySizer
-    
-    def _createVectorAttrb(self, parent):
-        """!Create part of dialog with layer/column selection"""
-        inputBox = wx.StaticBox(parent = parent, id = wx.ID_ANY,
-                                label = " %s " % _("Select vector columns"))
-        layer_label = wx.StaticText(parent, id = wx.ID_ANY, label = _('Layer:'))
-        self.rgb_check = wx.CheckBox(parent, id = wx.ID_ANY, label = _('Use color for thematic mapping:'))
-        if self.vectorType == 'points':
-            label = _('Use symbol size for thematic mapping:')
-        else:
-            label = _('Use line width for thematic mapping:')
-        self.size_check = wx.CheckBox(parent, id = wx.ID_ANY, label = label)
-        
-        self.rgb_check.SetValue(True)
-        self.size_check.SetValue(True)
-                                            
-        color_att_label = wx.StaticText(parent, id = wx.ID_ANY,
-                                         label = _('Attribute column:'))
-        size_att_label = wx.StaticText(parent, id = wx.ID_ANY,
-                                         label = _('Attribute column:'))
-        rgb_col_label = wx.StaticText(parent, id = wx.ID_ANY,
-                                           label = _('RGB color column:'))
-        if self.vectorType == 'points':
-            label = _('Symbol size column:')
-        else:
-            label = _('Line with column:')
-        size_col_label = wx.StaticText(parent, id = wx.ID_ANY, label = label)
-        
-        self.rgb_range_label = wx.StaticText(parent, id = wx.ID_ANY)                                        
-        self.size_range_label = wx.StaticText(parent, id = wx.ID_ANY)
-        cb_size = (150, -1)
-        self.cb_vlayer = gselect.LayerSelect(parent, size = cb_size)
-        self.cb_color_att = gselect.ColumnSelect(parent, size = cb_size)
-        self.cb_size_att = gselect.ColumnSelect(parent, size = cb_size)
-        self.cb_rgb_col = gselect.ColumnSelect(parent, size = cb_size)
-        self.cb_size_col = gselect.ColumnSelect(parent, size = cb_size)
-        self.btn_add_RGB = wx.Button(parent, id = wx.ID_ANY,
-                                             label = _('Add column'))
-        self.btn_add_size = wx.Button(parent, id = wx.ID_ANY,
-                                             label = _('Add column'))
-        self.btn_add_RGB.SetToolTipString(_("Add GRASSRGB column to current attribute table."))
-        
-        if self.vectorType == 'points':
-            label = _("Add size column to current attribute table.")
-        else:
-            label = _("Add width column to current attribute table.")
-        self.btn_add_size.SetToolTipString(label)
-        
-        # layout
-        inputSizer = wx.StaticBoxSizer(inputBox, wx.VERTICAL)
-        vSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
-        vSizer.AddGrowableCol(2)
-        
-        vSizer.Add(layer_label, pos = (0, 0),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.cb_vlayer,  pos = (0, 1),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-                
-        vSizer.Add(self.rgb_check,  pos = (1, 0), span = (1, 3),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.size_check,  pos = (1, 3), span = (1, 3),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-                
-        vSizer.Add(color_att_label, pos = (2, 0),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(size_att_label, pos = (2, 3),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-                
-        vSizer.Add(rgb_col_label, pos = (4, 0),
-                  flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(size_col_label, pos = (4, 3),
-                  flag = wx.ALIGN_CENTER_VERTICAL)
-                
-        vSizer.Add(self.cb_color_att, pos = (2, 1),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.cb_size_att, pos = (2, 4),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-                
-        vSizer.Add(self.rgb_range_label, pos = (3, 1),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.size_range_label, pos = (3, 4),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-                
-        vSizer.Add(self.cb_rgb_col, pos = (4, 1),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.cb_size_col, pos = (4, 4),
-                   flag = wx.ALIGN_CENTER_VERTICAL)
-                
-        vSizer.Add(self.btn_add_RGB, pos = (4, 2),
-                  flag = wx.ALIGN_CENTER_VERTICAL)
-        vSizer.Add(self.btn_add_size, pos = (4, 5),
-                  flag = wx.ALIGN_CENTER_VERTICAL)
-        inputSizer.Add(item = vSizer,
-                       flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, border = 5)
-                
-        return inputSizer 
-    
-    def OnAddSizeColumn(self, event):
-        """!Add size column if it doesn't exist"""
-        if self.vectorType == 'points':
-            name = 'GRASSSIZE'
-        else:
-            name = 'GRASSWIDTH'
-        
-        ret = gcmd.RunCommand('v.db.addcolumn',
-                               map = self.inmap,
-                              layer = self.properties['layer'],
-                              columns = '%s integer' % name)
-        self.cb_size_col.InsertColumns(self.inmap, self.properties['layer'], type = ["integer"])
-        self.cb_size_col.SetStringSelection(name)
-        self.properties['size'] = name
-        
-        self.LoadTable(attColumn = self.properties['source_size'], rgbColumn = self.properties['size'],
-                       rulesPanel = self.sizeRulesPanel, type = 'size')
-
-    def OnColorChecked(self, event):
-        """!Use color for thematic mapping"""
-        if self.rgb_check.IsChecked():
-            self.colorRulesPanel.Enable(True)
-        else:
-            self.colorRulesPanel.Enable(False)
-        
-    def OnSizeChecked(self, event):
-        """!Use size for thematic mapping"""
-        if self.size_check.IsChecked():
-            self.sizeRulesPanel.Enable(True)
-        else:
-            self.sizeRulesPanel.Enable(False)
-        
-    def OnPreview(self, event = None):
-        """!Update preview (based on computational region)"""
-        if not self.inmap or not self.properties['size'] or not self.properties['tmp_size']:
-            self.preview.EraseMap()
-            return
-        
-        cmdlist = ['d.vect',
-                    '-a',
-                   'map=%s' % self.inmap,
-                   'type=point,line,boundary,area']
-                
-        if self.size_check.IsChecked()\
-                and self.properties["size"] and self.properties["tmp_size"]:
-            if self.vectorType == 'points':
-                cmdlist.append('size_column=%s' % self.properties['tmp_size'])
-            else:
-                cmdlist.append('width_column=%s' % self.properties['tmp_size'])
-            
-        if self.rgb_check.IsChecked()\
-                and self.properties["rgb"] and self.properties['tmp_rgb']:
-            cmdlist.append('rgb_column=%s' % self.properties['tmp_rgb'])
-        ltype = 'vector'
-        ColorTable.DoPreview(self, ltype, cmdlist)
-    
     def OnApply(self, event):
         """!Apply selected color table
 
         @return True on success otherwise False
         """
-        ret = VectorColorTable.CreateColorTable(self)
+        
+        ret = self.CreateColorTable()
         if not ret:
-            gcmd.GMessage(parent = self, message = _("No color rules given."))
-        ret = self.CreateSizeTable()
-        if not ret:
-            gcmd.GMessage(parent = self, message = _("No size rules given."))
+            gcmd.GMessage(parent = self, message = _("No rules given."))
         
         data = self.parent.GetLayerData(nvizType = 'vector')
         data['vector']['points']['thematic']['layer'] = int(self.properties['layer'])
         
-        if self.size_check.IsChecked() and self.properties['size']:
-            data['vector'][self.vectorType]['thematic']['sizecolumn'] = self.properties['size']
-        else:
-            data['vector'][self.vectorType]['thematic']['sizecolumn'] = None
+        value = None
+        if self.properties['storeColumn']:
+            value = self.properties['storeColumn']
             
-        if self.rgb_check.IsChecked() and self.properties['rgb']:
-            data['vector'][self.vectorType]['thematic']['rgbcolumn'] = self.properties['rgb']
+        if not self.colorTable:
+            if self.attributeType == 'color':
+                data['vector'][self.vectorType]['thematic']['rgbcolumn'] = value
+            else:
+                data['vector'][self.vectorType]['thematic']['sizecolumn'] = value
         else:
-            data['vector'][self.vectorType]['thematic']['rgbcolumn'] = None
+            if self.attributeType == 'color':
+                data['vector'][self.vectorType]['thematic']['rgbcolumn'] = None
+            else:
+                data['vector'][self.vectorType]['thematic']['sizecolumn'] = None
         
         data['vector'][self.vectorType]['thematic']['update'] = None
         
@@ -1653,61 +1536,6 @@
         self.parent.mapWindow.Refresh(False)
         
         return ret
-    
-    def CreateColorTable(self, force = False):
-        """!Creates color and size table"""
-        VectorColorTable.CreateColorTable(self, force = True)
-        self.CreateSizeTable(force = True)
-        
-    def CreateSizeTable(self, force = False):
-        """!Creates size table
-
-        @return True on success
-        @return False on failure
-        """
-        VectorColorTable.CreateColorTable(self)
-        rulestxt = ''
-        
-        for rule in self.sizeRulesPanel.ruleslines.itervalues():
-            if not rule['value']: # skip empty rules
-                continue
-            
-            if force:
-                size_col = self.properties['tmp_size']
-            else:
-                size_col = self.properties['size']
-            rulestxt += "UPDATE %s SET %s='%s' WHERE %s ;\n" % (self.properties['table'],
-                                                                size_col,
-                                                                rule['size'],
-                                                                rule['value'])
-        if not rulestxt:
-            return False
-        
-        gtemp = utils.GetTempfile()
-        output = open(gtemp, "w")
-        try:
-            output.write(rulestxt)
-        finally:
-            output.close()
-        
-        gcmd.RunCommand('db.execute',
-                        parent = self,
-                        input = gtemp)
-        return True
-    
-    def OnOK(self, event):
-        """!Apply selected color table, close the dialog
-            and delete temporary column"""
-        if self.OnApply(event):
-            self.Destroy()
-            self.DeleteTemporaryColumn(name = 'tmp_size')
-            self.DeleteTemporaryColumn(name = 'tmp_rgb')
-    
-    def OnCancel(self, event):
-        """!Do not apply any changes and close the dialog"""
-        self.Destroy()
-        self.DeleteTemporaryColumn(name = 'tmp_size')    
-        self.DeleteTemporaryColumn(name = 'tmp_rgb') 
            
 class BufferedWindow(wx.Window):
     """!A Buffered window class"""

Modified: grass/trunk/gui/wxpython/gui_modules/gselect.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/gselect.py	2011-08-17 18:38:59 UTC (rev 47713)
+++ grass/trunk/gui/wxpython/gui_modules/gselect.py	2011-08-17 19:31:48 UTC (rev 47714)
@@ -800,12 +800,13 @@
         if vector:
             self.InsertColumns(vector, layer)
     
-    def InsertColumns(self, vector, layer, excludeKey = False, type = None, dbInfo = None):
+    def InsertColumns(self, vector, layer, excludeKey = False, excludeCols = None, type = None, dbInfo = None):
         """!Insert columns for a vector attribute table into the columns combobox
 
         @param vector vector name
         @param layer vector layer number
         @param excludeKey exclude key column from the list?
+        @param excludeCols list of columns to be removed from the list
         @param type only columns of given type (given as list)
         """
         if not dbInfo:
@@ -820,13 +821,20 @@
                 columns[val['index']] = key
             if excludeKey: # exclude key column
                 columns.remove(keyColumn)
+            if excludeCols: # exclude key column
+                for key in columnchoices.iterkeys():
+                    if key in excludeCols:
+                        columns.remove(key)
             if type: # only selected column types
                 for key, value in columnchoices.iteritems():
                     if value['type'] not in type:
-                        columns.remove(key)
+                        try:
+                            columns.remove(key)
+                        except ValueError:
+                            pass
         except (KeyError, ValueError):
             columns = list()
-        
+            
         self.SetItems(columns)
         self.SetValue(self.defaultValue)
         

Modified: grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py	2011-08-17 18:38:59 UTC (rev 47713)
+++ grass/trunk/gui/wxpython/gui_modules/nviz_mapdisp.py	2011-08-17 19:31:48 UTC (rev 47714)
@@ -1543,10 +1543,18 @@
             
         # thematic
         if 'update' in data['thematic']:
-            if data['thematic']['use']:
+            color = width = None
+            colorTable = False
+            if data['thematic']['usecolor'] or data['thematic']['usewidth']:
+                if data['thematic']['usecolor']:
+                    color = data['thematic']['rgbcolumn']
+                    colorTable = True
+                if data['thematic']['usewidth']:
+                    width = data['thematic']['sizecolumn']
                 self._display.SetLinesStyleThematic(id = id, layer = data['thematic']['layer'],
-                                               color = data['thematic']['rgbcolumn'],
-                                               width = data['thematic']['sizecolumn'])
+                                                     color = color,
+                                                     colorTable = colorTable, 
+                                                     width = width)
             else:
                 self._display.UnsetLinesStyleThematic(id = id)
             data['thematic'].pop('update')
@@ -1598,10 +1606,18 @@
         
         # thematic
         if 'update' in data['thematic']:
-            if data['thematic']['use']:
+            color = size = None
+            colorTable = False
+            if data['thematic']['usecolor'] or data['thematic']['usesize']:
+                if data['thematic']['usecolor']:
+                    color = data['thematic']['rgbcolumn']
+                    colorTable = True
+                if data['thematic']['usesize']:
+                    size = data['thematic']['sizecolumn']
                 self._display.SetPointsStyleThematic(id = id, layer = data['thematic']['layer'],
-                                               color = data['thematic']['rgbcolumn'],
-                                               size = data['thematic']['sizecolumn'])
+                                                     color = color,
+                                                     colorTable = colorTable, 
+                                                     size = size)
             else:
                 self._display.UnsetPointsStyleThematic(id = id)
             data['thematic'].pop('update')

Modified: grass/trunk/gui/wxpython/gui_modules/nviz_tools.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/nviz_tools.py	2011-08-17 18:38:59 UTC (rev 47713)
+++ grass/trunk/gui/wxpython/gui_modules/nviz_tools.py	2011-08-17 19:31:48 UTC (rev 47714)
@@ -1147,25 +1147,43 @@
         
         # thematic mapping
         self.win['vector']['lines']['thematic'] = {}
-        checkThematic = wx.CheckBox(parent = panel, id = wx.ID_ANY,
-                                         label = _("use thematic mapping for vector lines"))
-        self.win['vector']['lines']['thematic']['check'] = checkThematic.GetId()
-        checkThematic.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
-        checkThematic.SetValue(False)
+        checkThematicColor = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                         label = _("use color for thematic mapping"))
+        checkThematicWidth = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                         label = _("use width for thematic mapping"))
+        self.win['vector']['lines']['thematic']['checkcolor'] = checkThematicColor.GetId()
+        self.win['vector']['lines']['thematic']['checkwidth'] = checkThematicWidth.GetId()
+        checkThematicColor.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
+        checkThematicWidth.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
+        checkThematicColor.SetValue(False)
+        checkThematicWidth.SetValue(False)
         
+        vSizer = wx.BoxSizer(wx.VERTICAL)
         hSizer = wx.BoxSizer(wx.HORIZONTAL)
-        hSizer.Add(item = checkThematic, flag = wx.ALIGN_CENTER_VERTICAL,
+        hSizer.Add(item = checkThematicColor, flag = wx.ALIGN_CENTER_VERTICAL,
                     border = 5)
-        
         setThematic = wx.Button(parent = panel, id = wx.ID_ANY,
                                          label = _("Set options..."))
-        self.win['vector']['lines']['thematic']['button'] = setThematic.GetId()
+        self.win['vector']['lines']['thematic']['buttoncolor'] = setThematic.GetId()
         setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
         hSizer.Add(item = wx.Size(-1, -1), proportion = 1)
         hSizer.Add(item = setThematic, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT,
                     border = 5, proportion = 0)
+        vSizer.Add(hSizer, flag = wx.EXPAND)
+                    
+        hSizer = wx.BoxSizer(wx.HORIZONTAL)
+        hSizer.Add(item = checkThematicWidth, flag = wx.ALIGN_CENTER_VERTICAL,
+                    border = 5)
+        setThematic = wx.Button(parent = panel, id = wx.ID_ANY,
+                                         label = _("Set options..."))
+        self.win['vector']['lines']['thematic']['buttonwidth'] = setThematic.GetId()
+        setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
+        hSizer.Add(item = wx.Size(-1, -1), proportion = 1)
+        hSizer.Add(item = setThematic, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT,
+                    border = 5, proportion = 0)
         
-        gridSizer.Add(item = hSizer, flag = wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
+        vSizer.Add(hSizer, flag = wx.EXPAND)
+        gridSizer.Add(item = vSizer, flag = wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
                       pos = (1, 1), span = (1, 5))
         
         # display
@@ -1305,21 +1323,34 @@
                       pos = (0, 6))
         # thematic mapping
         self.win['vector']['points']['thematic'] = {}
-        checkThematic = wx.CheckBox(parent = panel, id = wx.ID_ANY,
-                                         label = _("use thematic mapping for vector points"))
-        self.win['vector']['points']['thematic']['check'] = checkThematic.GetId()
-        checkThematic.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
-        checkThematic.SetValue(False)
+        checkThematicColor = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                         label = _("use color for thematic mapping"))
+        checkThematicSize = wx.CheckBox(parent = panel, id = wx.ID_ANY,
+                                         label = _("use size for thematic mapping"))
+        self.win['vector']['points']['thematic']['checkcolor'] = checkThematicColor.GetId()
+        self.win['vector']['points']['thematic']['checksize'] = checkThematicSize.GetId()
+        checkThematicColor.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
+        checkThematicSize.Bind(wx.EVT_CHECKBOX, self.OnCheckThematic)
+        checkThematicColor.SetValue(False)
+        checkThematicSize.SetValue(False)
         
-        gridSizer.Add(item = checkThematic, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
+        gridSizer.Add(item = checkThematicColor, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
                       pos = (1, 1), span = (1, 5))
         setThematic = wx.Button(parent = panel, id = wx.ID_ANY,
                                          label = _("Set options..."))
-        self.win['vector']['points']['thematic']['button'] = setThematic.GetId()
+        self.win['vector']['points']['thematic']['buttoncolor'] = setThematic.GetId()
         setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
         gridSizer.Add(item = setThematic, flag = wx.ALIGN_CENTER_VERTICAL,
                       pos = (1, 6))
-                           
+                    
+        gridSizer.Add(item = checkThematicSize, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT,
+                      pos = (2, 1), span = (1, 5))
+        setThematic = wx.Button(parent = panel, id = wx.ID_ANY,
+                                         label = _("Set options..."))
+        self.win['vector']['points']['thematic']['buttonsize'] = setThematic.GetId()
+        setThematic.Bind(wx.EVT_BUTTON, self.OnSetThematic)
+        gridSizer.Add(item = setThematic, flag = wx.ALIGN_CENTER_VERTICAL,
+                      pos = (2, 6))                   
         vertSizer.Add(gridSizer, proportion = 0, flag = wx.EXPAND, border = 0)
         # high
         gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
@@ -3211,17 +3242,28 @@
         """!Switch on/off thematic mapping"""
         # can be called with no event to enable/disable button
         if not event:
-            ids = (self.win['vector']['points']['thematic']['check'],
-                  self.win['vector']['lines']['thematic']['check'])
+            ids = (self.win['vector']['points']['thematic']['checkcolor'],
+                  self.win['vector']['lines']['thematic']['checkcolor'],
+                  self.win['vector']['points']['thematic']['checksize'],
+                  self.win['vector']['lines']['thematic']['checkwidth'])
         else:
             ids = (event.GetId(),)
         for id in ids:
-            if id == self.win['vector']['points']['thematic']['check']:
-                type = 'points'
+            if id in self.win['vector']['points']['thematic'].values():
+                vtype = 'points'
+                if id == self.win['vector'][vtype]['thematic']['checkcolor']:
+                    attrType = 'color'
+                else:
+                    attrType = 'size'
             else:
-                type = 'lines'
-            check = self.win['vector'][type]['thematic']['check']
-            button = self.win['vector'][type]['thematic']['button']
+                vtype = 'lines'
+                if id == self.win['vector'][vtype]['thematic']['checkcolor']:
+                    attrType = 'color'
+                else:
+                    attrType = 'width'
+                
+            check = self.win['vector'][vtype]['thematic']['check' + attrType]
+            button = self.win['vector'][vtype]['thematic']['button' + attrType]
             if self.FindWindowById(check).GetValue():
                 checked = True
             else:
@@ -3229,8 +3271,8 @@
             self.FindWindowById(button).Enable(checked)
             
             data = self.GetLayerData('vector')
-            data['vector'][type]['thematic']['use'] = checked
-            data['vector'][type]['thematic']['update'] = None
+            data['vector'][vtype]['thematic']['use' + attrType] = checked
+            data['vector'][vtype]['thematic']['update'] = None
         
         # update properties
         event = wxUpdateProperties(data = data)
@@ -3241,11 +3283,17 @@
             
     def OnSetThematic(self, event):
         """!Set options for thematic points"""
-        if event.GetId() == self.win['vector']['points']['thematic']['button']:
-            vectorType = 'points'
+        if event.GetId() in self.win['vector']['points']['thematic'].values():
+            vtype = 'points'
         else:
-            vectorType = 'lines'            
-        ctable = colorrules.ThematicVectorTable(self, vectorType)
+            vtype = 'lines'
+        if event.GetId() == self.win['vector'][vtype]['thematic']['buttoncolor']:
+            attrType = 'color'
+        elif vtype == 'points':
+            attrType = 'size'
+        else:
+            attrType = 'width'
+        ctable = colorrules.ThematicVectorTable(self, vtype, attributeType = attrType)
         ctable.CentreOnScreen()
         ctable.Show()
         
@@ -4269,6 +4317,16 @@
             self.FindWindowById(self.win['vector'][v]['height']['slider']).Enable(enable)
             self.FindWindowById(self.win['vector'][v]['height']['text']).Enable(enable)
             
+            if data[v]['thematic']['usecolor']:
+                check = self.FindWindowById(self.win['vector'][v]['thematic']['checkcolor'])
+                check.SetValue(data[v]['thematic']['usecolor'])
+            if 'usesize' in data[v]['thematic'] and data[v]['thematic']['usesize']:
+                check = self.FindWindowById(self.win['vector'][v]['thematic']['checksize'])
+                check.SetValue(data[v]['thematic']['usesize'])
+            elif 'usewidth' in data[v]['thematic'] and data[v]['thematic']['usewidth']:
+                check = self.FindWindowById(self.win['vector'][v]['thematic']['checkwidth'])
+                check.SetValue(data[v]['thematic']['usewidth'])
+            self.OnCheckThematic(None)
         #
         # lines
         #
@@ -4342,7 +4400,7 @@
                 win.SetValue(color)
             else:
                 win.SetValue(data['points'][prop]['value'])
-        self.OnCheckThematic(None)
+##        self.OnCheckThematic(None)
         # height
         for type in ('slider', 'text'):
             win = self.FindWindowById(self.win['vector']['points']['height'][type])

Modified: grass/trunk/gui/wxpython/gui_modules/workspace.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/workspace.py	2011-08-17 18:38:59 UTC (rev 47713)
+++ grass/trunk/gui/wxpython/gui_modules/workspace.py	2011-08-17 19:31:48 UTC (rev 47714)
@@ -387,7 +387,20 @@
                 # height
                 self.__processLayerNvizNode(node_vpoints, 'size', int,
                                             nviz['vector']['points'])
-            
+                
+                # thematic
+                node_thematic = node_vpoints.find('thematic')
+                thematic = nviz['vector']['points']['thematic'] = {}
+                thematic['rgbcolumn'] = self.__processLayerNvizNode(node_thematic, 'rgbcolumn', str)
+                thematic['sizecolumn'] = self.__processLayerNvizNode(node_thematic, 'sizecolumn', str)
+                for col in ('rgbcolumn', 'sizecolumn'):
+                    if thematic[col] == 'None':
+                        thematic[col] = None
+                thematic['layer'] = self.__processLayerNvizNode(node_thematic, 'layer', int)
+                for use in ('usecolor', 'usesize', 'usewidth'):
+                    if node_thematic.get(use, ''):
+                        thematic[use] = int(node_thematic.get(use, '0'))
+                
             # vlines
             node_vlines = node_nviz.find('vlines')
             if node_vlines is not None:
@@ -417,6 +430,19 @@
                 # height
                 self.__processLayerNvizNode(node_vlines, 'height', int,
                                             nviz['vector']['lines'])
+                
+                # thematic
+                node_thematic = node_vlines.find('thematic')
+                thematic = nviz['vector']['lines']['thematic'] = {}
+                thematic['rgbcolumn'] = self.__processLayerNvizNode(node_thematic, 'rgbcolumn', str)
+                thematic['sizecolumn'] = self.__processLayerNvizNode(node_thematic, 'sizecolumn', str)
+                for col in ('rgbcolumn', 'sizecolumn'):
+                    if thematic[col] == 'None':
+                        thematic[col] = None
+                thematic['layer'] = self.__processLayerNvizNode(node_thematic, 'layer', int)
+                for use in ('usecolor', 'usesize', 'usewidth'):
+                    if node_thematic.get(use, ''):
+                        thematic[use] = int(node_thematic.get(use, '0'))
             
         return nviz
     
@@ -711,7 +737,8 @@
                             'sizecolumn' : UserSettings.Get(group='nviz', key='vector',
                                                       subkey=['lines', 'sizecolumn']),
                             'layer': 1,
-                            'use' : False}
+                            'usecolor' : False,
+                            'usewidth' : False}
         if 'object' in data:
             for attrb in ('color', 'width', 'mode', 'height'):
                 data[attrb]['update'] = None
@@ -749,7 +776,8 @@
                             'sizecolumn' : UserSettings.Get(group='nviz', key='vector',
                                                       subkey=['points', 'sizecolumn']),
                             'layer': 1,
-                            'use' : False}
+                            'usecolor' : False,
+                            'usesize' : False}
         if 'object' in data:
             for attrb in ('size', 'width', 'marker',
                           'color', 'surface', 'height', 'thematic'):
@@ -1123,7 +1151,7 @@
                                                            marker))
             self.indent += 4
             for name in data[attrb].iterkeys():
-                if name in ('object', 'marker', 'thematic'):
+                if name in ('object', 'marker'):
                     continue
                 if name == 'mode':
                     self.file.write('%s<%s type="%s">\n' % (' ' * self.indent, name,
@@ -1140,6 +1168,21 @@
                             self.file.write('%s</map>\n' % (' ' * self.indent))
                         self.indent -= 4
                     self.file.write('%s</%s>\n' % ((' ' * self.indent, name)))
+                elif name == 'thematic':
+                    self.file.write('%s<%s ' % (' ' * self.indent, name))
+                    for key in data[attrb][name].iterkeys():
+                        if key.startswith('use'):
+                            self.file.write('%s="%s" ' % (key, int(data[attrb][name][key])))
+                    self.file.write('>\n')
+                    self.indent += 4
+                    for key, value in data[attrb][name].iteritems():
+                        if key.startswith('use'):
+                            continue
+                        if value is None:
+                            value = ''
+                        self.file.write('%s<%s>%s</%s>\n' % (' ' * self.indent, key, value, key))
+                    self.indent -= 4
+                    self.file.write('%s</%s>\n' % (' ' * self.indent, name))
                 else:
                     self.file.write('%s<%s>\n' % (' ' * self.indent, name))
                     self.indent += 4
@@ -1219,7 +1262,7 @@
         self.indent -= 4
         self.file.write('%s</focus>\n' % (' ' * self.indent))
         # background
-        self.__writeTagWithValue('background_color', view['background']['color'], format = 'd:%d:%d')
+        self.__writeTagWithValue('background_color', view['background']['color'][:3], format = 'd:%d:%d')
         
         self.indent -= 4
         self.file.write('%s</view>\n' % (' ' * self.indent))

Modified: grass/trunk/gui/wxpython/gui_modules/wxnviz.py
===================================================================
--- grass/trunk/gui/wxpython/gui_modules/wxnviz.py	2011-08-17 18:38:59 UTC (rev 47713)
+++ grass/trunk/gui/wxpython/gui_modules/wxnviz.py	2011-08-17 19:31:48 UTC (rev 47714)
@@ -29,6 +29,7 @@
 try:
     from grass.lib.gis   import *
     from grass.lib.raster3d   import *
+    from grass.lib.vector  import *
     from grass.lib.ogsf  import *
     from grass.lib.nviz  import *
     from grass.lib.raster import *
@@ -84,6 +85,9 @@
         
         self.data_obj = nv_data()
         self.data = pointer(self.data_obj)
+        self.color_obj = Colors()
+        self.color = pointer(self.color_obj)
+        
         self.width = self.height = -1
         self.showLight = False
         
@@ -943,21 +947,74 @@
         
         return 1
 
-    def SetPointsStyleThematic(self, id, layer, color = None, width = None, size = None, symbol = None):
-        """!Set thematic style for vector points"""
-        GP_set_style_thematic(id, layer, color, width, size, symbol)
+    def ReadVectorColors(self, name, mapset):
+        """!Read vector colors
+        
+        @param name vector map name
+        @mapset mapset name ("" for search path)
+        
+        @return -1 on error 
+        @return 0 if color table missing 
+        @return 1 on success (color table found) 
+        """
+        return Vect_read_colors(name, mapset, self.color)
+        
+    def SetPointsStyleThematic(self, id, layer, color = None, colorTable = False, 
+                               width = None, size = None, symbol = None):
+        """!Set thematic style for vector points
+        
+        @param id vector set id
+        @param layer layer number for thematic mapping
+        @param colorTable use color table 
+        @param color color column name 
+        @param width width column name 
+        @param size size column name 
+        @param symbol symbol column name 
+        """
+        file = c_char_p()
+        ret = GP_get_sitename(id, byref(file))
+        if ret < 0:
+            return -1
+        
+        ret = self.ReadVectorColors(file, "")
+        if ret < 0:
+            return -1
+        
+        if colorTable:
+            GP_set_style_thematic(id, layer, color, width, size, symbol, self.color)
+        else:
+            GP_set_style_thematic(id, layer, color, width, size, symbol, None)
 
-    def SetLinesStyleThematic(self, id, layer, color = None, width = None):
-        """!Set thematic style for vector lines"""
-        GV_set_style_thematic(id, layer, color, width) 
+    def SetLinesStyleThematic(self, id, layer, color = None, colorTable = False, width = None):
+        """!Set thematic style for vector lines
         
+        @param id vector set id
+        @param layer layer number for thematic mapping
+        @param color color column name 
+        @param colorTable use color table 
+        @param width width column name 
+        """
+        file = c_char_p()
+        ret = GV_get_vectname(id, byref(file))
+        if ret < 0:
+            return -1
+        
+        ret = self.ReadVectorColors(file, "")
+        if ret < 0:
+            return -1
+        
+        if colorTable:
+            GV_set_style_thematic(id, layer, color, width, self.color)
+        else:
+            GV_set_style_thematic(id, layer, color, width, None)
+        
     def UnsetLinesStyleThematic(self, id):
         """!Unset thematic style for vector points"""
-        GP_unset_style_thematic(id)      
+        GV_unset_style_thematic(id)      
          
     def UnsetPointsStyleThematic(self, id):
         """!Unset thematic style for vector lines"""
-        GV_unset_style_thematic(id)
+        GP_unset_style_thematic(id)
         
     def UnsetVectorPointSurface(self, id, surf_id):
         """!Unset reference surface of vector set (points)

Modified: grass/trunk/gui/wxpython/wxgui.py
===================================================================
--- grass/trunk/gui/wxpython/wxgui.py	2011-08-17 18:38:59 UTC (rev 47713)
+++ grass/trunk/gui/wxpython/wxgui.py	2011-08-17 19:31:48 UTC (rev 47714)
@@ -1041,7 +1041,7 @@
         if cmd[0] == 'r.colors':
             ctable = colorrules.RasterColorTable(self)
         else:
-            ctable = colorrules.VectorColorTable(self)
+            ctable = colorrules.VectorColorTable(self, attributeType = 'color')
         ctable.CentreOnScreen()
         ctable.Show()
         



More information about the grass-commit mailing list