openETCS
case study for the European Train Control System developed for the authors dissertation
DriverMachineInterfaceMOC.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010-2012
3  Johannes Feuser <feuser@uni-bremen.de>
4  This file is part of the openETCS library.
5 
6  The openETCS library is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  any later version.
10 
11  The openETCS library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with the openETCS library. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /*!
21  * \author Johannes Feuser <feuser@uni-bremen.de>
22  * \brief driver machine classes for observer usage
23  */
24 
26 #include "EVCStateMachine.h"
27 
28 
29 
30 
31 namespace oETCS {
32 
33 namespace DF {
34 
35 
36 CDMIQWidget::CDMIQWidget(oETCS::DF::CEVCStateMachine * const pStateMachine, QWidget * pWidgetParent, const bool& bSimAdaptor) throw()
37 :QWidget(pWidgetParent),
38  CDMIObserver(pStateMachine),
39  m_pAdaptor(nullptr),
40  m_Layout(this),
41  m_Labels(0),
42  m_InputWidgets(0),
43  m_OutputWidgets(0),
44  m_pLastSubject(0),
45  m_InputButtons(0),
46  m_Mutex(QMutex::Recursive)
47 {
48  // Bouml preserved body begin 000C3302
49  bool bConnected(true);
50  QDBusConnection Connection = QDBusConnection::sessionBus();
51 
52 
53  // attach this observer to the EVC state machine
54  m_pStateMachine->AttachObserver(this);
55 
56  // connect slots and signal
57  QObject::connect(this, SIGNAL(Updated(void)), this, SLOT(UpdateSlot(void)), Qt::AutoConnection);
58 
59  // set size policy of widget
60  this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
61 
62  // call initial update to create input and output elements
63  this->Update();
64 
65  // check, if simulation adaptor should be used
66  if (bSimAdaptor)
67  {
68  try
69  {
70  // create adaptor object
71  m_pAdaptor = new ::ADMI(this);
72 
73  // register all adaptors
74  bConnected &= Connection.registerService("oETCS.DF.IDMI");
75  bConnected &= Connection.registerObject("/oETCS/DMI", this);
76  } //
77  catch (const ::std::bad_alloc& Exception)
78  {
79  // only print error, cannot do more in constructor
80  ::std::cerr << Exception.what() << ::std::endl;
81 
82  } // catch (const ::std::bad_alloc& Exception)
83 
84  // check, if DMI adaptor could be registered successfully
85  if (not bConnected)
86  {
87  // print error
88  ::std::cerr << "DMI adaptor was not registered successfully on D-Bus" << ::std::endl;
89 
90  } // if (not bConnected)
91 
92  } // if (bSimAdaptor)
93  // Bouml preserved body end 000C3302
94 
95 } // CDMIQWidget::CDMIQWidget() throw()
96 
97 
98 
99 
101 {
102  // Bouml preserved body begin 000C3382
103  decltype (m_InputWidgets.begin()) iw(0);
104  decltype (m_OutputWidgets.begin()) ow(0);
105  decltype (m_Labels.begin()) l(0);
106  decltype (m_InputButtons.begin()) ib(0);
107 
108 
109 
110  // remove all input widgets from layout and delete them
111  for (iw = m_InputWidgets.begin(); iw != m_InputWidgets.end(); iw++)
112  {
113  // remove current widget from layout
114  m_Layout.removeWidget(*iw);
115 
116  // delete widget
117  delete *iw;
118 
119  } // for (iw = m_InputWidgets.begin(); iw != m_InputWidgets.end(); iw++)
120 
121  // clear input widget vector
122  m_InputWidgets.clear();
123 
124  // remove all output widgets from layout and delete them
125  for (ow = m_OutputWidgets.begin(); ow != m_OutputWidgets.end(); ow++)
126  {
127  // remove current widget from layout
128  m_Layout.removeWidget(*ow);
129 
130  // delete widget
131  delete *ow;
132 
133  } // for (ow = m_OutputWidgets.begin(); ow != m_OutputWidgets.end(); ow++)
134 
135  // clear output widget vector
136  m_OutputWidgets.clear();
137 
138  // remove all labels from layout and delete them
139  for (l = m_Labels.begin(); l != m_Labels.end(); l++)
140  {
141  // remove current label from layout
142  m_Layout.removeWidget(*l);
143 
144  // delete label
145  delete *l;
146 
147  } // for (l = m_Labels.begin(); l != m_Labels.end(); l++)
148 
149  // clear label vector
150  m_Labels.clear();
151 
152  // remove all input buttons from layout and delete them
153  for (ib = m_InputButtons.begin(); ib != m_InputButtons.end(); ib++)
154  {
155  // remove current button from layout
156  m_Layout.removeWidget(*ib);
157 
158  // delete input button
159  delete *ib;
160 
161  } // for (ib = m_InputButtons.begin(); ib != m_InputButtons.end(); ib++)
162 
163  // clear input button vector
164  m_InputButtons.clear();
165 
166  // delete adaptor
167  delete (m_pAdaptor);
168  // Bouml preserved body end 000C3382
169 
170 } // CDMIQWidget::~CDMIQWidget() throw()
171 
172 
173 
174 
175 void CDMIQWidget::Update() throw()
176 {
177  // Bouml preserved body begin 000CBF02
178  // just emit signal for update here to start slot in GUI/QApplication thread
179  emit Updated();
180  // Bouml preserved body end 000CBF02
181 
182 } // void CDMIQWidget::Update() throw()
183 
184 
185 
186 
187 void CDMIQWidget::Detached() throw()
188 {
189  // Bouml preserved body begin 000CD982
190  // close this widget
191  this->close();
192  // Bouml preserved body end 000CD982
193 
194 } // void CDMIQWidget::Detached() throw()
195 
196 
197 
198 
200 {
201  // Bouml preserved body begin 000CD882
202  decltype (m_InputButtons.begin()) ib(0);
203  decltype (CDMIInput::m_AllowedBoolInputs.begin()) abi;
204  decltype (CDMIInput::m_AllowedDoubleInputs.begin()) adi;
205  decltype (CDMIInput::m_AllowedIntInputs.begin()) aii;
206  decltype (CDMIInput::m_AllowedStringInputs.begin()) asi;
207  QObject* pSender(0);
208  QString AllowedValues;
209  QMessageBox ErrorMessage(this);
210  ::std::string StringInput;
211  unsigned int uiIndex(0);
212  double dDoubleInput(0.0);
213  int iIntInput(0);
214  bool bFound(false);
215  bool bBoolInput(false);
216 
217 
218 
219 
220  // set general message box properties
221  ErrorMessage.setWindowModality(Qt::NonModal);
222  ErrorMessage.setText(tr("Error while setting input: value not allowed"));
223  ErrorMessage.setStandardButtons(QMessageBox::Ok);
224  ErrorMessage.setWindowTitle(tr("Input value not allowed"));
225  ErrorMessage.setIcon(QMessageBox::Critical);
226 
227 
228  // lock mutex
229  m_Mutex.lock();
230 
231  // initial try to get the sender for this slot
232  pSender = this->sender();
233 
234  // check, if sender was a push button, otherwise ignore the signal (should never happen anyway)
235  if (dynamic_cast< QPushButton* >(pSender) != 0)
236  {
237  // find the pressed button in vector
238  for (uiIndex = 0, ib = m_InputButtons.begin(); ib != m_InputButtons.end() && not bFound; uiIndex++, ib++)
239  {
240  // compare current button with sender
241  bFound = (*ib == pSender);
242 
243  } // for (uiIndex = 0, ib = m_InputButtons.begin(); ib != m_InputButtons.end() && not bFound; uiIndex++, ib++)
244 
245  // check, if sender button was found (otherwise just ignore the signal)
246  if (bFound)
247  {
248  // decrement index once to gain correct one
249  uiIndex--;
250 
251  // switch the type of the corresponding input value
252  switch (m_pLastSubject->m_Inputs[uiIndex]->m_eType)
253  {
255  // get boolean input from check box
256  bBoolInput = static_cast< QCheckBox* >(m_InputWidgets[uiIndex])->checkState() == 0 ? false : true;
257 
258  // check is new value is allowed
259  if (not CDMIQWidget::IsPartOf(bBoolInput, m_pLastSubject->m_Inputs[uiIndex]->m_AllowedBoolInputs))
260  {
261  // convert vector of allowed values to string
262  for (abi = m_pLastSubject->m_Inputs[uiIndex]->m_AllowedBoolInputs.begin(); abi != m_pLastSubject->m_Inputs[uiIndex]->m_AllowedBoolInputs.end(); abi++)
263  {
264  // add current allowed value to string
265  AllowedValues += QString(*abi ? "true" : "false") + QString("; ");
266 
267  } // for (abi = m_pLastSubject->m_Inputs[uiIndex]->m_AllowedBoolInputs.begin(); abi != m_pLastSubject->m_Inputs[uiIndex]->m_AllowedBoolInputs.end(); abi++)
268 
269  // set certain message box properties
270  ErrorMessage.setInformativeText(tr("Allowed values: ") + AllowedValues);
271 
272  // show error message box non-modal
273  ErrorMessage.exec();
274 
275 
276  } // if (not CDMIQWidget::IsPartOf(bBoolInput, m_pLastSubject->m_Inputs[uiIndex]->m_AllowedBoolInputs))
277  else
278  {
279  // set value in DMI input
280  m_pLastSubject->m_Inputs[uiIndex]->m_bBool = bBoolInput;
281 
282  } // else
283 
284  break;
285 
286 
288  // get boolean input from double spin box
289  dDoubleInput = static_cast< QDoubleSpinBox* >(m_InputWidgets[uiIndex])->value();
290 
291  // check is new value is allowed
292  if (not CDMIQWidget::IsPartOf(dDoubleInput, m_pLastSubject->m_Inputs[uiIndex]->m_AllowedDoubleInputs))
293  {
294  // convert vector of allowed values to string
295  for (adi = m_pLastSubject->m_Inputs[uiIndex]->m_AllowedDoubleInputs.begin(); adi != m_pLastSubject->m_Inputs[uiIndex]->m_AllowedDoubleInputs.end(); adi++)
296  {
297  // add current allowed value to string
298  AllowedValues += QString::number(*adi) + QString("; ");
299 
300  } // for (adi = m_pLastSubject->m_Inputs[uiIndex]->m_AllowedDoubleInputs.begin(); adi != m_pLastSubject->m_Inputs[uiIndex]->m_AllowedDoubleInputs.end(); adi++)
301 
302  // set certain message box properties
303  ErrorMessage.setInformativeText(tr("Allowed values: ") + AllowedValues);
304 
305  // show error message box non-modal
306  ErrorMessage.exec();
307 
308 
309  } // if (not CDMIQWidget::IsPartOf(dDoubleInput, m_pLastSubject->m_Inputs[uiIndex]->m_AllowedDoubleInputs))
310  else
311  {
312  // set value in DMI input
313  m_pLastSubject->m_Inputs[uiIndex]->m_dDouble = dDoubleInput;
314 
315  } // else
316 
317  break;
318 
319 
321 
322  // not (yet) implemented
323 
324  break;
325 
326 
328  // get integer input from spin box
329  iIntInput = static_cast< QSpinBox* >(m_InputWidgets[uiIndex])->value();
330 
331  // check is new value is allowed
332  if (not CDMIQWidget::IsPartOf(iIntInput, m_pLastSubject->m_Inputs[uiIndex]->m_AllowedIntInputs))
333  {
334  // convert vector of allowed values to string
335  for (aii = m_pLastSubject->m_Inputs[uiIndex]->m_AllowedIntInputs.begin(); aii != m_pLastSubject->m_Inputs[uiIndex]->m_AllowedIntInputs.end(); aii++)
336  {
337  // add current allowed value to string
338  AllowedValues += QString::number(*aii) + QString("; ");
339 
340  } // for (aii = m_pLastSubject->m_Inputs[uiIndex]->m_AllowedIntInputs.begin(); aii != m_pLastSubject->m_Inputs[uiIndex]->m_AllowedIntInputs.end(); aii++)
341 
342  // set certain message box properties
343  ErrorMessage.setInformativeText(tr("Allowed values: ") + AllowedValues);
344 
345  // show error message box non-modal
346  ErrorMessage.exec();
347 
348 
349  } // if (not CDMIQWidget::IsPartOf(iIntInput, m_pLastSubject->m_Inputs[uiIndex]->m_AllowedIntInputs))
350  else
351  {
352  // set value in DMI input
353  m_pLastSubject->m_Inputs[uiIndex]->m_iInt = iIntInput;
354 
355  } // else
356 
357  break;
358 
359 
361  // get string input from spin box
362  StringInput = static_cast< QLineEdit* >(m_InputWidgets[uiIndex])->text().toStdString();
363 
364  // check is new value is allowed
365  if (not CDMIQWidget::IsPartOf(StringInput, m_pLastSubject->m_Inputs[uiIndex]->m_AllowedStringInputs))
366  {
367  // convert vector of allowed values to string
368  for (asi = m_pLastSubject->m_Inputs[uiIndex]->m_AllowedStringInputs.begin(); asi != m_pLastSubject->m_Inputs[uiIndex]->m_AllowedStringInputs.end(); asi++)
369  {
370  // add current allowed value to string
371  AllowedValues += QString((*asi).c_str()) + QString("; ");
372 
373  } // for (asi = m_pLastSubject->m_Inputs[uiIndex]->m_AllowedStringInputs.begin(); asi != m_pLastSubject->m_Inputs[uiIndex]->m_AllowedStringInputs.end(); asi++)
374 
375  // set certain message box properties
376  ErrorMessage.setInformativeText(tr("Allowed values: ") + AllowedValues);
377 
378  // show error message box non-modal
379  ErrorMessage.exec();
380 
381 
382  } // if (not CDMIQWidget::IsPartOf(iIntInput, m_pLastSubject->m_Inputs[uiIndex]->m_AllowedIntInputs))
383  else
384  {
385  // set value in DMI input
386  m_pLastSubject->m_Inputs[uiIndex]->m_String = StringInput;
387 
388  } // else
389 
390  break;
391 
392  } // switch (m_pLastSubject->m_Inputs[uiIndex]->m_eType)
393 
394  } // if (bFound)
395 
396  } // if (dynamic_cast< QPushButton* >(pSender) != 0)
397 
398  // unlock mutex
399  m_Mutex.unlock();
400  // Bouml preserved body end 000CD882
401 
402 } // void CDMIQWidget::DataEntered() throw()
403 
404 
405 
406 
407 void CDMIQWidget::UpdateSlot() throw()
408 {
409  // Bouml preserved body begin 000E4282
410  ::oETCS::DF::CDMISubject* pSubject(nullptr);
411  decltype (CDMISubject::m_Inputs.begin()) i(0);
412  decltype (CDMISubject::m_Outputs.begin()) o(0);
413  decltype (m_InputWidgets.begin()) iw(0);
414  decltype (m_OutputWidgets.begin()) ow(0);
415  decltype (m_Labels.begin()) l(0);
416  decltype (m_InputButtons.begin()) ib(0);
417  decltype (CDMIOutput::m_DoubleArrayMessage().begin()) da(0);
418  QMessageBox ErrorMessage(this);
419  unsigned int uiRow(0);
420  bool bSubjectChanged(false);
421 
422 
423 
424  // lock mutex
425  m_Mutex.lock();
426 
427  // get subject from state machine
428  pSubject = m_pStateMachine->GetCurrentDMI();
429 
430  // check, if pointer to current subject is valid
431  if (pSubject != nullptr)
432  {
433  // check, if only values but not subject itself has changed
434  bSubjectChanged = (pSubject != m_pLastSubject);
435 
436  try
437  {
438  // check, if subject has changed
439  if (bSubjectChanged)
440  {
441  // remove all input widgets from layout and delete them
442  for (iw = m_InputWidgets.begin(); iw != m_InputWidgets.end(); iw++)
443  {
444  // remove current widget from layout
445  m_Layout.removeWidget(*iw);
446 
447  // delete widget
448  delete *iw;
449 
450  } // for (iw = m_InputWidgets.begin(); iw != m_InputWidgets.end(); iw++)
451 
452  // clear input widget vector
453  m_InputWidgets.clear();
454 
455  // remove all output widgets from layout and delete them
456  for (ow = m_OutputWidgets.begin(); ow != m_OutputWidgets.end(); ow++)
457  {
458  // remove current widget from layout
459  m_Layout.removeWidget(*ow);
460 
461  // delete widget
462  delete *ow;
463 
464  } // for (ow = m_OutputWidgets.begin(); ow != m_OutputWidgets.end(); ow++)
465 
466  // clear output widget vector
467  m_OutputWidgets.clear();
468 
469  // remove all labels from layout and delete them
470  for (l = m_Labels.begin(); l != m_Labels.end(); l++)
471  {
472  // remove current label from layout
473  m_Layout.removeWidget(*l);
474 
475  // delete label
476  delete *l;
477 
478  } // for (l = m_Labels.begin(); l != m_Labels.end(); l++)
479 
480  // clear label vector
481  m_Labels.clear();
482 
483  // remove all input buttons from layout and delete them
484  for (ib = m_InputButtons.begin(); ib != m_InputButtons.end(); ib++)
485  {
486  // remove current button from layout
487  m_Layout.removeWidget(*ib);
488 
489  // delete input button
490  delete *ib;
491 
492  } // for (ib = m_InputButtons.begin(); ib != m_InputButtons.end(); ib++)
493 
494  // clear input button vector
495  m_InputButtons.clear();
496 
497  // process all outputs of current subject
498  for (uiRow = 0, o = pSubject->m_Outputs.begin(); o != pSubject->m_Outputs.end(); uiRow++, o++)
499  {
500  // create QLabel
501  m_Labels.push_back(new QLabel((*o)->m_Label.c_str(), this));
502 
503  // add current label to grid layout
504  m_Layout.addWidget(m_Labels[uiRow], uiRow, 0);
505 
506  // create QLineEdit as general output
507  m_OutputWidgets.push_back(new QLineEdit(this));
508 
509  // disable editing in new object
510  m_OutputWidgets[uiRow]->setEnabled(false);
511 
512  // add current input widget to grid layout
513  m_Layout.addWidget(m_OutputWidgets[uiRow], uiRow, 1);
514 
515  } // for (uiRow = 0, o = pSubject->m_Outputs.begin(); o != pSubject->m_Outputs.end(); uiRow++, o++)
516 
517 
518  // process all inputs of current subject
519  for (uiRow = 0, i = pSubject->m_Inputs.begin(); i != pSubject->m_Inputs.end(); uiRow++, i++)
520  {
521  // create QLabel
522  m_Labels.push_back(new QLabel((*i)->m_Label.c_str(), this));
523 
524  // add current label to grid layout
525  m_Layout.addWidget(m_Labels[uiRow + m_OutputWidgets.size()], uiRow, 2);
526 
527 
528  // switch type of current input object for concrete widget creation
529  switch ((*i)->m_eType)
530  {
532  // create check box
533  m_InputWidgets.push_back(new QCheckBox(this));
534 
535  break;
536 
537 
539  // create double spin box
540  m_InputWidgets.push_back(new QDoubleSpinBox(this));
541 
542  // set minimum and maximum
543  static_cast < ::QDoubleSpinBox* >(*(m_InputWidgets.end() - 1))->setMinimum(0.0);
544  static_cast < ::QDoubleSpinBox* >(*(m_InputWidgets.end() - 1))->setMaximum(10000.0);
545 
546  break;
547 
548 
550  // create list view
551  m_InputWidgets.push_back(new QListView(this));
552 
553  break;
554 
555 
557  // create spin box
558  m_InputWidgets.push_back(new QSpinBox(this));
559 
560  // set minimum and maximum
561  static_cast < ::QSpinBox* >(*(m_InputWidgets.end() - 1))->setMinimum(0);
562  static_cast < ::QSpinBox* >(*(m_InputWidgets.end() - 1))->setMaximum(10000);
563 
564  break;
565 
566 
568  // create line edit
569  m_InputWidgets.push_back(new QLineEdit(this));
570 
571  break;
572 
573  } // switch ((*i)->m_eType)
574 
575  // add current input widget to grid layout
576  m_Layout.addWidget(m_InputWidgets[uiRow], uiRow, 3);
577 
578  // create input push button
579  m_InputButtons.push_back(new QPushButton("Enter Data", this));
580 
581  // add current input button to grid layout
582  m_Layout.addWidget(m_InputButtons[uiRow], uiRow, 4);
583 
584  // connect clicked signal of button with slot
585  QObject::connect(m_InputButtons[uiRow], SIGNAL(clicked(bool)), this, SLOT(DataEntered(void)), Qt::AutoConnection);
586 
587  } // for (uiRow = 0, i = pSubject->m_Inputs.begin(); i != pSubject->m_Inputs.end(); uiRow++, i++)
588 
589  } // if (bSubjectChanged)
590 
591 
592  // process all outputs of current subjects (again) to set the input values from subject
593  for (uiRow = 0, o = pSubject->m_Outputs.begin(); o != pSubject->m_Outputs.end(); uiRow++, o++)
594  {
595  // set visibility flag from current output
596  m_OutputWidgets[uiRow]->setVisible((*o)->m_bVisible());
597  m_Labels[uiRow]->setVisible((*o)->m_bVisible());
598 
599  // switch type of current output of subject for setting the output value
600  switch ((*o)->m_eType)
601  {
603  // set value of QLineEdit from boolean
604  static_cast< QLineEdit* >(m_OutputWidgets[uiRow])->setText((*o)->m_bBoolMessage() ? "true" : "false");
605 
606  break;
607 
608 
610  // set value of QLineEdit from double
611  static_cast< QLineEdit* >(m_OutputWidgets[uiRow])->setText(QString::number((*o)->m_dDoubleMessage()));
612 
613  break;
614 
615 
617  // set value of QLineEdit from double
618  for (da = (*o)->m_DoubleArrayMessage().begin(); da != (*o)->m_DoubleArrayMessage().end(); da++)
619  {
620  // copy current double value
621  static_cast< QLineEdit* >(m_OutputWidgets[uiRow])->setText(static_cast< QLineEdit* >((*(m_OutputWidgets.end() - 1)))->text()+ QString::number(*da)+ "; ");
622 
623  } // for (da = (*o)->m_DoubleArrayMessage().begin(); da != (*o)->m_DoubleArrayMessage().end(); da++)
624 
625  break;
626 
627 
629  // set value of QLineEdit from integer
630  static_cast< QLineEdit* >(m_OutputWidgets[uiRow])->setText(QString::number((*o)->m_iIntMessage()));
631 
632  break;
633 
634 
636  // set value of QLineEdit from string
637  static_cast< QLineEdit* >(m_OutputWidgets[uiRow])->setText((*o)->m_StringMessage().c_str());
638 
639  break;
640 
641  } // switch ((*o)->m_eType)
642 
643  } // for (uiRow = 0, o = pSubject->m_Outputs.begin(); o != pSubject->m_Outputs.end(); uiRow++, o++)
644 
645 
646  // process all inputs of current subject (again) to set visibility flag
647  for (uiRow = 0, i = pSubject->m_Inputs.begin(); i != pSubject->m_Inputs.end(); uiRow++, i++)
648  {
649  // set visibility flag from current output
650  m_InputWidgets[uiRow]->setVisible((*i)->m_bVisible());
651  m_Labels[uiRow + m_OutputWidgets.size()]->setVisible((*i)->m_bVisible());
652  m_InputButtons[uiRow]->setVisible((*i)->m_bVisible());
653 
654  } // for (uiRow = 0, i = pSubject->m_Inputs.begin(); i != pSubject->m_Inputs.end(); uiRow++, i++)
655 
656 
657  // store pointer to current subject
658  m_pLastSubject = pSubject;
659 
660  } // try
661  catch (const ::std::bad_alloc& Exception)
662  {
663  // reset subject storage
664  m_pLastSubject = 0;
665 
666  // set message box
667  ErrorMessage.setWindowModality(Qt::NonModal);
668  ErrorMessage.setText(tr("Error while allocation of memory for GUI elements.\nThe GUI representation might not be correct!"));
669  ErrorMessage.setStandardButtons(QMessageBox::Ok);
670  ErrorMessage.setWindowTitle(tr("Not enough memory"));
671  ErrorMessage.setInformativeText(tr("Unfortunately there is nothing you can do about it."));
672  ErrorMessage.setIcon(QMessageBox::Critical);
673 
674  // show message box non-model
675  ErrorMessage.exec();
676 
677  } // catch (const ::std::bad_alloc& Exception)
678 
679  } // if (pSubject != nullptr)
680 
681  // unlock mutex
682  m_Mutex.unlock();
683 
684  // Bouml preserved body end 000E4282
685 
686 } // void CDMIQWidget::UpdateSlot() throw()
687 
688 
689 
690 
692 {
693  // Bouml preserved body begin 000F1702
694  QStringList Inputs;
695  decltype (m_Labels) Labels(m_Labels);
696  decltype (m_InputWidgets) InputWidgets(m_InputWidgets);
697  unsigned int x(0);
698  const unsigned int NUMBER_INPUTS(m_InputWidgets.size());
699  const unsigned int NUMBER_OUTPUTS(m_OutputWidgets.size());
700 
701 
702 
703  // get all labels for input (second)
704  for (x = NUMBER_OUTPUTS; x < (NUMBER_INPUTS + NUMBER_OUTPUTS); x++)
705  {
706  // check, if current input field is visible
707  if (InputWidgets[x - NUMBER_OUTPUTS]->isVisible())
708  {
709  // add current label value to string list
710  Inputs.append(Labels[x]->text());
711 
712 
713  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
714  // DEBUG
715  ::std::cout << "DEBUG: GetInputs() -> input #" << x << " \"" << Labels[x]->text().toStdString() << "\"" << ::std::endl;
716  #endif
717 
718  } // if (InputWidgets[x - NUMBER_OUTPUTS]->isVisible())
719 
720  } // for (x = NUMBER_OUTPUTS; x < (NUMBER_INPUTS + NUMBER_OUTPUTS); x++)
721 
722  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
723  // DEBUG
724  ::std::cout << "DEBUG: GetInputs() -> number of inputs in list " << Inputs.size() << ::std::endl;
725  #endif
726 
727  // return inputs
728  return (Inputs);
729  // Bouml preserved body end 000F1702
730 
731 } // ::QStringList CDMIQWidget::GetInputs() throw()
732 
733 
734 
735 
736 ::QStringList CDMIQWidget::GetOutputs()
737 {
738  // Bouml preserved body begin 000F3082
739  QStringList Outputs;
740  unsigned int x(0);
741  const unsigned int NUMBER_OUTPUTS(m_OutputWidgets.size());
742 
743 
744 
745  // lock mutex
746  m_Mutex.lock();
747 
748  // get all labels for output (first)
749  for (x = 0; x < NUMBER_OUTPUTS; x++)
750  {
751  // check, if current output is visible
752  if (m_OutputWidgets[x]->isVisible())
753  {
754  // add current label value to string list
755  Outputs.append(m_Labels[x]->text());
756 
757  } // if (m_OutputWidgets[x]->isVisible())
758 
759  } // for (x = 0; x < NUMBER_OUTPUTS; x++)
760 
761  // unlock mutex
762  m_Mutex.unlock();
763 
764  // return outputs
765  return (Outputs);
766  // Bouml preserved body end 000F3082
767 
768 } // ::QStringList CDMIQWidget::GetOutputs() throw()
769 
770 
771 
772 
773 QString CDMIQWidget::GetOutputValue(const QString & OutputName)
774 {
775  // Bouml preserved body begin 000F3102
776  QString Value;
777  decltype (m_Labels.begin()) x;
778  int p(0);
779  int iPosition(-1);
780 
781 
782 
783  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
784  // DEBUG
785  ::std::cout << "DEBUG: GetOutputValue() -> started" << ::std::endl;
786  #endif
787 
788  // lock mutex
789  m_Mutex.lock();
790 
791  // try to find output field in labels
792  for (x = m_Labels.begin(), p = 0; x != m_Labels.end() - m_InputWidgets.size() && iPosition == -1; x++, p++)
793  {
794  // check, if current label corresponds to output field and is visible
795  if ((*x)->text() == OutputName && (*x)->isVisible())
796  {
797  // store position
798  iPosition = p;
799 
800  } // if ((*x)->text() == OutputName && (*x)->isVisible())
801 
802  } // for (x = m_Labels.begin(), p = 0; x != m_Labels.end() - m_InputWidgets.size() && iPosition == -1; x++, p++)
803 
804 
805  // check, if output field could be found
806  if (iPosition != -1)
807  {
808  // get output field value
809  Value = static_cast< ::QLineEdit* >(m_OutputWidgets[iPosition])->text();
810 
811  } // if (iPosition != -1)
812  else
813  {
814  // print warning
815  ::std::cerr << "warning in CDMIQWidget::GetOutputValue() in " << __FILE__ << ":" << __LINE__ << " -> output field \"" << OutputName.toStdString() << "\" not found" << ::std::endl;
816 
817  } // else
818 
819  // unlock mutex
820  m_Mutex.unlock();
821 
822  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
823  // DEBUG
824  ::std::cout << "DEBUG: GetOutputValue() -> finished with value \"" << Value.toStdString() << "\"" << ::std::endl;
825  #endif
826 
827  // return output value
828  return (Value);
829  // Bouml preserved body end 000F3102
830 
831 } // ::QString CDMIQWidget::GetOutputValue() throw()
832 
833 
834 
835 
837 {
838  // Bouml preserved body begin 000F3182
839  bool bHasInput(false);
840 
841 
842  // get list of outputs and evaluate size
843  bHasInput = !(this->GetInputs().empty());
844 
845  // return input flag
846  return (bHasInput);
847  // Bouml preserved body end 000F3182
848 
849 } // bool CDMIQWidget::HasInput() throw()
850 
851 
852 
853 
854 void CDMIQWidget::SetBooleanValue(const QString & InputName, bool bValue)
855 {
856  // Bouml preserved body begin 000F3202
857  decltype (m_Labels.begin()) x;
858  int p(0);
859  int iPosition(-1);
860 
861 
862 
863  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
864  // DEBUG
865  ::std::cout << "DEBUG: started CDMIQWidget::SetBooleanValue()" << ::std::endl;
866  #endif
867 
868  // lock mutex
869  m_Mutex.lock();
870 
871  // try to find input field in labels
872  for (x = m_Labels.begin() + m_OutputWidgets.size(), p = 0; x != m_Labels.end() && iPosition == -1; x++, p++)
873  {
874  // check, if current label corresponds to input field
875  if ((*x)->text() == InputName)
876  {
877  // store position
878  iPosition = p;
879 
880  } // if ((*x)->text() == InputName)
881 
882  } // for (x = m_Labels.begin() + m_OutputWidgets.size(), p = 0; x != m_Labels.end() && iPosition == -1; x++, p++)
883 
884  // check, if input field was found
885  if (iPosition!= -1)
886  {
887  // check, if input widget is a QCheckBox
888  if (dynamic_cast< ::QCheckBox* >(m_InputWidgets[iPosition]) != nullptr)
889  {
890  // check, if input field is visible
891  if (static_cast< ::QCheckBox* >(m_InputWidgets[iPosition])->isVisible())
892  {
893  // set input field (boolean)
894  static_cast< ::QCheckBox* >(m_InputWidgets[iPosition])->setChecked(bValue);
895 
896  // press related input button to activate update
897  m_InputButtons[iPosition]->click();
898 
899  } // if (static_cast< ::QCheckBox* >(m_InputWidgets[iPosition])->isVisible())
900  else
901  {
902  // print warning
903  ::std::cerr << "warning in CDMIQWidget::SetBooleanValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" is currently not visible" << ::std::endl;
904 
905  } // else
906 
907 
908  } // if (dynamic_cast< ::QCheckBox* >(m_InputWidgets[iPosition]) != nullptr)
909  else
910  {
911  // print warning
912  ::std::cerr << "warning in CDMIQWidget::SetBooleanValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" is not a boolean field" << ::std::endl;
913 
914  } // else
915 
916  } // if (iPosition != -1)
917  else
918  {
919  // print warning
920  ::std::cerr << "warning in CDMIQWidget::SetBooleanValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" not found" << ::std::endl;
921 
922  } // else
923 
924  // unlock mutex
925  m_Mutex.unlock();
926 
927  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
928  // DEBUG
929  ::std::cout << "DEBUG: finished CDMIQWidget::SetBooleanValue()" << ::std::endl;
930  #endif
931  // Bouml preserved body end 000F3202
932 
933 } // void CDMIQWidget::SetBooleanValue() throw()
934 
935 
936 
937 
938 void CDMIQWidget::SetDoubleValue(const QString & InputName, double dValue)
939 {
940  // Bouml preserved body begin 000F3282
941  decltype (m_Labels.begin()) x;
942  int p(0);
943  int iPosition(-1);
944 
945 
946 
947  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
948  // DEBUG
949  ::std::cout << "DEBUG: started CDMIQWidget::SetDoubleValue()" << ::std::endl;
950 #endif
951 
952  // lock mutex
953  m_Mutex.lock();
954 
955  // try to find input field in labels
956  for (x = m_Labels.begin() + m_OutputWidgets.size(), p = 0; x != m_Labels.end() && iPosition == -1; x++, p++)
957  {
958  // check, if current label corresponds to input field
959  if ((*x)->text() == InputName)
960  {
961  // store position
962  iPosition = p;
963 
964  } // if ((*x)->text() == InputName)
965 
966  } // for (x = m_Labels.begin() + m_OutputWidgets.size(), p = 0; x != m_Labels.end() && iPosition == -1; x++, p++)
967 
968  // check, if input field was found
969  if (iPosition != -1)
970  {
971  // check, if input widget is a QDoubleSpinBox
972  if (dynamic_cast< ::QDoubleSpinBox* >(m_InputWidgets[iPosition]) != nullptr)
973  {
974  // check, if input field is visible
975  if (static_cast< ::QDoubleSpinBox* >(m_InputWidgets[iPosition])->isVisible())
976  {
977  // set input field (double)
978  static_cast< ::QDoubleSpinBox* >(m_InputWidgets[iPosition])->setValue(dValue);
979 
980  // press related input button to activate update
981  m_InputButtons[iPosition]->click();
982 
983  } // if (static_cast< ::QDoubleSpinBox* >(m_InputWidgets[iPosition])->isVisible())
984  else
985  {
986  // print warning
987  ::std::cerr << "warning in CDMIQWidget::SetDoubleValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" is currently not visible" << ::std::endl;
988 
989  } // else
990 
991  } // if (dynamic_cast< ::QDoubleSpinBox* >(m_InputWidgets[iPosition]) != nullptr)
992  else
993  {
994  // print warning
995  ::std::cerr << "warning in CDMIQWidget::SetDoubleValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" is not a double field" << ::std::endl;
996  ::std::cerr << typeid (*m_InputWidgets[p]).name() << ::std::endl;
997 
998  } // else
999 
1000  } // if (iPosition != -1)
1001  else
1002  {
1003  // print warning
1004  ::std::cerr << "warning in CDMIQWidget::SetDoubleValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" not found" << ::std::endl;
1005 
1006  } // else
1007 
1008  // unlock mutex
1009  m_Mutex.unlock();
1010 
1011  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
1012  // DEBUG
1013  ::std::cout << "DEBUG: finished CDMIQWidget::SetDoubleValue()" << ::std::endl;
1014  #endif
1015  // Bouml preserved body end 000F3282
1016 
1017 } // void CDMIQWidget::SetDoubleValue() throw()
1018 
1019 
1020 
1021 
1022 void CDMIQWidget::SetIntegerValue(const QString & InputName, int iValue)
1023 {
1024  // Bouml preserved body begin 000F3302
1025  decltype (m_Labels.begin()) x;
1026  int p(0);
1027  int iPosition(-1);
1028 
1029 
1030 
1031  // lock mutex
1032  m_Mutex.lock();
1033 
1034  // try to find input field in labels
1035  for (x = m_Labels.begin() + m_OutputWidgets.size(), p = 0; x != m_Labels.end() && iPosition == -1; x++, p++)
1036  {
1037  // check, if current label corresponds to input field
1038  if ((*x)->text() == InputName)
1039  {
1040  // store position
1041  iPosition = p;
1042 
1043  } // if ((*x)->text() == InputName)
1044 
1045  } // for (x = m_Labels.begin() + m_OutputWidgets.size(), p = 0; x != m_Labels.end() && iPosition == -1; x++, p++)
1046 
1047  // check, if input field was found
1048  if (iPosition != -1)
1049  {
1050  // check, if input widget is a QSpinBox
1051  if (dynamic_cast< ::QSpinBox* >(m_InputWidgets[iPosition]) != nullptr)
1052  {
1053  // check, if input field is visible
1054  if (static_cast< ::QSpinBox* >(m_InputWidgets[iPosition])->isVisible())
1055  {
1056  // set input field (integer)
1057  static_cast< ::QSpinBox* >(m_InputWidgets[iPosition])->setValue(iValue);
1058 
1059  // press related input button to activate update
1060  m_InputButtons[iPosition]->click();
1061 
1062  } // if (static_cast< ::QSpinBox* >(m_InputWidgets[iPosition])->isVisible())
1063  else
1064  {
1065  // print warning
1066  ::std::cerr << "warning in CDMIQWidget::SetIntegerValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" is currently not visible" << ::std::endl;
1067 
1068  } // else
1069 
1070  } // if (dynamic_cast< ::QSpinBox* >(m_InputWidgets[iPosition]) != nullptr)
1071  else
1072  {
1073  // print warning
1074  ::std::cerr << "warning in CDMIQWidget::SetIntegerValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" is not a integer field" << ::std::endl;
1075 
1076  } // else
1077 
1078  } // if (iPosition != -1)
1079  else
1080  {
1081  // print warning
1082  ::std::cerr << "warning in CDMIQWidget::SetIntegerValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" not found" << ::std::endl;
1083 
1084  } // else
1085 
1086  // unlock mutex
1087  m_Mutex.unlock();
1088  // Bouml preserved body end 000F3302
1089 
1090 } // void CDMIQWidget::SetIntegerValue() throw()
1091 
1092 
1093 
1094 
1095 void CDMIQWidget::SetStringValue(const QString & InputName, const QString & Value)
1096 {
1097  // Bouml preserved body begin 000F3382
1098  decltype (m_Labels.begin()) x;
1099  int p(0);
1100  int iPosition(-1);
1101 
1102 
1103 
1104 
1105 
1106  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
1107  // DEBUG
1108  ::std::cout << "DEBUG: started CDMIQWidget::SetStringValue()" << ::std::endl;
1109  #endif
1110 
1111  // lock mutex
1112  m_Mutex.lock();
1113 
1114  // try to find input field in labels
1115  for (x = m_Labels.begin() + m_OutputWidgets.size(), p = 0; x != m_Labels.end() && iPosition == -1; x++, p++)
1116  {
1117  // check, if current label corresponds to input field
1118  if ((*x)->text() == InputName)
1119  {
1120  // store position
1121  iPosition = p;
1122 
1123  } // if ((*x)->text() == InputName)
1124 
1125  } // for (x = m_Labels.begin() + m_OutputWidgets.size(), p = 0; x != m_Labels.end() && iPosition == -1; x++, p++)
1126 
1127  // check, if input field was found
1128  if (iPosition != -1)
1129  {
1130  // check, if input widget is a QLineEdit
1131  if (dynamic_cast< ::QLineEdit* >(m_InputWidgets[iPosition]) != nullptr)
1132  {
1133  // check, if input field is visible
1134  if (static_cast< ::QLineEdit* >(m_InputWidgets[iPosition])->isVisible())
1135  {
1136  // set input field (string)
1137  static_cast< ::QLineEdit* >(m_InputWidgets[iPosition])->setText(Value);
1138 
1139  // press related input button to activate update
1140  m_InputButtons[iPosition]->click();
1141 
1142  } // if (static_cast< ::QLineEdit* >(m_InputWidgets[iPosition])->isVisible())
1143  else
1144  {
1145  // print warning
1146  ::std::cerr << "warning in CDMIQWidget::SetStringValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" is currently not visible" << ::std::endl;
1147 
1148  } // else
1149 
1150  } // if (dynamic_cast< ::QLineEdit* >(m_InputWidgets[iPosition]) != nullptr)
1151  else
1152  {
1153  // print warning
1154  ::std::cerr << "warning in CDMIQWidget::SetStringValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" is not a string field" << ::std::endl;
1155 
1156  } // else
1157 
1158  } // if (p != -1)
1159  else
1160  {
1161  // print warning
1162  ::std::cerr << "warning in CDMIQWidget::SetStringValue() in " << __FILE__ << ":" << __LINE__ << " -> input field \"" << InputName.toStdString() << "\" not found" << ::std::endl;
1163 
1164  } // else
1165 
1166  // unlock mutex
1167  m_Mutex.unlock();
1168 
1169  #ifdef __OETCS_DF_DMI_DEBUG_OUTPUT__
1170  // DEBUG
1171  ::std::cout << "DEBUG: finished CDMIQWidget::SetStringValue()" << ::std::endl;
1172  #endif
1173  // Bouml preserved body end 000F3382
1174 
1175 } // void CDMIQWidget::SetStringValue() throw()
1176 
1177 
1178 
1179 
1180 
1181 
1182 } // namespace oETCS::DF
1183 
1184 } // namespace oETCS

Copyright (C) 2010-2012 Johannes Feuser (feuser@uni-bremen.de)
The openETCS library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version.
The openETCS library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with the openETCS library. If not, see "http://www.gnu.org/licenses/.