Salome HOME
1a083b2c93f74349b1979721de08789605051bc5
[modules/yacs.git] / src / genericgui / GuiEditor.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include <Python.h>
20 #include "GuiEditor.hxx"
21 #include "RuntimeSALOME.hxx"
22 #include "Proc.hxx"
23 #include "Node.hxx"
24 #include "Catalog.hxx"
25 #include "guiObservers.hxx"
26 #include "QtGuiContext.hxx"
27 #include "TypeCode.hxx"
28 #include "SceneComposedNodeItem.hxx"
29 #include "SceneLinkItem.hxx"
30 #include "Catalog.hxx"
31 #include "ItemMimeData.hxx"
32 #include "Message.hxx"
33
34 #include <string>
35 #include <sstream>
36 #include <iostream>
37
38 //#define _DEVDEBUG_
39 #include "YacsTrace.hxx"
40
41 using namespace std;
42 using namespace YACS::ENGINE;
43 using namespace YACS::HMI;
44
45 GuiEditor::GuiEditor()
46 {
47   DEBTRACE("GuiEditor::GuiEditor");
48 }
49
50 GuiEditor::~GuiEditor()
51 {
52   DEBTRACE("GuiEditor::~GuiEditor");
53 }
54
55 void GuiEditor::CreateNodeFromCatalog(const ItemMimeData* myData, SubjectComposedNode *cnode)
56 {
57   DEBTRACE("GuiEditor::CreateNodeFromCatalog");
58   Catalog* catalog = myData->getCatalog();
59   string compoName =  myData->getCompo();
60   string service = myData->getType();
61   DEBTRACE(compoName << "/" << service);
62   std::stringstream name;
63   name << service << GuiContext::getCurrent()->getNewId();
64   
65   int swCase = 0;
66   SubjectSwitch *aSwitch = dynamic_cast<SubjectSwitch*>(cnode);
67   if (aSwitch)
68     {
69       map<int, SubjectNode*> bodyMap = aSwitch->getBodyMap();
70       if (bodyMap.empty()) swCase = 1;
71       else
72         {
73           map<int, SubjectNode*>::reverse_iterator rit = bodyMap.rbegin();
74           swCase = (*rit).first + 1;
75         }
76       if (!aSwitch->addNode(catalog, compoName, service, name.str(), swCase))
77         Message mess;
78     }
79   else if (cnode)
80     if (! cnode->addNode(catalog, compoName, service, name.str()))
81       Message mess;
82 }
83
84 void GuiEditor::AddTypeFromCatalog(const ItemMimeData* myData)
85 {
86   DEBTRACE("GuiEditor::AddTypeFromCatalog");
87   Catalog* catalog = myData->getCatalog();
88   DEBTRACE("catalog " << catalog);
89   string aType = myData->getType();
90   DEBTRACE(aType);
91   SubjectProc* sProc = QtGuiContext::getQtCurrent()->getSubjectProc();
92   sProc->addDataType(catalog, aType);
93 }
94
95 void GuiEditor::CreateNode(std::string typeNode)
96 {
97   DEBTRACE("GuiEditor::CreateNode " << typeNode);
98   YACS::ENGINE::Catalog *catalog = YACS::ENGINE::getSALOMERuntime()->getBuiltinCatalog();
99
100   Subject *sub = QtGuiContext::getQtCurrent()->getSelectedSubject();
101   if (!sub)
102     {
103       DEBTRACE("GuiEditor::CreateNode : invalid selection!");
104       return;
105     }
106   DEBTRACE(sub->getName());
107
108   YACS::HMI::SubjectComposedNode *subject = dynamic_cast< YACS::HMI::SubjectComposedNode*>(sub);
109   if (!subject)
110     {
111       DEBTRACE("GuiEditor::CreateNode : no ComposedNode selected!");
112       return;
113     }
114
115   std::stringstream name;
116   name << typeNode << GuiContext::getCurrent()->getNewId();
117
118   YACS::HMI::SubjectSwitch *aSwitch = dynamic_cast< YACS::HMI::SubjectSwitch*>(subject);
119   if (aSwitch)
120     {
121       map<int, SubjectNode*> bodyMap = aSwitch->getBodyMap();
122       int swCase = 0;
123       if (bodyMap.empty()) swCase = 1;
124       else
125         {
126           map<int, SubjectNode*>::reverse_iterator rit = bodyMap.rbegin();
127           swCase = (*rit).first + 1;
128         }
129       if (!aSwitch->addNode(catalog, "", typeNode, name.str(), swCase))
130         Message mess;
131     }
132   else
133     if (!subject->addNode(catalog, "", typeNode, name.str()))
134       Message mess;
135 }
136
137 void GuiEditor::CreateBloc()
138 {
139   DEBTRACE("GuiEditor::CreateBloc");
140   CreateNode("Bloc");
141 }
142
143 void GuiEditor::CreateForLoop()
144 {
145   DEBTRACE("GuiEditor::CreateForLoop");
146   CreateNode("ForLoop");
147 }
148
149 void GuiEditor::CreateForEachLoop()
150 {
151   DEBTRACE("GuiEditor::CreateForEachLoop");
152   CreateNode("ForEachLoopDouble");
153 }
154
155 void GuiEditor::CreateWhileLoop()
156 {
157   DEBTRACE("GuiEditor::CreateWhileLoop");
158   CreateNode("WhileLoop");
159 }
160
161 void GuiEditor::CreateSwitch()
162 {
163   DEBTRACE("GuiEditor::CreateSwitch");
164   CreateNode("Switch");
165 }
166
167 void GuiEditor::CreateContainer()
168 {
169   DEBTRACE("GuiEditor::CreateContainer");
170   SubjectProc *sproc = QtGuiContext::getQtCurrent()->getSubjectProc();
171   assert(sproc);
172   std::stringstream name;
173   name << "container" << GuiContext::getCurrent()->getNewId();
174   sproc->addContainer(name.str());
175 }
176
177 SubjectDataPort* GuiEditor::CreateInputPort(SubjectElementaryNode* seNode, 
178                                             std::string name,
179                                             YACS::ENGINE::Catalog *catalog,
180                                             std::string type,
181                                             SubjectDataPort* before)
182 {
183   DEBTRACE("GuiEditor::CreateInputPort");
184
185   std::stringstream aName;
186   if (name.empty())
187     aName << "i" << GuiContext::getCurrent()->getNewId();
188   else
189     aName << name;
190   SubjectDataPort *sdp = seNode->addInputPort(catalog,type, aName.str());
191   if (!sdp)
192     Message mess;
193   return sdp;
194 }
195
196 SubjectDataPort*  GuiEditor::CreateOutputPort(SubjectElementaryNode* seNode, 
197                                               std::string name,
198                                               YACS::ENGINE::Catalog *catalog,
199                                               std::string type,
200                                               SubjectDataPort* before)
201 {
202   DEBTRACE("GuiEditor::CreateOutputPort");
203
204   std::stringstream aName;
205   if (name.empty())
206     aName << "o" << GuiContext::getCurrent()->getNewId();
207   else
208     aName << name;
209   SubjectDataPort *sdp = seNode->addOutputPort(catalog,type, aName.str());
210   if (!sdp)
211     Message mess;
212   return sdp;
213 }
214
215 /*!
216  * Subject destruction, command from popup menu: needs a valid selection
217  */
218 void GuiEditor::DeleteSubject()
219 {
220   DEBTRACE("GuiEditor::DeleteSubject");
221   QModelIndexList selList
222     = QtGuiContext::getQtCurrent()->getSelectionModel()->selectedIndexes();
223   if (selList.isEmpty())
224     return;
225
226   QModelIndex selected = selList.front();
227   if (!selected.isValid())
228     return;
229
230   SchemaItem *selItem = static_cast<SchemaItem*>(selected.internalPointer());
231   if (!selItem) return;
232   Subject *subToRemove = selItem->getSubject();
233   Subject *subParent = subToRemove->getParent();
234
235   DeleteSubject(subParent, subToRemove);
236 }
237
238 /*!
239  * Subject destruction, command from button in port table view or via selection
240  */
241 void GuiEditor::DeleteSubject(Subject* parent,
242                               Subject* toRemove)
243 {
244   DEBTRACE("GuiEditor::DeleteSubject "<<parent->getName()<<" "<<toRemove->getName());
245   parent->destroy(toRemove);
246 }
247
248 void GuiEditor::CutSubject()
249 {
250   DEBTRACE("GuiEditor::CutSubject");
251   Subject *sub = QtGuiContext::getQtCurrent()->getSelectedSubject();
252   if (!sub)
253     {
254       Message mess("GuiEditor::Cut : invalid selection!");
255       return;
256     }
257   DEBTRACE(sub->getName());
258   QtGuiContext::getQtCurrent()->setSubjectToCut(sub);
259 }
260
261 void GuiEditor::CopySubject()
262 {
263   DEBTRACE("GuiEditor::CopySubject");
264   Subject *sub = QtGuiContext::getQtCurrent()->getSelectedSubject();
265   if (!sub)
266     {
267       Message mess("GuiEditor::Copy : invalid selection!");
268       return;
269     }
270   DEBTRACE(sub->getName());
271   QtGuiContext::getQtCurrent()->setSubjectToCopy(sub);
272 }
273
274 void GuiEditor::PasteSubject()
275 {
276   DEBTRACE("GuiEditor::PasteSubject");
277   Subject *newParent = QtGuiContext::getQtCurrent()->getSelectedSubject();
278   if (!newParent)
279     {
280       Message mess("GuiEditor::Paste : invalid selection!");
281       return;
282     }
283   bool isCut = false;
284   Subject *sub = QtGuiContext::getQtCurrent()->getSubjectToPaste(isCut);
285   if (!sub)
286     {
287       Message mess("Nothing to paste");
288       return;
289     }
290   if (SubjectNode *snode = dynamic_cast<SubjectNode*>(sub))
291     {
292       if (isCut)
293         {
294           DEBTRACE("cut");
295           if (!snode->reparent(newParent))
296             Message mess;
297         }
298       else
299         {
300           DEBTRACE("copy");
301           if (!snode->copy(newParent))
302             Message mess;
303         }
304       return;
305     }
306   Message mess("Paste not possible for this kind of object");
307 }
308
309 void GuiEditor::rebuildLinks()
310 {
311 // --- only global link redraw for now...
312   
313   YACS::HMI::SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
314   SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
315   SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
316   proc->rebuildLinks();
317 }
318
319 void GuiEditor::arrangeNodes(bool isRecursive)
320 {
321   Subject *sub = QtGuiContext::getQtCurrent()->getSelectedSubject();
322   if (!sub)
323     {
324       DEBTRACE("GuiEditor::arrangeNodes : invalid selection!");
325       return;
326     }
327   DEBTRACE(sub->getName());
328
329   if (! QtGuiContext::getQtCurrent()->_mapOfSceneItem.count(sub))
330     {
331       DEBTRACE("no scene item corresponding to this subject");
332       return;
333     }
334   SceneItem* item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[sub];
335   SceneComposedNodeItem *sci = dynamic_cast<SceneComposedNodeItem*>(item);
336   if (! sci)
337     {
338       DEBTRACE("no scene composed node item corresponding to this subject");
339       return;
340     }
341   sci->arrangeNodes(isRecursive);
342 }