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

tfry at users.sourceforge.net tfry at users.sourceforge.net
Wed Sep 20 14:20:49 UTC 2006


Revision: 748
          http://svn.sourceforge.net/rkward/?rev=748&view=rev
Author:   tfry
Date:     2006-09-20 07:20:27 -0700 (Wed, 20 Sep 2006)

Log Message:
-----------
Make all string passing UTF-8 aware
Most importantly, RCommand and RKVariable operate on QStrings instead of char*s
Add -DQT_NO_ASCII_CAST globally, to avoid base conversions
Many small adjustments needed all over the place

Modified Paths:
--------------
    trunk/rkward/configure
    trunk/rkward/configure.in
    trunk/rkward/configure.in.in
    trunk/rkward/rkward/core/rcontainerobject.cpp
    trunk/rkward/rkward/core/rcontainerobject.h
    trunk/rkward/rkward/core/rkvariable.cpp
    trunk/rkward/rkward/core/rkvariable.h
    trunk/rkward/rkward/core/robjectlist.cpp
    trunk/rkward/rkward/dataeditor/rkeditordataframe.cpp
    trunk/rkward/rkward/debug.h
    trunk/rkward/rkward/main.cpp
    trunk/rkward/rkward/plugin/rkcomponentmap.cpp
    trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
    trunk/rkward/rkward/rbackend/rcommand.cpp
    trunk/rkward/rkward/rbackend/rcommand.h
    trunk/rkward/rkward/rbackend/rembedinternal.cpp
    trunk/rkward/rkward/rbackend/rembedinternal.h
    trunk/rkward/rkward/rbackend/rthread.cpp
    trunk/rkward/rkward/rbackend/rthread.h
    trunk/rkward/rkward/rkconsole.cpp
    trunk/rkward/rkward/rkglobals.cpp
    trunk/rkward/rkward/rkglobals.h

Modified: trunk/rkward/configure
===================================================================
--- trunk/rkward/configure	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/configure	2006-09-20 14:20:27 UTC (rev 748)
@@ -35692,8 +35692,10 @@
 
 
 
+CPPFLAGS+=" -DQT_NO_ASCII_CAST"
 
 
+
 DO_NOT_COMPILE="$DO_NOT_COMPILE CVS bsd-port admin"
 TOPSUBDIRS=""
 

Modified: trunk/rkward/configure.in
===================================================================
--- trunk/rkward/configure.in	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/configure.in	2006-09-20 14:20:27 UTC (rev 748)
@@ -74,6 +74,9 @@
 dnl KDE_NEED_FLEX dnl __kdevelop__
 dnl AC_PROG_YACC dnl __kdevelop__
 
+dnl set QT_NO_ASCII_CAST globally
+CPPFLAGS+=" -DQT_NO_ASCII_CAST"
+
 KDE_CREATE_SUBDIRSLIST
 AC_CONFIG_FILES([ Makefile ])
 AC_CONFIG_FILES([ doc/Makefile ])

Modified: trunk/rkward/configure.in.in
===================================================================
--- trunk/rkward/configure.in.in	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/configure.in.in	2006-09-20 14:20:27 UTC (rev 748)
@@ -9,3 +9,6 @@
 dnl KDE_NEED_FLEX dnl __kdevelop__
 dnl AC_PROG_YACC dnl __kdevelop__
 
+dnl set QT_NO_ASCII_CAST globally
+CPPFLAGS+=" -DQT_NO_ASCII_CAST"
+

Modified: trunk/rkward/rkward/core/rcontainerobject.cpp
===================================================================
--- trunk/rkward/rkward/core/rcontainerobject.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/core/rcontainerobject.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -88,7 +88,7 @@
 			parent->childUpdateComplete ();
 		}
 		for (int i = 0; i < command->stringVectorLength (); ++i) {
-			QString cname = command->getStringVector ()[i];
+			QString cname = command->getStringVector ()[i]; 	// for easier typing
 			if (childmap.find (cname) != childmap.end ()) {
 				RK_DO (qDebug ("updating existing child: %s", cname.latin1 ()), APP, DL_DEBUG);
 				childmap[cname]->updateFromR ();
@@ -228,15 +228,15 @@
 	return false;
 }
 
-void RContainerObject::checkRemovedChildren (char **current_children, int current_child_count) {
+void RContainerObject::checkRemovedChildren (QString *current_children, int child_count) {
 	RK_TRACE (OBJECTS);
 	QValueList<RObject*> removed_list;
-	
-// is there a more efficient algorythm for doing this?
+
+// is there a more efficient algorithm for doing this?
 	for (RObjectMap::iterator it = childmap.begin (); it != childmap.end (); ++it) {
 		QString child_string = it.key ();
 		bool found = false;
-		for (int i=0; i < current_child_count; ++i) {
+		for (int i = 0; i < child_count; ++i) {
 			if (child_string == current_children[i]) {
 				found = true;
 				break;

Modified: trunk/rkward/rkward/core/rcontainerobject.h
===================================================================
--- trunk/rkward/rkward/core/rcontainerobject.h	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/core/rcontainerobject.h	2006-09-20 14:20:27 UTC (rev 748)
@@ -69,7 +69,7 @@
 	virtual void removeChild (RObject *object, bool removed_in_workspace);
 /** given the current list of children (as returned by the "names"-command or similar in derived classes) find out, which children have been removed,
 and takes the appropriate measures */
-	void checkRemovedChildren (char **current_children, int current_child_count);
+	void checkRemovedChildren (QString *current_children, int child_count);
 
 	int num_dimensions;
 	int *dimension;

Modified: trunk/rkward/rkward/core/rkvariable.cpp
===================================================================
--- trunk/rkward/rkward/core/rkvariable.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/core/rkvariable.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -160,8 +160,6 @@
 		} else if (command->stringVectorLength ()) {
 			RK_ASSERT (command->stringVectorLength () == getLength ());
 			setCharacter (0, command->stringVectorLength () - 1, command->getStringVector ());
-			delete command->getStringVector ();
-			command->detachStringVector ();
 		} else {
 			RK_ASSERT (false);
 		}
@@ -219,7 +217,7 @@
 void RKVariable::deleteStringData (int row) {
 	RK_ASSERT (myData ());
 
-	if (myData ()->cell_string_data[row] && (myData ()->cell_string_data[row] != RKGlobals::empty_char) && (myData ()->cell_string_data[row] != RKGlobals::unknown_char)) {
+	if (myData ()->cell_string_data[row] && (myData ()->cell_string_data[row] != RKGlobals::na_char) && (myData ()->cell_string_data[row] != RKGlobals::unknown_char)) {
 		delete myData ()->cell_string_data[row];
 		if (getVarType () != String) {
 			myData ()->invalid_count--;
@@ -256,7 +254,7 @@
 	
 	if (to_empty) {
 		for (int row=0; row < getLength (); ++row) {
-			myData ()->cell_string_data[row] = RKGlobals::empty_char;
+			myData ()->cell_string_data[row] = RKGlobals::na_char;
 			myData ()->cell_double_data[row] = RKGlobals::na_double;
 		}
 	} else {
@@ -390,11 +388,11 @@
 	}
 	RK_DO (qDebug ("resizing from %d to %d", myData ()->allocated_length, target), OBJECTS, DL_DEBUG);
 
-	char **new_string_data = new char*[target];
+	QString **new_string_data = new QString*[target];
 	double *new_double_data = new double[target];
 	
 	if (myData ()->cell_string_data) {		// not starting from 0
-		qmemmove (new_string_data, myData ()->cell_string_data, myData ()->allocated_length * sizeof (char*));
+		qmemmove (new_string_data, myData ()->cell_string_data, myData ()->allocated_length * sizeof (QString*));
 		qmemmove (new_double_data, myData ()->cell_double_data, myData ()->allocated_length * sizeof (double));
 	
 		delete [] (myData ()->cell_string_data);
@@ -429,13 +427,13 @@
 QString RKVariable::getText (int row) {
 	if (row >= getLength ()) {
 		RK_ASSERT (false);
-		return RKGlobals::unknown_char;
+		return (*RKGlobals::unknown_char);
 	}
 	if (getVarType () == String) {
-		return QString::fromLocal8Bit (myData ()->cell_string_data[row]);
+		return (*(myData ()->cell_string_data[row]));
 	} else {
 		if (myData ()->cell_string_data[row] != 0) {
-			return QString::fromLocal8Bit (myData ()->cell_string_data[row]);
+			return (*(myData ()->cell_string_data[row]));
 		} else {
 			return QString::number (myData ()->cell_double_data[row], 'g', MAX_PRECISION);
 		}
@@ -460,49 +458,36 @@
 
 void RKVariable::setText (int row, const QString &text) {
 	RK_TRACE (OBJECTS);
-	char *temp = qstrdup (text.local8Bit ());
-	setTextPlain (row, temp);
-	delete temp;
-}
-
-void RKVariable::setTextPlain (int row, char *text) {
-	RK_TRACE (OBJECTS);
 	RK_ASSERT (row < getLength ());
 	// delete previous string data, unless it's a special value
 	deleteStringData (row);
 
 	if (getVarType () == String) {
-		if (text[0] == '\0') {
-			myData ()->cell_string_data[row] = RKGlobals::empty_char;
-		} else if (text == RKGlobals::empty_char) {
-			myData ()->cell_string_data[row] = RKGlobals::empty_char;
+		if (text.isNull ()) {
+			myData ()->cell_string_data[row] = RKGlobals::na_char;
 		} else {
-			myData ()->cell_string_data[row] = qstrdup (text);
+			myData ()->cell_string_data[row] = new QString (text);
 		}
 	} else if (getVarType () == Factor) {
-		if (text[0] == '\0') {
-			myData ()->cell_string_data[row] = RKGlobals::empty_char;
-		} else if (text == RKGlobals::empty_char) {
-			myData ()->cell_string_data[row] = RKGlobals::empty_char;
+		if (text.isNull ()) {
+			myData ()->cell_string_data[row] = RKGlobals::na_char;
 		} else if (myData ()->value_labels && myData ()->value_labels->contains (text)) {
-			myData ()->cell_double_data[row] = QCString (text).toInt ();
+			myData ()->cell_double_data[row] = text.toInt ();
 		} else {
 			myData ()->invalid_count++;
 			myData ()->previously_valid = false;
-			myData ()->cell_string_data[row] = qstrdup (text);
+			myData ()->cell_string_data[row] = new QString (text);
 		}
 	} else {
 		bool ok;
-		myData ()->cell_double_data[row] = QCString (text).toDouble (&ok);
+		myData ()->cell_double_data[row] = text.toDouble (&ok);
 		if (!ok) {
-			if (text[0] == '\0') {
-				myData ()->cell_string_data[row] = RKGlobals::empty_char;
-			} else if (text == RKGlobals::empty_char) {
-				myData ()->cell_string_data[row] = RKGlobals::empty_char;
+			if (text.isNull ()) {
+				myData ()->cell_string_data[row] = RKGlobals::na_char;
 			} else {
 				myData ()->invalid_count++;
 				myData ()->previously_valid = false;
-				myData ()->cell_string_data[row] = qstrdup (text);
+				myData ()->cell_string_data[row] = new QString (text);
 			}
 		}
 	}
@@ -513,7 +498,7 @@
 QString RKVariable::getFormatted (int row) {
 	if (row >= getLength ()) {
 		RK_ASSERT (false);
-		return RKGlobals::unknown_char;
+		return (*RKGlobals::unknown_char);
 	}
 
 	if (myData ()->value_labels) {
@@ -523,10 +508,10 @@
 	}
 
 	if (getVarType () == String) {
-		return QString::fromLocal8Bit (myData ()->cell_string_data[row]);
+		return (*(myData ()->cell_string_data[row]));
 	} else {
 		if (myData ()->cell_string_data[row] != 0) {
-			return QString::fromLocal8Bit (myData ()->cell_string_data[row]);
+			return (*(myData ()->cell_string_data[row]));
 		} else {
 			if (myData ()->formatting_options && (myData ()->formatting_options->precision_mode != FormattingOptions::PrecisionDefault)) {
 				if (myData ()->formatting_options->precision_mode == FormattingOptions::PrecisionRequired) {
@@ -578,40 +563,39 @@
 		RK_ASSERT (false);		// asserting false to catch cases of this use for now. it's not really a problem, though
 		int i = 0;
 		for (int row=from_row; row <= to_row; ++row) {
-			myData ()->cell_string_data[row] = qstrdup (QString::number (data[i++], 'g', MAX_PRECISION));
+			myData ()->cell_string_data[row] = new QString (QString::number (data[i++], 'g', MAX_PRECISION));
 		}
 	} else if (getVarType () == Factor) {
 		int i = 0;
 		for (int row=from_row; row <= to_row; ++row) {
-			setTextPlain (row, qstrdup (QString::number (data[i++], 'g', MAX_PRECISION)));
+			setText (row, QString::number (data[i++], 'g', MAX_PRECISION));
 		}
 	} else {
 		int i = 0;
 		for (int row=from_row; row <= to_row; ++row) {
 			deleteStringData (row);
-			if (isnan (data[i])) myData ()->cell_string_data[row] = RKGlobals::empty_char;
+			if (isnan (data[i])) myData ()->cell_string_data[row] = RKGlobals::na_char;
 			myData ()->cell_double_data[row] = data[i++];
 		}
 	}
 	cellsChanged (from_row, to_row);
 }
 
-/** like getNumeric, but returns values as an array of char*s */
-char **RKVariable::getCharacter (int from_row, int to_row) {
+QString *RKVariable::getCharacter (int from_row, int to_row) {
 	if (to_row >= getLength ()) {
 		RK_ASSERT (false);
 		return 0;
 	}
 	RK_ASSERT (from_row <= to_row);
 
-	char **ret = new char*[(to_row - from_row) + 1];
+	QString *ret = new QString[(to_row - from_row) + 1];
 	
 	int i = 0;
 	for (int row = from_row; row <= to_row; ++row) {
 		if (myData ()->cell_string_data[row]) {
-			ret[i] = myData ()->cell_string_data[row];
+			ret[i] = *(myData ()->cell_string_data[row]);
 		} else {
-			ret[i] = qstrdup (getText (row).local8Bit ());;
+			ret[i] = getText (row).local8Bit ();
 		}
 		i++;
 	}
@@ -619,20 +603,19 @@
 	return ret;
 }
 
-/** like setNumeric, but sets chars. If internalStorage () is numeric, attempts to convert the given strings to numbers. I.e. the function behaves essentially like setText (), but operates on a range of cells. */
-void RKVariable::setCharacter (int from_row, int to_row, char **data) {
+void RKVariable::setCharacter (int from_row, int to_row, QString *data) {
 	RK_ASSERT (to_row < getLength ());
 	
 	if (getVarType () == String) {
 		int i=0;
 		for (int row=from_row; row <= to_row; ++row) {
 			deleteStringData (row);
-			myData ()->cell_string_data[row] = data[i++];
+			myData ()->cell_string_data[row] = new QString (data[i++]);
 		}
 	} else {
 		int i=0;
 		for (int row=from_row; row <= to_row; ++row) {
-			setTextPlain (row, data[i++]);
+			setText (row, data[i++]);
 		}
 		return;
 	}
@@ -652,7 +635,7 @@
 }
 
 RKVariable::Status RKVariable::cellStatus (int row) {
-	if (myData ()->cell_string_data[row] == RKGlobals::empty_char) {
+	if (myData ()->cell_string_data[row] == RKGlobals::na_char) {
 		return ValueUnused;
 	} else if (myData ()->cell_string_data[row] == RKGlobals::unknown_char) {
 		return ValueUnknown;
@@ -678,12 +661,12 @@
 	}
 	
 	if (to_row < (myData ()->allocated_length - 1)) {	// not the last rows
-		qmemmove (&(myData ()->cell_string_data[from_row]), &(myData ()->cell_string_data[to_row+1]), (myData ()->allocated_length - to_row - 1) * sizeof (char*));
+		qmemmove (&(myData ()->cell_string_data[from_row]), &(myData ()->cell_string_data[to_row+1]), (myData ()->allocated_length - to_row - 1) * sizeof (QString*));
 		qmemmove (&(myData ()->cell_double_data[from_row]), &(myData ()->cell_double_data[to_row+1]), (myData ()->allocated_length - to_row - 1) * sizeof (double));
 	}
 
 	for (int row = (myData ()->allocated_length - 1 - (to_row - from_row)); row < myData ()->allocated_length; ++row) {
-		myData ()->cell_string_data[myData ()->allocated_length - 1] = RKGlobals::empty_char;
+		myData ()->cell_string_data[myData ()->allocated_length - 1] = RKGlobals::unknown_char;
 		myData ()->cell_double_data[myData ()->allocated_length - 1] = 0;
 	}
 
@@ -701,7 +684,7 @@
 	extendToLength (getLength () + count);
 
 	for (int i=old_len; i <= row+count; ++i) {
-		myData ()->cell_string_data[i] = RKGlobals::empty_char;
+		myData ()->cell_string_data[i] = RKGlobals::na_char;
 		myData ()->cell_double_data[i] = 0;
 	}
 
@@ -709,12 +692,12 @@
 		myData ()->cell_string_data[row+count] = myData ()->cell_string_data[row];
 		myData ()->cell_double_data[row+count] = myData ()->cell_double_data[row];
 	} else { 
-		qmemmove (&(myData ()->cell_string_data[row+count]), &(myData ()->cell_string_data[row]), (myData ()->allocated_length - (row + count) - 1) * sizeof (char*));
+		qmemmove (&(myData ()->cell_string_data[row+count]), &(myData ()->cell_string_data[row]), (myData ()->allocated_length - (row + count) - 1) * sizeof (QString*));
 		qmemmove (&(myData ()->cell_double_data[row+count]), &(myData ()->cell_double_data[row]), (myData ()->allocated_length - (row + count) - 1) * sizeof (double));
 	}
 	
 	for (int i=row+count-1; i >= row; --i) {
-		myData ()->cell_string_data[i] = RKGlobals::empty_char;
+		myData ()->cell_string_data[i] = RKGlobals::na_char;
 		myData ()->cell_double_data[i] = 0;
 	}
 }

Modified: trunk/rkward/rkward/core/rkvariable.h
===================================================================
--- trunk/rkward/rkward/core/rkvariable.h	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/core/rkvariable.h	2006-09-20 14:20:27 UTC (rev 748)
@@ -79,8 +79,6 @@
 	QString getRText (int row);
 /** set the value at the given row in text-form. Will try to convert the given string to the internal storage format if possible. */
 	void setText (int row, const QString &text);
-/** essentially like setText */
-	void setTextPlain (int row, char *text);
 
 /** get the text in pretty form, e.g. rounding numbers to a certain number of digits, replacing numeric values with value labels if available, etc. Formatting is done according to the meta-information stored in the RObject and global user preferences */
 	QString getFormatted (int row);
@@ -89,10 +87,10 @@
 	double *getNumeric (int from_row, int to_row);
 /** set numeric values in the given range. Assumes you provide enough values for the range. If internalStorage is String, all values will be converted to strings, so you should use this function only, if you know you are dealing with a numeric object */
 	void setNumeric (int from_row, int to_row, double *data);
-/** like getNumeric, but returns values as an array of char*s */
-	char **getCharacter (int from_row, int to_row);
+/** like getNumeric, but returns values as an array of QString*s. */
+	QString *getCharacter (int from_row, int to_row);
 /** like setNumeric, but sets chars. If internalStorage () is numeric, attempts to convert the given strings to numbers. I.e. the function behaves essentially like setText (), but operates on a range of cells. */
-	void setCharacter (int from_row, int to_row, char **data);
+	void setCharacter (int from_row, int to_row, QString *data);
 	
 /** returns the current status of the given cell */
 	Status cellStatus (int row);
@@ -151,8 +149,9 @@
 	struct RKVarEditData : public EditData {
 /// array of numeric data for the cells.
 		double *cell_double_data;
-/// array of string data for the cells.
-		char **cell_string_data;
+/** array of string data for the cells.
+Why is this an array of Qstring* instead of just of QString? The reason is that we need to differentiate three special strings: 1) empty 2) NA 3) unknown / unused. QString.isNull () vs. QString.isEmpty () would buy us two, but that's not enough, unfortunately. */
+		QString **cell_string_data;
 /// the currently allocated length of cell_double_data of cell_string_data. Used to determine, when a re-allocation is required
 		int allocated_length;
 /// see setSyncing

Modified: trunk/rkward/rkward/core/robjectlist.cpp
===================================================================
--- trunk/rkward/rkward/core/robjectlist.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/core/robjectlist.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -66,7 +66,7 @@
 		checkRemovedChildren (command->getStringVector (), command->stringVectorLength ());
 		
 		// next, update the existing and/or new children
-		num_children_updating = command->stringVectorLength ();
+		num_children_updating = command->stringVectorLength ();		// TODO: is this correct? Some children might have been removed!
 		// empty workspace?
 		if (!num_children_updating) {
 			num_children_updating = 1;
@@ -74,7 +74,7 @@
 			return;
 		}
 		for (int i = 0; i < command->stringVectorLength (); ++i) {
-			QString cname = command->getStringVector ()[i];
+			QString cname = command->getStringVector ()[i];		// for easier typing
 			/*if (cname == (".rk.meta")) {
 				childUpdateComplete ();
 				continue;

Modified: trunk/rkward/rkward/dataeditor/rkeditordataframe.cpp
===================================================================
--- trunk/rkward/rkward/dataeditor/rkeditordataframe.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/dataeditor/rkeditordataframe.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -120,23 +120,23 @@
 		}
 
 		// set the names and meta-information
-		for (int i = 0; i < command->stringVectorLength (); ++i) {
-			if (numTrueCols () <= i) {
+		for (int col = 0; col < command->stringVectorLength (); ++col) {
+			if (numTrueCols () <= col) {
 				insertNewColumn ();
 			}
 			// TODO: make clean
-			RKVariable *current_child = static_cast<RKVariable *> (static_cast <RContainerObject*> (getObject ())->findChild (command->getStringVector ()[i]));
+			RKVariable *current_child = static_cast<RKVariable *> (static_cast <RContainerObject*> (getObject ())->findChild (command->getStringVector ()[col]));
 			// this is really just a very preliminary HACK. If we find new children now exist, create them now in order to avoid crash..
 			// TODO: actually, we should have a true check for object type/structure each time before opening an object.
 			if (!current_child) {
-				current_child = static_cast<RKVariable *> (static_cast<RContainerObject *> (getObject ())->createNewChild (command->getStringVector ()[i], this));
+				current_child = static_cast<RKVariable *> (static_cast<RContainerObject *> (getObject ())->createNewChild (command->getStringVector ()[col], this));
 			}
 			if (current_child->isVariable ()) {
-				if (!getColObject (i)) {		// if we initialized the table to empty, the object may already exist in our map
-					setColObject (i, current_child);
+				if (!getColObject (col)) {		// if we initialized the table to empty, the object may already exist in our map
+					setColObject (col, current_child);
 					current_child->setObjectOpened (this, true);
 				} else {
-					RK_ASSERT (getColObject (i) == current_child);
+					RK_ASSERT (getColObject (col) == current_child);
 				}
 			} else {
 				RK_ASSERT (false);

Modified: trunk/rkward/rkward/debug.h
===================================================================
--- trunk/rkward/rkward/debug.h	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/debug.h	2006-09-20 14:20:27 UTC (rev 748)
@@ -2,7 +2,7 @@
                           debug  -  description
                              -------------------
     begin                : Sun Aug 8 2004
-    copyright            : (C) 2004 by Thomas Friedrichsmeier
+    copyright            : (C) 2004, 2006 by Thomas Friedrichsmeier
     email                : tfry at users.sourceforge.net
  ***************************************************************************/
 
@@ -14,7 +14,7 @@
  *   (at your option) any later version.                                   *
  *                                                                         *
  ***************************************************************************/
- 
+
 #define RKWARD_DEBUG
 
 extern int RK_Debug_Level;

Modified: trunk/rkward/rkward/main.cpp
===================================================================
--- trunk/rkward/rkward/main.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/main.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -81,24 +81,24 @@
 };
 
 int main(int argc, char *argv[]) {
-	KAboutData aboutData( "rkward", I18N_NOOP ("RKWard"), version, description, KAboutData::License_GPL, "(c) 2002, 2004, 2005, 2006", 0, "http://rkward.sf.net", QString::null);
-	aboutData.addAuthor ("Thomas Friedrichsmeier", I18N_NOOP ("Project leader"), QString::null);
-	aboutData.addAuthor ("Pierre Ecochard",  I18N_NOOP ("Core coder since 0.2.9"), QString::null);
-	aboutData.addCredit ("Contributors in alphabetical order", QString::null, QString::null);
-	aboutData.addCredit ("Philippe Grosjean", I18N_NOOP ("Several helpful comments and discussions"), QString::null);
-	aboutData.addCredit ("Adrien d'Hardemare", I18N_NOOP ("Plugins and patches"), QString::null);
-	aboutData.addCredit ("Yves Jacolin", I18N_NOOP ("New website"), QString::null);
-	aboutData.addCredit ("Marco Martin", I18N_NOOP ("A cool icon"), QString::null);
-	aboutData.addCredit ("Daniele Medri", I18N_NOOP ("RKWard logo, many suggestions, help on wording"), QString::null);
-	aboutData.addCredit ("Stefan Roediger", I18N_NOOP ("Several plugins, and suggestions"), QString::null);
-	aboutData.addCredit ("David Sibai", I18N_NOOP ("Several valuable comments, hints and patches"), QString::null);
-	aboutData.addCredit (I18N_NOOP ("Many more people on rkward-devel at lists.sourceforge.net"), I18N_NOOP ("Sorry, if we forgot to list you. Please contact us to get added"), QString::null);
+	KAboutData aboutData( "rkward", I18N_NOOP ("RKWard"), version, description, KAboutData::License_GPL, "(c) 2002, 2004, 2005, 2006", 0, "http://rkward.sf.net", 0);
+	aboutData.addAuthor ("Thomas Friedrichsmeier", I18N_NOOP ("Project leader"), 0);
+	aboutData.addAuthor ("Pierre Ecochard",  I18N_NOOP ("Core coder since 0.2.9"), 0);
+	aboutData.addCredit ("Contributors in alphabetical order", 0, 0);
+	aboutData.addCredit ("Philippe Grosjean", I18N_NOOP ("Several helpful comments and discussions"), 0);
+	aboutData.addCredit ("Adrien d'Hardemare", I18N_NOOP ("Plugins and patches"), 0);
+	aboutData.addCredit ("Yves Jacolin", I18N_NOOP ("New website"), 0);
+	aboutData.addCredit ("Marco Martin", I18N_NOOP ("A cool icon"), 0);
+	aboutData.addCredit ("Daniele Medri", I18N_NOOP ("RKWard logo, many suggestions, help on wording"), 0);
+	aboutData.addCredit ("Stefan Roediger", I18N_NOOP ("Several plugins, and suggestions"), 0);
+	aboutData.addCredit ("David Sibai", I18N_NOOP ("Several valuable comments, hints and patches"), 0);
+	aboutData.addCredit (I18N_NOOP ("Many more people on rkward-devel at lists.sourceforge.net"), I18N_NOOP ("Sorry, if we forgot to list you. Please contact us to get added"), 0);
 
 	// before initializing the commandline args, remove the ".bin" from "rkward.bin".
 	// This is so it prints "Usage rkward..." instead of "Usage rkward.bin...", etc.
 	// it seems safest to keep a copy, since the shell still owns argv[0]
 	char *argv_zero_copy = argv[0];
-	argv[0] = qstrdup (QString (argv_zero_copy).remove (".bin").utf8 ());
+	argv[0] = qstrdup (QString (argv_zero_copy).remove (".bin").local8Bit ());
 	KCmdLineArgs::init( argc, argv, &aboutData );
 	KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
 	

Modified: trunk/rkward/rkward/plugin/rkcomponentmap.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkcomponentmap.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/plugin/rkcomponentmap.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -201,7 +201,7 @@
 RKComponentHandle* RKComponentHandle::createComponentHandle (const QString &filename, RKComponentType type, const QString& id, const QString& label) {
 	if (type == (int) Standard) {
 		RKStandardComponentHandle *ret = new RKStandardComponentHandle (filename, type);
-		new KAction (label, 0, ret, SLOT (activated ()), RKGlobals::componentMap ()->actionCollection (), id);
+		new KAction (label, 0, ret, SLOT (activated ()), RKGlobals::componentMap ()->actionCollection (), id.latin1 ());
 		return (ret);
 	}
 	// TODO: create an RKPluginHandle instead!

Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -567,7 +567,7 @@
 		} else if (mode == RKComponentPropertyConvert::Range) {
 			convert->setRange (xml->getDoubleAttribute (*it, "min", -FLT_MAX, DL_INFO), xml->getDoubleAttribute (*it, "max", FLT_MAX, DL_INFO));
 		}
-		convert->setRequireTrue (xml->getStringAttribute (*it, "require_true", false, DL_INFO));
+		convert->setRequireTrue (xml->getBoolAttribute (*it, "require_true", false, DL_INFO));
 		component ()->addChild (id, convert);
 	}
 }

Modified: trunk/rkward/rkward/rbackend/rcommand.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rcommand.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/rbackend/rcommand.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -53,9 +53,6 @@
 
 RCommand::~RCommand(){
 	RK_TRACE (RBACKEND);
-	for (int i = 0; i < string_count; ++i) {
-		DELETE_STRING (string_data[i]);
-	}
 	delete [] string_data;
 	delete real_data;
 	delete integer_data;

Modified: trunk/rkward/rkward/rbackend/rcommand.h
===================================================================
--- trunk/rkward/rkward/rbackend/rcommand.h	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/rbackend/rcommand.h	2006-09-20 14:20:27 UTC (rev 748)
@@ -59,7 +59,7 @@
 private:
 friend class RInterface;
 friend class RThread;
-	char **call;
+	QString *call;
 	int call_length;
 	RCommandChain *in_chain;
 };
@@ -192,8 +192,8 @@
 	int realVectorLength () { return (real_count); };
 /** returns the length (size) of the int array. @see RCommand::GetIntVector @see RCommand::getIntVector @see RCommand::detachIntVector */
 	int intVectorLength () { return (integer_count); };
-/** returns a pointer to the char * array. The char* array is owned by the RCommand! @see RCommand::GetStringVector @see RCommand::getStringVector @see RCommand::detachStringVector */
-	char **getStringVector () { return (string_data); };
+/** returns an array of QString*. The array is owned by the RCommand! @see RCommand::GetStringVector @see RCommand::getStringVector @see RCommand::detachStringVector */
+	QString *getStringVector () { return (string_data); };
 /** returns a pointer to the double array. The double array is owned by the RCommand! @see RCommand::GetRealVector @see RCommand::getRealVector @see RCommand::detachRealVector */
 	double *getRealVector () { return (real_data); };
 /** returns a pointer to the int array. The int array is owned by the RCommand! @see RCommand::GetIntVector @see RCommand::getIntVector @see RCommand::detachIntVector */
@@ -219,7 +219,7 @@
 	void newOutput (ROutput *output);
 	QValueList<ROutput*> output_list;
 	QString _command;
-	char **string_data;
+	QString *string_data;
 	int string_count;
 	double *real_data;
 	int real_count;

Modified: trunk/rkward/rkward/rbackend/rembedinternal.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rembedinternal.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/rbackend/rembedinternal.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -288,10 +288,9 @@
 
 // ############## R Standard callback overrides END ####################
 
-REmbedInternal::REmbedInternal() {
-	RKGlobals::empty_char = strdup ("");
-	RKGlobals::unknown_char = strdup ("?");
-//	RKGlobals::na_double = NA_REAL;			// this will be repeated in startR, as NA_REAL is 0 at this point!
+char *REmbedInternal::na_char_internal = new char;
+
+REmbedInternal::REmbedInternal () {
 }
 
 void REmbedInternal::connectCallbacks () {
@@ -324,7 +323,7 @@
 //	ptr_R_savehistory = ...	// we keep our own history
 }
 
-REmbedInternal::~REmbedInternal (){
+REmbedInternal::~REmbedInternal () {
 }
 
 void REmbedInternal::shutdown (bool suicidal) {
@@ -375,44 +374,41 @@
 	}
 }
 
-char **extractStrings (SEXP from_exp, int *count) {
+/** This function is the R side wrapper around stringsToStringList */
+QString *SEXPToStringList (SEXP from_exp, int *count) {
 	char **strings = 0;
 	
 	SEXP strexp;
 	PROTECT (strexp = coerceVector (from_exp, STRSXP));
 	*count = length (strexp);
 	strings = new char* [length (strexp)];
-	for (int i = 0; i < *count; ++i) {
+	int i = 0;
+	for (; i < *count; ++i) {
 		SEXP dummy = VECTOR_ELT (strexp, i);
-// TODO: can we avoid this string copying by protecting strexp?
+
 		if (TYPEOF (dummy) != CHARSXP) {
 			strings[i] = strdup ("not defined");	// can this ever happen?
 		} else {
 			if (dummy == NA_STRING) {
-				strings[i] = RKGlobals::empty_char;
+				strings[i] = REmbedInternal::na_char_internal;
 			} else {
-				strings[i] = strdup ((char *) STRING_PTR (dummy));
+				strings[i] = (char *) STRING_PTR (dummy);
 			}
 		}
 	}
+	QString *list = stringsToStringList (strings, i);
+	delete [] strings;
+
 	UNPROTECT (1);	// strexp
-	
-	return strings;
-}
 
-void deleteStrings (char **strings, int count) {
-	for (int i= (count-1); i >=0; --i) {
-		DELETE_STRING (strings[i]);
-	}
-	delete [] strings;
+	return list;
 }
 
 SEXP doError (SEXP call) {
 	int count;
-	char **strings = extractStrings (call, &count);
+	QString *strings = SEXPToStringList (call, &count);
 	REmbedInternal::this_pointer->handleError (strings, count);
-	deleteStrings (strings, count);
-
+	deleteQStringArray (strings);
 	return R_NilValue;
 }
 
@@ -426,9 +422,9 @@
 
 SEXP doSubstackCall (SEXP call) {
 	int count;
-	char **strings = extractStrings (call, &count);
+	QString *strings = SEXPToStringList (call, &count);
 	REmbedInternal::this_pointer->handleSubstackCall (strings, count);
-	deleteStrings (strings, count);
+	deleteQStringArray (strings);
 	return R_NilValue;
 }
 
@@ -446,7 +442,7 @@
 #endif
 }
 
-bool REmbedInternal::registerFunctions (char *library_path) {
+bool REmbedInternal::registerFunctions (const char *library_path) {
 	DllInfo *info = R_getDllInfo (library_path);
 	if (!info) return false;
 
@@ -584,14 +580,14 @@
 	}
 }
 
-char **REmbedInternal::getCommandAsStringVector (const char *command, int *count, RKWardRError *error) {	
+QString *REmbedInternal::getCommandAsStringVector (const char *command, int *count, RKWardRError *error) {	
 	SEXP exp;
-	char **strings = 0;
+	QString *list = 0;
 	
 	PROTECT (exp = runCommandInternalBase (command, error));
 	
 	if (*error == NoError) {
-		strings = extractStrings (exp, count);
+		list = SEXPToStringList (exp, count);
 	}
 	
 	UNPROTECT (1); // exp
@@ -600,7 +596,7 @@
 		*count = 0;
 		return 0;
 	}
-	return strings;
+	return list;
 }
 
 double *REmbedInternal::getCommandAsRealVector (const char *command, int *count, RKWardRError *error) {

Modified: trunk/rkward/rkward/rbackend/rembedinternal.h
===================================================================
--- trunk/rkward/rkward/rbackend/rembedinternal.h	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/rbackend/rembedinternal.h	2006-09-20 14:20:27 UTC (rev 748)
@@ -45,6 +45,12 @@
 	bool bool_a;		/**< a bool parameter. Look at the respective callbacks to find out, what it is used for. */
 };
 
+class QString;
+/** This function converts a list of strings to a QStringList (locale aware), and returns the pointer. Needed to keep R and Qt includes separate. The strings can be deleted afterwards. Implementation is in rthread.cpp */
+QString *stringsToStringList (char **strings, int count);
+/** Function to delete an array of Qstring. Does delete [] strings, nothing more. But can not inline this in this class due to conflicting R and Qt includes. Implementation is in rthread.cpp */
+void deleteQStringArray (QString *strings);
+
  /** The main purpose of separating this class from RThread is that R- and Qt-includes don't go together well. Hence this class is Qt-agnostic while
 	RThread is essentially R-agnostic.
 	
@@ -87,11 +93,11 @@
 /** basically a wrapper to runCommandInternal (). Tries to convert the result of the command to an array of char* after running the command. Since
 this will not ever be done for user commands, the R_Visible flag will never be set. @see RCommand::GetStringVector
 @param command char* of the command to be run 
- at param count length of array returned
+ at param count length of list returned
 @param error this will be set to a value in RKWardError depending on success/failure of the command
- at returns an array of char* or 0 on failure
+ at returns an array of QString or 0 on failure
 @see RCommand::GetStringVector */
-	char **getCommandAsStringVector (const char *command, int *count, RKWardRError *error);
+	QString *getCommandAsStringVector (const char *command, int *count, RKWardRError *error);
 /** basically a wrapper to runCommandInternal (). Tries to convert the result of the command to an array of double after running the command. Since
 this will not ever be done for user commands, the R_Visible flag will never be set. @see RCommand::GetRealVector
 @param command char* of the command to be run 
@@ -122,11 +128,11 @@
 //	virtual void handleCondition (char **call, int call_length) = 0;
 
 /** This gets called, when R reports an error (override of options ("error") in R). Used to get at error-output. */
-	virtual void handleError (char **call, int call_length) = 0;
+	virtual void handleError (QString *call, int call_length) = 0;
 
 /** The main callback from R to rkward. Since we need QStrings and stuff to handle the requests, this is only a pure virtual function. The real
 implementation is in RThread::handleSubstackCall () */
-	virtual void handleSubstackCall (char **call, int call_length) = 0;
+	virtual void handleSubstackCall (QString *call, int call_length) = 0;
 
 /** This second callback handles R standard callbacks. The difference to the first one is, that these are typically required to finish within the same
 function. On the other hand, also, they don't require further computations in R, and hence no full-fledged substack.
@@ -135,9 +141,10 @@
 @see RCallbackArgs @see RCallbackType */
 	virtual void handleStandardCallback (RCallbackArgs *args) = 0;
 
-	bool registerFunctions (char *library_path);
+	bool registerFunctions (const char *library_path);
 /** only one instance of this class may be around. This pointer keeps the reference to it, for interfacing to from C to C++ */
 	static REmbedInternal *this_pointer;
+	static char *na_char_internal;
 
 /** Flags used to classify output. */
 //	static bool output_is_warning;

Modified: trunk/rkward/rkward/rbackend/rthread.cpp
===================================================================
--- trunk/rkward/rkward/rbackend/rthread.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/rbackend/rthread.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -145,7 +145,7 @@
 		RK_DO (qDebug ("running command: %s", ccommand), RBACKEND, DL_DEBUG);
 	
 		if (command->type () & RCommand::DirectToOutput) {
-			runCommandInternal ("sink (\"" + RKSettingsModuleGeneral::filesPath () + "/rk_out.html\", append=TRUE, split=TRUE)\n", &error);
+			runCommandInternal (QString ("sink (\"" + RKSettingsModuleGeneral::filesPath () + "/rk_out.html\", append=TRUE, split=TRUE)\n").local8Bit (), &error);
 		}
 
 		MUTEX_UNLOCK;
@@ -280,7 +280,7 @@
 	qDebug ("condition '%s', message '%s'", call[0], call[1]);
 } */
 
-void RThread::handleError (char **call, int call_length) {
+void RThread::handleError (QString *call, int call_length) {
 	RK_TRACE (RBACKEND);
 
 	if (!call_length) return;
@@ -292,11 +292,11 @@
 	current_command->output_list.last ()->type = ROutput::Error;
 	current_command->status |= RCommand::HasError;
 
-	RK_DO (qDebug ("error '%s'", call[0]), RBACKEND, DL_DEBUG);
+	RK_DO (qDebug ("error '%s'", call[0].latin1 ()), RBACKEND, DL_DEBUG);
 	MUTEX_UNLOCK;
 }
 
-void RThread::handleSubstackCall (char **call, int call_length) {
+void RThread::handleSubstackCall (QString *call, int call_length) {
 	RK_TRACE (RBACKEND);
 
 	RCommand *prev_command = current_command;
@@ -385,34 +385,29 @@
 	RKWardRError error;
 	int status = 0;
 	
-	char **paths;
 	runCommandInternal ("library (\"rkward\")\n", &error);
 	if (error) status |= LibLoadFail;
 	int c;
-	paths = getCommandAsStringVector ("library.dynam (\"rkward\", \"rkward\")[[\"path\"]]\n", &c, &error);
+	QString *paths = getCommandAsStringVector ("library.dynam (\"rkward\", \"rkward\")[[\"path\"]]\n", &c, &error);
 	if ((error) || (c != 1)) {
 		status |= LibLoadFail;
 	} else {
-		if (!registerFunctions (paths[0])) status |= LibLoadFail;
+		if (!registerFunctions (paths[0].local8Bit ())) status |= LibLoadFail;
 	}
-	for (int i = (c-1); i >=0; --i) {
-		DELETE_STRING (paths[i]);
-	}
 	delete [] paths;
 
 // find out about standard library locations
-	char **standardliblocs = getCommandAsStringVector (".libPaths ()\n", &c, &error);
+	QString *standardliblocs = getCommandAsStringVector (".libPaths ()\n", &c, &error);
 	if (error) status |= OtherFail;
 	for (int i = 0; i < c; ++i) {
 		RKSettingsModuleRPackages::defaultliblocs.append (standardliblocs[i]);
-		DELETE_STRING (standardliblocs[i]);
 	}
 	delete [] standardliblocs;
 
 // apply user configurable run time options
 	QStringList commands = RKSettingsModuleR::makeRRunTimeOptionCommands () + RKSettingsModuleRPackages::makeRRunTimeOptionCommands ();
 	for (QStringList::const_iterator it = commands.begin (); it != commands.end (); ++it) {
-		runCommandInternal (*it, &error);
+		runCommandInternal ((*it).local8Bit (), &error);
 		if (error) {
 			status |= OtherFail;
 			RK_DO (qDebug ("error in initialization call '%s'", (*it).latin1()), RBACKEND, DL_ERROR);
@@ -437,3 +432,16 @@
 
 	return status;
 }
+
+QString *stringsToStringList (char **strings, int count) {
+	QString *list = new QString[count];
+	for (int i=0; i < count; ++i) {
+		if (strings[i] == REmbedInternal::na_char_internal) list[i] = QString::null;
+		else list[i] = (QString::fromLocal8Bit (strings[i]));
+	}
+	return list;
+}
+
+void deleteQStringArray (QString *strings) {
+	delete [] strings;
+}

Modified: trunk/rkward/rkward/rbackend/rthread.h
===================================================================
--- trunk/rkward/rkward/rbackend/rthread.h	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/rbackend/rthread.h	2006-09-20 14:20:27 UTC (rev 748)
@@ -120,13 +120,13 @@
 
 /** this function is public for technical reasons, only. Don't use except from REmbedInternal! Called from REmbedInternal when the R backend
 reports an error. @see REmbedInternal::handleError () */
-	void handleError (char **call, int call_length);
+	void handleError (QString *call, int call_length);
 
 /** This function is public for technical reasons, only. Don't use except from REmbedInternal!
 
 This is a sub-eventloop, being run when the backend request information from the frontend. See \ref RThread for a more detailed description
 @see REmbedInternal::handleSubstackCall () */
-	void handleSubstackCall (char **call, int call_length);
+	void handleSubstackCall (QString *call, int call_length);
 
 /** This function is public for technical reasons, only. Don't use except from REmbedInternal!
 

Modified: trunk/rkward/rkward/rkconsole.cpp
===================================================================
--- trunk/rkward/rkward/rkconsole.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/rkconsole.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -479,7 +479,7 @@
 }
 
 void RKConsole::unplugAction(QString action, KActionCollection* ac) {
-	KAction* a = ac->action(action);
+	KAction* a = ac->action(action.latin1 ());
 	if( a ){
 		a->setEnabled(false);
 	}

Modified: trunk/rkward/rkward/rkglobals.cpp
===================================================================
--- trunk/rkward/rkward/rkglobals.cpp	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/rkglobals.cpp	2006-09-20 14:20:27 UTC (rev 748)
@@ -16,6 +16,8 @@
  ***************************************************************************/
 #include "rkglobals.h"
 
+#include <qstring.h>
+
 RKwardApp *RKGlobals::app;
 RInterface *RKGlobals::rinter;
 RObjectList *RKGlobals::list;
@@ -25,8 +27,8 @@
 KHelpDlg *RKGlobals::helpdlg;
 RControlWindow *RKGlobals::rcontrol;
 
-char *RKGlobals::empty_char;
-char *RKGlobals::unknown_char;
+QString *RKGlobals::na_char = new QString ("");
+QString *RKGlobals::unknown_char = new QString ("?");
 double RKGlobals::na_double;
 
 RKGlobals::RKGlobals () {
@@ -45,3 +47,11 @@
 int RKGlobals::spacingHint () {
 	return KDialog::spacingHint ();
 }
+
+void RKGlobals::deleteStrings (QString **strings, int count) {
+	for (int i = (count-1); i >= 0; --i) {
+		DELETE_STRING (strings[i]);
+	}
+	delete [] strings;
+}
+

Modified: trunk/rkward/rkward/rkglobals.h
===================================================================
--- trunk/rkward/rkward/rkglobals.h	2006-09-20 09:47:50 UTC (rev 747)
+++ trunk/rkward/rkward/rkglobals.h	2006-09-20 14:20:27 UTC (rev 748)
@@ -25,9 +25,10 @@
 class RKComponentMap;
 class KHelpDlg;
 class RControlWindow;
+class QString;
 
 // deletes the given char*, if it is not a special value. Does not set to 0.
-#define DELETE_STRING(x) if (x && (x != RKGlobals::empty_char) && (x != RKGlobals::unknown_char)) { delete x; };
+#define DELETE_STRING(x) if (x && (x != RKGlobals::na_char) && (x != RKGlobals::unknown_char)) { delete x; };
 
 /**
 This class basically keeps some static pointers which are needed all over the place, so they won't have to be passed around.
@@ -61,9 +62,9 @@
 	static RControlWindow *controlWindow () { return rcontrol; };
 
 /// an empty char
-	static char *empty_char;
+	static QString *na_char;
 /// an unknown value
-	static char *unknown_char;
+	static QString *unknown_char;
 /// a NA double
 	static double na_double;
 	
@@ -71,6 +72,9 @@
 	static int marginHint ();
 /// returns KDialog::spacingHint (), without the need to include kdialog.h in all the sources
 	static int spacingHint ();
+
+	static void deleteStrings (QString **strings, int count);
+
 private:
 	friend class RKwardApp;
 	static RKwardApp *app;


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