#5632 Python method commands (#5649)

* General PdmObjectMethods for scripting.
This commit is contained in:
Gaute Lindkvist
2020-03-10 14:11:22 +01:00
committed by GitHub
parent 587478cbd1
commit c51aa91c42
145 changed files with 2646 additions and 1587 deletions
+79
View File
@@ -0,0 +1,79 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: true
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '$'
IndentCaseLabels: true
IndentWidth: 4
IndentWrappedFunctionNames: true
JavaScriptQuotes: Leave
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
PenaltyBreakAssignment: 13
PenaltyBreakBeforeFirstCallParameter: 10000
PenaltyBreakComment: 20
PenaltyBreakFirstLessLess: 12
PenaltyBreakString: 100
PenaltyExcessCharacter: 5
PenaltyReturnTypeOnItsOwnLine: 30
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: true
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never
...
+5
View File
@@ -0,0 +1,5 @@
---
Checks: '-*,modernize-use-nullptr,modernize-use-override,modernize-deprecated-headers'
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
...
+9 -1
View File
@@ -6,12 +6,20 @@ set( PROJECT_FILES
cafPdmCodeGenerator.h
cafPdmFieldScriptability.h
cafPdmFieldScriptability.cpp
cafPdmFieldIOScriptability.h
cafPdmFieldIOScriptability.cpp
cafPdmObjectMethod.h
cafPdmObjectMethod.cpp
cafPdmObjectScriptabilityRegister.h
cafPdmObjectScriptabilityRegister.cpp
cafPdmPythonGenerator.h
cafPdmPythonGenerator.cpp
cafPdmScriptIOMessages.h
cafPdmScriptIOMessages.cpp
cafPdmObjectScriptability.h
cafPdmObjectScriptability.cpp
cafPdmScriptResponse.h
cafPdmScriptResponse.cpp
)
@@ -24,7 +32,7 @@ target_include_directories(${PROJECT_NAME}
${CMAKE_CURRENT_SOURCE_DIR}
)
target_link_libraries( ${PROJECT_NAME} cafProjectDataModel ${QT_LIBRARIES} )
target_link_libraries( ${PROJECT_NAME} LibCore cafProjectDataModel ${QT_LIBRARIES} )
source_group("" FILES ${PROJECT_FILES})
@@ -0,0 +1,218 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmFieldIOScriptability.h"
#include <QColor>
using namespace caf;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptabilityIOHandler<QString>::writeToField( QString& fieldValue,
QTextStream& inputStream,
caf::PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted )
{
fieldValue = "";
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
QString accumulatedFieldValue;
QChar currentChar;
bool validStringStart = !stringsAreQuoted;
bool validStringEnd = !stringsAreQuoted;
if ( stringsAreQuoted )
{
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
if ( currentChar == QChar( '"' ) )
{
validStringStart = true;
}
}
if ( validStringStart )
{
while ( !inputStream.atEnd() )
{
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
if ( currentChar != QChar( '\\' ) )
{
if ( currentChar == QChar( '"' ) ) // End Quote
{
// Reached end of string
validStringEnd = true;
break;
}
else
{
accumulatedFieldValue += currentChar;
}
}
else
{
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
accumulatedFieldValue += currentChar;
}
}
}
if ( !validStringStart )
{
// Unexpected start of string, Missing '"'
// Error message
errorMessageContainer->addError(
"String argument does not seem to be quoted. Missing the start '\"' in the \"" +
errorMessageContainer->currentArgument + "\" argument of the command: \"" +
errorMessageContainer->currentCommand + "\"" );
// Could interpret as unquoted text
}
else if ( !validStringEnd )
{
// Unexpected end of string, Missing '"'
// Error message
errorMessageContainer->addError( "String argument does not seem to be quoted. Missing the end '\"' in the \"" +
errorMessageContainer->currentArgument + "\" argument of the command: \"" +
errorMessageContainer->currentCommand + "\"" );
// Could interpret as unquoted text
}
fieldValue = accumulatedFieldValue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptabilityIOHandler<QString>::readFromField( const QString& fieldValue,
QTextStream& outputStream,
bool quoteStrings,
bool quoteNonBuiltin )
{
outputStream << "\"";
for ( int i = 0; i < fieldValue.size(); ++i )
{
if ( fieldValue[i] == QChar( '"' ) || fieldValue[i] == QChar( '\\' ) )
{
outputStream << "\\";
}
outputStream << fieldValue[i];
}
outputStream << "\"";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptabilityIOHandler<bool>::writeToField( bool& fieldValue,
QTextStream& inputStream,
caf::PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted )
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
QString accumulatedFieldValue;
QChar nextChar;
QChar currentChar;
while ( !inputStream.atEnd() )
{
nextChar = errorMessageContainer->peekNextChar( inputStream );
if ( nextChar.isLetter() )
{
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
accumulatedFieldValue += currentChar;
}
else
{
break;
}
}
// Accept TRUE or False in any case combination.
bool evaluatesToTrue = QString::compare( accumulatedFieldValue, QString( "true" ), Qt::CaseInsensitive ) == 0;
bool evaluatesToFalse = QString::compare( accumulatedFieldValue, QString( "false" ), Qt::CaseInsensitive ) == 0;
if ( evaluatesToTrue == evaluatesToFalse )
{
QString formatString(
"Boolean argument \"%1\" for the command \"%2\" does not evaluate to either true or false" );
QString errorMessage =
formatString.arg( errorMessageContainer->currentArgument ).arg( errorMessageContainer->currentCommand );
errorMessageContainer->addError( errorMessage );
}
fieldValue = evaluatesToTrue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptabilityIOHandler<bool>::readFromField( const bool& fieldValue,
QTextStream& outputStream,
bool quoteStrings,
bool quoteNonBuiltin )
{
// Lower-case true/false is used in the documentation.
outputStream << ( fieldValue ? "true" : "false" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptabilityIOHandler<cvf::Color3f>::writeToField( cvf::Color3f& fieldValue,
QTextStream& inputStream,
caf::PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted )
{
QString fieldStringValue;
PdmFieldScriptabilityIOHandler<QString>::writeToField( fieldStringValue,
inputStream,
errorMessageContainer,
stringsAreQuoted );
QColor qColor( fieldStringValue );
if ( qColor.isValid() )
{
fieldValue = cvf::Color3f( qColor.redF(), qColor.greenF(), qColor.blueF() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptabilityIOHandler<cvf::Color3f>::readFromField( const cvf::Color3f& fieldValue,
QTextStream& outputStream,
bool quoteStrings,
bool quoteNonBuiltin )
{
QColor qColor( fieldValue.rByte(), fieldValue.gByte(), fieldValue.bByte() );
QString fieldStringValue = qColor.name();
PdmFieldScriptabilityIOHandler<QString>::readFromField( fieldStringValue, outputStream, quoteStrings );
}
@@ -0,0 +1,529 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafAppEnum.h"
#include "cafPdmFieldScriptability.h"
#include "cafPdmPtrArrayField.h"
#include "cafPdmPtrField.h"
#include "cafPdmScriptIOMessages.h"
#include "cvfColor3.h"
#include <QString>
#include <QStringList>
#include <QTextStream>
#define CAF_PDM_InitScriptableFieldWithIO( field, keyword, default, uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitField( field, \
keyword, \
default, \
uiName, \
iconResourceName, \
caf::PdmFieldScriptability::helpString( toolTip, keyword ), \
whatsThis ); \
caf::AddFieldIOScriptabilityToField( field, keyword )
#define CAF_PDM_InitScriptableFieldWithIONoDefault( field, keyword, uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitFieldNoDefault( field, \
keyword, \
uiName, \
iconResourceName, \
caf::PdmFieldScriptability::helpString( toolTip, keyword ), \
whatsThis ); \
caf::AddFieldIOScriptabilityToField( field, keyword )
#define CAF_PDM_InitScriptableFieldWithIOAndScriptName( field, \
keyword, \
scriptKeyword, \
default, \
uiName, \
iconResourceName, \
toolTip, \
whatsThis ) \
CAF_PDM_InitField( field, \
keyword, \
default, \
uiName, \
iconResourceName, \
caf::PdmFieldScriptability::helpString( toolTip, scriptKeyword ), \
whatsThis ); \
caf::AddFieldIOScriptabilityToField( field, scriptKeyword )
#define CAF_PDM_InitScriptableFieldWithIOAndScriptNameNoDefault( field, \
keyword, \
scriptKeyword, \
uiName, \
iconResourceName, \
toolTip, \
whatsThis ) \
CAF_PDM_InitFieldNoDefault( field, \
keyword, \
uiName, \
iconResourceName, \
caf::PdmFieldScriptability::helpString( toolTip, scriptKeyword ), \
whatsThis ); \
caf::AddFieldIOScriptabilityToField( field, scriptKeyword )
namespace caf
{
template <typename DataType>
struct PdmFieldScriptabilityIOHandler
{
static void writeToField( DataType& fieldValue,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true )
{
inputStream >> fieldValue;
if ( inputStream.status() == QTextStream::ReadCorruptData )
{
errorMessageContainer->addError( "Argument value is unreadable in the argument: \"" +
errorMessageContainer->currentArgument + "\" in the command: \"" +
errorMessageContainer->currentCommand + "\"" );
inputStream.setStatus( QTextStream::Ok );
}
}
static void readFromField( const DataType& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false )
{
outputStream << fieldValue;
}
};
template <>
struct PdmFieldScriptabilityIOHandler<QString>
{
static void writeToField( QString& fieldValue,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true );
static void readFromField( const QString& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false );
};
template <>
struct PdmFieldScriptabilityIOHandler<bool>
{
static void writeToField( bool& fieldValue,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true );
static void readFromField( const bool& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false );
};
template <>
struct PdmFieldScriptabilityIOHandler<cvf::Color3f>
{
static void writeToField( cvf::Color3f& fieldValue,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true );
static void readFromField( const cvf::Color3f& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false );
};
template <typename T>
struct PdmFieldScriptabilityIOHandler<AppEnum<T>>
{
static void writeToField( AppEnum<T>& fieldValue,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true )
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
QString accumulatedFieldValue;
QChar nextChar;
QChar currentChar;
while ( !inputStream.atEnd() )
{
nextChar = errorMessageContainer->peekNextChar( inputStream );
if ( nextChar.isLetterOrNumber() || nextChar == QChar( '_' ) )
{
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
accumulatedFieldValue += currentChar;
}
else
{
break;
}
}
if ( !fieldValue.setFromText( accumulatedFieldValue ) )
{
// Unexpected enum value
// Error message
errorMessageContainer->addError( "Argument must be valid enum value. " +
errorMessageContainer->currentArgument + "\" argument of the command: \"" +
errorMessageContainer->currentCommand + "\"" );
}
}
static void readFromField( const AppEnum<T>& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false )
{
if ( quoteNonBuiltins )
{
outputStream << "\"" << fieldValue << "\"";
}
else
{
outputStream << fieldValue;
}
}
};
template <typename T>
struct PdmFieldScriptabilityIOHandler<std::vector<T>>
{
static void writeToField( std::vector<T>& fieldValue,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true )
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
QChar chr = errorMessageContainer->readCharWithLineNumberCount( inputStream );
if ( chr == QChar( '[' ) )
{
while ( !inputStream.atEnd() )
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
QChar nextChar = errorMessageContainer->peekNextChar( inputStream );
if ( nextChar == QChar( ']' ) )
{
nextChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
break;
}
else if ( nextChar == QChar( ',' ) )
{
nextChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
}
T value;
PdmFieldScriptabilityIOHandler<T>::writeToField( value, inputStream, errorMessageContainer, true );
fieldValue.push_back( value );
}
}
else
{
errorMessageContainer->addError( "Array argument is missing start '['. " +
errorMessageContainer->currentArgument + "\" argument of the command: \"" +
errorMessageContainer->currentCommand + "\"" );
}
}
static void readFromField( const std::vector<T>& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false )
{
outputStream << "[";
for ( size_t i = 0; i < fieldValue.size(); ++i )
{
PdmFieldScriptabilityIOHandler<T>::readFromField( fieldValue[i], outputStream, quoteNonBuiltins );
if ( i < fieldValue.size() - 1 )
{
outputStream << ", ";
}
}
outputStream << "]";
}
};
template <typename T>
struct PdmFieldScriptabilityIOHandler<std::vector<T*>>
{
static void writeToField( std::vector<T*>& fieldValue,
const std::vector<T*>& allObjectsOfType,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer )
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
QChar chr = errorMessageContainer->readCharWithLineNumberCount( inputStream );
if ( chr == QChar( '[' ) )
{
while ( !inputStream.atEnd() )
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
QChar nextChar = errorMessageContainer->peekNextChar( inputStream );
if ( nextChar == QChar( ']' ) )
{
nextChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
break;
}
else if ( nextChar == QChar( ',' ) )
{
nextChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
}
T* value;
PdmFieldScriptabilityIOHandler<T*>::writeToField( value, allObjectsOfType, inputStream, errorMessageContainer );
fieldValue.push_back( value );
}
}
else
{
errorMessageContainer->addError( "Array argument is missing start '['. " +
errorMessageContainer->currentArgument + "\" argument of the command: \"" +
errorMessageContainer->currentCommand + "\"" );
}
}
static void readFromField( const std::vector<T*>& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false )
{
outputStream << "[";
for ( size_t i = 0; i < fieldValue.size(); ++i )
{
PdmFieldScriptabilityIOHandler<T*>::readFromField( fieldValue[i], outputStream, quoteNonBuiltins );
if ( i < fieldValue.size() - 1 )
{
outputStream << ", ";
}
}
outputStream << "]";
}
};
template <typename DataType>
struct PdmFieldScriptabilityIOHandler<DataType*>
{
static void writeToField( DataType*& fieldValue,
const std::vector<DataType*>& allObjectsOfType,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer )
{
QString fieldString;
PdmFieldScriptabilityIOHandler<QString>::writeToField( fieldString, inputStream, errorMessageContainer, true );
if ( inputStream.status() == QTextStream::ReadCorruptData )
{
errorMessageContainer->addError( "Argument value is unreadable in the argument: \"" +
errorMessageContainer->currentArgument + "\" in the command: \"" +
errorMessageContainer->currentCommand + "\"" );
inputStream.setStatus( QTextStream::Ok );
return;
}
QStringList classAndAddress = fieldString.split( ":" );
CAF_ASSERT( classAndAddress.size() == 2 );
qulonglong address = classAndAddress[1].toULongLong();
fieldValue = nullptr;
for ( DataType* object : allObjectsOfType )
{
if ( reinterpret_cast<qulonglong>( object ) == address )
{
fieldValue = object;
break;
}
}
}
static void readFromField( const DataType* fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false )
{
outputStream
<< QString( "%1:%2" ).arg( DataType::classKeywordStatic() ).arg( reinterpret_cast<uint64_t>( fieldValue ) );
}
};
//==================================================================================================
//
//
//
//==================================================================================================
template <typename FieldType>
class PdmFieldIOScriptability : public PdmFieldScriptability
{
public:
PdmFieldIOScriptability( FieldType* field, const QString& fieldName, bool giveOwnership )
: PdmFieldScriptability( field, fieldName, giveOwnership )
{
m_field = field;
}
// Xml Serializing
public:
void writeToField( QTextStream& inputStream,
PdmObjectFactory* objectFactory,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true,
caf::PdmObjectHandle* existingObjectsRoot = nullptr ) override
{
typename FieldType::FieldDataType value;
PdmFieldScriptabilityIOHandler<typename FieldType::FieldDataType>::writeToField( value,
inputStream,
errorMessageContainer,
stringsAreQuoted );
if ( this->isIOWriteable() )
{
m_field->setValue( value );
}
}
void readFromField( QTextStream& outputStream, bool quoteStrings = true, bool quoteNonBuiltins = false ) const override
{
PdmFieldScriptabilityIOHandler<typename FieldType::FieldDataType>::readFromField( m_field->value(),
outputStream,
quoteStrings,
quoteNonBuiltins );
}
private:
FieldType* m_field;
};
template <typename DataType>
class PdmFieldIOScriptability<PdmPtrField<DataType*>> : public PdmFieldScriptability
{
public:
PdmFieldIOScriptability( PdmPtrField<DataType*>* field, const QString& fieldName, bool giveOwnership )
: PdmFieldScriptability( field, fieldName, giveOwnership )
{
m_field = field;
}
// Xml Serializing
public:
void writeToField( QTextStream& inputStream,
PdmObjectFactory* objectFactory,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true,
caf::PdmObjectHandle* existingObjectsRoot = nullptr ) override
{
std::vector<DataType*> allObjectsOfType;
existingObjectsRoot->descendantsIncludingThisOfType( allObjectsOfType );
DataType* object;
PdmFieldScriptabilityIOHandler<std::vector<DataType*>>::writeToField( object,
allObjectsOfType,
inputStream,
errorMessageContainer );
if ( this->isIOWriteable() )
{
m_field->setValue( object );
}
}
void readFromField( QTextStream& outputStream, bool quoteStrings = true, bool quoteNonBuiltins = false ) const override
{
PdmFieldScriptabilityIOHandler<DataType*>::readFromField( m_field->value(),
outputStream,
quoteStrings,
quoteNonBuiltins );
}
private:
PdmPtrField<DataType*>* m_field;
};
template <typename DataType>
class PdmFieldIOScriptability<PdmPtrArrayField<DataType*>> : public PdmFieldScriptability
{
public:
PdmFieldIOScriptability( PdmPtrArrayField<DataType*>* field, const QString& fieldName, bool giveOwnership )
: PdmFieldScriptability( field, fieldName, giveOwnership )
{
m_field = field;
}
// Xml Serializing
public:
void writeToField( QTextStream& inputStream,
PdmObjectFactory* objectFactory,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true,
caf::PdmObjectHandle* existingObjectsRoot = nullptr ) override
{
std::vector<DataType*> allObjectsOfType;
existingObjectsRoot->descendantsIncludingThisOfType( allObjectsOfType );
std::vector<DataType*> objects;
PdmFieldScriptabilityIOHandler<std::vector<DataType*>>::writeToField( objects,
allObjectsOfType,
inputStream,
errorMessageContainer );
if ( this->isIOWriteable() )
{
m_field->setValue( objects );
}
}
void readFromField( QTextStream& outputStream, bool quoteStrings = true, bool quoteNonBuiltins = false ) const override
{
PdmFieldScriptabilityIOHandler<std::vector<DataType*>>::readFromField( m_field->ptrReferencedObjects(),
outputStream,
quoteStrings,
quoteNonBuiltins );
}
private:
PdmPtrArrayField<DataType*>* m_field;
};
template <typename FieldType>
void AddFieldIOScriptabilityToField( FieldType* field, const QString& fieldName )
{
if ( field->template capability<PdmFieldIOScriptability<FieldType>>() == nullptr )
{
new PdmFieldIOScriptability<FieldType>( field, fieldName, true );
}
}
} // namespace caf
@@ -36,19 +36,19 @@
#include "cafPdmFieldScriptability.h"
#include "cafPdmFieldHandle.h"
#include "cafPdmPythonGenerator.h"
using namespace caf;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmFieldScriptability::PdmFieldScriptability(caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership)
PdmFieldScriptability::PdmFieldScriptability( caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership )
{
m_IOWriteable = true;
m_owner = owner;
m_IOWriteable = true;
m_owner = owner;
m_scriptFieldName = scriptFieldName;
owner->addCapability(this, giveOwnership);
owner->addCapability( this, giveOwnership );
}
//--------------------------------------------------------------------------------------------------
@@ -56,7 +56,6 @@ PdmFieldScriptability::PdmFieldScriptability(caf::PdmFieldHandle* owner, const Q
//--------------------------------------------------------------------------------------------------
PdmFieldScriptability::~PdmFieldScriptability()
{
}
//--------------------------------------------------------------------------------------------------
@@ -78,7 +77,7 @@ bool PdmFieldScriptability::isIOWriteable() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptability::setIOWriteable(bool writeable)
void PdmFieldScriptability::setIOWriteable( bool writeable )
{
m_IOWriteable = writeable;
}
@@ -86,26 +85,43 @@ void PdmFieldScriptability::setIOWriteable(bool writeable)
//--------------------------------------------------------------------------------------------------
/// Empty default implementation that doesn't offer any script IO for the field
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptability::readFromField(QTextStream& outputStream, bool quoteStrings /*= true*/, bool quoteNonBuiltins /*= false*/) const
void PdmFieldScriptability::readFromField( QTextStream& outputStream,
bool quoteStrings /*= true*/,
bool quoteNonBuiltins /*= false*/ ) const
{
}
//--------------------------------------------------------------------------------------------------
/// Empty default implementation that doesn't offer any script IO for the field
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptability::writeToField(QTextStream& inputStream, caf::PdmObjectFactory* objectFactory, caf::PdmScriptIOMessages* errorMessageContainer, bool stringsAreQuoted /*= true*/)
void PdmFieldScriptability::writeToField( QTextStream& inputStream,
caf::PdmObjectFactory* objectFactory,
caf::PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted /*= true*/,
caf::PdmObjectHandle* existingObjectsRoot /*= nullptr*/ )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptability::addToField(caf::PdmFieldHandle* field, const QString& fieldName)
void PdmFieldScriptability::addToField( caf::PdmFieldHandle* field, const QString& fieldName )
{
if (field->template capability<PdmFieldScriptability>() == nullptr)
if ( field->template capability<PdmFieldScriptability>() == nullptr )
{
new PdmFieldScriptability(field, fieldName, true);
new PdmFieldScriptability( field, fieldName, true );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmFieldScriptability::helpString( const QString& existingTooltip, const QString& keyword )
{
QString snake_case = caf::PdmPythonGenerator::camelToSnakeCase( keyword );
QString helpString = QString( "Available through python/rips as the attribute '%1'" ).arg( snake_case );
if ( !existingTooltip.isEmpty() ) return existingTooltip + "\n\n" + helpString;
return helpString;
}
@@ -35,79 +35,81 @@
//##################################################################################################
#pragma once
#include <QString>
#include "cafPdmFieldCapability.h"
#include <QString>
class QTextStream;
namespace caf {
namespace caf
{
class PdmFieldHandle;
class PdmObjectFactory;
class PdmObjectHandle;
class PdmScriptIOMessages;
#define CAF_PDM_InitScriptableField( field, keyword, default, uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitField( field, \
keyword, \
default, \
uiName, \
iconResourceName, \
caf::PdmPythonGenerator::pythonHelpString( toolTip, keyword ), \
whatsThis ); \
CAF_PDM_InitField( field, \
keyword, \
default, \
uiName, \
iconResourceName, \
caf::PdmFieldScriptability::helpString( toolTip, keyword ), \
whatsThis ); \
caf::PdmFieldScriptability::addToField( field, keyword )
#define CAF_PDM_InitScriptableFieldNoDefault( field, keyword, uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitFieldNoDefault( field, \
keyword, \
uiName, \
iconResourceName, \
caf::PdmPythonGenerator::pythonHelpString( toolTip, keyword ), \
whatsThis ); \
CAF_PDM_InitFieldNoDefault( field, \
keyword, \
uiName, \
iconResourceName, \
caf::PdmFieldScriptability::helpString( toolTip, keyword ), \
whatsThis ); \
caf::PdmFieldScriptability::addToField( field, keyword )
#define CAF_PDM_InitScriptableFieldWithKeyword( field, keyword, scriptKeyword, default, uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitField( field, \
keyword, \
default, \
uiName, \
iconResourceName, \
caf::PdmPythonGenerator::pythonHelpString( toolTip, scriptKeyword ), \
whatsThis ); \
CAF_PDM_InitField( field, \
keyword, \
default, \
uiName, \
iconResourceName, \
caf::PdmFieldScriptability::helpString( toolTip, scriptKeyword ), \
whatsThis ); \
caf::PdmFieldScriptability::addToField( field, scriptKeyword )
#define CAF_PDM_InitScriptableFieldWithKeywordNoDefault( field, keyword, scriptKeyword, uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitFieldNoDefault( field, \
keyword, \
uiName, \
iconResourceName, \
caf::PdmPythonGenerator::pythonHelpString( toolTip, scriptKeyword ), \
whatsThis ); \
CAF_PDM_InitFieldNoDefault( field, \
keyword, \
uiName, \
iconResourceName, \
caf::PdmFieldScriptability::helpString( toolTip, scriptKeyword ), \
whatsThis ); \
caf::PdmFieldScriptability::addToField( field, scriptKeyword )
class PdmFieldScriptability : public PdmFieldCapability
{
public:
PdmFieldScriptability(caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership);
PdmFieldScriptability( caf::PdmFieldHandle* owner, const QString& scriptFieldName, bool giveOwnership );
virtual ~PdmFieldScriptability();
const QString scriptFieldName() const;
bool isIOWriteable() const;
void setIOWriteable(bool writeable);
void setIOWriteable( bool writeable );
virtual void readFromField(QTextStream& outputStream, bool quoteStrings = true, bool quoteNonBuiltins = false) const;
virtual void writeToField(QTextStream& inputStream,
caf::PdmObjectFactory* objectFactory,
caf::PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true);
virtual void readFromField( QTextStream& outputStream, bool quoteStrings = true, bool quoteNonBuiltins = false ) const;
virtual void writeToField( QTextStream& inputStream,
caf::PdmObjectFactory* objectFactory,
caf::PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true,
caf::PdmObjectHandle* existingObjectsRoot = nullptr );
static void addToField(caf::PdmFieldHandle* field, const QString& fieldName);
private:
caf::PdmFieldHandle* m_owner;
QString m_scriptFieldName;
bool m_IOWriteable;
static void addToField( caf::PdmFieldHandle* field, const QString& fieldName );
static QString helpString( const QString& existingTooltip, const QString& keyword );
protected:
PdmFieldHandle* m_owner;
QString m_scriptFieldName;
bool m_IOWriteable;
};
}
} // namespace caf
@@ -0,0 +1,95 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmObjectMethod.h"
using namespace caf;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmObjectMethodFactory* PdmObjectMethodFactory::instance()
{
static PdmObjectMethodFactory* factory = new PdmObjectMethodFactory;
return factory;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::shared_ptr<PdmObjectMethod> PdmObjectMethodFactory::createMethod( PdmObjectHandle* self, const QString& methodName )
{
QString className = self->xmlCapability()->classKeyword();
auto classIt = m_factoryMap.find( className );
if ( classIt != m_factoryMap.end() )
{
auto methodIt = classIt->second.find( methodName );
if ( methodIt != classIt->second.end() )
{
return methodIt->second->create( self );
}
}
return std::shared_ptr<PdmObjectMethod>();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> PdmObjectMethodFactory::registeredMethodNames( const PdmObjectHandle* self ) const
{
std::vector<QString> methods;
QString className = self->xmlCapability()->classKeyword();
auto classIt = m_factoryMap.find( className );
if ( classIt != m_factoryMap.end() )
{
for ( auto methodPair : classIt->second )
{
methods.push_back( methodPair.first );
}
}
return methods;
}
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( PdmObjectMethod, "PdmObjectMethod" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmObjectMethod::PdmObjectMethod( PdmObjectHandle* self )
: m_self( self )
{
}
@@ -0,0 +1,151 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafAssert.h"
#include "cafPdmObject.h"
#include "cafPdmObjectFactory.h"
#include "cafPdmPointer.h"
#include "cafPdmScriptResponse.h"
/// CAF_PDM_OBJECT_METHOD_SOURCE_INIT associates the self class keyword and the method keyword with the method factory
/// Place this in the cpp file, preferably above the constructor
#define CAF_PDM_OBJECT_METHOD_SOURCE_INIT( SelfClassName, MethodClassName, methodKeyword ) \
CAF_PDM_XML_ABSTRACT_SOURCE_INIT( MethodClassName, methodKeyword ) \
static bool PDM_OBJECT_STRING_CONCATENATE( method##MethodClassName, __LINE__ ) = \
caf::PdmObjectMethodFactory::instance()->registerMethod<SelfClassName, MethodClassName>()
namespace caf
{
//==================================================================================================
/// PdmObject script method
/// Sub-class and register to the PdmObject
/// Store arguments as member fields and set a return values in the return value for execute
//==================================================================================================
class PdmObjectMethod : public PdmObject
{
CAF_PDM_HEADER_INIT;
public:
PdmObjectMethod( PdmObjectHandle* self );
// The returned object contains the results of the method and is the responsibility of the caller.
virtual PdmObjectHandle* execute() = 0;
virtual QString selfClassKeyword() const { return m_self->xmlCapability()->classKeyword(); }
// False if object is a persistent project tree item. True if the object is to be deleted on completion.
virtual bool deleteObjectAfterReply() const = 0;
protected:
// Basically the "this" pointer to the object the method belongs to
template <typename PdmObjectType>
PdmObjectType* self()
{
PdmObjectType* object = dynamic_cast<PdmObjectType*>( m_self.p() );
CAF_ASSERT( object );
return object;
}
private:
friend class PdmObjectScriptability;
PdmPointer<PdmObjectHandle> m_self;
};
//==================================================================================================
/// PdmObject script method factory
/// Register methods with this factory to be able to create and call methods.
//==================================================================================================
class PdmObjectMethodFactory
{
public:
static PdmObjectMethodFactory* instance();
std::shared_ptr<PdmObjectMethod> createMethod( PdmObjectHandle* self, const QString& methodName );
template <typename PdmObjectDerivative, typename PdmObjectScriptMethodDerivative>
bool registerMethod()
{
QString className = PdmObjectDerivative::classKeywordStatic();
QString methodName = PdmObjectScriptMethodDerivative::classKeywordStatic();
auto classEntryIt = m_factoryMap.find( className );
if ( classEntryIt != m_factoryMap.end() )
{
auto methodEntryIt = classEntryIt->second.find( methodName );
if ( methodEntryIt != classEntryIt->second.end() )
{
CAF_ASSERT( methodName != methodEntryIt->first ); // classNameKeyword has already been used
CAF_ASSERT( false ); // To be sure ..
return false; // never hit;
}
}
m_factoryMap[className][methodName] =
std::shared_ptr<PdmObjectMethodCreatorBase>( new PdmObjectMethodCreator<PdmObjectScriptMethodDerivative>() );
return true;
}
std::vector<QString> registeredMethodNames( const PdmObjectHandle* self ) const;
private:
PdmObjectMethodFactory() = default;
~PdmObjectMethodFactory() = default;
// Internal helper classes
class PdmObjectMethodCreatorBase
{
public:
PdmObjectMethodCreatorBase() {}
virtual ~PdmObjectMethodCreatorBase() {}
virtual std::shared_ptr<PdmObjectMethod> create( PdmObjectHandle* self ) = 0;
};
template <typename PdmObjectScriptMethodDerivative>
class PdmObjectMethodCreator : public PdmObjectMethodCreatorBase
{
public:
std::shared_ptr<PdmObjectMethod> create( PdmObjectHandle* self ) override
{
return std::shared_ptr<PdmObjectMethod>( new PdmObjectScriptMethodDerivative( self ) );
}
};
private:
// Map to store factory
std::map<QString, std::map<QString, std::shared_ptr<PdmObjectMethodCreatorBase>>> m_factoryMap;
// Self pointer
}; // namespace caf
} // namespace caf
@@ -0,0 +1,240 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmObjectScriptability.h"
#include "cafPdmFieldScriptability.h"
#include "cafPdmObject.h"
#include "cafPdmObjectHandle.h"
#include "cafPdmScriptIOMessages.h"
#include "cafPdmXmlFieldHandle.h"
#include <QTextStream>
using namespace caf;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmObjectScriptability::PdmObjectScriptability( PdmObjectHandle* owner, bool giveOwnership )
: m_owner( owner )
{
m_owner->addCapability( this, giveOwnership );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmObjectScriptability::~PdmObjectScriptability()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmObjectScriptability::readFields( QTextStream& inputStream,
PdmObjectFactory* objectFactory,
PdmScriptIOMessages* errorMessageContainer )
{
std::set<QString> readFields;
bool isLastArgumentRead = false;
while ( !inputStream.atEnd() && !isLastArgumentRead )
{
// Read field keyword
bool fieldDataFound = false;
bool isEndOfArgumentFound = false;
QString keyword;
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
{
QChar currentChar;
while ( !inputStream.atEnd() )
{
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
if ( currentChar == QChar( '=' ) || currentChar == QChar( ')' ) || currentChar == QChar( ',' ) ||
currentChar.isSpace() )
{
break;
}
else
{
keyword += currentChar;
}
}
if ( currentChar.isSpace() )
{
errorMessageContainer->skipWhiteSpaceWithLineNumberCount( inputStream );
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
}
if ( currentChar == QChar( '=' ) )
{
fieldDataFound = true;
}
else if ( currentChar == QChar( ')' ) )
{
if ( !keyword.isNull() )
{
errorMessageContainer->addError(
QString( "Can't find the '=' after the argument named '%1' in the command '%2'" )
.arg( keyword )
.arg( errorMessageContainer->currentCommand ) );
}
isLastArgumentRead = true;
}
else if ( currentChar == QChar( ',' ) )
{
errorMessageContainer->addError(
QString( "Can't find the '=' after the argument named '%1' in the command '%2'" )
.arg( keyword )
.arg( errorMessageContainer->currentCommand ) );
isEndOfArgumentFound = true;
}
else
{
errorMessageContainer->addError(
QString( "Can't find the '=' after the argument named '%1' in the command '%2'" )
.arg( keyword )
.arg( errorMessageContainer->currentCommand ) );
}
}
if ( readFields.count( keyword ) )
{
// Warning message: Referenced the same argument several times
errorMessageContainer->addWarning( "The argument: \"" + keyword +
"\" is referenced several times in the command: \"" +
errorMessageContainer->currentCommand + "\"" );
}
}
if ( fieldDataFound )
{
// Make field read its data
PdmFieldHandle* fieldHandle = m_owner->findField( keyword );
if ( fieldHandle && fieldHandle->xmlCapability() && fieldHandle->capability<PdmFieldScriptability>() )
{
PdmXmlFieldHandle* xmlFieldHandle = fieldHandle->xmlCapability();
PdmFieldScriptability* scriptability = fieldHandle->capability<PdmFieldScriptability>();
if ( xmlFieldHandle->isIOReadable() )
{
errorMessageContainer->currentArgument = keyword;
scriptability->writeToField( inputStream, objectFactory, errorMessageContainer );
errorMessageContainer->currentArgument = keyword;
}
}
else
{
// Error message: Unknown argument name
errorMessageContainer->addWarning( "The argument: \"" + keyword + "\" does not exist in the command: \"" +
errorMessageContainer->currentCommand + "\"" );
}
}
// Skip to end of argument ',' or end of call ')'
if ( !( isLastArgumentRead || isEndOfArgumentFound ) )
{
QChar currentChar;
bool isOutsideQuotes = true;
while ( !inputStream.atEnd() )
{
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
if ( isOutsideQuotes )
{
if ( currentChar == QChar( ',' ) )
{
break;
}
if ( currentChar == QChar( ')' ) )
{
isLastArgumentRead = true;
break;
}
if ( currentChar == QChar( '\"' ) )
{
isOutsideQuotes = false;
}
}
else
{
if ( currentChar == QChar( '\"' ) )
{
isOutsideQuotes = true;
}
if ( currentChar == QChar( '\\' ) )
{
currentChar = errorMessageContainer->readCharWithLineNumberCount( inputStream );
}
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmObjectScriptability::writeFields( QTextStream& outputStream ) const
{
std::vector<PdmFieldHandle*> fields;
m_owner->fields( fields );
int writtenFieldCount = 0;
for ( size_t it = 0; it < fields.size(); ++it )
{
const PdmXmlFieldHandle* xmlField = fields[it]->xmlCapability();
const PdmFieldScriptability* scriptability = fields[it]->capability<PdmFieldScriptability>();
if ( scriptability && xmlField && xmlField->isIOWritable() )
{
QString keyword = xmlField->fieldHandle()->keyword();
CAF_ASSERT( PdmXmlObjectHandle::isValidXmlElementName( keyword ) );
if ( writtenFieldCount >= 1 )
{
outputStream << ", ";
}
outputStream << keyword << " = ";
scriptability->readFromField( outputStream );
writtenFieldCount++;
}
}
}
@@ -0,0 +1,84 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafPdmChildArrayField.h"
#include "cafPdmObjectCapability.h"
#include "cafPdmObjectMethod.h"
#include "cafPdmObjectScriptabilityRegister.h"
#include <QString>
#include <map>
#include <memory>
#include <vector>
class QTextStream;
#define CAF_PDM_InitScriptableObject( uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \
caf::PdmObjectScriptabilityRegister::registerScriptClassNameAndComment( classKeyword(), classKeyword(), whatsThis );
#define CAF_PDM_InitScriptableObjectWithNameAndComment( uiName, iconResourceName, toolTip, whatsThis, scriptClassName, scriptComment ) \
CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \
caf::PdmObjectScriptabilityRegister::registerScriptClassNameAndComment( classKeyword(), scriptClassName, scriptComment );
namespace caf
{
class PdmObject;
class PdmObjectHandle;
class PdmObjectFactory;
class PdmScriptIOMessages;
//==================================================================================================
//
//
//
//==================================================================================================
class PdmObjectScriptability : public PdmObjectCapability
{
public:
PdmObjectScriptability( PdmObjectHandle* owner, bool giveOwnership );
~PdmObjectScriptability() override;
void readFields( QTextStream& inputStream, PdmObjectFactory* objectFactory, PdmScriptIOMessages* errorMessageContainer );
void writeFields( QTextStream& outputStream ) const;
private:
PdmObjectHandle* m_owner;
};
} // namespace caf
@@ -39,16 +39,8 @@
#include <map>
#define CAF_PDM_InitScriptableObject( uiName, iconResourceName, toolTip, whatsThis ) \
CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \
caf::PdmObjectScriptabilityRegister::registerScriptClassNameAndComment( classKeyword(), classKeyword(), whatsThis );
#define CAF_PDM_InitScriptableObjectWithNameAndComment( uiName, iconResourceName, toolTip, whatsThis, scriptClassName, scriptComment ) \
CAF_PDM_InitObject( uiName, iconResourceName, toolTip, whatsThis ); \
caf::PdmObjectScriptabilityRegister::registerScriptClassNameAndComment( classKeyword(), scriptClassName, scriptComment );
namespace caf {
namespace caf
{
class PdmObject;
//==================================================================================================
@@ -57,14 +49,14 @@ class PdmObject;
class PdmObjectScriptabilityRegister
{
public:
static void registerScriptClassNameAndComment(const QString& classKeyword,
const QString& scriptClassName,
const QString& scriptClassComment);
static QString scriptClassNameFromClassKeyword(const QString& classKeyword);
static QString classKeywordFromScriptClassName(const QString& scriptClassName);
static QString scriptClassComment(const QString& classKeyword);
static void registerScriptClassNameAndComment( const QString& classKeyword,
const QString& scriptClassName,
const QString& scriptClassComment );
static QString scriptClassNameFromClassKeyword( const QString& classKeyword );
static QString classKeywordFromScriptClassName( const QString& scriptClassName );
static QString scriptClassComment( const QString& classKeyword );
static bool isScriptable(const caf::PdmObject* object);
static bool isScriptable( const caf::PdmObject* object );
private:
static std::map<QString, QString> s_classKeywordToScriptClassName;
@@ -72,4 +64,4 @@ private:
static std::map<QString, QString> s_scriptClassComments;
};
}
} // namespace caf
@@ -40,6 +40,7 @@
#include "cafPdmFieldScriptability.h"
#include "cafPdmObject.h"
#include "cafPdmObjectFactory.h"
#include "cafPdmObjectMethod.h"
#include "cafPdmObjectScriptabilityRegister.h"
#include "cafPdmProxyValueField.h"
#include "cafPdmXmlFieldHandle.h"
@@ -53,186 +54,231 @@
using namespace caf;
CAF_PDM_CODE_GENERATOR_SOURCE_INIT(PdmPythonGenerator, "py");
CAF_PDM_CODE_GENERATOR_SOURCE_INIT( PdmPythonGenerator, "py" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
QString PdmPythonGenerator::generate( PdmObjectFactory* factory ) const
{
QString generatedCode;
QTextStream out(&generatedCode);
QTextStream out( &generatedCode );
std::vector<QString> classKeywords = factory->classKeywords();
std::vector<std::shared_ptr<const PdmObject>> dummyObjects;
for (QString classKeyword : classKeywords)
std::vector<std::shared_ptr<PdmObject>> dummyObjects;
for ( QString classKeyword : classKeywords )
{
auto objectHandle = factory->create(classKeyword);
const PdmObject* object = dynamic_cast<const PdmObject*>(objectHandle);
CAF_ASSERT(object);
auto objectHandle = factory->create( classKeyword );
PdmObject* object = dynamic_cast<PdmObject*>( objectHandle );
CAF_ASSERT( object );
std::shared_ptr<const PdmObject> sharedObject(object);
if (PdmObjectScriptabilityRegister::isScriptable(sharedObject.get()))
std::shared_ptr<PdmObject> sharedObject( object );
if ( PdmObjectScriptabilityRegister::isScriptable( sharedObject.get() ) )
{
dummyObjects.push_back(sharedObject);
dummyObjects.push_back( sharedObject );
}
}
// Sort to make sure super classes get created before sub classes
std::sort(dummyObjects.begin(),
dummyObjects.end(),
[](std::shared_ptr<const PdmObject> lhs, std::shared_ptr<const PdmObject> rhs) {
if (lhs->inheritsClassWithKeyword(rhs->classKeyword()))
{
return false;
}
return lhs->classKeyword() < rhs->classKeyword();
});
std::sort( dummyObjects.begin(), dummyObjects.end(), []( std::shared_ptr<PdmObject> lhs, std::shared_ptr<PdmObject> rhs ) {
if ( lhs->inheritsClassWithKeyword( rhs->classKeyword() ) )
{
return false;
}
return lhs->classKeyword() < rhs->classKeyword();
} );
std::map<QString, std::map<QString, std::pair<QString, QString>>> classAttributesGenerated;
std::map<QString, std::map<QString, QString>> classMethodsGenerated;
std::map<QString, QString> classCommentsGenerated;
// First generate all attributes and comments to go into each object
for (std::shared_ptr<const PdmObject> object : dummyObjects)
for ( std::shared_ptr<PdmObject> object : dummyObjects )
{
const std::list<QString>& classInheritanceStack = object->classInheritanceStack();
for (auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it)
for ( auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it )
{
const QString& classKeyword = *it;
QString scriptClassComment = PdmObjectScriptabilityRegister::scriptClassComment(classKeyword);
const QString& classKeyword = *it;
QString scriptClassComment = PdmObjectScriptabilityRegister::scriptClassComment( classKeyword );
std::map<QString, QString> attributesGenerated;
if (!scriptClassComment.isEmpty()) classCommentsGenerated[classKeyword] = scriptClassComment;
if ( !scriptClassComment.isEmpty() ) classCommentsGenerated[classKeyword] = scriptClassComment;
if (classKeyword == object->classKeyword())
if ( classKeyword == object->classKeyword() )
{
std::vector<PdmFieldHandle*> fields;
object->fields(fields);
for (auto field : fields)
object->fields( fields );
for ( auto field : fields )
{
auto scriptability = field->template capability<PdmFieldScriptability>();
if (scriptability != nullptr)
auto scriptability = field->template capability<PdmFieldScriptability>();
if ( scriptability != nullptr )
{
QString snake_field_name = camelToSnakeCase(scriptability->scriptFieldName());
QString snake_field_name = camelToSnakeCase( scriptability->scriptFieldName() );
QString comment;
{
QStringList commentComponents;
commentComponents << field->capability<PdmUiFieldHandle>()->uiName();
commentComponents << field->capability<PdmUiFieldHandle>()->uiWhatsThis();
commentComponents.removeAll(QString(""));
comment = commentComponents.join(". ");
commentComponents.removeAll( QString( "" ) );
comment = commentComponents.join( ". " );
}
auto pdmValueField = dynamic_cast<const PdmValueField*>(field);
auto pdmChildField = dynamic_cast<const PdmChildFieldHandle*>(field);
auto pdmChildArrayField = dynamic_cast<const PdmChildArrayFieldHandle*>(field);
if (pdmValueField)
auto pdmValueField = dynamic_cast<const PdmValueField*>( field );
auto pdmChildField = dynamic_cast<const PdmChildFieldHandle*>( field );
auto pdmChildArrayField = dynamic_cast<const PdmChildArrayFieldHandle*>( field );
if ( pdmValueField )
{
QString dataType = PdmPythonGenerator::dataTypeString(field, true);
if (field->xmlCapability()->isVectorField())
QString dataType = PdmPythonGenerator::dataTypeString( field, true );
if ( field->xmlCapability()->isVectorField() )
{
dataType = QString("List of %1").arg(dataType);
dataType = QString( "List of %1" ).arg( dataType );
}
bool shouldBeMethod = false;
auto proxyField = dynamic_cast<const PdmProxyFieldHandle*>(field);
if (proxyField && proxyField->isStreamingField()) shouldBeMethod = true;
auto proxyField = dynamic_cast<const PdmProxyFieldHandle*>( field );
if ( proxyField && proxyField->isStreamingField() ) shouldBeMethod = true;
if (classAttributesGenerated[field->ownerClass()].count(snake_field_name)) continue;
if (classMethodsGenerated[field->ownerClass()].count(snake_field_name)) continue;
if ( classAttributesGenerated[field->ownerClass()].count( snake_field_name ) ) continue;
if ( classMethodsGenerated[field->ownerClass()].count( snake_field_name ) ) continue;
QVariant valueVariant = pdmValueField->toQVariant();
if (shouldBeMethod)
if ( shouldBeMethod )
{
if (proxyField->hasGetter())
if ( proxyField->hasGetter() )
{
QString fullComment =
QString(" \"\"\"%1\n Returns:\n %2\n \"\"\"")
.arg(comment)
.arg(dataType);
QString( " \"\"\"%1\n Returns:\n %2\n \"\"\"" )
.arg( comment )
.arg( dataType );
QString fieldCode = QString(" def %1(self):\n%2\n return "
"self._call_get_method(\"%3\")\n")
.arg(snake_field_name)
.arg(fullComment)
.arg(scriptability->scriptFieldName());
QString fieldCode = QString( " def %1(self):\n%2\n return "
"self._call_get_method(\"%3\")\n" )
.arg( snake_field_name )
.arg( fullComment )
.arg( scriptability->scriptFieldName() );
classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode;
}
if (proxyField->hasSetter())
if ( proxyField->hasSetter() )
{
QString fullComment = QString(" \"\"\"Set %1\n Arguments:\n"
" values (%2): data\n \"\"\"")
.arg(comment)
.arg(dataType);
QString fullComment = QString( " \"\"\"Set %1\n Arguments:\n"
" values (%2): data\n \"\"\"" )
.arg( comment )
.arg( dataType );
QString fieldCode = QString(" def set_%1(self, values):\n%2\n "
"self._call_set_method(\"%3\", values)\n")
.arg(snake_field_name)
.arg(fullComment)
.arg(scriptability->scriptFieldName());
classMethodsGenerated[field->ownerClass()][QString("set_%1").arg(snake_field_name)] =
QString fieldCode = QString( " def set_%1(self, values):\n%2\n "
"self._call_set_method(\"%3\", values)\n" )
.arg( snake_field_name )
.arg( fullComment )
.arg( scriptability->scriptFieldName() );
classMethodsGenerated[field->ownerClass()][QString( "set_%1" ).arg( snake_field_name )] =
fieldCode;
}
}
else
{
QString valueString;
QTextStream valueStream(&valueString);
scriptability->readFromField(valueStream, true, true);
if (valueString.isEmpty())
valueString = QString("\"\"");
valueString = pythonifyDataValue(valueString);
{
QString valueString;
QTextStream valueStream( &valueString );
scriptability->readFromField( valueStream, true, true );
if ( valueString.isEmpty() ) valueString = QString( "\"\"" );
valueString = pythonifyDataValue( valueString );
QString fieldCode =
QString( " self.%1 = %2\n" ).arg( snake_field_name ).arg( valueString );
QString fieldCode = QString(" self.%1 = %2\n").arg(snake_field_name).arg(valueString);
QString fullComment =
QString("%1 (%2): %3\n").arg(snake_field_name).arg(dataType).arg(comment);
QString( "%1 (%2): %3\n" ).arg( snake_field_name ).arg( dataType ).arg( comment );
classAttributesGenerated[field->ownerClass()][snake_field_name].first = fieldCode;
classAttributesGenerated[field->ownerClass()][snake_field_name].first = fieldCode;
classAttributesGenerated[field->ownerClass()][snake_field_name].second = fullComment;
}
}
else if (pdmChildField || pdmChildArrayField)
else if ( pdmChildField || pdmChildArrayField )
{
QString dataType = PdmPythonGenerator::dataTypeString(field, false);
QString scriptDataType = PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword(dataType);
QString dataType = PdmPythonGenerator::dataTypeString( field, false );
QString scriptDataType =
PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword( dataType );
QString commentDataType = field->xmlCapability()->isVectorField() ?
QString("List of %1").arg(scriptDataType) : scriptDataType;
QString commentDataType = field->xmlCapability()->isVectorField()
? QString( "List of %1" ).arg( scriptDataType )
: scriptDataType;
QString fullComment =
QString(" \"\"\"%1\n Returns:\n %2\n \"\"\"")
.arg(comment)
.arg(commentDataType);
QString( " \"\"\"%1\n Returns:\n %2\n \"\"\"" )
.arg( comment )
.arg( commentDataType );
if (pdmChildField)
if ( pdmChildField )
{
QString fieldCode = QString(" def %1(self):\n%2\n children = "
"self.children(\"%3\", %4)\n return children[0] if len(children) > 0 else None\n")
.arg(snake_field_name)
.arg(fullComment)
.arg(scriptability->scriptFieldName())
.arg(scriptDataType);
QString fieldCode = QString( " def %1(self):\n%2\n children = "
"self.children(\"%3\", %4)\n return children[0] if "
"len(children) > 0 else None\n" )
.arg( snake_field_name )
.arg( fullComment )
.arg( scriptability->scriptFieldName() )
.arg( scriptDataType );
classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode;
}
else
{
QString fieldCode = QString(" def %1(self):\n%2\n return "
"self.children(\"%3\", %4)\n")
.arg(snake_field_name)
.arg(fullComment)
.arg(scriptability->scriptFieldName())
.arg(scriptDataType);
QString fieldCode = QString( " def %1(self):\n%2\n return "
"self.children(\"%3\", %4)\n" )
.arg( snake_field_name )
.arg( fullComment )
.arg( scriptability->scriptFieldName() )
.arg( scriptDataType );
classMethodsGenerated[field->ownerClass()][snake_field_name] = fieldCode;
}
}
}
for ( QString methodName : PdmObjectMethodFactory::instance()->registeredMethodNames( object.get() ) )
{
std::shared_ptr<PdmObjectMethod> method =
PdmObjectMethodFactory::instance()->createMethod( object.get(), methodName );
std::vector<PdmFieldHandle*> arguments;
method->fields( arguments );
QString methodComment = method->uiCapability()->uiWhatsThis();
QString snake_method_name = camelToSnakeCase( methodName );
QStringList inputArgumentStrings;
QStringList outputArgumentStrings;
QStringList argumentComments;
outputArgumentStrings.push_back( QString( "\"%1\"" ).arg( methodName ) );
for ( auto field : arguments )
{
bool isList = field->xmlCapability()->isVectorField();
QString defaultValue = isList ? "[]" : "None";
auto scriptability = field->capability<PdmFieldScriptability>();
auto argumentName = camelToSnakeCase( scriptability->scriptFieldName() );
auto dataType = dataTypeString( field, false );
if ( isList ) dataType = "List of " + dataType;
inputArgumentStrings.push_back( QString( "%1=%2" ).arg( argumentName ).arg( defaultValue ) );
outputArgumentStrings.push_back( QString( "%1=%1" ).arg( argumentName ) );
argumentComments.push_back( QString( "%1 (%2): %3" )
.arg( argumentName )
.arg( dataType )
.arg( field->uiCapability()->uiWhatsThis() ) );
}
QString fullComment =
QString( " \"\"\"\n %1\n Arguments:\n %2\n \"\"\"" )
.arg( methodComment )
.arg( argumentComments.join( "\n " ) );
QString methodCode = QString( " def %1(self, %2):\n%3\n return "
"self._call_pdm_method(%4)\n" )
.arg( snake_method_name )
.arg( inputArgumentStrings.join( ", " ) )
.arg( fullComment )
.arg( outputArgumentStrings.join( ", " ) );
classMethodsGenerated[field->ownerClass()][snake_method_name] = methodCode;
}
}
}
}
@@ -240,42 +286,42 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
// Write out classes
std::set<QString> classesWritten;
for (std::shared_ptr<const PdmObject> object : dummyObjects)
for ( std::shared_ptr<PdmObject> object : dummyObjects )
{
const std::list<QString>& classInheritanceStack = object->classInheritanceStack();
std::list<QString> scriptSuperClassNames;
for (auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it)
for ( auto it = classInheritanceStack.begin(); it != classInheritanceStack.end(); ++it )
{
const QString& classKeyword = *it;
QString scriptClassName = PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword(classKeyword);
if (scriptClassName.isEmpty()) scriptClassName = classKeyword;
QString scriptClassName = PdmObjectScriptabilityRegister::scriptClassNameFromClassKeyword( classKeyword );
if ( scriptClassName.isEmpty() ) scriptClassName = classKeyword;
if (!classesWritten.count(scriptClassName))
if ( !classesWritten.count( scriptClassName ) )
{
QString classCode;
if (scriptSuperClassNames.empty())
if ( scriptSuperClassNames.empty() )
{
classCode = QString("class %1:\n").arg(scriptClassName);
classCode = QString( "class %1:\n" ).arg( scriptClassName );
}
else
{
classCode = QString("class %1(%2):\n").arg(scriptClassName).arg(scriptSuperClassNames.back());
classCode = QString( "class %1(%2):\n" ).arg( scriptClassName ).arg( scriptSuperClassNames.back() );
}
if (!classCommentsGenerated[classKeyword].isEmpty() || !classAttributesGenerated[classKeyword].empty())
if ( !classCommentsGenerated[classKeyword].isEmpty() || !classAttributesGenerated[classKeyword].empty() )
{
classCode += " \"\"\"\n";
if (!classCommentsGenerated[classKeyword].isEmpty())
if ( !classCommentsGenerated[classKeyword].isEmpty() )
{
if (!classCommentsGenerated[classKeyword].isEmpty())
if ( !classCommentsGenerated[classKeyword].isEmpty() )
{
classCode += QString(" %1\n\n").arg(classCommentsGenerated[classKeyword]);
classCode += QString( " %1\n\n" ).arg( classCommentsGenerated[classKeyword] );
}
}
if (!classAttributesGenerated[classKeyword].empty())
if ( !classAttributesGenerated[classKeyword].empty() )
{
classCode += " Attributes\n";
for (auto keyWordValuePair : classAttributesGenerated[classKeyword])
for ( auto keyWordValuePair : classAttributesGenerated[classKeyword] )
{
classCode += " " + keyWordValuePair.second.second;
}
@@ -283,27 +329,27 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
classCode += " \"\"\"\n";
}
classCode +=
QString(" __custom_init__ = None #: Assign a custom init routine to be run at __init__\n\n");
QString( " __custom_init__ = None #: Assign a custom init routine to be run at __init__\n\n" );
classCode += QString(" def __init__(self, pb2_object=None, channel=None):\n");
if (!scriptSuperClassNames.empty())
classCode += QString( " def __init__(self, pb2_object=None, channel=None):\n" );
if ( !scriptSuperClassNames.empty() )
{
// Own attributes. This initializes a lot of attributes to None.
// This means it has to be done before we set any values.
for (auto keyWordValuePair : classAttributesGenerated[classKeyword])
for ( auto keyWordValuePair : classAttributesGenerated[classKeyword] )
{
classCode += keyWordValuePair.second.first;
}
// Parent constructor
classCode +=
QString(" %1.__init__(self, pb2_object, channel)\n").arg(scriptSuperClassNames.back());
QString( " %1.__init__(self, pb2_object, channel)\n" ).arg( scriptSuperClassNames.back() );
}
classCode += QString(" if %1.__custom_init__ is not None:\n").arg(scriptClassName);
classCode += QString(" %1.__custom_init__(self, pb2_object=pb2_object, channel=channel)\n")
.arg(scriptClassName);
classCode += QString( " if %1.__custom_init__ is not None:\n" ).arg( scriptClassName );
classCode += QString( " %1.__custom_init__(self, pb2_object=pb2_object, channel=channel)\n" )
.arg( scriptClassName );
for (auto keyWordValuePair : classMethodsGenerated[classKeyword])
for ( auto keyWordValuePair : classMethodsGenerated[classKeyword] )
{
classCode += "\n";
classCode += keyWordValuePair.second;
@@ -311,16 +357,16 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
}
out << classCode << "\n";
classesWritten.insert(scriptClassName);
classesWritten.insert( scriptClassName );
}
scriptSuperClassNames.push_back(scriptClassName);
scriptSuperClassNames.push_back( scriptClassName );
}
}
out << "def class_dict():\n";
out << " classes = {}\n";
for (QString classKeyword : classesWritten)
for ( QString classKeyword : classesWritten )
{
out << QString(" classes['%1'] = %1\n").arg(classKeyword);
out << QString( " classes['%1'] = %1\n" ).arg( classKeyword );
}
out << " return classes\n\n";
@@ -336,71 +382,56 @@ QString PdmPythonGenerator::generate(PdmObjectFactory* factory) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmPythonGenerator::camelToSnakeCase(const QString& camelString)
QString PdmPythonGenerator::camelToSnakeCase( const QString& camelString )
{
static QRegularExpression re1("(.)([A-Z][a-z]+)");
static QRegularExpression re2("([a-z0-9])([A-Z])");
static QRegularExpression re1( "(.)([A-Z][a-z]+)" );
static QRegularExpression re2( "([a-z0-9])([A-Z])" );
QString snake_case = camelString;
snake_case.replace(re1, "\\1_\\2");
snake_case.replace(re2, "\\1_\\2");
snake_case.replace( re1, "\\1_\\2" );
snake_case.replace( re2, "\\1_\\2" );
return snake_case.toLower();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmPythonGenerator::dataTypeString(const PdmFieldHandle* field, bool useStrForUnknownDataTypes)
QString PdmPythonGenerator::dataTypeString( const PdmFieldHandle* field, bool useStrForUnknownDataTypes )
{
auto xmlObj = field->capability<PdmXmlFieldHandle>();
QString dataType = xmlObj->dataTypeName();
std::map<QString, QString> builtins =
{ {QString::fromStdString(typeid(double).name()), "float"},
{QString::fromStdString(typeid(float).name()), "float"},
{QString::fromStdString(typeid(int).name()), "int"},
{QString::fromStdString(typeid(QString).name()), "str"}
};
std::map<QString, QString> builtins = {{QString::fromStdString( typeid( double ).name() ), "float"},
{QString::fromStdString( typeid( float ).name() ), "float"},
{QString::fromStdString( typeid( int ).name() ), "int"},
{QString::fromStdString( typeid( QString ).name() ), "str"}};
bool foundBuiltin = false;
for (auto builtin : builtins)
for ( auto builtin : builtins )
{
if (dataType == builtin.first)
if ( dataType == builtin.first )
{
dataType.replace(builtin.first, builtin.second);
dataType.replace( builtin.first, builtin.second );
foundBuiltin = true;
}
}
if (!foundBuiltin && useStrForUnknownDataTypes)
if ( !foundBuiltin && useStrForUnknownDataTypes )
{
dataType = "str";
}
return dataType;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmPythonGenerator::pythonifyDataValue(const QString& dataValue)
QString PdmPythonGenerator::pythonifyDataValue( const QString& dataValue )
{
QString outValue = dataValue;
outValue.replace("false", "False");
outValue.replace("true", "True");
outValue.replace( "false", "False" );
outValue.replace( "true", "True" );
return outValue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmPythonGenerator::pythonHelpString(const QString& existingTooltip, const QString& keyword)
{
QString snake_case = caf::PdmPythonGenerator::camelToSnakeCase(keyword);
QString helpString = QString("Available through python/rips as the attribute '%1'").arg(snake_case);
if (!existingTooltip.isEmpty()) return existingTooltip + "\n\n" + helpString;
return helpString;
}
@@ -49,11 +49,10 @@ class PdmPythonGenerator : public PdmCodeGenerator
CAF_PDM_CODE_GENERATOR_HEADER_INIT;
public:
QString generate(PdmObjectFactory* factory) const override;
static QString camelToSnakeCase(const QString& camelString);
static QString dataTypeString(const PdmFieldHandle* field, bool useStrForUnknownDataTypes);
static QString camelToSnakeCase( const QString& camelString );
static QString dataTypeString( const PdmFieldHandle* field, bool useStrForUnknownDataTypes );
static QString pythonifyDataValue(const QString& dataValue);
static QString pythonHelpString(const QString& existingTooltip, const QString& keyword);
};
@@ -0,0 +1,126 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#include "cafPdmScriptResponse.h"
using namespace caf;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmScriptResponse::PdmScriptResponse( Status status, const QString& message )
: m_status( COMMAND_OK )
{
updateStatus( status, message );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmScriptResponse::PdmScriptResponse( PdmObject* ok_result )
: m_status( COMMAND_OK )
, m_result( ok_result )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmScriptResponse::Status PdmScriptResponse::status() const
{
return m_status;
}
//--------------------------------------------------------------------------------------------------
/// The resulting message is sent in HTTP metadata and must not have any newlines.
//--------------------------------------------------------------------------------------------------
QString PdmScriptResponse::sanitizedResponseMessage() const
{
QString completeMessage = m_messages.join( ";;" );
completeMessage.replace( '\n', ";;" );
return completeMessage;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QStringList PdmScriptResponse::messages() const
{
return m_messages;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmObject* PdmScriptResponse::result() const
{
return m_result.get();
}
//--------------------------------------------------------------------------------------------------
/// Takes ownership of the result object
//--------------------------------------------------------------------------------------------------
void PdmScriptResponse::setResult( PdmObject* result )
{
m_result.reset( result );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmScriptResponse::updateStatus( Status status, const QString& message )
{
m_status = std::max( m_status, status );
if ( !message.isEmpty() )
{
m_messages.push_back( QString( "%1: %2" ).arg( statusLabel( status ) ).arg( message ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString PdmScriptResponse::statusLabel( Status status )
{
switch ( status )
{
case COMMAND_WARNING:
return "Warning";
case COMMAND_ERROR:
return "Error";
default:
return "";
}
}
@@ -0,0 +1,83 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) Ceetron Solutions AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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.
//
// This library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafPdmObject.h"
#include "cafPdmPointer.h"
#include <QString>
#include <QStringList>
#include <memory>
namespace caf
{
//==================================================================================================
//
// Command response which contains status and possibly a result
//
//==================================================================================================
class PdmScriptResponse
{
public:
// Status in order of severity from ok to critical
enum Status
{
COMMAND_OK,
COMMAND_WARNING,
COMMAND_ERROR
};
public:
PdmScriptResponse( Status status = COMMAND_OK, const QString& message = "" );
explicit PdmScriptResponse( PdmObject* ok_result );
Status status() const;
QString sanitizedResponseMessage() const;
QStringList messages() const;
PdmObject* result() const;
void setResult( PdmObject* result );
void updateStatus( Status status, const QString& message );
private:
static QString statusLabel( Status status );
private:
Status m_status;
QStringList m_messages;
std::unique_ptr<PdmObject> m_result;
};
} // namespace caf