1 // Copyright (C) 2006-2012 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include "Resource.hxx"
23 #include "SchemaComposedNodeItem.hxx"
24 #include "SchemaNodeItem.hxx"
25 #include "SchemaInPortItem.hxx"
26 #include "SchemaOutPortItem.hxx"
27 #include "SchemaComponentItem.hxx"
28 #include "SchemaContainerItem.hxx"
29 #include "SchemaDataTypeItem.hxx"
30 #include "SchemaLinkItem.hxx"
31 #include "SchemaDirTypesItem.hxx"
32 #include "SchemaDirContainersItem.hxx"
33 #include "SchemaDirLinksItem.hxx"
35 #include "Message.hxx"
36 #include "QtGuiContext.hxx"
37 #include "ItemMimeData.hxx"
38 #include "GuiEditor.hxx"
39 #include "RuntimeSALOME.hxx"
40 #include "Catalog.hxx"
42 #include "commandsProc.hxx"
43 #include "ComposedNode.hxx"
44 #include "guiObservers.hxx"
54 #include "YacsTrace.hxx"
57 using namespace YACS::ENGINE;
58 using namespace YACS::HMI;
60 SchemaComposedNodeItem::SchemaComposedNodeItem(SchemaItem *parent, QString label, Subject* subject)
61 : SchemaItem(parent, label, subject)
63 DEBTRACE("SchemaComposedNodeItem::SchemaComposedNodeItem");
64 switch (subject->getType())
67 _itemDeco.replace(YLabel, QIcon("icons:block_node.png"));
69 case YACS::HMI::FORLOOP:
70 case YACS::HMI::FOREACHLOOP:
71 case YACS::HMI::WHILELOOP:
72 case YACS::HMI::OPTIMIZERLOOP:
73 _itemDeco.replace(YLabel, QIcon("icons:loop_node.png"));
75 case YACS::HMI::SWITCH:
76 _itemDeco.replace(YLabel, QIcon("icons:switch_node.png"));
79 _itemDeco.replace(YLabel, QIcon("icons:block_node.png"));
82 _dirContainersItem = 0;
85 int nbsons = childCount();
86 SchemaModel *model = QtGuiContext::getQtCurrent()->getSchemaModel();
88 model->beginInsertRows(modelIndex(), nbsons, nbsons);
89 if (SubjectProc* sProc = dynamic_cast<SubjectProc*>(subject))
91 son = new Subject(getSubject());
92 _dirTypesItem = new SchemaDirTypesItem(this, "Types", son);
93 son = new Subject(getSubject());
94 _dirContainersItem = new SchemaDirContainersItem(this, "Containers", son);
96 son = new Subject(getSubject());
97 _dirLinksItem = new SchemaDirLinksItem(this, "Links", son);
98 model->endInsertRows();
100 if (!model->isEdition())
102 setExecState(YACS::UNDEFINED);
105 SubjectComposedNode *scn = dynamic_cast<SubjectComposedNode*>(subject);
109 _itemData.replace(YType, scn->getValue().c_str());
110 model->setData(modelIndex(YType), 0);
116 SchemaComposedNodeItem::~SchemaComposedNodeItem()
118 DEBTRACE("SchemaComposedNodeItem::~SchemaComposedNodeItem");
121 void SchemaComposedNodeItem::update(GuiEvent event, int type, Subject* son)
123 DEBTRACE("SchemaComposedNodeItem::update "<<eventName(event)<<" "<<type<<" "<<son);
124 SchemaModel *model = QtGuiContext::getQtCurrent()->getSchemaModel();
125 SchemaItem *item = 0;
126 SubjectNode *snode = 0;
127 SubjectComposedNode *scnode = 0;
134 case YACS::HMI::BLOC:
135 case YACS::HMI::FORLOOP:
136 case YACS::HMI::WHILELOOP:
137 case YACS::HMI::SWITCH:
138 case YACS::HMI::FOREACHLOOP:
139 case YACS::HMI::OPTIMIZERLOOP:
141 int nbsons = childCount();
142 model->beginInsertRows(modelIndex(), nbsons, nbsons);
143 item = new SchemaComposedNodeItem(this,
144 son->getName().c_str(),
146 model->endInsertRows();
149 case YACS::HMI::PYTHONNODE:
150 case YACS::HMI::PYFUNCNODE:
151 case YACS::HMI::CORBANODE:
152 case YACS::HMI::CPPNODE:
153 case YACS::HMI::SALOMENODE:
154 case YACS::HMI::SALOMEPYTHONNODE:
155 case YACS::HMI::XMLNODE:
156 case YACS::HMI::PRESETNODE:
157 case YACS::HMI::OUTNODE:
158 case YACS::HMI::STUDYINNODE:
159 case YACS::HMI::STUDYOUTNODE:
161 int nbsons = childCount();
162 model->beginInsertRows(modelIndex(), nbsons, nbsons);
163 item = new SchemaNodeItem(this,
164 son->getName().c_str(),
166 model->endInsertRows();
169 case YACS::HMI::INPUTPORT:
170 case YACS::HMI::INPUTDATASTREAMPORT:
172 int nbsons = childCount();
173 model->beginInsertRows(modelIndex(), nbsons, nbsons);
174 item = new SchemaInPortItem(this,
175 son->getName().c_str(),
177 model->endInsertRows();
180 case YACS::HMI::OUTPUTPORT:
181 case YACS::HMI::OUTPUTDATASTREAMPORT:
183 int nbsons = childCount();
184 model->beginInsertRows(modelIndex(), nbsons, nbsons);
185 item = new SchemaOutPortItem(this,
186 son->getName().c_str(),
188 model->endInsertRows();
191 case YACS::HMI::COMPONENT:
193 YASSERT(_dirContainersItem);
194 _dirContainersItem->addComponentItem(son);
197 case YACS::HMI::CONTAINER:
199 YASSERT(_dirContainersItem);
200 _dirContainersItem->addContainerItem(son);
203 case YACS::HMI::DATATYPE:
205 YASSERT(_dirTypesItem);
206 _dirTypesItem->addTypeItem(son);
212 case YACS::HMI::REMOVE:
215 case YACS::HMI::DATATYPE:
217 YASSERT(_dirTypesItem);
218 _dirTypesItem->removeTypeItem(son);
224 case YACS::HMI::UPDATE:
225 snode = dynamic_cast<SubjectNode*>(_subject);
227 node = snode->getNode();
229 switch (node->getState())
232 _itemForeground.replace(YLabel, QColor("red"));
233 model->setData(modelIndex(YLabel), 0);
236 _itemForeground.replace(YLabel, QColor("blue"));
237 model->setData(modelIndex(YLabel), 0);
243 case YACS::HMI::ADDLINK:
244 case YACS::HMI::ADDCONTROLLINK:
246 YASSERT(_dirLinksItem);
247 _dirLinksItem->addLinkItem(son);
250 case YACS::HMI::UPDATEPROGRESS:
252 model->setData(modelIndex(YState), 0);
254 case YACS::HMI::SETVALUE:
255 scnode = dynamic_cast<SubjectComposedNode*>(_subject);
256 if (scnode->hasValue())
258 _itemData.replace(YType, scnode->getValue().c_str());
259 model->setData(modelIndex(YType), 0);
261 case YACS::HMI::SETCASE:
263 SubjectSwitch *sSwitch = dynamic_cast<SubjectSwitch*>(_subject);
266 Switch *aSwitch = dynamic_cast<Switch*>(sSwitch->getNode());
267 Node *node = aSwitch->edGetNode(type);
270 if (GuiContext::getCurrent()->_mapOfSubjectNode.count(node))
272 Subject* sub = GuiContext::getCurrent()->_mapOfSubjectNode[node];
273 if (QtGuiContext::getQtCurrent()->_mapOfSchemaItem.count(sub))
275 SchemaItem* item = QtGuiContext::getQtCurrent()->_mapOfSchemaItem[sub];
276 item->setCaseValue();
283 case YACS::HMI::SETSELECT:
285 SubjectSwitch *sSwitch = dynamic_cast<SubjectSwitch*>(_subject);
286 if (sSwitch && sSwitch->hasValue())
288 _itemData.replace(YType, sSwitch->getValue().c_str());
289 model->setData(modelIndex(YType), 0);
295 SchemaItem *toMove = QtGuiContext::getQtCurrent()->_mapOfSchemaItem[son];
296 int position = toMove->row();
297 model->beginRemoveRows(modelIndex(), position, position);
299 model->endRemoveRows();
302 case YACS::HMI::PASTE:
304 SchemaItem *toPaste = QtGuiContext::getQtCurrent()->_mapOfSchemaItem[son];
305 int nbsons = childCount();
306 model->beginInsertRows(modelIndex(), nbsons, nbsons);
307 toPaste->reparent(this);
308 model->endInsertRows();
312 //DEBTRACE("SchemaComposedNodeItem::update(), event not handled: "<< eventName(event));
313 SchemaItem::update(event, type, son);
317 std::list<YACS::ENGINE::Node*> SchemaComposedNodeItem::getDirectDescendants() const
319 SubjectNode* SNode = dynamic_cast<SubjectNode*>(_subject);
321 ComposedNode* CNode = dynamic_cast<ComposedNode*>(SNode->getNode());
323 return CNode->edGetDirectDescendants();
326 void SchemaComposedNodeItem::popupMenu(QWidget *caller, const QPoint &globalPos)
329 m.popupMenu(caller, globalPos);
332 Qt::ItemFlags SchemaComposedNodeItem::flags(const QModelIndex &index)
334 //DEBTRACE("SchemaComposedNodeItem::flags");
335 Qt::ItemFlags pflag = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
336 if (!QtGuiContext::getQtCurrent() || !QtGuiContext::getQtCurrent()->isEdition())
339 Qt::ItemFlags flagEdit = 0;
340 int column = index.column();
344 flagEdit = Qt::ItemIsEditable; // --- item value editable in model view (for node case in switch)
348 return pflag | flagEdit;
353 * drop in composed nodes are used for add nodes from catalog, or reparent nodes,
356 bool SchemaComposedNodeItem::dropMimeData(const QMimeData* data, Qt::DropAction action)
358 DEBTRACE("SchemaComposedNodeItem::dropMimeData");
359 if (!data) return false;
360 const ItemMimeData* myData = dynamic_cast<const ItemMimeData*>(data);
361 if (!myData) return false;
363 if (myData->hasFormat("yacs/cataService") || myData->hasFormat("yacs/cataNode"))
366 SubjectComposedNode *cnode = dynamic_cast<SubjectComposedNode*>(getSubject());
367 bool createNewComponentInstance=Resource::COMPONENT_INSTANCE_NEW;
368 // by default getControl gives false. In this case we use the user preference COMPONENT_INSTANCE_NEW
369 // to create the node. If getControl gives true we invert the user preference
370 if(myData->getControl())
371 createNewComponentInstance=!Resource::COMPONENT_INSTANCE_NEW;
372 QtGuiContext::getQtCurrent()->getGMain()->_guiEditor->CreateNodeFromCatalog(myData, cnode,createNewComponentInstance);
374 else if(myData->hasFormat("yacs/subjectNode"))
377 Subject *sub = myData->getSubject();
378 if (!sub) return false;
379 SubjectNode *node = dynamic_cast<SubjectNode*>(sub);
380 if (!node) return false;
381 SubjectComposedNode *cnode = dynamic_cast<SubjectComposedNode*>(getSubject());
383 if (! node->reparent(cnode))
386 else if(myData->hasFormat("yacs/subjectOutGate"))
388 Subject *subFrom = myData->getSubject();
389 if (!subFrom) return false;
390 SubjectNode* from = dynamic_cast<SubjectNode*>(subFrom);
392 SubjectNode *to = dynamic_cast<SubjectNode*>(getSubject());
393 if (!to) return false;
399 if (!SubjectNode::tryCreateLink(from, to))
407 * drag for composed nodes in tree are used for control link with Left Mouse Button
408 * and for reparent with Middle Mouse Button
410 QString SchemaComposedNodeItem::getMimeFormat()
412 if (QApplication::mouseButtons() == Qt::MidButton)
413 return "yacs/subjectNode";
415 return "yacs/subjectOutGate";
418 void SchemaComposedNodeItem::setCaseValue()
420 DEBTRACE("SchemaComposedNodeItem::setCaseValue");
421 Subject *sub = _parentItem->getSubject();
422 SubjectSwitch *sSwitch = dynamic_cast<SubjectSwitch*>(sub);
423 if (!sSwitch) return;
425 SchemaModel *model = QtGuiContext::getQtCurrent()->getSchemaModel();
426 Switch *aSwitch = dynamic_cast<Switch*>(sSwitch->getNode());
428 SubjectNode *sNode = dynamic_cast<SubjectNode*>(_subject);
430 int rank = aSwitch->getRankOfNode(sNode->getNode());
431 if (rank == Switch::ID_FOR_DEFAULT_NODE)
432 _itemData.replace(YValue, "default");
434 _itemData.replace(YValue, rank);
435 model->setData(modelIndex(YValue), 0);
438 QVariant SchemaComposedNodeItem::editionWhatsThis(int column) const
440 return "<p>To edit the node properties, select the node and use the input panel. <a href=\"modification.html#property-page-for-block-node\">More...</a></p>";