Example #1
0
	void Executer::executeCurrentAction()
	{
		//Skip disabled actions
		if(mCurrentActionIndex >= 0)
		{
			while(mCurrentActionIndex < mScript->actionCount() && canExecuteAction(mCurrentActionIndex) != CanExecute)
				++mCurrentActionIndex;
		}

		if(mCurrentActionIndex < 0 || mCurrentActionIndex >= mScript->actionCount())
		{
			stopExecution();
			return;
		}

        int nextLine = mCurrentActionIndex + 2;
		if(nextLine > mScript->actionCount())
			nextLine = -1;

		QScriptValue script = mScriptEngine->globalObject().property("Script");
		script.setProperty("nextLine", mScriptEngine->newVariant(QVariant(nextLine)));
        script.setProperty("line", mCurrentActionIndex + 1, QScriptValue::ReadOnly);

		ActionTools::ActionInstance *actionInstance = currentActionInstance();

        const ActionTools::ExceptionActionInstancesHash &exceptionActionInstancesHash = actionInstance->exceptionActionInstances();
        const ActionTools::ActionException::ExceptionActionInstance &exceptionAction = exceptionActionInstancesHash.value(ActionTools::ActionException::CodeErrorException);
        mShowDebuggerOnCodeError = (exceptionAction.action() == ActionTools::ActionException::StopExecutionExceptionAction);

		mExecutionWindow->setCurrentActionName(actionInstance->definition()->name());
		mExecutionWindow->setCurrentActionColor(actionInstance->color());

		connect(actionInstance, SIGNAL(executionEnded()), this, SLOT(actionExecutionEnded()));
		connect(actionInstance, SIGNAL(executionException(int,QString)), this, SLOT(executionException(int,QString)));
		connect(actionInstance, SIGNAL(disableAction(bool)), this, SLOT(disableAction(bool)));
		connect(actionInstance, SIGNAL(showProgressDialog(QString,int)), this, SLOT(showProgressDialog(QString,int)));
		connect(actionInstance, SIGNAL(updateProgressDialog(int)), this, SLOT(updateProgressDialog(int)));
		connect(actionInstance, SIGNAL(updateProgressDialog(QString)), this, SLOT(updateProgressDialog(QString)));
		connect(actionInstance, SIGNAL(hideProgressDialog()), this, SLOT(hideProgressDialog()));
		connect(actionInstance, SIGNAL(consolePrint(QString)), this, SLOT(consolePrint(QString)));
		connect(actionInstance, SIGNAL(consolePrintWarning(QString)), this, SLOT(consolePrintWarning(QString)));
		connect(actionInstance, SIGNAL(consolePrintError(QString)), this, SLOT(consolePrintError(QString)));
		
		mExecutionStatus = PrePause;

		mExecutionTimer.start();
		mExecutionTime.start();
		if(currentActionInstance()->pauseBefore() + mPauseBefore > 0)
		{
			mExecutionWindow->setProgressEnabled(true);
			mExecutionWindow->setProgressMinimum(0);
			mExecutionWindow->setProgressMaximum(currentActionInstance()->pauseBefore() + mPauseBefore);
			mExecutionWindow->setProgressValue(0);
		}
		else
			mExecutionWindow->setProgressEnabled(false);

		mExecutionEnded = true;
	}
Example #2
0
QMimeData* ScriptModel::mimeData(const QModelIndexList &indexes) const
{
	if(indexes.isEmpty())
		return 0;

	QMimeData *mimeDataPtr = new QMimeData();
	QByteArray encodedData;
	QDataStream stream(&encodedData, QIODevice::WriteOnly);

	QList<int> rowIdList;

	for(const QModelIndex &index: indexes)
	{
		if(!index.isValid() || index.column() != ColumnLabel)
			continue;

		if(!rowIdList.contains(index.row()))
			rowIdList << index.row();
	}

    std::sort(rowIdList.begin(), rowIdList.end(), qGreater<int>());

	for(int row: rowIdList)
	{
		ActionTools::ActionInstance *actionInstance = mScript->actionAt(row);

		if(!actionInstance)
			continue;

		stream << row;
		stream << ActionTools::ActionInstanceBuffer(actionInstance->definition()->id(), *actionInstance);
	}

    mimeDataPtr->setData("application/actiona.action", encodedData);
	return mimeDataPtr;
}
Example #3
0
QVariant ScriptModel::data(const QModelIndex &index, int role) const
{
	if(!index.isValid())
		return QVariant();

	ActionTools::ActionInstance *actionInstance = mScript->actionAt(index.row());
	if(!actionInstance)
		return QVariant();

	switch(role)
	{
	case ActionDataRole:
		return QVariant::fromValue(*actionInstance);
	case ActionIdRole:
		return actionInstance->definition()->id();
	case Qt::BackgroundRole:
		{
			const QColor &color = actionInstance->color();

			if(color.isValid())
				return QBrush(color);

			return QBrush();
		}
	case Qt::FontRole:
		{
			if(!actionInstance->definition()->worksUnderThisOS())
			{
				QFont font = QApplication::font();

				font.setItalic(true);

				return font;
			}

			return QFont();
		}
	case Qt::ForegroundRole:
		{
			const QColor &color = actionInstance->color();
			if(color.isValid())
			{
				if(color.lightness() < 128)
					return QBrush(Qt::white);
				else
					return QBrush(Qt::black);
			}
			else
			{
				const QPalette &palette = QApplication::palette();

				if(!actionInstance->isEnabled())
					return QBrush(palette.color(QPalette::Disabled, QPalette::WindowText));

				return QBrush();
			}
		}
	}

	switch(index.column())
	{
	case ColumnLabel:
		switch(role)
		{
			case Qt::CheckStateRole:
				return QVariant(actionInstance->isEnabled() ? Qt::Checked : Qt::Unchecked);
			case Qt::DisplayRole:
			{
				QString labelString = actionInstance->label();
				if(!labelString.isNull() && !labelString.isEmpty())
					return labelString;

				return QString("%1").arg(index.row() + 1, 3, 10, QChar('0'));
			}
			case Qt::EditRole:
				return actionInstance->label();
		}
		break;
	case ColumnActionName:
		switch(role)
		{
			case Qt::ToolTipRole:
				return tr("Double-clic to edit the action");
			case Qt::DisplayRole:
				return actionInstance->definition()->name();
			case Qt::DecorationRole:
				return QIcon(actionInstance->definition()->icon());
			case Qt::TextAlignmentRole:
				return Qt::AlignCenter;
		}
		break;
	case ColumnComment:
		switch(role)
		{
			case Qt::DisplayRole:
			case Qt::EditRole:
				return actionInstance->comment();
		}
		break;
	}

	return QVariant();
}
Example #4
0
	void Executer::executionException(int exception,
									  const QString &message)
	{
		ActionTools::ActionInstance *actionInstance = currentActionInstance();
		bool standardException = (exception >= 0 && exception < ActionTools::ActionException::ExceptionCount);
		bool customException = false;

		for(ActionTools::ActionException *actionException: actionInstance->definition()->exceptions())
		{
			if(actionException->id() == exception)
			{
				customException = true;
				break;
			}
		}

		if(!standardException && !customException)
		{
			mConsoleWidget->addDesignErrorLine(tr("Action design error: Invalid exception emitted (%1, line %2)")
											   .arg(actionInstance->definition()->name())
											   .arg(mCurrentActionIndex+1), ActionTools::ConsoleWidget::Error);
			stopExecution();
			return;
		}

		ActionTools::ActionException::ExceptionActionInstance exceptionActionInstance = actionInstance->exceptionActionInstance(static_cast<ActionTools::ActionException::Exception>(exception));
		ActionTools::ConsoleWidget::Type exceptionType;
		bool shouldStopExecution;
		switch(exceptionActionInstance.action())
		{
		case ActionTools::ActionException::SkipExceptionAction:
			exceptionType = ActionTools::ConsoleWidget::Information;
			actionExecutionEnded();

			shouldStopExecution = false;
			break;
		case ActionTools::ActionException::GotoLineExceptionAction:
			{
				exceptionType = ActionTools::ConsoleWidget::Information;

				if(canExecuteAction(exceptionActionInstance.line()) != CanExecute)
				{
					ActionTools::ActionInstance *currentAction = mScript->actionAt(mCurrentActionIndex);
					qint64 currentActionRuntimeId = -1;
					if(currentAction)
						currentActionRuntimeId = currentAction->runtimeId();

					mConsoleWidget->addExceptionLine(tr("Invalid exception line: %1").arg(exceptionActionInstance.line()),
													 currentActionRuntimeId,
													 exception,
													 ActionTools::ConsoleWidget::Error);
					shouldStopExecution = true;
				}
				else
				{
					QScriptValue script = mScriptEngine->globalObject().property("Script");
					script.setProperty("nextLine", mScriptEngine->newVariant(QVariant(exceptionActionInstance.line())));
					actionExecutionEnded();
					shouldStopExecution = false;
				}
			}
			break;
		default:
			exceptionType = ActionTools::ConsoleWidget::Error;

			shouldStopExecution = true;
		}

		if(shouldStopExecution)
		{
            QString finalMessage = tr("Script line %1: ").arg(mCurrentActionIndex+1);

			ActionTools::ActionInstance *currentAction = mScript->actionAt(mCurrentActionIndex);
			qint64 currentActionRuntimeId = -1;
			if(currentAction)
				currentActionRuntimeId = currentAction->runtimeId();

			mConsoleWidget->addActionLine(finalMessage + message,
										currentActionRuntimeId,
                                        mScriptEngine->globalObject().property("currentParameter").toString(),
                                        mScriptEngine->globalObject().property("currentSubParameter").toString(),
										mScriptAgent->currentLine(),
										mScriptAgent->currentColumn(),
										exceptionType);

			stopExecution();
		}
	}
Example #5
0
	bool Executer::startExecution(bool onlySelection)
	{
		Q_ASSERT(mScriptAgent);
		Q_ASSERT(mScriptEngine);
		
	#ifdef ACT_PROFILE
		Tools::HighResolutionTimer timer("Executer::startExecution");
	#endif

        Code::CodeTools::addClassToScriptEngine<CodeActiona>("Actiona", mScriptEngine);
        CodeActiona::setActExec(mIsActExec);
        CodeActiona::setActionaVersion(mActionaVersion);
        CodeActiona::setScriptVersion(mScriptVersion);
        Code::CodeTools::addClassGlobalFunctionToScriptEngine("Actiona", &CodeActiona::version, "version", mScriptEngine);
        Code::CodeTools::addClassGlobalFunctionToScriptEngine("Actiona", &CodeActiona::scriptVersion, "scriptVersion", mScriptEngine);
        Code::CodeTools::addClassGlobalFunctionToScriptEngine("Actiona", &CodeActiona::isActExec, "isActExec", mScriptEngine);
        Code::CodeTools::addClassGlobalFunctionToScriptEngine("Actiona", &CodeActiona::isActiona, "isActiona", mScriptEngine);
		
		mScriptAgent->setContext(ScriptAgent::ActionInit);
		CodeInitializer::initialize(mScriptEngine, mScriptAgent, mActionFactory);
		mScriptAgent->setContext(ScriptAgent::Parameters);
		
        QScriptValue script = mScriptEngine->newObject();
		mScriptEngine->globalObject().setProperty("Script", script, QScriptValue::ReadOnly);
        script.setProperty("nextLine", 1);
        script.setProperty("line", 1, QScriptValue::ReadOnly);
        QScriptValue callProcedureFun = mScriptEngine->newFunction(callProcedureFunction);
        callProcedureFun.setData(mScriptEngine->newQObject(this));
        script.setProperty("callProcedure", callProcedureFun);

		QScriptValue console = mScriptEngine->newObject();
		mScriptEngine->globalObject().setProperty("Console", console, QScriptValue::ReadOnly);

        QScriptValue function = mScriptEngine->newFunction(printFunction);
        function.setData(mScriptEngine->newQObject(this));
        console.setProperty("print", function);

        function = mScriptEngine->newFunction(printWarningFunction);
        function.setData(mScriptEngine->newQObject(this));
        console.setProperty("printWarning", function);

        function = mScriptEngine->newFunction(printErrorFunction);
        function.setData(mScriptEngine->newQObject(this));
        console.setProperty("printError", function);

        function = mScriptEngine->newFunction(clearConsoleFunction);
        function.setData(mScriptEngine->newQObject(this));
        console.setProperty("clear", function);

		mExecuteOnlySelection = onlySelection;
		mCurrentActionIndex = 0;
		mActiveActionsCount = 0;
		mExecutionPaused = false;

		bool initSucceeded = true;
		int lastBeginProcedure = -1;

		mScript->clearProcedures();
		mScript->clearCallStack();

        const QHash<QString, ActionTools::Resource> &resources = mScript->resources();
        for(const QString &key: resources.keys())
        {
            const ActionTools::Resource &resource = resources.value(key);
            QScriptValue value;

            switch(resource.type())
            {
            case ActionTools::Resource::BinaryType:
            case ActionTools::Resource::TypeCount:
                value = Code::RawData::constructor(resource.data(), mScriptEngine);
                break;
            case ActionTools::Resource::TextType:
                value = QString::fromUtf8(resource.data(), resource.data().size());
                break;
            case ActionTools::Resource::ImageType:
                {
                    QImage image;

                    if(!image.loadFromData(resource.data()))
                    {
                        mConsoleWidget->addResourceLine(tr("Invalid image resource"), key, ActionTools::ConsoleWidget::Error);

                        return false;
                    }

                    value = Code::Image::constructor(image, mScriptEngine);
                }
                break;
            }

            mScriptEngine->globalObject().setProperty(key, value, QScriptValue::ReadOnly | QScriptValue::Undeletable);
        }

		for(int actionIndex = 0; actionIndex < mScript->actionCount(); ++actionIndex)
		{
			ActionTools::ActionInstance *actionInstance = mScript->actionAt(actionIndex);
			actionInstance->reset();
			actionInstance->clearRuntimeParameters();
			actionInstance->setupExecution(mScriptEngine, mScript, actionIndex);
			mActionEnabled.append(true);

			qint64 currentActionRuntimeId = -1;
			if(actionInstance)
				currentActionRuntimeId = actionInstance->runtimeId();

			if(canExecuteAction(actionIndex) == CanExecute)
			{
				++mActiveActionsCount;

				if(actionInstance->definition()->id() == "ActionBeginProcedure")
				{
					if(lastBeginProcedure != -1)
					{
						mConsoleWidget->addActionLine(tr("Invalid Begin procedure action, you have to end the previous procedure before starting another one"), currentActionRuntimeId, QString(), QString(), -1, -1, ActionTools::ConsoleWidget::Error);

						return false;
					}

					lastBeginProcedure = actionIndex;

					const ActionTools::SubParameter &nameParameter = actionInstance->subParameter("name", "value");
					const QString &procedureName = nameParameter.value().toString();

					if(procedureName.isEmpty())
					{
						mConsoleWidget->addActionLine(tr("A procedure name cannot be empty"), currentActionRuntimeId, QString(), QString(), -1, -1, ActionTools::ConsoleWidget::Error);

						return false;
					}

					if(mScript->findProcedure(procedureName) != -1)
					{
						mConsoleWidget->addActionLine(tr("A procedure with the name \"%1\" has already been declared").arg(procedureName), currentActionRuntimeId, QString(), QString(), -1, -1, ActionTools::ConsoleWidget::Error);

						return false;
					}

					mScript->addProcedure(procedureName, actionIndex);
				}
				else if(actionInstance->definition()->id() == "ActionEndProcedure")
				{
					if(lastBeginProcedure == -1)
					{
						mConsoleWidget->addActionLine(tr("Invalid End procedure"), currentActionRuntimeId, QString(), QString(), -1, -1, ActionTools::ConsoleWidget::Error);

						return false;
					}

					ActionTools::ActionInstance *beginProcedureActionInstance = mScript->actionAt(lastBeginProcedure);

					actionInstance->setRuntimeParameter("procedureBeginLine", lastBeginProcedure);
					beginProcedureActionInstance->setRuntimeParameter("procedureEndLine", actionIndex);

					lastBeginProcedure = -1;
				}
			}
		}

		if(lastBeginProcedure != -1)
		{
			ActionTools::ActionInstance *actionInstance = mScript->actionAt(lastBeginProcedure);
			qint64 actionRuntimeId = -1;
			if(actionInstance)
				actionRuntimeId = actionInstance->runtimeId();

			mConsoleWidget->addActionLine(tr("Begin procedure action without end procedure"), actionRuntimeId, QString(), QString(), -1, -1, ActionTools::ConsoleWidget::Error);

			return false;
		}

		for(int parameterIndex = 0; parameterIndex < mScript->parameterCount(); ++parameterIndex)
		{
			mScriptAgent->setCurrentParameter(parameterIndex);

			const ActionTools::ScriptParameter &scriptParameter = mScript->parameter(parameterIndex);
			QRegExp nameRegExp("[a-z_][a-z0-9_]*", Qt::CaseInsensitive);

			if(!nameRegExp.exactMatch(scriptParameter.name()))
			{
				mConsoleWidget->addScriptParameterLine(tr("Incorrect parameter name: \"%1\"").arg(scriptParameter.name()),
													   parameterIndex,
													   -1,
													   -1,
													   ActionTools::ConsoleWidget::Error);
				initSucceeded = false;
				continue;
			}

			QString value;
			if(scriptParameter.isCode())
			{
				QScriptValue result = mScriptEngine->evaluate(scriptParameter.value());
				if(result.isError())
				{
					mConsoleWidget->addScriptParameterLine(tr("Error while evaluating parameter \"%1\", error message: \"%2\"")
														   .arg(scriptParameter.name())
														   .arg(result.toString()),
														   parameterIndex,
														   -1,
														   -1,
														   ActionTools::ConsoleWidget::Error);
					initSucceeded = false;
					continue;
				}
				else
					value = result.toString();
			}
			else
				value = scriptParameter.value();

			mScriptEngine->globalObject().setProperty(scriptParameter.name(), value, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		}

		if(!initSucceeded || mScript->actionCount() == 0)
			return false;

		if(mShowExecutionWindow)
		{
			QRect screenRect = QApplication::desktop()->availableGeometry(mExecutionWindowScreen);
			QPoint position;

			if(mExecutionWindowPosition >= 0 && mExecutionWindowPosition <= 2)//Left
				position.setX(screenRect.left());
			else if(mExecutionWindowPosition >= 3 && mExecutionWindowPosition <= 5)//HCenter
				position.setX(screenRect.left() + screenRect.width() / 2 - mExecutionWindow->width() / 2);
			else if(mExecutionWindowPosition >= 6 && mExecutionWindowPosition <= 8)//Right
				position.setX(screenRect.left() + screenRect.width() - mExecutionWindow->width());

			if(mExecutionWindowPosition == 0 || mExecutionWindowPosition == 3 || mExecutionWindowPosition == 6)//Up
				position.setY(screenRect.top());
			else if(mExecutionWindowPosition == 1 || mExecutionWindowPosition == 4 || mExecutionWindowPosition == 7)//VCenter
				position.setY(screenRect.top() + screenRect.height() / 2 - mExecutionWindow->height() / 2);
			else if(mExecutionWindowPosition == 2 || mExecutionWindowPosition == 5 || mExecutionWindowPosition == 8)//Down
				position.setY(screenRect.top() + screenRect.height() - mExecutionWindow->height());

			mExecutionWindow->setPauseStatus(false);
			mExecutionWindow->move(position);
			mExecutionWindow->show();
		}

		if(mShowConsoleWindow)
		{
			QRect screenRect = QApplication::desktop()->availableGeometry(mConsoleWindowScreen);
			QPoint position;

			if(mConsoleWindowPosition >= 0 && mConsoleWindowPosition <= 2)//Left
				position.setX(screenRect.left());
			else if(mConsoleWindowPosition >= 3 && mConsoleWindowPosition <= 5)//HCenter
				position.setX(screenRect.left() + screenRect.width() / 2 - mConsoleWidget->width() / 2);
			else if(mConsoleWindowPosition >= 6 && mConsoleWindowPosition <= 8)//Right
				position.setX(screenRect.left() + screenRect.width() - mConsoleWidget->width());

			if(mConsoleWindowPosition == 0 || mConsoleWindowPosition == 3 || mConsoleWindowPosition == 6)//Up
				position.setY(screenRect.top());
			else if(mConsoleWindowPosition == 1 || mConsoleWindowPosition == 4 || mConsoleWindowPosition == 7)//VCenter
				position.setY(screenRect.top() + screenRect.height() / 2 - mConsoleWidget->height() / 2);
			else if(mConsoleWindowPosition == 2 || mConsoleWindowPosition == 5 || mConsoleWindowPosition == 8)//Down
				position.setY(screenRect.top() + screenRect.height() - mConsoleWidget->height());

			mConsoleWidget->move(position);
			mConsoleWidget->show();
		}

		mExecutionStarted = true;

		mScriptAgent->setContext(ScriptAgent::Actions);
		
		mHasExecuted = true;

		executeCurrentAction();

		return true;
	}