KSeExpr  4.0.4.0
EditableExpression.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2 // SPDX-License-Identifier: LicenseRef-Apache-2.0
3 // SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 
6 #include "EditableExpression.h"
7 #include "Editable.h"
8 #include <sstream>
9 
10 bool ExprSpecParse(std::vector<Editable *> &literals, std::vector<std::string> &variables, std::vector<std::pair<int, int>> &comments, const char *str);
11 
13 {
14  cleanup();
15 }
16 
17 void EditableExpression::setExpr(const std::string &expr)
18 {
19  // get rid of old data
20  cleanup();
21 
22  // run parser
23  _expr = expr;
24  std::vector<std::pair<int, int>> comments;
25  ExprSpecParse(_editables, _variables, comments, _expr.c_str());
26 
27  for (auto it = _editables.begin(); it != _editables.end();) {
28  Editable &literal = **it;
29  int endPos = literal.endPos;
30  std::string comment;
31  for (auto &ci : comments) {
32  if (ci.first >= endPos) {
33  // check to make sure there is no newlines between end of editable and comment
34  size_t pos = _expr.find('\n', endPos);
35  if (pos == std::string::npos || pos >= (size_t)ci.second) {
36  comment = _expr.substr(ci.first, ci.second - ci.first);
37  break;
38  }
39  }
40  }
41  bool keepEditable = literal.parseComment(comment);
42  if (!keepEditable) { // TODO: this is potentially quadratic if we remove a bunch
43  delete &literal;
44  it = _editables.erase(it);
45  } else {
46  ++it;
47  }
48  }
49 }
50 
52 {
53  for (auto &_editable : _editables)
54  delete _editable;
55  _editables.clear();
56  _variables.clear();
57 }
58 
60 {
61  int offset = 0;
62  std::stringstream stream;
63  for (auto *_editable : _editables) {
64  Editable &literal = *_editable;
65  stream << _expr.substr(offset, literal.startPos - offset);
66  literal.appendString(stream);
67  offset = literal.endPos;
68  }
69  stream << _expr.substr(offset, _expr.size() - offset);
70  return stream.str();
71 }
72 
74 {
75  // TODO: move semantics?
76  _variables = other._variables;
77  _expr = other._expr;
78  _variables = other._variables;
79  for (size_t i = 0, sz = _editables.size(); i < sz; i++) {
80  Editable &literal = *_editables[i];
81  Editable &otherLiteral = *other._editables[i];
82  assert(literal.controlsMatch(otherLiteral));
83  literal.updatePositions(otherLiteral);
84  }
85 }
86 
88 {
89  if (_editables.size() != other._editables.size())
90  return false;
91 
92  for (size_t i = 0, sz = _editables.size(); i < sz; i++) {
93  const Editable &literal = *_editables[i];
94  const Editable &otherLiteral = *other._editables[i];
95  if (!literal.controlsMatch(otherLiteral))
96  return false;
97  }
98  return true;
99 }
bool ExprSpecParse(std::vector< Editable * > &literals, std::vector< std::string > &variables, std::vector< std::pair< int, int >> &comments, const char *str)
Factors a SeExpr into an editable expression with controls (i.e. value boxes, curve boxes)
std::vector< std::string > _variables
void setExpr(const std::string &expr)
Set's expressions and parses it into "control editable form".
std::string getEditedExpr() const
Return a reconstructed expression using all the editable's current values.
bool controlsMatch(const EditableExpression &other) const
Check if the other editable expression has editables that all match i.e. the controls are same.
void cleanup()
clean memeory
void updateString(const EditableExpression &other)
Update the string refered to into the controls (this is only valid if controlsmatch)
void updatePositions(const Editable &other)
Definition: Editable.cpp:26
virtual void appendString(std::stringstream &stream) const =0
int endPos
Definition: Editable.h:34
int startPos
Definition: Editable.h:34
virtual bool parseComment(const std::string &comment)=0
parses a comment. if false is returned then delete the control from the editable
virtual bool controlsMatch(const Editable &) const =0