FlowGraphModel.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #include "FlowGraphModel.h"
  2. FlowGraphModel::FlowGraphModel() : _nextNodeId { 0 } { }
  3. FlowGraphModel::~FlowGraphModel()
  4. {
  5. //
  6. }
  7. std::unordered_set<NodeId> FlowGraphModel::allNodeIds() const
  8. {
  9. return _nodeIds;
  10. }
  11. std::unordered_set<ConnectionId> FlowGraphModel::allConnectionIds(NodeId const nodeId) const
  12. {
  13. std::unordered_set<ConnectionId> result;
  14. std::copy_if(_connectivity.begin(), _connectivity.end(), std::inserter(result, std::end(result)),
  15. [&nodeId](ConnectionId const &cid) { return cid.inNodeId == nodeId || cid.outNodeId == nodeId; });
  16. return result;
  17. }
  18. std::unordered_set<ConnectionId> FlowGraphModel::connections(NodeId nodeId, PortType portType,
  19. PortIndex portIndex) const
  20. {
  21. std::unordered_set<ConnectionId> result;
  22. std::copy_if(_connectivity.begin(), _connectivity.end(), std::inserter(result, std::end(result)),
  23. [&portType, &portIndex, &nodeId](ConnectionId const &cid) {
  24. return (getNodeId(portType, cid) == nodeId && getPortIndex(portType, cid) == portIndex);
  25. });
  26. return result;
  27. }
  28. bool FlowGraphModel::connectionExists(ConnectionId const connectionId) const
  29. {
  30. return (_connectivity.find(connectionId) != _connectivity.end());
  31. }
  32. NodeId FlowGraphModel::addNode(QString const nodeType)
  33. {
  34. NodeId newId = newNodeId();
  35. // Create new node.
  36. _nodeIds.insert(newId);
  37. Q_EMIT nodeCreated(newId);
  38. return newId;
  39. }
  40. bool FlowGraphModel::connectionPossible(ConnectionId const connectionId) const
  41. {
  42. return _connectivity.find(connectionId) == _connectivity.end();
  43. }
  44. void FlowGraphModel::addConnection(ConnectionId const connectionId)
  45. {
  46. _connectivity.insert(connectionId);
  47. Q_EMIT connectionCreated(connectionId);
  48. }
  49. bool FlowGraphModel::nodeExists(NodeId const nodeId) const
  50. {
  51. return (_nodeIds.find(nodeId) != _nodeIds.end());
  52. }
  53. QVariant FlowGraphModel::nodeData(NodeId nodeId, NodeRole role) const
  54. {
  55. Q_UNUSED(nodeId);
  56. QVariant result;
  57. switch (role) {
  58. case NodeRole::Type:
  59. result = QString("Default Node Type");
  60. break;
  61. case NodeRole::Position:
  62. result = _nodeGeometryData[nodeId].pos;
  63. break;
  64. case NodeRole::Size:
  65. result = _nodeGeometryData[nodeId].size;
  66. break;
  67. case NodeRole::CaptionVisible:
  68. result = true;
  69. break;
  70. case NodeRole::Caption:
  71. result = QString("Node");
  72. break;
  73. case NodeRole::Style: {
  74. auto style = StyleCollection::nodeStyle();
  75. result = style.toJson().toVariantMap();
  76. } break;
  77. case NodeRole::InternalData:
  78. break;
  79. case NodeRole::InPortCount:
  80. result = 1u;
  81. break;
  82. case NodeRole::OutPortCount:
  83. result = 1u;
  84. break;
  85. case NodeRole::Widget:
  86. result = QVariant();
  87. break;
  88. }
  89. return result;
  90. }
  91. bool FlowGraphModel::setNodeData(NodeId nodeId, NodeRole role, QVariant value)
  92. {
  93. bool result = false;
  94. switch (role) {
  95. case NodeRole::Type:
  96. break;
  97. case NodeRole::Position: {
  98. _nodeGeometryData[nodeId].pos = value.value<QPointF>();
  99. Q_EMIT nodePositionUpdated(nodeId);
  100. result = true;
  101. } break;
  102. case NodeRole::Size: {
  103. _nodeGeometryData[nodeId].size = value.value<QSize>();
  104. result = true;
  105. } break;
  106. case NodeRole::CaptionVisible:
  107. break;
  108. case NodeRole::Caption:
  109. break;
  110. case NodeRole::Style:
  111. break;
  112. case NodeRole::InternalData:
  113. break;
  114. case NodeRole::InPortCount:
  115. break;
  116. case NodeRole::OutPortCount:
  117. break;
  118. case NodeRole::Widget:
  119. break;
  120. }
  121. return result;
  122. }
  123. QVariant FlowGraphModel::portData(NodeId nodeId, PortType portType, PortIndex portIndex, PortRole role) const
  124. {
  125. switch (role) {
  126. case PortRole::Data:
  127. return QVariant();
  128. break;
  129. case PortRole::DataType:
  130. return QVariant();
  131. break;
  132. case PortRole::ConnectionPolicyRole:
  133. return QVariant::fromValue(ConnectionPolicy::One);
  134. break;
  135. case PortRole::CaptionVisible:
  136. return true;
  137. break;
  138. case PortRole::Caption:
  139. if (portType == PortType::In)
  140. return QString::fromUtf8("Port In");
  141. else
  142. return QString::fromUtf8("Port Out");
  143. break;
  144. }
  145. return QVariant();
  146. }
  147. bool FlowGraphModel::setPortData(NodeId nodeId, PortType portType, PortIndex portIndex, QVariant const &value,
  148. PortRole role)
  149. {
  150. Q_UNUSED(nodeId);
  151. Q_UNUSED(portType);
  152. Q_UNUSED(portIndex);
  153. Q_UNUSED(value);
  154. Q_UNUSED(role);
  155. return false;
  156. }
  157. bool FlowGraphModel::deleteConnection(ConnectionId const connectionId)
  158. {
  159. bool disconnected = false;
  160. auto it = _connectivity.find(connectionId);
  161. if (it != _connectivity.end()) {
  162. disconnected = true;
  163. _connectivity.erase(it);
  164. }
  165. if (disconnected)
  166. Q_EMIT connectionDeleted(connectionId);
  167. return disconnected;
  168. }
  169. bool FlowGraphModel::deleteNode(NodeId const nodeId)
  170. {
  171. // Delete connections to this node first.
  172. auto connectionIds = allConnectionIds(nodeId);
  173. for (auto &cId : connectionIds) {
  174. deleteConnection(cId);
  175. }
  176. _nodeIds.erase(nodeId);
  177. _nodeGeometryData.erase(nodeId);
  178. Q_EMIT nodeDeleted(nodeId);
  179. return true;
  180. }
  181. QJsonObject FlowGraphModel::saveNode(NodeId const nodeId) const
  182. {
  183. QJsonObject nodeJson;
  184. nodeJson["id"] = static_cast<qint64>(nodeId);
  185. {
  186. QPointF const pos = nodeData(nodeId, NodeRole::Position).value<QPointF>();
  187. QJsonObject posJson;
  188. posJson["x"] = pos.x();
  189. posJson["y"] = pos.y();
  190. nodeJson["position"] = posJson;
  191. }
  192. return nodeJson;
  193. }
  194. void FlowGraphModel::loadNode(QJsonObject const &nodeJson)
  195. {
  196. NodeId restoredNodeId = static_cast<NodeId>(nodeJson["id"].toInt());
  197. // Next NodeId must be larger that any id existing in the graph
  198. _nextNodeId = std::max(_nextNodeId, restoredNodeId + 1);
  199. // Create new node.
  200. _nodeIds.insert(restoredNodeId);
  201. Q_EMIT nodeCreated(restoredNodeId);
  202. {
  203. QJsonObject posJson = nodeJson["position"].toObject();
  204. QPointF const pos(posJson["x"].toDouble(), posJson["y"].toDouble());
  205. setNodeData(restoredNodeId, NodeRole::Position, pos);
  206. }
  207. }