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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Wed Feb 9 11:02:03 UTC 2011


Revision: 3431
          http://rkward.svn.sourceforge.net/rkward/?rev=3431&view=rev
Author:   tfry
Date:     2011-02-09 11:02:03 +0000 (Wed, 09 Feb 2011)

Log Message:
-----------
Fix several problems when rows are added to / removed from an edited data.frame from outside the editor.

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/rkward/core/rcontainerobject.cpp
    trunk/rkward/rkward/core/rkmodificationtracker.cpp
    trunk/rkward/rkward/core/rkmodificationtracker.h
    trunk/rkward/rkward/core/rkvariable.cpp
    trunk/rkward/rkward/core/rkvariable.h
    trunk/rkward/rkward/core/robject.cpp
    trunk/rkward/rkward/core/robject.h
    trunk/rkward/rkward/dataeditor/rkvareditmodel.cpp
    trunk/rkward/rkward/dataeditor/rkvareditmodel.h
    trunk/rkward/rkward/windows/rkworkplace.cpp

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/ChangeLog	2011-02-09 11:02:03 UTC (rev 3431)
@@ -1,4 +1,5 @@
 --- Version 0.5.5 - XXX-XX-2011
+- Fixed: Potential crashes when changing length of a data.frame that is currently opened for editing from R code
 - All pages in the package installation dialog now support sorting and keyboard search
 - Fixed: Converting from factor to string in the data editor set values to numeric, internally
 - Allow entering factor labels instead of only numbers, when editing factors in the data editor

Modified: trunk/rkward/rkward/core/rcontainerobject.cpp
===================================================================
--- trunk/rkward/rkward/core/rcontainerobject.cpp	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/core/rcontainerobject.cpp	2011-02-09 11:02:03 UTC (rev 3431)
@@ -265,6 +265,7 @@
 
 	int childlen = 0;
 	if (!childmap.isEmpty ()) childlen = childmap[0]->getLength ();
+	rownames_object->extendToLength (childlen);	// in case it is being edited
 	rownames_object->dimensions[0] = childlen;
 
 	if (rownames_object->isType (NeedDataUpdate)) {

Modified: trunk/rkward/rkward/core/rkmodificationtracker.cpp
===================================================================
--- trunk/rkward/rkward/core/rkmodificationtracker.cpp	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/core/rkmodificationtracker.cpp	2011-02-09 11:02:03 UTC (rev 3431)
@@ -225,10 +225,10 @@
 	}
 }
 
-RKEditor* RKModificationTracker::objectEditor (RObject* object) {
+RKEditor* RKModificationTracker::objectEditor (const RObject* object) {
 	RK_TRACE (OBJECTS);
 
-	QList<RObjectListener*> obj_listeners = listeners.values (object);
+	QList<RObjectListener*> obj_listeners = listeners.values (const_cast<RObject*> (object));
 	for (int i = obj_listeners.size () - 1; i >= 0; --i) {
 		RObjectListener* listener = obj_listeners[i];
 		if (!(listener->listenerType () == RObjectListener::DataModel)) continue;

Modified: trunk/rkward/rkward/core/rkmodificationtracker.h
===================================================================
--- trunk/rkward/rkward/core/rkmodificationtracker.h	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/core/rkmodificationtracker.h	2011-02-09 11:02:03 UTC (rev 3431)
@@ -125,7 +125,7 @@
 /** recursive! */
 	void lockUpdates (bool lock);
 /** returns (the first) editor that is currently active for this object, or 0, if there is no editor */
-	RKEditor* objectEditor (RObject* object);
+	RKEditor* objectEditor (const RObject* object);
 private:
 	int updates_locked;
 /** relay change notifications to connected listeners. This is not pretty, since the arguments change their meanings depending on the type of notification, but for now this is ok */

Modified: trunk/rkward/rkward/core/rkvariable.cpp
===================================================================
--- trunk/rkward/rkward/core/rkvariable.cpp	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/core/rkvariable.cpp	2011-02-09 11:02:03 UTC (rev 3431)
@@ -157,8 +157,8 @@
 			QVector<double> dd;
 			dd.reserve (len);
 			for (unsigned int i = 0; i < len; ++i) {
-				if (RInterface::isNaInt (cdata->getIntVector ()[i])) dd[i] = NAN;
-				else dd[i] = (double) cdata->getIntVector ()[i];
+				if (RInterface::isNaInt (cdata->getIntVector ()[i])) dd.append (NAN);
+				else dd.append ((double) cdata->getIntVector ()[i]);
 			}
 			setNumericFromR (0, getLength () - 1, dd);
 		}
@@ -384,6 +384,7 @@
 }
 
 void RKVariable::extendToLength (int length) {
+	if (!data) return;
 	RK_TRACE (OBJECTS);
 
 	if (length <= 0) length = 0;

Modified: trunk/rkward/rkward/core/rkvariable.h
===================================================================
--- trunk/rkward/rkward/core/rkvariable.h	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/core/rkvariable.h	2011-02-09 11:02:03 UTC (rev 3431)
@@ -121,6 +121,8 @@
 	static FormattingOptions parseFormattingOptionsString (const QString &string);
 /** inverse of parseFormattingOptionsString () */
 	static QString formattingOptionsToString (const FormattingOptions& options);
+/** changes the allocated storage to contain a least length elements. More data may be allocated than acutally needed. This function only ever does upsizing. */
+	void extendToLength (int length);
 protected:
 /** Discards pending unsynced changes. */
 	void discardUnsyncedChanges ();
@@ -165,8 +167,6 @@
 /** reimplemented from RObject */
 	void endEdit ();
 
-/** changes the allocated storage to contain a least length elements. More data may be allocated than acutally needed. This function only ever does upsizing. */
-	void extendToLength (int length);
 /** takes care of syncing the given range of cells */
 	void cellsChanged (int from_row, int to_row);
 /** writes the given range of cells to the backend (regardless of whether syncing should be immediate) */

Modified: trunk/rkward/rkward/core/robject.cpp
===================================================================
--- trunk/rkward/rkward/core/robject.cpp	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/core/robject.cpp	2011-02-09 11:02:03 UTC (rev 3431)
@@ -440,16 +440,23 @@
 		if (new_dimensions.isEmpty ()) {
 			if (dimensions != RObjectPrivate::dim_null) {
 				dimensions = RObjectPrivate::dim_null;
-				return true;
+				return (true);
 			}
 		} else {
+#warning TODO: ugly hack. Should be moved to RKVariable, somehow.
+			if (type & Variable) static_cast<RKVariable*> (this)->extendToLength (new_dimensions[0]);
+
 			dimensions = new_dimensions;
-			return true;
+			return (true);
 		}
 	}
-	return false;
+	return (false);
 }
 
+RKEditor *RObject::editor () const {
+	return (RKGlobals::tracker ()->objectEditor (this));
+}
+
 void RObject::rename (const QString &new_short_name) {
 	RK_TRACE (OBJECTS);
 	parent->renameChild (this, new_short_name);

Modified: trunk/rkward/rkward/core/robject.h
===================================================================
--- trunk/rkward/rkward/core/robject.h	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/core/robject.h	2011-02-09 11:02:03 UTC (rev 3431)
@@ -109,6 +109,8 @@
 /** mark the data of this object and all of its children as dirty (recursively). Dirty data will be updated *after* the new structure update (if the object is opened for editing) */
 	void markDataDirty ();
 
+/** Returns the editor of this object, if any, or 0 */
+	RKEditor* editor () const;
 	bool canEdit () const;
 	bool canRead () const;
 	bool canRename () const;

Modified: trunk/rkward/rkward/dataeditor/rkvareditmodel.cpp
===================================================================
--- trunk/rkward/rkward/dataeditor/rkvareditmodel.cpp	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/dataeditor/rkvareditmodel.cpp	2011-02-09 11:02:03 UTC (rev 3431)
@@ -2,7 +2,7 @@
                           rkvareditmodel  -  description
                              -------------------
     begin                : Mon Nov 05 2007
-    copyright            : (C) 2007, 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2007, 2010, 2011 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -40,6 +40,7 @@
 	rownames = 0;
 	header_locked = false;
 	duplicate_check_triggered = false;
+	reset_scheduled = false;
 
 	addNotificationType (RObjectListener::ObjectRemoved);
 	addNotificationType (RObjectListener::MetaChanged);
@@ -133,10 +134,29 @@
 	int cindex = objects.indexOf (static_cast<RKVariable*> (changed));	// no check for isVariable needed. we only need to look up, if we have this object, and where.
 	if (cindex < 0) return;	// none of our buisiness
 
-	emit (dataChanged (index (0, cindex), index (trueRows (), cindex)));
 	if (meta_model) meta_model->objectMetaChanged (cindex);
+
+	if (!reset_scheduled) {
+		reset_scheduled = true;
+		QTimer::singleShot (0, this, SLOT (doResetNow()));
+#if QT_VERSION >= 0x040600
+		beginResetModel ();
+#endif
+	}
 }
 
+void RKVarEditModel::doResetNow () {
+	RK_TRACE (EDITOR);
+	RK_ASSERT (reset_scheduled);
+
+	reset_scheduled = false;
+#if QT_VERSION >= 0x040600
+	endResetModel ();
+#else
+	reset ();
+#endif
+}
+
 void RKVarEditModel::objectDataChanged (RObject* object, const RObject::ChangeSet *changes) {
 	RK_TRACE (EDITOR);
 

Modified: trunk/rkward/rkward/dataeditor/rkvareditmodel.h
===================================================================
--- trunk/rkward/rkward/dataeditor/rkvareditmodel.h	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/dataeditor/rkvareditmodel.h	2011-02-09 11:02:03 UTC (rev 3431)
@@ -2,7 +2,7 @@
                           rkvareditmodel  -  description
                              -------------------
     begin                : Mon Nov 05 2007
-    copyright            : (C) 2007, 2010 by Thomas Friedrichsmeier
+    copyright            : (C) 2007, 2010, 2011 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -97,6 +97,9 @@
 	void hasDuplicates (const QStringList& dupes);
 private slots:
 	void checkDuplicatesNow ();
+	void doResetNow ();
+private:
+	bool reset_scheduled;
 protected:
 friend class RKVarEditMetaModel;
 	QList<RKVariable*> objects;

Modified: trunk/rkward/rkward/windows/rkworkplace.cpp
===================================================================
--- trunk/rkward/rkward/windows/rkworkplace.cpp	2011-02-09 10:55:16 UTC (rev 3430)
+++ trunk/rkward/rkward/windows/rkworkplace.cpp	2011-02-09 11:02:03 UTC (rev 3431)
@@ -327,10 +327,11 @@
 
 RKEditor *RKWorkplace::editObject (RObject *object) {
 	RK_TRACE (APP);
+	RK_ASSERT (object);
 
 	RObject *iobj = object;
 	RKEditor *ed = 0;
-	RKEditor *existing_editor = RKGlobals::tracker ()->objectEditor (object);
+	RKEditor *existing_editor = object->editor ();
 	if (!existing_editor) {
 		if (!iobj->isDataFrame ()) {
 			if (iobj->isVariable () && iobj->getContainer ()->isDataFrame ()) {


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