//################################################################################################## // // Custom Visualization Core library // Copyright (C) 2011-2012 Ceetron AS // // This 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 // (at your option) any later version. // // This 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 at <> // for more details. // //################################################################################################## #include "cafPdmObject.h" #include namespace caf { //================================================================================================== /// Implementation of PdmField methods //================================================================================================== //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void caf::PdmField::setValueFromUi(const QVariant& uiValue) { QVariant oldValue = PdmFieldTypeSpecialization::convert(m_fieldValue); if (m_optionEntryCache.size()) { // Check if we got an index into the option list if (uiValue.type() == QVariant::UInt) { assert(uiValue.toUInt() < static_cast(m_optionEntryCache.size())); PdmFieldTypeSpecialization::setFromVariant(m_optionEntryCache[uiValue.toUInt()].value, m_fieldValue); } else { m_optionEntryCache.clear(); } } else { PdmFieldTypeSpecialization::setFromVariant(uiValue, m_fieldValue); } QVariant newValue = PdmFieldTypeSpecialization::convert(m_fieldValue); // Call changed methods if field value has changed if (newValue != oldValue) { assert(m_ownerObject != NULL); m_ownerObject->fieldChangedByUi(this, oldValue, newValue); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template QList caf::PdmField::valueOptions(bool* useOptionsOnly) { if (m_ownerObject) { m_optionEntryCache = m_ownerObject->calculateValueOptions(this, useOptionsOnly); if (m_optionEntryCache.size()) { // Find this field value in the list if present QVariant convertedFieldValue = PdmFieldTypeSpecialization::convert(m_fieldValue); unsigned int index; bool foundFieldValue = PdmOptionItemInfo::findValue(m_optionEntryCache, convertedFieldValue, &index); // If not found, we have to add it to the list, to be able to show it if (!foundFieldValue) { m_optionEntryCache.push_front(PdmOptionItemInfo(convertedFieldValue.toString(), convertedFieldValue, true, QIcon())); } if (m_optionEntryCache.size()) return m_optionEntryCache; } } return PdmFieldTypeSpecialization::valueOptions(useOptionsOnly, m_fieldValue); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template QVariant caf::PdmField::uiValue() const { if (m_optionEntryCache.size()) { QVariant convertedFieldValue = PdmFieldTypeSpecialization::convert(m_fieldValue); unsigned int index; bool foundFieldValue = PdmOptionItemInfo::findValue(m_optionEntryCache, convertedFieldValue, &index); assert(foundFieldValue); return QVariant(index); } return PdmFieldTypeSpecialization::convert(m_fieldValue); } //================================================================================================== /// Implementation of PdmField methods /// (Partial specialization for pointers) //================================================================================================== //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void caf::PdmField::readFieldData(QXmlStreamReader& xmlStream) { PdmFieldIOHelper::skipCharactersAndComments(xmlStream); if (!xmlStream.isStartElement()) return; // Todo: Error handling QString className = xmlStream.name().toString(); if (m_fieldValue.isNull()) { m_fieldValue.setRawPtr(caf::PdmObjectFactory::instance()->create(className)); if (m_fieldValue.notNull()) { m_fieldValue.rawPtr()->addParentField(this); } } if (m_fieldValue.isNull()) return; // Warning: Unknown className read if (xmlStream.name() != m_fieldValue.rawPtr()->classKeyword()) return; // Error: Field contains different class type than on file m_fieldValue.rawPtr()->readFields(xmlStream); // Make stream point to end of element QXmlStreamReader::TokenType type; type = xmlStream.readNext(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void caf::PdmField::writeFieldData(QXmlStreamWriter& xmlStream) { if (m_fieldValue == NULL) return; QString className = m_fieldValue.rawPtr()->classKeyword(); xmlStream.writeStartElement("", className); m_fieldValue.rawPtr()->writeFields(xmlStream); xmlStream.writeEndElement(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void caf::PdmField::childObjects(std::vector* objects) { assert (objects); PdmObject* obj = m_fieldValue.rawPtr(); if (obj) { objects->push_back(obj); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template caf::PdmField::PdmField(const PdmField& other) { if (m_fieldValue) m_fieldValue.rawPtr()->removeParentField(this); m_fieldValue = other.m_fieldValue; if (m_fieldValue != NULL) m_fieldValue.rawPtr()->addParentField(this); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template caf::PdmField::PdmField(const DataTypePtr& fieldValue) { if (m_fieldValue) m_fieldValue->removeParentField(this); m_fieldValue = fieldValue; if (m_fieldValue != NULL) m_fieldValue->addParentField(this); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template caf::PdmField::~PdmField() { if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeParentField(this); m_fieldValue = NULL; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template caf::PdmField& PdmField::operator=(const PdmField& other) { if (m_fieldValue) m_fieldValue->removeParentField(this); m_fieldValue = other.m_fieldValue; if (m_fieldValue != NULL) m_fieldValue->addParentField(this); return *this; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template caf::PdmField& PdmField::operator=(const DataTypePtr & fieldValue) { if (m_fieldValue) m_fieldValue->removeParentField(this); m_fieldValue = fieldValue; if (m_fieldValue != NULL) m_fieldValue->addParentField(this); return *this; } //================================================================================================== /// Implementation of PdmPointersField<> //================================================================================================== //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template PdmPointersField::PdmPointersField(const PdmPointersField& other) { this->removeThisAsParentField(); m_pointers = other.m_pointers; this->addThisAsParentField(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template PdmPointersField::~PdmPointersField() { this->removeThisAsParentField(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template caf::PdmPointersField& PdmPointersField::operator=(const PdmPointersField& other) { this->removeThisAsParentField(); m_pointers = other.m_pointers; this->addThisAsParentField(); return *this; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template DataType* PdmPointersField::operator[](size_t index) const { return m_pointers[index]; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::push_back(DataType* pointer) { m_pointers.push_back(pointer); if (pointer) pointer->addParentField(this); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::set(size_t index, DataType* pointer) { if (m_pointers[index]) m_pointers[index]->removeParentField(this); m_pointers[index] = pointer; if (m_pointers[index]) pointer->addParentField(this); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::insert(size_t indexAfter, DataType* pointer) { m_pointers.insert(m_pointers.begin()+indexAfter, pointer); if (pointer) pointer->addParentField(this); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::clear() { this->removeThisAsParentField(); m_pointers.clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::deleteChildren() { size_t index; for (index = 0; index < m_pointers.size(); ++index) { delete(m_pointers[index]); } m_pointers.clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::erase(size_t index) { if (m_pointers[index]) m_pointers[index]->removeParentField(this); m_pointers.erase(m_pointers.begin() + index); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::removeAll(DataType* pointer) { size_t index; std::vector< PdmPointer > tempPointers; tempPointers = m_pointers; m_pointers.clear(); for (index = 0; index < tempPointers.size(); ++index) { if (tempPointers[index] != pointer) { m_pointers.push_back(tempPointers[index]); } else { if (tempPointers[index]) tempPointers[index]->removeParentField(this); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::writeFieldData( QXmlStreamWriter& xmlStream) { typename std::vector< PdmPointer >::iterator it; for (it = m_pointers.begin(); it != m_pointers.end(); ++it) { if (*it == NULL) continue; QString className = (*it)->classKeyword(); xmlStream.writeStartElement("", className); (*it)->writeFields(xmlStream); xmlStream.writeEndElement(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::readFieldData(QXmlStreamReader& xmlStream) { DataType * currentObject = NULL; PdmFieldIOHelper::skipCharactersAndComments(xmlStream); while (xmlStream.isStartElement()) { QString className = xmlStream.name().toString(); PdmObject * obj = PdmObjectFactory::instance()->create(className); if (obj == NULL) { // Warning: Unknown className read // Skip to corresponding end element xmlStream.skipCurrentElement(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); continue; } currentObject = dynamic_cast (obj); if (currentObject == NULL) { // Warning: Inconsistency in factory !! Assert ? // Skip to corresponding end element xmlStream.skipCurrentElement(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); continue; } currentObject->readFields(xmlStream); m_pointers.push_back(currentObject); // Skip comments and for some reason: Characters. The last bit should not be correct, // but Qt reports a character token between EndElement and StartElement QXmlStreamReader::TokenType type; type = xmlStream.readNext(); PdmFieldIOHelper::skipCharactersAndComments(xmlStream); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::childObjects(std::vector* objects) { if (!objects) return; size_t i; for (i = 0; i < m_pointers.size(); ++i) { objects->push_back(m_pointers[i]); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::removeThisAsParentField() { typename std::vector< PdmPointer< DataType > >::iterator it; for (it = m_pointers.begin(); it != m_pointers.end(); ++it) { if (!it->isNull()) { (*it)->removeParentField(this); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- template void PdmPointersField::addThisAsParentField() { typename std::vector< PdmPointer< DataType > >::iterator it; for (it = m_pointers.begin(); it != m_pointers.end(); ++it) { if (!it->isNull()) { (*it)->addParentField(this); } } } } //End of namespace caf