[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