[rkward-cvs] SF.net SVN: rkward:[4400] trunk/rkward/rkward
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Tue Oct 30 18:37:23 UTC 2012
Revision: 4400
http://rkward.svn.sourceforge.net/rkward/?rev=4400&view=rev
Author: tfry
Date: 2012-10-30 18:37:23 +0000 (Tue, 30 Oct 2012)
Log Message:
-----------
Matrix input element is basically working.
Quirks:
- Should remove values on Backspace / Delete
- Should move to next cell on cursor right, even when editing a cell
- Cursor placement after expanding table
- When columns=1, should appear slim
Missing features:
- Cut / Copy / Paste
Modified Paths:
--------------
trunk/rkward/rkward/plugin/rkmatrixinput.cpp
trunk/rkward/rkward/plugin/rkmatrixinput.h
trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
trunk/rkward/rkward/plugins/under_development.pluginmap
Added Paths:
-----------
trunk/rkward/rkward/plugins/testing/matrix1.js
trunk/rkward/rkward/plugins/testing/matrix1.xml
Modified: trunk/rkward/rkward/plugin/rkmatrixinput.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkmatrixinput.cpp 2012-10-30 15:59:36 UTC (rev 4399)
+++ trunk/rkward/rkward/plugin/rkmatrixinput.cpp 2012-10-30 18:37:23 UTC (rev 4400)
@@ -49,7 +49,7 @@
max = xml->getIntAttribute (element, "max", INT_MAX, DL_INFO) + .1;
} else if (mode == Real) {
min = xml->getDoubleAttribute (element, "min", -FLT_MAX, DL_INFO);
- max = xml->getDoubleAttribute (element, "min", FLT_MAX, DL_INFO);
+ max = xml->getDoubleAttribute (element, "max", FLT_MAX, DL_INFO);
} else {
min = -FLT_MAX;
max = FLT_MAX;
@@ -58,8 +58,8 @@
allow_missings = xml->getBoolAttribute (element, "allow_missings", false, DL_INFO);
allow_user_resize_columns = xml->getBoolAttribute (element, "allow_user_resize_columns", true, DL_INFO);
allow_user_resize_rows = xml->getBoolAttribute (element, "allow_user_resize_rows", true, DL_INFO);
- trailing_rows = allow_user_resize_rows ? 1 :0;
- trailing_columns = allow_user_resize_columns ? 1 :0;
+ trailing_rows = allow_user_resize_rows ? 1 : 0;
+ trailing_columns = allow_user_resize_columns ? 1 : 0;
row_count = new RKComponentPropertyInt (this, false, xml->getIntAttribute (element, "rows", 2, DL_INFO));
column_count = new RKComponentPropertyInt (this, false, xml->getIntAttribute (element, "columns", 2, DL_INFO));
@@ -76,14 +76,33 @@
updating_dimensions = false;
model = new RKMatrixInputModel (this);
+ QString headers = xml->getStringAttribute (element, "horiz_headers", QString (), DL_INFO);
+ if (!headers.isEmpty ()) model->horiz_header = headers.split (';');
+ headers = xml->getStringAttribute (element, "vert_headers", QString (), DL_INFO);
+ if (!headers.isEmpty ()) model->vert_header = headers.split (';');
+ updateDataAndDimensions ();
display->setModel (model);
}
-
RKMatrixInput::~RKMatrixInput () {
RK_TRACE (PLUGIN);
}
+QString RKMatrixInput::value (const QString& modifier) {
+ if (modifier == "cbind") {
+ QStringList ret;
+ for (int i = 0; i < column_count->intValue (); ++i) {
+ ret.append ("\tc (" + makeColumnString (i, ", ") + ")");
+ }
+ return QString ("cbind (\n" + ret.join ("\n") + "\n)");
+ }
+
+ bool ok;
+ int col = modifier.toInt (&ok);
+ if ((col >= 0) && ok) return makeColumnString (col, "\t");
+ return tsv_data->value (modifier);
+}
+
bool RKMatrixInput::expandStorageForColumn (int column) {
RK_TRACE (PLUGIN);
@@ -149,16 +168,16 @@
col.cached_tab_joined_string.clear (); // == no valid cache
updateDataAndDimensions ();
- updateValidityFlag ();
}
void RKMatrixInput::updateValidityFlag () {
RK_TRACE (PLUGIN);
+ is_valid = true;
for (int i = 0; i < column_count->intValue (); ++i) {
if (i >= columns.size ()) { // hit end of data, before hitting any invalid strings
is_valid = allow_missings;
- return;
+ break;
}
Column &col = columns[i];
@@ -166,12 +185,27 @@
else if (allow_missings && (col.valid_up_to_row >= (col.storage.size () - 1))) continue;
else {
is_valid = false;
- return;
+ break;
}
}
- is_valid = true;
+ changed ();
}
+QString RKMatrixInput::makeColumnString (int column, const QString& sep) {
+ RK_TRACE (PLUGIN);
+
+ QStringList storage;
+ if (column < columns.size ()) {
+ storage = columns[column].storage;
+ }
+ QString ret;
+ if (!storage.isEmpty ()) ret = QStringList (storage.mid (0, row_count->intValue ())).join (sep);
+ for (int i = storage.size (); i < row_count->intValue (); ++i) {
+ ret.append (sep);
+ }
+ return ret;
+}
+
void RKMatrixInput::updateDataAndDimensions () {
RK_TRACE (PLUGIN);
@@ -187,7 +221,7 @@
if (max_row != row_count->intValue () - 1) {
updating_dimensions = true;
model->layoutAboutToBeChanged ();
- row_count->setIntValue (max_row);
+ row_count->setIntValue (max_row + 1);
model->layoutChanged ();
updating_dimensions = false;
}
@@ -196,42 +230,35 @@
int max_col = column_count->intValue () - 1;
if (allow_user_resize_columns) {
for (max_col = columns.size () - 1; max_col >= 0; --max_col) {
- if (columns[max_col].filled_up_to_row < 0) {
- columns.pop_back ();
- } else {
+ if (columns[max_col].filled_up_to_row >= 0) {
break;
}
}
if (max_col != column_count->intValue () - 1) {
updating_dimensions = true;
model->layoutAboutToBeChanged ();
- column_count->setIntValue (max_col);
+ column_count->setIntValue (max_col + 1);
model->layoutChanged ();
updating_dimensions = false;
}
}
QStringList tsv;
- QString empty_column (max_row, '\t'); // NOTE: *Not* max_row+1, as the number of seps is rows - 1
- for (int i = 0; i < max_col; ++i) {
- if (i > (columns.size () - 1)) {
- tsv.append (empty_column);
- } else {
- Column& col = columns[i];
- if (col.cached_tab_joined_string.isNull ()) {
- QString cache = QStringList (col.storage.mid (0, max_row + 1)).join ("\t");
- if (col.storage.size () < max_row) {
- QString empty_trail (max_row - col.storage.size (), '\t');
- cache.append (empty_trail);
- }
- col.cached_tab_joined_string = cache;
- }
- tsv.append (col.cached_tab_joined_string);
+ int i = 0;
+ for (; i < columns.size (); ++i) {
+ Column& col = columns[i];
+ if (col.cached_tab_joined_string.isEmpty ()) {
+ col.cached_tab_joined_string = makeColumnString (i, "\t");
}
+ tsv.append (col.cached_tab_joined_string);
}
+ for (; i < max_col; ++i) {
+ tsv.append (QString (max_row, '\t'));
+ }
tsv_data->setValue (tsv.join ("\n"));
updating_tsv_data = false;
+ updateValidityFlag ();
}
void RKMatrixInput::dimensionPropertyChanged (RKComponentPropertyBase *property) {
@@ -253,14 +280,15 @@
}
}
- updateValidityFlag ();
+ model->layoutAboutToBeChanged ();
updateDataAndDimensions ();
+ model->layoutChanged ();
}
void RKMatrixInput::tsvPropertyChanged () {
RK_TRACE (PLUGIN);
- bool old_updating_tsv_data = updating_tsv_data;
+ if (updating_tsv_data) return;
updating_tsv_data = true;
columns.clear ();
@@ -269,7 +297,7 @@
setColumnValue (i, coldata[i]);
}
- updating_tsv_data = old_updating_tsv_data;
+ updating_tsv_data = false;
updateDataAndDimensions ();
}
@@ -282,7 +310,7 @@
if (mode == Integer) {
val = value.toInt (&number_ok);
} else {
- val = value.toDouble (&number_ok);
+ val = value.toFloat (&number_ok);
}
if (!number_ok) return false;
if (val < min) return false;
@@ -321,22 +349,22 @@
// handle trailing rows / cols in user expandable tables
bool trailing = false;
- if (row > matrix->row_count->intValue ()) {
- if ((!matrix->allow_user_resize_rows) || (row > matrix->row_count->intValue () + matrix->trailing_rows)) {
+ if (row >= matrix->row_count->intValue ()) {
+ if ((!matrix->allow_user_resize_rows) || (row >= matrix->row_count->intValue () + matrix->trailing_rows)) {
RK_ASSERT (false);
return QVariant ();
}
trailing = true;
}
- if (column > matrix->column_count->intValue ()) {
- if ((!matrix->allow_user_resize_columns) || (column > matrix->column_count->intValue () + matrix->trailing_columns)) {
+ if (column >= matrix->column_count->intValue ()) {
+ if ((!matrix->allow_user_resize_columns) || (column >= matrix->column_count->intValue () + matrix->trailing_columns)) {
RK_ASSERT (false);
return QVariant ();
}
trailing = true;
};
if (trailing) {
- if (role == Qt::BackgroundRole) return QVariant (QBrush (Qt::lightGray));
+ if (role == Qt::BackgroundRole) return QVariant (QBrush (Qt::gray));
if (role == Qt::ToolTipRole || role == Qt::StatusTipRole) return QVariant (i18n ("Type on these cells to expand the table"));
return QVariant ();
}
@@ -357,6 +385,25 @@
return QVariant ();
}
+Qt::ItemFlags RKMatrixInputModel::flags (const QModelIndex& index) const {
+ // handle trailing rows / cols in user expandable tables
+ if ((index.row () > matrix->row_count->intValue ()) || (index.column () > matrix->column_count->intValue ())) {
+ return (Qt::ItemIsEditable | Qt::ItemIsEnabled);
+ }
+ return (Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+}
+
+QVariant RKMatrixInputModel::headerData (int section, Qt::Orientation orientation, int role) const {
+ if (role == Qt::DisplayRole) {
+ const QStringList* list;
+ if (orientation == Qt::Horizontal) list = &horiz_header;
+ else list = &vert_header;
+ if (section < list->size ()) return QVariant ((*list)[section]);
+ return QVariant (QString::number (section + 1));
+ }
+ return QVariant ();
+}
+
bool RKMatrixInputModel::setData (const QModelIndex& index, const QVariant& value, int role) {
RK_TRACE (PLUGIN);
Modified: trunk/rkward/rkward/plugin/rkmatrixinput.h
===================================================================
--- trunk/rkward/rkward/plugin/rkmatrixinput.h 2012-10-30 15:59:36 UTC (rev 4399)
+++ trunk/rkward/rkward/plugin/rkmatrixinput.h 2012-10-30 18:37:23 UTC (rev 4400)
@@ -69,6 +69,7 @@
void setColumnValue (int column, const QString& value);
void updateColumn (int offset, int column);
bool expandStorageForColumn (int column);
+ QString makeColumnString (int column, const QString& sep);
bool is_valid;
@@ -101,8 +102,12 @@
int columnCount (const QModelIndex &parent = QModelIndex()) const; // implemented for QAbstractTableModel
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const; // re-implemented for QAbstractTableModel
bool setData (const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); // re-implemented for QAbstractTableModel
+ Qt::ItemFlags flags (const QModelIndex &index) const; // re-implemented for QAbstractTableModel
+ QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; // re-implemented for QAbstractTableModel
RKMatrixInput *matrix;
+ QStringList horiz_header;
+ QStringList vert_header;
};
#endif
Modified: trunk/rkward/rkward/plugin/rkstandardcomponent.cpp
===================================================================
--- trunk/rkward/rkward/plugin/rkstandardcomponent.cpp 2012-10-30 15:59:36 UTC (rev 4399)
+++ trunk/rkward/rkward/plugin/rkstandardcomponent.cpp 2012-10-30 18:37:23 UTC (rev 4400)
@@ -47,6 +47,7 @@
#include "rkdropdown.h"
#include "rkcheckbox.h"
#include "rkpluginspinbox.h"
+#include "rkmatrixinput.h"
#include "rkinput.h"
#include "rkpluginbrowser.h"
#include "rkpluginsaveobject.h"
@@ -622,6 +623,8 @@
widget = new RKCheckBox (e, component (), parent_widget);
} else if (e.tagName () == "spinbox") {
widget = new RKPluginSpinBox (e, component (), parent_widget);
+ } else if (e.tagName () == "matrix") {
+ widget = new RKMatrixInput (e, component (), parent_widget);
} else if (e.tagName () == "input") {
widget = new RKInput (e, component (), parent_widget);
} else if (e.tagName () == "browser") {
Added: trunk/rkward/rkward/plugins/testing/matrix1.js
===================================================================
--- trunk/rkward/rkward/plugins/testing/matrix1.js (rev 0)
+++ trunk/rkward/rkward/plugins/testing/matrix1.js 2012-10-30 18:37:23 UTC (rev 4400)
@@ -0,0 +1,11 @@
+function calculate () {
+ echo ("Matrix A:\n");
+ echo (getValue ("matrixa.cbind"));
+ echo ("\nMatrix B:\n");
+ echo (getValue ("matrixb.cbind"));
+ echo ("\nMatrix C:\n");
+ echo (getValue ("matrixc.cbind"));
+ echo ("\nMatrix C, column 2:\n");
+ echo (getValue ("matrixc.2"));
+}
+
Added: trunk/rkward/rkward/plugins/testing/matrix1.xml
===================================================================
--- trunk/rkward/rkward/plugins/testing/matrix1.xml (rev 0)
+++ trunk/rkward/rkward/plugins/testing/matrix1.xml 2012-10-30 18:37:23 UTC (rev 4400)
@@ -0,0 +1,33 @@
+<!DOCTYPE rkplugin>
+
+<document>
+ <code file="matrix1.js"/>
+
+ <logic>
+ <connect governor="c_rows.int" client="matrixc.rows"/>
+ <connect governor="c_columns.int" client="matrixc.columns"/>
+ </logic>
+
+ <dialog label="Testing Matrix input element">
+ <text id="text">
+ This plugin is bogus! Do not use!
+ </text>
+ <tabbook>
+ <tab label="User resizable matrix">
+ <matrix id="matrixa" allow_missings="false" mode="string" label="Enter data"/>
+ </tab>
+ <tab label="User resizable vector">
+ <row>
+ <matrix id="matrixb" mode="real" columns="1" allow_user_resize_columns="false" label="Enter data (0.0 .. 1.0)" min="0" max="1"/>
+ <stretch/>
+ </row>
+ </tab>
+ <tab label="Dimension controlled matrix">
+ <spinbox id="c_rows" type="integer" min="0" label="Number of rows" initial="3"/>
+ <spinbox id="c_columns" type="integer" min="0" label="Number of columns" initial="4"/>
+ <matrix id="matrixc" allow_user_resize_columns="false" allow_user_resize_rows="false" mode="integer" min="1" max="10" allow_missings="true" label="Enter data (integer 1 to 10 or missing)"/>
+ </tab>
+ </tabbook>
+ </dialog>
+
+</document>
Modified: trunk/rkward/rkward/plugins/under_development.pluginmap
===================================================================
--- trunk/rkward/rkward/plugins/under_development.pluginmap 2012-10-30 15:59:36 UTC (rev 4399)
+++ trunk/rkward/rkward/plugins/under_development.pluginmap 2012-10-30 18:37:23 UTC (rev 4400)
@@ -10,6 +10,7 @@
<component type="standard" id="qtscript_test1" file="testing/test1.xml" label="QtScript Test 1" />
<component type="standard" id="qtscript_test2" file="testing/test2.xml" label="QtScript Test 2" />
<component type="standard" id="optionset_test" file="testing/optionset.xml" label="Optionset Test" />
+ <component type="standard" id="matrix_test1" file="testing/matrix1.xml" label="Input Matrix Test" />
<!-- End -->
<component type="standard" id="import_xls" file="00saveload/import/import_xls.xml" label="Import MS EXCEL">
@@ -36,6 +37,7 @@
<entry component="simple_anova" index="9"/>
<entry component="qtscript_test1" index="1"/>
<entry component="optionset_test" index="1"/>
+ <entry component="matrix_test1" index="1"/>
</menu>
<menu id="plots" label="Plots" index="5">
<entry component="sieve_plot" />
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