diff -Nru actionaz-3.6.2/CHANGELOG actionaz-3.7.0/CHANGELOG --- actionaz-3.6.2/CHANGELOG 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/CHANGELOG 2013-06-27 21:41:48.000000000 +0000 @@ -1,3 +1,28 @@ +3.7.0 (28/06/13) +Actions: +- added a button to insert detected variables into parameter fields +- added a more explicit error message when a list field is empty +- fixed a bug when opening a script that had been created using a previous version of Actionaz: new action parameters did not have default values +- corrected a bug that prevented using the Code Error exception to skip the current action or go to a line of the script +- Pixel Color: added an offset to the position to be checked +- Read INI File: added reading the whole file at once +- Read INI File: corrected a bug that froze the execution when trying to read a file with an empty filename +- Find Image: added a field allowing to retreive the confidence value +- Find Image: added a field to choose which matching method to use +- Find Image: added a delay between two searches when waiting +- Find Image: added two conditions actions "if found" and "if not found" +- Find Image: removed the "Image not found" exception, previous scripts will be automatically upgraded to use the "if found" and "if not found" parameters +- Find Image: search can now be done in multiple windows if they satisfy the search criterion +- Find Image: renamed "Down pyramids" to "Downsampling" +- Find Image: fixed a bug that prevented searching in some screens when using a multiple screen configuration +- Find Image: fixed a bug that prevented using an absolute position when searching within a window +Code: +- Script: added the line attribute +- Image: added the Image.takeScreenshotUsingScreenIndex function that allows taking screenshots using a screen index +- Image: added a parameter to the findSubImage functions to choose which matching method to use +- Image: fixed a bug that prevented searching in some screens when using a multiple screen configuration +- Image: fixed a bug in the Image.takeScreenshot function that took only a screenshot of the main screen when using a multiple screen configuration + 3.6.2 (04/05/13) - Actions: fixed a regression that caused a memory leak and a crash after a repeated use of the Find Image action - Code: fixed a bug that caused a memory leak and a crash after a repeated use of Image.findSubImage and similar diff -Nru actionaz-3.6.2/actexecuter/scriptexecuter.cpp actionaz-3.7.0/actexecuter/scriptexecuter.cpp --- actionaz-3.6.2/actexecuter/scriptexecuter.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actexecuter/scriptexecuter.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -51,14 +51,14 @@ stream.flush(); } return false; - case ActionTools::Script::ReadBadSchema: + case ActionTools::Script::ReadInvalidSchema: { QTextStream stream(stdout); - stream << QObject::tr("Input script file has a bad script schema") << "\n"; + stream << QObject::tr("Input script file has an invalid script schema") << "\n"; stream.flush(); } return false; - case ActionTools::Script::ReadBadScriptVersion: + case ActionTools::Script::ReadInvalidScriptVersion: { QTextStream stream(stdout); stream << QObject::tr("Input script file is too recent") << "\n"; diff -Nru actionaz-3.6.2/actions/actionpackdata/actions/actions.pri actionaz-3.7.0/actions/actionpackdata/actions/actions.pri --- actionaz-3.6.2/actions/actionpackdata/actions/actions.pri 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackdata/actions/actions.pri 2013-06-27 21:41:48.000000000 +0000 @@ -29,7 +29,8 @@ actions/writeregistryinstance.cpp \ actions/writetextfileinstance.cpp \ actions/webdownloadinstance.cpp \ - actions/readenvironmentinstance.cpp + actions/readenvironmentinstance.cpp \ + actions/readinifileinstance.cpp diff -Nru actionaz-3.6.2/actions/actionpackdata/actions/readenvironmentinstance.cpp actionaz-3.7.0/actions/actionpackdata/actions/readenvironmentinstance.cpp --- actionaz-3.6.2/actions/actionpackdata/actions/readenvironmentinstance.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackdata/actions/readenvironmentinstance.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -61,7 +61,7 @@ setVariable(variable, environmentHashVariableValue.value(environmentVariable)); else { - emit executionException(ActionTools::ActionException::BadParameterException, tr("The specified variable cannot be found in the system environment")); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("The specified variable cannot be found in the system environment")); return; } } diff -Nru actionaz-3.6.2/actions/actionpackdata/actions/readinifiledefinition.h actionaz-3.7.0/actions/actionpackdata/actions/readinifiledefinition.h --- actionaz-3.6.2/actions/actionpackdata/actions/readinifiledefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackdata/actions/readinifiledefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -26,6 +26,8 @@ #include "textparameterdefinition.h" #include "fileparameterdefinition.h" #include "variableparameterdefinition.h" +#include "listparameterdefinition.h" +#include "groupdefinition.h" namespace ActionTools { @@ -37,12 +39,14 @@ { class ReadIniFileDefinition : public QObject, public ActionTools::ActionDefinition { - Q_OBJECT + Q_OBJECT public: explicit ReadIniFileDefinition(ActionTools::ActionPack *pack) : ActionDefinition(pack) { + translateItems("ReadIniFileInstance::modes", ReadIniFileInstance::modes); + ActionTools::FileParameterDefinition *file = new ActionTools::FileParameterDefinition(ActionTools::Name("file", tr("File")), this); file->setTooltip(tr("The file to read from")); file->setMode(ActionTools::FileEdit::FileOpen); @@ -50,17 +54,29 @@ file->setFilter(tr("INI files (*.ini);;All files (*.*)")); addElement(file); + ActionTools::VariableParameterDefinition *variable = new ActionTools::VariableParameterDefinition(ActionTools::Name("variable", tr("Variable")), this); + variable->setTooltip(tr("The variable where to store the data")); + addElement(variable); + + ActionTools::ListParameterDefinition *mode = new ActionTools::ListParameterDefinition(ActionTools::Name("mode", tr("Mode")), this); + mode->setTooltip(tr("The INI file read mode")); + mode->setItems(ReadIniFileInstance::modes); + mode->setDefaultValue(ReadIniFileInstance::modes.second.at(ReadIniFileInstance::SingleParameter)); + addElement(mode); + + ActionTools::GroupDefinition *selectionMode = new ActionTools::GroupDefinition(this); + selectionMode->setMasterList(mode); + selectionMode->setMasterValues(QStringList() << ReadIniFileInstance::modes.first.at(ReadIniFileInstance::SingleParameter)); + ActionTools::TextParameterDefinition *section = new ActionTools::TextParameterDefinition(ActionTools::Name("section", tr("Section")), this); - section->setTooltip(tr("The section name of the parameter")); - addElement(section); + section->setTooltip(tr("The parameter section")); + selectionMode->addMember(section); ActionTools::TextParameterDefinition *parameter = new ActionTools::TextParameterDefinition(ActionTools::Name("parameter", tr("Parameter")), this); parameter->setTooltip(tr("The parameter name")); - addElement(parameter); + selectionMode->addMember(parameter); - ActionTools::VariableParameterDefinition *variable = new ActionTools::VariableParameterDefinition(ActionTools::Name("variable", tr("Variable")), this); - variable->setTooltip(tr("The variable where to store the data")); - addElement(variable); + addElement(selectionMode); addException(ReadIniFileInstance::UnableToReadFileException, tr("Unable to read file")); addException(ReadIniFileInstance::UnableToFindSectionException, tr("Unable to find section")); @@ -69,7 +85,7 @@ QString name() const { return QObject::tr("Read INI file"); } QString id() const { return "ActionReadIniFile"; } ActionTools::Flag flags() const { return ActionDefinition::flags() | ActionTools::Official; } - QString description() const { return QObject::tr("Read an entry in an INI file"); } + QString description() const { return QObject::tr("Read one or all the entries in an INI file"); } ActionTools::ActionInstance *newActionInstance() const { return new ReadIniFileInstance(this); } ActionTools::ActionCategory category() const { return ActionTools::Data; } QPixmap icon() const { return QPixmap(":/icons/readini.png"); } diff -Nru actionaz-3.6.2/actions/actionpackdata/actions/readinifileinstance.cpp actionaz-3.7.0/actions/actionpackdata/actions/readinifileinstance.cpp --- actionaz-3.6.2/actions/actionpackdata/actions/readinifileinstance.cpp 1970-01-01 00:00:00.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackdata/actions/readinifileinstance.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -0,0 +1,105 @@ +/* + Actionaz + Copyright (C) 2008-2013 Jonathan Mercier-Ganady + + Actionaz is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Actionaz is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contact : jmgr@jmgr.info +*/ + +#include "readinifileinstance.h" +#include "stringlistpair.h" + +#include + +namespace Actions +{ + ActionTools::StringListPair ReadIniFileInstance::modes = qMakePair( + QStringList() << "singleParameter" << "wholeFile", + QStringList() << QT_TRANSLATE_NOOP("ReadIniFileInstance::modes", "Read a single parameter") << QT_TRANSLATE_NOOP("ReadIniFileInstance::modes", "Read the entire file")); + + void ReadIniFileInstance::startExecution() + { + bool ok = true; + + QString filename = evaluateString(ok, "file"); + QString variable = evaluateVariable(ok, "variable"); + Mode mode = evaluateListElement(ok, modes, "mode"); + + if(!ok) + return; + + if(filename.isEmpty()) + { + emit executionException(UnableToReadFileException, tr("Unable to read the file")); + return; + } + + rude::Config config; + if(!config.load(filename.toLocal8Bit())) + { + setCurrentParameter("filename"); + emit executionException(UnableToReadFileException, tr("Unable to read the file")); + return; + } + + if(mode == WholeFile) + { + QHash fileContent; + int sectionCount = config.getNumSections(); + + for(int sectionIndex = 0; sectionIndex < sectionCount; ++sectionIndex) + { + QString sectionName = QString::fromLatin1(config.getSectionNameAt(sectionIndex)); + + if(!config.setSection(sectionName.toLatin1(), false)) + { + emit executionException(UnableToReadFileException, tr("Unable to read the file")); + return; + } + + int parameterCount = config.getNumDataMembers(); + + for(int parameterIndex = 0; parameterIndex < parameterCount; ++parameterIndex) + { + QString parameterName = QString::fromLatin1(config.getDataNameAt(parameterIndex)); + QString parameterValue = QString::fromLatin1(config.getStringValue(parameterName.toLatin1())); + + fileContent[sectionName + "/" + parameterName] = parameterValue; + } + } + + setArrayKeyValue(variable, fileContent); + } + else + { + QString section = evaluateString(ok, "section"); + QString parameter = evaluateString(ok, "parameter"); + + if(!ok) + return; + + if(!config.setSection(section.toLatin1(), false)) + { + setCurrentParameter("section"); + emit executionException(UnableToFindSectionException, tr("Unable to find the section named \"%1\"").arg(section)); + return; + } + + setVariable(variable, QString::fromLatin1(config.getStringValue(parameter.toLatin1()))); + } + + emit executionEnded(); + } +} diff -Nru actionaz-3.6.2/actions/actionpackdata/actions/readinifileinstance.h actionaz-3.7.0/actions/actionpackdata/actions/readinifileinstance.h --- actionaz-3.6.2/actions/actionpackdata/actions/readinifileinstance.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackdata/actions/readinifileinstance.h 2013-06-27 21:41:48.000000000 +0000 @@ -23,55 +23,31 @@ #include "actioninstance.h" -#include - namespace Actions { class ReadIniFileInstance : public ActionTools::ActionInstance { Q_OBJECT + Q_ENUMS(Mode) public: + enum Mode + { + SingleParameter, + WholeFile + }; enum Exceptions { UnableToReadFileException = ActionTools::ActionException::UserException, - UnableToFindSectionException + UnableToFindSectionException }; ReadIniFileInstance(const ActionTools::ActionDefinition *definition, QObject *parent = 0) : ActionTools::ActionInstance(definition, parent) {} - void startExecution() - { - bool ok = true; - - QString filename = evaluateString(ok, "file"); - QString section = evaluateString(ok, "section"); - QString parameter = evaluateString(ok, "parameter"); - QString variable = evaluateVariable(ok, "variable"); - - if(!ok) - return; - - rude::Config config; - if(!config.load(filename.toLocal8Bit())) - { - setCurrentParameter("filename"); - emit executionException(UnableToReadFileException, tr("Unable to read the file")); - return; - } - - if(!config.setSection(section.toLatin1(), false)) - { - setCurrentParameter("section"); - emit executionException(UnableToFindSectionException, tr("Unable to find the section named \"%1\"").arg(section)); - return; - } - - setVariable(variable, QString::fromLatin1(config.getStringValue(parameter.toLatin1()))); + static ActionTools::StringListPair modes; - emit executionEnded(); - } + void startExecution(); private: Q_DISABLE_COPY(ReadIniFileInstance) diff -Nru actionaz-3.6.2/actions/actionpackdata/actions/readtextfileinstance.cpp actionaz-3.7.0/actions/actionpackdata/actions/readtextfileinstance.cpp --- actionaz-3.6.2/actions/actionpackdata/actions/readtextfileinstance.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackdata/actions/readtextfileinstance.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -47,21 +47,21 @@ if(firstline < 1) { setCurrentParameter("firstline"); - emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid first line value : %1").arg(firstline)); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid first line value : %1").arg(firstline)); return; } if(lastline < 1) { setCurrentParameter("lastline"); - emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid last line value : %1").arg(lastline)); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid last line value : %1").arg(lastline)); return; } if(lastline < firstline) { setCurrentParameter("firstline"); - emit executionException(ActionTools::ActionException::BadParameterException, tr("The first line has to be smaller than the last line")); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("The first line has to be smaller than the last line")); return; } } diff -Nru actionaz-3.6.2/actions/actionpackdata/actions/webdownloadinstance.cpp actionaz-3.7.0/actions/actionpackdata/actions/webdownloadinstance.cpp --- actionaz-3.6.2/actions/actionpackdata/actions/webdownloadinstance.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackdata/actions/webdownloadinstance.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -67,7 +67,7 @@ if(!url.isValid()) { setCurrentParameter("url"); - emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid URL")); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid URL")); return; } diff -Nru actionaz-3.6.2/actions/actionpackdevice/actions/clickinstance.cpp actionaz-3.7.0/actions/actionpackdevice/actions/clickinstance.cpp --- actionaz-3.6.2/actions/actionpackdevice/actions/clickinstance.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackdevice/actions/clickinstance.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -52,7 +52,7 @@ if(amount <= 0) { setCurrentParameter("amount"); - emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid click amount")); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid click amount")); return; } diff -Nru actionaz-3.6.2/actions/actionpackdevice/actions/keyinstance.cpp actionaz-3.7.0/actions/actionpackdevice/actions/keyinstance.cpp --- actionaz-3.6.2/actions/actionpackdevice/actions/keyinstance.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackdevice/actions/keyinstance.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -73,7 +73,7 @@ if(mAmount <= 0) { setCurrentParameter("amount"); - emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid key presses amount")); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid key presses amount")); return; } diff -Nru actionaz-3.6.2/actions/actionpackinternal/actions/endprocedureinstance.h actionaz-3.7.0/actions/actionpackinternal/actions/endprocedureinstance.h --- actionaz-3.6.2/actions/actionpackinternal/actions/endprocedureinstance.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackinternal/actions/endprocedureinstance.h 2013-06-27 21:41:48.000000000 +0000 @@ -40,7 +40,7 @@ setNextLine(script()->popProcedureCall() + 2);//Lines start at 1 else { - emit executionException(ActionTools::ActionException::BadParameterException, tr("End procedure reached without a call")); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("End procedure reached without a call")); return; } diff -Nru actionaz-3.6.2/actions/actionpackinternal/actions/pauseinstance.h actionaz-3.7.0/actions/actionpackinternal/actions/pauseinstance.h --- actionaz-3.6.2/actions/actionpackinternal/actions/pauseinstance.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackinternal/actions/pauseinstance.h 2013-06-27 21:41:48.000000000 +0000 @@ -63,7 +63,7 @@ if(duration < 0) { - emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid pause duration")); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid pause duration")); return; } diff -Nru actionaz-3.6.2/actions/actionpackinternal/actions/timeconditioninstance.h actionaz-3.7.0/actions/actionpackinternal/actions/timeconditioninstance.h --- actionaz-3.6.2/actions/actionpackinternal/actions/timeconditioninstance.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackinternal/actions/timeconditioninstance.h 2013-06-27 21:41:48.000000000 +0000 @@ -46,7 +46,7 @@ if(!mTestedDateTime.isValid()) { setCurrentParameter("date"); - emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid date")); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid date")); return; } diff -Nru actionaz-3.6.2/actions/actionpackinternal/actions/variableconditioninstance.h actionaz-3.7.0/actions/actionpackinternal/actions/variableconditioninstance.h --- actionaz-3.6.2/actions/actionpackinternal/actions/variableconditioninstance.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpackinternal/actions/variableconditioninstance.h 2013-06-27 21:41:48.000000000 +0000 @@ -67,7 +67,7 @@ if(!variableValue.isValid()) { setCurrentParameter("variable"); - emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid variable")); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid variable")); return; } diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/actions.pri actionaz-3.7.0/actions/actionpacksystem/actions/actions.pri --- actionaz-3.6.2/actions/actionpacksystem/actions/actions.pri 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/actions.pri 2013-06-27 21:41:48.000000000 +0000 @@ -21,4 +21,5 @@ actions/systeminstance.cpp \ actions/pixelcolorinstance.cpp \ actions/playsoundinstance.cpp \ - actions/findimageinstance.cpp + actions/findimageinstance.cpp \ + actions/findimagedefinition.cpp diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/commanddefinition.h actionaz-3.7.0/actions/actionpacksystem/actions/commanddefinition.h --- actionaz-3.6.2/actions/actionpacksystem/actions/commanddefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/commanddefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -25,6 +25,7 @@ #include "commandinstance.h" #include "fileparameterdefinition.h" #include "variableparameterdefinition.h" +#include "textparameterdefinition.h" namespace ActionTools { diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/detachedcommanddefinition.h actionaz-3.7.0/actions/actionpacksystem/actions/detachedcommanddefinition.h --- actionaz-3.6.2/actions/actionpacksystem/actions/detachedcommanddefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/detachedcommanddefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -25,6 +25,7 @@ #include "detachedcommandinstance.h" #include "fileparameterdefinition.h" #include "variableparameterdefinition.h" +#include "textparameterdefinition.h" namespace ActionTools { diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/findimagedefinition.cpp actionaz-3.7.0/actions/actionpacksystem/actions/findimagedefinition.cpp --- actionaz-3.6.2/actions/actionpacksystem/actions/findimagedefinition.cpp 1970-01-01 00:00:00.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/findimagedefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -0,0 +1,57 @@ +/* + Actionaz + Copyright (C) 2008-2013 Jonathan Mercier-Ganady + + Actionaz is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Actionaz is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contact : jmgr@jmgr.info +*/ + +#include "findimagedefinition.h" +#include "actioninstance.h" +#include "ifactionparameterdefinition.h" + +void Actions::FindImageDefinition::updateAction(ActionTools::ActionInstance *actionInstance, const Tools::Version &version) const +{ + //In 1.1.0 we have removed the ImageNotFound exception and added ifActions instead + if(version < Tools::Version(1, 1, 0)) + { + const ActionTools::ExceptionActionInstancesHash &exceptions = actionInstance->exceptionActionInstances(); + + if(exceptions.contains(static_cast(FindImageInstance::CannotFindTheImageException))) + { + const ActionTools::ActionException::ExceptionActionInstance &exceptionAction = exceptions.value(static_cast(FindImageInstance::CannotFindTheImageException)); + ActionTools::Parameter ifNotFoundParameter = actionInstance->parameter("ifNotFound"); + + switch(exceptionAction.action()) + { + case ActionTools::ActionException::StopExecutionExceptionAction: + ifNotFoundParameter.setSubParameter("action", false, ActionTools::IfActionParameterDefinition::actions.first[ActionTools::IfActionParameterDefinition::RunCode]); + ifNotFoundParameter.setSubParameter("line", true, "Console.printError(\"Script line \" + Script.line + \": Cannot find the image\");\nExecution.stop();"); + break; + case ActionTools::ActionException::SkipExceptionAction: + ifNotFoundParameter.setSubParameter("action", false, ActionTools::IfActionParameterDefinition::actions.first[ActionTools::IfActionParameterDefinition::DoNothing]); + break; + case ActionTools::ActionException::GotoLineExceptionAction: + ifNotFoundParameter.setSubParameter("action", false, ActionTools::IfActionParameterDefinition::actions.first[ActionTools::IfActionParameterDefinition::Goto]); + ifNotFoundParameter.setSubParameter("line", false, exceptionAction.line()); + break; + default: + break; + } + + actionInstance->setParameter("ifNotFound", ifNotFoundParameter); + } + } +} diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/findimagedefinition.h actionaz-3.7.0/actions/actionpacksystem/actions/findimagedefinition.h --- actionaz-3.6.2/actions/actionpacksystem/actions/findimagedefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/findimagedefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -30,6 +30,7 @@ #include "groupdefinition.h" #include "windowparameterdefinition.h" #include "booleanparameterdefinition.h" +#include "ifactionparameterdefinition.h" #include @@ -50,6 +51,7 @@ : ActionDefinition(pack) { translateItems("FindImageInstance::sources", FindImageInstance::sources); + translateItems("FindImageInstance::methods", FindImageInstance::methods); ActionTools::ListParameterDefinition *source = new ActionTools::ListParameterDefinition(ActionTools::Name("source", tr("Source")), this); source->setTooltip(tr("The source of the image to search in")); @@ -57,15 +59,19 @@ source->setDefaultValue(FindImageInstance::sources.second.at(FindImageInstance::ScreenshotSource)); addElement(source); - ActionTools::GroupDefinition *windowNameGroup = new ActionTools::GroupDefinition(this); - windowNameGroup->setMasterList(source); - windowNameGroup->setMasterValues(QStringList() << FindImageInstance::sources.first.at(FindImageInstance::WindowSource)); + ActionTools::GroupDefinition *windowGroup = new ActionTools::GroupDefinition(this); + windowGroup->setMasterList(source); + windowGroup->setMasterValues(QStringList() << FindImageInstance::sources.first.at(FindImageInstance::WindowSource)); ActionTools::WindowParameterDefinition *windowName = new ActionTools::WindowParameterDefinition(ActionTools::Name("windowName", tr("Window name")), this); windowName->setTooltip(tr("The title of the window to search in, you can use wildcards like * (any number of characters) or ? (one character) here")); - windowNameGroup->addMember(windowName); + windowGroup->addMember(windowName); - addElement(windowNameGroup); + ActionTools::BooleanParameterDefinition *relativePosition = new ActionTools::BooleanParameterDefinition(ActionTools::Name("windowRelativePosition", tr("Window relative position")), this); + relativePosition->setTooltip(tr("The position is relative to the window\nIf this parameter is set to false (not checked) then the position is absolute")); + windowGroup->addMember(relativePosition); + + addElement(windowGroup); ActionTools::GroupDefinition *imageToSearchInGroup = new ActionTools::GroupDefinition(this); imageToSearchInGroup->setMasterList(source); @@ -87,19 +93,25 @@ imageToFind->setFilter(tr("Image files (*.bmp *.gif *.jpg *.jpeg *.mng *.png *.pbm *.pgm *.ppm *.tiff *.xbm *.xpm *.svg)\nAll files (*.*)")); addElement(imageToFind); + ActionTools::IfActionParameterDefinition *ifFound = new ActionTools::IfActionParameterDefinition(ActionTools::Name("ifFound", tr("If found")), this); + ifFound->setTooltip(tr("What to do if the image is found")); + ifFound->setAllowWait(true); + addElement(ifFound); + + ActionTools::IfActionParameterDefinition *ifNotFound = new ActionTools::IfActionParameterDefinition(ActionTools::Name("ifNotFound", tr("If not found")), this); + ifNotFound->setTooltip(tr("What to do if the image is not found")); + ifNotFound->setAllowWait(true); + addElement(ifNotFound); + ActionTools::VariableParameterDefinition *position = new ActionTools::VariableParameterDefinition(ActionTools::Name("position", tr("Position")), this); position->setTooltip(tr("The name of the variable where to store the coordinates of the center of the found image")); addElement(position); - ActionTools::GroupDefinition *relativePositionGroup = new ActionTools::GroupDefinition(this); - relativePositionGroup->setMasterList(source); - relativePositionGroup->setMasterValues(QStringList() << FindImageInstance::sources.first.at(FindImageInstance::WindowSource)); - - ActionTools::BooleanParameterDefinition *relativePosition = new ActionTools::BooleanParameterDefinition(ActionTools::Name("windowRelativePosition", tr("Window relative position")), this); - relativePosition->setTooltip(tr("The position is relative to the window\nIf this parameter is set to false (not checked) then the position is absolute")); - relativePositionGroup->addMember(relativePosition); - - addElement(relativePositionGroup, 1); + ActionTools::ListParameterDefinition *method = new ActionTools::ListParameterDefinition(ActionTools::Name("method", tr("Method")), this); + method->setTooltip(tr("The matching method to use")); + method->setItems(FindImageInstance::methods); + method->setDefaultValue(FindImageInstance::methods.second.at(FindImageInstance::CorrelationCoefficientMethod)); + addElement(method, 1); ActionTools::NumberParameterDefinition *confidenceMinimum = new ActionTools::NumberParameterDefinition(ActionTools::Name("confidenceMinimum", tr("Confidence minimum")), this); confidenceMinimum->setTooltip(tr("The minimum confidence percentage required to select a possible matching image")); @@ -115,8 +127,8 @@ maximumMatches->setDefaultValue(1); addElement(maximumMatches, 1); - ActionTools::NumberParameterDefinition *downPyramidCount = new ActionTools::NumberParameterDefinition(ActionTools::Name("downPyramidCount", tr("Down pyramid count")), this); - downPyramidCount->setTooltip(tr("The number of down pyramids to use\nA pyramid is a subdivision of the image used to accelerate the search\nEnter 1 here if the searched image is not very different from the source image")); + ActionTools::NumberParameterDefinition *downPyramidCount = new ActionTools::NumberParameterDefinition(ActionTools::Name("downPyramidCount", tr("Downsampling")), this); + downPyramidCount->setTooltip(tr("The downsampling value to use\nDownsampling is used to accelerate the search when using large images")); downPyramidCount->setMinimum(1); downPyramidCount->setMaximum(std::numeric_limits::max()); downPyramidCount->setDefaultValue(1); @@ -129,22 +141,36 @@ searchExpansion->setDefaultValue(15); addElement(searchExpansion, 1); + ActionTools::NumberParameterDefinition *searchDelay = new ActionTools::NumberParameterDefinition(ActionTools::Name("searchDelay", tr("Delay between two searches when waiting")), this); + searchDelay->setTooltip(tr("The delay between two searches")); + searchDelay->setMinimum(0); + searchDelay->setMaximum(std::numeric_limits::max()); + searchDelay->setDefaultValue(100); + searchDelay->setSuffix(tr(" ms", "milliseconds")); + addElement(searchDelay, 1); + + ActionTools::VariableParameterDefinition *confidence = new ActionTools::VariableParameterDefinition(ActionTools::Name("confidence", tr("Confidence")), this); + confidence->setTooltip(tr("The name of the variable where to store the confidence value found image")); + addElement(confidence, 1); + addException(FindImageInstance::ErrorWhileSearchingException, tr("Error while searching")); - addException(FindImageInstance::CannotFindTheImageException, tr("Cannot find the image")); } QString name() const { return QObject::tr("Find image"); } QString id() const { return "ActionFindImage"; } ActionTools::Flag flags() const { return ActionDefinition::flags() | ActionTools::Official; } QString description() const { return QObject::tr("Finds an image on the screen, on a window or on another image"); } + Tools::Version version() const { return Tools::Version(1, 1, 0); } ActionTools::ActionInstance *newActionInstance() const { return new FindImageInstance(this); } ActionTools::ActionCategory category() const { return ActionTools::System; } QPixmap icon() const { return QPixmap(":/icons/findimage.png"); } QStringList tabs() const { return ActionDefinition::StandardTabs; } + void updateAction(ActionTools::ActionInstance *actionInstance, const Tools::Version &version) const; + private: - Q_DISABLE_COPY(FindImageDefinition) - }; + Q_DISABLE_COPY(FindImageDefinition) + }; } #endif // FINDIMAGEDEFINITION_H diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/findimageinstance.cpp actionaz-3.7.0/actions/actionpacksystem/actions/findimageinstance.cpp --- actionaz-3.6.2/actions/actionpacksystem/actions/findimageinstance.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/findimageinstance.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -21,9 +21,9 @@ #include "findimageinstance.h" #include "opencvalgorithms.h" #include "code/point.h" +#include "screenshooter.h" #include -#include #include #include @@ -35,15 +35,28 @@ << QT_TRANSLATE_NOOP("FindImageInstance::sources", "Screenshot") << QT_TRANSLATE_NOOP("FindImageInstance::sources", "Window") << QT_TRANSLATE_NOOP("FindImageInstance::sources", "Image")); + ActionTools::StringListPair FindImageInstance::methods = qMakePair( + QStringList() << "correlationcoefficient" << "crosscorrelation" << "squareddifference", + QStringList() + << QT_TRANSLATE_NOOP("FindImageInstance::sources", "Correlation Coefficient") + << QT_TRANSLATE_NOOP("FindImageInstance::sources", "Cross Correlation") + << QT_TRANSLATE_NOOP("FindImageInstance::sources", "Squared Difference")); FindImageInstance::FindImageInstance(const ActionTools::ActionDefinition *definition, QObject *parent) : ActionTools::ActionInstance(definition, parent), mOpenCVAlgorithms(new ActionTools::OpenCVAlgorithms(this)), + mMethod(CorrelationCoefficientMethod), mWindowRelativePosition(false), - mSource(ScreenshotSource), - mMaximumMatches(1) + mConfidenceMinimum(0), + mSource(ScreenshotSource), + mMaximumMatches(1), + mDownPyramidCount(0), + mSearchExpansion(0) { connect(mOpenCVAlgorithms, SIGNAL(finished(ActionTools::MatchingPointList)), this, SLOT(searchFinished(ActionTools::MatchingPointList))); + connect(&mWaitTimer, SIGNAL(timeout()), this, SLOT(startSearching())); + + mWaitTimer.setSingleShot(true); } FindImageInstance::~FindImageInstance() @@ -56,129 +69,215 @@ mSource = evaluateListElement(ok, sources, "source"); QString imageToFindFilename = evaluateString(ok, "imageToFind"); + mIfFound = evaluateIfAction(ok, "ifFound"); + mIfNotFound = evaluateIfAction(ok, "ifNotFound"); mPositionVariableName = evaluateVariable(ok, "position"); + mMethod = evaluateListElement(ok, methods, "method"); mWindowRelativePosition = evaluateBoolean(ok, "windowRelativePosition"); - int confidenceMinimum = evaluateInteger(ok, "confidenceMinimum"); + mConfidenceMinimum = evaluateInteger(ok, "confidenceMinimum"); mMaximumMatches = evaluateInteger(ok, "maximumMatches"); - int downPyramidCount = evaluateInteger(ok, "downPyramidCount"); - int searchExpansion = evaluateInteger(ok, "searchExpansion"); + mDownPyramidCount = evaluateInteger(ok, "downPyramidCount"); + mSearchExpansion = evaluateInteger(ok, "searchExpansion"); + mConfidenceVariableName = evaluateVariable(ok, "confidence"); + mSearchDelay = evaluateInteger(ok, "searchDelay"); if(!ok) return; - validateParameterRange(ok, confidenceMinimum, "confidenceMinimum", tr("minimum confidence"), 0, 100); + validateParameterRange(ok, mConfidenceMinimum, "confidenceMinimum", tr("minimum confidence"), 0, 100); validateParameterRange(ok, mMaximumMatches, "maximumMatches", tr("maximum matches"), 1); - validateParameterRange(ok, downPyramidCount, "downPyramidCount", tr("down pyramid count"), 1); - validateParameterRange(ok, searchExpansion, "searchExpansion", tr("search expansion"), 1); + validateParameterRange(ok, mDownPyramidCount, "downPyramidCount", tr("downsampling"), 1); + validateParameterRange(ok, mSearchExpansion, "searchExpansion", tr("search expansion"), 1); if(!ok) return; - QImage imageToFind; - QImage imageToSearchIn; - - if(!imageToFind.load(imageToFindFilename)) + if(!mImageToFind.load(imageToFindFilename)) { - emit executionException(ActionTools::ActionException::BadParameterException, tr("Unable to load image to find from file %1").arg(imageToFindFilename)); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Unable to load image to find from file %1").arg(imageToFindFilename)); return; } - switch(mSource) - { - case ScreenshotSource: - imageToSearchIn = QPixmap::grabWindow(QApplication::desktop()->winId()).toImage(); - break; - case WindowSource: - { - bool ok = true; - - QString windowName = evaluateString(ok, "windowName"); - - if(!ok) - return; - - mWindow = ActionTools::WindowHandle::findWindow(QRegExp(windowName, Qt::CaseSensitive, QRegExp::WildcardUnix)); - - if(!mWindow.isValid()) - { - emit executionException(ActionTools::ActionException::BadParameterException, tr("Unable to find any window named %1").arg(windowName)); - - return; - } - - imageToSearchIn = QPixmap::grabWindow(mWindow.value()).toImage(); - - if(imageToSearchIn.isNull()) - { - emit executionException(ActionTools::ActionException::BadParameterException, tr("Unable to take a screenshot of the window named %1").arg(mWindow.title())); - - return; - } - } - break; - case ImageSource: - { - bool ok = true; - - QString imageToSearchInFilename = evaluateString(ok, "imageToSearchIn"); - - if(!ok) - return; - - if(!imageToSearchIn.load(imageToSearchInFilename)) - { - emit executionException(ActionTools::ActionException::BadParameterException, tr("Unable to load image to search in from file %1").arg(imageToSearchInFilename)); - - return; - } - } - break; - } + startSearching(); + } - if(!mOpenCVAlgorithms->findSubImageAsync(imageToSearchIn, imageToFind, confidenceMinimum, mMaximumMatches, downPyramidCount, searchExpansion)) - { - emit executionException(ErrorWhileSearchingException, tr("Error while searching: %1").arg(mOpenCVAlgorithms->errorString())); + void FindImageInstance::stopExecution() + { + mOpenCVAlgorithms->cancelSearch(); - return; - } + mWaitTimer.stop(); } - void FindImageInstance::stopExecution() + void FindImageInstance::startSearching() { mOpenCVAlgorithms->cancelSearch(); + + mImagesToSearchIn.clear(); + + switch(mSource) + { + case ScreenshotSource: + mImagesToSearchIn = ActionTools::ScreenShooter::captureScreens(); + break; + case WindowSource: + { + bool ok = true; + + QString windowName = evaluateString(ok, "windowName"); + + if(!ok) + return; + + mWindows = ActionTools::WindowHandle::findWindows(QRegExp(windowName, Qt::CaseSensitive, QRegExp::WildcardUnix)); + + if(mWindows.isEmpty()) + { + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Unable to find any window named %1").arg(windowName)); + + return; + } + + mImagesToSearchIn = ActionTools::ScreenShooter::captureWindows(mWindows); + } + break; + case ImageSource: + { + bool ok = true; + + QString imageToSearchInFilename = evaluateString(ok, "imageToSearchIn"); + + if(!ok) + return; + + QPixmap imageToSearchIn; + + if(!imageToSearchIn.load(imageToSearchInFilename)) + { + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Unable to load image to search in from file %1").arg(imageToSearchInFilename)); + + return; + } + + mImagesToSearchIn.append(qMakePair(imageToSearchIn, imageToSearchIn.rect())); + } + break; + } + + QList sourceImages; + sourceImages.reserve(mImagesToSearchIn.size()); + + typedef QPair PixmapRectPair; + foreach(const PixmapRectPair &imageToSearchIn, mImagesToSearchIn) + sourceImages.append(imageToSearchIn.first.toImage()); + + if(!mOpenCVAlgorithms->findSubImageAsync(sourceImages, + mImageToFind, + mConfidenceMinimum, + mMaximumMatches, + mDownPyramidCount, + mSearchExpansion, + static_cast(mMethod))) + { + emit executionException(ErrorWhileSearchingException, tr("Error while searching: %1").arg(mOpenCVAlgorithms->errorString())); + + return; + } } void FindImageInstance::searchFinished(const ActionTools::MatchingPointList &matchingPointList) { - if(matchingPointList.empty()) - { - emit executionException(CannotFindTheImageException, tr("Cannot find the image")); + bool ok = true; - return; - } + if(matchingPointList.empty()) + { + setCurrentParameter("ifNotFound", "line"); + + QString line = evaluateSubParameter(ok, mIfNotFound.actionParameter()); + if(!ok) + return; + + if(mIfNotFound.action() == ActionTools::IfActionValue::GOTO) + { + setNextLine(line); + + emit executionEnded(); + } + else if(mIfNotFound.action() == ActionTools::IfActionValue::CALLPROCEDURE) + { + if(!callProcedure(line)) + return; + + emit executionEnded(); + } + else if(mIfNotFound.action() == ActionTools::IfActionValue::WAIT) + { + mWaitTimer.start(mSearchDelay); + } + else + emit executionEnded(); + + return; + } if(mMaximumMatches == 1) { - QPoint position = matchingPointList.first().first; + const ActionTools::MatchingPoint &bestMatchingPoint = matchingPointList.first(); + QPoint position = bestMatchingPoint.position; - if(mSource == WindowSource && !mWindowRelativePosition) - position += mWindow.rect().topLeft(); + if(mSource != WindowSource || !mWindowRelativePosition) + position += mImagesToSearchIn.at(bestMatchingPoint.imageIndex).second.topLeft(); setVariable(mPositionVariableName, Code::Point::constructor(position, scriptEngine())); + setVariable(mConfidenceVariableName, bestMatchingPoint.confidence); } else { QScriptValue arrayResult = scriptEngine()->newArray(matchingPointList.size()); + QScriptValue arrayConfidenceResult = scriptEngine()->newArray(matchingPointList.size()); for(int i = 0; i < matchingPointList.size(); ++i) - arrayResult.setProperty(i, Code::Point::constructor(matchingPointList.at(i).first, scriptEngine())); + { + const ActionTools::MatchingPoint &matchingPoint = matchingPointList.at(i); + QPoint position = matchingPoint.position; + + if(mSource != WindowSource || !mWindowRelativePosition) + position += mImagesToSearchIn.at(matchingPoint.imageIndex).second.topLeft(); + + arrayResult.setProperty(i, Code::Point::constructor(position, scriptEngine())); + arrayConfidenceResult.setProperty(i, matchingPoint.confidence); + } setVariable(mPositionVariableName, arrayResult); + setVariable(mConfidenceVariableName, arrayConfidenceResult); } - emit executionEnded(); - } + setCurrentParameter("ifFound", "line"); + + QString line = evaluateSubParameter(ok, mIfFound.actionParameter()); + if(!ok) + return; + + if(mIfFound.action() == ActionTools::IfActionValue::GOTO) + { + setNextLine(line); + + emit executionEnded(); + } + else if(mIfFound.action() == ActionTools::IfActionValue::CALLPROCEDURE) + { + if(!callProcedure(line)) + return; + + emit executionEnded(); + } + else if(mIfFound.action() == ActionTools::IfActionValue::WAIT) + { + mWaitTimer.start(mSearchDelay); + } + else + emit executionEnded(); + } void FindImageInstance::validateParameterRange(bool &ok, int parameter, const QString ¶meterName, const QString ¶meterTranslatedName, int minimum, int maximum) { @@ -187,7 +286,7 @@ ok = false; setCurrentParameter(parameterName); - emit executionException(ActionTools::ActionException::BadParameterException, tr("Invalid %1 value : %2").arg(parameterTranslatedName).arg(parameter)); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Invalid %1 value : %2").arg(parameterTranslatedName).arg(parameter)); return; } } diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/findimageinstance.h actionaz-3.7.0/actions/actionpacksystem/actions/findimageinstance.h --- actionaz-3.6.2/actions/actionpacksystem/actions/findimageinstance.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/findimageinstance.h 2013-06-27 21:41:48.000000000 +0000 @@ -25,6 +25,9 @@ #include "matchingpointlist.h" #include "windowhandle.h" +#include +#include + #include namespace ActionTools @@ -38,6 +41,7 @@ { Q_OBJECT Q_ENUMS(Source) + Q_ENUMS(Method) public: enum Source @@ -46,21 +50,29 @@ WindowSource, ImageSource }; + enum Method + { + CorrelationCoefficientMethod, + CrossCorrelationMethod, + SquaredDifferenceMethod + }; enum Exceptions { - ErrorWhileSearchingException = ActionTools::ActionException::UserException, - CannotFindTheImageException + ErrorWhileSearchingException = ActionTools::ActionException::UserException, + CannotFindTheImageException }; FindImageInstance(const ActionTools::ActionDefinition *definition, QObject *parent = 0); ~FindImageInstance(); static ActionTools::StringListPair sources; + static ActionTools::StringListPair methods; void startExecution(); void stopExecution(); private slots: + void startSearching(); void searchFinished(const ActionTools::MatchingPointList &matchingPointList); private: @@ -68,10 +80,21 @@ ActionTools::OpenCVAlgorithms *mOpenCVAlgorithms; QString mPositionVariableName; + QString mConfidenceVariableName; + Method mMethod; bool mWindowRelativePosition; - ActionTools::WindowHandle mWindow; - Source mSource; + int mConfidenceMinimum; + QList< QPair > mImagesToSearchIn; + QList mWindows; + Source mSource; + ActionTools::IfActionValue mIfFound; + ActionTools::IfActionValue mIfNotFound; + QImage mImageToFind; int mMaximumMatches; + int mDownPyramidCount; + int mSearchExpansion; + int mSearchDelay; + QTimer mWaitTimer; Q_DISABLE_COPY(FindImageInstance) }; diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/pixelcolordefinition.h actionaz-3.7.0/actions/actionpacksystem/actions/pixelcolordefinition.h --- actionaz-3.6.2/actions/actionpacksystem/actions/pixelcolordefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/pixelcolordefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -28,6 +28,7 @@ #include "numberparameterdefinition.h" #include "variableparameterdefinition.h" #include "ifactionparameterdefinition.h" +#include "positionparameterdefinition.h" namespace ActionTools { @@ -90,6 +91,10 @@ blueTolerance->setMaximum(100); blueTolerance->setDefaultValue(0); addElement(blueTolerance, 1); + + ActionTools::PositionParameterDefinition *positionOffset = new ActionTools::PositionParameterDefinition(ActionTools::Name("positionOffset", tr("Offset")), this); + positionOffset->setTooltip(tr("The offset to apply to the pixel position")); + addElement(positionOffset, 1); } QString name() const { return QObject::tr("Pixel color"); } diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/pixelcolorinstance.h actionaz-3.7.0/actions/actionpacksystem/actions/pixelcolorinstance.h --- actionaz-3.6.2/actions/actionpacksystem/actions/pixelcolorinstance.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/pixelcolorinstance.h 2013-06-27 21:41:48.000000000 +0000 @@ -64,6 +64,7 @@ int redTolerance = evaluateInteger(ok, "redTolerance"); int greenTolerance = evaluateInteger(ok, "greenTolerance"); int blueTolerance = evaluateInteger(ok, "blueTolerance"); + QPoint positionOffset = evaluatePoint(ok, "positionOffset"); if(!ok) return; @@ -79,6 +80,8 @@ normalizeColor(mPixelColorValue.green() + greenTolerance), normalizeColor(mPixelColorValue.blue() + blueTolerance)); + mPixelPosition += positionOffset; + if(testPixel()) { setCurrentParameter("ifTrue", "line"); diff -Nru actionaz-3.6.2/actions/actionpacksystem/actions/playsoundinstance.cpp actionaz-3.7.0/actions/actionpacksystem/actions/playsoundinstance.cpp --- actionaz-3.6.2/actions/actionpacksystem/actions/playsoundinstance.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actions/actionpacksystem/actions/playsoundinstance.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -64,7 +64,7 @@ if(!mMediaPlaylist->addMedia(url)) { - emit executionException(ActionTools::ActionException::BadParameterException, tr("Unable to load file %1: %2").arg(file).arg(mMediaPlayer->errorString())); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Unable to load file %1: %2").arg(file).arg(mMediaPlayer->errorString())); return; } @@ -76,7 +76,7 @@ if(mMediaPlayer->error() != QMediaPlayer::NoError) { - emit executionException(ActionTools::ActionException::BadParameterException, tr("Unable to play file %1: %2").arg(file).arg(mMediaPlayer->errorString())); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Unable to play file %1: %2").arg(file).arg(mMediaPlayer->errorString())); return; } diff -Nru actionaz-3.6.2/actiontools/abstractcodeeditor.h actionaz-3.7.0/actiontools/abstractcodeeditor.h --- actionaz-3.6.2/actiontools/abstractcodeeditor.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/abstractcodeeditor.h 2013-06-27 21:41:48.000000000 +0000 @@ -29,6 +29,8 @@ namespace ActionTools { + class ParameterContainer; + class ACTIONTOOLSSHARED_EXPORT AbstractCodeEditor { public: @@ -36,6 +38,8 @@ virtual void openEditor(int line = -1, int column = -1) = 0; virtual void setCompletionModel(QAbstractItemModel *completionModel) = 0; + virtual void setParameterContainer(const ParameterContainer *parameterContainer) = 0; + virtual QSet findVariables() const = 0; }; } diff -Nru actionaz-3.6.2/actiontools/actiondefinition.h actionaz-3.7.0/actiontools/actiondefinition.h --- actionaz-3.6.2/actiontools/actiondefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/actiondefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -48,28 +48,30 @@ virtual QString name() const = 0; virtual QString id() const = 0; - virtual Flag flags() const { return WorksOnWindows | WorksOnGnuLinux | WorksOnMac; } - virtual QString description() const { return QObject::tr("No description"); } - virtual Tools::Version version() const { return Tools::Version(1, 0, 0); } + virtual Flag flags() const { return WorksOnWindows | WorksOnGnuLinux | WorksOnMac; } + virtual QString description() const { return QObject::tr("No description"); } + virtual Tools::Version version() const { return Tools::Version(1, 0, 0); } virtual ActionInstance *newActionInstance() const = 0; - virtual ActionStatus status() const { return Stable; } + virtual ActionStatus status() const { return Stable; } virtual ActionCategory category() const = 0; - virtual QString author() const { return (flags() & Official) ? QObject::tr("The Actionaz Team") : QString(); } - virtual QString website() const { return QString(); } - virtual QString email() const { return QString(); } - virtual QPixmap icon() const { return QPixmap(); } - virtual QStringList tabs() const { return QStringList(); } - - void setIndex(int index) { mIndex = index; } - int index() const { return mIndex; } - - ActionPack *pack() const { return mPack; } - const QList &elements() const { return mElements; } - const QList &exceptions() const { return mExceptions; } + virtual QString author() const { return (flags() & Official) ? QObject::tr("The Actionaz Team") : QString(); } + virtual QString website() const { return QString(); } + virtual QString email() const { return QString(); } + virtual QPixmap icon() const { return QPixmap(); } + virtual QStringList tabs() const { return QStringList(); } + + virtual void updateAction(ActionInstance *actionInstance, const Tools::Version &version) const { Q_UNUSED(actionInstance) Q_UNUSED(version) } + + void setIndex(int index) { mIndex = index; } + int index() const { return mIndex; } + + ActionPack *pack() const { return mPack; } + const QList &elements() const { return mElements; } + const QList &exceptions() const { return mExceptions; } bool worksUnderThisOS() const; - virtual bool requirementCheck(QStringList &missingRequirements) const { Q_UNUSED(missingRequirements) return true; } + virtual bool requirementCheck(QStringList &missingRequirements) const { Q_UNUSED(missingRequirements) return true; } static QString CategoryName[CategoryCount]; static QStringList StandardTabs; diff -Nru actionaz-3.6.2/actiontools/actionexception.cpp actionaz-3.7.0/actiontools/actionexception.cpp --- actionaz-3.6.2/actiontools/actionexception.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/actionexception.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -26,7 +26,7 @@ { QString ActionException::ExceptionName[ExceptionCount] = { - QT_TRANSLATE_NOOP("ActionException::ExceptionName", "Bad parameter"), + QT_TRANSLATE_NOOP("ActionException::ExceptionName", "Invalid parameter"), QT_TRANSLATE_NOOP("ActionException::ExceptionName", "Code error"), QT_TRANSLATE_NOOP("ActionException::ExceptionName", "Timeout") }; diff -Nru actionaz-3.6.2/actiontools/actionexception.h actionaz-3.7.0/actiontools/actionexception.h --- actionaz-3.6.2/actiontools/actionexception.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/actionexception.h 2013-06-27 21:41:48.000000000 +0000 @@ -32,7 +32,7 @@ public: enum Exception { - BadParameterException, + InvalidParameterException, CodeErrorException, TimeoutException, diff -Nru actionaz-3.6.2/actiontools/actionfactory.cpp actionaz-3.7.0/actiontools/actionfactory.cpp --- actionaz-3.6.2/actiontools/actionfactory.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/actionfactory.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -147,7 +147,7 @@ ActionPack *actionPack = qobject_cast(actionPackObject); if(!actionPack) { - emit actionPackLoadError(tr("%1: bad definition version").arg(shortFilename)); + emit actionPackLoadError(tr("%1: invalid definition version").arg(shortFilename)); return; } diff -Nru actionaz-3.6.2/actiontools/actioninstance.cpp actionaz-3.7.0/actiontools/actioninstance.cpp --- actionaz-3.6.2/actiontools/actioninstance.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/actioninstance.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -48,9 +48,10 @@ timeout == other.timeout); } - const QRegExp ActionInstance::mNumericalIndex("(\\d+)"); - const QRegExp ActionInstance::mNameRegExp("^[A-Za-z_][A-Za-z0-9_]*$", Qt::CaseSensitive, QRegExp::RegExp2); - const QRegExp ActionInstance::mVariableRegExp("\\$([A-Za-z_][A-Za-z0-9_]*)", Qt::CaseSensitive, QRegExp::RegExp2); + + const QRegExp ActionInstance::NumericalIndex("(\\d+)"); + const QRegExp ActionInstance::NameRegExp("^[A-Za-z_][A-Za-z0-9_]*$", Qt::CaseSensitive, QRegExp::RegExp2); + const QRegExp ActionInstance::VariableRegExp("\\$([A-Za-z_][A-Za-z0-9_]*)", Qt::CaseSensitive, QRegExp::RegExp2); qint64 ActionInstance::mCurrentRuntimeId = 0; ActionInstance::ActionInstance(const ActionDefinition *definition, QObject *parent) @@ -170,11 +171,11 @@ if(!ok) return 0; - if(!result.isEmpty() && !mNameRegExp.exactMatch(result)) + if(!result.isEmpty() && !NameRegExp.exactMatch(result)) { ok = false; - emit executionException(ActionException::BadParameterException, tr("A variable name can only contain alphanumeric characters and cannot start with a digit.")); + emit executionException(ActionException::InvalidParameterException, tr("A variable name can only contain alphanumeric characters and cannot start with a digit.")); return QString(); } @@ -204,7 +205,7 @@ if(nextScriptValue.isArray()) result += evaluateVariableArray(ok, nextScriptValue); else - if(mNumericalIndex.exactMatch(it.name())) //it.name : numerical only ? + if(NumericalIndex.exactMatch(it.name())) //it.name : numerical only ? { int newIndex = it.name().toInt(); if( newIndex > lastIndex+1) @@ -248,7 +249,7 @@ { ok = false; - emit executionException(ActionException::BadParameterException, tr("Integer value expected.")); + emit executionException(ActionException::InvalidParameterException, tr("Integer value expected.")); return 0; } @@ -283,7 +284,7 @@ { ok = false; - emit executionException(ActionException::BadParameterException, tr("Decimal value expected.")); + emit executionException(ActionException::InvalidParameterException, tr("Decimal value expected.")); return 0.0; } @@ -353,7 +354,7 @@ { ok = false; - emit executionException(ActionException::BadParameterException, tr("\"%1\" is not a valid position.").arg(result)); + emit executionException(ActionException::InvalidParameterException, tr("\"%1\" is not a valid position.").arg(result)); return QPoint(); } @@ -361,7 +362,7 @@ QPoint point = QPoint(positionStringList.at(0).toInt(&ok), positionStringList.at(1).toInt(&ok)); if(!ok) { - emit executionException(ActionException::BadParameterException, tr("\"%1\" is not a valid position.").arg(result)); + emit executionException(ActionException::InvalidParameterException, tr("\"%1\" is not a valid position.").arg(result)); return QPoint(); } @@ -456,7 +457,7 @@ { ok = false; - emit executionException(ActionException::BadParameterException, tr("\"%1\" is not a valid color.").arg(result)); + emit executionException(ActionException::InvalidParameterException, tr("\"%1\" is not a valid color.").arg(result)); return QColor(); } @@ -464,7 +465,7 @@ QColor color = QColor(colorStringList.at(0).toInt(&ok), colorStringList.at(1).toInt(&ok), colorStringList.at(2).toInt(&ok)); if(!ok) { - emit executionException(ActionException::BadParameterException, tr("\"%1\" is not a valid color.").arg(result)); + emit executionException(ActionException::InvalidParameterException, tr("\"%1\" is not a valid color.").arg(result)); return QColor(); } @@ -532,7 +533,7 @@ for(int index = 0; index < stringList.count(); ++index) back.setProperty(index, stringList.at(index)); - if(!name.isEmpty() && mNameRegExp.exactMatch(name)) + if(!name.isEmpty() && NameRegExp.exactMatch(name)) d->scriptEngine->globalObject().setProperty(name, back); } @@ -555,13 +556,13 @@ void ActionInstance::setVariable(const QString &name, const QScriptValue &value) { - if(!name.isEmpty() && mNameRegExp.exactMatch(name)) + if(!name.isEmpty() && NameRegExp.exactMatch(name)) d->scriptEngine->globalObject().setProperty(name, value); } QScriptValue ActionInstance::variable(const QString &name) { - if(name.isEmpty() || !mNameRegExp.exactMatch(name)) + if(name.isEmpty() || !NameRegExp.exactMatch(name)) return QScriptValue(); return d->scriptEngine->globalObject().property(name); @@ -579,7 +580,7 @@ int beginProcedureLine = script()->findProcedure(procedureName); if(beginProcedureLine == -1) { - emit executionException(ActionTools::ActionException::BadParameterException, tr("Unable to find any procedure named \"%1\"").arg(procedureName)); + emit executionException(ActionTools::ActionException::InvalidParameterException, tr("Unable to find any procedure named \"%1\"").arg(procedureName)); return false; } @@ -605,9 +606,9 @@ QScriptValue result = d->scriptEngine->evaluate(toEvaluate.value().toString()); if(result.isError()) { - ok = false; + ok = false; - emit executionException(ActionException::CodeErrorException, result.toString()); + emit executionException(ActionException::CodeErrorException, result.toString()); return QScriptValue(); } @@ -625,37 +626,37 @@ { ok = true; - int pos = 0; + int position = 0; QString value = toEvaluate.value().toString(); - return evaluateTextString(ok, (const QString) value, pos); + return evaluateTextString(ok, (const QString) value, position); } - QString ActionInstance::evaluateTextString(bool &ok, const QString &toEvaluate, int &pos) + QString ActionInstance::evaluateTextString(bool &ok, const QString &toEvaluate, int &position) { ok = true; - int startIndex = pos; + int startIndex = position; QString result; - while(pos < toEvaluate.length()) + while(position < toEvaluate.length()) { - if( toEvaluate[pos] == QChar('$') ) + if(toEvaluate[position] == QChar('$')) { //find a variable name - if( mVariableRegExp.indexIn(toEvaluate , pos) != -1 ) + if(VariableRegExp.indexIn(toEvaluate, position) != -1) { - QString foundVariableName = mVariableRegExp.cap(1); + QString foundVariableName = VariableRegExp.cap(1); QScriptValue foundVariable = d->scriptEngine->globalObject().property(foundVariableName); - pos += foundVariableName.length(); + position += foundVariableName.length(); if(!foundVariable.isValid()) { ok = false; - emit executionException(ActionException::BadParameterException, tr("Undefined variable \"%1\"").arg(foundVariableName)); + emit executionException(ActionException::InvalidParameterException, tr("Undefined variable \"%1\"").arg(foundVariableName)); return QString(); } @@ -667,22 +668,20 @@ stringEvaluationResult = "[Undefined]"; else if(foundVariable.isArray()) { - while( (pos + 1 < toEvaluate.length()) && toEvaluate[pos + 1] == QChar('[') ) + while((position + 1 < toEvaluate.length()) && toEvaluate[position + 1] == QChar('[')) { - pos += 2; - QString indexArray = evaluateTextString(ok, toEvaluate, pos); + position += 2; + QString indexArray = evaluateTextString(ok, toEvaluate, position); - if((pos < toEvaluate.length()) && toEvaluate[pos] == QChar(']')) + if((position < toEvaluate.length()) && toEvaluate[position] == QChar(']')) { - QScriptString internalIndexArray = d->scriptEngine->toStringHandle(indexArray) ; + QScriptString internalIndexArray = d->scriptEngine->toStringHandle(indexArray); bool flag = true; int numIndex = internalIndexArray.toArrayIndex(&flag); - if(flag) - //numIndex is valid + if(flag) //numIndex is valid foundVariable = foundVariable.property(numIndex); - else - //use internalIndexArray + else //use internalIndexArray foundVariable = foundVariable.property(internalIndexArray); } else @@ -690,12 +689,13 @@ //syntax error ok = false; - emit executionException(ActionException::BadParameterException, tr("Bad parameter. Unable to evaluate string")); + emit executionException(ActionException::InvalidParameterException, tr("Invalid parameter. Unable to evaluate string")); return QString(); } //COMPATIBILITY: we break the while loop if foundVariable is no more of Array type - if (!foundVariable.isArray()) break; + if(!foundVariable.isArray()) + break; } //end of while, no more '[' if(foundVariable.isArray()) @@ -726,48 +726,48 @@ } } - else if ( toEvaluate[pos] == QChar(']') ) + else if (toEvaluate[position] == QChar(']')) { - if( startIndex == 0 ) + if(startIndex == 0) //in top level evaluation isolated character ']' is accepted (for compatibility reason), now prefer "\]" //i.e without matching '[' - result.append(toEvaluate[pos]); + result.append(toEvaluate[position]); else //on other levels, the parsing is stopped at this point return result; } - else if( toEvaluate[pos] == QChar('\\') ) + else if(toEvaluate[position] == QChar('\\')) { if(startIndex == 0) { //for ascendant compatibility reason //in top level evaluation '\' is not only an escape character, //but can also be a standard character in some cases - if((pos + 1) < toEvaluate.length()) + if((position + 1) < toEvaluate.length()) { - pos++; - if(toEvaluate[pos] == QChar('$') || toEvaluate[pos] == QChar('[') || toEvaluate[pos] == QChar(']') || toEvaluate[pos] == QChar('\\')) - result.append(toEvaluate[pos]); + position++; + if(toEvaluate[position] == QChar('$') || toEvaluate[position] == QChar('[') || toEvaluate[position] == QChar(']') || toEvaluate[position] == QChar('\\')) + result.append(toEvaluate[position]); else { - pos--; - result.append(toEvaluate[pos]); + position--; + result.append(toEvaluate[position]); } } else - result.append(toEvaluate[pos]); + result.append(toEvaluate[position]); } else { - pos++; - if( pos < toEvaluate.length() ) - result.append(toEvaluate[pos]); + position++; + if( position < toEvaluate.length() ) + result.append(toEvaluate[position]); } } else - result.append(toEvaluate[pos]); + result.append(toEvaluate[position]); - pos++; + position++; } return result; diff -Nru actionaz-3.6.2/actiontools/actioninstance.h actionaz-3.7.0/actiontools/actioninstance.h --- actionaz-3.6.2/actiontools/actioninstance.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/actioninstance.h 2013-06-27 21:41:48.000000000 +0000 @@ -164,6 +164,10 @@ void copyActionDataFrom(const ActionInstance &other); + static const QRegExp NumericalIndex; + static const QRegExp NameRegExp; + static const QRegExp VariableRegExp; + signals: void showProgressDialog(const QString &title, int maximum); void updateProgressDialog(const QString &caption); @@ -242,13 +246,26 @@ return static_cast(i); } + if(result.isEmpty()) + { + ok = false; + + setCurrentParameter(parameterName, subParameterName); + + emit executionException(ActionException::InvalidParameterException, tr("Please choose a value for this field.")); + + return T(); + } + T back = static_cast(result.toInt(&ok)); if(!ok || back < 0 || back >= listElements.first.count()) { ok = false; - emit executionException(ActionException::BadParameterException, tr("\"%1\" is an invalid value.").arg(result)); + setCurrentParameter(parameterName, subParameterName); + + emit executionException(ActionException::InvalidParameterException, tr("\"%1\" is an invalid value.").arg(result)); return T(); } @@ -295,9 +312,6 @@ QString evaluateText(bool &ok, const SubParameter &toEvaluate); QString evaluateTextString(bool &ok, const QString &toEvaluate, int &pos); - static const QRegExp mNumericalIndex; - static const QRegExp mNameRegExp; - static const QRegExp mVariableRegExp; static qint64 mCurrentRuntimeId; qint64 mRuntimeId; diff -Nru actionaz-3.6.2/actiontools/actiontools.pro actionaz-3.7.0/actiontools/actiontools.pro --- actionaz-3.6.2/actiontools/actiontools.pro 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/actiontools.pro 2013-06-27 21:41:48.000000000 +0000 @@ -45,7 +45,8 @@ opencvalgorithms.cpp \ systeminputreceiver.cpp \ systeminputtask.cpp \ - systeminputrecorder.cpp + systeminputrecorder.cpp \ + screenshooter.cpp HEADERS += actiontools_global.h \ actionpack.h \ actionfactory.h \ @@ -87,7 +88,9 @@ systeminputtask.h \ systeminputlistener.h \ systeminput.h \ - systeminputrecorder.h + systeminputrecorder.h \ + screenshooter.h \ + parametercontainer.h win32:LIBS += -luser32 \ -ladvapi32 \ -lgdi32 \ diff -Nru actionaz-3.6.2/actiontools/actiontools.qrc actionaz-3.7.0/actiontools/actiontools.qrc --- actionaz-3.6.2/actiontools/actiontools.qrc 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/actiontools.qrc 2013-06-27 21:41:48.000000000 +0000 @@ -14,5 +14,6 @@ images/editor.png script.xsd images/help.png + images/insert.png diff -Nru actionaz-3.6.2/actiontools/booleanedit.cpp actionaz-3.7.0/actiontools/booleanedit.cpp --- actionaz-3.6.2/actiontools/booleanedit.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/booleanedit.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -90,8 +90,18 @@ void BooleanEdit::setCompletionModel(QAbstractItemModel *completionModel) { - ui->comboBox->setCompletionModel(completionModel); - } + ui->comboBox->setCompletionModel(completionModel); + } + + void BooleanEdit::setParameterContainer(const ParameterContainer *parameterContainer) + { + ui->comboBox->setParameterContainer(parameterContainer); + } + + QSet BooleanEdit::findVariables() const + { + return ui->comboBox->findVariables(); + } void BooleanEdit::on_switchTextModePushButton_clicked() { diff -Nru actionaz-3.6.2/actiontools/booleanedit.h actionaz-3.7.0/actiontools/booleanedit.h --- actionaz-3.6.2/actiontools/booleanedit.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/booleanedit.h 2013-06-27 21:41:48.000000000 +0000 @@ -50,6 +50,8 @@ void setFromSubParameter(const SubParameter &subParameter); void openEditor(int line, int column); void setCompletionModel(QAbstractItemModel *completionModel); + void setParameterContainer(const ParameterContainer *parameterContainer); + QSet findVariables() const; private slots: void on_switchTextModePushButton_clicked(); diff -Nru actionaz-3.6.2/actiontools/booleanparameterdefinition.cpp actionaz-3.7.0/actiontools/booleanparameterdefinition.cpp --- actionaz-3.6.2/actiontools/booleanparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/booleanparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -24,8 +24,8 @@ namespace ActionTools { - BooleanParameterDefinition::BooleanParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + BooleanParameterDefinition::BooleanParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mBooleanEdit(0) { } diff -Nru actionaz-3.6.2/actiontools/booleanparameterdefinition.h actionaz-3.7.0/actiontools/booleanparameterdefinition.h --- actionaz-3.6.2/actiontools/booleanparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/booleanparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -32,7 +32,7 @@ { Q_OBJECT public: - BooleanParameterDefinition(const Name &name, QObject *parent); + BooleanParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); diff -Nru actionaz-3.6.2/actiontools/code/image.cpp actionaz-3.7.0/actiontools/code/image.cpp --- actionaz-3.6.2/actiontools/code/image.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/code/image.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -28,6 +28,7 @@ #include "codetools.h" #include "opencvalgorithms.h" #include "qtimagefilters/QtImageFilterFactory" +#include "screenshooter.h" #include #include @@ -82,10 +83,10 @@ QScriptValue Image::takeScreenshot(QScriptContext *context, QScriptEngine *engine) { - WId windowId = QApplication::desktop()->winId(); - if(context->argumentCount() > 0) { + WId windowId; + if(Window *window = qobject_cast(context->argument(0).toQObject())) windowId = window->windowHandle().value(); else @@ -97,17 +98,41 @@ windowId = context->argument(0).toInt32(); #endif } + + return constructor(QPixmap::grabWindow(windowId).toImage(), engine); } - QPixmap screenPixmap = QPixmap::grabWindow(windowId); + return constructor(ActionTools::ScreenShooter::captureScreen().toImage(), engine); + } + + QScriptValue Image::takeScreenshotUsingScreenIndex(QScriptContext *context, QScriptEngine *engine) + { + if(context->argumentCount() == 0) + { + throwError(context, engine, "ParameterCountError", tr("Incorrect parameter count")); + return engine->undefinedValue(); + } + + int screenIndex = context->argument(0).toInt32(); + QDesktopWidget *desktop = QApplication::desktop(); + + if(screenIndex < 0 || screenIndex >= desktop->screenCount()) + { + throwError(context, engine, "InvalidScreenIndexError", tr("Invalid screen index")); + return engine->undefinedValue(); + } + + QRect screenGeometry = desktop->screenGeometry(screenIndex); + QPixmap screenPixmap = QPixmap::grabWindow(desktop->winId(), screenGeometry.x(), screenGeometry.y(), screenGeometry.width(), screenGeometry.height()); return constructor(screenPixmap.toImage(), engine); - } + } void Image::registerClass(QScriptEngine *scriptEngine) { CodeTools::addClassToScriptEngine(scriptEngine); CodeTools::addClassGlobalFunctionToScriptEngine(&takeScreenshot, "takeScreenshot", scriptEngine); + CodeTools::addClassGlobalFunctionToScriptEngine(&takeScreenshotUsingScreenIndex, "takeScreenshotUsingScreenIndex", scriptEngine); } const QString Image::filterNames[] = @@ -398,10 +423,11 @@ int confidenceMinimum; int downPyramidCount; int searchExpansion; + AlgorithmMethod method; - findSubImageOptions(options, &confidenceMinimum, &downPyramidCount, &searchExpansion); + findSubImageOptions(options, &confidenceMinimum, &downPyramidCount, &searchExpansion, &method); - if(!mOpenCVAlgorithms->findSubImage(mImage, codeImage->image(), matchingPointList, confidenceMinimum, 1, downPyramidCount, searchExpansion)) + if(!mOpenCVAlgorithms->findSubImage(QList() << mImage, codeImage->image(), matchingPointList, confidenceMinimum, 1, downPyramidCount, searchExpansion, static_cast(method))) { throwError("FindSubImageError", tr("Error while searching for a sub-image: %1").arg(mOpenCVAlgorithms->errorString())); return QScriptValue(); @@ -413,8 +439,8 @@ const ActionTools::MatchingPoint &matchingPoint = matchingPointList.first(); QScriptValue back = engine()->newObject(); - back.setProperty("position", Point::constructor(matchingPoint.first, engine())); - back.setProperty("confidence", matchingPoint.second); + back.setProperty("position", Point::constructor(matchingPoint.position, engine())); + back.setProperty("confidence", matchingPoint.confidence); return back; } @@ -427,7 +453,7 @@ bool matchingPointGreaterThan(const ActionTools::MatchingPoint &matchingPoint1, const ActionTools::MatchingPoint &matchingPoint2) { - return matchingPoint1.second > matchingPoint2.second; + return matchingPoint1.confidence > matchingPoint2.confidence; } QScriptValue Image::findSubImages(const QScriptValue &otherImage, const QScriptValue &options) const @@ -439,11 +465,12 @@ int confidenceMinimum; int downPyramidCount; int searchExpansion; + AlgorithmMethod method; int maximumMatches; - findSubImageOptions(options, &confidenceMinimum, &downPyramidCount, &searchExpansion, &maximumMatches); + findSubImageOptions(options, &confidenceMinimum, &downPyramidCount, &searchExpansion, &method, &maximumMatches); - if(!mOpenCVAlgorithms->findSubImage(mImage, codeImage->image(), matchingPointList, confidenceMinimum, maximumMatches, downPyramidCount, searchExpansion)) + if(!mOpenCVAlgorithms->findSubImage(QList() << mImage, codeImage->image(), matchingPointList, confidenceMinimum, maximumMatches, downPyramidCount, searchExpansion, static_cast(method))) { throwError("FindSubImageError", tr("Error while searching for a sub-image: %1").arg(mOpenCVAlgorithms->errorString())); return QScriptValue(); @@ -462,8 +489,8 @@ { QScriptValue object = engine()->newObject(); - object.setProperty("position", Point::constructor(matchingPointIt->first, engine())); - object.setProperty("confidence", matchingPointIt->second); + object.setProperty("position", Point::constructor(matchingPointIt->position, engine())); + object.setProperty("confidence", matchingPointIt->confidence); back.setProperty(index, object); @@ -495,10 +522,11 @@ int confidenceMinimum; int downPyramidCount; int searchExpansion; + AlgorithmMethod method; - findSubImageOptions(options, &confidenceMinimum, &downPyramidCount, &searchExpansion); + findSubImageOptions(options, &confidenceMinimum, &downPyramidCount, &searchExpansion, &method); - if(!mOpenCVAlgorithms->findSubImageAsync(mImage, codeImage->image(), confidenceMinimum, 1, downPyramidCount, searchExpansion)) + if(!mOpenCVAlgorithms->findSubImageAsync(QList() << mImage, codeImage->image(), confidenceMinimum, 1, downPyramidCount, searchExpansion, static_cast(method))) { throwError("FindSubImageError", tr("Error while searching for a sub-image: %1").arg(mOpenCVAlgorithms->errorString())); return thisObject(); @@ -530,11 +558,12 @@ int confidenceMinimum; int downPyramidCount; int searchExpansion; + AlgorithmMethod method; int maximumMatches; - findSubImageOptions(options, &confidenceMinimum, &downPyramidCount, &searchExpansion, &maximumMatches); + findSubImageOptions(options, &confidenceMinimum, &downPyramidCount, &searchExpansion, &method, &maximumMatches); - if(!mOpenCVAlgorithms->findSubImageAsync(mImage, codeImage->image(), confidenceMinimum, maximumMatches, downPyramidCount, searchExpansion)) + if(!mOpenCVAlgorithms->findSubImageAsync(QList() << mImage, codeImage->image(), confidenceMinimum, maximumMatches, downPyramidCount, searchExpansion, static_cast(method))) { throwError("FindSubImageError", tr("Error while searching for a sub-image: %1").arg(mOpenCVAlgorithms->errorString())); return thisObject(); @@ -567,8 +596,8 @@ const ActionTools::MatchingPoint &matchingPoint = matchingPointList.first(); QScriptValue back = mFindSubImageAsyncFunction.engine()->newObject(); - back.setProperty("position", CodeClass::constructor(new Point(matchingPoint.first), mFindSubImageAsyncFunction.engine())); - back.setProperty("confidence", matchingPoint.second); + back.setProperty("position", CodeClass::constructor(new Point(matchingPoint.position), mFindSubImageAsyncFunction.engine())); + back.setProperty("confidence", matchingPoint.confidence); mFindSubImageAsyncFunction.call(thisObject(), QScriptValueList() << back); } @@ -585,8 +614,8 @@ { QScriptValue object = mFindSubImageAsyncFunction.engine()->newObject(); - object.setProperty("position", CodeClass::constructor(new Point(matchingPointIt->first), mFindSubImageAsyncFunction.engine())); - object.setProperty("confidence", matchingPointIt->second); + object.setProperty("position", CodeClass::constructor(new Point(matchingPointIt->position), mFindSubImageAsyncFunction.engine())); + object.setProperty("confidence", matchingPointIt->confidence); back.setProperty(index, object); @@ -599,7 +628,7 @@ } } - void Image::findSubImageOptions(const QScriptValue &options, int *confidenceMinimum, int *downPyramidCount, int *searchExpansion, int *maximumMatches) const + void Image::findSubImageOptions(const QScriptValue &options, int *confidenceMinimum, int *downPyramidCount, int *searchExpansion, AlgorithmMethod *method, int *maximumMatches) const { QScriptValueIterator it(options); @@ -615,6 +644,9 @@ if(searchExpansion) *searchExpansion = 15; + if(method) + *method = CorrelationCoefficient; + while(it.hasNext()) { it.next(); @@ -627,6 +659,8 @@ *downPyramidCount = it.value().toInt32(); else if(searchExpansion && it.name() == "searchExpansion") *searchExpansion = it.value().toInt32(); + else if(searchExpansion && it.name() == "method") + *method = static_cast(it.value().toInt32()); } } } diff -Nru actionaz-3.6.2/actiontools/code/image.h actionaz-3.7.0/actiontools/code/image.h --- actionaz-3.6.2/actiontools/code/image.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/code/image.h 2013-06-27 21:41:48.000000000 +0000 @@ -43,6 +43,7 @@ Q_OBJECT Q_ENUMS(Filter) Q_ENUMS(MirrorOrientation) + Q_ENUMS(AlgorithmMethod) public: enum Filter @@ -67,11 +68,18 @@ Vertical = 1, Horizontal = 2 }; + enum AlgorithmMethod + { + CorrelationCoefficient, + CrossCorrelation, + SquaredDifference + }; static QScriptValue constructor(QScriptContext *context, QScriptEngine *engine); static QScriptValue constructor(const QImage &image, QScriptEngine *engine); static QScriptValue takeScreenshot(QScriptContext *context, QScriptEngine *engine); + static QScriptValue takeScreenshotUsingScreenIndex(QScriptContext *context, QScriptEngine *engine); static void registerClass(QScriptEngine *scriptEngine); @@ -116,7 +124,7 @@ void findSubImageAsyncFinished(const ActionTools::MatchingPointList &matchingPointList); private: - void findSubImageOptions(const QScriptValue &options, int *confidenceMinimum, int *downPyramidCount, int *searchExpansion, int *maximumMatches = 0) const; + void findSubImageOptions(const QScriptValue &options, int *confidenceMinimum, int *downPyramidCount, int *searchExpansion, AlgorithmMethod *method, int *maximumMatches = 0) const; enum FilterOption { diff -Nru actionaz-3.6.2/actiontools/codecombobox.cpp actionaz-3.7.0/actiontools/codecombobox.cpp --- actionaz-3.6.2/actiontools/codecombobox.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/codecombobox.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -20,10 +20,10 @@ #include "codecombobox.h" #include "codelineedit.h" +#include "codelineeditbutton.h" #include #include -#include namespace ActionTools { @@ -61,13 +61,13 @@ return flags; } - CodeComboBox::CodeComboBox(QWidget *parent) : + CodeComboBox::CodeComboBox(QWidget *parent) : QComboBox(parent) { setModel(new CodeComboBoxModel(this)); setItemDelegate(new CodeComboBoxDelegate(this)); - CodeLineEdit *codeLineEdit = new CodeLineEdit(parent); + CodeLineEdit *codeLineEdit = new CodeLineEdit(parent); codeLineEdit->setEmbedded(true); setLineEdit(codeLineEdit); @@ -103,6 +103,16 @@ void CodeComboBox::setCompletionModel(QAbstractItemModel *completionModel) { - codeLineEdit()->setCompletionModel(completionModel); - } + codeLineEdit()->setCompletionModel(completionModel); + } + + void CodeComboBox::setParameterContainer(const ParameterContainer *parameterContainer) + { + codeLineEdit()->setParameterContainer(parameterContainer); + } + + QSet CodeComboBox::findVariables() const + { + return codeLineEdit()->findVariables(); + } } diff -Nru actionaz-3.6.2/actiontools/codecombobox.h actionaz-3.7.0/actiontools/codecombobox.h --- actionaz-3.6.2/actiontools/codecombobox.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/codecombobox.h 2013-06-27 21:41:48.000000000 +0000 @@ -31,7 +31,7 @@ namespace ActionTools { - class CodeLineEdit; + class CodeLineEdit; class CodeComboBoxDelegate : public QStyledItemDelegate { @@ -55,7 +55,7 @@ Q_PROPERTY(bool code READ isCode WRITE setCode) public: - explicit CodeComboBox(QWidget * parent = 0); + explicit CodeComboBox(QWidget * parent = 0); CodeLineEdit *codeLineEdit() const; @@ -64,6 +64,8 @@ void openEditor(int line = -1, int column = -1); void setCompletionModel(QAbstractItemModel *completionModel); + void setParameterContainer(const ParameterContainer *parameterContainer); + QSet findVariables() const; signals: void codeChanged(bool code); diff -Nru actionaz-3.6.2/actiontools/codedatetimeedit.cpp actionaz-3.7.0/actiontools/codedatetimeedit.cpp --- actionaz-3.6.2/actiontools/codedatetimeedit.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/codedatetimeedit.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -69,8 +69,18 @@ void CodeDateTimeEdit::setCompletionModel(QAbstractItemModel *completionModel) { - codeLineEdit()->setCompletionModel(completionModel); - } + codeLineEdit()->setCompletionModel(completionModel); + } + + void CodeDateTimeEdit::setParameterContainer(const ParameterContainer *parameterContainer) + { + codeLineEdit()->setParameterContainer(parameterContainer); + } + + QSet CodeDateTimeEdit::findVariables() const + { + return codeLineEdit()->findVariables(); + } void CodeDateTimeEdit::codeChanged(bool code) { diff -Nru actionaz-3.6.2/actiontools/codedatetimeedit.h actionaz-3.7.0/actiontools/codedatetimeedit.h --- actionaz-3.6.2/actiontools/codedatetimeedit.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/codedatetimeedit.h 2013-06-27 21:41:48.000000000 +0000 @@ -46,6 +46,8 @@ void openEditor(int line = -1, int column = -1); void setCompletionModel(QAbstractItemModel *completionModel); + void setParameterContainer(const ParameterContainer *parameterContainer); + QSet findVariables() const; private slots: void codeChanged(bool code); diff -Nru actionaz-3.6.2/actiontools/codelineedit.cpp actionaz-3.7.0/actiontools/codelineedit.cpp --- actionaz-3.6.2/actiontools/codelineedit.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/codelineedit.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -22,6 +22,10 @@ #include "codeeditordialog.h" #include "settings.h" #include "scriptcompleter.h" +#include "parametercontainer.h" +#include "codelineeditbutton.h" +#include "script.h" +#include "actioninstance.h" #include #include @@ -32,28 +36,33 @@ #include #include #include +#include +#include namespace ActionTools { - CodeLineEdit::CodeLineEdit(QWidget *parent, const QRegExp ®expValidation) - : QLineEdit(parent), + CodeLineEdit::CodeLineEdit(QWidget *parent, const QRegExp ®expValidation) + : QLineEdit(parent), + mParameterContainer(0), mCode(false), mMultiline(false), mAllowTextCodeChange(true), mShowEditorButton(true), mEmbedded(false), - mSwitchTextCode(new QAction(tr("Set to text/code"), this)), - mOpenEditor(new QAction(tr("Open editor"), this)), + mSwitchTextCode(new QAction(QIcon(":/images/code.png"), tr("Set to text/code"), this)), + mOpenEditor(new QAction(QIcon(":/images/editor.png"), tr("Open editor"), this)), mRegExp(regexpValidation), mCompletionModel(0), - mCodeButton(new QToolButton(this)), - mEditorButton(new QToolButton(this)) + mCodeButton(new CodeLineEditButton(this)), + mEditorButton(new CodeLineEditButton(this)), + mInsertButton(new CodeLineEditButton(this)) { connect(this, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); connect(mSwitchTextCode, SIGNAL(triggered()), this, SLOT(reverseCode())); connect(mOpenEditor, SIGNAL(triggered()), this, SLOT(openEditor())); connect(mCodeButton, SIGNAL(clicked()), this, SLOT(reverseCode())); connect(mEditorButton, SIGNAL(clicked()), this, SLOT(openEditor())); + connect(mInsertButton, SIGNAL(clicked()), this, SLOT(showVariableMenuAsPopup())); QSettings settings; @@ -64,7 +73,7 @@ addAction(mSwitchTextCode); addAction(mOpenEditor); - + mCodeButton->setIcon(QIcon(":/images/code.png")); mCodeButton->setMaximumWidth(14); mCodeButton->setToolTip(tr("Click here to switch text/code")); @@ -72,11 +81,19 @@ mEditorButton->setIcon(QIcon(":/images/editor.png")); mEditorButton->setMaximumWidth(18); mEditorButton->setToolTip(tr("Click here to open the editor")); - - setMinimumWidth(minimumWidth() + 14 + 18); - - setEmbedded(false); - } + + mInsertButton->setIcon(QIcon(":/images/insert.png")); + mInsertButton->setMaximumWidth(18); + mInsertButton->setToolTip(tr("Click here to insert a variable")); + + setMinimumWidth(minimumWidth() + mCodeButton->maximumWidth() + mEditorButton->maximumWidth() + mInsertButton->maximumWidth()); + + setEmbedded(false); + } + + CodeLineEdit::~CodeLineEdit() + { + } void CodeLineEdit::setCode(bool code) { @@ -116,6 +133,7 @@ w += mCodeButton->maximumWidth(); if(mShowEditorButton) w += mEditorButton->maximumWidth(); + w += mInsertButton->maximumWidth(); setStyleSheet(QString("QLineEdit { padding-right: %1px; }").arg(w)); @@ -167,8 +185,52 @@ mCompletionModel = completionModel; if(mCode) - setCompleter(new ScriptCompleter(mCompletionModel, this)); - } + setCompleter(new ScriptCompleter(mCompletionModel, this)); + } + + void CodeLineEdit::setParameterContainer(const ParameterContainer *parameterContainer) + { + mParameterContainer = parameterContainer; + } + + QSet CodeLineEdit::findVariables() const + { + QSet back; + + if(isCode()) + { + foreach(const QString &codeLine, text().split(QRegExp("[\n\r;]"), QString::SkipEmptyParts)) + { + int position = 0; + + while((position = Script::CodeVariableDeclarationRegExp.indexIn(codeLine, position)) != -1) + { + QString foundVariableName = Script::CodeVariableDeclarationRegExp.cap(1); + + position += Script::CodeVariableDeclarationRegExp.cap(1).length(); + + if(!foundVariableName.isEmpty()) + back << foundVariableName; + } + } + } + else + { + int position = 0; + + while((position = ActionInstance::VariableRegExp.indexIn(text(), position)) != -1) + { + QString foundVariableName = ActionInstance::VariableRegExp.cap(2); + + position += ActionInstance::VariableRegExp.cap(0).length(); + + if(!foundVariableName.isEmpty()) + back << foundVariableName; + } + } + + return back; + } void CodeLineEdit::reverseCode() { @@ -209,6 +271,13 @@ addShortcuts(menu); + menu->addSeparator(); + + QMenu *variablesMenu = createVariablesMenu(menu); + variablesMenu->setIcon(QIcon(":/images/insert.png")); + + menu->addMenu(variablesMenu); + menu->exec(event->globalPos()); delete menu; @@ -220,13 +289,56 @@ { resizeButtons(); - QLineEdit::resizeEvent(event); - } + QLineEdit::resizeEvent(event); + } + + void CodeLineEdit::insertVariable(const QString &variable) + { + if(isCode()) + insert(variable); + else + insert("$" + variable); + } + + void CodeLineEdit::insertVariable(QAction *action) + { + insertVariable(action->text()); + } + + QMenu *CodeLineEdit::createVariablesMenu(QMenu *parentMenu) + { + Q_ASSERT(mParameterContainer); + QMenu *variablesMenu = mParameterContainer->createVariablesMenu(parentMenu); + if(variablesMenu) + { + variablesMenu->setTitle(tr("Insert variable")); + connect(variablesMenu, SIGNAL(triggered(QAction*)), this, SLOT(insertVariable(QAction*))); + } + else + { + variablesMenu = new QMenu(tr("No variables to insert"), parentMenu); + variablesMenu->setEnabled(false); + } + + return variablesMenu; + } + + void CodeLineEdit::showVariableMenuAsPopup() + { + QMenu *menu = new QMenu; + + menu->addMenu(createVariablesMenu(menu)); + + menu->exec(QCursor::pos()); + + delete menu; + } void CodeLineEdit::resizeButtons() { QRect codeButtonGeometry; - QRect editorButtonGeometry; + QRect editorButtonGeometry; + QRect insertButtonGeometry; codeButtonGeometry.setX(rect().right() - mCodeButton->maximumWidth() + (mEmbedded ? 1 : 0)); codeButtonGeometry.setY(rect().top() + (mEmbedded ? -1 : 0)); @@ -234,16 +346,27 @@ codeButtonGeometry.setHeight(height() + (mEmbedded ? 2 : 0)); mCodeButton->setGeometry(codeButtonGeometry); - - editorButtonGeometry.setX(rect().right() - - (mShowEditorButton ? mEditorButton->maximumWidth() : 0) - - (mAllowTextCodeChange ? codeButtonGeometry.width() : 0) - + (mEmbedded ? 2 : 1)); - editorButtonGeometry.setY(rect().top() + (mEmbedded ? -1 : 0)); - editorButtonGeometry.setWidth(mEditorButton->maximumWidth()); - editorButtonGeometry.setHeight(height() + (mEmbedded ? 2 : 0)); - - mEditorButton->setGeometry(editorButtonGeometry); + + insertButtonGeometry.setX(rect().right() + - (mShowEditorButton ? mEditorButton->maximumWidth() : 0) + - (mAllowTextCodeChange ? codeButtonGeometry.width() : 0) + + (mEmbedded ? 2 : 1)); + insertButtonGeometry.setY(rect().top() + (mEmbedded ? -1 : 0)); + insertButtonGeometry.setWidth(mInsertButton->maximumWidth()); + insertButtonGeometry.setHeight(height() + (mEmbedded ? 2 : 0)); + + mInsertButton->setGeometry(insertButtonGeometry); + + editorButtonGeometry.setX(rect().right() + - (mShowEditorButton ? mEditorButton->maximumWidth() : 0) + - (mAllowTextCodeChange ? codeButtonGeometry.width() : 0) + - insertButtonGeometry.width() + + (mEmbedded ? 2 : 1)); + editorButtonGeometry.setY(rect().top() + (mEmbedded ? -1 : 0)); + editorButtonGeometry.setWidth(mEditorButton->maximumWidth()); + editorButtonGeometry.setHeight(height() + (mEmbedded ? 2 : 0)); + + mEditorButton->setGeometry(editorButtonGeometry); } void CodeLineEdit::mouseMoveEvent(QMouseEvent *event) @@ -317,6 +440,6 @@ painter.setBrush(QBrush(color)); painter.drawPolygon(polygon); } - } - } + } + } } diff -Nru actionaz-3.6.2/actiontools/codelineedit.h actionaz-3.7.0/actiontools/codelineedit.h --- actionaz-3.6.2/actiontools/codelineedit.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/codelineedit.h 2013-06-27 21:41:48.000000000 +0000 @@ -30,24 +30,27 @@ class QMenu; class QAbstractItemModel; -class QToolButton; namespace ActionTools { + class ParameterContainer; + class CodeLineEditButton; + class ACTIONTOOLSSHARED_EXPORT CodeLineEdit : public QLineEdit, public AbstractCodeEditor { Q_OBJECT Q_PROPERTY(bool code READ isCode WRITE setCode) public: - CodeLineEdit(QWidget *parent = 0, const QRegExp ®expValidation = QRegExp()); + CodeLineEdit(QWidget *parent, const QRegExp ®expValidation = QRegExp()); + virtual ~CodeLineEdit(); bool isMultiline() const { return mMultiline; } bool isCode() const { return mCode; } bool isEmbedded() const { return mEmbedded; } - QToolButton *codeButton() const { return mCodeButton; } - QToolButton *editorButton() const { return mEditorButton; } + CodeLineEditButton *codeButton() const { return mCodeButton; } + CodeLineEditButton *editorButton() const { return mEditorButton; } void setCode(bool code); void setEmbedded(bool embedded); @@ -55,10 +58,13 @@ void setAllowTextCodeChange(bool allowTextCodeChange); void setShowEditorButton(bool showEditorButton); void setFromSubParameter(const SubParameter &subParameter); + void setRegexpValidation(const QRegExp ®expValidation) { mRegExp = regexpValidation; } void addShortcuts(QMenu *menu); void setCompletionModel(QAbstractItemModel *completionModel); + void setParameterContainer(const ParameterContainer *parameterContainer); + QSet findVariables() const; public slots: void reverseCode(); @@ -71,8 +77,14 @@ protected: void contextMenuEvent(QContextMenuEvent *event); void resizeEvent(QResizeEvent *event); + virtual void insertVariable(const QString &variable); + + private slots: + void showVariableMenuAsPopup(); + void insertVariable(QAction *action); private: + QMenu *createVariablesMenu(QMenu *parentMenu); void resizeButtons(); void mouseMoveEvent(QMouseEvent *event); @@ -81,6 +93,7 @@ void mouseDoubleClickEvent(QMouseEvent *event); void paintEvent(QPaintEvent *event); + const ActionTools::ParameterContainer *mParameterContainer; bool mCode; bool mMultiline; bool mAllowTextCodeChange; @@ -90,8 +103,9 @@ QAction *mOpenEditor; QRegExp mRegExp; QAbstractItemModel *mCompletionModel; - QToolButton *mCodeButton; - QToolButton *mEditorButton; + CodeLineEditButton *mCodeButton; + CodeLineEditButton *mEditorButton; + CodeLineEditButton *mInsertButton; Q_DISABLE_COPY(CodeLineEdit) }; diff -Nru actionaz-3.6.2/actiontools/codelineeditbutton.cpp actionaz-3.7.0/actiontools/codelineeditbutton.cpp --- actionaz-3.6.2/actiontools/codelineeditbutton.cpp 1970-01-01 00:00:00.000000000 +0000 +++ actionaz-3.7.0/actiontools/codelineeditbutton.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -0,0 +1,32 @@ +/* + Actionaz + Copyright (C) 2008-2013 Jonathan Mercier-Ganady + + Actionaz is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Actionaz is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contact : jmgr@jmgr.info +*/ + +#include "codelineeditbutton.h" + +#include + +namespace ActionTools +{ + CodeLineEditButton::CodeLineEditButton(QWidget *parent) + : QToolButton(parent) + { + setCursor(Qt::ArrowCursor); + } +} diff -Nru actionaz-3.6.2/actiontools/codelineeditbutton.h actionaz-3.7.0/actiontools/codelineeditbutton.h --- actionaz-3.6.2/actiontools/codelineeditbutton.h 1970-01-01 00:00:00.000000000 +0000 +++ actionaz-3.7.0/actiontools/codelineeditbutton.h 2013-06-27 21:41:48.000000000 +0000 @@ -0,0 +1,39 @@ +/* + Actionaz + Copyright (C) 2008-2013 Jonathan Mercier-Ganady + + Actionaz is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Actionaz is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contact : jmgr@jmgr.info +*/ + +#ifndef CODELINEEDITBUTTON_H +#define CODELINEEDITBUTTON_H + +#include "actiontools_global.h" + +#include + +namespace ActionTools +{ + class ACTIONTOOLSSHARED_EXPORT CodeLineEditButton : public QToolButton + { + Q_OBJECT + + public: + explicit CodeLineEditButton(QWidget *parent = 0); + }; +} + +#endif // CODELINEEDITBUTTON_H diff -Nru actionaz-3.6.2/actiontools/codespinbox.cpp actionaz-3.7.0/actiontools/codespinbox.cpp --- actionaz-3.6.2/actiontools/codespinbox.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/codespinbox.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -68,8 +68,18 @@ void CodeSpinBox::setCompletionModel(QAbstractItemModel *completionModel) { - codeLineEdit()->setCompletionModel(completionModel); - } + codeLineEdit()->setCompletionModel(completionModel); + } + + void CodeSpinBox::setParameterContainer(const ParameterContainer *parameterContainer) + { + codeLineEdit()->setParameterContainer(parameterContainer); + } + + QSet CodeSpinBox::findVariables() const + { + return codeLineEdit()->findVariables(); + } QString CodeSpinBox::text() { diff -Nru actionaz-3.6.2/actiontools/codespinbox.h actionaz-3.7.0/actiontools/codespinbox.h --- actionaz-3.6.2/actiontools/codespinbox.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/codespinbox.h 2013-06-27 21:41:48.000000000 +0000 @@ -46,6 +46,8 @@ void openEditor(int line = -1, int column = -1); void setCompletionModel(QAbstractItemModel *completionModel); + void setParameterContainer(const ParameterContainer *parameterContainer); + QSet findVariables() const; QString text(); diff -Nru actionaz-3.6.2/actiontools/coloredit.cpp actionaz-3.7.0/actiontools/coloredit.cpp --- actionaz-3.6.2/actiontools/coloredit.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/coloredit.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -78,8 +78,18 @@ void ColorEdit::setCompletionModel(QAbstractItemModel *completionModel) { - codeLineEdit()->setCompletionModel(completionModel); - } + codeLineEdit()->setCompletionModel(completionModel); + } + + void ColorEdit::setParameterContainer(const ParameterContainer *parameterContainer) + { + codeLineEdit()->setParameterContainer(parameterContainer); + } + + QSet ColorEdit::findVariables() const + { + return codeLineEdit()->findVariables(); + } void ColorEdit::setChooseByPositionButtonVisible(bool visible) { diff -Nru actionaz-3.6.2/actiontools/coloredit.h actionaz-3.7.0/actiontools/coloredit.h --- actionaz-3.6.2/actiontools/coloredit.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/coloredit.h 2013-06-27 21:41:48.000000000 +0000 @@ -54,6 +54,8 @@ void setFromSubParameter(const SubParameter &subParameter); void openEditor(int line = -1, int column = -1); void setCompletionModel(QAbstractItemModel *completionModel); + void setParameterContainer(const ParameterContainer *parameterContainer); + QSet findVariables() const; void setChooseByPositionButtonVisible(bool visible); signals: diff -Nru actionaz-3.6.2/actiontools/colorparameterdefinition.cpp actionaz-3.7.0/actiontools/colorparameterdefinition.cpp --- actionaz-3.6.2/actiontools/colorparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/colorparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -25,8 +25,8 @@ namespace ActionTools { - ColorParameterDefinition::ColorParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + ColorParameterDefinition::ColorParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mColorEdit(0) { } diff -Nru actionaz-3.6.2/actiontools/colorparameterdefinition.h actionaz-3.7.0/actiontools/colorparameterdefinition.h --- actionaz-3.6.2/actiontools/colorparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/colorparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -33,7 +33,7 @@ Q_OBJECT public: - ColorParameterDefinition(const Name &name, QObject *parent); + ColorParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); diff -Nru actionaz-3.6.2/actiontools/colorpositionparameterdefinition.cpp actionaz-3.7.0/actiontools/colorpositionparameterdefinition.cpp --- actionaz-3.6.2/actiontools/colorpositionparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/colorpositionparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -26,8 +26,8 @@ namespace ActionTools { - ColorPositionParameterDefinition::ColorPositionParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + ColorPositionParameterDefinition::ColorPositionParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mPositionEdit(0), mColorEdit(0) { diff -Nru actionaz-3.6.2/actiontools/colorpositionparameterdefinition.h actionaz-3.7.0/actiontools/colorpositionparameterdefinition.h --- actionaz-3.6.2/actiontools/colorpositionparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/colorpositionparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -37,7 +37,7 @@ Q_OBJECT public: - ColorPositionParameterDefinition(const Name &name, QObject *parent); + ColorPositionParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); diff -Nru actionaz-3.6.2/actiontools/datetimeparameterdefinition.cpp actionaz-3.7.0/actiontools/datetimeparameterdefinition.cpp --- actionaz-3.6.2/actiontools/datetimeparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/datetimeparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -25,8 +25,8 @@ namespace ActionTools { - DateTimeParameterDefinition::DateTimeParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + DateTimeParameterDefinition::DateTimeParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mDateTimeEdit(0) { } diff -Nru actionaz-3.6.2/actiontools/datetimeparameterdefinition.h actionaz-3.7.0/actiontools/datetimeparameterdefinition.h --- actionaz-3.6.2/actiontools/datetimeparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/datetimeparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -33,7 +33,7 @@ Q_OBJECT public: - DateTimeParameterDefinition(const Name &name, QObject *parent); + DateTimeParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); diff -Nru actionaz-3.6.2/actiontools/elementdefinition.cpp actionaz-3.7.0/actiontools/elementdefinition.cpp --- actionaz-3.6.2/actiontools/elementdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/elementdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -22,9 +22,9 @@ namespace ActionTools { - ElementDefinition::ElementDefinition(const Name &name, QObject *parent) + ElementDefinition::ElementDefinition(const Name &name, QObject *parent) : QObject(parent), - mName(name), + mName(name), mCategory(INPUT), mTab(0) { diff -Nru actionaz-3.6.2/actiontools/elementdefinition.h actionaz-3.7.0/actiontools/elementdefinition.h --- actionaz-3.6.2/actiontools/elementdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/elementdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -28,6 +28,7 @@ namespace ActionTools { + class ParameterContainer; class ActionInstance; class ACTIONTOOLSSHARED_EXPORT ElementDefinition : public QObject @@ -41,20 +42,20 @@ OUTPUT }; - ElementDefinition(const Name &name, QObject *parent); - virtual ~ElementDefinition() {} + ElementDefinition(const Name &name, QObject *parent); + virtual ~ElementDefinition() {} - const Name &name() const { return mName; } - const QString &tooltip() const { return mTooltip; } - Category category() const { return mCategory; } - const QString &description() const { return mDescription; } - int tab() const { return mTab; } - - void setName(const Name &name) { mName = name; } - void setTooltip(const QString &tooltip) { mTooltip = tooltip; } - void setCategory(Category category) { mCategory = category; } - void setDescription(const QString &description) { mDescription = description; } - void setTab(int tab) { mTab = tab; } + const Name &name() const { return mName; } + const QString &tooltip() const { return mTooltip; } + Category category() const { return mCategory; } + const QString &description() const { return mDescription; } + int tab() const { return mTab; } + + void setName(const Name &name) { mName = name; } + void setTooltip(const QString &tooltip) { mTooltip = tooltip; } + void setCategory(Category category) { mCategory = category; } + void setDescription(const QString &description) { mDescription = description; } + void setTab(int tab) { mTab = tab; } virtual void setDefaultValues(ActionInstance *actionInstance) = 0; diff -Nru actionaz-3.6.2/actiontools/environmentvariableparameterdefinition.cpp actionaz-3.7.0/actiontools/environmentvariableparameterdefinition.cpp --- actionaz-3.6.2/actiontools/environmentvariableparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/environmentvariableparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -41,7 +41,7 @@ emit editorBuilt(); } - void EnvironmentVariableParameterDefinition::update(Script *script) + void EnvironmentVariableParameterDefinition::actionUpdate(Script *script) { Q_UNUSED(script) diff -Nru actionaz-3.6.2/actiontools/environmentvariableparameterdefinition.h actionaz-3.7.0/actiontools/environmentvariableparameterdefinition.h --- actionaz-3.6.2/actiontools/environmentvariableparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/environmentvariableparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -31,11 +31,11 @@ Q_OBJECT public: - EnvironmentVariableParameterDefinition(const Name &name, QObject *parent) - : ListParameterDefinition(name, parent) {} + EnvironmentVariableParameterDefinition(const Name &name, QObject *parent) + : ListParameterDefinition(name, parent) {} void buildEditors(Script *script, QWidget *parent); - void update(Script *script); + void actionUpdate(Script *script); }; } diff -Nru actionaz-3.6.2/actiontools/fileedit.cpp actionaz-3.7.0/actiontools/fileedit.cpp --- actionaz-3.6.2/actiontools/fileedit.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/fileedit.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -75,8 +75,18 @@ void FileEdit::setCompletionModel(QAbstractItemModel *completionModel) { - codeLineEdit()->setCompletionModel(completionModel); - } + codeLineEdit()->setCompletionModel(completionModel); + } + + void FileEdit::setParameterContainer(const ParameterContainer *parameterContainer) + { + codeLineEdit()->setParameterContainer(parameterContainer); + } + + QSet FileEdit::findVariables() const + { + return codeLineEdit()->findVariables(); + } void FileEdit::on_browse_clicked() { diff -Nru actionaz-3.6.2/actiontools/fileedit.h actionaz-3.7.0/actiontools/fileedit.h --- actionaz-3.6.2/actiontools/fileedit.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/fileedit.h 2013-06-27 21:41:48.000000000 +0000 @@ -60,6 +60,8 @@ void setFromSubParameter(const SubParameter &subParameter); void openEditor(int line = -1, int column = -1); void setCompletionModel(QAbstractItemModel *completionModel); + void setParameterContainer(const ParameterContainer *parameterContainer); + QSet findVariables() const; void setMode(Mode mode) { mMode = mode; } void setCaption(const QString &caption) { mCaption = caption; } diff -Nru actionaz-3.6.2/actiontools/fileparameterdefinition.cpp actionaz-3.7.0/actiontools/fileparameterdefinition.cpp --- actionaz-3.6.2/actiontools/fileparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/fileparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -25,8 +25,8 @@ namespace ActionTools { - FileParameterDefinition::FileParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + FileParameterDefinition::FileParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mFileEdit(0) { } diff -Nru actionaz-3.6.2/actiontools/fileparameterdefinition.h actionaz-3.7.0/actiontools/fileparameterdefinition.h --- actionaz-3.6.2/actiontools/fileparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/fileparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -32,7 +32,7 @@ Q_OBJECT public: - FileParameterDefinition(const Name &name, QObject *parent); + FileParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); diff -Nru actionaz-3.6.2/actiontools/groupdefinition.cpp actionaz-3.7.0/actiontools/groupdefinition.cpp --- actionaz-3.6.2/actiontools/groupdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/groupdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -29,7 +29,7 @@ namespace ActionTools { GroupDefinition::GroupDefinition(QObject *parent) - : ElementDefinition(Name(), parent), + : ElementDefinition(Name(), parent), mMasterList(0), mMasterCodeComboBox(0) { diff -Nru actionaz-3.6.2/actiontools/ifactionparameterdefinition.cpp actionaz-3.7.0/actiontools/ifactionparameterdefinition.cpp --- actionaz-3.6.2/actiontools/ifactionparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/ifactionparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -40,8 +40,8 @@ << QT_TRANSLATE_NOOP("IfActionParameterDefinition::actions", "Run code") << QT_TRANSLATE_NOOP("IfActionParameterDefinition::actions", "Call procedure")); - IfActionParameterDefinition::IfActionParameterDefinition(const Name &name, QObject *parent) - : ItemsParameterDefinition(name, parent), + IfActionParameterDefinition::IfActionParameterDefinition(const Name &name, QObject *parent) + : ItemsParameterDefinition(name, parent), mActionEdit(0), mLineComboBox(0), mCodeLineEdit(0), @@ -157,7 +157,7 @@ actionInstance->setSubParameter(name().original(), "line", defaultLine()); } - void IfActionParameterDefinition::update(Script *script) + void IfActionParameterDefinition::actionUpdate(Script *script) { mLineComboBox->setup(script->labels(), script->actionCount()); mProcedureComboBox->clear(); diff -Nru actionaz-3.6.2/actiontools/ifactionparameterdefinition.h actionaz-3.7.0/actiontools/ifactionparameterdefinition.h --- actionaz-3.6.2/actiontools/ifactionparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/ifactionparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -36,7 +36,18 @@ Q_OBJECT public: - IfActionParameterDefinition(const Name &name, QObject *parent); + enum Actions + { + DoNothing, + Goto, + RunCode, + CallProcedure, + Wait + }; + + static StringListPair actions; + + IfActionParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); @@ -51,7 +62,7 @@ void setDefaultLine(const QString &line) { mDefaultLine = line; } QString defaultLine() const { return mDefaultLine; } - void update(Script *script); + void actionUpdate(Script *script); private slots: void codeChanged(bool code); @@ -66,14 +77,6 @@ ProcedureEditor, NoEditor }; - enum Actions - { - DoNothing, - Goto, - RunCode, - CallProcedure, - Wait - }; Editor findAppropriateEditor(const QString &actionText) const; void updateStatus(const QString &actionText); @@ -81,7 +84,6 @@ void setDefaultValue(const QVariant &defaultValue) { Q_UNUSED(defaultValue); } static bool translated; - static StringListPair actions; CodeComboBox *mActionEdit; LineComboBox *mLineComboBox; Binary files /tmp/JMEeLlU7Z4/actionaz-3.6.2/actiontools/images/insert.png and /tmp/qobjZXCshB/actionaz-3.7.0/actiontools/images/insert.png differ diff -Nru actionaz-3.6.2/actiontools/itemsparameterdefinition.h actionaz-3.7.0/actiontools/itemsparameterdefinition.h --- actionaz-3.6.2/actiontools/itemsparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/itemsparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -31,8 +31,8 @@ Q_OBJECT public: - ItemsParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent) {} + ItemsParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent) {} const StringListPair &items() const { return mItems; } diff -Nru actionaz-3.6.2/actiontools/keyparameterdefinition.cpp actionaz-3.7.0/actiontools/keyparameterdefinition.cpp --- actionaz-3.6.2/actiontools/keyparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/keyparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -27,8 +27,8 @@ namespace ActionTools { - KeyParameterDefinition::KeyParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + KeyParameterDefinition::KeyParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mKeyEdit(0) { } diff -Nru actionaz-3.6.2/actiontools/keyparameterdefinition.h actionaz-3.7.0/actiontools/keyparameterdefinition.h --- actionaz-3.6.2/actiontools/keyparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/keyparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -33,7 +33,7 @@ Q_OBJECT public: - KeyParameterDefinition(const Name &name, QObject *parent); + KeyParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); diff -Nru actionaz-3.6.2/actiontools/linecombobox.cpp actionaz-3.7.0/actiontools/linecombobox.cpp --- actionaz-3.6.2/actiontools/linecombobox.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/linecombobox.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -22,8 +22,8 @@ namespace ActionTools { - LineComboBox::LineComboBox(const QStringList &labels, int lineCount, QWidget *parent) - : CodeComboBox(parent) + LineComboBox::LineComboBox(const QStringList &labels, int lineCount, QWidget *parent) + : CodeComboBox(parent) { setup(labels, lineCount); } diff -Nru actionaz-3.6.2/actiontools/linecombobox.h actionaz-3.7.0/actiontools/linecombobox.h --- actionaz-3.6.2/actiontools/linecombobox.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/linecombobox.h 2013-06-27 21:41:48.000000000 +0000 @@ -31,7 +31,7 @@ Q_OBJECT public: - LineComboBox(const QStringList &labels, int lineCount, QWidget *parent = 0); + LineComboBox(const QStringList &labels, int lineCount, QWidget *parent = 0); void setup(const QStringList &labels, int lineCount); diff -Nru actionaz-3.6.2/actiontools/lineparameterdefinition.cpp actionaz-3.7.0/actiontools/lineparameterdefinition.cpp --- actionaz-3.6.2/actiontools/lineparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/lineparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -35,7 +35,7 @@ emit editorBuilt(); } - void LineParameterDefinition::update(Script *script) + void LineParameterDefinition::actionUpdate(Script *script) { ActionTools::LineComboBox *lineComboBox = qobject_cast(mComboBox); diff -Nru actionaz-3.6.2/actiontools/lineparameterdefinition.h actionaz-3.7.0/actiontools/lineparameterdefinition.h --- actionaz-3.6.2/actiontools/lineparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/lineparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -31,11 +31,11 @@ Q_OBJECT public: - LineParameterDefinition(const Name &name, QObject *parent) - : ListParameterDefinition(name, parent) {} + LineParameterDefinition(const Name &name, QObject *parent) + : ListParameterDefinition(name, parent) {} void buildEditors(Script *script, QWidget *parent); - void update(Script *script); + void actionUpdate(Script *script); }; } diff -Nru actionaz-3.6.2/actiontools/listparameterdefinition.cpp actionaz-3.7.0/actiontools/listparameterdefinition.cpp --- actionaz-3.6.2/actiontools/listparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/listparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -27,8 +27,8 @@ namespace ActionTools { - ListParameterDefinition::ListParameterDefinition(const Name &name, QObject *parent) - : ItemsParameterDefinition(name, parent), + ListParameterDefinition::ListParameterDefinition(const Name &name, QObject *parent) + : ItemsParameterDefinition(name, parent), mComboBox(0) { } diff -Nru actionaz-3.6.2/actiontools/listparameterdefinition.h actionaz-3.7.0/actiontools/listparameterdefinition.h --- actionaz-3.6.2/actiontools/listparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/listparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -33,7 +33,7 @@ Q_OBJECT public: - ListParameterDefinition(const Name &name, QObject *parent); + ListParameterDefinition(const Name &name, QObject *parent); virtual ~ListParameterDefinition() {} virtual void buildEditors(Script *script, QWidget *parent); diff -Nru actionaz-3.6.2/actiontools/matchingpointlist.h actionaz-3.7.0/actiontools/matchingpointlist.h --- actionaz-3.6.2/actiontools/matchingpointlist.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/matchingpointlist.h 2013-06-27 21:41:48.000000000 +0000 @@ -27,7 +27,20 @@ namespace ActionTools { - typedef QPair MatchingPoint; + struct MatchingPoint + { + MatchingPoint(const QPoint &position, int confidence, int imageIndex) + : position(position), + confidence(confidence), + imageIndex(imageIndex) + { + } + + QPoint position; + int confidence; + int imageIndex; + }; + typedef QList MatchingPointList; } diff -Nru actionaz-3.6.2/actiontools/multitextparameterdefinition.cpp actionaz-3.7.0/actiontools/multitextparameterdefinition.cpp --- actionaz-3.6.2/actiontools/multitextparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/multitextparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -25,8 +25,8 @@ namespace ActionTools { - MultiTextParameterDefinition::MultiTextParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + MultiTextParameterDefinition::MultiTextParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mItemListWidget(0) { } diff -Nru actionaz-3.6.2/actiontools/multitextparameterdefinition.h actionaz-3.7.0/actiontools/multitextparameterdefinition.h --- actionaz-3.6.2/actiontools/multitextparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/multitextparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -33,7 +33,7 @@ Q_OBJECT public: - MultiTextParameterDefinition(const Name &name, QObject *parent); + MultiTextParameterDefinition(const Name &namez, QObject *parent); virtual ~MultiTextParameterDefinition() {} virtual void buildEditors(Script *script, QWidget *parent); diff -Nru actionaz-3.6.2/actiontools/numberparameterdefinition.cpp actionaz-3.7.0/actiontools/numberparameterdefinition.cpp --- actionaz-3.6.2/actiontools/numberparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/numberparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -26,8 +26,8 @@ namespace ActionTools { - NumberParameterDefinition::NumberParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + NumberParameterDefinition::NumberParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mSpinBox(0), mMaximum(99), mMinimum(0), diff -Nru actionaz-3.6.2/actiontools/numberparameterdefinition.h actionaz-3.7.0/actiontools/numberparameterdefinition.h --- actionaz-3.6.2/actiontools/numberparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/numberparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -33,7 +33,7 @@ Q_OBJECT public: - NumberParameterDefinition(const Name &name, QObject *parent); + NumberParameterDefinition(const Name &namez, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); diff -Nru actionaz-3.6.2/actiontools/opencvalgorithms.cpp actionaz-3.7.0/actiontools/opencvalgorithms.cpp --- actionaz-3.6.2/actiontools/opencvalgorithms.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/opencvalgorithms.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -37,12 +37,13 @@ qRegisterMetaType("MatchingPointList"); } - bool OpenCVAlgorithms::findSubImageAsync(const QImage &source, - const QImage &target, - int matchPercentage, - int maximumMatches, - int downPyrs, - int searchExpansion) + bool OpenCVAlgorithms::findSubImageAsync(const QList &sources, + const QImage &target, + int matchPercentage, + int maximumMatches, + int downPyrs, + int searchExpansion, + AlgorithmMethod method) { mError = NoError; mErrorString.clear(); @@ -55,38 +56,49 @@ return false; } - cv::Mat sourceMat = toCVMat(source); + QList sourcesMat; + sourcesMat.reserve(sources.size()); + + foreach(const QImage &source, sources) + sourcesMat.append(toCVMat(source)); + cv::Mat targetMat = toCVMat(target); - if(!checkInputImages(sourceMat, targetMat)) + if(!checkInputImages(sourcesMat, targetMat)) return false; connect(&mFutureWatcher, SIGNAL(finished()), this, SLOT(finished())); - mFuture = QtConcurrent::run(boost::bind(&OpenCVAlgorithms::fastMatchTemplate, this, sourceMat, targetMat, matchPercentage, maximumMatches, downPyrs, searchExpansion)); + mFuture = QtConcurrent::run(boost::bind(&OpenCVAlgorithms::fastMatchTemplate, this, sourcesMat, targetMat, matchPercentage, maximumMatches, downPyrs, searchExpansion, method)); mFutureWatcher.setFuture(mFuture); return true; } - bool OpenCVAlgorithms::findSubImage(const QImage &source, - const QImage &target, - MatchingPointList &matchingPoints, - int matchPercentage, - int maximumMatches, - int downPyrs, - int searchExpansion) + bool OpenCVAlgorithms::findSubImage(const QList &sources, + const QImage &target, + MatchingPointList &matchingPoints, + int matchPercentage, + int maximumMatches, + int downPyrs, + int searchExpansion, + AlgorithmMethod method) { mError = NoError; mErrorString.clear(); - cv::Mat sourceMat = toCVMat(source); + QList sourcesMat; + sourcesMat.reserve(sources.size()); + + foreach(const QImage &source, sources) + sourcesMat.append(toCVMat(source)); + cv::Mat targetMat = toCVMat(target); - if(!checkInputImages(sourceMat, targetMat)) + if(!checkInputImages(sourcesMat, targetMat)) return false; - matchingPoints = OpenCVAlgorithms::fastMatchTemplate(sourceMat, targetMat, matchPercentage, maximumMatches, downPyrs, searchExpansion); + matchingPoints = OpenCVAlgorithms::fastMatchTemplate(sourcesMat, targetMat, matchPercentage, maximumMatches, downPyrs, searchExpansion, method); return true; } @@ -102,209 +114,229 @@ emit finished(mFutureWatcher.result()); } - bool OpenCVAlgorithms::checkInputImages(const cv::Mat &source, const cv::Mat &target) + bool OpenCVAlgorithms::checkInputImages(const QList &sources, const cv::Mat &target) { - // make sure that the template image is smaller than the source - if(target.size().width > source.size().width || - target.size().height > source.size().height) - { - mError = SourceImageSmallerThanTargerImageError; - mErrorString = tr("Source image must be larger than target image"); - - return false; - } - - if(source.depth() != target.depth()) - { - mError = NotSameDepthError; - mErrorString = tr("Source image and target image must have same depth"); - - return false; - } - - if(source.channels() != target.channels()) - { - mError = NotSameChannelCountError; - mErrorString = tr("Source image and target image must have same number of channels"); - - return false; - } + foreach(const cv::Mat &source, sources) + { + // make sure that the template image is smaller than the source + if(target.size().width > source.size().width || + target.size().height > source.size().height) + { + mError = SourceImageSmallerThanTargerImageError; + mErrorString = tr("Source images must be larger than target image"); + + return false; + } + + if(source.depth() != target.depth()) + { + mError = NotSameDepthError; + mErrorString = tr("Source images and target image must have same depth"); + + return false; + } + + if(source.channels() != target.channels()) + { + mError = NotSameChannelCountError; + mErrorString = tr("Source images and target image must have same number of channels"); + + return false; + } + } return true; } - MatchingPointList OpenCVAlgorithms::fastMatchTemplate(const cv::Mat &source, + MatchingPointList OpenCVAlgorithms::fastMatchTemplate(const QList &sources, const cv::Mat &target, int matchPercentage, int maximumMatches, int downPyrs, - int searchExpansion) + int searchExpansion, + AlgorithmMethod method) { - MatchingPointList matchingPointList; - - try - { - // create copies of the images to modify - cv::Mat copyOfSource = source.clone(); - cv::Mat copyOfTarget = target.clone(); + MatchingPointList matchingPointList; + int sourceIndex = 0; - cv::Size sourceSize = source.size(); - cv::Size targetSize = target.size(); - - // down pyramid the images - for(int ii = 0; ii < downPyrs; ii++) - { - // start with the source image - sourceSize.width = (sourceSize.width + 1) / 2; - sourceSize.height = (sourceSize.height + 1) / 2; + foreach(const cv::Mat &source, sources) + { + try + { + // create copies of the images to modify + cv::Mat copyOfSource = source.clone(); + cv::Mat copyOfTarget = target.clone(); + + cv::Size sourceSize = source.size(); + cv::Size targetSize = target.size(); + + // down pyramid the images + for(int ii = 0; ii < downPyrs; ii++) + { + // start with the source image + sourceSize.width = (sourceSize.width + 1) / 2; + sourceSize.height = (sourceSize.height + 1) / 2; + + cv::Mat smallSource(sourceSize, source.type()); + cv::pyrDown(copyOfSource, smallSource); + + // prepare for next loop, if any + copyOfSource = smallSource.clone(); + + // next, do the target + targetSize.width = (targetSize.width + 1) / 2; + targetSize.height = (targetSize.height + 1) / 2; + + cv::Mat smallTarget(targetSize, target.type()); + pyrDown(copyOfTarget, smallTarget); + + // prepare for next loop, if any + copyOfTarget = smallTarget.clone(); + } + + // perform the match on the shrunken images + cv::Size smallTargetSize = copyOfTarget.size(); + cv::Size smallSourceSize = copyOfSource.size(); + + cv::Size resultSize; + resultSize.width = smallSourceSize.width - smallTargetSize.width + 1; + resultSize.height = smallSourceSize.height - smallTargetSize.height + 1; + + cv::Mat result(resultSize, CV_32FC1); + cv::matchTemplate(copyOfSource, copyOfTarget, result, toOpenCVMethod(method)); + + // find the top match locations + QVector locations = multipleMinMaxLoc(result, maximumMatches, method); + + // search the large images at the returned locations + sourceSize = source.size(); + targetSize = target.size(); + + int twoPowerNumDownPyrs = std::pow(2.0f, downPyrs); + + // create a copy of the source in order to adjust its ROI for searching + for(int currMax = 0; currMax < maximumMatches; ++currMax) + { + // transform the point to its corresponding point in the larger image + QPoint &currMaxLocation = locations[currMax]; + currMaxLocation *= twoPowerNumDownPyrs; + currMaxLocation.setX(currMaxLocation.x() + targetSize.width / 2); + currMaxLocation.setY(currMaxLocation.y() + targetSize.height / 2); + + const QPoint &searchPoint = locations.at(currMax); + + // if we are searching for multiple targets and we have found a target or + // multiple targets, we don't want to search in the same location(s) again + if(maximumMatches > 1 && !matchingPointList.isEmpty()) + { + bool thisTargetFound = false; + + for(int currPoint = 0; currPoint < matchingPointList.size(); currPoint++) + { + const QPoint &foundPoint = matchingPointList.at(currPoint).position; + if(std::abs(searchPoint.x() - foundPoint.x()) <= searchExpansion * 2 && + std::abs(searchPoint.y() - foundPoint.y()) <= searchExpansion * 2) + { + thisTargetFound = true; + break; + } + } + + // if the current target has been found, continue onto the next point + if(thisTargetFound) + continue; + } + + // set the source image's ROI to slightly larger than the target image, + // centred at the current point + cv::Rect searchRoi; + searchRoi.x = searchPoint.x() - (target.size().width) / 2 - searchExpansion; + searchRoi.y = searchPoint.y() - (target.size().height) / 2 - searchExpansion; + searchRoi.width = target.size().width + searchExpansion * 2; + searchRoi.height = target.size().height + searchExpansion * 2; + + // make sure ROI doesn't extend outside of image + if(searchRoi.x < 0) + searchRoi.x = 0; + + if(searchRoi.y < 0) + searchRoi.y = 0; + + if((searchRoi.x + searchRoi.width) > (sourceSize.width - 1)) + { + int numPixelsOver = (searchRoi.x + searchRoi.width) - (sourceSize.width - 1); + + searchRoi.width -= numPixelsOver; + } + + if((searchRoi.y + searchRoi.height) > (sourceSize.height - 1)) + { + int numPixelsOver = (searchRoi.y + searchRoi.height) - (sourceSize.height - 1); + + searchRoi.height -= numPixelsOver; + } + + cv::Mat searchImage(source, searchRoi); + + // perform the search on the large images + resultSize.width = searchRoi.width - target.size().width + 1; + resultSize.height = searchRoi.height - target.size().height + 1; + + result = cv::Mat(resultSize, CV_32FC1); + cv::matchTemplate(searchImage, target, result, toOpenCVMethod(method)); + + // find the best match location + double minValue; + double maxValue; + cv::Point minLoc; + cv::Point maxLoc; + + cv::minMaxLoc(result, &minValue, &maxValue, &minLoc, &maxLoc); + + double &value = (method == SquaredDifferenceMethod) ? minValue : maxValue; + cv::Point &loc = (method == SquaredDifferenceMethod) ? minLoc : maxLoc; + + value *= 100.0; + + // transform point back to original image + loc.x += searchRoi.x + target.size().width / 2; + loc.y += searchRoi.y + target.size().height / 2; + + if(method == SquaredDifferenceMethod) + value = 100.0f - value; + + if(value >= matchPercentage) + { + // add the point to the list + matchingPointList.append(MatchingPoint(QPoint(loc.x, loc.y), value, sourceIndex)); + + // if we are only looking for a single target, we have found it, so we + // can return + if(maximumMatches <= 1) + break; + } + else + break; // skip the rest + } + } + catch(const cv::Exception &e) + { + mError = OpenCVException; + mErrorString = tr("OpenCV exception: %1").arg(e.what()); - cv::Mat smallSource(sourceSize, source.type()); - cv::pyrDown(copyOfSource, smallSource); + return MatchingPointList(); + } - // prepare for next loop, if any - copyOfSource = smallSource.clone(); - - // next, do the target - targetSize.width = (targetSize.width + 1) / 2; - targetSize.height = (targetSize.height + 1) / 2; - - cv::Mat smallTarget(targetSize, target.type()); - pyrDown(copyOfTarget, smallTarget); - - // prepare for next loop, if any - copyOfTarget = smallTarget.clone(); - } - - // perform the match on the shrunken images - cv::Size smallTargetSize = copyOfTarget.size(); - cv::Size smallSourceSize = copyOfSource.size(); - - cv::Size resultSize; - resultSize.width = smallSourceSize.width - smallTargetSize.width + 1; - resultSize.height = smallSourceSize.height - smallTargetSize.height + 1; - - cv::Mat result(resultSize, CV_32FC1); - cv::matchTemplate(copyOfSource, copyOfTarget, result, CV_TM_CCOEFF_NORMED); - - // find the top match locations - QVector locations = multipleMaxLoc(result, maximumMatches); - - // search the large images at the returned locations - sourceSize = source.size(); - targetSize = target.size(); - - int twoPowerNumDownPyrs = std::pow(2.0f, downPyrs); - - // create a copy of the source in order to adjust its ROI for searching - for(int currMax = 0; currMax < maximumMatches; ++currMax) - { - // transform the point to its corresponding point in the larger image - QPoint &currMaxLocation = locations[currMax]; - currMaxLocation *= twoPowerNumDownPyrs; - currMaxLocation.setX(currMaxLocation.x() + targetSize.width / 2); - currMaxLocation.setY(currMaxLocation.y() + targetSize.height / 2); - - const QPoint &searchPoint = locations.at(currMax); - - // if we are searching for multiple targets and we have found a target or - // multiple targets, we don't want to search in the same location(s) again - if(maximumMatches > 1 && !matchingPointList.isEmpty()) - { - bool thisTargetFound = false; - - for(int currPoint = 0; currPoint < matchingPointList.size(); currPoint++) - { - const QPoint &foundPoint = matchingPointList.at(currPoint).first; - if(std::abs(searchPoint.x() - foundPoint.x()) <= searchExpansion * 2 && - std::abs(searchPoint.y() - foundPoint.y()) <= searchExpansion * 2) - { - thisTargetFound = true; - break; - } - } - - // if the current target has been found, continue onto the next point - if(thisTargetFound) - continue; - } - - // set the source image's ROI to slightly larger than the target image, - // centred at the current point - cv::Rect searchRoi; - searchRoi.x = searchPoint.x() - (target.size().width) / 2 - searchExpansion; - searchRoi.y = searchPoint.y() - (target.size().height) / 2 - searchExpansion; - searchRoi.width = target.size().width + searchExpansion * 2; - searchRoi.height = target.size().height + searchExpansion * 2; - - // make sure ROI doesn't extend outside of image - if(searchRoi.x < 0) - searchRoi.x = 0; - - if(searchRoi.y < 0) - searchRoi.y = 0; - - if((searchRoi.x + searchRoi.width) > (sourceSize.width - 1)) - { - int numPixelsOver = (searchRoi.x + searchRoi.width) - (sourceSize.width - 1); - - searchRoi.width -= numPixelsOver; - } - - if((searchRoi.y + searchRoi.height) > (sourceSize.height - 1)) - { - int numPixelsOver = (searchRoi.y + searchRoi.height) - (sourceSize.height - 1); - - searchRoi.height -= numPixelsOver; - } - - cv::Mat searchImage(source, searchRoi); - - // perform the search on the large images - resultSize.width = searchRoi.width - target.size().width + 1; - resultSize.height = searchRoi.height - target.size().height + 1; - - result = cv::Mat(resultSize, CV_32FC1); - cv::matchTemplate(searchImage, target, result, CV_TM_CCOEFF_NORMED); - - // find the best match location - double maxValue; - cv::Point maxLoc; - cv::minMaxLoc(result, 0, &maxValue, 0, &maxLoc); - maxValue *= 100.0; - - // transform point back to original image - maxLoc.x += searchRoi.x + target.size().width / 2; - maxLoc.y += searchRoi.y + target.size().height / 2; - - if(maxValue >= matchPercentage) - { - // add the point to the list - matchingPointList.append(qMakePair(QPoint(maxLoc.x, maxLoc.y), maxValue)); - - // if we are only looking for a single target, we have found it, so we - // can return - if(maximumMatches <= 1) - break; - } - else - break; // skip the rest - } - } - catch(const cv::Exception &e) - { - mError = OpenCVException; - mErrorString = tr("OpenCV exception: %1").arg(e.what()); - - return MatchingPointList(); - } + ++sourceIndex; + } return matchingPointList; } - QVector OpenCVAlgorithms::multipleMaxLoc(const cv::Mat &image, int maximumMatches) const + QVector OpenCVAlgorithms::multipleMinMaxLoc(const cv::Mat &image, int maximumMatches, AlgorithmMethod method) { QVector locations(maximumMatches); - QVector maxima(maximumMatches, 0.0f); + QVector matches(maximumMatches, (method == SquaredDifferenceMethod) ? std::numeric_limits::max() : -std::numeric_limits::max()); cv::Size size = image.size(); // extract the raw data for analysis @@ -320,17 +352,18 @@ { // require at least 50% confidence on the sub-sampled image // in order to make this as fast as possible - if(data > 0.5f && data > maxima.at(j)) + if((method == SquaredDifferenceMethod && data < 0.5f && data < matches.at(j)) || + (method != SquaredDifferenceMethod && data > 0.5f && data > matches.at(j))) { // move the maxima down for(int k = maximumMatches - 1; k > j; --k) { - maxima[k] = maxima.at(k-1); + matches[k] = matches.at(k-1); locations[k] = locations.at(k-1); } // insert the value - maxima[j] = data; + matches[j] = data; locations[j].setX(x); locations[j].setY(y); break; @@ -342,12 +375,12 @@ return locations; } - QImage OpenCVAlgorithms::toQImage(const cv::Mat &image) const + QImage OpenCVAlgorithms::toQImage(const cv::Mat &image) { return QImage(image.data, image.size().width, image.size().height, image.step, QImage::Format_RGB888).rgbSwapped(); } - cv::Mat OpenCVAlgorithms::toCVMat(const QImage &image) const + cv::Mat OpenCVAlgorithms::toCVMat(const QImage &image) { cv::Mat mat(image.height(), image.width(), CV_8UC4, const_cast(image.bits()), image.bytesPerLine()); cv::Mat back(mat.rows, mat.cols, CV_8UC3); @@ -357,4 +390,18 @@ return back; } + + int OpenCVAlgorithms::toOpenCVMethod(OpenCVAlgorithms::AlgorithmMethod method) + { + switch(method) + { + default: + case ActionTools::OpenCVAlgorithms::CorrelationCoefficientMethod: + return CV_TM_CCOEFF_NORMED; + case ActionTools::OpenCVAlgorithms::CrossCorrelationMethod: + return CV_TM_CCORR_NORMED; + case ActionTools::OpenCVAlgorithms::SquaredDifferenceMethod: + return CV_TM_SQDIFF_NORMED; + } + } } diff -Nru actionaz-3.6.2/actiontools/opencvalgorithms.h actionaz-3.7.0/actiontools/opencvalgorithms.h --- actionaz-3.6.2/actiontools/opencvalgorithms.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/opencvalgorithms.h 2013-06-27 21:41:48.000000000 +0000 @@ -69,6 +69,7 @@ #include "matchingpointlist.h" #include +#include #include #include #include @@ -97,21 +98,30 @@ OpenCVException }; + enum AlgorithmMethod + { + CorrelationCoefficientMethod, + CrossCorrelationMethod, + SquaredDifferenceMethod + }; + explicit OpenCVAlgorithms(QObject *parent = 0); - bool findSubImageAsync(const QImage &source, + bool findSubImageAsync(const QList &sources, const QImage &target, int matchPercentage = 70, int maximumMatches = 10, int downPyrs = 2, - int searchExpansion = 15); - bool findSubImage(const QImage &source, + int searchExpansion = 15, + AlgorithmMethod method = CorrelationCoefficientMethod); + bool findSubImage(const QList &sources, const QImage &target, MatchingPointList &matchingPoints, int matchPercentage = 70, int maximumMatches = 10, int downPyrs = 2, - int searchExpansion = 15); + int searchExpansion = 15, + AlgorithmMethod method = CorrelationCoefficientMethod); void cancelSearch(); AlgorithmError error() const { return mError; } @@ -124,7 +134,7 @@ void finished(); private: - bool checkInputImages(const cv::Mat &source, const cv::Mat &target); + bool checkInputImages(const QList &sources, const cv::Mat &target); /*============================================================================= FastMatchTemplate @@ -148,17 +158,19 @@ with +/- searchExpansion pixels in both the x and y directions */ - MatchingPointList fastMatchTemplate(const cv::Mat &source, + MatchingPointList fastMatchTemplate(const QList &sources, const cv::Mat &target, - int matchPercentage, - int maximumMatches, - int downPyrs, - int searchExpansion); - - QVector multipleMaxLoc(const cv::Mat &image, int maximumMatches) const; - - QImage toQImage(const cv::Mat &image) const; - cv::Mat toCVMat(const QImage &image) const; + int matchPercentage, + int maximumMatches, + int downPyrs, + int searchExpansion, + AlgorithmMethod method); + + static QVector multipleMinMaxLoc(const cv::Mat &image, int maximumMatches, AlgorithmMethod method); + + static QImage toQImage(const cv::Mat &image); + static cv::Mat toCVMat(const QImage &image); + static int toOpenCVMethod(AlgorithmMethod method); AlgorithmError mError; QString mErrorString; diff -Nru actionaz-3.6.2/actiontools/parametercontainer.h actionaz-3.7.0/actiontools/parametercontainer.h --- actionaz-3.6.2/actiontools/parametercontainer.h 1970-01-01 00:00:00.000000000 +0000 +++ actionaz-3.7.0/actiontools/parametercontainer.h 2013-06-27 21:41:48.000000000 +0000 @@ -0,0 +1,46 @@ +/* + Actionaz + Copyright (C) 2008-2013 Jonathan Mercier-Ganady + + Actionaz is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Actionaz is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contact : jmgr@jmgr.info +*/ + +#ifndef PARAMETERCONTAINER_H +#define PARAMETERCONTAINER_H + +#include "actiontools_global.h" + +class QMenu; +class QWidget; + +namespace ActionTools +{ + class ACTIONTOOLSSHARED_EXPORT ParameterContainer + { + public: + ParameterContainer() + { + } + + virtual ~ParameterContainer() + { + } + + virtual QMenu *createVariablesMenu(QWidget *parent) const = 0; + }; +} + +#endif // PARAMETERCONTAINER_H diff -Nru actionaz-3.6.2/actiontools/parameterdefinition.cpp actionaz-3.7.0/actiontools/parameterdefinition.cpp --- actionaz-3.6.2/actiontools/parameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/parameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -25,8 +25,8 @@ namespace ActionTools { - ParameterDefinition::ParameterDefinition(const Name &name, QObject *parent) - : ElementDefinition(name, parent), + ParameterDefinition::ParameterDefinition(const Name &name, QObject *parent) + : ElementDefinition(name, parent), mOperatingSystems(WorksOnGnuLinux | WorksOnWindows | WorksOnMac), diff -Nru actionaz-3.6.2/actiontools/parameterdefinition.h actionaz-3.7.0/actiontools/parameterdefinition.h --- actionaz-3.6.2/actiontools/parameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/parameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -40,25 +40,29 @@ Q_OBJECT public: - ParameterDefinition(const Name &name, QObject *parent = 0); - virtual ~ParameterDefinition() {} + ParameterDefinition(const Name &name, QObject *parent = 0); + virtual ~ParameterDefinition() {} virtual void buildEditors(Script *script, QWidget *parent); virtual void load(const ActionInstance *actionInstance) = 0; virtual void save(ActionInstance *actionInstance) = 0; virtual void setDefaultValues(ActionInstance *actionInstance); - virtual Qt::Orientation editorsOrientation() const { return Qt::Horizontal; } + virtual Qt::Orientation editorsOrientation() const { return Qt::Horizontal; } - const QList &editors() const { return mEditors; } - Flag operatingSystems() const { return mOperatingSystems; } + const QList &editors() const { return mEditors; } + Flag operatingSystems() const { return mOperatingSystems; } virtual QVariant defaultValue(QVariant defaultValue = QVariant()) const; - virtual void setDefaultValue(const QVariant &defaultValue) { mDefaultValue = defaultValue; } - virtual void setOperatingSystems(Flag operatingSystems) { mOperatingSystems = operatingSystems; } + virtual void setDefaultValue(const QVariant &defaultValue) { mDefaultValue = defaultValue; } + virtual void setOperatingSystems(Flag operatingSystems) { mOperatingSystems = operatingSystems; } - virtual void update(Script *script) { Q_UNUSED(script) } + //Called when the action is edited + virtual void actionUpdate(Script *script) { Q_UNUSED(script) } - QWidget *parentWidget() { return mParentWidget; } + QWidget *parentWidget() { return mParentWidget; } + + signals: + void changed(); protected: void addEditor(QWidget *editor); diff -Nru actionaz-3.6.2/actiontools/pointlistparameterdefinition.cpp actionaz-3.7.0/actiontools/pointlistparameterdefinition.cpp --- actionaz-3.6.2/actiontools/pointlistparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/pointlistparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -25,8 +25,8 @@ namespace ActionTools { - PointListParameterDefinition::PointListParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + PointListParameterDefinition::PointListParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mPointListWidget(0) { } diff -Nru actionaz-3.6.2/actiontools/pointlistparameterdefinition.h actionaz-3.7.0/actiontools/pointlistparameterdefinition.h --- actionaz-3.6.2/actiontools/pointlistparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/pointlistparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -33,7 +33,7 @@ Q_OBJECT public: - PointListParameterDefinition(const Name &name, QObject *parent); + PointListParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); diff -Nru actionaz-3.6.2/actiontools/positionedit.cpp actionaz-3.7.0/actiontools/positionedit.cpp --- actionaz-3.6.2/actiontools/positionedit.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/positionedit.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -74,8 +74,18 @@ void PositionEdit::setCompletionModel(QAbstractItemModel *completionModel) { - codeLineEdit()->setCompletionModel(completionModel); - } + codeLineEdit()->setCompletionModel(completionModel); + } + + void PositionEdit::setParameterContainer(const ParameterContainer *parameterContainer) + { + codeLineEdit()->setParameterContainer(parameterContainer); + } + + QSet PositionEdit::findVariables() const + { + return codeLineEdit()->findVariables(); + } void PositionEdit::setPosition(QPoint position) { diff -Nru actionaz-3.6.2/actiontools/positionedit.h actionaz-3.7.0/actiontools/positionedit.h --- actionaz-3.6.2/actiontools/positionedit.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/positionedit.h 2013-06-27 21:41:48.000000000 +0000 @@ -52,6 +52,8 @@ void setFromSubParameter(const SubParameter &subParameter); void openEditor(int line = -1, int column = -1); void setCompletionModel(QAbstractItemModel *completionModel); + void setParameterContainer(const ParameterContainer *parameterContainer); + QSet findVariables() const; signals: void positionChosen(QPoint position); diff -Nru actionaz-3.6.2/actiontools/positionparameterdefinition.cpp actionaz-3.7.0/actiontools/positionparameterdefinition.cpp --- actionaz-3.6.2/actiontools/positionparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/positionparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -24,8 +24,8 @@ namespace ActionTools { - PositionParameterDefinition::PositionParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + PositionParameterDefinition::PositionParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mPositionEdit(0) { } diff -Nru actionaz-3.6.2/actiontools/positionparameterdefinition.h actionaz-3.7.0/actiontools/positionparameterdefinition.h --- actionaz-3.6.2/actiontools/positionparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/positionparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -32,7 +32,7 @@ { Q_OBJECT public: - PositionParameterDefinition(const Name &name, QObject *parent); + PositionParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); diff -Nru actionaz-3.6.2/actiontools/procedureparameterdefinition.cpp actionaz-3.7.0/actiontools/procedureparameterdefinition.cpp --- actionaz-3.6.2/actiontools/procedureparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/procedureparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -39,7 +39,7 @@ emit editorBuilt(); } - void ProcedureParameterDefinition::update(Script *script) + void ProcedureParameterDefinition::actionUpdate(Script *script) { mComboBox->clear(); mComboBox->addItems(script->procedureNames()); diff -Nru actionaz-3.6.2/actiontools/procedureparameterdefinition.h actionaz-3.7.0/actiontools/procedureparameterdefinition.h --- actionaz-3.6.2/actiontools/procedureparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/procedureparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -31,11 +31,11 @@ Q_OBJECT public: - ProcedureParameterDefinition(const Name &name, QObject *parent) - : ListParameterDefinition(name, parent) {} + ProcedureParameterDefinition(const Name &name, QObject *parent) + : ListParameterDefinition(name, parent) {} void buildEditors(Script *script, QWidget *parent); - void update(Script *script); + void actionUpdate(Script *script); }; } diff -Nru actionaz-3.6.2/actiontools/screenshooter.cpp actionaz-3.7.0/actiontools/screenshooter.cpp --- actionaz-3.6.2/actiontools/screenshooter.cpp 1970-01-01 00:00:00.000000000 +0000 +++ actionaz-3.7.0/actiontools/screenshooter.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -0,0 +1,99 @@ +/* + Actionaz + Copyright (C) 2008-2013 Jonathan Mercier-Ganady + + Actionaz is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Actionaz is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contact : jmgr@jmgr.info +*/ + +#include "screenshooter.h" +#include "windowhandle.h" + +#include +#include +#include +#include + +#include + +namespace ActionTools +{ + QList< QPair > ScreenShooter::captureScreens() + { + QDesktopWidget *desktop = QApplication::desktop(); + QList< QPair > result; + + for(int screenIndex = 0; screenIndex < desktop->screenCount(); ++screenIndex) + { + const QRect &screenGeometry = desktop->screenGeometry(screenIndex); + + result.append(qMakePair(QPixmap::grabWindow(desktop->winId(), screenGeometry.x(), screenGeometry.y(), screenGeometry.width(), screenGeometry.height()), screenGeometry)); + } + + return result; + } + + QList > ScreenShooter::captureWindows(const QList &windows) + { + QDesktopWidget *desktop = QApplication::desktop(); + QList< QPair > result; + + foreach(const WindowHandle &window, windows) + { + if(!window.isValid()) + continue; + + const QRect &windowGeometry = window.rect(); + + result.append(qMakePair(QPixmap::grabWindow(desktop->winId(), windowGeometry.x(), windowGeometry.y(), windowGeometry.width(), windowGeometry.height()), windowGeometry)); + } + + return result; + } + + QPixmap ScreenShooter::captureScreen() + { + const QList< QPair > &screens = captureScreens(); + QRect resultRect; + QPoint minimalTopLeft(std::numeric_limits::max(), std::numeric_limits::max()); + + typedef QPair PixmapRectPair; + foreach(const PixmapRectPair &screen, screens) + { + const QRect &screenRect = screen.second; + + resultRect = resultRect.united(screenRect); + + if(minimalTopLeft.x() > screenRect.x()) + minimalTopLeft.setX(screenRect.x()); + if(minimalTopLeft.y() > screenRect.y()) + minimalTopLeft.setY(screenRect.y()); + } + + QImage result(resultRect.width(), resultRect.height(), QImage::Format_RGB32); + { + QPainter painter(&result); + + foreach(const PixmapRectPair &screen, screens) + { + const QRect &screenRect = screen.second; + + painter.drawPixmap(screenRect.x() - minimalTopLeft.x(), screenRect.y() - minimalTopLeft.y(), screen.first); + } + } + + return QPixmap::fromImage(result); + } +} diff -Nru actionaz-3.6.2/actiontools/screenshooter.h actionaz-3.7.0/actiontools/screenshooter.h --- actionaz-3.6.2/actiontools/screenshooter.h 1970-01-01 00:00:00.000000000 +0000 +++ actionaz-3.7.0/actiontools/screenshooter.h 2013-06-27 21:41:48.000000000 +0000 @@ -0,0 +1,46 @@ +/* + Actionaz + Copyright (C) 2008-2013 Jonathan Mercier-Ganady + + Actionaz is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Actionaz is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contact : jmgr@jmgr.info +*/ + +#ifndef SCREENSHOOTER_H +#define SCREENSHOOTER_H + +#include "actiontools_global.h" + +#include +#include +#include + +namespace ActionTools +{ + class WindowHandle; + + class ACTIONTOOLSSHARED_EXPORT ScreenShooter + { + public: + static QList< QPair > captureScreens(); + static QList< QPair > captureWindows(const QList &windows); + static QPixmap captureScreen(); + + private: + ScreenShooter(); + }; +} + +#endif // SCREENSHOOTER_H diff -Nru actionaz-3.6.2/actiontools/script.cpp actionaz-3.7.0/actiontools/script.cpp --- actionaz-3.6.2/actiontools/script.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/script.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -21,10 +21,13 @@ #include "script.h" #include "actioninstance.h" #include "actiondefinition.h" +#include "elementdefinition.h" #include "actionfactory.h" #include "parameter.h" #include "subparameter.h" #include "messagehandler.h" +#include "variableparameterdefinition.h" +#include "groupdefinition.h" #include #include @@ -35,6 +38,8 @@ namespace ActionTools { + const QRegExp Script::CodeVariableDeclarationRegExp("^[ \t]*var ([A-Za-z_][A-Za-z0-9_]*)", Qt::CaseSensitive, QRegExp::RegExp2); + Script::Script(ActionFactory *actionFactory, QObject *parent) : QObject(parent), mActionFactory(actionFactory), @@ -370,7 +375,7 @@ mOs = attributes.value("os").toString(); if(mScriptVersion > scriptVersion) - return ReadBadScriptVersion; + return ReadInvalidScriptVersion; } } @@ -378,7 +383,7 @@ mLine = messageHandler.line(); mColumn = messageHandler.column(); - return ReadBadSchema; + return ReadInvalidSchema; } } @@ -392,6 +397,8 @@ Tools::HighResolutionTimer timer2("Reading content"); #endif + QHash updatableActionDefinitions; + QXmlStreamReader stream(device); while(!stream.atEnd() && !stream.hasError()) { @@ -412,7 +419,7 @@ mOs = attributes.value("os").toString(); if(mScriptVersion > scriptVersion) - return ReadBadScriptVersion; + return ReadInvalidScriptVersion; } else if(stream.name() == "actions") { @@ -425,11 +432,13 @@ const QXmlStreamAttributes &attributes = stream.attributes(); QString name = attributes.value("name").toString(); - //TODO : Do something with the action version + Tools::Version version(attributes.value("version").toString()); ActionDefinition *actionDefinition = mActionFactory->actionDefinition(name); if(!actionDefinition) mMissingActions << name; + else if(actionDefinition->version() > version) + updatableActionDefinitions[actionDefinition] = version; } } else if(stream.name() == "parameters") @@ -524,9 +533,18 @@ } } + //Set default values, will be overwritten afterwards, but this is done to make sure we have valid parameters everywhere + foreach(ElementDefinition *element, actionInstance->definition()->elements()) + element->setDefaultValues(actionInstance); + actionInstance->setLabel(label); actionInstance->setComment(comment); - actionInstance->setParametersData(parametersData); + + ParametersData defaultParametersData = actionInstance->parametersData(); + foreach(const QString ¶meterKey, parametersData.keys()) + defaultParametersData[parameterKey] = parametersData.value(parameterKey); + + actionInstance->setParametersData(defaultParametersData); actionInstance->setColor(color); actionInstance->setEnabled(enabled); actionInstance->setExceptionActionInstances(exceptionActionsHash); @@ -539,6 +557,15 @@ } } + foreach(ActionDefinition *actionDefinition, updatableActionDefinitions.keys()) + { + foreach(ActionInstance *actionInstance, mActionInstances) + { + if(actionInstance->definition() == actionDefinition) + actionDefinition->updateAction(actionInstance, updatableActionDefinitions.value(actionDefinition)); + } + } + return ReadSuccess; } @@ -616,6 +643,110 @@ back << actionInstance->label(); } - return back; - } + return back; + } + + QSet Script::findVariables(ActionInstance *actionInstance, ActionInstance *excludedActionInstance) const + { + QSet back; + + if(actionInstance) + { + if(actionInstance != excludedActionInstance) + findVariablesInAction(actionInstance, back); + } + else + { + foreach(const ScriptParameter &scriptParameter, mParameters) + { + if(!scriptParameter.name().isEmpty()) + back << scriptParameter.name(); + } + + foreach(ActionInstance *currentActionInstance, mActionInstances) + { + if(currentActionInstance != excludedActionInstance) + findVariablesInAction(currentActionInstance, back); + } + } + + return back; + } + + void Script::parametersFromDefinition(QSet &variables, const ActionInstance *actionInstance, const ElementDefinition *elementDefinition) const + { + const Parameter ¶meter = actionInstance->parameter(elementDefinition->name().original()); + const SubParameterHash &subParameters = parameter.subParameters(); + + SubParameterHash::ConstIterator it = subParameters.constBegin(); + for(;it != subParameters.constEnd();++it) + { + const SubParameter &subParameter = it.value(); + + if(subParameter.isCode()) + { + //Add every variable in any parameter type that is in code mode + const QString &code = subParameter.value().toString(); + + foreach(const QString &codeLine, code.split(QRegExp("[\n\r;]"), QString::SkipEmptyParts)) + { + int position = 0; + + while((position = CodeVariableDeclarationRegExp.indexIn(codeLine, position)) != -1) + { + QString foundVariableName = CodeVariableDeclarationRegExp.cap(1); + + position += CodeVariableDeclarationRegExp.cap(1).length(); + + if(!foundVariableName.isEmpty()) + variables << foundVariableName; + } + } + } + else + { + //Add every variable in a variable parameter that is not in code mode + if(qobject_cast(elementDefinition)) + { + const QString &foundVariableName = subParameter.value().toString(); + + if(!foundVariableName.isEmpty()) + variables << foundVariableName; + + continue; + } + + //Add every variable in any parameter type that is not in code mode + const QString &text = subParameter.value().toString(); + + int position = 0; + + while((position = ActionInstance::VariableRegExp.indexIn(text, position)) != -1) + { + QString foundVariableName = ActionInstance::VariableRegExp.cap(2); + + position += ActionInstance::VariableRegExp.cap(0).length(); + + if(!foundVariableName.isEmpty()) + variables << foundVariableName; + } + } + } + } + + void Script::findVariablesInAction(ActionInstance *actionInstance, QSet &result) const + { + const ActionDefinition *actionDefinition = actionInstance->definition(); + + foreach(const ElementDefinition *elementDefinition, actionDefinition->elements()) + { + if(const GroupDefinition *groupDefinition = qobject_cast(elementDefinition)) + { + foreach(const ParameterDefinition *parameterDefinition, groupDefinition->members()) + parametersFromDefinition(result, actionInstance, parameterDefinition); + } + else + parametersFromDefinition(result, actionInstance, elementDefinition); + } + } } diff -Nru actionaz-3.6.2/actiontools/script.h actionaz-3.7.0/actiontools/script.h --- actionaz-3.6.2/actiontools/script.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/script.h 2013-06-27 21:41:48.000000000 +0000 @@ -36,6 +36,7 @@ { class ActionInstance; class ActionFactory; + class ElementDefinition; class ACTIONTOOLSSHARED_EXPORT Script : public QObject { @@ -46,10 +47,12 @@ { ReadSuccess, // Ok ReadInternal, // Internal error - ReadBadSchema, // Did not pass schema validation - ReadBadScriptVersion // Script version is newer than ours + ReadInvalidSchema, // Did not pass schema validation + ReadInvalidScriptVersion // Script version is newer than ours }; + static const QRegExp CodeVariableDeclarationRegExp; + Script(ActionFactory *actionFactory, QObject *parent = 0); ~Script(); @@ -103,8 +106,12 @@ int actionIndexFromRuntimeId(qint64 runtimeId) const; QStringList procedureNames() const; QStringList labels() const; + QSet findVariables(ActionInstance *actionInstance = 0, ActionInstance *excludedActionInstance = 0) const; private: + void parametersFromDefinition(QSet &variables, const ActionInstance *actionInstance, const ActionTools::ElementDefinition *elementDefinition) const; + void findVariablesInAction(ActionInstance *actionInstance, QSet &result) const; + QList mParameters; QList mActionInstances; ActionFactory *mActionFactory; diff -Nru actionaz-3.6.2/actiontools/textparameterdefinition.cpp actionaz-3.7.0/actiontools/textparameterdefinition.cpp --- actionaz-3.6.2/actiontools/textparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/textparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -27,8 +27,8 @@ namespace ActionTools { - TextParameterDefinition::TextParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + TextParameterDefinition::TextParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mTextCodeMode(TextAndCode), mLineEdit(0) { diff -Nru actionaz-3.6.2/actiontools/textparameterdefinition.h actionaz-3.7.0/actiontools/textparameterdefinition.h --- actionaz-3.6.2/actiontools/textparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/textparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -40,7 +40,7 @@ TextAndCode }; - TextParameterDefinition(const Name &name, QObject *parent); + TextParameterDefinition(const Name &name, QObject *parent); virtual ~TextParameterDefinition() {} virtual void buildEditors(Script *script, QWidget *parent); diff -Nru actionaz-3.6.2/actiontools/variablelineedit.cpp actionaz-3.7.0/actiontools/variablelineedit.cpp --- actionaz-3.6.2/actiontools/variablelineedit.cpp 1970-01-01 00:00:00.000000000 +0000 +++ actionaz-3.7.0/actiontools/variablelineedit.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -0,0 +1,50 @@ +/* + Actionaz + Copyright (C) 2008-2013 Jonathan Mercier-Ganady + + Actionaz is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Actionaz is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contact : jmgr@jmgr.info +*/ + +#include "variablelineedit.h" +#include "actioninstance.h" + +#include + +namespace ActionTools +{ + VariableLineEdit::VariableLineEdit(QWidget *parent) + : CodeLineEdit(parent, ActionInstance::NameRegExp) + { + } + + QSet VariableLineEdit::findVariables() const + { + QSet back = CodeLineEdit::findVariables(); + + if(!isCode() && !text().isEmpty()) + back.insert(text()); + + return back; + } + + void VariableLineEdit::insertVariable(const QString &variable) + { + if(isCode()) + insert(variable); + else + setText(variable); + } +} diff -Nru actionaz-3.6.2/actiontools/variablelineedit.h actionaz-3.7.0/actiontools/variablelineedit.h --- actionaz-3.6.2/actiontools/variablelineedit.h 1970-01-01 00:00:00.000000000 +0000 +++ actionaz-3.7.0/actiontools/variablelineedit.h 2013-06-27 21:41:48.000000000 +0000 @@ -0,0 +1,42 @@ +/* + Actionaz + Copyright (C) 2008-2013 Jonathan Mercier-Ganady + + Actionaz is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Actionaz is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Contact : jmgr@jmgr.info +*/ + +#ifndef VARIABLELINEEDIT_H +#define VARIABLELINEEDIT_H + +#include "codelineedit.h" + +namespace ActionTools +{ + class VariableLineEdit : public CodeLineEdit + { + Q_OBJECT + + public: + explicit VariableLineEdit(QWidget *parent); + + QSet findVariables() const; + + protected: + virtual void insertVariable(const QString &variable); + }; +} + +#endif // VARIABLELINEEDIT_H diff -Nru actionaz-3.6.2/actiontools/variableparameterdefinition.cpp actionaz-3.7.0/actiontools/variableparameterdefinition.cpp --- actionaz-3.6.2/actiontools/variableparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/variableparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -19,7 +19,7 @@ */ #include "variableparameterdefinition.h" -#include "codelineedit.h" +#include "variablelineedit.h" #include "script.h" namespace ActionTools @@ -28,11 +28,8 @@ { ParameterDefinition::buildEditors(script, parent); - mLineEdit = new CodeLineEdit(parent, QRegExp("^[A-Za-z_][A-Za-z0-9_]*$")); + mLineEdit = new VariableLineEdit(parent); - //TODO - //Do nothing special here for now, but later we could add a variable list - - addEditor(mLineEdit); - } + addEditor(mLineEdit); + } } diff -Nru actionaz-3.6.2/actiontools/variableparameterdefinition.h actionaz-3.7.0/actiontools/variableparameterdefinition.h --- actionaz-3.6.2/actiontools/variableparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/variableparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -26,18 +26,18 @@ namespace ActionTools { - class ACTIONTOOLSSHARED_EXPORT VariableParameterDefinition : public TextParameterDefinition + class ACTIONTOOLSSHARED_EXPORT VariableParameterDefinition : public TextParameterDefinition { Q_OBJECT public: - VariableParameterDefinition(const Name &name, QObject *parent) - : TextParameterDefinition(name, parent) + VariableParameterDefinition(const Name &name, QObject *parent) + : TextParameterDefinition(name, parent) { setCategory(OUTPUT); } - void buildEditors(Script *script, QWidget *parent); + void buildEditors(Script *script, QWidget *parent); }; } diff -Nru actionaz-3.6.2/actiontools/widgets.pri actionaz-3.7.0/actiontools/widgets.pri --- actionaz-3.6.2/actiontools/widgets.pri 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/widgets.pri 2013-06-27 21:41:48.000000000 +0000 @@ -27,7 +27,9 @@ switchtextmodepushbutton.cpp \ itemlistwidget.cpp \ itemlistview.cpp \ - itemlistmodel.cpp + itemlistmodel.cpp \ + codelineeditbutton.cpp \ + variablelineedit.cpp HEADERS += codelineedit.h \ codecombobox.h \ codespinbox.h \ @@ -50,4 +52,6 @@ switchtextmodepushbutton.h \ itemlistwidget.h \ itemlistview.h \ - itemlistmodel.h + itemlistmodel.h \ + codelineeditbutton.h \ + variablelineedit.h diff -Nru actionaz-3.6.2/actiontools/windowedit.cpp actionaz-3.7.0/actiontools/windowedit.cpp --- actionaz-3.6.2/actiontools/windowedit.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/windowedit.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -74,8 +74,18 @@ void WindowEdit::setCompletionModel(QAbstractItemModel *completionModel) { - codeLineEdit()->setCompletionModel(completionModel); - } + codeLineEdit()->setCompletionModel(completionModel); + } + + void WindowEdit::setParameterContainer(const ParameterContainer *parameterContainer) + { + codeLineEdit()->setParameterContainer(parameterContainer); + } + + QSet WindowEdit::findVariables() const + { + return codeLineEdit()->findVariables(); + } void WindowEdit::setWindowTitles(const QStringList &windowTitles) { diff -Nru actionaz-3.6.2/actiontools/windowedit.h actionaz-3.7.0/actiontools/windowedit.h --- actionaz-3.6.2/actiontools/windowedit.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/windowedit.h 2013-06-27 21:41:48.000000000 +0000 @@ -53,6 +53,8 @@ void setFromSubParameter(const SubParameter &subParameter); void openEditor(int line = -1, int column = -1); void setCompletionModel(QAbstractItemModel *completionModel); + void setParameterContainer(const ParameterContainer *parameterContainer); + QSet findVariables() const; void setWindowTitles(const QStringList &windowTitles); private slots: diff -Nru actionaz-3.6.2/actiontools/windowparameterdefinition.cpp actionaz-3.7.0/actiontools/windowparameterdefinition.cpp --- actionaz-3.6.2/actiontools/windowparameterdefinition.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/windowparameterdefinition.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -26,8 +26,8 @@ namespace ActionTools { - WindowParameterDefinition::WindowParameterDefinition(const Name &name, QObject *parent) - : ParameterDefinition(name, parent), + WindowParameterDefinition::WindowParameterDefinition(const Name &name, QObject *parent) + : ParameterDefinition(name, parent), mWindowEdit(0) { } @@ -51,7 +51,7 @@ actionInstance->setSubParameter(name().original(), "value", mWindowEdit->isCode(), mWindowEdit->text()); } - void WindowParameterDefinition::update(Script *script) + void WindowParameterDefinition::actionUpdate(Script *script) { Q_UNUSED(script) diff -Nru actionaz-3.6.2/actiontools/windowparameterdefinition.h actionaz-3.7.0/actiontools/windowparameterdefinition.h --- actionaz-3.6.2/actiontools/windowparameterdefinition.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/actiontools/windowparameterdefinition.h 2013-06-27 21:41:48.000000000 +0000 @@ -33,12 +33,12 @@ Q_OBJECT public: - WindowParameterDefinition(const Name &name, QObject *parent); + WindowParameterDefinition(const Name &name, QObject *parent); void buildEditors(Script *script, QWidget *parent); void load(const ActionInstance *actionInstance); void save(ActionInstance *actionInstance); - void update(Script *script); + void actionUpdate(Script *script); private: WindowEdit *mWindowEdit; diff -Nru actionaz-3.6.2/common.pri actionaz-3.7.0/common.pri --- actionaz-3.6.2/common.pri 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/common.pri 2013-06-27 21:41:48.000000000 +0000 @@ -1,7 +1,7 @@ DEFINES += QT_USE_FAST_CONCATENATION \ QT_USE_FAST_OPERATOR_PLUS -ACTIONAZ_VERSION = 3.6.2 +ACTIONAZ_VERSION = 3.7.0 SCRIPT_VERSION = 1.0.0 DEFINES *= ACT_VERSION=$$ACTIONAZ_VERSION diff -Nru actionaz-3.6.2/debian/changelog actionaz-3.7.0/debian/changelog --- actionaz-3.6.2/debian/changelog 2013-06-15 15:23:24.000000000 +0000 +++ actionaz-3.7.0/debian/changelog 2013-08-27 09:21:24.000000000 +0000 @@ -1,3 +1,9 @@ +actionaz (3.7.0-0ubuntu1) saucy; urgency=low + + * New upstream release + + -- Adrien Cunin Tue, 27 Aug 2013 11:21:16 +0200 + actionaz (3.6.2-1) unstable; urgency=low * New upstream release diff -Nru actionaz-3.6.2/executer/executer.cpp actionaz-3.7.0/executer/executer.cpp --- actionaz-3.6.2/executer/executer.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/executer/executer.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -24,6 +24,7 @@ #include "executionwindow.h" #include "codeinitializer.h" #include "actiondefinition.h" +#include "actionexception.h" #include "scriptagent.h" #include "actioninstance.h" #include "code/codetools.h" @@ -48,7 +49,8 @@ mScriptEngine(0), mScriptAgent(0), mHasExecuted(false), - mPauseInterrupt(false) + mPauseInterrupt(false), + mShowDebuggerOnCodeError(true) { connect(mExecutionWindow, SIGNAL(canceled()), this, SLOT(stopExecution())); connect(mExecutionWindow, SIGNAL(paused()), this, SLOT(pauseExecution())); @@ -243,7 +245,8 @@ QScriptValue script = mScriptEngine->newObject(); mScriptEngine->globalObject().setProperty("Script", script, QScriptValue::ReadOnly); - script.setProperty("nextLine", mScriptEngine->newVariant(QVariant(1))); + script.setProperty("nextLine", 1); + script.setProperty("line", 1, QScriptValue::ReadOnly); QScriptValue console = mScriptEngine->newObject(); mScriptEngine->globalObject().setProperty("Console", console, QScriptValue::ReadOnly); @@ -786,8 +789,13 @@ { mExecutionPaused = true; - if(!mPauseInterrupt) - mDebuggerWindow->show(); + if(!mPauseInterrupt) + { + if(mShowDebuggerOnCodeError) + mDebuggerWindow->show(); + else + mScriptEngineDebugger.action(QScriptEngineDebugger::ContinueAction)->trigger(); + } else mPauseInterrupt = false; } @@ -926,15 +934,20 @@ return; } - int nextLine = mCurrentActionIndex+2; + 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()); diff -Nru actionaz-3.6.2/executer/executer.h actionaz-3.7.0/executer/executer.h --- actionaz-3.6.2/executer/executer.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/executer/executer.h 2013-06-27 21:41:48.000000000 +0000 @@ -165,6 +165,7 @@ Tools::Version mActionazVersion; Tools::Version mScriptVersion; bool mIsActExec; + bool mShowDebuggerOnCodeError; Q_DISABLE_COPY(Executer) }; diff -Nru actionaz-3.6.2/gui/actiondialog.cpp actionaz-3.7.0/gui/actiondialog.cpp --- actionaz-3.6.2/gui/actiondialog.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/gui/actiondialog.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -294,7 +295,33 @@ ActionDialog::~ActionDialog() { - delete ui; + delete ui; +} + +QMenu *ActionDialog::createVariablesMenu(QWidget *parent) const +{ + QSet thisActionsVariables; + foreach(ActionTools::ParameterDefinition *parameter, mParameters) + { + foreach(QWidget *editor, parameter->editors()) + { + if(ActionTools::AbstractCodeEditor *codeEditor = dynamic_cast(editor)) + thisActionsVariables.unite(codeEditor->findVariables()); + } + } + + QStringList variableList = thisActionsVariables.unite(mOtherActionsVariables).toList(); + qSort(variableList); + + if(variableList.isEmpty()) + return 0; + + QMenu *back = new QMenu(parent); + + foreach(const QString &variable, variableList) + back->addAction(variable); + + return back; } void ActionDialog::accept() @@ -357,9 +384,11 @@ #ifdef ACT_PROFILE Tools::HighResolutionTimer timer("ActionDialog postInit"); #endif + mOtherActionsVariables = mScript->findVariables(0, mActionInstance);//Find in all actions except this one + foreach(ActionTools::ParameterDefinition *parameter, mParameters) { - parameter->update(mScript); + parameter->actionUpdate(mScript); parameter->load(mActionInstance); } @@ -465,7 +494,7 @@ if(!widget) return; - widget->setEnabled(exceptionAction == ActionTools::ActionException::GotoLineExceptionAction); + widget->setEnabled(exceptionAction == ActionTools::ActionException::GotoLineExceptionAction); } void ActionDialog::addParameter(ActionTools::ParameterDefinition *parameter, int tab) @@ -493,7 +522,10 @@ foreach(QWidget *editor, parameter->editors()) { if(ActionTools::AbstractCodeEditor *codeEditor = dynamic_cast(editor)) + { codeEditor->setCompletionModel(mCompletionModel); + codeEditor->setParameterContainer(this); + } layout->addWidget(editor); } diff -Nru actionaz-3.6.2/gui/actiondialog.h actionaz-3.7.0/gui/actiondialog.h --- actionaz-3.6.2/gui/actiondialog.h 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/gui/actiondialog.h 2013-06-27 21:41:48.000000000 +0000 @@ -21,9 +21,12 @@ #ifndef ACTIONDIALOG_H #define ACTIONDIALOG_H +#include "parametercontainer.h" + #include #include #include +#include namespace Ui { @@ -46,7 +49,7 @@ class QSpinBox; class QTranslator; -class ActionDialog : public QDialog +class ActionDialog : public QDialog, public ActionTools::ParameterContainer { Q_OBJECT @@ -54,6 +57,8 @@ ActionDialog(QAbstractItemModel *completionModel, ActionTools::Script *script, ActionTools::ActionDefinition *actionDefinition, const QString &localeName, QWidget *parent = 0); ~ActionDialog(); + virtual QMenu *createVariablesMenu(QWidget *parent) const; + public slots: void accept(); int exec(ActionTools::ActionInstance *actionInstance, const QString &field, const QString &subField, int currentLine, int currentColumn); @@ -91,6 +96,7 @@ QSpinBox *mPauseBeforeSpinBox; QSpinBox *mPauseAfterSpinBox; QSpinBox *mTimeoutSpinBox; + QSet mOtherActionsVariables; Q_DISABLE_COPY(ActionDialog) }; diff -Nru actionaz-3.6.2/gui/mainwindow.cpp actionaz-3.7.0/gui/mainwindow.cpp --- actionaz-3.6.2/gui/mainwindow.cpp 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/gui/mainwindow.cpp 2013-06-27 21:41:48.000000000 +0000 @@ -1252,7 +1252,7 @@ case ActionTools::Script::ReadInternal: QMessageBox::warning(this, tr("Load script"), tr("Unable to load the script due to an internal error.")); return false; - case ActionTools::Script::ReadBadSchema: + case ActionTools::Script::ReadInvalidSchema: { QMessageBox messageBox(tr("Load script"), tr("Unable to load the script because it has an incorrect schema.%1Line: %2
Column: %3") .arg(mScript->statusMessage()) @@ -1262,7 +1262,7 @@ messageBox.exec(); } return false; - case ActionTools::Script::ReadBadScriptVersion: + case ActionTools::Script::ReadInvalidScriptVersion: QMessageBox::warning(this, tr("Load script"), tr("Unable to load the script because it was created with a more recent version of Actionaz.\nPlease update your version of Actionaz to load this script.\nYour version: %1\nScript version: %2") .arg(Global::SCRIPT_VERSION.toString()).arg(mScript->scriptVersion().toString())); return false; diff -Nru actionaz-3.6.2/locale/actexecuter_fr_FR.ts actionaz-3.7.0/locale/actexecuter_fr_FR.ts --- actionaz-3.6.2/locale/actexecuter_fr_FR.ts 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/locale/actexecuter_fr_FR.ts 2013-06-27 21:41:48.000000000 +0000 @@ -150,8 +150,12 @@ La lecture du script a échoué à cause d'une erreur interne - Input script file has a bad script schema + Le fichier d'entrée a un schéma incorrect + + + + Input script file has an invalid script schema Le fichier d'entrée a un schéma incorrect diff -Nru actionaz-3.6.2/locale/actionpackdata_fr_FR.ts actionaz-3.7.0/locale/actionpackdata_fr_FR.ts --- actionaz-3.6.2/locale/actionpackdata_fr_FR.ts 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/locale/actionpackdata_fr_FR.ts 2013-06-27 21:41:48.000000000 +0000 @@ -174,62 +174,76 @@ Actions::ReadIniFileDefinition - + File Fichier - + The file to read from Le fichier à lire - + Choose the INI file Choisissez le fichier INI - + INI files (*.ini);;All files (*.*) Fichiers INI (*.ini);;Tous les fichiers (*.*) - + + Mode + Mode + + + + The INI file read mode + Le mode de lecture du fichier INI + + + Section Section - The section name of the parameter - Le nom de section du paramètre + Le nom de section du paramètre - + Parameter Paramètre - + The parameter name Le nom du paramètre - + Variable Variable - + The variable where to store the data La variable où stocker les données - + + The parameter section + La section du paramètre + + + Unable to read file Impossible de lire le fichier - + Unable to find section Impossible de trouver la section @@ -237,12 +251,14 @@ Actions::ReadIniFileInstance - + + + Unable to read the file Impossible de lire le fichier - + Unable to find the section named "%1" Impossible de trouver la section nommée "%1" @@ -1127,14 +1143,18 @@ Lit le contenu du presse-papier - + Read INI file Lire fichier INI - + + Read one or all the entries in an INI file + Lire une ou plusieurs entrées d'un fichier INI + + Read an entry in an INI file - Lire une entrée dans un fichier INI + Lire une entrée dans un fichier INI @@ -1257,6 +1277,19 @@ + ReadIniFileInstance::modes + + + Read a single parameter + Line un seul paramètre + + + + Read the entire file + Lire le fichier complet + + + ReadTextFileInstance::modes diff -Nru actionaz-3.6.2/locale/actionpacksystem_fr_FR.ts actionaz-3.7.0/locale/actionpacksystem_fr_FR.ts --- actionaz-3.6.2/locale/actionpacksystem_fr_FR.ts 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/locale/actionpacksystem_fr_FR.ts 2013-06-27 21:41:48.000000000 +0000 @@ -12,92 +12,92 @@ Actions::CommandDefinition - + Command Commande - + The command to execute La commande à exécuter - + Parameters Paramètres - + The command's parameters Les paramètres de la commande - + Working directory Dossier de travail - + The command's working directory Le dossier de travail de la commande - + Command working directory Dossier de travail de la commande - + Exit code Code de sortie - + The command's exit code Le code de sortie de la commande - + Process id Identifiant de processus - + The command's process id L'identifiant de processus de la commande - + Output Sortie - + The command's output La sortie de la commande - + Error output Sortie d'erreur - + The command's error output La sortie d'erreur de la commande - + Exit status Statut de sortie - + The command's exit status Le statut de sortie de la commande - + Failed to start the command Impossible d'exécuter la commande @@ -113,52 +113,52 @@ Actions::DetachedCommandDefinition - + Command Commande - + The command to execute La commande à exécuter - + Parameters Paramètres - + The command's parameters Les paramètres de la commande - + Working directory Dossier de travail - + The command's working directory Le dossier de travail de la commande - + Command working directory Dossier de travail de la commande - + Process id Identifiant de processus - + The command's process id L'identifiant de processus de la commande - + Unable to execute the detached command Impossible d'exécuter la commande détachée @@ -174,192 +174,259 @@ Actions::FindImageDefinition - + Source Source - + The source of the image to search in La source de l'image où chercher - + Window name Titre de fenêtre - + The title of the window to search in, you can use wildcards like * (any number of characters) or ? (one character) here Le titre de la fenêtre où chercher, vous pouvez utiliser des wildcards ici comme * (n'importe quel nombre de caractères) ou ? (un caractère) - + Image to search in Image où chercher - + The image to search in L'image où chercher - - + + Choose an image file Choisissez un fichier image - - + + Image files (*.bmp *.gif *.jpg *.jpeg *.mng *.png *.pbm *.pgm *.ppm *.tiff *.xbm *.xpm *.svg) All files (*.*) Images (*.bmp *.gif *.jpg *.jpeg *.mng *.png *.pbm *.pgm *.ppm *.tiff *.xbm *.xpm *.svg) Tous les fichiers (*.*) - + Image to find Image à chercher - + The image to search for l'image à chercher - + + If found + Si trouvé + + + + What to do if the image is found + Ce qui doit être fait si l'image a été trouvée + + + + If not found + Si non trouvé + + + + What to do if the image is not found + Ce qui doit être fait si l'image n'a pas été trouvée + + + Position Position - + The name of the variable where to store the coordinates of the center of the found image Le nom de la variable où stocker les coordonnées du centre de l'image trouvée - + + Downsampling + Sous-échantillonnage + + + + The downsampling value to use +Downsampling is used to accelerate the search when using large images + La valeur de sous-échantillonnage à utiliser +Le sous-échantillonnage sert à accélérer la recherche lors d'une recherche sur de grandes images + + + Window relative position Position relative à la fenêtre - + The position is relative to the window If this parameter is set to false (not checked) then the position is absolute La position est-elle relative à la fenêtre Si ce paramètre est faux (non coché) alors la position est absolue - + + Method + Méthode + + + + The matching method to use + La méthode de recherche à utiliser + + + Confidence minimum Confiance minimale - + The minimum confidence percentage required to select a possible matching image Le pourcentage minimum de confiance nécessaire pour sélectionner un résultat possible - + Maximum matches Nombre maximum de résultats - + The maximum matching images count Setting this parameter higher will increase the duration of the search Le nombre maximum de résultats Choisir une valeur élevée pour ce paramètre va augmenter la durée de la recherche - Down pyramid count - Nombre de pyramides descendantes + Nombre de pyramides descendantes - The number of down pyramids to use A pyramid is a subdivision of the image used to accelerate the search Enter 1 here if the searched image is not very different from the source image - Le nombre de pyramides descendantes à utiliser + Le nombre de pyramides descendantes à utiliser Une pyramide est une subdivision de l'image utilisée pour accélérer la recherche Entrez 1 ici si l'image recherchée n'est pas très différente de l'image source - + Search expansion Expansion de la recherche - + The number of pixels to shift when searching for another matching image Le décalage en pixels à effectuer lors de la recherche d'une autre solution possible - + + Delay between two searches when waiting + Délai entre deux recherches lors d'une attente + + + + The delay between two searches + Le délai entre deux recherches lors d'une attente + + + + ms + milliseconds + ms + + + + Confidence + Confiance + + + + The name of the variable where to store the confidence value found image + Le nom de la variable où stocker la confiance en l'image trouvée + + + Error while searching Erreur lors de la recherche - Cannot find the image - Impossible de trouver l'image + Impossible de trouver l'image Actions::FindImageInstance - + minimum confidence confiance minimum - + maximum matches nombre maximum de résultats - down pyramid count - nombre de pyramides descendantes + nombre de pyramides descendantes + + + + downsampling + sous-échantillonnage - + search expansion expansion de la recherche - + Unable to load image to find from file %1 Impossible de charger l'image à trouver à partir du fichier %1 - + Unable to find any window named %1 Impossible de trouver une fenêtre nommée %1 - Unable to take a screenshot of the window named %1 - Impossible de prendre une capture d'écran de la fenêtre nommée %1 + Impossible de prendre une capture d'écran de la fenêtre nommée %1 - + Unable to load image to search in from file %1 Impossible de charger l'image où chercher à partir du fichier %1 - + Error while searching: %1 Erreur lors de la recherche : %1 - Cannot find the image - Impossible de trouver l'image + Impossible de trouver l'image - + Invalid %1 value : %2 Valeur %1 incorrecte : %2 @@ -491,85 +558,95 @@ Actions::PixelColorDefinition - + Pixel Pixel - + The pixel position and color to check La position et la couleur du pixel à vérifier - + Comparison Comparaison - + The comparison La comparaison - + If true Si vrai - + What to to if the pixel comparison is true Ce qui doit être fait si la comparaison de pixel est vraie - + If false Si faux - + What to to if the pixel comparison is false Ce qui doit être fait si la comparaison de pixel est fausse - + Pixel color variable Variable de la couleur de pixel - + Variable name where to store the pixel color Nom de la variable où stocker la couleur du pixel - + Red tolerance Tolérance du rouge - + The tolerance percentage for the red color component Le pourcentage de tolérance pour le composant rouge - + Green tolerance Tolérance du vert - + The tolerance percentage for the green color component Le pourcentage de tolérance pour le composant vert - + Blue tolerance Tolérance du bleu - + The tolerance percentage for the blue color component Le pourcentage de tolérance pour le composant bleu + + + Offset + Décalage + + + + The offset to apply to the pixel position + Le décalage à appliquer à la position du pixel + Actions::PlaySoundDefinition @@ -945,6 +1022,21 @@ Image Image + + + Correlation Coefficient + Coefficient de corrélation + + + + Cross Correlation + Corrélation croisée + + + + Squared Difference + Différence de carrés + KillProcessInstance::killModes @@ -985,12 +1077,12 @@ QObject - + Command Commande - + Executes a command Exécute une commande @@ -1015,12 +1107,12 @@ Affiche un message via le système de notifications - + Pixel color Couleur de pixel - + Check a pixel color on the screen Vérifie la couleur d'un pixel sur l'écran @@ -1093,12 +1185,12 @@ Ouvre une URL - + Detached command Commande détachée - + Executes a detached command Exécute une commande détachée @@ -1113,12 +1205,12 @@ Lit un son - + Find image Trouver image - + Finds an image on the screen, on a window or on another image Trouve une image sur l'écran, dans une fenêtre ou dans une autre image diff -Nru actionaz-3.6.2/locale/actiontools_fr_FR.ts actionaz-3.7.0/locale/actiontools_fr_FR.ts --- actionaz-3.6.2/locale/actiontools_fr_FR.ts 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/locale/actiontools_fr_FR.ts 2013-06-27 21:41:48.000000000 +0000 @@ -55,9 +55,13 @@ ActionException::ExceptionName - Bad parameter - Mauvais paramètre + Mauvais paramètre + + + + Invalid parameter + Paramètre incorrect @@ -140,9 +144,13 @@ %1 : "%2" - %1: bad definition version - %1 : mauvause définition de version + %1 : mauvause définition de version + + + + %1: invalid definition version + %1 : définition de version incorrecte @@ -158,48 +166,52 @@ ActionTools::ActionInstance - + A variable name can only contain alphanumeric characters and cannot start with a digit. Un nom de variable ne peut contenir que des caractères alphanumériques et ne peut pas commencer par un chiffre. - + Integer value expected. Valeur entière attendue. - + Decimal value expected. Valeur décimale attendue. - - + + "%1" is not a valid position. "%1" n'est pas une position valide. - - + + "%1" is not a valid color. "%1" n'est pas une couleur valide. - + Unable to find any procedure named "%1" Impossible de trouver une procédure nommée "%1" - + Undefined variable "%1" La variable "%1" est inconnue - - Bad parameter. Unable to evaluate string + + Invalid parameter. Unable to evaluate string Paramètre incorrect. Impossible d'évaluer la chaîne de caractères + Bad parameter. Unable to evaluate string + Paramètre incorrect. Impossible d'évaluer la chaîne de caractères + + [Null] [Nul] @@ -212,7 +224,12 @@ [Données brutes] - + + Please choose a value for this field. + Merci de choisir une valeur pour ce champ. + + + "%1" is an invalid value. "%1" est une valeur incorrecte. @@ -291,12 +308,12 @@ ActionTools::CodeDateTimeEdit - + &Step up &Monter - + Step &down &Descendre @@ -328,27 +345,42 @@ ActionTools::CodeLineEdit - + Set to text/code Changer en texte/code - + Open editor Ouvrir éditeur - + Click here to switch text/code Cliquez ici pour passer en mode texte/code - + Click here to open the editor Cliquez ici pour ouvrir l'éditeur - + + Click here to insert a variable + Cliquez ici pour insérer une variable + + + + Insert variable + Insérer une variable + + + + No variables to insert + Pas de variables à insérer + + + Double-click to edit Double-cliquez pour éditer @@ -356,12 +388,12 @@ ActionTools::CodeSpinBox - + &Step up &Monter - + Step &down &Descendre @@ -431,27 +463,39 @@ ActionTools::OpenCVAlgorithms - + FindSubImage is already running Recherche via FindSubImage en cours - + + Source images must be larger than target image + Les images source doivent être plus grandes que l'image cible + + + + Source images and target image must have same depth + Les images source et l'image cible doivent avoir la même profondeur + + + + Source images and target image must have same number of channels + Les images source et l'image cible doivent avoir le même nombre de canaux + + Source image must be larger than target image - L'image source doit être plus grande que l'image cible + L'image source doit être plus grande que l'image cible - Source image and target image must have same depth - L'image source et l'image cible doivent avoir la même profondeur + L'image source et l'image cible doivent avoir la même profondeur - Source image and target image must have same number of channels - L'image source et l'image cible doivent avoir le même nombre de canaux + L'image source et l'image cible doivent avoir le même nombre de canaux - + OpenCV exception: %1 Exception OpenCV : %1 @@ -467,22 +511,22 @@ ActionTools::Script - + Unknown Inconnu - + GNU/Linux GNU/Linux - + Windows Windows - + Mac Mac @@ -540,66 +584,72 @@ Code::Image - - - - - + + + + + Incorrect parameter type Type de paramètre incorrect - + + Incorrect parameter count Nombre de paramètres incorrect - + Invalid window Fenêtre invalide - + + Invalid screen index + Index d'écran non valide + + + Unable to set the image data Impossible de changer les données de l'image - + Unable to get the image data Impossible de récupérer les données de l'image - - - - + + + + Error while searching for a sub-image: %1 Erreur lors de la recherche d'une sous-image : %1 - - + + Parameter "callback" is not a function Le paramètre "callback" n'est pas une fonction - - + + Unable to load image from file %1 Impossible de charger l'image à partir du fichier %1 - + Unable to save image to file %1 Impossible de sauvegarder l'image dans le fichier %1 - + Unable to apply filter Impossible d'appliquer le filtre - + Cannot set filter option %1 %2 Impossible de changer les options du filtre %1 %2 diff -Nru actionaz-3.6.2/locale/executer_fr_FR.ts actionaz-3.7.0/locale/executer_fr_FR.ts --- actionaz-3.6.2/locale/executer_fr_FR.ts 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/locale/executer_fr_FR.ts 2013-06-27 21:41:48.000000000 +0000 @@ -69,72 +69,72 @@ LibExecuter::Executer - + Invalid Begin procedure action, you have to end the previous procedure before starting another one Début de procédure incorrect, vous devez d'abord terminer la procédure précédente avant d'en débuter une autre - + A procedure name cannot be empty Le nom d'une procédure ne peut être vide - + A procedure with the name "%1" has already been declared Une procédure nommée "%1" existe déjà - + Invalid End procedure Fin de procédure incorrecte - + Begin procedure action without end procedure Début de procédure sans fin de procédure - + Incorrect parameter name: "%1" Nom de paramètre incorrect : "%1" - + Error while evaluating parameter "%1", error message: "%2" Erreur lors de l'évaluation du paramètre "%1", message d'erreur : "%2" - + Action design error: Invalid exception emitted (%1, line %2) Erreur de conception de l'action : Exception invalide émise (%1, ligne %2) - + Invalid exception line: %1 Ligne d'exception invalide : %1 - + Script line %1: Ligne de script %1 : - + Script %1, line %2: Script %1, ligne %2 : - + Unable to find the label named "%1" Impossible de trouver le label nommé "%1" - + Incorrect Script.nextLine value: %1 Valeur de Script.nextLine incorrecte : %1 - + The action at line %1 is invalid L'action à la ligne %1 est invalide diff -Nru actionaz-3.6.2/locale/gui_fr_FR.ts actionaz-3.7.0/locale/gui_fr_FR.ts --- actionaz-3.6.2/locale/gui_fr_FR.ts 2013-05-04 11:48:12.000000000 +0000 +++ actionaz-3.7.0/locale/gui_fr_FR.ts 2013-06-27 21:41:48.000000000 +0000 @@ -435,117 +435,117 @@ Paramètres - - + + Input parameters Paramètres d'entrée - + Output parameters Paramètres de sortie - + Pause before executing the action Pause avant d'exécuter l'action - + Pause after executing the action Pause après l'exécution de l'action - + Action maximal execution time Temps d'exécution maximum - + ms milliseconds ms - + No pause before Pas de pause avant - + No pause after Pas de pause après - + No timeout Pas de temps d'exécution maximum - + Pause before: Pause avant : - + Pause after: Pause après : - + Timeout: Temps d'exécution maximum : - + Common Commun - + Exceptions Exceptions - + By Par - + Version %1 Version %1 - + Alpha Alpha - + Beta Beta - + Testing En test - + Stable Stable - - + + : : - + <i>No parameters</i> <i>Pas de paramètres</i> @@ -553,7 +553,7 @@ ActionTabs - + Parameters Paramètres