HAL
action_move_node.cpp
Go to the documentation of this file.
2 #include <QStringList>
4 #include "gui/gui_globals.h"
8 
9 namespace hal
10 {
12  : UserActionFactory("MoveNode") {;}
13 
15 
17  {
18  return new ActionMoveNode;
19  }
20 
21  bool ActionMoveNode::checkContextId()
22  {
23  if (!mContextId)
24  {
25  log_warning("gui", "ActionMoveNode invoked without context ID.");
26  return false;
27  }
28  GraphContext* ctx = gGraphContextManager->getContextById(mContextId);
29  if (!ctx)
30  {
31  log_warning("gui", "ActionMoveNode invoked with illegal context ID {}.", mContextId);
32  mContextId = 0;
33  return false;
34  }
35  return true;
36  }
37 
39  : mContextId(ctxId), mSwap(false)
40  {
41  if (!checkContextId()) return;
42  if (gridPlc)
43  mGridPlacement = *gridPlc;
44  }
45 
47  : mContextId(ctxID), mTo(to), mSwap(false)
48  {
49  if (!checkContextId()) return;
50 
51  // This special constructor is mainly used in compound statement.
52  // At construction target position might still be occupied, so don't do any checks before exec()
53  }
54 
55  /*
56  ActionMoveNode::ActionMoveNode(u32 ctxID, const QPoint& from, const QPoint& to, bool swap)
57  : mContextId(ctxID), mTo(to), mSwap(swap)
58  {
59  if (!checkContextId()) return;
60  GraphContext* ctx = gGraphContextManager->getContextById(mContextId);
61 
62  // get the node we want to move
63  Node ndToMove = ctx->getLayouter()->positionToNodeMap().value(from);
64  if (ndToMove.isNull())
65  {
66  mContextId = 0; // node not found, exit
67  return;
68  }
69 
70  mTargetNode = ctx->getLayouter()->positionToNodeMap().value(to);
71  if(!mTargetNode.isNull() && !mSwap)
72  {
73  mContextId = 0; // move to an occupied position without swap modifier
74  return;
75  }
76 
77  switch (ndToMove.type())
78  {
79  case Node::Module:
80  mObject = UserActionObject(ndToMove.id(),UserActionObjectType::Module);
81  break;
82  case Node::Gate:
83  mObject = UserActionObject(ndToMove.id(),UserActionObjectType::Gate);
84  break;
85  default:
86  mContextId = 0; // node type None, exit
87  return;
88  }
89  }
90 */
91 
93  {
95  }
96 
98  {
99  cryptoHash.addData((char*)(&mTo) , sizeof(QPoint));
100  }
101 
103  {
104  xmlOut.writeTextElement("to", QString("%1,%2").arg(mTo.x()).arg(mTo.y()));
105  }
106 
108  {
109  while (xmlIn.readNextStartElement())
110  {
111  if (xmlIn.name() == "to")
112  mTo = parseFromString(xmlIn.readElementText());
113  }
114  }
115 
116  QPoint ActionMoveNode::parseFromString(const QString& s)
117  {
118  QStringList sl = s.split(',');
119  Q_ASSERT(sl.size()==2);
120  return QPoint(sl.at(0).toInt(),sl.at(1).toInt());
121  }
122 
124  {
125  if (!mContextId) return false;
127  if (!ctx) return false;
128 
129  // current placement for undo
130  ActionMoveNode* undo = new ActionMoveNode(mContextId, GuiApiClasses::View::getGridPlacement(mContextId));
131  mUndoAction = undo;
132 
133  if (mGridPlacement.isEmpty())
134  {
135  // No placement given by constructor
136  // load current placement and modify from and to position
137  mGridPlacement = undo->mGridPlacement;
138 
139  // test whether there is a user object to move
140  Node ndToMove;
141  switch (mObject.type()) {
143  ndToMove = Node(mObject.id(),Node::Gate);
144  break;
146  ndToMove = Node(mObject.id(),Node::Module);
147  break;
148  default:
149  break;
150  }
151  if (ndToMove.type() == Node::None) return false;
152 
153  if (!mTargetNode.isNull())
154  {
155  // there is a node at target position
156  if (!mSwap) return false;
157  mGridPlacement[mTargetNode] = ctx->getLayouter()->nodeToPositionMap().value(ndToMove);
158  }
159  mGridPlacement[ndToMove] = mTo;
160  }
161 
162  LayoutLocker llock;
163  ctx->clear();
164 
165  QSet<u32> modIds;
166  QSet<u32> gateIds;
167 
168  for (Node node : mGridPlacement.keys())
169  {
170  if(node.isModule()) modIds.insert(node.id());
171  else gateIds.insert(node.id());
172  }
173 
174  ctx->add(modIds, gateIds, PlacementHint(mGridPlacement));
175  ctx->scheduleSceneUpdate();
176 
177  return UserAction::exec();
178  }
179 }
UserActionFactory for ActionMoveNode.
UserAction * newAction() const
static ActionMoveNodeFactory * sFactory
void addToHash(QCryptographicHash &cryptoHash) const override
void writeToXml(QXmlStreamWriter &xmlOut) const override
void readFromXml(QXmlStreamReader &xmlIn) override
QString tagname() const override
ActionMoveNode(u32 ctxID, const QPoint &to)
Logical container for modules, gates, and nets.
Definition: graph_context.h:55
void add(const QSet< u32 > &modules, const QSet< u32 > &gates, PlacementHint placement=PlacementHint())
GraphLayouter * getLayouter() const
GraphContext * getContextById(u32 id) const
const QMap< Node, QPoint > nodeToPositionMap() const
static GridPlacement * getGridPlacement(int viewId)
Definition: gui_api.cpp:921
The Node class object represents a module or a gate.
Definition: gui_def.h:61
NodeType type() const
type getter for type information
Definition: gui_def.h:71
@ Module
Definition: gui_def.h:63
@ Gate
Definition: gui_def.h:63
@ None
Definition: gui_def.h:63
bool isNull() const
isNull test for null-Node object typically returned from functions
Definition: gui_def.h:83
The PlacementHint class object provides hints for the layouter how new box objects are placed on a vi...
Definition: gui_def.h:196
The UserActionFactory is the abstract base class for registration.
Definition: user_action.h:225
QString tagname() const
Definition: user_action.h:242
The UserAction class is the abstract base class for user interactions.
Definition: user_action.h:57
UserAction * mUndoAction
Definition: user_action.h:186
virtual bool exec()
Definition: user_action.cpp:23
UserActionObject mObject
Definition: user_action.h:183
UserActionObjectType::ObjectType type() const
#define log_warning(channel,...)
Definition: log.h:76
S to(const T &str)
GraphContextManager * gGraphContextManager
Definition: plugin_gui.cpp:85
quint32 u32
void addData(const char *data, int length)
bool isEmpty() const const
QList< Key > keys() const const
const T & at(int i) const const
int size() const const
int x() const const
int y() const const
QSet::iterator insert(const T &value)
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QStringRef name() const const
QString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour)
bool readNextStartElement()
void writeTextElement(const QString &qualifiedName, const QString &text)