[rkward-cvs] SF.net SVN: rkward: [1915] trunk/rkward/rkward

tfry at users.sourceforge.net tfry at users.sourceforge.net
Sun May 20 13:05:31 UTC 2007


Revision: 1915
          http://svn.sourceforge.net/rkward/?rev=1915&view=rev
Author:   tfry
Date:     2007-05-20 06:05:30 -0700 (Sun, 20 May 2007)

Log Message:
-----------
Further fixes to inserting/deleting rows in the presence of invalid fields

Modified Paths:
--------------
    trunk/rkward/rkward/core/rkvariable.cpp
    trunk/rkward/rkward/core/rkvariable.h
    trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R

Modified: trunk/rkward/rkward/core/rkvariable.cpp
===================================================================
--- trunk/rkward/rkward/core/rkvariable.cpp	2007-05-18 13:58:16 UTC (rev 1914)
+++ trunk/rkward/rkward/core/rkvariable.cpp	2007-05-20 13:05:30 UTC (rev 1915)
@@ -510,7 +510,7 @@
 	RK_ASSERT (row < getLength ());
 
 	if (myData ()->cell_states[row] & RKVarEditData::Invalid) {
-		myData ()->cell_states[row] = RKVarEditData::UnsyncedInvalidState;
+		myData ()->cell_states[row] = RKVarEditData::Invalid | RKVarEditData::UnsyncedInvalidState;
 		myData ()->invalid_fields.remove (row);
 	} else {
 		myData ()->cell_states[row] = 0;
@@ -589,7 +589,7 @@
 	} else if (getDataType () == DataFactor) {
 		int i = 0;
 		for (int row=from_row; row <= to_row; ++row) {
-			if (myData ()->cell_states[row] & RKVarEditData::Invalid) myData ()->cell_states[row] = RKVarEditData::UnsyncedInvalidState;
+			if (myData ()->cell_states[row] & RKVarEditData::Invalid) myData ()->cell_states[row] = RKVarEditData::Invalid | RKVarEditData::UnsyncedInvalidState;
 			else myData ()->cell_states[row] = 0;
 
 			if (isnan (data[i]) || (!myData ()->value_labels) || (!myData ()->value_labels->contains (QString::number (data[i])))) {
@@ -603,7 +603,7 @@
 	} else {
 		int i = 0;
 		for (int row=from_row; row <= to_row; ++row) {
-			if (myData ()->cell_states[row] & RKVarEditData::Invalid) myData ()->cell_states[row] = RKVarEditData::UnsyncedInvalidState;
+			if (myData ()->cell_states[row] & RKVarEditData::Invalid) myData ()->cell_states[row] = RKVarEditData::Invalid | RKVarEditData::UnsyncedInvalidState;
 			else myData ()->cell_states[row] = 0;
 
 			if (isnan (data[i])) {
@@ -644,7 +644,7 @@
 	if (getDataType () == DataCharacter) {
 		int i=0;
 		for (int row=from_row; row <= to_row; ++row) {
-			if (myData ()->cell_states[row] & RKVarEditData::Invalid) myData ()->cell_states[row] = RKVarEditData::UnsyncedInvalidState;
+			if (myData ()->cell_states[row] & RKVarEditData::Invalid) myData ()->cell_states[row] = RKVarEditData::Invalid | RKVarEditData::UnsyncedInvalidState;
 			else myData ()->cell_states[row] = 0;
 
 			if (data[i].isNull ()) myData ()->cell_states[row] |= RKVarEditData::NA;
@@ -688,18 +688,24 @@
 
 void RKVariable::removeRows (int from_row, int to_row) {
 	RK_TRACE (OBJECTS);
+	QValueList<int> *changed_invalids = 0;
 	int offset = (to_row - from_row) + 1;
-	for (int row = from_row; row <= to_row; ++row) {
-		myData ()->invalid_fields.remove (row);
-	}
 
-	if (to_row < (myData ()->allocated_length - 1)) {	// not the last rows
-		for (int row = to_row; row < getLength (); ++row) {
-			QString *dummy = myData ()->invalid_fields.take (row);
-			if (dummy) {
+	for (int row = from_row; row < getLength (); ++row) {
+		QString *dummy = myData ()->invalid_fields.take (row);
+		if (dummy) {
+			if (!changed_invalids) changed_invalids = new QValueList<int>;
+			changed_invalids->append (row);
+			if (row > to_row) {
+				changed_invalids->append (row - offset);
 				myData ()->invalid_fields.replace (row - offset, dummy);
+			} else {
+				delete dummy;
 			}
 		}
+	}
+
+	if (to_row < (myData ()->allocated_length - 1)) {	// not the last rows
 		if (myData ()->cell_strings) {
 			qmemmove (&(myData ()->cell_strings[from_row]), &(myData ()->cell_strings[to_row+1]), (myData ()->allocated_length - to_row - 1) * sizeof (QString));
 		} else {
@@ -709,9 +715,16 @@
 	}
 
 	for (int row = (myData ()->allocated_length - offset); row < myData ()->allocated_length; ++row) {
-		myData ()->cell_states[myData ()->allocated_length - 1] = RKVarEditData::Unknown;
+		myData ()->cell_states[row] = RKVarEditData::Unknown;
 	}
 
+	if (changed_invalids) {
+		for (QValueList<int>::const_iterator it = changed_invalids->constBegin (); it != changed_invalids->constEnd (); ++it) {
+			writeInvalidField (*it, 0);
+		}
+		delete changed_invalids;
+	}
+
 	dimensions[0] -= offset;	
 	downSize ();
 }
@@ -724,23 +737,28 @@
 void RKVariable::insertRows (int row, int count) {
 	RK_TRACE (OBJECTS);
 	int old_len = getLength ();
-	extendToLength (getLength () + count);		// getLength is the new length after this
+	extendToLength (getLength () + count);		// getLength is the new length after this!
 
-	for (int i=old_len; i <= row+count; ++i) {
+	for (int i=old_len; i < getLength(); ++i) {
 		myData ()->cell_states[i] = RKVarEditData::NA;
 	}
 
+	QValueList<int> *changed_invalids = 0;
+	for (int i = getLength () - count - 1; i >= row; --i) {
+		QString *dummy = myData ()->invalid_fields.take (i);
+		if (dummy) {
+			if (!changed_invalids) changed_invalids = new QValueList<int>;
+			changed_invalids->append (i);
+			changed_invalids->append (i + count);
+			myData ()->invalid_fields.replace (i + count, dummy);
+		}
+	}
+
 	if (row >= getLength () && (count == 1)) {		// important special case
-		if (myData ()->cell_strings) myData ()->cell_strings[row+count] = myData ()->cell_strings[row];
-		if (myData ()->cell_doubles) myData ()->cell_doubles[row+count] = myData ()->cell_doubles[row];
-		myData ()->cell_states[row+count] = myData ()->cell_states[row];
+		if (myData ()->cell_strings) myData ()->cell_strings[row+count] = QString::null;
+		if (myData ()->cell_doubles) myData ()->cell_doubles[row+count] = 0.0;
+		myData ()->cell_states[row+count] = RKVarEditData::NA;
 	} else {
-		for (int i=getLength () - count; i >= row; --i) {
-			QString *dummy = myData ()->invalid_fields.take (i);
-			if (dummy) {
-				myData ()->invalid_fields.replace (i + count, dummy);
-			}
-		}
 		if (myData ()->cell_strings) qmemmove (&(myData ()->cell_strings[row+count]), &(myData ()->cell_strings[row]), (myData ()->allocated_length - (row + count) - 1) * sizeof (QString));
 		if (myData ()->cell_doubles) qmemmove (&(myData ()->cell_doubles[row+count]), &(myData ()->cell_doubles[row]), (myData ()->allocated_length - (row + count) - 1) * sizeof (double));
 		qmemmove (&(myData ()->cell_states[row+count]), &(myData ()->cell_states[row]), (myData ()->allocated_length - (row + count) - 1) * sizeof (int));
@@ -749,6 +767,13 @@
 	for (int i=row+count-1; i >= row; --i) {
 		myData ()->cell_states[i] = RKVarEditData::NA;
 	}
+
+	if (changed_invalids) {
+		for (QValueList<int>::const_iterator it = changed_invalids->constBegin (); it != changed_invalids->constEnd (); ++it) {
+			writeInvalidField (*it, 0);
+		}
+		delete changed_invalids;
+	}
 }
 
 RObject::ValueLabels *RKVariable::getValueLabels () {

Modified: trunk/rkward/rkward/core/rkvariable.h
===================================================================
--- trunk/rkward/rkward/core/rkvariable.h	2007-05-18 13:58:16 UTC (rev 1914)
+++ trunk/rkward/rkward/core/rkvariable.h	2007-05-20 13:05:30 UTC (rev 1915)
@@ -88,9 +88,9 @@
 	void removeRow (int row);
 /** see removeRow (), but removes a range of rows (i.e. cells). Since data only needs to be copied once, this is more efficient than several single calls to removeRow (). Does not sync with the backend for technical reasons! You have to remove the row in the backend explicitly. */
 	void removeRows (int from_row, int to_row);
-/** inserts a row/cell (with empty value) just above the given index. Does not sync with the backend for technical reasons! You have to remove the row in the backend explicitly. */
+/** inserts a row/cell (with empty value) just above the given index. Does not sync with the backend for technical reasons! You have to insert the row in the backend explicitly. */
 	void insertRow (int row);
-/** like insertRow (), but inserts count rows. Does not sync with the backend for technical reasons! You have to remove the row in the backend explicitly. */
+/** like insertRow (), but inserts count rows. Does not sync with the backend for technical reasons! You have to insert the row in the backend explicitly. */
 	void insertRows (int row, int count);
 /** Tells the object it has (data) length len. Usually this will only be called directly after creating a new object */
 	void setLength (int len);

Modified: trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R
===================================================================
--- trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R	2007-05-18 13:58:16 UTC (rev 1914)
+++ trunk/rkward/rkward/rbackend/rpackages/rkward/R/internal.R	2007-05-20 13:05:30 UTC (rev 1915)
@@ -30,12 +30,12 @@
 ".rk.data.frame.delete.row" <- function (x, index) {
 	attriblist <- list ()
 	for (i in 1:dim (x)[2]) {
-		attriblist[[names (x)[i]]] <- attr (x[[i]], ".rk.meta")
+		attriblist[[names (x)[i]]] <- attributes (x[[i]])
 	}
 	eval (substitute (x <<- x[-index,]))
 	eval (substitute (row.names (x) <<- c (1:dim(x)[1])))
 	for (i in 1:dim (x)[2]) {
-		eval (substitute (attr (x[[i]], ".rk.meta") <<- attriblist[[names (x)[i]]]))
+		eval (substitute (attributes (x[[i]]) <<- attriblist[[names (x)[i]]]))
 	}
 }
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the rkward-tracker mailing list