mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Initial commit of ResInsight version 0.4.8
This commit is contained in:
11
cafProjectDataModel/CMakeLists.txt
Normal file
11
cafProjectDataModel/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project (cafProjectDataModel)
|
||||
|
||||
add_library( ${PROJECT_NAME}
|
||||
cafPdmObject.cpp
|
||||
cafPdmDocument.cpp
|
||||
cafPdmField.cpp
|
||||
cafPdmUiItem.cpp
|
||||
cafPdmPointer.cpp
|
||||
)
|
||||
313
cafProjectDataModel/cafAppEnum.h
Normal file
313
cafProjectDataModel/cafAppEnum.h
Normal file
@@ -0,0 +1,313 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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 <vector>
|
||||
#include <string>
|
||||
#include <QtCore/QString>
|
||||
#include <QTextStream>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// An enum class to make it easier to handle IO and UI based on the enum.
|
||||
/// Usage:
|
||||
/// In Header file of SomeClass:
|
||||
/// enum SomeEnumType
|
||||
/// {
|
||||
/// A = 2,
|
||||
/// B = 7
|
||||
/// };
|
||||
/// caf::AppEnum<SomeEnumType> m_enumValue;
|
||||
///
|
||||
/// In C++ file :
|
||||
/// namespace caf {
|
||||
/// template<>
|
||||
/// void caf::AppEnum<SomeClass::SomeEnumType>::setUp()
|
||||
/// {
|
||||
/// addItem(SomeClass::A, "A", "An A letter");
|
||||
/// addItem(SomeClass::B, "B", "A B letter");
|
||||
/// setDefault(SomeClass::B);
|
||||
/// }
|
||||
/// }
|
||||
/// General use:
|
||||
///
|
||||
/// m_enumValue = A;
|
||||
/// if (m_enumValue == A || m_enumValue != B ){}
|
||||
///
|
||||
/// switch (m_enumValue)
|
||||
/// {
|
||||
/// case A:
|
||||
/// break;
|
||||
/// case B:
|
||||
/// break;
|
||||
/// }
|
||||
///
|
||||
/// cout << m_enumValue.text();
|
||||
/// m_enumValue.setFromText("A");
|
||||
///
|
||||
/// for (size_t i = 0; i < caf::AppEnum<SomeClass::SomeEnumType>::size(); ++i)
|
||||
/// cout << caf::AppEnum<SomeClass::SomeEnumType>::text(caf::AppEnum<SomeClass::SomeEnumType>::fromIndex(i)) << endl;
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
template <class T>
|
||||
class AppEnum
|
||||
{
|
||||
public:
|
||||
AppEnum() { m_value = EnumMapper::instance()->defaultValue();}
|
||||
AppEnum(T value): m_value(value) {}
|
||||
|
||||
bool operator== (T value) const { return m_value == value;}
|
||||
bool operator!= (T value) const { return m_value != value;}
|
||||
|
||||
operator T () const { return m_value;}
|
||||
QString text() const { return EnumMapper::instance()->text(m_value);}
|
||||
QString uiText() const { return EnumMapper::instance()->uiText(m_value);}
|
||||
|
||||
AppEnum& operator= (T value) { m_value = value; return *this; }
|
||||
bool setFromText(const QString& text){ return EnumMapper::instance()->enumVal(m_value, text);}
|
||||
bool setFromIndex (size_t index) { return EnumMapper::instance()->enumVal(m_value, index); }
|
||||
|
||||
// Static interface to access the properties of the enum definition
|
||||
|
||||
static bool isValid(const QString& text) { return EnumMapper::instance()->isValid(text);}
|
||||
static bool isValid(size_t index) { return index < EnumMapper::instance()->size();}
|
||||
static size_t size() { return EnumMapper::instance()->size();}
|
||||
|
||||
static QStringList uiTexts() { return EnumMapper::instance()->uiTexts(); }
|
||||
static T fromIndex (size_t idx) { T val; EnumMapper::instance()->enumVal(val, idx); return val;}
|
||||
static T fromText(const QString& text) { T val; EnumMapper::instance()->enumVal(val, text); return val;}
|
||||
static size_t index (T enumValue) { return EnumMapper::instance()->index(enumValue);}
|
||||
static QString text (T enumValue) { return EnumMapper::instance()->text(enumValue);}
|
||||
static QString textFromIndex (size_t idx) { return text(fromIndex(idx));}
|
||||
static QString uiText(T enumValue) { return EnumMapper::instance()->uiText(enumValue);}
|
||||
static QString uiTextFromIndex(size_t idx) { return uiText(fromIndex(idx)); }
|
||||
|
||||
private:
|
||||
//==================================================================================================
|
||||
/// The setup method is supposed to be specialized for each and every type instantiation of this class,
|
||||
/// and is supposed to set up the mapping between enum values, text and ui-text using the \m addItem
|
||||
/// method. It may also set a default value using \m setDefault
|
||||
//==================================================================================================
|
||||
static void setUp();
|
||||
static void addItem(T enumVal, const QString& text, const QString& uiText)
|
||||
{
|
||||
EnumMapper::instance()->addItem(enumVal, text, uiText);
|
||||
}
|
||||
|
||||
static void setDefault( T defaultEnumValue)
|
||||
{
|
||||
EnumMapper::instance()->setDefault(defaultEnumValue);
|
||||
}
|
||||
|
||||
T m_value;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// A private class to handle the instance of the mapping vector.
|
||||
/// all access methods could have been placed directly in the \class AppEnum class,
|
||||
/// but AppEnum implementation gets nicer this way.
|
||||
/// The real core of this class is the vector map member and the static instance method
|
||||
//==================================================================================================
|
||||
|
||||
class EnumMapper
|
||||
{
|
||||
private:
|
||||
struct Triplet
|
||||
{
|
||||
Triplet(T enumVal, const QString& text, QString uiText) :
|
||||
m_enumVal(enumVal), m_text(text), m_uiText(uiText)
|
||||
{}
|
||||
|
||||
T m_enumVal;
|
||||
QString m_text;
|
||||
QString m_uiText;
|
||||
};
|
||||
|
||||
public:
|
||||
void addItem(T enumVal, const QString& text, QString uiText)
|
||||
{
|
||||
instance()->m_mapping.push_back(Triplet(enumVal, text, uiText));
|
||||
}
|
||||
|
||||
static EnumMapper * instance()
|
||||
{
|
||||
static EnumMapper * storedInstance = 0;
|
||||
if (!storedInstance)
|
||||
{
|
||||
storedInstance = new EnumMapper;
|
||||
AppEnum<T>::setUp();
|
||||
}
|
||||
return storedInstance;
|
||||
}
|
||||
|
||||
void setDefault(T defaultEnumValue)
|
||||
{
|
||||
m_defaultValue = defaultEnumValue;
|
||||
m_defaultValueIsSet = true;
|
||||
}
|
||||
|
||||
T defaultValue() const
|
||||
{
|
||||
if (m_defaultValueIsSet)
|
||||
{
|
||||
return m_defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// assert(m_mapping.size());
|
||||
return m_mapping[0].m_enumVal;
|
||||
}
|
||||
}
|
||||
|
||||
bool isValid( const QString& text) const
|
||||
{
|
||||
size_t idx;
|
||||
for(idx = 0; idx < m_mapping.size(); ++idx)
|
||||
{
|
||||
if (text == m_mapping[idx].m_text) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_mapping.size();
|
||||
}
|
||||
|
||||
bool enumVal(T& value, const QString& text) const
|
||||
{
|
||||
value = defaultValue();
|
||||
size_t idx;
|
||||
for(idx = 0; idx < m_mapping.size(); ++idx)
|
||||
{
|
||||
if (text == m_mapping[idx].m_text)
|
||||
{
|
||||
value = m_mapping[idx].m_enumVal;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool enumVal(T& value, size_t index) const
|
||||
{
|
||||
value = defaultValue();
|
||||
if (index < m_mapping.size())
|
||||
{
|
||||
value = m_mapping[index].m_enumVal;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t index(T enumValue) const
|
||||
{
|
||||
size_t idx;
|
||||
for(idx = 0; idx < m_mapping.size(); ++idx)
|
||||
{
|
||||
if (enumValue == m_mapping[idx].m_enumVal)
|
||||
return idx;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
QString uiText(T value) const
|
||||
{
|
||||
size_t idx;
|
||||
for(idx = 0; idx < m_mapping.size(); ++idx)
|
||||
{
|
||||
if (value == m_mapping[idx].m_enumVal) return m_mapping[idx].m_uiText;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
QStringList uiTexts () const
|
||||
{
|
||||
QStringList uiTextList;
|
||||
size_t idx;
|
||||
for(idx = 0; idx < m_mapping.size(); ++idx)
|
||||
{
|
||||
uiTextList.append(m_mapping[idx].m_uiText);
|
||||
}
|
||||
return uiTextList;
|
||||
}
|
||||
|
||||
QString text(T value) const
|
||||
{
|
||||
size_t idx;
|
||||
for(idx = 0; idx < m_mapping.size(); ++idx)
|
||||
{
|
||||
if (value == m_mapping[idx].m_enumVal) return m_mapping[idx].m_text;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
private:
|
||||
EnumMapper() : m_defaultValueIsSet(false) { }
|
||||
|
||||
friend class AppEnum<T>;
|
||||
|
||||
std::vector<Triplet> m_mapping;
|
||||
T m_defaultValue;
|
||||
bool m_defaultValueIsSet;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
/// Cant remember why we need those comparison operators...
|
||||
//==================================================================================================
|
||||
|
||||
template<class T>
|
||||
bool operator == ( T value, const caf::AppEnum<T>& appEnum)
|
||||
{
|
||||
return (appEnum == value);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool operator != ( T value, const caf::AppEnum<T>& appEnum)
|
||||
{
|
||||
return (appEnum != value);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
/// Implementation of stream operators to make PdmField<AppEnum<> > work smoothly
|
||||
/// Assumes that the stream ends at the end of the enum text
|
||||
//==================================================================================================
|
||||
|
||||
template < typename T >
|
||||
void operator >> (QTextStream& str, caf::AppEnum<T>& appEnum)
|
||||
{
|
||||
QString text;
|
||||
str >> text;
|
||||
appEnum.setFromText(text);
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void operator << (QTextStream& str, const caf::AppEnum<T>& appEnum)
|
||||
{
|
||||
str << appEnum.text();
|
||||
}
|
||||
110
cafProjectDataModel/cafFactory.h
Normal file
110
cafProjectDataModel/cafFactory.h
Normal file
@@ -0,0 +1,110 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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 <assert.h>
|
||||
#include <map>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// A generic Factory class template
|
||||
/// Usage:
|
||||
/// caf::Factory<BaseType, KeyType>::instance()->registerCreator<TypeToCreate>(key);
|
||||
/// BaseType* newObject = caf::Factory<BaseType, KeyType>::instance()->create(key);
|
||||
//==================================================================================================
|
||||
|
||||
template<typename BaseType, typename KeyType>
|
||||
class Factory
|
||||
{
|
||||
public:
|
||||
static Factory<BaseType, KeyType> * instance()
|
||||
{
|
||||
static Factory<BaseType, KeyType>* fact = new Factory<BaseType, KeyType>;
|
||||
return fact;
|
||||
}
|
||||
|
||||
template< typename TypeToCreate >
|
||||
void registerCreator(const KeyType& key)
|
||||
{
|
||||
std::map<KeyType, ObjectCreatorBase*>::iterator entryIt;
|
||||
|
||||
entryIt = m_factoryMap.find(key);
|
||||
if (entryIt == m_factoryMap.end())
|
||||
{
|
||||
m_factoryMap[key] = new ObjectCreator<TypeToCreate>();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(key != entryIt->first); // classNameKeyword has already been used
|
||||
assert(false); // To be sure ..
|
||||
}
|
||||
}
|
||||
|
||||
BaseType* create(const KeyType& key);
|
||||
{
|
||||
std::map<KeyType, ObjectCreatorBase*>::iterator entryIt;
|
||||
entryIt = m_factoryMap.find(key);
|
||||
if (entryIt != m_factoryMap.end())
|
||||
{
|
||||
return entryIt->second->create();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Factory () {}
|
||||
~Factory()
|
||||
{
|
||||
std::map<KeyType, ObjectCreatorBase*>::iterator entryIt;
|
||||
for (entryIt = m_factoryMap.begin(); entryIt != m_factoryMap.end(); ++entryIt)
|
||||
{
|
||||
delete(entryIt->second);
|
||||
}
|
||||
}
|
||||
|
||||
// Internal helper classes
|
||||
|
||||
class ObjectCreatorBase
|
||||
{
|
||||
public:
|
||||
ObjectCreatorBase() {}
|
||||
virtual ~ObjectCreatorBase() {}
|
||||
virtual BaseType * create() = 0;
|
||||
};
|
||||
|
||||
template< typename TypeToCreate >
|
||||
class ObjectCreator : public ObjectCreatorBase
|
||||
{
|
||||
public:
|
||||
virtual BaseType * create() { return new TypeToCreate(); }
|
||||
};
|
||||
|
||||
// Map to store factory
|
||||
std::map<KeyType, ObjectCreatorBase*> m_factoryMap;
|
||||
};
|
||||
|
||||
|
||||
} //End of namespace caf
|
||||
45
cafProjectDataModel/cafFixedArray.h
Normal file
45
cafProjectDataModel/cafFixedArray.h
Normal file
@@ -0,0 +1,45 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// A fixed array class. Used to create small fixed size index arrays typically
|
||||
//==================================================================================================
|
||||
|
||||
template < typename T, size_t size >
|
||||
class FixedArray
|
||||
{
|
||||
public:
|
||||
T m_array[size];
|
||||
template<typename IndexType> T& operator[](const IndexType& index) { CVF_TIGHT_ASSERT(static_cast<size_t>(index) < size); return m_array[index]; }
|
||||
template<typename IndexType> T operator[](const IndexType& index) const { CVF_TIGHT_ASSERT(static_cast<size_t>(index) < size); return m_array[index]; }
|
||||
};
|
||||
|
||||
typedef FixedArray<int, 3> IntArray3;
|
||||
typedef FixedArray<int, 4> IntArray4;
|
||||
typedef FixedArray<int, 8> IntArray8;
|
||||
typedef FixedArray<size_t, 3> SizeTArray3;
|
||||
typedef FixedArray<size_t, 4> SizeTArray4;
|
||||
typedef FixedArray<size_t, 8> SizeTArray8;
|
||||
|
||||
}
|
||||
87
cafProjectDataModel/cafOmpMutex.h
Normal file
87
cafProjectDataModel/cafOmpMutex.h
Normal file
@@ -0,0 +1,87 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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 <omp.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// OpenMP mutex definition
|
||||
/// Taken from http://bisqwit.iki.fi/story/howto/openmp/
|
||||
//==================================================================================================
|
||||
class MutexType
|
||||
{
|
||||
public:
|
||||
MutexType() { omp_init_lock(&m_lock); }
|
||||
~MutexType() { omp_destroy_lock(&m_lock); }
|
||||
void lock() { omp_set_lock(&m_lock); }
|
||||
void unlock() { omp_unset_lock(&m_lock); }
|
||||
|
||||
MutexType(const MutexType& ) { omp_init_lock(&m_lock); }
|
||||
MutexType& operator= (const MutexType& ) { return *this; }
|
||||
|
||||
private:
|
||||
omp_lock_t m_lock;
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// OpenMP scoped lock on a mutex
|
||||
/// Taken from http://bisqwit.iki.fi/story/howto/openmp/
|
||||
//==================================================================================================
|
||||
class ScopedLock
|
||||
{
|
||||
public:
|
||||
explicit ScopedLock(MutexType& m) : m_mutex(m), m_locked(true)
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
~ScopedLock()
|
||||
{
|
||||
unlock();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
if(!m_locked) return;
|
||||
m_locked = false;
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
void lockAgain()
|
||||
{
|
||||
if (m_locked) return;
|
||||
m_mutex.lock();
|
||||
m_locked = true;
|
||||
}
|
||||
|
||||
private:
|
||||
MutexType& m_mutex;
|
||||
bool m_locked;
|
||||
|
||||
private: // prevent copying the scoped lock.
|
||||
void operator=(const ScopedLock&);
|
||||
ScopedLock(const ScopedLock&);
|
||||
};
|
||||
|
||||
}
|
||||
209
cafProjectDataModel/cafPdmDocument.cpp
Normal file
209
cafProjectDataModel/cafPdmDocument.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cafPdmDocument.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
CAF_PDM_SOURCE_INIT(PdmObjectGroup, "PdmObjectGroup");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectGroup::PdmObjectGroup()
|
||||
{
|
||||
CAF_PDM_InitObject("Object Group", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&objects, "PdmObjects","", "", "", "")
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectGroup::~PdmObjectGroup()
|
||||
{
|
||||
deleteObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectGroup::deleteObjects()
|
||||
{
|
||||
size_t it;
|
||||
for (it = 0; it != objects.size(); ++it)
|
||||
{
|
||||
delete objects[it];
|
||||
}
|
||||
removeNullPtrs();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectGroup::removeNullPtrs()
|
||||
{
|
||||
objects.removeAll(NULL);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectGroup::addObject(PdmObject * obj)
|
||||
{
|
||||
objects.push_back(obj);
|
||||
}
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(PdmDocument, "PdmDocument");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmDocument::PdmDocument()
|
||||
{
|
||||
CAF_PDM_InitObject("File", "", "", "");
|
||||
CAF_PDM_InitField(&fileName, "DocumentFileName", QString(""), "File Name", "", "", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmDocument::readFile()
|
||||
{
|
||||
QFile xmlFile(fileName);
|
||||
if (!xmlFile.open(QIODevice::ReadOnly ))
|
||||
return;
|
||||
|
||||
readFile(&xmlFile);
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmDocument::readFile(QIODevice* xmlFile)
|
||||
{
|
||||
QXmlStreamReader xmlStream(xmlFile);
|
||||
|
||||
while (!xmlStream.atEnd())
|
||||
{
|
||||
xmlStream.readNext();
|
||||
if (xmlStream.isStartElement())
|
||||
{
|
||||
if (xmlStream.name() != classKeyword())
|
||||
{
|
||||
// Error: This is not a Ceetron Pdm based xml document
|
||||
return;
|
||||
}
|
||||
readFields(xmlStream);
|
||||
}
|
||||
}
|
||||
|
||||
// Ask all objects to initialize and set up internal datastructure and pointers
|
||||
// after everything is read from file
|
||||
|
||||
PdmDocument::initAfterReadTraversal(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmDocument::writeFile()
|
||||
{
|
||||
QFile xmlFile(fileName);
|
||||
if (!xmlFile.open(QIODevice::WriteOnly ))
|
||||
return;
|
||||
|
||||
writeFile(&xmlFile);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmDocument::writeFile(QIODevice* xmlFile)
|
||||
{
|
||||
// Ask all objects to make them ready to write themselves to file
|
||||
PdmDocument::setupBeforeSaveTraversal(this);
|
||||
|
||||
QXmlStreamWriter xmlStream(xmlFile);
|
||||
xmlStream.setAutoFormatting(true);
|
||||
|
||||
xmlStream.writeStartDocument();
|
||||
QString className = classKeyword();
|
||||
|
||||
xmlStream.writeStartElement("", className);
|
||||
writeFields(xmlStream);
|
||||
xmlStream.writeEndElement();
|
||||
|
||||
xmlStream.writeEndDocument();
|
||||
}
|
||||
|
||||
void PdmDocument::initAfterReadTraversal(PdmObject* object)
|
||||
{
|
||||
if (object == NULL) return;
|
||||
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
object->fields(fields);
|
||||
|
||||
std::vector<PdmObject*> children;
|
||||
size_t fIdx;
|
||||
for (fIdx = 0; fIdx < fields.size(); ++fIdx)
|
||||
{
|
||||
if (fields[fIdx]) fields[fIdx]->childObjects(&children);
|
||||
}
|
||||
|
||||
size_t cIdx;
|
||||
for (cIdx = 0; cIdx < children.size(); ++cIdx)
|
||||
{
|
||||
PdmDocument::initAfterReadTraversal(children[cIdx]);
|
||||
if (children[cIdx]) children[cIdx]->initAfterRead();
|
||||
}
|
||||
|
||||
object->initAfterRead();
|
||||
}
|
||||
|
||||
void PdmDocument::setupBeforeSaveTraversal(PdmObject * object)
|
||||
{
|
||||
if (object == NULL) return;
|
||||
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
object->fields(fields);
|
||||
|
||||
std::vector<PdmObject*> children;
|
||||
size_t fIdx;
|
||||
for (fIdx = 0; fIdx < fields.size(); ++fIdx)
|
||||
{
|
||||
if (fields[fIdx]) fields[fIdx]->childObjects(&children);
|
||||
}
|
||||
|
||||
size_t cIdx;
|
||||
for (cIdx = 0; cIdx < children.size(); ++cIdx)
|
||||
{
|
||||
PdmDocument::initAfterReadTraversal(children[cIdx]);
|
||||
if (children[cIdx]) children[cIdx]->setupBeforeSave();
|
||||
}
|
||||
|
||||
object->setupBeforeSave();
|
||||
}
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
89
cafProjectDataModel/cafPdmDocument.h
Normal file
89
cafProjectDataModel/cafPdmDocument.h
Normal file
@@ -0,0 +1,89 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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 "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// The PdmObjectGroup serves as a container of unknown PdmObjects, and is inherited by
|
||||
/// PdmDocument. Can be used to create sub assemblies.
|
||||
/// This class should possibly be merged with PdmDocument. It is not clear whether it really has
|
||||
/// a reusable value on its own.
|
||||
//==================================================================================================
|
||||
class PdmObjectGroup : public PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
PdmObjectGroup();
|
||||
~PdmObjectGroup();
|
||||
|
||||
PdmPointersField<PdmObject*> objects;
|
||||
|
||||
void deleteObjects();
|
||||
void removeNullPtrs();
|
||||
void addObject(PdmObject * obj);
|
||||
|
||||
// Needs renaming to objectsByType
|
||||
template <typename T>
|
||||
void objectsByType(std::vector<PdmPointer<T> >* typedObjects ) const
|
||||
{
|
||||
if (!typedObjects) return;
|
||||
size_t it;
|
||||
for (it = 0; it != objects.size(); ++it)
|
||||
{
|
||||
T* obj = dynamic_cast<T*>(objects[it]);
|
||||
if (obj) typedObjects->push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// The PdmDocument class is the main class to do file based IO,
|
||||
/// and is also supposed to act as the overall container of the objects read.
|
||||
//==================================================================================================
|
||||
class PdmDocument: public PdmObjectGroup
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
PdmDocument();
|
||||
|
||||
PdmField<QString> fileName;
|
||||
|
||||
void readFile();
|
||||
void writeFile();
|
||||
|
||||
void readFile(QIODevice* device);
|
||||
void writeFile(QIODevice* device);
|
||||
|
||||
private:
|
||||
static void initAfterReadTraversal(PdmObject * root);
|
||||
static void setupBeforeSaveTraversal(PdmObject * root);
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
|
||||
138
cafProjectDataModel/cafPdmField.cpp
Normal file
138
cafProjectDataModel/cafPdmField.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cafPdmField.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// PdmFieldHandle implementations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmFieldIOHelper::skipCharactersAndComments(QXmlStreamReader& xmlStream)
|
||||
{
|
||||
QXmlStreamReader::TokenType type;
|
||||
while (!xmlStream.atEnd() && xmlStream.isCharacters() || xmlStream.isComment())
|
||||
{
|
||||
type = xmlStream.readNext();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmFieldIOHelper::skipComments(QXmlStreamReader& xmlStream)
|
||||
{
|
||||
QXmlStreamReader::TokenType type;
|
||||
while (!xmlStream.atEnd() && xmlStream.isComment())
|
||||
{
|
||||
type = xmlStream.readNext();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmFieldHandle::assertValid() const
|
||||
{
|
||||
if (m_keyword == "UNDEFINED")
|
||||
{
|
||||
std::cout << "Detected use of non-initialized field\n";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// PdmObjectFactory implementations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObject * PdmObjectFactory::create(const QString& classNameKeyword)
|
||||
{
|
||||
std::map<QString, PdmObjectCreatorBase*>::iterator entryIt;
|
||||
entryIt = m_factoryMap.find(classNameKeyword);
|
||||
if (entryIt != m_factoryMap.end())
|
||||
{
|
||||
return entryIt->second->create();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectFactory * PdmObjectFactory::instance()
|
||||
{
|
||||
static PdmObjectFactory* fact = new PdmObjectFactory;
|
||||
return fact;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Specialized read function for QStrings, because the >> operator only can read word by word
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<>
|
||||
void PdmFieldReader<QString>::readFieldData(PdmField<QString> & field, QXmlStreamReader& xmlStream)
|
||||
{
|
||||
PdmFieldIOHelper::skipComments(xmlStream);
|
||||
if (!xmlStream.isCharacters()) return;
|
||||
|
||||
field = xmlStream.text().toString();
|
||||
|
||||
// Make stream point to end of element
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
}
|
||||
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Specialized read operation for Bool`s
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void operator >> (QTextStream& str, bool& value)
|
||||
{
|
||||
QString text;
|
||||
str >> text;
|
||||
if (text == "True" || text == "true" || text == "1" || text == "Yes" || text == "yes") value = true;
|
||||
else value = false;
|
||||
}
|
||||
|
||||
void operator << (QTextStream& str, const bool& value)
|
||||
{
|
||||
if (value) str << "True ";
|
||||
else str << "False ";
|
||||
}
|
||||
|
||||
|
||||
228
cafProjectDataModel/cafPdmField.h
Normal file
228
cafProjectDataModel/cafPdmField.h
Normal file
@@ -0,0 +1,228 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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 <assert.h>
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QTextStream>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject;
|
||||
template <class T> class PdmPointer;
|
||||
|
||||
//==================================================================================================
|
||||
/// Base class for all fields, making it possible to handle them generically
|
||||
//==================================================================================================
|
||||
|
||||
class PdmFieldHandle : public PdmUiItem
|
||||
{
|
||||
public:
|
||||
PdmFieldHandle() { m_ownerObject = NULL; m_keyword = "UNDEFINED"; }
|
||||
virtual ~PdmFieldHandle() { }
|
||||
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream) = 0;
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream) = 0;
|
||||
|
||||
void setKeyword(const QString& keyword) { m_keyword = 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 QList<PdmOptionItemInfo>
|
||||
valueOptions( bool* useOptionsOnly) { return QList<PdmOptionItemInfo>(); }
|
||||
|
||||
protected:
|
||||
bool assertValid() const;
|
||||
protected:
|
||||
PdmObject* m_ownerObject;
|
||||
private:
|
||||
QString m_keyword;
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// 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) { assertValid(); m_fieldValue = other.m_fieldValue; }
|
||||
PdmField(const DataType& fieldValue) { 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() { 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 removeAll(DataType* pointer);
|
||||
void deleteChildren();
|
||||
|
||||
// Reimplementation of PdmFieldhandle methods
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream);
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream);
|
||||
|
||||
// Gui generalized methods
|
||||
virtual void childObjects(std::vector<PdmObject*>* objects);
|
||||
private:
|
||||
void removeThisAsParentField();
|
||||
void addThisAsParentField();
|
||||
|
||||
private:
|
||||
std::vector< PdmPointer<DataType> > m_pointers;
|
||||
};
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafPdmField.inl"
|
||||
493
cafProjectDataModel/cafPdmField.inl
Normal file
493
cafProjectDataModel/cafPdmField.inl
Normal file
@@ -0,0 +1,493 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// Implementation of PdmField<T> methods
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
void caf::PdmField<DataType>::setValueFromUi(const QVariant& uiValue)
|
||||
{
|
||||
QVariant oldValue = PdmFieldTypeSpecialization<DataType>::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<unsigned int>(m_optionEntryCache.size()));
|
||||
PdmFieldTypeSpecialization<DataType>::setFromVariant(m_optionEntryCache[uiValue.toUInt()].value, m_fieldValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_optionEntryCache.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PdmFieldTypeSpecialization<DataType>::setFromVariant(uiValue, m_fieldValue);
|
||||
}
|
||||
|
||||
QVariant newValue = PdmFieldTypeSpecialization<DataType>::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<typename DataType >
|
||||
QList<PdmOptionItemInfo> caf::PdmField<DataType>::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<DataType>::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<DataType>::valueOptions(useOptionsOnly, m_fieldValue);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
QVariant caf::PdmField<DataType>::uiValue() const
|
||||
{
|
||||
if (m_optionEntryCache.size())
|
||||
{
|
||||
QVariant convertedFieldValue = PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
|
||||
unsigned int index;
|
||||
bool foundFieldValue = PdmOptionItemInfo::findValue(m_optionEntryCache, convertedFieldValue, &index);
|
||||
assert(foundFieldValue);
|
||||
return QVariant(index);
|
||||
}
|
||||
|
||||
return PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
/// Implementation of PdmField<T*> methods
|
||||
/// (Partial specialization for pointers)
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename DataType >
|
||||
void caf::PdmField<DataType*>::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<typename DataType >
|
||||
void caf::PdmField<DataType*>::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<typename DataType >
|
||||
void caf::PdmField<DataType*>::childObjects(std::vector<PdmObject*>* objects)
|
||||
{
|
||||
assert (objects);
|
||||
PdmObject* obj = m_fieldValue.rawPtr();
|
||||
if (obj)
|
||||
{
|
||||
objects->push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmField<DataType*>::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<typename DataType >
|
||||
caf::PdmField<DataType*>::PdmField(const DataTypePtr& fieldValue)
|
||||
{
|
||||
if (m_fieldValue) m_fieldValue->removeParentField(this);
|
||||
m_fieldValue = fieldValue;
|
||||
if (m_fieldValue != NULL) m_fieldValue->addParentField(this);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmField<DataType*>::~PdmField()
|
||||
{
|
||||
if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeParentField(this);
|
||||
m_fieldValue = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmField<DataType*>& PdmField<DataType*>::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<typename DataType >
|
||||
caf::PdmField<DataType*>& PdmField<DataType*>::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<typename DataType>
|
||||
PdmPointersField<DataType*>::PdmPointersField(const PdmPointersField& other)
|
||||
{
|
||||
this->removeThisAsParentField();
|
||||
m_pointers = other.m_pointers;
|
||||
this->addThisAsParentField();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
PdmPointersField<DataType*>::~PdmPointersField()
|
||||
{
|
||||
this->removeThisAsParentField();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
caf::PdmPointersField<DataType*>& PdmPointersField<DataType*>::operator=(const PdmPointersField& other)
|
||||
{
|
||||
this->removeThisAsParentField();
|
||||
m_pointers = other.m_pointers;
|
||||
this->addThisAsParentField();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
DataType* PdmPointersField<DataType*>::operator[](size_t index) const
|
||||
{
|
||||
return m_pointers[index];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::push_back(DataType* pointer)
|
||||
{
|
||||
m_pointers.push_back(pointer);
|
||||
if (pointer) pointer->addParentField(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::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<typename DataType>
|
||||
void PdmPointersField<DataType*>::insert(size_t indexAfter, DataType* pointer)
|
||||
{
|
||||
m_pointers.insert(m_pointers.begin()+indexAfter, pointer);
|
||||
|
||||
if (pointer) pointer->addParentField(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::clear()
|
||||
{
|
||||
|
||||
this->removeThisAsParentField();
|
||||
m_pointers.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::deleteChildren()
|
||||
{
|
||||
size_t index;
|
||||
for (index = 0; index < m_pointers.size(); ++index)
|
||||
{
|
||||
delete(m_pointers[index]);
|
||||
}
|
||||
|
||||
m_pointers.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::erase(size_t index)
|
||||
{
|
||||
if (m_pointers[index]) m_pointers[index]->removeParentField(this);
|
||||
m_pointers.erase(m_pointers.begin() + index);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::removeAll(DataType* pointer)
|
||||
{
|
||||
size_t index;
|
||||
std::vector< PdmPointer<DataType> > 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<typename DataType>
|
||||
void PdmPointersField<DataType*>::writeFieldData( QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
typename std::vector< PdmPointer<DataType> >::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<typename DataType>
|
||||
void PdmPointersField<DataType*>::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<DataType *> (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<typename DataType>
|
||||
void PdmPointersField<DataType*>::childObjects(std::vector<PdmObject*>* objects)
|
||||
{
|
||||
if (!objects) return;
|
||||
size_t i;
|
||||
for (i = 0; i < m_pointers.size(); ++i)
|
||||
{
|
||||
objects->push_back(m_pointers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::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<typename DataType>
|
||||
void PdmPointersField<DataType*>::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
|
||||
448
cafProjectDataModel/cafPdmFieldImpl.h
Normal file
448
cafProjectDataModel/cafPdmFieldImpl.h
Normal file
@@ -0,0 +1,448 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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 <QVariant>
|
||||
#include <QList>
|
||||
#include <QStringList>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafPdmObjectFactory.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
// Forward declarations
|
||||
template <typename T> class PdmField;
|
||||
template <typename T> class PdmPointer;
|
||||
template <typename T> class AppEnum;
|
||||
|
||||
//==================================================================================================
|
||||
/// A proxy class that implements the Gui interface of fields
|
||||
///
|
||||
/// This class collects methods that need specialization when introducing a new type in a PdmField.
|
||||
/// Having those methods in a separate class makes it possible to "partially specialize" the methods
|
||||
/// for container classes etc. since partial specialization of template functions is not C++ as of yet.
|
||||
///
|
||||
/// When introducing a new type in a PdmField, you might need to implement a (partial)specialization
|
||||
/// of this class.
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmFieldTypeSpecialization
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert(const T& value)
|
||||
{
|
||||
return QVariant(value);
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant(const QVariant& variantValue, T& value)
|
||||
{
|
||||
value = variantValue.value<T>();
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for AppEnum
|
||||
static QList<PdmOptionItemInfo> valueOptions( bool* useOptionsOnly, const T& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects(const PdmField<T>& , std::vector<PdmObject*>* )
|
||||
{ }
|
||||
/*
|
||||
static void writeFieldData(PdmField<T> & field, QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
QString dataString;
|
||||
QTextStream data(&dataString, QIODevice::WriteOnly);
|
||||
data << field.v();
|
||||
xmlStream.writeCharacters(dataString);
|
||||
}
|
||||
|
||||
static void readFieldData(PdmField<DataType> & field, QXmlStreamReader& xmlStream)
|
||||
{
|
||||
PdmFieldHandle::skipComments(xmlStream);
|
||||
if (!xmlStream.isCharacters()) return;
|
||||
|
||||
QString dataString = xmlStream.text().toString();
|
||||
QTextStream data(&dataString, QIODevice::ReadOnly);
|
||||
data >> field.v();
|
||||
|
||||
// Make stream point to end of element
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldHandle::skipCharactersAndComments(xmlStream);
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< std::list<T> >
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmFieldTypeSpecialization < std::list<T> >
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert(const std::list<T>& value)
|
||||
{
|
||||
QList<QVariant> returnList;
|
||||
typename std::list<T>::const_iterator it;
|
||||
for (it = value.begin(); it != value.end() ; ++it)
|
||||
{
|
||||
returnList.push_back(QVariant(*it));
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant(const QVariant& variantValue, std::list<T>& value)
|
||||
{
|
||||
if (variantValue.canConvert< QList<QVariant> >())
|
||||
{
|
||||
value.clear();
|
||||
QList<QVariant> lst = variantValue.toList();
|
||||
int i;
|
||||
for (i = 0; i < lst.size(); ++i)
|
||||
{
|
||||
value.push_back(lst[i].value<T>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for AppEnum
|
||||
static QList<PdmOptionItemInfo> valueOptions( bool* useOptionsOnly, const std::list<T>& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects(const PdmField< std::list<T> >& , std::vector<PdmObject*>* )
|
||||
{ }
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< std::list< PdmPointer<T> > >
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmFieldTypeSpecialization < std::list<PdmPointer<T> > >
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert(const std::list<PdmPointer<T> >& )
|
||||
{
|
||||
return QVariant(); // Do nothing. The members are "children"
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
// Overloaded to do nothing because this is supposed to be handled as children
|
||||
static void setFromVariant(const QVariant& , std::list<PdmPointer<T> >& )
|
||||
{ }
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for AppEnum
|
||||
static QList<PdmOptionItemInfo> valueOptions( bool* useOptionsOnly, const std::list<PdmPointer<T> >& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects(const PdmField<std::list<PdmPointer<T> > >& field, std::vector<PdmObject*>* objects)
|
||||
{
|
||||
if (!objects) return;
|
||||
|
||||
typename std::list<PdmPointer<T> >::const_iterator it;
|
||||
for (it = field.v().begin() ; it != field.v().end(); ++it)
|
||||
{
|
||||
objects->push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< std::vector<T> >
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmFieldTypeSpecialization < std::vector<T> >
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert(const std::vector<T>& value)
|
||||
{
|
||||
QList<QVariant> returnList;
|
||||
typename std::vector<T>::const_iterator it;
|
||||
for (it = value.begin(); it != value.end() ; ++it)
|
||||
{
|
||||
returnList.push_back(QVariant(*it));
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant(const QVariant& variantValue, std::vector<T>& value)
|
||||
{
|
||||
if (variantValue.canConvert< QList<QVariant> >())
|
||||
{
|
||||
value.clear();
|
||||
QList<QVariant> lst = variantValue.toList();
|
||||
int i;
|
||||
for (i = 0; i < lst.size(); ++i)
|
||||
{
|
||||
value.push_back(lst[i].value<T>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for AppEnum
|
||||
static QList<PdmOptionItemInfo> valueOptions( bool* useOptionsOnly, const std::vector<T>& )
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects(const PdmField< std::vector<T> > & field, std::vector<PdmObject*>* objects)
|
||||
{ }
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< caf::AppEnum<T> >
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmFieldTypeSpecialization < caf::AppEnum<T> >
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert(const caf::AppEnum<T>& value)
|
||||
{
|
||||
return QVariant(static_cast<unsigned int>(caf::AppEnum<T>::index(value)));
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant(const QVariant& variantValue, caf::AppEnum<T>& value)
|
||||
{
|
||||
value.setFromIndex(variantValue.toInt());
|
||||
}
|
||||
|
||||
/// Methods to get a list of options for a field, specialized for AppEnum
|
||||
static QList<PdmOptionItemInfo> valueOptions( bool* useOptionsOnly, const caf::AppEnum<T>& )
|
||||
{
|
||||
if (useOptionsOnly) *useOptionsOnly = true;
|
||||
|
||||
QStringList optionTexts = caf::AppEnum<T>::uiTexts();
|
||||
QList<PdmOptionItemInfo> optionList;
|
||||
int i;
|
||||
for (i = 0; i < optionTexts.size(); ++i)
|
||||
{
|
||||
optionList.push_back(PdmOptionItemInfo(optionTexts[i]));
|
||||
}
|
||||
|
||||
return optionList;
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects(const PdmField< caf::AppEnum<T> >& field, std::vector<PdmObject*>* objects)
|
||||
{ }
|
||||
|
||||
};
|
||||
|
||||
class PdmFieldIOHelper
|
||||
{
|
||||
public:
|
||||
// Utility functions for reading from QXmlStreamReader
|
||||
static void skipCharactersAndComments(QXmlStreamReader& xmlStream);
|
||||
static void skipComments(QXmlStreamReader& xmlStream);
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Generic write method for fields. Will work as long as DataType supports the stream operator
|
||||
/// towards a QTextStream. Some special datatype should not specialize this method unless it is
|
||||
/// impossible/awkward to implement the stream operator
|
||||
/// Implemented in a proxy class to allow partial specialization
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct PdmFieldWriter
|
||||
{
|
||||
static void writeFieldData(PdmField<T> & field, QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
QString dataString;
|
||||
QTextStream data(&dataString, QIODevice::WriteOnly);
|
||||
data << field.v();
|
||||
xmlStream.writeCharacters(dataString);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct PdmFieldReader
|
||||
{
|
||||
static void readFieldData(PdmField<T> & field, QXmlStreamReader& xmlStream);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Generic read method for fields. Will work as long as DataType supports the stream operator
|
||||
/// towards a QTextStream. Some special datatype should not specialize this method unless it is
|
||||
/// impossible/awkward to implement the stream operator
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
void PdmFieldReader<DataType>::readFieldData(PdmField<DataType> & field, QXmlStreamReader& xmlStream)
|
||||
{
|
||||
PdmFieldIOHelper::skipComments(xmlStream);
|
||||
if (!xmlStream.isCharacters()) return;
|
||||
|
||||
QString dataString = xmlStream.text().toString();
|
||||
QTextStream data(&dataString, QIODevice::ReadOnly);
|
||||
data >> field.v();
|
||||
|
||||
// Make stream point to end of element
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Specialized read function for QStrings, because the >> operator only can read word by word
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<>
|
||||
void PdmFieldReader<QString>::readFieldData(PdmField<QString> & field, QXmlStreamReader& xmlStream);
|
||||
|
||||
//==================================================================================================
|
||||
/// Read and write method specializations for containers of pointers
|
||||
/// std::list is the main one
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
struct PdmFieldWriter<std::list< PdmPointer<T> > >
|
||||
{
|
||||
static void writeFieldData(PdmField<std::list< PdmPointer<T> > > & field, QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
typename std::list< PdmPointer<T> >::iterator it;
|
||||
for (it = field.v().begin(); it != field.v().end(); ++it)
|
||||
{
|
||||
if (*it == NULL) continue;
|
||||
|
||||
QString className = (*it)->classKeyword();
|
||||
|
||||
xmlStream.writeStartElement("", className);
|
||||
(*it)->writeFields(xmlStream);
|
||||
xmlStream.writeEndElement();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
struct PdmFieldReader<std::list< PdmPointer<T> > >
|
||||
{
|
||||
static void readFieldData(PdmField<std::list< PdmPointer<T> > > & field, QXmlStreamReader& xmlStream)
|
||||
{
|
||||
T * 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<T *> (obj);
|
||||
|
||||
if (currentObject == NULL)
|
||||
{
|
||||
// Warning: Inconsistency in factory !! Assert ?
|
||||
// Skip to corresponding end element
|
||||
xmlStream.skipCurrentElement();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
continue;
|
||||
}
|
||||
|
||||
currentObject->readFields(xmlStream);
|
||||
field.v().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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// QTextStream Stream operator overloading for std::vector of things.
|
||||
/// Makes automated IO of PdmField< std::vector< Whatever > possible as long as
|
||||
/// the type will print as one single word
|
||||
//==================================================================================================
|
||||
|
||||
template < typename T >
|
||||
void operator << (QTextStream& str, const std::vector<T>& sobj)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sobj.size(); ++i)
|
||||
{
|
||||
str << sobj[i] << " ";
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void operator >> (QTextStream& str, std::vector<T>& sobj)
|
||||
{
|
||||
while (str.status() == QTextStream::Ok )
|
||||
{
|
||||
T d;
|
||||
str >> d;
|
||||
if (str.status() == QTextStream::Ok ) sobj.push_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
/// QTextStream Stream operator overloading for bool`s
|
||||
/// Prints bool`s as "True"/"False", and reads them too
|
||||
//==================================================================================================
|
||||
|
||||
void operator >> (QTextStream& str, bool& value);
|
||||
void operator << (QTextStream& str, const bool& value);
|
||||
|
||||
211
cafProjectDataModel/cafPdmObject.cpp
Normal file
211
cafProjectDataModel/cafPdmObject.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Reads all the fields into this PdmObject
|
||||
/// Assumes xmlStream points to the start element token of the containing object.
|
||||
/// ( and not first token of object content)
|
||||
/// This makes attribute based field storage possible.
|
||||
/// Leaves the xmlStream pointing to the EndElement corresponding to the start element.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::readFields (QXmlStreamReader& xmlStream )
|
||||
{
|
||||
if (!xmlStream.isStartElement())
|
||||
{
|
||||
// Error
|
||||
return ;
|
||||
}
|
||||
/*
|
||||
Attributes will not be used ...
|
||||
|
||||
QXmlStreamAttributes attribs = xmlStream.attributes();
|
||||
int i;
|
||||
for (i = 0; i < attribs.size(); ++i)
|
||||
{
|
||||
QString name = attribs[i].name().toString();
|
||||
|
||||
PdmFieldBase* field = findField(name);
|
||||
|
||||
if (field)
|
||||
{
|
||||
//field->readFieldData(attribs[i].value().toString());
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
bool isObjectFinished = false;
|
||||
QXmlStreamReader::TokenType type;
|
||||
while(!isObjectFinished)
|
||||
{
|
||||
type = xmlStream.readNext();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case QXmlStreamReader::StartElement:
|
||||
{
|
||||
QString name = xmlStream.name().toString();
|
||||
PdmFieldHandle* currentField = findField(name);
|
||||
if (currentField)
|
||||
{
|
||||
// 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")
|
||||
QXmlStreamReader::TokenType tt;
|
||||
tt = xmlStream.readNext();
|
||||
currentField->readFieldData( xmlStream );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Warning: Could not find a field with name " << name.toLatin1().data() << " in the current object : " << classKeyword().toLatin1().data() << std::endl;
|
||||
xmlStream.skipCurrentElement();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case QXmlStreamReader::EndElement:
|
||||
{
|
||||
// End of object.
|
||||
isObjectFinished = true;
|
||||
}
|
||||
break;
|
||||
case QXmlStreamReader::EndDocument:
|
||||
{
|
||||
// End of object.
|
||||
isObjectFinished = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// Just read on
|
||||
// Todo: Error handling
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::writeFields(QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
std::vector<PdmFieldHandle*>::iterator it;
|
||||
for (it = m_fields.begin(); it != m_fields.end(); ++it)
|
||||
{
|
||||
PdmFieldHandle* obj = *it;
|
||||
QString keyword = obj->keyword();
|
||||
xmlStream.writeStartElement("", keyword);
|
||||
obj->writeFieldData(xmlStream);
|
||||
xmlStream.writeEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmFieldHandle* PdmObject::findField(const QString& keyword)
|
||||
{
|
||||
std::vector<PdmFieldHandle*>::iterator it;
|
||||
for (it = m_fields.begin(); it != m_fields.end(); it++)
|
||||
{
|
||||
PdmFieldHandle* obj = *it;
|
||||
if (obj->keyword() == keyword)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObject::~PdmObject()
|
||||
{
|
||||
// Set all guarded pointers pointing to this to NULL
|
||||
|
||||
std::set<PdmObject**>::iterator it;
|
||||
for (it = m_pointersReferencingMe.begin(); it != m_pointersReferencingMe.end() ; ++it)
|
||||
{
|
||||
(**it) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::fields(std::vector<PdmFieldHandle*>& fields) const
|
||||
{
|
||||
fields = m_fields;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::addParentField(PdmFieldHandle* parentField)
|
||||
{
|
||||
if (parentField != NULL) m_parentFields.insert(parentField);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::removeParentField(PdmFieldHandle* parentField)
|
||||
{
|
||||
if (parentField != NULL) m_parentFields.erase(parentField);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Appends pointers to all the PdmFields/PdmPointerFields containing a pointer to this object.
|
||||
/// As the PdmPointersField can hold several pointers to the same object, the returned vector can
|
||||
/// contain multiple pointers to the same field.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::parentFields(std::vector<PdmFieldHandle*>& parentFields) const
|
||||
{
|
||||
std::multiset<PdmFieldHandle*>::const_iterator it;
|
||||
|
||||
for (it = m_parentFields.begin(); it != m_parentFields.end(); ++it)
|
||||
{
|
||||
parentFields.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void PdmObject::addFieldNoDefault(PdmFieldHandle* field, const QString& keyword, PdmUiItemInfo * fieldDescription)
|
||||
{
|
||||
field->setUiItemInfo(fieldDescription);
|
||||
field->setKeyword(keyword);
|
||||
field->setOwnerObject(this);
|
||||
|
||||
assert(findField(keyword) == NULL);
|
||||
m_fields.push_back(field);
|
||||
}
|
||||
|
||||
} //End of namespace caf
|
||||
169
cafProjectDataModel/cafPdmObject.h
Normal file
169
cafProjectDataModel/cafPdmObject.h
Normal file
@@ -0,0 +1,169 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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 "cafPdmPointer.h"
|
||||
|
||||
#include <set>
|
||||
#include <assert.h>
|
||||
|
||||
class QXmlStreamReader;
|
||||
class QXmlStreamWriter;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmFieldHandle;
|
||||
template < class FieldDataType > class PdmField;
|
||||
|
||||
//==================================================================================================
|
||||
/// Macros helping in development of PDM objects
|
||||
//==================================================================================================
|
||||
|
||||
/// CAF_PDM_HEADER_INIT assists the factory used when reading objects from file
|
||||
/// Place this in the header file inside the class definition of your PdmObject
|
||||
|
||||
#define CAF_PDM_HEADER_INIT \
|
||||
public: \
|
||||
virtual QString classKeyword() { return classKeywordStatic(); } \
|
||||
static QString classKeywordStatic()
|
||||
|
||||
/// CAF_PDM_SOURCE_INIT associates the file keyword used for storage with the class and initializes the factory
|
||||
/// Place this in the cpp file, preferably above the constructor
|
||||
|
||||
#define CAF_PDM_SOURCE_INIT(ClassName, keyword) \
|
||||
QString ClassName::classKeywordStatic() { return keyword; } \
|
||||
bool ClassName##_initialized = caf::PdmObjectFactory::instance()->registerCreator<ClassName>()
|
||||
|
||||
/// InitObject sets up the user interface related information for the object
|
||||
/// Placed in the constructor of your PdmObject
|
||||
|
||||
#define CAF_PDM_InitObject(uiName, iconResourceName, toolTip, whatsThis) \
|
||||
{ \
|
||||
static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \
|
||||
setUiItemInfo(&objDescr); \
|
||||
}
|
||||
|
||||
/// InitField sets the file keyword for the field,
|
||||
/// adds the field to the internal data structure in the PdmObject,
|
||||
/// sets the default value for the field,
|
||||
/// and sets up the static user interface related information for the field
|
||||
|
||||
#define CAF_PDM_InitField(field, keyword, default, uiName, iconResourceName, toolTip, whatsThis) \
|
||||
{ \
|
||||
static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \
|
||||
addField(field, keyword, default, &objDescr); \
|
||||
}
|
||||
|
||||
/// InitFieldNoDefault does the same as InitField but omits the default value.
|
||||
|
||||
#define CAF_PDM_InitFieldNoDefault(field, keyword, uiName, iconResourceName, toolTip, whatsThis) \
|
||||
{ \
|
||||
static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \
|
||||
addFieldNoDefault(field, keyword, &objDescr); \
|
||||
}
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// The base class of all objects that will use the features of the field based IO
|
||||
/// Inherit this class to make your Pdm-based data structure
|
||||
//==================================================================================================
|
||||
|
||||
class PdmObject : public PdmUiItem
|
||||
{
|
||||
public:
|
||||
PdmObject() { }
|
||||
virtual ~PdmObject();
|
||||
|
||||
void readFields (QXmlStreamReader& inputStream );
|
||||
void writeFields(QXmlStreamWriter& outputStream);
|
||||
|
||||
/// The registered fields contained in this PdmObject. Registered by subclasses.
|
||||
void fields(std::vector<PdmFieldHandle*>& fields) const;
|
||||
/// The fields containing pointers to this PdmObject. Use ownerObject() on the fieldHandle to get the PdmObject parent.
|
||||
void parentFields(std::vector<PdmFieldHandle*>& fields) const;
|
||||
|
||||
/// The classKeyword method is overridden in subclasses by the CAF_PDM_HEADER_INIT macro
|
||||
virtual QString classKeyword() = 0;
|
||||
|
||||
// Virtual interface to override in subclasses to support special behaviour if needed
|
||||
public: // Virtual
|
||||
virtual PdmFieldHandle* userDescriptionField() { return NULL; }
|
||||
/// Method to reimplement to catch when the field has changed due to setUiValue()
|
||||
virtual void fieldChangedByUi(const PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) {}
|
||||
/// Method to re-implement to supply option values for a specific field
|
||||
virtual QList<PdmOptionItemInfo>
|
||||
calculateValueOptions(const PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) { return QList<PdmOptionItemInfo>(); }
|
||||
|
||||
protected: // Virtual
|
||||
/// Method gets called from PdmDocument after all objects are read.
|
||||
/// Re-implement to set up internal pointers etc. in your data structure
|
||||
virtual void initAfterRead() {};
|
||||
/// Method gets called from PdmDocument before saving document.
|
||||
/// Re-implement to make sure your fields have correct data before saving
|
||||
virtual void setupBeforeSave() {};
|
||||
public:
|
||||
/// operator= implemented to avoid copying the internal m_fields
|
||||
PdmObject& operator=(const PdmObject& ) { return *this; }
|
||||
|
||||
protected:
|
||||
/// Adds field to the internal data structure and sets the file keyword and Ui information
|
||||
/// Consider this method private. Please use the CAF_PDM_InitField() macro instead
|
||||
template< typename FieldDataType >
|
||||
void addField(PdmField<FieldDataType>* field, const QString& keyword, const FieldDataType& defaultValue, PdmUiItemInfo * fieldDescription)
|
||||
{
|
||||
addFieldNoDefault(field, keyword, fieldDescription);
|
||||
field->setDefaultValue(defaultValue);
|
||||
*field = defaultValue;
|
||||
}
|
||||
|
||||
/// Does the same as the above method, but omits the default value.
|
||||
/// Consider this method private. Please use the CAF_PDM_InitFieldNoDefault() macro instead.
|
||||
void addFieldNoDefault(PdmFieldHandle* field, const QString& keyword, PdmUiItemInfo * fieldDescription);
|
||||
|
||||
private:
|
||||
// Copy and assignment operators are implemented to avoid copying the internal management data structures.
|
||||
|
||||
// If you use copy constructor in your application code, the compiler reports
|
||||
// "error C2248: 'caf::PdmObjectBase::PdmObjectBase' : cannot access private member declared in ..."
|
||||
// To fix this issue, implement a public copy constructor in your derived class.
|
||||
PdmObject(const PdmObject& ): PdmUiItem() { }
|
||||
PdmFieldHandle* findField(const QString& keyword);
|
||||
|
||||
template < class T > friend class PdmField;
|
||||
template < class T > friend class PdmPointersField;
|
||||
|
||||
friend class PdmDocument;
|
||||
friend class PdmObjectGroup;
|
||||
|
||||
void addParentField(PdmFieldHandle* parentField);
|
||||
void removeParentField(PdmFieldHandle* parentField);
|
||||
|
||||
private:
|
||||
std::multiset<PdmFieldHandle*> m_parentFields;
|
||||
std::vector<PdmFieldHandle*> m_fields;
|
||||
|
||||
// Support system for PdmPointer
|
||||
friend class PdmPointerImpl;
|
||||
std::set<PdmObject**> m_pointersReferencingMe;
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
88
cafProjectDataModel/cafPdmObjectFactory.h
Normal file
88
cafProjectDataModel/cafPdmObjectFactory.h
Normal file
@@ -0,0 +1,88 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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 <assert.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject;
|
||||
|
||||
//==================================================================================================
|
||||
/// "Private" class for implementation of a factory for PdmObjectBase derived objects
|
||||
/// Every PdmObject must register with this factory to be readable
|
||||
/// This class can be considered private in the Pdm system
|
||||
//==================================================================================================
|
||||
|
||||
class PdmObjectFactory
|
||||
{
|
||||
public:
|
||||
static PdmObjectFactory * instance();
|
||||
PdmObject * create(const QString& classNameKeyword);
|
||||
|
||||
template< typename PdmObjectBaseDerivative >
|
||||
bool registerCreator()
|
||||
{
|
||||
std::map<QString, PdmObjectCreatorBase*>::iterator entryIt;
|
||||
|
||||
QString classNameKeyword = PdmObjectBaseDerivative::classKeywordStatic();
|
||||
|
||||
entryIt = m_factoryMap.find(classNameKeyword);
|
||||
if (entryIt == m_factoryMap.end())
|
||||
{
|
||||
m_factoryMap[classNameKeyword] = new PdmObjectCreator<PdmObjectBaseDerivative>();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(classNameKeyword != entryIt->first); // classNameKeyword has already been used
|
||||
assert(false); // To be sure ..
|
||||
return false; // never hit;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PdmObjectFactory() {}
|
||||
~PdmObjectFactory() { /* Could clean up, but ... */ }
|
||||
|
||||
// Internal helper classes
|
||||
|
||||
class PdmObjectCreatorBase
|
||||
{
|
||||
public:
|
||||
PdmObjectCreatorBase() {}
|
||||
virtual ~PdmObjectCreatorBase() {}
|
||||
virtual PdmObject * create() = 0;
|
||||
};
|
||||
|
||||
template< typename PdmObjectBaseDerivative >
|
||||
class PdmObjectCreator : public PdmObjectCreatorBase
|
||||
{
|
||||
public:
|
||||
virtual PdmObject * create() { return new PdmObjectBaseDerivative(); }
|
||||
};
|
||||
|
||||
// Map to store factory
|
||||
std::map<QString, PdmObjectCreatorBase*> m_factoryMap;
|
||||
};
|
||||
|
||||
|
||||
} //End of namespace caf
|
||||
42
cafProjectDataModel/cafPdmPointer.cpp
Normal file
42
cafProjectDataModel/cafPdmPointer.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//##################################################################################################
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmPointerImpl::addReference(PdmObject ** addressToObjectPointer)
|
||||
{
|
||||
if (*addressToObjectPointer) (*addressToObjectPointer)->m_pointersReferencingMe.insert(addressToObjectPointer);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmPointerImpl::removeReference(PdmObject ** addressToObjectPointer)
|
||||
{
|
||||
if (*addressToObjectPointer) (*addressToObjectPointer)->m_pointersReferencingMe.erase(addressToObjectPointer);
|
||||
}
|
||||
|
||||
} // End of namespace caf
|
||||
81
cafProjectDataModel/cafPdmPointer.h
Normal file
81
cafProjectDataModel/cafPdmPointer.h
Normal file
@@ -0,0 +1,81 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject;
|
||||
|
||||
//==================================================================================================
|
||||
/// Helper class for the PdmPointer class
|
||||
/// The add and removing of references is put into a pure static class to
|
||||
/// resolve circular include problems.
|
||||
//
|
||||
/// Overall idea of the referencing system:
|
||||
/// The addressToObjectPointer is added to a std::set in the object pointed to.
|
||||
/// when the object pointed to is deleted, its destructor sets the object pointers
|
||||
/// it has addresses to to NULL
|
||||
//==================================================================================================
|
||||
|
||||
class PdmPointerImpl
|
||||
{
|
||||
private:
|
||||
template < class T > friend class PdmPointer;
|
||||
static void addReference(PdmObject ** addressToObjectPointer);
|
||||
static void removeReference(PdmObject ** addressToObjectPointer);
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Guarded pointer class to point at PdmObjects
|
||||
/// Use a PdmPointer<SomePdmObject> in the same way as a normal pointer.
|
||||
/// The guarding sets the pointer to NULL if the object pointed to dies
|
||||
///
|
||||
/// NOTE: This is not reference counting. The user is responsible to delete the objects pointed to.
|
||||
/// It _can_ be used together with the cvf::ref system if neccesary (this is no recomendation)
|
||||
//==================================================================================================
|
||||
|
||||
template < class T >
|
||||
class PdmPointer
|
||||
{
|
||||
PdmObject* m_object;
|
||||
public :
|
||||
inline PdmPointer () : m_object(NULL) { }
|
||||
inline PdmPointer ( T * p ) : m_object(p) { PdmPointerImpl::addReference(&m_object); }
|
||||
inline PdmPointer ( const PdmPointer<T> & p ) : m_object ( p.m_object )
|
||||
{ PdmPointerImpl::addReference(&m_object); }
|
||||
inline ~PdmPointer () { PdmPointerImpl::removeReference(&m_object); }
|
||||
|
||||
T* p() const { return static_cast<T*>(const_cast<PdmObject*>(m_object)); }
|
||||
bool isNull() const { return !m_object; }
|
||||
bool notNull() const { return !isNull(); }
|
||||
operator T* () const { return static_cast<T*>(const_cast<PdmObject*>(m_object)); }
|
||||
T& operator* () const { return *static_cast<T*>(const_cast<PdmObject*>(m_object)); }
|
||||
T* operator->() const { return static_cast<T*>(const_cast<PdmObject*>(m_object)); }
|
||||
PdmPointer<T> & operator= ( const PdmPointer<T>& p ) { if (this != &p) PdmPointerImpl::removeReference(&m_object); m_object = p.m_object; PdmPointerImpl::addReference(&m_object); return *this; }
|
||||
PdmPointer<T> & operator= ( T* p ) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); return *this; }
|
||||
|
||||
// Private methods used by PdmField<T*> and PdmPointersField<T*>. Do not use unless you mean it !
|
||||
PdmObject* rawPtr() const { return m_object; }
|
||||
void setRawPtr( PdmObject* p) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); }
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
656
cafProjectDataModel/cafPdmUIBindingNotes.h
Normal file
656
cafProjectDataModel/cafPdmUIBindingNotes.h
Normal file
@@ -0,0 +1,656 @@
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
|
||||
|
||||
class PdmFieldHandle
|
||||
{
|
||||
// ....
|
||||
|
||||
void removeFieldView(PdmUiFieldViewHandle* fieldView) { m_fieldViews.erase(fieldView); }
|
||||
void addFieldView(PdmUiFieldViewHandle* fieldView) { m_fieldViews.insert(fieldView); }
|
||||
private:
|
||||
std::set<PdmUiFieldViewHandle*> m_fieldViews;
|
||||
// ....
|
||||
void setValueFromUI(...)
|
||||
{
|
||||
//...
|
||||
std::set<PdmUiFieldViewHandle*>::iterator it;
|
||||
for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it)
|
||||
{
|
||||
m_fieldViews[i]->updateUiValue();
|
||||
}
|
||||
|
||||
//...
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class PdmUiItemInfo
|
||||
{
|
||||
// ....
|
||||
QString m_editorType; // Int, type_info, className or ??
|
||||
int m_isHidden;
|
||||
int m_isReadOnly;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class PdmUiItem
|
||||
{
|
||||
// ...
|
||||
|
||||
QString editorType(const QString& uiConfigName);
|
||||
void setEditorType(const QString& uiConfigName, const QString& editorKeyword);
|
||||
|
||||
bool isHidden(QString uiConfigName);
|
||||
void setHidden(QString uiConfigName, bool isHidden);
|
||||
|
||||
bool readOnly(QString uiConfigName);
|
||||
void setReadOnly(QString uiConfigName, bool isReadOnly);
|
||||
|
||||
virtual bool isGroup() { return false; }
|
||||
|
||||
private :
|
||||
/// Map containing the UiItemInfo's for the different UiConfigurations
|
||||
/// Each UiItemInfo member is undefined until set. If the member is undefined, we use the default
|
||||
/// settings for that parameter.
|
||||
std::map< QString, PdmUiItemInfo > m_uiConfigurations; // Empty config name is replacing m_dynamicItemInfo
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class PdmUiConfiguration
|
||||
{
|
||||
public:
|
||||
PdmUiConfiguration(): m_forgetRemainingFields(false) { };
|
||||
virtual ~PdmUiConfiguration()
|
||||
{
|
||||
for (size_t i = 0; i < m_createdGroups.size(); ++i)
|
||||
{
|
||||
delete m_createdGroups[i];
|
||||
m_createdGroups[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PdmUiGroup* addNewGroup(QString displayName)
|
||||
{
|
||||
PdmUiGroup* group = new PdmUiGroup;
|
||||
group->setUiName(displayName);
|
||||
|
||||
m_createdGroups.push_back(group);
|
||||
m_config.push_back(group);
|
||||
}
|
||||
|
||||
void add(PdmUiItem* item) { m_config.push_back(item); }
|
||||
bool forgetRemainingFields() const { return m_forgetRemainingFields; }
|
||||
void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; }
|
||||
|
||||
const std::vector<PdmUiItem*>& uiItems() const { return m_config; }
|
||||
|
||||
private:
|
||||
// Private copy constructor and assignment to prevent this. (The vectors below will make trouble)
|
||||
PdmUiConfiguration(const PdmUiConfiguration& other) { }
|
||||
PdmUiConfiguration& operator= (const PdmUiConfiguration& other) { }
|
||||
|
||||
std::vector<PdmUiItem*> m_config;
|
||||
std::vector<PdmUiGroup*> m_createdGroups; /// Owned PdmUiGroups, for mem management
|
||||
bool m_forgetRemainingFields;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class PdmUiGroup : public PdmUiItem, PdmUiConfiguration
|
||||
{
|
||||
virtual bool isGroup() { return true; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class PdmObject : public PdmUiItem
|
||||
{
|
||||
public:
|
||||
|
||||
/// For a specific field, return editor specific parameters used to customize the editor behavior..
|
||||
virtual void setUpUiAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiAttributeHandle * attributes);
|
||||
// For later // virtual void uiAttributeChangedByUI(const PdmFieldHandle* field, QString uiConfigName, const PdmUiAttributeHandle * attributes);
|
||||
|
||||
// Method to be called from the Ui classes creating Auto Gui to get the group information
|
||||
// supplied by the \sa setUpUIConfiguration method that can be reimplemented
|
||||
|
||||
void uiConfiguration(QString uiConfigName, PdmUiConfiguration& uiConfig)
|
||||
{
|
||||
this->setUpUIConfiguration(uiConfigName, uiConfig);
|
||||
if (!uiConfig.forgetRemainingFields())
|
||||
{
|
||||
// Todo: add Remaining Fields To UiConfig
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Fill up the UiConfig object with groups and field references to create the gui structure
|
||||
/// If the uiConfig is empty, it is interpreted as meaning all fields w/o grouping.
|
||||
|
||||
virtual void setUpUIConfiguration(QString uiConfigName, PdmUiConfiguration& uiConfig) ;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class PdmPropertyWindow : public QWidget
|
||||
{
|
||||
public:
|
||||
PdmPropertyWindow()
|
||||
{
|
||||
setLayout(new QHBoxLayout());
|
||||
}
|
||||
|
||||
~PdmPropertyWindow()
|
||||
{
|
||||
if (m_currentObjectView) delete m_currentObjectView;
|
||||
}
|
||||
|
||||
void setUiConfigurationName(QString uiConfigName)
|
||||
{
|
||||
// Reset everything, and possibly create widgets etc afresh
|
||||
if (m_uiConfigName != uiConfigName)
|
||||
{
|
||||
m_uiConfigName = uiConfigName;
|
||||
|
||||
if (m_currentObjectView)
|
||||
{
|
||||
PdmObject* object = m_currentObjectView->pdmObject();
|
||||
delete m_currentObjectView;
|
||||
m_currentObjectView = NULL;
|
||||
this->showProperties(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void showProperties(const PdmObject* object)
|
||||
{
|
||||
// Find specialized object view handle
|
||||
|
||||
// If the current ObjectView has the same type as the one to view, reuse, with Widget etc.
|
||||
|
||||
if (!(m_currentObjectView && m_currentObjectView->m_pdmObject->editorType(m_uiConfigName) == object->editorType(m_uiConfigName)))
|
||||
{
|
||||
// Remove Widget from layout
|
||||
layout()->removeWidget(m_currentObjectView->widget());
|
||||
delete m_currentObjectView;
|
||||
|
||||
m_currentObjectView = PdmObjViewFactory::instance()->create(object->editorType(m_uiConfigName));
|
||||
if (!m_currentObjectView)
|
||||
{
|
||||
m_currentObjectView = new PdmStdObjView();
|
||||
}
|
||||
|
||||
// Create widget to handle this
|
||||
QWidget * page = NULL;
|
||||
page = m_currentObjectView->getOrCreateWidget(this);
|
||||
|
||||
CVF_ASSERT(page);
|
||||
|
||||
this->layout()->addWidget(page);
|
||||
}
|
||||
|
||||
m_currentObjectView->setPdmObject(object);
|
||||
m_currentObjectView->updateUi(m_uiConfigName);
|
||||
}
|
||||
|
||||
private:
|
||||
PdmObjectViewHandle* m_currentObjectView;
|
||||
QString m_uiConfigName;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class PdmObjectViewHandle: public QObject
|
||||
{
|
||||
public:
|
||||
PdmObjectViewHandle() : m_pdmObject(NULL) {}
|
||||
~PdmObjectViewHandle() {}
|
||||
///
|
||||
QWidget* getOrCreateWidget(QWidget* parent)
|
||||
{
|
||||
if (m_widget.isNull())
|
||||
{
|
||||
m_widget = this->createWidget(parent);
|
||||
}
|
||||
return m_widget;
|
||||
}
|
||||
QWidget* widget() { return m_widget; }
|
||||
|
||||
/// Virtual method to be overridden. Needs to set up the supplied widget
|
||||
/// with all signals etc to make it communicate with this object
|
||||
void setPdmObject(PdmObject* object, QString uiConfigName) { m_pdmObject = object; }
|
||||
PdmObject* pdmObject() { return m_pdmObject; }
|
||||
|
||||
virtual void updateUi(QString uiConfigName) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual QWidget* createWidget(QWidget* parent) = 0;
|
||||
|
||||
private:
|
||||
PdmObject* m_pdmObject;
|
||||
QPointer<QWidget> m_widget;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class PdmUiFieldViewHandle : public QObject
|
||||
{
|
||||
public:
|
||||
PdmUiFieldViewHandle() : m_field(NULL) {}
|
||||
~PdmUiFieldViewHandle()
|
||||
{
|
||||
if (m_field) m_field->removeFieldView(this);
|
||||
|
||||
if (!m_combinedWidget.isNull()) delete m_combinedWidget;
|
||||
if (!m_editorWidget.isNull()) delete m_editorWidget ;
|
||||
if (!m_labelWidget.isNull()) delete m_labelWidget;
|
||||
}
|
||||
|
||||
///
|
||||
PdmFieldHandle* field() { return m_field; }
|
||||
void setField(PdmFieldHandle * field)
|
||||
{
|
||||
if (m_field) m_field->removeFieldView(this);
|
||||
m_field = field;
|
||||
if (m_field) m_field->addFieldView(this);
|
||||
}
|
||||
|
||||
|
||||
void setValueToField(const QVariant& value)
|
||||
{
|
||||
if (m_field) m_field->setUiValue(value);
|
||||
}
|
||||
|
||||
void createWidgets(QWidget * parent)
|
||||
{
|
||||
if (m_combinedWidget.isNull()) m_combinedWidget = createCombinedWidget(parent);
|
||||
if (m_editorWidget.isNull()) m_editorWidget = createEditorWidget(parent);
|
||||
if (m_labelWidget.isNull()) m_labelWidget = createLabelWidget(parent);
|
||||
}
|
||||
|
||||
QWidget* combinedWidget() { return m_combinedWidget; }
|
||||
QWidget* editorWidget() { return m_editorWidget; }
|
||||
QWidget* labelWidget() { return m_labelWidget; }
|
||||
|
||||
public: // Virtual interface to override
|
||||
/// Update only the display of the data value, because some other view has changed it.
|
||||
virtual void updateUiValue() = 0;
|
||||
|
||||
/// Supposed to update all parts of the widgets, both visibility, sensitivity, decorations and field data
|
||||
virtual void updateUi(QString uiConfigName) = 0;
|
||||
|
||||
/// Supposed to do all wiring of singals and slots
|
||||
virtual void connectUi() = 0;
|
||||
|
||||
protected: // Virtual interface to override
|
||||
/// Implement one of these, or both editor and label. The widgets will be used in the parent layout according to
|
||||
/// being "Label" Editor" or a single combined widget.
|
||||
|
||||
virtual QWidget* createCombinedWidget(QWidget * parent) { return NULL; }
|
||||
virtual QWidget* createEditorWidget(QWidget * parent) { return NULL; }
|
||||
virtual QWidget* createLabelWidget(QWidget * parent) { return NULL; }
|
||||
|
||||
private:
|
||||
PdmFieldHandle* m_field;
|
||||
|
||||
QPointer<QWidget> m_combinedWidget;
|
||||
QPointer<QWidget> m_editorWidget;
|
||||
QPointer<QWidget> m_labelWidget;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class PdmStdObjView : PdmObjectViewHandle
|
||||
{
|
||||
public:
|
||||
PdmStdObjView() {};
|
||||
~PdmStdObjView() {}
|
||||
|
||||
protected:
|
||||
|
||||
virtual QWidget* createWidget(QWidget* parent)
|
||||
{
|
||||
m_mainWidget = new QWidget(parent);
|
||||
m_layout = new QGridLayout();
|
||||
m_mainWidget->setLayout(m_layout);
|
||||
return m_mainWidget;
|
||||
}
|
||||
|
||||
virtual void updateUi(QString uiConfigName)
|
||||
{
|
||||
PdmUiConfiguration config;
|
||||
m_pdmObject->uiConfiguration(uiConfigName, &config);
|
||||
|
||||
// Set all fieldViews to be unvisited
|
||||
std::map<QString, PdmFieldViewHandle*>::iterator it;
|
||||
for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it)
|
||||
{
|
||||
it->second->setField(NULL);
|
||||
}
|
||||
|
||||
// Set all group Boxes to be unvisited
|
||||
m_newGroupBoxes.clear();
|
||||
|
||||
const std::vector<PdmUiItem*>& uiItems = config.uiItems();
|
||||
|
||||
recursiveSetupFieldsAndGroups(uiItems, m_mainWidget, m_layout, uiConfigName);
|
||||
|
||||
// Remove all fieldViews not mentioned by the configuration from the layout
|
||||
|
||||
std::map<QString, PdmFieldViewHandle*>::iterator it;
|
||||
std::vector< QString > fvhToRemoveFromMap;
|
||||
for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it)
|
||||
{
|
||||
if (it->second->field() == 0)
|
||||
{
|
||||
PdmFieldViewHandle* fvh = it->second;
|
||||
delete fvh;
|
||||
fvhToRemoveFromMap.push_back(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < fvhToRemoveFromMap.size(); ++i)
|
||||
{
|
||||
m_fieldViews.erase(fvhToRemoveFromMap[i]);
|
||||
}
|
||||
|
||||
// Remove all unmentioned group boxes
|
||||
|
||||
std::map<QString, QPointer<QGroupBox> >::iterator itOld;
|
||||
std::map<QString, QPointer<QGroupBox> >::iterator itNew;
|
||||
|
||||
for (itOld = m_groupBoxes.begin(); itOld != m_groupBoxes.end(); ++itOld )
|
||||
{
|
||||
itNew = m_newGroupBoxes.find(itOld->first);
|
||||
if (itNew == m_newGroupBoxes.end())
|
||||
{
|
||||
// The old groupBox is not present anymore, get rid of it
|
||||
if (!itOld->second.isNull()) delete itOld->second;
|
||||
}
|
||||
}
|
||||
m_groupBoxes = m_newGroupBoxes;
|
||||
}
|
||||
|
||||
void recursiveSetupFieldsAndGroups(const std::vector<PdmUiItem*>& uiItems, QWidget* parent, QGridLayout* parentLayout, const QString& uiConfigName )
|
||||
{
|
||||
int currentRowIndex = 0;
|
||||
for (size_t i = 0; i < uiItems.size(); ++i)
|
||||
{
|
||||
if (uiItems[i].isGroup())
|
||||
{
|
||||
const std::vector<PdmUiItem*>& groupChildren = uiItems[i]->uiItems();
|
||||
QString groupBoxKey = uiItems[i]->uiName();
|
||||
QGroupBox* groupBox = NULL;
|
||||
QGridLayout* groupBoxLayout = NULL;
|
||||
|
||||
// Find or create groupBox
|
||||
std::map<QString, QPointer<QGroupBox> >::iterator it;
|
||||
it = m_groupBoxes.find(groupBoxKey);
|
||||
|
||||
if (it == m_groupBoxes.end())
|
||||
{
|
||||
groupBox = new QGroupBox( parent );
|
||||
groupBox->setTitle(uiItems[i]->uiName());
|
||||
|
||||
m_newGroupBoxes[groupBoxKey] = groupBox;
|
||||
groupBoxLayout = new QGridLayout();
|
||||
groupBox->setLayout(groupBoxLayout);
|
||||
}
|
||||
else
|
||||
{
|
||||
groupBox = it->second;
|
||||
CVF_ASSERT(groupBox);
|
||||
groupBoxLayout = dynamic_cast<QGridLayout*>(groupBox->layout());
|
||||
CVF_ASSERT(groupBoxLayout);
|
||||
m_newGroupBoxes[uiItems[i]->uiName()];
|
||||
}
|
||||
|
||||
/// Insert the group box at the correct position of the parent layout
|
||||
|
||||
parentLayout->addWidget(groupBox, currentRowIndex, 0, 1, 2);
|
||||
recursiveSetupFieldsAndGroups(groupChildren, groupBox, groupBoxLayout);
|
||||
currentRowIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
PdmFieldHandle* field = dynamic_cast<PdmFieldHandle*>(uiItems[i]);
|
||||
PdmUiFieldViewHandle* fvh = NULL;
|
||||
|
||||
if (!field->isHidden(uiConfName))
|
||||
{
|
||||
|
||||
// Find or create FieldView
|
||||
std::map<QString, PdmUiFieldViewHandle*>::iterator it;
|
||||
it = m_fieldViews.find(field->keyword());
|
||||
|
||||
if (it == m_fieldViews.end())
|
||||
{
|
||||
if ( uiItems[i]->editorType(uiConfigName).isDefined() )
|
||||
{
|
||||
fvh = PdmFieldViewFactory::instance()->create( uiItems[i]->editorType(uiConfigName));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
fvh = PdmFieldViewFactory::instance()->create(typeid(uiItems[i]));
|
||||
}
|
||||
m_fieldViews[field->keyword()] = fvh;
|
||||
fvh->createWidgets(parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
fvh = it->second;
|
||||
}
|
||||
|
||||
CVF_ASSERT(fvh);
|
||||
|
||||
fvh->setField(field);
|
||||
|
||||
// Place the widget(s) into the correct parent and layout
|
||||
QWidget* fieldCombinedWidget = fvh->combinedWidget();
|
||||
|
||||
if (combinedWidget)
|
||||
{
|
||||
combinedWidget->setParent(parent);
|
||||
parentLayout->addWidget(combinedWidget, currentRowIndex, 0, 1, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
QWidget* fieldEditorWidget = fvh->editorWidget();
|
||||
QWidget* fieldLabelWidget = fvh->labelWidget();
|
||||
|
||||
if (fieldEditorWidget)
|
||||
{
|
||||
fieldEditorWidget->setParent(parent); // To make sure this widget has the current group box as parent.
|
||||
parentLayout->addWidget(fieldEditorWidget, currentRowIndex, 1);
|
||||
}
|
||||
|
||||
if (fieldLabelWidget)
|
||||
{
|
||||
fieldLabelWidget->setParent(parent);
|
||||
parentLayout->addWidget(fieldLabelWidget, currentRowIndex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
fvh->updateUi(uiConfigName);
|
||||
currentRowIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::map<QString, PdmUiFieldViewHandle*> m_fieldViews;
|
||||
std::map<QString, QPointer<QGroupBox> > m_groupBoxes;
|
||||
std::map<QString, QPointer<QGroupBox> > m_newGroupBoxes; ///< used temporarily to store the new(complete) set of group boxes
|
||||
|
||||
QPointer<QWidget> m_mainWidget
|
||||
QGridLayout* m_layout;
|
||||
};
|
||||
|
||||
|
||||
|
||||
caf::Factory<PdmUiFieldViewHandle, type_info>::instance()->registerCreator<PdmLineEditFieldView>(typeid(PdmField<QString>));
|
||||
caf::Factory<PdmUiFieldViewHandle, type_info>::instance()->registerCreator<PdmLineEditFieldView>(typeid(PdmField<int>));
|
||||
caf::Factory<PdmUiFieldViewHandle, type_info>::instance()->registerCreator<PdmLineEditFieldView>(typeid(PdmField<double>));
|
||||
caf::Factory<PdmUiFieldViewHandle, type_info>::instance()->registerCreator<PdmLineEditFieldView>(typeid(PdmField<size_t>));
|
||||
|
||||
caf::Factory<PdmUiFieldViewHandle, type_info>::instance()->registerCreator<PdmLineEditFieldView>(typeid(PdmUiFileEditor));
|
||||
|
||||
class PdmUiAttributeHandle
|
||||
{
|
||||
public:
|
||||
PdmUiAttributeHandle() {}
|
||||
virtual ~PdmUiAttributeHandle() {}
|
||||
};
|
||||
|
||||
class PdmLineEditAttribute : public PdmUiAttributeHandle
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
class PdmLineEditFieldView : public PdmUiFieldViewHandle
|
||||
{
|
||||
public:
|
||||
PdmLineEditFieldView() {}
|
||||
virtual ~PdmLineEditFieldView() {}
|
||||
|
||||
|
||||
virtual void updateUiValue()
|
||||
{
|
||||
m_lineEdit->setText(m_field->uiValue().asString());
|
||||
};
|
||||
|
||||
virtual void updateUi(const QString& uiConfigName)
|
||||
{
|
||||
CVF_ASSERT(!m_lineEdit.isNull());
|
||||
CVF_ASSERT(!m_label.isNull());
|
||||
|
||||
QIcon ic = m_field->uiIcon(uiConfigName);
|
||||
if (!ic.isNull())
|
||||
{
|
||||
m_label->setPixmap(ic->pixmap());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_label->setText(m_field->uiName(uiConfigName));
|
||||
}
|
||||
|
||||
m_label->show( !m_field->isHidden(uiConfigName));
|
||||
|
||||
m_lineEdit->setEnabled(!m_field->readOnly(uiConfigName));
|
||||
m_label->setEnabled(!m_field->readOnly(uiConfigName));
|
||||
|
||||
PdmLineEditAttribute leab;
|
||||
m_field->ownerObject()->setUpUiAttribute(m_field, uiConfigName, &leab);
|
||||
|
||||
if (dynamic_cast<PdmField<int>*> (m_field))
|
||||
{
|
||||
m_lineEdit->setValidator(QIntValidator());
|
||||
}
|
||||
|
||||
m_lineEdit->setAlignment(leab.alignment);
|
||||
}
|
||||
|
||||
virtual void connectUi()
|
||||
{
|
||||
connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(slotEditingFinished()));
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual QWidget* createEditorWidget(QWidget * parent)
|
||||
{
|
||||
m_lineEdit = new QLineEdit(parent);
|
||||
return m_lineEdit;
|
||||
}
|
||||
|
||||
virtual QWidget* createLabelWidget(QWidget * parent)
|
||||
{
|
||||
m_label = new QLabel(parent);
|
||||
return m_label;
|
||||
}
|
||||
|
||||
protected slots:
|
||||
void slotEditingFinished()
|
||||
{
|
||||
QVariant v;
|
||||
QString textValue = m_lineEdit->text();
|
||||
v = textValue;
|
||||
this->setValueToField(v);
|
||||
}
|
||||
|
||||
private:
|
||||
QPointer<QLineEdit> m_lineEdit;
|
||||
QPointer<QLabel> m_label;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
DemoPdmObj::DemoPdmObj()
|
||||
{
|
||||
CAF_PDM_InitObject("DemoPdmObj", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&f1, "f1", 1, "Field 1", "", "","");
|
||||
CAF_PDM_InitField(&f2, "f2", 1, "Field 2", "", "","");
|
||||
CAF_PDM_InitField(&f3, "f3", 1, "Field 3", "", "","");
|
||||
CAF_PDM_InitField(&f4, "f4", 1, "Field 4", "", "","");
|
||||
CAF_PDM_InitField(&f5, "f5", 1, "Field 5", "", "","");
|
||||
|
||||
f1.setEditorType(PdmUiFileEditor::editorName()); // "FileEditor" // typeid(PdmUiFileEditor) // "PdmUiFileEditor"
|
||||
this->addFieldToGroup(configname, 0, &f1);
|
||||
this->addFieldToGroup(configname, 0, &f2);
|
||||
|
||||
this->addFieldToGroup(configname, 1, &f3);
|
||||
this->addFieldToGroup(configname, 1, &f4);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DemoPdmObj::setUpUIConfiguration(QString uiConfigName, PdmUiConfiguration& uiConfig)
|
||||
{
|
||||
if (uiConfigName == "DetailsView")
|
||||
{
|
||||
uiConfig->add(&f1);
|
||||
PdmUiGroup* group1 = uiConfig->addNewGroup("Name1");
|
||||
group1->add(&f2);
|
||||
PdmUiGroup* group2 = uiConfig->addNewGroup("Name2");
|
||||
group2->add(&f4);
|
||||
PdmUiGroup* group3 = group2->addNewGroup("Name3");
|
||||
group3->add(&f5);
|
||||
|
||||
uiConfig->add(&f3);
|
||||
uiConfig->forgetRemainingFields();
|
||||
|
||||
|
||||
|
||||
} else if (uiConfigName == "NormalView")
|
||||
{
|
||||
|
||||
} else if (uiConfigName == "AnimationPanel")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
127
cafProjectDataModel/cafPdmUiItem.cpp
Normal file
127
cafProjectDataModel/cafPdmUiItem.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList PdmOptionItemInfo::extractUiTexts(const QList<PdmOptionItemInfo>& optionList)
|
||||
{
|
||||
QStringList texts;
|
||||
int i;
|
||||
for (i = 0; i < optionList.size(); ++i)
|
||||
{
|
||||
texts.push_back(optionList[i].optionUiText);
|
||||
}
|
||||
return texts;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmOptionItemInfo::findValue(const QList<PdmOptionItemInfo>& optionList , QVariant fieldValue, unsigned int* indexToValue /*= NULL*/)
|
||||
{
|
||||
// Find this field value in the list if present
|
||||
unsigned int i;
|
||||
bool foundFieldValue = false;
|
||||
|
||||
for(i = 0; i < static_cast<unsigned int>(optionList.size()); ++i)
|
||||
{
|
||||
if (optionList[i].value == fieldValue)
|
||||
{
|
||||
foundFieldValue = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (indexToValue) *indexToValue = i;
|
||||
return foundFieldValue;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QString PdmUiItem::uiName() const
|
||||
{
|
||||
if(m_dynamicItemInfo.m_uiName.isNull())
|
||||
{
|
||||
if(m_staticItemInfo) return m_staticItemInfo->m_uiName;
|
||||
else return QString("");
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_dynamicItemInfo.m_uiName;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QIcon PdmUiItem::uiIcon() const
|
||||
{
|
||||
if(m_dynamicItemInfo.m_icon.isNull())
|
||||
{
|
||||
if(m_staticItemInfo) return m_staticItemInfo->m_icon;
|
||||
else return QIcon();
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_dynamicItemInfo.m_icon;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QString PdmUiItem::uiToolTip() const
|
||||
{
|
||||
if(m_dynamicItemInfo.m_toolTip.isNull())
|
||||
{
|
||||
if(m_staticItemInfo) return m_staticItemInfo->m_toolTip;
|
||||
else return QString("");
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_dynamicItemInfo.m_toolTip;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QString PdmUiItem::uiWhatsThis() const
|
||||
{
|
||||
if(m_dynamicItemInfo.m_whatsThis.isNull())
|
||||
{
|
||||
if(m_staticItemInfo) return m_staticItemInfo->m_whatsThis;
|
||||
else return QString("");
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_dynamicItemInfo.m_whatsThis;
|
||||
}
|
||||
}
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
119
cafProjectDataModel/cafPdmUiItem.h
Normal file
119
cafProjectDataModel/cafPdmUiItem.h
Normal file
@@ -0,0 +1,119 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// 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 <QString>
|
||||
#include <QIcon>
|
||||
#include <QVariant>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// Class to keep (principally static) gui presentation information
|
||||
/// of a data structure item (field or object) used by PdmUiItem
|
||||
//==================================================================================================
|
||||
|
||||
class PdmUiItemInfo
|
||||
{
|
||||
public:
|
||||
PdmUiItemInfo() {}
|
||||
|
||||
PdmUiItemInfo( QString uiName, QIcon icon = QIcon(), QString toolTip = "", QString whatsThis = "")
|
||||
: m_uiName(uiName), m_icon(icon), m_toolTip(toolTip), m_whatsThis(whatsThis)
|
||||
{ }
|
||||
|
||||
QString m_uiName;
|
||||
QString m_toolTip;
|
||||
QString m_whatsThis;
|
||||
QIcon m_icon;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Class to keep Ui information about an option /choice in a Combobox or similar.
|
||||
//==================================================================================================
|
||||
|
||||
class PdmOptionItemInfo
|
||||
{
|
||||
public:
|
||||
PdmOptionItemInfo( QString anOptionUiText, QVariant aValue = QVariant(), bool anIsDimmed = false, QIcon anIcon = QIcon() )
|
||||
: value(aValue), optionUiText(anOptionUiText), isDimmed(anIsDimmed), icon(anIcon)
|
||||
{}
|
||||
|
||||
QString optionUiText;
|
||||
bool isDimmed;
|
||||
QIcon icon;
|
||||
QVariant value;
|
||||
|
||||
// Static utility methods to handle QList of PdmOptionItemInfo
|
||||
|
||||
static QStringList extractUiTexts(const QList<PdmOptionItemInfo>& optionList );
|
||||
static bool findValue (const QList<PdmOptionItemInfo>& optionList , QVariant fieldValue,
|
||||
unsigned int* indexToValue = NULL);
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Base class for all datastructure items (fields or objects) to make them have information on
|
||||
/// how to display them in the GUI. All the information can have a static variant valid for all
|
||||
/// instances of a PDM object, and a dynamic variant that can be changed for a specific instance.
|
||||
/// the dynamic values overrides the static ones if set.
|
||||
//==================================================================================================
|
||||
|
||||
class PdmUiItem
|
||||
{
|
||||
public:
|
||||
PdmUiItem() : m_staticItemInfo(NULL), m_isHidden(false) { }
|
||||
virtual ~PdmUiItem() { }
|
||||
|
||||
// Copy and assignment to avoid hampering our internal pointer.
|
||||
PdmUiItem(const PdmUiItem& ) : m_staticItemInfo(NULL) , m_isHidden(false) { }
|
||||
PdmUiItem& operator=(const PdmUiItem& ) { return *this; }
|
||||
|
||||
const QString uiName() const;
|
||||
void setUiName(const QString& uiName) { m_dynamicItemInfo.m_uiName = uiName; }
|
||||
|
||||
const QIcon uiIcon() const;
|
||||
void setUiIcon(const QIcon& uiIcon) { m_dynamicItemInfo.m_icon = uiIcon; }
|
||||
|
||||
const QString uiToolTip() const;
|
||||
void setUiToolTip(const QString& uiToolTip) { m_dynamicItemInfo.m_toolTip = uiToolTip; }
|
||||
|
||||
const QString uiWhatsThis() const;
|
||||
void setUiWhatsThis(const QString& uiWhatsThis) { m_dynamicItemInfo.m_whatsThis = uiWhatsThis; }
|
||||
|
||||
bool isHidden() const { return m_isHidden; }
|
||||
void setHidden(bool isHidden) { m_isHidden = isHidden; }
|
||||
|
||||
//==================================================================================================
|
||||
/// This method sets the GUI description pointer, which is supposed to be statically allocated
|
||||
/// somewhere. the PdmGuiEntry class will not delete it in any way, and always trust it to be present.
|
||||
//==================================================================================================
|
||||
|
||||
void setUiItemInfo(PdmUiItemInfo* itemInfo) { m_staticItemInfo = itemInfo; }
|
||||
|
||||
private:
|
||||
PdmUiItemInfo* m_staticItemInfo;
|
||||
PdmUiItemInfo m_dynamicItemInfo;
|
||||
bool m_isHidden;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
Reference in New Issue
Block a user