51#include "types/number.hh"
52#include "types/string.hh"
53#include "types/bool.hh"
54#include "types/filename.hh"
55#include "types/selection.hh"
56#include "types/vec3d.hh"
57#include "types/vec4d.hh"
58#include "types/matrix4x4.hh"
59#include "types/objectId/objectId.hh"
60#include "types/any.hh"
62#include <QRegularExpression>
64#define DATA_NAME "DataFlow"
77 loggingInterface_(_loggingInterface), pythonInterface_(_pythonInterface)
83 e->category_ =
"Undefined";
85 e->shortDesc_ =
"Start";
86 e->longDesc_ =
"Start";
88 e->dataOut_ =
new Output (e);
89 e->dataOut_->name_ =
"data";
90 e->dataOut_->type_ =
"data";
92 e->dataOut_->shortDesc_ = DATA_NAME;
93 e->dataOut_->longDesc_ = DATA_NAME;
95 e->flags_ = ELEMENT_FLAG_NO_DELETE | ELEMENT_FLAG_SKIP_TOOLBOX;
101 e->category_ =
"Undefined";
103 e->shortDesc_ =
"End";
104 e->longDesc_ =
"End";
106 e->dataIn_ =
new Input (e);
107 e->dataIn_->name_ =
"data";
108 e->dataIn_->type_ =
"data";
110 e->dataIn_->shortDesc_ = DATA_NAME;
111 e->dataIn_->longDesc_ = DATA_NAME;
113 e->flags_ = ELEMENT_FLAG_NO_DELETE | ELEMENT_FLAG_SKIP_TOOLBOX;
134 foreach (
Element *e, elements_)
136 foreach (
Type *t, types_)
145 QVector <Element *> rv;
146 foreach (
Element *e, elements_)
157 foreach (
Element *e, elements_)
158 if (e->
name () == _name)
170 foreach (
Element *e, elements_)
171 if (!sl.contains (e->
category ()) && !(e->
flags () & ELEMENT_FLAG_SKIP_TOOLBOX))
183 QDomDocument doc(
"OpenFlipper");
184 if (!doc.setContent(&_xml)) {
189 QDomElement docElem = doc.documentElement();
191 QDomNode n = docElem.firstChild();
193 QDomElement e = n.toElement();
208 if ( !_domElement.hasAttribute(
"name"))
213 elements_.append (e);
215 e->category_ =
getXmlString (_domElement,
"category",
"Undefined");
218 e->longDesc_ =
getXmlString (_domElement,
"long", e->shortDesc_);
223 e->dataIn_ =
new Input (e);
224 e->dataIn_->name_ =
"data";
225 e->dataIn_->type_ =
"---";
227 e->dataIn_->shortDesc_ = DATA_NAME;
228 e->dataIn_->longDesc_ = DATA_NAME;
229 e->dataIn_->
setState (Input::NoRuntimeUserInput | Input::NoUserInput);
231 e->dataOut_ =
new Output (e);
232 e->dataOut_->name_ =
"data";
233 e->dataOut_->type_ =
"---";
235 e->dataOut_->shortDesc_ = DATA_NAME;
236 e->dataOut_->longDesc_ = DATA_NAME;
240 for(QDomElement n = _domElement.firstChildElement(); !n.isNull(); n = n.nextSiblingElement() )
243 if (n.tagName() ==
"inputs") {
246 for(QDomElement inputElement = n.firstChildElement(); !inputElement.isNull(); inputElement = inputElement.nextSiblingElement() )
248 Input* i =parseInput(inputElement,e);
251 e->inputs_.append (i);
257 if (n.tagName() ==
"outputs") {
260 for(QDomElement outputElement = n.firstChildElement(); !outputElement.isNull(); outputElement = outputElement.nextSiblingElement() )
262 Output *o = parseOutput(outputElement,e);
266 e->outputs_.append (o);
273 if (n.tagName() ==
"functions") {
276 for(QDomElement functionElement = n.firstChildElement(); !functionElement.isNull(); functionElement = functionElement.nextSiblingElement() )
278 Function *f = parseFunction (functionElement, e);
281 e->functions_.append (f);
291 e->precode_ =
getXmlString (_domElement,
"precode",
"");
294 if (e->precode_.contains(QRegularExpression(
"^\\s*\\t"))) {
296 emit loggingInterface_->
log(
LOGWARN,
"Precode block of "+e->
name()+
" contains tab identation");
298 if (e->code_.contains(QRegularExpression(
"^\\s*\\t"))) {
300 emit loggingInterface_->
log(
LOGWARN,
"Code block of "+e->
name()+
" contains tab identation");
312Input* Context::parseInput(QDomElement& _domElement,
Element *_e)
317 if (!parseInOutBase (_domElement, i))
324 QString stateStr = _domElement.attribute(
"external");
325 unsigned int state = 0;
327 if (!stateStr.isEmpty () && !
strToBool (stateStr))
328 state |= Input::NoExternalInput;
330 stateStr = _domElement.attribute(
"user");
332 if (!stateStr.isEmpty () && !
strToBool (stateStr))
333 state |= Input::NoUserInput;
335 stateStr = _domElement.attribute(
"runtime");
337 if (!stateStr.isEmpty () && !
strToBool (stateStr))
338 state |= Input::NoRuntimeUserInput;
340 stateStr = _domElement.attribute(
"optional");
342 if (!stateStr.isEmpty () &&
strToBool (stateStr))
343 state |= Input::Optional;
353Output* Context::parseOutput (QDomElement& _domElement, Element *_e)
355 Output *o =
new Output (_e);
358 if (!parseInOutBase (_domElement, o))
370bool Context::parseInOutBase (QDomElement &_domElement, InOut *_io)
372 QString type = _domElement.attribute(
"type",
"");
374 if ( !_domElement.hasAttribute(
"name") || type.isEmpty() )
377 _io->name_ = _domElement.attribute(
"name");
380 _io->shortDesc_ =
getXmlString (_domElement,
"short", _io->name ());
381 _io->longDesc_ =
getXmlString (_domElement,
"long", _io->shortDesc_);
386 foreach (QString hint, supportedTypes_[type]->supportedHints ())
389 if (!value.isEmpty ())
390 _io->hints_[hint] = value;
400Function* Context::parseFunction (QDomElement& _domElement, Element *_e)
402 QString name = _domElement.attribute(
"name");
406 Function *f =
new Function (_e, name);
408 f->shortDesc_ =
getXmlString (_domElement,
"short", f->name ());
409 f->longDesc_ =
getXmlString (_domElement,
"long", f->shortDesc_);
412 f->start_ =
new Element (_e->context (),
"start_" + _e->name () +
"_" + name);
414 f->start_->category_ =
"Undefined";
416 f->start_->shortDesc_ =
"Start";
417 f->start_->longDesc_ =
"Start";
419 f->start_->dataOut_ =
new Output (f->start_);
420 f->start_->dataOut_->name_ =
"data";
421 f->start_->dataOut_->type_ =
"data";
423 f->start_->dataOut_->shortDesc_ = DATA_NAME;
424 f->start_->dataOut_->longDesc_ = DATA_NAME;
426 f->start_->flags_ = ELEMENT_FLAG_NO_DELETE | ELEMENT_FLAG_SKIP_TOOLBOX;
428 elements_.append (f->start_);
431 f->end_ =
new Element (_e->context (),
"end_" + _e->name () +
"_" + name);
433 f->end_->category_ =
"Undefined";
435 f->end_->shortDesc_ =
"End";
436 f->end_->longDesc_ =
"End";
438 f->end_->dataIn_ =
new Input (f->end_);
439 f->end_->dataIn_->name_ =
"data";
440 f->end_->dataIn_->type_ =
"data";
442 f->end_->dataIn_->shortDesc_ = DATA_NAME;
443 f->end_->dataIn_->longDesc_ = DATA_NAME;
445 f->end_->flags_ = ELEMENT_FLAG_NO_DELETE | ELEMENT_FLAG_SKIP_TOOLBOX;
447 elements_.append (f->end_);
452 for(QDomElement n = _domElement.firstChildElement(); !n.isNull(); n = n.nextSiblingElement() )
455 if (n.tagName() ==
"inputs") {
458 for(QDomElement inputElement = n.firstChildElement(); !inputElement.isNull(); inputElement = inputElement.nextSiblingElement() )
460 Output *o =
new Output (f->start_);
461 if (parseInOutBase(inputElement, o))
463 f->start_->outputs_.append (o);
474 if (n.tagName() ==
"outputs") {
477 for(QDomElement outputElement = n.firstChildElement(); !outputElement.isNull(); outputElement = outputElement.nextSiblingElement() )
479 Input *i =
new Input (f->end_);
480 if (parseInOutBase(outputElement, i))
482 i->state_ = Input::NoUserInput | Input::NoRuntimeUserInput;
483 f->end_->inputs_.append (i);
495 if (!f->end_->inputs ().isEmpty ())
499 QString endCode =
"return { ";
500 foreach (Input *i, f->end_->inputs ())
501 endCode +=
"\"" + i->name () +
"\" : [input=\"" + i->name () +
"\"], ";
502 endCode.remove (endCode.length () - 2, 2);
505 f->end_->code_ = endCode;
518 for(QDomElement n = _domElement.firstChildElement(); !n.isNull(); n = n.nextSiblingElement() )
520 if (n.tagName() == _tag)
532 if (_str ==
"1" || _str ==
"true" || _str ==
"True" || _str ==
"TRUE" ||
533 _str ==
"yes" || _str ==
"Yes" || _str ==
"YES")
543 types_.append (_type);
546 supportedTypes_.insert (s, _type);
554 return supportedTypes_.contains (_type);
564 return supportedTypes_[_type1]->canConvertTo (_type2) ||
565 supportedTypes_[_type2]->canConvertTo (_type1);
574 return supportedTypes_[_type];
589 QStringList lines = in.split(
"\n");
592 int commonTrailingSpaces = INF;
594 for (
int line=0;line<lines.length();line++) {
595 int lenWithoutTrailingSpaces = QString(lines[line]).replace(QRegularExpression (
"^\\s*"),
"").length();
597 if (lenWithoutTrailingSpaces > 0) {
599 int trailingSpaces = lines[line].length() - lenWithoutTrailingSpaces;
601 if (trailingSpaces < commonTrailingSpaces) {
603 commonTrailingSpaces = trailingSpaces;
610 if (commonTrailingSpaces >= INF) {
615 for (
int line=0;line<lines.length();line++) {
616 int subLength = lines[line].length() - commonTrailingSpaces;
620 lines[line] = QString(
"");
623 lines[line] = lines[line].right(subLength);
627 QString output = lines.join(
"\n");
632void Context::executeScript(
const QString& _script) {
636void Context::openScriptInEditor(
const QString& _script) {
Interface for all Plugins which do logging to the logging window of the framework.
virtual void log(Logtype _type, QString _message)=0
Interface class for exporting functions to python.
virtual void openPythonScriptInEditor(QString _script)
virtual void executePythonScript(QString _script)
Context(LoggingInterface *_loggingInterface, PythonInterface *_pythonInterface)
Constructor.
static bool strToBool(const QString &_str)
Converts the given string to bool.
void registerType(Type *_type)
Registers a supported datatype.
bool typeSupported(const QString &_type)
Is the given type supported.
void parseElement(QDomElement &_element)
parse element from xml
static QString getXmlString(QDomElement &_element, const QString &_tag, QString _default="")
Gets the string of a xml query.
Type * getType(const QString &_type)
Get type object for given type name.
bool canConvert(const QString &_type1, const QString &_type2)
Can the given types be converted to each other.
const QVector< Element * > & elements() const
Returns all available elements.
static QString removeCommonTrailingSpaces(const QString &in)
Removes trailing spaces from string which are present in each line - relative trailing spaces are not...
Element * element(const QString &_name)
Returns the element with a given name.
void parse(QFile &_xml)
Parse xml content.
QStringList categories()
List of categories.
QString name() const
Element name.
const QString & category() const
Element category.
unsigned int flags() const
Flags.
virtual QStringList supportedTypes()
Names of Types.