[GRASS-SVN] r33166 - in grass/branches/develbranch_6/gui/wxpython: gui_modules vdigit

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Aug 30 12:21:13 EDT 2008


Author: martinl
Date: 2008-08-30 12:21:13 -0400 (Sat, 30 Aug 2008)
New Revision: 33166

Modified:
   grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py
   grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py
   grass/branches/develbranch_6/gui/wxpython/vdigit/cats.cpp
   grass/branches/develbranch_6/gui/wxpython/vdigit/digit.h
   grass/branches/develbranch_6/gui/wxpython/vdigit/message.cpp
Log:
wxGUI/vdigit: copy categories/attributes implemented


Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py	2008-08-30 06:30:10 UTC (rev 33165)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/goutput.py	2008-08-30 16:21:13 UTC (rev 33166)
@@ -193,8 +193,8 @@
         """
         if Debug.get_level() == 0:
             # don't redirect when debugging is enabled
-            # sys.stdout = self.cmd_stdout
-            # sys.stderr = self.cmd_stderr
+            sys.stdout = self.cmd_stdout
+            sys.stderr = self.cmd_stderr
             
             return True
 

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py	2008-08-30 06:30:10 UTC (rev 33165)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/mapdisp.py	2008-08-30 16:21:13 UTC (rev 33166)
@@ -1125,7 +1125,7 @@
                     self.UpdateMap(render=False) # redraw map
 
                     # add new record into atribute table
-                    if UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled') is True:
+                    if UserSettings.Get(group='vdigit', key="addRecord", subkey='enabled')  is True:
                         # select attributes based on layer and category
                         cats = {}
                         cats[UserSettings.Get(group='vdigit', key="layer", subkey='value')] = \
@@ -1261,7 +1261,7 @@
                             # upgrade dialog
                             self.parent.dialogs['category'].UpdateDialog(cats=digitClass.GetLineCats(),
                                                                      line=line)
-
+                    
                     if self.parent.dialogs['category']:
                         line = self.parent.dialogs['category'].GetLine()
                         if line:
@@ -1276,7 +1276,7 @@
 
                 self.UpdateMap(render=False)
 
-            elif digitToolbar.GetAction() == "copyCats":
+            elif digitToolbar.GetAction() in ("copyCats", "copyAttrs"):
                 if not hasattr(self, "copyCatsList"):
                     self.copyCatsList = []
                 else:
@@ -1391,7 +1391,7 @@
                 self.mouse['begin'] = self.mouse['end'] 
 
             if digitToolbar.GetAction() in ["deleteLine", "moveLine", "moveVertex",
-                                            "copyCats", "editLine", "flipLine",
+                                            "copyCats", "copyAttrs", "editLine", "flipLine",
                                             "mergeLine", "snapLine",
                                             "queryLine", "breakLine", "typeConv", "connectLine"]:
                 nselected = 0
@@ -1431,26 +1431,29 @@
 
                             self.UpdateMap(render=False)
 
-                elif digitToolbar.GetAction() == "copyCats":
+                elif digitToolbar.GetAction() in ("copyCats", "copyAttrs"):
                     if not hasattr(self, "copyCatsIds"):
-                        # collect categories
+                        # 'from' -> select by point
                         nselected = digitClass.driver.SelectLineByPoint(pos1, type=VDigit_Lines_Type)
                         if nselected:
-                            qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / \
-                                                self.Map.width)
-                            vWhat = gcmd.Command(['v.what',
-                                                 '--q',
-                                                 'map=%s' % digitClass.map,
-                                                 'east_north=%f,%f' % \
-                                                     (float(pos1[0]), float(pos1[1])),
-                                                 'distance=%f' % qdist])
-
-                            for line in vWhat.ReadStdOutput():
-                                if "Category:" in line:
-                                    cat = int(line.split(':')[1].strip())
-                                    self.copyCatsList.append(cat)
+                            if UserSettings.Get(group='advanced', key='digitInterface', subkey='type') == 'vedit':
+                                qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / \
+                                                    self.Map.width)
+                                vWhat = gcmd.Command(['v.what',
+                                                      '--q',
+                                                      'map=%s' % digitClass.map,
+                                                      'east_north=%f,%f' % \
+                                                          (float(pos1[0]), float(pos1[1])),
+                                                      'distance=%f' % qdist])
+                                
+                                for line in vWhat.ReadStdOutput():
+                                    if "Category:" in line:
+                                        cat = int(line.split(':')[1].strip())
+                                        self.copyCatsList.append(cat)
+                            else:
+                                self.copyCatsList = digitClass.driver.GetSelected()
                     else:
-                        # collect ids
+                        # -> 'to' -> select by bbox
                         digitClass.driver.SetSelected([])
                         # return number of selected features (by box/point)
                         nselected = digitClass.driver.SelectLinesByBox(pos1, pos2,
@@ -1783,13 +1786,18 @@
             elif digitToolbar.GetAction() == "removeVertex":
                 # remove vertex
                 digitClass.RemoveVertex(self.Pixel2Cell(self.mouse['begin']))
-            elif digitToolbar.GetAction() == "copyCats":
+            elif digitToolbar.GetAction() in ("copyCats", "copyAttrs"):
                 try:
-                    digitClass.CopyCats(self.copyCatsList,
-                                        self.copyCatsIds)
+                    if digitToolbar.GetAction() == 'copyCats':
+                        digitClass.CopyCats(self.copyCatsList,
+                                            self.copyCatsIds, copyAttrb=False)
+                    else:
+                        digitClass.CopyCats(self.copyCatsList,
+                                            self.copyCatsIds, copyAttrb=True)
+                    
                     del self.copyCatsList
                     del self.copyCatsIds
-                except:
+                except AttributeError:
                     pass
             elif digitToolbar.GetAction() == "editLine" and hasattr(self, "moveBegin"):
                 line = digitClass.driver.GetSelected()
@@ -1884,8 +1892,9 @@
                     try:
                         del self.copyCatsList
                         del self.copyCatsIds
-                    except:
+                    except AttributeError:
                         pass
+                
                 elif digitToolbar.GetAction() == "copyLine":
                     del self.copyIds
                     if self.layerTmp:

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py	2008-08-30 06:30:10 UTC (rev 33165)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/toolbars.py	2008-08-30 16:21:13 UTC (rev 33166)
@@ -684,6 +684,8 @@
                             text=_('Duplicate attributes'),
                             kind=wx.ITEM_CHECK)
         toolMenu.AppendItem(attrb)
+        if UserSettings.Get(group='advanced', key='digitInterface', subkey='type') == 'vedit':
+            attrb.Enable(False) # Not implemeneted for vedit
         self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnCopyAttrb, attrb)
         if self.action['desc'] == "copyAttrs":
             attrb.Check(True)

Modified: grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py	2008-08-30 06:30:10 UTC (rev 33165)
+++ grass/branches/develbranch_6/gui/wxpython/gui_modules/vdigit.py	2008-08-30 16:21:13 UTC (rev 33166)
@@ -91,6 +91,9 @@
 
         self.driver = CDisplayDriver(self, mapwindow)
 
+    def __del__(self):
+        pass
+    
     def SetCategoryNextToUse(self):
         """Find maximum category number in the map layer
         and update Digit.settings['category']
@@ -678,7 +681,7 @@
                         
         return True
 
-    def CopyCats(self, cats, ids):
+    def CopyCats(self, cats, ids, copyAttrb=False):
         """Copy given categories to objects with id listed in ids
 
         @param cats list of cats to be copied
@@ -1093,7 +1096,7 @@
 
         return ret
 
-    def CopyCats(self, fromId, toId):
+    def CopyCats(self, fromId, toId, copyAttrb=False):
         """Copy given categories to objects with id listed in ids
 
         @param cats ids of 'from' feature
@@ -1104,9 +1107,9 @@
         """
         if len(fromId) == 0 or len(toId) == 0:
             return 0
+        
+        ret = self.digit.CopyCats(fromId, toId, copyAttrb)
 
-        ret = self.digit.CopyCats(fromId, toId)
-
         if ret > 0:
             self.toolbar.EnableUndo()
 
@@ -2299,25 +2302,23 @@
         if cats is None:
             if self.__GetCategories(query[0], query[1]) == 0 or not self.line:
                 Debug.msg(3, "VDigitCategoryDialog(): nothing found!")
-                return
         else:
             # self.cats = dict(cats)
             for layer in cats.keys():
                 self.cats[layer] = list(cats[layer]) # TODO: tuple to list
             self.line = line
+            Debug.msg(3, "VDigitCategoryDialog(): line=%d, cats=%s" % \
+                          (self.line, self.cats))
 
         # make copy of cats (used for 'reload')
         self.cats_orig = copy.deepcopy(self.cats)
-
-        Debug.msg(3, "VDigitCategoryDialog(): line=%d, cats=%s" % \
-                      (self.line, self.cats))
-
+        
         wx.Dialog.__init__(self, parent=self.parent, id=wx.ID_ANY, title=title,
                            style=style, pos=pos)
 
         # list of categories
         box = wx.StaticBox(parent=self, id=wx.ID_ANY,
-                           label=" %s " % _("List of categories"))
+                           label=" %s " % _("List of categories - right-click to delete"))
         listSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
         self.list = CategoryListCtrl(parent=self, id=wx.ID_ANY,
                                      style=wx.LC_REPORT |
@@ -2366,9 +2367,11 @@
 
         # buttons
         btnApply = wx.Button(self, wx.ID_APPLY)
+        btnApply.SetToolTipString(_("Apply changes"))
         btnCancel = wx.Button(self, wx.ID_CANCEL)
-        #btnReload = wx.Button(self, wx.ID_UNDO, _("&Reload"))
+        btnCancel.SetToolTipString(_("Ignore changes and close dialog"))
         btnOk = wx.Button(self, wx.ID_OK)
+        btnOk.SetToolTipString(_("Apply changes and close dialog"))
         btnOk.SetDefault()
 
         # sizers
@@ -2534,7 +2537,7 @@
 
         for item in cmdWhat.ReadStdOutput():
             litem = item.lower()
-            if "line:" in litem: # get line id
+            if "id:" in litem: # get line id
                 self.line = int(item.split(':')[1].strip())
             elif "layer:" in litem: # add layer
                 layer = int(item.split(':')[1].strip())

Modified: grass/branches/develbranch_6/gui/wxpython/vdigit/cats.cpp
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/vdigit/cats.cpp	2008-08-30 06:30:10 UTC (rev 33165)
+++ grass/branches/develbranch_6/gui/wxpython/vdigit/cats.cpp	2008-08-30 16:21:13 UTC (rev 33166)
@@ -14,6 +14,10 @@
    \date 2008 
 */
 
+extern "C" {
+#include <grass/dbmi.h>
+}
+
 #include "driver.h"
 #include "digit.h"
 
@@ -238,7 +242,7 @@
     if (line_id == -1) {
 	line = display->selected.values->value[0];
     }
-     
+
     if (!Vect_line_alive(display->mapInfo, line)) {
 	DeadLineMsg(line);
 	return -1;
@@ -272,14 +276,17 @@
     ret = Vect_rewrite_line(display->mapInfo, line, type,
 			    Points, Cats);
 
-    if (ret > 0) {
-	/* updates feature id (id is changed since line has been rewriten) */
-	changesets[changesets.size()-1][0].line = ret;
-    }
-    else {
-	changesets.erase(changesets.size()-1);
-    }
-
+    /* TODO
+       updates feature id (id is changed since line has been rewriten)
+       if (ret > 0) {
+       
+       changesets[changesets.size()-1][0].line = ret;
+       }
+       else {
+       changesets.erase(changesets.size()-1);
+       }
+    */
+    
     if (line_id == -1) {
 	/* update line id since the line was rewritten */
 	display->selected.values->value[0] = ret;
@@ -296,14 +303,15 @@
 
    \param fromId list of 'from' feature ids
    \param toId   list of 'to' feature ids
+   \param copyAttrb duplicate attribures instead of copying categories
 
    \return number of modified features
    \return -1 on error
 */
-int Digit::CopyCats(std::vector<int> fromId, std::vector<int> toId)
+int Digit::CopyCats(std::vector<int> fromId, std::vector<int> toId, bool copyAttrb)
 {
     int fline, tline, nlines, type;
-    bool error;
+    int cat;
     
     struct line_pnts *Points;
     struct line_cats *Cats_from, *Cats_to;
@@ -313,46 +321,158 @@
     Cats_to = Vect_new_cats_struct();
 
     nlines = 0;
-    error = false;
+
     for (std::vector<int>::const_iterator fi = fromId.begin(), fe = fromId.end();
-	 fi != fe && !error; ++fi) {
+	 fi != fe; ++fi) {
+
 	fline = *fi;
 	if (!Vect_line_alive(display->mapInfo, fline))
 	    continue;
 
 	type = Vect_read_line(display->mapInfo, NULL, Cats_from, fline);
 	if (type < 0) {
-	    nlines = -1;
-	    error = true;
+	    ReadLineMsg(fline);
+	    return -1;
 	}
 
 	for(std::vector<int>::const_iterator ti = toId.begin(), te = toId.end();
-	    ti != te && !error; ++ti) {
+	    ti != te; ++ti) {
+
 	    tline = *ti;
 	    if (!Vect_line_alive(display->mapInfo, tline))
 		continue;
+
 	    type = Vect_read_line(display->mapInfo, Points, Cats_to, tline);
 	    if (type < 0) {
-		nlines = -1;
-		error = true;
+		ReadLineMsg(tline);
+		return -1;
 	    }
 
-	    for (int i = 0; Cats_from->n_cats; i++) {
-		if (Vect_cat_set(Cats_to, Cats_from->field[i], Cats_from->field[i]) < 1) {
-		    nlines = -1;
-		    error = true;
+	    for (int i = 0; i < Cats_from->n_cats; i++) {
+		if (!copyAttrb) {
+		    cat = Cats_from->cat[i]; /* duplicate category */
 		}
+		else {
+		    /* duplicate attributes */
+		    struct field_info *fi;
+		    char buf[GSQL_MAX];
+		    dbDriver *driver;
+		    dbHandle handle;
+		    dbCursor cursor;
+		    dbTable *table;
+		    dbColumn *column;
+		    dbValue *value;
+		    dbString stmt, value_string;
+		    int col, ncols;
+		    int more, ctype;
+		    		    
+		    cat = ++cats[Cats_from->field[i]];
+
+		    fi = Vect_get_field(display->mapInfo, Cats_from->field[i]);
+
+		    if (fi == NULL) {
+			DblinkMsg(Cats_from->field[i]);
+			return -1;
+		    }
+		    
+		    driver = db_start_driver(fi->driver);
+		    if (driver == NULL) {
+			DbDriverMsg(fi->driver);
+			return -1;
+		    }
+		    
+		    db_init_handle (&handle);
+		    db_set_handle (&handle, fi->database, NULL);
+		    if (db_open_database(driver, &handle) != DB_OK) {
+			db_shutdown_driver(driver);
+			DbDatabaseMsg(fi->driver, fi->database);
+			return -1;
+		    }
+
+		    db_init_string (&stmt);
+		    sprintf (buf, "SELECT * FROM %s WHERE %s=%d",
+			     fi->table, fi->key, Cats_from->cat[i]);
+		    db_set_string(&stmt, buf);
+
+		    if (db_open_select_cursor(driver, &stmt, &cursor, DB_SEQUENTIAL) != DB_OK) {
+			db_close_database(driver);
+			db_shutdown_driver(driver);
+			DbSelectCursorMsg(db_get_string(&stmt));
+			return -1;
+		    }
+
+
+		    table = db_get_cursor_table(&cursor);
+		    ncols = db_get_table_number_of_columns(table);
+		    
+		    sprintf(buf, "INSERT INTO %s VALUES (", fi->table);
+		    db_set_string(&stmt, buf);
+
+		    /* fetch the data */
+		    while (1) {
+			if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) {
+			    db_close_database(driver);
+			    db_shutdown_driver(driver);
+			    return -1;
+			}
+			if (!more)
+			    break;
+			
+			for (col = 0; col < ncols; col++) {
+			    if (col > 0)
+				db_append_string(&stmt, ",");
+			    
+			    column = db_get_table_column(table, col);
+			    if (strcmp(db_get_column_name(column), fi->key) == 0) {
+				sprintf(buf, "%d", cat);
+				db_append_string(&stmt, buf);
+				continue;
+			    }
+			    
+			    value = db_get_column_value(column);
+			    db_convert_column_value_to_string(column, &value_string);
+			    if (db_test_value_isnull(value))
+				db_append_string(&stmt, "NULL");
+			    else {
+				ctype = db_sqltype_to_Ctype(db_get_column_sqltype(column));
+				if (ctype != DB_C_TYPE_STRING) 
+				    db_append_string(&stmt, db_get_string(&value_string));
+				else {
+				    sprintf(buf, "'%s'", db_get_string(&value_string));
+				    db_append_string(&stmt, buf);
+				}
+			    }
+			}
+		    }
+		    db_append_string(&stmt, ")");
+		    
+		    if (db_execute_immediate (driver, &stmt) != DB_OK ) {
+			db_close_database(driver);
+			db_shutdown_driver(driver);
+			DbExecuteMsg(db_get_string(&stmt));
+			return -1;
+		    }
+		    
+		    db_close_database(driver);
+		    db_shutdown_driver(driver);
+		}
+		
+		if (Vect_cat_set(Cats_to, Cats_from->field[i], cat) < 1) {
+		    continue;
+		}
 	    }
 	    
 	    if (Vect_rewrite_line(display->mapInfo, tline, type, Points, Cats_to) < 0) {
-		nlines = -1;
-		error = true;
+		WriteLineMsg();
+		return -1;
 	    }
-		
+	
+	    G_debug(1, "Digit::CopyCats(): fline=%d, tline=%d", fline, tline);
+	    
 	    nlines++;
 	}
     }
-
+    
     Vect_destroy_line_struct(Points);
     Vect_destroy_cats_struct(Cats_from);
     Vect_destroy_cats_struct(Cats_to);

Modified: grass/branches/develbranch_6/gui/wxpython/vdigit/digit.h
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/vdigit/digit.h	2008-08-30 06:30:10 UTC (rev 33165)
+++ grass/branches/develbranch_6/gui/wxpython/vdigit/digit.h	2008-08-30 16:21:13 UTC (rev 33166)
@@ -55,6 +55,7 @@
     void DbDriverMsg(const char *);
     void DbDatabaseMsg(const char *, const char *);
     void DbExecuteMsg(const char *);
+    void DbSelectCursorMsg(const char *);
     void GetLineCatsMsg(int);
 
 public:
@@ -94,7 +95,7 @@
 					double, double, double, bool,
 					int, int, double);
 
-    int CopyCats(std::vector<int>, std::vector<int>);
+    int CopyCats(std::vector<int>, std::vector<int>, bool);
     int GetCategory(int);
     std::map<int, std::vector<int> > GetLineCats(int);
     int SetLineCats(int, int, std::vector<int>, bool);

Modified: grass/branches/develbranch_6/gui/wxpython/vdigit/message.cpp
===================================================================
--- grass/branches/develbranch_6/gui/wxpython/vdigit/message.cpp	2008-08-30 06:30:10 UTC (rev 33165)
+++ grass/branches/develbranch_6/gui/wxpython/vdigit/message.cpp	2008-08-30 16:21:13 UTC (rev 33166)
@@ -127,7 +127,8 @@
 void Digit::DbDriverMsg(const char *driver)
 {
     wxString msg;
-    msg.Printf(_("Unable to start driver <%s>"), driver);
+    msg.Printf(_("Unable to start driver <%s>"),
+	       wxString(driver, wxConvUTF8).c_str());
     wxMessageDialog dlg(parentWin, msg,
 			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
     dlg.ShowModal();
@@ -145,7 +146,8 @@
 {
     wxString msg;
     msg.Printf(_("Unable to open database <%s> by driver <%s>"),
-	       database, driver);
+	       wxString(database, wxConvUTF8).c_str(),
+	       wxString(driver, wxConvUTF8).c_str());
     wxMessageDialog dlg(parentWin, msg,
 			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
     dlg.ShowModal();
@@ -161,7 +163,8 @@
 void Digit::DbExecuteMsg(const char *sql)
 {
     wxString msg;
-    msg.Printf(_("Unable to execute: '%s'"), sql);
+    msg.Printf(_("Unable to execute: '%s'"),
+	       wxString(sql, wxConvUTF8).c_str());
     wxMessageDialog dlg(parentWin, msg,
 			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
     dlg.ShowModal();
@@ -169,15 +172,32 @@
     return;
 }
 
-	wxString msg;
 /**
+   \brief Error message - unable to open select cursor
+
+   \param sql sql command
+*/
+void Digit::DbSelectCursorMsg(const char *sql)
+{
+    wxString msg;
+    msg.Printf(_("Unable to open select cursor: '%s'"),
+	       wxString(sql, wxConvUTF8).c_str());
+    wxMessageDialog dlg(parentWin, msg,
+			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
+    dlg.ShowModal();
+    
+    return;
+}
+
+/**
    \brief Error message - unable to get line categories
 
    \param line line id
 */
 void Digit::GetLineCatsMsg(int line)
 {
-    msg.Printf(_("Unable to get feature categories"), line);
+    wxString msg;
+    msg.Printf(_("Unable to get feature (%d) categories"), line);
     wxMessageDialog dlg(parentWin, msg,
 			msgCaption, wxOK | wxICON_ERROR | wxCENTRE);
     dlg.ShowModal();



More information about the grass-commit mailing list