RKTextMatrix RKTextMatrix::transformed (bool reverse_h, bool reverse_v, bool transpose) const {
	RK_TRACE (EDITOR);

	RKTextMatrix ret;
	if (isEmpty ()) return ret;		// empty matrices would violate some assumptions of the following code

	const int maxrow = rows.size () - 1;		// for easier typing
	const int maxcol = rows[0].size () - 1;

	if (transpose) ret.upsize (maxcol, maxrow);		// set dimensions from the start to save a few cycles
	else ret.upsize (maxrow, maxcol);

	for (int row=0; row <= maxrow; ++row) {
		for (int col=0; col <= maxcol; ++col) {
			int dest_row = row;
			if (reverse_v) dest_row = maxrow - row;
			int dest_col = col;
			if (reverse_h) dest_col = maxcol - col;

			if (transpose) {
				int dummy = dest_row;
				dest_row = dest_col;
				dest_col = dummy;
			}

			ret.setText (dest_row, dest_col, rows[row][col]);
		}
	}

	return ret;
}
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->lockSyncing (true);
		for (int row = top; row <= bottom; ++row) {
			setData (index (row, col), text.getText (trow, tcol), Qt::EditRole);
			++trow;
		}
		var->lockSyncing (false);
		++tcol;
	}
}
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 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];
		int trow = 0;
		for (int row = top; row <= bottom; ++row) {
			var->setText (row, text.getText (trow, tcol));
			++trow;
		}
		++tcol;
	}
}
Esempio n. 5
0
void RKMatrixInput::copy () {
	RK_TRACE (PLUGIN);

	QItemSelectionRange range = display->getSelectionBoundaries ();
	if (!range.isValid ()) return;

	RKTextMatrix ret;
	for (int col = range.left (); col <= range.right (); ++col) {
		for (int row = range.top (); row <= range.bottom (); ++row) {
			ret.setText (row - range.top (), col - range.left (), cellValue (row, col));
		}
	}
	ret.copyToClipboard ();
}
// static
RKTextMatrix RKTextMatrix::matrixFromSeparatedValues (const QString& text, const QRegExp& tab, const QChar& brk) {
	RK_TRACE (EDITOR);

	RKTextMatrix ret;
	if (text.isEmpty ()) return ret;

	QStringList textrows = text.split (brk);
	if (textrows.last ().isEmpty ()) textrows.removeLast ();	// some apps append a trailing line break
	for (int i = 0; i < textrows.size (); ++i) {
		QStringList split = textrows[i].split (tab);
		ret.appendRow (split);
	}

	return ret;
}
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, bottom - top + 1);
		delete [] data;
		++tcol;
	}

	return ret;
}
Esempio n. 8
0
void RKMatrixInput::paste () {
	RK_TRACE (PLUGIN);

	int left = 0;
	int top = 0;
	QItemSelectionRange range = display->getSelectionBoundaries ();
	if (range.isValid ()) {
		left = range.left ();
		top = range.top ();
	}

	RKTextMatrix pasted = RKTextMatrix::matrixFromClipboard ();
	int height = allow_user_resize_rows ? pasted.numRows () : qMin (pasted.numRows (), row_count->intValue () - top);
	int width = allow_user_resize_columns ? pasted.numColumns () : qMin (pasted.numColumns (), column_count->intValue () - left);
	
	updating_tsv_data = true;
	for (int c = 0; c < width; ++c) {
		for (int r = 0; r < height; ++r) {
			setCellValue (r + top, c + left, pasted.getText (r, c));
		}
	}
	updating_tsv_data = false;
	updateAll ();
}