Salome HOME
updated copyright message
[modules/yacs.git] / src / genericgui / SchemaNodeItem.cxx
1 // Copyright (C) 2006-2023  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, or (at your option) any later version.
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
20 #include "SchemaNodeItem.hxx"
21 #include "SchemaInPortItem.hxx"
22 #include "SchemaOutPortItem.hxx"
23 #include "InputPort.hxx"
24 #include "OutputPort.hxx"
25 #include "ItemMimeData.hxx"
26 #include "QtGuiContext.hxx"
27 #include "GuiExecutor.hxx"
28 #include "Menus.hxx"
29 #include "Message.hxx"
30
31 #include "Node.hxx"
32 #include "Switch.hxx"
33
34 #include <QIcon>
35
36 #include <cassert>
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 SchemaNodeItem::SchemaNodeItem(SchemaItem *parent, QString label, Subject* subject)
46   : SchemaItem(parent, label, subject)
47 {
48   DEBTRACE("SchemaNodeItem::SchemaNodeItem");
49   _itemDeco.replace(YLabel, QIcon("icons:node.png"));
50   SchemaModel *model = QtGuiContext::getQtCurrent()->getSchemaModel();
51   if (!model->isEdition())
52     {
53       _itemCheckState.replace(YLabel, Qt::Unchecked);
54       setExecState(YACS::UNDEFINED);
55     }
56   setCaseValue();
57 }
58
59 SchemaNodeItem::~SchemaNodeItem()
60 {
61   DEBTRACE("SchemaNodeItem::~SchemaNodeItem");
62 }
63
64 void SchemaNodeItem::update(GuiEvent event, int type, Subject* son)
65 {
66   DEBTRACE("SchemaNodeItem::update "<<eventName(event)<<" "<<type<<" "<<son);
67   SchemaModel *model = QtGuiContext::getQtCurrent()->getSchemaModel();
68   SchemaItem *item = 0;
69   SubjectNode *snode = 0;
70   Node* node = 0;
71   switch (event)
72     {
73     case YACS::HMI::ADD:
74       switch (type)
75         {
76         case YACS::HMI::INPUTPORT:
77         case YACS::HMI::INPUTDATASTREAMPORT:
78           {
79             int nbsons = childCount();
80             model->beginInsertRows(modelIndex(), nbsons, nbsons);
81             item =  new SchemaInPortItem(this,
82                                          son->getName().c_str(),
83                                          son);
84             model->endInsertRows();
85           }
86           break;
87         case YACS::HMI::OUTPUTPORT:
88         case YACS::HMI::OUTPUTDATASTREAMPORT:
89           {
90             int nbsons = childCount();
91             model->beginInsertRows(modelIndex(), nbsons, nbsons);
92             item =  new SchemaOutPortItem(this,
93                                           son->getName().c_str(),
94                                           son);
95             model->endInsertRows();
96           }
97           break;
98 //         default:
99 //           DEBTRACE("SchemaNodeItem::update(), ADD, type not handled: " << type);
100         }
101       break;
102     case YACS::HMI::ORDER:
103       {
104         YASSERT(QtGuiContext::getQtCurrent()->_mapOfSchemaItem.count(son));
105         //bool isInput = dynamic_cast<SubjectInputPort*>(son);
106
107         snode = dynamic_cast<SubjectNode*>(_subject);
108         YASSERT(snode);
109         Node* node = snode->getNode();
110         ElementaryNode* father = dynamic_cast<ElementaryNode*>(node);
111         YASSERT(father);
112         int nbChildren = childCount();
113
114         model->beginRemoveRows(modelIndex(), 0, nbChildren-1);
115         for (int i = nbChildren; i >= 0; i--)
116           removeChild(child(i));
117         model->endRemoveRows();
118
119         list<InputPort*> plisti = father->getSetOfInputPort();
120         int nbIn = plisti.size();
121         if (nbIn)
122           {
123             model->beginInsertRows(modelIndex(), 0, nbIn-1);
124             list<InputPort*>::iterator iti = plisti.begin();
125             for(; iti != plisti.end(); iti++)
126               {
127                 Subject *sub = QtGuiContext::getQtCurrent()->_mapOfSubjectDataPort[(*iti)];
128                 SchemaItem *item = QtGuiContext::getQtCurrent()->_mapOfSchemaItem[sub];
129                 appendChild(item);
130               }
131             model->endInsertRows();
132           }
133
134         list<OutputPort*> plisto = father->getSetOfOutputPort();
135         int nbOut = plisto.size();
136         if (nbOut)
137           {
138             model->beginInsertRows(modelIndex(), nbIn, nbIn + nbOut -1);
139             list<OutputPort*>::iterator ito = plisto.begin();
140             for(; ito != plisto.end(); ito++)
141               {
142                 Subject *sub = QtGuiContext::getQtCurrent()->_mapOfSubjectDataPort[(*ito)];
143                 SchemaItem *item = QtGuiContext::getQtCurrent()->_mapOfSchemaItem[sub];
144                 appendChild(item);
145               }
146             model->endInsertRows();
147           }
148       }
149       break;
150     case YACS::HMI::UPDATE:
151       snode = dynamic_cast<SubjectNode*>(_subject);
152       YASSERT(snode);
153       node = snode->getNode();
154       YASSERT(node);
155       switch (node->getState())
156         {
157         case YACS::INVALID:
158           _itemForeground.replace(YLabel, QColor("red"));
159           model->setData(modelIndex(YLabel), 0);  // --- to emit dataChanged signal
160           break;
161         case YACS::READY:
162           _itemForeground.replace(YLabel, QColor("blue"));
163           model->setData(modelIndex(YLabel), 0);
164           break;
165         default:
166           break;
167         }
168       break;
169     case YACS::HMI::UPDATEPROGRESS:
170       setExecState(type);
171       model->setData(modelIndex(YState), 0);
172       break;
173     default:
174       //DEBTRACE("SchemaNodeItem::update(), event not handled: " << eventName(event));
175       SchemaItem::update(event, type, son);
176     }
177 }
178
179 void SchemaNodeItem::popupMenu(QWidget *caller, const QPoint &globalPos)
180 {
181   ElementaryNodeMenu m;
182   m.popupMenu(caller, globalPos);
183 }
184
185 Qt::ItemFlags SchemaNodeItem::flags(const QModelIndex &index)
186 {
187   Qt::ItemFlags pflag = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled;
188   if ( !QtGuiContext::getQtCurrent() || !QtGuiContext::getQtCurrent()->isEdition())
189     return pflag;
190
191   if (QtGuiContext::getQtCurrent()->isEdition())
192     pflag = pflag | Qt::ItemIsDragEnabled;
193   Qt::ItemFlags flagEdit = 0;
194   int column = index.column();
195   switch (column)
196     {
197     case YValue:
198       flagEdit = Qt::ItemIsEditable; // --- item value editable in model view (for node case in switch)
199       break;     
200     }
201
202   return pflag | flagEdit;
203 }
204
205 /*!
206  *  drag for nodes in tree are used for control link with Left Mouse Button
207  *  and for reparent with Middle Mouse Button
208  */
209 QString SchemaNodeItem::getMimeFormat()
210 {
211   if (QApplication::mouseButtons() == Qt::MidButton)
212     return "yacs/subjectNode";
213   else
214     return "yacs/subjectOutGate";
215 }
216
217 void SchemaNodeItem::toggleState()
218 {
219   DEBTRACE("SchemaNodeItem::toggleState");
220   SchemaItem::toggleState();
221   GuiExecutor *guiExec = QtGuiContext::getQtCurrent()->getGuiExecutor();
222   YASSERT(guiExec);
223   SubjectNode *subjectNode = dynamic_cast<SubjectNode*>(getSubject());
224   YASSERT(subjectNode);
225   string nodeName = QtGuiContext::getQtCurrent()->getProc()->getChildName(subjectNode->getNode());
226   DEBTRACE("nodeName=" << nodeName);
227
228   if (_itemCheckState.value(YLabel) == Qt::Checked) // already toggled
229     guiExec->addBreakpoint(nodeName);
230   else
231     guiExec->removeBreakpoint(nodeName);
232 }
233
234 /*!
235  *  drop in nodes are used for control link
236  */
237 bool SchemaNodeItem::dropMimeData(const QMimeData* data, Qt::DropAction action)
238 {
239   DEBTRACE("SchemaNodeItem::dropMimeData");
240   if (!data) return false;
241   const ItemMimeData* myData = dynamic_cast<const ItemMimeData*>(data);
242   if (!myData) return false;
243   if(!myData->hasFormat("yacs/subjectOutGate")) return false;
244
245   Subject *subFrom = myData->getSubject();
246   if (!subFrom) return false;
247   SubjectNode* from = dynamic_cast<SubjectNode*>(subFrom);
248
249   SubjectNode *to = dynamic_cast<SubjectNode*>(getSubject());
250   if (!to) return false;
251
252   bool ret =false;
253   if (from && to)
254     {
255        ret =true;
256        if (!SubjectNode::tryCreateLink(from, to))
257          Message mess;
258     }
259   return ret;
260 }
261
262 void SchemaNodeItem::setCaseValue()
263 {
264   DEBTRACE("SchemaNodeItem::setCaseValue");
265   Subject *sub = _parentItem->getSubject();
266   SubjectSwitch *sSwitch = dynamic_cast<SubjectSwitch*>(sub);
267   if (!sSwitch) return;
268
269   SchemaModel *model = QtGuiContext::getQtCurrent()->getSchemaModel();
270   Switch *aSwitch = dynamic_cast<Switch*>(sSwitch->getNode());
271   YASSERT(aSwitch);
272   SubjectNode *sNode = dynamic_cast<SubjectNode*>(_subject);
273   YASSERT(sNode);
274   int rank = aSwitch->getRankOfNode(sNode->getNode());
275   if (rank == Switch::ID_FOR_DEFAULT_NODE)
276     _itemData.replace(YValue, "default");
277   else
278     _itemData.replace(YValue, rank);
279   model->setData(modelIndex(YValue), 0);
280 }
281
282 QVariant SchemaNodeItem::editionWhatsThis(int column) const
283 {
284   return "<p>To edit the node properties, select the node and use the input panel. <a href=\"modification.html#property-page-for-node\">More...</a></p>";
285 }