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()130FxSchematicNodeSelection::FxSchematicNodeSelection() {} 131 132 //--------------------------------------------------------- 133 FxSchematicNodeSelection(const FxSchematicNodeSelection & src)134FxSchematicNodeSelection::FxSchematicNodeSelection( 135 const FxSchematicNodeSelection &src) 136 : m_selectedNodes(src.m_selectedNodes) {} 137 138 //--------------------------------------------------------- 139 ~FxSchematicNodeSelection()140FxSchematicNodeSelection::~FxSchematicNodeSelection() {} 141 142 //--------------------------------------------------------- 143 enableCommands()144void FxSchematicNodeSelection::enableCommands() { 145 enableCommand(this, MI_Clear, &FxSchematicNodeSelection::deleteSelection); 146 } 147 148 //--------------------------------------------------------- 149 clone() const150TSelection *FxSchematicNodeSelection::clone() const { 151 assert(0); 152 return new FxSchematicNodeSelection(); 153 } 154 155 //--------------------------------------------------------- 156 select(FxSchematicNode * node)157void FxSchematicNodeSelection::select(FxSchematicNode *node) { 158 m_selectedNodes.append(node); 159 } 160 161 //--------------------------------------------------------- 162 unselect(FxSchematicNode * node)163void 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) const177bool FxSchematicNodeSelection::isSelected(FxSchematicNode *node) const { 178 return m_selectedNodes.contains(node); 179 } 180 181 //--------------------------------------------------------- 182 deleteSelection()183void 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)199void 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