Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / genericgui / ValueDelegate.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 "ValueDelegate.hxx"
20 #include "guiObservers.hxx"
21 #include "SchemaItem.hxx"
22 #include "DataPort.hxx"
23 #include "TypeCode.hxx"
24 #include "Switch.hxx"
25
26 //#define _DEVDEBUG_
27 #include "YacsTrace.hxx"
28
29 #include <QSize>
30 #include <QSpinBox>
31 #include <cassert>
32 #include <climits>
33
34 using namespace std;
35 using namespace YACS::HMI;
36
37
38 // -----------------------------------------------------------------------------
39
40 GenericEditor::GenericEditor()
41 {
42   _subject = 0;
43   _column = 0;
44   _delegate = 0;
45   _first = true;
46 }
47
48 GenericEditor::~GenericEditor()
49 {
50   DEBTRACE("GenericEditor::~GenericEditor " << this);
51   
52 }
53
54 void GenericEditor::setSubject(Subject* subject)
55 {
56   _subject = subject;
57 }
58
59 void GenericEditor::setColumn(int column)
60 {
61   _column= column;
62 }
63
64 void GenericEditor::setDelegate(const ValueDelegate* delegate)
65 {
66   _delegate = delegate;
67 }
68
69 QString GenericEditor::GetStrValue()
70 {
71 }
72
73 Subject* GenericEditor::getSubject()
74 {
75   return _subject;
76 }
77
78 int GenericEditor::getColumnInSubject()
79 {
80   return _column;
81 }
82
83 void GenericEditor::setData(QVariant val)
84 {
85 }
86
87 bool GenericEditor::firstSetData()
88 {
89   bool ret = _first;
90   _first = false;
91   return ret; 
92 }
93
94 // -----------------------------------------------------------------------------
95
96 GeneralEditor::GeneralEditor(Subject* subject,
97                              const ValueDelegate* delegate,
98                              int column,
99                              QWidget * parent)
100   : QLineEdit(parent), GenericEditor()
101 {
102   DEBTRACE("GeneralEditor::GeneralEditor");
103   setDelegate(delegate);
104   setSubject(subject);
105   setColumn(column);
106 }
107
108 GeneralEditor::~GeneralEditor()
109 {
110 }
111
112 QString GeneralEditor::GetStrValue()
113 {
114   DEBTRACE("GeneralEditor::GetStrValue " << text().toStdString());
115   return text();
116 }
117
118 void GeneralEditor::setData(QVariant val)
119 {
120   DEBTRACE("GeneralEditor::setData " << this);
121   DEBTRACE(val.canConvert<QString>());
122   DEBTRACE(val.toString().toStdString());
123   setText(val.toString());
124 }
125
126 // -----------------------------------------------------------------------------
127
128 IntEditor::IntEditor(Subject* subject,
129                      const ValueDelegate* delegate,
130                      int column,
131                      QWidget * parent)
132   : QSpinBox(parent), GenericEditor()
133 {
134   setMinimum(INT_MIN);
135   setMaximum(INT_MAX);
136   setSubject(subject);
137   setDelegate(delegate);
138   setColumn(column);
139 }
140
141 IntEditor::~IntEditor()
142 {
143 }
144
145 QString IntEditor::GetStrValue()
146 {
147   QString str;
148   str.setNum(value());
149   return str;
150 }
151
152 void IntEditor::setData(QVariant val)
153 {
154   DEBTRACE("IntEditor::setData");
155   DEBTRACE(val.canConvert<int>());
156   setValue(val.toInt());
157 }
158
159 // -----------------------------------------------------------------------------
160
161 CaseSwitchEditor::CaseSwitchEditor(Subject* subject,
162                        const ValueDelegate* delegate,
163                        int column,
164                        QWidget* parent)
165   : CaseSwitch(parent), GenericEditor()
166 {
167   sb_case->setMinimum(INT_MIN);
168   sb_case->setMaximum(INT_MAX);
169   setSubject(subject);
170   setDelegate(delegate);
171   setColumn(column);
172 }
173
174 CaseSwitchEditor::~CaseSwitchEditor()
175 {
176 }
177
178 QString CaseSwitchEditor::GetStrValue()
179 {
180   QString str;
181   int val = sb_case->value();
182   if (_isDefault)
183     val = YACS::ENGINE::Switch::ID_FOR_DEFAULT_NODE;
184   str.setNum(val);
185   DEBTRACE(val);
186   return str;
187 }
188
189 void CaseSwitchEditor::setData(QVariant val)
190 {
191   DEBTRACE("CaseSwitchEditor::setData");
192   if (val == "default")
193     {
194       setDefaultChecked(true);
195     }
196   else
197     {
198       setDefaultChecked(false);
199       DEBTRACE(val.canConvert<int>() << " " << val.toInt());
200       sb_case->setValue(val.toInt());
201     }
202 }
203
204
205 // -----------------------------------------------------------------------------
206
207 ValueDelegate::ValueDelegate(QObject *parent)
208   : QItemDelegate(parent)
209 {
210   DEBTRACE("ValueDelegate::ValueDelegate");
211   _errorMap.clear();
212 }
213
214 ValueDelegate::~ValueDelegate()
215 {
216   DEBTRACE("ValueDelegate::~ValueDelegate");
217 }
218       
219 QWidget *ValueDelegate::createEditor(QWidget *parent,
220                                      const QStyleOptionViewItem &option,
221                                      const QModelIndex &index) const
222 {
223   DEBTRACE("ValueDelegate::createEditor");
224
225   SchemaItem *item = static_cast<SchemaItem*>(index.internalPointer());
226   Subject *subject = item->getSubject();
227   int column = index.column();
228   DEBTRACE(subject->getName() << " " << column);
229   
230   QWidget *editor = 0;
231   SubjectDataPort *sport = 0;
232   SubjectNode *snode = 0;
233
234   if (column == YValue)
235     {
236       sport = dynamic_cast<SubjectDataPort*>(subject);
237       if (!sport)
238         snode= dynamic_cast<SubjectNode*>(subject);
239       
240       if (sport)
241         {
242           YACS::ENGINE::DataPort *port = sport->getPort();
243           YACS::ENGINE::TypeCode *tc = port->edGetType();
244           YACS::ENGINE::DynType dt = tc->kind();
245           if (dt == YACS::ENGINE::Int)
246             editor = new IntEditor(subject, this, column, parent);
247         }
248       else if (snode)
249         {
250           SubjectSwitch *sSwitch = dynamic_cast<SubjectSwitch*>(snode->getParent());
251           if (sSwitch)
252             editor = new CaseSwitchEditor(subject, this, column, parent);
253         }
254     }
255
256   if (!editor) editor = new GeneralEditor(subject, this, column, parent);
257   return editor;
258 }
259
260 /*!
261  * Initialise the editor with data from model, unless there is a
262  * previous error in edition of this item, and it is the first
263  * initialisation of the editor: in case of error, a new editor
264  * must be initialised with the wrong edited string, for correction.
265  */     
266 void ValueDelegate::setEditorData(QWidget *editor,
267                                   const QModelIndex &index) const
268 {
269   DEBTRACE("ValueDelegate::setEditorData");
270   GenericEditor* gedit = dynamic_cast<GenericEditor*>(editor);
271   assert(gedit);
272   QString edited = gedit->GetStrValue();
273   DEBTRACE(edited.toStdString());
274   Subject *sub = gedit->getSubject();
275   if (! gedit->firstSetData())    // --- editor already initialized
276     return;
277   else if (_errorMap.count(sub))  // --- initialize with previous error
278     {
279       string error = _errorMap[sub];
280       gedit->setData(QString(error.c_str()));
281       _errorMap.erase(gedit->getSubject());
282       DEBTRACE("--------erase-----------");
283     }
284   else                            // --- initialize with model
285     gedit->setData(index.model()->data(index, Qt::DisplayRole));
286 }
287
288 /*!
289  * Nothing done here: model->setData is done by UPDATE.
290  */
291 void ValueDelegate::setModelData(QWidget *editor,
292                                  QAbstractItemModel *model,
293                                  const QModelIndex &index) const
294 {
295   DEBTRACE("ValueDelegate::setModelData");
296   GenericEditor* gedit = dynamic_cast<GenericEditor*>(editor);
297   assert(gedit);
298   QString value = gedit->GetStrValue();
299   DEBTRACE(value.toStdString());
300   //model->setData(index, value, Qt::EditRole); // real set done by update
301 }
302       
303 void ValueDelegate::updateEditorGeometry(QWidget *editor,
304                                          const QStyleOptionViewItem &option,
305                                          const QModelIndex &index) const
306 {
307   DEBTRACE("ValueDelegate::updateEditorGeometry");
308   editor->setGeometry(option.rect);
309 }
310
311 /*!
312  *  If edition is in error, keep the wrong string value in a map,
313  *  to initialise a next instance of editor with the wrong string,
314  *  in order to help correction of the edition.
315  */
316 void ValueDelegate::setResultEditing(QWidget *editor, bool isOk)
317 {
318   DEBTRACE("ValueDelegate::setResultEditing " << isOk);
319   GenericEditor* gedit = dynamic_cast<GenericEditor*>(editor);
320   assert(gedit);
321   Subject *sub = gedit->getSubject();
322   string val = gedit->GetStrValue().toStdString();
323   DEBTRACE(sub->getName() << " " << val);
324   if (!isOk)
325     {
326       sub->update(EDIT, 1, sub);
327       _errorMap[sub] = val;
328     }
329   else
330       sub->update(EDIT, 0, sub);
331 }