diff --git a/sdk/applications/actionstatemachine/ActionState.cpp b/sdk/applications/actionstatemachine/ActionState.cpp index c041c3e5b4d0ffab443f0490ad91bd6ca26ee8b7..7fc6382ec48f7a0c3c854fbf2bdc7bfe54e8cb18 100644 --- a/sdk/applications/actionstatemachine/ActionState.cpp +++ b/sdk/applications/actionstatemachine/ActionState.cpp @@ -213,27 +213,29 @@ void ActionState::onEntry(QEvent* event) { } // log the parameters - (*logStream) << "\t\t\t" << myAction->getName() << "" << endl; + (*logStream) << "\t\t" << myAction->getName() << "" << endl; // Properties int nbStaticProps = myAction->metaObject()->propertyCount(); QList propertyNames = myAction->dynamicPropertyNames(); // static properties if ((nbStaticProps > 0) || (! propertyNames.isEmpty())) { - (*logStream) << "\t\t\t" << endl; + (*logStream) << "\t\t" << endl; for (int index = 0 ; index < nbStaticProps; index++) { QString staticPropName = myAction->metaObject()->property(index).name(); - (*logStream) << "\t\t\t\t" << endl; + if (staticPropName != "objectName") { + (*logStream) << "\t\t\t" << endl; + } } // dynamic properties for (QList::const_iterator it = propertyNames.begin(); it != propertyNames.end(); it++) { - (*logStream) << "\t\t\t\t" << endl; } - (*logStream) << "\t\t\t" << endl; + (*logStream) << "\t\t" << endl; } @@ -244,7 +246,7 @@ void ActionState::onEntry(QEvent* event) { // log inputs if (inputComponentNames.size() > 0) { - (*logStream) << "\t\t\t" << endl; + (*logStream) << "\t\t" << endl; } // search for proper input considering name and type @@ -260,14 +262,14 @@ void ActionState::onEntry(QEvent* event) { } if (compIt != allComps.end()) { - (*logStream) << "\t\t\t\tgetName() << "' type='" << compType << "'/>" << endl; inputComps.append((*compIt)); } } if (inputComponentNames.size() > 0) { - (*logStream) << "\t\t\t" << endl; + (*logStream) << "\t\t" << endl; } myAction->setInputComponents(inputComps); @@ -299,7 +301,7 @@ void ActionState::onExit(QEvent* event) { QTime endTime = QTime::currentTime(); (*logStream) << "\t\t" << endl; (*logStream) << "\t\t" << endTime.toString("hh:mm:ss:zzz") << "" << endl; - (*logStream) << "\t\t" << (startTime->elapsed()) << "" << endl; + (*logStream) << "\t\t" << (startTime->elapsed()) << "" << endl; (*logStream) << "\t" << endl; } } diff --git a/sdk/applications/actionstatemachine/ActionStateMachine.cpp b/sdk/applications/actionstatemachine/ActionStateMachine.cpp index 43ef997f1ea1db3f4382325b7d0e90800b270c60..6e8fdf3366ac23c544c9bdcc924d80073b5f1f09 100644 --- a/sdk/applications/actionstatemachine/ActionStateMachine.cpp +++ b/sdk/applications/actionstatemachine/ActionStateMachine.cpp @@ -46,6 +46,7 @@ using namespace camitk; #include "ActionStateViewer.h" #include "ActionStateViewerExtension.h" #include "ActionTransition.h" +#include "ActionStateWizard.h" // ---------------------- constructor ---------------------------- ActionStateMachine::ActionStateMachine(int& argc, char** argv, QString inputFileName, QString outputDirectory) : @@ -54,20 +55,20 @@ ActionStateMachine::ActionStateMachine(int& argc, char** argv, QString inputFile setProperty("Log to File", true); setProperty("Logger Level", InterfaceLogger::TRACE); - asmwiz = new ActionStateWizard(); - - // Read parameters or ask for scxml file name and output save directory + // Read parameters or ask for scxml filename and output directory QString filename; if (inputFileName.isEmpty() || outputDirectory.isEmpty()) { - // open dialog for parameters input + // open dialog wizard for parameters input + ActionStateWizard asmwiz(inputFileName, outputDirectory); + // if OK is pressed we continue starting action state machine // otherwise we exit - if (asmwiz->exec()) { - filename = asmwiz->getSCXMLFilename(); - saveDirectory = QDir(asmwiz->getLogDirectory()); - asmwiz->done(QDialog::Accepted); + if (asmwiz.exec()) { + filename = asmwiz.getSCXMLFilename(); + saveDirectory = QDir(asmwiz.getLogDirectory()); + asmwiz.done(QDialog::Accepted); } else { - asmwiz->done(QDialog::Rejected); + asmwiz.done(QDialog::Rejected); throw AbortException("Operation aborted by user."); } } else { @@ -80,8 +81,6 @@ ActionStateMachine::ActionStateMachine(int& argc, char** argv, QString inputFile ext->initResources(); ext->init(); registerAllViewers(ext); - - statesMap = new QMap(); // Atributes initialization mainWindow = NULL; @@ -97,19 +96,17 @@ ActionStateMachine::ActionStateMachine(int& argc, char** argv, QString inputFile // NOTE on Windows ":" (colon) is reserved by the system for separating drive names, therefore hh:mm:ss cannot be used QString newDir = now.toString("yyyy-MM-dd") + "T" + now.toString("hh-mm-ss"); - if (! saveDirectory.mkdir(newDir)) { + if (!saveDirectory.mkdir(newDir)) { saveDirectory = QFileDialog::getExistingDirectory(this->mainWindow, tr("Please select a directory where to save log and component files")); saveDirectory.mkdir(newDir); } saveDirectory.cd(newDir); + CAMITK_TRACE(tr("Logging in %1").arg(saveDirectory.absolutePath())); // parse XML file and store actions and transitions in states name = this->parseSCXMLTree(); mainWindow->setWindowSubtitle(name); - // Prepare the output directory - QFile::copy(":/logXSL", saveDirectory.absolutePath() + "/log2html.xsl"); - // Starting the Machine !! //create the main timer @@ -117,16 +114,390 @@ ActionStateMachine::ActionStateMachine(int& argc, char** argv, QString inputFile startTime->start(); (*logStream) << "" << endl; - (*logStream) << "" << endl << endl; + (*logStream) << "" << endl; + (*logStream) << "" << endl; + (*logStream) << "]>" << endl; + (*logStream) << "" << endl; + // embed the XSL stylesheet directly in the XML + + (*logStream) << "" << endl; + (*logStream) << "" << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " Log of Application <xsl:value-of select='log:application/log:name'/>" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "
" << endl; + (*logStream) << "
" << endl; + (*logStream) << "

" << endl; + (*logStream) << "

Log file

" << endl; + (*logStream) << "

Date:

" << endl; + (*logStream) << "

Started: - Finished:

" << endl; + (*logStream) << "

Duration: " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "

" << endl; + (*logStream) << "

Input xml file name:

" << endl; + (*logStream) << "

" << endl; + (*logStream) << "
" << endl; + (*logStream) << "" << endl; + (*logStream) << "
" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "" << endl; + (*logStream) << "

Total time spend within states: " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " ( ms)" << endl; + (*logStream) << "

" << endl; + (*logStream) << " " << endl; + (*logStream) << "

Total time spend on action transitions: " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " ( ms)" << endl; + (*logStream) << "

" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "
State
(click on a state to show its execution details)
" << endl; + (*logStream) << "
" << endl; + (*logStream) << "
" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "
" << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "
" << endl; + (*logStream) << " . " << endl; + (*logStream) << "
" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " CamiTK action's name: " << endl; + (*logStream) << " " << endl; + (*logStream) << " State duration: " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "
" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "" << endl; + (*logStream) << " Transition duration: " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " Action applied with status: " << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " Parameters: " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " Input:" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " Output:" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " Closing:" << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << "
    " << endl; + (*logStream) << " " << endl; + (*logStream) << "
" << endl; + (*logStream) << "
" << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << "
  • :
  • " << endl; + (*logStream) << "
    " << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << "
      " << endl; + (*logStream) << " " << endl; + (*logStream) << "
    " << endl; + (*logStream) << "
    " << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << "
      " << endl; + (*logStream) << " " << endl; + (*logStream) << "
    " << endl; + (*logStream) << "
    " << endl; + (*logStream) << "" << endl; + (*logStream) << " " << endl; + (*logStream) << "
  • :
  • " << endl; + (*logStream) << "
    " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " " << endl; + (*logStream) << " h " << endl; + (*logStream) << " min " << endl; + (*logStream) << " s " << endl; + (*logStream) << " ms" << endl; + (*logStream) << " <1 ms" << endl; + (*logStream) << " " << endl; + (*logStream) << "
    " << endl; (*logStream) << "" << endl; - (*logStream) << "\t" << name << "" << endl; + (*logStream) << "\t" << getName() << "" << endl; (*logStream) << "\t" << filename << "" << endl; (*logStream) << "\t" << now.toString("yyyy-MM-dd") << "" << endl; (*logStream) << "\t" << startTime->toString("hh:mm:ss:zzz") << "" << endl; machine.start(); - - } // ---------------------- autoNext ---------------------------- @@ -140,23 +511,43 @@ void ActionStateMachine::autoNext() { // loop until no more state is available while (currentState != nullptr && currentState->transitions().size() > 0) { // look for the "Next" or "Quit" transition + // (if there is a "Next" and a "Quit", "Next" is prioritized) auto it = currentState->transitions().begin(); bool foundNextState = false; - while (it != currentState->transitions().end() && !foundNextState) { // && nextState==nullptr) { + while (it != currentState->transitions().end() && !foundNextState) { // all transition in this state machine are ActionTransition instances... ActionTransition* currentActionTransition = qobject_cast(*it); - //... in which we can look for the "Next" or "Quit" transition - if (currentActionTransition->isNamed("Next") || currentActionTransition->isNamed("Quit")) { + //... in which we can look for the "Next" transition first + if (currentActionTransition->isNamed("Next")) { // activate the transition (simulate a click on the button) currentActionTransition->autoNext(); // activating the "Quit" transition enter the final state, which make the state machine to emit the finished() signal foundNextState = true; } + ++it; } + // if the next state is not found, look for the "Quit" state + if (!foundNextState) { + it = currentState->transitions().begin(); + while (it != currentState->transitions().end() && !foundNextState) { + // all transition in this state machine are ActionTransition instances... + ActionTransition* currentActionTransition = qobject_cast(*it); + + //... in which we can look for the "Quit" transition + if (currentActionTransition->isNamed("Quit")) { + // activate the transition (simulate a click on the button) + currentActionTransition->autoNext(); // activating the "Quit" transition enter the final state, which make the state machine to emit the finished() signal + foundNextState = true; + } + + ++it; + } + } // get the new current active state currentState = dynamic_cast(machine.configuration().toList().first()); } + while (currentState != nullptr); } @@ -230,6 +621,7 @@ void ActionStateMachine::checkSCXMLFile(QString filename) { // ---------------------- parseSCXMLTree ---------------------------- QString ActionStateMachine::parseSCXMLTree() { + // Get the name of the application QString applicationName = ""; QDomElement docElem = scxmlDoc.documentElement(); @@ -252,7 +644,7 @@ QString ActionStateMachine::parseSCXMLTree() { // Set the initial state (specified in the scxml element with initial attribute). QString initialStateName = scxmlDoc.documentElement().attribute("initial"); - ActionState* initialState = statesMap->find(initialStateName).value(); + ActionState* initialState = statesMap.find(initialStateName).value(); machine.setInitialState(initialState); dynamic_cast(Application::getViewer("Action State Viewer"))->setState(initialState); @@ -262,10 +654,6 @@ QString ActionStateMachine::parseSCXMLTree() { // and connect the about to quit with some final cleanup method (recommended instead using destructor to cleanup) QObject::connect(this, SIGNAL(aboutToQuit()), this, SLOT(finished())); - // Ok, Actions and Wizard are created. We do not need the file any more. - // Clean up: - delete statesMap; - return applicationName; } @@ -274,8 +662,9 @@ void ActionStateMachine::finished() { QTime endTime = QTime::currentTime(); (*logStream) << "\t" << endTime.toString("hh:mm:ss:zzz") << "" << endl; - (*logStream) << "\t" << (startTime->elapsed()) << "" << endl; + (*logStream) << "\t" << (startTime->elapsed()) << "" << endl; (*logStream) << "" << endl; + (*logStream) << "
    " << endl; logFile->close(); } @@ -295,20 +684,23 @@ void ActionStateMachine::createAllActionStates(QDomNodeList nodeList) { if (elementName == QString("state")) { QString stateId = element.attribute("id"); QString stateDescription = element.elementsByTagName("camitk:description").item(0).toElement().text(); - ActionState* state = new ActionState(&machine, stateId, stateDescription, logStream); - if (element.elementsByTagName("camitk:action").size() > 0) { + ActionState* state = nullptr; + if (element.elementsByTagName("camitk:action").size() > 0) { QDomElement actionElement = element.elementsByTagName("camitk:action").item(0).toElement(); // Find the name of the action QString camiTKActionName = actionElement.elementsByTagName("camitk:name").item(0).toElement().text(); if (camiTKActionName == "Save") { - delete (state); state = new SaveActionState(&machine, stateId, stateDescription, saveDirectory.absolutePath(), logStream); setCamiTKSaveAction((SaveActionState*) state, actionElement); } else { + state = new ActionState(&machine, stateId, stateDescription, logStream); setCamiTKAction(state, actionElement); } } + else { + state = new ActionState(&machine, stateId, stateDescription, logStream); + } QDomNodeList alternativeDescriptions = element.elementsByTagName("camitk:altDescription"); for (int i = 0; i < alternativeDescriptions.size(); i++) { QDomElement altDescElmt = alternativeDescriptions.item(i).toElement(); @@ -319,7 +711,7 @@ void ActionStateMachine::createAllActionStates(QDomNodeList nodeList) { state->setAlternativeDesc(altDescText, statusList); } - statesMap->insert(stateId, state); + statesMap.insert(stateId, state); } } } @@ -331,8 +723,8 @@ void ActionStateMachine::createAllActionStates(QDomNodeList nodeList) { // 1. build the map QMap inputNames; QMap outputNames; - QMap ::const_iterator it = statesMap->constBegin(); - while (it != statesMap->constEnd()) { + QMap ::const_iterator it = statesMap.constBegin(); + while (it != statesMap.constEnd()) { foreach (QString inputCompName, it.value()->getInputComponents().keys()) { if (inputNames.values().contains(inputCompName)) { CAMITK_WARNING(tr("Warning: same input \"%1\" for more than one state. It might be wrong.\n").arg(inputCompName)) @@ -376,7 +768,7 @@ void ActionStateMachine::createTransitions(QDomNodeList nodeList) { // Find its name (id attribute)... QString stateId = element.attribute("id"); // ... and get the corresponding created state in the map: - ActionState* state = (statesMap->find(stateId)).value(); + ActionState* state = (statesMap.find(stateId)).value(); // Check if this state is final bool isFinal = (element.attribute("final", "false").toLower() == QString("true")); @@ -397,8 +789,8 @@ void ActionStateMachine::createTransitions(QDomNodeList nodeList) { QVector disableConditions = stringToStatus(disableConds); // Find the corresponding target state - QMap ::iterator it = statesMap->find(targetName); - if (it == statesMap->end()) { + QMap ::iterator it = statesMap.find(targetName); + if (it == statesMap.end()) { QString msg = tr(R"(XML Parsing: %1 in state "%2": cannot find target "%3" for event "%4")") .arg(getDomNodeLocation(transitionsList.item(transNb)), state->getName(), diff --git a/sdk/applications/actionstatemachine/ActionStateMachine.h b/sdk/applications/actionstatemachine/ActionStateMachine.h index 79f40cf902722df164fc13ae911db0a1f586ac12..652af07ebbd82f145f4e0d1ac8d916c1eab57db6 100644 --- a/sdk/applications/actionstatemachine/ActionStateMachine.h +++ b/sdk/applications/actionstatemachine/ActionStateMachine.h @@ -46,7 +46,6 @@ // -- CamiTK Local stuff #include "ActionState.h" #include "SaveActionState.h" -#include "ActionStateWizard.h" /** * @ingroup group_sdk_application_asm @@ -109,7 +108,7 @@ protected: QDomDocument scxmlDoc; /// Map of action state to build transitions - QMap* statesMap; + QMap statesMap; /// Final State QFinalState* finalState; @@ -149,11 +148,6 @@ private: /// build a specific error message containing the line and column if available QString getDomNodeLocation(QDomNode); - - /// - /// Wizard to ask wich file and directory to use - /// - ActionStateWizard* asmwiz; }; #endif // ACTIONSTATEMACHINE_H diff --git a/sdk/applications/actionstatemachine/ActionStateWizard.cpp b/sdk/applications/actionstatemachine/ActionStateWizard.cpp index 56c94a683ed78ebf9ff93615152f92dfba3a973d..8b90aeebee12c3c297545dd29b7d3e7385a59902 100644 --- a/sdk/applications/actionstatemachine/ActionStateWizard.cpp +++ b/sdk/applications/actionstatemachine/ActionStateWizard.cpp @@ -28,56 +28,70 @@ // -- CamiTK Application Local stuff #include "ActionStateWizard.h" -ActionStateWizard::ActionStateWizard() { - uiasmwiz = new Ui::ActionStateWizard(); - uiasmwiz->setupUi(this); +// ---------------------- constructor ---------------------------- +ActionStateWizard::ActionStateWizard(QString inputFileName, QString outputDir) { + // init GUI + ui = new Ui::ActionStateWizard(); + ui->setupUi(this); + ui->buttonBox->button(QDialogButtonBox::Ok)->setText("Start CamiTK Action State Machine"); - connect(uiasmwiz->browseSCXML, SIGNAL(clicked()), this, SLOT(findSCXMLFileName())); - connect(uiasmwiz->browseLogDirectory, SIGNAL(clicked()), this, SLOT(findLogDirectory())); + connect(ui->browseSCXML, SIGNAL(clicked()), this, SLOT(selectSCXMLFilename())); + connect(ui->browseLogDir, SIGNAL(clicked()), this, SLOT(selectLogDirectory())); + + SCXMLFileName = inputFileName; + logDirectory = outputDir; initLogDirLabel(); initSCXMLLabel(); } -// Getter and setter for chosen file and directory +// ---------------------- getSCXMLFilename ---------------------------- QString ActionStateWizard::getSCXMLFilename() { return SCXMLFileName; } +// ---------------------- getLogDirectory ---------------------------- QString ActionStateWizard::getLogDirectory() { return logDirectory; } -void ActionStateWizard::setSCXMLFileName(QString inputFileName) { - SCXMLFileName = inputFileName; -} - -void ActionStateWizard::setLogDirectory(QString outputDir) { - logDirectory = outputDir; -} - -void ActionStateWizard::findLogDirectory() { +// ---------------------- selectLogDirectory ---------------------- +void ActionStateWizard::selectLogDirectory() { logDirectory = QFileDialog::getExistingDirectory(this, tr("Please select a directory where to save log and component files")); initLogDirLabel(); } -void ActionStateWizard::findSCXMLFileName() { +// ---------------------- selectSCXMLFilename ---------------------- +void ActionStateWizard::selectSCXMLFilename() { SCXMLFileName = QFileDialog::getOpenFileName(this, tr("Please select an xml file")); initSCXMLLabel(); } +// ---------------------- initSCXMLLabel ---------------------- void ActionStateWizard::initSCXMLLabel() { if (SCXMLFileName.isEmpty()) { - uiasmwiz->SCXMLLabel->setText("No xml file !"); + ui->SCXMLLabel->setText("No SCXML document: please select an XML file..."); + ui->browseSCXMLLabel->setText("Select SCXML document"); } else { - uiasmwiz->SCXMLLabel->setText(SCXMLFileName); + ui->SCXMLLabel->setText(SCXMLFileName); + ui->browseSCXMLLabel->setText("Modify SCXML document"); } + updateStartButtonState(); } +// ---------------------- initLogDirLabel ---------------------- void ActionStateWizard::initLogDirLabel() { if (logDirectory.isEmpty()) { - uiasmwiz->LogDirLabel->setText("No output directory !"); + ui->LogDirLabel->setText("No output directory: please select a directory"); + ui->browseLogDirLabel->setText("Secect output directory"); } else { - uiasmwiz->LogDirLabel->setText(logDirectory); + ui->LogDirLabel->setText(logDirectory); + ui->browseLogDirLabel->setText("Modify output directory"); } + updateStartButtonState(); +} + +// ---------------------- updateStartButtonState ---------------------- +void ActionStateWizard::updateStartButtonState() { + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!SCXMLFileName.isEmpty() && !logDirectory.isEmpty()); } \ No newline at end of file diff --git a/sdk/applications/actionstatemachine/ActionStateWizard.h b/sdk/applications/actionstatemachine/ActionStateWizard.h index e2102d039c11b18b3987d33bd974d477e7013bca..d357e6a39a0131135b9302f0a785456740db92b7 100644 --- a/sdk/applications/actionstatemachine/ActionStateWizard.h +++ b/sdk/applications/actionstatemachine/ActionStateWizard.h @@ -28,35 +28,50 @@ #include "ui_ActionStateWizard.h" +/** + * @ingroup group_sdk_application_asm + * + * @brief + * This dialog is shown only if at least one of the two required input parameters (SCXML + * and output directory) is missing when the application is started. + * + */ class ActionStateWizard : public QDialog { Q_OBJECT public: - ActionStateWizard(); + /// Constructor (initialize the application parameters) + ActionStateWizard(QString inputFileName, QString outputDir); - // Return the filename of scxml file to use as input file + /// Return the current filename of scxml file to use as input file QString getSCXMLFilename(); - // Return the directory name to use as output log directory + /// Return the current directory name to use as output log directory QString getLogDirectory(); - void setSCXMLFileName(QString inputFileName); - - void setLogDirectory(QString outputDir); - private slots: - void findLogDirectory(); + /// called when the user click on "Browse" to select an output directory + void selectLogDirectory(); - void findSCXMLFileName(); + /// called when the user click on "Browse" to select an SCXML input file + void selectSCXMLFilename(); private: - Ui::ActionStateWizard* uiasmwiz; + /// the Dialog GUI + Ui::ActionStateWizard* ui; + /// the current value of the SCXML input file QString SCXMLFileName; + /// the current value of the output directory QString logDirectory; + /// initialize the GUI to display the current value of SCXML input file + void initSCXMLLabel(); + + /// initialize the GUI to display the current value of output directory void initLogDirLabel(); - void initSCXMLLabel(); + /// enable the Start button state only if both parameters are set + void updateStartButtonState(); }; #endif // ACTIONSTATEWIZARD_H \ No newline at end of file diff --git a/sdk/applications/actionstatemachine/ActionStateWizard.ui b/sdk/applications/actionstatemachine/ActionStateWizard.ui index e975fd2a8d067d95c93184f95aeb6ac2f495e68b..be211556e2c707f8a2028f8a9ddf36c7f1e4de5c 100644 --- a/sdk/applications/actionstatemachine/ActionStateWizard.ui +++ b/sdk/applications/actionstatemachine/ActionStateWizard.ui @@ -6,8 +6,8 @@ 0 0 - 471 - 146 + 482 + 388 @@ -19,87 +19,101 @@ - CamiTK Action State Machine needs two parameters to run. + <html><head/><body><p>CamiTK Action State Machine requires two parameters to run</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">An SCXML to describe the state machine</li><li style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">An output directory to write the log</li></ul></body></html> + + + Qt::RichText - - - - - Choose a SCXML file : - - - - - - - Browse - - - - + + + SCXML + + + + + + TextLabel + + + + + + + + + Select SCXML file + + + + + + + Browse + + + + + + + - - - TextLabel + + + Output directory + + + + + TextLabel + + + + + + + + + Select output directory + + + + + + + Browse + + + + + + - + - - - Choose an output directory : + + + Qt::LeftToRight - - - - - - Browse + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + true - - - - TextLabel - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Qt::Vertical - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - diff --git a/sdk/applications/actionstatemachine/ActionTransition.cpp b/sdk/applications/actionstatemachine/ActionTransition.cpp index d9ae760f0d34f50cab1078a5d54afc9dc94f9907..1cd8d1c1a081cd806a906cb09ce2ea2eaf1a1f52 100644 --- a/sdk/applications/actionstatemachine/ActionTransition.cpp +++ b/sdk/applications/actionstatemachine/ActionTransition.cpp @@ -139,7 +139,7 @@ void ActionTransition::onTransition(QEvent* e) { QTime endTime = QTime::currentTime(); (*logStream) << "\t\t" << endTime.toString("hh:mm:ss:zzz") << "" << endl; - (*logStream) << "\t\t" << (startTime->elapsed()) << "" << endl; + (*logStream) << "\t\t" << (startTime->elapsed()) << "" << endl; (*logStream) << "\t" << endl; } } diff --git a/sdk/applications/actionstatemachine/CMakeLists.txt b/sdk/applications/actionstatemachine/CMakeLists.txt index 11055400faac8ca3cc24105c20c04fa20a1a68fb..e38020d3ea2af9eae101df2309bf83cee7f857ea 100644 --- a/sdk/applications/actionstatemachine/CMakeLists.txt +++ b/sdk/applications/actionstatemachine/CMakeLists.txt @@ -9,4 +9,30 @@ camitk_application(NEEDS_QT_MODULES #we use QtXML # Recursively update the shiboken path variable containing the CamiTK SDK tree structure set(SHIBOKEN_CAMITK_SDK_PATH ${SHIBOKEN_CAMITK_SDK_PATH}:${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "") -# TODO add two automatic test using the testdata scxml +# Automatic tests +set(TEST_BASENAME ${APPLICATION_TARGET_NAME}) +camitk_init_test(${TEST_BASENAME}) + +# should pass because invoking camitk-actionstatemachine without arguments or with help +# arg shows usage and exit success +camitk_add_test(EXECUTABLE_ARGS "--help" PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-") +camitk_add_test(EXECUTABLE_ARGS "-h" PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-") + +# should pass because invoking testcomponents with a faulty arguments results in printing +# an "Argument error" message (and exit failure) +camitk_add_test(EXECUTABLE_ARGS "-badarg" + PASS_REGULAR_EXPRESSION "unknown option '-badarg'" + PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-") + +# Testing using the testdata scxml +# note for the regular expression: +# as [ ] are regex wild card and " is not easy to escaped, all theses characters are replaced by . +# see https://cmake.org/cmake/help/latest/command/string.html#regex-specification +# for more information on CMake regex +camitk_add_test(EXECUTABLE_ARGS "-f ${PROJECT_SOURCE_DIR}/sdk/applications/actionstatemachine/testdata/asmSimpleImageFilter.xml -o . -a" + PASS_REGULAR_EXPRESSION ".INFO . Application .camitk-actionstatemachine. - Exiting application..." + PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-") + +camitk_add_test(EXECUTABLE_ARGS "-f ${PROJECT_SOURCE_DIR}/sdk/applications/actionstatemachine/testdata/asmSimpleMeshProcessing.xml -o . -a" + PASS_REGULAR_EXPRESSION ".INFO . Application .camitk-actionstatemachine. - Exiting application..." + PROJECT_NAME ${TEST_BASENAME} TEST_SUFFIX "-") diff --git a/sdk/applications/actionstatemachine/SaveActionState.cpp b/sdk/applications/actionstatemachine/SaveActionState.cpp index 45a1992b41d434780015be40db305d37c8fc6134..b84b402f8a87d9a1d45e5f0e25c5ab23198130ac 100644 --- a/sdk/applications/actionstatemachine/SaveActionState.cpp +++ b/sdk/applications/actionstatemachine/SaveActionState.cpp @@ -52,12 +52,11 @@ Action::ApplyStatus SaveActionState::applyAction() { Action::ApplyStatus status(Action::TRIGGERED); if (logStream != nullptr) { - (*logStream) << " " << endl; - (*logStream) << " " << myAction->getName() << "" << endl; - (*logStream) << " " << endl; + (*logStream) << "\t\t" << endl; + (*logStream) << "\t\t\t" << myAction->getName() << "" << endl; + (*logStream) << "\t\t\t" << endl; } - // set input components ComponentList allComps = Application::getAllComponents(); ComponentList::const_iterator compIt; @@ -111,13 +110,13 @@ Action::ApplyStatus SaveActionState::applyAction() { inputComps.append((*compIt)); if (logStream != NULL) { - (*logStream) << " " << endl; } } if (logStream != nullptr) { - (*logStream) << " " << endl; + (*logStream) << "\t\t\t" << endl; } @@ -134,12 +133,10 @@ Action::ApplyStatus SaveActionState::applyAction() { } if (logStream != nullptr) { - (*logStream) << " " << Action::getStatusAsString(status) << "" << endl; - (*logStream) << " " << endl; + (*logStream) << "\t\t\t" << Action::getStatusAsString(status) << "" << endl; + (*logStream) << "\t\t" << endl; } - - Application::refresh(); return status; diff --git a/sdk/applications/actionstatemachine/resources/camitk-actionstatemachine.qrc b/sdk/applications/actionstatemachine/resources/camitk-actionstatemachine.qrc index 5eb85285bb5f81d9c4993de6808cc0a9fb079df8..864c4d390a1f8b58bd83d5af24816b8f5e17aaf0 100644 --- a/sdk/applications/actionstatemachine/resources/camitk-actionstatemachine.qrc +++ b/sdk/applications/actionstatemachine/resources/camitk-actionstatemachine.qrc @@ -1,7 +1,6 @@ - log2html.xsl camitk-actionstatemachine.xpm \ No newline at end of file diff --git a/sdk/applications/actionstatemachine/resources/log2html.xsl b/sdk/applications/actionstatemachine/resources/log2html.xsl deleted file mode 100644 index 16d6f05ae45f3389477147d06aad8dd7397e7407..0000000000000000000000000000000000000000 --- a/sdk/applications/actionstatemachine/resources/log2html.xsl +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - Log of Application <xsl:value-of select="/log:application/log:name"/> - - - -
    -
    -

    -

    Log file

    -

    Runned the

    -

    Start: Stop:

    -

    duration: - - -

    -

    Input xml file name:

    -
    - -
    - - - -

    Total time within states (action triggering): - - - - - (i.e., ms) -

    - -

    Total time on action application: - - - - - (i.e., ms) -

    - - - - - -

    State

    Duration

    -
    - -
    - - -
    - - - - - - - - -
    - ) -
    - - - - - - - - - -
    - - - - - - - - - Action Applied: - with status - - - - - - - - - - - - - - - -
    ParametersInputsOutputs
    - - - - - - - - - -
    - - - - - Closing: - - - - - - -
    - - - - - - - - - -
    - - - - - - - - -
    - Name - Value -
    -
    - - - - - - - - - - - - - - - - - - - -
    - Type - - Name -
    -
    - - - - - - - - -
    - Type - - Name -
    -
    - - - - - - - - - - - - - - - - - - - h - min - s - ms - -
    diff --git a/sdk/applications/actionstatemachine/testdata/asmSimpleImageFilter.xml b/sdk/applications/actionstatemachine/testdata/asmSimpleImageFilter.xml index 83a88000d6832e05386fb38531bb253c4ab9d7b4..f4e73db2293416e50db1afd366758ac7c891cd27 100644 --- a/sdk/applications/actionstatemachine/testdata/asmSimpleImageFilter.xml +++ b/sdk/applications/actionstatemachine/testdata/asmSimpleImageFilter.xml @@ -43,6 +43,7 @@ This Action State Machine performs a very simple image processing pipeline:
    + diff --git a/sdk/applications/actionstatemachine/testdata/asmSimpleMeshProcessing.xml b/sdk/applications/actionstatemachine/testdata/asmSimpleMeshProcessing.xml index 9a5faa861b54b57023e9a78cb80c3b04aba243c6..ed387f6d82e6eb67eddfad4817a5fc48ed5839cd 100644 --- a/sdk/applications/actionstatemachine/testdata/asmSimpleMeshProcessing.xml +++ b/sdk/applications/actionstatemachine/testdata/asmSimpleMeshProcessing.xml @@ -84,6 +84,28 @@ to the testdata directory before running. + + + + + + + Save the decimated mesh + + Save + + + + + + + + + + + + + diff --git a/sdk/viewers/explorer/Explorer.cpp b/sdk/viewers/explorer/Explorer.cpp index 8f4d1d439e4f57caefbc9fc58d6b0bf9e01d0dac..1af8948cf4d941740a5fd34d831fd52858a7109f 100644 --- a/sdk/viewers/explorer/Explorer.cpp +++ b/sdk/viewers/explorer/Explorer.cpp @@ -53,11 +53,6 @@ Explorer::Explorer(QString name) : Viewer(name, Viewer::DOCKED) { //----------------------- destructor ------------------------ Explorer::~Explorer() { - // remove all vector actors - while (!itemComponentMap.values().empty()) { - delete itemComponentMap.values().takeFirst(); - } - delete explorerTree; explorerTree = nullptr; @@ -196,7 +191,7 @@ QTreeWidgetItem* Explorer::getItem(Component* comp) { //----------------------- getNewItem ------------------------ QTreeWidgetItem* Explorer::getNewItem(QTreeWidgetItem* parent, Component* abstractNode) { //-- create the tree widget for abstractNode - auto* tw = new QTreeWidgetItem(parent); + QTreeWidgetItem* tw = new QTreeWidgetItem(parent); // set the first column (#0) QString itemText = abstractNode->getName();