[rkward-cvs] SF.net SVN: rkward: [2190] branches/KDE4_port/rkward
tfry at users.sourceforge.net
tfry at users.sourceforge.net
Thu Nov 8 23:23:15 UTC 2007
Revision: 2190
http://rkward.svn.sourceforge.net/rkward/?rev=2190&view=rev
Author: tfry
Date: 2007-11-08 15:23:14 -0800 (Thu, 08 Nov 2007)
Log Message:
-----------
After a lot of butchering, the data editor can be compiled again, but opening an editor crashes right away...
Modified Paths:
--------------
branches/KDE4_port/rkward/core/rcontainerobject.cpp
branches/KDE4_port/rkward/core/rkvariable.cpp
branches/KDE4_port/rkward/dataeditor/editlabelsdialog.cpp
branches/KDE4_port/rkward/dataeditor/editlabelsdialog.h
branches/KDE4_port/rkward/dataeditor/rkeditordataframe.cpp
branches/KDE4_port/rkward/dataeditor/rkeditordataframe.h
branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.cpp
branches/KDE4_port/rkward/dataeditor/rktextmatrix.cpp
branches/KDE4_port/rkward/dataeditor/rktextmatrix.h
branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp
branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h
branches/KDE4_port/rkward/dataeditor/twintable.cpp
branches/KDE4_port/rkward/dataeditor/twintable.h
branches/KDE4_port/rkward/dataeditor/twintabledatamember.cpp
branches/KDE4_port/rkward/dataeditor/twintabledatamember.h
branches/KDE4_port/rkward/dataeditor/twintablemember.cpp
branches/KDE4_port/rkward/dataeditor/twintablemember.h
branches/KDE4_port/rkward/dataeditor/twintablemetamember.cpp
branches/KDE4_port/rkward/dataeditor/twintablemetamember.h
branches/KDE4_port/rkward/windows/rkworkplace.cpp
Modified: branches/KDE4_port/rkward/core/rcontainerobject.cpp
===================================================================
--- branches/KDE4_port/rkward/core/rcontainerobject.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/core/rcontainerobject.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -408,6 +408,8 @@
}
if (!unique) return ret;
+// NOTE: this is potentially a quadratic time algorithm with respect to number of children.
+// Its only called on user actions, though, and hopefully users will not keep all objects named "varX".
int i=0;
QString postfix;
while (findChildByName (ret + postfix)) {
Modified: branches/KDE4_port/rkward/core/rkvariable.cpp
===================================================================
--- branches/KDE4_port/rkward/core/rkvariable.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/core/rkvariable.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -648,7 +648,7 @@
RK_ASSERT (from_row <= to_row);
QString *ret = new QString[(to_row - from_row) + 1];
-
+
int i = 0;
for (int row = from_row; row <= to_row; ++row) {
ret[i] = getText (row);
Modified: branches/KDE4_port/rkward/dataeditor/editlabelsdialog.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/editlabelsdialog.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/editlabelsdialog.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -2,7 +2,7 @@
editlabelsdialog - description
-------------------
begin : Tue Sep 21 2004
- copyright : (C) 2004, 2006 by Thomas Friedrichsmeier
+ copyright : (C) 2004, 2006, 2007 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -22,200 +22,201 @@
#include <kactioncollection.h>
#include <kvbox.h>
-#include <qapplication.h>
-#include <qclipboard.h>
#include <qlabel.h>
#include <qlayout.h>
-#include <qpushbutton.h>
-#include <qpainter.h>
-#include <qrect.h>
-#include <qpalette.h>
-#include <qstyle.h>
+#include <QHeaderView>
//Added by qt3to4:
-#include <Q3HBoxLayout>
-#include <QResizeEvent>
-#include <Q3VBoxLayout>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
#include "../core/rkvariable.h"
+#include "rktextmatrix.h"
#include "celleditor.h"
#include "../debug.h"
-LevelsTable::LevelsTable (QWidget *parent, RObject::ValueLabels *labels) : TwinTableMember (parent, 0, 1, 0) {
+RKVarLevelsTable::RKVarLevelsTable (QWidget *parent, RObject::ValueLabels *labels) : QTableView (parent) {
RK_TRACE (EDITOR);
RK_ASSERT (labels);
- storage = labels;
- updating_size = false;
-
- setNumCols (1);
- setNumRows (storage->count () + 1);
- horizontalHeader ()->setLabel (0, i18n ("Label"));
- setHScrollBarMode (Q3ScrollView::AlwaysOff);
- setLeftMargin (40);
+ setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
+ setSelectionMode (QAbstractItemView::ContiguousSelection);
+ horizontalHeader ()->setStretchLastSection (true);
+ verticalHeader ()->setFixedWidth (40);
setMinimumWidth (80);
KActionCollection *ac = new KActionCollection (this);
ac->addAction (KStandardAction::Cut, this, SLOT (cut ()));
ac->addAction (KStandardAction::Copy, this, SLOT (copy ()));
ac->addAction (KStandardAction::Paste, this, SLOT (paste ()));
+
+ setModel (lmodel = new RKVarLevelsTableModel (labels, this));
}
-LevelsTable::~LevelsTable () {
+RKVarLevelsTable::~RKVarLevelsTable () {
RK_TRACE (EDITOR);
}
-void LevelsTable::cut () {
+bool RKVarLevelsTable::getSelectionBoundaries (int* top, int* bottom) const {
RK_TRACE (EDITOR);
+ RK_ASSERT (selectionModel ());
+ QItemSelection sel = selectionModel ()->selection ();
+ if (sel.isEmpty ()){
+ QModelIndex current = currentIndex ();
+ if (!current.isValid ()) return false;
+
+ *top = current.row ();
+ *bottom = current.row ();
+ } else {
+ RK_ASSERT (sel.size () == 1);
+ *top = sel[0].top ();
+ *bottom = sel[0].bottom ();
+ }
+ return true;
+}
+
+void RKVarLevelsTable::cut () {
+ RK_TRACE (EDITOR);
+
+ int top;
+ int bottom;
+ if (!getSelectionBoundaries (&top, &bottom)) return;
+
copy ();
- blankSelected ();
+
+ for (int i = top; i <= bottom; ++i) lmodel->setData (lmodel->index (i, 0), QString ());
}
-void LevelsTable::paste () {
+void RKVarLevelsTable::copy () {
RK_TRACE (EDITOR);
-// Unfortunately, we need to duplicate some of TwinTable::paste () and RKEditorDataFramPart::doPaste. Those are not easy to reconcile.
+ int top;
+ int bottom;
+ if (!getSelectionBoundaries (&top, &bottom)) return;
- // actually, we don't care, whether tsv or plain gets pasted - it's both
- // treated the same. We should however encourage external senders to
- // provided the two in order.
- QString pasted;
- const QMimeData* data = QApplication::clipboard ()->mimeData ();
- if (data->hasFormat ("text/tab-separated-values")) {
- pasted = QString::fromLocal8Bit (data->data ("text/tab-separated-values"));
- } else if (data->hasText ()) {
- pasted = data->text ();
- } else {
- RK_DO (qDebug ("no suitable format for pasting"), EDITOR, DL_INFO);
- return;
+ RKTextMatrix mat;
+ int trow = 0;
+ for (int i = top; i <= bottom; ++i) {
+ mat.setText (trow++, 0, lmodel->data (lmodel->index (i, 0)).toString ());
}
+ mat.copyToClipboard ();
+}
- int content_offset = 0;
- int content_length = pasted.length ();
- bool look_for_tabs; // break on tabs or on lines?
- int next_delim;
+void RKVarLevelsTable::paste () {
+ RK_TRACE (EDITOR);
- int first_tab = pasted.find ('\t', 0);
- if (first_tab < 0) first_tab = content_length;
- int first_line = pasted.find ('\n', 0);
- if (first_line < 0) first_line = content_length;
- if (first_tab < first_line) {
- look_for_tabs = true;
- next_delim = first_tab;
- } else {
- look_for_tabs = false;
- next_delim = first_line;
- }
+// Unfortunately, we need to duplicate some of TwinTable::paste () and RKEditorDataFramPart::doPaste. Those are not easy to reconcile.
+ QModelIndex current = currentIndex ();
+ if (!current.isValid ()) return;
+ int row = current.row ();
+ RK_ASSERT (current.column () == 0);
- int row = currentRow ();
- do {
- if (row >= numTrueRows ()) insertRows (row);
- setText (row, 0, pasted.mid (content_offset, next_delim - content_offset));
+ RKTextMatrix pasted = RKTextMatrix::matrixFromClipboard ();
+ if (pasted.isEmpty ()) return;
- ++row;
- content_offset = next_delim + 1;
- if (look_for_tabs) {
- next_delim = pasted.find ('\t', content_offset);
- } else {
- next_delim = pasted.find ('\n', content_offset);
+ if (pasted.numColumns () > 1) { // there were tabs in the pasted text. Let's transpose the first row
+ for (int i = 0; i < pasted.numColumns (); ++i) {
+ lmodel->setData (lmodel->index (row++, 0), pasted.getText (0, i));
}
- if (next_delim < 0) next_delim = content_length;
- } while (content_offset < content_length);
+ } else { // else paste the first column
+ for (int i = 0; i < pasted.numRows (); ++i) {
+ lmodel->setData (lmodel->index (row++, 0), pasted.getText (i, 0));
+ }
+ }
}
-void LevelsTable::setText (int row, int col, const QString &text) {
+/////////////// RKVarLevelsTableModel /////////////////
+
+RKVarLevelsTableModel::RKVarLevelsTableModel (RObject::ValueLabels* labels, QObject* parent) : QAbstractTableModel (parent) {
RK_TRACE (EDITOR);
- RK_ASSERT (col == 0);
- storage->insert (QString::number (row+1), text);
- if (text.isEmpty ()) {
- int maxrow = numTrueRows ()-1;
- while ((maxrow >= 0) && LevelsTable::text (maxrow, 1).isEmpty ()) {
- storage->remove (QString::number (maxrow + 1));
- --maxrow;
- }
- setNumRows (maxrow + 2);
- }
+ RKVarLevelsTableModel::labels = labels;
+}
- updateCell (row, col);
+RKVarLevelsTableModel::~RKVarLevelsTableModel () {
+ RK_TRACE (EDITOR);
}
-QString LevelsTable::text (int row, int) const {
+int RKVarLevelsTableModel::rowCount (const QModelIndex& parent) const {
RK_TRACE (EDITOR);
- if (row < numTrueRows ()) {
- return ((*storage)[QString::number (row+1)]);
- }
- return QString ();
+ if (parent.isValid ()) return 0;
+ return labels->count () + 1;
}
-void LevelsTable::paintCell (QPainter *p, int row, int col, const QRect &cr, bool selected, const QColorGroup &cg) {
- // no trace for paint operations
+int RKVarLevelsTableModel::columnCount (const QModelIndex& parent) const {
+ RK_TRACE (EDITOR);
- paintCellInternal (p, row, col, cr, selected, cg, 0, 0, text (row, col), 0);
+ if (parent.isValid ()) return 0;
+ return 1;
}
-QWidget *LevelsTable::beginEdit (int row, int col, bool) {
+QVariant RKVarLevelsTableModel::data (const QModelIndex& index, int role) const {
RK_TRACE (EDITOR);
- RK_ASSERT (!tted);
- if (col != 0) return 0;
+ if (!index.isValid ()) return QVariant ();
+ if (index.column () != 0) return QVariant ();
+ if ((role == Qt::BackgroundRole) && (index.row () == labels->count ())) return QBrush (Qt::gray);
+ if (index.row () >= labels->count ()) return QVariant ();
- if (row >= numTrueRows ()) {
- insertRows (numRows (), 1);
- }
-
- tted = new CellEditor (this, text (row, col), 0, 0);
+ if ((role != Qt::DisplayRole) || (role != Qt::EditRole)) return QVariant ();
- QRect cr = cellGeometry (row, col);
- tted->resize (cr.size ());
- moveChild (tted, cr.x (), cr.y ());
- tted->show ();
-
- tted->setActiveWindow ();
- tted->setFocus ();
- connect (tted, SIGNAL (lostFocus ()), this, SLOT (editorLostFocus ()));
-
- updateCell (row, col);
- return (tted);
+ return labels->value (QString::number (index.row ()+1));
}
-void LevelsTable::resizeEvent (QResizeEvent *e) {
+Qt::ItemFlags RKVarLevelsTableModel::flags (const QModelIndex& index) const {
RK_TRACE (EDITOR);
- updating_size = true;
- int nwidth = e->size ().width () - leftMargin ();
- if (nwidth < 40) {
- setLeftMargin (e->size ().width () - 40);
- nwidth = 40;
- }
- setColumnWidth (0, nwidth);
- updating_size = false;
-
- Q3Table::resizeEvent (e);
+ if (!index.isValid ()) return 0;
+ if (index.column () != 0) return 0;
+ if (index.row () >= labels->count ()) return (Qt::ItemIsEditable | Qt::ItemIsEnabled);
+ return (Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
-void LevelsTable::columnWidthChanged (int col) {
+bool RKVarLevelsTableModel::setData (const QModelIndex& index, const QVariant& value, int role) {
RK_TRACE (EDITOR);
- if (updating_size) return;
+ if (role != Qt::EditRole) return false;
+ if (!index.isValid ()) return false;
+ if (index.column () != 0) return false;
+ if (!value.isValid ()) return false;
+ if (index.row () > labels->count ()) return false;
- updating_size = true;
+ QString text = value.toString ();
+ if (index.row () == labels->count ()) {
+ beginInsertRows (QModelIndex (), index.row (), index.row ());
+ labels->insert (QString::number (index.row () + 1), value.toString ());
+ endInsertRows ();
+ } else {
+ labels->insert (QString::number (index.row () + 1), value.toString ());
+ emit (dataChanged (index, index));
+ }
- if (columnWidth (0) < 40) {
- setColumnWidth (0, 40);
+ if (text.isEmpty ()) { // remove trailing empty rows
+ while ((!labels->isEmpty ()) && labels->value (QString::number (labels->size ())).isEmpty ()) {
+ int row = labels->size () - 1;
+ beginRemoveRows (QModelIndex (), row, row);
+ labels->remove (QString::number (row + 1));
+ endRemoveRows ();
+ }
}
- setLeftMargin (width () - columnWidth (0));
- updating_size = false;
-
- Q3Table::columnWidthChanged (col);
+ return true;
}
+QVariant RKVarLevelsTableModel::headerData (int section, Qt::Orientation orientation, int role) const {
+ RK_TRACE (EDITOR);
+ if (role != Qt::DisplayRole) return QVariant ();
+ if (orientation == Qt::Vertical) return QString::number (section + 1);
+ if (section != 0) return QVariant ();
+ return i18n ("Label");
+}
+//////////////// EditLabelsDialog ///////////////////////
+
EditLabelsDialog::EditLabelsDialog (QWidget *parent, RKVariable *var, int mode) : KDialog (parent) {
RK_TRACE (EDITOR);
RK_ASSERT (var);
@@ -229,26 +230,14 @@
QLabel *label = new QLabel (i18n ("Levels can be assigned only to consecutive integers starting with 1 (the index column is read only). To remove levels at the end of the list, just set them to empty."), mainvbox);
label->setWordWrap (true);
- Q3HBoxLayout *hbox = new Q3HBoxLayout (mainvbox, KDialog::spacingHint ());
-
RObject::ValueLabels *labels = var->getValueLabels ();
if (!labels) {
labels = new RObject::ValueLabels;
}
- table = new LevelsTable (this, labels);
- hbox->addWidget (table);
+ table = new RKVarLevelsTable (mainvbox, labels);
- Q3HBoxLayout *buttonbox = new Q3HBoxLayout (mainvbox, KDialog::spacingHint ());
-
- QPushButton *ok_button = new QPushButton (i18n ("Ok"), this);
- connect (ok_button, SIGNAL (clicked ()), this, SLOT (accept ()));
- buttonbox->addWidget (ok_button);
-
- QPushButton *cancel_button = new QPushButton (i18n ("Cancel"), this);
- connect (cancel_button, SIGNAL (clicked ()), this, SLOT (reject ()));
- buttonbox->addWidget (cancel_button);
-
+ setButtons (KDialog::Ok | KDialog::Cancel);
setCaption (i18n ("Levels / Value labels for '%1'", var->getShortName ()));
}
@@ -259,8 +248,10 @@
void EditLabelsDialog::accept () {
RK_TRACE (EDITOR);
- table->stopEditing ();
- RObject::ValueLabels *labels = table->storage;
+#warning do we need something like this? how to achieve it?
+// table->stopEditing ();
+
+ RObject::ValueLabels *labels = table->lmodel->labels;
if (labels->isEmpty ()) {
var->setValueLabels (0);
} else {
Modified: branches/KDE4_port/rkward/dataeditor/editlabelsdialog.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/editlabelsdialog.h 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/editlabelsdialog.h 2007-11-08 23:23:14 UTC (rev 2190)
@@ -2,7 +2,7 @@
editlabelsdialog - description
-------------------
begin : Tue Sep 21 2004
- copyright : (C) 2004, 2006 by Thomas Friedrichsmeier
+ copyright : (C) 2004, 2006, 2007 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -18,49 +18,56 @@
#define EDITLABELSDIALOG_H
#include <kdialog.h>
-//Added by qt3to4:
-#include <QResizeEvent>
+#include <QTableView>
+#include <QAbstractTableModel>
+
#include "../core/robject.h"
class RKVariable;
+class RKVarLevelsTableModel;
-#include "twintablemember.h"
-
/** special mini class provides the table in EditLabelsDialog
TODO: make copy/paste work
@author Thomas Friedrichsmeier
*/
-class LevelsTable : public TwinTableMember {
+class RKVarLevelsTable : public QTableView {
Q_OBJECT
public:
- LevelsTable (QWidget *parent, RObject::ValueLabels *labels);
- ~LevelsTable ();
-/** reimplemented form QTable not to add trailing rows/cols if needed */
- QWidget *beginEdit (int row, int col, bool replace);
-/** reimplemented form QTable to work on RObject::ValueLabels instead of QTableItems */
- void paintCell (QPainter *p, int row, int col, const QRect &cr, bool selected, const QColorGroup &cg);
-/** reimplemented form QTable to work on RObject::ValueLabels instead of QTableItems */
- void setText (int row, int col, const QString &text);
-/** reimplemented form QTable to work on RObject::ValueLabels instead of QTableItems */
- QString text (int row, int col) const;
+ RKVarLevelsTable (QWidget *parent, RObject::ValueLabels *labels);
+ ~RKVarLevelsTable ();
public slots:
/** cut */
- void cut();
+ void cut ();
+/** cut */
+ void copy ();
/** paste */
- void paste();
-protected:
-/** reimplemented to resize the table columns so that there's no unused space to the right */
- void resizeEvent (QResizeEvent *e);
-/** reimplemented to resize the table columns so that there's no unused space to the right */
- void columnWidthChanged (int col);
+ void paste ();
private:
+ bool getSelectionBoundaries (int* top, int* bottom) const;
friend class EditLabelsDialog;
- RObject::ValueLabels *storage;
+ RKVarLevelsTableModel* lmodel;
bool updating_size;
};
+/** Data model for the RKVarLevelsTable */
+class RKVarLevelsTableModel : public QAbstractTableModel {
+public:
+ RKVarLevelsTableModel (RObject::ValueLabels* labels, QObject* parent);
+ ~RKVarLevelsTableModel ();
+
+ int rowCount (const QModelIndex& parent = QModelIndex()) const;
+ int columnCount (const QModelIndex& parent = QModelIndex()) const;
+ QVariant data (const QModelIndex& index, int role = Qt::DisplayRole) const;
+ Qt::ItemFlags flags (const QModelIndex& index) const;
+ bool setData (const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
+ QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+private:
+friend class EditLabelsDialog;
+ RObject::ValueLabels* labels;
+};
+
/**
Allows editing of value labels / factor levels for an (edited) RKVariable
@@ -80,7 +87,7 @@
/// reimplemented to submit the changes to the backend
void accept ();
private:
- LevelsTable *table;
+ RKVarLevelsTable *table;
RKVariable *var;
int mode;
};
Modified: branches/KDE4_port/rkward/dataeditor/rkeditordataframe.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkeditordataframe.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/rkeditordataframe.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -23,13 +23,11 @@
#include "../rkglobals.h"
#include "twintable.h"
#include "twintablemember.h"
-#include "twintabledatamember.h"
-#include "twintablemetamember.h"
+#include "rkvareditmodel.h"
#include "../core/robject.h"
#include "../core/robjectlist.h"
#include "../core/rkvariable.h"
#include "../core/rcontainerobject.h"
-#include "../core/rkmodificationtracker.h"
#include "rkeditordataframepart.h"
#include "../windows/rkworkplace.h"
#include "../misc/rkstandardicons.h"
@@ -40,13 +38,19 @@
// warning! numbers above GET_DATA_OFFSET are used to determine, which row, the data should go to!
#define GET_DATA_OFFSET 10
-RKEditorDataFrame::RKEditorDataFrame (RObject* object, QWidget *parent) : TwinTable (parent) {
+RKEditorDataFrame::RKEditorDataFrame (RContainerObject* object, QWidget *parent) : TwinTable (parent) {
RK_TRACE (EDITOR);
commonInit ();
RK_ASSERT (!object->isPending ());
- openObject (object);
+ RKEditor::object = object;
+ RK_ASSERT (object->isDataFrame ());
+
+ RKVarEditDataFrameModel* model = new RKVarEditDataFrameModel (object, this);
+ initTable (model);
+
+ waitForLoad ();
}
RKEditorDataFrame::RKEditorDataFrame (const QString& new_object_name, QWidget* parent) : TwinTable (parent) {
@@ -56,21 +60,15 @@
QString valid = RObjectList::getObjectList ()->validizeName (new_object_name);
if (valid != new_object_name) KMessageBox::sorry (this, i18n ("The name you specified was already in use or not valid. Renamed to %1", valid), i18n ("Invalid Name"));
- RObject *object = RObjectList::getObjectList ()->createPendingChild (valid, -1, true, true);
-// initialize the new object
-#warning TODO: call model->insertColumns() instead.
- for (int i=0; i < numTrueCols (); ++i) {
- RObject *child = static_cast<RContainerObject *> (object)->createPendingChild (static_cast<RContainerObject *> (object)->validizeName (QString ()), i);
- if (child->isVariable ()) {
- static_cast<RKVariable*> (child)->setLength (dataview->numTrueRows ());
- } else {
- RK_ASSERT (false);
- }
- }
- pushTable (open_chain);
+ RKVarEditDataFrameModel* model = new RKVarEditDataFrameModel (valid, RObjectList::getObjectList (), open_chain, 5, this);
+ initTable (model);
- openObject (object);
+ RKEditor::object = model->getObject ();;
+ RK_ASSERT (object->isDataFrame ());
+
+#warning is this needed? Of is it enough to close the chain?
+ waitForLoad ();
}
void RKEditorDataFrame::commonInit () {
@@ -89,10 +87,10 @@
if (on) {
connect (this, SIGNAL (deleteColumnRequest (int)), this, SLOT (columnDeletionRequested (int)));
connect (this, SIGNAL (addedColumn (int)), this, SLOT (columnAdded (int)));
- varview->setEnabled (true);
+ metaview->setEnabled (true);
dataview->setEnabled (true);
} else {
- varview->setEnabled (false);
+ metaview->setEnabled (false);
dataview->setEnabled (false);
disconnect (this, SIGNAL (deleteColumnRequest (int)), this, SLOT (columnDeletionRequested (int)));
disconnect (this, SIGNAL (addedColumn (int)), this, SLOT (columnAdded (int)));
@@ -108,18 +106,12 @@
flushEdit ();
}
-void RKEditorDataFrame::openObject (RObject *object) {
+void RKEditorDataFrame::waitForLoad () {
RK_TRACE (EDITOR);
flushEdit ();
- RKEditor::object = object;
- RK_ASSERT (object->isDataFrame ());
enableEditing (false);
- // trigger fetching of the edit data
- object->markDataDirty ();
- object->updateFromR (open_chain);
-
RCommand *command = new RCommand (QString (), RCommand::EmptyCommand | RCommand::Sync | RCommand::GetStringVector, QString (), this, LOAD_COMPLETE_COMMAND);
RKGlobals::rInterface ()->issueCommand (command, open_chain);
}
@@ -135,72 +127,11 @@
}
}
-void RKEditorDataFrame::pushTable (RCommandChain *sync_chain) {
- RK_TRACE (EDITOR);
- flushEdit ();
- QString command;
-#warning TODO: move to model
- // first push the data-table
- TwinTableMember *table = dataview;
- command = getObject ()->getFullName ();
- command.append (" <- data.frame (");
-
- QString na_vector = "=as.numeric (rep (NA, " + QString::number (getColObject (0)->getLength ()) + "))";
- for (int col=0; col < table->numTrueCols (); col++) {
- if (col != 0) command.append (", ");
- command.append (getColObject (col)->getShortName () + na_vector);
- }
- command.append (")");
-
- RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Sync | RCommand::ObjectListUpdate), sync_chain);
- for (int col=0; col < table->numTrueCols (); col++) {
- getColObject (col)->restore (sync_chain);
- }
-
- // now store the meta-data
- getObject ()->writeMetaData (sync_chain);
-}
-
-void RKEditorDataFrame::columnDeletionRequested (int col) {
- RK_TRACE (EDITOR);
- RObject *obj = getColObject (col);
- RK_ASSERT (obj);
- // for now:
- if (!obj) return;
-
- RKGlobals::tracker ()->removeObject (obj);
-}
-
void RKEditorDataFrame::restoreObject (RObject *object) {
RK_TRACE (EDITOR);
- // for now, simply sync the whole table unconditionally.
- if (object == getObject ()) {
- pushTable (0);
- } else {
- RK_ASSERT (object->isVariable ());
- static_cast<RKVariable*> (object)->restore ();
- }
-}
-void RKEditorDataFrame::updateObjectMeta (RObject *object) {
- RK_TRACE (EDITOR);
- if (object == getObject ()) return; // for now: can't update meta on the table itself
-
- int col = getObjectCol (object);
- for (int i=0; i < varview->numTrueRows (); ++i) {
- varview->updateCell (i, col);
- }
+#warning TODO: this interface should be moved to the model for good.
+ datamodel->restoreObject (object, 0);
}
-void RKEditorDataFrame::updateObjectData (RObject *object, RObject::ChangeSet *changes) {
- RK_TRACE (EDITOR);
-
- if (object != getObject ()) {
- int col = getObjectCol (object);
- for (int i=0; i < dataview->numTrueRows (); ++i) {
- dataview->updateCell (i, col);
- }
- }
-}
-
#include "rkeditordataframe.moc"
Modified: branches/KDE4_port/rkward/dataeditor/rkeditordataframe.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkeditordataframe.h 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/rkeditordataframe.h 2007-11-08 23:23:14 UTC (rev 2190)
@@ -31,12 +31,11 @@
@author Thomas Friedrichsmeier
*/
class RKEditorDataFrame : public TwinTable, public RCommandReceiver {
- Q_OBJECT
public:
/** constructor.
@param object an existing R object
@param parent parent widget */
- RKEditorDataFrame (RObject* object, QWidget *parent);
+ RKEditorDataFrame (RContainerObject* object, QWidget *parent);
/** This constructor creates a new (empty) data.frame with the given name and then opens it for editing.
@param new_object_name name of the new data.frame
@param parent parent widget */
@@ -51,23 +50,14 @@
/** Tells the editor to restore the given object in the R-workspace from its copy of the data */
void restoreObject (RObject *object);
-/** Tell the editor to (unconditionally) update its representation of the object meta data */
- void updateObjectMeta (RObject *object);
-/** Tell the editor to (unconditionally) update its representation of the object data (in the range given in the ChangeSet) */
- void updateObjectData (RObject *object, RObject::ChangeSet *changes);
-public slots:
- void columnDeletionRequested (int col);
private:
/// syncs the whole table.
void pushTable (RCommandChain *sync_chain);
void commonInit ();
RCommandChain *open_chain;
void enableEditing (bool on);
- void updateMetaValue (RObject *obj, int row, int col, bool sync=true);
-
- void modifyObjectMeta (RObject *object, int column);
+ void waitForLoad ();
protected:
- void openObject (RObject *object);
void rCommandDone (RCommand *command);
};
Modified: branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/rkeditordataframepart.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -103,17 +103,7 @@
RKWardMainWindow::getMain ()->slotSetStatusBarText (i18n ("Inserting clipboard contents..."));
- const QMimeData* data = QApplication::clipboard ()->mimeData ();
- // actually, we don't care, whether tsv or plain gets pasted - it's both
- // treated the same. We should however encourage external senders to
- // provided the two in order.
- if (data->hasFormat ("text/tab-separated-values")) {
- RK_DO (qDebug ("paste tsv"), EDITOR, DL_DEBUG);
- editor->paste (QString::fromLocal8Bit (data->data ("text/tab-separated-values")), mode);
- } else if (data->hasText ()) {
- RK_DO (qDebug ("paste plain text"), EDITOR, DL_DEBUG);
- editor->paste (data->text (), mode);
- }
+ editor->paste (mode);
RKWardMainWindow::getMain ()->slotSetStatusReady ();
}
Modified: branches/KDE4_port/rkward/dataeditor/rktextmatrix.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rktextmatrix.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/rktextmatrix.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -144,18 +144,15 @@
return (columns[col][row]);
}
-QString* RKTextMatrix::getColumn (int col, int* col_length) const {
+QString* RKTextMatrix::getColumn (int col) const {
RK_TRACE (EDITOR);
if (col > colcount) {
- *col_length = 0;
return 0;
}
TextColumn column = columns[col];
QString* ret = new QString[column.size ()];
- *col_length = column.size ();
- RK_ASSERT (*col_length == rowcount);
for (int i = 0; i < column.size (); ++i) {
ret[i] = column[i];
}
Modified: branches/KDE4_port/rkward/dataeditor/rktextmatrix.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rktextmatrix.h 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/rktextmatrix.h 2007-11-08 23:23:14 UTC (rev 2190)
@@ -39,13 +39,18 @@
void copyToClipboard () const;
void setText (int row, int col, const QString& text);
+ /** set an entire column at once. This takes a copy of the data, so you will still have to delete it when done. */
void setColumn (int column, const QString* textarray, int length);
QString getText (int row, int col) const;
- QString* getColumn (int col, int* col_length) const;
+ /** get the contents of an entire column at once. It's your responsibility to delete the data when done. The returned array has length numRows() */
+ QString* getColumn (int col) const;
void clear ();
bool isEmpty () const;
+
+ int numColumns () const { return colcount; }
+ int numRows () const { return rowcount; }
private:
typedef QVector<QString> TextColumn;
QVector<TextColumn> columns;
Modified: branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/rkvareditmodel.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -26,7 +26,7 @@
#include "../debug.h"
-RKVarEditModel::RKVarEditModel (QObject *parent) : QAbstractTableModel (parent), RObjectListener (RObjectListener::DataModel) {
+RKVarEditModel::RKVarEditModel (QObject *parent) : RKVarEditModelBase (parent), RObjectListener (RObjectListener::DataModel) {
RK_TRACE (EDITOR);
meta_model = 0;
@@ -75,7 +75,7 @@
}
}
-void RKVarEditModel::doInsertColumn (int) {
+void RKVarEditModel::doInsertColumns (int, int) {
RK_TRACE (EDITOR);
RK_ASSERT (false); // should be implemented in a subclass, or never called
}
@@ -233,7 +233,7 @@
if (col >= objects.size ()) { // trailing col
// somebody should add a column for us
- doInsertColumn (objects.size ());
+ doInsertColumns (objects.size (), 1);
if (col >= objects.size ()) {
// apparently, no column has been added in the above signal
@@ -264,10 +264,95 @@
return QString::number (section);
}
+RKTextMatrix RKVarEditModel::getTextMatrix (const QItemSelectionRange& range) const {
+ RK_TRACE (EDITOR);
+ if ((!range.isValid ()) || objects.isEmpty ()) return RKTextMatrix ();
+
+// NOTE: of course, when the range is small, this is terribly inefficient. On the other hand, it doesn't really matter, then, either.
+ QItemSelectionRange erange = range.intersected (QItemSelectionRange (index (0, 0), index (trueRows () - 1, trueCols () - 1)));
+ int top = erange.top ();
+ int bottom = erange.bottom ();
+ int left = erange.left ();
+ int right = erange.right ();
+
+ RKTextMatrix ret;
+ int tcol = 0;
+ for (int col = left; col <= right; ++col) {
+ QString* data = objects[col]->getCharacter (top, bottom);
+ RK_ASSERT (data);
+ ret.setColumn (tcol, data, top - bottom + 1);
+ delete [] data;
+ ++tcol;
+ }
+
+ return ret;
+}
+
+void RKVarEditModel::blankRange (const QItemSelectionRange& range) {
+ RK_TRACE (EDITOR);
+
+ if ((!range.isValid ()) || objects.isEmpty ()) return;
+
+// NOTE: of course, when the range is small, this is terribly inefficient. On the other hand, it doesn't really matter, then, either.
+ QItemSelectionRange erange = range.intersected (QItemSelectionRange (index (0, 0), index (trueRows () - 1, trueCols () - 1)));
+ int top = erange.top ();
+ int bottom = erange.bottom ();
+ int left = erange.left ();
+ int right = erange.right ();
+
+ for (int col = left; col <= right; ++col) {
+ RKVariable* var = objects[col];
+ for (int row = top; row <= bottom; ++row) {
+ var->setText (row, QString ());
+ }
+ }
+}
+
+void RKVarEditModel::setTextMatrix (const QModelIndex& offset, const RKTextMatrix& text, const QItemSelectionRange& confine_to) {
+ RK_TRACE (EDITOR);
+
+// NOTE: of course, when the range is small, this is terribly inefficient. On the other hand, it doesn't really matter, then, either. Single cells will be set using setData()
+ if ((!offset.isValid ()) || text.isEmpty ()) return;
+
+ int top = offset.row ();
+ int left = offset.column ();
+ int bottom = top + text.numRows () - 1;
+ int right = left + text.numColumns () - 1;
+ if (confine_to.isValid ()) {
+ if (confine_to.top () > top) return; // can't confine top-left. Should have been set by caller
+ if (confine_to.left () > left) return;
+ bottom = qMin (confine_to.bottom (), bottom);
+ right = qMin (confine_to.right (), right);
+ }
+
+// TODO: some models might not support column addition.
+ if (right >= trueCols ()) doInsertColumns (objects.size (), right - trueCols () + 1);
+ RK_ASSERT (right < trueCols ());
+ int current_rows = objects[0]->getLength ();
+ if (bottom >= current_rows) insertRows (current_rows, bottom - current_rows + 1);
+
+ int tcol = 0;
+ for (int col = left; col <= right; ++col) {
+ RKVariable* var = objects[col];
+ QString* data = text.getColumn (tcol);
+ RK_ASSERT (data);
+ var->setCharacter (top, bottom, data);
+ delete [] data; // hm, why doesn't RKVariable take ownership?
+ ++tcol;
+ }
+}
+
+void RKVarEditModel::restoreObject (RObject* object, RCommandChain* chain) {
+ RK_TRACE (EDITOR);
+
+ RK_ASSERT (objects.contains (static_cast<RKVariable*> (object)));
+ static_cast<RKVariable*> (object)->restore (chain);
+}
+
/////////////////// RKVarEditMetaModel ////////////////////////
-RKVarEditMetaModel::RKVarEditMetaModel (RKVarEditModel* data_model) : QAbstractTableModel (data_model) {
+RKVarEditMetaModel::RKVarEditMetaModel (RKVarEditModel* data_model) : RKVarEditModelBase (data_model) {
RK_TRACE (EDITOR);
RK_ASSERT (data_model);
@@ -382,7 +467,7 @@
if (col >= data_model->objects.size ()) { // trailing col
// somebody should add a column for us
- data_model->doInsertColumn (data_model->objects.size ());
+ data_model->doInsertColumns (data_model->objects.size (), 1);
if (col >= data_model->objects.size ()) {
// apparently, no column has been added in the above signal
@@ -431,13 +516,126 @@
return QVariant ();
}
+RKTextMatrix RKVarEditMetaModel::getTextMatrix (const QItemSelectionRange& range) const {
+ RK_TRACE (EDITOR);
+ if ((!range.isValid ()) || data_model->objects.isEmpty ()) return RKTextMatrix ();
+
+// NOTE: of course, when the range is small, this is terribly inefficient. On the other hand, it doesn't really matter, then, either.
+ QItemSelectionRange erange = range.intersected (QItemSelectionRange (index (0, 0), index (trueRows () - 1, trueCols () - 1)));
+ int top = erange.top ();
+ int bottom = erange.bottom ();
+ int left = erange.left ();
+ int right = erange.right ();
+
+ RKTextMatrix ret;
+ int tcol = 0;
+ for (int col = left; col <= right; ++col) {
+ int trow = 0;
+ for (int row = top; row <= bottom; ++row) {
+ QVariant celldata = data (index (row, col), Qt::EditRole);
+ if (!celldata.isValid ()) {
+ RK_ASSERT (false);
+ break;
+ }
+ ret.setText (trow, tcol, celldata.toString ());
+ ++trow;
+ }
+ ++tcol;
+ }
+
+ return ret;
+}
+
+void RKVarEditMetaModel::blankRange (const QItemSelectionRange& range) {
+ RK_TRACE (EDITOR);
+
+ if ((!range.isValid ()) || data_model->objects.isEmpty ()) return;
+
+// NOTE: of course, when the range is small, this is terribly inefficient. On the other hand, it doesn't really matter, then, either.
+ QItemSelectionRange erange = range.intersected (QItemSelectionRange (index (0, 0), index (trueRows () - 1, trueCols () - 1)));
+ int top = erange.top ();
+ int bottom = erange.bottom ();
+ int left = erange.left ();
+ int right = erange.right ();
+
+ for (int col = left; col <= right; ++col) {
+ RKVariable* var = data_model->objects[col];
+ var->setSyncing (false);
+ for (int row = top; row <= bottom; ++row) {
+ setData (createIndex (row, col), QString (), Qt::EditRole);
+ }
+ var->setSyncing (true);
+ }
+}
+
+void RKVarEditMetaModel::setTextMatrix (const QModelIndex& offset, const RKTextMatrix& text, const QItemSelectionRange& confine_to) {
+ RK_TRACE (EDITOR);
+
+ if ((!offset.isValid ()) || text.isEmpty ()) return;
+
+ int top = offset.row ();
+ int left = offset.column ();
+ int bottom = top + text.numRows () - 1;
+ int right = left + text.numColumns () - 1;
+ if (confine_to.isValid ()) {
+ if (confine_to.top () > top) return; // can't confine top-left. Should have been set by caller
+ if (confine_to.left () > left) return;
+ bottom = qMin (confine_to.bottom (), bottom);
+ right = qMin (confine_to.right (), right);
+ }
+
+// TODO: some models might not support column addition.
+ if (right >= trueCols ()) data_model->doInsertColumns (trueCols (), right - trueCols () + 1);
+ RK_ASSERT (right < data_model->objects.size ());
+ bottom = qMin (bottom, trueRows () - 1);
+
+ int tcol = 0;
+ for (int col = left; col <= right; ++col) {
+ int trow = 0;
+ RKVariable* var = data_model->objects[col];
+ var->setSyncing (false);
+ for (int row = top; row <= bottom; ++row) {
+ setData (index (row, col), text.getText (trow, tcol), Qt::EditRole);
+ ++trow;
+ }
+ var->setSyncing (true);
+ ++tcol;
+ }
+}
+
+
/////////////////// RKVarEditDataFrameModel ////////////////////////
-RKVarEditDataFrameModel::RKVarEditDataFrameModel (RContainerObject* dataframe, QObject *parent) : RKVarEditModel (parent) {
+RKVarEditDataFrameModel::RKVarEditDataFrameModel (RContainerObject* dataframe, QObject* parent) : RKVarEditModel (parent) {
RK_TRACE (EDITOR);
+ init (dataframe);
+}
+
+RKVarEditDataFrameModel::RKVarEditDataFrameModel (const QString& validized_name, RContainerObject* parent_object, RCommandChain* chain, int initial_cols, QObject* parent) : RKVarEditModel (parent) {
+ RK_TRACE (EDITOR);
+
+ RObject *object = parent_object->createPendingChild (validized_name, -1, true, true);
+ RK_ASSERT (object->isDataFrame ());
+ RContainerObject* df = static_cast<RContainerObject*> (object);
+
+// initialize the new object
+ for (int i = 0; i < initial_cols; ++i) {
+ RObject* child = df->createPendingChild (QString (), -1, false, false);
+ RK_ASSERT (child->isVariable ());
+ }
+
+ init (df);
+
+ // creates the pending object in the backend
+ pushTable (chain);
+}
+
+void RKVarEditDataFrameModel::init (RContainerObject* dataframe) {
+ RK_TRACE (EDITOR);
+
RKVarEditDataFrameModel::dataframe = dataframe;
trailing_rows = 1;
@@ -559,10 +757,47 @@
}
}
-void RKVarEditDataFrameModel::doInsertColumn (int index) {
+void RKVarEditDataFrameModel::doInsertColumns (int index, int count) {
RK_TRACE (EDITOR);
- insertColumns (index, 1);
+ insertColumns (index, count);
}
+void RKVarEditDataFrameModel::pushTable (RCommandChain *sync_chain) {
+ RK_TRACE (EDITOR);
+
+ // first push real data
+ QString command = dataframe->getFullName ();
+ command.append (" <- data.frame (");
+
+ RK_ASSERT (objects.size ());
+ RKVariable* child = objects[0];
+ QString na_vector = "=as.numeric (rep (NA, " + QString::number (child->getLength ()) + "))";
+ for (int col=0; col < objects.size (); ++col) {
+ if (col != 0) command.append (", ");
+ command.append (objects[col]->getShortName () + na_vector);
+ }
+ command.append (")");
+
+ // push all children
+ RKGlobals::rInterface ()->issueCommand (new RCommand (command, RCommand::Sync | RCommand::ObjectListUpdate), sync_chain);
+ for (int col=0; col < objects.size (); ++col) {
+ objects[col]->restore (sync_chain);
+ }
+
+ // now store the meta-data
+ dataframe->writeMetaData (sync_chain);
+}
+
+void RKVarEditDataFrameModel::restoreObject (RObject* object, RCommandChain* chain) {
+ RK_TRACE (EDITOR);
+
+ if (object == dataframe) {
+ pushTable (chain);
+ } else {
+ RKVarEditModel::restoreObject (object, chain);
+ }
+}
+
+
#include "rkvareditmodel.moc"
Modified: branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/rkvareditmodel.h 2007-11-08 23:23:14 UTC (rev 2190)
@@ -19,16 +19,34 @@
#define RKVAREDITMODEL
#include <QAbstractTableModel>
+#include <QItemSelectionRange>
#include <QList>
+#include "rktextmatrix.h"
#include "../core/rkvariable.h"
#include "../core/rkmodificationtracker.h"
class RKVarEditMetaModel;
+class RCommandChain;
class RKEditor;
+/** Base class for RKVarEditModel and RKVarEditMetaModel. Defines a common interface for copy and paste operations. Models might reimplement these functions for more efficiency.
+ at author Thomas Friedrichsmeier */
+class RKVarEditModelBase : public QAbstractTableModel {
+public:
+ RKVarEditModelBase (QObject *parent) : QAbstractTableModel (parent) {};
+ virtual ~RKVarEditModelBase () {};
+
+ virtual RKTextMatrix getTextMatrix (const QItemSelectionRange& range) const = 0;
+ virtual void blankRange (const QItemSelectionRange& range) = 0;
+ virtual void setTextMatrix (const QModelIndex& offset, const RKTextMatrix& text, const QItemSelectionRange& confine_to = QItemSelectionRange ()) = 0;
+
+ virtual int trueRows () const = 0;
+ virtual int trueCols () const = 0;
+};
+
/** This class represents a collection of RKVariables of uniform length (typically a data.frame) suitable for editing in a model/view editor such as QTableView. Probably it will only ever support editing a single RKVariable, though, as it is not possible to ensure uniform length outside of a data.frame. For a data.frame use RKVarEditDataFrameModel . Since the real data storage is in RKVariable, it is ok (and recommended) to create separate models for separate editors/viewers, even if the objects in question are the same. */
-class RKVarEditModel : public QAbstractTableModel, public RObjectListener {
+class RKVarEditModel : public RKVarEditModelBase, public RObjectListener {
Q_OBJECT
public:
RKVarEditModel (QObject *parent);
@@ -55,6 +73,15 @@
Qt::ItemFlags flags (const QModelIndex& index) const;
bool setData (const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+
+ RKTextMatrix getTextMatrix (const QItemSelectionRange& range) const;
+ void blankRange (const QItemSelectionRange& range);
+ void setTextMatrix (const QModelIndex& offset, const RKTextMatrix& text, const QItemSelectionRange& confine_to = QItemSelectionRange ());
+
+ int trueCols () const { return objects.size (); };
+ int trueRows () const { return (objects.isEmpty () ? 0 : objects[0]->getLength ()); };
+
+ virtual void restoreObject (RObject* object, RCommandChain* chain);
protected:
friend class RKVarEditMetaModel;
QList<RKVariable*> objects;
@@ -67,8 +94,8 @@
/** Receives notifications of object removals. Takes care of removing the object from the list. */
void objectRemoved (RObject* object);
- /** insert a new column at index. Default implementation does nothing. To be implemented in subclasses */
- virtual void doInsertColumn (int index);
+ /** insert new columns at index. Default implementation does nothing. To be implemented in subclasses */
+ virtual void doInsertColumns (int index, int count);
virtual void doInsertRowsInBackend (int row, int count);
virtual void doRemoveRowsInBackend (int row, int count);
@@ -83,7 +110,7 @@
};
/** Represents the meta information portion belonging to an RKVarEditModel. Implemented in a separate class for technical reasons, only (so this info can be displayed in a separate QTableView). This model mostly acts as a slave of an RKVarEditModel. You will not need to call any functions directly except from the RKVarEditModel, or an item view. */
-class RKVarEditMetaModel : public QAbstractTableModel {
+class RKVarEditMetaModel : public RKVarEditModelBase {
Q_OBJECT
public:
enum Rows {
@@ -102,6 +129,13 @@
Qt::ItemFlags flags (const QModelIndex& index) const;
bool setData (const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+
+ RKTextMatrix getTextMatrix (const QItemSelectionRange& range) const;
+ void blankRange (const QItemSelectionRange& range);
+ void setTextMatrix (const QModelIndex& offset, const RKTextMatrix& text, const QItemSelectionRange& confine_to = QItemSelectionRange ());
+
+ int trueCols () const { return data_model->trueCols (); };
+ int trueRows () const { return RowCount; };
protected:
friend class RKVarEditModel;
RKVarEditMetaModel (RKVarEditModel* data_model);
@@ -119,13 +153,19 @@
class RKVarEditDataFrameModel : public RKVarEditModel {
Q_OBJECT
public:
- RKVarEditDataFrameModel (RContainerObject* dataframe, QObject *parent);
+ RKVarEditDataFrameModel (RContainerObject* dataframe, QObject* parent);
+/** ctor that constructs a new empty data frame */
+ RKVarEditDataFrameModel (const QString& validized_name, RContainerObject* parent_object, RCommandChain* chain, int initial_cols, QObject* parent);
~RKVarEditDataFrameModel ();
bool insertColumns (int column, int count, const QModelIndex& parent = QModelIndex());
bool removeColumns (int column, int count, const QModelIndex& parent = QModelIndex());
+
+ RContainerObject* getObject () const { return dataframe; };
+
+ void restoreObject (RObject* object, RCommandChain* chain);
protected:
- void doInsertColumn (int index);
+ void doInsertColumns (int index, int count);
/** reimplemented from RKVarEditModel to listen for the dataframe object as well */
void objectRemoved (RObject* object);
/** receives notifications of new objects added to this data.frame */
@@ -137,6 +177,9 @@
void doRemoveRowsInBackend (int row, int count);
RContainerObject* dataframe;
+
+ void init (RContainerObject* dataframe);
+ void pushTable (RCommandChain* sync_chain);
};
#endif
Modified: branches/KDE4_port/rkward/dataeditor/twintable.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintable.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/twintable.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -2,7 +2,7 @@
twintable.cpp - description
-------------------
begin : Tue Oct 29 2002
- copyright : (C) 2002, 2006 by Thomas Friedrichsmeier
+ copyright : (C) 2002, 2006, 2007 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -16,99 +16,70 @@
***************************************************************************/
#include "twintable.h"
+
#include <klocale.h>
#include <qvariant.h>
#include <qsplitter.h>
#include <qlayout.h>
-#include <qtooltip.h>
-#include <q3whatsthis.h>
-#include <qimage.h>
-#include <qpixmap.h>
-#include <q3popupmenu.h>
-#include <q3cstring.h>
-//Added by qt3to4:
-#include <Q3GridLayout>
-#include <Q3ValueList>
+#include <QMenu>
+#include <QVBoxLayout>
+#include <QHeaderView>
-#include "twintabledatamember.h"
-#include "twintablemetamember.h"
#include "twintablemember.h"
+#include "rkvareditmodel.h"
#include "../debug.h"
-#include "../core/robject.h"
-#include "../core/rkvariable.h"
-
-#define HEADER_MENU_ID_ADD_COL_LEFT 0
-#define HEADER_MENU_ID_ADD_COL_RIGHT 1
-#define HEADER_MENU_ID_DEL_COL 2
-
-#define HEADER_MENU_ID_ADD_ROW_ABOVE 0
-#define HEADER_MENU_ID_ADD_ROW_BELOW 1
-#define HEADER_MENU_ID_DEL_ROW 2
-#define HEADER_MENU_ID_DEL_ROWS 3
-
-
TwinTable::TwinTable (QWidget *parent) : RKEditor (parent) {
RK_TRACE (EDITOR);
- Q3GridLayout *grid_layout = new Q3GridLayout(this);
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->setContentsMargins (0, 0, 0, 0);
QSplitter *splitter = new QSplitter(this);
splitter->setOrientation(Qt::Vertical);
+
+ metaview = new TwinTableMember (splitter, this);
+ splitter->setResizeMode (metaview, QSplitter::KeepSize);
+ metaview->verticalHeader()->setResizeMode (QHeaderView::Fixed);
+
+#warning TODO set item delegates
- varview = new TwinTableMetaMember (splitter, this);
- varview->setNumRows (5);
- varview->setNumCols (5);
- varview->verticalHeader ()->setLabel (LABEL_ROW, i18n ("Label"));
- varview->verticalHeader ()->setLabel (TYPE_ROW, i18n ("Type"));
- varview->verticalHeader ()->setLabel (LEVELS_ROW, i18n ("Levels"));
- varview->verticalHeader ()->setLabel (FORMAT_ROW, i18n ("Format"));
- varview->verticalHeader ()->setLabel (NAME_ROW, i18n ("Name"));
- varview->setMinimumHeight (varview->horizontalHeader ()->height ());
- varview->setMaximumHeight (varview->rowPos (NAME_ROW) + varview->rowHeight (NAME_ROW) + varview->horizontalHeader ()->height () + 5);
- splitter->setResizeMode (varview, QSplitter::KeepSize);
- varview->verticalHeader()->setResizeEnabled (false);
+ dataview = new TwinTableMember (splitter, this);
+ dataview->verticalHeader()->setResizeMode (QHeaderView::Fixed);
- dataview = new TwinTableDataMember (splitter, this);
- dataview->setNumRows (1);
- dataview->setNumCols (5);
- dataview->verticalHeader()->setResizeEnabled (false);
-
dataview->horizontalHeader ()->hide ();
- dataview->setTopMargin (0);
- dataview->setLeftMargin (varview->leftMargin ());
- varview->setHScrollBarMode (Q3ScrollView::AlwaysOff);
+#warning is this needed?
+// dataview->setTopMargin (0);
+// dataview->setLeftMargin (metaview->leftMargin ());
+ metaview->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
- grid_layout->addWidget (splitter, 0, 0);
+ layout->addWidget (splitter);
// these are to keep the two tables in sync
- varview->setTwin (dataview);
- dataview->setTwin (varview);
- connect (dataview, SIGNAL (contentsMoving (int, int)), this, SLOT (scrolled (int, int)));
- connect (varview, SIGNAL (contentsMoving (int, int)), this, SLOT (autoScrolled (int, int)));
- connect (varview->horizontalHeader (), SIGNAL (clicked (int)), dataview, SLOT (columnClicked (int)));
- connect (varview->horizontalHeader (), SIGNAL (clicked (int)), this, SLOT (headerClicked (int)));
- connect (varview, SIGNAL (selectionChanged ()), this, SLOT (dataClearSelection ()));
- connect (dataview, SIGNAL (selectionChanged ()), this, SLOT (viewClearSelection ()));
+ metaview->setTwin (dataview);
+ dataview->setTwin (metaview);
+ connect (metaview->horizontalHeader (), SIGNAL (sectionClicked(int)), dataview, SLOT (selectColumn(int)));
+ connect (metaview->horizontalHeader (), SIGNAL (sectionPressed(int)), dataview, SLOT (selectColumn(int)));
+ connect (metaview, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)), this, SLOT (metaSelectionChanged (const QItemSelection&, const QItemSelection&)));
+ connect (dataview, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)), this, SLOT (dataSelectionChanged (const QItemSelection&, const QItemSelection&)));
- // this is to catch right-clicks on the top header
- connect (varview, SIGNAL (headerRightClick (int, int)), this, SLOT (varviewHeaderRightClicked (int, int)));
+ // catch header context menu requests
+ connect (dataview, SIGNAL (contextMenuRequest(int,int)), this, SLOT (dataHeaderContextMenu(int,int)));
+ connect (metaview, SIGNAL (contextMenuRequest(int,int)), this, SLOT (metaHeaderContextMenu(int,int)));
// which will be reacted upon by the following popup-menu:
- top_header_menu = new Q3PopupMenu (this);
- top_header_menu->insertItem (i18n ("Insert new variable left"), this, SLOT (insertColumnLeft ()), 0, HEADER_MENU_ID_ADD_COL_LEFT);
- top_header_menu->insertItem (i18n ("Insert new variable right"), this, SLOT (insertColumnRight ()), 0, HEADER_MENU_ID_ADD_COL_RIGHT);
- top_header_menu->insertItem (i18n ("Delete this variable"), this, SLOT (requestDeleteColumn ()), 0, HEADER_MENU_ID_DEL_COL);
+ top_header_menu = new QMenu (this);
+ action_insert_col_left = top_header_menu->addAction (QString (), this, SLOT (insertColumn()));
+ action_insert_col_right = top_header_menu->addAction (QString (), this, SLOT (insertColumn()));
+ action_delete_col = top_header_menu->addAction (QString (), this, SLOT (deleteColumn()));
- // and the same for the left header
- connect (dataview, SIGNAL (headerRightClick (int, int)), this, SLOT (dataviewHeaderRightClicked (int, int)));
- left_header_menu = new Q3PopupMenu (this);
- left_header_menu->insertItem (i18n ("Insert new case above"), this, SLOT (insertRowAbove ()), 0, HEADER_MENU_ID_ADD_ROW_ABOVE);
- left_header_menu->insertItem (i18n ("Insert new case below"), this, SLOT (insertRowBelow ()), 0, HEADER_MENU_ID_ADD_ROW_BELOW);
- left_header_menu->insertItem (QString::null, this, SLOT (deleteRow ()), 0, HEADER_MENU_ID_DEL_ROW);
- left_header_menu->insertItem (QString::null, this, SLOT (deleteRows ()), 0, HEADER_MENU_ID_DEL_ROWS);
+ left_header_menu = new QMenu (this);
+ action_insert_row_above = left_header_menu->addAction (QString (), this, SLOT (insertRow()));
+ action_insert_row_below = left_header_menu->addAction (QString (), this, SLOT (insertRow()));
+ action_delete_row = left_header_menu->addAction (QString (), this, SLOT (deleteRow()));
+ action_delete_rows = left_header_menu->addAction (QString (), this, SLOT (deleteSelectedRows()));
setFocusPolicy (Qt::StrongFocus);
}
@@ -116,220 +87,170 @@
TwinTable::~TwinTable() {
RK_TRACE (EDITOR);
- delete top_header_menu;
- delete left_header_menu;
-
-/* for (int i=0; i < numTrueCols (); ++i) {
- RObject *object = getColObject (i);
- if (object) object->setObjectOpened (this, false);
- else RK_ASSERT (false);
- } */
+// TODO: are the models auto-destructed?
}
-void TwinTable::scrolled (int x, int) {
+void TwinTable::initTable (RKVarEditDataFrameModel* model) {
RK_TRACE (EDITOR);
- disconnect (varview, SIGNAL (contentsMoving (int, int)), this, SLOT (autoScrolled (int, int)));
- varview->setContentsPos (x, varview->contentsY ());
- connect (varview, SIGNAL (contentsMoving (int, int)), this, SLOT (autoScrolled (int, int)));
+ datamodel = model;
+ dataview->setModel (model);
+ metaview->setModel (model->getMetaModel ());
+
+ metaview->setMinimumHeight (metaview->horizontalHeader ()->height ());
+ metaview->setMaximumHeight (metaview->rowHeight (0) * 5 + metaview->horizontalHeader ()->height () + 5);
}
-void TwinTable::autoScrolled (int x, int) {
+// TODO: handle situation when several entire cols are selected!
+void TwinTable::metaHeaderContextMenu (int row, int col) {
RK_TRACE (EDITOR);
- disconnect (dataview, SIGNAL (contentsMoving (int, int)), this, SLOT (scrolled (int, int)));
- dataview->setContentsPos (x, dataview->contentsY ());
- connect (dataview, SIGNAL (contentsMoving (int, int)), this, SLOT (scrolled (int, int)));
-}
+ if (col >= 0) {
+ RK_ASSERT (row == -1);
+ RK_ASSERT (col <= datamodel->trueCols ());
-void TwinTable::deleteColumn (int column) {
- RK_TRACE (EDITOR);
+ action_insert_col_left->setVisible (true);
+ action_insert_col_left->setText (i18n ("Insert new variable left")); // TODO: show name
+ action_insert_col_left->setData (col);
+ action_insert_col_right->setVisible (col < datamodel->trueCols ());
+ action_insert_col_right->setText (i18n ("Insert new variable right")); // TODO: show name
+ action_insert_col_right->setData (col+1);
+ action_delete_col->setVisible (col < datamodel->trueCols ());
+ action_delete_col->setText (i18n ("Delete this variable")); // TODO: show name
+ action_delete_col->setData (col);
- flushEdit ();
- if ((column >= 0) && (column < numTrueCols ())) {
- varview->removeColumn (column);
- dataview->removeColumn (column);
- varview->updateContents ();
- dataview->updateContents ();
+ // TODO: should be passed as a parameter, instead
+ top_header_menu->popup (metaview->mouse_at);
}
}
-void TwinTable::insertNewColumn (int where) {
+void TwinTable::dataHeaderContextMenu (int row, int col) {
RK_TRACE (EDITOR);
- flushEdit ();
- if ((where < 0) || (where > varview->numCols ())) {
- where = varview->numCols ();
- }
+ RK_ASSERT (col < 0);
+ if (row >= 0) {
+ RK_ASSERT (row <= datamodel->trueRows ());
- varview->insertColumns (where);
- dataview->insertColumns (where);
+ action_insert_row_above->setVisible (true);
+ action_insert_row_above->setText (i18n ("Insert new case above (at %1)", col + 1));
+ action_insert_row_above->setData (col);
+ action_insert_row_below->setVisible (row < datamodel->trueRows ());
+ action_insert_row_above->setText (i18n ("Insert new case below (at %1)", col + 2));
+ action_insert_row_below->setData (col + 1);
- if (where >= varview->numTrueCols ()) { // the new addition was acutally not the new trailing row, but the one to the left - for all practical purposes
- where = varview->numTrueCols () - 1;
+ QItemSelectionRange sel = dataview->getSelectionBoundaries ();
+ if (sel.isValid ()) {
+ int top = sel.top ();
+ int bottom = sel.bottom ();
+ if (bottom >= datamodel->trueRows ()) bottom = datamodel->trueRows () - 1;
+ if (top > bottom) top = bottom;
+
+ action_delete_rows->setVisible (true);
+ action_delete_rows->setText (i18n ("Delete marked rows (%1-%2)", (top+1), (bottom+1)));
+ } else {
+ action_delete_rows->setVisible (false);
+ }
+
+ action_delete_row->setVisible (row < datamodel->trueRows ());
+ action_delete_row->setText (i18n ("Delete this row (%1)", (row+1)));
+ action_delete_row->setData (row);
+
+ left_header_menu->popup (dataview->mouse_at);
}
- emit (addedColumn (where));
}
-void TwinTable::insertNewRow (int where, TwinTableMember *table) {
+void TwinTable::deleteColumn () {
RK_TRACE (EDITOR);
- flushEdit ();
- if (!table) table = dataview;
-
- if ((where < 0) || (where > table->numTrueRows ())) {
- where = table->numRows ();
- }
-
- if (table == dataview) {
- emit (dataAddingRow (where));
- } else if (table == varview) {
+ QObject *s = sender ();
+ int col;
+ if (s == action_delete_col) col = action_delete_col->data ().toInt ();
+ else {
RK_ASSERT (false);
+ return;
}
- table->insertRows (where);
+ flushEdit ();
+
+ datamodel->removeColumns (col, 1);
}
-void TwinTable::deleteRow (int where, TwinTableMember *table) {
+void TwinTable::insertColumn () {
RK_TRACE (EDITOR);
- flushEdit ();
- if (!table) table = dataview;
-
- if ((where < 0) || (where > table->numTrueRows ())) {
- where = table->numRows () - 1;
- }
-
- if (table == dataview) {
- emit (dataRemovingRow (where));
- } else if (table == varview) {
+ QObject *s = sender ();
+ int where;
+ if (s == action_insert_col_left) where = action_insert_col_left->data ().toInt ();
+ else if (s == action_insert_col_right) where = action_insert_col_right->data ().toInt ();
+ else {
RK_ASSERT (false);
+ return;
}
- table->removeRow (where);
-}
+ flushEdit ();
-void TwinTable::headerClicked (int col) {
- RK_TRACE (EDITOR);
-
- Q3TableSelection selection;
- selection.init (0, col);
- selection.expandTo (dataview->numTrueRows (), col);
-
- dataview->addSelection (selection);
+ datamodel->insertColumns (where, 1);
}
-// TODO: handle situation when several entire rows/cols are selected!
-void TwinTable::varviewHeaderRightClicked (int, int col) {
+void TwinTable::deleteRow () {
RK_TRACE (EDITOR);
- if (col >= 0) {
- header_pos = col;
- if (col < varview->numTrueCols ()) {
- top_header_menu->setItemVisible (HEADER_MENU_ID_ADD_COL_LEFT, true);
- top_header_menu->setItemVisible (HEADER_MENU_ID_ADD_COL_RIGHT, true);
- top_header_menu->setItemVisible (HEADER_MENU_ID_DEL_COL, true);
- top_header_menu->popup (varview->mouse_at);
- } else if (col == varview->numTrueCols ()) { // trailing col
- top_header_menu->setItemVisible (HEADER_MENU_ID_ADD_COL_LEFT, true);
- top_header_menu->setItemVisible (HEADER_MENU_ID_ADD_COL_RIGHT, false);
- top_header_menu->setItemVisible (HEADER_MENU_ID_DEL_COL, false);
- top_header_menu->popup (varview->mouse_at);
- } else {
- RK_ASSERT (false);
- }
+ QObject *s = sender ();
+ int where;
+ if (s == action_delete_row) where = action_delete_row->data ().toInt ();
+ else {
+ RK_ASSERT (false);
+ return;
}
-}
-void TwinTable::dataviewHeaderRightClicked (int row, int col) {
- RK_TRACE (EDITOR);
+ flushEdit ();
- RK_ASSERT (col < 0);
- if (row >= 0) {
- header_pos = row;
- left_header_menu->setItemVisible (HEADER_MENU_ID_ADD_ROW_ABOVE, true);
- int top, bottom, left, right;
- dataview->getSelectionBoundaries (&top, &left, &bottom, &right);
- if (top >= 0 && bottom <= dataview->numTrueRows () && top != bottom) {
- left_header_menu->setItemVisible (HEADER_MENU_ID_DEL_ROWS, true);
- left_header_menu->changeItem (HEADER_MENU_ID_DEL_ROWS, i18n ("Delete marked rows (%1-%2)", (top+1), (bottom+1)));
- } else {
- left_header_menu->setItemVisible (HEADER_MENU_ID_DEL_ROWS, false);
- }
- if (row < dataview->numTrueRows ()) {
- left_header_menu->setItemVisible (HEADER_MENU_ID_ADD_ROW_BELOW, true);
- left_header_menu->setItemVisible (HEADER_MENU_ID_DEL_ROW, true);
- left_header_menu->changeItem (HEADER_MENU_ID_DEL_ROW, i18n ("Delete this row (%1)", (row+1)));
- left_header_menu->popup (dataview->mouse_at);
- } else if (row == dataview->numTrueRows ()) { // trailing row
- left_header_menu->setItemVisible (HEADER_MENU_ID_ADD_ROW_BELOW, false);
- left_header_menu->setItemVisible (HEADER_MENU_ID_DEL_ROW, false);
- left_header_menu->popup (dataview->mouse_at);
- } else {
- RK_ASSERT (false);
- }
- }
+ datamodel->removeRows (where, 1);
}
-void TwinTable::viewClearSelection () {
+void TwinTable::deleteSelectedRows () {
RK_TRACE (EDITOR);
-
- disconnect (varview, SIGNAL (selectionChanged ()), this, SLOT (dataClearSelection ()));
- varview->clearSelection ();
- connect (varview, SIGNAL (selectionChanged ()), this, SLOT (dataClearSelection ()));
-}
-void TwinTable::dataClearSelection () {
- RK_TRACE (EDITOR);
+ QItemSelectionRange sel = dataview->getSelectionBoundaries ();
+ if (sel.isValid ()) {
+ int top = sel.top ();
+ int bottom = sel.bottom ();
+ if (bottom >= datamodel->trueRows ()) bottom = datamodel->trueRows () - 1;
+ if (top > bottom) top = bottom;
- disconnect (dataview, SIGNAL (selectionChanged ()), this, SLOT (viewClearSelection ()));
- dataview->clearSelection ();
- connect (dataview, SIGNAL (selectionChanged ()), this, SLOT (viewClearSelection ()));
+ datamodel->removeRows (top, bottom - top + 1);
+ } else {
+ RK_ASSERT (false);
+ }
}
-QString TwinTable::getSelectedText () {
+void TwinTable::insertRow () {
RK_TRACE (EDITOR);
- return (activeTable ()->getSelectionText ());
-}
-void TwinTable::insertColumnRight () {
- RK_TRACE (EDITOR);
- insertNewColumn (header_pos+1);
-}
+ QObject *s = sender ();
+ int where;
+ if (s == action_insert_row_above) where = action_insert_row_above->data ().toInt ();
+ else if (s == action_insert_row_below) where = action_insert_row_below->data ().toInt ();
+ else {
+ RK_ASSERT (false);
+ return;
+ }
-void TwinTable::insertColumnLeft () {
- RK_TRACE (EDITOR);
- insertNewColumn (header_pos);
-}
+ flushEdit ();
-void TwinTable::requestDeleteColumn () {
- RK_TRACE (EDITOR);
- emit (deleteColumnRequest (header_pos));
+ datamodel->insertRows (where, 1);
}
-void TwinTable::insertRowBelow () {
+void TwinTable::metaSelectionChanged (const QItemSelection& selected, const QItemSelection&) {
RK_TRACE (EDITOR);
- insertNewRow (header_pos+1);
-}
-void TwinTable::insertRowAbove () {
- RK_TRACE (EDITOR);
- insertNewRow (header_pos);
+ if (!selected.isEmpty ()) dataview->clearSelection ();
}
-void TwinTable::deleteRow () {
+void TwinTable::dataSelectionChanged (const QItemSelection& selected, const QItemSelection&) {
RK_TRACE (EDITOR);
- deleteRow (header_pos);
-}
-void TwinTable::deleteRows () {
- RK_TRACE (EDITOR);
-// TODO: this is inefficient. Remove all rows at once
- int top, bottom, left, right;
- dataview->getSelectionBoundaries (&top, &left, &bottom, &right);
- for (; bottom >= top; --bottom) {
- deleteRow (bottom);
- }
+ if (!selected.isEmpty ()) metaview->clearSelection ();
}
void TwinTable::copy () {
@@ -341,7 +262,7 @@
table->copy ();
}
-void TwinTable::paste (const QString& pasted, RKEditor::PasteMode paste_mode) {
+void TwinTable::paste (RKEditor::PasteMode paste_mode) {
RK_TRACE (EDITOR);
flushEdit ();
@@ -349,77 +270,14 @@
TwinTableMember *table = activeTable ();
if (!table) return;
- int top_row, left_col, bottom_row, right_col;
- table->getSelectionBoundaries (&top_row, &left_col, &bottom_row, &right_col);
- if (paste_mode == RKEditor::PasteToSelection) {
- // ok, we got our values
- } else if (paste_mode == RKEditor::PasteToTable) {
- bottom_row = table->numTrueRows () - 1;
- right_col = table->numTrueCols () - 1;
- if (right_col < left_col) return; // may happen, if the current cell is in the trailing cols/rows
- if (bottom_row < top_row) return;
- } else if (paste_mode == RKEditor::PasteEverywhere) {
- bottom_row = INT_MAX;
- right_col = INT_MAX;
- }
- if (table == varview) { // do not allow new rows in the varview
- if (bottom_row >= varview->numTrueRows ()) bottom_row = varview->numTrueRows () - 1;
- }
-
- Q3ValueList<RKVariable*> col_list;
-
- int row = top_row;
- int col = left_col;
- int content_offset = 0;
- int content_length = pasted.length ();
- do {
- // first add new rows/cols if needed. Range check is done below, and on first iteration, we're always inside the valid range
- if (row >= table->numTrueRows ()) insertNewRow (-1, table);
- if (col >= table->numTrueCols ()) insertNewColumn ();
-
- if (!col_list.contains (getColObject (col))) { // avoid syncing while doing the paste
- col_list.append (getColObject (col));
- getColObject (col)->setSyncing (false);
- }
-
- int next_tab = pasted.find ('\t', content_offset);
- if (next_tab < 0) next_tab = content_length;
- int next_delim = next_tab;
- int next_line = pasted.find ('\n', content_offset);
- if (next_line < 0) next_line = content_length;
- if (next_line < next_tab) next_delim = next_line;
-
- table->setText (row, col, pasted.mid (content_offset, next_delim - content_offset));
-
- if (next_delim == next_tab) { // move to next row/column
- ++col;
- } else if (next_delim == next_line) {
- col = left_col;
- ++row;
- }
-
- if (col > right_col) { // check boundaries for next iteration
- next_delim = next_line;
- col = left_col;
- ++row;
- }
- if (row > bottom_row) break;
-
- content_offset = next_delim + 1;
- } while (content_offset < content_length);
-
- // now do the syncing
- for (Q3ValueList<RKVariable*>::ConstIterator it = col_list.constBegin (); it != col_list.constEnd (); ++it) {
- (*it)->syncDataToR ();
- (*it)->setSyncing (true);
- }
+ table->paste (paste_mode);
}
TwinTableMember *TwinTable::activeTable () {
RK_TRACE (EDITOR);
- if (varview->hasFocus ()) {
- return varview;
+ if (metaview->hasFocus ()) {
+ return metaview;
} else if (dataview->hasFocus ()) {
return dataview;
} else {
@@ -431,75 +289,17 @@
RK_TRACE (EDITOR);
TwinTableMember *table = activeTable ();
- if (!table) return;
+ if (!table) return;
table->blankSelected ();
}
-void TwinTable::setRow (TwinTableMember* table, int row, int start_col, int end_col, char **data) {
- RK_TRACE (EDITOR);
-
- flushEdit ();
- while (numTrueCols () <= end_col) {
- insertNewColumn ();
- }
-
- int i=0;
- for (int col=start_col; col <= end_col; ++col) {
- table->setText (row, col, data[i++]);
- }
-}
-
-void TwinTable::setColumn (TwinTableMember* table, int col, int start_row, int end_row, char **data) {
- RK_TRACE (EDITOR);
-
- flushEdit ();
- while (table->numTrueRows () <= end_row) {
- insertNewRow (table->numTrueRows (), table);
- }
-
- int i=0;
- for (int row=start_row; row <= end_row; ++row) {
- table->setText (row, col, data[i++]);
- }
-}
-
void TwinTable::flushEdit () {
RK_TRACE (EDITOR);
// flush pending edit operations
- varview->stopEditing ();
+ metaview->stopEditing ();
dataview->stopEditing ();
}
-int TwinTable::numTrueCols () {
-// RK_TRACE (EDITOR);
- return varview->numTrueCols ();
-}
-
-void TwinTable::setColObject (long int column, RKVariable *object) {
- RK_TRACE (EDITOR);
- if (object) {
- col_map.replace (column, object); // will insert, if not already in dict
- } else {
- col_map.remove (column);
- }
-}
-
-RKVariable *TwinTable::getColObject (long int col) {
- // do not trace. called very often
- //RK_TRACE (EDITOR);
- return col_map.find (col);
-}
-
-long int TwinTable::getObjectCol (RObject *object) {
- RK_TRACE (EDITOR);
- for (Q3IntDictIterator<RKVariable> it (col_map); it.current (); ++it) {
- if (it.current () == object) return it.currentKey ();
- }
-
- RK_ASSERT (false);
- return -1;
-}
-
#include "twintable.moc"
Modified: branches/KDE4_port/rkward/dataeditor/twintable.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintable.h 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/twintable.h 2007-11-08 23:23:14 UTC (rev 2190)
@@ -2,7 +2,7 @@
twintable.h - description
-------------------
begin : Tue Oct 29 2002
- copyright : (C) 2002, 2006 by Thomas Friedrichsmeier
+ copyright : (C) 2002, 2006, 2007 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -20,29 +20,12 @@
#include "rkeditor.h"
-#include <qvariant.h>
#include <qstring.h>
-#include <q3intdict.h>
-//Added by qt3to4:
-#include <Q3GridLayout>
-#include <Q3HBoxLayout>
-#include <Q3VBoxLayout>
-#include <Q3PopupMenu>
+#include <QItemSelection>
-class Q3VBoxLayout;
-class Q3HBoxLayout;
-class Q3GridLayout;
-class QSplitter;
class TwinTableMember;
-class TwinTableDataMember;
-class TwinTableMetaMember;
-class TableColumn;
-class Q3PopupMenu;
-class Q3Table;
-class RKDrag;
-class RObject;
-struct RObject::ChangeSet;
-class RKVariable;
+class QMenu;
+class RKVarEditDataFrameModel;
/**
*@author Thomas Friedrichsmeier
@@ -51,16 +34,10 @@
class TwinTable : public RKEditor {
Q_OBJECT
public:
- TwinTable(QWidget *parent=0);
- ~TwinTable();
-/** Inserts a new column at the given position (or at the end for -1) */
- void insertNewColumn (int where=-1);
-/** Inserts a new row at the given position (or at the end for -1) in the given table. Don't try to do this in the varview, yet! */
- void insertNewRow (int where=-1, TwinTableMember *table=0);
-/** Inserts the row at the given position (or at the end for -1) in the given table. Don't try to do this in the varview, yet! */
- void deleteRow (int where, TwinTableMember *table=0);
-/** Pastes content to the current table */
- void paste (const QString& pasted, RKEditor::PasteMode paste_mode);
+ TwinTable (QWidget *parent=0);
+ ~TwinTable ();
+/** Pastes clipboard content to the current table */
+ void paste (RKEditor::PasteMode paste_mode);
/** Copy selection in the current table to clipboard */
void copy ();
/** Same as above, but flips the data (i.e. row <-> cols) */
@@ -72,67 +49,48 @@
/** Flushes pending edit-operations */
void flushEdit ();
-/** Returns the number of (true) columns in the tables. See TwinTableMember::numTrueCols () */
- int numTrueCols ();
+ void initTable (RKVarEditDataFrameModel* model);
- TwinTableMetaMember* varview;
- TwinTableDataMember* dataview;
-/** get the object at the given column (0 if there is no object for the column) */
- RKVariable *getColObject (long int col);
-signals:
- void deleteColumnRequest (int);
-/** emitted so the RKEditorDataFrame can add a corresponding object */
- void addedColumn (int);
-/** emitted so the RKEditorDataFrame can update the R workspace accordingly. Only signals row additions in the data table, not the meta table */
- void dataAddingRow (int);
-/** emitted so the RKEditorDataFrame can update the R workspace accordingly. Only signals row deletions in the data table, not the meta table */
- void dataRemovingRow (int);
+ RKVarEditDataFrameModel* datamodel;
public slots:
- void dataviewHeaderRightClicked (int row, int col);
- void varviewHeaderRightClicked (int row, int col);
+ void dataHeaderContextMenu (int row, int col);
+ void metaHeaderContextMenu (int row, int col);
+/*
void headerClicked (int col);
- void viewClearSelection ();
- void dataClearSelection ();
+ void headerPressed (int col); */
+ void metaSelectionChanged (const QItemSelection& selected, const QItemSelection& deselected);
+ void dataSelectionChanged (const QItemSelection& selected, const QItemSelection& deselected);
private:
/** PopupMenu shown when top header is right-clicked */
- Q3PopupMenu *top_header_menu;
+ QMenu *top_header_menu;
/** PopupMenu shown when top header is right-clicked */
- Q3PopupMenu *left_header_menu;
-/** position (row or col) the header_menu is operating on */
- int header_pos;
-
- typedef Q3IntDict<RKVariable> ColMap;
- ColMap col_map;
+ QMenu *left_header_menu;
protected:
-/** set a row of cells, expanding the table if necessary. Assumes you provide the correct amount of data! */
- void setRow (TwinTableMember* table, int row, int start_col, int end_col, char **data);
-/** set a column of cells, expanding the table if necessary. Assumes you provide the correct amount of data! */
- void setColumn (TwinTableMember* table, int col, int start_row, int end_row, char **data);
-/** deletes the given column. To be called only from RKEditorDataFrame, in order to take care of object-removal! */
- void deleteColumn (int column);
/** Returns the active Table (of the two members), 0 if no table active */
TwinTableMember *activeTable ();
- long int getObjectCol (RObject *object);
-/// if object == 0, removes the column from the list
- void setColObject (long int column, RKVariable *object);
+ TwinTableMember* metaview;
+ TwinTableMember* dataview;
+
+ QAction* action_insert_col_left;
+ QAction* action_insert_col_right;
+ QAction* action_delete_col;
+
+ QAction* action_insert_row_above;
+ QAction* action_insert_row_below;
+ QAction* action_delete_row;
+ QAction* action_delete_rows;
private slots:
- void scrolled (int x, int y);
- void autoScrolled (int x, int y);
-/** inserts a new column to the right of the current header_pos */
- void insertColumnRight ();
-/** inserts a new column to the left of the current header_pos */
- void insertColumnLeft ();
-/** inserts a new row below the current header_pos */
- void insertRowBelow ();
-/** inserts a new row above the current header_pos */
- void insertRowAbove ();
-/** deletes the current row (in the data view) */
+/** inserts a new column (NOTE the action connected to this signal carries the info, where the column is to be inserted) */
+ void insertColumn ();
+/** inserts a new row in the dataview (NOTE the action connected to this signal carries the info, where the column is to be inserted) */
+ void insertRow ();
+/** deletes the current row (in the dataview) */
void deleteRow ();
-/** deletes all marked rows (in the data view) */
- void deleteRows ();
-/** deletes the column at the current header_pos. Actually it does not really delete the column, but requests object-removal from the RKEditorDataFrame. That will take care of calling deleteColumn (int) */
- void requestDeleteColumn ();
+/** deletes all marked rows (in the dataview) */
+ void deleteSelectedRows ();
+/** deletes the column at the current header_pos. Actually it does not really delete the column, but requests object-removal from the model, which will pass the request to RKModifcationTracker */
+ void deleteColumn ();
};
#endif
Modified: branches/KDE4_port/rkward/dataeditor/twintabledatamember.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintabledatamember.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/twintabledatamember.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -27,6 +27,9 @@
#include "../debug.h"
+#warning TODO remove
+#if 0
+
TwinTableDataMember::TwinTableDataMember (QWidget *parent, TwinTable *table) : TwinTableMember (parent, table, 1, 1) {
}
@@ -150,3 +153,4 @@
}
#include "twintabledatamember.moc"
+#endif
\ No newline at end of file
Modified: branches/KDE4_port/rkward/dataeditor/twintabledatamember.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintabledatamember.h 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/twintabledatamember.h 2007-11-08 23:23:14 UTC (rev 2190)
@@ -18,7 +18,7 @@
#define TWINTABLEDATAMEMBER_H
#include "twintablemember.h"
-
+#if 0
/**
The TwinTableMember responsible for storing the data (i.e. the bottom half of the TwinTable). See TwinTable and TwinTableMember.
@@ -49,5 +49,5 @@
/** reimplemented form TwinTableDataMember to use information from RKVariable for proper treatment of values */
QString rText (int row, int col) const;
};
-
#endif
+#endif
Modified: branches/KDE4_port/rkward/dataeditor/twintablemember.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintablemember.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/twintablemember.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -2,7 +2,7 @@
twintablemember.cpp - description
-------------------
begin : Tue Oct 29 2002
- copyright : (C) 2002, 2006 by Thomas Friedrichsmeier
+ copyright : (C) 2002, 2006, 2007 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -17,108 +17,47 @@
#include "twintablemember.h"
-#include <qevent.h>
-#include <qpainter.h>
-#include <qstyle.h>
-#include <qapplication.h>
-#include <qclipboard.h>
-//Added by qt3to4:
-#include <QMouseEvent>
#include <QKeyEvent>
-#include <Q3MemArray>
#include "celleditor.h"
#include "twintable.h"
+#include "rktextmatrix.h"
+#include "rkvareditmodel.h"
+
#include "../debug.h"
-TwinTableMember::TwinTableMember (QWidget *parent, TwinTable *table, int trailing_rows, int trailing_cols) : Q3Table (parent){
+TwinTableMember::TwinTableMember (QWidget *parent, TwinTable *table) : QTableView (parent){
+ RK_TRACE (EDITOR);
+
twin = 0;
TwinTableMember::table = table;
- setRowMovingEnabled (false);
- setVScrollBarMode (Q3ScrollView::AlwaysOn);
- horizontalHeader()->installEventFilter (this);
- verticalHeader()->installEventFilter (this);
- setSelectionMode (Q3Table::Single);
+ setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOn);
+ setSelectionMode (QAbstractItemView::ContiguousSelection);
+ setContextMenuPolicy (Qt::CustomContextMenu);
+ connect (this, SIGNAL (customContextMenuRequested (const QPoint&)), this, SLOT (headerContextMenuRequested (const QPoint&)));
- TwinTableMember::trailing_cols = trailing_cols;
- TwinTableMember::trailing_rows = trailing_rows;
-
tted = 0;
+#warning tted and changing width currently unused, but likey will be used.
changing_width = false;
+ changing_scroll = false;
connect (this, SIGNAL (currentChanged (int, int)), this, SLOT (currentCellChanged (int, int)));
}
TwinTableMember::~TwinTableMember(){
+ RK_TRACE (EDITOR);
}
-int TwinTableMember::numTrueCols () const {
- return numCols () - trailing_cols;
-}
+void TwinTableMember::setRKModel (RKVarEditModelBase* model) {
+ RK_TRACE (EDITOR);
+ mymodel = model; setModel (model);
+};
-int TwinTableMember::numTrueRows () const {
- return Q3Table::numRows () - trailing_rows;
-}
-
void TwinTableMember::setTwin (TwinTableMember * new_twin) {
+ RK_TRACE (EDITOR);
twin = new_twin;
}
-void TwinTableMember::columnWidthChanged (int col) {
- // does all repainting and stuff ...
- Q3Table::columnWidthChanged (col);
-
- // syncs the twin
- if (twin) {
- if (!changing_width) {
- changing_width = true;
- twin->setColumnWidth (col, columnWidth (col));
- }
- changing_width = false;
- }
-}
-
-bool TwinTableMember::eventFilter (QObject *object, QEvent *event) {
- // filter out right mouse button events of the varview-header
- if (event && (event->type () == QEvent::MouseButtonPress)) {
- QMouseEvent *mouseEvent = (QMouseEvent *) event;
- if (mouseEvent && (mouseEvent->button () == Qt::RightButton)) {
- mouse_at = mouseEvent->globalPos ();
- if (object == horizontalHeader ()) {
- emit headerRightClick (-1, horizontalHeader ()->sectionAt (contentsX () + mouseEvent->x ()));
- return (true); // got it
- }
- if (object == verticalHeader ()) {
- emit headerRightClick (verticalHeader ()->sectionAt (contentsY () + mouseEvent->y ()), -1);
- return (true); // got it
- }
- }
- setFocus ();
- }
-
- // default processing
- return (Q3Table::eventFilter (object, event));
-}
-
-// virtual
-QString TwinTableMember::rText (int row, int col) const {
- return (RObject::rQuote (text (row, col)));
-}
-
-void TwinTableMember::removeRows (const Q3MemArray<int> &) {
- RK_ASSERT (false);
-}
-
-void TwinTableMember::swapRows (int, int, bool) {
-}
-
-void TwinTableMember::swapCells (int, int, int, int) {
- RK_ASSERT (false);
-}
-
-void TwinTableMember::swapColumns (int, int, bool) {
-}
-
void TwinTableMember::editorLostFocus () {
RK_TRACE (EDITOR);
stopEditing ();
@@ -126,35 +65,20 @@
void TwinTableMember::stopEditing () {
RK_TRACE (EDITOR);
- if (tted) endEdit (currEditRow (), currEditCol (), true, false);
+#warning todo
+// if (tted) endEdit (currEditRow (), currEditCol (), true, false);
RK_ASSERT (!tted);
}
-QWidget *TwinTableMember::cellWidget (int row, int col) const {
- if (tted && (currEditRow () == row) && (currEditCol () == col)) return tted;
- return 0;
-}
-
-void TwinTableMember::currentCellChanged (int row, int col) {
- RK_TRACE (EDITOR);
- if ((row == currEditRow ()) && (col == currEditCol ())) return;
- if (tted) stopEditing ();
-
-/* if (numSelections ()) {
- QTableSelection sel = selection (currentSelection ());
- if (sel.bottomRow () != sel.topRow ()) return;
- if (sel.leftCol () != sel.rightCol ()) return;
- }
-
- editCell (row, col); */
-}
-
+#if 0
void TwinTableMember::endEdit (int row, int col, bool, bool) {
RK_TRACE (EDITOR);
if (tted) setCellContentFromEditor (row, col);
setEditMode (NotEditing, -1, -1);
}
+#endif
+#if 0
void TwinTableMember::setCellContentFromEditor (int row, int col) {
RK_TRACE (EDITOR);
RK_ASSERT (tted);
@@ -173,150 +97,80 @@
viewport ()->setFocus ();
}
+#endif
void TwinTableMember::copy () {
RK_TRACE (EDITOR);
- QString text = getSelectionText ();
- QMimeData* data = new QMimeData ();
- data->setText (text);
- data->setData ("text/tab-separated-values", text.toLocal8Bit ());
- QApplication::clipboard()->setMimeData (data);
+ QItemSelectionRange range = getSelectionBoundaries ();
+ if (range.isValid ()) {
+ RKTextMatrix mat = mymodel->getTextMatrix (range);
+ mat.copyToClipboard ();
+ }
}
-QString TwinTableMember::getSelectionText () {
+void TwinTableMember::blankSelected () {
RK_TRACE (EDITOR);
- int top_row, left_col, bottom_row, right_col;
- getSelectionBoundaries (&top_row, &left_col, &bottom_row, &right_col);
- return (getRangeText (top_row, left_col, bottom_row, right_col));
+ QItemSelectionRange range = getSelectionBoundaries ();
+ if (range.isValid ()) mymodel->blankRange (range);
}
-QString TwinTableMember::getRangeText (int top_row, int left_col, int bottom_row, int right_col) {
+void TwinTableMember::paste (RKEditor::PasteMode mode) {
RK_TRACE (EDITOR);
- QString data;
- for (int row=top_row; row <= bottom_row; ++row) {
- for (int col=left_col; col <= right_col; ++col) {
- data.append (text (row, col));
- if (col != right_col) {
- data.append ("\t");
- }
- }
- if (row != bottom_row) {
- data.append ("\n");
- }
- }
- return data;
+ RKTextMatrix pasted = RKTextMatrix::matrixFromClipboard ();
+ QItemSelectionRange range;
+ if (mode == RKEditor::PasteToSelection) {
+ range = getSelectionBoundaries ();
+ } else if (mode == RKEditor::PasteToTable) {
+ range = QItemSelectionRange (mymodel->index (0, 0), mymodel->index (mymodel->trueRows (), mymodel->trueCols ()));
+ } // else: range not set means not confined = PasteAnywhere
+ mymodel->setTextMatrix (currentIndex (), pasted, range);
}
-void TwinTableMember::blankSelected () {
+QItemSelectionRange TwinTableMember::getSelectionBoundaries () {
RK_TRACE (EDITOR);
- int top_row, left_col, bottom_row, right_col;
- getSelectionBoundaries (&top_row, &left_col, &bottom_row, &right_col);
+ RK_ASSERT (selectionModel ());
+ QItemSelection sel = selectionModel ()->selection ();
+ if (sel.isEmpty ()){
+ QModelIndex current = currentIndex ();
+ if (!current.isValid ()) return (QItemSelectionRange ());
- for (int row=top_row; row <= bottom_row; ++row) {
- for (int col=left_col; col <= right_col; ++col) {
- setText (row, col, QString::null);
- }
+ return (QItemSelectionRange (currentIndex (), currentIndex ()));
+ } else {
+ RK_ASSERT (sel.size () == 1);
+ return (sel[0]);
}
}
-void TwinTableMember::getSelectionBoundaries (int *top_row, int *left_col, int *bottom_row, int *right_col) {
+void TwinTableMember::keyPressEvent (QKeyEvent *e) {
RK_TRACE (EDITOR);
- RK_ASSERT (top_row);
- RK_ASSERT (bottom_row);
- RK_ASSERT (left_col);
- RK_ASSERT (right_col);
-
- int selnum = -1;
- if (currentSelection () >= 0) selnum = currentSelection ();
- else if (numSelections () >= 1) selnum = 0; // this is the one and only selection, as we only allow one single selection. Unfortunately, QTable does not regard a selection as current, if it was added programatically, instead of user-selected.
- if (selnum >= 0) {
- Q3TableSelection sel = selection (selnum);
- *top_row = sel.topRow ();
- *left_col = sel.leftCol ();
- *bottom_row = sel.bottomRow ();
- *right_col = sel.rightCol ();
+ if ((e->key () == Qt::Key_Delete) || (e->key () == Qt::Key_Backspace)) {
+ blankSelected ();
+ e->accept ();
} else {
- // Nothing selected. Set current cell coordinates
- *top_row = *bottom_row = currentRow ();
- *left_col = *right_col = currentColumn ();
+ QTableView::keyPressEvent (e);
}
}
-void TwinTableMember::paintCellInternal (QPainter *p, int row, int col, const QRect &cr, bool selected, const QColorGroup &cg, QBrush *brush_override, QPen *pen_override, const QString &text, int alignment) {
- // no trace for paint operations
+void TwinTableMember::scrollContentsBy (int dx, int dy) {
+ RK_TRACE (EDITOR);
- // draw background
- QBrush brush = cg.brush (QColorGroup::Base);
- if (!brush_override) {
- if (selected) {
- brush = cg.brush(QColorGroup::Highlight);
- if ((row >= numTrueRows ()) || (col >= numTrueCols ())) {
- brush = QBrush (QColor (127, 127, 255));
- }
- } else {
- if ((row >= numTrueRows ()) || (col >= numTrueCols ())) {
- brush = QBrush (Qt::gray);
- }
- }
- } else {
- brush = *brush_override;
- }
- p->fillRect(0, 0, cr.width(), cr.height(), brush);
-
- // draw grid
- QPen pen (p->pen ());
- int gridColor = style ()->styleHint (QStyle::SH_Table_GridLineColor, 0, this);
- if (gridColor != -1) {
- const QPalette &pal = palette ();
- if (cg != colorGroup () && cg != pal.disabled () && cg != pal.inactive ()) p->setPen (cg.mid ());
- else p->setPen ((QRgb) gridColor);
- } else {
- p->setPen (cg.mid ());
- }
- int x2 = cr.width () - 1;
- int y2 = cr.height () - 1;
- p->drawLine (x2, 0, x2, y2);
- p->drawLine (0, y2, x2, y2);
- p->setPen (pen);
-
- if (tted && (currEditRow () == row) && (currEditCol () == col)) {
- tted->raise ();
- return;
- }
-
- if (text.isNull ()) return;
-
- if (!pen_override) {
- if (selected) {
- p->setPen (cg.highlightedText());
- } else {
- p->setPen (cg.text ());
- }
- } else {
- p->setPen (*pen_override);
- }
-
- if (alignment == 1) {
- p->drawText (2, 0, cr.width () - 4, cr.height (), Qt::AlignRight, text);
- } else {
- p->drawText (2, 0, cr.width () - 4, cr.height (), Qt::AlignLeft, text);
- }
+ if (changing_scroll) return;
+ changing_scroll = true;
+ RK_ASSERT (twin);
+ twin->scrollContentsBy (dx, 0);
+ changing_scroll = false;
}
-void TwinTableMember::keyPressEvent (QKeyEvent *e) {
+void TwinTableMember::headerContextMenuRequested (const QPoint& pos) {
RK_TRACE (EDITOR);
- if ((e->key () == Qt::Key_Delete) || (e->key () == Qt::Key_Backspace)) {
- blankSelected ();
- e->accept ();
- } else {
- Q3Table::keyPressEvent (e);
- }
+ mouse_at = pos;
+#warning TODO
}
#include "twintablemember.moc"
Modified: branches/KDE4_port/rkward/dataeditor/twintablemember.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintablemember.h 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/twintablemember.h 2007-11-08 23:23:14 UTC (rev 2190)
@@ -2,7 +2,7 @@
twintablemember.h - description
-------------------
begin : Tue Oct 29 2002
- copyright : (C) 2002, 2006 by Thomas Friedrichsmeier
+ copyright : (C) 2002, 2006, 2007 by Thomas Friedrichsmeier
email : tfry at users.sourceforge.net
***************************************************************************/
@@ -18,110 +18,73 @@
#ifndef TWINTABLEMEMBER_H
#define TWINTABLEMEMBER_H
-#include <q3table.h>
+#include <QTableView>
+#include <QItemSelectionRange>
#include <qpoint.h>
//Added by qt3to4:
#include <QEvent>
-#include <Q3MemArray>
#include <QMouseEvent>
#include <QKeyEvent>
-#define LABEL_ROW 0
-#define TYPE_ROW 1
-#define LEVELS_ROW 2
-#define FORMAT_ROW 3
-#define NAME_ROW 4
-
class QMouseEvent;
class TwinTable;
class CellEditor;
+class RKVarEditModelBase;
-/**
- *@author Thomas Friedrichsmeier
- */
+#include "rkeditor.h"
-class TwinTableMember : public Q3Table {
+/** One of the tables used in a TwinTable.
+ at author Thomas Friedrichsmeier
+*/
+class TwinTableMember : public QTableView {
Q_OBJECT
public:
- TwinTableMember (QWidget *parent, TwinTable *table, int trailing_rows=0, int trailing_cols=0);
+ TwinTableMember (QWidget *parent, TwinTable *table);
~TwinTableMember();
-/** stores the position of the mouse, when headerRightClick gets emitted */
- QPoint mouse_at;
-/// TODO: can this be removed?
- virtual TwinTableMember *varTable () { return this; };
-/** returns cell-value in a form suitable for submission to R (e.g. quoted for strings). Default implementation simply quotes the result of text () */
- virtual QString rText (int row, int col) const;
TwinTableMember *getTwin () { return twin; };
/** like QTable::numRows (), but returns only the "true", i.e. active rows (excluding the trailing_rows) */
int numTrueRows () const;
/** like QTable::numCols (), but returns only the "true", i.e. active columns (excluding the trailing_cols) */
int numTrueCols () const;
-/** reimplemented form QTable not to use QTableItems. This one raises an assert (should never be called) */
- void removeRows (const Q3MemArray<int> &rows);
-/** reimplemented form QTable not to use QTableItems. This one has no effect */
- void swapRows (int row1, int row2, bool swapHeader);
-/** reimplemented form QTable not to use QTableItems. This one raises an assert (should never be called) */
- void swapCells (int row1, int col1, int row2, int col2);
-/** reimplemented form QTable not to use QTableItems. This one has no effect */
- void swapColumns (int col1, int col2, bool swapHeader);
-/** reimplemented form QTable not to use QTableItems. This one always returns 0 */
- Q3TableItem *item (int, int) { return 0; }
-/** reimplemented form QTable not to use QTableItems. This one has no effect */
- void setItem (int, int, Q3TableItem *) {};
-/** reimplemented form QTable not to use QTableItems. This one has no effect */
- void takeItem (Q3TableItem *) {};
-/** reimplemented form QTable not to use QTableItems. This one always returns 0 or tted */
- QWidget *cellWidget (int row, int col) const;
-/** reimplemented form QTable not to use QTableItems. This one has no effect */
- void clearCellWidget (int, int) {};
-/** reimplemented form QTable not to use QTableItems. This one has no effect */
- void setCellWidget (int, int, QWidget *) {};
/** ends editing. Actually it's just a simple wrapper around QTable::endEdit () */
void stopEditing ();
-/** reimplemented form QTable not to work on TableColumns instead of QTableItems. */
- void endEdit (int row, int col, bool accept, bool replace);
-/** reimplemented form QTable not to work on TableColumns instead of QTableItems */
- void setCellContentFromEditor (int row, int col);
+#warning maybe still needed?
/** needed to detect right mouse clicks in the header and tab-keypresses in the CellEditor */
- bool eventFilter (QObject *object, QEvent *event);
+// bool eventFilter (QObject *object, QEvent *event);
/** reimplemented to delete cell contents on DEL and BACKSPACE. Placed in public, here, so CellEditor can have access */
void keyPressEvent (QKeyEvent *e);
-/** get contents of current selection as text (tab-separated-values) */
- QString getSelectionText ();
-/** get contents of the specified range as text (tab-separated-values) */
- QString getRangeText (int top_row, int left_col, int bottom_row, int right_col);
+
+ void copy ();
+ void paste (RKEditor::PasteMode mode);
+
/** blanks out the currently selected cells (or the currently active cell, if there is no selection) */
void blankSelected ();
/** shortcut to get the boundaries of the current selection */
- void getSelectionBoundaries (int *top_row, int *left_col, int *bottom_row, int *right_col);
-/** internal function to paint the cell. Accepts the parameters of QTable::paintCell, and also:
- at param brush_override If not null, the cell-background will be painted in this brush
- at param pen_override If not null, the cell text will be painted in this pen
- at param text The text to draw
- at param aligment Alignment of the text. 0 = Left, 1=Right */
- void paintCellInternal (QPainter *p, int row, int col, const QRect &cr, bool selected, const QColorGroup &cg, QBrush *brush_override, QPen *pen_override, const QString &text, int alignment);
+ QItemSelectionRange getSelectionBoundaries ();
+
+ void setRKModel (RKVarEditModelBase* model);
signals:
- void headerRightClick (int row, int col);
+ void contextMenuRequest (int row, int col);
protected:
-/** reimplemented form QTable not to use QTableItems. This one has no effect */
- void resizeData (int) {};
-/** reimplemented form QTable not to use QTableItems. This one has no effect */
- void insertWidget (int, int, QWidget *) {};
TwinTableMember *twin;
TwinTable *table;
bool changing_width;
- int trailing_rows;
- int trailing_cols;
+ bool changing_scroll;
CellEditor *tted;
+/** stores the position of the mouse, when headerRightClick gets emitted */
+ QPoint mouse_at;
+/** reimplemented from QTableView to also adjust the twin */
+ void scrollContentsBy (int dx, int dy);
+
+ RKVarEditModelBase* mymodel;
friend class TwinTable;
void setTwin (TwinTableMember *new_twin);
public slots:
void editorLostFocus ();
- void copy ();
/** called when the current cell is changed. If no selection is in place, will (does not do it yet) pop up the value-list */
- void currentCellChanged (int row, int col);
+// void currentCellChanged (int row, int col);
protected slots:
- void columnWidthChanged (int col);
+ void headerContextMenuRequested (const QPoint& pos);
};
#endif
Modified: branches/KDE4_port/rkward/dataeditor/twintablemetamember.cpp
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintablemetamember.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/twintablemetamember.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -32,6 +32,8 @@
#include "../debug.h"
+#warning TODO remove
+#if 0
TwinTableMetaMember::TwinTableMetaMember (QWidget *parent, TwinTable *table) : TwinTableMember (parent, table, 0, 1) {
type_values.insert (QString::number (RObject::DataNumeric), RObject::typeToText (RObject::DataNumeric));
type_values.insert (QString::number (RObject::DataFactor), RObject::typeToText (RObject::DataFactor));
@@ -166,3 +168,4 @@
}
#include "twintablemetamember.moc"
+#endif
Modified: branches/KDE4_port/rkward/dataeditor/twintablemetamember.h
===================================================================
--- branches/KDE4_port/rkward/dataeditor/twintablemetamember.h 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/dataeditor/twintablemetamember.h 2007-11-08 23:23:14 UTC (rev 2190)
@@ -23,7 +23,7 @@
class QWidget;
class TwinTable;
-
+#if 0
/**
The TwinTableMember responsible for storing the meta-information (i.e. the top half of the TwinTable). See TwinTable and TwinTableMember.
@@ -53,5 +53,5 @@
private:
RObject::ValueLabels type_values;
};
-
#endif
+#endif
Modified: branches/KDE4_port/rkward/windows/rkworkplace.cpp
===================================================================
--- branches/KDE4_port/rkward/windows/rkworkplace.cpp 2007-11-08 15:07:49 UTC (rev 2189)
+++ branches/KDE4_port/rkward/windows/rkworkplace.cpp 2007-11-08 23:23:14 UTC (rev 2190)
@@ -327,7 +327,7 @@
}
}
- ed = new RKEditorDataFrame (iobj, 0);
+ ed = new RKEditorDataFrame (static_cast<RContainerObject*> (iobj), 0);
addWindow (ed);
} else {
ed = existing_editor;
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