COPASI API  4.16.103
CQPlotSubwidget.cpp
Go to the documentation of this file.
1 // Copyright (C) 2012 - 2013 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 #include "CQPlotSubwidget.h"
7 #include "CQPlotEditWidget.h"
8 
9 #include "curve2dwidget.h"
10 #include "HistoWidget.h"
11 #ifdef COPASI_BANDED_GRAPH
12 #include "BandedGraphWidget.h"
13 #endif // COPASI_BANDED_GRAPH
14 #include "plotwindow.h"
17 #include "report/CKeyFactory.h"
22 #include "UI/DataModelGUI.h"
23 #include "copasi/UI/qtUtilities.h"
25 
27 #include <QtGui/QListWidgetItem>
28 #include <QtCore/QList>
29 #include <QtCore/QMap>
30 #include <QtGui/QMessageBox>
31 //-----------------------------------------------------------------------------
32 
33 /*
34  * Constructs a PlotWidget1 as a child of 'parent', with the
35  * name 'name' and widget flags set to 'f'.
36  */
37 CQPlotSubwidget::CQPlotSubwidget(QWidget* parent, const char* name, Qt::WFlags fl)
38  : CopasiWidget(parent, name, fl)
39  , mpCurveWidget(NULL)
40  , mpHistoWidget(NULL)
41 #ifdef COPASI_BANDED_GRAPH
42  , mpBandedGraphWidget(NULL)
43 #endif
44  , mLastItem(NULL)
45 {
46  setupUi(this);
47 
48  mpCurveWidget = new Curve2DWidget(this);
49  mpStack->addWidget(mpCurveWidget);
50 
51  mpHistoWidget = new HistoWidget(this);
52  mpStack->addWidget(mpHistoWidget);
53 
54 #ifdef COPASI_BANDED_GRAPH
55  // this should be implemented in the CQPlotSubwidget.ui file
56  // as the button will be appended behind the 'delete' button:
57  QToolButton * buttonBandedGraph = new QToolButton(this);
58  buttonBandedGraph->setText("New Banded Graph");
59  layoutCurves->addWidget(buttonBandedGraph);
60  connect(buttonBandedGraph, SIGNAL(clicked()), this, SLOT(addBandedGraphSlot()));
61 
62  mpBandedGraphWidget = new BandedGraphWidget(this);
63  mpStack->addWidget(mpBandedGraphWidget);
64 
65 #endif // COPASI_BANDED_GRAPH
66 }
67 
69 {
70 
71  if (item == NULL || !mpStack->isEnabled()) return NULL;
72 
73  QWidget *widget = mpStack->currentWidget();
74 
75  CQPlotEditWidget *current = dynamic_cast<CQPlotEditWidget*>(widget);
76 
77  if (current != NULL)
78  {
79  if (!current->SaveToCurveSpec(item, mLastItem))
80  {
81  return NULL;
82  }
83  }
84 
85  return item;
86 }
87 
89 {
90  if (mLastSelection.size() == 0)
91  return;
92 
93  if (mLastSelection.size() == 1)
94  {
95  QString oldName = mLastSelection[0]->text();
96  CPlotItem* item = mList[oldName];
97  updateItem(item);
98 
99  if (item == NULL) return;
100 
101  QString newName = FROM_UTF8(item->getTitle());
102 
103  if (oldName != newName)
104  {
105  mList.remove(oldName);
106  mLastSelection[0]->setText(newName);
107  mList.insert(newName, item);
108  }
109 
110  // assign current
111  }
112  else
113  {
114  if (!areOfSameType(mLastSelection) || !mpStack->isEnabled())
115  return;
116 
117  CPlotItem *common = new CPlotItem("nope");
118 
119  if (mpStack->currentWidget() == mpHistoWidget)
120  {
122  }
123 
124 #if COPASI_BANDED_GRAPH
125  else if (mpStack->currentWidget() == mpBandedGraphWidget)
126  {
128  }
129 
130 #endif
131  else
132  {
133  common->setType(CPlotItem::curve2d);
134  }
135 
136  common = updateItem(common);
137 
138  if (common == NULL)
139  return;
140 
141  QList<QListWidgetItem*>::const_iterator it;
142 
143  for (it = mLastSelection.begin(); it != mLastSelection.end(); ++it)
144  {
145  CPlotItem* current = mList[(*it)->text()];
146 
147  if (current == NULL)
148  continue;
149 
150  std::vector<CPlotDataChannelSpec> channels = current->getChannels();
151 
152  CPlotItem* newItem = new CPlotItem(*common);
153  newItem->setType(current->getType());
154  newItem->setTitle(current->getTitle());
155  newItem->getChannels() = channels;
156  newItem->setActivity(common->getActivity());
157 
158  mList[(*it)->text()] = newItem;
159 
160  delete current;
161  }
162 
163  pdelete(common);
164  // assign multiple
165  }
166 }
167 
168 //-----------------------------------------------------------------------------
169 /*
170  * Destroys the object and frees any allocated resources
171  */
173 {}
174 
175 //-----------------------------------------------------------------------------
176 
177 //the slot...
179 {
180  if (mType == CPlotItem::plot2d)
181  addCurve2D();
182 }
183 
184 #ifdef COPASI_BANDED_GRAPH
185 void CQPlotSubwidget::addBandedGraphSlot()
186 {
187  if (mType == CPlotItem::plot2d)
188  addBandedGraph();
189 }
190 #endif // COPASI_BANDED_GRAPH
191 
193 {
194  if (mType == CPlotItem::plot2d)
195  addHisto1D();
196 }
197 
199 {
200  return mpListPlotItems->currentRow();
201 }
202 
204 {
205  mLastSelection.clear();
206 
207  for (int i = mpListPlotItems->count(); i >= 0; --i)
208  {
209  deleteCurve(i);
210  }
211 
212  mList.clear();
213  mpListPlotItems->clear();
214  mLastSelection.clear();
215 }
216 
217 int CQPlotSubwidget::getRow(QListWidgetItem* item)
218 {
219  for (int i = 0; i < mpListPlotItems->count(); ++i)
220  {
221  if (mpListPlotItems->item(i)->text() == item->text())
222  return i;
223  }
224 
225  return -1;
226 }
227 void CQPlotSubwidget::deleteCurve(QListWidgetItem* item)
228 {
229  if (item == NULL)
230  return;
231 
232  delete mList[item->text()];
233  mList.remove(item->text());
234  mLastSelection.removeOne(item);
235 
236  delete mpListPlotItems->takeItem(getRow(item));
237 }
238 
240 {
241  QListWidgetItem *item = mpListPlotItems->item(index);
242  deleteCurve(item);
243 }
244 
246 {
247  if (index < 0)
248  {
249  mpListPlotItems->clearSelection();
250  return;
251  }
252 
253  if (mpListPlotItems->count() == 0)
254  return;
255 
256  if (index < 0 && mpListPlotItems->count() > 0)
257  index = 0;
258 
259  if (index >= mpListPlotItems->count())
260  index = mpListPlotItems->count() - 1;
261 
262  mpListPlotItems->setCurrentRow(index, QItemSelectionModel::Select);
263 }
264 
266 {
267  QString title = FROM_UTF8(item->getTitle());
268  int count = 0;
269  mpListPlotItems->clearSelection();
270 
271  while (mList.contains(title))
272  {
273  title = (FROM_UTF8(item->getTitle()) + " %1").arg(++count);
274  }
275 
276  item->setTitle(TO_UTF8(title));
277 
278  QListWidgetItem *listItem = new QListWidgetItem(FROM_UTF8(item->getTitle()));
279  mpListPlotItems->addItem(listItem);
280  mList.insert(FROM_UTF8(item->getTitle()), new CPlotItem(*item));
281  mpListPlotItems->setCurrentRow(mpListPlotItems->count() - 1);
282 }
283 
285 {
286 
287  switch (type)
288  {
289 #ifdef COPASI_BANDED_GRAPH
290 
292  {
293  mpStack->setCurrentIndex(2);
294  return mpBandedGraphWidget;
295  }
296 
297 #endif
298 
300  {
301  mpStack->setCurrentIndex(1);
302  return mpHistoWidget;
303  }
304 
305  case CPlotItem::curve2d:
306  {
307  mpStack->setCurrentIndex(0);
308  return mpCurveWidget;
309  }
310 
311  default:
312  return NULL;
313  }
314 }
315 
317 {
318  CQPlotEditWidget* current = static_cast< CQPlotEditWidget * >(mpStack->currentWidget());
319 
320  if (item != NULL)
321  {
322  current = selectControl(item->getType());
323  }
324 
325  if (item == NULL)
326  {
327  mpStack->setEnabled(false);
328  }
329 
330  current->setModel((*CCopasiRootContainer::getDatamodelList())[0]->getModel());
331  current->LoadFromCurveSpec(item);
332 
334 
335  if (item != NULL)
336  mLastItem = new CPlotItem(*item);
337 }
338 
339 void CQPlotSubwidget::addCurveTab(const std::string & title,
340  const CPlotDataChannelSpec & x,
341  const CPlotDataChannelSpec & y)
342 {
343  CPlotItem* item = new CPlotItem(title, NULL, CPlotItem::curve2d);
344  item->addChannel(x);
345  item->addChannel(y);
346 
347  addPlotItem(item);
348 }
349 
351 {
353  std::vector< const CCopasiObject * > vector1;
354  std::vector< const CCopasiObject * > vector2;
355  pBrowser->setOutputVectors(&vector1, &vector2);
356  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
358  assert(pDataModel != NULL);
359  pBrowser->setModel(pDataModel->getModel(), CQSimpleSelectionTree::NumericValues);
360 
361  if (pBrowser->exec() == QDialog::Rejected)
362  {
363  return;
364  }
365 
366  //this assumes that the vector is empty if nothing was chosen
367  if (vector1.size() == 0 || vector2.size() == 0)
368  {
369  return;
370  }
371 
372  std::vector<CCopasiObjectName> objects1, objects2;
373  size_t i;
374  std::vector<CCopasiObjectName>::const_iterator sit;
375  const CArrayAnnotation *pArray;
376 
377  // 1. enable user to choose either a cell, an entire row/column, or even the objects themselves, if they are arrays.
378  // 2. translate to CNs and remove duplicates
379 
380  // x-axis is set for single cell selection
381  std::string cn;
382 
383  for (i = 0; i < vector1.size(); i++)
384  {
385  if (vector1[i]) // the object is not empty
386  {
387  // is it an array annotation?
388  if ((pArray = dynamic_cast< const CArrayAnnotation * >(vector1[i])))
389  {
390  // second argument is true as only single cell here is allowed. In this case we
391  //can assume that the size of the return vector is 1.
392  const CCopasiObject * pObject = CCopasiSelectionDialog::chooseCellMatrix(pArray, true, true, "X axis: ")[0];
393 
394  if (!pObject) continue;
395 
396  cn = pObject->getCN();
397  }
398  else
399  cn = vector1[i]->getCN();
400 
401  // check whether cn is already on objects1
402  for (sit = objects1.begin(); sit != objects1.end(); ++sit)
403  {
404  if (*sit == cn) break;
405  }
406 
407  // if not exist, input cn into objects1
408  if (sit == objects1.end())
409  {
410  objects1.push_back(cn);
411  }
412  }
413  }
414 
415  for (i = 0; i < vector2.size(); i++)
416  {
417  if (vector2[i])
418  {
419  // is it an array annotation?
420  if ((pArray = dynamic_cast< const CArrayAnnotation * >(vector2[i])))
421  {
422  // second argument is set false for multi selection
423  std::vector<const CCopasiObject*> vvv = CCopasiSelectionDialog::chooseCellMatrix(pArray, false, true, "Y axis: ");
424  std::vector<const CCopasiObject*>::const_iterator it;
425 
426  for (it = vvv.begin(); it != vvv.end(); ++it)
427  {
428  if (!*it) continue;
429 
430  cn = (*it)->getCN();
431 
432  //check if the CN already is in the list, if not add it.
433  for (sit = objects2.begin(); sit != objects2.end(); ++sit)
434  if (*sit == cn) break;
435 
436  if (sit == objects2.end())
437  objects2.push_back(cn);
438  }
439  }
440  else
441  {
442  cn = vector2[i]->getCN();
443 
444  //check if the CN already is in the list, if not add it.
445  for (sit = objects2.begin(); sit != objects2.end(); ++sit)
446  if (*sit == cn) break;
447 
448  if (sit == objects2.end())
449  objects2.push_back(cn);
450  }
451  }
452  }
453 
454  if (objects1.size() == 1)
455  {
456  for (i = 0; i < objects2.size(); ++i)
457  {
458  addCurveTab(pDataModel->getDataObject(objects2[i])->getObjectDisplayName()
459  + "|"
460  + pDataModel->getDataObject(objects1[0])->getObjectDisplayName(),
461  objects1[0], objects2[i]);
462  }
463  }
464  else if (objects2.size() == 1)
465  {
466  for (i = 0; i < objects1.size(); ++i)
467  {
468  addCurveTab(pDataModel->getDataObject(objects2[0])->getObjectDisplayName()
469  + "|"
470  + pDataModel->getDataObject(objects1[i])->getObjectDisplayName(),
471  objects1[i], objects2[0]);
472  }
473  }
474  else
475  {
476  size_t imax;
477 
478  if (objects1.size() > objects2.size())
479  imax = objects2.size();
480  else
481  imax = objects1.size();
482 
483  for (i = 0; i < imax; ++i)
484  {
485  addCurveTab(pDataModel->getDataObject(objects2[i])->getObjectDisplayName()
486  + "|"
487  + pDataModel->getDataObject(objects1[i])->getObjectDisplayName() ,
488  objects1[i], objects2[i]);
489  }
490  }
491 }
492 
493 #ifdef COPASI_BANDED_GRAPH
494 void CQPlotSubwidget::addBandedGraphTab(const std::string & title,
495  const CPlotDataChannelSpec & x,
496  const CPlotDataChannelSpec & yone,
497  const CPlotDataChannelSpec & ytwo)
498 {
499  CPlotItem* item = new CPlotItem(title, NULL, CPlotItem::bandedGraph);
500  item->addChannel(x);
501  item->addChannel(yone);
502  item->addChannel(ytwo);
503 
504  addPlotItem(item);
505 }
506 
507 void CQPlotSubwidget::addBandedGraph()
508 {
510  std::vector< const CCopasiObject * > vector1;
511  std::vector< const CCopasiObject * > vector2;
512  pBrowser->setOutputVectors(&vector1, &vector2);
513  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
515  assert(pDataModel != NULL);
516  pBrowser->setModel(pDataModel->getModel(), CQSimpleSelectionTree::NumericValues);
517 
518  if (pBrowser->exec() == QDialog::Rejected)
519  {
520  return;
521  }
522 
523  //this assumes that the vector is empty if nothing was chosen
524  if (vector1.size() == 0 || vector2.size() == 0)
525  {
526  return;
527  }
528 
529  std::vector<CCopasiObjectName> objects1, objects2;
530  size_t i;
531  std::vector<CCopasiObjectName>::const_iterator sit;
532  const CArrayAnnotation *pArray;
533 
534  // 1. enable user to choose either a cell, an entire row/column, or even the objects themselves, if they are arrays.
535  // 2. translate to CNs and remove duplicates
536 
537  // x-axis is set for single cell selection
538  std::string cn;
539 
540  for (i = 0; i < vector1.size(); i++)
541  {
542  if (vector1[i]) // the object is not empty
543  {
544  // is it an array annotation?
545  if ((pArray = dynamic_cast< const CArrayAnnotation * >(vector1[i])))
546  {
547  // second argument is true as only single cell here is allowed. In this case we
548  //can assume that the size of the return vector is 1.
549  const CCopasiObject * pObject = CCopasiSelectionDialog::chooseCellMatrix(pArray, true, true, "X axis: ")[0];
550 
551  if (!pObject) continue;
552 
553  cn = pObject->getCN();
554  }
555  else
556  cn = vector1[i]->getCN();
557 
558  // check whether cn is already on objects1
559  for (sit = objects1.begin(); sit != objects1.end(); ++sit)
560  {
561  if (*sit == cn) break;
562  }
563 
564  // if not exist, input cn into objects1
565  if (sit == objects1.end())
566  {
567  objects1.push_back(cn);
568  }
569  }
570  }
571 
572  for (i = 0; i < vector2.size(); i++)
573  {
574  if (vector2[i])
575  {
576  // is it an array annotation?
577  if ((pArray = dynamic_cast< const CArrayAnnotation * >(vector2[i])))
578  {
579  // second argument is set false for multi selection
580  std::vector<const CCopasiObject*> vvv = CCopasiSelectionDialog::chooseCellMatrix(pArray, false, true, "Y axis: ");
581  std::vector<const CCopasiObject*>::const_iterator it;
582 
583  for (it = vvv.begin(); it != vvv.end(); ++it)
584  {
585  if (!*it) continue;
586 
587  cn = (*it)->getCN();
588 
589  //check if the CN already is in the list, if not add it.
590  for (sit = objects2.begin(); sit != objects2.end(); ++sit)
591  if (*sit == cn) break;
592 
593  if (sit == objects2.end())
594  objects2.push_back(cn);
595  }
596  }
597  else
598  {
599  cn = vector2[i]->getCN();
600 
601  //check if the CN already is in the list, if not add it.
602  for (sit = objects2.begin(); sit != objects2.end(); ++sit)
603  if (*sit == cn) break;
604 
605  if (sit == objects2.end())
606  objects2.push_back(cn);
607  }
608  }
609  }
610 
611  if (objects1.size() == 1)
612  {
613  for (i = 0; i < objects2.size(); ++i)
614  {
615  addBandedGraphTab(pDataModel->getDataObject(objects2[i])->getObjectDisplayName()
616  + "|"
617  + pDataModel->getDataObject(objects1[0])->getObjectDisplayName(),
618  objects1[0], objects2[i]);
619  }
620  }
621  else if (objects2.size() == 1)
622  {
623  for (i = 0; i < objects1.size(); ++i)
624  {
625  addBandedGraphTab(pDataModel->getDataObject(objects2[0])->getObjectDisplayName()
626  + "|"
627  + pDataModel->getDataObject(objects1[i])->getObjectDisplayName(),
628  objects1[i], objects2[0]);
629  }
630  }
631  else
632  {
633  size_t imax;
634 
635  if (objects1.size() > objects2.size())
636  imax = objects2.size();
637  else
638  imax = objects1.size();
639 
640  for (i = 0; i < imax; ++i)
641  {
642  addBandedGraphTab(pDataModel->getDataObject(objects2[i])->getObjectDisplayName()
643  + "|"
644  + pDataModel->getDataObject(objects1[i])->getObjectDisplayName() ,
645  objects1[i], objects2[i]);
646  }
647  }
648 }
649 #endif // COPASI_BANDED_GRAPH
650 
651 void CQPlotSubwidget::addHisto1DTab(const std::string & title,
652  const CPlotDataChannelSpec & x, const C_FLOAT64 & incr)
653 {
654  CPlotItem* item = new CPlotItem(title, NULL, CPlotItem::histoItem1d);
655  item->addChannel(x);
656  item->setValue("increment", incr);
657 
658  addPlotItem(item);
659 }
660 
662 {
663  addHisto1DTab("Histogram", CPlotDataChannelSpec(CCopasiObjectName("")), 1.0);
664 }
665 
666 void CQPlotSubwidget::createHistograms(std::vector<const CCopasiObject* >objects, const C_FLOAT64 & incr)
667 {
668  C_INT32 storeTab = getCurrentIndex();
669 
670  size_t i;
671 
672  for (i = 1; i < objects.size(); ++i)
673  {
674  if (objects[i])
675  addHisto1DTab("Histogram: " + objects[i]->getObjectDisplayName(),
676  CPlotDataChannelSpec(objects[i]->getCN()), incr);
677 
678  // lineEditTitle->setText("Histogram: " + FROM_UTF8(mpObjectX->getObjectDisplayName()));
679  }
680 
681  setCurrentIndex(storeTab);
682 }
683 
684 //-----------------------------------------------------------------------------
685 
687 {
688  QList<QListWidgetItem*> selection = mpListPlotItems->selectedItems();
689 
690  if (selection.size() == 0)
691  return;
692 
693  if (QMessageBox::question(this, "Delete Curves", QString("Do you really want to delete the %1 selected curve(s)?").arg(selection.size()), QMessageBox::Yes, QMessageBox::No | QMessageBox::Default) == QMessageBox::Yes)
694  {
695 
696  for (int index = selection.size() - 1; index >= 0; --index)
697  {
698  deleteCurve(selection.at(index));
699  }
700 
701  mLastSelection.clear();
702  }
703 }
704 
705 //-----------------------------------------------------------------------------
706 
708 {
709  saveToPlotSpec();
710 
711  loadFromPlotSpec(dynamic_cast<CPlotSpecification*>(CCopasiRootContainer::getKeyFactory()->get(mKey)));
712 }
713 
714 //-----------------------------------------------------------------------------
715 
717 {
718  size_t Index, Size;
719 
720  assert(CCopasiRootContainer::getDatamodelList()->size() > 0);
722  assert(pDataModel != NULL);
723 
724  if (!pDataModel->getModel())
725  return;
726 
728 
729  if (!pspec) return;
730 
731  Index =
732  pDataModel->getPlotDefinitionList()->CCopasiVector<CPlotSpecification>::getIndex(pspec);
733  pDataModel->getPlotDefinitionList()->removePlotSpec(mKey);
734  std::string deletedKey = mKey;
735 
736  Size = pDataModel->getPlotDefinitionList()->size();
737 
738  if (Size > 0)
739  enter((*pDataModel->getPlotDefinitionList())[std::min(Index, Size - 1)]->CCopasiParameter::getKey());
740  else
741  enter("");
742 
743  //ListViews::
745 }
746 
747 //-----------------------------------------------------------------------------
748 
750 {
751  leave();
752 
754  if (pDataModel == NULL) return;
755 
756  CPlotSpecification * pPl = new CPlotSpecification(*dynamic_cast<CPlotSpecification*>(CCopasiRootContainer::getKeyFactory()->get(mKey)));
757 
758  std::string baseName = pPl->getObjectName() + "_copy";
759  std::string name = baseName;
760 
761  int i = 1;
762 
763  while (pDataModel->getPlotDefinitionList()->getIndex(name) != C_INVALID_INDEX)
764  {
765  i++;
766  name = baseName + TO_UTF8(QString::number(i));
767  }
768 
769  pPl->setObjectName(name);
770 
771  pDataModel->getPlotDefinitionList()->add(pPl, true);
772 
773  std::string key = pPl->CCopasiParameter::getKey();
775  enter(key);
777 }
778 
779 //-----------------------------------------------------------------------------
780 
782 {
783  leave();
784 
786  if (pDataModel == NULL) return;
787 
788  std::string name = "plot_";
789  int i = 0;
790  CPlotSpecification* pPl = NULL;
791  name += TO_UTF8(QString::number(i));
792 
793  while (!(pPl = pDataModel->getPlotDefinitionList()->createPlotSpec(name, CPlotItem::plot2d)))
794  {
795  i++;
796  name = "plot_";
797  name += TO_UTF8(QString::number(i));
798  }
799 
800  std::string key = pPl->CCopasiParameter::getKey();
802  enter(key);
804 }
805 
806 //-----------------------------------------------------------------------------
807 
809 {
810  loadFromPlotSpec(dynamic_cast<CPlotSpecification*>(CCopasiRootContainer::getKeyFactory()->get(mKey)));
811 }
812 
813 //-----------------------------------------------------------------------------
814 
816 {
817  if (!pspec) return false;
818 
819  mLastSelection.clear();
820 
821  //title
822  titleLineEdit->setText(pspec->getTitle().c_str());
823 
824  //active?
825  activeCheckBox->setChecked(pspec->isActive());
826 
827  //type
828  mType = pspec->getType();
829 
830  switch (mType)
831  {
832 #ifdef COPASI_BANDED_GRAPH
833 
835 #endif // COPASI_BANDED_GRAPH
836  case CPlotItem::plot2d:
837  checkLogX->setChecked(pspec->isLogX());
838  checkLogY->setChecked(pspec->isLogY());
839  break;
840 
841  default:
842  fatalError();
843  break;
844  }
845 
846  //clear tabWidget
847  deleteCurves();
848 
849  mpListPlotItems->clearSelection();
850 
851  //reconstruct tabWidget from curve specs
854 
855  QStringList PlotItems;
856 
857  for (; it != end; ++it)
858  {
859  QString title = FROM_UTF8((*it)->getTitle());
860  PlotItems.append(title);
861 
862  mList.insert(title, new CPlotItem(**it));
863  }
864 
865  mpListPlotItems->addItems(PlotItems);
866 
867  if (pspec->getItems().size() > 0)
868  {
869  mpListPlotItems->setCurrentRow(0, QItemSelectionModel::Select);
870  }
871  else
872  {
873  // We need to clear the current items display
874  selectPlotItem(NULL);
875  }
876 
877  return true; //TODO really check
878 }
879 
881 {
882  CPlotSpecification* pspec = dynamic_cast< CPlotSpecification * >(mpObject);
883 
884  if (!pspec) return true;
885 
886  pspec->cleanup();
887 
888  //title
889  if (pspec->getTitle() != TO_UTF8(titleLineEdit->text()))
890  {
891  pspec->setTitle(TO_UTF8(titleLineEdit->text()));
893  }
894 
895  //active?
896  pspec->setActive(activeCheckBox->isChecked());
897 
898  //scales
899  pspec->setLogX(checkLogX->isChecked());
900  pspec->setLogY(checkLogY->isChecked());
901 
902  //curves
903  CPlotItem* item;
904 
905  storeChanges();
906 
907  QMap<QString, CPlotItem*>::iterator it;
908 
909  for (it = mList.begin(); it != mList.end(); ++it)
910  {
911  CPlotItem* currentItem = (*it);
912 
913  if (currentItem == NULL) continue;
914 
915  item = new CPlotItem(*currentItem);
916 
917  if (item != NULL)
918  if (!pspec->getItems().add(item , true))
919  delete item;
920  }
921 
922  // :TODO Bug 322: This should only be called when actual changes have been saved.
923  // However we do not check whether the scan item are changed we delete all
924  // and create them new.
925  if (true)
926  {
927  if (mpDataModel != NULL)
928  {
929  mpDataModel->changed();
930  }
931 
932  // mChanged = false;
933  }
934 
935  return true;
936 }
937 
938 //-----------------------------------------------------------------------------
939 
940 //TODO: save a copy!
941 
943 {
944  CPlotSpecification* pspec = dynamic_cast< CPlotSpecification * >(mpObject);
945 
946  if (!pspec)
947  {
949  return false;
950  }
951 
952  return loadFromPlotSpec(pspec);
953 }
954 bool CQPlotSubwidget::areOfSameType(QList<QListWidgetItem*>& items)
955 {
956  if (items.size() <= 1) return true;
957 
958  QList<CPlotItem::Type> listOfUniqueTypes;
959 
960  QList<QListWidgetItem*>::const_iterator it = items.begin();
961 
962  while (it != items.end())
963  {
964  QString currentText = (*it)->text();
965  CPlotItem *item = mList[currentText];
966 
967  if (!listOfUniqueTypes.contains(item->getType()))
968  listOfUniqueTypes.append(item->getType());
969 
970  ++it;
971  }
972 
973  return listOfUniqueTypes.size() == 1;
974 }
975 
977 {
978  storeChanges();
979  QList<QListWidgetItem*> current = mpListPlotItems->selectedItems();
980 
981  if (current.size() == 0)
982  {
983  mpStack->setEnabled(false);
984  }
985  else if (current.size() == 1)
986  {
987  mpStack->setEnabled(true);
988  selectPlotItem(mList[current[0]->text()]);
989  (static_cast<CQPlotEditWidget*>(mpStack->currentWidget()))->setMultipleEditMode(false);
990  }
991  else
992  {
993  if (!areOfSameType(current))
994  {
995  mpStack->setEnabled(false);
996  }
997  else
998  {
999  mpStack->setEnabled(true);
1000  selectPlotItem(mList[current[0]->text()]);
1001  (static_cast<CQPlotEditWidget*>(mpStack->currentWidget()))->setMultipleEditMode(true);
1002  }
1003  }
1004 
1005  mLastSelection = current;
1006 }
1007 
1008 //-----------------------------------------------------------------------------
1009 
1011 {
1012  if (mIgnoreUpdates || isHidden()) return true;
1013 
1014  switch (objectType)
1015  {
1016  //TODO: check list:
1017  case ListViews::MODEL:
1018 
1019  switch (action)
1020  {
1021  case ListViews::DELETE:
1022  mpObject = NULL;
1023  mKey = "";
1024  return enterProtected();
1025  break;
1026 
1027  default:
1028  break;
1029  }
1030 
1031  break;
1032 
1033  case ListViews::PLOT:
1034 
1035  if (key == mKey)
1036  {
1037  switch (action)
1038  {
1039  case ListViews::DELETE:
1040  mpObject = NULL;
1041  mKey = "";
1042  return enterProtected();
1043  break;
1044 
1045  case ListViews::CHANGE:
1046  return enterProtected();
1047  break;
1048 
1049  default:
1050  break;
1051  }
1052  }
1053 
1054  break;
1055 
1056  default:
1057  break;
1058  }
1059 
1060  return true;
1061 }
1062 
1063 //-----------------------------------------------------------------------------
1064 
1066 {
1067  return saveToPlotSpec();
1068 }
CCopasiDataModel * getObjectDataModel()
CCopasiObject * getDataObject(const CCopasiObjectName &CN) const
virtual std::string getObjectDisplayName(bool regular=true, bool richtext=false) const
#define pdelete(p)
Definition: copasi.h:215
objectType
#define FROM_UTF8(__x)
Definition: qtUtilities.h:73
void switchToOtherWidget(const size_t &id, const std::string &key)
Definition: listviews.cpp:926
virtual CCopasiObjectName getCN() const
const std::string & getObjectName() const
void addHisto1DTab(const std::string &title, const CPlotDataChannelSpec &x, const C_FLOAT64 &incr)
virtual size_t size() const
CPlotItem * mLastItem
CCopasiObject * get(const std::string &key)
iterator begin()
#define fatalError()
void setActive(const bool &active)
void addChannel(const CPlotDataChannelSpec &channel)
Definition: CPlotItem.cpp:223
bool areOfSameType(QList< QListWidgetItem * > &items)
CCopasiObject * mpObject
Definition: copasiWidget.h:64
std::vector< CPlotDataChannelSpec > & getChannels()
Definition: CPlotItem.cpp:214
HistoWidget * mpHistoWidget
#define C_INVALID_INDEX
Definition: copasi.h:222
void setActivity(const COutputInterface::Activity &activity)
Definition: CPlotItem.cpp:161
virtual size_t getIndex(const std::string &name) const
const bool & isActive() const
void changed(const bool &changed=true)
#define C_INT32
Definition: copasi.h:90
void addCurveTab(const std::string &title, const CPlotDataChannelSpec &x, const CPlotDataChannelSpec &y)
QMap< QString, CPlotItem * > mList
static std::vector< const CCopasiObject * > chooseCellMatrix(const CArrayAnnotation *pArrayAnnotation, bool single, bool value, std::string caption="")
bool mIgnoreUpdates
Definition: copasiWidget.h:67
CPlotItem * updateItem(CPlotItem *item)
iterator end()
void setCurrentIndex(int index)
virtual bool add(const CType &src)
void setModel(CModel *model, const CQSimpleSelectionTree::ObjectClasses &classes)
virtual bool leave()
CQPlotSubwidget(QWidget *parent=0, const char *name=0, Qt::WFlags fl=0)
ListViews * mpListView
Definition: copasiWidget.h:62
void setType(CPlotItem::Type type)
Definition: CPlotItem.cpp:99
Curve2DWidget * mpCurveWidget
virtual bool add(const CType &src)
const CPlotItem::Type & getType() const
Definition: CPlotItem.cpp:158
bool setValue(const std::string &name, const CType &value)
static CCopasiVector< CCopasiDataModel > * getDatamodelList()
bool removePlotSpec(const std::string &key)
CPlotSpecification * createPlotSpec(const std::string &name, CPlotItem::Type type=CPlotItem::plot2d)
const COutputInterface::Activity & getActivity() const
Definition: CPlotItem.cpp:179
virtual bool protectedNotify(ListViews::ObjectType objectType, ListViews::Action action, const std::string &key="")
CCopasiDataModel * mpDataModel
Definition: copasiWidget.h:65
virtual void setModel(const CModel *model)
virtual bool SaveToCurveSpec(CPlotItem *curve, const CPlotItem *original=NULL) const =0
virtual bool LoadFromCurveSpec(const CPlotItem *curve)=0
virtual bool enterProtected()
static CKeyFactory * getKeyFactory()
Header file of class CArrayAnnotation.
const COutputDefinitionVector * getPlotDefinitionList() const
const CCopasiVector< CPlotItem > & getItems() const
#define C_FLOAT64
Definition: copasi.h:92
CPlotItem::Type mType
QList< QListWidgetItem * > mLastSelection
bool fl(const C_FLOAT64 &d1, const C_FLOAT64 &d2)
void addPlotItem(CPlotItem *item)
#define TO_UTF8(__x)
Definition: qtUtilities.h:74
bool loadFromPlotSpec(const CPlotSpecification *)
const std::string & getTitle() const
Definition: CPlotItem.cpp:228
CQPlotEditWidget * selectControl(CPlotItem::Type type)
void selectPlotItem(CPlotItem *item)
bool setObjectName(const std::string &name)
std::string mKey
Definition: copasiWidget.h:63
void deleteCurve(int index)
int getRow(QListWidgetItem *item)
void setOutputVectors(std::vector< const CCopasiObject * > *outputVector1, std::vector< const CCopasiObject * > *outputVector2)
#define min(a, b)
Definition: f2c.h:175
void setTitle(const std::string &title)
Definition: CPlotItem.cpp:233
virtual bool update(ListViews::ObjectType objectType, ListViews::Action action, const std::string &key)
void createHistograms(std::vector< const CCopasiObject * >objects, const C_FLOAT64 &incr)
bool enter(const std::string &key)