Exemplo n.º 1
0
RKEditor *RKWorkplace::editObject (RObject *object) {
	RK_TRACE (APP);

	RObject *iobj = object;
	RKEditor *ed = 0;
	RKEditor *existing_editor = RKGlobals::tracker ()->objectEditor (object);
	if (!existing_editor) {
		if (!iobj->isDataFrame ()) {
			if (iobj->isVariable () && iobj->getContainer ()->isDataFrame ()) {
				iobj = iobj->getContainer ();
			} else {
				return 0;
			}
		}

		unsigned long size = 1;
		foreach (int dim, iobj->getDimensions ()) {
			size *= dim;
		}
		if ((RKSettingsModuleGeneral::warnLargeObjectThreshold () != 0) && (size > RKSettingsModuleGeneral::warnLargeObjectThreshold ())) {
			if (KMessageBox::warningContinueCancel (view (), i18n ("You are about to edit object \"%1\", which is very large (%2 fields). RKWard is not optimized to handle very large objects in the built in data editor. This will use a lot of memory, and - depending on your system - might be very slow. For large objects it is generally recommended to edit using command line means or to split into smaller chunks before editing. On the other hand, if you have enough memory, or the data is simple enough (numeric data is easier to handle, than factor), editing may not be a problem at all. You can configure this warning (or turn it off entirely) under Settings->Configure RKWard->General.\nReally edit object?", iobj->getFullName (), size), i18n ("About to edit very large object")) != KMessageBox::Continue) {
				return 0;
			}
		}

		ed = new RKEditorDataFrame (static_cast<RContainerObject*> (iobj), 0);
		addWindow (ed);
	} else {
QVariant RKObjectListModel::data (const QModelIndex& index, int role) const {
	RK_TRACE (OBJECTS);

	int col = index.column ();
	RObject *object = static_cast<RObject*> (index.internalPointer ());

	if ((!object) || (col >= ColumnCount)) {
		RK_ASSERT (false);
		return QVariant ();
	}

	if (role == Qt::DisplayRole) {
		if (col == NameColumn) return object->getShortName ();
		if (col == LabelColumn) return object->getLabel ();
		if (col == TypeColumn) {
			if (object->isVariable ()) return RObject::typeToText (object->getDataType ());
			return QVariant ();
		}
		if ((col == ClassColumn) && (!object->isPseudoObject ())) return object->makeClassString ("; ");
	} else if (role == Qt::FontRole) {
		if (col == NameColumn && object->isPseudoObject ()) {
			QFont font;
			font.setItalic (true);
			return (font);
		}
	} else if (role == Qt::DecorationRole) {
		if (col == NameColumn) return RKStandardIcons::iconForObject (object);
	} else if (role == Qt::ToolTipRole) {
		return object->getObjectDescription ();
	}

	return QVariant ();
}
void RKVarEditDataFrameModel::childAdded (int index, RObject* parent) {
	RK_TRACE (EDITOR);

	if (parent == dataframe) {
		RObject* child = dataframe->findChildByIndex (index);
		RK_ASSERT (child);

		if (child->isVariable ()) addObject (index + var_col_offset, static_cast<RKVariable*> (child));
		else RK_ASSERT (false);
	}
}
void RKVarEditDataFrameModel::childMoved (int old_index, int new_index, RObject* parent) {
	RK_TRACE (EDITOR);

	if (parent == dataframe) {
		RObject *child = dataframe->findChildByIndex (new_index);	// it's at the new position, already
		RK_ASSERT (objects.size () > (old_index + var_col_offset));
		RK_ASSERT (child == objects[old_index + var_col_offset]);
		// if an object has changed position, there should be at least two objects left. Hence, the objectRemoved-call will never lead to editor destruction
		RK_ASSERT (objects.size () >= (var_col_offset + 2));
		objectRemoved (child);

		RK_ASSERT (child->isVariable ());
		addObject (new_index + var_col_offset, static_cast<RKVariable*> (child));
	} else {
		// even though we are listening for the child objects as well, we should see move notifications
		// only for children of the parent.
		RK_ASSERT (false);
	}
}
bool RKVarEditDataFrameModel::insertColumns (int column, int count, const QModelIndex& parent) {
	RK_TRACE (EDITOR);

	if (parent.isValid ()) {
		RK_ASSERT (false);
		return false;
	}

	if (column > trueCols ()) column = trueCols ();
	if (column < var_col_offset) column = var_col_offset;
	for (int col = column; col < (column + count); ++col) {
		RObject *obj = dataframe->createPendingChild (dataframe->validizeName (QString ()), col-var_col_offset);
		RK_ASSERT (obj->isVariable ());
//		addObject (col, obj);	// the object will be added via RKModificationTracker::addObject -> this::childAdded. That will also take care of calling beginInsertColumns()/endInsertColumns()
	
		RKGlobals::rInterface ()->issueCommand (new RCommand (".rk.data.frame.insert.column (" + dataframe->getFullName () + ", \"" + obj->getShortName () + "\", " + QString::number (col+1-var_col_offset) + ")", RCommand::App | RCommand::Sync));
	}

	return true;
}
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 (df->validizeName (QString ()), -1, false, false);
		RK_ASSERT (child->isVariable ());
		// let's start with one (empty) row, to avoid confusion
		static_cast<RKVariable*> (child)->setLength (1);
	}

	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;
	trailing_cols = 1;

	addNotificationType (RObjectListener::ChildAdded);
	addNotificationType (RObjectListener::ChildMoved);
	listenForObject (dataframe);

	for (int i = 0; i < dataframe->numChildren (); ++i) {
		RObject* obj = dataframe->findChildByIndex (i);
		RK_ASSERT (obj);
		RK_ASSERT (obj->isVariable ());
		addObject (i, static_cast<RKVariable*> (obj));
	}
	rownames = dataframe->rowNames ();
	addObject (0, rownames);
	getMetaModel ()->var_col_offset = var_col_offset = 1;
}