[education/rkward] /: Paste special action: Add support for data.frame()s and labels

Thomas Friedrichsmeier null at kde.org
Mon Apr 25 21:42:30 BST 2022


Git commit 57104e9e732fdeaed674949d9fbfc4a287caf215 by Thomas Friedrichsmeier.
Committed on 25/04/2022 at 20:42.
Pushed by tfry into branch 'master'.

Paste special action: Add support for data.frame()s and labels

M  +4    -0    ChangeLog
M  +1    -10   rkward/dataeditor/rktextmatrix.cpp
M  +0    -2    rkward/dataeditor/rktextmatrix.h
M  +52   -18   rkward/misc/rkspecialactions.cpp
M  +5    -2    rkward/misc/rkspecialactions.h

https://invent.kde.org/education/rkward/commit/57104e9e732fdeaed674949d9fbfc4a287caf215

diff --git a/ChangeLog b/ChangeLog
index 607c8d2d..ed62fa82 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+TODOs:
+	- More tolerant handshake on Windows? Simply a matter of allowing more time?
+
+- "Paste special" action gains option to format as data.frame, optionally with labels
 - Add "rio"-based generic import plugin
 - Fixed: Installation from dialog would fail for R packages requiring the rkward package
 - Allow separate analysis by grouping factors in Analysis->Descriptive Statistics
diff --git a/rkward/dataeditor/rktextmatrix.cpp b/rkward/dataeditor/rktextmatrix.cpp
index d7c07dba..5cdfcdde 100644
--- a/rkward/dataeditor/rktextmatrix.cpp
+++ b/rkward/dataeditor/rktextmatrix.cpp
@@ -13,17 +13,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "../debug.h"
 
-RKTextMatrix::RKTextMatrix () {
+RKTextMatrix::RKTextMatrix() : colcount(0) {
 	RK_TRACE (EDITOR);
-
-	clear ();
-}
-
-RKTextMatrix::RKTextMatrix (const RKTextMatrix& copy) {
-	RK_TRACE (EDITOR);
-
-	colcount = copy.colcount;
-	rows = copy.rows;
 }
 
 RKTextMatrix::~RKTextMatrix () {
diff --git a/rkward/dataeditor/rktextmatrix.h b/rkward/dataeditor/rktextmatrix.h
index 429af4be..e2c9654b 100644
--- a/rkward/dataeditor/rktextmatrix.h
+++ b/rkward/dataeditor/rktextmatrix.h
@@ -17,8 +17,6 @@ to and from text/tab-separated-values format, and it does not hickup in case of
 class RKTextMatrix {
 public:
 	RKTextMatrix ();
-/** copy constructor. Since we're mostly just copying a QList (which is implicitly shared) and two ints, this is pretty fast. */
-	RKTextMatrix (const RKTextMatrix& copy);
 	~RKTextMatrix ();
 
 	static RKTextMatrix matrixFromClipboard ();
diff --git a/rkward/misc/rkspecialactions.cpp b/rkward/misc/rkspecialactions.cpp
index 70fb755b..ed8b3655 100644
--- a/rkward/misc/rkspecialactions.cpp
+++ b/rkward/misc/rkspecialactions.cpp
@@ -77,6 +77,9 @@ RKPasteSpecialDialog::RKPasteSpecialDialog (QWidget* parent) : QDialog (parent)
 	group_layout->addWidget (rbutton);
 	rbutton = new QRadioButton (i18n ("Matrix"), box);
 	dimensionality_group->addButton (rbutton, DimMatrix);
+	group_layout->addWidget (rbutton);
+	rbutton = new QRadioButton (i18n ("data.frame"), box);
+	dimensionality_group->addButton (rbutton, DimDataFrame);
 	rbutton->setChecked (true);
 	group_layout->addWidget (rbutton);
 	connect (dimensionality_group, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &RKPasteSpecialDialog::updateState);
@@ -132,6 +135,15 @@ RKPasteSpecialDialog::RKPasteSpecialDialog (QWidget* parent) : QDialog (parent)
 	connect (quoting_group, static_cast<void (QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &RKPasteSpecialDialog::updateState);
 	rowlayout->addWidget (box);
 
+	// Labels
+	box = new QGroupBox(i18n("Labels"), this);
+	group_layout = new QVBoxLayout (box);
+	names_box = new QCheckBox(i18n("First column contains labels"), box);
+	group_layout->addWidget(names_box);
+	rownames_box = new QCheckBox(i18n("First row contains labels"), box);
+	group_layout->addWidget(rownames_box);
+	rowlayout->addWidget(box);
+
 	// further controls
 	box = new QGroupBox (i18n ("Transformations"), this);
 	group_layout = new QVBoxLayout (box);
@@ -165,9 +177,11 @@ void RKPasteSpecialDialog::updateState () {
 	
 	static_cast<QWidget*> (separator_group->parent ())->setEnabled (dimensionality != DimSingleString);
 	reverse_h_box->setEnabled (dimensionality != DimSingleString);
-	reverse_v_box->setEnabled (dimensionality == DimMatrix);
+	reverse_v_box->setEnabled (dimensionality >= DimMatrix);
 	insert_nas_box->setEnabled (dimensionality != DimSingleString);
-	transpose_box->setEnabled (dimensionality == DimMatrix);
+	transpose_box->setEnabled(dimensionality >= DimMatrix);
+	names_box->setEnabled(dimensionality == DimDataFrame);
+	rownames_box->setEnabled(dimensionality == DimDataFrame);
 
 	separator_freefield->setEnabled ((dimensionality != DimSingleString) && (separator_group->checkedId () == SepCustom));
 }
@@ -178,8 +192,11 @@ QString RKPasteSpecialDialog::resultingText () {
 	const int sep = separator_group->checkedId ();		// for easier typing
 	const int dim = dimensionality_group->checkedId ();
 	const bool reverse_h = reverse_h_box->isChecked () && (dim != DimSingleString);
-	const bool reverse_v = reverse_v_box->isChecked () && (dim == DimMatrix);
-	const bool transpose = transpose_box->isChecked () && (dim == DimMatrix);
+	const bool reverse_v = reverse_v_box->isChecked () && (dim >= DimMatrix);
+	const bool transpose = transpose_box->isChecked () && (dim >= DimMatrix);
+	const bool names = names_box->isChecked() && (dim == DimDataFrame);
+	const bool rownames = rownames_box->isChecked() && (dim == DimDataFrame);
+	Quoting quot = (Quoting) quoting_group->checkedId();
 
 	QString clip;
 
@@ -192,7 +209,7 @@ QString RKPasteSpecialDialog::resultingText () {
 		clip = data->text ();
 	}
 
-	if (dim == DimSingleString) return prepString (clip);
+	if (dim == DimSingleString) return prepString(clip, quot);
 
 	QRegExp fieldsep;
 	if (sep == SepCustom) fieldsep.setPattern (separator_freefield->text ());
@@ -215,30 +232,47 @@ QString RKPasteSpecialDialog::resultingText () {
 	if (reverse_h || reverse_v || transpose) matrix = matrix.transformed (reverse_h, reverse_v, transpose);
 
 	QString ret;
-	if (dim == DimMatrix) ret.append ("cbind (\n");
-	else ret.append ("c (");	// DimVector
-
-	for (int i = 0; i < matrix.numColumns (); ++i) {
-		if (dim == DimMatrix) {
-			if (i != 0) ret.append ("),\n");
-			ret.append ("c(");
+	if (dim == DimDataFrame) ret.append("data.frame(");
+	if (dim >= DimMatrix) ret.append ("cbind(\n");
+	else ret.append ("c(");	// DimVector
+
+	int startcol = rownames ? 1 : 0;
+	int startrow = names ? 1 : 0;
+	for (int i = startcol; i < matrix.numColumns (); ++i) {
+		if (dim >= DimMatrix) {
+			if (i != startcol) ret.append ("),\n");
+			if (names) {
+				ret.append(prepString(matrix.getText(0, i), QuoteAll) + "=c(");
+			} else {
+				ret.append("c(");
+			}
 		} else if (i != 0) ret.append (",");
 
-		for (int j = 0; j < matrix.numRows (); ++j) {
-			if (j != 0) ret.append (",");
-			ret.append (prepString (matrix.getText (j, i)));
+		for (int j = startrow; j < matrix.numRows (); ++j) {
+			if (j != startrow) ret.append (",");
+			ret.append(prepString(matrix.getText(j, i), quot));
 		}
 	}
 	ret.append (")\n");
-	if (dim == DimMatrix) ret.append (")\n");
+	if (dim == DimDataFrame) {
+		ret.append(')');
+		if (rownames) {
+			ret.append(", rownames=c(\n");
+			for (int row = startrow; row < matrix.numRows(); ++row) {
+				if (row != startrow) ret.append (",");
+				ret.append(prepString(matrix.getText(row, 0), QuoteAll));
+			}
+			ret.append(")\n");
+		}
+	}
+	if (dim >= DimMatrix) ret.append (")\n");
 
 	return (ret);
 }
 
-QString RKPasteSpecialDialog::prepString (const QString& src) const {
+QString RKPasteSpecialDialog::prepString(const QString& src, const Quoting quot) const {
 //	RK_TRACE (MISC);
 
-	const int quot = quoting_group->checkedId ();
 	if (quot == QuoteAll) return (RObject::rQuote (src));
 	if (src.isEmpty() && insert_nas_box->isChecked ()) return ("NA");
 	if (quot == QuoteNone) return (src);
diff --git a/rkward/misc/rkspecialactions.h b/rkward/misc/rkspecialactions.h
index 548a300c..fd4e59ee 100644
--- a/rkward/misc/rkspecialactions.h
+++ b/rkward/misc/rkspecialactions.h
@@ -43,7 +43,8 @@ public:
 	enum Dimensionality {
 		DimSingleString,
 		DimVector,
-		DimMatrix
+		DimMatrix,
+		DimDataFrame
 	};
 	enum Separator {
 		SepTab,
@@ -62,7 +63,7 @@ public:
 public slots:
 	void updateState ();
 private:
-	QString prepString (const QString& src) const;
+	QString prepString (const QString& src, const Quoting quot) const;
 
 	QButtonGroup* dimensionality_group;
 	QButtonGroup* separator_group;
@@ -72,6 +73,8 @@ private:
 	QCheckBox* reverse_h_box;
 	QCheckBox* reverse_v_box;
 	QCheckBox* insert_nas_box;
+	QCheckBox* names_box;
+	QCheckBox* rownames_box;
 };
 
 #endif


More information about the rkward-tracker mailing list