1 /*
2 * MoveCommand.cpp
3 *
4 * Copyright (C) 1999 Stephen F. White
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file "COPYING" for details); if
18 * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 * Cambridge, MA 02139, USA.
20 */
21
22 #include <stdio.h>
23 #include "stdafx.h"
24
25 #include "MoveCommand.h"
26 #include "Scene.h"
27 #include "Node.h"
28 #include "FieldValue.h"
29 #include "SFNode.h"
30 #include "MFNode.h"
31 #include "Path.h"
32 #include "DuneApp.h"
33
MoveCommand(Node * node,Node * src,int srcField,Node * dest,int destField,int destIndex,bool handleUSE)34 MoveCommand::MoveCommand(Node *node, Node *src, int srcField,
35 Node *dest, int destField, int destIndex,
36 bool handleUSE)
37 {
38 m_node = node;
39
40 m_src = src;
41 m_srcField = srcField;
42 m_dest = dest;
43 m_destField = destField;
44 m_failed = false;
45 m_isUSE = false;
46
47 m_oldValueSrc = m_newValueSrc = NULL;
48 m_oldValueDest = m_newValueDest = NULL;
49
50 if (handleUSE && (m_dest == NULL) && m_src && (m_node->getRefs() > 1)) {
51 if (!m_isUSE) {
52 m_isUSE = true;
53 m_node->setIsUse(m_isUSE);
54 m_node->getScene()->unuse(m_node->getName());
55 return;
56 }
57 }
58
59 if (m_src) {
60 m_oldValueSrc = m_src->getField(m_srcField);
61 m_oldValueSrc->ref();
62 if ((m_oldValueSrc->getType() == SFNODE) ||
63 (m_oldValueSrc->getType() == MFNODE))
64 m_newValueSrc = m_oldValueSrc->removeNode(node, destIndex);
65 else
66 m_newValueSrc = NULL;
67 if (m_newValueSrc == NULL) {
68 m_failed = true;
69 return;
70 }
71 m_newValueSrc->ref();
72 } else {
73 m_oldValueSrc = m_newValueSrc = NULL;
74 }
75
76 if (m_dest) {
77 m_oldValueDest = m_dest->getField(m_destField);
78 if (m_oldValueDest) {
79 m_oldValueDest->ref();
80 m_newValueDest = m_oldValueDest->addNode(node, destIndex);
81 m_newValueDest->ref();
82 }
83 } else {
84 m_oldValueDest = m_newValueDest = NULL;
85 }
86 }
87
~MoveCommand()88 MoveCommand::~MoveCommand()
89 {
90 if (m_src) {
91 m_oldValueSrc->unref();
92 m_newValueSrc->unref();
93 }
94 if (m_dest) {
95 m_oldValueDest->unref();
96 m_newValueDest->unref();
97 }
98 }
99
100 void
execute(SceneView * sender)101 MoveCommand::execute(SceneView* sender)
102 {
103 if (m_failed)
104 return;
105 if (m_node == NULL)
106 return;
107 if (m_src) {
108 m_src->setField(m_srcField, m_newValueSrc);
109 MyString nodeName = "";
110 if (m_node->hasName())
111 nodeName += m_node->getName();
112 if (m_isUSE && m_node->hasName()) {
113 m_isUSE = false;
114 m_node->setIsUse(m_isUSE);
115 } else {
116 m_node->getScene()->setSelection(m_node->getPrevSibling());
117 m_node->getScene()->UpdateViews(NULL, UPDATE_SELECTION, NULL);
118 m_node->getScene()->OnRemoveNode(m_node, m_src, m_srcField);
119 }
120 }
121 if (m_dest) {
122 MyString nodeName = "";
123 if (m_node->hasName())
124 nodeName += m_node->getName();
125 m_dest->setField(m_destField, m_newValueDest);
126 m_node->getScene()->def(nodeName, m_node);
127 m_node->setOutsideProto(m_dest->getOutsideProto());
128 m_node->getScene()->getNodes()->clearFlag(NODE_FLAG_TOUCHED);
129 m_node->getScene()->OnAddNode(m_node, m_dest, m_destField);
130 }
131 }
132
133 void
undo()134 MoveCommand::undo()
135 {
136 if (m_node == NULL)
137 return;
138 m_node->getScene()->setSelection(m_node);
139 m_node->getScene()->UpdateViews(NULL, UPDATE_SELECTION);
140 MyString nodeName = "";
141 if (m_node->hasName())
142 nodeName += m_node->getName();
143 if (m_dest) {
144 m_dest->setField(m_destField, m_oldValueDest);
145 m_node->getScene()->def(nodeName, m_node);
146 m_node->getScene()->OnRemoveNode(m_node, m_dest, m_destField);
147 }
148 if (m_src) {
149 m_src->setField(m_srcField, m_oldValueSrc);
150 m_node->getScene()->def(nodeName, m_node);
151 m_node->getScene()->OnAddNode(m_node, m_src, m_srcField);
152 }
153 }
154