1 
2 
3 #include "fxschematicnodeselection.h"
4 #include "fxschematicnode.h"
5 #include "tapp.h"
6 #include "toonz/tfxhandle.h"
7 #include "menubarcommandids.h"
8 #include "toonz/tcolumnfx.h"
9 #include "fxcommand.h"
10 
11 #include "tundo.h"
12 #include "toonz/fxdag.h"
13 #include "toonz/txsheethandle.h"
14 #include "toonz/txsheet.h"
15 #include "toonz/tcolumnfxset.h"
16 
17 //=========================================================
18 //
19 // DeleteFxsUndo
20 //
21 //=========================================================
22 
23 class DeleteFxsUndo : public TUndo {
24   struct Node {
25     TFxP m_fx;
26     std::vector<std::pair<int, TFxP>> m_outputLinks;
27     std::vector<TFxP> m_inputLinks;
28     bool m_xsheetConnected;
29   };
30   QList<Node> m_fxs;
31   QList<TFxP> m_inputConnectedToXsheet;
32 
33 public:
DeleteFxsUndo(const QList<TFx * > & fxs)34   DeleteFxsUndo(const QList<TFx *> &fxs) {
35     TApp *app    = TApp::instance();
36     FxDag *fxDag = app->getCurrentXsheet()->getXsheet()->getFxDag();
37     for (int i = 0; i < (int)fxs.size(); i++) {
38       TFx *fx              = fxs[i];
39       TZeraryColumnFx *zfx = dynamic_cast<TZeraryColumnFx *>(fx);
40       if (zfx) fx          = zfx->getZeraryFx();
41       Node node;
42       node.m_fx              = fx;
43       node.m_xsheetConnected = fxDag->getTerminalFxs()->containsFx(fx);
44       int j;
45       for (j = 0; j < fx->getInputPortCount(); j++) {
46         TFxP inputFx(fx->getInputPort(j)->getFx());
47         int i;
48         if (inputFx &&
49             !fxDag->getTerminalFxs()->containsFx(inputFx.getPointer())) {
50           for (i = 0; i < (int)m_inputConnectedToXsheet.size(); i++)
51             if (m_inputConnectedToXsheet[i].getPointer() ==
52                 inputFx.getPointer())
53               break;
54           if (i == (int)m_inputConnectedToXsheet.size())
55             m_inputConnectedToXsheet.push_back(inputFx);
56         }
57         node.m_inputLinks.push_back(inputFx);
58       }
59       for (j = 0; j < fx->getOutputConnectionCount(); j++) {
60         TFxPort *port = fx->getOutputConnection(j);
61         TFx *outFx    = port->getOwnerFx();
62         if (outFx) {
63           int k;
64           for (k = 0; k < outFx->getInputPortCount(); k++)
65             if (outFx->getInputPort(k)->getFx() == fx) break;
66           if (k < outFx->getInputPortCount())
67             node.m_outputLinks.push_back(std::make_pair(k, TFxP(outFx)));
68         }
69       }
70       m_fxs.push_back(node);
71     }
72   }
73 
onAdd()74   void onAdd() {
75     FxDag *fxDag =
76         TApp::instance()->getCurrentXsheet()->getXsheet()->getFxDag();
77     int i;
78     for (i = 0; i < (int)m_inputConnectedToXsheet.size();) {
79       TFx *inputFx = m_inputConnectedToXsheet[i].getPointer();
80       if (!fxDag->getTerminalFxs()->containsFx(inputFx))
81         i++;
82       else
83         m_inputConnectedToXsheet.erase(m_inputConnectedToXsheet.begin() + i);
84     }
85   }
86 
undo() const87   void undo() const {
88     FxDag *fxDag =
89         TApp::instance()->getCurrentXsheet()->getXsheet()->getFxDag();
90     int i, j;
91     for (i = 0; i < (int)m_fxs.size(); i++) {
92       TApp::instance()->getCurrentFx()->setFx(m_fxs[i].m_fx.getPointer());
93       TFxCommand::addFx(m_fxs[i].m_fx.getPointer());
94     }
95     for (i = 0; i < (int)m_fxs.size(); i++) {
96       const Node &node = m_fxs[i];
97       TFx *fx          = node.m_fx.getPointer();
98       if (node.m_xsheetConnected) fxDag->addToXsheet(fx);
99       for (j = 0; j < (int)node.m_inputLinks.size(); j++)
100         fx->getInputPort(j)->setFx(node.m_inputLinks[j].getPointer());
101       for (j = 0; j < (int)node.m_outputLinks.size(); j++) {
102         TFx *outFx = node.m_outputLinks[j].second.getPointer();
103         outFx->getInputPort(node.m_outputLinks[j].first)->setFx(fx);
104       }
105     }
106     for (i = 0; i < (int)m_inputConnectedToXsheet.size(); i++) {
107       TFx *inputFx = m_inputConnectedToXsheet[i].getPointer();
108       fxDag->getTerminalFxs()->removeFx(inputFx);
109     }
110     TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
111   }
redo() const112   void redo() const {
113     int i;
114     for (i = 0; i < (int)m_fxs.size(); i++) {
115       TFxCommand::removeFx(m_fxs[i].m_fx.getPointer());
116     }
117     TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
118   }
getSize() const119   int getSize() const {
120     return sizeof(*this) + m_fxs.size() * (sizeof(TFx) + 100);
121   }
122 };
123 
124 //=========================================================
125 //
126 // FxSchematicNodeSelection
127 //
128 //=========================================================
129 
FxSchematicNodeSelection()130 FxSchematicNodeSelection::FxSchematicNodeSelection() {}
131 
132 //---------------------------------------------------------
133 
FxSchematicNodeSelection(const FxSchematicNodeSelection & src)134 FxSchematicNodeSelection::FxSchematicNodeSelection(
135     const FxSchematicNodeSelection &src)
136     : m_selectedNodes(src.m_selectedNodes) {}
137 
138 //---------------------------------------------------------
139 
~FxSchematicNodeSelection()140 FxSchematicNodeSelection::~FxSchematicNodeSelection() {}
141 
142 //---------------------------------------------------------
143 
enableCommands()144 void FxSchematicNodeSelection::enableCommands() {
145   enableCommand(this, MI_Clear, &FxSchematicNodeSelection::deleteSelection);
146 }
147 
148 //---------------------------------------------------------
149 
clone() const150 TSelection *FxSchematicNodeSelection::clone() const {
151   assert(0);
152   return new FxSchematicNodeSelection();
153 }
154 
155 //---------------------------------------------------------
156 
select(FxSchematicNode * node)157 void FxSchematicNodeSelection::select(FxSchematicNode *node) {
158   m_selectedNodes.append(node);
159 }
160 
161 //---------------------------------------------------------
162 
unselect(FxSchematicNode * node)163 void FxSchematicNodeSelection::unselect(FxSchematicNode *node) {
164   int index = m_selectedNodes.indexOf(node);
165   if (index >= 0) m_selectedNodes.removeAt(index);
166   TFxHandle *fxHandle = TApp::instance()->getCurrentFx();
167   if (fxHandle->getFx() == node->getFx()) {
168     if (m_selectedNodes.empty())
169       fxHandle->setFx(0);
170     else
171       fxHandle->setFx((*m_selectedNodes.begin())->getFx());
172   }
173 }
174 
175 //---------------------------------------------------------
176 
isSelected(FxSchematicNode * node) const177 bool FxSchematicNodeSelection::isSelected(FxSchematicNode *node) const {
178   return m_selectedNodes.contains(node);
179 }
180 
181 //---------------------------------------------------------
182 
deleteSelection()183 void FxSchematicNodeSelection::deleteSelection() {
184   QList<TFx *> fxs;
185   QList<FxSchematicNode *>::const_iterator it;
186   for (it = m_selectedNodes.begin(); it != m_selectedNodes.end(); ++it) {
187     TFx *fx = (*it)->getFx();
188     if (0 != dynamic_cast<TXsheetFx *>(fx) ||
189         0 != dynamic_cast<TLevelColumnFx *>(fx))
190       continue;
191     fxs.push_back((*it)->getFx());
192   }
193   selectNone();
194   removeFxs(fxs);
195 }
196 
197 //---------------------------------------------------------
198 
removeFxs(const QList<TFx * > & fxs)199 void FxSchematicNodeSelection::removeFxs(const QList<TFx *> &fxs) {
200   TUndoManager::manager()->add(new DeleteFxsUndo(fxs));
201   for (int i = 0; i < (int)fxs.size(); i++) TFxCommand::removeFx(fxs[i]);
202   TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
203 }
204