[GRASS-SVN] r30529 - in grass/branches/releasebranch_6_3/gui/wxpython: . docs gui_modules icons images vdigit

svn_grass at osgeo.org svn_grass at osgeo.org
Tue Mar 11 14:40:46 EDT 2008


Author: martinl
Date: 2008-03-11 14:40:45 -0400 (Tue, 11 Mar 2008)
New Revision: 30529

Added:
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grass-gxw.dtd
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/mcalc_builder.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/workspace.py
   grass/branches/releasebranch_6_3/gui/wxpython/images/grass_form.png
Removed:
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grass-grc.dtd
   grass/branches/releasebranch_6_3/gui/wxpython/images/db_open_table.png
   grass/branches/releasebranch_6_3/gui/wxpython/images/grass-tiny-logo.png
   grass/branches/releasebranch_6_3/gui/wxpython/images/grass.form.gif
   grass/branches/releasebranch_6_3/gui/wxpython/images/grass.map.gif
   grass/branches/releasebranch_6_3/gui/wxpython/images/grass.smlogo.gif
   grass/branches/releasebranch_6_3/gui/wxpython/images/grass_db.png
   grass/branches/releasebranch_6_3/gui/wxpython/images/grass_sql.png
   grass/branches/releasebranch_6_3/gui/wxpython/images/grasslogo_big.gif
Modified:
   grass/branches/releasebranch_6_3/gui/wxpython/README
   grass/branches/releasebranch_6_3/gui/wxpython/docs/wxGUI.html
   grass/branches/releasebranch_6_3/gui/wxpython/gis_set.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/__init__.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/dbm.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/digit.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/gcmd.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/globalvar.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grassenv.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/gselect.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/location_wizard.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/mapdisp.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/menudata.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/menuform.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/preferences.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/render.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/rules.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/sqlbuilder.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/toolbars.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/utils.py
   grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/wxgui_utils.py
   grass/branches/releasebranch_6_3/gui/wxpython/icons/icon.py
   grass/branches/releasebranch_6_3/gui/wxpython/images/__init__.py
   grass/branches/releasebranch_6_3/gui/wxpython/vdigit/Makefile
   grass/branches/releasebranch_6_3/gui/wxpython/vdigit/cats.cpp
   grass/branches/releasebranch_6_3/gui/wxpython/vdigit/digit.h
   grass/branches/releasebranch_6_3/gui/wxpython/vdigit/driver.cpp
   grass/branches/releasebranch_6_3/gui/wxpython/vdigit/driver.h
   grass/branches/releasebranch_6_3/gui/wxpython/vdigit/grass6_wxvdigit.py
   grass/branches/releasebranch_6_3/gui/wxpython/vdigit/grass6_wxvdigit_wrap.cpp
   grass/branches/releasebranch_6_3/gui/wxpython/vdigit/vertex.cpp
   grass/branches/releasebranch_6_3/gui/wxpython/wxgui.py
Log:
wxGUI: backported from trunk (for 6.3.0 release)

Modified: grass/branches/releasebranch_6_3/gui/wxpython/README
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/README	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/README	2008-03-11 18:40:45 UTC (rev 30529)
@@ -144,13 +144,18 @@
 
 First, create a symlink to _gdi_.so shared library
 
-$ ln -s `locate _gdi_.so` $GISBASE/lib/libgdi.so
+$ sudo ln -s `locate _gdi_.so` /usr/local/lib/libgdi.so
 
 e.g.
 
-$ ln -s /usr/lib/python2.4/site-packages/wx-2.8-gtk2-unicode/wx/_gdi_.so $GISBASE/lib/libgdi.so
+$ sudo ln -s /usr/lib/python2.4/site-packages/wx-2.8-gtk2-unicode/wx/_gdi_.so /usr/local/lib/libgdi.so
 
+Make sure you set up LD_LIBRARY_PATH or noted '/usr/local/lib' in
+/etc/ld.so.conf.
+
+$ sudo ldconfig
+
 Then you can compile the driver
 
-$ cd $GISBASE/etc/wxpython/vdigit
+$ cd gui/wxpython/vdigit
 $ make

Modified: grass/branches/releasebranch_6_3/gui/wxpython/docs/wxGUI.html
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/docs/wxGUI.html	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/docs/wxGUI.html	2008-03-11 18:40:45 UTC (rev 30529)
@@ -418,7 +418,7 @@
 (Alphabetically ordered)<br><br>
 
 Michael Barton,<br>
-Daniel Cavelo,<br>
+Daniel Calvelo Aros,<br>
 Jachym Cepicky,<br>
 Martin Landa, FBK-irst, Trento, Italy
 

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gis_set.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gis_set.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gis_set.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -25,8 +25,10 @@
 import glob
 import shutil
 
+### i18N
+import gettext
+
 from gui_modules import utils
-from gui_modules import globalvar
 
 utils.CheckForWx()
 import wx
@@ -34,10 +36,14 @@
 import wx.lib.rcsizer as rcs
 import wx.lib.filebrowsebutton as filebrowse
 
+from gui_modules import globalvar
+
 class GRASSStartup(wx.Frame):
     """GRASS start-up screen"""
     def __init__(self, parent=None, id=wx.ID_ANY, style=wx.DEFAULT_FRAME_STYLE):
 
+        gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
+
         #
         # GRASS variables
         #
@@ -53,17 +59,19 @@
 
         wx.Frame.__init__(self, parent=parent, id=id, style=style)
 
+	self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
+
         #
         # graphical elements
         #
         # image
         try:
             name = os.path.join(globalvar.ETCDIR, "gintro.gif")
-            self.hbitmap = wx.StaticBitmap(self, wx.ID_ANY,
+            self.hbitmap = wx.StaticBitmap(self.panel, wx.ID_ANY,
                                            wx.Bitmap(name=name,
                                                      type=wx.BITMAP_TYPE_GIF))
         except:
-            self.hbitmap = wx.StaticBitmap(self, wx.ID_ANY, wx.EmptyBitmap(530,150))
+            self.hbitmap = wx.StaticBitmap(self.panel, wx.ID_ANY, wx.EmptyBitmap(530,150))
 
         # labels
         ### crashes when LOCATION doesn't exist
@@ -73,62 +81,63 @@
         grassVersion = versionFile.readline().replace('%s' % os.linesep, '').strip()
         versionFile.close()
 
-        self.select_box = wx.StaticBox (parent=self, id=wx.ID_ANY,
+        self.select_box = wx.StaticBox (parent=self.panel, id=wx.ID_ANY,
                                         label=" %s " % _("Choose project location and mapset"))
 
-        self.manage_box = wx.StaticBox (parent=self, id=wx.ID_ANY,
+        self.manage_box = wx.StaticBox (parent=self.panel, id=wx.ID_ANY,
                                         label=" %s " % _("Manage"))
-        self.lwelcome = wx.StaticText(parent=self, id=wx.ID_ANY,
+        self.lwelcome = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
                                       label=_("Welcome to GRASS GIS %s\n"
                                               "The world's leading open source GIS") % grassVersion,
                                       style=wx.ALIGN_CENTRE)
         #self.SetFont(wx.Font(pointSize=9, family=wx.FONTFAMILY_DEFAULT,
         #                     style=wx.NORMAL, weight=wx.NORMAL))
-        self.ltitle = wx.StaticText(parent=self, id=wx.ID_ANY,
+        self.ltitle = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
                                     label=_("Select an existing project location and mapset\n"
                                             "or define a new location"),
                                     style=wx.ALIGN_CENTRE)
-        self.ldbase = wx.StaticText(parent=self, id=wx.ID_ANY,
+        self.ldbase = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
                                     label=_("GIS Data Directory:"))
-        self.llocation = wx.StaticText(parent=self, id=wx.ID_ANY,
+        self.llocation = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
                                        label=_("Project location\n(projection/coordinate system)"),
                                        style=wx.ALIGN_CENTRE)
-        self.lmapset = wx.StaticText(parent=self, id=wx.ID_ANY,
+        self.lmapset = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
                                      label=_("Accessible mapsets\n(directories of GIS files)"),
                                      style=wx.ALIGN_CENTRE)
-        self.lcreate = wx.StaticText(parent=self, id=wx.ID_ANY,
+        self.lcreate = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
                                      label=_("Create new mapset\nin selected location"),
                                      style=wx.ALIGN_CENTRE)
-        self.ldefine = wx.StaticText(parent=self, id=wx.ID_ANY,
+        self.ldefine = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
                                      label=_("Define new location"),
                                      style=wx.ALIGN_CENTRE)
-        self.lmanageloc = wx.StaticText(parent=self, id=wx.ID_ANY,
+        self.lmanageloc = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
                                         label=_("Rename/delete selected\nmapset or location"),
                                         style=wx.ALIGN_CENTRE)
 
         # buttons
-        self.bstart = wx.Button(parent=self, id=wx.ID_ANY,
+        self.bstart = wx.Button(parent=self.panel, id=wx.ID_ANY,
                                 label=_("Start GRASS"), size=(180, -1))
         self.bstart.SetDefault()
-        self.bexit = wx.Button(parent=self, id=wx.ID_EXIT)
-        self.bhelp = wx.Button(parent=self, id=wx.ID_HELP)
-        self.bbrowse = wx.Button(parent=self, id=wx.ID_ANY,
+        self.bexit = wx.Button(parent=self.panel, id=wx.ID_EXIT)
+        self.bhelp = wx.Button(parent=self.panel, id=wx.ID_HELP)
+        self.bbrowse = wx.Button(parent=self.panel, id=wx.ID_ANY,
                                  label=_("Browse"))
-        self.bmapset = wx.Button(parent=self, id=wx.ID_ANY,
+        self.bmapset = wx.Button(parent=self.panel, id=wx.ID_ANY,
                                  label=_("Create mapset"))
-        self.bwizard = wx.Button(parent=self, id=wx.ID_ANY,
+        self.bwizard = wx.Button(parent=self.panel, id=wx.ID_ANY,
                                  label=_("Location wizard"))
-        self.manageloc = wx.Choice(parent=self, id=wx.ID_ANY,
+        self.manageloc = wx.Choice(parent=self.panel, id=wx.ID_ANY,
                                    choices=['Rename mapset','Rename location',
                                             'Delete mapset', 'Delete location'])
+	self.manageloc.SetSelection(0)
 
         # textinputs
-        self.tgisdbase = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(300, -1),
+        self.tgisdbase = wx.TextCtrl(parent=self.panel, id=wx.ID_ANY, value="", size=(300, -1),
                                      style=wx.TE_LEFT)
 
         # TODO: sort list, but keep mapsets aligned to sorted locations
         # Locations
-        self.lpanel = wx.Panel(parent=self,id=wx.ID_ANY)
+        self.lpanel = wx.Panel(parent=self.panel, id=wx.ID_ANY)
         self.lblocations = wx.ListBox(parent=self.lpanel,
                                       id=wx.ID_ANY, size=(180, 200),
                                       choices=self.listOfLocations,
@@ -136,7 +145,7 @@
 
         # TODO: sort; but keep PERMANENT on top of list
         # Mapsets
-        self.mpanel = wx.Panel(parent=self,id=wx.ID_ANY)
+        self.mpanel = wx.Panel(parent=self.panel, id=wx.ID_ANY)
         self.lbmapsets = wx.ListBox(parent=self.mpanel,
                                     id=wx.ID_ANY, size=(150, 200),
                                     choices=self.listOfMapsets,
@@ -162,8 +171,8 @@
     def _set_properties(self):
         """Set frame properties"""
         self.SetTitle(_("Welcome to GRASS GIS"))
-        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, "dm", "grass.gif"),
-                             wx.BITMAP_TYPE_GIF))
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, "grass.ico"),
+                             wx.BITMAP_TYPE_ICO))
 
         self.lwelcome.SetForegroundColour(wx.Colour(35, 142, 35))
         self.lwelcome.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
@@ -298,7 +307,7 @@
                   flag=wx.ADJUST_MINSIZE |
                   wx.ALIGN_CENTER_VERTICAL |
                   wx.ALIGN_CENTER_HORIZONTAL |
-                  wx.BOTTOM | wx.TOP,
+                  wx.ALL,
                   border=5) # image
         sizer.Add(item=self.lwelcome, # welcome message
                   proportion=0,
@@ -334,10 +343,11 @@
                   wx.RIGHT | wx.LEFT,
                   border=5)
 
-        self.SetAutoLayout(True)
-        self.SetSizer(sizer)
-        sizer.Fit(self)
+        self.panel.SetAutoLayout(True)
+        self.panel.SetSizer(sizer)
+        sizer.Fit(self.panel)
         sizer.SetSizeHints(self)
+
         self.Layout()
 
     def _read_grassrc(self):
@@ -353,7 +363,7 @@
             try:
                 rc = open(gisrc, "r")
                 for line in rc.readlines():
-                    key, val = line.split(":")
+                    key, val = line.split(":", 1)
                     grassrc[key.strip()] = val.strip()
             finally:
                 rc.close()
@@ -451,10 +461,11 @@
         location = self.listOfLocations[self.lblocations.GetSelection()]
         mapset   = self.listOfMapsets[self.lbmapsets.GetSelection()]
 
-        dlg = wx.MessageDialog(parent=self, message=_("Do you want to continue with deleting mapset <%s> "
-                                                      "from location <%s>?\n\n"
+        dlg = wx.MessageDialog(parent=self, message=_("Do you want to continue with deleting mapset <%(mapset)s> "
+                                                      "from location <%(location)s>?\n\n"
                                                       "ALL MAPS included in this mapset will be "
-                                                      "PERMANENTLY DELETED!") % (mapset, location),
+                                                      "PERMANENTLY DELETED!") % {'mapset' : mapset,
+                                                                                 'location' : location},
                                caption=_("Delete selected mapset"),
                                style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
 
@@ -504,9 +515,9 @@
                     self.listOfLocations.append(os.path.basename(location))
             except:
                 pass
-            
-        self.listOfLocations.sort(cmp=lambda x,y: cmp(x.lower(), y.lower()))
 
+        utils.ListSortLower(self.listOfLocations)
+
         self.lblocations.Clear()
         self.lblocations.InsertItems(self.listOfLocations, 0)
 
@@ -520,7 +531,7 @@
             if os.path.isdir(mapset) and os.path.basename(mapset) != 'PERMANENT':
                 self.listOfMapsets.append(os.path.basename(mapset))
         
-        self.listOfMapsets.sort(cmp=lambda x,y: cmp(x.lower(), y.lower()))
+        utils.ListSortLower(self.listOfMapsets)
         self.listOfMapsets.insert(0,'PERMANENT')
  
         self.lbmapsets.Clear()

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/__init__.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/__init__.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/__init__.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -21,4 +21,5 @@
         "toolbox",
         "track",
         "utils",
+        "workspace",
         "wxgui_utils" ]

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/dbm.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/dbm.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/dbm.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -37,10 +37,13 @@
 import locale
 import tempfile
 
+### i18N
+import gettext
+gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
+
 import wx
 import wx.lib.mixins.listctrl as listmix
 import wx.lib.flatnotebook as FN
-import wx.lib.colourselect as csel
 import wx.lib.scrolledpanel as scrolled
 
 import sqlbuilder
@@ -49,6 +52,7 @@
 import globalvar
 import utils
 from debug import Debug as Debug
+from preferences import globalSettings as UserSettings
 
 class Log:
     """
@@ -160,7 +164,11 @@
         if len(self.itemCatsMap) > 0:
             keyId = -1
         else:
-            keyId = columnNames.index(keyColumn)
+            try:
+                # for maps connected via v.external
+                keyId = columnNames.index(keyColumn)
+            except:
+                keyId = -1
 
         i = 0
         info = wx.ListItem()
@@ -173,7 +181,7 @@
             i += 1
 
             if i >= 256:
-                self.log.write(_("Can display only 256 columns"))
+                self.log.write(_("Can display only 256 columns."))
 
         ### self.mapDBInfo.SelectFromTable(layer, cols, where) # <- values (FIXME)
         #
@@ -197,7 +205,8 @@
         i = 0
         outFile.seek(0)
         while True:
-            record = outFile.readline().replace(os.linesep, '')
+            # os.linesep doesn't work here (MSYS)
+            record = outFile.readline().replace('\n', '')
             if not record:
                 break
             self.itemDataMap[i] = []
@@ -226,7 +235,7 @@
 
             i += 1
             if i >= 100000:
-                print >> sys.stderr, _("Limit 100000 records")
+                self.log.write(_("Limit 100000 records."))
                 break
 
         self.SetItemCount(i)
@@ -356,8 +365,13 @@
         self.pointdata = pointdata
         self.parent    = parent # GMFrame
 
-        wx.Frame.__init__(self, parent, id, title, size=(900,600), style=style)
+        wx.Frame.__init__(self, parent, id, title, style=style)
 
+        # icon
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, 'grass_sql.ico'), wx.BITMAP_TYPE_ICO))
+
+        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
+
         try:
             self.map        = self.parent.curr_page.maptree.Map
             self.mapdisplay = self.parent.curr_page.maptree.mapdisplay
@@ -386,19 +400,11 @@
                           message=_("Database connection for vector map <%s> "
                                     "is not defined in DB file. "
                                     "You can define new connection in "
-                                    "'Manage layers'.") % self.vectmap,
+                                    "'Manage layers' tab.") % self.vectmap,
                           caption=_("Attribute Table Manager"),
                           style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
 
         #
-        # default settings (TODO global settings file)
-        #
-        self.settings = {}
-        self.settings['highlight'] = {}
-        self.settings['highlight']['color'] = (255, 255, 0, 255) # yellow
-        self.settings['highlight']['width'] = 2
-
-        #
         # list of command/SQL statements to be performed
         #
         self.listOfCommands      = []
@@ -416,52 +422,45 @@
         # really needed (ML)
         # self.notebook.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, ''))
 
-        self.notebook = FN.FlatNotebook(parent=self, id=wx.ID_ANY,
+        self.notebook = FN.FlatNotebook(parent=self.panel, id=wx.ID_ANY,
                                         style=FN.FNB_BOTTOM |
                                         FN.FNB_NO_NAV_BUTTONS |
                                         FN.FNB_FANCY_TABS)
 
         dbmStyle = globalvar.FNPageStyle
 
-        self.browsePage = FN.FlatNotebook(self, id=wx.ID_ANY,
+        self.browsePage = FN.FlatNotebook(self.panel, id=wx.ID_ANY,
                                           style=dbmStyle)
         # self.notebook.AddPage(self.browsePage, caption=_("Browse data"))
         self.notebook.AddPage(self.browsePage, text=_("Browse data")) # FN
         self.browsePage.SetTabAreaColour(globalvar.FNPageColor)
 
-        self.manageTablePage = FN.FlatNotebook(self, id=wx.ID_ANY,
+        self.manageTablePage = FN.FlatNotebook(self.panel, id=wx.ID_ANY,
                                           style=dbmStyle)
         #self.notebook.AddPage(self.manageTablePage, caption=_("Manage tables"))
         self.notebook.AddPage(self.manageTablePage, text=_("Manage tables")) # FN
         self.manageTablePage.SetTabAreaColour(globalvar.FNPageColor)
 
-        self.manageLayerPage = FN.FlatNotebook(self, id=wx.ID_ANY,
+        self.manageLayerPage = FN.FlatNotebook(self.panel, id=wx.ID_ANY,
                                                style=dbmStyle)
         #self.notebook.AddPage(self.manageLayerPage, caption=_("Manage layers"))
         self.notebook.AddPage(self.manageLayerPage, text=_("Manage layers")) # FN
         self.manageLayerPage.SetTabAreaColour(globalvar.FNPageColor)
 
-        self.settingsPage = FN.FlatNotebook(self, id=wx.ID_ANY,
-                                            style=dbmStyle)
-        #self.notebook.AddPage(self.settingsPage, caption=_("Settings"))
-        self.notebook.AddPage(self.settingsPage, text=_("Settings")) # FN
-        self.settingsPage.SetTabAreaColour(globalvar.FNPageColor)
-
         self.infoCollapseLabelExp = _("Click here to show database connection information")
         self.infoCollapseLabelCol = _("Click here to hide database connection information")
 
         self.__createBrowsePage()
         self.__createManageTablePage()
         self.__createManageLayerPage()
-        self.__createSettingsPage()
 
         self.notebook.SetSelection(0) # select browse tab
 
         #
         # buttons
         #
-        self.btnApply      = wx.Button(parent=self, id=wx.ID_APPLY)
-        self.btnQuit       = wx.Button(parent=self, id=wx.ID_EXIT)
+        self.btnApply      = wx.Button(parent=self.panel, id=wx.ID_APPLY)
+        self.btnQuit       = wx.Button(parent=self.panel, id=wx.ID_EXIT)
         # self.btn_unselect = wx.Button(self, -1, "Unselect")
 
         # events
@@ -474,15 +473,9 @@
         self.__layout()
 
         # self.SetMinSize(self.GetBestSize())
-        self.SetSize((680, 520))
+        self.SetSize((680, 550)) # FIXME hard-coded size
         self.SetMinSize(self.GetSize())
 
-    def __del__(self):
-        pass
-        #         if self.qlayer and self.map:
-        #             self.map.DeleteLayer(self.qlayer)
-        #             self.mapdisplay.ReRender(None)
-
     def __createBrowsePage(self, onlyLayer=-1):
         """Create browse tab page"""
         for layer in self.mapDBInfo.layers.keys():
@@ -492,7 +485,7 @@
             panel = wx.Panel(parent=self.browsePage, id=wx.ID_ANY)
             self.layerPage[layer] = {'browsePage': panel.GetId()}
 
-            self.browsePage.AddPage(page=panel, text=_(" %s %d ") % (_("Layer"), layer))
+            self.browsePage.AddPage(page=panel, text=" %s %d " % (_("Layer"), layer))
 
             pageSizer = wx.BoxSizer(wx.VERTICAL)
 
@@ -533,7 +526,14 @@
             win.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnDataItemActivated)
             win.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnDataRightUp) #wxMSW
             win.Bind(wx.EVT_RIGHT_UP,            self.OnDataRightUp) #wxGTK
-
+            if UserSettings.Get(group='atm', key='leftDbClick', subkey='selection') == 0:
+                win.Bind(wx.EVT_LEFT_DCLICK, self.OnDataItemEdit)
+                win.Bind(wx.EVT_COMMAND_LEFT_DCLICK, self.OnDataItemEdit)
+            else:
+                win.Bind(wx.EVT_LEFT_DCLICK, self.OnDataDrawSelected)
+                win.Bind(wx.EVT_COMMAND_LEFT_DCLICK, self.OnDataDrawSelected)
+                
+            
             listSizer.Add(item=win, proportion=1,
                           flag=wx.EXPAND | wx.ALL,
                           border=3)
@@ -632,7 +632,7 @@
 
             panel = wx.Panel(parent=self.manageTablePage, id=wx.ID_ANY)
             self.layerPage[layer]['tablePage'] = panel.GetId()
-            self.manageTablePage.AddPage(page=panel, text=_(" %s %d ") % (_("Layer"), layer))
+            self.manageTablePage.AddPage(page=panel, text=" %s %d " % (_("Layer"), layer))
 
             pageSizer = wx.BoxSizer(wx.VERTICAL)
 
@@ -682,13 +682,14 @@
                                          "double",
                                          "varchar",
                                          "date"]) # FIXME
+            type.SetSelection(0)
             type.Bind(wx.EVT_CHOICE, self.OnTableChangeType)
             self.layerPage[layer]['addColType'] = type.GetId()
             subSizer.Add(item=type,
                          flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
                          border=3)
             # length
-            label  = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Length"))
+            label  = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Data length"))
             length = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
                                  initial=250,
                                  min=1, max=1e6)
@@ -705,7 +706,7 @@
                          flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
                          border=3)
 
-            btnAddCol = wx.Button(parent=panel, id=wx.ID_ANY, label=_('&Add'))
+            btnAddCol = wx.Button(parent=panel, id=wx.ID_ADD)
             btnAddCol.Bind(wx.EVT_BUTTON, self.OnTableItemAdd)
             btnAddCol.Enable(False)
             self.layerPage[layer]['addColButton'] = btnAddCol.GetId()
@@ -788,7 +789,7 @@
         return list
 
     def __createManageLayerPage(self):
-        """Create settings page"""
+        """Create manage page"""
         splitterWin = wx.SplitterWindow(parent=self.manageLayerPage, id=wx.ID_ANY)
         self.manageLayerPage.AddPage(page=splitterWin,
                                      text=_("Layers of vector map")) # dummy page
@@ -850,45 +851,6 @@
 
         return list
 
-    def __createSettingsPage(self):
-        """Create settings page"""
-        panel = wx.Panel(parent=self.settingsPage, id=wx.ID_ANY)
-        self.settingsPage.AddPage(page=panel, text=_("General settings")) # dummy page
-
-        pageSizer = wx.BoxSizer(wx.VERTICAL)
-        highlightBox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
-                                    label=" %s " % _("Highlighting"))
-        highlightSizer = wx.StaticBoxSizer(highlightBox, wx.VERTICAL)
-
-        flexSizer = wx.FlexGridSizer (cols=2, hgap=5, vgap=5)
-        flexSizer.AddGrowableCol(0)
-        label = wx.StaticText(parent=panel, id=wx.ID_ANY, label="Color")
-        self.hlColor = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
-                                          colour=self.settings['highlight']['color'],
-                                          size=(25, 25))
-        flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(self.hlColor, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
-
-        label = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Line width (in pixels)"))
-        self.hlWidth = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(50, -1),
-                                   initial=self.settings['highlight']['width'],
-                                   min=1, max=1e6)
-        flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(self.hlWidth, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
-
-
-        highlightSizer.Add(item=flexSizer,
-                           proportion=0,
-                           flag=wx.ALL | wx.EXPAND,
-                           border=5)
-
-        pageSizer.Add(item=highlightSizer,
-                      proportion=0,
-                      flag=wx.ALL | wx.EXPAND,
-                      border=5)
-
-        panel.SetSizer(pageSizer)
-
     def __layout(self):
         """Do layout"""
         # frame body
@@ -904,10 +866,9 @@
         mainSizer.Add(item=self.notebook, proportion=1, flag=wx.EXPAND)
         mainSizer.Add(item=btnSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
 
-        self.SetAutoLayout(True)
-        self.SetSizer(mainSizer)
-        # FIXME
-        # mainSizer.Fit(self) # problem connected to aui
+        self.panel.SetAutoLayout(True)
+        self.panel.SetSizer(mainSizer)
+        mainSizer.Fit(self.panel)
         self.Layout()
         
     def OnDataRightUp(self, event):
@@ -1038,16 +999,20 @@
             missingKey = False
             
         # add other visible columns
+        colIdx = 0
+        keyId = -1
         for col in columnName:
             if col == keyColumn: # key 
                 if missingKey is False: 
                     data.append((col, str(maxCat + 1)))
+                    keyId = colIdx
             else:
                 data.append((col, ''))
-
+            colIdx += 1
+                
         dlg = ModifyTableRecord(parent=self, id=wx.ID_ANY,
                                 title=_("Insert new record"),
-                                data=data)
+                                data=data, keyEditable=(keyId, True))
 
         if dlg.ShowModal() == wx.ID_OK:
             try: # get category number
@@ -1063,7 +1028,7 @@
                 values = dlg.GetValues() # values (need to be casted)
                 columnsString = ''
                 valuesString   = ''
-                
+
                 for i in range(len(values)):
                     if len(values[i]) == 0: # NULL
                         if columnName[i] == keyColumn:
@@ -1075,9 +1040,9 @@
                     try:
                         values[i] = list.columns[columnName[i]]['ctype'] (values[i])
                     except:
-                        raise ValueError(_("Casting value '%s' to %s failed.") % \
-                                             (str(values[i]),
-                                              list.columns[columnName[i]]['type']))
+                        raise ValueError(_("Casting value '%(value)s' to %(type)s failed.") % 
+                                         {'value' : str(values[i]),
+                                          'type' : list.columns[columnName[i]]['type']})
                     columnsString += '%s,' % columnName[i]
                     if list.columns[columnName[i]]['ctype'] == str:
                         valuesString += "'%s'," % values[i]
@@ -1086,8 +1051,8 @@
 
             except ValueError, err:
                 wx.MessageBox(parent=self,
-                              message=_("Unable to insert new record.%s"
-                                        "%s") % (os.linesep, err),
+                              message="%s%s%s" % (_("Unable to insert new record."),
+                                                    os.linesep, err),
                               caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
                 return
 
@@ -1172,9 +1137,9 @@
                                 list.itemDataMap[item][idx] = \
                                     list.columns[columnName[i]]['ctype'] (values[i])
                             except:
-                                raise ValueError(_("Casting value '%s' to %s failed.") % \
-                                                     (str(values[i]),
-                                                      list.columns[columnName[i]]['type']))
+                                raise ValueError(_("Casting value '%(value)s' to %(type)s failed.") % \
+                                                     {'value' : str(values[i]),
+                                                      'type' : list.columns[columnName[i]]['type']})
 
                             if list.columns[columnName[i]]['ctype'] == str:
                                 updateString += "%s='%s'," % (columnName[i], values[i])
@@ -1185,8 +1150,8 @@
 
             except ValueError, err:
                 wx.MessageBox(parent=self,
-                              message=_("Unable to update existing record.%s"
-                                        "%s") % (os.linesep, err),
+                              message="%s%s%s" % (_("Unable to update existing record."),
+                                                  os.linesep, err),
                               caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
                 return
 
@@ -1273,9 +1238,10 @@
             if item > -1:
                 if list.FindItem(start=-1, str=nameTo) > -1:
                     wx.MessageBox(parent=self,
-                                  message=_("Unable to rename column <%s>. "
-                                            "Column <%s> already exists in the table <%s>.") % \
-                                  (name, nameTo, self.mapDBInfo.layers[self.layer]["table"]),
+                                  message=_("Unable to rename column <%(column)s>. "
+                                            "Column <%(columnTo)s> already exists in the table <%(table)s>.") % \
+                                      {'column' : name, 'columnTo' : nameTo,
+                                       'table' : self.mapDBInfo.layers[self.layer]["table"]},
                                   caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
                 else:
                     list.SetItemText(item, nameTo)
@@ -1287,8 +1253,8 @@
             else:
                 wx.MessageBox(parent=self,
                               message=_("Unable to rename column. "
-                                        "Column <%s> doesn't exist in the table <%s>.") % \
-                                  (name, self.mapDBInfo.layers[self.layer]["table"]),
+                                        "Column <%(column)s> doesn't exist in the table <%(table)s>.") % 
+                              {'column' : name, 'table' : self.mapDBInfo.layers[self.layer]["table"]},
                               caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
 
         event.Skip()
@@ -1372,8 +1338,8 @@
             # check for duplicate items
             if list.FindItem(start=-1, str=name) > -1:
                 wx.MessageBox(parent=self,
-                              message=_("Column <%s> already exists in table <%s>.") % \
-                                  (name, self.mapDBInfo.layers[self.layer]["table"]),
+                              message=_("Column <%(column)s> already exists in table <%(table)s>.") % \
+                                  {'column' : name, 'table' : self.mapDBInfo.layers[self.layer]["table"]},
                               caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
                 return
             index = list.InsertStringItem(sys.maxint, str(name))
@@ -1471,9 +1437,6 @@
         # perform select statement
         self.OnApplySqlStatement(event)
 
-        # update settings
-        self.UpdateSettings()
-
     def OnApplySqlStatement(self, event):
         """Apply simple/advanced sql statement"""
         keyColumn = -1 # index of key column
@@ -1634,10 +1597,9 @@
             map.DeleteLayer(self.qlayer)
 
         list = self.FindWindowById(self.layerPage[self.layer]['data'])
-        # cats = list.selectedCats[:]
         cats = list.GetSelectedItems()
 
-        color = self.settings['highlight']['color']
+        color = UserSettings.Get(group='atm', key='highlight', subkey='color')
         colorStr = str(color[0]) + ":" + \
             str(color[1]) + ":" + \
             str(color[2]) + ":"
@@ -1645,10 +1607,8 @@
                "map=%s" % self.vectmap,
                "color=%s" % colorStr,
                "fcolor=%s" % colorStr,
-               #               "cats=%s" % (",".join(["%d" % c for c in cats])),
-               # FIXME
                "cats=%s" % utils.ListOfCatsToRange(cats),
-               "width=%d"  % self.settings['highlight']['width']]
+               "width=%d"  % UserSettings.Get(group='atm', key='highlight', subkey='width')]
         if self.icon:
             cmd.append("icon=%s" % (self.icon))
         if self.pointsize:
@@ -1698,11 +1658,6 @@
 
         return False
                 
-    def UpdateSettings(self):
-        """Update settings dict"""
-        self.settings['highlight']['color'] = self.hlColor.GetColour()
-        self.settings['highlight']['width'] = int(self.hlWidth.GetValue())
-
     def UpdateDialog(self, layer):
         """Updates dialog layout for given layer"""
         #
@@ -1883,7 +1838,7 @@
         itemData = {} # requested by sorter
 
         if not update:
-            headings = [_("Column name"), _("Type"), _("Length")]
+            headings = [_("Column name"), _("Data type"), _("Data length")]
             i = 0
             for h in headings:
                 self.InsertColumn(col=i, heading=h)
@@ -2009,6 +1964,11 @@
             elif item == 'database':
                 self.defaultDatabase = value
 
+        if len(self.defaultDriver) == 0 or \
+               len(self.defaultDatabase) == 0:
+            raise gcmd.DBMError(_('Unable to determine default DB connection settings. '
+                                  'Please define DB connection using db.connect module.'))
+        
         self.defaultTables = self.__getTables(self.defaultDriver, self.defaultDatabase)
         try:
             self.defaultColumns = self.__getColumns(self.defaultDriver, self.defaultDatabase,
@@ -2023,7 +1983,7 @@
     def __createAddPage(self):
         """Add new layer"""
         self.addPanel = wx.Panel(parent=self, id=wx.ID_ANY)
-        self.AddPage(page=self.addPanel, text=_("Add new layer"))
+        self.AddPage(page=self.addPanel, text=_("Add layer"))
 
         try:
             maxLayer = max(self.mapDBInfo.layers.keys())
@@ -2454,9 +2414,8 @@
         
         if not table or not key:
             wx.MessageBox(parent=self,
-                          message=_("Unable to create new table.%s"
-                                    "Table name or key column name is missing.") % \
-                          (os.linesep),
+                          message=_("Unable to create new table. "
+                                    "Table name or key column name is missing."),
                           caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
             return
         
@@ -2492,9 +2451,9 @@
         
         if layer in self.mapDBInfo.layers.keys():
             wx.MessageBox(parent=self,
-                          message=_("Unable to add new layer to vector map <%s>.%s"
-                                    "Layer %d already exists.") % \
-                          (self.mapDBInfo.map, os.linesep, layer),
+                          message=_("Unable to add new layer to vector map <%(vector)s>. "
+                                    "Layer %(layer)d already exists.") % 
+                          {'vector' : self.mapDBInfo.map, 'layer' : layer},
                           caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
             return
 
@@ -2674,11 +2633,11 @@
 
             wx.MessageBox(parent=self.parent,
                           message=_("No attribute table linked to "
-                                    "vector map <%s> found. %s "
-                                    "%sYou can disable this message from digitization settings. Or "
+                                    "vector map <%(vector)s> found. %(msg)s"
+                                    "\nYou can disable this message from digitization settings. Or "
                                     "you can create and link attribute table to the vector map "
-                                    "using Attribute Table Manager.") % \
-                              (self.map, label, os.linesep),
+                                    "using Attribute Table Manager.") % 
+                          {'vector' : self.map, 'msg' : label},
                           caption=_("Message"), style=wx.OK | wx.ICON_EXCLAMATION | wx.CENTRE)
             self.mapDBInfo = None
             return
@@ -2912,7 +2871,7 @@
                                            size=(-1, 150))
             panel.SetupScrolling(scroll_x=False)
             
-            self.notebook.AddPage(page=panel, text=_(" %s %d ") % (_("Layer"), layer))
+            self.notebook.AddPage(page=panel, text=" %s %d " % (_("Layer"), layer))
             
             # notebook body
             border = wx.BoxSizer(wx.VERTICAL)
@@ -3168,41 +3127,68 @@
         """
         wx.Dialog.__init__(self, parent, id, title, style=style)
 
-        self.panel = scrolled.ScrolledPanel(parent=self, id=wx.ID_ANY,
+        self.keyId = keyEditable[0]
+        
+        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
+
+        self.dataPanel = scrolled.ScrolledPanel(parent=self.panel, id=wx.ID_ANY,
                                             style=wx.TAB_TRAVERSAL)
+        self.dataPanel.SetupScrolling(scroll_x=False)
         
-        self.btnCancel = wx.Button(self, wx.ID_CANCEL)
-        self.btnSubmit = wx.Button(self, wx.ID_OK)
+        #
+        # buttons
+        #
+        self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
+        self.btnSubmit = wx.Button(self.panel, wx.ID_OK)
         self.btnSubmit.SetDefault()
 
+        #
+        # data area
+        #
         self.widgets = []
         id = 0
+        self.box = False
+        self.cat = None
         for column, value in data:
-            label = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
+            if keyEditable[0] == id:
+                self.cat = int(value)
+                if keyEditable[1] == False:
+                    self.box = True
+                    id += 1
+                    continue
+                else:
+                    valueWin = wx.SpinCtrl(parent=self.dataPanel, id=wx.ID_ANY,
+                                           value=value, min=-1e9, max=1e9, size=(250, -1))
+            else:
+                valueWin = wx.TextCtrl(parent=self.dataPanel, id=wx.ID_ANY,
+                                       value=value, size=(250, -1))
+                                
+            label = wx.StaticText(parent=self.dataPanel, id=wx.ID_ANY,
                                   label=column + ":")
-            value = wx.TextCtrl(parent=self.panel, id=wx.ID_ANY,
-                                value=value, size=(250, -1))
-            if keyEditable[0] > -1: # id given
-                if keyEditable[0] == id:
-                    value.Enable(keyEditable[1])
+
             self.widgets.append((label.GetId(),
-                                 value.GetId()))
+                                 valueWin.GetId()))
 
             id += 1
             
         self.__Layout()
 
-        winSize = self.GetSize()
+        # winSize = self.GetSize()
         # fix height of window frame if needed
-        if winSize[1] > 480:
-            winSize[1] = 480
-            self.SetSize(winSize)
-        self.SetMinSize(winSize)
+        # if winSize[1] > 480:
+        #    winSize[1] = 480
+        #    self.SetSize(winSize)
+        # self.SetMinSize(winSize)
 
     def __Layout(self):
         """Do layout"""
         sizer = wx.BoxSizer(wx.VERTICAL)
 
+        if self.box:
+            box = wx.StaticBox(parent=self.panel, id=wx.ID_ANY,
+                               label=" %s %d " % (_("Category"), self.cat))
+            boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
         # data area
         dataSizer = wx.FlexGridSizer (cols=2, hgap=3, vgap=3)
         dataSizer.AddGrowableCol(1)
@@ -3214,29 +3200,55 @@
             dataSizer.Add(label, proportion=0,
                           flag=wx.ALIGN_CENTER_VERTICAL)
             dataSizer.Add(value, proportion=0,
-                          flag=wx.EXPAND)
+                          flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
 
-        self.panel.SetSizer(dataSizer)
-        self.panel.SetAutoLayout(1)
-        self.panel.SetupScrolling(scroll_x=False)
+        self.dataPanel.SetAutoLayout(True)
+        self.dataPanel.SetSizer(dataSizer)
+        dataSizer.Fit(self.dataPanel)
 
+        if self.box:
+            boxSizer.Add(item=self.dataPanel, proportion=1,
+                         flag=wx.EXPAND | wx.ALL, border=5)
+            
         # buttons
         btnSizer = wx.StdDialogButtonSizer()
         btnSizer.AddButton(self.btnCancel)
         btnSizer.AddButton(self.btnSubmit)
         btnSizer.Realize()
 
-        sizer.Add(item=self.panel, proportion=1,
-                  flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+        if not self.box:
+            sizer.Add(item=self.dataPanel, proportion=1,
+                      flag=wx.EXPAND | wx.ALL, border=5)
+        else:
+            sizer.Add(item=boxSizer, proportion=1,
+                      flag=wx.EXPAND | wx.ALL, border=5)
+            
 
         sizer.Add(item=btnSizer, proportion=0,
-                  flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+                 flag=wx.EXPAND | wx.ALL, border=5)
 
-        self.SetSizer(sizer)
-        self.SetAutoLayout(1)
+        #sizer.SetSizeHints(self.panel)
+        self.panel.SetAutoLayout(True)
+        self.panel.SetSizer(sizer)
+        sizer.Fit(self.panel)
 
+        self.Layout()
+
+        # set window frame size (min & max)
+        minFrameHeight = 150
+        maxFrameHeight = 2 * minFrameHeight
+        if self.GetSize()[1] > minFrameHeight:
+            self.SetMinSize((self.GetSize()[0], minFrameHeight))
+        else:
+            self.SetMinSize(self.GetSize())
+
+        if self.GetSize()[1] > maxFrameHeight:
+            self.SetSize((self.GetSize()[0], maxFrameHeight))
+        else:
+            self.SetSize(self.panel.GetSize())
+            
     def GetValues(self, columns=None):
-        """Return list of values (as string).
+        """Return list of values (casted to string).
 
         If columns is given (list), return only values of given columns.
         """
@@ -3244,9 +3256,13 @@
         for labelId, valueId in self.widgets:
             column = self.FindWindowById(labelId).GetLabel().replace(':', '')
             if columns is None or column in columns:
-                value = self.FindWindowById(valueId).GetValue()
+                value = str(self.FindWindowById(valueId).GetValue()) # -> string
                 valueList.append(value)
 
+        # add key value
+        if self.box:
+            valueList.insert(self.keyId, str(self.cat))
+                             
         return valueList
 
 class NewVectorDialog(wx.Dialog):
@@ -3264,12 +3280,13 @@
         self.btnOK.Enable(False)
 
         self.label = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
-                                   label=_("Name for new vector map layer:"))
+                                   label=_("Name for new vector map:"))
         self.mapName = wx.TextCtrl(parent=self.panel, id=wx.ID_ANY,
                                    value='', size=(250, -1),
                                    style=wx.TE_PROCESS_ENTER)
         self.mapName.Bind(wx.EVT_TEXT, self.OnMapName)
 
+        # TODO remove (see Preferences dialog)
         self.overwrite = wx.CheckBox(parent=self.panel, id=wx.ID_ANY,
                                      label=_("Allow output files to overwrite existing files"))
 
@@ -3333,8 +3350,8 @@
 
     app = wx.PySimpleApp()
     f = AttributeManager(parent=None, id=wx.ID_ANY,
-                         title=_("GRASS GIS Attribute Table Manager - vector map layer <%s>") % \
-                             argv[1],
+                         title="%s - <%s>" % (_("GRASS GIS Attribute Table Manager"),
+                                              argv[1]),
                          size=(900,600), vectmap=argv[1])
     f.Show()
 

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/digit.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/digit.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/digit.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -52,14 +52,16 @@
     sys.path.append(digitPath)
     import grass6_wxvdigit as vdigit
     GV_LINES = vdigit.GV_LINES
+    digitErr = ''
 except ImportError, err:
     GV_LINES = None
-#    print >> sys.stderr, "%sWARNING: Digitization tool is disabled (%s). " \
-#          "Detailed information in README file." % \
-#          (os.linesep, err)
+    digitErr = err
+    #    print >> sys.stderr, "%sWARNING: Digitization tool is disabled (%s). " \
+    #          "Detailed information in README file." % \
+    #          (os.linesep, err)
 
 # which interface to use?
-if UserSettings.Get('digitInterface') == 'vedit' and GV_LINES is not None:
+if UserSettings.Get(group='advanced', key='digitInterface', subkey='type') == 'vedit' and GV_LINES is not None:
     print >> sys.stderr, "%sWARNING: Digitization tool uses v.edit interface. " \
         "This can significantly slow down some operations especially for " \
         "middle-large vector maps. "\
@@ -71,7 +73,7 @@
     """
     Abstract digitization class
     """
-    def __init__(self, mapwindow, settings=None):
+    def __init__(self, mapwindow):
         """Initialization
 
         @param mapwindow reference to mapwindow (MapFrame) instance
@@ -84,54 +86,6 @@
 
         #self.SetCategory()
 
-        # is unique for map window instance
-        if not settings:
-            self.settings = {}
-            # symbology
-            # self.settings["symbolBackground"] = (None, (255,255,255, 255)) # white
-            self.settings["symbolHighlight"] = (None, (255, 255, 0, 255)) #yellow
-            self.settings["symbolPoint"] = (True, (0, 0, 0, 255)) # black
-            self.settings["symbolLine"] = (True, (0, 0, 0, 255)) # black
-            self.settings["symbolBoundaryNo"] = (True, (126, 126, 126, 255)) # grey
-            self.settings["symbolBoundaryOne"] = (True, (0, 255, 0, 255)) # green
-            self.settings["symbolBoundaryTwo"] = (True, (255, 135, 0, 255)) # orange
-            self.settings["symbolCentroidIn"] = (True, (0, 0, 255, 255)) # blue
-            self.settings["symbolCentroidOut"] = (True, (165, 42, 42, 255)) # brown
-            self.settings["symbolCentroidDup"] = (True, (156, 62, 206, 255)) # violet
-            self.settings["symbolNodeOne"] = (True, (255, 0, 0, 255)) # red
-            self.settings["symbolNodeTwo"] = (True, (0, 86, 45, 255)) # dark green
-            self.settings["symbolVertex"] = (False, (255, 20, 147, 255)) # deep pink
-            
-            # display
-            self.settings["lineWidth"] = (2, "screen pixels")
-
-            # snapping
-            self.settings["snapping"] = (10, "screen pixels") # value, unit
-            self.settings["snapToVertex"] = False
-            self.settings["backgroundMap"] = ''
-
-            # digitize new record
-            self.settings["addRecord"] = True
-            self.settings["layer"] = 1
-            self.settings["category"] = 1
-            self.settings["categoryMode"] = "Next to use"
-            
-            # delete existing feature(s)
-            self.settings["delRecord"] = True
-
-            # query tool
-            self.settings["query"]       = ("length", True)   # name, select by box
-            self.settings["queryLength"] = ("shorter than", 0) # gt or lt, threshold
-            self.settings["queryDangle"] = ("shorter than", 0)
-            # select feature (point, line, centroid, boundary)
-            self.settings["selectFeature"] = {}
-            self.settings["selectFeature"]["point"] = {'id': None, 'val': True}
-            self.settings["selectFeature"]["line"] = {'id': None, 'val': True}
-            self.settings["selectFeature"]["centroid"] = {'id': None, 'val': True}
-            self.settings["selectFeature"]["boundary"] = {'id': None, 'val': True} 
-        else:
-            self.settings = settings
-
         self.driver = CDisplayDriver(self, mapwindow)
 
     def SetCategoryNextToUse(self):
@@ -141,10 +95,10 @@
         @return 'True' on success, 'False' on failure
         """
         # vector map layer without categories, reset to '1'
-        self.settings['category'] = 1
+        UserSettings.Set(group='vdigit', key='category', subkey='value', value=1)
 
         if self.map:
-            if UserSettings.Get('digitInterface') == 'vedit':
+            if UserSettings.Get(group='advanced', key='digitInterface', subkey='type') == 'vedit':
                 categoryCmd = gcmd.Command(cmd=["v.category", "-g", "--q",
                                                 "input=%s" % self.map, 
                                                 "option=report"])
@@ -154,25 +108,26 @@
         
                 for line in categoryCmd.ReadStdOutput():
                     if "all" in line:
-                        if self.settings['layer'] != int(line.split(' ')[0]):
+                        if UserSettings.Get(group='vdigit', key='layer', subkey='value') != int(line.split(' ')[0]):
                             continue
                         try:
                             maxCat = int(line.split(' ')[-1]) + 1
-                            self.settings['category'] = maxCat
+                            UserSettings.Set(group='vdigit', key='category', subkey='value', value=maxCat)
                         except:
                             return False
                         return True
             else:
-                self.settings['category'] = self.digit.GetCategory(self.settings['layer']) + 1
+                UserSettings.Set(group='vdigit', key='category', subkey='value',
+                                  value=self.digit.GetCategory(UserSettings.Get(group='vdigit', key='layer', subkey='value') + 1))
     
     def SetCategory(self):
         """Return category number to use (according Settings)"""
-        if self.settings["categoryMode"] == "No category":
-            self.settings["category"] = 1
-        elif self.settings["categoryMode"] == "Next to use":
+        if UserSettings.Get(group='vdigit', key="categoryMode", subkey='value') == "No category":
+            UserSettings.Set(group='vdigit', key="category", subkey='value', value=1)
+        elif UserSettings.Get(group='vdigit', key="categoryMode", subkey='value') == "Next to use":
             self.SetCategoryNextToUse()
 
-        return self.settings["category"]
+        return UserSettings.Get(group='vdigit', key="category", subkey='value')
 
     def SetMapName(self, map):
         """Set map name
@@ -184,17 +139,21 @@
 
         try:
             ret = self.driver.Reset(self.map)
-        except:
-            raise gcmd.DigitError('Unable to initialize display driver, see README file for more information.')
+        except StandardError, e:
+            raise gcmd.DigitError('Unable to initialize display driver, '
+                                  'see README file for more information.%s%s'
+                                  'Details: %s (%s)' % (os.linesep, os.linesep, e, digitErr))
         
         if map and ret == -1:
-            raise gcmd.DigitError(_('Unable to open vector map <%s> for editing. The vector map is probably broken. '
-                               'Try to run v.build for rebuilding the topology.') % map)
+            raise gcmd.DigitError(_('Unable to open vector map <%s> for editing. '
+                                    'Data are probably corrupted, '
+                                    'try to run v.build for rebuilding the topology.') % map)
         if not map and ret != 0:
-            raise gcmd.DigitError(_('Closing vector map <%s> failed. The vector map is probably broken. '
-                               'Try to run v.build for rebuilding the topology.') % map)
+            raise gcmd.DigitError(_('Unable to open vector map <%s> for editing. '
+                                    'Data are probably corrupted, '
+                                    'try to run v.build for rebuilding the topology.') % map)
             
-        if UserSettings.Get('digitInterface') != 'v.edit':
+        if UserSettings.Get(group='advanced', key='digitInterface', subkey='type') != 'v.edit':
             try:
                 self.digit.InitCats()
             except:
@@ -204,13 +163,13 @@
         """Generic method used for SelectLinesByQuery()
         -- to get threshold value"""
         thresh = 0.0
-        if self.settings['query'][0] == "length":
-            thresh = self.settings['queryLength'][1]
-            if self.settings["queryLength"][0] == "shorter than":
+        if UserSettings.Get(group='vdigit', key='query', subkey='type') == "length":
+            thresh = UserSettings.Get(group='vdigit', key='queryLength', subkey='thresh')
+            if UserSettings.Get(group='vdigit', key="queryLength", subkey='than') == "shorter than":
                 thresh = -1 * thresh
         else:
-            thresh = self.settings['queryDangle'][1]
-            if self.settings["queryDangle"][0] == "shorter than":
+            thresh = UserSettings.Get(group='vdigit', key='queryDangle', subkey='thresh')
+            if UserSettings.Get(group='vdigit', key="queryDangle", subkey='than') == "shorter than":
                 thresh = -1 * thresh
 
         return thresh
@@ -221,28 +180,61 @@
         Used by SelectLinesByBox() and SelectLinesByPoint()"""
 
         type = 0
-        for feature in (('point', vdigit.GV_POINT),
-                        ('line', vdigit.GV_LINE),
-                        ('centroid', vdigit.GV_CENTROID),
-                        ('boundary', vdigit.GV_BOUNDARY)):
-            if self.settings['selectFeature'][feature[0]]['val'] is True:
+        for feature in (('Point', vdigit.GV_POINT),
+                        ('Line', vdigit.GV_LINE),
+                        ('Centroid', vdigit.GV_CENTROID),
+                        ('Boundary', vdigit.GV_BOUNDARY)):
+            if UserSettings.Get(group='vdigit', key='selectFeature'+feature[0], subkey='enabled') is True:
                 type |= feature[1]
 
         return type
 
+    def SelectLinesFromBackgroundMap(self, pos1, pos2):
+        """Select features from background map
+
+        @param pos1,pos2 bounding box defifinition
+        """
+
+        if UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value') == '':
+            Debug.msg(4, "VEdit.SelectLinesFromBackgroundMap(): []")
+            return []
+
+        x1, y1 = pos1
+        x2, y2 = pos2
+
+        vEditCmd = gcmd.Command(['v.edit',
+                                 '--q',
+                                 'map=%s' % UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value'),
+                                 'tool=select',
+                                 'bbox=%f,%f,%f,%f' % (pos1[0], pos1[1], pos2[0], pos2[1])])
+                                 #'polygon=%f,%f,%f,%f,%f,%f,%f,%f,%f,%f' % \
+                                 #    (x1, y1, x2, y1, x2, y2, x1, y2, x1, y1)])
+                                             
+        try:
+            output = vEditCmd.ReadStdOutput()[0] # first line
+            ids = output.split(',') 
+            ids = map(int, ids) # str -> int
+        except:
+            return []
+
+        Debug.msg(4, "VEdit.SelectLinesFromBackgroundMap(): %s" % \
+                      ",".join(["%d" % v for v in ids]))
+        
+        return ids
+
 class VEdit(AbstractDigit):
     """
     Prototype of digitization class based on v.edit command
 
     Note: This should be replaced by VDigit class.
     """
-    def __init__(self, mapwindow, settings=None):
+    def __init__(self, mapwindow):
         """Initialization
 
         @param mapwindow reference to mapwindow (MapFrame) instance
         @param settings  initial settings of digitization tool
         """
-        AbstractDigit.__init__(self, mapwindow, settings)
+        AbstractDigit.__init__(self, mapwindow)
 
     def AddPoint (self, map, point, x, y, z=None):
         """Add point/centroid
@@ -256,7 +248,7 @@
         else:
             key = "C"
 
-        layer = self.settings["layer"]
+        layer = UserSettings.Get(group='vdigit', key="layer", subkey='value')
         cat   = self.SetCategory()
         
         if layer > 0 and cat != "None":
@@ -288,7 +280,7 @@
         if len(coords) < 2:
             return
 
-        layer = self.settings["layer"]
+        layer = UserSettings.Get(group='vdigit', key="layer", subkey='value')
         cat   = self.SetCategory()
         
         if line:
@@ -326,10 +318,10 @@
         @param input feature definition in GRASS ASCII format
         @param flags additional flags
         """
-        if self.settings['snapping'][0] <= 0.0:
+        if UserSettings.Get(group='vdigit', key='snapping', subkey='value') <= 0.0:
             snap = "no"
         else:
-            if self.settings['snapToVertex']:
+            if UserSettings.Get(group='vdigit', key='snapToVertex', subkey='enabled') is True:
                 snap = "vertex"
             else:
                 snap = "node"
@@ -337,11 +329,11 @@
         command = ["v.edit", "-n", "--q", 
                    "map=%s" % map,
                    "tool=add",
-                   "thresh=%f" % self.driver.GetThreshold(),
+                   "thresh=%f,%f" % (self.driver.GetThreshold(type='selectThresh'), self.driver.GetThreshold(type='snapping')),
                    "snap=%s" % snap]
 
-        if self.settings['backgroundMap'] != '':
-            command.append("bgmap=%s" % self.settings['backgroundMap'])
+        if UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value') != '':
+            command.append("bgmap=%s" % UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value'))
 
         # additional flags
         for flag in flags:
@@ -367,7 +359,7 @@
                       ids)
 
         # delete also attributes if requested
-        if self.settings['delRecord'] is True:
+        if UserSettings.Get(group='vdigit', key='delRecord', subkey='enabled') is True:
             layerCommand = gcmd.Command(cmd=["v.db.connect",
                                              "-g", "--q",
                                              "map=%s" % self.map],
@@ -449,10 +441,10 @@
         Debug.msg(4, "Digit.MoveSelectedLines(): ids=%s, move=%s" % \
                       (ids, move))
 
-        if self.settings['snapping'][0] <= 0:
+        if UserSettings.Get(group='vdigit', key='snapping', subkey='value') <= 0.0:
             snap = "no"
         else:
-            if self.settings['snapToVertex']:
+            if UserSettings.Get(group='vdigit', key='snapToVertex', subkey='enabled') is True:
                 snap = "vertex"
             else:
                 snap = "node"
@@ -463,19 +455,19 @@
                    "tool=%s" % tool,
                    "ids=%s" % ids,
                    "move=%f,%f" % (float(move[0]),float(move[1])),
-                   "thresh=%f" % self.driver.GetThreshold(),
+                   "thresh=%f,%f" % (self.driver.GetThreshold(type='selectThresh'), self.driver.GetThreshold(type='snapping')),
                    "snap=%s" % snap]
 
         if tool == "vertexmove":
             command.append("coords=%f,%f" % (float(coords[0]), float(coords[1])))
             command.append("-1") # modify only first selected
                          
-        if self.settings['backgroundMap'] != '':
-            command.append("bgmap=%s" % self.settings['backgroundMap'])
+        if UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value') != '':
+            command.append("bgmap=%s" % UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value'))
                     
         # run the command
         vedit = gcmd.Command(cmd=command, stderr=None)
-
+        
         # reload map (needed for v.edit)
         self.driver.ReloadMap()
 
@@ -511,7 +503,7 @@
                    "tool=%s" % action,
                    "ids=%s" % line,
                    "coords=%f,%f" % (float(coords[0]),float(coords[1])),
-                   "thresh=%f" % self.driver.GetThreshold()]
+                   "thresh=%f,%f" % (self.driver.GetThreshold(type='selectThresh'), self.driver.GetThreshold(type='snapping'))]
 
         # run the command
         vedit = gcmd.Command(cmd=command, stderr=None)
@@ -536,7 +528,7 @@
                    "tool=break",
                    "ids=%s" % line,
                    "coords=%f,%f" % (float(coords[0]),float(coords[1])),
-                   "thresh=%f" % self.driver.GetThreshold()]
+                   "thresh=%f" % self.driver.GetThreshold(type='selectThresh')]
 
         # run the command
         vedit = gcmd.Command(cmd=command, stderr=None)
@@ -583,7 +575,7 @@
                  'ids=%s' % ",".join(["%d" % v for v in ids])]
 
         if tool in ['snap', 'connect']:
-            vEdit.append("thresh=%f" % self.driver.GetThreshold())
+            vEdit.append("thresh=%f,%f" % (self.driver.GetThreshold(type='selectThresh'), self.driver.GetThreshold(type='snapping')))
 
         runCmd = gcmd.Command(vEdit)
 
@@ -654,8 +646,8 @@
                  'tool=copy',
                  'ids=%s' % ",".join(["%d" % v for v in ids])]
 
-        if self.settings['backgroundMap'] != '':
-            vEdit.append('bgmap=%s' % self.settings['backgroundMap'])
+        if UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value') != '':
+            vEdit.append('bgmap=%s' % UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value'))
 
         runCmd = gcmd.Command(vEdit)
 
@@ -686,39 +678,6 @@
 
         return True
 
-    def SelectLinesFromBackgroundMap(self, pos1, pos2):
-        """Select features from background map
-
-        @param pos1,pos2 bounding box defifinition
-        """
-
-        if self.settings['backgroundMap'] == '':
-            Debug.msg(4, "VEdit.SelectLinesFromBackgroundMap(): []")
-            return []
-
-        x1, y1 = pos1
-        x2, y2 = pos2
-
-        vEditCmd = gcmd.Command(['v.edit',
-                                 '--q',
-                                 'map=%s' % self.settings['backgroundMap'],
-                                 'tool=select',
-                                 'bbox=%f,%f,%f,%f' % (pos1[0], pos1[1], pos2[0], pos2[1])])
-                                 #'polygon=%f,%f,%f,%f,%f,%f,%f,%f,%f,%f' % \
-                                 #    (x1, y1, x2, y1, x2, y2, x1, y2, x1, y1)])
-                                             
-        try:
-            output = vEditCmd.ReadStdOutput()[0] # first line
-            ids = output.split(',') 
-            ids = map(int, ids) # str -> int
-        except:
-            return []
-
-        Debug.msg(4, "VEdit.SelectLinesFromBackgroundMap(): %s" % \
-                      ",".join(["%d" % v for v in ids]))
-        
-        return ids
-
     def SelectLinesByQuery(self, pos1, pos2):
         """Select features by query
 
@@ -729,7 +688,7 @@
         w, n = pos1
         e, s = pos2
 
-        if self.settings['query'][1] == False: # select globaly
+        if UserSettings.Get(group='vdigit', key='query', subkey='box') == False: # select globaly
             vInfo = gcmd.Command(['v.info',
                                   'map=%s' % self.map,
                                   '-g'])
@@ -748,7 +707,7 @@
                   'map=%s' % self.map,
                   'tool=select',
                   'bbox=%f,%f,%f,%f' % (w, n, e, s),
-                  'query=%s' % self.settings['query'][0],
+                  'query=%s' % UserSettings.Get(group='vdigit', key='query', subkey='thresh'),
                   'thresh=%f' % thresh])
 
         vEditCmd = gcmd.Command(vEdit)
@@ -768,9 +727,9 @@
     def GetLayers(self):
         """Return list of layers"""
         layerCommand = gcmd.Command(cmd=["v.db.connect",
-                                             "-g", "--q",
-                                             "map=%s" % self.map],
-                                        rerr=None, stderr=None)
+                                         "-g", "--q",
+                                         "map=%s" % self.map],
+                                    rerr=None, stderr=None)
         if layerCommand.returncode == 0:
             layers = []
             for line in layerCommand.ReadStdOutput():
@@ -778,7 +737,7 @@
                 layers.append(int(lineList[0]))
             return layers
 
-        return [1]
+        return [1,]
 
 class VDigit(AbstractDigit):
     """
@@ -786,13 +745,13 @@
 
     Under development (wxWidgets C/C++ background)
     """
-    def __init__(self, mapwindow, settings=None):
+    def __init__(self, mapwindow):
         """Initialization
 
         @param mapwindow reference to mapwindow (MapFrame) instance
         @param settings  initial settings of digitization tool
         """
-        AbstractDigit.__init__(self, mapwindow, settings)
+        AbstractDigit.__init__(self, mapwindow)
 
         try:
             self.digit = vdigit.Digit(self.driver.GetDevice())
@@ -806,7 +765,7 @@
         @param point feature type (if true point otherwise centroid)
         @param x,y,z coordinates
         """
-        layer = self.settings["layer"]
+        layer = UserSettings.Get(group='vdigit', key="layer", subkey='value')
         cat   = self.SetCategory()
         
         if point:
@@ -818,10 +777,10 @@
 
         if z:
             ret = self.digit.AddLine(type, [x, y, z], layer, cat,
-                                     str(self.settings["backgroundMap"]), snap, thresh)
+                                     str(UserSettings.Get(group='vdigit', key="backgroundMap", subkey='value')), snap, thresh)
         else:
             ret = self.digit.AddLine(type, [x, y], layer, cat,
-                                     str(self.settings["backgroundMap"]), snap, thresh)
+                                     str(UserSettings.Get(group='vdigit', key="backgroundMap", subkey='value')), snap, thresh)
 
         if ret == -1:
             raise gcmd.DigitError, _("Adding new feature to vector map <%s> failed.") % map
@@ -836,7 +795,7 @@
         if len(coords) < 2:
             return
 
-        layer = self.settings["layer"]
+        layer = UserSettings.Get(group='vdigit', key="layer", subkey='value')
         cat   = self.SetCategory()
 
         if line:
@@ -852,7 +811,7 @@
         snap, thresh = self.__getSnapThreshold()
 
         ret = self.digit.AddLine(type, listCoords, layer, cat,
-                                 str(self.settings["backgroundMap"]), snap, thresh)
+                                 str(UserSettings.Get(group='vdigit', key="backgroundMap", subkey='value')), snap, thresh)
 
         if ret == -1:
             raise gcmd.DigitError, _("Adding new feature to vector map <%s> failed.") % map
@@ -863,7 +822,7 @@
 
         @return number of deleted lines
         """
-        nlines = self.digit.DeleteLines(self.settings['delRecord'])
+        nlines = self.digit.DeleteLines(UserSettings.Get(group='vdigit', key='delRecord', subkey='enabled'))
 
         return nlines
 
@@ -875,7 +834,7 @@
         snap, thresh = self.__getSnapThreshold()
 
         nlines = self.digit.MoveLines(move[0], move[1], 0.0, # TODO 3D
-                                      str(self.settings["backgroundMap"]), snap, thresh) 
+                                      str(UserSettings.Get(group='vdigit', key="backgroundMap", subkey='value')), snap, thresh)
 
         return nlines
 
@@ -892,7 +851,8 @@
 
         return self.digit.MoveVertex(coords[0], coords[1], 0.0, # TODO 3D
                                      move[0], move[1], 0.0,
-                                     str(self.settings["backgroundMap"]), snap, thresh)
+                                     str(UserSettings.Get(group='vdigit', key="backgroundMap", subkey='value')), snap,
+                                     self.driver.GetThreshold(type='selectThresh'), thresh)
 
     def AddVertex(self, coords):
         """Add new vertex to the selected line/boundary on position 'coords'
@@ -900,7 +860,7 @@
         @param coords coordinates to add vertex
         """
         return self.digit.ModifyLineVertex(1, coords[0], coords[1], 0.0, # TODO 3D
-                                           self.driver.GetThreshold())
+                                           self.driver.GetThreshold(type='selectThresh'))
 
     def RemoveVertex(self, coords):
         """Remove vertex from the selected line/boundary on position 'coords'
@@ -908,7 +868,7 @@
         @param coords coordinates to remove vertex
         """
         return self.digit.ModifyLineVertex(0, coords[0], coords[1], 0.0, # TODO 3D
-                                           self.driver.GetThreshold())
+                                           self.driver.GetThreshold(type='selectThresh'))
 
     def SplitLine(self, coords):
         """Split selected line/boundary on position 'coords'
@@ -920,7 +880,7 @@
         @return -1 error
         """
         return self.digit.SplitLine(coords[0], coords[1], 0.0, # TODO 3D
-                                    self.driver.GetThreshold())
+                                    self.driver.GetThreshold('selectThresh'))
 
     def EditLine(self, line, coords):
         """Edit existing line/boundary
@@ -941,7 +901,7 @@
         snap, thresh = self.__getSnapThreshold()
         
         return self.digit.RewriteLine(lineid, listCoords,
-                                      str(self.settings["backgroundMap"]), snap, thresh)
+                                      str(UserSettings.Get(group='vdigit', key="backgroundMap", subkey='value')), snap, thresh)
 
     def FlipLine(self):
         """Flip selected lines/boundaries"""
@@ -970,7 +930,7 @@
 
         @param ids list of line ids to be copied
         """
-        return self.digit.CopyLines(ids, self.settings['backgroundMap'])
+        return self.digit.CopyLines(ids, str(UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value')))
 
     def CopyCats(self, cats, ids):
         """Copy given categories to objects with id listed in ids
@@ -994,14 +954,14 @@
         e, s = pos2
 
         query = vdigit.QUERY_UNKNOWN
-        if self.settings['query'][0] == 'length':
+        if UserSettings.Get(group='vdigit', key='query', subkey='type') == 'length':
             query = vdigit.QUERY_LENGTH
-        elif self.settings['query'][0] == 'dangle':
+        elif UserSettings.Get(group='vdigit', key='query', subkey='type') == 'dangle':
             query = vdigit.QUERY_DANGLE
 
         type = vdigit.GV_POINTS | vdigit.GV_LINES # TODO: 3D
         
-        ids = self.digit.SelectLinesByQuery(w, n, 0.0, e, s, 1000.0, self.settings['query'][1],
+        ids = self.digit.SelectLinesByQuery(w, n, 0.0, e, s, 1000.0, UserSettings.Get(group='vdigit', key='query', subkey='box'),
                                             query, type, thresh)
 
         Debug.msg(4, "VDigit.SelectLinesByQuery(): %s" % \
@@ -1050,7 +1010,7 @@
         thresh = self.driver.GetThreshold()
 
         if thresh > 0.0:
-            if self.settings['snapToVertex']:
+            if UserSettings.Get(group='vdigit', key='snapToVertex', subkey='enabled') is True:
                 snap = vdigit.SNAPVERTEX
             else:
                 snap = vdigit.SNAP
@@ -1059,7 +1019,7 @@
 
         return (snap, thresh)
 
-if UserSettings.Get('digitInterface') == 'vedit':
+if UserSettings.Get(group='advanced', key='digitInterface', subkey='type') == 'vedit':
     class Digit(VEdit):
         """Default digit class"""
         def __init__(self, mapwindow):
@@ -1086,17 +1046,17 @@
         self.ids         = {}   # dict[g6id] = [pdcId]
         self.selected    = []   # list of selected objects (grassId!)
 
-    def GetThreshold(self, value=None, units=None):
+    def GetThreshold(self, type='snapping', value=None, units=None):
         """Return threshold in map units
 
         @param value threshold to be set up
         @param units units (map, screen)
         """
         if not value:
-            value = self.parent.settings["snapping"][0]
+            value = UserSettings.Get(group='vdigit', key=type, subkey='value')
 
         if not units:
-            units = self.parent.settings["snapping"][1]
+            units = UserSettings.Get(group='vdigit', key=type, subkey='units')
 
         if units == "screen pixels":
             # pixel -> cell
@@ -1110,7 +1070,7 @@
         else:
             threshold = value
 
-        Debug.msg(4, "AbstractDisplayDriver.GetThreshold(): thresh=%f" % threshold)
+        Debug.msg(4, "AbstractDisplayDriver.GetThreshold(): type=%s, thresh=%f" % (type, threshold))
         
         return threshold
 
@@ -1134,7 +1094,6 @@
         except:
             self.__display = None
             
-        settings = self.parent.settings
         self.UpdateSettings()
 
     def GetDevice(self):
@@ -1163,7 +1122,7 @@
         if map:
             name, mapset = map.split('@')
             try:
-                if UserSettings.Get('digitInterface') == 'vedit':
+                if UserSettings.Get(group='advanced', key='digitInterface', subkey='type') == 'vedit':
                     ret = self.__display.OpenMap(str(name), str(mapset), False)
                 else:
                     ret = self.__display.OpenMap(str(name), str(mapset), True)
@@ -1187,12 +1146,8 @@
 
         @return wx.Image instance
         """
-        import time
-        start = time.clock()
         nlines = self.__display.DrawMap(True) # force
-        stop = time.clock()
-        Debug.msg(3, "CDisplayDriver.DrawMap(): nlines=%d, sec=%f" % \
-                      (nlines, stop-start))
+        Debug.msg(3, "CDisplayDriver.DrawMap(): nlines=%d" % nlines)
 
         return nlines
 
@@ -1224,7 +1179,7 @@
         @param type  select only objects of given type
         """
         pointOnLine = self.__display.SelectLineByPoint(point[0], point[1], 0.0,
-                                                       self.GetThreshold(),
+                                                       self.GetThreshold(type='selectThresh'),
                                                        type, 0); # without_z
 
         if len(pointOnLine) > 0:
@@ -1258,7 +1213,7 @@
         """
         x, y = coords
 
-        id = self.__display.GetSelectedVertex(x, y, self.GetThreshold())
+        id = self.__display.GetSelectedVertex(x, y, self.GetThreshold(type='selectThresh'))
 
         Debug.msg(4, "CDisplayDriver.GetSelectedVertex(): id=%s" % \
                       (",".join(["%d" % v for v in id])))
@@ -1292,75 +1247,82 @@
                                  reg['center_easting'],
                                  reg['center_northing'],
                                  map.width, map.height)
+
+    def GetMapBoundingBox(self):
+        """Return bounding box of given vector map layer
+
+        @return (w,s,b,e,n,t)
+        """
+
+        return self.__display.GetMapBoundingBox()
     
     def UpdateSettings(self):
         """Update display driver settings"""
-        settings = self.parent.settings
         # TODO map units
 
         if not self.__display:
             return
         
-        self.__display.UpdateSettings (wx.Color(settings['symbolHighlight'][1][0],
-                                                settings['symbolHighlight'][1][1],
-                                                settings['symbolHighlight'][1][2],
+        self.__display.UpdateSettings (wx.Color(UserSettings.Get(group='vdigit', key='symbolHighlight', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolHighlight', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolHighlight', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolPoint'][0],
-                                       wx.Color(settings['symbolPoint'][1][0],
-                                                settings['symbolPoint'][1][1],
-                                                settings['symbolPoint'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolPoint', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolPoint', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolPoint', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolPoint', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolLine'][0],
-                                       wx.Color(settings['symbolLine'][1][0],
-                                                settings['symbolLine'][1][1],
-                                                settings['symbolLine'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolLine', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolLine', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolLine', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolLine', subkey='color')[2],
                                            255).GetRGB(),
-                                       settings['symbolBoundaryNo'][0],
-                                       wx.Color(settings['symbolBoundaryNo'][1][0],
-                                                settings['symbolBoundaryNo'][1][1],
-                                                settings['symbolBoundaryNo'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolBoundaryNo', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolBoundaryNo', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolBoundaryNo', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolBoundaryNo', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolBoundaryOne'][0],
-                                       wx.Color(settings['symbolBoundaryOne'][1][0],
-                                                settings['symbolBoundaryOne'][1][1],
-                                                settings['symbolBoundaryOne'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolBoundaryOne', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolBoundaryOne', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolBoundaryOne', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolBoundaryOne', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolBoundaryTwo'][0],
-                                       wx.Color(settings['symbolBoundaryTwo'][1][0],
-                                                settings['symbolBoundaryTwo'][1][1],
-                                                settings['symbolBoundaryTwo'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolBoundaryTwo', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolBoundaryTwo', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolBoundaryTwo', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolBoundaryTwo', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolCentroidIn'][0],
-                                       wx.Color(settings['symbolCentroidIn'][1][0],
-                                                settings['symbolCentroidIn'][1][1],
-                                                settings['symbolCentroidIn'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolCentroidIn', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolCentroidIn', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolCentroidIn', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolCentroidIn', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolCentroidOut'][0],
-                                       wx.Color(settings['symbolCentroidOut'][1][0],
-                                                settings['symbolCentroidOut'][1][1],
-                                                settings['symbolCentroidOut'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolCentroidOut', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolCentroidOut', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolCentroidOut', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolCentroidOut', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolCentroidDup'][0],
-                                       wx.Color(settings['symbolCentroidDup'][1][0],
-                                                settings['symbolCentroidDup'][1][1],
-                                                settings['symbolCentroidDup'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolCentroidDup', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolCentroidDup', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolCentroidDup', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolCentroidDup', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolNodeOne'][0],
-                                       wx.Color(settings['symbolNodeOne'][1][0],
-                                                settings['symbolNodeOne'][1][1],
-                                                settings['symbolNodeOne'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolNodeOne', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolNodeOne', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolNodeOne', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolNodeOne', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolNodeTwo'][0],
-                                       wx.Color(settings['symbolNodeTwo'][1][0],
-                                                settings['symbolNodeTwo'][1][1],
-                                                settings['symbolNodeTwo'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolNodeTwo', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolNodeTwo', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolNodeTwo', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolNodeTwo', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['symbolVertex'][0],
-                                       wx.Color(settings['symbolVertex'][1][0],
-                                                settings['symbolVertex'][1][1],
-                                                settings['symbolVertex'][1][2],
+                                       UserSettings.Get(group='vdigit', key='symbolVertex', subkey='enabled'),
+                                       wx.Color(UserSettings.Get(group='vdigit', key='symbolVertex', subkey='color')[0],
+                                                UserSettings.Get(group='vdigit', key='symbolVertex', subkey='color')[1],
+                                                UserSettings.Get(group='vdigit', key='symbolVertex', subkey='color')[2],
                                                 255).GetRGB(),
-                                       settings['lineWidth'][0])
+                                       UserSettings.Get(group='vdigit', key='lineWidth', subkey='value'))
 
 class DigitSettingsDialog(wx.Dialog):
     """
@@ -1375,25 +1337,30 @@
         notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
         self.__CreateSymbologyPage(notebook)
         parent.digit.SetCategory() # update category number (next to use)
-        self.__CreateSettingsPage(notebook)
+        self.__CreateGeneralPage(notebook)
+        self.__CreateAttributesPage(notebook)
         self.__CreateQueryPage(notebook)
 
         # buttons
-        btnApply = wx.Button(self, wx.ID_APPLY, _("Apply") )
+        btnApply = wx.Button(self, wx.ID_APPLY)
         btnCancel = wx.Button(self, wx.ID_CANCEL)
-        btnOk = wx.Button(self, wx.ID_OK, _("OK") )
-        btnOk.SetDefault()
+        btnSave = wx.Button(self, wx.ID_SAVE)
+        btnSave.SetDefault()
 
         # bindigs
         btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
-        btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
+        btnApply.SetToolTipString(_("Apply changes for this session"))
+        btnApply.SetDefault()
+        btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
+        btnSave.SetToolTipString(_("Close dialog and save changes to user settings file"))
         btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
-
+        btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
+        
         # sizers
         btnSizer = wx.StdDialogButtonSizer()
         btnSizer.AddButton(btnCancel)
         btnSizer.AddButton(btnApply)
-        btnSizer.AddButton(btnOk)
+        btnSizer.AddButton(btnSave)
         btnSizer.Realize()
         
         mainSizer = wx.BoxSizer(wx.VERTICAL)
@@ -1419,8 +1386,8 @@
         for label, key in self.__SymbologyData():
             textLabel = wx.StaticText(panel, wx.ID_ANY, label)
             color = csel.ColourSelect(panel, id=wx.ID_ANY,
-                                      colour=self.parent.digit.settings[key][1], size=(25, 25))
-            isEnabled = self.parent.digit.settings[key][0]
+                                      colour=UserSettings.Get(group='vdigit', key=key, subkey='color'), size=(25, 25))
+            isEnabled = UserSettings.Get(group='vdigit', key=key, subkey='enabled')
             if isEnabled is not None:
                 enabled = wx.CheckBox(panel, id=wx.ID_ANY, label="")
                 enabled.SetValue(isEnabled)
@@ -1439,11 +1406,11 @@
         
         return panel
 
-    def __CreateSettingsPage(self, notebook):
+    def __CreateGeneralPage(self, notebook):
         """Create notebook page concerning with symbology settings"""
 
         panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
-        notebook.AddPage(page=panel, text=_("Settings"))
+        notebook.AddPage(page=panel, text=_("General"))
 
         border = wx.BoxSizer(wx.VERTICAL)
         
@@ -1456,15 +1423,16 @@
         flexSizer.AddGrowableCol(0)
         # line width
         text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Line width"))
-        self.lineWidthValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(50, -1),
-                                          initial=self.parent.digit.settings["lineWidth"][0],
+        self.lineWidthValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(75, -1),
+                                          initial=UserSettings.Get(group='vdigit', key="lineWidth", subkey='value'),
                                           min=1, max=1e6)
-        self.lineWidthUnit = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                       choices=["screen pixels", "map units"])
-        self.lineWidthUnit.SetStringSelection(self.parent.digit.settings["lineWidth"][1])
+        units = wx.StaticText(parent=panel, id=wx.ID_ANY, size=(115, -1),
+                              label=UserSettings.Get(group='vdigit', key="lineWidth", subkey='units'),
+                              style=wx.ALIGN_LEFT)
         flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer.Add(self.lineWidthValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
-        flexSizer.Add(self.lineWidthUnit, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
+        flexSizer.Add(units, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
+                      border=10)
 
         sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
         border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
@@ -1480,13 +1448,13 @@
         flexSizer2.AddGrowableCol(0)
         # snapping
         text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Snapping threshold"))
-        self.snappingValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(50, -1),
-                                         initial=self.parent.digit.settings["snapping"][0],
+        self.snappingValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(75, -1),
+                                         initial=UserSettings.Get(group='vdigit', key="snapping", subkey='value'),
                                          min=1, max=1e6)
         self.snappingValue.Bind(wx.EVT_SPINCTRL, self.OnChangeSnappingValue)
         self.snappingUnit = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
                                       choices=["screen pixels", "map units"])
-        self.snappingUnit.SetStringSelection(self.parent.digit.settings["snapping"][1])
+        self.snappingUnit.SetStringSelection(UserSettings.Get(group='vdigit', key="snapping", subkey='units'))
         self.snappingUnit.Bind(wx.EVT_CHOICE, self.OnChangeSnappingUnits)
         flexSizer1.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer1.Add(self.snappingValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
@@ -1495,7 +1463,7 @@
         text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Backgroud vector map"))
         self.backgroundMap = gselect.Select(parent=panel, id=wx.ID_ANY, size=(200,-1),
                                            type="vector")
-        self.backgroundMap.SetValue(self.parent.digit.settings["backgroundMap"])
+        self.backgroundMap.SetValue(UserSettings.Get(group='vdigit', key="backgroundMap", subkey='value'))
         self.backgroundMap.Bind(wx.EVT_TEXT, self.OnChangeBackgroundMap)
         flexSizer2.Add(text, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer2.Add(self.backgroundMap, proportion=1, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
@@ -1504,13 +1472,13 @@
         vertexSizer = wx.BoxSizer(wx.VERTICAL)
         self.snapVertex = wx.CheckBox(parent=panel, id=wx.ID_ANY,
                                       label=_("Snap also to vertex"))
-        self.snapVertex.SetValue(self.parent.digit.settings["snapToVertex"])
+        self.snapVertex.SetValue(UserSettings.Get(group='vdigit', key="snapToVertex", subkey='enabled'))
         vertexSizer.Add(item=self.snapVertex, proportion=0, flag=wx.EXPAND)
         self.mapUnits = self.parent.MapWindow.Map.ProjInfo()['units']
         self.snappingInfo = wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                          label=_("Snapping threshold is %.1f %s") % \
-                                              (self.parent.digit.driver.GetThreshold(),
-                                               self.mapUnits))
+                                          label=_("Snapping threshold is %(value).1f %(units)s") % \
+                                              {'value' : self.parent.digit.driver.GetThreshold(),
+                                               'units' : self.mapUnits})
         vertexSizer.Add(item=self.snappingInfo, proportion=0,
                         flag=wx.ALL | wx.EXPAND, border=1)
 
@@ -1520,69 +1488,39 @@
         border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
 
         #
-        # attributes
+        # select box
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Digitize new feature"))
+        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Select vector features"))
+        # feature type
         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        # checkbox
-        self.addRecord = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                     label=_("Add new record into table"))
-        self.addRecord.SetValue(self.parent.digit.settings["addRecord"])
-        sizer.Add(item=self.addRecord, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
-        # settings
-        flexSizer = wx.FlexGridSizer(cols=2, hgap=3, vgap=3)
+        inSizer = wx.BoxSizer(wx.HORIZONTAL)
+        self.selectFeature = {}
+        for feature in ('Point', 'Line',
+                        'Centroid', 'Boundary'):
+            chkbox = wx.CheckBox(parent=panel, label=feature)
+            self.selectFeature[feature] = chkbox.GetId()
+            chkbox.SetValue(UserSettings.Get(group='vdigit', key='selectFeature'+feature, subkey='enabled'))
+            inSizer.Add(item=chkbox, proportion=0,
+                        flag=wx.EXPAND | wx.ALL, border=5)
+        sizer.Add(item=inSizer, proportion=0, flag=wx.EXPAND)
+        # threshold
+        flexSizer = wx.FlexGridSizer (cols=3, hgap=5, vgap=5)
         flexSizer.AddGrowableCol(0)
-        settings = ((_("Layer"), 1), (_("Category"), 1), (_("Mode"), _("Next to use")))
-        # layer
-        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Layer"))
-        if self.parent.digit.map:
-            layers = map(str, self.parent.digit.GetLayers())
-        else:
-            layers = [str(self.parent.digit.settings["layer"])]
-        self.layer = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                               choices=layers)
-        self.layer.SetStringSelection(str(self.parent.digit.settings["layer"]))
-        flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(item=self.layer, proportion=0,
-                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
-        # category number
-        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Category number"))
-        self.category = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                    initial=self.parent.digit.settings["category"],
-                                    min=-1e9, max=1e9) 
-        if self.parent.digit.settings["categoryMode"] != "Manual entry":
-            self.category.Enable(False)
-        flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(item=self.category, proportion=0,
-                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
-        # category mode
-        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Category mode"))
-        self.categoryMode = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                      choices=[_("Next to use"), _("Manual entry"), _("No category")])
-        self.categoryMode.SetStringSelection(self.parent.digit.settings["categoryMode"])
-        flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
-        flexSizer.Add(item=self.categoryMode, proportion=0,
-                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select threshold"))
+        self.selectThreshValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(75, -1),
+                                             initial=UserSettings.Get(group='vdigit', key="selectThresh", subkey='value'),
+                                             min=1, max=1e6)
+        units = wx.StaticText(parent=panel, id=wx.ID_ANY, size=(115, -1),
+                              label=UserSettings.Get(group='vdigit', key="lineWidth", subkey='units'),
+                              style=wx.ALIGN_LEFT)
+        flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(self.selectThreshValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+        flexSizer.Add(units, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL | wx.LEFT,
+                      border=10)
+        sizer.Add(item=flexSizer, proportion=0, flag=wx.EXPAND)
+        
+        border.Add(item=sizer, proportion=0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5)
 
-        sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
-        border.Add(item=sizer, proportion=0,
-                   flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
-        # delete existing feature
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Delete existing feature(s)"))
-        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
-        # checkbox
-        self.deleteRecord = wx.CheckBox(parent=panel, id=wx.ID_ANY,
-                                        label=_("Delete record from table"))
-        self.deleteRecord.SetValue(self.parent.digit.settings["delRecord"])
-        sizer.Add(item=self.deleteRecord, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
-        border.Add(item=sizer, proportion=0,
-                   flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
-
-        # bindings
-        self.Bind(wx.EVT_CHECKBOX, self.OnChangeAddRecord, self.addRecord)
-        self.Bind(wx.EVT_CHOICE, self.OnChangeCategoryMode, self.categoryMode)
-        self.Bind(wx.EVT_CHOICE, self.OnChangeLayer, self.layer)
-
         panel.SetSizer(border)
         
         return panel
@@ -1590,8 +1528,6 @@
     def __CreateQueryPage(self, notebook):
         """Create notebook page for query tool"""
 
-        settings = self.parent.digit.settings
-
         panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
         notebook.AddPage(page=panel, text=_("Query tool"))
 
@@ -1606,7 +1542,7 @@
         LocUnits = self.parent.MapWindow.Map.ProjInfo()['units']
 
         self.queryBox = wx.CheckBox(parent=panel, id=wx.ID_ANY, label=_("Select by box"))
-        self.queryBox.SetValue(settings["query"][1])
+        self.queryBox.SetValue(UserSettings.Get(group='vdigit', key="query", subkey='box'))
 
         sizer.Add(item=self.queryBox, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
         sizer.Add((0, 5))
@@ -1622,11 +1558,11 @@
         txt = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select lines"))
         self.queryLengthSL = wx.Choice (parent=panel, id=wx.ID_ANY, 
                                         choices = [_("shorter than"), _("longer than")])
-        self.queryLengthSL.SetStringSelection(settings["queryLength"][0])
+        self.queryLengthSL.SetStringSelection(UserSettings.Get(group='vdigit', key="queryLength", subkey='than'))
         self.queryLengthValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(100, -1),
                                             initial=1,
                                             min=0, max=1e6)
-        self.queryLengthValue.SetValue(settings["queryLength"][1])
+        self.queryLengthValue.SetValue(UserSettings.Get(group='vdigit', key="queryLength", subkey='thresh'))
         units = wx.StaticText(parent=panel, id=wx.ID_ANY, label="%s" % LocUnits)
         flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer.Add(self.queryLengthSL, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
@@ -1645,11 +1581,11 @@
         txt = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select dangles"))
         self.queryDangleSL = wx.Choice (parent=panel, id=wx.ID_ANY, 
                                         choices = [_("shorter than"), _("longer than")])
-        self.queryDangleSL.SetStringSelection(settings["queryDangle"][0])
+        self.queryDangleSL.SetStringSelection(UserSettings.Get(group='vdigit', key="queryDangle", subkey='than'))
         self.queryDangleValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(100, -1),
                                        initial=1,
                                        min=0, max=1e6)
-        self.queryDangleValue.SetValue(settings["queryDangle"][1])
+        self.queryDangleValue.SetValue(UserSettings.Get(group='vdigit', key="queryDangle", subkey='thresh'))
         units = wx.StaticText(parent=panel, id=wx.ID_ANY, label="%s" % LocUnits)
         flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         flexSizer.Add(self.queryDangleSL, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
@@ -1657,7 +1593,7 @@
         flexSizer.Add(units, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
         sizer.Add(item=flexSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
 
-        if settings["query"][0] == "length":
+        if UserSettings.Get(group='vdigit', key="query", subkey='type') == "length":
             self.queryLength.SetValue(True)
         else:
             self.queryDangle.SetValue(True)
@@ -1667,26 +1603,94 @@
 
         border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
 
+        panel.SetSizer(border)
+        
+        return panel
+
+    def __CreateAttributesPage(self, notebook):
+        """Create notebook page for query tool"""
+
+        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
+        notebook.AddPage(page=panel, text=_("Attributes"))
+
+        border = wx.BoxSizer(wx.VERTICAL)
+
         #
-        # select box
+        # add new record
         #
-        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Select vector features"))
-        sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
-        for feature in ('point', 'line',
-                        'centroid', 'boundary'):
-            chkbox = wx.CheckBox(parent=panel, label=feature)
-            settings['selectFeature'][feature]['id'] = chkbox.GetId()
-            chkbox.SetValue(settings['selectFeature'][feature]['val'])
-            sizer.Add(item=chkbox, proportion=0,
-                      flag=wx.EXPAND | wx.ALL, border=3)
+        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Digitize new feature"))
+        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
 
-        border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
+        # checkbox
+        self.addRecord = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+                                     label=_("Add new record into table"))
+        self.addRecord.SetValue(UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled'))
+        sizer.Add(item=self.addRecord, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+        # settings
+        flexSizer = wx.FlexGridSizer(cols=2, hgap=3, vgap=3)
+        flexSizer.AddGrowableCol(0)
+        settings = ((_("Layer"), 1), (_("Category"), 1), (_("Mode"), _("Next to use")))
+        # layer
+        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Layer"))
+        if self.parent.digit.map:
+            layers = map(str, self.parent.digit.GetLayers())
+            if len(layers) == 0:
+                layers = [str(UserSettings.Get(group='vdigit', key="layer", subkey='value')), ]
+        else:
+            layers = [str(UserSettings.Get(group='vdigit', key="layer", subkey='value')), ]
+        
+        self.layer = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                               choices=layers)
+        self.layer.SetStringSelection(str(UserSettings.Get(group='vdigit', key="layer", subkey='value')))
+        flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item=self.layer, proportion=0,
+                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+        # category number
+        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Category number"))
+        self.category = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                                    initial=UserSettings.Get(group='vdigit', key="category", subkey='value'),
+                                    min=-1e9, max=1e9) 
+        if UserSettings.Get(group='vdigit', key="categoryMode", subkey='value') != "Manual entry":
+            self.category.Enable(False)
+        flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item=self.category, proportion=0,
+                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
+        # category mode
+        text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Category mode"))
+        self.categoryMode = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                                      choices=[_("Next to use"), _("Manual entry"), _("No category")])
+        self.categoryMode.SetStringSelection(UserSettings.Get(group='vdigit', key="categoryMode", subkey='value'))
+        flexSizer.Add(item=text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(item=self.categoryMode, proportion=0,
+                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
 
+        sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
+        border.Add(item=sizer, proportion=0,
+                   flag=wx.ALL | wx.EXPAND, border=5)
+
+        #
+        # delete existing record
+        #
+        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Delete existing feature(s)"))
+        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+        
+        # checkbox
+        self.deleteRecord = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+                                        label=_("Delete record from table"))
+        self.deleteRecord.SetValue(UserSettings.Get(group='vdigit', key="delRecord", subkey='enabled'))
+        sizer.Add(item=self.deleteRecord, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+        border.Add(item=sizer, proportion=0,
+                   flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
+
+        # bindings
+        self.Bind(wx.EVT_CHECKBOX, self.OnChangeAddRecord, self.addRecord)
+        self.Bind(wx.EVT_CHOICE, self.OnChangeCategoryMode, self.categoryMode)
+        self.Bind(wx.EVT_CHOICE, self.OnChangeLayer, self.layer)
+
         panel.SetSizer(border)
         
         return panel
 
-
     def __SymbologyData(self):
         """
         Data for __CreateSymbologyPage()
@@ -1713,7 +1717,7 @@
         """Change category mode"""
 
         mode = event.GetString()
-        self.parent.digit.settings["categoryMode"] = mode
+        UserSettings.Set(group='vdigit', key="categoryMode", subkey='value', value=mode)
         if mode == "Manual entry": # enable
             self.category.Enable(True)
         elif self.category.IsEnabled(): # disable
@@ -1722,15 +1726,15 @@
         if mode == "No category" and self.addRecord.IsChecked():
             self.addRecord.SetValue(False)
         self.parent.digit.SetCategory()
-        self.category.SetValue(self.parent.digit.settings['category'])
+        self.category.SetValue(UserSettings.Get(group='vdigit', key='category', subkey='value'))
 
     def OnChangeLayer(self, event):
         """Layer changed"""
         layer = int(event.GetString())
         if layer > 0:
-            self.parent.digit.settings['layer'] = layer
+            UserSettings.Set(group='vdigit', key='layer', subkey='value', value=layer)
             self.parent.digit.SetCategory()
-            self.category.SetValue(self.parent.digit.settings['category'])
+            self.category.SetValue(UserSettings.Get(group='vdigit', key='category', subkey='value'))
             
         event.Skip()
 
@@ -1746,9 +1750,9 @@
         else:
             threshold = self.parent.digit.driver.GetThreshold(value)
 
-        self.snappingInfo.SetLabel(_("Snapping threshold is %.1f %s") % 
-                                   (threshold,
-                                    self.mapUnits))
+        self.snappingInfo.SetLabel(_("Snapping threshold is %(value).1f %(units)s") % 
+                                   {'value' : threshold,
+                                    'units' : self.mapUnits})
 
         event.Skip()
 
@@ -1759,13 +1763,13 @@
         threshold = self.parent.digit.driver.GetThreshold(value, units)
 
         if units == "map units":
-            self.snappingInfo.SetLabel(_("Snapping threshold is %.1f %s") % \
-                                           (value,
-                                            self.mapUnits))
+            self.snappingInfo.SetLabel(_("Snapping threshold is %(value).1f %(units)s") % 
+                                       {'value' : value,
+                                        'units' : self.mapUnits})
         else:
-            self.snappingInfo.SetLabel(_("Snapping threshold is %.1f %s") % \
-                                           (threshold,
-                                            self.mapUnits))
+            self.snappingInfo.SetLabel(_("Snapping threshold is %(value).1f %(units)s") % 
+                                       {'value' : threshold,
+                                        'units' : self.mapUnits})
             
         event.Skip()
 
@@ -1773,7 +1777,7 @@
         """Change background map"""
         map = self.backgroundMap.GetValue()
         
-        self.parent.digit.settings['backgroundMap'] = map
+        UserSettings.Set(group='vdigit', key='backgroundMap', subkey='value', value=map)
         
     def OnChangeQuery(self, event):
         """Change query"""
@@ -1790,10 +1794,12 @@
             self.queryDangleSL.Enable(True)
             self.queryDangleValue.Enable(True)
 
-    def OnOK(self, event):
-        """Button 'OK' clicked"""
+    def OnSave(self, event):
+        """Button 'Save' clicked"""
         self.UpdateSettings()
         self.parent.digittoolbar.settingsDialog = None
+        file = UserSettings.SaveToFile()
+        self.parent.gismanager.goutput.cmd_stdout.write('Settings saved to file <%s>.' % file)
         self.Close()
 
     def OnApply(self, event):
@@ -1806,63 +1812,62 @@
         self.Close()
 
     def UpdateSettings(self):
-        """Update self.parent.digit.settings"""
+        """Update UserSettings"""
 
         # symbology
         for key, (enabled, color) in self.symbology.iteritems():
             if enabled:
-                self.parent.digit.settings[key] = (enabled.IsChecked(), color.GetColour())
+                UserSettings.Set(group='vdigit', key=key, subkey='enabled', value=enabled.IsChecked())
+                UserSettings.Set(group='vdigit', key=key, subkey='color', value=color.GetColour())
             else:
-                self.parent.digit.settings[key] = (None, color.GetColour())
+                UserSettings.Set(group='vdigit', key=key, subkey='color', value=color.GetColour())
         # display
-        self.parent.digit.settings["lineWidth"] = (int(self.lineWidthValue.GetValue()),
-                                                   self.lineWidthUnit.GetStringSelection())
+        UserSettings.Set(group='vdigit', key="lineWidth", subkey='value', value=int(self.lineWidthValue.GetValue()))
 
         # snapping
-        self.parent.digit.settings["snapping"] = (int(self.snappingValue.GetValue()), # value
-                                      self.snappingUnit.GetStringSelection()) # unit
-        self.parent.digit.settings["snapToVertex"] = self.snapVertex.IsChecked()
+        UserSettings.Set(group='vdigit', key="snapping", subkey='value', value=int(self.snappingValue.GetValue()))
+        UserSettings.Set(group='vdigit', key="snapping", subkey='units', value=self.snappingUnit.GetStringSelection())
+        UserSettings.Set(group='vdigit', key="snapToVertex", subkey='enabled', value=self.snapVertex.IsChecked())
         
         # digitize new feature
-        self.parent.digit.settings["addRecord"] = self.addRecord.IsChecked()
-        self.parent.digit.settings["layer"] = int(self.layer.GetStringSelection())
-        if self.parent.digit.settings["categoryMode"] == "No category":
-            self.parent.digit.settings["category"] = None
+        UserSettings.Set(group='vdigit', key="addRecord", subkey='enabled', value=self.addRecord.IsChecked())
+        UserSettings.Set(group='vdigit', key="layer", subkey='value', value=int(self.layer.GetStringSelection()))
+        if UserSettings.Get(group='vdigit', key="categoryMode", subkey='value') == "No category":
+            UserSettings.Set(group='vdigit', key="category", subkey='value', value=None)
         else:
-            self.parent.digit.settings["category"] = int(self.category.GetValue())
-        self.parent.digit.settings["categoryMode"] = self.categoryMode.GetStringSelection()
+            UserSettings.Set(group='vdigit', key="category", subkey='value', value=int(self.category.GetValue()))
+        UserSettings.Set(group='vdigit', key="categoryMode", subkey='value', value=self.categoryMode.GetStringSelection())
 
         # delete existing feature
-        self.parent.digit.settings["delRecord"] = self.deleteRecord.IsChecked()
+        UserSettings.Set(group='vdigit', key="delRecord", subkey='enabled', value=self.deleteRecord.IsChecked())
 
-        # threshold
-        try:
-            self.parent.digit.threshold = self.parent.digit.driver.GetThreshold()
-        except:
-            pass
+        # snapping threshold
+        self.parent.digit.threshold = self.parent.digit.driver.GetThreshold()
 
         # query tool
         if self.queryLength.GetValue():
-            self.parent.digit.settings["query"] = ("length", self.queryBox.IsChecked())
+            UserSettings.Set(group='vdigit', key="query", subkey='type', value="length")
         else:
-            self.parent.digit.settings["query"] = ("dangle", self.queryBox.IsChecked())
-        self.parent.digit.settings["queryLength"] = (self.queryLengthSL.GetStringSelection(),
-                                                     int(self.queryLengthValue.GetValue()))
-        self.parent.digit.settings["queryDangle"] = (self.queryDangleSL.GetStringSelection(),
-                                                     int(self.queryDangleValue.GetValue()))
+            UserSettings.Set(group='vdigit', key="query", subkey='type', value="dangle")
+        UserSettings.Set(group='vdigit', key="query", subkey='box', value=self.queryBox.IsChecked())
+        UserSettings.Set(group='vdigit', key="queryLength", subkey='than', value=self.queryLengthSL.GetStringSelection())
+        UserSettings.Set(group='vdigit', key="queryLength", subkey='thresh', value=int(self.queryLengthValue.GetValue()))
+        UserSettings.Set(group='vdigit', key="queryDangle", subkey='than', value=self.queryDangleSL.GetStringSelection())
+        UserSettings.Set(group='vdigit', key="queryDangle", subkey='thresh', value=int(self.queryDangleValue.GetValue()))
 
         # select features
-        for feature in ('point', 'line',
-                        'centroid', 'boundary'):
-            self.parent.digit.settings['selectFeature'][feature]['val'] = \
-                self.FindWindowById(self.parent.digit.settings["selectFeature"][feature]['id']).IsChecked()
+        for feature in ('Point', 'Line',
+                        'Centroid', 'Boundary'):
+            UserSettings.Set(group='vdigit', key='selectFeature'+feature, subkey='enabled',
+                                           value=self.FindWindowById(self.selectFeature[feature]).IsChecked())
+        UserSettings.Set(group='vdigit', key="selectThresh", subkey='value', value=int(self.selectThreshValue.GetValue()))
 
         # update driver settings
         self.parent.digit.driver.UpdateSettings()
 
         # redraw map if auto-rendering is enabled
         if self.parent.autoRender.GetValue(): 
-            self.parent.ReRender(None)
+            self.parent.OnRender(None)
 
 class DigitCategoryDialog(wx.Dialog, listmix.ColumnSorterMixin):
     """
@@ -2045,10 +2050,11 @@
             event.Veto()
             self.list.SetStringItem(itemIndex, 0, str(layerNew))
             self.list.SetStringItem(itemIndex, 1, str(catNew))
-            dlg = wx.MessageDialog(self, _("Unable to add new layer/category <%s/%s>.\n"
+            dlg = wx.MessageDialog(self, _("Unable to add new layer/category <%(layer)s/%(category)s>.\n"
                                            "Layer and category number must be integer.\n"
                                            "Layer number must be greater then zero.") %
-                                   (str(self.layerNew.GetValue()), str(self.catNew.GetValue())),
+                                   { 'layer': str(self.layerNew.GetValue()),
+                                     'category' : str(self.catNew.GetValue()) },
                                    _("Error"), wx.OK | wx.ICON_ERROR)
             dlg.ShowModal()
             dlg.Destroy()
@@ -2175,7 +2181,7 @@
                             cat not in cats[1][layer]:
                         catList.append(cat)
                 if catList != []:
-                    if UserSettings.Get('digitInterface') == 'vedit':
+                    if UserSettings.Get(group='advanced', key='digitInterface', subkey='type') == 'vedit':
                         vEditCmd = ['v.edit', '--q',
                                     'map=%s' % self.map,
                                     'layer=%d' % layer,
@@ -2194,7 +2200,7 @@
                         if self.line < 0:
                             wx.MessageBox(parent=self, message=_("Unable to update vector map."),
                                           caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
-        if UserSettings.Get('digitInterface') == 'vedit':           
+        if UserSettings.Get(group='advanced', key='digitInterface', subkey='type') == 'vedit':           
             # reload map (needed for v.edit)
             self.parent.parent.digit.driver.ReloadMap()
 
@@ -2215,10 +2221,11 @@
             if layer <= 0:
                 raise ValueError
         except ValueError:
-            dlg = wx.MessageDialog(self, _("Unable to add new layer/category <%s/%s>.\n"
+            dlg = wx.MessageDialog(self, _("Unable to add new layer/category <%(layer)s/%(category)s>.\n"
                                            "Layer and category number must be integer.\n"
                                            "Layer number must be greater then zero.") %
-                                   (str(self.layerNew.GetValue()), str(self.catNew.GetValue())),
+                                   {'layer' : str(self.layerNew.GetValue()),
+                                    'category' : str(self.catNew.GetValue())},
                                    _("Error"), wx.OK | wx.ICON_ERROR)
             dlg.ShowModal()
             dlg.Destroy()

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/gcmd.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/gcmd.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/gcmd.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -6,7 +6,7 @@
 Classes:
  * GException
  * DigitError
- * Popen
+ * Popen (from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440554)
  * Command
  * CommandThread
 
@@ -25,6 +25,7 @@
 import sys
 import time
 import errno
+import signal
 
 import wx
 
@@ -44,65 +45,64 @@
 from threading import Thread
 
 # import wxgui_utils # log window
+import globalvar
+import utils
 from debug import Debug as Debug
 
 class GException(Exception):
     """Generic exception"""
-    def __init__(self, message, parent=None):
+    def __init__(self, message, title=_("Error"), parent=None):
         self.message = message
         self.parent = parent
-
+        self.title = title
+        
     def __str__(self):
         wx.MessageBox(parent=self.parent,
-                      caption=_("Error"),
+                      caption=self.title,
                       message=self.message,
                       style=wx.ICON_ERROR | wx.CENTRE)
 
         return ''
 
+class GStdError(GException):
+    """Generic exception"""
+
+    def __init__(self, message, title=_("Error"), parent=None):
+        GException.__init__(self, message, title=title, parent=parent)
+
 class CmdError(GException):
     """Exception used for GRASS commands.
 
     See Command class (command exits with EXIT_FAILURE,
     G_fatal_error() is called)."""
-    def __init(self, cmd, message):
-        GException.__init__(message)
+    def __init__(self, cmd, message, parent=None):
+        self.cmd = cmd
+        GException.__init__(self, message,
+                            title=_("Error in command execution %s" % self.cmd[0]),
+                            parent=parent)
 
-    def __str__(self):
-        wx.MessageBox(parent=self.parent,
-                      caption=_("Error in command execution"),
-                      message=self.message,
-                      style=wx.ICON_ERROR | wx.CENTRE)
-        
-        return '' 
-
 class SettingsError(GException):
     """Exception used for GRASS settings, see
     gui_modules/preferences.py."""
-    def __init(self, message):
-        GException.__init__(message)
+    def __init__(self, message, parent=None):
+        GException.__init__(self, message,
+                            title=_("Preferences error"),
+                            parent=parent)
 
-    def __str__(self):
-        wx.MessageBox(parent=self.parent,
-                      caption=_("Preferences error"),
-                      message=self.message,
-                      style=wx.ICON_ERROR | wx.CENTRE)
-        
-        return '' 
-
 class DigitError(GException):
     """Exception raised during digitization session"""
-    def __init(self, message):
-        GException.__init__(message)
+    def __init__(self, message, parent=None):
+        GException.__init__(self, message,
+                            title=_("Error in digitization tool"),
+                            parent=parent)
 
-    def __str__(self):
-        wx.MessageBox(parent=None,
-                      caption=_("Error in digitization tool"),
-                      message=self.message,
-                      style=wx.ICON_ERROR)
+class DBMError(GException):
+    """Exception raised for Attribute Table Manager"""
+    def __init__(self, message):
+        GException.__init__(self, message,
+                            title=_("Error in Attribute Table Manager"),
+                            parent=parent)
 
-        return ''
-
 class Popen(subprocess.Popen):
     """Subclass subprocess.Popen"""
     def recv(self, maxsize=None):
@@ -124,7 +124,19 @@
     def _close(self, which):
         getattr(self, which).close()
         setattr(self, which, None)
-    
+
+    def kill(self):
+        """Try to kill running process"""
+        if subprocess.mswindows:
+            import win32api
+            handle = win32api.OpenProcess(1, 0, self.pid)
+            return (0 != win32api.TerminateProcess(handle, 0))
+	else:
+            try:
+                os.kill(-self.pid, signal.SIGTERM) # kill whole group
+            except OSError:
+                pass
+
     if subprocess.mswindows:
         def send(self, input):
             if not self.stdin:
@@ -206,6 +218,53 @@
                 if not conn.closed:
                     fcntl.fcntl(conn, fcntl.F_SETFL, flags)
 
+message = "Other end disconnected!"
+
+def recv_some(p, t=.1, e=1, tr=5, stderr=0):
+    if tr < 1:
+        tr = 1
+    x = time.time()+t
+    y = []
+    r = ''
+    pr = p.recv
+    if stderr:
+        pr = p.recv_err
+    while time.time() < x or r:
+        r = pr()
+        if r is None:
+            if e:
+                raise Exception(message)
+            else:
+                break
+        elif r:
+            y.append(r)
+        else:
+            time.sleep(max((x-time.time())/tr, 0))
+    return ''.join(y)
+    
+def send_all(p, data):
+    while len(data):
+        sent = p.send(data)
+        if sent is None:
+            raise Exception(message)
+        data = buffer(data, sent)
+
+# Define notification event for thread completion
+EVT_RESULT_ID = wx.NewId()
+
+def EVT_RESULT(win, func):
+    """Define Result Event"""
+    win.Connect(-1, -1, EVT_RESULT_ID, func)
+
+class ResultEvent(wx.PyEvent):
+    """Simple event to carry arbitrary result data"""
+    def __init__(self, data):
+        wx.PyEvent.__init__(self)
+
+        self.SetEventType(EVT_RESULT_ID)
+
+        self.cmdThread = data
+
 class Command:
     """
     Run GRASS command in separate thread
@@ -239,6 +298,12 @@
                   stdout=None, stderr=sys.stderr):
 
         self.cmd = cmd
+	# hack around platform-specific extension for binaries
+	if self.cmd[0] in globalvar.grassCmd['script']:
+	    self.cmd[0] = self.cmd[0] + globalvar.EXT_SCT
+	else:
+	    self.cmd[0] = self.cmd[0] + globalvar.EXT_BIN
+
         self.stderr = stderr
 
         #
@@ -286,14 +351,14 @@
                            (' '.join(cmd), wait, self.returncode, self.cmdThread.isAlive()))
             if rerr is not None and self.returncode != 0:
                 if rerr is False: # GUI dialog
-                    try:
-                        raise CmdError, _("Execution failed: '%s'%s%s" 
-                                          "Details:%s%s") % (' '.join(self.cmd),
-                                                             os.linesep, os.linesep,
-                                                             os.linesep,
-                                                             self.PrintModuleOutput())
-                    except CmdError, e:
-                        print e
+                    raise CmdError(cmd=self.cmd,
+                                   message="%s '%s'%s%s%s %s%s" %
+                                   (_("Execution failed:"),
+                                    ' '.join(self.cmd),
+                                    os.linesep, os.linesep,
+                                    _("Details:"),
+                                    os.linesep,
+                                    self.PrintModuleOutput()))
                 elif rerr == sys.stderr: # redirect message to sys
                     stderr.write("Execution failed: '%s'" % (' '.join(self.cmd)))
                     stderr.write("%sDetails:%s%s" % (os.linesep,
@@ -423,16 +488,22 @@
 
         Thread.__init__(self)
         
-        self.cmd          = cmd
-        self.stdin        = stdin
-        self.stdout       = stdout
-        self.stderr       = stderr
+        self.cmd    = cmd
+        self.stdin  = stdin
+        self.stdout = stdout
+        self.stderr = stderr
 
-        self.module       = None
-        self.rerr         = ''
+        self.module = None
+        self.rerr   = ''
 
+        self._want_abort = False
+        self.startTime = None
+
+        self.setDaemon(True)
+        
     def run(self):
         """Run command"""
+        self.startTime = time.time()
         # TODO: wx.Exectute/wx.Process (?)
         self.module = Popen(self.cmd,
                             stdin=subprocess.PIPE,
@@ -471,35 +542,59 @@
             # make module stdout/stderr non-blocking
             out_fileno = self.module.stdout.fileno()
             # FIXME (MS Windows)
-            flags = fcntl.fcntl(out_fileno, fcntl.F_GETFL)
-            fcntl.fcntl(out_fileno, fcntl.F_SETFL, flags| os.O_NONBLOCK)
-            
+	    if not subprocess.mswindows:
+                flags = fcntl.fcntl(out_fileno, fcntl.F_GETFL)
+                fcntl.fcntl(out_fileno, fcntl.F_SETFL, flags| os.O_NONBLOCK)
+                
         if self.stderr:
             # make module stdout/stderr non-blocking
             out_fileno = self.module.stderr.fileno()
             # FIXME (MS Windows)
-            flags = fcntl.fcntl(out_fileno, fcntl.F_GETFL)
-            fcntl.fcntl(out_fileno, fcntl.F_SETFL, flags| os.O_NONBLOCK)
-
+	    if not subprocess.mswindows:
+                flags = fcntl.fcntl(out_fileno, fcntl.F_GETFL)
+                fcntl.fcntl(out_fileno, fcntl.F_SETFL, flags| os.O_NONBLOCK)
+                
         # wait for the process to end, sucking in stuff until it does end
         while self.module.poll() is None:
             time.sleep(.1)
+            if self._want_abort: # abort running process
+                if hasattr(self.stderr, "gmstc"):
+                    self.module.kill()
+                    # -> GMConsole
+                    wx.PostEvent(self.stderr.gmstc.parent, ResultEvent(None))
+                return 
             if self.stdout:
-                line = self.__read_all(self.module.stdout)
+                # line = self.__read_all(self.module.stdout)
+                line = recv_some(self.module, e=0, stderr=0)
                 self.stdout.write(line)
             if self.stderr:
-                line = self.__read_all(self.module.stderr)
+                # line = self.__read_all(self.module.stderr)
+                line = recv_some(self.module, e=0, stderr=1)
                 self.stderr.write(line)
 
         # get the last output
         if self.stdout:
-            line = self.__read_all(self.module.stdout)
+            # line = self.__read_all(self.module.stdout)
+            line = recv_some(self.module, e=0, stderr=0)
             self.stdout.write(line)
         if self.stderr:
-            line = self.__read_all(self.module.stderr)
+            # line = self.__read_all(self.module.stderr)
+            line = recv_some(self.module, e=0, stderr=1)
             self.stderr.write(line)
-            self.rerr = self.__parseString(line)
-        
+
+        self.rerr = self.__parseString(line)
+
+        if hasattr(self.stderr, "gmstc"):
+            # -> GMConsole
+            if self._want_abort: # abort running process
+                wx.PostEvent(self.stderr.gmstc.parent, ResultEvent(None))
+            else:
+                wx.PostEvent(self.stderr.gmstc.parent, ResultEvent(self))
+
+    def abort(self):
+        """Abort running process, used by main thread to signal an abort"""
+        self._want_abort = True
+
     def __parseString(self, string):
         """Parse line
 

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/globalvar.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/globalvar.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/globalvar.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -17,12 +17,27 @@
 """
 
 import os
+import sys
+import locale
 
-import utils
-utils.CheckForWx()
-import wx
+### recursive import problem 
+# import utils
+# utils.CheckForWx()
+try:
+    import wx
+except locale.Error, e:
+    print >> sys.stderr, "Unable to set locale:", e
+    os.environ['LC_ALL'] = ''
+    import wx
 import wx.lib.flatnotebook as FN
 
+try:
+    import subprocess
+except:
+    compatPath = os.path.join(globalvar.ETCWXDIR, "compat")
+    sys.path.append(compatPath)
+    import subprocess
+
 """
 Query layer (generated for example by selecting item in the Attribute Table Manager)
 Deleted automatically on re-render action
@@ -40,3 +55,44 @@
     FN.FNB_NODRAG | \
     FN.FNB_TABS_BORDER_SIMPLE 
 FNPageColor = wx.Colour(125,200,175)
+
+"""@brief File name extension binaries/scripts"""
+if subprocess.mswindows:
+    EXT_BIN = '.exe'
+    EXT_SCT = '.bat'
+else:
+    EXT_BIN = ''
+    EXT_SCT = ''
+
+def __getGRASSCmds(bin=True, scripts=True):
+    """
+    Create list of all available GRASS commands to use when
+    parsing string from the command line
+    """
+    gisbase = os.environ['GISBASE']
+    binlst = []
+    if bin is True:
+        binlst = os.listdir(os.path.join(gisbase, 'bin'))
+        if subprocess.mswindows:
+            for idx in range(len(binlst)):
+                binlst[idx] = binlst[idx].replace(EXT_BIN, '')
+                binlst[idx] = binlst[idx].replace(EXT_SCT, '')
+    sctlst = []
+    if scripts is True:
+        sctlst = sctlst + os.listdir(os.path.join(gisbase, 'scripts'))
+        if subprocess.mswindows:
+            for idx in range(len(binlst)):
+                binlst[idx] = binlst[idx].replace(EXT_BIN, '')
+                binlst[idx] = binlst[idx].replace(EXT_SCT, '')
+
+    # self.gcmdlst = self.gcmdlst + os.listdir(os.path.join(gisbase,'etc','gm','script'))
+
+    return binlst + sctlst
+
+"""@brief Collected GRASS-relared binaries/scripts"""
+grassCmd = {}
+grassCmd['all'] = __getGRASSCmds()
+grassCmd['script'] = __getGRASSCmds(bin=False)
+
+"""@Toolbar icon size"""
+toolbarSize = (24, 24)

Deleted: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grass-grc.dtd
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grass-grc.dtd	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grass-grc.dtd	2008-03-11 18:40:45 UTC (rev 30529)
@@ -1,57 +0,0 @@
-<!--	grass-grc.dtd
-
-	Copyright (C) 2007 by the GRASS Development Team
-	Author: Martin Landa <landa.martin gmail.com>
-	
-	This program is free software under the GPL (>=v2)
-	Read the file COPYING coming with GRASS for details.
--->
-
-
-<!--
-        a grass-grc defines workspace file content
--->
-
-<!ELEMENT grass-grc (grc)>
-
-<!ELEMENT grc (display*)>
-
-<!--    a display element defines map layer connected to given
-	map display widnow
--->
-<!ELEMENT display (group*, layer*)>
-
-<!--    group of map layers
--->
-<!ELEMENT group (layer*)>
-<!ATTLIST group	name	CDATA #REQUIRED>
-<!ATTLIST group	checked CDATA #REQUIRED>
-
-<!--    map layer
--->
-<!ELEMENT layer (task?)>
-<!ATTLIST layer	type	CDATA #REQUIRED>
-<!ATTLIST layer	name	CDATA #REQUIRED>
-<!ATTLIST layer	checked CDATA #REQUIRED>
-<!ATTLIST layer	opacity	CDATA #IMPLIED>
-
-<!--	task describes the interface of a single
-	GRASS command. 
--->
-<!ELEMENT task	        (parameter*, flag*)>
-<!ATTLIST task	name	CDATA #REQUIRED>
-
-<!--	a parameter must have a name and a value
--->
-<!ELEMENT parameter     (value)>
-<!ATTLIST parameter	name		CDATA #REQUIRED>
-
-<!--    value of parameter
--->
-<!ELEMENT value         (#PCDATA)>
-
-
-<!--    enabled flag
--->
-<!ELEMENT flag         EMPTY>
-<!ATTLIST flag         name            CDATA #REQUIRED>

Added: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grass-gxw.dtd
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grass-gxw.dtd	                        (rev 0)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grass-gxw.dtd	2008-03-11 18:40:45 UTC (rev 30529)
@@ -0,0 +1,57 @@
+<!--	grass-gxw.dtd
+
+	Copyright (C) 2007 by the GRASS Development Team
+	Author: Martin Landa <landa.martin gmail.com>
+	
+	This program is free software under the GPL (>=v2)
+	Read the file COPYING coming with GRASS for details.
+-->
+
+
+<!--
+        a grass-gxw defines workspace file content
+-->
+
+<!ELEMENT grass-gxw (gxw)>
+
+<!ELEMENT gxw (display*)>
+
+<!--    a display element defines map layer connected to given
+	map display widnow
+-->
+<!ELEMENT display (group*, layer*)>
+
+<!--    group of map layers
+-->
+<!ELEMENT group (layer*)>
+<!ATTLIST group	name	CDATA #REQUIRED>
+<!ATTLIST group	checked CDATA #REQUIRED>
+
+<!--    map layer
+-->
+<!ELEMENT layer (task?)>
+<!ATTLIST layer	type	CDATA #REQUIRED>
+<!ATTLIST layer	name	CDATA #REQUIRED>
+<!ATTLIST layer	checked CDATA #REQUIRED>
+<!ATTLIST layer	opacity	CDATA #IMPLIED>
+
+<!--	task describes the interface of a single
+	GRASS command. 
+-->
+<!ELEMENT task	        (parameter*, flag*)>
+<!ATTLIST task	name	CDATA #REQUIRED>
+
+<!--	a parameter must have a name and a value
+-->
+<!ELEMENT parameter     (value)>
+<!ATTLIST parameter	name		CDATA #REQUIRED>
+
+<!--    value of parameter
+-->
+<!ELEMENT value         (#PCDATA)>
+
+
+<!--    enabled flag
+-->
+<!ELEMENT flag         EMPTY>
+<!ATTLIST flag         name            CDATA #REQUIRED>

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grassenv.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grassenv.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/grassenv.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -32,11 +32,10 @@
     """Return GRASS variable or '' if variable is not defined"""
     # gisEnv = gcmd.Command(['g.gisenv'])
 
-    gisEnv = subprocess.Popen(['g.gisenv'],
+    gisEnv = subprocess.Popen(['g.gisenv' + globalvar.EXT_BIN],
                               stdin=None,
                               stdout=subprocess.PIPE,
-                              stderr=None,
-                              close_fds=True)
+                              stderr=None)
 
     for item in gisEnv.stdout.readlines():
         if var in item:

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/gselect.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/gselect.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/gselect.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -21,7 +21,9 @@
 import wx
 import wx.combo
 
+import globalvar
 import gcmd
+from preferences import globalSettings as UserSettings
 
 class SelectDialog(wx.Dialog):
     def __init__(self, parent, id=wx.ID_ANY, title='Select GIS element',
@@ -159,9 +161,7 @@
         curr_mapset = gcmd.Command(cmdlist).ReadStdOutput()[0]
 
         #mapsets in current location
-        cmdlist = ['g.mapsets', '-p']
-        mapsets = gcmd.Command(cmdlist).ReadStdOutput()[0].split(' ')
-
+        mapsets = UserSettings.Get(group='general', key='mapsetPath', subkey='value', internal=True)
         # map element types to g.mlist types
         elementdict = {'cell':'rast',
                        'raster':'rast',

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/location_wizard.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/location_wizard.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/location_wizard.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -208,11 +208,10 @@
             error = _("Location already exists in GRASS Database.")
 
         if error != '':
-            dlg = wx.MessageDialog(parent=self, message=_("Unable to create location <%s>.%s"
-                                                          "%s" % \
-                                                              (str(self.tlocation.GetValue()),
-                                                               os.linesep,
-                                                               error)),
+            dlg = wx.MessageDialog(parent=self, message="%s <%s>.%s%s" % (_("Unable to create location"),
+                                                                          str(self.tlocation.GetValue()),
+                                                                          os.linesep,
+                                                                          error),
                                    caption=_("Error"),  style=wx.OK | wx.ICON_ERROR)
             
             dlg.ShowModal()
@@ -245,7 +244,7 @@
                                      label=_("Select coordinate system"),
                                      style = wx.RB_GROUP)
         self.radio2 = wx.RadioButton(parent=self, id=wx.ID_ANY,
-                                     label=_("Select EPSG code for coordinate system"))
+                                     label=_("Select EPSG code of coordinate system"))
         self.radio3 = wx.RadioButton(parent=self, id=wx.ID_ANY,
                                      label=_("Use coordinate system of selected "
                                              "georeferenced file"))
@@ -253,7 +252,7 @@
                                      label=_("Create custom PROJ.4 parameters "
                                              "string for coordinate system"))
         self.radio5 = wx.RadioButton(parent=self, id=wx.ID_ANY,
-                                     label=_("Create arbitrary non-earth "
+                                     label=_("Use arbitrary non-earth "
                                              "coordinate system (XY)"))
         # layout
         self.sizer.AddGrowableCol(1)
@@ -344,7 +343,7 @@
                        flag=wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL,
                        border=5, pos=(1, 2))
 
-        self.sizer.Add(item=self.MakeLabel(_("Search in projection description:")),
+        self.sizer.Add(item=self.MakeLabel(_("Search in description:")),
                        flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
                        border=5, pos=(2, 1))
         self.sizer.Add(item=self.searchb,
@@ -525,7 +524,7 @@
             
         except StandardError, e:
             wx.MessageBox(parent=self,
-                          message=_("Unable to read list: %s ") % e,
+                          message=_("Unable to read list: %s") % e,
                           caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
 
     def OnColumnClick(self, event):
@@ -1114,7 +1113,7 @@
     def OnBrowse(self, event):
         """Choose file"""
         dlg = wx.FileDialog(self,
-                            _("Choose a georeferenced file"),
+                            _("Select georeferenced file"),
                             os.getcwd(), "", "*.*", wx.OPEN)
         if dlg.ShowModal() == wx.ID_OK:
             path = dlg.GetPath()
@@ -1145,7 +1144,7 @@
                                     style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
         self.lcode= self.MakeLabel(_("EPSG code:"),
                                     style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
-        self.lsearch = self.MakeLabel(_("Search in code description:"),
+        self.lsearch = self.MakeLabel(_("Search in description:"),
                                        style=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
 
         # text input
@@ -1317,7 +1316,7 @@
             self.epsglist.Populate(data, update=True)
         except StandardError, e:
             wx.MessageBox(parent=self,
-                          message=_("Unable to read EPGS codes: %s ") % e,
+                          message=_("Unable to read EPGS codes: %s") % e,
                           caption=_("Error"),  style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
 
 class CustomPage(TitledPage):
@@ -1436,13 +1435,13 @@
         self.sizer.Add(item=(10,20),
                        flag=wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
                        border=5, pos=(5, 0), span=(1, 2))
-        self.sizer.AddGrowableRow(6)
-        self.sizer.Add(item=self.MakeLabel(_("You can set the default extents "
-                                             "and resolution after creating new location%s"
-                                             "or you can set them during a working session.") % os.linesep,
-                                           style=wx.ALIGN_CENTER),
-                       flag=wx.ALIGN_CENTRE | wx.ALL, border=5, pos=(6, 0),
-                       span=(1, 2))
+        # self.sizer.AddGrowableRow(6)
+        #self.sizer.Add(item=self.MakeLabel(_("You can set the default extents "
+        #                                     "and resolution after creating new location%s"
+        #                                     "or you can set them during a working session.") % os.linesep,
+        #                                   style=wx.ALIGN_CENTER),
+        #               flag=wx.ALIGN_CENTRE | wx.ALL, border=5, pos=(6, 0),
+        #               span=(1, 2))
 
     def OnEnterPage(self,event):
         """
@@ -1460,7 +1459,7 @@
             self.lproj4string.SetLabel('')
         else:
             self.lproj4string.Show()
-            self.lproj4stringLabel.SetLabel(_("Proj4 definition:"))
+            self.lproj4stringLabel.SetLabel(_("PROJ.4 definition:"))
             if coordsys == 'proj':
                 self.lproj4string.SetLabel(self.parent.CreateProj4String())
             else:
@@ -1502,7 +1501,7 @@
 
     def OnFinish(self, event):
         dlg = wx.MessageDialog(parent=self.wizard,
-                               message=_("Do you want to create new location '%s'?") % location,
+                               message=_("Do you want to create GRASS location <%s>?") % location,
                                caption=_("Create new location?"),
                                style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
 
@@ -1614,7 +1613,7 @@
                 dlg = wx.MessageDialog(parent=self.parent,
                                        message=_("Do you want to set the default "
                                                  "region extents and resolution now?"),
-                                       caption=_("New location '%s' created") % self.location,
+                                       caption=_("Location <%s> created") % self.location,
                                        style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
                 dlg.CenterOnScreen()
                 if dlg.ShowModal() == wx.ID_YES:
@@ -1627,7 +1626,7 @@
 
             elif success == False:
                 dlg = wx.MessageDialog(parent=self.wizard,
-                                       message=_("Unable to create new location."),
+                                       message="%s." % _("Unable to create new location"),
                                        caption=_("Error"),
                                        style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
                 if dlg.ShowModal() == wx.ID_OK:
@@ -1636,10 +1635,9 @@
                 pass
         else:
             win = wx.MessageBox(parent=self.parent,
-                          message=_("Location wizard canceled.%s"
-                                    "New location not created.") % \
-                              os.linesep,
-                          caption=_("Location wizard"))
+                                message=_("Location wizard canceled. "
+                                          "Location not created."),
+                                caption=_("Location wizard"))
 
     def __readData(self):
         """Get georeferencing information from tables in $GISBASE/etc"""
@@ -1726,9 +1724,11 @@
         # location already exists?
         if os.path.isdir(os.path.join(database,location)):
             dlg = wx.MessageDialog(parent=self.wizard,
-                                   message=_("Unable to create new location: %s already exists")
-                                             % os.path.join(database, location),
-                                   caption=_("ERROR"),
+                                   message="%s <%s>: %s" % \
+                                       (_("Unable to create new location"),
+                                        os.path.join(database, location),
+                                        _("Location already exists in GRASS Database.")),
+                                   caption=_("Error"),
                                    style=wx.OK | wx.ICON_ERROR)
             dlg.ShowModal()
             dlg.Destroy()
@@ -1801,7 +1801,7 @@
 
         except OSError, e:
             dlg = wx.MessageDialog(parent=self.wizard,
-                                   message=_("Unable to create new location: %s") % e,
+                                   message="%s: %s" % (_("Unable to create new location"), e),
                                    caption=_("Error"),
                                    style=wx.OK | wx.ICON_ERROR)
             dlg.ShowModal()
@@ -1902,7 +1902,7 @@
         # should not happend
         if epsgcode == '':
             wx.MessageBox(parent=self,
-                          message=_("EPSG code missing. Unable to create new location"),
+                          message="%s: %s" % (_("Unable to create new location"), _("EPSG code missing.")),
                           caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
             return False
         
@@ -1921,7 +1921,7 @@
             dtrans = ''
             # open a dialog to select datum transform number
             dlg = wx.TextEntryDialog(self.wizard, dtoptions,
-                                     caption=_('Select the number of a datum transformation to use'),
+                                     caption=_('Select datum transformation'),
                                      defaultValue='1',
                                          style=wx.TE_WORDWRAP | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX|
                                      wx.RESIZE_BORDER |wx.VSCROLL |
@@ -1935,7 +1935,7 @@
                 if dtrans != '':
                     dlg.Destroy()
                 else:
-                    wx.MessageBox(_('You must select a datum transform'))
+                    wx.MessageBox(_('Datum transform is required.'))
                     return False
 
             cmdlist = ['g.proj', '-c',
@@ -1966,7 +1966,10 @@
         # this should not happen
         if not georeffile or not os.path.isfile(georeffile):
             dlg = wx.MessageBox(parent=self.wizard,
-                                message=_("Unable to create new location: could not find file %s") % georeffile,
+                                message="%s: %s ('%s')" % \
+                                    (_("Unable to create new location"),
+                                     _("file not found"),
+                                     georeffile),
                                 caption=("Error"), style=wx.OK | wx.ICON_ERROR)
             return False
 
@@ -2031,7 +2034,7 @@
         # buttons
         #
         self.bset = self.MakeButton(_("&Set region"), id=wx.ID_OK)
-        self.bcancel = self.MakeButton(_("Cancel"), id=wx.ID_CANCEL)
+        self.bcancel = wx.Button(self, id=wx.ID_CANCEL)
         self.bset.SetDefault()
 
         #
@@ -2063,7 +2066,7 @@
                 gcmd.Command(cmdlist)
         else:
             dlg = wx.MessageBox(parent=self,
-                                message=_('A valid location must be selected'),
+                                message=_('Invalid location selected.'),
                                 caption=_("Error"), style=wx.ID_OK | wx.ICON_ERROR)
             return
 

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/mapdisp.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/mapdisp.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -68,6 +68,7 @@
 from digit import GV_LINES            as Digit_Lines_Type
 from debug import Debug               as Debug
 from icon  import Icons               as Icons
+from preferences import globalSettings as UserSettings
 
 import images
 imagepath = images.__path__[0]
@@ -391,7 +392,7 @@
 
         Debug.msg(4, "BufferedWindow.OnPaint(): redrawAll=%s" % self.redrawAll)
 
-        dc = wx.BufferedPaintDC(self, self._buffer)
+        dc = wx.BufferedPaintDC(self, self.buffer)
 
         # we need to clear the dc BEFORE calling PrepareDC
         #bg = wx.Brush(self.GetBackgroundColour())
@@ -414,9 +415,9 @@
             if self.pdcVector:
                 self.pdcVector.DrawToDCClipped(dc, rgn)
 
-            self._bufferLast = None
+            self.bufferLast = None
         else: # do not redraw pdc and pdcVector
-            if self._bufferLast is None:
+            if self.bufferLast is None:
                 # draw to the dc
                 self.pdc.DrawToDC(dc)
 
@@ -424,11 +425,11 @@
                     self.pdcVector.DrawToDC(dc)
 
                 # store buffered image
-                # self._bufferLast = wx.BitmapFromImage(self._buffer.ConvertToImage())
-                self._bufferLast = dc.GetAsBitmap(wx.Rect(0, 0, self.Map.width, self.Map.height))
+                # self.bufferLast = wx.BitmapFromImage(self.buffer.ConvertToImage())
+                self.bufferLast = dc.GetAsBitmap(wx.Rect(0, 0, self.Map.width, self.Map.height))
 
             pdcLast = wx.PseudoDC()
-            pdcLast.DrawBitmap(bmp=self._bufferLast, x=0, y=0)
+            pdcLast.DrawBitmap(bmp=self.bufferLast, x=0, y=0)
             pdcLast.DrawToDC(dc)
 
         # draw temporary object on the foreground
@@ -452,8 +453,8 @@
         # Make new off screen bitmap: this bitmap will always have the
         # current drawing in it, so it can be used to save the image to
         # a file, or whatever.
-        self._buffer = wx.EmptyBitmap(max(1, self.Map.width), max(1,self.Map.height))
-        #self._buffer = wx.EmptyBitmap(mwidth, mheight)
+        self.buffer = wx.EmptyBitmap(max(1, self.Map.width), max(1,self.Map.height))
+        #self.buffer = wx.EmptyBitmap(mwidth, mheight)
 
         # get the image to be rendered
         self.img = self.GetImage()
@@ -488,11 +489,11 @@
         This draws the psuedo DC to a buffer that
         can be saved to a file.
         """
-        dc = wx.BufferedPaintDC(self, self._buffer)
+        dc = wx.BufferedPaintDC(self, self.buffer)
         self.pdc.DrawToDC(dc)
         if self.pdcVector:
             self.pdcVector.DrawToDC(dc)
-        self._buffer.SaveFile(FileName, FileType)
+        self.buffer.SaveFile(FileName, FileType)
 
     def GetOverlay(self):
         """
@@ -529,17 +530,33 @@
         """
         Updates the canvas anytime there is a change to the underlaying images
         or to the geometry of the canvas.
+
+        @param render render map layer composition
+        @param renderVector render vector map layer (digitizer)
+        @param counter reference to layer counter (progress bar)
         """
 
-        Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s, renderVector=%s" % \
-                   (render, renderVector))
+        start = time.clock()
 
+        if self.img is None:
+            render = True
+
         #
+        # initialize process bar
+        #
+        if render is True or renderVector is True:
+            self.parent.onRenderGauge.Show()
+            if self.parent.onRenderGauge.GetRange() > 0:
+                self.parent.onRenderGauge.SetValue(1)
+                self.parent.onRenderTimer.Start(100)
+            self.parent.onRenderCounter = 0
+
+        #
         # render background image if needed
         #
-        if render or self.img == None:
+        if render:
             self.Map.ChangeMapSize(self.GetClientSize())
-            self.mapfile = self.Map.Render(force=True)
+            self.mapfile = self.Map.Render(force=True, mapWindow=self.parent)
             self.img = self.GetImage() # id=99
             self.resize = False
 
@@ -618,12 +635,24 @@
         if len(self.polycoords) > 0:
             self.DrawLines(self.pdcTmp)
 
+        stop = time.clock()
+
         #
+        # hide process bar
+        #
+        if self.parent.onRenderGauge.GetRange() > 0:
+            self.parent.onRenderTimer.Stop()
+        self.parent.onRenderGauge.Hide()
+
+        #
         # update statusbar
         #
         self.Map.SetRegion()
         self.parent.StatusbarUpdate()
 
+        Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s, renderVector=%s -> time=%g" % \
+                   (render, renderVector, (stop-start)))
+
         return True
 
     def EraseMap(self):
@@ -641,7 +670,7 @@
         dc.SetBackground(wx.Brush("White"))
         dc.Clear()
 
-        self.dragimg = wx.DragImage(self._buffer)
+        self.dragimg = wx.DragImage(self.buffer)
         self.dragimg.BeginDrag((0, 0), self)
         self.dragimg.GetImageRect(moveto)
         self.dragimg.Move(moveto)
@@ -836,7 +865,9 @@
             # dragging anything else - rubber band box or line
             else:
                 self.mouse['end'] = event.GetPositionTuple()[:]
-                self.MouseDraw(pdc=self.pdcTmp)
+                if event.LeftIsDown():
+                    # draw box only when left mouse button is pressed
+                    self.MouseDraw(pdc=self.pdcTmp)
 
         # double click
         elif event.ButtonDClick():
@@ -887,7 +918,7 @@
                 map = digitToolbar.layers[digitToolbar.layerSelectedID].name
             except:
                 map = None
-                dlg = wx.MessageDialog(self, _("No vector map layer selected for editing"),
+                dlg = wx.MessageDialog(self, _("No vector map selected for editing."),
                                        _("Error"), wx.OK | wx.ICON_ERROR)
                 dlg.ShowModal()
                 dlg.Destroy()
@@ -919,10 +950,11 @@
                     self.UpdateMap(render=False) # redraw map
 
                     # add new record into atribute table
-                    if digitClass.settings["addRecord"]:
+                    if UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled') is True:
                         # select attributes based on layer and category
                         cats = {}
-                        cats[digitClass.settings["layer"]] = (digitClass.settings["category"],)
+                        cats[UserSettings.Get(group='vdigit', key="layer", subkey='value')] = \
+                                                              (UserSettings.Get(group='vdigit', key="category", subkey='value'), )
                         addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map,
                                                                    cats=cats,
                                                                    pos=posWindow,
@@ -960,7 +992,7 @@
                 self.moveIds   = [] 
                 if digitToolbar.action in ["moveVertex", "editLine"]:
                     # set pen
-                    self.pen = self.polypen = wx.Pen(colour=digitClass.settings["symbolHighlight"][1],
+                    self.pen = self.polypen = wx.Pen(colour=UserSettings.Get(group='vdigit', key="symbolHighlight", subkey='color'),
                                                      width=2, style=wx.SHORT_DASH)
                     self.pdcTmp.SetPen(self.polypen)
 
@@ -968,7 +1000,7 @@
                 pass
 
             elif digitToolbar.action in ["displayAttrs", "displayCats"]:
-                qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / self.Map.width)
+                qdist = digitClass.driver.GetThreshold(type='selectThresh')
                 coords = (east, north)
                 if digitToolbar.action == "displayAttrs":
                     # select attributes based on coordinates (all layers)
@@ -1169,7 +1201,13 @@
             pos2 = self.Pixel2Cell(self.mouse['end'])
 
             if hasattr(self, "moveBegin"):
-                self.moveCoords = pos2
+                if len(digitClass.driver.GetSelected()) == 0:
+                    self.moveCoords = pos2
+                else:
+                    dx = pos2[0] - pos1[0]
+                    dy = pos2[1] - pos1[1]
+                    self.moveCoords = (self.moveCoords[0] + dx,
+                                       self.moveCoords[1] + dy)
                 # eliminate initial mouse moving efect
                 self.mouse['begin'] = self.mouse['end'] 
 
@@ -1241,12 +1279,16 @@
 
                 else:
                     # -> moveLine || deleteLine, etc. (select by point/box)
-                    nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
-                                                                   digitClass.GetSelectType())
-                    if nselected == 0:
-                        if digitClass.driver.SelectLineByPoint(pos1,
-                                                               digitClass.GetSelectType()) is not None:
-                            nselected = 1
+                    if digitToolbar.action == 'moveLine' and \
+                           len(digitClass.driver.GetSelected()) > 0:
+                        nselected = 0
+                    else:
+                        nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
+                                                                       digitClass.GetSelectType())
+                        if nselected == 0:
+                            if digitClass.driver.SelectLineByPoint(pos1,
+                                                                   digitClass.GetSelectType()) is not None:
+                                nselected = 1
 
                 if nselected > 0:
                     if digitToolbar.action in ["moveLine", "moveVertex"]:
@@ -1285,7 +1327,7 @@
                                        size=5)
 
             elif digitToolbar.action == "copyLine":
-                if digitClass.settings['backgroundMap'] == '':
+                if UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value') == '':
                     # no background map -> copy from current vector map layer
                     nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
                                                                    digitClass.GetSelectType())
@@ -1299,12 +1341,12 @@
                     # copy features from background map
                     self.copyIds = digitClass.SelectLinesFromBackgroundMap(pos1, pos2)
                     if len(self.copyIds) > 0:
-                        color = digitClass.settings['symbolHighlight'][1]
+                        color = UserSettings.Get(group='vdigit', key='symbolHighlight', subkey='color')
                         colorStr = str(color[0]) + ":" + \
                             str(color[1]) + ":" + \
                             str(color[2]) + ":"
                         dVectTmp = ['d.vect',
-                                    'map=%s' % digitClass.settings['backgroundMap'],
+                                    'map=%s' % UserSettings.Get(group='vdigit', key='backgroundMap', subkey='value'),
                                     'cats=%s' % utils.ListOfCatsToRange(self.copyIds),
                                     '-i',
                                     'color=%s' % colorStr,
@@ -1417,6 +1459,29 @@
                 r.Inflate(4,4)
                 self.RefreshRect(r, False)
 
+        digitToolbar = self.parent.digittoolbar
+        if digitToolbar:
+            digitClass = self.parent.digit
+            # digitization tool (confirm action)
+            if digitToolbar.action in ["moveLine", "moveVertex"] and \
+                    hasattr(self, "moveBegin"):
+
+                pTo = self.Pixel2Cell(event.GetPositionTuple())
+                pFrom = self.moveCoords
+                move = (pTo[0]-pFrom[0], pTo[1]-pFrom[1])
+                
+                if digitToolbar.action == "moveLine":
+                    # move line
+                    digitClass.MoveSelectedLines(move)
+                elif digitToolbar.action == "moveVertex":
+                    # move vertex
+                    digitClass.MoveSelectedVertex(pFrom,
+                                                  move)
+
+                del self.moveBegin
+                del self.moveCoords
+                del self.moveIds
+
         event.Skip()
 
     def OnRightUp(self, event):
@@ -1437,7 +1502,7 @@
                     map = digitToolbar.layers[digitToolbar.layerSelectedID].name
                 except:
                     map = None
-                    dlg = wx.MessageDialog(self, _("No vector map layer is selected"),
+                    dlg = wx.MessageDialog(self, _("No vector map selected for editing."),
                                            _("Error"), wx.OK | wx.ICON_ERROR)
                     dlg.ShowModal()
                     dlg.Destroy()
@@ -1458,14 +1523,15 @@
                     self.UpdateMap(render=False)
 
                     # add new record into atribute table
-                    if digitClass.settings["addRecord"]:
+                    if UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled') is True:
                         offset   = 5
                         posWindow = self.ClientToScreen((position[0] + offset,
                                                          position[1] + offset))
 
                         # select attributes based on layer and category
                         cats = {}
-                        cats[digitClass.settings["layer"]] = (digitClass.settings["category"],)
+                        cats[UserSettings.Get(group='vdigit', key="layer", subkey='value')] = \
+                                                              (UserSettings.Get(group='vdigit', key="category", subkey='value'), )
                         addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map,
                                                                    cats=cats,
                                                                    pos=posWindow,
@@ -1482,24 +1548,6 @@
             elif digitToolbar.action == "deleteLine":
                 # -> delete selected vector features
                 digitClass.DeleteSelectedLines()
-            elif digitToolbar.action in ["moveLine", "moveVertex"] and \
-                    hasattr(self, "moveBegin"):
-
-                pTo = self.Pixel2Cell(event.GetPositionTuple())
-                pFrom = self.moveCoords
-                move = (pTo[0]-pFrom[0], pTo[1]-pFrom[1])
-
-                if digitToolbar.action == "moveLine":
-                    # move line
-                    digitClass.MoveSelectedLines(move)
-                elif digitToolbar.action == "moveVertex":
-                    # move vertex
-                    digitClass.MoveSelectedVertex(pFrom,
-                                                  move)
-
-                del self.moveBegin
-                del self.moveCoords
-                del self.moveIds
             elif digitToolbar.action == "splitLine":
                 # split line
                 digitClass.SplitLine(self.Pixel2Cell(self.mouse['begin']))
@@ -1910,7 +1958,12 @@
         if layer.type in ('raster', 'rgb', 'his', 'shaded', 'arrow'):
             self.Map.region = self.Map.GetRegion(rast="%s" % layer.name)
         elif layer.type in ('vector', 'thememap', 'themechart'):
-            self.Map.region = self.Map.GetRegion(vect="%s" % layer.name)
+            if self.parent.digit and layer.name == self.parent.digit.map and \
+               self.parent.digit.type == 'vdigit':
+                w, s, b, e, n, t = self.parent.digit.driver.GetMapBoundingBox()
+                self.Map.region = self.Map.GetRegion(n=n, s=s, w=w, e=e)
+            else:
+                self.Map.region = self.Map.GetRegion(vect="%s" % layer.name)
         else:
             return
 
@@ -1984,7 +2037,8 @@
 
         wind = dlg.wind
 
-        p = gcmd.Command (["g.region", "-ugp", "region=%s" % wind])
+        p = gcmd.Command (["g.region",
+	                   "-ugp", "region=%s" % wind])
 
         if p.returncode == 0:
             output = p.ReadStdOutput()
@@ -2023,7 +2077,8 @@
         if windpath and not os.path.exists(windpath):
             self.SaveRegion(wind)
         elif windpath and os.path.exists(windpath):
-            overwrite = wx.MessageBox(_("Region file <%s>already exists.\nDo you want to overwrite it?") % (wind),
+            overwrite = wx.MessageBox(_("Region file <%s> already exists. "
+                                        "Do you want to overwrite it?") % (wind),
                                       _("Warning"), wx.YES_NO)
             if (overwrite == wx.YES):
                 self.SaveRegion(wind)
@@ -2126,8 +2181,9 @@
         #
         self.SetClientSize(size)
         self.iconsize = (16, 16)
-        self.SetIcon(wx.Icon(os.path.join(imagepath,'grass.map.gif'), wx.BITMAP_TYPE_ANY))
 
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, 'grass_map.ico'), wx.BITMAP_TYPE_ICO))
+
         #
         # Fancy gui
         #
@@ -2155,6 +2211,7 @@
                                                  "Geometry",
                                                  "Map scale"])
         self.statusText = "Coordinates"
+	self.toggleStatus.SetStringSelection(self.statusText)
         self.statusbar.Bind(wx.EVT_CHOICE, self.OnToggleStatus, self.toggleStatus)
         # auto-rendering checkbox
         self.autoRender = wx.CheckBox(parent=self.statusbar, id=wx.ID_ANY,
@@ -2176,6 +2233,12 @@
                                     size=(150, -1))
         self.mapScale.Hide()
         self.statusbar.Bind(wx.EVT_TEXT_ENTER, self.OnChangeMapScale, self.mapScale)
+        # on-render gauge
+        self.onRenderGauge = wx.Gauge(parent=self.statusbar, id=wx.ID_ANY,
+                                      range=0, style=wx.GA_HORIZONTAL)
+        self.onRenderGauge.Hide()
+        self.Bind(wx.EVT_TIMER, self.TimerOnRender)
+        self.onRenderTimer = wx.Timer(self)
 
         self.Map.SetRegion() # set region
 
@@ -2361,18 +2424,21 @@
 
         event.Skip()
 
-    def ReDraw(self, event):
+    def OnDraw(self, event):
         """
         Redraw button clicked
         """
-        Debug.msg(3, "BufferedWindow.ReDraw():")
         self.MapWindow.UpdateMap(render=False)
 
-    def ReRender(self, event):
+    def TimerOnRender(self, event):
+        """Update process bar"""
+        self.onRenderGauge.SetValue(self.onRenderCounter)
+
+    def OnRender(self, event):
         """
         Rerender button clicked
         """
-        Debug.msg(3, "BufferedWindow.ReRender():")
+        # redraw map composition
         qlayer = self.Map.GetListOfLayers(l_name=globalvar.QUERYLAYER)
         for layer in qlayer:
             self.Map.DeleteLayer(layer)
@@ -2478,7 +2544,7 @@
     def OnToggleRender(self, event):
         """Enable/disable auto-rendering"""
         if self.autoRender.GetValue():
-            self.ReRender(None)
+            self.OnRender(None)
 
     def OnToggleShowRegion(self, event):
         """Show/Hide extent in map canvas"""
@@ -2490,7 +2556,7 @@
 
         # redraw map if auto-rendering is enabled
         if self.autoRender.GetValue():
-            self.ReRender(None)
+            self.OnRender(None)
 
 
     def OnToggleStatus(self, event):
@@ -2600,20 +2666,27 @@
         # reposition checkbox
         widgets = [(0, self.showRegion),
                    (0, self.mapScale),
+                   (0, self.onRenderGauge),
                    (1, self.toggleStatus),
                    (2, self.autoRender)]
         for idx, win in widgets:
             rect = self.statusbar.GetFieldRect(idx)
-            if idx == 0: # show region / mapscale
+            if idx == 0: # show region / mapscale / process bar
+                # -> size
                 wWin, hWin = win.GetBestSize()
+                if win == self.onRenderGauge:
+                    wWin = rect.width - 6
+                # -> position
                 if win == self.showRegion:
-                    x, y = rect.x + rect.width - wWin, rect.y-1
+                    x, y = rect.x + rect.width - wWin, rect.y - 1
                 else:
-                    x, y = rect.x + 3, rect.y-1
-                w, h = wWin, rect.height+2
+                    x, y = rect.x + 3, rect.y - 1
+                w, h = wWin, rect.height + 2
             else: # choice || auto-rendering
-                x, y = rect.x, rect.y-1
-                w, h = rect.width, rect.height+2
+                x, y = rect.x, rect.y - 1
+                w, h = rect.width, rect.height + 2
+		if idx == 2:
+		    x += 5
 
             win.SetPosition((x, y))
             win.SetSize((w, h))
@@ -2723,9 +2796,8 @@
 
         if not self.tree.GetSelections():
             dlg = wx.MessageDialog(parent=self,
-                                   message=_('You must select a map layer in the '
-                                             'Layer Manager to query'),
-                                   caption=_('Nothing to query'),
+                                   message=_('No map layer selected for querying.'),
+                                   caption=_('Message'),
                                    style=wx.OK | wx.ICON_INFORMATION)
             dlg.ShowModal()
             dlg.Destroy()
@@ -2997,7 +3069,7 @@
                         ovltype=ovltype,
                         cmd='d.barscale',
                         drawid=id,
-                        checktxt = _("Show/hide scale and arrow"),
+                        checktxt = _("Show/hide scale and North arrow"),
                         ctrltxt = _("scale object"),
                         params = params)
 
@@ -3231,8 +3303,8 @@
 
         box = wx.BoxSizer(wx.HORIZONTAL)
         label = wx.StaticText(parent=self, id=wx.ID_ANY,
-                              label=_("Drag %s with mouse in pointer mode\nto position. "
-                                      "Double-click to change options" % ctrltxt))
+                              label=_("Drag %s with mouse in pointer mode to position. "
+                                      "Double-click to change options." % ctrltxt))
         box.Add(item=label, proportion=0,
                 flag=wx.ALIGN_CENTRE|wx.ALL, border=5)
         sizer.Add(item=box, proportion=0,
@@ -3492,7 +3564,7 @@
     def watcher(self):
         """Redraw, if new layer appears"""
         if self.redraw:
-            self.mapFrm.ReDraw(None)
+            self.mapFrm.OnDraw(None)
         self.redraw = False
         return
 # end of class MapApp

Added: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/mcalc_builder.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/mcalc_builder.py	                        (rev 0)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/mcalc_builder.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -0,0 +1,431 @@
+"""
+MODULE:    mcalc_builder.py
+
+CLASSES:
+    * MapCalcFrame
+
+PURPOSE:   GRASS builds r.mapcalc statements
+
+           Usage:
+           mcalc_builder
+
+AUTHOR(S): GRASS Development Team
+           Original author: Michael Barton, Arizona State University
+
+COPYRIGHT: (C) 2008 by the GRASS Development Team
+
+           This program is free software under the GNU General Public
+           License (>=v2). Read the file COPYING that comes with GRASS
+           for details.
+"""
+
+import wx
+import os,sys
+import time
+
+import grassenv
+import gcmd
+import gselect
+import subprocess
+
+imagePath = os.path.join( os.getenv("GISBASE"), "etc", "wxpython")
+sys.path.append(imagePath)
+import images
+imagepath = images.__path__[0]
+sys.path.append(imagepath)
+
+class MapCalcFrame(wx.Frame):
+    """
+    Mapcalc Frame class. Calculator-style window to create
+    and run r.mapcalc statements
+    """
+    def __init__(self, parent, id, title, pos=wx.DefaultPosition,
+                 size=wx.DefaultSize, style=wx.TAB_TRAVERSAL|wx.DEFAULT_FRAME_STYLE,
+                 dimension=2):
+
+        wx.Frame.__init__(self, parent, id, title, pos, size,
+                          style)
+        
+        self.Centre(wx.BOTH)
+
+        if dimension == 3:
+            self.SetTitle(_("GRASS %s Map Calculator") % "3D" )
+        else:
+            self.SetTitle(_("GRASS %s Map Calculator") % "2D" )
+
+        #
+        # variables
+        #
+        self.parent = parent
+        self.heading = 'mapcalc statement'
+        self.newmap = ''
+        self.dimension = dimension
+        self.funct_list = [
+                        'abs(x)',
+                        'acos(x)',
+                        'asin(x)',
+                        'atan(x)',
+                        'atan(x,y)',
+                        'cos(x)',
+                        'double(x)',
+                        'eval([x,y,...,]z)',
+                        'exp(x)',
+                        'exp(x,y)',
+                        'float(x)',
+                        'graph(x,x1,y1[x2,y2..])',
+                        'if(x)',
+                        'if(x,a)',
+                        'if(x,a,b)',
+                        'if(x,a,b,c)',
+                        'int(x)',
+                        'isnull(x)',
+                        'log(x)',
+                        'log(x,b)',
+                        'max(x,y[,z...])',
+                        'median(x,y[,z...])',
+                        'min(x,y[,z...])',
+                        'mode(x,y[,z...])',
+                        'not(x)',
+                        'pow(x,y)',
+                        'rand(a,b)',
+                        'round(x)',
+                        'sin(x)',
+                        'sqrt(x)',
+                        'tan(x)',
+                        'xor(x,y)',
+                        'row()',
+                        'col()',
+                        'x()',
+                        'y()',
+                        'ewres()',
+                        'nsres()',
+                        'null()'
+                        ]
+        
+        if self.dimension == 3:
+            indx = self.funct_list.index('y()') +1
+            self.funct_list.insert(indx, 'z()')
+            indx = self.funct_list.index('nsres()') +1
+            self.funct_list.insert(indx, 'tbres()')
+            maplabel = 'volume'
+            element = 'rast3d'
+        else:
+            maplabel = 'map'
+            element = 'cell'
+
+        #
+        # Buttons
+        #
+        self.btn_clear = wx.Button(self, -1, "Clear")
+        self.btn_help = wx.Button(self, -1, "Help")
+        self.btn_run = wx.Button(self, -1, "Run")
+        self.btn_run.SetDefault()
+        self.btn_close = wx.Button(self, -1, "Close")
+
+        self.btn_pow = wx.Button(self, -1, "^")
+        self.btn_pow.SetToolTipString('exponent')
+        self.btn_div = wx.Button(self, -1, "/")
+        self.btn_div.SetToolTipString('divide')
+        self.btn_add = wx.Button(self, -1, "+")
+        self.btn_add.SetToolTipString('add')
+        self.btn_minus = wx.Button(self, -1, "-")
+        self.btn_minus.SetToolTipString('subtract')
+        self.btn_mod = wx.Button(self, -1, "%")
+        self.btn_mod.SetToolTipString('modulus')
+        self.btn_mult = wx.Button(self, -1, "*")
+        self.btn_mult.SetToolTipString('multiply')
+
+        self.btn_paren = wx.Button(self, -1, "( )") 
+
+        self.btn_lshift = wx.Button(self, -1, "<<")
+        self.btn_lshift.SetToolTipString('left shift')
+        self.btn_rshift = wx.Button(self, -1, ">>")
+        self.btn_rshift.SetToolTipString('right shift')
+        self.btn_rshiftu = wx.Button(self, -1, ">>>")
+        self.btn_rshiftu.SetToolTipString('right shift (unsigned)')
+        self.btn_gt = wx.Button(self, -1, ">")
+        self.btn_gt.SetToolTipString('greater than')
+        self.btn_gteq = wx.Button(self, -1, ">=")
+        self.btn_gteq.SetToolTipString('greater than or equal to')
+        self.btn_lt = wx.Button(self, -1, "<")
+        self.btn_lt.SetToolTipString('less than or equal to')
+        self.btn_lteq = wx.Button(self, -1, "<=")
+        self.btn_lteq.SetToolTipString('less than')
+        self.btn_eq = wx.Button(self, -1, "==")
+        self.btn_eq.SetToolTipString('equal to')
+        self.btn_noteq = wx.Button(self, -1, "!=")
+        self.btn_noteq.SetToolTipString('not equal to')
+
+        self.btn_compl = wx.Button(self, -1, "~")
+        self.btn_compl.SetToolTipString("one's complement")
+        self.btn_not = wx.Button(self, -1, "!")
+        self.btn_not.SetToolTipString("NOT")
+        self.btn_andbit = wx.Button(self, -1, '&')
+        self.btn_andbit.SetToolTipString("bitwise AND")
+        self.btn_orbit = wx.Button(self, -1, "|")
+        self.btn_orbit.SetToolTipString("bitwise OR")
+        self.btn_and = wx.Button(self, -1, "&&&")
+        self.btn_and.SetToolTipString('logical AND')
+        self.btn_andnull = wx.Button(self, -1, "&&&&&")
+        self.btn_andnull.SetToolTipString('logical AND (ignores NULLs')
+        self.btn_or = wx.Button(self, -1, "||")
+        self.btn_or.SetToolTipString('logical OR')
+        self.btn_ornull = wx.Button(self, -1, "|||")
+        self.btn_ornull.SetToolTipString('logical OR (ignores NULLs')
+        self.btn_cond = wx.Button(self, -1, "?:") 
+        self.btn_cond.SetToolTipString('conditional')
+        
+        #
+        # Text area
+        #
+        self.text_mcalc = wx.TextCtrl(self, -1, '', size=(-1,75),style=wx.TE_MULTILINE)
+        
+        #
+        # Map and function insertion text and ComboBoxes
+        self.newmaplabel = wx.StaticText(self, -1, 'Name of new %s to create' % maplabel)
+        self.newmaptxt = wx.TextCtrl(self, wx.ID_ANY, size=(250,-1))
+        self.mapsellabel = wx.StaticText(self, -1, 'Insert existing %s' % maplabel)
+        self.mapselect = gselect.Select(self, wx.ID_ANY, size=(250,-1),
+                                        type=element, multiple=False)
+        self.functlabel = wx.StaticText(self, -1, 'Insert mapcalc function')
+        self.function = wx.ComboBox(self, wx.ID_ANY, "", (-1,-1), 
+                         (250, -1), self.funct_list, wx.CB_DROPDOWN
+                         | wx.CB_READONLY
+                         | wx.TE_PROCESS_ENTER
+                         #| wx.CB_SORT
+                         )
+        #
+        # Bindings
+        #
+        self.btn_compl.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_not.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_pow.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_div.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_add.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_minus.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_mod.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_mult.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_lshift.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_rshift.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_rshiftu.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_gt.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_gteq.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_lt.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_lteq.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_eq.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_noteq.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_andbit.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_orbit.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_and.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_andnull.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_or.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_ornull.Bind(wx.EVT_BUTTON, self.AddMark)        
+        self.btn_cond.Bind(wx.EVT_BUTTON, self.AddMark)
+        self.btn_paren.Bind(wx.EVT_BUTTON, self.AddMark)
+        
+        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
+        self.btn_clear.Bind(wx.EVT_BUTTON, self.OnClear)
+        self.btn_run.Bind(wx.EVT_BUTTON, self.OnMCalcRun)
+        self.btn_help.Bind(wx.EVT_BUTTON, self.OnHelp)
+        
+        self.newmaptxt.Bind(wx.EVT_TEXT, self.OnNewmap)
+        
+        #self.mapselect.Bind(wx.EVT_COMBOBOX, self.OnSelect)
+        self.mapselect.Bind(wx.EVT_TEXT, self.OnSelect)
+        #self.mapselect.Bind(wx.EVT_TEXT_ENTER, self.OnSelect)
+        self.function.Bind(wx.EVT_COMBOBOX, self.OnSelect)
+        #self.function.Bind(wx.EVT_TEXT, self.OnSelect)
+        self.function.Bind(wx.EVT_TEXT_ENTER, self.OnSelect)
+
+        self.__doLayout()
+
+    def __doLayout(self):
+        pagesizer = wx.BoxSizer(wx.VERTICAL)
+        
+        controlsizer = wx.BoxSizer(wx.HORIZONTAL)
+        btnpanelsizer = wx.GridBagSizer(1,1)
+
+        buttonsizer1 = wx.GridBagSizer(5,1)
+        buttonsizer1.Add(self.btn_add, (0,0))
+        buttonsizer1.Add(self.btn_minus, (0,1))
+        buttonsizer1.Add(self.btn_mod, (5,0))
+        buttonsizer1.Add(self.btn_mult, (1,0))
+        buttonsizer1.Add(self.btn_div, (1,1))
+        buttonsizer1.Add(self.btn_pow, (5,1))
+        buttonsizer1.Add(self.btn_gt, (2,0))
+        buttonsizer1.Add(self.btn_gteq, (2,1))
+        buttonsizer1.Add(self.btn_eq, (4,0))
+        buttonsizer1.Add(self.btn_lt, (3,0))
+        buttonsizer1.Add(self.btn_lteq, (3,1))
+        buttonsizer1.Add(self.btn_noteq, (4,1))
+
+        buttonsizer2 = wx.GridBagSizer(5,1)
+        buttonsizer2.Add(self.btn_and, (0,0))
+        buttonsizer2.Add(self.btn_andbit, (1,0))
+        buttonsizer2.Add(self.btn_andnull, (2,0))
+        buttonsizer2.Add(self.btn_or, (0,1))
+        buttonsizer2.Add(self.btn_orbit, (1,1))
+        buttonsizer2.Add(self.btn_ornull, (2,1))
+        buttonsizer2.Add(self.btn_lshift, (3,0))
+        buttonsizer2.Add(self.btn_rshift, (3,1))
+        buttonsizer2.Add(self.btn_rshiftu, (4,0))
+        buttonsizer2.Add(self.btn_cond, (5,0))
+        buttonsizer2.Add(self.btn_compl, (5,1))
+        buttonsizer2.Add(self.btn_not, (4,1))
+
+        buttonsizer3 = wx.GridBagSizer(7, 1)
+        buttonsizer3.Add(self.newmaplabel, (0,0), (1,2), wx.ALIGN_CENTER)
+        buttonsizer3.Add(self.newmaptxt, (1,0), (1,2), wx.TOP, 4)
+        buttonsizer3.Add(self.mapsellabel, (2,0), (1,2), wx.ALIGN_CENTER)
+        buttonsizer3.Add(self.mapselect, (3,0), (1,2))
+        buttonsizer3.Add(self.functlabel, (4,0), (1,2), wx.ALIGN_CENTER)
+        buttonsizer3.Add(self.function, (5,0), (1,2))
+        buttonsizer3.Add(self.btn_paren, (6,0), (1,1), wx.ALIGN_CENTER)
+        buttonsizer3.Add(self.btn_clear, (6,1), (1,1), wx.ALIGN_CENTER)
+        
+        buttonsizer4 = wx.GridSizer(4, 3, 3, 3)
+        buttonsizer4.Add(self.btn_run,0,wx.RIGHT,5)
+        buttonsizer4.Add(self.btn_close,0,wx.RIGHT,5)
+        buttonsizer4.Add(self.btn_help,0,wx.RIGHT,5)
+        
+        label = wx.StaticText(self, -1, 'Mapcalc operators')
+
+        btnpanelsizer.Add(label, (0,0), (1,2), wx.ALIGN_CENTER)
+        btnpanelsizer.Add(buttonsizer1, (1,0), (1,1), wx.RIGHT|wx.TOP, 5)
+        btnpanelsizer.Add(buttonsizer2, (1,1), (1,1), wx.LEFT|wx.TOP, 5)
+
+        controlsizer.Add(btnpanelsizer, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.RIGHT, border=20)
+        controlsizer.Add(buttonsizer3, proportion=0)
+        
+        pagesizer.Add(controlsizer, flag=wx.EXPAND|wx.ALL,border=10)        
+        pagesizer.Add(self.text_mcalc, flag=wx.EXPAND|wx.ALL,border=5)
+        pagesizer.Add(buttonsizer4, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, border=5)
+        self.SetAutoLayout(True)
+        self.SetSizer(pagesizer)
+        pagesizer.Fit(self)
+        #pagesizer.SetSizeHints(self)
+        self.Layout()
+        self.Show(True)
+
+    def AddMark(self,event):
+        """
+        Sends operators to insertion method
+        """
+        
+        if event.GetId() == self.btn_compl.GetId(): mark = "~"
+        elif event.GetId() == self.btn_not.GetId(): mark = "!"
+        elif event.GetId() == self.btn_pow.GetId(): mark = "^"
+        elif event.GetId() == self.btn_div.GetId(): mark = "/"
+        elif event.GetId() == self.btn_add.GetId(): mark = "+"
+        elif event.GetId() == self.btn_minus.GetId(): mark = "-"
+        elif event.GetId() == self.btn_mod.GetId(): mark = "%"
+        elif event.GetId() == self.btn_mult.GetId(): mark = "*"
+        elif event.GetId() == self.btn_lshift.GetId(): mark = "<<"
+        elif event.GetId() == self.btn_rshift.GetId(): mark = ">>"
+        elif event.GetId() == self.btn_rshiftu.GetId(): mark = ">>>"
+        elif event.GetId() == self.btn_gt.GetId(): mark = ">"
+        elif event.GetId() == self.btn_gteq.GetId(): mark = ">="
+        elif event.GetId() == self.btn_lt.GetId(): mark = "<"
+        elif event.GetId() == self.btn_lteq.GetId(): mark = "<="
+        elif event.GetId() == self.btn_eq.GetId(): mark = "=="
+        elif event.GetId() == self.btn_noteq.GetId(): mark = "!="
+        elif event.GetId() == self.btn_andbit.GetId(): mark = "&"
+        elif event.GetId() == self.btn_orbit.GetId(): mark = "|"
+        elif event.GetId() == self.btn_or.GetId(): mark =  "||"
+        elif event.GetId() == self.btn_ornull.GetId(): mark = "|||"
+        elif event.GetId() == self.btn_and.GetId(): mark = "&&"
+        elif event.GetId() == self.btn_andnull.GetId(): mark = "&&&"
+        elif event.GetId() == self.btn_cond.GetId(): mark = "?:"
+        elif event.GetId() == self.btn_paren.GetId(): mark = "()"        
+        self.__addSomething(mark)
+        
+    def OnNewmap(self, event):
+        self.newmap = event.GetString()
+
+    def OnSelect(self, event):
+        """
+        Gets raster map or function selection and send it to insertion method
+        """
+        item = event.GetString()
+        self.__addSomething(item)
+        self.text_mcalc.SetFocus()
+
+    def __addSomething(self,what):
+        """
+        Inserts operators, map names, and functions into text area
+        """
+        self.text_mcalc.SetFocus()
+        mcalcstr = self.text_mcalc.GetValue()
+        newmcalcstr = ''
+        position = self.text_mcalc.GetInsertionPoint()
+        
+        selection = self.text_mcalc.GetSelection()
+
+        newmcalcstr = mcalcstr[:position]
+        
+        try:
+            if newmcalcstr[-1] != " ":
+                newmcalcstr += " "
+        except:
+            pass
+        newmcalcstr += what
+        position_offset = len(what)
+        newmcalcstr += " "+mcalcstr[position:]
+
+        self.text_mcalc.SetValue(newmcalcstr)
+        self.text_mcalc.SetInsertionPoint(position+position_offset)
+        self.text_mcalc.Update()
+
+    def OnMCalcRun(self,event):
+        """
+        Builds and runs r.mapcalc statement
+        """
+        if self.newmap == '':
+            wx.MessageBox("You must enter the name of a new map to create")
+            return
+        
+        if self.text_mcalc.GetValue() == '':
+            wx.MessageBox("You must enter a mapcalc statement to create a new map")
+            return
+
+        try:
+            mctxt = self.text_mcalc.GetValue().strip().replace("\n"," ")
+            mctxt = mctxt.replace(" ","")
+            if self.dimension == 3:
+                cmdlist = ["r3.mapcalc"," %s=%s" % (self.newmap,mctxt)]
+            else:
+                cmdlist = ["r.mapcalc"," %s=%s" % (self.newmap,mctxt)]
+
+            p = gcmd.Command(cmdlist)
+            if p.returncode == 0:
+                wx.MessageBox("Map %s created successfully" % self.newmap)
+        except:
+            pass
+
+    def OnClear(self, event):
+        """
+        Clears text area
+        """
+        self.text_mcalc.SetValue("")
+        
+    def OnHelp(self, event):
+        """
+        Launches r.mapcalc help
+        """
+        cmdlist = ['g.manual','r.mapcalc']
+        gcmd.Command(cmdlist)
+
+    def OnClose(self,event):
+        self.Destroy()
+
+if __name__ == "__main__":
+
+    if len(sys.argv) != 2:
+        print >>sys.stderr, __doc__
+        sys.exit()
+
+    app = wx.App(0)
+    sqlb = SQLFrame(None, -1, 'SQL Builder',sys.argv[1])
+    app.MainLoop()
+
+

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/menudata.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/menudata.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/menudata.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -27,12 +27,12 @@
         return [(
           ("File", (
               ("Workspace", (
-                 ("New", "Create new workspace file (erase current workspace settings first)", "self.OnWorkspaceNew", ""),
-                 ("Open", "Open existing workspace file", "self.OnWorkspaceOpen", ""),
-                 ("Load", "Load map layers into layer tree", "self.OnWorkspaceLoad", ""),
-                 ("Save", "Save current workspace to file", "self.OnWorkspaceSave", ""),
-                 ("Save as", "Save current workspace as", "self.OnWorkspaceSaveAs", ""),
-                 ("Close", "Close selected workspace file", "self.OnWorkspaceClose", ""),
+                 ("New workspace", "Create new workspace file (erase current workspace settings first)", "self.OnWorkspaceNew", ""),
+                 ("Open existing workspace", "Open existing workspace file", "self.OnWorkspaceOpen", ""),
+                 ("Load map layers", "Load map layers into layer tree", "self.OnWorkspaceLoad", ""),
+                 ("Save workspace", "Save current workspace to file", "self.OnWorkspaceSave", ""),
+                 ("Save workspace as", "Save current workspace as file", "self.OnWorkspaceSaveAs", ""),
+                 ("Close current workspace", "Close current workspace", "self.OnWorkspaceClose", ""),
                  )),
               ("","","", ""),
               ("Import raster map", (
@@ -198,7 +198,7 @@
               ("Buffer rasters", "Create raster buffers around raster objects", "self.OnMenuCmd", "r.buffer"),
               ("Closest points", "r.distance", "self.OnMenuCmd", "r.distance"),
               ("MASK", "Develop raster mask", "self.OnMenuCmd", "r.mask"),
-              ("Map calculator", "Map calculator for map algebra", "self.OnMenuCmd", "scripts/mapcalc_gparser.sh"),
+              ("Map calculator", "Map calculator for map algebra", "self.DispMapCalculator", ""),
               ("Neighborhood analysis", (
                 ("Moving window", "Moving window analysis of raster cells", "self.OnMenuCmd", "r.neighbors"),
                 ("Neighborhood points", "Analyze vector points in neighborhood of raster cells", "self.OnMenuCmd", "v.neighbors"),
@@ -355,6 +355,7 @@
                 ("","","", ""),
                 ("Create/rebuild topology", "Create or rebuild topology of vector objects", "self.OnMenuCmd", "v.build"),
                 ("Clean vector map", "Clean vector objects", "self.OnMenuCmd", "v.clean"),
+                ("Generalization", "Smooth, simplify, displace, or generalize a vector map", "self.OnMenuCmd", "v.generalize"),
                 ("","","", ""),
                 ("Convert object types", "Convert vector objects from one feature type to another", "self.OnMenuCmd", "v.type.sh"),
                 ("","","", ""),
@@ -397,6 +398,7 @@
               ("Network analysis", (
                 ("Allocate subnets", "Allocate subnets for nearest centers", "self.OnMenuCmd", "v.net.alloc"),
                 ("Network maintenance", "Network maintenance", "self.OnMenuCmd", "v.net"),
+                ("Visibility network", "Create and maintain a visibility network", "self.OnMenuCmd", "v.net.visibility"),
                 ("Shortest route", "Calculate shortest route along network between 2 nodes", "self.OnMenuCmd", "v.net.path"),
                 ("Display shortest route (requires XTerm)", " Display shortest route along network between 2 nodes (visualization only)", "self.OnXTerm", "d.path"),
                 ("Split net", "Split net into bands between cost isolines", "self.OnMenuCmd", "v.net.iso"),
@@ -462,12 +464,8 @@
                 ("HIS to RGB", "Transform HIS (Hue/Intensity/Saturation) color image to RGB (Red/Green/Blue)", "self.OnMenuCmd", "i.his.rgb"),
                 ("RGB to HIS", "Transform RGB (Red/Green/Blue) color image to HIS (Hue/Intensity/Saturation)", "self.OnMenuCmd", "i.rgb.his"),
                 )),
-              ("Rectify and georeference image group", (
-                ("Set GCP's from raster map (requires Xterm)", "Set ground control points (GCP's) from raster map or keyboard entry", "self.OnXTerm", "i.points"),
-                ("Set GCP's from vector map (requires Xterm)", "Set ground control points (GCP's) from vector map or keyboard entry", "self.OnXTerm", "i.vpoints"),
-                ("Georectification (rubber sheet)", "Affine and Polynomial rectification (rubber sheet)", "self.OnMenuCmd", "i.rectify"),
-                ("Ortho photo rectification (requies Xterm)", "Ortho Photo rectification", "self.OnXTerm", "i.ortho.photo"),
-                )),
+              ("Rectify image or raster", "Rectifies raster using information in previously created POINTS file", "self.OnMenuCmd", "i.rectify"),
+              ("Ortho photo rectification (requires Xterm)", "Ortho Photo rectification", "self.OnXTerm", "i.ortho.photo"),
               ("","","", ""),
               ("Brovey sharpening", "Brovey transformation and pan sharpening", "self.OnMenuCmd", "i.fusion.brovey"),
               ("Classify image", (
@@ -507,7 +505,7 @@
                 )),
               ("","","", ""),
               ("3D MASK", "Create 3D mask for grid3D operations", "self.OnMenuCmd", "r3.mask"),
-              ("3D map calculator", "Map calculator for volumetric map algebra", "self.OnMenuCmd", "r3.mapcalculator"),
+              ("3D map calculator", "Map calculator for volumetric map algebra", "self.Disp3DMapCalculator", ""),
               ("Cross section", "Create 2D raster cross section from grid3d volume", "self.OnMenuCmd", "r3.cross.rast"),
               ("Interpolate volume from points", "Interpolate volume from vector points using splines", "self.OnMenuCmd", "v.vol.rst"),
               ("","","", ""),

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/menuform.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/menuform.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/menuform.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -50,7 +50,13 @@
 import re
 import string
 import textwrap
+import os
+from os import system
 
+### i18N
+import gettext
+gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
+
 import utils
 utils.CheckForWx()
 import wx
@@ -66,11 +72,6 @@
 HandlerBase=xml.sax.handler.ContentHandler
 from xml.sax import make_parser
 
-import os
-from os import system
-import gettext
-gettext.install("wxgui")
-
 gisbase = os.getenv("GISBASE")
 import globalvar
 if gisbase is None:
@@ -81,12 +82,14 @@
     wxbase = os.path.join(globalvar.ETCWXDIR)
 
 sys.path.append( wxbase)
-imagepath = os.path.join(wxbase,"images")
+imagepath = os.path.join(wxbase, "images")
 sys.path.append(imagepath)
 
 import grassenv
 import gselect
 import gcmd
+import wxgui_utils
+from preferences import globalSettings as UserSettings
 try:
     import subprocess
 except:
@@ -106,7 +109,8 @@
 HSPACE = 4
 MENU_HEIGHT = 25
 STATUSBAR_HEIGHT = 30
-ENTRY_HEIGHT = 25
+# ENTRY_HEIGHT = 25
+ENTRY_HEIGHT = -1
 STRING_ENTRY_WIDTH = 300
 BUTTON_HEIGHT = 44
 BUTTON_WIDTH = 100
@@ -207,7 +211,7 @@
             if p['name'] == aParam or \
                     p['name'][:lparam] == aParam:
                 return p
-        raise ValueError, _("Parameter not found : %s") % aParam
+        raise ValueError, _("Parameter not found: %s") % aParam
 
     def set_param(self, aParam, aValue):
         """
@@ -223,7 +227,7 @@
         for f in self.flags:
             if f['name'] == aFlag:
                 return f
-        raise ValueError, _("Flag not found : %s") % aFlag
+        raise ValueError, _("Flag not found: %s") % aFlag
 
     def set_flag(self, aFlag, aValue):
         """
@@ -258,7 +262,8 @@
                     cmd += [ '%s=%s' % ( p['name'], p['default'] ) ]
                 else:
                     cmd += [ '%s=%s' % ( p['name'], _('<required>') ) ]
-                    errStr += _("Parameter %s (%s) is missing.\n") % ( p['name'], p['description'] )
+                    errStr += _("Parameter %(name)s (%(desc)s) is missing.\n") % \
+                        {'name' : p['name'], 'desc' : p['description']}
                     errors += 1
             elif p.get('value','') != '' and p['value'] != p.get('default','') :
                 # Output only values that have been set, and different from defaults
@@ -551,10 +556,13 @@
         wx.Frame.__init__(self, parent=parent, id=ID, title=title,
                           pos=wx.DefaultPosition, style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
 
+	self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
+
         # statusbar
         self.CreateStatusBar()
+
         # icon
-        self.SetIcon(wx.Icon(os.path.join(imagepath, 'grass.form.gif'), wx.BITMAP_TYPE_GIF))
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, 'grass_dialog.ico'), wx.BITMAP_TYPE_ICO))
 
         # menu
         #         menu = wx.Menu()
@@ -587,16 +595,17 @@
         topsizer = wx.BoxSizer(wx.HORIZONTAL)
 
         # GRASS logo
-        self.logo = wx.StaticBitmap(parent=self,
+        self.logo = wx.StaticBitmap(parent=self.panel,
                                     bitmap=wx.Bitmap(name=os.path.join(imagepath,
-                                                                       'grass-tiny-logo.png'),
+                                                                       'grass_form.png'),
                                                      type=wx.BITMAP_TYPE_PNG))
         topsizer.Add (item=self.logo, proportion=0, border=3,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL)
         guisizer.Add (item=topsizer, proportion=0, flag=wx.EXPAND)
 
         # notebooks
-        self.notebookpanel = cmdPanel (parent=self, task=self.task, standalone=self.standalone)
+        self.notebookpanel = cmdPanel (parent=self.panel, task=self.task, standalone=self.standalone,
+                                       mainFrame=self)
         ### add 'command output' tab also for dialog open from menu
         #         if self.standalone:
         self.goutput = self.notebookpanel.goutput
@@ -608,7 +617,7 @@
         if self.notebookpanel.hasMain:
             # We have to wait for the notebookpanel to be filled in order
             # to know if there actually is a Main tab
-            status_text += _(" (those of Main in bold typeface are required)")
+            status_text += _(" (those in bold typeface are required)")
         try:
             self.task.getCmd()
             self.updateValuesHook()
@@ -618,13 +627,13 @@
         # buttons
         btnsizer = wx.BoxSizer(orient=wx.HORIZONTAL)
         # cancel
-        btn_cancel = wx.Button(parent=self, id=wx.ID_CANCEL)
+        btn_cancel = wx.Button(parent=self.panel, id=wx.ID_CANCEL)
         btn_cancel.SetToolTipString(_("Cancel the command settings and ignore changes"))
         btnsizer.Add(item=btn_cancel, proportion=0, flag=wx.ALL | wx.ALIGN_CENTER, border=10)
         btn_cancel.Bind(wx.EVT_BUTTON, self.OnCancel)
         if self.get_dcmd is not None: # A callback has been set up
-            btn_apply = wx.Button(parent=self, id=wx.ID_APPLY)
-            btn_ok = wx.Button(parent=self, id=wx.ID_OK)
+            btn_apply = wx.Button(parent=self.panel, id=wx.ID_APPLY)
+            btn_ok = wx.Button(parent=self.panel, id=wx.ID_OK)
             btn_ok.SetDefault()
 
             btnsizer.Add(item=btn_apply, proportion=0,
@@ -638,51 +647,72 @@
             btn_ok.Bind(wx.EVT_BUTTON, self.OnOK)
         else: # We're standalone
             # run
-            btn_run = wx.Button(parent=self, id=wx.ID_OK, label= _("&Run"))
-            btn_run.SetToolTipString(_("Run the command"))
-            btn_run.SetDefault()
+            self.btn_run = wx.Button(parent=self.panel, id=wx.ID_OK, label= _("&Run"))
+            self.btn_run.SetToolTipString(_("Run the command"))
+            self.btn_run.SetDefault()
+            # abort
+            btn_abort = wx.Button(parent=self.panel, id=wx.ID_STOP)
+            btn_abort.SetToolTipString(_("Abort the running command"))
             # copy
-            btn_clipboard = wx.Button(parent=self, id=wx.ID_COPY, label=_("C&opy"))
+            btn_clipboard = wx.Button(parent=self.panel, id=wx.ID_COPY)
             btn_clipboard.SetToolTipString(_("Copy the current command string to the clipboard"))
 
-            btnsizer.Add(item=btn_run, proportion=0,
+            btnsizer.Add(item=btn_abort, proportion=0,
                          flag=wx.ALL | wx.ALIGN_CENTER,
                          border=10)
 
+            btnsizer.Add(item=self.btn_run, proportion=0,
+                         flag=wx.ALL | wx.ALIGN_CENTER,
+                         border=10)
+
             btnsizer.Add(item=btn_clipboard, proportion=0,
                          flag=wx.ALL | wx.ALIGN_CENTER,
                          border=10)
 
-            btn_run.Bind(wx.EVT_BUTTON, self.OnRun)
+            self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun)
+            btn_abort.Bind(wx.EVT_BUTTON, self.OnAbort)
             btn_clipboard.Bind(wx.EVT_BUTTON, self.OnCopy)
 
         guisizer.Add(item=btnsizer, proportion=0, flag=wx.ALIGN_CENTER)
 
         if self.get_dcmd is None:
-            # close dialog on run?
-            self.closebox = wx.CheckBox(parent=self,
-                                        label=_('Close dialog on run'), style = wx.NO_BORDER)
-            self.closebox.SetValue(False)
+            # close dialog when command is terminated
+            self.closebox = wx.CheckBox(parent=self.panel,
+                                        label=_('Close dialog on finish'), style = wx.NO_BORDER)
+            self.closebox.SetValue(UserSettings.Get(group='cmd', key='closeDlg', subkey='enabled'))
             guisizer.Add(item=self.closebox, proportion=0,
                          flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
                          border=5)
 
         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
 
-        constrained_size = self.notebookpanel.GetSize()
+        #constrained_size = self.notebookpanel.GetSize()
         # 80 takes the tabbar into account
-        self.notebookpanel.SetSize( (constrained_size[0],constrained_size[1]+80) ) 
-        self.notebookpanel.Layout()
-        
-        # for too long descriptions
-        self.description = StaticWrapText (parent=self, label=self.task.description)
+        #self.notebookpanel.SetSize( (constrained_size[0] + 25, constrained_size[1]) ) 
+        #self.notebookpanel.Layout()
+
+        #
+        # put module description
+        #
+        self.description = StaticWrapText (parent=self.panel, label=self.task.description)
         topsizer.Add (item=self.description, proportion=1, border=5,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND)
 
-        guisizer.SetSizeHints(self)
-        self.SetAutoLayout(True)
-        self.SetSizer(guisizer)
-        guisizer.Fit(self)
+        #
+        # do layout
+        #
+        guisizer.SetSizeHints(self.panel)
+        # called automatically by SetSizer()
+        self.panel.SetAutoLayout(True) 
+        self.panel.SetSizer(guisizer)
+        guisizer.Fit(self.panel)
+
+        sizeFrame = self.GetBestSize()
+        self.SetMinSize(sizeFrame)
+        self.SetSize((sizeFrame[0], sizeFrame[1] +
+                      self.notebookpanel.constrained_size[1] -
+                      self.notebookpanel.panelMinHeight))
+
         self.Layout()
 
     def updateValuesHook(self):
@@ -711,6 +741,9 @@
 
     def OnRun(self, event):
         """Run the command"""
+        if len(self.goutput.GetListOfCmdThreads()) > 0:
+            return
+
         cmd = self.createCmd()
 
         if cmd == [] or cmd == None:
@@ -726,17 +759,21 @@
                 print >> sys.stderr, "parent window is: %s" % (str(self.parent))
             # Send any other command to the shell.
         else:
-            runCmd = gcmd.Command(cmd)
+            gcmd.Command(cmd)
 
-        #if self.standalone:
+        # if self.standalone:
         # change page if needed
         if self.notebookpanel.notebook.GetSelection() != self.notebookpanel.outpageid:
             self.notebookpanel.notebook.SetSelection(self.notebookpanel.outpageid)
 
-        if self.get_dcmd is None:
-            # close dialog?
-            if self.closebox.IsChecked():
-                self.Close()
+        self.btn_run.Enable(False)
+        
+    def OnAbort(self, event):
+        """Abort running command"""
+        try:
+            self.goutput.GetListOfCmdThreads()[0].abort()
+        except IndexError:
+            pass
 
     def OnCopy(self, event):
         """Copy the command"""
@@ -764,9 +801,9 @@
     def OnAbout(self, event):
         """General 'about' information"""
         dlg = wx.MessageDialog(self, _("This is a sample program for\n"
-            "GRASS command interface parsing\n"
-            "and automatic GUI building. \n%s") %(__version__),
-            _("About GrassGUI"), wx.OK | wx.ICON_INFORMATION)
+                                       "GRASS command interface parsing\n"
+                                       "and automatic GUI building.\n%s") %(__version__),
+                               _("About wxPython GRASS GUI"), wx.OK | wx.ICON_INFORMATION)
         dlg.ShowModal()
         dlg.Destroy()
 
@@ -787,9 +824,10 @@
     """
     A panel containing a notebook dividing in tabs the different guisections of the GRASS cmd.
     """
-    def __init__( self, parent, task, standalone, *args, **kwargs ):
+    def __init__( self, parent, task, standalone, mainFrame, *args, **kwargs ):
         wx.Panel.__init__( self, parent, *args, **kwargs )
 
+        self.parent = mainFrame
         self.task = task
         fontsize = 10
 
@@ -838,8 +876,7 @@
         # are we running from command line?
         ### add 'command output' tab regardless standalone dialog
         #        if standalone:
-        from gui_modules import wxgui_utils
-        self.goutput = wxgui_utils.GMConsole(self)
+        self.goutput = wxgui_utils.GMConsole(parent=self, margin=False)
         self.outpage = self.notebook.AddPage(self.goutput, text=_("Command output") )
         self.outpageid = self.notebook.GetPageCount() - 1
 
@@ -872,15 +909,22 @@
                 chk.SetToolTipString(tooltip)
             if 'value' in f:
                 chk.SetValue( f['value'] )
-            chk.SetFont(wx.Font(pointSize=fontsize, family=wx.FONTFAMILY_DEFAULT,
-                                style=wx.NORMAL, weight=text_style))
+            # chk.SetFont(wx.Font(pointSize=fontsize, family=wx.FONTFAMILY_DEFAULT,
+            #                    style=wx.NORMAL, weight=text_style))
             which_sizer.Add( item=chk, proportion=0,
                              flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border=5)
             f['wxId'] = chk.GetId()
             chk.Bind(wx.EVT_CHECKBOX, self.OnSetValue)
             if f['name'] in ('verbose', 'quiet'):
                 chk.Bind(wx.EVT_CHECKBOX, self.OnVerbosity)
-
+                vq = UserSettings.Get(group='cmd', key='verbosity', subkey='selection')
+                if f['name'] == vq:
+                    chk.SetValue(True)
+                    f['value'] = True
+            elif f['name'] == 'overwrite':
+                chk.SetValue(UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))
+                f['value'] = True
+                
         #
         # parameters
         #
@@ -921,7 +965,7 @@
                     else:
                         hSizer=wx.StaticBoxSizer ( box=txt, orient=wx.HORIZONTAL )
                     isDefault = {}
-                    for defval in p.get('value','').split(','):
+                    for defval in p.get('default','').split(','):
                         isDefault[ defval ] = 'yes'
                         # for multi checkboxes, this is an array of all wx IDs
                         # for each individual checkbox
@@ -939,8 +983,8 @@
                 else:
                     if len(valuelist) == 1: # -> textctrl
                         txt = wx.StaticText(parent=which_panel,
-                                            label = _('%s. Valid range=%s') % \
-                                                (title, str(valuelist).strip("[]'") + ':' ) )
+                                            label = "%s. %s=%s" (title, _('Valid range'),
+                                                                 str(valuelist).strip("[]'") + ':'))
                         which_sizer.Add(item=txt, proportion=0,
                                         flag=wx.ADJUST_MINSIZE | wx.TOP | wx.RIGHT | wx.LEFT, border=5)
 
@@ -989,15 +1033,25 @@
                 which_sizer.Add(item=txt, proportion=0,
                                 flag=wx.RIGHT | wx.LEFT | wx.TOP | wx.EXPAND, border=5)
 
-                txt3 = wx.TextCtrl(parent=which_panel, value = p.get('default',''),
+                if p.get('multiple','yes') == 'yes' or \
+                        p.get('type','string') == 'string':
+                    txt3 = wx.TextCtrl(parent=which_panel, value = p.get('default',''),
                                    size = (STRING_ENTRY_WIDTH, ENTRY_HEIGHT))
-
+                    txt3.Bind(wx.EVT_TEXT, self.OnSetValue)
+                else:
+                    minValue = -1e9
+                    maxValue = 1e9
+                    txt3 = wx.SpinCtrl(parent=which_panel, value=p.get('default',''),
+                                       size = (STRING_ENTRY_WIDTH, ENTRY_HEIGHT),
+                                       min=minValue, max=maxValue)
+                    txt3.Bind(wx.EVT_SPINCTRL, self.OnSetValue)
+                    txt3.Bind(wx.EVT_TEXT, self.OnSetValue)
+                    
                 if p.get('value','') != '':
                     txt3.SetValue(p['value']) # parameter previously set
 
                 which_sizer.Add(item=txt3, proportion=0, flag=wx.BOTTOM | wx.LEFT, border=5)
                 p['wxId'] = txt3.GetId()
-                txt3.Bind(wx.EVT_TEXT, self.OnSetValue)
 
             if p.get('type','string') == 'string' and p.get('gisprompt',False) == True:
                 txt = wx.StaticText(parent=which_panel, label = title + ':')
@@ -1015,7 +1069,7 @@
                         selection.SetValue(p['value']) # parameter previously set
 
                     which_sizer.Add(item=selection, proportion=0,
-                                    flag=wx.ADJUST_MINSIZE| wx.BOTTOM | wx.LEFT, border=5)
+                                    flag=wx.ADJUST_MINSIZE| wx.BOTTOM | wx.LEFT | wx.RIGHT, border=5)
                     # A select.Select is a combobox with two children: a textctl and a popupwindow;
                     # we target the textctl here
                     p['wxId'] = selection.GetChildren()[0].GetId()
@@ -1049,7 +1103,7 @@
                             none_check.SetValue(True)
                         else:
                             none_check.SetValue(False)
-                        none_check.SetFont( wx.Font( fontsize, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, ''))
+                        # none_check.SetFont( wx.Font( fontsize, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, ''))
                         this_sizer.Add(item=none_check, proportion=0,
                                        flag=wx.ADJUST_MINSIZE | wx.LEFT | wx.RIGHT | wx.TOP, border=5)
                         which_sizer.Add( this_sizer )
@@ -1076,40 +1130,49 @@
                     p['wxId'] = fbb.GetChildren()[1].GetId()
 
             if txt is not None:
-                txt.SetFont( wx.Font( fontsize, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, ''))
+                # txt.SetFont( wx.Font( fontsize, wx.FONTFAMILY_DEFAULT, wx.NORMAL, text_style, 0, ''))
                 # create tooltip if given
                 if len(p['values_desc']) > 0:
                     if tooltip:
                         tooltip += 2 * os.linesep
                     else:
                         tooltip = ''
-                    for i in range(len(p['values'])):
-                        tooltip += p['values'][i] + ': ' + p['values_desc'][i] + os.linesep
+                    if len(p['values']) == len(p['values_desc']):
+                        for i in range(len(p['values'])):
+                            tooltip += p['values'][i] + ': ' + p['values_desc'][i] + os.linesep
                     tooltip.strip(os.linesep)
                 if tooltip:
                     txt.SetToolTipString(tooltip)
 
+	#
+	# determine panel size
+	#
         maxsizes = (0,0)
         for section in sections:
-            tabsizer[section].SetSizeHints( tab[section] )
-            tab[section].SetAutoLayout(True)
+            # tabsizer[section].SetSizeHints( tab[section] )
+            #tab[section].SetAutoLayout(True)
             tab[section].SetSizer( tabsizer[section] )
             tabsizer[section].Fit( tab[section] )
             tab[section].Layout()
-            minsecsizes = tabsizer[section].GetMinSize()
+            minsecsizes = tabsizer[section].GetSize()
             maxsizes = map( lambda x: max( maxsizes[x], minsecsizes[x] ), (0,1) )
 
         # TODO: be less arbitrary with these 600
-        constrained_size = (min(600, maxsizes[0]), min(600, maxsizes[1]) + 25 )
+        self.panelMinHeight = 100
+        self.constrained_size = (min(600, maxsizes[0]) + 25, min(600, maxsizes[1]))
         for section in sections:
-            tab[section].SetMinSize( constrained_size )
+            tab[section].SetMinSize( (self.constrained_size[0], self.panelMinHeight) )
+            # tab[section].SetMinSize( constrained_size )
+
         if manual_tab.Ok:
-            manual_tab.SetMinSize( constrained_size )
+            manual_tab.SetMinSize( (self.constrained_size[0], self.panelMinHeight) )
+            # manual_tab.SetMinSize( constrained_size )
 
         self.SetSizer( panelsizer )
-        panelsizer.Fit(self)
-        self.hasMain = tab.has_key( _('Main') ) # publish, to enclosing Frame for instance
+        panelsizer.Fit(self.notebook)
 
+        self.hasMain = tab.has_key( _('Required') ) # publish, to enclosing Frame for instance
+
     def OnVerbosity(self, event):
         """Verbosity level changed"""
         verbose = self.FindWindowById(self.task.get_flag('verbose')['wxId'])
@@ -1228,7 +1291,7 @@
     """
     cmdout = os.popen(cmd + r' --interface-description', "r").read()
     if not len(cmdout) > 0 :
-        raise IOError, _("Couldn't fetch interface description for command <%s>.") % cmd
+        raise IOError, _("Unable to fetch interface description for command '%s'.") % cmd
     p = re.compile( '(grass-interface.dtd)')
     p.search( cmdout )
     cmdout = p.sub(globalvar.ETCDIR + r'/grass-interface.dtd', cmdout)
@@ -1240,7 +1303,7 @@
     """
     def __init__(self, grass_task):
         self.grass_task = grass_task
-        wx.App.__init__(self)
+        wx.App.__init__(self, False)
 
     def OnInit(self):
         self.mf = mainFrame(parent=None, ID=wx.ID_ANY, task_description=self.grass_task)
@@ -1368,6 +1431,7 @@
         print _("usage: %s <grass command>") % sys.argv[0]
         sys.exit()
     if sys.argv[1] != 'test':
+        q=wx.LogNull()
         GrassGUIApp( grassTask( sys.argv[1] ) ).MainLoop()
     else: #Test
         # Test grassTask from within a GRASS session
@@ -1458,5 +1522,6 @@
             "value" : True
             }
             ]
+        q=wx.LogNull()
         GrassGUIApp( task ).MainLoop()
 

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/preferences.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/preferences.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/preferences.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -6,8 +6,9 @@
 Sets default display font, etc.
 
 Classes:
- * PreferencesDialog
- * SetDefaultFont
+ - PreferencesDialog
+ - SetDefaultFont
+ - MapsetAccess
 
 (C) 2007-2008 by the GRASS Development Team
 This program is free software under the GNU General Public
@@ -24,36 +25,151 @@
 
 import wx
 import wx.lib.filebrowsebutton as filebrowse
+import wx.lib.colourselect as csel
 from wx.lib.wordwrap import wordwrap
 
 import gcmd
 import grassenv
+import utils
+from debug import Debug as Debug
 
 class Settings:
     """Generic class where to store settings"""
     def __init__(self):
-        # filename for settings
+        #
+        # settings filename
+        #
         self.fileName = ".grasswx"
+        self.filePath = None
 
+        #
         # default settings
+        #
         self.defaultSettings = {
+            #
             # general
-            'displayFont' : '',
+            #
+            'general': {
+                'mapsetPath'  : { 'selection' : 0 }, # current mapset search path
+                },
+            #
+            # display
+            #
+            'display': {
+                'displayFont' : { 'value' : '' },
+                'rasterOverlay' : { 'enabled' : False },
+                },
+            #
             # advanced
-            'settingsFile' : 'gisdbase', # gisdbase, location, mapset
-            'digitInterface' : 'vdigit', # vedit, vdigit
-            'iconTheme': 'silk', # grass, silk
+            #
+            'advanced' : {
+                'settingsFile'   : { 'type' : 'gisdbase' }, # gisdbase, location, mapset
+                'digitInterface' : { 'type' : 'vdigit' }, # vedit, vdigit
+                'iconTheme'      : { 'type' : 'silk' }, # grass, silk
+                },
+            #
+            # Attribute Table Manager
+            #
+            'atm' : {
+            'highlight' : { 'color' : (255, 255, 0, 255), 'width' : 2},
+            'leftDbClick' : { 'selection' : 0 },
+            },
+            #
+            # Command
+            #
+            'cmd': {
+            'overwrite' : { 'enabled' : False },
+            'closeDlg' : { 'enabled' : False },
+            'verbosity' : { 'selection' : 'grassenv' },
+            },
+            #
+            # vdigit
+            #
+            'vdigit' : {
+                # symbology
+                'symbolHighlight'   : { 'enabled' : None,  'color' : (255, 255, 0, 255) }, #yellow
+                'symbolPoint'       : { 'enabled' : True,  'color' : (0, 0, 0, 255) }, # black
+                'symbolLine'        : { 'enabled' : True,  'color' : (0, 0, 0, 255) }, # black
+                'symbolBoundaryNo'  : { 'enabled' : True,  'color' : (126, 126, 126, 255) }, # grey
+                'symbolBoundaryOne' : { 'enabled' : True,  'color' : (0, 255, 0, 255) }, # green
+                'symbolBoundaryTwo' : { 'enabled' : True,  'color' : (255, 135, 0, 255) }, # orange
+                'symbolCentroidIn'  : { 'enabled' : True,  'color' : (0, 0, 255, 255) }, # blue
+                'symbolCentroidOut' : { 'enabled' : True,  'color' : (165, 42, 42, 255) }, # brown
+                'symbolCentroidDup' : { 'enabled' : True,  'color' : (156, 62, 206, 255) }, # violet
+                'symbolNodeOne'     : { 'enabled' : True,  'color' : (255, 0, 0, 255) }, # red
+                'symbolNodeTwo'     : { 'enabled' : True,  'color' : (0, 86, 45, 255) }, # dark green
+                'symbolVertex'      : { 'enabled' : False, 'color' : (255, 20, 147, 255) }, # deep pink
+                # display
+                'lineWidth' : { 'value' : 2, 'units' : 'screen pixels' },
+                # snapping
+                'snapping' : { 'value' : 10, 'units' : 'screen pixels' },
+                'snapToVertex' : { 'enabled' : False },
+                'backgroundMap' : {'value' : ''},
+                # digitize new record
+                'addRecord' : { 'enabled' : True },
+                'layer' : {'value' : 1 },
+                'category' : {'value' : 1 },
+                'categoryMode' : {'value' : 'Next to use' },
+                # delete existing feature(s)
+                'delRecord' : { 'enabled' : True },
+                # query tool
+                'query'       : { 'type' : 'length', 'box' : True },
+                'queryLength' : { 'than' : 'shorter than', 'thresh' : 0 },
+                'queryDangle' : { 'than' : 'shorter than', 'thresh' : 0 },
+                # select feature (point, line, centroid, boundary)
+                'selectFeaturePoint'    : { 'enabled' : True },
+                'selectFeatureLine'     : { 'enabled' : True },
+                'selectFeatureCentroid' : { 'enabled' : True },
+                'selectFeatureBoundary' : { 'enabled' : True },
+                'selectThresh'          : { 'value' : 10, 'units' : 'screen pixels'},
+                }
             }
-        
+
+        #
         # user settings
+        #
         self.userSettings = copy.deepcopy(self.defaultSettings)
         try:
             self.ReadSettingsFile()
-        except IOError, e:
-            raise gcmd.SettingsError(e)
-        except:
-            gcmd.SettingsError('Reading settings failed.')
+        except gcmd.SettingsError, e:
+            print >> sys.stderr, e.message
 
+        #
+        # internal settings (based on user settings)
+        #
+        self.internalSettings = {}
+        for group in self.userSettings.keys():
+            if group == 'vdigit':
+                continue # skip digitization settings (separate window frame)
+            self.internalSettings[group] = {}
+            for key in self.userSettings[group].keys():
+                self.internalSettings[group][key] = {}
+
+        self.internalSettings['general']["mapsetPath"]['value'] = self.GetMapsetPath()
+        self.internalSettings['general']['mapsetPath']['choices'] = [_('Mapset search path'),
+                                                                     _('All available mapsets')]
+        self.internalSettings['atm']['leftDbClick']['choices'] = [_('Edit selected record'),
+                                                                  _('Display selected')]
+        self.internalSettings['advanced']['settingsFile']['choices'] = ['gisdbase',
+                                                                        'location',
+                                                                        'mapset']
+        self.internalSettings['advanced']['iconTheme']['choices'] = ['grass',
+                                                                     'silk']
+        self.internalSettings['advanced']['digitInterface']['choices'] = ['vedit',
+                                                                          'vdigit']
+        self.internalSettings['cmd']['verbosity']['choices'] = ['grassenv',
+                                                                'verbose',
+                                                                'quiet']
+
+    def GetMapsetPath(self):
+        """Store mapset search path"""
+        all, access = utils.ListOfMapsets()
+
+        if self.Get(group='general', key='mapsetPath', subkey='selection') == 0:
+            return access
+        else:
+            return all
+    
     def ReadSettingsFile(self, settings=None):
         """Reads settings file (mapset, location, gisdbase)"""
         if settings is None:
@@ -72,12 +188,15 @@
         gisdbase_file = os.path.join(gisdbase, self.fileName)
 
         if os.path.isfile(mapset_file):
-            self.__ReadFile(mapset_file)
+            self.filePath = mapset_file
         elif os.path.isfile(location_file):
-            self.__ReadFile(location_file)
+            self.filePath = location_file
         elif os.path.isfile(gisdbase_file):
-            self.__ReadFile(gisdbase_file)
-
+            self.filePath = gisdbase_file
+        
+        if self.filePath:
+            self.__ReadFile(self.filePath)
+            
     def __ReadFile(self, filename, settings=None):
         """Read settings from file to dict"""
         if settings is None:
@@ -86,29 +205,47 @@
         try:
             file = open(filename, "r")
             for line in file.readlines():
-                try:
-                    key, value = line.rstrip('%s' % os.linesep).split(':', 1)
-                except:
-                    raise SettingsError('Reading settings from file <%s> failed. '
-                                        'Line \'%s\'.' % (filename, line))
-                if settings.has_key(key):
-                    settings[key] = value
-                else:
-                    raise SettingsError('Reading settings from file <%s> failed. '
-                                        'Unknow item <%s>.' % (filename, key))
-        except IOError, e:
-            raise gcmd.SettingsError(e)
-        except:
-            raise gcmd.SettingsError('Reading settings from file <%s> failed.' % filename)
+                line = line.rstrip('%s' % os.linesep)
+                group, key = line.split(':')[0:2]
+                kv = line.split(':')[2:]
+                idx = 0
+                while idx < len(kv):
+                    subkey = kv[idx]
+                    value = kv[idx+1]
+                    if len(value) == 0:
+                        self.Set(group=group, key=key, subkey=subkey, value='')
+                    else:
+                        # casting
+                        if value == 'True':
+                            value = True
+                        elif value == 'False':
+                            value = False
+                        elif value == 'None':
+                            value = None
+                        elif value[0] == '(':
+                            tmp = value.replace('(','').replace(')', '').split(',')
+                            try:
+                                value = tuple(map(int, tmp))
+                            except:
+                                value = tuple(tmp)
+                        else:
+                            try:
+                                value = int(value)
+                            except:
+                                pass
+                        # Debug.msg(3, 'Settings(): group=%s, key=%s, subkey=%s, value=%s' %
+                        #          (group, key, subkey, value))
+                        self.Set(group=group, key=key, subkey=subkey, value=value)
+                    idx += 2
+        finally:
+            file.close()
 
-        file.close()
-
     def SaveToFile(self, settings=None):
         """Save settings to the file"""
         if settings is None:
             settings = self.userSettings
         
-        loc = self.Get('settingsFile')
+        loc = self.Get(group='advanced', key='settingsFile', subkey='type')
         gisdbase = grassenv.GetGRASSVariable("GISDBASE")
         location_name = grassenv.GetGRASSVariable("LOCATION_NAME")
         mapset_name = grassenv.GetGRASSVariable("MAPSET")
@@ -121,13 +258,19 @@
             filePath = os.path.join(gisdbase, location_name, mapset_name, self.fileName)
         
         if filePath is None:
-            raise gcmd.SettingsError('Uknown file location.')
+            raise gcmd.SettingsError(_('Uknown settings file location.'))
 
         try:
             file = open(filePath, "w")
-            for item in settings.keys():
-                if settings[item] != '':
-                    file.write('%s:%s%s' % (item, settings[item], os.linesep))
+            for group in settings.keys():
+                for item in settings[group].keys():
+                    file.write('%s:%s:' % (group, item))
+                    items = settings[group][item].keys()
+                    for idx in range(len(items)):
+                        file.write('%s:%s' % (items[idx], settings[group][item][items[idx]]))
+                        if idx < len(items) - 1:
+                            file.write(':')
+                    file.write('%s' % os.linesep)
         except IOError, e:
             raise gcmd.SettingsError(e)
         except:
@@ -137,34 +280,61 @@
 
         return filePath
 
-    def Get(self, key):
-        """Get value by key
+    def Get(self, group, key, subkey=None, internal=False):
+        """Get value by key/subkey
 
+        Raise KeyError if key is not found
+        
+        @param group settings group
+        @param key
+        @param subkey if not given return dict of key
+        
         @return value
-        @return None if key not found
+
         """
-        if self.userSettings.has_key(key):
-            return self.userSettings[key]
+        if internal is True:
+            settings = self.internalSettings
         else:
-            None
-    
-    def Set(self, key, value):
-        """Set value by key
+            settings = self.userSettings
+            
+        try:
+            if subkey is None:
+                return settings[group][key]
+            else:
+                return settings[group][key][subkey]
+        except KeyError:
+            raise gcmd.SettingsError("%s %s:%s:%s." % (_("Unable to get value"),
+                                                       group, key, subkey))
+        
+    def Set(self, group, key, subkey, value, internal=False):
+        """Set value by key/subkey
 
         Raise KeyError if key is not found
+        
+        @param group settings group
+        @param key
+        @param subkey
+        @param value 
         """
-        if self.userSettings.has_key(key):
-            self.userSettings[key] = value
+        if internal is True:
+            settings = self.internalSettings
         else:
-            raise KeyError
+            settings = self.userSettings
 
+        try:
+            if not settings[group][key].has_key(subkey):
+                raise KeyError
+            settings[group][key][subkey] = value
+        except KeyError:
+            raise gcmd.SettingsError("%s '%s:%s:%s'" % (_("Unable to set "), group, key, subkey))
+
 globalSettings = Settings()
 
 class PreferencesDialog(wx.Dialog):
     """User preferences dialog"""
-    def __init__(self, parent, title,
+    def __init__(self, parent, title=_("User settings"),
                  settings=globalSettings,
-                 style=wx.DEFAULT_DIALOG_STYLE):
+                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
         self.parent = parent # GMFrame
         self.title = title
         wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title,
@@ -174,38 +344,57 @@
         # notebook
         notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
 
+        # dict for window ids
+        self.winId = {}
+
         # create notebook pages
         self.__CreateGeneralPage(notebook)
+        self.__CreateDisplayPage(notebook)
+        self.__CreateCmdPage(notebook)
+        self.__CreateAttributeManagerPage(notebook)
         self.__CreateAdvancedPage(notebook)
 
         # buttons
+        btnDefault = wx.Button(self, wx.ID_ANY, _("Set to default"))
         btnSave = wx.Button(self, wx.ID_SAVE)
         btnApply = wx.Button(self, wx.ID_APPLY)
         btnCancel = wx.Button(self, wx.ID_CANCEL)
-        # btnOk = wx.Button(self, wx.ID_OK)
         btnSave.SetDefault()
 
         # bindigs
+        btnDefault.Bind(wx.EVT_BUTTON, self.OnDefault)
+        btnDefault.SetToolTipString(_("Revert settings to default and apply changes"))
         btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
+        btnApply.SetToolTipString(_("Apply changes for this session"))
         btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
+        btnSave.SetToolTipString(_("Close dialog and save changes to user settings file"))
+        btnSave.SetDefault()
         btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
+        btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
 
         # sizers
-        btnSizer = wx.StdDialogButtonSizer()
-        btnSizer.AddButton(btnCancel)
-        btnSizer.AddButton(btnSave)
-        btnSizer.AddButton(btnApply)
-        # btnSizer.AddButton(btnOk)
-        btnSizer.Realize()
+        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
+        btnSizer.Add(item=btnDefault, proportion=1,
+                     flag=wx.ALL, border=5)
+        btnStdSizer = wx.StdDialogButtonSizer()
+        btnStdSizer.AddButton(btnCancel)
+        btnStdSizer.AddButton(btnSave)
+        btnStdSizer.AddButton(btnApply)
+        btnStdSizer.Realize()
         
         mainSizer = wx.BoxSizer(wx.VERTICAL)
         mainSizer.Add(item=notebook, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
         mainSizer.Add(item=btnSizer, proportion=0,
-                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+                      flag=wx.EXPAND, border=0)
+        mainSizer.Add(item=btnStdSizer, proportion=0,
+                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT, border=5)
 
         self.SetSizer(mainSizer)
         mainSizer.Fit(self)
 
+        self.SetMinSize(self.GetBestSize())
+        self.SetSize((500, 375))
+
     def __CreateGeneralPage(self, notebook):
         """Create notebook page concerning with symbology settings"""
         panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
@@ -219,35 +408,231 @@
         gridSizer.AddGrowableCol(0)
 
         #
-        # display font
+        # mapsets path
         #
+        row = 0
         gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Mapsets path:")),
+                       flag=wx.ALIGN_LEFT |
+                       wx.ALIGN_CENTER_VERTICAL,
+                       pos=(row, 0))
+        mapsetPath = wx.Choice(parent=panel, id=wx.ID_ANY, size=(200, -1),
+                                    choices=self.settings.Get(group='general', key='mapsetPath',
+                                                              subkey='choices', internal=True),
+                                    name="GetSelection")
+        mapsetPath.SetSelection(self.settings.Get(group='general', key='mapsetPath', subkey='selection'))
+        self.winId['general:mapsetPath:selection'] = mapsetPath.GetId()
+        
+        gridSizer.Add(item=mapsetPath,
+                      flag=wx.ALIGN_RIGHT |
+                      wx.ALIGN_CENTER_VERTICAL,
+                      pos=(row, 1))
+        
+        sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
+        border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
+
+        panel.SetSizer(border)
+        
+        return panel
+
+    def __CreateDisplayPage(self, notebook):
+        """Create notebook page concerning for display settings"""
+        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
+        notebook.AddPage(page=panel, text=_("Display"))
+
+        border = wx.BoxSizer(wx.VERTICAL)
+        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Font settings"))
+        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
+        gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
+        gridSizer.AddGrowableCol(0)
+
+        #
+        # font settings
+        #
+        row = 0
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
                                          label=_("Default font for GRASS displays:")),
                        flag=wx.ALIGN_LEFT |
-                       wx.ALIGN_CENTER_VERTICAL,
-                       pos=(0, 0))
+                      wx.ALIGN_CENTER_VERTICAL,
+                      pos=(row, 0))
         fontButton = wx.Button(parent=panel, id=wx.ID_ANY,
                                label=_("Set font"), size=(100, -1))
         gridSizer.Add(item=fontButton,
                       flag=wx.ALIGN_RIGHT |
                        wx.ALIGN_CENTER_VERTICAL,
-                       pos=(0, 1))
-        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
-                                         label=_("Currently selected font:")),
-                       flag=wx.ALIGN_LEFT |
-                       wx.ALIGN_CENTER_VERTICAL,
-                       pos=(1, 0), span=(1, 2))
+                       pos=(row, 1))
 
         sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
-        border.Add(item=sizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=3)
+        border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
 
+        #
+        # raster settings
+        #
+        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Raster settings"))
+        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
+        gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
+        gridSizer.AddGrowableCol(0)
+
+        #
+        # raster overlay
+        #
+        row = 0
+        rasterOverlay = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+                                    label=_("Overlay raster maps"),
+                                    name='IsChecked')
+        rasterOverlay.SetValue(self.settings.Get(group='display', key='rasterOverlay', subkey='enabled'))
+        self.winId['display:rasterOverlay:enabled'] = rasterOverlay.GetId()
+
+        gridSizer.Add(item=rasterOverlay,
+                      pos=(row, 0), span=(1, 2))
+        
+        sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
+        border.Add(item=sizer, proportion=0, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=3)
+
         panel.SetSizer(border)
         
         # bindings
         fontButton.Bind(wx.EVT_BUTTON, self.OnSetFont)
+        
+        return panel
 
+    def __CreateCmdPage(self, notebook):
+        """Create notebook page for commad dialog settings"""
+        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
+        notebook.AddPage(page=panel, text=_("Command"))
+
+        border = wx.BoxSizer(wx.VERTICAL)
+        box   = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Command dialog settings"))
+        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
+        gridSizer = wx.GridBagSizer (hgap=3, vgap=3)
+        gridSizer.AddGrowableCol(0)
+
+        #
+        # command dialog settings
+        #
+        row = 0
+        # overwrite
+        overwrite = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+                                label=_("Allow output files to overwrite existing files"),
+                                name="IsChecked")
+        overwrite.SetValue(self.settings.Get(group='cmd', key='overwrite', subkey='enabled'))
+        self.winId['cmd:overwrite:enabled'] = overwrite.GetId()
+
+        gridSizer.Add(item=overwrite,
+                      pos=(row, 0), span=(1, 2))
+        row += 1
+        # close
+        close = wx.CheckBox(parent=panel, id=wx.ID_ANY,
+                            label=_("Close dialog on finish"),
+                            name="IsChecked")
+        close.SetValue(self.settings.Get(group='cmd', key='closeDlg', subkey='enabled'))
+        self.winId['cmd:closeDlg:enabled'] = close.GetId()
+
+        gridSizer.Add(item=close,
+                      pos=(row, 0), span=(1, 2))
+        row += 1
+        # verbosity
+        gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
+                                         label=_("Verbosity level:")),
+                      flag=wx.ALIGN_LEFT |
+                      wx.ALIGN_CENTER_VERTICAL,
+                      pos=(row, 0))
+        verbosity = wx.Choice(parent=panel, id=wx.ID_ANY, size=(200, -1),
+                              choices=self.settings.Get(group='cmd', key='verbosity', subkey='choices', internal=True),
+                              name="GetStringSelection")
+        verbosity.SetStringSelection(self.settings.Get(group='cmd', key='verbosity', subkey='selection'))
+        self.winId['cmd:verbosity:selection'] = verbosity.GetId()
+
+        gridSizer.Add(item=verbosity,
+                      pos=(row, 1))
+
+        sizer.Add(item=gridSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
+        border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
+
+        panel.SetSizer(border)
+        
         return panel
 
+    def __CreateAttributeManagerPage(self, notebook):
+        """Create notebook page concerning for 'Attribute Table Manager' settings"""
+        panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
+        notebook.AddPage(page=panel, text=_("Attribute Table Manager"))
+
+        pageSizer = wx.BoxSizer(wx.VERTICAL)
+
+        #
+        # highlighting
+        #
+        highlightBox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
+                                    label=" %s " % _("Highlighting"))
+        highlightSizer = wx.StaticBoxSizer(highlightBox, wx.VERTICAL)
+
+        flexSizer = wx.FlexGridSizer (cols=2, hgap=5, vgap=5)
+        flexSizer.AddGrowableCol(0)
+        label = wx.StaticText(parent=panel, id=wx.ID_ANY, label="Color")
+        hlColor = csel.ColourSelect(parent=panel, id=wx.ID_ANY,
+                                    colour=self.settings.Get(group='atm', key='highlight', subkey='color'),
+                                    size=(25, 25))
+        self.winId['atm:highlight:color'] = hlColor.GetId()
+
+        flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(hlColor, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
+
+        label = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Line width (in pixels)"))
+        hlWidth = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(50, -1),
+                              initial=self.settings.Get(group='atm', key='highlight',subkey='width'),
+                              min=1, max=1e6)
+        self.winId['atm:highlight:width'] = hlWidth.GetId()
+
+        flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(hlWidth, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
+
+        highlightSizer.Add(item=flexSizer,
+                           proportion=0,
+                           flag=wx.ALL | wx.EXPAND,
+                           border=5)
+
+        pageSizer.Add(item=highlightSizer,
+                      proportion=0,
+                      flag=wx.ALL | wx.EXPAND,
+                      border=5)
+
+        #
+        # data browser related settings
+        #
+        dataBrowserBox = wx.StaticBox(parent=panel, id=wx.ID_ANY,
+                                    label=" %s " % _("Data browser"))
+        dataBrowserSizer = wx.StaticBoxSizer(dataBrowserBox, wx.VERTICAL)
+
+        flexSizer = wx.FlexGridSizer (cols=2, hgap=5, vgap=5)
+        flexSizer.AddGrowableCol(0)
+        label = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Left mouse double click"))
+        leftDbClick = wx.Choice(parent=panel, id=wx.ID_ANY,
+                                choices=self.settings.Get(group='atm', key='leftDbClick', subkey='choices', internal=True),
+                                name="GetSelection")
+        leftDbClick.SetSelection(self.settings.Get(group='atm', key='leftDbClick', subkey='selection'))
+        self.winId['atm:leftDbClick:selection'] = leftDbClick.GetId()
+
+        flexSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+        flexSizer.Add(leftDbClick, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
+
+        dataBrowserSizer.Add(item=flexSizer,
+                           proportion=0,
+                           flag=wx.ALL | wx.EXPAND,
+                           border=5)
+
+        pageSizer.Add(item=dataBrowserSizer,
+                      proportion=0,
+                      flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
+                      border=5)
+
+        panel.SetSizer(pageSizer)
+
+        return panel
+
     def __CreateAdvancedPage(self, notebook):
         """Create notebook page concerning with symbology settings"""
         panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
@@ -270,10 +655,14 @@
                        flag=wx.ALIGN_LEFT |
                        wx.ALIGN_CENTER_VERTICAL,
                        pos=(row, 0))
-        self.settingsFile = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                      choices=['gisdbase', 'location', 'mapset'])
-        self.settingsFile.SetStringSelection(self.settings.Get('settingsFile'))
-        gridSizer.Add(item=self.settingsFile,
+        settingsFile = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                                 choices=self.settings.Get(group='advanced', key='settingsFile',
+                                                           subkey='choices', internal=True),
+                                 name='GetStringSelection')
+        settingsFile.SetStringSelection(self.settings.Get(group='advanced', key='settingsFile', subkey='type'))
+        self.winId['advanced:settingsFile:type'] = settingsFile.GetId()
+
+        gridSizer.Add(item=settingsFile,
                       flag=wx.ALIGN_RIGHT |
                       wx.ALIGN_CENTER_VERTICAL,
                       pos=(row, 1))
@@ -287,10 +676,14 @@
                        flag=wx.ALIGN_LEFT |
                        wx.ALIGN_CENTER_VERTICAL,
                        pos=(row, 0))
-        self.iconTheme = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                   choices=['grass', 'silk'])
-        self.iconTheme.SetStringSelection(self.settings.Get('iconTheme'))
-        gridSizer.Add(item=self.iconTheme,
+        iconTheme = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                              choices=self.settings.Get(group='advanced', key='iconTheme',
+                                                        subkey='choices', internal=True),
+                              name="GetStringSelection")
+        iconTheme.SetStringSelection(self.settings.Get(group='advanced', key='iconTheme', subkey='type'))
+        self.winId['advanced:iconTheme:type'] = iconTheme.GetId()
+
+        gridSizer.Add(item=iconTheme,
                       flag=wx.ALIGN_RIGHT |
                       wx.ALIGN_CENTER_VERTICAL,
                       pos=(row, 1))
@@ -314,10 +707,15 @@
                        flag=wx.ALIGN_LEFT |
                        wx.ALIGN_CENTER_VERTICAL,
                        pos=(row, 0))
-        self.digitInterface = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
-                                        choices=['vdigit', 'vedit'])
-        self.digitInterface.SetStringSelection(self.settings.Get('digitInterface'))
-        gridSizer.Add(item=self.digitInterface,
+        digitInterface = wx.Choice(parent=panel, id=wx.ID_ANY, size=(125, -1),
+                                   choices=self.settings.Get(group='advanced', key='digitInterface',
+                                                             subkey='choices', internal=True),
+                                   name="GetStringSelection")
+        digitInterface.SetStringSelection(self.settings.Get(group='advanced', key='digitInterface',
+                                                            subkey='type'))
+        self.winId['advanced:digitInterface:type'] = digitInterface.GetId()
+
+        gridSizer.Add(item=digitInterface,
                       flag=wx.ALIGN_RIGHT |
                       wx.ALIGN_CENTER_VERTICAL,
                       pos=(row, 1))
@@ -328,7 +726,7 @@
                                "Map topology is rebuild on each operation which can "
                                "significantly slow-down response. The vdigit is a native "
                                "interface which uses v.edit functionality, but doesn't "
-                               "call the command itself."),
+                               "call the module itself."),
                              self.GetSize()[0]-50, wx.ClientDC(self))
 
         gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
@@ -371,34 +769,58 @@
         event.Skip()
 
     def OnSave(self, event):
-        """Button 'Save' clicked"""
+        """Button 'Save' pressed"""
         self.__UpdateSettings()
         file = self.settings.SaveToFile()
-        self.parent.goutput.cmd_stdout.write('Settings saved to file <%s>.' % file)
+        self.parent.goutput.cmd_stdout.write(_('Settings saved to file \'%s\'.') % file)
         self.Close()
 
     def OnApply(self, event):
-        """Button 'Apply' clicked"""
+        """Button 'Apply' pressed"""
         self.__UpdateSettings()
-        
+        self.Close()
+
     def OnCancel(self, event):
-        """Button 'Cancel' clicked"""
+        """Button 'Cancel' pressed"""
         self.Close()
 
+    def OnDefault(self, event):
+        """Button 'Set to default' pressed"""
+        self.settings.userSettings = copy.deepcopy(self.settings.defaultSettings)
+        
+        # update widgets
+        for gks in self.winId.keys():
+            group, key, subkey = gks.split(':')
+            value = self.settings.Get(group, key, subkey)
+            win = self.FindWindowById(self.winId[gks])
+            if win.GetName() in ('GetValue', 'IsChecked'):
+                value = win.SetValue(value)
+            elif win.GetName() == 'GetSelection':
+                value = win.SetSelection(value)
+            elif win.GetName() == 'GetStringSelection':
+                value = win.SetStringSelection(value)
+            else:
+                value = win.SetValue(value)
+
+
     def __UpdateSettings(self):
         """Update user settings"""
-        # font
-        # TODO
+        for item in self.winId.keys():
+            group, key, subkey = item.split(':')
+            id = self.winId[item]
+            win = self.FindWindowById(id)
+            if win.GetName() == 'GetValue':
+                value = win.GetValue()
+            elif win.GetName() == 'GetSelection':
+                value = win.GetSelection()
+            elif win.GetName() == 'IsChecked':
+                value = win.IsChecked()
+            elif win.GetName() == 'GetStringSelection':
+                value = win.GetStringSelection()
+            else:
+                value = win.GetValue()
+            self.settings.Set(group, key, subkey, value)
 
-        # location
-        self.settings.Set('settingsFile', self.settingsFile.GetStringSelection())
-
-        # icon theme
-        self.settings.Set('iconTheme', self.iconTheme.GetStringSelection())
-        
-        # digitization interface
-        self.settings.Set('digitInterface', self.digitInterface.GetStringSelection())
-
 class SetDefaultFont(wx.Dialog):
     """
     Opens a file selection dialog to select default font
@@ -498,3 +920,81 @@
               fontlist.append(dfonts[item])
 
         return fontlist
+
+class MapsetAccess(wx.Dialog):
+    """
+    Controls setting options and displaying/hiding map overlay decorations
+    """
+    def __init__(self, parent, id, title=_('Set/unset access to mapsets in current location'),
+                 pos=wx.DefaultPosition, size=(-1, -1),
+                 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER):
+        wx.Dialog.__init__(self, parent, id, title, pos, size, style)
+
+        self.all_mapsets, self.accessible_mapsets = utils.ListOfMapsets()
+        self.curr_mapset = grassenv.GetGRASSVariable('MAPSET')
+
+        # make a checklistbox from available mapsets and check those that are active
+        sizer = wx.BoxSizer(wx.VERTICAL)
+
+        label = wx.StaticText(parent=self, id=wx.ID_ANY,
+                              label=_("Check mapset to make it accessible, uncheck it to hide it.%s"
+                                      "Note: PERMANENT and current mapset are always accessible.") % os.linesep)
+        sizer.Add(item=label, proportion=0,
+                  flag=wx.ALL, border=5)
+
+        self.mapsetlb = wx.CheckListBox(parent=self, id=wx.ID_ANY, pos=wx.DefaultPosition,
+                                        size=(350,200), choices=self.all_mapsets)
+        self.mapsetlb.Bind(wx.EVT_CHECKLISTBOX, self.OnCheckMapset)
+        
+        sizer.Add(item=self.mapsetlb, proportion=1,
+                  flag=wx.ALL | wx.EXPAND, border=5)
+
+        # check all accessible mapsets
+        if globalSettings.Get(group='general', key='mapsetPath', subkey='selection') == 1:
+            for mset in self.all_mapsets:
+                self.mapsetlb.Check(self.all_mapsets.index(mset), True)
+        else:
+            for mset in self.accessible_mapsets:
+                self.mapsetlb.Check(self.all_mapsets.index(mset), True)
+
+        # dialog buttons
+        line = wx.StaticLine(parent=self, id=wx.ID_ANY,
+                             style=wx.LI_HORIZONTAL)
+        sizer.Add(item=line, proportion=0,
+                  flag=wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border=5)
+
+        btnsizer = wx.StdDialogButtonSizer()
+        okbtn = wx.Button(self, wx.ID_OK)
+        okbtn.SetDefault()
+        btnsizer.AddButton(okbtn)
+
+        cancelbtn = wx.Button(self, wx.ID_CANCEL)
+        btnsizer.AddButton(cancelbtn)
+        btnsizer.Realize()
+
+        sizer.Add(item=btnsizer, proportion=0,
+                  flag=wx.EXPAND | wx.ALIGN_RIGHT | wx.ALL, border=5)
+
+        # do layout
+        self.Layout()
+        self.SetSizer(sizer)
+        sizer.Fit(self)
+
+        self.SetMinSize(self.GetBestSize())
+        
+    def OnCheckMapset(self, event):
+        """Mapset checked/unchecked"""
+        mapset = self.mapsetlb.GetString(event.GetSelection())
+        if mapset == 'PERMANENT' or mapset == self.curr_mapset:
+            self.mapsetlb.Check(event.GetSelection(), True)
+        
+    def GetMapsets(self):
+        """Get list of checked mapsets"""
+        ms = []
+        i = 0
+        for mset in self.all_mapsets:
+            if self.mapsetlb.IsChecked(i):
+                ms.append(mset)
+            i += 1
+
+        return ms

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/render.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/render.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/render.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -1,45 +1,58 @@
 """
-MODULE: render
+ at package render
 
-CLASSES:
-    * MapLayer
-    * Map
+Rendering map layers into image
 
-PURPOSE: Rendering
+Classes:
+ - MapLayer
+ - Map
 
-AUTHORS: The GRASS Development Team
-         Michael Barton, Jachym Cepicky, Martin Landa
+C) 2006-2008 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
 
-COPYRIGHT: (C) 2006-2007 by the GRASS Development Team
-         This program is free software under the GNU General Public
-         License (>=v2). Read the file COPYING that comes with GRASS
-         for details.
+ at author Michael Barton, Jachym Cepicky, Martin Landa
+
+ at date 2006-2008
 """
 
-import os, sys, glob, math
+import os
+import sys
+import glob
+import math
+try:
+    import subprocess
+except:
+    compatPath = os.path.join(globalvar.ETCWXDIR, "compat")
+    sys.path.append(compatPath)
+    import subprocess
+
+import wx
+
+import globalvar
 import utils
-
 import gcmd
 from debug import Debug as Debug
 
+#
+# use g.pnmcomp for creating image composition or
+# wxPython functionality
+#
+USE_GPNMCOMP = True
+
 class MapLayer(object):
-    """
-    This class serves for storing map layers to be displayed
-
-    Common layer attributes:
-    type     - layer type (raster, vector, overlay, command, etc.)
-    name     - layer name, e.g. map name ('elevation at PERMANENT')
-    cmdlist  - GRASS command (e.g. ['d.rast', 'map=elevation at PERMANENT'])
-
-    active   - layer is active, will be rendered only if True
-    hidden   - layer is hidden, won't be listed in GIS Manager if True
-    opacity  - layer opacity <0;1>
-
-    mapfile  - file name of rendered layer
-    maskfile - mask name of rendered layer
-    """
+    """Stores information about map layers or overlays to be displayed"""
     def __init__(self, type, cmd, name=None,
-                 active=True, hidden=False, opacity=1):
+                 active=True, hidden=False, opacity=1.0):
+        """
+        @param type layer type (raster, vector, overlay, command, etc.)
+        @param cmd GRASS command for rendering layer, given as list, e.g. ['d.rast', 'map=elevation at PERMANENT']
+        @param name layer name, e.g. 'elevation at PERMANENT'
+        @param active layer is active, will be rendered only if True
+        @param hidden layer is hidden, won't be listed in Layer Manager if True
+        @param opacity layer opacity <0;1>
+        """
         self.type    = type
         self.name    = name
         self.cmdlist = cmd
@@ -53,6 +66,7 @@
                    (self.type, self.GetCmd(string=True), self.name, self.active,
                     self.opacity, self.hidden))
 
+        # generated file for layer
         gtemp = utils.GetTempfile()
         self.maskfile = gtemp + ".pgm"
         if self.type == "overlay":
@@ -64,24 +78,10 @@
         Debug.msg (3, "MapLayer.__del__(): layer=%s, cmd='%s'" %
                    (self.name, self.GetCmd(string=True)))
 
-    def __renderLayer(self):
-        """
-        Stores generic command with all parameters in the self.cmdlist variable
-        """
-        try:
-            Debug.msg (3, "MapLayer.__renderLayer(): cmd=%s" % self.cmdlist)
-
-        except StandardError, e:
-            sys.stderr.write("Could not render command layer <%s>: %s\n" %\
-                 (self.name, str(e)))
-            self.cmdlist = None
-
     def Render(self):
-        """
-        Runs all d.* commands.
+        """Render map layer to image
 
-        Returns:
-            Name of file with rendered image or None
+        @return name of file with rendered image or None
         """
 
         Debug.msg (3, "MapLayer.Render(): type=%s" % \
@@ -90,44 +90,39 @@
         #
         # to be sure, set temporary file with layer and mask
         #
+        gtemp = utils.GetTempfile()
+        self.maskfile = gtemp + ".pgm"
         if self.type == 'overlay':
-            if not self.mapfile:
-                gtemp = utils.GetTempfile()
-                self.mapfile  = gtemp + ".png"
+            self.mapfile  = gtemp + ".png"
         else:
-            if not self.mapfile:
-                gtemp = utils.GetTempfile()
-                self.maskfile = gtemp + ".pgm"
-                self.mapfile  = gtemp + ".ppm"
+            self.mapfile  = gtemp + ".ppm"
 
-
         #
         # prepare command for each layer
         #
-        layertypes = ['raster','rgb','his','shaded','rastarrow','rastnum','vector','thememap','themechart',\
-                      'grid','geodesic','rhumb','labels','command','overlay']
-        if self.type in layertypes:
-            self.__renderLayer()
-        elif self.type == "wms":
-            print "Type wms is not supported yet"
-        else:
-            print "Type <%s> of layer <%s> is not supported yet" % \
-                  (self.type, self.name)
+        layertypes = ['raster', 'rgb', 'his', 'shaded', 'rastarrow', 'rastnum',
+                      'vector','thememap','themechart',
+                      'grid', 'geodesic', 'rhumb', 'labels',
+                      'command',
+                      'overlay']
 
+        if self.type not in layertypes:
+            raise gcmd.GStdError(_("<%(name)s>: layer type <%(type)s> is not supported yet.") % \
+                                     {'type' : self.type, 'name' : self.name})
+        
         #
         # start monitor
         #
         os.environ["GRASS_PNGFILE"] = self.mapfile
-
+        
         #
         # execute command
         #
-        if not self.cmdlist:
-            sys.stderr.write("Cannot render layer <%s> with command: #%s#" %\
-                             (self.name, self.cmdlist))
-            return None
-
-        runcmd = gcmd.Command(cmd=self.cmdlist + ['--q']) # run quiet
+        try:
+            runcmd = gcmd.Command(cmd=self.cmdlist + ['--q'],
+                                  stderr=None)
+        except gcmd.CmdError, e:
+            print e
         
         if runcmd.returncode != 0:
             self.mapfile = None
@@ -142,45 +137,49 @@
         return self.mapfile
 
     def GetMapset(self):
-        """Return mapset name of the layer or None"""
+        """
+        @return mapset name of the layer
+        """
         if not self.name:
-            return None
+            return ''
 
-        idxAt = self.name.find('@')
-        if idxAt > -1:
-            return self.name[idxAt+1:]
-        else:
-            return None
+        return self.name.split('@')[1]
 
     def GetCmd(self, string=False):
-        """Get command list/string"""
+        """
+        @param string get command as string if True otherwise list
+
+        @return command list/string
+        """
         if string:
             return ' '.join(self.cmdlist)
         else:
             return self.cmdlist
 
     def GetOpacity(self, float=False):
-        """Get opacity level"""
+        """
+        Get opacity level
+        @param float get opacity level in <0,1> otherwise <0,100>
+
+        @return opacity level
+        """
         if float:
             return self.opacity
-        else:
-            return int (self.opacity * 100)
+        
+        return int (self.opacity * 100)
 
 class Map(object):
     """
-    The class serves for rendering of output images.
+    Map composition (stack of map layers)
     """
-
     def __init__(self):
-        """Map constructor"""
-
         # 
         # region/extent settigns
         #
         self.wind      = {}    # WIND settings (wind file)
         self.region    = {}    # region settings (g.region)
-        self.width     = 640.0 # map width
-        self.height    = 480.0 # map height
+        self.width     = 640   # map width
+        self.height    = 480   # map height
 
         #
         # list of layers
@@ -194,7 +193,6 @@
         # environment settings
         #
         self.env       = {}  # enviroment variables, like MAPSET, LOCATION_NAME, etc.
-
         self.verbosity = 0   # --q
 
         # 
@@ -222,7 +220,7 @@
         Set up 'self.region' using g.region command and
         self.wind according to the wind file.
 
-        At the end adjust self.region based on map window size.
+        Adjust self.region based on map window size.
         """
 
         #
@@ -240,38 +238,13 @@
         #
         self.SetRegion()
 
-
-        # self.region['ewres'] = self.region['nsres'] = abs(float(self.region['e'])
-        # - float(self.region['w']))/self.width
-
-        # I don't think that this method is used anymore (Michael 8/6/2007
-        #    def __initMonSize(self):
-        #        """
-        #        Reads current GRASS monitor dimensions from env or
-        #        use the default values [640x480]
-        #        """
-        #        print 'in initmonsize'
-        #
-        #        try:
-        #            self.width = int (os.getenv("GRASS_WIDTH"))
-        #        except:
-        #            self.width = 640
-        #
-        #        try:
-        #            self.height = int(os.getenv("GRASS_HEIGHT"))
-        #
-        #        except:
-        #            self.height = 480
-        
-        
     def InitGisEnv(self):
         """
         Stores GRASS variables (g.gisenv) to self.env variable
         """
 
         if not os.getenv("GISBASE"):
-            sys.stderr.write(_("GISBASE not set, you must be "
-                               "in GRASS GIS to run this program\n"))
+            print >> sys.stderr, _("GISBASE not set. You must be in GRASS GIS to run this program.")
             sys.exit(1)
 
         gisenvCmd = gcmd.Command(["g.gisenv"])
@@ -293,8 +266,7 @@
         try:
             windfile = open (windfile, "r")
         except StandardError, e:
-            sys.stderr.write(_("Could open file <%s>: %s\n") % \
-                                 (windfile,e))
+            sys.stderr.write("%s %<s>: %s" % (_("Unable to open file"), windfile, e))
             sys.exit(1)
 
         for line in windfile.readlines():
@@ -388,27 +360,34 @@
     def ChangeMapSize(self, (width, height)):
         """Change size of rendered map.
         
-        Return:
-        True on success
-        False on failure
+        @param width,height map size
+
+        @return True on success
+        @return False on failure
         """
         try:
-            self.width  = float(width)
-            self.height = float(height)
-            Debug.msg(2, "Map.ChangeMapSize(): width=%.1f, height=%.1f" % \
+            self.width  = int(width)
+            self.height = int(height)
+            Debug.msg(2, "Map.ChangeMapSize(): width=%d, height=%d" % \
                           (self.width, self.height))
             return True
         except:
+            self.width  = 640
+            self.height = 480
             return False
 
-    def GetRegion(self, rast=None, vect=None):
+    def GetRegion(self, rast=None, vect=None,
+                  n=None, s=None, e=None, w=None):
         """
-        Returns dictionary with output from g.region -ugpc
+        Get region settings
 
         Optionaly raster or vector map layer can be given.
 
-        Return e.g.:
-            {"n":"4928010", "s":"4913700", "w":"589980",...}
+        @param rast raster name or None
+        @param vect vector name or None
+        
+        @return region settings as directory, e.g. {
+        "n":"4928010", "s":"4913700", "w":"589980",...}
         """
 
         region = {}
@@ -419,13 +398,33 @@
         # do not update & shell style output
         cmdList = ["g.region", "-u", "-g", "-p", "-c"]
 
+        if n:
+            cmdList.append('n=%s' % n)
+        if s:
+            cmdList.append('s=%s' % s)
+        if e:
+            cmdList.append('e=%s' % e)
+        if w:
+            cmdList.append('w=%s' % w)
+
         if rast:
             cmdList.append('rast=%s' % rast)
-        elif vect:
+        if vect:
             cmdList.append('vect=%s' % vect)
 
-        cmdRegion = gcmd.Command(cmdList)
+        try:
+            cmdRegion = gcmd.Command(cmdList)
+        except gcmd.CmdError, e:
+            if rast:
+                e.message = _("Unable to zoom to raster map <%s>.") % rast + \
+                '%s%s' % (os.linesep, os.linesep) + e.message
+            elif vect:
+                e.message = _("Unable to zoom to vector map <%s>.") % vect + \
+                '%s%s' % (os.linesep, os.linesep) + e.message
 
+            print e
+            return self.region
+
         for reg in cmdRegion.ReadStdOutput():
             key, val = reg.split("=", 1)
             try:
@@ -446,12 +445,12 @@
         Render string for GRASS_REGION env. variable, so that the images will be rendered
         from desired zoom level.
 
-        Returns:
-        String usable for GRASS_REGION variable or None
-        If windres set to True, uses resolution from WIND file rather than display
-        (for modules that require set resolution like d.rast.num)
+        @param windres If windres set to True, uses resolution from
+        WIND file rather than display (for modules that require set
+        resolution like d.rast.num)
+
+        @return String usable for GRASS_REGION variable or None
         """
-
         grass_region = ""
 
         # adjust region settigns to match monitor
@@ -533,19 +532,16 @@
     def GetListOfLayers(self, l_type=None, l_mapset=None, l_name=None,
                         l_active=None, l_hidden=None):
         """
-        Returns list of layers (including overlays [l_type='overlay'] of
-        selected type or list of all layers. It
-        is also possible to get list of active or hidden layers.
+        Returns list of layers of selected properties or list of all
+        layers. 
 
-        Parameters:
-            l_type   - layer type, e.g. raster/vector/wms/overlay ...
-            l_mapset - all layer from given mapset
-            l_name   - all layer with given name
-            l_active - only layers with 'active' attribute set to True or False
-            l_hidden - only layers with 'hidden' attribute set to True or False
+        @param l_type layer type, e.g. raster/vector/wms/overlay
+        @param l_mapset all layers from given mapset
+        @param l_name all layers with given name
+        @param l_active only layers with 'active' attribute set to True or False
+        @param l_hidden only layers with 'hidden' attribute set to True or False
 
-        Returns:
-            List of selected layers or None
+        @return list of selected layers
         """
 
         selected = []
@@ -589,15 +585,17 @@
 
         return selected
 
-    def Render(self, force=False):
+    def Render(self, force=False, mapWindow=None):
         """
         Creates final image composite
 
-        NOTE: This function should be done by high-level tools, which
+        This function can conditionaly use high-level tools, which
         should be avaliable in wxPython library
+        
+        @param force force rendering
+        @param reference for MapFrame instance (for progress bar)
 
-        Returns:
-            Name of file with rendered image or None
+        @return name of file with rendered image or None
         """
 
         maps = []
@@ -609,86 +607,106 @@
         os.environ["GRASS_WIDTH"]  = str(self.width)
         os.environ["GRASS_HEIGHT"] = str(self.height)
 
-        try:
-            # render map layers
-            for layer in self.layers + self.overlays:
-                # skip if not active
-                if layer == None or layer.active == False:
+        # render map layers
+        for layer in self.layers + self.overlays:
+            # skip if not active
+            if layer == None or layer.active == False:
+                continue
+            
+            # render if there is no mapfile
+            if layer.mapfile == None:
+                layer.Render()
+                    
+            # process bar
+            if mapWindow is not None:
+                mapWindow.onRenderCounter += 1
+
+            wx.Yield()
+            # redraw layer content
+            if force:
+                if not layer.Render():
                     continue
 
-                # render if there is no mapfile
-                if layer.mapfile == None:
-                    layer.Render()
-
-                # redraw layer content
-                if force:
-                    if not layer.Render():
-                        continue
-
-                # add image to compositing list
-                if layer.type != "overlay":
-                    maps.append(layer.mapfile)
-                    masks.append(layer.maskfile)
-                    opacities.append(str(layer.opacity))
-
+            # add image to compositing list
+            if layer.type != "overlay":
+                maps.append(layer.mapfile)
+                masks.append(layer.maskfile)
+                opacities.append(str(layer.opacity))
+                
             Debug.msg (3, "Map.Render() type=%s, layer=%s " % (layer.type, layer.name))
 
-            # make arrays to strings
-            mapstr = ",".join(maps)
-            maskstr = ",".join(masks)
-            opacstr = repr(",".join(opacities))
+	# ugly hack for MSYS
+	if not subprocess.mswindows:
+	    mapstr = ",".join(maps)
+	    maskstr = ",".join(masks)
+            mapoutstr = self.mapfile
+	else:
+	    mapstr = ""
+	    for item in maps:
+                mapstr += item.replace('\\', '/')		
+	    mapstr = mapstr.rstrip(',')
+	    maskstr = ""
+            for item in masks:
+		maskstr += item.replace('\\', '/')
+	    maskstr = maskstr.rstrip(',')
+	    mapoutstr = self.mapfile.replace('\\', '/')
 
-            # compose command
-            compcmd = "g.pnmcomp in='" + mapstr + \
-                "' mask='" + maskstr + \
-                "' opacity=" + opacstr + \
-                " background=255:255:255" + \
-                " width=" + str(self.width) + \
-                " height=" + str(self.height) + \
-                " output='" + self.mapfile + "'"
+        compstring = "g.pnmcomp" + globalvar.EXT_BIN + \
+            " in=" + mapstr + \
+            " mask=" + maskstr + \
+            " opacity=" + ",".join(opacities)+ \
+            " background=255:255:255" + \
+            " width=" + str(self.width) + \
+            " height=" + str(self.height) + \
+            " output=" + mapoutstr
 
-            # render overlays
+        # compose command
+        complist = ["g.pnmcomp",
+                   "in=%s" % ",".join(maps),
+	           "mask=%s" % ",".join(masks),
+                   "opacity=%s" % ",".join(opacities),
+                   "background=255:255:255",
+                   "width=%s" % str(self.width),
+                   "height=%s" % str(self.height),
+                   "output=%s" % self.mapfile]
 
-            os.unsetenv("GRASS_REGION")
 
-            if tmp_region:
-                os.environ["GRASS_REGION"] = tmp_region
+        # render overlays
 
-            # run g.composite to get composite image
-            if os.system(compcmd):
-                sys.stderr.write("Could not run g.pnmcomp [%s]\n" % compcmd)
-                raise Exception (compcmd)
+        os.unsetenv("GRASS_REGION")
 
-            Debug.msg (2, "Map.Render() force=%s file=%s" % (force, self.mapfile))
+        if tmp_region:
+            os.environ["GRASS_REGION"] = tmp_region
 
-            return self.mapfile
+        # run g.pngcomp to get composite image
+        try:
+            gcmd.Command(complist)
+	    # os.system(compstring)
+        except gcmd.CmdError, e:
+            print e
+            return None
 
-        except Exception, e:
-            os.unsetenv("GRASS_REGION")
+        Debug.msg (2, "Map.Render() force=%s file=%s" % (force, self.mapfile))
 
-            if tmp_region:
-                os.environ["GRASS_REGION"] = tmp_region
-            return None
+        return self.mapfile
 
     def AddLayer(self, type, command, name=None,
                  l_active=True, l_hidden=False, l_opacity=1, l_render=False):
         """
         Adds generic display command layer to list of layers
 
-        Layer Attributes:
-        item - gis manager layer tree item
-        type - layer type
-        name - layer name
-        cmd  - GRASS command given as list
+        @param item reference to item in layer tree
+        @param type layer type
+        @param name layer name
+        @param cmd  GRASS command to render layer
+        @param l_active checked/not checked for display in layer tree
+        @param l_hidden not used here
+        @param l_opacity opacity leve range from 0(transparent)-1(not transparent)
+        @param l_render render an image if False
 
-        l_active   - checked/not checked for display in layer tree
-        l_hidden   - not used here
-        l_opacity  - range from 0-1
-        l_render   - render an image if False
+        @return new layer on success
+        @return None on failure
 
-        Returns:
-            Added layer on success or None
-
         """
         # l_opacity must be <0;1>
         if l_opacity < 0: l_opacity = 0
@@ -703,8 +721,7 @@
         Debug.msg (3, "Map.AddLayer(): layer=%s" % layer.name)
         if l_render:
             if not layer.Render():
-                print >> sys.stderr, _("Could not render layer <%s>\n") % \
-                                      (name)
+                raise gcmd.GStdError(_("Unable to render map layer <%s>.") % (name))
 
         return self.layers[-1]
 
@@ -766,16 +783,18 @@
         if layer:
             self.layers[oldlayerindex] = newlayer
 
-        if l_render:
-            if not layer.Render():
-                sys.stderr.write("Could not render layer <%s>\n" % \
-                       (name))
+        if l_render and not layer.Render():
+            raise gcmd.GException(_("Unable to render map layer <%s>.") % 
+                                  (name))
 
         return self.layers[-1]
 
     def ChangeOpacity(self, layer, l_opacity):
         """
-        Changes opacity value for rendering
+        Changes opacity value of map layer
+
+        @param layer layer instance
+        @param l_opacity opacity level <0;1>
         """
         # l_opacity must be <0;1>
         if l_opacity < 0: l_opacity = 0
@@ -785,10 +804,12 @@
         Debug.msg (3, "Map.ChangeOpacity(): layer=%s, opacity=%f" % \
                    (layer.name, layer.opacity))
 
-
     def ChangeLayerActive(self, layer, active):
         """
         Change the active state of a layer
+
+        @param layer layer instance
+        @param active to be rendered (True)
         """
         layer.active = active
 
@@ -798,6 +819,9 @@
     def ChangeLayerName (self, layer, name):
         """
         Change name of the layer
+
+        @param layer layer instance
+        @param name  layer name to set up
         """
         Debug.msg (3, "Map.ChangeLayerName(): from=%s to=%s" % \
                    (layer.name, name))
@@ -805,17 +829,18 @@
 
     def RemoveLayer(self, name=None, id=None):
         """
-        Removes layer from list of layers, defined by name at mapset or id
+        Removes layer from layer list of layers
 
-        Parameters:
-            name	- map name
-            id	- index of the layer in layer list
+        Layer is defined by name at mapset or id.
 
-        Returns:
-            Removed layer on success or None
+        @param name layer name (must be unique)
+        @param id layer index in layer list
+
+        @return removed layer on success
+        @return None on failure
         """
 
-        # del by name
+        # delete by name
         if name:
             retlayer = None
             for layer in self.layers:
@@ -835,11 +860,10 @@
         """
         Returns index of layer in layer list.
 
-        Parameters:
-         layer -
+        @param layer layer instace
 
-        Returns:
-         Integer or None
+        @return layer index
+        @return None
         """
 
         if layer in self.layers:
@@ -852,13 +876,13 @@
         """
         Adds overlay (grid, barscale, others?) to list of overlays
 
-        Overlay Attributes:
-            command	   - display command
-            l_active   - see MapLayer class
-            l_render   - render an image
+        @param ovltype overlay type
+        @param command GRASS command to render overlay
+        @param l_active overlay activated (True) or disabled (False)
+        @param l_render render an image (True)
 
-        Returns:
-            Added layer on success or None
+        @return new layer on success
+        @retutn None on failure
         """
 
         Debug.msg (2, "Map.AddOverlay(): cmd=%s, render=%d" % (command, l_render))
@@ -868,9 +892,9 @@
         # add maplayer to the list of layers
         self.overlays.append(overlay)
 
-        if l_render and command != '':
-            if not overlay.Render():
-                sys.stderr.write("Could not render overlay <%s>\n" % (command))
+        if l_render and command != '' and not overlay.Render():
+            raise gcmd.GException(_("Unable render overlay <%s>.") % 
+                                  (name))
 
         self.ovlookup[ovltype] = overlay
 
@@ -880,6 +904,16 @@
                       l_active=True, l_hidden=False, l_opacity=1, l_render=False):
         """
         Change overlay properities
+
+        @param ovltype overlay type
+        @param type layer type
+        @param command GRASS command to render an overlay
+        @param l_active overlay is active (True) or disabled (False)
+        @param l_hidded not used here
+        @param l_opacity opacity level <0,1>
+        @param l_render render overlay (True)
+
+        @return new overlay instance
         """
 
         newoverlay = MapLayer(type='overlay', name=name, cmd=command,
@@ -892,9 +926,9 @@
             self.overlays[oldovlindex] = newoverlay
             self.ovlookup[ovltype] = newoverlay
 
-        if l_render and command != '':
-            if not overlay.Render():
-                sys.stderr.write("Could not render overlay <%s>\n" % (command))
+        if l_render and command != '' and not overlay.Render():
+            raise gcmd.GException(_("Unable render overlay <%s>.") % 
+                                  (name))
 
         return self.overlays[-1]
 
@@ -914,7 +948,8 @@
         Go trough all layers and remove them from layer list
         Removes also l_mapfile and l_maskfile
 
-        Returns 1 if failed or None if ok
+        @return 1 on faulure
+        @return None on success
         """
         try:
             for layer in self.layers:
@@ -942,7 +977,6 @@
 
     def ReverseListOfLayers(self):
         """Reverse list of layers"""
-
         return self.layers.reverse()
 
 if __name__ == "__main__":

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/rules.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/rules.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/rules.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -17,14 +17,16 @@
 
 """
 
-import wx
 import os
 import sys
 
+import wx
+
+import gcmd
 import gselect
 
 class RulesText(wx.Dialog):
-    def __init__(self, parent, id=wx.ID_ANY, title="Enter rules",
+    def __init__(self, parent, id=wx.ID_ANY, title=_("Enter rules"),
                  pos=wx.DefaultPosition, size=wx.DefaultSize,
                  style=wx.DEFAULT_DIALOG_STYLE,
                  cmd=None):
@@ -33,6 +35,8 @@
         """
         Dialog for interactively entering rules
         for map management commands
+
+        @param cmd command (given as list)
         """
         self.parent = parent
         self.cmd = cmd # map management command
@@ -41,97 +45,89 @@
         self.rules = '' # rules for changing
         self.overwrite = False
 
-        if self.cmd == 'r.colors':
-            label1 = 'Create new color table using color rules'
-            label2 = 'Raster map:'
+        if self.cmd[0] == 'r.colors':
+            label1 = _('Create new color table using color rules')
+            label2 = _('Raster map:')
             label3 = None
-            label4 = 'Enter color rules'
+            label4 = _('Enter color rules')
             seltype = 'cell'
-        elif self.cmd == 'r.reclass':
-            label1 = 'Reclassify raster map using rules'
-            label2 = 'Map to reclassify:'
-            label3 = 'Reclassified map:'
-            label4 = 'Enter reclassification rules'
+        elif self.cmd[0] == 'r.reclass':
+            label1 = _('Reclassify raster map using rules')
+            label2 = _('Raster map to reclassify:')
+            label3 = _('Reclassified raster map:')
+            label4 = _('Enter reclassification rules')
             seltype = 'cell'
-        elif self.cmd == 'r.recode':
-            label1 = 'Recode raster map using rules'
-            label2 = 'Map to recode:'
-            label3 = 'Recoded map:'
-            label4 = 'Enter recoding rules'
+        elif self.cmd[0] == 'r.recode':
+            label1 = _('Recode raster map using rules')
+            label2 = _('Raster map to recode:')
+            label3 = _('Recoded raster map:')
+            label4 = _('Enter recoding rules')
             seltype = 'cell'
-        elif self.cmd == 'v.reclass':
-            label1 = 'Reclassify vector map using SQL rules'
-            label2 = 'Map to reclassify:'
-            label3 = 'Reclassified map:'
-            label4 = 'Enter reclassification rules'
+        elif self.cmd[0] == 'v.reclass':
+            label1 = _('Reclassify vector map using SQL rules')
+            label2 = _('Vector map to reclassify:')
+            label3 = _('Reclassified vector map:')
+            label4 = _('Enter reclassification rules')
             seltype = 'vector'
 
+        # set window frame title
+        self.SetTitle(label1)
+
         sizer = wx.BoxSizer(wx.VERTICAL)
+        boxSizer =  wx.GridBagSizer(hgap=5, vgap=5)
+        boxSizer.AddGrowableCol(0)
 
-        box = wx.BoxSizer(wx.HORIZONTAL)
-        label = wx.StaticText(self, wx.ID_ANY, label1)
-        box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-        sizer.Add(item=box, proportion=0,
-                  flag=wx.ALIGN_CENTER|
-                  wx.ALL,border=5)
+        row = 0
+        boxSizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY, label=label2),
+                     flag=wx.ALIGN_CENTER_VERTICAL,
+                     pos=(row,0))
 
-        box = wx.BoxSizer(wx.HORIZONTAL)
-        label = wx.StaticText(self, wx.ID_ANY, label2)
-        box.Add(label, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
-        self.selection = gselect.Select(self, id=wx.ID_ANY, size=(300,-1),
-                                        type=seltype)
-        box.Add(self.selection, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
-        sizer.Add(item=box, proportion=0,
-                  flag=wx.ALIGN_CENTER_VERTICAL|
-                  wx.ALIGN_RIGHT|
-                  wx.ALL,border=5)
+        self.selectionInput = gselect.Select(parent=self, id=wx.ID_ANY, size=(300,-1),
+                                             type=seltype)
+        boxSizer.Add(item=self.selectionInput,
+                     pos=(row,1))
+        row += 1
 
-        if cmd != 'r.colors':
-            box = wx.BoxSizer(wx.HORIZONTAL)
-            label = wx.StaticText(self, wx.ID_ANY, label3)
-            box.Add(label, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
-            self.textentry = wx.TextCtrl(self, wx.ID_ANY, "", size=(300,-1))
-            box.Add(self.textentry, 0, wx.ALIGN_RIGHT|wx.ALL, 5)
-            self.textentry.Bind(wx.EVT_TEXT, self.OnText)
-            sizer.Add(item=box, proportion=0,
-                      flag=wx.ALIGN_CENTER_VERTICAL|
-                      wx.ALIGN_RIGHT|
-                      wx.ALL,border=5)
-
-            box = wx.BoxSizer(wx.HORIZONTAL)
-            self.ovrwrtcheck = wx.CheckBox(self, wx.ID_ANY, 'overwrite existing file')
+        if self.cmd[0] != 'r.colors':
+            boxSizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY, label=label3),
+                         flag=wx.ALIGN_CENTER_VERTICAL,
+                         pos=(row, 0))
+            self.selectionOutput = gselect.Select(parent=self, id=wx.ID_ANY, size=(300,-1),
+                                                  type=seltype)
+            self.selectionOutput.Bind(wx.EVT_TEXT, self.OnSelectionOutput)
+            boxSizer.Add(item=self.selectionOutput,
+                         pos=(row,1))
+            row += 1
+            # TODO remove (see Preferences dialog)
+            self.ovrwrtcheck = wx.CheckBox(parent=self, id=wx.ID_ANY, label=_('overwrite existing file'))
             self.ovrwrtcheck.SetValue(self.overwrite)
-            box.Add(self.ovrwrtcheck, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-            sizer.Add(item=box, proportion=0,
-                      flag=wx.ALIGN_CENTER_VERTICAL|
-                      wx.ALIGN_RIGHT|
-                      wx.ALL,border=5)
+            boxSizer.Add(item=self.ovrwrtcheck,
+                         pos=(row, 1))
             self.Bind(wx.EVT_CHECKBOX, self.OnOverwrite,   self.ovrwrtcheck)
+            row += 1
 
-        box = wx.BoxSizer(wx.HORIZONTAL)
-        label = wx.StaticText(self, wx.ID_ANY, label4)
-        box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-        helpbtn = wx.Button(self, wx.ID_ANY, "Help")
-        box.Add(helpbtn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-        sizer.Add(item=box, proportion=0,
-                  flag=wx.ALIGN_CENTER|
-                  wx.ALL,border=5)
+        boxSizer.Add(item=wx.StaticText(parent=self, id=wx.ID_ANY, label=label4),
+                     flag=wx.ALIGN_CENTER_VERTICAL,
+                     pos=(row, 0))
+        helpbtn = wx.Button(parent=self, id=wx.ID_HELP)
+        boxSizer.Add(item=helpbtn, flag=wx.ALIGN_RIGHT, pos=(row, 1))
+        row += 1 
 
-        box = wx.BoxSizer(wx.HORIZONTAL)
-        self.rulestxt = wx.TextCtrl(self, id=wx.ID_ANY, value='',
+        self.rulestxt = wx.TextCtrl(parent=self, id=wx.ID_ANY, value='',
                                     pos=wx.DefaultPosition, size=(400,150),
-                                    style=wx.TE_MULTILINE|
-                                    wx.HSCROLL|
+                                    style=wx.TE_MULTILINE |
+                                    wx.HSCROLL |
                                     wx.TE_NOHIDESEL)
         self.rulestxt.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, ''))
-        box.Add(self.rulestxt, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
-        sizer.Add(item=box, proportion=0,
-                  flag=wx.ALIGN_CENTER|
-                  wx.ALL,border=5)
+        boxSizer.Add(item=self.rulestxt, pos=(row, 0), flag=wx.EXPAND, span=(1, 2))
 
-        line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
-        sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
+        sizer.Add(item=boxSizer, proportion=1,
+                  flag=wx.ALL ,border=10)
 
+        line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20,-1), style=wx.LI_HORIZONTAL)
+        sizer.Add(item=line, proportion=0,
+                  flag=wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
+
         btnsizer = wx.StdDialogButtonSizer()
 
         btn = wx.Button(self, wx.ID_OK)
@@ -142,28 +138,32 @@
         btnsizer.AddButton(btn)
         btnsizer.Realize()
 
-        sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
+        sizer.Add(item=btnsizer, proportion=0,
+                  flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
 
         self.SetSizer(sizer)
         sizer.Fit(self)
 
+        # bindings
         self.Bind(wx.EVT_BUTTON, self.OnHelp, helpbtn)
-        self.selection.Bind(wx.EVT_TEXT, self.OnSelection)
+        self.selectionInput.Bind(wx.EVT_TEXT, self.OnSelectionInput)
         self.Bind(wx.EVT_TEXT, self.OnRules,   self.rulestxt)
 
-    def OnSelection(self, event):
+    def OnSelectionInput(self, event):
         self.inmap = event.GetString()
 
-    def OnText(self, event):
+    def OnSelectionOutput(self, event):
         self.outmap = event.GetString()
 
     def OnRules(self, event):
         self.rules = event.GetString().strip()
-        if self.cmd == 'r.recode':
-            self.rules = self.rules+'\n'
+        if self.cmd[0] == 'r.recode':
+            self.rules = self.rules + '%s' % os.linesep
 
     def OnHelp(self, event):
-        os.popen('g.manual --quiet %s ' % self.cmd)
+        gcmd.Command(['g.manual',
+                      '--quiet', 
+                      '%s' % self.cmd[0]])
 
     def OnOverwrite(self, event):
         self.overwrite = event.IsChecked()

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/sqlbuilder.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/sqlbuilder.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/sqlbuilder.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -41,9 +41,7 @@
         wx.Frame.__init__(self, parent, id, title)
 
         self.SetTitle(_("GRASS SQL Builder: %s") % (qtype.upper()))
-        self.SetIcon(wx.Icon(os.path.join(imagepath, 
-                                          'grass_sql.png'),
-                             wx.BITMAP_TYPE_ANY))
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, 'grass_sql.ico'), wx.BITMAP_TYPE_ICO))
 
         #
         # variables

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/toolbars.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/toolbars.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -37,11 +37,17 @@
         pass
 
     def InitToolbar(self, parent, toolbar, toolData):
-        """Initialize toolbar, i.e. add tools to the toolbar"""
+        """Initialize toolbar, i.e. add tools to the toolbar
 
+        @return list of ids (of added tools)
+        """
+
+        ids = []
         for tool in toolData:
-            self.CreateTool(parent, toolbar, *tool)
+            ids.append(self.CreateTool(parent, toolbar, *tool))
 
+        return ids
+
     def ToolbarData(self):
         """Toolbar data"""
 
@@ -49,18 +55,24 @@
 
     def CreateTool(self, parent, toolbar, tool, label, bitmap, kind,
                    shortHelp, longHelp, handler):
-        """Add tool to the toolbar"""
+        """Add tool to the toolbar
 
+        @return id of tool
+        """
+
         bmpDisabled=wx.NullBitmap
 
+        id = wx.NewId()
         if label:
-            tool = toolbar.AddLabelTool(wx.ID_ANY, label, bitmap,
+            tool = toolbar.AddLabelTool(id, label, bitmap,
                                         bmpDisabled, kind,
                                         shortHelp, longHelp)
             parent.Bind(wx.EVT_TOOL, handler, tool)
         else: # add separator
             toolbar.AddSeparator()
 
+        return id
+    
 class MapToolbar(AbstractToolbar):
     """
     Main Map Display toolbar
@@ -70,14 +82,11 @@
         self.mapcontent = map
         self.mapdisplay = mapdisplay
 
-        self.toolbar = wx.ToolBar(parent=self.mapdisplay, id=wx.ID_ANY)
+	self.toolbar = wx.ToolBar(parent=self.mapdisplay, id=wx.ID_ANY)
+        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
 
-        # self.SetToolBar(self.toolbar)
-        tsize = (24, 24)
-        self.toolbar.SetToolBitmapSize(tsize)
-
-        self.InitToolbar(self.mapdisplay, self.toolbar, self.ToolbarData())
-
+        self.pointerId = self.InitToolbar(self.mapdisplay, self.toolbar, self.ToolbarData())[4]
+        
         # optional tools
         self.combo = wx.ComboBox(parent=self.toolbar, id=wx.ID_ANY, value='Tools',
                                  choices=['Digitize'], style=wx.CB_READONLY, size=(90, -1))
@@ -87,7 +96,7 @@
 
         # realize the toolbar
         self.toolbar.Realize()
-
+            
     def ToolbarData(self):
         """Toolbar data"""
 
@@ -99,10 +108,10 @@
         return (
             (self.displaymap, "displaymap", Icons["displaymap"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["displaymap"].GetLabel(), Icons["displaymap"].GetDesc(),
-             self.mapdisplay.ReDraw),
+             self.mapdisplay.OnDraw),
             (self.rendermap, "rendermap", Icons["rendermap"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["rendermap"].GetLabel(), Icons["rendermap"].GetDesc(),
-             self.mapdisplay.ReRender),
+             self.mapdisplay.OnRender),
             (self.erase, "erase", Icons["erase"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["erase"].GetLabel(), Icons["erase"].GetDesc(),
              self.mapdisplay.OnErase),
@@ -167,8 +176,7 @@
         self.toolbar = wx.ToolBar(parent=self.mapdisplay, id=wx.ID_ANY)
 
         # self.SetToolBar(self.toolbar)
-        tsize = (24, 24)
-        self.toolbar.SetToolBitmapSize(tsize)
+        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
 
         self.InitToolbar(self.mapdisplay, self.toolbar, self.ToolbarData())
 
@@ -186,10 +194,10 @@
         return (
             (self.displaymap, "displaymap", Icons["displaymap"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["displaymap"].GetLabel(), Icons["displaymap"].GetDesc(),
-             self.mapdisplay.ReDraw),
+             self.mapdisplay.OnDraw),
             (self.rendermap, "rendermap", Icons["rendermap"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["rendermap"].GetLabel(), Icons["rendermap"].GetDesc(),
-             self.mapdisplay.ReRender),
+             self.mapdisplay.OnRender),
             (self.erase, "erase", Icons["erase"].GetBitmap(),
              wx.ITEM_NORMAL, Icons["erase"].GetLabel(), Icons["erase"].GetDesc(),
              self.mapdisplay.OnErase),
@@ -254,8 +262,10 @@
         self.numOfRows = 1 # number of rows for toolbar
         for row in range(0, self.numOfRows):
             self.toolbar.append(wx.ToolBar(parent=self.parent, id=wx.ID_ANY))
+	    self.toolbar[row].SetToolBitmapSize(globalvar.toolbarSize)
             self.toolbar[row].SetToolBitmapSize(wx.Size(24,24))
-
+            self.toolbar[row].Bind(wx.EVT_TOOL, self.OnTool)
+            
             # create toolbar
             if self.numOfRows ==  1:
                 rowdata=None
@@ -270,6 +280,9 @@
         for row in range(0, self.numOfRows):
             self.toolbar[row].Realize()
 
+        # toogle to pointer by default
+        self.OnTool(None)
+        
     def ToolbarData(self, row=None):
         """
         Toolbar data
@@ -346,6 +359,14 @@
 
         return data
 
+    def OnTool(self, event):
+        """Tool selected -> toggle tool to pointer"""
+        id = self.parent.maptoolbar.pointerId
+        self.parent.maptoolbar.toolbar.ToggleTool(id, True)
+        self.parent.maptoolbar.mapdisplay.OnPointer(event)
+        if event:
+            event.Skip()
+        
     def OnAddPoint(self, event):
         """Add point to the vector map Laier"""
         Debug.msg (2, "DigitToolbar.OnAddPoint()")

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/utils.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/utils.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/utils.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -17,28 +17,43 @@
 import os
 import sys
 
+import globalvar
+try:
+    import subprocess
+except:
+    compatPath = os.path.join(globalvar.ETCWXDIR, "compat")
+    sys.path.append(compatPath)
+    import subprocess
+
 def GetTempfile(pref=None):
     """
     Creates GRASS temporary file using defined prefix.
 
+    @todo Fix path on MS Windows/MSYS
+
     @param pref prefer the given path
 
     @return Path to file name (string) or None
     """
     import gcmd
+
     tempfileCmd = gcmd.Command(["g.tempfile",
-                                "pid=%d" %
-                                os.getpid()])
+                                "pid=%d" % os.getpid()])
 
     tempfile = tempfileCmd.ReadStdOutput()[0].strip()
 
+    # FIXME
+    # ugly hack for MSYS (MS Windows)
+    if subprocess.mswindows:
+	tempfile = tempfile.replace("/", "\\")
     try:
         path, file = os.path.split(tempfile)
         if pref:
-            file = "%s%s" % (pref, file)
-        return os.path.join(path, file)
+            return os.path.join(pref, file)
+	else:
+	    return tempfile
     except:
-        return Node
+        return None
 
 def GetLayerNameFromCmd(dcmd):
     """Get layer name from GRASS command
@@ -139,20 +154,40 @@
     import gcmd
     all_mapsets = []
     accessible_mapsets = []
+
+    ### FIXME
+    # problem using Command here (see preferences.py)
+    # cmd = gcmd.Command(['g.mapsets', '-l'])
+    cmd = subprocess.Popen(['g.mapsets' + globalvar.EXT_BIN, '-l'],
+                           stdout=subprocess.PIPE)
     
-    cmd = gcmd.Command(['g.mapsets', '-l'])
-    
     try:
-        for mset in cmd.ReadStdOutput()[0].split(' '):
-            all_mapsets.append(mset.strip('%s' % os.linesep))
+        # for mset in cmd.ReadStdOutput()[0].split(' '):
+        for line in cmd.stdout.readlines():
+            for mset in line.strip('%s' % os.linesep).split(' '):
+                if len(mset) == 0:
+                    continue
+                all_mapsets.append(mset)
     except:
         raise gcmd.CmdError('Unable to get list of available mapsets.')
-            
-    cmd = gcmd.Command(['g.mapsets', '-p'])
+    
+    # cmd = gcmd.Command(['g.mapsets', '-p'])
+    cmd = subprocess.Popen(['g.mapsets' + globalvar.EXT_BIN, '-p'],
+                           stdout=subprocess.PIPE)
     try:
-        for mset in cmd.ReadStdOutput()[0].split(' '):
-            accessible_mapsets.append(mset.strip('\n'))
+        # for mset in cmd.ReadStdOutput()[0].split(' '):
+        for line in cmd.stdout.readlines():
+            for mset in line.strip('%s' % os.linesep).split(' '):
+                if len(mset) == 0:
+                    continue
+                accessible_mapsets.append(mset)
     except:
         raise gcmd.CmdError('Unable to get list of accessible mapsets.')
 
+    ListSortLower(all_mapsets)
+    
     return (all_mapsets, accessible_mapsets)
+
+def ListSortLower(list):
+    """Sort list items (not case-sensitive)"""
+    list.sort(cmp=lambda x, y: cmp(x.lower(), y.lower()))

Added: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/workspace.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/workspace.py	                        (rev 0)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/workspace.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -0,0 +1,146 @@
+"""
+ at package workspace
+
+ at brief Open/save workspace definition file
+
+Classes:
+ - ProcessWorkspaceFile
+
+(C) 2007-2008 by the GRASS Development Team
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
+
+ at author Martin Landa <landa.martin gmail.com>
+
+ at date 2007-2008
+"""
+
+### for gxw (workspace file) parsering
+# xmlproc not available on Mac OS
+# from xml.parsers.xmlproc import xmlproc
+# from xml.parsers.xmlproc import xmlval
+# from xml.parsers.xmlproc import xmldtd
+import xml.sax
+import xml.sax.handler
+HandlerBase=xml.sax.handler.ContentHandler
+from xml.sax import make_parser
+
+class ProcessWorkspaceFile(HandlerBase):
+    """
+    A SAX handler for the GXW XML file, as
+    defined in grass-gxw.dtd.
+    """
+    def __init__(self):
+        self.inGxw       = False
+        self.inLayer     = False
+        self.inTask      = False
+        self.inParameter = False
+        self.inFlag      = False
+        self.inValue     = False
+        self.inGroup     = False
+        self.inDisplay   = False
+
+        # list of layers
+        self.layers = []
+        self.cmd    = []
+        self.displayIndex = -1 # first display has index '0'
+
+    def startElement(self, name, attrs):
+        if name == 'gxw':
+            self.inGxw = True
+
+        elif name == 'display':
+            self.inDisplay = True
+            self.displayIndex += 1
+
+        elif name == 'group':
+            self.groupName    = attrs.get('name', None)
+            self.groupChecked = attrs.get('checked', None)
+            self.layers.append({
+                    "type"    : 'group',
+                    "name"    : self.groupName,
+                    "checked" : int(self.groupChecked),
+                    "opacity" : None,
+                    "cmd"     : None,
+                    "group"   : self.inGroup,
+                    "display" : self.displayIndex})
+            self.inGroup = True
+
+        elif name == 'layer':
+            self.inLayer = True
+            self.layerType    = attrs.get('type', None)
+            self.layerName    = attrs.get('name', None)
+            self.layerChecked = attrs.get('checked', None)
+            self.layerOpacity = attrs.get('opacity', None)
+            self.cmd = []
+
+        elif name == 'task':
+            self.inTask = True;
+            name = attrs.get('name', None)
+            self.cmd.append(name)
+
+        elif name == 'parameter':
+            self.inParameter = True;
+            self.parameterName = attrs.get('name', None)
+
+        elif name == 'value':
+            self.inValue = True
+            self.value = ''
+
+        elif name == 'flag':
+            self.inFlag = True;
+            name = attrs.get('name', None)
+            self.cmd.append('-' + name)
+
+    def endElement(self, name):
+        if name == 'gxw':
+            self.inGxw = False
+
+        elif name == 'display':
+            self.inDisplay = False
+
+        elif name == 'group':
+            self.inGroup = False
+            self.groupName = self.groupChecked = None
+
+        elif name == 'layer':
+            self.inLayer = False
+            self.layers.append({
+                    "type"    : self.layerType,
+                    "name"    : self.layerName,
+                    "checked" : int(self.layerChecked),
+                    "opacity" : None,
+                    "cmd"     : None,
+                    "group"   : self.inGroup,
+                    "display" : self.displayIndex})
+
+            if self.layerOpacity:
+                self.layers[-1]["opacity"] = float(self.layerOpacity)
+            if self.cmd:
+                self.layers[-1]["cmd"] = self.cmd
+
+            self.layerType = self.layerName = self.Checked = \
+                self.Opacity = self.cmd = None
+
+        elif name == 'task':
+            self.inTask = False
+
+        elif name == 'parameter':
+            self.inParameter = False
+            self.cmd.append('%s=%s' % (self.parameterName, self.value))
+            self.parameterName = self.value = None
+
+        elif name == 'value':
+            self.inValue = False
+
+        elif name == 'flag':
+            self.inFlag = False
+
+    def characters(self, ch):
+        self.my_characters(ch)
+
+    def my_characters(self, ch):
+        if self.inValue:
+            self.value += ch
+

Modified: grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/wxgui_utils.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/wxgui_utils.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/gui_modules/wxgui_utils.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -37,6 +37,7 @@
 import wx.stc
 import wx.lib.newevent
 
+import globalvar
 import menuform
 import mapdisp
 import render
@@ -46,6 +47,7 @@
 import utils
 from debug import Debug as Debug
 from icon import Icons as Icons
+from preferences import globalSettings as UserSettings
 try:
     import subprocess
 except:
@@ -65,10 +67,12 @@
                  ctstyle=CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT |
                  CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT|
                  CT.TR_EDIT_LABELS|CT.TR_MULTIPLE,
-                 idx=None, gismgr=None, notebook=None, auimgr=None):
-        CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style,ctstyle)
+                 idx=None, gismgr=None, notebook=None, auimgr=None, showMapDisplay=True):
+        CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style, ctstyle)
 
-        self.SetAutoLayout(True)
+        ### SetAutoLayout() causes that no vertical scrollbar is displayed
+        ### when some layers are not visible in layer tree
+        # self.SetAutoLayout(True)
         self.SetGradientStyle(1)
         self.EnableSelectionGradient(True)
         self.SetFirstGradientColour(wx.Colour(150, 150, 150))
@@ -100,10 +104,11 @@
                                    str(self.disp_idx) + 
                                    " - Location: " + grassenv.GetGRASSVariable("LOCATION_NAME")))
 
-        #show new display
-        self.mapdisplay.Show()
-        self.mapdisplay.Refresh()
-        self.mapdisplay.Update()
+        # show new display
+        if showMapDisplay is True:
+            self.mapdisplay.Show()
+            self.mapdisplay.Refresh()
+            self.mapdisplay.Update()
 
         self.root = self.AddRoot("Map Layers")
         self.SetPyData(self.root, (None,None))
@@ -303,8 +308,8 @@
         """
         mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
         if not mapLayer.name:
-            dlg = wx.MessageDialog(self, _("Unable to display histogram for "
-                                           "raster map layer"),
+            dlg = wx.MessageDialog(self, _("Unable to display histogram of "
+                                           "raster map."),
                                    _("Error"), wx.OK | wx.ICON_ERROR)
             dlg.ShowModal()
             dlg.Destroy()
@@ -532,6 +537,10 @@
             else:
                 ctrl.SetValue(lname)
 
+        # updated progress bar range (mapwindow statusbar)
+        if checked is True:
+            self.mapdisplay.onRenderGauge.SetRange(len(self.Map.GetListOfLayers(l_active=True)))
+
         return layer
 
     def PropertiesDialog (self, layer, show=True):
@@ -550,7 +559,10 @@
                                                        parentframe=self, show=show)
             self.GetPyData(layer)[0]['cmd'] = cmdValidated
         elif ltype == 'raster':
-            menuform.GUI().ParseCommand(['d.rast'], completed=(self.GetOptData,layer,params),
+            cmd = ['d.rast']
+            if UserSettings.Get(group='display', key='rasterOverlay', subkey='enabled'):
+                cmd.append('-o')
+            menuform.GUI().ParseCommand(cmd, completed=(self.GetOptData,layer,params),
                                         parentframe=self)
         elif ltype == 'rgb':
             menuform.GUI().ParseCommand(['d.rgb'], completed=(self.GetOptData,layer,params),
@@ -571,7 +583,9 @@
             menuform.GUI().ParseCommand(['d.vect'], completed=(self.GetOptData,layer,params),
                                         parentframe=self)
         elif ltype == 'thememap':
-            menuform.GUI().ParseCommand(['d.vect.thematic'],
+            # -s flag requested, otherwise only first thematic category is displayed
+            # should be fixed by C-based d.thematic.* modules
+            menuform.GUI().ParseCommand(['d.vect.thematic', '-s'], 
                                         completed=(self.GetOptData,layer,params),
                                         parentframe=self)
         elif ltype == 'themechart':
@@ -638,11 +652,14 @@
 
         # redraw map if auto-rendering is enabled
         if self.mapdisplay.autoRender.GetValue(): 
-            self.mapdisplay.ReRender(None)
+            self.mapdisplay.OnRender(None)
 
         if self.mapdisplay.digittoolbar:
             self.mapdisplay.digittoolbar.UpdateListOfLayers (updateTool=True)
 
+        # update progress bar range (mapwindow statusbar)
+        self.mapdisplay.onRenderGauge.SetRange(len(self.Map.GetListOfLayers(l_active=True)))
+
         event.Skip()
 
     def OnLayerChecked(self, event):
@@ -661,9 +678,12 @@
             else:
                 self.Map.ChangeLayerActive(self.GetPyData(item)[0]['maplayer'], checked)
 
+        # update progress bar range (mapwindow statusbar)
+        self.mapdisplay.onRenderGauge.SetRange(len(self.Map.GetListOfLayers(l_active=True)))
+
         # redraw map if auto-rendering is enabled
         if self.mapdisplay.autoRender.GetValue(): 
-            self.mapdisplay.ReRender(None)
+            self.mapdisplay.OnRender(None)
 
     def OnCmdChanged(self, event):
         """Change command string"""
@@ -722,7 +742,7 @@
 
         # redraw map if auto-rendering is enabled
         if self.mapdisplay.autoRender.GetValue(): 
-            self.mapdisplay.ReRender(None)
+            self.mapdisplay.OnRender(None)
 
     def OnChangeSel(self, event):
         oldlayer = event.GetOldItem()
@@ -968,7 +988,7 @@
 
         # redraw map if auto-rendering is enabled
         if self.mapdisplay.autoRender.GetValue(): 
-            self.mapdisplay.ReRender(None)
+            self.mapdisplay.OnRender(None)
 
     def setNotebookPage(self,pg):
         self.parent.notebook.SetSelection(pg)
@@ -1002,16 +1022,15 @@
     Create and manage output console for commands entered on the
     GIS Manager command line.
     """
-    def __init__(self, parent, id=wx.ID_ANY,
+    def __init__(self, parent, id=wx.ID_ANY, margin=False,
                  pos=wx.DefaultPosition, size=wx.DefaultSize,
-                 style=wx.TAB_TRAVERSAL|wx.FULL_REPAINT_ON_RESIZE):
+                 style=wx.TAB_TRAVERSAL | wx.FULL_REPAINT_ON_RESIZE):
         wx.Panel.__init__(self, parent, id, pos, size, style)
 
         # initialize variables
         self.Map             = None
-        self.parent          = parent              # GMFrame
-        self.gcmdlst         = self.GetGRASSCmds() # list of commands in bin and scripts
-        self.cmdThreads      = []                  # list of command threads (alive or dead)
+        self.parent          = parent # GMFrame
+        self.cmdThreads      = []     # list of running commands (alive or dead)
 
         # progress bar
         self.console_progressbar = wx.Gauge(parent=self, id=wx.ID_ANY,
@@ -1019,11 +1038,7 @@
                                             style=wx.GA_HORIZONTAL)
 
         # text control for command output
-        ### self.cmd_output = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="",
-        ### style=wx.TE_MULTILINE| wx.TE_READONLY)
-        ### self.cmd_output.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN,
-        ### wx.NORMAL, wx.NORMAL, 0, ''))
-        self.cmd_output = GMStc(parent=self, id=wx.ID_ANY)
+        self.cmd_output = GMStc(parent=self, id=wx.ID_ANY, margin=margin)
         # redirect
         self.cmd_stdout = GMStdout(self.cmd_output)
         self.cmd_stderr = GMStderr(self.cmd_output,
@@ -1035,7 +1050,7 @@
         self.Bind(wx.EVT_BUTTON, self.ClearHistory, self.console_clear)
         self.Bind(wx.EVT_BUTTON, self.SaveHistory,  self.console_save)
 
-         # output control layout
+        # output control layout
         boxsizer1 = wx.BoxSizer(wx.VERTICAL)
         gridsizer1 = wx.GridSizer(rows=1, cols=2, vgap=0, hgap=0)
         boxsizer1.Add(item=self.cmd_output, proportion=1,
@@ -1055,25 +1070,32 @@
         boxsizer1.Fit(self)
         boxsizer1.SetSizeHints(self)
 
+        # set up event handler for any command thread results
+        gcmd.EVT_RESULT(self, self.OnResult)
+
+        # layout
         self.SetAutoLayout(True)
         self.SetSizer(boxsizer1)
 
-    def GetGRASSCmds(self):
-        """
-        Create list of all available GRASS commands to use when
-        parsing string from the command line
-        """
-        gcmdlst = []
-        gisbase = os.environ['GISBASE']
-        gcmdlst = os.listdir(os.path.join(gisbase,'bin'))
-        gcmdlst = gcmdlst + os.listdir(os.path.join(gisbase,'scripts'))
-        #self.gcmdlst = self.gcmdlst + os.listdir(os.path.join(gisbase,'etc','gm','script'))
-
-        return gcmdlst
-
+    def WriteCmdLog(self, line, pid=None):
+        """Write out line in selected style"""
+        self.cmd_output.GotoPos(self.cmd_output.GetEndStyled())
+        p1 = self.cmd_output.GetCurrentPos()
+        if pid:
+            line = '(' + str(pid) + ') ' + line
+        if len(line) < 80:
+            diff = 80 - len(line)
+            line += diff * ' '
+            line += '%s' % os.linesep
+            self.cmd_output.AddText(line)
+            self.cmd_output.EnsureCaretVisible()
+            p2 = self.cmd_output.GetCurrentPos()
+            self.cmd_output.StartStyling(p1, 0xff)
+            self.cmd_output.SetStyling(p2 - p1, self.cmd_output.StyleCommand)
+        
     def RunCmd(self, command):
         """
-        Run in GUI or shell GRASS (or other) commands typed into
+        Run in GUI GRASS (or other) commands typed into
         console command text widget, and send stdout output to output
         text widget.
 
@@ -1092,13 +1114,22 @@
         except:
             curr_disp = None
 
+        if len(self.GetListOfCmdThreads()) > 0:
+            # only one running command enabled (per GMConsole instance)
+            busy = wx.BusyInfo(message=_("Unable to run the command, another command is running..."),
+                               parent=self)
+            wx.Yield()
+            time.sleep(3)
+            busy.Destroy()
+            return 
+
+        # command given as a string ?
         try:
-            # if command is not already a list, make it one
             cmdlist = command.strip().split(' ')
         except:
             cmdlist = command
 
-        if cmdlist[0] in self.gcmdlst:
+        if cmdlist[0] in globalvar.grassCmd['all']:
             # send GRASS command without arguments to GUI command interface
             # except display commands (they are handled differently)
             if cmdlist[0][0:2] == "d.": # display GRASS commands
@@ -1118,64 +1149,43 @@
                                  'd.rhumbline'    : 'rhumb',
                                  'd.labels'       : 'labels'}[cmdlist[0]]
                 except KeyError:
-                    wx.MessageBox(message=_("Command '%s' not yet implemented") % cmdlist[0])
+                    wx.MessageBox(message=_("Command '%s' not yet implemented.") % cmdlist[0])
                     return False
 
-                # add layer
+                # add layer into layer tree
                 self.parent.curr_page.maptree.AddLayer(ltype=layertype,
                                                        lcmd=cmdlist)
 
-            else: # other GRASS commands
+            else: # other GRASS commands (r|v|g|...)
                 if self.parent.notebook.GetSelection() != 1:
                     # select 'Command output' tab
                     self.parent.notebook.SetSelection(1)
                 
-                if len(self.GetListOfCmdThreads(onlyAlive=True)) > 0:
-                    busy = wx.BusyInfo(message=_("Please wait, there is another command "
-                                                 "currently running"),
-                                       parent=self.parent)
-                    # wx.Yield()
-                    time.sleep(3)
-                    busy.Destroy()
+                # activate computational region (set with g.region)
+                # for all non-display commands.
+                tmpreg = os.getenv("GRASS_REGION")
+                os.unsetenv("GRASS_REGION")
+                if len(cmdlist) == 1:
+                    # process GRASS command without argument
+                    menuform.GUI().ParseCommand(cmdlist, parentframe=self)
                 else:
-                    # activate computational region (set with g.region)
-                    # for all non-display commands.
-                    tmpreg = os.getenv("GRASS_REGION")
-                    os.unsetenv("GRASS_REGION")
-
-                    if len(cmdlist) == 1:
-                        #process GRASS command without argument
-                        menuform.GUI().ParseCommand(cmdlist, parentframe=self)
-                    else:
-                        # process GRASS command with argument
-                        self.cmd_output.GotoPos(self.cmd_output.GetEndStyled())
-                        p1 = self.cmd_output.GetCurrentPos()
-                        line = '$ %s' % ' '.join(cmdlist)
-                        if len(line) < 80:
-                            diff = 80 - len(line)
-                            line += diff * ' '
-                        line += '%s' % os.linesep
-                        self.cmd_output.AddText(line)
-                        self.cmd_output.EnsureCaretVisible()
-                        p2 = self.cmd_output.GetCurrentPos()
-                        self.cmd_output.StartStyling(p1, 0xff)
-                        self.cmd_output.SetStyling(p2 - p1, self.cmd_output.StyleCommand)
-
-                        # TODO: allow running multiple instances
-                        grassCmd = gcmd.Command(cmdlist, wait=False,
-                                                stdout=self.cmd_stdout,
-                                                stderr=self.cmd_stderr)
-    
-                        self.cmdThreads.append(grassCmd.cmdThread)
-
-                    # deactivate computational region and return to display settings
-                    if tmpreg:
-                        os.environ["GRASS_REGION"] = tmpreg
-
+                    # process GRASS command with argument
+                    self.cmdPID = len(self.cmdThreads)+1
+                    self.WriteCmdLog('%s' % ' '.join(cmdlist), pid=self.cmdPID)
+                    
+                    grassCmd = gcmd.Command(cmdlist, wait=False,
+                                            stdout=self.cmd_stdout,
+                                            stderr=self.cmd_stderr)
+                    
+                    self.cmdThreads.append(grassCmd.cmdThread)
+                    
+                    return grassCmd
+                # deactivate computational region and return to display settings
+                if tmpreg:
+                    os.environ["GRASS_REGION"] = tmpreg
         else:
             # Send any other command to the shell. Send output to
             # console output window
-
             if self.parent.notebook.GetSelection() != 1:
                 # select 'Command output' tab
                 self.parent.notebook.SetSelection(1)
@@ -1185,13 +1195,12 @@
             # if command is not a GRASS command, treat it like a shell command
             generalCmd = subprocess.Popen(cmdlist,
                                           stdout=subprocess.PIPE,
-                                          stderr=subprocess.PIPE,
-                                          close_fds=True)
+                                          stderr=subprocess.PIPE)
             
             for outline in generalCmd.stdout:
                 print outline
                    
-        return True
+            return None
 
     def ClearHistory(self, event):
         """Clear history of commands"""
@@ -1210,7 +1219,7 @@
 
         wildcard = "Text file (*.txt)|*.txt"
         dlg = wx.FileDialog(
-            self, message=_("Save file as ..."), defaultDir=os.getcwd(),
+            self, message=_("Save file as..."), defaultDir=os.getcwd(),
             defaultFile="grass_cmd_history.txt", wildcard=wildcard,
             style=wx.SAVE|wx.FD_OVERWRITE_PROMPT)
 
@@ -1225,7 +1234,7 @@
 
         dlg.Destroy()
 
-    def GetListOfCmdThreads(self, onlyAlive=False):
+    def GetListOfCmdThreads(self, onlyAlive=True):
         """Return list of command threads)"""
         list = []
         for t in self.cmdThreads:
@@ -1237,6 +1246,26 @@
 
         return list
 
+    def OnResult(self, event):
+        """Show result status"""
+        if event.cmdThread is None:
+            # Thread aborted (using our convention of None return)
+            self.WriteCmdLog(_('Command aborted'),
+                             pid=self.cmdPID)
+        else:
+            # Process results here
+            self.WriteCmdLog(_('Command finished (%d sec)') % (time.time() - event.cmdThread.startTime),
+                             pid=self.cmdPID)
+
+        self.console_progressbar.SetValue(0) # reset progress bar on '0%'
+        if hasattr(self.parent.parent, "btn_run"): # menuform.mainFrame
+            dialog = self.parent.parent
+            dialog.btn_run.Enable(True)
+            if dialog.get_dcmd is None and \
+                   dialog.closebox.IsChecked():
+                time.sleep(1)
+                dialog.Close()
+
 class GMStdout:
     """GMConsole standard output
 
@@ -1291,7 +1320,7 @@
                 if value < 100:
                     self.gmgauge.SetValue(value)
                 else:
-                    self.gmgauge.SetValue(0) # reset progress bar on '100%'
+                    self.gmgauge.SetValue(0) # reset progress bar on '0%'
             elif 'GRASS_INFO_MESSAGE' in line:
                 type = 'message'
                 message += line.split(':')[1].strip()
@@ -1340,7 +1369,7 @@
     Copyright: (c) 2005-2007 Jean-Michel Fauth
     Licence:   GPL
     """    
-    def __init__(self, parent, id):
+    def __init__(self, parent, id, margin=False):
         wx.stc.StyledTextCtrl.__init__(self, parent, id)
         self.parent = parent
         
@@ -1375,23 +1404,25 @@
         self.StyleSetSpec(self.StyleWarning, self.StyleWarningSpec)
         self.StyleSetSpec(self.StyleMessage, self.StyleMessageSpec)
         self.StyleSetSpec(self.StyleUnknown, self.StyleUnknownSpec)
-        
+
         #
-        # margin widths
+        # line margins
         #
-        self.SetMarginWidth(0, 0)
+        # TODO print number only from cmdlog
         self.SetMarginWidth(1, 0)
         self.SetMarginWidth(2, 0)
+        if margin:
+            self.SetMarginType(0, wx.stc.STC_MARGIN_NUMBER)
+            self.SetMarginWidth(0, 30)
+        else:
+            self.SetMarginWidth(0, 0)
 
         #
         # miscellaneous
         #
-        self.SetMarginLeft(2)
         self.SetViewWhiteSpace(False)
         self.SetTabWidth(4)
         self.SetUseTabs(False)
-        # self.SetEOLMode(wx.stc.STC_EOL_CRLF)
-        # self.SetViewEOL(True)
         self.UsePopUp(True)
         self.SetSelBackground(True, "#FFFF00")
         self.SetUseHorizontalScrollBar(True)
@@ -1469,7 +1500,7 @@
         bodySizer.AddGrowableRow(2)
         
         # layer type
-        bodySizer.Add(item=wx.StaticText(parent=self, label=_("Layer type:")),
+        bodySizer.Add(item=wx.StaticText(parent=self, label=_("Map layer type:")),
                       flag=wx.ALIGN_CENTER_VERTICAL,
                       pos=(0,0))
 
@@ -1483,9 +1514,10 @@
         bodySizer.Add(item=wx.StaticText(parent=self, label=_("Mapset:")),
                       flag=wx.ALIGN_CENTER_VERTICAL,
                       pos=(1,0))
+
         self.mapset = wx.ComboBox(parent=self, id=wx.ID_ANY,
                                   style=wx.CB_SIMPLE | wx.CB_READONLY,
-                                  choices=utils.ListOfMapsets()[0],
+                                  choices=UserSettings.Get(group='general', key='mapsetPath', subkey='value', internal=True),
                                   size=(200,-1))
         self.mapset.SetStringSelection(grassenv.GetGRASSVariable("MAPSET"))
         bodySizer.Add(item=self.mapset,

Modified: grass/branches/releasebranch_6_3/gui/wxpython/icons/icon.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/icons/icon.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/icons/icon.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -32,7 +32,7 @@
 # iconpath = grassenv.GetGRASSVariable('GRASS_ICONPATH')
 # if not iconpath:
 #    iconpath = os.getenv("GRASS_ICONPATH")
-iconTheme = UserSettings.Get('iconTheme')
+iconTheme = UserSettings.Get(group='advanced', key='iconTheme', subkey='type')
 if iconTheme and iconTheme == 'silk':
     iconpath = os.path.join(globalvar.ETCWXDIR, "icons", "silk")
 else:

Modified: grass/branches/releasebranch_6_3/gui/wxpython/images/__init__.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/images/__init__.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/images/__init__.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -1,8 +1,8 @@
-all = ["grass.form.gif",
-       "grass.map.gif",
-       "grass.smlogo.gif",
-       "grasslogo_big.gif",
-       "db_open_table.png",
-       "grass_db.png",
-       "grass_sql.png",
-       ]
+all = [
+    "grass_form.png",
+    "intro.png",
+    "intro.xcf",
+    "loc_wizard.png",
+    "loc_wizard_qgis.png",
+    "qgis_world.png",
+    ]

Deleted: grass/branches/releasebranch_6_3/gui/wxpython/images/db_open_table.png
===================================================================
(Binary files differ)

Deleted: grass/branches/releasebranch_6_3/gui/wxpython/images/grass-tiny-logo.png
===================================================================
(Binary files differ)

Deleted: grass/branches/releasebranch_6_3/gui/wxpython/images/grass.form.gif
===================================================================
(Binary files differ)

Deleted: grass/branches/releasebranch_6_3/gui/wxpython/images/grass.map.gif
===================================================================
(Binary files differ)

Deleted: grass/branches/releasebranch_6_3/gui/wxpython/images/grass.smlogo.gif
===================================================================
(Binary files differ)

Deleted: grass/branches/releasebranch_6_3/gui/wxpython/images/grass_db.png
===================================================================
(Binary files differ)

Added: grass/branches/releasebranch_6_3/gui/wxpython/images/grass_form.png
===================================================================
(Binary files differ)


Property changes on: grass/branches/releasebranch_6_3/gui/wxpython/images/grass_form.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: grass/branches/releasebranch_6_3/gui/wxpython/images/grass_sql.png
===================================================================
(Binary files differ)

Deleted: grass/branches/releasebranch_6_3/gui/wxpython/images/grasslogo_big.gif
===================================================================
(Binary files differ)

Modified: grass/branches/releasebranch_6_3/gui/wxpython/vdigit/Makefile
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/vdigit/Makefile	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/vdigit/Makefile	2008-03-11 18:40:45 UTC (rev 30529)
@@ -3,12 +3,10 @@
 include $(MODULE_TOPDIR)/include/Make/Platform.make
 include $(MODULE_TOPDIR)/include/Make/Lib.make
 
-SWIG = swig
+CXXFLAGS += $(SHLIB_CFLAGS) $(GDALCFLAGS) $(PYTHONCFLAGS) $(WXWIDGETSCXXFLAGS)
 
-CXXFLAGS = -c -fpic -I$(ARCH_DISTDIR)/include $(GDALCFLAGS) $(PYTHONCFLAGS) $(WXWIDGETSCXXFLAGS)
+LDFLAGS += $(SHLIB_LDFLAGS) -L$(ARCH_LIBDIR) $(VECTLIB) $(GISLIB) $(GDALLIBS) $(VEDITLIB) $(WXWIDGETSLIB) $(PYTHONLDFLAGS) -lgdi
 
-LDFLAGS = -shared -fpic -L$(ARCH_LIBDIR) $(VECTLIB) $(GISLIB) $(GDALLIBS) $(VEDITLIB) $(WXWIDGETSLIB) -lgdi 
-
 LOCAL_HEADERS = digit.h driver.h
 SOURCES = driver.cpp digit.cpp cats.cpp line.cpp vertex.cpp select.cpp grass6_wxvdigit_wrap.cpp
 
@@ -17,8 +15,10 @@
 
 ETCDIR = $(ETC)/wxpython
 
-default: grass6_wxvdigit.so install_vdigit
+SHLIB = _grass6_wxvdigit$(SHLIB_SUFFIX)
 
+default: $(SHLIB) install_vdigit
+
 clean:
 	-rm -rf $(OBJARCH) _grass6_wxvdigit.so grass6_wxvdigit.i	 
 
@@ -33,10 +33,10 @@
 	$(SWIG) -c++ -python -shadow -o grass6_wxvdigit_wrap.cpp $<
 
 $(OBJARCH)/%.o: %.cpp $(LOCAL_HEADERS)
-	$(CXX) $(CXXFLAGS) $(INCLUDE_DIRS) $< -o $@
+	$(CXX) $(CXXFLAGS) -c $< -o $@
 
-grass6_wxvdigit.so: $(OBJ)
-	$(CXX) $(LDFLAGS) $(OBJ) -o _grass6_wxvdigit.so
+$(SHLIB): $(OBJ)
+	$(SHLIB_LD) $(LDFLAGS) $(OBJ) -o $(SHLIB) 
 
 install_vdigit:
 	$(INSTALL_DATA) _grass6_wxvdigit.so $(ETCDIR)/vdigit/

Modified: grass/branches/releasebranch_6_3/gui/wxpython/vdigit/cats.cpp
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/vdigit/cats.cpp	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/vdigit/cats.cpp	2008-03-11 18:40:45 UTC (rev 30529)
@@ -54,6 +54,9 @@
     for (int i = 0; i < nfields; i++ ) {
 	field = Vect_cidx_get_field_number(display->mapInfo, i);
 	ncats = Vect_cidx_get_num_cats_by_index(display->mapInfo, i);
+	if (field <= 0) {
+	    continue;
+	}
 	for (int j = 0; j < ncats; j++) {
 	    Vect_cidx_get_cat_by_index (display->mapInfo, i, j, &cat, &type, &id);
 	    if (cat > cats[field])

Modified: grass/branches/releasebranch_6_3/gui/wxpython/vdigit/digit.h
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/vdigit/digit.h	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/vdigit/digit.h	2008-03-11 18:40:45 UTC (rev 30529)
@@ -43,7 +43,8 @@
 
     int MoveVertex(double, double, double,
 		   double, double, double,
-		   const char*, int, double);
+		   const char*, int,
+		   double, double);
     int ModifyLineVertex(int, double, double, double,
 			 double);
 

Modified: grass/branches/releasebranch_6_3/gui/wxpython/vdigit/driver.cpp
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/vdigit/driver.cpp	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/vdigit/driver.cpp	2008-03-11 18:40:45 UTC (rev 30529)
@@ -1109,6 +1109,33 @@
 }
 
 /**
+   \brief Get bounding box of (opened) vector map layer
+
+   \return (w,s,b,e,n,t)
+*/
+std::vector<double> DisplayDriver::GetMapBoundingBox()
+{
+    std::vector<double> region;
+    BOUND_BOX bbox;
+
+    if (!mapInfo) {
+	return region;
+    }
+    
+    Vect_get_map_box(mapInfo, &bbox);
+
+    region.push_back(bbox.W);
+    region.push_back(bbox.S);
+    region.push_back(bbox.B);
+
+    region.push_back(bbox.E);
+    region.push_back(bbox.N);
+    region.push_back(bbox.T);
+
+    return region;
+}
+
+/**
    \brief Error messages handling 
 
    \param msg message
@@ -1122,3 +1149,4 @@
     
     return 0;
 }
+

Modified: grass/branches/releasebranch_6_3/gui/wxpython/vdigit/driver.h
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/vdigit/driver.h	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/vdigit/driver.h	2008-03-11 18:40:45 UTC (rev 30529)
@@ -172,6 +172,9 @@
     void ReloadMap();
     void SetDevice(void *);
 
+    /* misc */
+    std::vector<double> GetMapBoundingBox();
+
     /* set */
     void SetRegion(double, double, double, double,
 		   double, double,

Modified: grass/branches/releasebranch_6_3/gui/wxpython/vdigit/grass6_wxvdigit.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/vdigit/grass6_wxvdigit.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/vdigit/grass6_wxvdigit.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -237,6 +237,7 @@
     def OpenMap(*args): return _grass6_wxvdigit.DisplayDriver_OpenMap(*args)
     def ReloadMap(*args): return _grass6_wxvdigit.DisplayDriver_ReloadMap(*args)
     def SetDevice(*args): return _grass6_wxvdigit.DisplayDriver_SetDevice(*args)
+    def GetMapBoundingBox(*args): return _grass6_wxvdigit.DisplayDriver_GetMapBoundingBox(*args)
     def SetRegion(*args): return _grass6_wxvdigit.DisplayDriver_SetRegion(*args)
     def UpdateSettings(*args): return _grass6_wxvdigit.DisplayDriver_UpdateSettings(*args)
 DisplayDriver_swigregister = _grass6_wxvdigit.DisplayDriver_swigregister

Modified: grass/branches/releasebranch_6_3/gui/wxpython/vdigit/grass6_wxvdigit_wrap.cpp
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/vdigit/grass6_wxvdigit_wrap.cpp	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/vdigit/grass6_wxvdigit_wrap.cpp	2008-03-11 18:40:45 UTC (rev 30529)
@@ -10384,6 +10384,28 @@
 }
 
 
+SWIGINTERN PyObject *_wrap_DisplayDriver_GetMapBoundingBox(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  DisplayDriver *arg1 = (DisplayDriver *) 0 ;
+  std::vector<double,std::allocator<double > > result;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject * obj0 = 0 ;
+  
+  if (!PyArg_ParseTuple(args,(char *)"O:DisplayDriver_GetMapBoundingBox",&obj0)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_DisplayDriver, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "DisplayDriver_GetMapBoundingBox" "', argument " "1"" of type '" "DisplayDriver *""'"); 
+  }
+  arg1 = reinterpret_cast< DisplayDriver * >(argp1);
+  result = (arg1)->GetMapBoundingBox();
+  resultobj = swig::from(static_cast< std::vector<double,std::allocator<double > > >(result));
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_DisplayDriver_SetRegion(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   DisplayDriver *arg1 = (DisplayDriver *) 0 ;
@@ -11430,6 +11452,7 @@
   char *arg8 = (char *) 0 ;
   int arg9 ;
   double arg10 ;
+  double arg11 ;
   int result;
   void *argp1 = 0 ;
   int res1 = 0 ;
@@ -11452,6 +11475,8 @@
   int ecode9 = 0 ;
   double val10 ;
   int ecode10 = 0 ;
+  double val11 ;
+  int ecode11 = 0 ;
   PyObject * obj0 = 0 ;
   PyObject * obj1 = 0 ;
   PyObject * obj2 = 0 ;
@@ -11462,8 +11487,9 @@
   PyObject * obj7 = 0 ;
   PyObject * obj8 = 0 ;
   PyObject * obj9 = 0 ;
+  PyObject * obj10 = 0 ;
   
-  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOO:Digit_MoveVertex",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9)) SWIG_fail;
+  if (!PyArg_ParseTuple(args,(char *)"OOOOOOOOOOO:Digit_MoveVertex",&obj0,&obj1,&obj2,&obj3,&obj4,&obj5,&obj6,&obj7,&obj8,&obj9,&obj10)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Digit, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Digit_MoveVertex" "', argument " "1"" of type '" "Digit *""'"); 
@@ -11514,7 +11540,12 @@
     SWIG_exception_fail(SWIG_ArgError(ecode10), "in method '" "Digit_MoveVertex" "', argument " "10"" of type '" "double""'");
   } 
   arg10 = static_cast< double >(val10);
-  result = (int)(arg1)->MoveVertex(arg2,arg3,arg4,arg5,arg6,arg7,(char const *)arg8,arg9,arg10);
+  ecode11 = SWIG_AsVal_double(obj10, &val11);
+  if (!SWIG_IsOK(ecode11)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode11), "in method '" "Digit_MoveVertex" "', argument " "11"" of type '" "double""'");
+  } 
+  arg11 = static_cast< double >(val11);
+  result = (int)(arg1)->MoveVertex(arg2,arg3,arg4,arg5,arg6,arg7,(char const *)arg8,arg9,arg10,arg11);
   resultobj = SWIG_From_int(static_cast< int >(result));
   if (alloc8 == SWIG_NEWOBJ) delete[] buf8;
   return resultobj;
@@ -12052,6 +12083,7 @@
 	 { (char *)"DisplayDriver_OpenMap", _wrap_DisplayDriver_OpenMap, METH_VARARGS, NULL},
 	 { (char *)"DisplayDriver_ReloadMap", _wrap_DisplayDriver_ReloadMap, METH_VARARGS, NULL},
 	 { (char *)"DisplayDriver_SetDevice", _wrap_DisplayDriver_SetDevice, METH_VARARGS, NULL},
+	 { (char *)"DisplayDriver_GetMapBoundingBox", _wrap_DisplayDriver_GetMapBoundingBox, METH_VARARGS, NULL},
 	 { (char *)"DisplayDriver_SetRegion", _wrap_DisplayDriver_SetRegion, METH_VARARGS, NULL},
 	 { (char *)"DisplayDriver_UpdateSettings", _wrap_DisplayDriver_UpdateSettings, METH_VARARGS, NULL},
 	 { (char *)"DisplayDriver_swigregister", DisplayDriver_swigregister, METH_VARARGS, NULL},

Modified: grass/branches/releasebranch_6_3/gui/wxpython/vdigit/vertex.cpp
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/vdigit/vertex.cpp	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/vdigit/vertex.cpp	2008-03-11 18:40:45 UTC (rev 30529)
@@ -27,7 +27,8 @@
    \param move_x,move_y,move_z direction for moving vertex
    \param bgmap  map of background map or NULL
    \param snap snap mode (see vector/v.edit/lib/vedit.h)
-   \param thresh threshold value to identify vertex position
+   \param thresh_coords threshold value to identify vertex position
+   \param thresh_snap threshold value to snap moved vertex
 
    \param 1 vertex moved
    \param 0 nothing changed
@@ -35,7 +36,8 @@
 */
 int Digit::MoveVertex(double x, double y, double z,
 		      double move_x, double move_y, double move_z,
-		      const char *bgmap, int snap, double thresh) {
+		      const char *bgmap, int snap,
+		      double thresh_coords, double thresh_snap) {
 
     int ret;
     struct line_pnts *point;
@@ -63,7 +65,7 @@
     /* move only first found vertex in bbox */
     ret = Vedit_move_vertex(display->mapInfo, BgMap, nbgmaps, 
 			    display->selected,
-			    point, thresh,
+			    point, thresh_coords, thresh_snap,
 			    move_x, move_y, move_z,
 			    1, snap); 
 

Modified: grass/branches/releasebranch_6_3/gui/wxpython/wxgui.py
===================================================================
--- grass/branches/releasebranch_6_3/gui/wxpython/wxgui.py	2008-03-11 18:25:14 UTC (rev 30528)
+++ grass/branches/releasebranch_6_3/gui/wxpython/wxgui.py	2008-03-11 18:40:45 UTC (rev 30529)
@@ -4,7 +4,6 @@
 CLASSES:
     * GMFrame
     * GMApp
-    * ProcessGrcXml
 
 PURPOSE:    Main Python app for GRASS wxPython GUI. Main menu, layer management
             toolbar, notebook control for display management and access to
@@ -28,16 +27,19 @@
 import traceback
 import types
 import re
-### for GRC (workspace file) parsering
-# xmlproc not available on Mac OS
-# from xml.parsers.xmlproc import xmlproc
-# from xml.parsers.xmlproc import xmlval
-# from xml.parsers.xmlproc import xmldtd
+import string
+import getopt
+
+### XML 
 import xml.sax
 import xml.sax.handler
 HandlerBase=xml.sax.handler.ContentHandler
 from xml.sax import make_parser
 
+### i18N
+import gettext
+gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode=True)
+
 import gui_modules
 gmpath = gui_modules.__path__[0]
 sys.path.append(gmpath)
@@ -65,22 +67,25 @@
 except:
     import compat.subprocess as subprocess
 
+import gui_modules.preferences as preferences
 import gui_modules.wxgui_utils as wxgui_utils
 import gui_modules.mapdisp as mapdisp
 import gui_modules.menudata as menudata
 import gui_modules.menuform as menuform
 import gui_modules.grassenv as grassenv
-import gui_modules.preferences as preferences
 import gui_modules.histogram as histogram
 import gui_modules.profile as profile
 import gui_modules.rules as rules
+import gui_modules.mcalc_builder as mapcalculator
 import gui_modules.gcmd as gcmd
 import gui_modules.georect as georect
 import gui_modules.dbm as dbm
 import gui_modules.globalvar as globalvar
+import gui_modules.workspace as workspace
 from   gui_modules.debug import Debug as Debug
 from   icons.icon import Icons as Icons
 
+UserSettings = preferences.globalSettings
 
 class GMFrame(wx.Frame):
     """
@@ -88,8 +93,7 @@
     GRASS GIS. Includes command console page for typing GRASS
     (and other) commands, tree widget page for managing GIS map layers.
     """
-    def __init__(self, parent, id=wx.ID_ANY,
-                 title=_("GRASS GIS Layer Manager"),
+    def __init__(self, parent, id=wx.ID_ANY, title=_("GRASS GIS Layer Manager (Experimental Prototype)"),
                  workspace=None):
         self.parent    = parent
         self.baseTitle = title
@@ -99,7 +103,7 @@
                           style=wx.DEFAULT_FRAME_STYLE)
         self.SetTitle(self.baseTitle)
 
-        self.SetIcon(wx.Icon(os.path.join(imagepath, 'grass.smlogo.gif'), wx.BITMAP_TYPE_ANY))
+        self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
 
         self._auimgr = wx.aui.AuiManager(self)
 
@@ -149,16 +153,19 @@
         wx.CallAfter(self.notebook.SetSelection, 0)
 
         # start default initial display
-        self.NewDisplay()
+        self.NewDisplay(show=False)
         
         # load workspace file if requested
         if (self.workspaceFile):
             # load given workspace file
-            if self.LoadGrcXmlToLayerTree(self.workspaceFile):
+            if self.LoadWorkspaceFile(self.workspaceFile):
                 self.SetTitle(self.baseTitle + " - " +  os.path.basename(self.workspaceFile))
             else:
                 self.workspaceFile = None
 
+        # show map display widnow
+        self.curr_page.maptree.mapdisplay.Show()
+
     def __doLayout(self):
         """Do Layout (unused bacause of aui manager...)"""
         # self.panel = wx.Panel(self,-1, style= wx.EXPAND)
@@ -178,11 +185,11 @@
         self.cmdprompt = wx.Panel(self)
 
         label = wx.StaticText(parent=self.cmdprompt, id=wx.ID_ANY, label="Cmd >")
-        label.SetFont(wx.Font(pointSize=11, family=wx.FONTFAMILY_DEFAULT,
-                              style=wx.NORMAL, weight=wx.BOLD))
+	# label.SetFont(wx.Font(pointSize=11, family=wx.FONTFAMILY_DEFAULT,
+        #                      style=wx.NORMAL, weight=wx.BOLD))
         input = wx.TextCtrl(parent=self.cmdprompt, id=wx.ID_ANY,
                             value="",
-                            style=wx.HSCROLL | wx.TE_LINEWRAP | wx.TE_PROCESS_ENTER,
+                            style=wx.TE_LINEWRAP | wx.TE_PROCESS_ENTER,
                             size=(-1, 25))
 
         input.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, ''))
@@ -295,6 +302,8 @@
         """Creates toolbar"""
 
         self.toolbar = self.CreateToolBar()
+        self.toolbar.SetToolBitmapSize(globalvar.toolbarSize)
+
         for each in self.ToolbarData():
             self.AddToolbarButton(self.toolbar, *each)
         self.toolbar.Realize()
@@ -326,27 +335,17 @@
         """
         Launch mapset access dialog
         """
-        dlg = MapsetAccess(self, wx.ID_ANY)
-
+        dlg = preferences.MapsetAccess(parent=self, id=wx.ID_ANY)
         dlg.CenterOnScreen()
 
         # if OK is pressed...
         if dlg.ShowModal() == wx.ID_OK:
-            # create string of accessible mapsets
-            ms_string = 'PERMANENT'
-            if dlg.curr_mapset == 'PERMANENT':
-                ms_string = 'PERMANENT'
-            else:
-                ms_string = 'PERMANENT,%s' % dlg.curr_mapset
-            for mset in dlg.all_mapsets:
-                    index = dlg.all_mapsets.index(mset)
-                    if dlg.mapsetlb.IsChecked(index):
-                        ms_string += ',%s' % mset
-
+            ms = dlg.GetMapsets()
             # run g.mapsets with string of accessible mapsets
-            cmdlist = ['g.mapsets', 'mapset=%s' % ms_string]
+            cmdlist = ['g.mapsets', 'mapset=%s' % ','.join(ms)]
             gcmd.Command(cmdlist)
-
+            UserSettings.Set(group='general', key='mapsetPath', subkey='value', value=ms, internal=True)
+            
     def OnRDigit(self, event):
         """
         Launch raster digitizing module
@@ -510,7 +509,7 @@
     def OnWorkspaceOpen(self, event=None):
         """Open file with workspace definition"""
         dlg = wx.FileDialog(parent=self, message=_("Choose workspace file"),
-                            defaultDir=os.getcwd(), wildcard="*.grc")
+                            defaultDir=os.getcwd(), wildcard="*.gxw")
 
         filename = ''
         if dlg.ShowModal() == wx.ID_OK:
@@ -521,19 +520,19 @@
 
         Debug.msg(4, "GMFrame.OnWorkspaceOpen(): filename=%s" % filename)
 
-        self.LoadGrcXmlToLayerTree(filename)
+        self.LoadWorkspaceFile(filename)
 
         self.workspaceFile = filename
         self.SetTitle(self.baseTitle + " - " +  os.path.basename(self.workspaceFile))
 
-    def LoadGrcXmlToLayerTree(self, filename):
-        """Load layer tree definition stored in GRC XML file
+    def LoadWorkspaceFile(self, filename):
+        """Load layer tree definition stored in GRASS Workspace XML file (gxw)
 
         Return True on success
         Return False on error"""
 
         # dtd
-        dtdFilename = os.path.join(globalvar.ETCWXDIR, "gui_modules", "grass-grc.dtd")
+        dtdFilename = os.path.join(globalvar.ETCWXDIR, "gui_modules", "grass-gxw.dtd")
 
         # validate xml agains dtd
         #         dtd = xmldtd.load_dtd(dtdFilename)
@@ -546,7 +545,7 @@
         #             parser.parse_resource(filename)
         #         except:
         #             dlg = wx.MessageDialog(self, _("Unable to open workspace file <%s>. "
-        #                                            "It is not valid GRC XML file.") % filename,
+        #                                            "It is not valid GRASS Workspace File.") % filename,
         #                                    _("Error"), wx.OK | wx.ICON_ERROR)
         #             dlg.ShowModal()
         #             dlg.Destroy()
@@ -560,14 +559,31 @@
             file = open(filename, "r")
 
             fileStream = ''.join(file.readlines())
-            p = re.compile( '(grass-grc.dtd)')
+            p = re.compile( '(grass-gxw.dtd)')
             p.search(fileStream)
             fileStream = p.sub(dtdFilename, fileStream)
 
             # sax
-            grcXml = ProcessGrcXml()
-            xml.sax.parseString(fileStream, grcXml)
-            for layer in grcXml.layers:
+            gxwXml = workspace.ProcessWorkspaceFile()
+            
+            try:
+                xml.sax.parseString(fileStream, gxwXml)
+            except xml.sax.SAXParseException, err:
+                raise gcmd.GStdError(_("Reading workspace file <%s> failed. "
+                                       "Invalid file, unable to parse XML document.") % filename + \
+                                         "\n\n%s" % err,
+                                     parent=self)
+            except ValueError, err:
+                raise gcmd.GStdError(_("Reading workspace file <%s> failed. "
+                                       "Invalid file, unable to parse XML document.") % filename + \
+                                         "\n\n%s" % err,
+                                     parent=self)
+
+            busy = wx.BusyInfo(message=_("Please wait, loading map layers into layer tree..."),
+                               parent=self)
+            wx.Yield()
+
+            for layer in gxwXml.layers:
                 if layer['display'] >= self.disp_idx:
                     # create new map display window if needed
                     self.NewDisplay()
@@ -580,17 +596,22 @@
                                            lgroup=layer['group'])
                 maptree.PropertiesDialog(newItem, show=False)
 
+            busy.Destroy()
+            
             # reverse list of map layers
             maptree.Map.ReverseListOfLayers()
 
             file.close()
         except IOError, err:
             wx.MessageBox(parent=self,
-                          message=_("Unable to read workspace file <%s>.%s%s") % \
-                          (filename, os.linesep, err),
+                          message="%s <%s>. %s%s" % (_("Unable to read workspace file"),
+                                                     filename, os.linesep, err),
                           caption=_("Error"), style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
             return False
-
+        except gcmd.GStdError, e:
+            print e
+            return False
+                               
         return True
 
     def OnWorkspaceLoad(self, event=None):
@@ -617,14 +638,11 @@
 
             busy.Destroy()
 
-            # reverse list of map layers
-            maptree.Map.ReverseListOfLayers()
-
     def OnWorkspaceSaveAs(self, event=None):
         """Save workspace definition to selected file"""
 
         dlg = wx.FileDialog(parent=self, message=_("Choose file to save current workspace"),
-                            defaultDir=os.getcwd(), wildcard="*.grc", style=wx.FD_SAVE)
+                            defaultDir=os.getcwd(), wildcard="*.gxw", style=wx.FD_SAVE)
 
         filename = ''
         if dlg.ShowModal() == wx.ID_OK:
@@ -634,20 +652,20 @@
             return False
 
         # check for extension
-        if filename[-4:] != ".grc":
-            filename += ".grc"
+        if filename[-4:] != ".gxw":
+            filename += ".gxw"
 
         if os.path.exists(filename):
             dlg = wx.MessageDialog(self, message=_("Workspace file <%s> already exists. "
                                                    "Do you want to overwrite this file?") % filename,
-                                   caption=_("File exits"), style=wx.OK | wx.CANCEL | wx.ICON_QUESTION)
+                                   caption=_("Warning"), style=wx.OK | wx.CANCEL | wx.ICON_QUESTION)
             if dlg.ShowModal() != wx.ID_OK:
                 dlg.Destroy()
                 return False
 
         Debug.msg(4, "GMFrame.OnWorkspaceSaveAs(): filename=%s" % filename)
 
-        self.SaveLayerTreeToGrcXml(filename)
+        self.SaveToWorkspaceFile(filename)
         self.workspaceFile = filename
         self.SetTitle(self.baseTitle + " - " + os.path.basename(self.workspaceFile))
 
@@ -658,17 +676,17 @@
             dlg = wx.MessageDialog(self, message=_("Workspace file <%s> already exists. "
                                                    "Do you want to overwrite this file?") % \
                                        self.workspaceFile,
-                                   caption=_("File exits"), style=wx.OK | wx.CANCEL | wx.ICON_QUESTION)
+                                   caption=_("Warning"), style=wx.OK | wx.CANCEL | wx.ICON_QUESTION)
             if dlg.ShowModal() != wx.ID_OK:
                 dlg.Destroy()
             else:
                 Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % self.workspaceFile)
-                self.SaveLayerTreeToGrcXml(self.workspaceFile)
+                self.SaveToWorkspaceFile(self.workspaceFile)
         else:
             self.OnWorkspaceSaveAs()
 
-    def WriteLayersToGrcXml(self, file, mapTree, item):
-        """Write bunch of layers to GRC XML file"""
+    def WriteLayersToWorkspaceFile(self, file, mapTree, item):
+        """Write bunch of layers to GRASS Workspace XML file"""
         self.indent += 4
         while item and item.IsOk():
             type = mapTree.GetPyData(item)[0]['type']
@@ -689,7 +707,7 @@
                                (' ' * self.indent, name, checked));
                 self.indent += 4
                 subItem = mapTree.GetFirstChild(item)[0]
-                self.WriteLayersToGrcXml(file, mapTree, subItem)
+                self.WriteLayersToWorkspaceFile(file, mapTree, subItem)
                 self.indent -= 4
                 file.write('%s</group>\n' % (' ' * self.indent));
             else:
@@ -721,7 +739,7 @@
             item = mapTree.GetNextSibling(item)
         self.indent -= 4
 
-    def SaveLayerTreeToGrcXml(self, filename):
+    def SaveToWorkspaceFile(self, filename):
         """Save layer tree layout to workspace file
 
         Return True on success, False on error
@@ -740,8 +758,8 @@
             self.indent = 0 # number of spaces
             # write header
             file.write('<?xml version="1.0" encoding="UTF-8"?>\n')
-            file.write('<!DOCTYPE grc SYSTEM "grass-grc.dtd">\n')
-            file.write('%s<grc>\n' % (' ' * self.indent))
+            file.write('<!DOCTYPE gxw SYSTEM "grass-gxw.dtd">\n')
+            file.write('%s<gxw>\n' % (' ' * self.indent))
             # list of displays
             for page in range(0, self.gm_cb.GetPageCount()):
                 self.indent =+ 4
@@ -749,10 +767,10 @@
                 mapTree = self.gm_cb.GetPage(page).maptree
                 # list of layers
                 item = mapTree.GetFirstChild(mapTree.root)[0]
-                self.WriteLayersToGrcXml(file, mapTree, item)
+                self.WriteLayersToWorkspaceFile(file, mapTree, item)
                 file.write('%s</display>\n' % (' ' * self.indent))
             self.indent =- 4
-            file.write('%s</grc>\n' % (' ' * self.indent))
+            file.write('%s</gxw>\n' % (' ' * self.indent))
             del self.indent
         except:
             dlg = wx.MessageDialog(self, _("Writing current settings to workspace file failed."),
@@ -781,26 +799,32 @@
         input and processes rules
         """
         command = self.GetMenuCmd(event)
+
         dlg = rules.RulesText(self, cmd=command)
         if dlg.ShowModal() == wx.ID_OK:
             gtemp = utils.GetTempfile()
-            output = open(gtemp,"w")
+            output = open(gtemp, "w")
             try:
                 output.write(dlg.rules)
             finally:
                 output.close()
 
-            if command == 'r.colors':
-                cmdlist = [command,'map=%s' % dlg.inmap,'rules=%s' % gtemp,'--verbose']
+            if command[0] == 'r.colors':
+                cmdlist = [command[0],
+                           'map=%s' % dlg.inmap,
+                           'rules=%s' % gtemp]
             else:
-                cmdlist = [command,'input=%s' % dlg.inmap,'output=%s' % dlg.outmap,'rules=%s' % gtemp]
+                cmdlist = [command[0],
+                           'input=%s' % dlg.inmap,
+                           'output=%s' % dlg.outmap,
+                           'rules=%s' % gtemp]
 
             if dlg.overwrite == True:
                 cmdlist.append('--o')
 
-            gcmd.Command(cmdlist, verbose=3)
+            dlg.Destroy()
 
-        dlg.Destroy()
+            self.goutput.RunCmd(cmdlist)
 
     def OnXTerm(self, event):
         """
@@ -816,33 +840,37 @@
         gisbase = os.environ['GISBASE']
 
         # make list of xmons that are not running
-        cmdlist = ['d.mon', '-L']
+        cmdlist = ["d.mon", "-L"]
         p = gcmd.Command(cmdlist)
-        output = p.module_stdout.read().split('\n')
-        for outline in output:
-            outline = outline.strip()
-            if outline.startswith('x') and 'not running' in outline:
 
-                xmonlist.append(outline[0:2])
+        for line in p.ReadStdOutput():                
+            line = line.strip()
+            if line.startswith('x') and 'not running' in line:
+                xmonlist.append(line[0:2])
 
         # open available xmon
         xmon = xmonlist[0]
-        cmdlist = ['d.mon','start=%s' % xmon]
-        p = subprocess.Popen(cmdlist)
+        cmdlist = ["d.mon","start=%s" % xmon]
+        p = gcmd.Command(cmdlist)
 
-        # run the command
+        # run the command        
+        runbat = os.path.join(gisbase,'etc','grass-run.bat')
+        xtermwrapper = os.path.join(gisbase,'etc','grass-xterm-wrapper')
+        grassrun = os.path.join(gisbase,'etc','grass-run.sh')
+        command = ' '.join(command)
+        
         if 'OS' in os.environ and os.environ['OS'] == "Windows_NT":
-            cmdlist = ['cmd.exe', '/c', 'start', os.path.join(gisbase,'etc','grass-run.bat'), command]
+            cmdlist = ["cmd.exe", "/c", 'start "%s"' % runbat, command]
         else:
-            cmdlist = [os.path.join(gisbase,'etc','grass-xterm-wrapper'), '-name', 'xterm-grass', '-e', os.path.join(gisbase,'etc','grass-run.sh'), command]
-        gcmd.Command(cmdlist)
+            cmdlist = [xtermwrapper, '-e "%s"' % grassrun, command]
+        p = gcmd.Command(cmdlist)
 
         # reset display mode
         os.environ['GRASS_RENDER_IMMEDIATE'] = 'TRUE'
 
     def OnPreferences(self, event):
         """General GUI preferences/settings"""
-        preferences.PreferencesDialog(parent=self, title=_("User preferences")).ShowModal()
+        preferences.PreferencesDialog(parent=self).ShowModal()
 
     def DispHistogram(self, event):
         """
@@ -867,7 +895,22 @@
         self.profile.Show()
         self.profile.Refresh()
         self.profile.Update()
+        
+    def DispMapCalculator(self, event):
+        """
+        Init map calculator for interactive creation of mapcalc statements
+        """
+        
+        self.mapcalculator = mapcalculator.MapCalcFrame(self, wx.ID_ANY, title='',
+                                                        dimension=2)
 
+    def Disp3DMapCalculator(self, event):
+        """
+        Init map calculator for interactive creation of mapcalc statements
+        """
+        
+        self.mapcalculator = mapcalculator.MapCalcFrame(self, wx.ID_ANY, title='',
+                                                        dimension=3)
 
     def AddToolbarButton(self, toolbar, label, icon, help, handler):
         """Adds button to the given toolbar"""
@@ -882,7 +925,7 @@
 
         return   (
                  ('newdisplay', Icons["newdisplay"].GetBitmap(),
-                  Icons["newdisplay"].GetLabel(), self.NewDisplay),
+                  Icons["newdisplay"].GetLabel(), self.OnNewDisplay),
                  ('', '', '', ''),
                  ('workspaceLoad', Icons["workspaceLoad"].GetBitmap(),
                   Icons["workspaceLoad"].GetLabel(), self.OnWorkspace),
@@ -929,7 +972,7 @@
         if not maptype or maptype != 'vector':
             dlg = wx.MessageDialog(parent=self,
                                    message=_("Attribute management is available only "
-                                             "for vector map layers"),
+                                             "for vector maps."),
                                    caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
             dlg.ShowModal()
             dlg.Destroy()
@@ -953,18 +996,20 @@
         pointdata = (icon, size)
 
         self.dbmanager = dbm.AttributeManager(parent=self, id=wx.ID_ANY,
-                                              title=_("GRASS GIS Attribute Table Manager - "
-                                                      "vector map layer <%s>") % mapname,
+                                              title="%s - <%s>" % (_("GRASS GIS Attribute Table Manager"),
+                                                                   mapname),
                                               size=wx.Size(500,300), vectmap=mapname,
                                               pointdata=pointdata)
         self.dbmanager.Show()
 
-    def NewDisplay(self, event=None):
-        """
-        Create new layer tree, which will
+    def OnNewDisplay(self, event=None):
+        """Create new layer tree and map display instance"""
+        self.NewDisplay()
+
+    def NewDisplay(self, show=True):
+        """Create new layer tree, which will
         create an associated map display frame
         """
-
         Debug.msg(3, "GMFrame.NewDisplay(): idx=%d" % self.disp_idx)
 
         # make a new page in the bookcontrol for the layer tree (on page 0 of the notebook)
@@ -978,7 +1023,7 @@
                                                        |wx.TR_LINES_AT_ROOT|wx.TR_EDIT_LABELS|wx.TR_HIDE_ROOT
                                                        |wx.TR_DEFAULT_STYLE|wx.NO_BORDER|wx.FULL_REPAINT_ON_RESIZE,
                                                        idx=self.disp_idx, gismgr=self, notebook=self.gm_cb,
-                                                       auimgr=self._auimgr)
+                                                       auimgr=self._auimgr, showMapDisplay=show)
 
         # layout for controls
         cb_boxsizer = wx.BoxSizer(wx.VERTICAL)
@@ -1178,10 +1223,11 @@
 
         layerName = str(self.curr_page.maptree.GetItemText(self.curr_page.maptree.layer_selected))
         if layerName:
-            message = _("Do you want to remove map layer <" + layerName + "> "
-                        "from layer tree?")
+            message = _("Do you want to remove map layer <%s> "
+                        "from layer tree?") % layerName
         else:
-            message = _("Do you want to remove selected layer from layer tree?")
+            message = _("Do you want to remove selected map layer "
+                        "from layer tree?")
 
         dlg = wx.MessageDialog (parent=self, message=message,
                                 caption=_("Remove map layer"),
@@ -1217,72 +1263,6 @@
         dlg.ShowModal()
         dlg.Destroy()
 
-class MapsetAccess(wx.Dialog):
-    """
-    Controls setting options and displaying/hiding map overlay decorations
-    """
-    def __init__(self, parent, id, title=_('Set/unset access to mapsets in current location'),
-                           pos=wx.DefaultPosition, size=(-1,-1),
-                           style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER):
-        wx.Dialog.__init__(self, parent, id, title, pos, size, style)
-
-        self.all_mapsets, self.accessible_mapsets = utils.ListOfMapsets()
-        self.curr_mapset = grassenv.GetGRASSVariable('MAPSET')
-
-        # remove PERMANENT and current mapset from list because they are always accessible
-        self.PERMANENT_ndx = self.all_mapsets.index("PERMANENT")
-        self.all_mapsets.pop(self.PERMANENT_ndx)
-        if self.curr_mapset != "PERMANENT":
-            self.curr_ndx = self.all_mapsets.index(self.curr_mapset)
-            self.all_mapsets.pop(self.curr_ndx)
-
-        # make a checklistbox from available mapsets and check those that are active
-        sizer = wx.BoxSizer(wx.VERTICAL)
-
-        box = wx.BoxSizer(wx.HORIZONTAL)
-        if len(self.all_mapsets) == 0:
-            label = wx.StaticText(self, -1, "No other accessible mapsets besides \
-                                \nPERMANENT and current mapset.",
-                                style=wx.ALIGN_CENTRE)
-        else:
-            label = wx.StaticText(self, -1, "Check mapset to make it accessible, uncheck it to hide it.\
-                                \nPERMANENT and current mapset are always accessible.",
-                                style=wx.ALIGN_CENTRE)
-        box.Add(label, 0, wx.ALIGN_CENTRE)
-        sizer.Add(box, 0, wx.ALIGN_CENTRE|wx.TOP|wx.BOTTOM, 5)
-
-        box = wx.BoxSizer(wx.HORIZONTAL)
-        self.mapsetlb = wx.CheckListBox(self, -1, pos=wx.DefaultPosition,
-                                        size=(350,200), choices=self.all_mapsets)
-        box.Add(self.mapsetlb, 0, wx.ALIGN_CENTRE)
-        sizer.Add(box, 0, wx.ALIGN_CENTRE|wx.TOP|wx.BOTTOM, 5)
-
-        # check all accessible mapsets
-        for mset in self.accessible_mapsets:
-            if mset != 'PERMANENT' and mset != self.curr_mapset:
-                self.mapsetlb.Check(self.all_mapsets.index(mset),True)
-
-        # dialog buttons
-        line = wx.StaticLine(self, -1, size=(-1,-1), style=wx.LI_HORIZONTAL)
-        sizer.Add(line, 0, wx.EXPAND|wx.ALIGN_CENTRE|wx.TOP|wx.BOTTOM, 5)
-
-        btnsizer = wx.StdDialogButtonSizer()
-
-        okbtn = wx.Button(self, wx.ID_OK)
-        okbtn.SetDefault()
-        btnsizer.AddButton(okbtn)
-
-        cancelbtn = wx.Button(self, wx.ID_CANCEL)
-        btnsizer.AddButton(cancelbtn)
-        btnsizer.Realize()
-
-        sizer.Add(btnsizer, 0, wx.EXPAND|wx.ALIGN_RIGHT|wx.ALL, 5)
-
-        self.Layout()
-        self.SetSizer(sizer)
-
-        sizer.Fit(self)
-
 class GMApp(wx.App):
     """
     GMApp class
@@ -1291,7 +1271,7 @@
         self.workspaceFile = workspace
         
         # call parent class initializer
-        wx.App.__init__(self)
+        wx.App.__init__(self, False)
         
     def OnInit(self):
         # initialize all available image handlers
@@ -1307,7 +1287,6 @@
 
         # create and show main frame
         mainframe = GMFrame(parent=None, id=wx.ID_ANY,
-                            title=_("GRASS GIS Layer Manager (Experimental Prototype)"),
                             workspace = self.workspaceFile)
 
         mainframe.Show()
@@ -1315,128 +1294,10 @@
 
         return True
 
-class ProcessGrcXml(HandlerBase):
-    """
-    A SAX handler for the GRC XML file, as
-    defined in grass-grc.dtd.
-    """
-    def __init__(self):
-        self.inGrc       = False
-        self.inLayer     = False
-        self.inTask      = False
-        self.inParameter = False
-        self.inFlag      = False
-        self.inValue     = False
-        self.inGroup     = False
-        self.inDisplay   = False
-
-        # list of layers
-        self.layers = []
-        self.cmd    = []
-        self.displayIndex = -1 # first display has index '0'
-
-    def startElement(self, name, attrs):
-        if name == 'grc':
-            self.inGrc = True
-
-        elif name == 'display':
-            self.inDisplay = True
-            self.displayIndex += 1
-
-        elif name == 'group':
-            self.groupName    = attrs.get('name', None)
-            self.groupChecked = attrs.get('checked', None)
-            self.layers.append({
-                    "type"    : 'group',
-                    "name"    : self.groupName,
-                    "checked" : int(self.groupChecked),
-                    "opacity" : None,
-                    "cmd"     : None,
-                    "group"   : self.inGroup,
-                    "display" : self.displayIndex})
-            self.inGroup = True
-
-        elif name == 'layer':
-            self.inLayer = True
-            self.layerType    = attrs.get('type', None)
-            self.layerName    = attrs.get('name', None)
-            self.layerChecked = attrs.get('checked', None)
-            self.layerOpacity = attrs.get('opacity', None)
-            self.cmd = []
-
-        elif name == 'task':
-            self.inTask = True;
-            name = attrs.get('name', None)
-            self.cmd.append(name)
-
-        elif name == 'parameter':
-            self.inParameter = True;
-            self.parameterName = attrs.get('name', None)
-
-        elif name == 'value':
-            self.inValue = True
-            self.value = ''
-
-        elif name == 'flag':
-            self.inFlag = True;
-            name = attrs.get('name', None)
-            self.cmd.append('-' + name)
-
-    def endElement(self, name):
-        if name == 'grc':
-            self.inGrc = False
-
-        elif name == 'display':
-            self.inDisplay = False
-
-        elif name == 'group':
-            self.inGroup = False
-            self.groupName = self.groupChecked = None
-
-        elif name == 'layer':
-            self.inLayer = False
-            self.layers.append({
-                    "type"    : self.layerType,
-                    "name"    : self.layerName,
-                    "checked" : int(self.layerChecked),
-                    "opacity" : None,
-                    "cmd"     : None,
-                    "group"   : self.inGroup,
-                    "display" : self.displayIndex})
-
-            if self.layerOpacity:
-                self.layers[-1]["opacity"] = float(self.layerOpacity)
-            if self.cmd:
-                self.layers[-1]["cmd"] = self.cmd
-
-            self.layerType = self.layerName = self.Checked = \
-                self.Opacity = self.cmd = None
-
-        elif name == 'task':
-            self.inTask = False
-
-        elif name == 'parameter':
-            self.inParameter = False
-            self.cmd.append('%s=%s' % (self.parameterName, self.value))
-            self.parameterName = self.value = None
-
-        elif name == 'value':
-            self.inValue = False
-
-        elif name == 'flag':
-            self.inFlag = False
-
-    def characters(self, ch):
-        self.my_characters(ch)
-
-    def my_characters(self, ch):
-        if self.inValue:
-            self.value += ch
-
 def reexec_with_pythonw():
   if sys.platform == 'darwin' and \
     not sys.executable.endswith('MacOS/Python'):
-    print >> sys.stderr, _('re-executing using pythonw')
+    print >> sys.stderr, 're-executing using pythonw'
     os.execvp('pythonw', ['pythonw', __file__] + sys.argv[1:])
 
 class Usage(Exception):
@@ -1491,16 +1352,14 @@
 
     workspaceFile = process_opt(opts, args)[0]
 
-    # replace with the appropriate catalog name
-    gettext.install("GMApp") 
-
     #
     # run application
     #
     app = GMApp(workspaceFile)
+    # suppress wxPython logs
+    q = wx.LogNull()
+
     app.MainLoop()
 
 if __name__ == "__main__":
-    import getopt
-    import gettext
     sys.exit(main())



More information about the grass-commit mailing list