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