ResInsight/cafProjectDataModel/cafPdmField.h

240 lines
11 KiB
C++

//##################################################################################################
//
// 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 <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
//##################################################################################################
#pragma once
#include "cafPdmUiItem.h"
#include "cafPdmFieldImpl.h"
#include <set>
#include <assert.h>
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
#include <QTextStream>
namespace caf
{
class PdmObject;
template <class T> class PdmPointer;
class PdmUiFieldEditorHandle;
//==================================================================================================
/// Base class for all fields, making it possible to handle them generically
//==================================================================================================
class PdmFieldHandle : public PdmUiItem
{
public:
PdmFieldHandle() : m_isIOReadable(true), m_isIOWritable(true) { m_ownerObject = NULL; m_keyword = "UNDEFINED"; }
virtual ~PdmFieldHandle() { }
virtual void readFieldData(QXmlStreamReader& xmlStream) = 0;
virtual void writeFieldData(QXmlStreamWriter& xmlStream) = 0;
bool isIOReadable() { return m_isIOReadable; }
bool isIOWritable() { return m_isIOWritable; }
void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; }
void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; }
void setKeyword(const QString& keyword);
QString keyword() const { return m_keyword; }
void setOwnerObject(PdmObject * owner) { m_ownerObject = owner; }
PdmObject* ownerObject() { return m_ownerObject; }
// Generalized access methods for User interface
virtual QVariant uiValue() const { return QVariant(); }
virtual void setValueFromUi(const QVariant& ) { }
virtual void childObjects(std::vector<PdmObject*>* ) { }
virtual void removeChildObject(PdmObject* ) { }
virtual QList<PdmOptionItemInfo>
valueOptions( bool* useOptionsOnly) { return QList<PdmOptionItemInfo>(); }
protected:
bool assertValid() const;
protected:
PdmObject* m_ownerObject;
private:
QString m_keyword;
bool m_isIOReadable;
bool m_isIOWritable;
};
//==================================================================================================
/// Field class encapsulating data with input and output of this data to/from a QXmlStream
/// read/write-FieldData is supposed to be specialized for types needing specialization
//==================================================================================================
template <typename T> struct PdmFieldWriter;
template <typename T> struct PdmFieldReader;
template<typename DataType >
class PdmField : public PdmFieldHandle
{
public:
PdmField() {}
virtual ~PdmField() {}
// Copy and assignment must ignore the default value.
PdmField(const PdmField& other) : PdmFieldHandle() { assertValid(); m_fieldValue = other.m_fieldValue; }
PdmField(const DataType& fieldValue) : PdmFieldHandle() { assertValid(); m_fieldValue = fieldValue; }
PdmField& operator= (const PdmField& other) { assertValid(); m_fieldValue = other.m_fieldValue; return *this; }
PdmField& operator= (const DataType& fieldValue) { assertValid(); m_fieldValue = fieldValue; return *this; }
operator DataType () const { return m_fieldValue; }
// DataType& operator()() { assertValid(); return m_fieldValue; }
const DataType& operator()() const { return m_fieldValue; }
DataType& v() { assertValid(); return m_fieldValue; }
const DataType& v() const { return m_fieldValue; }
bool operator== (const DataType& fieldValue) const { return m_fieldValue == fieldValue; }
// readFieldData assumes that the xmlStream points to first token of field content.
// After reading, the xmlStream is supposed to point to the first token after the field content.
// (typically an "endElement")
virtual void readFieldData(QXmlStreamReader& xmlStream) { PdmFieldReader<DataType>::readFieldData(*this, xmlStream); }
virtual void writeFieldData(QXmlStreamWriter& xmlStream) { PdmFieldWriter<DataType>::writeFieldData(*this, xmlStream);}
const DataType& defaultValue() const { return m_defaultFieldValue; }
void setDefaultValue(const DataType& val) { m_defaultFieldValue = val; }
// Gui generalized interface
virtual QVariant uiValue() const;
virtual void setValueFromUi(const QVariant& uiValue);
virtual QList<PdmOptionItemInfo> valueOptions( bool* useOptionsOnly);
virtual void childObjects(std::vector<PdmObject*>* objects) { PdmFieldTypeSpecialization<DataType>::childObjects(*this, objects); }
protected:
DataType m_fieldValue;
DataType m_defaultFieldValue;
QList<PdmOptionItemInfo> m_optionEntryCache;
};
//==================================================================================================
/// Specialization for pointers, but only applicable to PdmObjectBase derived objects.
/// The pointer is guarded, meaning that it will be set to NULL if the object pointed to
/// is deleted. The referenced object will be printed in place in the xml-file
//==================================================================================================
template<typename DataType >
class PdmField <DataType*> : public PdmFieldHandle
{
typedef DataType* DataTypePtr;
public:
PdmField() : PdmFieldHandle() { m_fieldValue = NULL; }
PdmField(const PdmField& other);
PdmField(const DataTypePtr& fieldValue);
virtual ~PdmField();
PdmField& operator= (const PdmField& other);
PdmField& operator= (const DataTypePtr & fieldValue);
operator DataType* () const { return m_fieldValue; }
DataType* operator->() const { return m_fieldValue; }
const PdmPointer<DataType>& operator()() const { return m_fieldValue; }
const PdmPointer<DataType>& v() const { return m_fieldValue; }
bool operator==(const DataTypePtr& fieldValue) { return m_fieldValue == fieldValue; }
// readFieldData assumes that the xmlStream points to first token of field content.
// After reading, the xmlStream is supposed to point to the first token after the field content.
// (typically an "endElement")
virtual void readFieldData(QXmlStreamReader& xmlStream);
virtual void writeFieldData(QXmlStreamWriter& xmlStream);
const DataTypePtr& defaultValue() const { return NULL; }
void setDefaultValue(const DataTypePtr& ) { }
// Gui generalized methods
virtual QVariant uiValue() const { return QVariant();}
virtual void childObjects(std::vector<PdmObject*>* objects);
protected:
PdmPointer<DataType> m_fieldValue;
};
//==================================================================================================
/// PdmFieldClass to handle a collection of PdmObject derived pointers
/// The reasons for this class is to add itself as parentField into the objects being pointed to.
/// The interface is made similar to std::vector<>, and the complexity of the methods is similar too.
//==================================================================================================
template<typename DataType>
class PdmPointersField : public PdmFieldHandle
{
public:
PdmPointersField()
{ bool doNotUsePdmPointersFieldForAnythingButPointersToPdmObject = false; assert(doNotUsePdmPointersFieldForAnythingButPointersToPdmObject); }
};
template<typename DataType>
class PdmPointersField<DataType*> : public PdmFieldHandle
{
typedef DataType* DataTypePtr;
public:
PdmPointersField() { }
PdmPointersField(const PdmPointersField& other);
virtual ~PdmPointersField();
PdmPointersField& operator= (const PdmPointersField& other);
bool operator==(const PdmPointersField& other) { return m_pointers == other.m_pointers; }
PdmPointersField& operator() () { return *this; }
size_t size() const { return m_pointers.size(); }
bool empty() const { return m_pointers.empty(); }
DataType* operator[] (size_t index) const;
void push_back(DataType* pointer);
void set(size_t index, DataType* pointer);
void insert(size_t indexAfter, DataType* pointer);
void clear();
void erase(size_t index);
void deleteAllChildObjects();
// Reimplementation of PdmFieldhandle methods
virtual void readFieldData(QXmlStreamReader& xmlStream);
virtual void writeFieldData(QXmlStreamWriter& xmlStream);
// Gui generalized methods
virtual void childObjects(std::vector<PdmObject*>* objects);
virtual void removeChildObject(PdmObject* object);
private:
void removeThisAsParentField();
void addThisAsParentField();
private:
std::vector< PdmPointer<DataType> > m_pointers;
};
} // End of namespace caf
#include "cafPdmField.inl"