void TableModelVariablesAssigned::assign(const Terms &variables)
{
	if (_boundTo == NULL)
		return;

	Terms v;

	if (_boundTo->onlyOneTerm())
	{
		if (variables.size() > 0)
			v.add(variables.at(0));

		if (_variables.size() > 0)
		{
			_toSendBack.set(_variables);
			_variables.clear();
			QTimer::singleShot(0, this, SLOT(sendBack()));
		}
	}
	else
	{
		v.set(_variables);
		v.add(variables);
	}

	setAssigned(v);

	emit assignedTo(variables);
}
bool TableModelVariables::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
	if (_dragActions == Qt::CopyAction && _dropActions == Qt::MoveAction && action == Qt::MoveAction) // if delete
		return true;

	if ( ! canDropMimeData(data, action, row, column, parent))
		return false;

	if (action == Qt::IgnoreAction)
		return true;

	if (data->hasFormat(_mimeType))
	{
		QByteArray encodedData = data->data(_mimeType);

		Terms variables;
		variables.set(encodedData);

		beginResetModel();
		_variables.add(variables);
		endResetModel();

		return true;
	}

	return false;
}
void TableModelVariablesAssigned::unassign(const Terms &variables)
{
	Terms variablesToKeep;
	variablesToKeep.set(_variables);
	variablesToKeep.remove(variables);
	setAssigned(variablesToKeep);

	emit unassigned(variables);
}
bool TableModelAnovaWithinSubjectCells::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
{
	Q_UNUSED(row);

	int colNo = (column == -1 ? parent.column() : column);
	int rowNo = (row    == -1 ? parent.row()    : row);

	if (_boundTo == NULL)
		return false;

	if (action == Qt::IgnoreAction)
		return true;

	if ( ! data->hasFormat("application/vnd.list.variable"))
		return false;

	if (action != Qt::MoveAction)
		return false;

	if (colNo != 0)
		return false;

	QByteArray encodedData = data->data("application/vnd.list.variable");

	Terms dropped;
	dropped.set(encodedData);

	foreach (const Term &term, dropped)
	{
		if ( ! isAllowed(term))
			return false;
	}

	if (rowNo == -1)
	{
		int available = 0;

		for (int i = 0; i < _variables.size(); i++)
		{
			if (_variables.at(i) == "")
				available++;
		}

		return dropped.size() <= available;
	}
	else
	{
		return dropped.size() <= _variables.size() - rowNo;
	}

	return true;
}
void TableModelVariablesAssigned::sourceVariablesChanged()
{
	emit assignmentsChanging();

	const Terms &variables = _source->allVariables();
	Terms variablesToKeep;
	bool variableRemoved = false;

	variablesToKeep.set(_variables);
	variableRemoved = variablesToKeep.discardWhatDoesntContainTheseComponents(variables);

	if (variableRemoved)
		setAssigned(variablesToKeep);

	emit assignmentsChanged();
}
bool TableModelVariables::canDropMimeData(const QMimeData *data, Qt::DropAction action, int, int, const QModelIndex &) const
{
	if (_dragActions == Qt::CopyAction && _dropActions == Qt::MoveAction && action == Qt::MoveAction) // if delete
		return true;

	if (data->hasFormat(_mimeType))
	{
		QByteArray encodedData = data->data(_mimeType);

		Terms variables;
		variables.set(encodedData);

		foreach (const Term &variable, variables)
		{
			if ( ! isAllowed(variable))
				return false;
		}

		return true;
	}
bool TableModelVariablesAssigned::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
{
	if (_boundTo == NULL)
		return false;

	if (isDroppingToSelf(data))
		return false;

	if ( ! TableModelVariables::canDropMimeData(data, action, row, column, parent))
		return false;

	if (_boundTo->onlyOneTerm())
	{
		QByteArray encodedData = data->data(_mimeType);

		Terms variables;
		variables.set(encodedData);

		if (variables.size() != 1)
			return false;
	}

	return true;
}
bool TableModelAnovaWithinSubjectCells::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
	Q_UNUSED(column);

	if (action == Qt::IgnoreAction)
		return true;

	if ( ! canDropMimeData(data, action, row, column, parent))
		return false;

	//int colNo = (column == -1 ? parent.column() : column);
	int rowNo = (row    == -1 ? parent.row()    : row);

	QByteArray encodedData = data->data("application/vnd.list.variable");

	Terms dropped;
	dropped.set(encodedData);

	vector<string> droppedItems = dropped.asVector();

	beginResetModel();

	if (rowNo == -1)
	{
		int pos = 0;

		for (int i = 0; i < _variables.size(); i++)
		{
			if (_variables.at(i) == "")
				_variables[i] = droppedItems.at(pos++);

			if (pos >= droppedItems.size())
				break;
		}
	}
	else
	{
		int pos = 0;

		for (int i = rowNo; i < _variables.size(); i++)
		{
			string existingVariable = _variables.at(i);
			if (existingVariable != "")
				_toSendBack.add(existingVariable);

			_variables[i] = droppedItems[pos++];

			if (pos >= droppedItems.size())
				break;
		}

		if (_toSendBack.size() > 0)
			QTimer::singleShot(0, this, SLOT(sendBack()));
	}

	_boundTo->setValue(_variables);

	endResetModel();

	return true;
}