Salome HOME
478fdbccbfc18ef49d13f501cbb17ca8849f9a8f
[modules/yacs.git] / src / genericgui / SchemaModel.cxx
1 // Copyright (C) 2006-2014  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 "SchemaModel.hxx"
21 #include "SchemaItem.hxx"
22 #include "SchemaNodeItem.hxx"
23 #include "SchemaProcItem.hxx"
24 #include "QtGuiContext.hxx"
25 #include "GuiEditor.hxx"
26 #include "ItemMimeData.hxx"
27 #include "guiObservers.hxx"
28
29 #include <QMetaType>
30 #include <QVariant>
31 Q_DECLARE_METATYPE(YACS::HMI::Subject);
32
33 //#define _DEVDEBUG_
34 #include "YacsTrace.hxx"
35
36 using namespace std;
37 using namespace YACS::HMI;
38
39 SchemaModel::SchemaModel(YACS::HMI::Subject *context,
40                          QObject * parent): 
41   QAbstractItemModel(parent)
42 {
43   DEBTRACE("SchemaModel::SchemaModel");
44   _context=context;
45   _root=0;
46   _rootItem=0;
47   _context->attach(this);
48   _stdBackBrush = QColor("white");
49   _editedBackBrush = QColor("yellow");
50   _emphasizeBackBrush = QColor("magenta");
51   _isEdition = true;
52 }
53
54 SchemaModel::~SchemaModel()
55 {
56   DEBTRACE("SchemaModel::~SchemaModel");
57   _subjectSet.clear(); // --- avoid destruction loop on delete context
58 }
59
60 QModelIndex SchemaModel::index(int row, int column, const QModelIndex &parent) const
61 {
62   //  DEBTRACE("SchemaModel::index");
63   if (!hasIndex(row, column, parent))
64     return QModelIndex();
65
66   SchemaItem *parentItem = 0;
67
68   if (!parent.isValid())
69     parentItem = _rootItem;
70   else
71     parentItem = static_cast<SchemaItem*>(parent.internalPointer());
72
73   SchemaItem *childItem = parentItem->child(row);
74   if (childItem)
75     return createIndex(row, column, childItem);
76   else
77     return QModelIndex();
78 }
79
80 QModelIndex SchemaModel::parent(const QModelIndex &index) const
81 {
82   //  DEBTRACE("SchemaModel::parent");
83   if (!index.isValid())
84     return QModelIndex();
85   SchemaItem *childItem = static_cast<SchemaItem*>(index.internalPointer());
86   SchemaItem *parentItem = childItem->parent();
87   if (parentItem == _rootItem)
88     return QModelIndex();
89   return createIndex(parentItem->row(), 0, parentItem);
90 }
91
92 int SchemaModel::rowCount(const QModelIndex &parent) const
93 {
94   //DEBTRACE("SchemaModel::rowCount");
95   SchemaItem *parentItem;
96   if (parent.column() > 0)
97     return 0;
98   if (!parent.isValid())
99     parentItem = _rootItem;
100   else
101     parentItem = static_cast<SchemaItem*>(parent.internalPointer());
102   if (parentItem)
103     return parentItem->childCount();
104   else return 0;
105 }
106
107 int SchemaModel::columnCount(const QModelIndex &parent) const
108 {
109   //DEBTRACE("SchemaModel::columnCount " << parent.isValid());
110   if (parent.isValid())
111     return static_cast<SchemaItem*>(parent.internalPointer())->columnCount();
112   if (_rootItem)
113     {
114       if (_isEdition) return 3;
115       else return 3; //_rootItem->columnCount();
116     }
117   else
118     return 0;
119 }
120
121 QVariant SchemaModel::data(const QModelIndex &index, int role) const
122 {
123   //DEBTRACE("SchemaModel::data");
124   if (!index.isValid())
125     return QVariant();
126   SchemaItem *item = static_cast<SchemaItem*>(index.internalPointer());
127   return item->data(index.column(), role);
128 }
129
130 QVariant SchemaModel::headerData(int section, Qt::Orientation orientation, int role) const
131 {
132   //DEBTRACE("SchemaModel::headerData");
133   if (role != Qt::DisplayRole)
134     return QVariant();
135
136   if (orientation == Qt::Horizontal)
137     //return QString("Colonne %1").arg(section);
138     if (_isEdition)
139       switch (section)
140         {
141         case YLabel: return QString("Name");
142         case YType:  return QString("Type");
143         case YValue: return QString("Value");
144         default:     return QString("- %1 -").arg(section);
145         }
146     else
147       switch (section)
148         {
149         case YLabel: return QString("Name");
150         case YType:  return QString("Type");
151         case YState: return QString("State");
152         default:     return QString("- %1 -").arg(section);
153         }
154     else
155     return QVariant();
156 }
157
158 /*!
159  *  For EditRole, setData only emit dataChanged signal,
160  *  actual modification is done in SchemaItem.
161  */
162 bool SchemaModel::setData(const QModelIndex &index, const QVariant &value, int role)
163 {
164   DEBTRACE("SchemaModel::setData");
165   if (index.isValid() && role == Qt::EditRole)
166     {
167       DEBTRACE("Qt::EditRole, emit dataChanged");
168       emit dataChanged(index, index);
169       return true;
170     }
171   if (index.isValid() && role == Qt::CheckStateRole)
172     {
173       DEBTRACE("Qt::CheckStateRole, toggle state");
174       SchemaItem *item = static_cast<SchemaItem*>(index.internalPointer());
175       item->toggleState();
176       emit dataChanged(index, index);
177       return true;
178     }
179   return false;
180 }
181
182 Qt::ItemFlags SchemaModel::flags(const QModelIndex &index) const
183 {
184   //DEBTRACE("SchemaModel::flags");
185   if (!index.isValid())
186     return 0;
187   SchemaItem *item = static_cast<SchemaItem*>(index.internalPointer());
188   return item->flags(index);
189 }
190
191
192 void SchemaModel::update(GuiEvent event, int type, Subject* son)
193 {
194   DEBTRACE("SchemaModel::update "<<eventName(event)<<" "<<type<<" "<<son);
195   switch (event)
196     {
197     case YACS::HMI::NEWROOT:
198       setNewRoot(son);
199       break;
200 //     default:
201 //       DEBTRACE("SchemaModel::update(), event not handled: "<< eventName(event));
202     }
203 }
204
205 void SchemaModel::updateSelection(const QItemSelection &selected,
206                                   const QItemSelection &deselected)
207 {
208   DEBTRACE("SchemaModel::updateSelection");
209      QModelIndex index;
210      QModelIndexList items = selected.indexes();
211
212      foreach (index, items)
213        {
214          SchemaItem *item = static_cast<SchemaItem*>(index.internalPointer());
215          DEBTRACE("updateSelection select "<< item->getSubject()->getName());
216          item->getSubject()->select(true);
217          emit signalSelection(index);         
218        }
219
220      items = deselected.indexes();
221
222      foreach (index, items)
223        {
224          SchemaItem *item = static_cast<SchemaItem*>(index.internalPointer());
225          DEBTRACE("updateSelection deselect "<< item->getSubject()->getName());
226          item->getSubject()->select(false);
227        }  
228 }
229
230 void SchemaModel::setEdition(bool isEdition)
231 {
232   _isEdition = isEdition;
233 }
234
235 const QBrush& SchemaModel::stdBackBrush()
236 {
237   return _stdBackBrush;
238 }
239
240 const QBrush& SchemaModel::editedBackBrush()
241 {
242   return _editedBackBrush;
243 }
244
245 const QBrush& SchemaModel::emphasizeBackBrush()
246 {
247   return _emphasizeBackBrush;
248 }
249
250 void SchemaModel::setNewRoot(YACS::HMI::Subject *root)
251 {
252   _root = root;
253   QString name = _root->getName().c_str();
254   _rootItem= new SchemaItem(0, "root", QtGuiContext::getQtCurrent());
255   SchemaProcItem *procItem = new SchemaProcItem(_rootItem, name, _root);
256 }
257
258 QMimeData* SchemaModel::mimeData(const QModelIndexList &indexes) const
259 {
260   DEBTRACE("SchemaModel::mimeData");
261   ItemMimeData *mime = new ItemMimeData;
262   mime->setSubject(_root);
263
264   if (indexes.empty())
265     return mime;
266   QModelIndex index = indexes.first();
267   if (!index.isValid())
268     return mime;
269   SchemaItem *item = static_cast<SchemaItem*>(index.internalPointer());
270   DEBTRACE("mimeData valid index");
271   return item->mimeData(mime);
272 }
273
274 bool SchemaModel::dropMimeData(const QMimeData* data, Qt::DropAction action,
275                                int row, int column, const QModelIndex& parent)
276 {
277   DEBTRACE("SchemaModel::dropMimeData");
278   if (action == Qt::IgnoreAction)
279     return true;
280
281   string name = "empty";
282   SchemaItem *item = 0;
283   if (parent.isValid())
284     {
285       item = static_cast<SchemaItem*>(parent.internalPointer());
286       name = item->getSubject()->getName();
287     }
288   DEBTRACE(row << " " << column << " "<< name);
289
290   if ((row >= 0) && (column >=0))
291     {
292       QModelIndex ind = index(row, column, parent);
293       if (!ind.isValid())
294         return false;
295       DEBTRACE("---");
296       item = static_cast<SchemaItem*>(ind.internalPointer());
297     }
298   if (!item)
299     return false;
300   return item->dropMimeData(data, action);
301 }
302
303 Qt::DropActions SchemaModel::supportedDropActions() const
304 {
305   //DEBTRACE("SchemaModel::supportedDropActions");
306   return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
307 }
308
309 QStringList SchemaModel::mimeTypes() const
310 {
311   //DEBTRACE("SchemaModel::mimeTypes");
312   QStringList types;
313   types << "yacs/subject" << "yacs/subjectNode" << "yacs/subjectOutPort"
314         << "yacs/cataService" << "yacs/cataType" << "yacs/cataNode"
315         << "yacs/subjectOutGate";
316   return types;
317 }