bool CQPlotSubwidget::areOfSameType(QList<QListWidgetItem *> &items) { if (items.size() <= 1) return true; QList<CPlotItem::Type> listOfUniqueTypes; QList<QListWidgetItem *>::const_iterator it = items.begin(); while (it != items.end()) { QString currentText = (*it)->text(); CPlotItem *item = mList[currentText]; if (!listOfUniqueTypes.contains(item->getType())) listOfUniqueTypes.append(item->getType()); ++it; } return listOfUniqueTypes.size() == 1; }
void CQPlotSubwidget::storeChanges() { if (mLastSelection.size() == 0) return; if (mLastSelection.size() == 1) { QString oldName = mLastSelection[0]->text(); CPlotItem *item = mList[oldName]; updateItem(item); if (item == NULL) return; QString newName = FROM_UTF8(item->getTitle()); if (oldName != newName) { mList.remove(oldName); mLastSelection[0]->setText(newName); mList.insert(newName, item); } // assign current } else { if (!areOfSameType(mLastSelection) || !mpStack->isEnabled()) return; CPlotItem *common = new CPlotItem("nope"); if (mpStack->currentWidget() == mpHistoWidget) { common->setType(CPlotItem::histoItem1d); } #if COPASI_BANDED_GRAPH else if (mpStack->currentWidget() == mpBandedGraphWidget) { common->setType(CPlotItem::bandedGraph); } #endif else if (mpStack->currentWidget() == mpSpectogramWidget) { common->setType(CPlotItem::spectogram); } else { common->setType(CPlotItem::curve2d); } common = updateItem(common); if (common == NULL) return; QList<QListWidgetItem *>::const_iterator it; for (it = mLastSelection.begin(); it != mLastSelection.end(); ++it) { CPlotItem *current = mList[(*it)->text()]; if (current == NULL) continue; std::vector<CPlotDataChannelSpec> channels = current->getChannels(); CPlotItem *newItem = new CPlotItem(*common, NO_PARENT); newItem->setType(current->getType()); newItem->setTitle(current->getTitle()); newItem->getChannels() = channels; newItem->setActivity(common->getActivity()); mList[(*it)->text()] = newItem; delete current; } pdelete(common); // assign multiple } }
bool CopasiPlot::compile(std::vector< CCopasiContainer * > listOfContainer, const CCopasiDataModel* pDataModel) { clearBuffers(); size_t i, imax; size_t j, jmax; std::pair< std::set< const CCopasiObject * >::iterator, bool > Inserted; std::pair< Activity, size_t > DataIndex; std::vector< std::set < const CCopasiObject * > > ActivityObjects; ActivityObjects.resize(ActivitySize); // Loop over all curves. imax = mpPlotSpecification->getItems().size(); mDataIndex.resize(imax); std::vector< std::vector < const CCopasiObject * > >::iterator itX; assert(pDataModel != NULL); for (i = 0; i < imax; ++i) { CPlotItem * pItem = mpPlotSpecification->getItems()[i]; Activity ItemActivity = pItem->getActivity(); DataIndex.first = ItemActivity; // Loop over all channels jmax = pItem->getNumChannels(); mDataIndex[i].resize(jmax); for (j = 0; j < jmax; ++j) { const CCopasiObject* pObj = pDataModel->ObjectFromName(listOfContainer, pItem->getChannels()[j]); if (pObj) mObjects.insert(pObj); else CCopasiMessage(CCopasiMessage::WARNING, MCCopasiTask + 6, pItem->getChannels()[j].c_str()); // Remember the actual order for saving the data. // Note, we are currently only dealing with 2D curves and histograms. // In addition the data is not normalized. The same data column may appear // multiple times, e.g. as X value and as Y value for another curve. if (j == 0) { // We have an X value for (itX = mSaveCurveObjects.begin(); itX != mSaveCurveObjects.end(); ++itX) if (*itX->begin() == pObj) break; if (itX == mSaveCurveObjects.end()) { std::vector < const CCopasiObject * > NewX; NewX.push_back(pObj); mSaveCurveObjects.push_back(NewX); itX = mSaveCurveObjects.end() - 1; setAxisUnits(xBottom, pObj); } if (pItem->getType() == CPlotItem::histoItem1d) mSaveHistogramObjects.push_back(pObj); } else { itX->push_back(pObj); setAxisUnits(yLeft, pObj); } Inserted = ActivityObjects[ItemActivity].insert(pObj); if (Inserted.second) { if (ItemActivity & COutputInterface::BEFORE) mHaveBefore = true; if (ItemActivity & COutputInterface::DURING) mHaveDuring = true; if (ItemActivity & COutputInterface::AFTER) mHaveAfter = true; // The insert was successful DataIndex.second = ActivityObjects[ItemActivity].size() - 1; // Allocate the data buffer mData[ItemActivity].push_back(new CVector<double>(1000)); // Store the pointer to the current object value. (Only if it has a double or integer value // and the value pointer actually exists. If not, use a dummy value.) void * tmp; if ((pObj && (pObj->isValueInt() || pObj->isValueDbl())) && (tmp = pObj->getValuePointer())) { mObjectValues[ItemActivity].push_back((C_FLOAT64 *) tmp); //pObj->getValuePointer()); mObjectInteger[ItemActivity].push_back(pObj->isValueInt()); } else { mObjectValues[ItemActivity].push_back(&MissingValue); mObjectInteger[ItemActivity].push_back(false); } // Store [curve][channel] to data index mDataIndex[i][j] = DataIndex; // Store the [Activity][object] to data index. mObjectIndex[ItemActivity][pObj] = DataIndex.second; } else { // The object already existed we only need to // store [curve][channel] to data index. DataIndex.second = mObjectIndex[ItemActivity][pObj]; mDataIndex[i][j] = DataIndex; } } } // We need to set the curve data here! size_t k = 0; C2DPlotCurve ** itCurves = mCurves.array(); C2DPlotCurve ** endCurves = itCurves + mCurves.size(); for (; itCurves != endCurves; ++itCurves, ++k) { std::vector< CVector< double > * > & data = mData[(*itCurves)->getActivity()]; switch ((*itCurves)->getType()) { case CPlotItem::curve2d: (*itCurves)->setData(C2DCurveData(*data[mDataIndex[k][0].second], *data[mDataIndex[k][1].second], 0)); break; case CPlotItem::bandedGraph: (*itCurves)->setData(CBandedGraphData(*data[mDataIndex[k][0].second], *data[mDataIndex[k][1].second], *data[mDataIndex[k][2].second], 0)); break; case CPlotItem::histoItem1d: (*itCurves)->setData(CHistoCurveData(*data[mDataIndex[k][0].second], 0, mCurves[k]->getIncrement())); break; default: fatalError(); break; } } mNextPlotTime = CCopasiTimeVariable::getCurrentWallTime(); mReplotFinished = true; return true; }