Salome HOME
Copyright update 2022
[modules/yacs.git] / src / genericgui / SchemaItem.cxx
1 // Copyright (C) 2006-2022  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 "SchemaItem.hxx"
21 #include "QtGuiContext.hxx"
22 #include "Resource.hxx"
23 #include "Menus.hxx"
24 #include "ItemMimeData.hxx"
25
26 #include <QMetaType>
27 #include <QVariant>
28 #include <QMenu>
29
30 Q_DECLARE_METATYPE(YACS::HMI::Subject);
31
32 //#define _DEVDEBUG_
33 #include "YacsTrace.hxx"
34
35 using namespace std;
36 using namespace YACS::HMI;
37
38
39 SchemaItem::SchemaItem(SchemaItem *parent, QString label, Subject* subject)
40 {
41   DEBTRACE("SchemaItem::SchemaItem " << label.toStdString() << " " << this);
42   _parentItem = parent;
43   _label = label;
44   _subject = subject;
45
46   _itemData << QVariant() << QVariant() << QVariant(); // --- 3 columns max
47   _itemDeco << QVariant() << QVariant() << QVariant(); // --- 3 columns max
48   _itemForeground << QVariant() << QVariant() << QVariant(); // --- 3 columns max
49   _itemBackground << QVariant() << QVariant() << QVariant(); // --- 3 columns max
50   _itemCheckState << QVariant() << QVariant() << QVariant(); // --- 3 columns max
51   _itemToolTip    << QVariant() << QVariant() << QVariant(); // --- 3 columns max
52   _itemWhatsThis  << QVariant() << QVariant() << QVariant(); // --- 3 columns max
53   _itemData.replace(YLabel, label);
54   _itemToolTip.replace(YLabel, label);
55   _itemWhatsThis.replace(YLabel, QString("This is the default WhatsThis of ") + label);
56
57   _itemForeground.replace(YLabel, QColor("blue"));
58   _itemBackground.replace(YLabel, QtGuiContext::getQtCurrent()->getSchemaModel()->stdBackBrush());
59   //_itemCheckState.replace(YLabel, Qt::Unchecked); // --- only for item with checkbox
60
61   if (_subject)
62     {
63       _subject->attach(this);
64       QtGuiContext::getQtCurrent()->_mapOfSchemaItem[_subject]=this;
65     }
66
67   if (_parentItem)
68     _parentItem->appendChild(this);
69   _execState = YACS::UNDEFINED;
70   _emphasized = false;
71 }
72
73 SchemaItem::~SchemaItem()
74 {
75   DEBTRACE("SchemaItem::~SchemaItem " << _label.toStdString() << " " << this);
76   if (_parentItem)
77     {
78       SchemaModel *model = QtGuiContext::getQtCurrent()->getSchemaModel();
79       int position = row();
80       model->beginRemoveRows(_parentItem->modelIndex(), position, position);
81       if (_subject) QtGuiContext::getQtCurrent()->_mapOfSchemaItem.erase(_subject);
82       _parentItem->removeChild(this);
83       model->endRemoveRows();
84     }
85 }
86
87 void SchemaItem::appendChild(SchemaItem *child)
88 {
89   DEBTRACE("SchemaItem::appendChild");
90   _childItems.append(child);
91 }
92
93 void SchemaItem::removeChild(SchemaItem *child)
94 {
95   DEBTRACE("SchemaItem::removeChild");
96   _childItems.removeAll(child);
97 }
98
99 void SchemaItem::insertChild(int row, SchemaItem *child)
100 {
101   DEBTRACE("SchemaItem::insertChild");
102   _childItems.insert(row, child);
103 }
104
105 SchemaItem *SchemaItem::child(int row)
106 {
107   //DEBTRACE("SchemaItem::child");
108   return _childItems.value(row);
109 }
110
111 int SchemaItem::childCount() const
112 {
113   //DEBTRACE("SchemaItem::childCount " << _label.toStdString() << " " << _childItems.count());
114   return _childItems.count();
115 }
116
117 int SchemaItem::columnCount() const
118 {
119   //DEBTRACE("SchemaItem::columnCount " << _itemData.count());
120   return _itemData.count();
121 }
122
123 QVariant SchemaItem::data(int column, int role) const
124 {
125   //DEBTRACE("SchemaItem::data "<< column);
126   if (role == Qt::DisplayRole)
127     return _itemData.value(column);
128   if (role == Qt::DecorationRole)
129     return _itemDeco.value(column);
130   if (role == Qt::ForegroundRole)
131     return _itemForeground.value(column);
132   if (role == Qt::BackgroundRole)
133     return _itemBackground.value(column);
134   if (role == Qt::CheckStateRole)
135     return _itemCheckState.value(column);
136   if (role == Qt::ToolTipRole)
137     if (QtGuiContext::getQtCurrent()->isEdition())
138       return editionToolTip(column);
139     else
140       return runToolTip(column);
141   if (role == Qt::WhatsThisRole)
142     if (QtGuiContext::getQtCurrent()->isEdition())
143       return editionWhatsThis(column);
144     else
145       return runWhatsThis(column);
146   return QVariant();
147 }
148
149 Qt::ItemFlags SchemaItem::flags(const QModelIndex &index)
150 {
151   return Qt::ItemIsEnabled | Qt::ItemIsSelectable;// | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
152 }
153
154 int SchemaItem::row() const
155 {
156   //DEBTRACE("SchemaItem::row");
157   int row=0;
158   if (_parentItem)
159     row = _parentItem->_childItems.indexOf(const_cast<SchemaItem*>(this));
160   return row;
161 }
162
163 SchemaItem *SchemaItem::parent()
164 {
165   //DEBTRACE("SchemaItem::parent");
166   return _parentItem;
167 }
168
169 Subject* SchemaItem::getSubject()
170 {
171   return _subject;
172 }
173
174 void SchemaItem::update(GuiEvent event, int type, Subject* son)
175 {
176   //DEBTRACE("SchemaItem::update "<< eventName(event) <<" "<<type<<" "<<son);
177   QModelIndex index = QModelIndex();
178   SchemaModel *model = QtGuiContext::getQtCurrent()->getSchemaModel();
179   switch (event)
180     {
181     case RENAME:
182       DEBTRACE("SchemaItem::update RENAME " << _subject->getName());
183       _label = _subject->getName().c_str();
184       _itemData.replace(YLabel, _label);
185       model->setData(modelIndex(YLabel), 0);  // --- to emit dataChanged signal
186       break;
187     case EDIT:
188       if (type)
189         _itemBackground.replace(YLabel, model->editedBackBrush());
190       else
191         _itemBackground.replace(YLabel, model->stdBackBrush());
192       model->setData(modelIndex(YLabel), 0);  // --- to emit dataChanged signal
193       break;
194     case EMPHASIZE:
195       if (type)
196         _itemBackground.replace(YLabel, model->emphasizeBackBrush());
197       else
198         _itemBackground.replace(YLabel, model->stdBackBrush());
199       model->setData(modelIndex(YLabel), 0);  // --- to emit dataChanged signal
200       break;
201     default:
202       break;
203     }
204 }
205
206 void SchemaItem::select(bool isSelected)
207 {
208   DEBTRACE("SchemaItem::select " << _label.toStdString() << " " << isSelected);
209   QItemSelectionModel* selectionModel = QtGuiContext::getQtCurrent()->getSelectionModel();
210   QModelIndex anIndex = modelIndex();
211   QItemSelection newSelection(anIndex, anIndex);
212
213   if (isSelected)
214     {
215       if (!QtGuiContext::getQtCurrent()->_mapOfEditionItem.count(_subject))
216         {
217           int elemType = _subject->getType();
218           YACS::HMI::GuiEvent event = YACS::HMI::ADD;
219           if (elemType == YACS::HMI::DATALINK) event = YACS::HMI::ADDLINK;
220           else if (elemType == YACS::HMI::CONTROLLINK) event = YACS::HMI::ADDCONTROLLINK;
221           QtGuiContext::getQtCurrent()->getEditionRoot()->update(event, elemType, _subject);
222         }
223
224       QtGuiContext::getQtCurrent()->getGMain()->raiseStacked();
225       QItemSelection currentSelected = selectionModel->selection();
226       if (currentSelected != newSelection)
227         {
228           DEBTRACE("currentSelected != newSelection");
229           // selectionModel->select(newSelection, QItemSelectionModel::ClearAndSelect);
230           selectionModel->select(newSelection, QItemSelectionModel::Clear);
231           selectionModel->select(newSelection, QItemSelectionModel::Select);
232         }
233       QtGuiContext::getQtCurrent()->setSelectedSubject(_subject);
234     }
235   else
236     selectionModel->select(newSelection, QItemSelectionModel::Deselect);
237 }
238
239 void SchemaItem::toggleState()
240 {
241   if (_itemCheckState.value(YLabel) == Qt::Unchecked)
242     {
243       DEBTRACE("SchemaItem::toggleState true");
244       _itemCheckState.replace(YLabel, Qt::Checked);
245     }
246   else
247     {
248       DEBTRACE("SchemaItem::toggleState false");
249       _itemCheckState.replace(YLabel, Qt::Unchecked);
250     }
251 }
252
253 QModelIndex SchemaItem::modelIndex(int column)
254 {
255   //DEBTRACE("SchemaItem::modelIndex " << _label.toStdString() << " " << column);
256   SchemaModel *schema = QtGuiContext::getQtCurrent()->getSchemaModel();
257   if (_parentItem && (_parentItem !=schema->getRootItem()))
258     return schema->index(row(),
259                          column,
260                          _parentItem->modelIndex());
261   else
262     return schema->index(row(),
263                          column,
264                          QModelIndex());
265 }
266
267 void SchemaItem::popupMenu(QWidget *caller, const QPoint &globalPos)
268 {
269   MenusBase m;
270   m.popupMenu(caller, globalPos);
271 }
272
273 /*!
274  * setData mime type must be coherent with SchemaModel::mimeTypes
275  */
276 ItemMimeData* SchemaItem::mimeData(ItemMimeData *mime)
277 {
278   DEBTRACE("SchemaItem::mimeData");
279   mime->setSubject(_subject);
280   mime->setData(getMimeFormat(), "_subject");
281   return mime;
282 }
283
284 bool SchemaItem::dropMimeData(const QMimeData* data, Qt::DropAction action)
285 {
286   return false;
287 }
288
289 void SchemaItem::reparent(SchemaItem *parent)
290 {
291   _parentItem = parent;
292   if (_parentItem)
293     _parentItem->appendChild(this);
294 }
295
296 //! used in node derived classes
297 void SchemaItem::setCaseValue()
298 {
299 }
300
301 QVariant SchemaItem::editionToolTip(int column) const
302 {
303   QString val = QString("Edition: ") + _itemData.value(0).toString();
304   QString val1 = _itemData.value(1).toString();
305   QString val2 = _itemData.value(2).toString();
306   if (!val1.isEmpty()) val += QString(" | ") + val1;
307   if (!val2.isEmpty()) val += QString(" | ") + val2;
308   return val;
309 }
310
311 QVariant SchemaItem::runToolTip(int column) const
312 {
313   QString val = QString("Execution: ") + _itemData.value(0).toString();
314   QString val1 = _itemData.value(1).toString();
315   QString val2 = _itemData.value(2).toString();
316   if (!val1.isEmpty()) val += QString(" | ") + val1;
317   if (!val2.isEmpty()) val += QString(" | ") + val2;
318   return val;
319 }
320
321 QVariant SchemaItem::editionWhatsThis(int column) const
322 {
323   QString val = QString("Edition help: ") + _itemWhatsThis.value(column).toString();
324   return val;
325 }
326
327 QVariant SchemaItem::runWhatsThis(int column) const
328 {
329   QString val = QString("Execution help: ") + _itemWhatsThis.value(column).toString();
330   return val;
331 }
332
333 QString SchemaItem::getMimeFormat()
334 {
335   return "yacs/subject";
336 }
337
338 void SchemaItem::setExecState(int execState)
339 {
340   DEBTRACE("SchemaItem::setExecState " << execState);
341   _execState = execState;
342   QString stateDef;
343   QColor sc;
344   switch (_execState)
345     {
346       case YACS::UNDEFINED:    sc = Resource::UNDEFINED   ; stateDef = "UNDEFINED"   ; break;
347       case YACS::INVALID:      sc = Resource::INVALID     ; stateDef = "INVALID"     ; break;
348       case YACS::READY:        sc = Resource::READY       ; stateDef = "READY"       ; break;
349       case YACS::TOLOAD:       sc = Resource::TOLOAD      ; stateDef = "TOLOAD"      ; break;
350       case YACS::LOADED:       sc = Resource::LOADED      ; stateDef = "LOADED"      ; break;
351       case YACS::TOACTIVATE:   sc = Resource::TOACTIVATE  ; stateDef = "TOACTIVATE"  ; break;
352       case YACS::ACTIVATED:    sc = Resource::ACTIVATED   ; stateDef = "ACTIVATED"   ; break;
353       case YACS::DESACTIVATED: sc = Resource::DESACTIVATED; stateDef = "DESACTIVATED"; break;
354       case YACS::DONE:         sc = Resource::DONE        ; stateDef = "DONE"        ; break;
355       case YACS::SUSPENDED:    sc = Resource::SUSPENDED   ; stateDef = "SUSPENDED"   ; break;
356       case YACS::LOADFAILED:   sc = Resource::LOADFAILED  ; stateDef = "LOADFAILED"  ; break;
357       case YACS::EXECFAILED:   sc = Resource::EXECFAILED  ; stateDef = "EXECFAILED"  ; break;
358       case YACS::PAUSE:        sc = Resource::PAUSE       ; stateDef = "PAUSE"       ; break;
359       case YACS::INTERNALERR:  sc = Resource::INTERNALERR ; stateDef = "INTERNALERR" ; break;
360       case YACS::DISABLED:     sc = Resource::DISABLED    ; stateDef = "DISABLED"    ; break;
361       case YACS::FAILED:       sc = Resource::FAILED      ; stateDef = "FAILED"      ; break;
362       case YACS::ERROR:        sc = Resource::ERROR       ; stateDef = "ERROR"       ; break;
363       default:                 sc = Resource::DEFAULT     ; stateDef = "---"         ;
364    }
365   _itemData.replace(YState, stateDef);
366   _itemForeground.replace(YState, sc);
367 }