mirror of
https://github.com/OPM/ResInsight.git
synced 2026-08-07 11:55:06 -05:00
Copied in RPM/Fwk/AppFwk
Commented out use of stipple line, as VizFwk is not update yet
This commit is contained in:
@@ -2,35 +2,30 @@ cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project (cafProjectDataModel)
|
||||
|
||||
add_library( ${PROJECT_NAME}
|
||||
cafAppEnum.h
|
||||
# Qt
|
||||
find_package ( Qt4 COMPONENTS QtCore QtGui )
|
||||
include (${QT_USE_FILE})
|
||||
|
||||
include_directories (
|
||||
${cafPdmCore_SOURCE_DIR}
|
||||
${cafPdmUiCore_SOURCE_DIR}
|
||||
${cafPdmXml_SOURCE_DIR}
|
||||
)
|
||||
|
||||
set( PROJECT_FILES
|
||||
cafFactory.h
|
||||
cafFixedArray.h
|
||||
cafOmpMutex.h
|
||||
cafUiTreeItem.h
|
||||
cafPdmDocument.cpp
|
||||
cafPdmDocument.h
|
||||
cafPdmField.cpp
|
||||
cafPdmField.h
|
||||
cafPdmField.inl
|
||||
cafPdmFieldImpl.h
|
||||
cafPdmObject.cpp
|
||||
cafPdmObjectGroup.cpp
|
||||
cafPdmObjectGroup.h
|
||||
cafPdmObject.h
|
||||
cafPdmObjectFactory.h
|
||||
cafPdmPointer.cpp
|
||||
cafPdmPointer.h
|
||||
cafPdmUiEditorHandle.cpp
|
||||
cafPdmUiEditorHandle.h
|
||||
cafPdmUiFieldEditorHandle.cpp
|
||||
cafPdmUiFieldEditorHandle.h
|
||||
cafPdmUiItem.cpp
|
||||
cafPdmUiItem.h
|
||||
cafPdmUiObjectEditorHandle.cpp
|
||||
cafPdmUiObjectEditorHandle.h
|
||||
cafPdmUiOrdering.cpp
|
||||
cafPdmUiOrdering.h
|
||||
cafPdmUiTreeOrdering.cpp
|
||||
cafPdmUiTreeOrdering.h
|
||||
cafPdmUiTreeEditorHandle.h
|
||||
cafPdmUiTreeEditorHandle.cpp
|
||||
cafPdmField.h
|
||||
)
|
||||
|
||||
add_library( ${PROJECT_NAME}
|
||||
${PROJECT_FILES}
|
||||
)
|
||||
|
||||
source_group("" FILES ${PROJECT_FILES})
|
||||
@@ -0,0 +1,166 @@
|
||||
@startuml
|
||||
|
||||
class PdmObject {
|
||||
name()
|
||||
fields();
|
||||
referencingFields();
|
||||
parentField();
|
||||
template<T> capability()
|
||||
void addCapability()
|
||||
|
||||
---
|
||||
std::vector<PdmFieldHandle> m_fields;
|
||||
std::vector<PdmObjectCapability*> m_capabilities;
|
||||
}
|
||||
|
||||
|
||||
PdmObject --* "n" PdmObjectCapability
|
||||
|
||||
class PdmUiItem{
|
||||
|
||||
}
|
||||
|
||||
PdmObjectCapability <|- PdmUiObject
|
||||
PdmUiItem <|- PdmUiObject
|
||||
|
||||
class PdmUiObject{
|
||||
uiOrdering() = ?;
|
||||
uiTreeOrdering() = ? ;
|
||||
editorAttribute() = ?;
|
||||
|
||||
objectEditorAttribute() = ? ;
|
||||
|
||||
userDescriptionField();
|
||||
objectToggleField()
|
||||
|
||||
calculateValueOptions() = ?;
|
||||
|
||||
fieldChangedByUi() = 0;
|
||||
---
|
||||
m_descriptionField;
|
||||
m_objectToggleField;
|
||||
}
|
||||
|
||||
PdmUiObject <|-- PdmCompleteObject
|
||||
PdmObject <|-- PdmCompleteObject
|
||||
PdmXmlSerializable <|-- PdmCompleteObject
|
||||
|
||||
|
||||
class PdmXmlSerializable {
|
||||
classKeyword() = 0;
|
||||
readFields ();
|
||||
writeFields();
|
||||
}
|
||||
|
||||
PdmObjectCapability <|- PdmXmlSerializable
|
||||
|
||||
|
||||
|
||||
package FieldHandle{
|
||||
|
||||
PdmObject --> "n" PdmFieldHandle
|
||||
|
||||
class PdmFieldHandle{
|
||||
name()
|
||||
|
||||
setOwnerObject();
|
||||
ownerObject();
|
||||
|
||||
hasChildObjects() = 0;
|
||||
childObjects( ) = 0;
|
||||
---
|
||||
std::vector<PdmFieldCapability*> m_attributes;
|
||||
}
|
||||
|
||||
|
||||
PdmFieldHandle --* "n" PdmFieldCapability
|
||||
|
||||
class PdmUiFieldHandle{
|
||||
|
||||
uiValue()
|
||||
setValueFromUi()
|
||||
|
||||
valueOptions( ) = 0;
|
||||
|
||||
}
|
||||
|
||||
PdmFieldCapability <|- PdmUiFieldHandle
|
||||
PdmUiItem <|- PdmUiFieldHandle
|
||||
|
||||
|
||||
class PdmXmlFieldHandle {
|
||||
setKeyword();
|
||||
keyword();
|
||||
|
||||
readFieldData() = 0;
|
||||
writeFieldData() = 0;
|
||||
|
||||
isIOReadable()
|
||||
isIOWritable()
|
||||
setIOWritable()
|
||||
setIOReadable()
|
||||
---
|
||||
bool m_isReadable;
|
||||
bool m_isWritable;
|
||||
}
|
||||
|
||||
PdmFieldCapability <|- PdmXmlFieldHandle
|
||||
|
||||
|
||||
PdmFieldHandle <|-- PdmCompleteFieldHandle
|
||||
PdmUiFieldHandle <|-- PdmCompleteFieldHandle
|
||||
PdmXmlFieldHandle <|-- PdmCompleteFieldHandle
|
||||
|
||||
}
|
||||
|
||||
package ToDoFields{
|
||||
class "PdmFieldXmlCap<PdmPtrField<T>>"{
|
||||
}
|
||||
}
|
||||
|
||||
package SplittedFields{
|
||||
|
||||
PdmFieldHandle <|--- "PdmField<T>"
|
||||
"PdmField<T>" --> "PdmFieldUiCap<FieldT>"
|
||||
"PdmField<T>" --> "PdmFieldXmlCap<FieldT>"
|
||||
|
||||
PdmFieldHandle <|--- "PdmProxyField<T>"
|
||||
"PdmProxyField<T>" --> "PdmFieldUiCap<FieldT>"
|
||||
"PdmProxyField<T>" --> "PdmFieldXmlCap<FieldT>"
|
||||
|
||||
PdmUiFieldHandle <|--- "PdmFieldUiCap<FieldT>"
|
||||
PdmXmlFieldHandle <|--- "PdmFieldXmlCap<FieldT>"
|
||||
|
||||
PdmFieldHandle <|--- "PdmPtrField<T*>"
|
||||
"PdmPtrField<T*>" --> "PdmFieldUiCap<FieldT>"
|
||||
"PdmPtrField<T*>" --> "PdmFieldXmlCap<FieldT>"
|
||||
"PdmPtrField<T*>" ..> "Todo" "PdmFieldXmlCap<PdmPtrField<T>>"
|
||||
|
||||
PdmFieldHandle <|--- "PdmChildField<T*>"
|
||||
"PdmChildField<T*>"--> "PdmFieldUiCap<PdmField<T*>>"
|
||||
"PdmChildField<T*>"--> "PdmFieldXmlCap<PdmField<T*>>"
|
||||
PdmFieldHandle <|--- "PdmChildArrayField<T*>"
|
||||
"PdmChildArrayField<T*>"--> "PdmFieldUiCap<PdmPointersField<T*>>"
|
||||
"PdmChildArrayField<T*>"--> "PdmFieldXmlCap<PdmPointersField<T*>>"
|
||||
|
||||
}
|
||||
|
||||
|
||||
package ToDoFields{
|
||||
PdmFieldHandle <|-- "PdmProxyPtrField<T>"
|
||||
"PdmProxyPtrField<T>" --> "PdmFieldUiCap<FieldT>"
|
||||
"PdmProxyPtrField<T>" ..> "Todo" "PdmFieldXmlCap<PdmPtrField<T>>"
|
||||
|
||||
PdmFieldHandle <|-- "PdmProxyChildField<T*>"
|
||||
"PdmProxyChildField<T*>"--> "PdmFieldUiCap<PdmField<T*>>"
|
||||
"PdmProxyChildField<T*>"--> "PdmFieldXmlCap<PdmField<T*>>"
|
||||
PdmFieldHandle <|-- "PdmProxyChildArrayField<T*>"
|
||||
"PdmProxyChildArrayField<T*>"--> "PdmFieldUiCap<PdmPointersField<T*>>"
|
||||
"PdmProxyChildArrayField<T*>"--> "PdmFieldXmlCap<PdmPointersField<T*>>"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
@startuml
|
||||
|
||||
class PdmObjectHandle {
|
||||
name()
|
||||
fields();
|
||||
referencingFields();
|
||||
parentField();
|
||||
template<T> capability()
|
||||
void addCapability()
|
||||
|
||||
---
|
||||
std::vector<PdmFieldHandle> m_fields;
|
||||
std::vector<PdmObjectCapability*> m_capabilities;
|
||||
}
|
||||
|
||||
|
||||
PdmObjectHandle --* "n" PdmObjectCapability
|
||||
|
||||
class PdmUiItem{
|
||||
|
||||
}
|
||||
|
||||
PdmObjectCapability <|- PdmUiObjectHandle
|
||||
PdmUiItem <|- PdmUiObjectHandle
|
||||
|
||||
class PdmUiObjectHandle {
|
||||
uiOrdering() = ?;
|
||||
uiTreeOrdering() = ? ;
|
||||
editorAttribute() = ?;
|
||||
|
||||
objectEditorAttribute() = ? ;
|
||||
|
||||
userDescriptionField();
|
||||
objectToggleField()
|
||||
|
||||
calculateValueOptions() = ?;
|
||||
|
||||
fieldChangedByUi() = 0;
|
||||
---
|
||||
m_descriptionField;
|
||||
m_objectToggleField;
|
||||
}
|
||||
|
||||
PdmUiObjectHandle <|-- PdmObject
|
||||
PdmObjectHandle <|-- PdmObject
|
||||
PdmXmlObjectHandle <|-- PdmObject
|
||||
|
||||
|
||||
class PdmXmlObjectHandle {
|
||||
classKeyword() = 0;
|
||||
readFields ();
|
||||
writeFields();
|
||||
}
|
||||
|
||||
PdmObjectCapability <|- PdmXmlObjectHandle
|
||||
|
||||
|
||||
|
||||
package FieldHandle{
|
||||
|
||||
PdmObjectHandle --> "n" PdmFieldHandle
|
||||
|
||||
class PdmFieldHandle{
|
||||
name()
|
||||
|
||||
setOwnerObject();
|
||||
ownerObject();
|
||||
|
||||
hasChildObjects() = 0;
|
||||
childObjects( ) = 0;
|
||||
---
|
||||
std::vector<PdmFieldCapability*> m_attributes;
|
||||
}
|
||||
|
||||
|
||||
PdmFieldHandle --* "n" PdmFieldCapability
|
||||
|
||||
class PdmUiFieldHandle{
|
||||
|
||||
uiValue()
|
||||
setValueFromUi()
|
||||
|
||||
valueOptions( ) = 0;
|
||||
|
||||
}
|
||||
|
||||
PdmFieldCapability <|- PdmUiFieldHandle
|
||||
PdmUiItem <|- PdmUiFieldHandle
|
||||
|
||||
|
||||
class PdmXmlFieldHandle {
|
||||
setKeyword();
|
||||
keyword();
|
||||
|
||||
readFieldData() = 0;
|
||||
writeFieldData() = 0;
|
||||
|
||||
isIOReadable()
|
||||
isIOWritable()
|
||||
setIOWritable()
|
||||
setIOReadable()
|
||||
---
|
||||
bool m_isReadable;
|
||||
bool m_isWritable;
|
||||
}
|
||||
|
||||
PdmFieldCapability <|- PdmXmlFieldHandle
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
package ToDoFields{
|
||||
class "InternalPdmXmlFieldCapability<PdmPtrField<T>>"{
|
||||
}
|
||||
}
|
||||
|
||||
package SplittedFields{
|
||||
|
||||
PdmFieldHandle <|--- "PdmField<T>"
|
||||
"PdmField<T>" --> "InternalPdmUiFieldCapability<FieldT>"
|
||||
"PdmField<T>" --> "InternalPdmXmlFieldCapability<FieldT>"
|
||||
|
||||
PdmFieldHandle <|--- "PdmProxyField<T>"
|
||||
"PdmProxyField<T>" --> "InternalPdmUiFieldCapability<FieldT>"
|
||||
"PdmProxyField<T>" --> "InternalPdmXmlFieldCapability<FieldT>"
|
||||
|
||||
PdmUiFieldHandle <|--- "InternalPdmUiFieldCapability<FieldT>"
|
||||
PdmXmlFieldHandle <|--- "InternalPdmXmlFieldCapability<FieldT>"
|
||||
|
||||
PdmFieldHandle <|--- "PdmPtrField<T*>"
|
||||
"PdmPtrField<T*>" --> "InternalPdmUiFieldCapability<FieldT>"
|
||||
"PdmPtrField<T*>" --> "InternalPdmXmlFieldCapability<FieldT>"
|
||||
"PdmPtrField<T*>" ..> "Todo" "InternalPdmXmlFieldCapability<PdmPtrField<T>>"
|
||||
|
||||
PdmFieldHandle <|--- "PdmChildField<T*>"
|
||||
"PdmChildField<T*>"--> "InternalPdmUiFieldCapability<PdmField<T*>>"
|
||||
"PdmChildField<T*>"--> "InternalPdmXmlFieldCapability<PdmField<T*>>"
|
||||
PdmFieldHandle <|--- "PdmChildArrayField<T*>"
|
||||
"PdmChildArrayField<T*>"--> "InternalPdmUiFieldCapability<PdmPointersField<T*>>"
|
||||
"PdmChildArrayField<T*>"--> "InternalPdmXmlFieldCapability<PdmPointersField<T*>>"
|
||||
|
||||
}
|
||||
|
||||
|
||||
package ToDoFields{
|
||||
PdmFieldHandle <|-- "PdmProxyPtrField<T>"
|
||||
"PdmProxyPtrField<T>" --> "InternalPdmUiFieldCapability<FieldT>"
|
||||
"PdmProxyPtrField<T>" ..> "Todo" "InternalPdmXmlFieldCapability<PdmPtrField<T>>"
|
||||
|
||||
PdmFieldHandle <|-- "PdmProxyChildField<T*>"
|
||||
"PdmProxyChildField<T*>"--> "InternalPdmUiFieldCapability<PdmField<T*>>"
|
||||
"PdmProxyChildField<T*>"--> "InternalPdmXmlFieldCapability<PdmField<T*>>"
|
||||
PdmFieldHandle <|-- "PdmProxyChildArrayField<T*>"
|
||||
"PdmProxyChildArrayField<T*>"--> "InternalPdmUiFieldCapability<PdmPointersField<T*>>"
|
||||
"PdmProxyChildArrayField<T*>"--> "InternalPdmXmlFieldCapability<PdmPointersField<T*>>"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@enduml
|
||||
|
||||
@@ -39,6 +39,25 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <map>
|
||||
#include <cstddef>
|
||||
|
||||
// Taken from gtest.h
|
||||
//
|
||||
// Due to C++ preprocessor weirdness, we need double indirection to
|
||||
// concatenate two tokens when one of them is __LINE__. Writing
|
||||
//
|
||||
// foo ## __LINE__
|
||||
//
|
||||
// will result in the token foo__LINE__, instead of foo followed by
|
||||
// the current line number. For more details, see
|
||||
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
|
||||
#define CAF_FACTORY_CONCATENATE_STRINGS(foo, bar) CAF_FACTORY_CONCATENATE_STRINGS_IMPL_(foo, bar)
|
||||
#define CAF_FACTORY_CONCATENATE_STRINGS_IMPL_(foo, bar) foo ## bar
|
||||
|
||||
#define CAF_UNIQUE_COMPILE_UNIT_VAR_NAME CAF_FACTORY_CONCATENATE_STRINGS(caf_factory_init_, __LINE__)
|
||||
|
||||
#define CAF_FACTORY_REGISTER(BaseType, TypeToCreate, KeyType, key) \
|
||||
static bool CAF_UNIQUE_COMPILE_UNIT_VAR_NAME = caf::Factory<BaseType, KeyType>::instance()->registerCreator<TypeToCreate>(key)
|
||||
|
||||
namespace caf
|
||||
{
|
||||
@@ -56,6 +75,8 @@ namespace caf
|
||||
///
|
||||
/// static bool uniqueVarname = caf::Factory<BaseType, KeyType>::instance()->registerCreator<TypeToCreate>(key);
|
||||
///
|
||||
/// You can also use the macro CAF_FACTORY_REGISTER(BaseType, TypeToCreate, KeyType, key)
|
||||
///
|
||||
/// See also cafPdmUiFieldEditorHandle.h for an advanced example.
|
||||
///
|
||||
/// When you need an object:
|
||||
|
||||
@@ -55,8 +55,8 @@ public:
|
||||
|
||||
FixedArray<T, size>& operator=(const T* ptr) { for (size_t i = 0; i < size ; ++i) m_array[i] = ptr[i]; return *this;}
|
||||
|
||||
template<typename IndexType> T& operator[](const IndexType& index) { return m_array[index]; }
|
||||
template<typename IndexType> const T& operator[](const IndexType& index) const { return m_array[index]; }
|
||||
template<typename IndexType> T& operator[](const IndexType& index) { CVF_TIGHT_ASSERT(static_cast<size_t>(index) < size); return m_array[index]; }
|
||||
template<typename IndexType> const T& operator[](const IndexType& index) const { CVF_TIGHT_ASSERT(static_cast<size_t>(index) < size); return m_array[index]; }
|
||||
};
|
||||
|
||||
typedef FixedArray<int, 3> IntArray3;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project (cafPdmCore)
|
||||
|
||||
# Qt
|
||||
find_package ( Qt4 COMPONENTS QtCore )
|
||||
include (${QT_USE_FILE})
|
||||
|
||||
include_directories (
|
||||
)
|
||||
|
||||
set( PROJECT_FILES
|
||||
|
||||
cafAppEnum.h
|
||||
cafClassTypeName.h
|
||||
cafPdmBase.h
|
||||
cafPdmChildArrayField.h
|
||||
cafPdmChildArrayField.inl
|
||||
cafPdmChildArrayFieldHandle.cpp
|
||||
cafPdmChildField.h
|
||||
cafPdmChildField.inl
|
||||
cafPdmDataValueField.h
|
||||
cafPdmFieldCapability.h
|
||||
cafPdmFieldHandle.cpp
|
||||
cafPdmFieldHandle.h
|
||||
cafPdmObjectCapability.h
|
||||
cafPdmObjectHandle.cpp
|
||||
cafPdmObjectHandle.h
|
||||
cafPdmPointer.cpp
|
||||
cafPdmPointer.h
|
||||
cafPdmProxyValueField.h
|
||||
cafPdmPtrField.h
|
||||
cafPdmPtrField.inl
|
||||
cafPdmReferenceHelper.cpp
|
||||
cafPdmReferenceHelper.h
|
||||
cafPdmValueField.h
|
||||
|
||||
cafNotificationCenter.cpp
|
||||
cafNotificationCenter.h
|
||||
)
|
||||
|
||||
|
||||
add_library( ${PROJECT_NAME}
|
||||
${PROJECT_FILES}
|
||||
)
|
||||
|
||||
source_group("" FILES ${PROJECT_FILES})
|
||||
+5
-4
@@ -170,13 +170,14 @@ private:
|
||||
|
||||
static EnumMapper * instance()
|
||||
{
|
||||
static EnumMapper * storedInstance = 0;
|
||||
if (!storedInstance)
|
||||
static EnumMapper storedInstance;
|
||||
static bool isInitialized = false;
|
||||
if (!isInitialized)
|
||||
{
|
||||
storedInstance = new EnumMapper;
|
||||
isInitialized = true;
|
||||
AppEnum<T>::setUp();
|
||||
}
|
||||
return storedInstance;
|
||||
return &storedInstance;
|
||||
}
|
||||
|
||||
void setDefault(T defaultEnumValue)
|
||||
@@ -0,0 +1,43 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
/// Create a QString based on a typename
|
||||
#define qStringTypeName(TypeName) QString(typeid(TypeName).name())
|
||||
@@ -0,0 +1,118 @@
|
||||
#pragma once
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// A proxy class that implements the generic QVariant interface for a field
|
||||
///
|
||||
/// 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 PdmValueFieldSpecialization
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert(const T& value)
|
||||
{
|
||||
return QVariant::fromValue(value);
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant(const QVariant& variantValue, T& value)
|
||||
{
|
||||
value = variantValue.value<T>();
|
||||
}
|
||||
|
||||
/// Check equality between QVariants that carries a Field Value.
|
||||
/// The == operator will normally work, but does not support custom types in the QVariant
|
||||
/// See http://qt-project.org/doc/qt-4.8/qvariant.html#operator-eq-eq-64
|
||||
static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2)
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
};
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
class PdmValueFieldSpecialization<caf::AppEnum<T> >
|
||||
{
|
||||
public:
|
||||
static QVariant convert(const caf::AppEnum<T>& value)
|
||||
{
|
||||
T enumValue = value;
|
||||
return QVariant(enumValue);
|
||||
}
|
||||
|
||||
static void setFromVariant(const QVariant& variantValue, caf::AppEnum<T>& value)
|
||||
{
|
||||
value = (T)variantValue.toInt();
|
||||
}
|
||||
|
||||
static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2)
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
class PdmValueFieldSpecialization<std::vector<T> >
|
||||
{
|
||||
public:
|
||||
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::fromValue(*it));
|
||||
}
|
||||
return returnList;
|
||||
|
||||
}
|
||||
|
||||
static void setFromVariant(const QVariant& variantValue, std::vector<T>& value)
|
||||
{
|
||||
if (variantValue.canConvert< QList<QVariant> >())
|
||||
{
|
||||
value.clear();
|
||||
QList<QVariant> lst = variantValue.toList();
|
||||
for (int i = 0; i < lst.size(); ++i)
|
||||
{
|
||||
value.push_back(lst[i].value<T>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2)
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,116 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2014 Ceetron Solutions AS
|
||||
//
|
||||
// <APPLICATION_NAME> 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.
|
||||
//
|
||||
// <APPLICATION_NAME> 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 "cafNotificationCenter.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
NotificationCenter::NotificationCenter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
NotificationCenter::~NotificationCenter()
|
||||
{
|
||||
assert(m_observers.size() == 0);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void NotificationCenter::registerObserver(DataModelObserver* observer)
|
||||
{
|
||||
std::vector<DataModelObserver*>::iterator it = std::find(m_observers.begin(), m_observers.end(), observer);
|
||||
if (it == m_observers.end())
|
||||
{
|
||||
m_observers.push_back(observer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void NotificationCenter::removeObserver(DataModelObserver* observer)
|
||||
{
|
||||
std::vector<DataModelObserver*>::iterator it = std::find(m_observers.begin(), m_observers.end(), observer);
|
||||
if (it != m_observers.end())
|
||||
{
|
||||
m_observers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void NotificationCenter::notifyObserversOfDataChange(caf::PdmObjectHandle* itemThatChanged)
|
||||
{
|
||||
assert(itemThatChanged);
|
||||
|
||||
foreach(DataModelObserver* o, m_observers)
|
||||
{
|
||||
o->handleModelNotification(itemThatChanged);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void NotificationCenter::notifyObservers()
|
||||
{
|
||||
foreach(DataModelObserver* o, m_observers)
|
||||
{
|
||||
o->handleModelNotification(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void NotificationCenter::notifyObserversOfSelectionChange()
|
||||
{
|
||||
foreach(DataModelObserver* o, m_observers)
|
||||
{
|
||||
o->handleModelSelectionChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // end namespace caf
|
||||
@@ -0,0 +1,66 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2014 Ceetron Solutions AS
|
||||
//
|
||||
// <APPLICATION_NAME> 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.
|
||||
//
|
||||
// <APPLICATION_NAME> 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>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class PdmObjectHandle;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class DataModelObserver
|
||||
{
|
||||
public:
|
||||
virtual void handleModelNotification(caf::PdmObjectHandle* itemThatChanged) = 0;
|
||||
virtual void handleModelSelectionChange() = 0;
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class NotificationCenter
|
||||
{
|
||||
public:
|
||||
NotificationCenter();
|
||||
~NotificationCenter();
|
||||
|
||||
void registerObserver(DataModelObserver* observer);
|
||||
void removeObserver(DataModelObserver* observer);
|
||||
|
||||
void notifyObservers();
|
||||
void notifyObserversOfDataChange(caf::PdmObjectHandle* itemThatChanged);
|
||||
void notifyObserversOfSelectionChange();
|
||||
|
||||
private:
|
||||
std::vector<DataModelObserver*> m_observers;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace caf
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
// Brings in size_t and definition of NULL
|
||||
#include <cstddef>
|
||||
|
||||
// Macro to disable the copy constructor and assignment operator
|
||||
// Should be used in the private section of a class
|
||||
#define PDM_DISABLE_COPY_AND_ASSIGN(CLASS_NAME) \
|
||||
CLASS_NAME(const CLASS_NAME&); \
|
||||
void operator=(const CLASS_NAME&)
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
template <typename T> class PdmFieldXmlCap;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class PdmChildArrayFieldHandle : public PdmFieldHandle
|
||||
{
|
||||
public:
|
||||
PdmChildArrayFieldHandle() {}
|
||||
virtual ~PdmChildArrayFieldHandle() {}
|
||||
|
||||
virtual size_t size() const = 0;
|
||||
virtual bool empty() const = 0;
|
||||
virtual void clear() = 0;
|
||||
virtual void insertAt(size_t indexAfter, PdmObjectHandle* obj) = 0;
|
||||
virtual void erase(size_t index) = 0;
|
||||
virtual void deleteAllChildObjects() = 0;
|
||||
|
||||
bool hasSameFieldCountForAllObjects();
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// 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 PdmChildArrayField : public PdmFieldHandle
|
||||
{
|
||||
public:
|
||||
PdmChildArrayField()
|
||||
{
|
||||
bool doNotUsePdmPointersFieldForAnythingButPointersToPdmObject = false; assert(doNotUsePdmPointersFieldForAnythingButPointersToPdmObject);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename DataType>
|
||||
class PdmChildArrayField<DataType*> : public PdmChildArrayFieldHandle
|
||||
{
|
||||
typedef DataType* DataTypePtr;
|
||||
public:
|
||||
PdmChildArrayField() { }
|
||||
virtual ~PdmChildArrayField();
|
||||
|
||||
PdmChildArrayField& operator() () { return *this; }
|
||||
|
||||
// Reimplementation of PdmPointersFieldHandle methods
|
||||
|
||||
virtual size_t size() const { return m_pointers.size(); }
|
||||
virtual bool empty() const { return m_pointers.empty(); }
|
||||
virtual void clear();
|
||||
virtual void deleteAllChildObjects();
|
||||
virtual void insertAt(size_t indexAfter, PdmObjectHandle* obj);
|
||||
|
||||
// std::vector-like access
|
||||
|
||||
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 insert(size_t indexAfter, const std::vector<PdmPointer<DataType> >& objects);
|
||||
size_t count(const DataType* pointer) const;
|
||||
|
||||
void erase(size_t index);
|
||||
|
||||
// Child objects
|
||||
|
||||
virtual void childObjects(std::vector<PdmObjectHandle*>* objects);
|
||||
virtual void removeChildObject(PdmObjectHandle* object);
|
||||
|
||||
private: //To be disabled
|
||||
PDM_DISABLE_COPY_AND_ASSIGN(PdmChildArrayField);
|
||||
|
||||
private:
|
||||
void removeThisAsParentField();
|
||||
void addThisAsParentField();
|
||||
|
||||
private:
|
||||
friend class PdmFieldXmlCap< PdmChildArrayField<DataType*> >;
|
||||
std::vector< PdmPointer<DataType> > m_pointers;
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafPdmChildArrayField.inl"
|
||||
@@ -0,0 +1,244 @@
|
||||
#include "cafClassTypeName.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// Implementation of PdmPointersField<>
|
||||
//==================================================================================================
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
PdmChildArrayField<DataType*>::~PdmChildArrayField()
|
||||
{
|
||||
this->removeThisAsParentField();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
DataType* PdmChildArrayField<DataType*>::operator[](size_t index) const
|
||||
{
|
||||
return m_pointers[index];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::push_back(DataType* pointer)
|
||||
{
|
||||
m_pointers.push_back(pointer);
|
||||
if (pointer) pointer->setAsParentField(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the value at position index to pointer, overwriting any pointer already present at that
|
||||
/// position without deleting the object pointed to.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::set(size_t index, DataType* pointer)
|
||||
{
|
||||
if (m_pointers[index]) m_pointers[index]->removeAsParentField(this);
|
||||
m_pointers[index] = pointer;
|
||||
if (m_pointers[index]) pointer->setAsParentField(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Insert pointer at position index, pushing the value previously at that position and all
|
||||
/// the preceding values backwards
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::insert(size_t index, DataType* pointer)
|
||||
{
|
||||
m_pointers.insert(m_pointers.begin()+index, pointer);
|
||||
|
||||
if (pointer) pointer->setAsParentField(this);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Insert the pointers at position index, pushing the value previously at that position and all
|
||||
/// the preceding values backwards
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::insert(size_t index, const std::vector<PdmPointer<DataType> >& objects)
|
||||
{
|
||||
m_pointers.insert(m_pointers.begin()+index, objects.begin(), objects.end());
|
||||
|
||||
typename std::vector< PdmPointer< DataType > >::iterator it;
|
||||
for (it = m_pointers.begin()+index; it != m_pointers.end(); ++it)
|
||||
{
|
||||
if (!it->isNull())
|
||||
{
|
||||
(*it)->setAsParentField(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the number of times pointer is referenced from the container.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
size_t PdmChildArrayField<DataType*>::count(const DataType* pointer) const
|
||||
{
|
||||
size_t itemCount = 0;
|
||||
|
||||
typename std::vector< PdmPointer< DataType > >::const_iterator it;
|
||||
for (it = m_pointers.begin(); it != m_pointers.end(); ++it)
|
||||
{
|
||||
if (*it == pointer)
|
||||
{
|
||||
itemCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return itemCount;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Empty the container without deleting the objects pointed to.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::clear()
|
||||
{
|
||||
this->removeThisAsParentField();
|
||||
m_pointers.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Deletes all the objects pointed to by the field, then clears the container.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::deleteAllChildObjects()
|
||||
{
|
||||
size_t index;
|
||||
for (index = 0; index < m_pointers.size(); ++index)
|
||||
{
|
||||
delete(m_pointers[index].rawPtr());
|
||||
}
|
||||
|
||||
m_pointers.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Removes the pointer at index from the container. Does not delete the object pointed to.
|
||||
/// Todo: This implementation can't be necessary in the new regime. Should be to just remove
|
||||
/// the item at index (shrinking the array)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::erase(size_t index)
|
||||
{
|
||||
PdmObjectHandle* obj = m_pointers[index].rawPtr();
|
||||
if (obj)
|
||||
{
|
||||
removeChildObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Removes all instances of object pointer from the container without deleting the object.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::removeChildObject(PdmObjectHandle* object)
|
||||
{
|
||||
std::vector< PdmPointer<DataType> > tempPointers;
|
||||
|
||||
tempPointers = m_pointers;
|
||||
m_pointers.clear();
|
||||
|
||||
for (size_t index = 0; index < tempPointers.size(); ++index)
|
||||
{
|
||||
if (tempPointers[index].rawPtr() != object)
|
||||
{
|
||||
m_pointers.push_back(tempPointers[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tempPointers[index].rawPtr())
|
||||
{
|
||||
tempPointers[index].rawPtr()->removeAsParentField(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::childObjects(std::vector<PdmObjectHandle*>* objects)
|
||||
{
|
||||
if (!objects) return;
|
||||
size_t i;
|
||||
for (i = 0; i < m_pointers.size(); ++i)
|
||||
{
|
||||
objects->push_back(m_pointers[i].rawPtr());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::insertAt(size_t indexAfter, PdmObjectHandle* obj)
|
||||
{
|
||||
// This method should assert if obj to insert is not castable to the container type, but since this
|
||||
// is a virtual method, its implementation is always created and that makes a dyn_cast add the need for
|
||||
// #include of the header file "everywhere"
|
||||
typename std::vector< PdmPointer<DataType> >::iterator it;
|
||||
|
||||
if (indexAfter == -1)
|
||||
{
|
||||
m_pointers.push_back(PdmPointer<DataType>());
|
||||
it = m_pointers.end() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pointers.insert(m_pointers.begin() + indexAfter, PdmPointer<DataType>());
|
||||
it = m_pointers.begin() + indexAfter;
|
||||
}
|
||||
|
||||
it->setRawPtr(obj);
|
||||
obj->setAsParentField(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::removeThisAsParentField()
|
||||
{
|
||||
typename std::vector< PdmPointer< DataType > >::iterator it;
|
||||
for (it = m_pointers.begin(); it != m_pointers.end(); ++it)
|
||||
{
|
||||
if (!it->isNull())
|
||||
{
|
||||
it->rawPtr()->removeAsParentField(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmChildArrayField<DataType*>::addThisAsParentField()
|
||||
{
|
||||
typename std::vector< PdmPointer< DataType > >::iterator it;
|
||||
for (it = m_pointers.begin(); it != m_pointers.end(); ++it)
|
||||
{
|
||||
if (!it->isNull())
|
||||
{
|
||||
(*it)->setAsParentField(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#include "cafPdmChildArrayField.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmChildArrayFieldHandle::hasSameFieldCountForAllObjects()
|
||||
{
|
||||
std::vector<PdmObjectHandle*> listObjects;
|
||||
this->childObjects(&listObjects);
|
||||
|
||||
if (listObjects.size() == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t fieldCount = 0;
|
||||
for (size_t i = 0; i < listObjects.size(); i++)
|
||||
{
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
listObjects[i]->fields(fields);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
fieldCount = fields.size();
|
||||
}
|
||||
else if (fieldCount != fields.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
template< typename T> class PdmFieldXmlCap;
|
||||
//==================================================================================================
|
||||
/// Specialization for pointers, but only applicable to PdmObject 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
|
||||
/// This is supposed to be renamed to PdmChildField
|
||||
//==================================================================================================
|
||||
|
||||
template<typename DataType>
|
||||
class PdmChildField : public PdmFieldHandle
|
||||
{
|
||||
public:
|
||||
PdmChildField()
|
||||
{
|
||||
bool doNotUsePdmPtrFieldForAnythingButPointersToPdmObject = false; assert(doNotUsePdmPtrFieldForAnythingButPointersToPdmObject);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DataType >
|
||||
class PdmChildField <DataType*> : public PdmFieldHandle
|
||||
{
|
||||
typedef DataType* DataTypePtr;
|
||||
public:
|
||||
PdmChildField() { }
|
||||
explicit PdmChildField(const DataTypePtr& fieldValue);
|
||||
virtual ~PdmChildField();
|
||||
|
||||
// Assignment
|
||||
|
||||
PdmChildField& operator= (const DataTypePtr & fieldValue);
|
||||
|
||||
// Basic access
|
||||
|
||||
DataType* value() const { return m_fieldValue; }
|
||||
void setValue(const DataTypePtr& fieldValue);
|
||||
|
||||
// Access operators
|
||||
|
||||
/*Conversion*/ 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; }
|
||||
|
||||
// Child objects
|
||||
|
||||
virtual void childObjects(std::vector<PdmObjectHandle*>* objects);
|
||||
virtual void removeChildObject(PdmObjectHandle* object);
|
||||
|
||||
private:
|
||||
PDM_DISABLE_COPY_AND_ASSIGN(PdmChildField);
|
||||
|
||||
friend class PdmFieldXmlCap< PdmChildField <DataType*> >;
|
||||
PdmPointer<DataType> m_fieldValue;
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafPdmChildField.inl"
|
||||
@@ -0,0 +1,73 @@
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
void caf::PdmChildField<DataType*>::childObjects(std::vector<PdmObjectHandle*>* objects)
|
||||
{
|
||||
assert(objects);
|
||||
PdmObjectHandle* obj = m_fieldValue.rawPtr();
|
||||
if (obj)
|
||||
{
|
||||
objects->push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
void caf::PdmChildField<DataType*>::removeChildObject(PdmObjectHandle* object)
|
||||
{
|
||||
if (m_fieldValue.rawPtr() != NULL && m_fieldValue.rawPtr() == object)
|
||||
{
|
||||
m_fieldValue.rawPtr()->removeAsParentField(this);
|
||||
m_fieldValue.setRawPtr(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmChildField<DataType*>::PdmChildField(const DataTypePtr& fieldValue)
|
||||
{
|
||||
if (m_fieldValue) m_fieldValue->removeAsParentField(this);
|
||||
m_fieldValue = fieldValue;
|
||||
if (m_fieldValue != NULL) m_fieldValue->setAsParentField(this);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmChildField<DataType*>::~PdmChildField()
|
||||
{
|
||||
if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeAsParentField(this);
|
||||
m_fieldValue.setRawPtr(NULL);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmChildField<DataType*>& PdmChildField<DataType*>::operator=(const DataTypePtr & fieldValue)
|
||||
{
|
||||
if (m_fieldValue) m_fieldValue->removeAsParentField(this);
|
||||
m_fieldValue = fieldValue;
|
||||
if (m_fieldValue != NULL) m_fieldValue->setAsParentField(this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
find_package ( Qt4 COMPONENTS QtCore )
|
||||
include (${QT_USE_FILE})
|
||||
|
||||
project ( cafPdmCore_UnitTests )
|
||||
|
||||
include_directories (
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
)
|
||||
|
||||
|
||||
set( PROJECT_FILES
|
||||
|
||||
cafPdmCore_UnitTests.cpp
|
||||
gtest/gtest-all.cpp
|
||||
|
||||
cafPdmCoreBasicTest.cpp
|
||||
|
||||
Child.cpp
|
||||
Child.h
|
||||
Parent.cpp
|
||||
Parent.h
|
||||
TestObj.cpp
|
||||
TestObj.h
|
||||
)
|
||||
|
||||
# add the executable
|
||||
add_executable (${PROJECT_NAME}
|
||||
${PROJECT_FILES}
|
||||
)
|
||||
|
||||
source_group("" FILES ${PROJECT_FILES})
|
||||
|
||||
message(STATUS ${PROJECT_NAME}" - Qt includes : " ${QT_LIBRARIES})
|
||||
|
||||
target_link_libraries ( ${PROJECT_NAME}
|
||||
cafPdmCore
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
# Copy Qt Dlls
|
||||
if (MSVC)
|
||||
set (QTLIBLIST QtCore )
|
||||
foreach (qtlib ${QTLIBLIST})
|
||||
|
||||
# Debug
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}d4.dll ${CMAKE_CURRENT_BINARY_DIR}/Debug/${qtlib}d4.dll)
|
||||
|
||||
# Release
|
||||
execute_process(COMMAND cmake -E copy_if_different ${QT_BINARY_DIR}/${qtlib}4.dll ${CMAKE_CURRENT_BINARY_DIR}/Release/${qtlib}4.dll)
|
||||
endforeach( qtlib )
|
||||
endif(MSVC)
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "Child.h"
|
||||
#include "TestObj.h"
|
||||
|
||||
Child::Child()
|
||||
{
|
||||
this->addField(&m_testObj, "Numbers");
|
||||
}
|
||||
|
||||
Child::~Child()
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
|
||||
class TestObj;
|
||||
|
||||
class Child: public caf::PdmObjectHandle
|
||||
{
|
||||
|
||||
public:
|
||||
Child();
|
||||
~Child();
|
||||
|
||||
caf::PdmChildField<TestObj*> m_testObj;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "Parent.h"
|
||||
#include "Child.h"
|
||||
|
||||
|
||||
|
||||
Parent::Parent()
|
||||
{
|
||||
this->addField(&m_simpleObjectsField, "SimpleObjects");
|
||||
this->addField(&m_simpleObjectF, "SimpleObject");
|
||||
}
|
||||
|
||||
Parent::~Parent()
|
||||
{
|
||||
}
|
||||
|
||||
void Parent::doSome()
|
||||
{
|
||||
size_t i = m_simpleObjectsField.size();
|
||||
if (i){
|
||||
//Child* c = m_simpleObjectsField[0];
|
||||
//TestObj* to = c->m_testObj();
|
||||
}
|
||||
}
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(IncludeTest, Basic)
|
||||
{
|
||||
Parent* p = new Parent;
|
||||
delete(p);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
|
||||
class Child;
|
||||
|
||||
class Parent : public caf::PdmObjectHandle
|
||||
{
|
||||
public:
|
||||
Parent();
|
||||
~Parent();
|
||||
|
||||
void doSome();
|
||||
|
||||
caf::PdmChildArrayField<Child*> m_simpleObjectsField;
|
||||
caf::PdmChildField<Child*> m_simpleObjectF;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "TestObj.h"
|
||||
|
||||
|
||||
TestObj::TestObj()
|
||||
{
|
||||
this->addField(&m_position, "Position");
|
||||
}
|
||||
|
||||
TestObj::~TestObj() {}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafPdmDataValueField.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
|
||||
class TestObj : public caf::PdmObjectHandle
|
||||
{
|
||||
public:
|
||||
TestObj();
|
||||
~TestObj();
|
||||
|
||||
caf::PdmDataValueField<double> m_position;
|
||||
};
|
||||
+574
@@ -0,0 +1,574 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmDataValueField.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmProxyValueField.h"
|
||||
#include "cafPdmValueField.h"
|
||||
#include "Parent.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
|
||||
class DemoPdmObject: public caf::PdmObjectHandle
|
||||
{
|
||||
public:
|
||||
|
||||
DemoPdmObject()
|
||||
{
|
||||
this->addField(&m_proxyDoubleField, "m_proxyDoubleField");
|
||||
m_proxyDoubleField.registerSetMethod(this, &DemoPdmObject::setDoubleMember);
|
||||
m_proxyDoubleField.registerGetMethod(this, &DemoPdmObject::doubleMember);
|
||||
|
||||
this->addField(&m_proxyIntField, "m_proxyIntField");
|
||||
m_proxyIntField.registerSetMethod(this, &DemoPdmObject::setIntMember);
|
||||
m_proxyIntField.registerGetMethod(this, &DemoPdmObject::intMember);
|
||||
|
||||
this->addField(&m_proxyStringField, "m_proxyStringField");
|
||||
m_proxyStringField.registerSetMethod(this, &DemoPdmObject::setStringMember);
|
||||
m_proxyStringField.registerGetMethod(this, &DemoPdmObject::stringMember);
|
||||
|
||||
this->addField(&m_memberDoubleField, "m_memberDoubleField");
|
||||
this->addField(&m_memberIntField, "m_memberIntField");
|
||||
this->addField(&m_memberStringField, "m_memberStringField");
|
||||
|
||||
|
||||
// Default values
|
||||
m_doubleMember = 2.1;
|
||||
m_intMember = 7;
|
||||
m_stringMember = "abba";
|
||||
|
||||
m_memberDoubleField = 0.0;
|
||||
m_memberIntField = 0;
|
||||
m_memberStringField = "";
|
||||
|
||||
}
|
||||
|
||||
~DemoPdmObject()
|
||||
{
|
||||
}
|
||||
|
||||
// Fields
|
||||
caf::PdmProxyValueField<double> m_proxyDoubleField;
|
||||
caf::PdmProxyValueField<int> m_proxyIntField;
|
||||
caf::PdmProxyValueField<QString> m_proxyStringField;
|
||||
|
||||
caf::PdmDataValueField<double> m_memberDoubleField;
|
||||
caf::PdmDataValueField<int> m_memberIntField;
|
||||
caf::PdmDataValueField<QString> m_memberStringField;
|
||||
|
||||
|
||||
// Internal class members accessed by proxy fields
|
||||
double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; }
|
||||
void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; }
|
||||
|
||||
int intMember() const { return m_intMember; }
|
||||
void setIntMember(const int& val) { m_intMember = val; }
|
||||
|
||||
QString stringMember() const { return m_stringMember; }
|
||||
void setStringMember(const QString& val) { m_stringMember = val; }
|
||||
|
||||
private:
|
||||
double m_doubleMember;
|
||||
int m_intMember;
|
||||
QString m_stringMember;
|
||||
};
|
||||
|
||||
|
||||
class InheritedDemoObj : public DemoPdmObject
|
||||
{
|
||||
public:
|
||||
|
||||
InheritedDemoObj()
|
||||
{
|
||||
this->addField(&m_texts, "Texts");
|
||||
this->addField(&m_childArrayField, "DemoPdmObjectects");
|
||||
this->addField(&m_ptrField, "m_ptrField");
|
||||
|
||||
}
|
||||
|
||||
caf::PdmDataValueField<QString > m_texts;
|
||||
caf::PdmChildArrayField<DemoPdmObject*> m_childArrayField;
|
||||
caf::PdmPtrField<InheritedDemoObj*> m_ptrField;
|
||||
};
|
||||
|
||||
|
||||
TEST(BaseTest, Delete)
|
||||
{
|
||||
DemoPdmObject* s2 = new DemoPdmObject;
|
||||
delete s2;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// TestPdmDataValueField
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, TestPdmDataValueField)
|
||||
{
|
||||
DemoPdmObject* a = new DemoPdmObject;
|
||||
|
||||
|
||||
ASSERT_DOUBLE_EQ(0.0, a->m_memberDoubleField.value());
|
||||
a->m_memberDoubleField.setValue(1.2);
|
||||
ASSERT_DOUBLE_EQ(1.2, a->m_memberDoubleField.value());
|
||||
|
||||
ASSERT_EQ(0, a->m_memberIntField.value());
|
||||
a->m_memberIntField.setValue(11);
|
||||
ASSERT_EQ(11, a->m_memberIntField.value());
|
||||
|
||||
ASSERT_TRUE(a->m_memberStringField.value().isEmpty());
|
||||
a->m_memberStringField.setValue("123");
|
||||
ASSERT_TRUE(a->m_memberStringField.value() == "123");
|
||||
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// TestPdmProxyValueField
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, TestPdmProxyValueField)
|
||||
{
|
||||
DemoPdmObject* a = new DemoPdmObject;
|
||||
|
||||
ASSERT_DOUBLE_EQ(2.1, a->m_proxyDoubleField.value());
|
||||
a->m_proxyDoubleField.setValue(1.2);
|
||||
ASSERT_DOUBLE_EQ(1.2, a->m_proxyDoubleField.value());
|
||||
|
||||
ASSERT_EQ(7, a->m_proxyIntField.value());
|
||||
a->m_proxyIntField.setValue(11);
|
||||
ASSERT_EQ(11, a->m_proxyIntField.value());
|
||||
|
||||
ASSERT_TRUE(a->m_proxyStringField.value() == "abba");
|
||||
a->m_proxyStringField.setValue("123");
|
||||
ASSERT_TRUE(a->m_proxyStringField.value() == "123");
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, TestPdmValueFieldInterface)
|
||||
{
|
||||
DemoPdmObject* a = new DemoPdmObject;
|
||||
|
||||
{
|
||||
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_proxyDoubleField"));
|
||||
QVariant newVal = 3.4;
|
||||
valField->setFromQVariant(newVal);
|
||||
QVariant var = valField->toQVariant();
|
||||
ASSERT_TRUE(newVal == var);
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_proxyIntField"));
|
||||
QVariant newVal = 3;
|
||||
valField->setFromQVariant(newVal);
|
||||
QVariant var = valField->toQVariant();
|
||||
ASSERT_TRUE(newVal == var);
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_proxyStringField"));
|
||||
QVariant newVal = "test";
|
||||
valField->setFromQVariant(newVal);
|
||||
QVariant var = valField->toQVariant();
|
||||
ASSERT_TRUE(newVal == var);
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_memberDoubleField"));
|
||||
QVariant newVal = 3.4;
|
||||
valField->setFromQVariant(newVal);
|
||||
QVariant var = valField->toQVariant();
|
||||
ASSERT_TRUE(newVal == var);
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_memberIntField"));
|
||||
QVariant newVal = 3;
|
||||
valField->setFromQVariant(newVal);
|
||||
QVariant var = valField->toQVariant();
|
||||
ASSERT_TRUE(newVal == var);
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_memberStringField"));
|
||||
QVariant newVal = "test";
|
||||
valField->setFromQVariant(newVal);
|
||||
QVariant var = valField->toQVariant();
|
||||
ASSERT_TRUE(newVal == var);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test of PdmDataValueField operations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, NormalPdmField)
|
||||
{
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A(const std::vector<double>& testValue) : field2(testValue), field3(field2) {}
|
||||
|
||||
caf::PdmDataValueField<std::vector<double> > field1;
|
||||
caf::PdmDataValueField<std::vector<double> > field2;
|
||||
caf::PdmDataValueField<std::vector<double> > field3;
|
||||
};
|
||||
|
||||
|
||||
std::vector<double> testValue;
|
||||
testValue.push_back(1.1);
|
||||
testValue.push_back(1.2);
|
||||
testValue.push_back(1.3);
|
||||
|
||||
std::vector<double> testValue2;
|
||||
testValue2.push_back(2.1);
|
||||
testValue2.push_back(2.2);
|
||||
testValue2.push_back(2.3);
|
||||
|
||||
// Constructors
|
||||
|
||||
A a(testValue);
|
||||
|
||||
EXPECT_EQ(1.3, a.field2.v()[2]);
|
||||
EXPECT_EQ(1.3, a.field3.v()[2]);
|
||||
EXPECT_EQ(size_t(0), a.field1().size());
|
||||
|
||||
// Operators
|
||||
// ==
|
||||
EXPECT_FALSE(a.field1 == a.field3);
|
||||
// = field to field
|
||||
a.field1 = a.field2;
|
||||
// ()
|
||||
EXPECT_EQ(1.3, a.field1()[2]);
|
||||
// = value to field
|
||||
a.field1 = testValue2;
|
||||
// v()
|
||||
EXPECT_EQ(2.3, a.field1.v()[2]);
|
||||
// ==
|
||||
a.field3 = a.field1;
|
||||
EXPECT_TRUE(a.field1 == a.field3);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test of PdmChildArrayField operations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
TEST(BaseTest, PdmChildArrayField)
|
||||
{
|
||||
InheritedDemoObj* ihd1 = new InheritedDemoObj;
|
||||
|
||||
caf::PdmPointer<DemoPdmObject> s1 = new DemoPdmObject;
|
||||
caf::PdmPointer<DemoPdmObject> s2 = new DemoPdmObject;
|
||||
caf::PdmPointer<DemoPdmObject> s3 = new DemoPdmObject;
|
||||
|
||||
// empty() number 1
|
||||
EXPECT_TRUE(ihd1->m_childArrayField.empty());
|
||||
EXPECT_EQ(size_t(0), ihd1->m_childArrayField.size());
|
||||
|
||||
// push_back()
|
||||
ihd1->m_childArrayField.push_back(s1);
|
||||
ihd1->m_childArrayField.push_back(s2);
|
||||
ihd1->m_childArrayField.push_back(s3);
|
||||
|
||||
// Parent field
|
||||
EXPECT_EQ(s1->parentField(), &(ihd1->m_childArrayField));
|
||||
|
||||
// size()
|
||||
EXPECT_EQ(size_t(3), ihd1->m_childArrayField.size());
|
||||
EXPECT_EQ(size_t(3), ihd1->m_childArrayField.size());
|
||||
|
||||
// operator[]
|
||||
EXPECT_EQ(s2, ihd1->m_childArrayField[1]);
|
||||
EXPECT_EQ(s3, ihd1->m_childArrayField[2]);
|
||||
|
||||
// childObjects
|
||||
std::vector<caf::PdmObjectHandle*> objects;
|
||||
ihd1->m_childArrayField.childObjects(&objects);
|
||||
EXPECT_EQ(size_t(3), objects.size());
|
||||
|
||||
// set()
|
||||
ihd1->m_childArrayField.set(1, NULL);
|
||||
EXPECT_TRUE(NULL == ihd1->m_childArrayField[1]);
|
||||
EXPECT_TRUE(s2->parentField() == NULL);
|
||||
|
||||
ihd1->m_childArrayField.removeChildObject(NULL);
|
||||
EXPECT_EQ(size_t(2), ihd1->m_childArrayField.size());
|
||||
EXPECT_EQ(s3, ihd1->m_childArrayField[1]);
|
||||
EXPECT_EQ(s1, ihd1->m_childArrayField[0]);
|
||||
|
||||
// insert()
|
||||
ihd1->m_childArrayField.insert(1, s2);
|
||||
EXPECT_EQ(s1, ihd1->m_childArrayField[0]);
|
||||
EXPECT_EQ(s2, ihd1->m_childArrayField[1]);
|
||||
EXPECT_EQ(s3, ihd1->m_childArrayField[2]);
|
||||
|
||||
EXPECT_TRUE(s2->parentField() == &(ihd1->m_childArrayField));
|
||||
|
||||
// erase (index)
|
||||
ihd1->m_childArrayField.erase(1);
|
||||
EXPECT_EQ(size_t(2), ihd1->m_childArrayField.size());
|
||||
EXPECT_EQ(s3, ihd1->m_childArrayField[1]);
|
||||
EXPECT_EQ(s1, ihd1->m_childArrayField[0]);
|
||||
|
||||
EXPECT_TRUE(s2->parentField() == NULL);
|
||||
|
||||
// clear()
|
||||
ihd1->m_childArrayField.clear();
|
||||
EXPECT_EQ(size_t(0), ihd1->m_childArrayField.size());
|
||||
|
||||
EXPECT_TRUE(s1->parentField() == NULL);
|
||||
|
||||
ihd1->m_childArrayField.push_back(s1);
|
||||
ihd1->m_childArrayField.push_back(s2);
|
||||
ihd1->m_childArrayField.push_back(s3);
|
||||
|
||||
ihd1->m_childArrayField.deleteAllChildObjects();
|
||||
EXPECT_EQ(size_t(0), ihd1->m_childArrayField.size());
|
||||
EXPECT_TRUE(s1 == NULL);
|
||||
EXPECT_TRUE(s2 == NULL);
|
||||
EXPECT_TRUE(s3 == NULL);
|
||||
}
|
||||
|
||||
|
||||
TEST(BaseTest, PdmChildArrayParentField)
|
||||
{
|
||||
// Test of instanciating a class with forward declare of object used in PdmChildArrayField and PdmChildField
|
||||
Parent* parentObj = new Parent;
|
||||
|
||||
delete parentObj;
|
||||
|
||||
}
|
||||
|
||||
#include "Child.h"
|
||||
|
||||
TEST(BaseTest, PdmPointersFieldInsertVector)
|
||||
{
|
||||
Parent* ihd1 = new Parent;
|
||||
|
||||
Child* s1 = new Child;
|
||||
Child* s2 = new Child;
|
||||
Child* s3 = new Child;
|
||||
|
||||
std::vector<caf::PdmPointer<Child> > typedObjects;
|
||||
typedObjects.push_back(s1);
|
||||
typedObjects.push_back(s2);
|
||||
typedObjects.push_back(s3);
|
||||
|
||||
ihd1->m_simpleObjectsField.push_back(new Child);
|
||||
ihd1->m_simpleObjectsField.insert(ihd1->m_simpleObjectsField.size(), typedObjects);
|
||||
EXPECT_EQ(size_t(4), ihd1->m_simpleObjectsField.size());
|
||||
EXPECT_EQ(ihd1->m_simpleObjectsField[3], s3);
|
||||
|
||||
delete ihd1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// PdmChildArrayFieldHandle
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, PdmChildArrayFieldHandle)
|
||||
{
|
||||
|
||||
// virtual size_t size() const = 0;
|
||||
// virtual bool empty() const = 0;
|
||||
// virtual void clear() = 0;
|
||||
// virtual PdmObject* createAppendObject(int indexAfter) = 0;
|
||||
// virtual void erase(size_t index) = 0;
|
||||
// virtual void deleteAllChildObjects() = 0;
|
||||
//
|
||||
// virtual PdmObject* at(size_t index) = 0;
|
||||
//
|
||||
// bool hasSameFieldCountForAllObjects();
|
||||
DemoPdmObject* s0 = new DemoPdmObject;
|
||||
s0->m_memberDoubleField = 1000;
|
||||
|
||||
DemoPdmObject* s1 = new DemoPdmObject;
|
||||
s1->m_memberDoubleField = 1000;
|
||||
|
||||
DemoPdmObject* s2 = new DemoPdmObject;
|
||||
s2->m_memberDoubleField = 2000;
|
||||
|
||||
DemoPdmObject* s3 = new DemoPdmObject;
|
||||
s3->m_memberDoubleField = 3000;
|
||||
|
||||
InheritedDemoObj* ihd1 = new InheritedDemoObj;
|
||||
caf::PdmChildArrayFieldHandle* listField = &(ihd1->m_childArrayField);
|
||||
|
||||
EXPECT_EQ(0, listField->size());
|
||||
EXPECT_TRUE(listField->hasSameFieldCountForAllObjects());
|
||||
EXPECT_TRUE(listField->empty());
|
||||
|
||||
listField->insertAt(0, s0);
|
||||
EXPECT_EQ(1, listField->size());
|
||||
EXPECT_TRUE(listField->hasSameFieldCountForAllObjects());
|
||||
EXPECT_FALSE(listField->empty());
|
||||
|
||||
ihd1->m_childArrayField.push_back(s1);
|
||||
ihd1->m_childArrayField.push_back(s2);
|
||||
ihd1->m_childArrayField.push_back(s3);
|
||||
|
||||
EXPECT_EQ(4, listField->size());
|
||||
EXPECT_TRUE(listField->hasSameFieldCountForAllObjects());
|
||||
EXPECT_FALSE(listField->empty());
|
||||
|
||||
listField->erase(0);
|
||||
EXPECT_EQ(3, listField->size());
|
||||
EXPECT_TRUE(listField->hasSameFieldCountForAllObjects());
|
||||
EXPECT_FALSE(listField->empty());
|
||||
|
||||
listField->deleteAllChildObjects();
|
||||
EXPECT_EQ(0, listField->size());
|
||||
EXPECT_TRUE(listField->hasSameFieldCountForAllObjects());
|
||||
EXPECT_TRUE(listField->empty());
|
||||
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Test of PdmChildField
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
TEST(BaseTest, PdmChildField)
|
||||
{
|
||||
class A {
|
||||
public:
|
||||
A(Child* a) :field2(a) {}
|
||||
|
||||
caf::PdmChildField<Child*> field2;
|
||||
int b;
|
||||
};
|
||||
|
||||
{
|
||||
Parent* parent = new Parent;
|
||||
Child* testValue = new Child;
|
||||
|
||||
// Constructor assignment
|
||||
A a(testValue);
|
||||
EXPECT_EQ(testValue, a.field2.v());
|
||||
|
||||
// Guarded
|
||||
delete testValue;
|
||||
EXPECT_EQ((Child*)0, a.field2);
|
||||
}
|
||||
{
|
||||
A a(NULL);
|
||||
Child* c2 = new Child;
|
||||
// Assign
|
||||
a.field2 = c2;
|
||||
// Access
|
||||
EXPECT_EQ(c2, a.field2.v());
|
||||
EXPECT_EQ(c2, a.field2);
|
||||
EXPECT_EQ(c2, a.field2.value());
|
||||
EXPECT_TRUE(c2 == a.field2);
|
||||
|
||||
|
||||
std::vector<caf::PdmObjectHandle*> objects;
|
||||
a.field2.childObjects(&objects);
|
||||
EXPECT_EQ((size_t)1, objects.size());
|
||||
EXPECT_EQ(c2, objects[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(BaseTest, PdmPtrField)
|
||||
{
|
||||
InheritedDemoObj* ihd1 = new InheritedDemoObj;
|
||||
InheritedDemoObj* ihd2 = new InheritedDemoObj;
|
||||
|
||||
// Direct access
|
||||
EXPECT_EQ((InheritedDemoObj*)NULL, ihd1->m_ptrField);
|
||||
|
||||
InheritedDemoObj* accessedIhd = NULL;
|
||||
|
||||
// Assignment
|
||||
ihd1->m_ptrField = ihd1;
|
||||
accessedIhd = ihd1->m_ptrField;
|
||||
EXPECT_EQ(ihd1, accessedIhd);
|
||||
|
||||
ihd1->m_ptrField = caf::PdmPointer<InheritedDemoObj>(ihd2);
|
||||
accessedIhd = ihd1->m_ptrField;
|
||||
EXPECT_EQ(ihd2, accessedIhd);
|
||||
|
||||
// Access
|
||||
accessedIhd = ihd1->m_ptrField; // Conversion
|
||||
EXPECT_EQ(ihd2, accessedIhd);
|
||||
accessedIhd = ihd1->m_ptrField.value();
|
||||
EXPECT_EQ(ihd2, accessedIhd);
|
||||
accessedIhd = ihd1->m_ptrField.v();
|
||||
|
||||
caf::PdmPointer<InheritedDemoObj> accessedPdmPtr;
|
||||
EXPECT_EQ(ihd2, accessedIhd);
|
||||
accessedPdmPtr = ihd1->m_ptrField.v();
|
||||
EXPECT_EQ(ihd2, accessedPdmPtr.p());
|
||||
accessedPdmPtr = ihd1->m_ptrField();
|
||||
EXPECT_EQ(ihd2, accessedPdmPtr.p());
|
||||
|
||||
// Operator ==
|
||||
EXPECT_TRUE(ihd1->m_ptrField == ihd2);
|
||||
EXPECT_FALSE(ihd1->m_ptrField == ihd1);
|
||||
|
||||
EXPECT_TRUE(ihd1->m_ptrField == caf::PdmPointer<InheritedDemoObj>(ihd2));
|
||||
|
||||
// Generic access
|
||||
std::vector<caf::PdmObjectHandle*> objects;
|
||||
ihd1->m_ptrField.ptrReferencedObjects(&objects);
|
||||
EXPECT_EQ(1, objects.size());
|
||||
EXPECT_EQ(ihd2, objects[0]);
|
||||
|
||||
// Operator ->
|
||||
ihd1->m_ptrField->m_texts = "Hei PtrField";
|
||||
EXPECT_TRUE(ihd1->m_ptrField->m_texts == "Hei PtrField");
|
||||
|
||||
// Refrencing system
|
||||
std::vector<caf::PdmFieldHandle*> ptrFields;
|
||||
ihd2->referringPtrFields(ptrFields);
|
||||
EXPECT_EQ(1, ptrFields.size());
|
||||
EXPECT_EQ(&(ihd1->m_ptrField), ptrFields[0]);
|
||||
|
||||
objects.clear();
|
||||
ihd2->objectsWithReferringPtrFields(objects);
|
||||
EXPECT_EQ(1, objects.size());
|
||||
EXPECT_EQ(ihd1, objects[0]);
|
||||
|
||||
|
||||
delete ihd1;
|
||||
delete ihd2;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Tests the features of PdmPointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST(BaseTest, PdmPointer)
|
||||
{
|
||||
InheritedDemoObj * d = new InheritedDemoObj;
|
||||
|
||||
{
|
||||
caf::PdmPointer<InheritedDemoObj> p;
|
||||
EXPECT_TRUE(p == NULL);
|
||||
}
|
||||
|
||||
{
|
||||
caf::PdmPointer<InheritedDemoObj> p(d);
|
||||
caf::PdmPointer<InheritedDemoObj> p2(p);
|
||||
|
||||
EXPECT_TRUE(p == d && p2 == d);
|
||||
EXPECT_TRUE(p.p() == d);
|
||||
p = 0;
|
||||
EXPECT_TRUE(p == NULL);
|
||||
EXPECT_TRUE(p.isNull());
|
||||
EXPECT_TRUE(p2 == d);
|
||||
p = p2;
|
||||
EXPECT_TRUE(p == d);
|
||||
delete d;
|
||||
EXPECT_TRUE(p.isNull() && p2.isNull());
|
||||
}
|
||||
|
||||
caf::PdmPointer<DemoPdmObject> p3(new DemoPdmObject());
|
||||
|
||||
delete p3;
|
||||
|
||||
}
|
||||
|
||||
|
||||
+13
-33
@@ -35,42 +35,22 @@
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cafPdmUiTreeEditorHandle.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* PdmUiTreeEditorHandle::getOrCreateWidget(QWidget* parent)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (m_widget.isNull())
|
||||
{
|
||||
m_widget = this->createWidget(parent);
|
||||
}
|
||||
return m_widget;
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
char text[5];
|
||||
std::cin.getline(text, 5);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeEditorHandle::setPdmItemRoot(PdmUiItem* root)
|
||||
{
|
||||
cleanupBeforeSettingPdmObject();
|
||||
|
||||
this->bindToPdmItem(root);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiItem* PdmUiTreeEditorHandle::pdmItemRoot()
|
||||
{
|
||||
return this->pdmItem();
|
||||
}
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,108 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
#ifndef CAF_IS_DEFINING_PDM_FIELD
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "cafPdmValueField.h"
|
||||
#include "cafInternalPdmValueFieldSpecializations.h"
|
||||
|
||||
#include <vector>
|
||||
#include <QVariant>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObjectHandle;
|
||||
|
||||
//==================================================================================================
|
||||
/// 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 DataType >
|
||||
class PdmDataValueField : public PdmValueField
|
||||
{
|
||||
public:
|
||||
typedef DataType FieldDataType;
|
||||
PdmDataValueField() {}
|
||||
PdmDataValueField(const PdmDataValueField& other) { m_fieldValue = other.m_fieldValue; }
|
||||
explicit PdmDataValueField(const DataType& fieldValue) { m_fieldValue = fieldValue; }
|
||||
virtual ~PdmDataValueField() {}
|
||||
|
||||
// Assignment
|
||||
|
||||
PdmDataValueField& operator= (const PdmDataValueField& other) { m_fieldValue = other.m_fieldValue; return *this; }
|
||||
PdmDataValueField& operator= (const DataType& fieldValue) { m_fieldValue = fieldValue; return *this; }
|
||||
|
||||
// Basic access
|
||||
|
||||
DataType value() const { return m_fieldValue; }
|
||||
void setValue(const DataType& fieldValue) { m_fieldValue = fieldValue; }
|
||||
|
||||
// Implementation of PdmValueField interface
|
||||
|
||||
virtual QVariant toQVariant() const { return PdmValueFieldSpecialization<DataType>::convert(m_fieldValue); }
|
||||
virtual void setFromQVariant(const QVariant& variant) { PdmValueFieldSpecialization<DataType>::setFromVariant(variant, m_fieldValue); }
|
||||
virtual bool isReadOnly() const { return false; }
|
||||
|
||||
// Access operators
|
||||
|
||||
/*Conversion */ operator DataType () const { return m_fieldValue; }
|
||||
const DataType& operator()() const { return m_fieldValue; }
|
||||
|
||||
DataType& v() { return m_fieldValue; } // This one breaches encapsulation. Remove ?
|
||||
const DataType& v() const { return m_fieldValue; }
|
||||
|
||||
bool operator== (const DataType& fieldValue) const { return m_fieldValue == fieldValue; }
|
||||
|
||||
protected:
|
||||
DataType m_fieldValue;
|
||||
|
||||
// Default value stuff.
|
||||
//
|
||||
// This is not used enough. Remove when dust has settled.
|
||||
// ResInsight uses at one point to find whether the value is changed by the user
|
||||
public:
|
||||
const DataType& defaultValue() const { return m_defaultFieldValue; }
|
||||
void setDefaultValue(const DataType& val) { m_defaultFieldValue = val; }
|
||||
protected:
|
||||
DataType m_defaultFieldValue;
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmFieldCapability
|
||||
{
|
||||
public:
|
||||
PdmFieldCapability() {}
|
||||
virtual ~PdmFieldCapability() {}
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "cafPdmFieldHandle.h"
|
||||
|
||||
#include "cafPdmFieldCapability.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
#if 0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmFieldHandle::assertValid() const
|
||||
{
|
||||
if (m_keyword == "UNDEFINED")
|
||||
{
|
||||
std::cout << "PdmField: Detected use of non-initialized field. Did you forget to do CAF_PDM_InitField() on this field ?\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PdmXmlSerializable::isValidXmlElementName(m_keyword))
|
||||
{
|
||||
std::cout << "PdmField: The supplied keyword: \"" << m_keyword.toStdString() << "\" is an invalid XML element name, and will break your file format!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmFieldHandle::setKeyword(const QString& keyword)
|
||||
{
|
||||
m_keyword = keyword;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmFieldHandle::hasChildObjects()
|
||||
{
|
||||
std::vector<PdmObjectHandle*> children;
|
||||
this->childObjects(&children);
|
||||
return (children.size() > 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmFieldHandle::~PdmFieldHandle()
|
||||
{
|
||||
for (size_t i = 0; i < m_capabilities.size(); ++i)
|
||||
{
|
||||
if (m_capabilities[i].second) delete m_capabilities[i].first;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmFieldHandle::hasPtrReferencedObjects()
|
||||
{
|
||||
std::vector<PdmObjectHandle*> ptrReffedObjs;
|
||||
this->ptrReferencedObjects(&ptrReffedObjs);
|
||||
return (ptrReffedObjs.size() > 0);
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmBase.h"
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObjectHandle;
|
||||
|
||||
//==================================================================================================
|
||||
/// Base class for all fields, making it possible to handle them generically
|
||||
//==================================================================================================
|
||||
class PdmFieldCapability;
|
||||
|
||||
class PdmFieldHandle
|
||||
{
|
||||
public:
|
||||
PdmFieldHandle() { m_ownerObject = NULL; }
|
||||
virtual ~PdmFieldHandle();
|
||||
|
||||
QString keyword() const { return m_keyword; }
|
||||
|
||||
PdmObjectHandle* ownerObject() { return m_ownerObject; }
|
||||
|
||||
// Child objects
|
||||
bool hasChildObjects();
|
||||
virtual void childObjects(std::vector<PdmObjectHandle*>*) { }
|
||||
virtual void removeChildObject(PdmObjectHandle*) { }
|
||||
|
||||
// Ptr referenced objects
|
||||
bool hasPtrReferencedObjects();
|
||||
virtual void ptrReferencedObjects(std::vector<PdmObjectHandle*>*) { }
|
||||
|
||||
// Capabilities
|
||||
void addCapability(PdmFieldCapability* capability, bool takeOwnership) { m_capabilities.push_back(std::make_pair(capability, takeOwnership)); }
|
||||
|
||||
template <typename CapabilityType>
|
||||
CapabilityType* capability();
|
||||
|
||||
private:
|
||||
PDM_DISABLE_COPY_AND_ASSIGN(PdmFieldHandle);
|
||||
|
||||
friend class PdmObjectHandle; // Give access to m_ownerObject and set Keyword
|
||||
void setKeyword(const QString& keyword);
|
||||
PdmObjectHandle* m_ownerObject;
|
||||
|
||||
QString m_keyword;
|
||||
|
||||
std::vector<std::pair<PdmFieldCapability*, bool> > m_capabilities;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename CapabilityType>
|
||||
CapabilityType* PdmFieldHandle::capability()
|
||||
{
|
||||
for (size_t i = 0; i < m_capabilities.size(); ++i)
|
||||
{
|
||||
CapabilityType* capability = dynamic_cast<CapabilityType*>(m_capabilities[i].first);
|
||||
if (capability) return capability;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObjectCapability
|
||||
{
|
||||
public:
|
||||
PdmObjectCapability() {}
|
||||
virtual ~PdmObjectCapability() {}
|
||||
|
||||
};
|
||||
|
||||
} // End namespace caf
|
||||
@@ -0,0 +1,149 @@
|
||||
|
||||
#include "cafPdmObjectHandle.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmObjectCapability.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectHandle::~PdmObjectHandle()
|
||||
{
|
||||
for (size_t i = 0; i < m_capabilities.size(); ++i)
|
||||
{
|
||||
if (m_capabilities[i].second) delete m_capabilities[i].first;
|
||||
}
|
||||
|
||||
// Set all guarded pointers pointing to this to NULL
|
||||
|
||||
std::set<PdmObjectHandle**>::iterator it;
|
||||
for (it = m_pointersReferencingMe.begin(); it != m_pointersReferencingMe.end() ; ++it)
|
||||
{
|
||||
(**it) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectHandle::fields(std::vector<PdmFieldHandle*>& fields) const
|
||||
{
|
||||
fields = m_fields;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectHandle::setAsParentField(PdmFieldHandle* parentField)
|
||||
{
|
||||
assert(m_parentField == NULL);
|
||||
m_parentField = parentField;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectHandle::removeAsParentField(PdmFieldHandle* parentField)
|
||||
{
|
||||
assert(m_parentField == parentField);
|
||||
m_parentField = NULL;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectHandle::addReferencingPtrField(PdmFieldHandle* fieldReferringToMe)
|
||||
{
|
||||
if (fieldReferringToMe != NULL) m_referencingPtrFields.insert(fieldReferringToMe);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectHandle::removeReferencingPtrField(PdmFieldHandle* fieldReferringToMe)
|
||||
{
|
||||
if (fieldReferringToMe != NULL) m_referencingPtrFields.erase(fieldReferringToMe);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Appends pointers to all the PdmPtrFields containing a pointer to this object.
|
||||
/// As the PdmPtrArrayFields can hold several pointers to the same object, the returned vector can
|
||||
/// contain multiple pointers to the same field.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectHandle::referringPtrFields(std::vector<PdmFieldHandle*>& fieldsReferringToMe) const
|
||||
{
|
||||
std::multiset<PdmFieldHandle*>::const_iterator it;
|
||||
|
||||
for (it = m_referencingPtrFields.begin(); it != m_referencingPtrFields.end(); ++it)
|
||||
{
|
||||
fieldsReferringToMe.push_back(*it);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectHandle::objectsWithReferringPtrFields(std::vector<PdmObjectHandle*>& objects) const
|
||||
{
|
||||
std::vector<caf::PdmFieldHandle*> parentFields;
|
||||
this->referringPtrFields(parentFields);
|
||||
size_t i;
|
||||
for (i = 0; i < parentFields.size(); i++)
|
||||
{
|
||||
objects.push_back(parentFields[i]->ownerObject());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectHandle::addField(PdmFieldHandle* field, const QString& keyword)
|
||||
{
|
||||
field->m_ownerObject = this;
|
||||
|
||||
assert(!keyword.isEmpty());
|
||||
assert(this->findField(keyword) == NULL);
|
||||
|
||||
field->setKeyword(keyword);
|
||||
m_fields.push_back(field);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmFieldHandle* PdmObjectHandle::findField(const QString& keyword)
|
||||
{
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
this->fields(fields);
|
||||
|
||||
for (size_t it = 0; it < fields.size(); it++)
|
||||
{
|
||||
PdmFieldHandle* field = fields[it];
|
||||
if (field->keyword() == keyword)
|
||||
{
|
||||
return field;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmFieldHandle* PdmObjectHandle::parentField() const
|
||||
{
|
||||
return m_parentField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // End namespace caf
|
||||
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmBase.h"
|
||||
|
||||
class QString;
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObjectCapability;
|
||||
class PdmFieldHandle;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// The base class of all objects
|
||||
//==================================================================================================
|
||||
class PdmObjectHandle
|
||||
{
|
||||
public:
|
||||
PdmObjectHandle() { m_parentField = NULL; }
|
||||
virtual ~PdmObjectHandle();
|
||||
|
||||
/// The registered fields contained in this PdmObject.
|
||||
void fields(std::vector<PdmFieldHandle*>& fields) const;
|
||||
PdmFieldHandle* findField(const QString& keyword);
|
||||
|
||||
/// The field referencing this object as a child
|
||||
PdmFieldHandle* parentField() const;
|
||||
|
||||
// PtrReferences
|
||||
/// The PdmPtrField's containing pointers to this PdmObjecthandle
|
||||
/// Use ownerObject() on the fieldHandle to get the PdmObjectHandle
|
||||
void referringPtrFields(std::vector<PdmFieldHandle*>& fieldsReferringToMe) const;
|
||||
/// Convenience method to get the objects pointing to this field
|
||||
void objectsWithReferringPtrFields(std::vector<PdmObjectHandle*>& objects) const;
|
||||
|
||||
// Object capabilities
|
||||
void addCapability(PdmObjectCapability* capability, bool takeOwnership) { m_capabilities.push_back(std::make_pair(capability, takeOwnership)); }
|
||||
|
||||
template <typename CapabilityType>
|
||||
CapabilityType* capability()
|
||||
{
|
||||
for (size_t i = 0; i < m_capabilities.size(); ++i)
|
||||
{
|
||||
CapabilityType* capability = dynamic_cast<CapabilityType*>(m_capabilities[i].first);
|
||||
if (capability) return capability;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
void addField(PdmFieldHandle* field, const QString& keyword);
|
||||
|
||||
private:
|
||||
PDM_DISABLE_COPY_AND_ASSIGN(PdmObjectHandle);
|
||||
|
||||
// Fields
|
||||
std::vector<PdmFieldHandle*> m_fields;
|
||||
|
||||
// Capabilities
|
||||
std::vector<std::pair<PdmObjectCapability*, bool> > m_capabilities;
|
||||
|
||||
// Child/Parent Relationships
|
||||
void setAsParentField(PdmFieldHandle* parentField);
|
||||
void removeAsParentField(PdmFieldHandle* parentField);
|
||||
PdmFieldHandle* m_parentField;
|
||||
|
||||
// PtrReferences
|
||||
void addReferencingPtrField(PdmFieldHandle* fieldReferringToMe);
|
||||
void removeReferencingPtrField(PdmFieldHandle* fieldReferringToMe);
|
||||
std::multiset<PdmFieldHandle*> m_referencingPtrFields;
|
||||
|
||||
// Give access to set/removeAsParentField
|
||||
template < class T > friend class PdmChildArrayField;
|
||||
template < class T > friend class PdmChildField;
|
||||
template < class T > friend class PdmPtrField;
|
||||
template < class T > friend class PdmField; // For backwards compatibility layer
|
||||
|
||||
template < class T > friend class PdmFieldXmlCap;
|
||||
|
||||
static const char* classKeywordStatic() { return "PdmObjectHandle";} // For PdmXmlFieldCap to be able to handle fields of PdmObjectHandle directly
|
||||
|
||||
// Support system for PdmPointer
|
||||
friend class PdmPointerImpl;
|
||||
std::set<PdmObjectHandle**> m_pointersReferencingMe;
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
+3
-3
@@ -34,7 +34,7 @@
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
namespace caf
|
||||
@@ -44,7 +44,7 @@ namespace caf
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmPointerImpl::addReference(PdmObject ** addressToObjectPointer)
|
||||
void PdmPointerImpl::addReference(PdmObjectHandle ** addressToObjectPointer)
|
||||
{
|
||||
if (*addressToObjectPointer) (*addressToObjectPointer)->m_pointersReferencingMe.insert(addressToObjectPointer);
|
||||
}
|
||||
@@ -52,7 +52,7 @@ void PdmPointerImpl::addReference(PdmObject ** addressToObjectPointer)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmPointerImpl::removeReference(PdmObject ** addressToObjectPointer)
|
||||
void PdmPointerImpl::removeReference(PdmObjectHandle ** addressToObjectPointer)
|
||||
{
|
||||
if (*addressToObjectPointer) (*addressToObjectPointer)->m_pointersReferencingMe.erase(addressToObjectPointer);
|
||||
}
|
||||
+15
-10
@@ -37,11 +37,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject;
|
||||
class PdmObjectHandle;
|
||||
|
||||
//==================================================================================================
|
||||
/// Helper class for the PdmPointer class
|
||||
@@ -58,8 +60,8 @@ class PdmPointerImpl
|
||||
{
|
||||
private:
|
||||
template < class T > friend class PdmPointer;
|
||||
static void addReference(PdmObject ** addressToObjectPointer);
|
||||
static void removeReference(PdmObject ** addressToObjectPointer);
|
||||
static void addReference(PdmObjectHandle ** addressToObjectPointer);
|
||||
static void removeReference(PdmObjectHandle ** addressToObjectPointer);
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
@@ -74,7 +76,7 @@ private:
|
||||
template < class T >
|
||||
class PdmPointer
|
||||
{
|
||||
PdmObject* m_object;
|
||||
PdmObjectHandle* m_object;
|
||||
public :
|
||||
inline PdmPointer () : m_object(NULL) { }
|
||||
inline PdmPointer ( T * p ) : m_object(p) { PdmPointerImpl::addReference(&m_object); }
|
||||
@@ -82,18 +84,21 @@ public :
|
||||
{ PdmPointerImpl::addReference(&m_object); }
|
||||
inline ~PdmPointer () { PdmPointerImpl::removeReference(&m_object); }
|
||||
|
||||
T* p() const { return static_cast<T*>(const_cast<PdmObject*>(m_object)); }
|
||||
T* p() const { return static_cast<T*>(const_cast<PdmObjectHandle*>(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)); }
|
||||
operator T* () const { return static_cast<T*>(const_cast<PdmObjectHandle*>(m_object)); }
|
||||
T& operator* () const { return *static_cast<T*>(const_cast<PdmObjectHandle*>(m_object)); }
|
||||
T* operator->() const { return static_cast<T*>(const_cast<PdmObjectHandle*>(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); }
|
||||
PdmObjectHandle* rawPtr() const { return m_object; }
|
||||
void setRawPtr( PdmObjectHandle* p) { if (m_object != p) PdmPointerImpl::removeReference(&m_object); m_object = p; PdmPointerImpl::addReference(&m_object); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include "cafPdmValueField.h"
|
||||
#include "cafInternalPdmValueFieldSpecializations.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
//==================================================================================================
|
||||
/// Field class encapsulating data access through object setter/getter 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 DataType >
|
||||
class PdmProxyValueField : public PdmValueField
|
||||
{
|
||||
public:
|
||||
typedef DataType FieldDataType;
|
||||
PdmProxyValueField() { m_valueSetter = NULL; m_valueGetter = NULL; }
|
||||
virtual ~PdmProxyValueField() { if (m_valueSetter) delete m_valueSetter; if (m_valueGetter) delete m_valueGetter; }
|
||||
|
||||
// Assignment
|
||||
|
||||
PdmProxyValueField& operator= (const DataType& newFieldValue) { setValue(newFieldValue); return *this; }
|
||||
|
||||
// Basic access
|
||||
|
||||
void setValue(const DataType& fieldValue) { if (m_valueSetter) m_valueSetter->setValue(fieldValue); }
|
||||
DataType value() const { assert(m_valueGetter); return m_valueGetter->getValue(); }
|
||||
|
||||
// Implementation of PdmValueField interface
|
||||
|
||||
virtual QVariant toQVariant() const { DataType val = value(); return PdmValueFieldSpecialization<DataType>::convert(val); }
|
||||
virtual void setFromQVariant(const QVariant& variant) { DataType val; PdmValueFieldSpecialization<DataType>::setFromVariant(variant, val); setValue(val); }
|
||||
virtual bool isReadOnly() const { if (!m_valueSetter) { return true; } else { return false; } }
|
||||
|
||||
// Access operators
|
||||
|
||||
DataType operator()() const { return value(); }
|
||||
DataType v() const { return value(); }
|
||||
bool operator== (const DataType& otherValue) const { return value() == otherValue; }
|
||||
|
||||
private:
|
||||
PDM_DISABLE_COPY_AND_ASSIGN(PdmProxyValueField);
|
||||
|
||||
// Proxy Field stuff to handle the method pointers
|
||||
// The public registering methods must be written below the private classes
|
||||
// For some reason. Forward declaration did some weirdness.
|
||||
private:
|
||||
class SetValueInterface
|
||||
{
|
||||
public:
|
||||
virtual ~SetValueInterface() {}
|
||||
virtual void setValue(const DataType& value) = 0;
|
||||
};
|
||||
|
||||
template <typename ObjectType>
|
||||
class SetterMethodCB : public SetValueInterface
|
||||
{
|
||||
public:
|
||||
typedef void (ObjectType::*SetterMethodType)(const DataType& value);
|
||||
|
||||
SetterMethodCB(ObjectType* obj, SetterMethodType setterMethod)
|
||||
{
|
||||
m_setterMethod = setterMethod;
|
||||
m_obj = obj;
|
||||
}
|
||||
|
||||
void setValue(const DataType& value)
|
||||
{
|
||||
(m_obj->*m_setterMethod)(value);
|
||||
}
|
||||
|
||||
private:
|
||||
SetterMethodType m_setterMethod;
|
||||
PdmPointer<ObjectType> m_obj;
|
||||
};
|
||||
|
||||
class GetValueInterface
|
||||
{
|
||||
public:
|
||||
virtual ~GetValueInterface() {}
|
||||
virtual DataType getValue() const = 0;
|
||||
};
|
||||
|
||||
template <typename ObjectType>
|
||||
class GetterMethodCB : public GetValueInterface
|
||||
{
|
||||
public:
|
||||
typedef DataType (ObjectType::*GetterMethodType)() const;
|
||||
|
||||
GetterMethodCB(ObjectType* obj, GetterMethodType setterMethod)
|
||||
{
|
||||
m_getterMethod = setterMethod;
|
||||
m_obj = obj;
|
||||
}
|
||||
|
||||
DataType getValue() const
|
||||
{
|
||||
return (m_obj->*m_getterMethod)();
|
||||
}
|
||||
|
||||
private:
|
||||
GetterMethodType m_getterMethod;
|
||||
PdmPointer< ObjectType> m_obj;
|
||||
};
|
||||
|
||||
public:
|
||||
template <typename OwnerObjectType>
|
||||
void registerSetMethod(OwnerObjectType* obj, typename SetterMethodCB< OwnerObjectType>::SetterMethodType setterMethod)
|
||||
{
|
||||
if (m_valueSetter) delete m_valueSetter;
|
||||
m_valueSetter = new SetterMethodCB<OwnerObjectType>(obj, setterMethod);
|
||||
}
|
||||
|
||||
template <typename OwnerObjectType>
|
||||
void registerGetMethod(OwnerObjectType* obj, typename GetterMethodCB< OwnerObjectType>::GetterMethodType getterMethod)
|
||||
{
|
||||
if (m_valueGetter) delete m_valueGetter;
|
||||
m_valueGetter = new GetterMethodCB<OwnerObjectType>(obj, getterMethod);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SetValueInterface* m_valueSetter;
|
||||
GetValueInterface* m_valueGetter;
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include <assert.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
template< typename T> class PdmFieldXmlCap;
|
||||
|
||||
//==================================================================================================
|
||||
/// A field that contains a pointer to a PdmObjectHandle derived object.
|
||||
/// The referenced object will not be printed in the XML-output yet, but
|
||||
/// it is intended to be written as a reference (by path from common root)
|
||||
/// This field has nothing to do with ownership at all, and is not a part of the
|
||||
/// parent-child relations induced by the other PdmChildField<PdmPtrType*> PdmChildArrayField<PdmPtrType*>
|
||||
/// The pointer is guarded, meaning that it will be set to NULL if the object pointed to
|
||||
/// is deleted.
|
||||
//==================================================================================================
|
||||
|
||||
template<typename DataType>
|
||||
class PdmPtrField : public PdmFieldHandle
|
||||
{
|
||||
public:
|
||||
PdmPtrField()
|
||||
{
|
||||
bool doNotUsePdmPtrFieldForAnythingButPointersToPdmObject = false; assert(doNotUsePdmPtrFieldForAnythingButPointersToPdmObject);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DataType >
|
||||
class PdmPtrField <DataType*> : public PdmFieldHandle
|
||||
{
|
||||
typedef DataType* DataTypePtr;
|
||||
public:
|
||||
typedef PdmPointer<DataType> FieldDataType;
|
||||
|
||||
PdmPtrField() { }
|
||||
explicit PdmPtrField(const DataTypePtr& fieldValue);
|
||||
virtual ~PdmPtrField();
|
||||
|
||||
// Assignment
|
||||
|
||||
PdmPtrField& operator= (const DataTypePtr & fieldValue);
|
||||
PdmPtrField& operator= (const FieldDataType & fieldValue);
|
||||
|
||||
// Basic access
|
||||
|
||||
DataType* value() const { return m_fieldValue; }
|
||||
void setValue(const DataTypePtr& fieldValue);
|
||||
|
||||
// Access operators
|
||||
|
||||
/*Conversion*/ 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; }
|
||||
|
||||
// Ptr referenced objects
|
||||
|
||||
virtual void ptrReferencedObjects(std::vector<PdmObjectHandle*>* objectsToFill);
|
||||
|
||||
private:
|
||||
PDM_DISABLE_COPY_AND_ASSIGN(PdmPtrField);
|
||||
|
||||
friend class PdmFieldXmlCap< PdmPtrField <DataType*> >;
|
||||
void setRawPtr(PdmObjectHandle* obj);
|
||||
PdmPointer<DataType> m_fieldValue;
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafPdmPtrField.inl"
|
||||
|
||||
#include <QMetaType>
|
||||
Q_DECLARE_METATYPE(caf::PdmPointer<caf::PdmObjectHandle>);
|
||||
@@ -0,0 +1,88 @@
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmPtrField<DataType*>::PdmPtrField(const DataTypePtr& fieldValue)
|
||||
{
|
||||
m_fieldValue = fieldValue;
|
||||
if (m_fieldValue != NULL) m_fieldValue->addReferencingPtrField(this);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmPtrField<DataType*>::~PdmPtrField()
|
||||
{
|
||||
if (!m_fieldValue.isNull()) m_fieldValue.rawPtr()->removeReferencingPtrField(this);
|
||||
m_fieldValue.setRawPtr(NULL);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
void PdmPtrField<DataType*>::setValue(const DataTypePtr& fieldValue)
|
||||
{
|
||||
if (m_fieldValue) m_fieldValue->removeReferencingPtrField(this);
|
||||
m_fieldValue = fieldValue;
|
||||
if (m_fieldValue != NULL) m_fieldValue->addReferencingPtrField(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
void PdmPtrField<DataType*>::setRawPtr(PdmObjectHandle* obj)
|
||||
{
|
||||
if (m_fieldValue.notNull()) m_fieldValue.rawPtr()->removeReferencingPtrField(this);
|
||||
m_fieldValue.setRawPtr(obj);
|
||||
if (m_fieldValue.notNull()) m_fieldValue.rawPtr()->addReferencingPtrField(this);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmPtrField<DataType*>& PdmPtrField<DataType*>::operator=(const DataTypePtr & fieldValue)
|
||||
{
|
||||
if (m_fieldValue) m_fieldValue->removeReferencingPtrField(this);
|
||||
m_fieldValue = fieldValue;
|
||||
if (m_fieldValue != NULL) m_fieldValue->addReferencingPtrField(this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
caf::PdmPtrField<DataType*>& PdmPtrField<DataType*>::operator=(const FieldDataType & fieldValue)
|
||||
{
|
||||
if (m_fieldValue) m_fieldValue->removeReferencingPtrField(this);
|
||||
m_fieldValue = fieldValue;
|
||||
if (m_fieldValue != NULL) m_fieldValue->addReferencingPtrField(this);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
void PdmPtrField<DataType*>::ptrReferencedObjects(std::vector<PdmObjectHandle*>* objectsToFill)
|
||||
{
|
||||
if (m_fieldValue.rawPtr())
|
||||
{
|
||||
objectsToFill->push_back(m_fieldValue.rawPtr());
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cafPdmReferenceHelper.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString PdmReferenceHelper::referenceFromRootToObject(PdmObjectHandle* root, PdmObjectHandle* obj)
|
||||
{
|
||||
QStringList objectNames = referenceFromRootToObjectAsStringList(root, obj);
|
||||
|
||||
QString completeReference = objectNames.join(" ");
|
||||
return completeReference;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString PdmReferenceHelper::referenceFromRootToField(PdmObjectHandle* root, PdmFieldHandle* field)
|
||||
{
|
||||
if (field == NULL || root == NULL) return QString();
|
||||
|
||||
PdmObjectHandle* owner = field->ownerObject();
|
||||
if (!owner) return QString(); // Should be assert ?
|
||||
|
||||
QStringList refFromRootToField;
|
||||
|
||||
refFromRootToField = referenceFromRootToObjectAsStringList(root, owner);
|
||||
|
||||
refFromRootToField.push_front(field->keyword());
|
||||
|
||||
QString completeReference = refFromRootToField.join(" ");
|
||||
return completeReference;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectHandle* PdmReferenceHelper::objectFromReference(PdmObjectHandle* root, const QString& reference)
|
||||
{
|
||||
QStringList decodedReference = reference.split(" ");
|
||||
|
||||
return objectFromReferenceStringList(root, decodedReference);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmFieldHandle* PdmReferenceHelper::findField(PdmObjectHandle* object, const QString& fieldKeyword)
|
||||
{
|
||||
if (object == NULL) return NULL;
|
||||
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
object->fields(fields);
|
||||
|
||||
for (size_t i = 0; i < fields.size(); i++)
|
||||
{
|
||||
if (fields[i]->keyword() == fieldKeyword)
|
||||
{
|
||||
return fields[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QStringList PdmReferenceHelper::referenceFromRootToObjectAsStringList(PdmObjectHandle* root, PdmObjectHandle* obj)
|
||||
{
|
||||
QStringList objectNames;
|
||||
|
||||
if (obj != NULL && root)
|
||||
{
|
||||
if (obj == root) return objectNames;
|
||||
|
||||
PdmObjectHandle* currentObject = obj;
|
||||
|
||||
bool continueParsing = true;
|
||||
while (continueParsing)
|
||||
{
|
||||
caf::PdmFieldHandle* parentField = currentObject->parentField();
|
||||
assert(parentField);
|
||||
|
||||
std::vector<PdmObjectHandle*> childObjects;
|
||||
parentField->childObjects(&childObjects);
|
||||
|
||||
if (childObjects.size() > 0)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
for (size_t i = 0; i < childObjects.size(); i++)
|
||||
{
|
||||
if (childObjects[i] == currentObject)
|
||||
{
|
||||
index = static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
|
||||
objectNames.push_front(QString::number(index));
|
||||
objectNames.push_front(parentField->keyword());
|
||||
}
|
||||
else
|
||||
{
|
||||
continueParsing = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
PdmObjectHandle* ownerObject = parentField->ownerObject();
|
||||
assert(ownerObject);
|
||||
|
||||
if (ownerObject == root)
|
||||
{
|
||||
continueParsing = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
currentObject = ownerObject;
|
||||
}
|
||||
}
|
||||
|
||||
return objectNames;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmFieldHandle* PdmReferenceHelper::fieldFromReference(PdmObjectHandle* root, const QString& reference)
|
||||
{
|
||||
QStringList decodedReference = reference.split(" ");
|
||||
|
||||
QString fieldKeyword = decodedReference[0];
|
||||
decodedReference.pop_front();
|
||||
|
||||
PdmObjectHandle* parentObject = objectFromReferenceStringList(root, decodedReference);
|
||||
return findField(parentObject, fieldKeyword);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectHandle* PdmReferenceHelper::objectFromReferenceStringList(PdmObjectHandle* root, const QStringList& reference)
|
||||
{
|
||||
PdmObjectHandle* currentObject = root;
|
||||
|
||||
int i = 0;
|
||||
while (i < reference.size())
|
||||
{
|
||||
QString fieldKeyword = reference.at(i++);
|
||||
|
||||
PdmFieldHandle* field = findField(currentObject, fieldKeyword);
|
||||
if (field)
|
||||
{
|
||||
std::vector<PdmObjectHandle*> childObjects;
|
||||
field->childObjects(&childObjects);
|
||||
|
||||
if (childObjects.size() > 0)
|
||||
{
|
||||
QString fieldIndex = reference.at(i++);
|
||||
bool conversionOk = true;
|
||||
int index = fieldIndex.toInt(&conversionOk);
|
||||
if (!conversionOk)
|
||||
{
|
||||
index = -1;
|
||||
}
|
||||
|
||||
if (index > -1)
|
||||
{
|
||||
PdmObjectHandle* listObject = childObjects[index];
|
||||
currentObject = listObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentObject;
|
||||
}
|
||||
|
||||
std::vector<PdmObjectHandle*> findPathToObjectFromRoot(PdmObjectHandle* obj)
|
||||
{
|
||||
std::vector<PdmObjectHandle*> objPath;
|
||||
PdmObjectHandle* currentObj = obj;
|
||||
while (currentObj)
|
||||
{
|
||||
objPath.push_back(currentObj);
|
||||
if (currentObj->parentField())
|
||||
{
|
||||
currentObj = currentObj->parentField()->ownerObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentObj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
std::reverse(objPath.begin(), objPath.end());
|
||||
|
||||
return objPath;
|
||||
}
|
||||
|
||||
QString PdmReferenceHelper::referenceFromFieldToObject(PdmFieldHandle* fromField, PdmObjectHandle* toObj)
|
||||
{
|
||||
assert(fromField);
|
||||
if (toObj == NULL) return "";
|
||||
|
||||
PdmObjectHandle* fromObj = fromField->ownerObject();
|
||||
std::vector<PdmObjectHandle*> fromObjPath = findPathToObjectFromRoot(fromObj);
|
||||
std::vector<PdmObjectHandle*> toObjPath = findPathToObjectFromRoot(toObj);
|
||||
|
||||
// Make sure the objects actually have at least one common ancestor
|
||||
assert(fromObjPath.front() == toObjPath.front());
|
||||
|
||||
bool anchestorIsEqual = true;
|
||||
size_t idxToLastCommonAnchestor = 0;
|
||||
while (anchestorIsEqual)
|
||||
{
|
||||
++idxToLastCommonAnchestor;
|
||||
if ( idxToLastCommonAnchestor >= fromObjPath.size()
|
||||
|| idxToLastCommonAnchestor >= toObjPath.size()
|
||||
|| fromObjPath[idxToLastCommonAnchestor] != toObjPath[idxToLastCommonAnchestor])
|
||||
{
|
||||
anchestorIsEqual = false;
|
||||
idxToLastCommonAnchestor -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t levelCountToCommonAnchestor = (fromObjPath.size() - 1) - idxToLastCommonAnchestor;
|
||||
|
||||
PdmObjectHandle* lastCommonAnchestor = fromObjPath[idxToLastCommonAnchestor];
|
||||
|
||||
QStringList referenceList = referenceFromRootToObjectAsStringList(lastCommonAnchestor, toObj);
|
||||
|
||||
for (size_t i = 0; i < levelCountToCommonAnchestor; ++i)
|
||||
{
|
||||
referenceList.push_front("..");
|
||||
}
|
||||
|
||||
QString completeReference = referenceList.join(" ");
|
||||
|
||||
return completeReference;
|
||||
}
|
||||
|
||||
PdmObjectHandle* PdmReferenceHelper::objectFromFieldReference(PdmFieldHandle* fromField, const QString& reference)
|
||||
{
|
||||
if (reference.isEmpty()) return NULL;
|
||||
assert(fromField);
|
||||
|
||||
QStringList decodedReference = reference.split(" ");
|
||||
PdmObjectHandle* lastCommonAnchestor = fromField->ownerObject();
|
||||
assert(lastCommonAnchestor);
|
||||
assert(decodedReference.size());
|
||||
|
||||
while (decodedReference.front() == "..")
|
||||
{
|
||||
PdmFieldHandle* parentField = lastCommonAnchestor->parentField();
|
||||
if (!parentField)
|
||||
{
|
||||
// Error: Relative object reference has an invalid number of parent levels
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lastCommonAnchestor = parentField->ownerObject();
|
||||
assert(lastCommonAnchestor);
|
||||
decodedReference.pop_front();
|
||||
}
|
||||
|
||||
return objectFromReferenceStringList(lastCommonAnchestor, decodedReference);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectHandle* PdmReferenceHelper::findRoot(PdmObjectHandle* obj)
|
||||
{
|
||||
std::vector<PdmObjectHandle*> path = findPathToObjectFromRoot(obj);
|
||||
|
||||
if (path.size()) return path[0];
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectHandle* PdmReferenceHelper::findRoot(PdmFieldHandle* field)
|
||||
{
|
||||
if (field)
|
||||
{
|
||||
PdmObjectHandle* ownerObject = field->ownerObject();
|
||||
return findRoot(ownerObject);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // end namespace caf
|
||||
@@ -0,0 +1,75 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
class QStringList;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class PdmReferenceHelper
|
||||
{
|
||||
public:
|
||||
static PdmObjectHandle* findRoot(PdmObjectHandle* obj);
|
||||
static PdmObjectHandle* findRoot(PdmFieldHandle* field);
|
||||
|
||||
static QString referenceFromRootToField(PdmObjectHandle* root, PdmFieldHandle* field);
|
||||
static QString referenceFromRootToObject(PdmObjectHandle* root, PdmObjectHandle* obj);
|
||||
static PdmObjectHandle* objectFromReference(PdmObjectHandle* root, const QString& reference);
|
||||
static PdmFieldHandle* fieldFromReference(PdmObjectHandle* root, const QString& reference);
|
||||
|
||||
static QString referenceFromFieldToObject(PdmFieldHandle* fromField, PdmObjectHandle* toObj);
|
||||
static PdmObjectHandle* objectFromFieldReference(PdmFieldHandle* fromField, const QString& reference);
|
||||
|
||||
private:
|
||||
static QStringList referenceFromRootToObjectAsStringList(PdmObjectHandle* root, PdmObjectHandle* obj);
|
||||
static PdmObjectHandle* objectFromReferenceStringList(PdmObjectHandle* root, const QStringList& reference);
|
||||
|
||||
static PdmFieldHandle* findField(PdmObjectHandle* object, const QString& fieldKeyword);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace caf
|
||||
@@ -0,0 +1,66 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
|
||||
class QVariant;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
|
||||
|
||||
class PdmValueField : public PdmFieldHandle
|
||||
{
|
||||
public:
|
||||
virtual QVariant toQVariant() const = 0;
|
||||
virtual void setFromQVariant(const QVariant& variant) = 0;
|
||||
virtual bool isReadOnly() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// class PdmProxyValueField : public PdmValueField
|
||||
// {
|
||||
// DataType value() const { assert(m_valueGetter); return m_valueGetter->getValue(); }
|
||||
// void setValue(const DataType& fieldValue) { if (m_valueSetter) m_valueSetter->setValue(fieldValue); }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -38,69 +38,20 @@
|
||||
#include "cafPdmDocument.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
CAF_PDM_SOURCE_INIT(PdmObjectGroup, "PdmObjectGroup");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectGroup::PdmObjectGroup()
|
||||
{
|
||||
CAF_PDM_InitObject("Object Group", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&objects, "PdmObjects","", "", "", "")
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectGroup::~PdmObjectGroup()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectGroup::deleteObjects()
|
||||
{
|
||||
size_t it;
|
||||
for (it = 0; it != objects.size(); ++it)
|
||||
{
|
||||
delete objects[it];
|
||||
}
|
||||
removeNullPtrs();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectGroup::removeNullPtrs()
|
||||
{
|
||||
objects.removeChildObject(NULL);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectGroup::addObject(PdmObject * obj)
|
||||
{
|
||||
objects.push_back(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
CAF_PDM_SOURCE_INIT(PdmDocument, "PdmDocument");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmDocument::PdmDocument()
|
||||
PdmDocument::PdmDocument()
|
||||
{
|
||||
CAF_PDM_InitObject("File", "", "", "");
|
||||
CAF_PDM_InitField(&fileName, "DocumentFileName", QString(""), "File Name", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&fileName, "DocumentFileName", "File Name", "", "", "");
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -133,7 +84,7 @@ void PdmDocument::readFile(QIODevice* xmlFile)
|
||||
// Error: This is not a Ceetron Pdm based xml document
|
||||
return;
|
||||
}
|
||||
readFields(xmlStream);
|
||||
readFields(xmlStream, PdmDefaultObjectFactory::instance());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +92,6 @@ void PdmDocument::readFile(QIODevice* xmlFile)
|
||||
// after everything is read from file
|
||||
|
||||
PdmDocument::initAfterReadTraversal(this);
|
||||
PdmDocument::updateUiIconStateRecursively(this);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -177,17 +127,15 @@ void PdmDocument::writeFile(QIODevice* xmlFile)
|
||||
xmlStream.writeEndDocument();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmDocument::setupBeforeSaveTraversal(PdmObject * object)
|
||||
|
||||
void PdmDocument::setupBeforeSaveTraversal(PdmObjectHandle * object)
|
||||
{
|
||||
if (object == NULL) return;
|
||||
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
object->fields(fields);
|
||||
|
||||
std::vector<PdmObject*> children;
|
||||
std::vector<PdmObjectHandle*> children;
|
||||
size_t fIdx;
|
||||
for (fIdx = 0; fIdx < fields.size(); ++fIdx)
|
||||
{
|
||||
@@ -200,20 +148,24 @@ void PdmDocument::setupBeforeSaveTraversal(PdmObject * object)
|
||||
PdmDocument::setupBeforeSaveTraversal(children[cIdx]);
|
||||
}
|
||||
|
||||
object->setupBeforeSave();
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(object);
|
||||
if (xmlObject)
|
||||
{
|
||||
xmlObject->setupBeforeSave();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmDocument::initAfterReadTraversal(PdmObject* object)
|
||||
void PdmDocument::initAfterReadTraversal(PdmObjectHandle* object)
|
||||
{
|
||||
if (object == NULL) return;
|
||||
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
object->fields(fields);
|
||||
|
||||
std::vector<PdmObject*> children;
|
||||
std::vector<PdmObjectHandle*> children;
|
||||
size_t fIdx;
|
||||
for (fIdx = 0; fIdx < fields.size(); ++fIdx)
|
||||
{
|
||||
@@ -226,20 +178,24 @@ void PdmDocument::initAfterReadTraversal(PdmObject* object)
|
||||
PdmDocument::initAfterReadTraversal(children[cIdx]);
|
||||
}
|
||||
|
||||
object->initAfterRead();
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(object);
|
||||
if (xmlObject)
|
||||
{
|
||||
xmlObject->initAfterRead();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmDocument::updateUiIconStateRecursively(PdmObject* object)
|
||||
void PdmDocument::updateUiIconStateRecursively(PdmObjectHandle* object)
|
||||
{
|
||||
if (object == NULL) return;
|
||||
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
object->fields(fields);
|
||||
|
||||
std::vector<PdmObject*> children;
|
||||
std::vector<PdmObjectHandle*> children;
|
||||
size_t fIdx;
|
||||
for (fIdx = 0; fIdx < fields.size(); ++fIdx)
|
||||
{
|
||||
@@ -252,8 +208,13 @@ void PdmDocument::updateUiIconStateRecursively(PdmObject* object)
|
||||
PdmDocument::updateUiIconStateRecursively(children[cIdx]);
|
||||
}
|
||||
|
||||
object->updateUiIconFromToggleField();
|
||||
PdmUiObjectHandle* uiObjectHandle = uiObj(object);
|
||||
if (uiObjectHandle)
|
||||
{
|
||||
uiObjectHandle->updateUiIconFromToggleField();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
|
||||
@@ -39,45 +39,11 @@
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPointer.h"
|
||||
#include "cafPdmObjectGroup.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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void createCopyByType(std::vector<PdmPointer<T> >* copyOfTypedObjects) const;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// 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.
|
||||
@@ -96,52 +62,13 @@ class PdmDocument: public PdmObjectGroup
|
||||
void readFile(QIODevice* device);
|
||||
void writeFile(QIODevice* device);
|
||||
|
||||
static void updateUiIconStateRecursively(PdmObject * root);
|
||||
static void initAfterReadTraversal(PdmObject * root);
|
||||
|
||||
static void setupBeforeSaveTraversal(PdmObject * root);
|
||||
|
||||
private:
|
||||
static void updateUiIconStateRecursively(PdmObjectHandle* root);
|
||||
static void initAfterReadTraversal(PdmObjectHandle* root);
|
||||
static void setupBeforeSaveTraversal(PdmObjectHandle * root);
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void PdmObjectGroup::createCopyByType(std::vector<PdmPointer<T> >* copyOfTypedObjects) const
|
||||
{
|
||||
std::vector<PdmPointer<T> > sourceTypedObjects;
|
||||
objectsByType(&sourceTypedObjects);
|
||||
|
||||
QString encodedXml;
|
||||
{
|
||||
// Write original objects to XML file
|
||||
PdmObjectGroup typedObjectGroup;
|
||||
for (size_t i = 0; i < sourceTypedObjects.size(); i++)
|
||||
{
|
||||
typedObjectGroup.addObject(sourceTypedObjects[i]);
|
||||
PdmDocument::setupBeforeSaveTraversal(sourceTypedObjects[i]);
|
||||
}
|
||||
|
||||
QXmlStreamWriter xmlStream(&encodedXml);
|
||||
xmlStream.setAutoFormatting(true);
|
||||
|
||||
typedObjectGroup.writeFields(xmlStream);
|
||||
}
|
||||
|
||||
// Read back XML into object group, factory methods will be called that will create new objects
|
||||
PdmObjectGroup destinationObjectGroup;
|
||||
QXmlStreamReader xmlStream(encodedXml);
|
||||
destinationObjectGroup.readFields(xmlStream);
|
||||
|
||||
for (size_t it = 0; it < destinationObjectGroup.objects.size(); it++)
|
||||
{
|
||||
T* obj = dynamic_cast<T*>(destinationObjectGroup.objects[it]);
|
||||
if (obj) copyOfTypedObjects->push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.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 << "PdmField: Detected use of non-initialized field. Did you forget to do CAF_PDM_InitField() on this field ?\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PdmObject::isValidXmlElementName(m_keyword))
|
||||
{
|
||||
std::cout << "PdmField: The supplied keyword: \"" << m_keyword.toStdString() << "\" is an invalid XML element name, and will break your file format!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmFieldHandle::setKeyword(const QString& keyword)
|
||||
{
|
||||
assert(PdmObject::isValidXmlElementName(keyword));
|
||||
|
||||
m_keyword = keyword;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmFieldHandle::hasChildObjects()
|
||||
{
|
||||
std::vector<PdmObject*> children;
|
||||
this->childObjects(&children);
|
||||
return (children.size() > 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// 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
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QTextStream& 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;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
QTextStream& operator << (QTextStream& str, const bool& value)
|
||||
{
|
||||
if (value) str << "True ";
|
||||
else str << "False ";
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Specialized read operation for QDateTimes`s
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#include <QDateTime>
|
||||
QTextStream& operator >> (QTextStream& str, QDateTime& value)
|
||||
{
|
||||
QString text;
|
||||
str >> text;
|
||||
value = QDateTime::fromString(text, "yyyy_MM_dd-HH:mm:ss");
|
||||
return str;
|
||||
}
|
||||
|
||||
QTextStream& operator << (QTextStream& str, const QDateTime& value)
|
||||
{
|
||||
QString text = value.toString("yyyy_MM_dd-HH:mm:ss");
|
||||
str << text;
|
||||
return str;
|
||||
}
|
||||
@@ -1,267 +1,23 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
#pragma once
|
||||
|
||||
#define CAF_IS_DEFINING_PDM_FIELD
|
||||
#define PdmDataValueField PdmField
|
||||
#include "cafPdmDataValueField.h"
|
||||
#undef PdmDataValueField
|
||||
#undef CAF_IS_DEFINING_PDM_FIELD
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafPdmFieldImpl.h"
|
||||
|
||||
#include <set>
|
||||
#include <assert.h>
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QTextStream>
|
||||
|
||||
namespace caf
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject;
|
||||
template <class T> class PdmPointer;
|
||||
class PdmUiFieldEditorHandle;
|
||||
// Specialization to create compiler errors to help finding the PdmField's to rename
|
||||
|
||||
//==================================================================================================
|
||||
/// Base class for all fields, making it possible to handle them generically
|
||||
//==================================================================================================
|
||||
#ifdef WIN32
|
||||
|
||||
class PdmFieldHandle : public PdmUiItem
|
||||
{
|
||||
public:
|
||||
PdmFieldHandle() : m_isIOReadable(true), m_isIOWritable(true) { m_ownerObject = NULL; m_keyword = "UNDEFINED"; }
|
||||
virtual ~PdmFieldHandle() { }
|
||||
template<typename DataType >
|
||||
class PdmField <DataType*> : public Rename_PdmField_of_pointer_to_PdmChildField // You must rename PdmField<T*> to PdmChildField<T*>
|
||||
{
|
||||
};
|
||||
|
||||
virtual void resetToDefaultValue() { };
|
||||
#endif
|
||||
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream) = 0;
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream) = 0;
|
||||
|
||||
bool isIOReadable() { return m_isIOReadable; }
|
||||
bool isIOWritable() { return m_isIOWritable; }
|
||||
void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; }
|
||||
void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; }
|
||||
|
||||
void setKeyword(const QString& keyword);
|
||||
QString keyword() const { return m_keyword; }
|
||||
|
||||
void setOwnerObject(PdmObject * owner) { m_ownerObject = owner; }
|
||||
PdmObject* ownerObject() { return m_ownerObject; }
|
||||
|
||||
// Generalized access methods for User interface
|
||||
// The QVariant encapsulates the real value, or an index into the valueOptions
|
||||
//
|
||||
|
||||
virtual QVariant uiValue() const { return QVariant(); }
|
||||
virtual void setValueFromUi(const QVariant& ) { }
|
||||
|
||||
virtual bool hasChildObjects();
|
||||
virtual void childObjects(std::vector<PdmObject*>* ) { }
|
||||
virtual void removeChildObject(PdmObject* ) { }
|
||||
|
||||
virtual QList<PdmOptionItemInfo>
|
||||
valueOptions( bool* useOptionsOnly) { return QList<PdmOptionItemInfo>(); }
|
||||
|
||||
protected:
|
||||
bool assertValid() const;
|
||||
protected:
|
||||
PdmObject* m_ownerObject;
|
||||
private:
|
||||
QString m_keyword;
|
||||
bool m_isIOReadable;
|
||||
bool m_isIOWritable;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// Field class encapsulating data with input and output of this data to/from a QXmlStream
|
||||
/// read/write-FieldData is supposed to be specialized for types needing specialization
|
||||
//==================================================================================================
|
||||
template <typename T> struct PdmFieldWriter;
|
||||
template <typename T> struct PdmFieldReader;
|
||||
|
||||
template<typename DataType >
|
||||
class PdmField : public PdmFieldHandle
|
||||
{
|
||||
public:
|
||||
PdmField() {}
|
||||
virtual ~PdmField() {}
|
||||
|
||||
// Copy and assignment must ignore the default value.
|
||||
PdmField(const PdmField& other) : PdmFieldHandle() { assertValid(); m_fieldValue = other.m_fieldValue; }
|
||||
PdmField(const DataType& fieldValue) : PdmFieldHandle() { assertValid(); m_fieldValue = fieldValue; }
|
||||
PdmField& operator= (const PdmField& other) { assertValid(); m_fieldValue = other.m_fieldValue; return *this; }
|
||||
PdmField& operator= (const DataType& fieldValue) { assertValid(); m_fieldValue = fieldValue; return *this; }
|
||||
|
||||
operator DataType () const { return m_fieldValue; }
|
||||
|
||||
// DataType& operator()() { assertValid(); return m_fieldValue; }
|
||||
const DataType& operator()() const { return m_fieldValue; }
|
||||
DataType& v() { assertValid(); return m_fieldValue; }
|
||||
const DataType& v() const { return m_fieldValue; }
|
||||
|
||||
bool operator== (const DataType& fieldValue) const { return m_fieldValue == fieldValue; }
|
||||
|
||||
// readFieldData assumes that the xmlStream points to first token of field content.
|
||||
// After reading, the xmlStream is supposed to point to the first token after the field content.
|
||||
// (typically an "endElement")
|
||||
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream) { PdmFieldReader<DataType>::readFieldData(*this, xmlStream); }
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream) { PdmFieldWriter<DataType>::writeFieldData(*this, xmlStream);}
|
||||
|
||||
const DataType& defaultValue() const { return m_defaultFieldValue; }
|
||||
void setDefaultValue(const DataType& val) { m_defaultFieldValue = val; }
|
||||
virtual void resetToDefaultValue() { m_fieldValue = m_defaultFieldValue; }
|
||||
|
||||
// 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 PdmObject derived objects.
|
||||
/// The pointer is guarded, meaning that it will be set to NULL if the object pointed to
|
||||
/// is deleted. The referenced object will be printed in place in the xml-file
|
||||
//==================================================================================================
|
||||
|
||||
template<typename DataType >
|
||||
class PdmField <DataType*> : public PdmFieldHandle
|
||||
{
|
||||
typedef DataType* DataTypePtr;
|
||||
public:
|
||||
PdmField() : PdmFieldHandle() { }
|
||||
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 insert(size_t indexAfter, const std::vector<PdmPointer<DataType> >& objects);
|
||||
size_t count(const DataType* pointer) const;
|
||||
|
||||
void clear();
|
||||
void erase(size_t index);
|
||||
void deleteAllChildObjects();
|
||||
|
||||
// Reimplementation of PdmFieldhandle methods
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream);
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream);
|
||||
|
||||
// Gui generalized methods
|
||||
virtual void childObjects(std::vector<PdmObject*>* objects);
|
||||
virtual void removeChildObject(PdmObject* object);
|
||||
|
||||
private:
|
||||
void removeThisAsParentField();
|
||||
void addThisAsParentField();
|
||||
|
||||
private:
|
||||
std::vector< PdmPointer<DataType> > m_pointers;
|
||||
};
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafPdmField.inl"
|
||||
}
|
||||
|
||||
@@ -1,746 +0,0 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "cafPdmUiFieldEditorHandle.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//==================================================================================================
|
||||
/// Implementation of PdmField<T> methods
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// This method is supposed to be the interface for the implementation of UI editors to set values into
|
||||
/// the field. The data to set must be encapsulated in a QVariant.
|
||||
/// This method triggers PdmObject::fieldChangedByUi() and PdmObject::updateConnectedEditors(), an thus
|
||||
/// makes the application and the UI aware of the change.
|
||||
///
|
||||
/// Note : If the field has optionValues the interface is _index-based_. The QVariant must contain
|
||||
/// an UInt representing the index to the option selected by the user interface.
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
void caf::PdmField<DataType>::setValueFromUi(const QVariant& uiValue)
|
||||
{
|
||||
QVariant oldValue = PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
|
||||
|
||||
// Check whether we are handling selections of values or actual values
|
||||
if (m_optionEntryCache.size())
|
||||
{
|
||||
// This has an option based GUI, the uiValue is only indexes into the m_optionEntryCache
|
||||
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 if (uiValue.type() == QVariant::List)
|
||||
{
|
||||
QList<QVariant> selectedIndexes = uiValue.toList();
|
||||
QList<QVariant> valuesToSetInField;
|
||||
|
||||
if (selectedIndexes.isEmpty())
|
||||
{
|
||||
PdmFieldTypeSpecialization<DataType>::setFromVariant(valuesToSetInField, m_fieldValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedIndexes.front().type() == QVariant::UInt)
|
||||
{
|
||||
for (int i = 0; i < selectedIndexes.size(); ++i)
|
||||
{
|
||||
unsigned int opIdx = selectedIndexes[i].toUInt();
|
||||
if (opIdx < static_cast<unsigned int>(m_optionEntryCache.size()))
|
||||
{
|
||||
valuesToSetInField.push_back(m_optionEntryCache[opIdx].value);
|
||||
}
|
||||
}
|
||||
|
||||
PdmFieldTypeSpecialization<DataType>::setFromVariant(valuesToSetInField, m_fieldValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are not getting indexes as expected from the UI. For now assert, to catch this condition
|
||||
// but it should possibly be handled as setting the values explicitly. The code for that is below the assert
|
||||
assert(false);
|
||||
PdmFieldTypeSpecialization<DataType>::setFromVariant(uiValue, m_fieldValue);
|
||||
m_optionEntryCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are not getting indexes as expected from the UI. For now assert, to catch this condition
|
||||
// but it should possibly be handled as setting the values explicitly. The code for that is below the assert
|
||||
assert(false);
|
||||
PdmFieldTypeSpecialization<DataType>::setFromVariant(uiValue, m_fieldValue);
|
||||
m_optionEntryCache.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Not an option based GUI, the uiValue is a real field value
|
||||
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);
|
||||
|
||||
// This assumes that all field editors are updated by an instance of PdmUiObjectEditorHandle
|
||||
m_ownerObject->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the option values that is to be displayed in the UI for this field.
|
||||
/// This method calls the virtual PdmObject::calculateValueOptions to get the list provided from the
|
||||
/// application, then possibly adds the current field value(s) to the list, to
|
||||
/// make sure the actual values are shown
|
||||
///
|
||||
/// Note: This method is missing the uiConfigName concept. This is a Todo. The m_optionEntryCache
|
||||
/// then needs to be stored pr. uiConfigName.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
QList<PdmOptionItemInfo> caf::PdmField<DataType>::valueOptions(bool* useOptionsOnly)
|
||||
{
|
||||
// First check if the owner PdmObject has a value options specification.
|
||||
// if it has, use it.
|
||||
if (m_ownerObject)
|
||||
{
|
||||
m_optionEntryCache = m_ownerObject->calculateValueOptions(this, useOptionsOnly);
|
||||
if (m_optionEntryCache.size())
|
||||
{
|
||||
// Make sure the options contain the field values, event though they not necessarily
|
||||
// is supplied as possible options by the application. This is a convenience making sure
|
||||
// the actual data in the pdmObject is shown correctly in the UI, and to prevent accidental
|
||||
// changes of the field values
|
||||
|
||||
// Find the field value(s) in the list if present
|
||||
|
||||
QVariant convertedFieldValue = PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
|
||||
|
||||
std::vector<unsigned int> foundIndexes;
|
||||
bool foundAllFieldValues = PdmOptionItemInfo::findValues(m_optionEntryCache, convertedFieldValue, foundIndexes);
|
||||
|
||||
// If not all are found, we have to add the missing to the list, to be able to show it
|
||||
|
||||
if (!foundAllFieldValues)
|
||||
{
|
||||
if (convertedFieldValue.type() != QVariant::List) // Single value field
|
||||
{
|
||||
if (!convertedFieldValue.toString().isEmpty())
|
||||
{
|
||||
m_optionEntryCache.push_front(PdmOptionItemInfo(convertedFieldValue.toString(), convertedFieldValue, true, QIcon()));
|
||||
}
|
||||
}
|
||||
else // The field value is a list of values
|
||||
{
|
||||
QList<QVariant> valuesSelectedInField = convertedFieldValue.toList();
|
||||
for (int i= 0 ; i < valuesSelectedInField.size(); ++i)
|
||||
{
|
||||
bool isFound = false;
|
||||
for (unsigned int opIdx = 0; opIdx < static_cast<unsigned int>(m_optionEntryCache.size()); ++opIdx)
|
||||
{
|
||||
if (valuesSelectedInField[i] == m_optionEntryCache[opIdx].value) isFound = true;
|
||||
}
|
||||
|
||||
if (!isFound && !valuesSelectedInField[i].toString().isEmpty())
|
||||
{
|
||||
m_optionEntryCache.push_front(PdmOptionItemInfo(valuesSelectedInField[i].toString(), valuesSelectedInField[i], true, QIcon()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_optionEntryCache;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have no options, use the options defined by the type. Normally only caf::AppEnum type
|
||||
|
||||
#if 0
|
||||
m_optionEntryCache = PdmFieldTypeSpecialization<DataType>::valueOptions(useOptionsOnly, m_fieldValue);
|
||||
return m_optionEntryCache;
|
||||
#else
|
||||
return PdmFieldTypeSpecialization<DataType>::valueOptions(useOptionsOnly, m_fieldValue);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Extracts a QVariant representation of the data in the field to be used in the UI.
|
||||
///
|
||||
/// Note : For fields with a none-empty valueOptions list, the returned QVariant contains the
|
||||
/// _indexes_ to the selected options rather than the actual values, if they can be found.
|
||||
///
|
||||
/// If this is a multivalue field, and we cant find all of the field values among the options,
|
||||
/// the method asserts (For now), forcing the valueOptions to always contain the field values.
|
||||
/// Single value fields will return -1 if the option is not found, allowing the concept of "nothing selected"
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType >
|
||||
QVariant caf::PdmField<DataType>::uiValue() const
|
||||
{
|
||||
if (m_optionEntryCache.size())
|
||||
{
|
||||
QVariant convertedFieldValue = PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
|
||||
std::vector<unsigned int> indexesToFoundOptions;
|
||||
PdmOptionItemInfo::findValues(m_optionEntryCache, convertedFieldValue, indexesToFoundOptions);
|
||||
if (convertedFieldValue.type() == QVariant::List)
|
||||
{
|
||||
if (indexesToFoundOptions.size() == static_cast<size_t>(convertedFieldValue.toList().size()))
|
||||
{
|
||||
QList<QVariant> returnList;
|
||||
for(size_t i = 0; i < indexesToFoundOptions.size(); ++i)
|
||||
{
|
||||
returnList.push_back(QVariant(indexesToFoundOptions[i]));
|
||||
}
|
||||
return QVariant(returnList);
|
||||
}
|
||||
assert(false); // Did not find all the field values among the options available.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (indexesToFoundOptions.size() == 1) return QVariant(indexesToFoundOptions.front());
|
||||
else return QVariant(-1); // Return -1 if not found instead of assert. Should result in clearing the selection
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return convertedFieldValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
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; // This happens when the field is "shortcut" empty (written like: <ElementName/>)
|
||||
}
|
||||
|
||||
QString className = xmlStream.name().toString();
|
||||
PdmObject* obj = NULL;
|
||||
|
||||
// Create an object if needed
|
||||
if (m_fieldValue.isNull())
|
||||
{
|
||||
obj = caf::PdmObjectFactory::instance()->create(className);
|
||||
|
||||
if (obj == NULL)
|
||||
{
|
||||
std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl;
|
||||
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of this field
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (obj->classKeyword() != className)
|
||||
{
|
||||
assert(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword
|
||||
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of this field
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_fieldValue.setRawPtr(obj);
|
||||
obj->addParentField(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = m_fieldValue.rawPtr();
|
||||
}
|
||||
|
||||
if (className != obj->classKeyword())
|
||||
{
|
||||
// Error: Field contains different class type than on file
|
||||
std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl;
|
||||
std::cout << " Expected class name: " << obj->classKeyword().toLatin1().data() << std::endl;
|
||||
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of this field
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Everything seems ok, so read the contents of the object:
|
||||
|
||||
obj->readFields(xmlStream);
|
||||
|
||||
// Make stream point to endElement of this field
|
||||
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename DataType >
|
||||
void caf::PdmField<DataType*>::writeFieldData(QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
if (m_fieldValue.rawPtr() == 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)
|
||||
: PdmFieldHandle()
|
||||
{
|
||||
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.setRawPtr(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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the value at position index to pointer, overwriting any pointer already present at that
|
||||
/// position without deleting the object pointed to.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Insert pointer at position index, pushing the value previously at that position and all
|
||||
/// the preceding values backwards
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::insert(size_t index, DataType* pointer)
|
||||
{
|
||||
m_pointers.insert(m_pointers.begin()+index, pointer);
|
||||
|
||||
if (pointer) pointer->addParentField(this);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Insert the pointers at position index, pushing the value previously at that position and all
|
||||
/// the preceding values backwards
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::insert(size_t index, const std::vector<PdmPointer<DataType> >& objects)
|
||||
{
|
||||
m_pointers.insert(m_pointers.begin()+index, objects.begin(), objects.end());
|
||||
|
||||
typename std::vector< PdmPointer< DataType > >::iterator it;
|
||||
for (it = m_pointers.begin()+index; it != m_pointers.end(); ++it)
|
||||
{
|
||||
if (!it->isNull())
|
||||
{
|
||||
(*it)->addParentField(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the number of times pointer is referenced from the container.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
size_t PdmPointersField<DataType*>::count(const DataType* pointer) const
|
||||
{
|
||||
size_t itemCount = 0;
|
||||
|
||||
typename std::vector< PdmPointer< DataType > >::const_iterator it;
|
||||
for (it = m_pointers.begin(); it != m_pointers.end(); ++it)
|
||||
{
|
||||
if (*it == pointer)
|
||||
{
|
||||
itemCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return itemCount;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Empty the container without deleting the objects pointed to.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::clear()
|
||||
{
|
||||
this->removeThisAsParentField();
|
||||
m_pointers.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Deletes all the objects pointed to by the field, then clears the container.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::deleteAllChildObjects()
|
||||
{
|
||||
size_t index;
|
||||
for (index = 0; index < m_pointers.size(); ++index)
|
||||
{
|
||||
delete(m_pointers[index].rawPtr());
|
||||
}
|
||||
|
||||
m_pointers.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Removes the pointer at index from the container. Does not delete the object pointed to.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Removes all instances of object pointer from the container without deleting the object.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::removeChildObject(PdmObject* object)
|
||||
{
|
||||
std::vector< PdmPointer<DataType> > tempPointers;
|
||||
|
||||
tempPointers = m_pointers;
|
||||
m_pointers.clear();
|
||||
|
||||
for (size_t index = 0; index < tempPointers.size(); ++index)
|
||||
{
|
||||
if (tempPointers[index].rawPtr() != object)
|
||||
{
|
||||
m_pointers.push_back(tempPointers[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tempPointers[index].rawPtr())
|
||||
{
|
||||
tempPointers[index].rawPtr()->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->rawPtr() == NULL) continue;
|
||||
|
||||
QString className = it->rawPtr()->classKeyword();
|
||||
|
||||
xmlStream.writeStartElement("", className);
|
||||
it->rawPtr()->writeFields(xmlStream);
|
||||
xmlStream.writeEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void PdmPointersField<DataType*>::readFieldData(QXmlStreamReader& xmlStream)
|
||||
{
|
||||
DataType * currentObject = NULL;
|
||||
this->deleteAllChildObjects();
|
||||
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
|
||||
|
||||
std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << this->keyword().toLatin1().data() << std::endl;
|
||||
|
||||
// Skip to EndElement of the object
|
||||
xmlStream.skipCurrentElement();
|
||||
|
||||
// Jump off the end element, and head for next start element (or the final EndElement of the field)
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (obj->classKeyword() != className)
|
||||
{
|
||||
assert(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword
|
||||
|
||||
// Skip to EndElement of the object
|
||||
xmlStream.skipCurrentElement();
|
||||
|
||||
// Jump off the end element, and head for next start element (or the final EndElement of the field)
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
obj->readFields(xmlStream);
|
||||
|
||||
m_pointers.push_back(PdmPointer<DataType>());
|
||||
m_pointers.back().setRawPtr(obj);
|
||||
obj->addParentField(this);
|
||||
|
||||
// Jump off the end element, and head for next start element (or the final EndElement of the field)
|
||||
// Qt reports a character token between EndElements and StartElements so skip it
|
||||
|
||||
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].rawPtr());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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->rawPtr()->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
|
||||
@@ -1,497 +0,0 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.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> >
|
||||
///
|
||||
/// Note : Makes the setUiValue() and uiValue() interface index based, and NOT based on real enum values.
|
||||
/// The valueOptions() interface is thus also index based (the value in the PdmOptionItemInfo is index NOT enum)
|
||||
/// This is probably going to change, ans it is strange.
|
||||
/// This conversion should really be done in the editors we think (now)
|
||||
//==================================================================================================
|
||||
|
||||
#define PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE 1
|
||||
|
||||
template <typename T>
|
||||
class PdmFieldTypeSpecialization < caf::AppEnum<T> >
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert(const caf::AppEnum<T>& value)
|
||||
{
|
||||
#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE
|
||||
return QVariant(static_cast<unsigned int>(caf::AppEnum<T>::index(value)));
|
||||
#else
|
||||
unsigned int enumVal = value;
|
||||
return QVariant(enumVal);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant(const QVariant& variantValue, caf::AppEnum<T>& value)
|
||||
{
|
||||
#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE
|
||||
value.setFromIndex(variantValue.toInt());
|
||||
#else
|
||||
value = static_cast<T> (variantValue.toInt());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// 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)
|
||||
{
|
||||
#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE
|
||||
optionList.push_back(PdmOptionItemInfo(optionTexts[i], static_cast<unsigned int>(i)));
|
||||
#else
|
||||
optionList.push_back(PdmOptionItemInfo(optionTexts[i], caf::AppEnum<T>::fromIndex(i)));
|
||||
#endif
|
||||
}
|
||||
|
||||
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 bool`s
|
||||
/// Prints bool`s as "True"/"False", and reads them too
|
||||
//==================================================================================================
|
||||
|
||||
QTextStream& operator >> (QTextStream& str, bool& value);
|
||||
QTextStream& operator << (QTextStream& str, const bool& value);
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// QTextStream Stream operator overloading for QDateTimes`s
|
||||
///
|
||||
//==================================================================================================
|
||||
//class QDateTime;
|
||||
QTextStream& operator >> (QTextStream& str, QDateTime& value);
|
||||
QTextStream& operator << (QTextStream& str, const QDateTime& value);
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// 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 >
|
||||
QTextStream& operator << (QTextStream& str, const std::vector<T>& sobj)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sobj.size(); ++i)
|
||||
{
|
||||
str << sobj[i] << " ";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
QTextStream& 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);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
@@ -1,480 +0,0 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include "cafPdmObjectFactory.h"
|
||||
#include "cafPdmDocument.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Reads all the fields into this PdmObject
|
||||
/// Assumes xmlStream points to the start element token of the PdmObject for which to read fields.
|
||||
/// ( and not first token of object content)
|
||||
/// This makes attribute based field storage possible.
|
||||
/// Leaves the xmlStream pointing to the EndElement of the PdmObject.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::readFields (QXmlStreamReader& xmlStream )
|
||||
{
|
||||
bool isObjectFinished = false;
|
||||
QXmlStreamReader::TokenType type;
|
||||
while(!isObjectFinished)
|
||||
{
|
||||
type = xmlStream.readNext();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case QXmlStreamReader::StartElement:
|
||||
{
|
||||
QString name = xmlStream.name().toString();
|
||||
if (name == QString("SimpleObjPtrField"))
|
||||
{
|
||||
int a;
|
||||
a = 2 + 7;
|
||||
}
|
||||
PdmFieldHandle* currentField = findField(name);
|
||||
if (currentField)
|
||||
{
|
||||
if (currentField->isIOReadable())
|
||||
{
|
||||
// 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
|
||||
{
|
||||
xmlStream.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Line "<< xmlStream.lineNumber() << ": 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.
|
||||
QString name = xmlStream.name().toString(); // For debugging
|
||||
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* field = *it;
|
||||
if (field->isIOWritable())
|
||||
{
|
||||
QString keyword = field->keyword();
|
||||
assert(PdmObject::isValidXmlElementName(keyword));
|
||||
|
||||
xmlStream.writeStartElement("", keyword);
|
||||
field->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::parentObjects(std::vector<PdmObject*>& objects) const
|
||||
{
|
||||
std::vector<caf::PdmFieldHandle*> parentFields;
|
||||
this->parentFields(parentFields);
|
||||
size_t i;
|
||||
for (i = 0; i < parentFields.size(); i++)
|
||||
{
|
||||
objects.push_back(parentFields[i]->ownerObject());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::removeFromParentFields()
|
||||
{
|
||||
std::vector<caf::PdmFieldHandle*> parentFields;
|
||||
this->parentFields(parentFields);
|
||||
size_t i;
|
||||
for (i = 0; i < parentFields.size(); i++)
|
||||
{
|
||||
parentFields[i]->removeChildObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
this->defineUiOrdering(uiConfigName, uiOrdering);
|
||||
if (!uiOrdering.forgetRemainingFields())
|
||||
{
|
||||
// Add the remaining Fields To UiConfig
|
||||
|
||||
for (size_t i = 0; i < m_fields.size(); ++i)
|
||||
{
|
||||
if (!uiOrdering.contains(m_fields[i]))
|
||||
{
|
||||
uiOrdering.add( m_fields[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute)
|
||||
{
|
||||
this->defineEditorAttribute(field, uiConfigName, attribute);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute)
|
||||
{
|
||||
this->defineObjectEditorAttribute(uiConfigName, attribute);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if a string is a valid Xml element name
|
||||
//
|
||||
/// http://www.w3schools.com/xml/xml_elements.asp
|
||||
///
|
||||
/// XML elements must follow these naming rules:
|
||||
/// Names can contain letters, numbers, and other characters
|
||||
/// Names cannot start with a number or punctuation character
|
||||
/// Names cannot start with the letters xml (or XML, or Xml, etc)
|
||||
/// Names cannot contain spaces
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmObject::isValidXmlElementName(const QString& name)
|
||||
{
|
||||
if (name.size() > 0)
|
||||
{
|
||||
QChar firstChar = name[0];
|
||||
if (firstChar.isDigit() || firstChar == '.')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (name.size() >= 3)
|
||||
{
|
||||
if (name.left(3).compare("xml", Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (name.contains(' '))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObject* PdmObject::deepCopy()
|
||||
{
|
||||
QString encodedXml;
|
||||
|
||||
{
|
||||
PdmObjectGroup typedObjectGroup;
|
||||
typedObjectGroup.addObject(this);
|
||||
|
||||
QXmlStreamWriter xmlStream(&encodedXml);
|
||||
xmlStream.setAutoFormatting(true);
|
||||
|
||||
typedObjectGroup.writeFields(xmlStream);
|
||||
}
|
||||
|
||||
PdmObject* pdmCopy = NULL;
|
||||
{
|
||||
// Read back XML into object group, factory methods will be called that will create new objects
|
||||
PdmObjectGroup destinationObjectGroup;
|
||||
QXmlStreamReader xmlStream(encodedXml);
|
||||
destinationObjectGroup.readFields(xmlStream);
|
||||
|
||||
if (destinationObjectGroup.objects.size() == 1)
|
||||
{
|
||||
pdmCopy = destinationObjectGroup.objects[0];
|
||||
}
|
||||
}
|
||||
|
||||
return pdmCopy;
|
||||
|
||||
/*
|
||||
PdmObject* cloneRoot = PdmObjectFactory::instance()->create(this->classKeyword());
|
||||
|
||||
|
||||
|
||||
QString encodedXml;
|
||||
{
|
||||
QXmlStreamWriter xmlStream(&encodedXml);
|
||||
xmlStream.setAutoFormatting(true);
|
||||
|
||||
this->writeFields(xmlStream);
|
||||
}
|
||||
|
||||
QXmlStreamReader xmlStream(encodedXml);
|
||||
cloneRoot->readFields(xmlStream);
|
||||
|
||||
return cloneRoot;
|
||||
*/
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// This method is to be used to create a tree-representation of the object hierarchy starting at this
|
||||
/// object. The caller is responsible to delete the returned PdmUiTreeOrdering
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering* PdmObject::uiTreeOrdering(QString uiConfigName /*= ""*/)
|
||||
{
|
||||
PdmUiTreeOrdering* uiTreeOrdering = new PdmUiTreeOrdering(NULL, -1, this);
|
||||
|
||||
this->defineUiTreeOrdering(*uiTreeOrdering, uiConfigName);
|
||||
|
||||
if (!uiTreeOrdering->forgetRemainingFields())
|
||||
{
|
||||
// Add the remaining Fields To UiConfig
|
||||
|
||||
for (size_t fIdx = 0; fIdx < m_fields.size(); ++fIdx)
|
||||
{
|
||||
if (m_fields[fIdx]->hasChildObjects() && !uiTreeOrdering->containsField(m_fields[fIdx]))
|
||||
{
|
||||
if (m_fields[fIdx]->isUiHidden() && !m_fields[fIdx]->isUiChildrenHidden())
|
||||
{
|
||||
std::vector<PdmObject*> children;
|
||||
m_fields[fIdx]->childObjects(&children);
|
||||
|
||||
for (size_t cIdx = 0; cIdx < children.size(); cIdx++)
|
||||
{
|
||||
if (!uiTreeOrdering->containsObject(children[cIdx]))
|
||||
{
|
||||
uiTreeOrdering->add(children[cIdx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !m_fields[fIdx]->isUiHidden())
|
||||
{
|
||||
uiTreeOrdering->add(m_fields[fIdx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addUiTreeChildren(uiTreeOrdering, uiConfigName);
|
||||
return uiTreeOrdering;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::addUiTreeChildren(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */)
|
||||
{
|
||||
if (!root) return;
|
||||
|
||||
if ( root->childCount() == 0) // This means that no one has tried to expand it.
|
||||
{
|
||||
if (!root->ignoreSubTree() && root->dataObject())
|
||||
{
|
||||
|
||||
if (root->m_field && !root->m_field->isUiChildrenHidden(uiConfigName))
|
||||
{
|
||||
std::vector<PdmObject*> fieldsChildObjects;
|
||||
root->m_field->childObjects(&fieldsChildObjects);
|
||||
for (size_t cIdx = 0; cIdx < fieldsChildObjects.size(); ++cIdx)
|
||||
{
|
||||
root->add(fieldsChildObjects[cIdx]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
root->object()->defineUiTreeOrdering(*root, uiConfigName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int cIdx = 0; cIdx < root->childCount(); ++cIdx)
|
||||
{
|
||||
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>(root->child(cIdx));
|
||||
if (!child->ignoreSubTree())
|
||||
{
|
||||
addUiTreeChildren(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObject::updateUiIconFromToggleField()
|
||||
{
|
||||
if (objectToggleField())
|
||||
{
|
||||
bool active = objectToggleField()->uiValue().toBool();
|
||||
updateUiIconFromState(active);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //End of namespace caf
|
||||
@@ -37,7 +37,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
|
||||
#include "cafPdmObjectHandle.h"
|
||||
|
||||
#include "cafPdmUiOrdering.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
@@ -48,18 +50,17 @@ class QXmlStreamReader;
|
||||
class QXmlStreamWriter;
|
||||
|
||||
|
||||
// Taken from gtest.h
|
||||
//
|
||||
// Due to C++ preprocessor weirdness, we need double indirection to
|
||||
// concatenate two tokens when one of them is __LINE__. Writing
|
||||
//
|
||||
// foo ## __LINE__
|
||||
//
|
||||
// will result in the token foo__LINE__, instead of foo followed by
|
||||
// the current line number. For more details, see
|
||||
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
|
||||
#define PDM_OBJECT_STRING_CONCATENATE(foo, bar) PDM_OBJECT_STRING_CONCATENATE_IMPL_(foo, bar)
|
||||
#define PDM_OBJECT_STRING_CONCATENATE_IMPL_(foo, bar) foo ## bar
|
||||
|
||||
#include "cafPdmObjectCapability.h"
|
||||
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
#include "cafPdmXmlObjectHandle.h"
|
||||
#include "cafPdmXmlObjectHandleMacros.h"
|
||||
|
||||
#include "cafInternalPdmUiFieldCapability.h"
|
||||
#include "cafInternalPdmXmlFieldCapability.h"
|
||||
|
||||
#include "cafPdmUiFieldSpecialization.h"
|
||||
|
||||
|
||||
namespace caf
|
||||
@@ -69,34 +70,22 @@ class PdmFieldHandle;
|
||||
template < class FieldDataType > class PdmField;
|
||||
class PdmUiEditorAttribute;
|
||||
class PdmUiTreeOrdering;
|
||||
//==================================================================================================
|
||||
/// Macros helping in development of PDM objects
|
||||
//==================================================================================================
|
||||
class PdmObjectCapability;
|
||||
|
||||
/// 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 CAF_PDM_XML_HEADER_INIT
|
||||
#define CAF_PDM_SOURCE_INIT CAF_PDM_XML_SOURCE_INIT
|
||||
|
||||
#define CAF_PDM_HEADER_INIT \
|
||||
public: \
|
||||
virtual QString classKeyword() { return classKeywordStatic(); } \
|
||||
static QString classKeywordStatic(); \
|
||||
static bool Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class()
|
||||
|
||||
/// 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) \
|
||||
bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \
|
||||
QString ClassName::classKeywordStatic() { assert(PdmObject::isValidXmlElementName(keyword)); return keyword; } \
|
||||
static bool PDM_OBJECT_STRING_CONCATENATE(pdm_object_factory_init_, __LINE__) = 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) \
|
||||
{ \
|
||||
this->isInheritedFromPdmUiObject(); \
|
||||
this->isInheritedFromPdmXmlSerializable(); \
|
||||
\
|
||||
static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \
|
||||
setUiItemInfo(&objDescr); \
|
||||
this->setUiItemInfo(&objDescr); \
|
||||
}
|
||||
|
||||
/// InitField sets the file keyword for the field,
|
||||
@@ -106,216 +95,71 @@ public: \
|
||||
|
||||
#define CAF_PDM_InitField(field, keyword, default, uiName, iconResourceName, toolTip, whatsThis) \
|
||||
{ \
|
||||
static bool chekingThePresenceOfHeaderAndSourceInitMacros = Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class(); \
|
||||
\
|
||||
static bool chekingThePresenceOfHeaderAndSourceInitMacros = \
|
||||
Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class(); \
|
||||
this->isInheritedFromPdmUiObject(); \
|
||||
this->isInheritedFromPdmXmlSerializable(); \
|
||||
\
|
||||
AddXmlCapabilityToField(field); \
|
||||
AddUiCapabilityToField(field); \
|
||||
\
|
||||
static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \
|
||||
addField(field, keyword, default, &objDescr); \
|
||||
addFieldUi(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 bool chekingThePresenceOfHeaderAndSourceInitMacros = Error_You_forgot_to_add_the_macro_CAF_PDM_HEADER_INIT_and_or_CAF_PDM_SOURCE_INIT_to_your_cpp_file_for_this_class(); \
|
||||
static bool chekingThePresenceOfHeaderAndSourceInitMacros = \
|
||||
Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class(); \
|
||||
this->isInheritedFromPdmUiObject(); \
|
||||
this->isInheritedFromPdmXmlSerializable(); \
|
||||
\
|
||||
AddXmlCapabilityToField(field); \
|
||||
AddUiCapabilityToField(field); \
|
||||
\
|
||||
static caf::PdmUiItemInfo objDescr(uiName, QIcon(QString(iconResourceName)), toolTip, whatsThis); \
|
||||
addFieldNoDefault(field, keyword, &objDescr); \
|
||||
addFieldUiNoDefault(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
|
||||
} // End of namespace caf
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject : public PdmObjectHandle, public PdmXmlObjectHandle, public PdmUiObjectHandle
|
||||
{
|
||||
public:
|
||||
PdmObject() { }
|
||||
virtual ~PdmObject();
|
||||
PdmObject() : PdmObjectHandle(), PdmUiObjectHandle(this, false), PdmXmlObjectHandle(this, false) {}
|
||||
virtual ~PdmObject() {}
|
||||
|
||||
/// The classKeyword method is overridden in subclasses by the CAF_PDM_HEADER_INIT macro
|
||||
virtual QString classKeyword() = 0;
|
||||
|
||||
void readFields (QXmlStreamReader& inputStream );
|
||||
void writeFields(QXmlStreamWriter& outputStream);
|
||||
|
||||
PdmObject* deepCopy();
|
||||
|
||||
/// 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;
|
||||
/// Remove pointer to this from all parent fields
|
||||
void removeFromParentFields();
|
||||
|
||||
///
|
||||
void parentObjects(std::vector<PdmObject*>& objects) const;
|
||||
|
||||
///
|
||||
template <typename T>
|
||||
void parentObjectsOfType(std::vector<T*>& objects) const;
|
||||
|
||||
///
|
||||
template <typename T>
|
||||
void firstAncestorOfType(T*& ancestor) const;
|
||||
|
||||
/// Method to be called from the Ui classes creating Auto Gui to get the group information
|
||||
/// supplied by the \sa defineUiOrdering method that can be reimplemented
|
||||
void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) ;
|
||||
|
||||
/// Method to be called by Ui displaying a tree representation of the object hierarchy
|
||||
/// Caller must delete the returned object.
|
||||
PdmUiTreeOrdering* uiTreeOrdering( QString uiConfigName = "");
|
||||
|
||||
/// For a specific field, return editor specific parameters used to customize the editor behavior.
|
||||
void editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute);
|
||||
|
||||
/// Return object editor specific parameters used to customize the editor behavior.
|
||||
void objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute);
|
||||
|
||||
void updateUiIconFromToggleField();
|
||||
|
||||
// Virtual interface to override in subclasses to support special behaviour if needed
|
||||
public: // Virtual
|
||||
virtual PdmFieldHandle* userDescriptionField() { return NULL; }
|
||||
|
||||
/// Field used to toggle object on/off in UI-related uses of the object (ie checkbox in treeview)
|
||||
virtual PdmFieldHandle* objectToggleField() { 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>(); }
|
||||
// For later // virtual void editorAttributeChangedByUI(const PdmFieldHandle* field, QString uiConfigName, const PdmUiAttributeHandle * attributes);
|
||||
|
||||
|
||||
public:
|
||||
/// Check if a string is a valid Xml element name
|
||||
static bool isValidXmlElementName(const QString& name);
|
||||
|
||||
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() {};
|
||||
|
||||
/// Override to customize the order and grouping of the Gui.
|
||||
/// Fill up the uiOrdering object with groups and field references to create the gui structure
|
||||
/// If the uiOrdering is empty, it is interpreted as meaning all fields w/o grouping.
|
||||
virtual void defineUiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) {}
|
||||
|
||||
/// Override to customize the tree representations of the object hierarchy.
|
||||
/// If the PdmUiTreeOrdering is empty, it is interpreted as meaning all fields containing child objects in order
|
||||
virtual void defineUiTreeOrdering(PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) { }
|
||||
|
||||
/// Override to provide editor specific data for the field and uiConfigName
|
||||
virtual void defineEditorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) {}
|
||||
|
||||
/// Override to provide editor specific data for the uiConfigName for the object
|
||||
virtual void defineObjectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute * attribute) {}
|
||||
|
||||
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)
|
||||
void addFieldUi(PdmField<FieldDataType>* field, const QString& keyword, const FieldDataType& defaultValue, PdmUiItemInfo * fieldDescription)
|
||||
{
|
||||
addFieldNoDefault(field, keyword, fieldDescription);
|
||||
addFieldUiNoDefault(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);
|
||||
void addFieldUiNoDefault(PdmFieldHandle* field, const QString& keyword, PdmUiItemInfo * fieldDescription)
|
||||
{
|
||||
addField(field, keyword);
|
||||
|
||||
private:
|
||||
// Copy and assignment operators are implemented to avoid copying the internal management data structures.
|
||||
PdmUiFieldHandle* uiFieldHandle = uiField(field);
|
||||
if (uiFieldHandle)
|
||||
{
|
||||
uiFieldHandle->setUiItemInfo(fieldDescription);
|
||||
}
|
||||
}
|
||||
|
||||
// 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:
|
||||
/// Recursive function to traverse and create a Ui tree representation of the object hierarchy
|
||||
static void addUiTreeChildren( PdmUiTreeOrdering* root, QString uiConfigName = "" );
|
||||
|
||||
private:
|
||||
std::multiset<PdmFieldHandle*> m_parentFields;
|
||||
std::vector<PdmFieldHandle*> m_fields;
|
||||
|
||||
// Support system for PdmPointer
|
||||
friend class PdmPointerImpl;
|
||||
std::set<PdmObject**> m_pointersReferencingMe;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void PdmObject::parentObjectsOfType(std::vector<T*>& objects) const
|
||||
{
|
||||
std::vector<PdmObject*> parents;
|
||||
this->parentObjects(parents);
|
||||
|
||||
for (size_t i = 0; i < parents.size(); i++)
|
||||
{
|
||||
T* objectOfType = dynamic_cast<T*>(parents[i]);
|
||||
if (objectOfType)
|
||||
{
|
||||
objects.push_back(objectOfType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void PdmObject::firstAncestorOfType(T*& ancestor) const
|
||||
{
|
||||
std::vector<PdmObject*> parents;
|
||||
this->parentObjects(parents);
|
||||
|
||||
while (parents.size() > 0)
|
||||
{
|
||||
assert(parents.size() == 1);
|
||||
|
||||
PdmObject* firstParent = parents[0];
|
||||
assert(firstParent);
|
||||
|
||||
T* objectOfType = dynamic_cast<T*>(firstParent);
|
||||
if (objectOfType)
|
||||
{
|
||||
ancestor = objectOfType;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get next level parents
|
||||
parents.clear();
|
||||
firstParent->parentObjects(parents);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
|
||||
#include "cafPdmObjectGroup.h"
|
||||
#include "cafInternalPdmXmlFieldCapability.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
CAF_PDM_SOURCE_INIT(PdmObjectGroup, "PdmObjectGroup");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectGroup::PdmObjectGroup()
|
||||
{
|
||||
CAF_PDM_InitObject("Object Group", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&objects, "PdmObjects", "Children","", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectGroup::~PdmObjectGroup()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectGroup::deleteObjects()
|
||||
{
|
||||
size_t it;
|
||||
for (it = 0; it != objects.size(); ++it)
|
||||
{
|
||||
delete objects[it];
|
||||
}
|
||||
removeNullPtrs();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectGroup::removeNullPtrs()
|
||||
{
|
||||
objects.removeChildObject(NULL);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmObjectGroup::addObject(PdmObjectHandle * obj)
|
||||
{
|
||||
objects.push_back(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
//#include "cafPdmDataValueField.h"
|
||||
//#include "cafPdmObjectHandle.h"
|
||||
//#include "cafPdmPointer.h"
|
||||
//#include "cafPdmXmlObjectHandle.h"
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmReferenceHelper;
|
||||
|
||||
//==================================================================================================
|
||||
/// 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();
|
||||
|
||||
PdmChildArrayField<PdmObjectHandle*> objects;
|
||||
|
||||
void deleteObjects();
|
||||
void removeNullPtrs();
|
||||
void addObject(PdmObjectHandle * obj);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void createCopyByType(std::vector<PdmPointer<T> >* copyOfTypedObjects, PdmObjectFactory* objectFactory) const;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void PdmObjectGroup::createCopyByType(std::vector<PdmPointer<T> >* copyOfTypedObjects, PdmObjectFactory* objectFactory) const
|
||||
{
|
||||
std::vector<PdmPointer<T> > sourceTypedObjects;
|
||||
objectsByType(&sourceTypedObjects);
|
||||
|
||||
QString encodedXml;
|
||||
{
|
||||
// Write original objects to XML file
|
||||
QXmlStreamWriter xmlStream(&encodedXml);
|
||||
xmlStream.setAutoFormatting(true);
|
||||
|
||||
xmlStream.writeStartElement("", "PdmObjects");
|
||||
for (size_t i = 0; i < sourceTypedObjects.size(); i++)
|
||||
{
|
||||
PdmXmlObjectHandle* xmlObjHandle = sourceTypedObjects[i]->capability<PdmXmlObjectHandle>();
|
||||
assert(xmlObjHandle);
|
||||
|
||||
QString className = xmlObjHandle->classKeyword();
|
||||
|
||||
xmlStream.writeStartElement("", className);
|
||||
xmlObjHandle->writeFields(xmlStream);
|
||||
xmlStream.writeEndElement();
|
||||
}
|
||||
xmlStream.writeEndElement();
|
||||
}
|
||||
|
||||
// Read back XML into object group, factory methods will be called that will create new objects
|
||||
PdmObjectGroup destinationObjectGroup;
|
||||
QXmlStreamReader xmlStream(encodedXml);
|
||||
|
||||
PdmXmlObjectHandle* xmlObjHandle = destinationObjectGroup.capability<PdmXmlObjectHandle>();
|
||||
assert(xmlObjHandle);
|
||||
xmlObjHandle->readFields(xmlStream, objectFactory);
|
||||
|
||||
for (size_t it = 0; it < destinationObjectGroup.objects.size(); it++)
|
||||
{
|
||||
T* obj = dynamic_cast<T*>(destinationObjectGroup.objects[it]);
|
||||
if (obj) copyOfTypedObjects->push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project (cafPdmUiCore)
|
||||
|
||||
# Qt
|
||||
find_package ( Qt4 COMPONENTS QtCore QtGui )
|
||||
include (${QT_USE_FILE})
|
||||
|
||||
include_directories (
|
||||
|
||||
${cafPdmCore_SOURCE_DIR}
|
||||
..
|
||||
)
|
||||
|
||||
set( PROJECT_FILES
|
||||
|
||||
cafInternalPdmFieldTypeSpecializations.h
|
||||
cafInternalPdmUiFieldCapability.h
|
||||
cafInternalPdmUiFieldCapability.inl
|
||||
cafInternalPdmUiCommandSystemInterface.h
|
||||
|
||||
cafPdmUiEditorHandle.cpp
|
||||
cafPdmUiEditorHandle.h
|
||||
cafPdmUiFieldEditorHandle.cpp
|
||||
cafPdmUiFieldEditorHandle.h
|
||||
cafPdmUiFieldHandle.cpp
|
||||
cafPdmUiFieldHandle.h
|
||||
cafPdmUiFieldSpecialization.h
|
||||
cafPdmUiItem.cpp
|
||||
cafPdmUiItem.h
|
||||
cafPdmUiObjectEditorHandle.cpp
|
||||
cafPdmUiObjectEditorHandle.h
|
||||
cafPdmUiObjectHandle.cpp
|
||||
cafPdmUiObjectHandle.h
|
||||
cafPdmUiOrdering.cpp
|
||||
cafPdmUiOrdering.h
|
||||
cafPdmUiCommandSystemProxy.cpp
|
||||
cafPdmUiCommandSystemProxy.h
|
||||
cafPdmUiTreeOrdering.cpp
|
||||
cafPdmUiTreeOrdering.h
|
||||
cafUiTreeItem.h
|
||||
|
||||
cafSelectionManager.cpp
|
||||
cafSelectionManager.h
|
||||
|
||||
|
||||
)
|
||||
|
||||
|
||||
add_library( ${PROJECT_NAME}
|
||||
${PROJECT_FILES}
|
||||
)
|
||||
|
||||
source_group("" FILES ${PROJECT_FILES})
|
||||
@@ -0,0 +1,222 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
template <typename T> class PdmDataValueField;
|
||||
template <typename T> class PdmPointer;
|
||||
template <typename T> class AppEnum;
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< PdmPointer<T> >
|
||||
///
|
||||
/// Will package the PdmPointer<T> into QVariant as PdmPointer<PdmObject>
|
||||
/// Needed to support arbitrary types in PdmPointer without
|
||||
/// havning to declare everything Q_DECLARE_METATYPE()
|
||||
/// Also introduces the need for a isEqual() method, as this was the first
|
||||
/// custom type embedded in QVariant
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization < PdmPointer<T> >
|
||||
{
|
||||
public:
|
||||
static QVariant convert(const PdmPointer<T>& value)
|
||||
{
|
||||
return QVariant::fromValue(PdmPointer<PdmObjectHandle>(value.rawPtr()));
|
||||
}
|
||||
|
||||
static void setFromVariant(const QVariant& variantValue, PdmPointer<T>& value)
|
||||
{
|
||||
value.setRawPtr(variantValue.value<PdmPointer<PdmObjectHandle> >().rawPtr());
|
||||
}
|
||||
|
||||
static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2)
|
||||
{
|
||||
return variantValue.value<PdmPointer<PdmObjectHandle> >() == variantValue2.value<PdmPointer<PdmObjectHandle> >() ;
|
||||
}
|
||||
|
||||
static QList<PdmOptionItemInfo> valueOptions(bool* useOptionsOnly, const PdmPointer<T>&)
|
||||
{
|
||||
return QList<PdmOptionItemInfo>();
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< std::list<T> >
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization < 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>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2)
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
/// 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 PdmDataValueField< std::list<T> >& , std::vector<PdmObjectHandle*>* )
|
||||
{ }
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< std::vector<T> >
|
||||
//==================================================================================================
|
||||
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization < 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>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2)
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
/// 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 PdmDataValueField< std::vector<T> > & field, std::vector<PdmObjectHandle*>* objects)
|
||||
{ }
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
/// Partial specialization for PdmField< caf::AppEnum<T> >
|
||||
///
|
||||
/// Note : Makes the setUiValue() and uiValue() interface index based, and NOT based on real enum values.
|
||||
/// The valueOptions() interface is thus also index based (the value in the PdmOptionItemInfo is index NOT enum)
|
||||
/// This is probably going to change, ans it is strange.
|
||||
/// This conversion should really be done in the editors we think (now)
|
||||
//==================================================================================================
|
||||
|
||||
#define PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE 1
|
||||
|
||||
template <typename T>
|
||||
class PdmUiFieldSpecialization < caf::AppEnum<T> >
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert(const caf::AppEnum<T>& value)
|
||||
{
|
||||
#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE
|
||||
return QVariant(static_cast<unsigned int>(caf::AppEnum<T>::index(value)));
|
||||
#else
|
||||
unsigned int enumVal = value;
|
||||
return QVariant(enumVal);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant(const QVariant& variantValue, caf::AppEnum<T>& value)
|
||||
{
|
||||
#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE
|
||||
value.setFromIndex(variantValue.toInt());
|
||||
#else
|
||||
value = static_cast<T> (variantValue.toInt());
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2)
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
/// 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)
|
||||
{
|
||||
#if PDMFIELDAPPENUM_USE_INDEX_BASED_INTERFACE
|
||||
optionList.push_back(PdmOptionItemInfo(optionTexts[i], static_cast<unsigned int>(i)));
|
||||
#else
|
||||
optionList.push_back(PdmOptionItemInfo(optionTexts[i], caf::AppEnum<T>::fromIndex(i)));
|
||||
#endif
|
||||
}
|
||||
|
||||
return optionList;
|
||||
}
|
||||
|
||||
/// Methods to retrieve the possible PdmObject pointed to by a field
|
||||
static void childObjects(const PdmDataValueField< caf::AppEnum<T> >& field, std::vector<PdmObjectHandle*>* objects)
|
||||
{ }
|
||||
|
||||
};
|
||||
|
||||
} // End namespace caf
|
||||
@@ -0,0 +1,60 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
class QVariant;
|
||||
class QMenu;
|
||||
class QString;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmFieldHandle;
|
||||
class PdmUiFieldHandle;
|
||||
|
||||
|
||||
class PdmUiCommandSystemInterface
|
||||
{
|
||||
public:
|
||||
virtual void fieldChangedCommand(PdmFieldHandle* field, const QVariant& newUiValue) = 0;
|
||||
virtual void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
|
||||
|
||||
template < typename FieldType>
|
||||
class PdmFieldUiCap : public PdmUiFieldHandle
|
||||
{
|
||||
public:
|
||||
PdmFieldUiCap(FieldType* field, bool giveOwnership) : PdmUiFieldHandle(field, giveOwnership) { m_field = field; }
|
||||
|
||||
// Gui generalized interface
|
||||
public:
|
||||
virtual QVariant uiValue() const;
|
||||
virtual void setValueFromUi(const QVariant& uiValue);
|
||||
virtual QList<PdmOptionItemInfo> valueOptions(bool* useOptionsOnly);
|
||||
|
||||
virtual QVariant toUiBasedQVariant() const;
|
||||
|
||||
private:
|
||||
QList<PdmOptionItemInfo> m_optionEntryCache;
|
||||
|
||||
private:
|
||||
FieldType* m_field;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Specialization for ChildFields to do nothing towards GUI
|
||||
//
|
||||
template < typename DataType>
|
||||
class PdmFieldUiCap< PdmChildField<DataType*> > : public PdmUiFieldHandle
|
||||
{
|
||||
typedef PdmChildField<DataType*> FieldType;
|
||||
public:
|
||||
PdmFieldUiCap(FieldType* field, bool giveOwnership) : PdmUiFieldHandle(field, giveOwnership) { }
|
||||
|
||||
// Gui generalized interface
|
||||
public:
|
||||
virtual QVariant uiValue() const { return QVariant();}
|
||||
virtual void setValueFromUi(const QVariant& uiValue) { }
|
||||
virtual QList<PdmOptionItemInfo> valueOptions(bool* useOptionsOnly) { return QList<PdmOptionItemInfo>(); }
|
||||
|
||||
virtual QVariant toUiBasedQVariant() const { return QVariant(); }
|
||||
};
|
||||
|
||||
//
|
||||
// Specialization for ChildArrayFields to do nothing towards GUI
|
||||
//
|
||||
template < typename DataType>
|
||||
class PdmFieldUiCap< PdmChildArrayField<DataType*> > : public PdmUiFieldHandle
|
||||
{
|
||||
typedef PdmChildArrayField<DataType*> FieldType;
|
||||
public:
|
||||
PdmFieldUiCap(FieldType* field, bool giveOwnership) : PdmUiFieldHandle(field, giveOwnership) { }
|
||||
|
||||
// Gui generalized interface
|
||||
public:
|
||||
virtual QVariant uiValue() const { return QVariant(); }
|
||||
virtual void setValueFromUi(const QVariant& uiValue) { }
|
||||
virtual QList<PdmOptionItemInfo> valueOptions(bool* useOptionsOnly) { return QList<PdmOptionItemInfo>(); }
|
||||
|
||||
virtual QVariant toUiBasedQVariant() const { return QVariant(); }
|
||||
};
|
||||
|
||||
template<typename FieldType>
|
||||
void AddUiCapabilityToField(FieldType* field)
|
||||
{
|
||||
if(field->template capability< PdmFieldUiCap<FieldType> >() == NULL)
|
||||
{
|
||||
new PdmFieldUiCap<FieldType>(field, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafInternalPdmUiFieldCapability.inl"
|
||||
@@ -0,0 +1,233 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// This method is supposed to be the interface for the implementation of UI editors to set values into
|
||||
/// the field. The data to set must be encapsulated in a QVariant.
|
||||
/// This method triggers PdmObject::fieldChangedByUi() and PdmObject::updateConnectedEditors(), an thus
|
||||
/// makes the application and the UI aware of the change.
|
||||
///
|
||||
/// Note : If the field has optionValues the interface is _index-based_. The QVariant must contain
|
||||
/// an UInt representing the index to the option selected by the user interface.
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename FieldType >
|
||||
void caf::PdmFieldUiCap<FieldType>::setValueFromUi(const QVariant& uiValue)
|
||||
{
|
||||
QVariant oldUiBasedQVariant = toUiBasedQVariant();
|
||||
|
||||
// Check whether we are handling selections of values or actual values
|
||||
if (m_optionEntryCache.size())
|
||||
{
|
||||
// This has an option based GUI, the uiValue is only indexes into the m_optionEntryCache
|
||||
if (uiValue.type() == QVariant::UInt)
|
||||
{
|
||||
assert(uiValue.toUInt() < static_cast<unsigned int>(m_optionEntryCache.size()));
|
||||
typename FieldType::FieldDataType value;
|
||||
PdmUiFieldSpecialization<typename FieldType::FieldDataType>::setFromVariant(m_optionEntryCache[uiValue.toUInt()].value, value);
|
||||
m_field->setValue(value);
|
||||
}
|
||||
else if (uiValue.type() == QVariant::List)
|
||||
{
|
||||
QList<QVariant> selectedIndexes = uiValue.toList();
|
||||
QList<QVariant> valuesToSetInField;
|
||||
|
||||
if (selectedIndexes.isEmpty())
|
||||
{
|
||||
typename FieldType::FieldDataType value;
|
||||
PdmUiFieldSpecialization<typename FieldType::FieldDataType>::setFromVariant(valuesToSetInField, value);
|
||||
m_field->setValue(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedIndexes.front().type() == QVariant::UInt)
|
||||
{
|
||||
for (int i = 0; i < selectedIndexes.size(); ++i)
|
||||
{
|
||||
unsigned int opIdx = selectedIndexes[i].toUInt();
|
||||
if (opIdx < static_cast<unsigned int>(m_optionEntryCache.size()))
|
||||
{
|
||||
valuesToSetInField.push_back(m_optionEntryCache[opIdx].value);
|
||||
}
|
||||
}
|
||||
typename FieldType::FieldDataType value;
|
||||
PdmUiFieldSpecialization<typename FieldType::FieldDataType>::setFromVariant(valuesToSetInField, value);
|
||||
m_field->setValue(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are not getting indexes as expected from the UI. For now assert, to catch this condition
|
||||
// but it should possibly be handled as setting the values explicitly. The code for that is below the assert
|
||||
assert(false);
|
||||
typename FieldType::FieldDataType value;
|
||||
PdmUiFieldSpecialization<typename FieldType::FieldDataType>::setFromVariant(uiValue, value);
|
||||
m_field->setValue(value);
|
||||
m_optionEntryCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are not getting indexes as expected from the UI. For now assert, to catch this condition
|
||||
// but it should possibly be handled as setting the values explicitly. The code for that is below the assert
|
||||
assert(false);
|
||||
typename FieldType::FieldDataType value;
|
||||
PdmUiFieldSpecialization<typename FieldType::FieldDataType>::setFromVariant(uiValue, value);
|
||||
m_field->setValue(value);
|
||||
m_optionEntryCache.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Not an option based GUI, the uiValue is a real field value
|
||||
typename FieldType::FieldDataType value;
|
||||
PdmUiFieldSpecialization<typename FieldType::FieldDataType>::setFromVariant(uiValue, value);
|
||||
m_field->setValue(value);
|
||||
}
|
||||
|
||||
QVariant newUiBasedQVariant = toUiBasedQVariant();
|
||||
|
||||
this->notifyFieldChanged(oldUiBasedQVariant, newUiBasedQVariant);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Extracts a QVariant representation of the data in the field to be used in the UI.
|
||||
///
|
||||
/// Note : For fields with a none-empty valueOptions list, the returned QVariant contains the
|
||||
/// _indexes_ to the selected options rather than the actual values, if they can be found.
|
||||
///
|
||||
/// If this is a multivalue field, and we cant find all of the field values among the options,
|
||||
/// the method asserts (For now), forcing the valueOptions to always contain the field values.
|
||||
/// Single value fields will return -1 if the option is not found, allowing the concept of "nothing selected"
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename FieldType >
|
||||
QVariant caf::PdmFieldUiCap<FieldType>::uiValue() const
|
||||
{
|
||||
if (m_optionEntryCache.size())
|
||||
{
|
||||
QVariant uiBasedQVariant = toUiBasedQVariant();
|
||||
std::vector<unsigned int> indexesToFoundOptions;
|
||||
PdmOptionItemInfo::findValues<typename FieldType::FieldDataType>(m_optionEntryCache, uiBasedQVariant, indexesToFoundOptions);
|
||||
if (uiBasedQVariant.type() == QVariant::List)
|
||||
{
|
||||
if (indexesToFoundOptions.size() == static_cast<size_t>(uiBasedQVariant.toList().size()))
|
||||
{
|
||||
QList<QVariant> returnList;
|
||||
for (size_t i = 0; i < indexesToFoundOptions.size(); ++i)
|
||||
{
|
||||
returnList.push_back(QVariant(indexesToFoundOptions[i]));
|
||||
}
|
||||
return QVariant(returnList);
|
||||
}
|
||||
assert(false); // Did not find all the field values among the options available.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (indexesToFoundOptions.size() == 1) return QVariant(indexesToFoundOptions.front());
|
||||
else return QVariant(-1); // Return -1 if not found instead of assert. Should result in clearing the selection
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return uiBasedQVariant;
|
||||
}
|
||||
else
|
||||
{
|
||||
return toUiBasedQVariant();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the option values that is to be displayed in the UI for this field.
|
||||
/// This method calls the virtual PdmObject::calculateValueOptions to get the list provided from the
|
||||
/// application, then possibly adds the current field value(s) to the list, to
|
||||
/// make sure the actual values are shown
|
||||
///
|
||||
/// Note: This method is missing the uiConfigName concept. This is a Todo. The m_optionEntryCache
|
||||
/// then needs to be stored pr. uiConfigName.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename FieldType >
|
||||
QList<PdmOptionItemInfo> caf::PdmFieldUiCap<FieldType>::valueOptions(bool* useOptionsOnly)
|
||||
{
|
||||
// First check if the owner PdmObject has a value options specification.
|
||||
// if it has, use it.
|
||||
if (m_field->ownerObject())
|
||||
{
|
||||
m_optionEntryCache = uiObj(m_field->ownerObject())->calculateValueOptions(this->m_field, useOptionsOnly);
|
||||
if (m_optionEntryCache.size())
|
||||
{
|
||||
// Make sure the options contain the field values, event though they not necessarily
|
||||
// is supplied as possible options by the application. This is a convenience making sure
|
||||
// the actual data in the pdmObject is shown correctly in the UI, and to prevent accidental
|
||||
// changes of the field values
|
||||
|
||||
// Find the field value(s) in the list if present
|
||||
|
||||
QVariant uiBasedQVariant = toUiBasedQVariant();
|
||||
|
||||
std::vector<unsigned int> foundIndexes;
|
||||
bool foundAllFieldValues = PdmOptionItemInfo::findValues<typename FieldType::FieldDataType>(m_optionEntryCache, uiBasedQVariant, foundIndexes);
|
||||
|
||||
// If not all are found, we have to add the missing to the list, to be able to show it
|
||||
|
||||
if (!foundAllFieldValues)
|
||||
{
|
||||
if (uiBasedQVariant.type() != QVariant::List) // Single value field
|
||||
{
|
||||
if (!uiBasedQVariant.toString().isEmpty())
|
||||
{
|
||||
m_optionEntryCache.push_front(PdmOptionItemInfo(uiBasedQVariant.toString(), uiBasedQVariant, true, QIcon()));
|
||||
}
|
||||
}
|
||||
else // The field value is a list of values
|
||||
{
|
||||
QList<QVariant> valuesSelectedInField = uiBasedQVariant.toList();
|
||||
for (int i= 0 ; i < valuesSelectedInField.size(); ++i)
|
||||
{
|
||||
bool isFound = false;
|
||||
for (unsigned int opIdx = 0; opIdx < static_cast<unsigned int>(m_optionEntryCache.size()); ++opIdx)
|
||||
{
|
||||
if (valuesSelectedInField[i] == m_optionEntryCache[opIdx].value) isFound = true;
|
||||
}
|
||||
|
||||
if (!isFound && !valuesSelectedInField[i].toString().isEmpty())
|
||||
{
|
||||
m_optionEntryCache.push_front(PdmOptionItemInfo(valuesSelectedInField[i].toString(), valuesSelectedInField[i], true, QIcon()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_optionEntryCache;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have no options, use the options defined by the type. Normally only caf::AppEnum type
|
||||
|
||||
#if 0
|
||||
m_optionEntryCache = PdmFieldTypeSpecialization<typename FieldType::FieldDataType>::valueOptions(useOptionsOnly, m_fieldValue);
|
||||
return m_optionEntryCache;
|
||||
#else
|
||||
return PdmUiFieldSpecialization<typename FieldType::FieldDataType>::valueOptions(useOptionsOnly, m_field->value());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename FieldType>
|
||||
QVariant caf::PdmFieldUiCap<FieldType>::toUiBasedQVariant() const
|
||||
{
|
||||
return PdmUiFieldSpecialization<typename FieldType::FieldDataType>::convert(m_field->value());
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cafPdmUiCommandSystemProxy.h"
|
||||
|
||||
#include "cafInternalPdmUiCommandSystemInterface.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace caf {
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiCommandSystemProxy* PdmUiCommandSystemProxy::instance()
|
||||
{
|
||||
static PdmUiCommandSystemProxy staticInstance;
|
||||
|
||||
return &staticInstance;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiCommandSystemProxy::PdmUiCommandSystemProxy()
|
||||
{
|
||||
m_commandInterface = NULL;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiCommandSystemProxy::setCommandInterface(PdmUiCommandSystemInterface* commandInterface)
|
||||
{
|
||||
m_commandInterface = commandInterface;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiCommandSystemProxy::setUiValueToField(PdmUiFieldHandle* uiFieldHandle, const QVariant& newUiValue)
|
||||
{
|
||||
if (uiFieldHandle)
|
||||
{
|
||||
if (m_commandInterface)
|
||||
{
|
||||
m_commandInterface->fieldChangedCommand(uiFieldHandle->fieldHandle(), newUiValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
uiFieldHandle->setValueFromUi(newUiValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiCommandSystemProxy::populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu)
|
||||
{
|
||||
if (m_commandInterface)
|
||||
{
|
||||
m_commandInterface->populateMenuWithDefaultCommands(uiConfigName, menu);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace caf
|
||||
@@ -0,0 +1,67 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#pragma once
|
||||
|
||||
class QVariant;
|
||||
class QMenu;
|
||||
class QString;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmFieldHandle;
|
||||
class PdmUiFieldHandle;
|
||||
class PdmUiCommandSystemInterface;
|
||||
|
||||
|
||||
class PdmUiCommandSystemProxy
|
||||
{
|
||||
public:
|
||||
PdmUiCommandSystemProxy();
|
||||
|
||||
static PdmUiCommandSystemProxy* instance();
|
||||
void setCommandInterface(PdmUiCommandSystemInterface* undoCommandInterface);
|
||||
|
||||
void setUiValueToField(PdmUiFieldHandle* uiFieldHandle, const QVariant& newUiValue);
|
||||
void populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu);
|
||||
|
||||
private:
|
||||
PdmUiCommandSystemInterface* m_commandInterface;
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
+9
-1
@@ -36,11 +36,18 @@
|
||||
|
||||
|
||||
#include "cafPdmUiEditorHandle.h"
|
||||
#include "cafPdmUiItem.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiEditorHandle::PdmUiEditorHandle() : m_pdmItem(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -59,5 +66,6 @@ void PdmUiEditorHandle::bindToPdmItem(PdmUiItem* item)
|
||||
if (m_pdmItem) m_pdmItem->addFieldEditor(this);
|
||||
}
|
||||
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
+5
-5
@@ -36,24 +36,24 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmUiItem;
|
||||
|
||||
//==================================================================================================
|
||||
/// Abstract class to handle editors
|
||||
/// Abstract class to handle editors. Inherits QObject to be able to use signals and slots
|
||||
//==================================================================================================
|
||||
|
||||
class PdmUiEditorHandle: public QObject
|
||||
{
|
||||
public:
|
||||
PdmUiEditorHandle() : m_pdmItem(NULL) {}
|
||||
PdmUiEditorHandle();
|
||||
virtual ~PdmUiEditorHandle();
|
||||
|
||||
public:
|
||||
+16
-10
@@ -36,7 +36,11 @@
|
||||
|
||||
|
||||
#include "cafPdmUiFieldEditorHandle.h"
|
||||
#include "cafPdmField.h"
|
||||
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
#include "cafPdmUiCommandSystemProxy.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
@@ -57,15 +61,15 @@ PdmUiFieldEditorHandle::PdmUiFieldEditorHandle()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiFieldEditorHandle::~PdmUiFieldEditorHandle()
|
||||
{
|
||||
if (!m_combinedWidget.isNull()) delete m_combinedWidget;
|
||||
if (!m_editorWidget.isNull()) delete m_editorWidget ;
|
||||
if (!m_labelWidget.isNull()) delete m_labelWidget;
|
||||
if (!m_combinedWidget.isNull()) m_combinedWidget->deleteLater();
|
||||
if (!m_editorWidget.isNull()) m_editorWidget->deleteLater();
|
||||
if (!m_labelWidget.isNull()) m_labelWidget->deleteLater();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiFieldEditorHandle::setField(PdmFieldHandle * field)
|
||||
void PdmUiFieldEditorHandle::setField(PdmUiFieldHandle * field)
|
||||
{
|
||||
this->bindToPdmItem(field);
|
||||
}
|
||||
@@ -73,9 +77,9 @@ void PdmUiFieldEditorHandle::setField(PdmFieldHandle * field)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmFieldHandle* PdmUiFieldEditorHandle::field()
|
||||
PdmUiFieldHandle* PdmUiFieldEditorHandle::field()
|
||||
{
|
||||
return dynamic_cast<PdmFieldHandle*>(pdmItem());
|
||||
return dynamic_cast<PdmUiFieldHandle*>(pdmItem());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -89,11 +93,13 @@ void PdmUiFieldEditorHandle::createWidgets(QWidget * parent)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
/// Well this is food for thought. How do we spawn commands, without making us
|
||||
/// dependent on the command system. It should be optional to use, and not depending on the command "library"
|
||||
/// JJS
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiFieldEditorHandle::setValueToField(const QVariant& value)
|
||||
void PdmUiFieldEditorHandle::setValueToField(const QVariant& newUiValue)
|
||||
{
|
||||
if (field()) field()->setValueFromUi(value);
|
||||
PdmUiCommandSystemProxy::instance()->setUiValueToField(field(), newUiValue);
|
||||
}
|
||||
|
||||
|
||||
+13
-15
@@ -36,17 +36,17 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include <QPointer>
|
||||
#include <QWidget>
|
||||
|
||||
#include "cafFactory.h"
|
||||
|
||||
#include "cafPdmUiEditorHandle.h"
|
||||
#include <typeinfo>
|
||||
#include "cafClassTypeName.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QPointer>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
// Taken from gtest.h
|
||||
//
|
||||
@@ -68,9 +68,6 @@ namespace caf
|
||||
/// Macros helping in development of PDM UI editors
|
||||
//==================================================================================================
|
||||
|
||||
/// Create a QString based on a typename
|
||||
#define qStringTypeName(TypeName) QString(typeid(TypeName).name())
|
||||
|
||||
/// CAF_PDM_UI_EDITOR_HEADER_INIT assists the factory used when creating editors
|
||||
/// Place this in the header file inside the class definition of your PdmUiEditor
|
||||
|
||||
@@ -86,10 +83,11 @@ public: \
|
||||
static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(pdm_field_editor_registrate_, __LINE__) = caf::Factory<caf::PdmUiFieldEditorHandle, QString>::instance()->registerCreator<EditorClassName>(EditorClassName::uiEditorTypeName())
|
||||
|
||||
#define CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(EditorClassName, TypeName) \
|
||||
static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(pdm_field_register_default_editor_, __LINE__) = caf::Factory<caf::PdmUiFieldEditorHandle, QString>::instance()->registerCreator<EditorClassName>(qStringTypeName(caf::PdmField<TypeName>))
|
||||
static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(pdm_field_register_default_editor_, __LINE__) = caf::Factory<caf::PdmUiFieldEditorHandle, QString>::instance()->registerCreator<EditorClassName>(qStringTypeName(caf::PdmField<TypeName>)); \
|
||||
static bool PDM_FIELD_EDITOR_STRING_CONCATENATE(pdm_Proxy_field_register_default_editor_, __LINE__) = caf::Factory<caf::PdmUiFieldEditorHandle, QString>::instance()->registerCreator<EditorClassName>(qStringTypeName(caf::PdmProxyValueField<TypeName>))
|
||||
|
||||
class PdmUiGroup;
|
||||
class PdmFieldHandle;
|
||||
class PdmUiFieldHandle;
|
||||
|
||||
//==================================================================================================
|
||||
/// Abstract class to handle editors of PdmFields
|
||||
@@ -102,8 +100,8 @@ public:
|
||||
PdmUiFieldEditorHandle();
|
||||
~PdmUiFieldEditorHandle();
|
||||
|
||||
PdmFieldHandle* field();
|
||||
void setField(PdmFieldHandle * field);
|
||||
PdmUiFieldHandle* field();
|
||||
void setField(PdmUiFieldHandle * field);
|
||||
|
||||
void createWidgets(QWidget * parent);
|
||||
QWidget* combinedWidget() { return m_combinedWidget; }
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
#include "cafPdmFieldHandle.h"
|
||||
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiFieldHandle* uiField(PdmFieldHandle* field)
|
||||
{
|
||||
if (!field) return NULL;
|
||||
PdmUiFieldHandle* uiField = field->capability<PdmUiFieldHandle>();
|
||||
return uiField;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiFieldHandle::PdmUiFieldHandle(PdmFieldHandle* owner, bool giveOwnership)
|
||||
{
|
||||
m_owner = owner;
|
||||
owner->addCapability(this, giveOwnership);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiFieldHandle::notifyFieldChanged(const QVariant& oldFieldValue, const QVariant& newFieldValue)
|
||||
{
|
||||
if (oldFieldValue != newFieldValue)
|
||||
{
|
||||
PdmFieldHandle* fieldHandle = this->fieldHandle();
|
||||
assert(fieldHandle && fieldHandle->ownerObject());
|
||||
|
||||
PdmUiObjectHandle* uiObjHandle = uiObj(fieldHandle->ownerObject());
|
||||
if (uiObjHandle)
|
||||
{
|
||||
uiObjHandle->fieldChangedByUi(fieldHandle, oldFieldValue, newFieldValue);
|
||||
uiObjHandle->updateConnectedEditors();
|
||||
}
|
||||
|
||||
// Update field editors
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiFieldHandle::updateConnectedUiEditors(PdmFieldHandle* field)
|
||||
{
|
||||
if (!field) return;
|
||||
|
||||
PdmUiFieldHandle* uiFieldHandle = field->capability<PdmUiFieldHandle>();
|
||||
if (uiFieldHandle)
|
||||
{
|
||||
uiFieldHandle->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafPdmFieldCapability.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmFieldHandle;
|
||||
|
||||
class PdmUiFieldHandle : public PdmUiItem, public PdmFieldCapability
|
||||
{
|
||||
public:
|
||||
PdmUiFieldHandle(PdmFieldHandle* owner, bool giveOwnership);
|
||||
virtual ~PdmUiFieldHandle() { }
|
||||
|
||||
PdmFieldHandle* fieldHandle() { return m_owner; }
|
||||
|
||||
// Generalized access methods for User interface
|
||||
// The QVariant encapsulates the real value, or an index into the valueOptions
|
||||
|
||||
virtual QVariant uiValue() const { return QVariant(); }
|
||||
virtual void setValueFromUi(const QVariant& uiValue) { }
|
||||
virtual QList<PdmOptionItemInfo>
|
||||
valueOptions(bool* useOptionsOnly) { return QList<PdmOptionItemInfo>(); }
|
||||
|
||||
virtual QVariant toUiBasedQVariant() const { return QVariant(); }
|
||||
void notifyFieldChanged(const QVariant& oldUiBasedQVariant, const QVariant& newUiBasedQVariant);
|
||||
|
||||
static void updateConnectedUiEditors(PdmFieldHandle* field);
|
||||
|
||||
private:
|
||||
PdmFieldHandle* m_owner;
|
||||
};
|
||||
|
||||
PdmUiFieldHandle* uiField(PdmFieldHandle* field);
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <QVariant>
|
||||
#include <QList>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
template <typename T> class PdmDataValueField;
|
||||
class PdmOptionItemInfo;
|
||||
class PdmObjectHandle;
|
||||
|
||||
//==================================================================================================
|
||||
/// 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 PdmUiFieldSpecialization
|
||||
{
|
||||
public:
|
||||
/// Convert the field value into a QVariant
|
||||
static QVariant convert(const T& value)
|
||||
{
|
||||
return QVariant::fromValue(value);
|
||||
}
|
||||
|
||||
/// Set the field value from a QVariant
|
||||
static void setFromVariant(const QVariant& variantValue, T& value)
|
||||
{
|
||||
value = variantValue.value<T>();
|
||||
}
|
||||
|
||||
/// Check equality between QVariants that carries a Field Value.
|
||||
/// The == operator will normally work, but does not support custom types in the QVariant
|
||||
/// See http://qt-project.org/doc/qt-4.8/qvariant.html#operator-eq-eq-64
|
||||
/// This is needed for the lookup regarding OptionValues
|
||||
static bool isEqual(const QVariant& variantValue, const QVariant& variantValue2)
|
||||
{
|
||||
return variantValue == variantValue2;
|
||||
}
|
||||
|
||||
/// 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 PdmDataValueField<T>& , std::vector<PdmObjectHandle*>* )
|
||||
{ }
|
||||
|
||||
};
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafInternalPdmFieldTypeSpecializations.h"
|
||||
|
||||
-45
@@ -55,51 +55,6 @@ QStringList PdmOptionItemInfo::extractUiTexts(const QList<PdmOptionItemInfo>& op
|
||||
return texts;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Finds the indexes into the optionList that the field value(s) corresponds to.
|
||||
/// In the case where the field is some kind of array, several indexes might be returned
|
||||
/// The returned bool is true if all the fieldValues were found.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmOptionItemInfo::findValues(const QList<PdmOptionItemInfo>& optionList , QVariant fieldValue, std::vector<unsigned int>& foundIndexes)
|
||||
{
|
||||
foundIndexes.clear();
|
||||
|
||||
// Find this fieldvalue in the optionlist if present
|
||||
|
||||
// First handle lists/arrays of values
|
||||
if (fieldValue.type() == QVariant::List)
|
||||
{
|
||||
QList<QVariant> valuesSelectedInField = fieldValue.toList();
|
||||
|
||||
if (valuesSelectedInField.size())
|
||||
{
|
||||
for (int i= 0 ; i < valuesSelectedInField.size(); ++i)
|
||||
{
|
||||
for (unsigned int opIdx = 0; opIdx < static_cast<unsigned int>(optionList.size()); ++opIdx)
|
||||
{
|
||||
if (valuesSelectedInField[i] == optionList[opIdx].value)
|
||||
{
|
||||
foundIndexes.push_back(opIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (static_cast<size_t>(valuesSelectedInField.size()) <= foundIndexes.size());
|
||||
}
|
||||
else // Then handle single value fields
|
||||
{
|
||||
for(unsigned int opIdx = 0; opIdx < static_cast<unsigned int>(optionList.size()); ++opIdx)
|
||||
{
|
||||
if (optionList[opIdx].value == fieldValue)
|
||||
{
|
||||
foundIndexes.push_back(opIdx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (foundIndexes.size() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
+50
@@ -36,6 +36,9 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmUiFieldSpecialization.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QIcon>
|
||||
#include <QVariant>
|
||||
@@ -96,11 +99,58 @@ public:
|
||||
// Please regard as private to the PDM system
|
||||
|
||||
static QStringList extractUiTexts(const QList<PdmOptionItemInfo>& optionList );
|
||||
template<typename T>
|
||||
static bool findValues (const QList<PdmOptionItemInfo>& optionList , QVariant fieldValue,
|
||||
std::vector<unsigned int>& foundIndexes);
|
||||
};
|
||||
|
||||
class PdmUiEditorHandle;
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Finds the indexes into the optionList that the field value(s) corresponds to.
|
||||
/// In the case where the field is some kind of array, several indexes might be returned
|
||||
/// The returned bool is true if all the fieldValues were found.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
bool PdmOptionItemInfo::findValues(const QList<PdmOptionItemInfo>& optionList, QVariant fieldValue, std::vector<unsigned int>& foundIndexes)
|
||||
{
|
||||
foundIndexes.clear();
|
||||
|
||||
// Find this fieldvalue in the optionlist if present
|
||||
|
||||
// First handle lists/arrays of values
|
||||
if (fieldValue.type() == QVariant::List)
|
||||
{
|
||||
QList<QVariant> valuesSelectedInField = fieldValue.toList();
|
||||
|
||||
if (valuesSelectedInField.size())
|
||||
{
|
||||
for (int i= 0 ; i < valuesSelectedInField.size(); ++i)
|
||||
{
|
||||
for (unsigned int opIdx = 0; opIdx < static_cast<unsigned int>(optionList.size()); ++opIdx)
|
||||
{
|
||||
if (PdmUiFieldSpecialization<T>::isEqual(valuesSelectedInField[i], optionList[opIdx].value))
|
||||
{
|
||||
foundIndexes.push_back(opIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (static_cast<size_t>(valuesSelectedInField.size()) <= foundIndexes.size());
|
||||
}
|
||||
else // Then handle single value fields
|
||||
{
|
||||
for (unsigned int opIdx = 0; opIdx < static_cast<unsigned int>(optionList.size()); ++opIdx)
|
||||
{
|
||||
if (PdmUiFieldSpecialization<T>::isEqual(optionList[opIdx].value, fieldValue))
|
||||
{
|
||||
foundIndexes.push_back(opIdx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (foundIndexes.size() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
/// Base class for all datastructure items (fields or objects) to make them have information on
|
||||
+16
-5
@@ -36,7 +36,9 @@
|
||||
|
||||
|
||||
#include "cafPdmUiObjectEditorHandle.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
@@ -57,19 +59,28 @@ QWidget* PdmUiObjectEditorHandle::getOrCreateWidget(QWidget* parent)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiObjectEditorHandle::setPdmObject(PdmObject* object)
|
||||
void PdmUiObjectEditorHandle::setPdmObject(PdmObjectHandle* object)
|
||||
{
|
||||
cleanupBeforeSettingPdmObject();
|
||||
|
||||
this->bindToPdmItem(object);
|
||||
caf::PdmUiObjectHandle* uiObject = uiObj(object);
|
||||
this->bindToPdmItem(uiObject);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObject* PdmUiObjectEditorHandle::pdmObject()
|
||||
PdmObjectHandle* PdmUiObjectEditorHandle::pdmObject()
|
||||
{
|
||||
return dynamic_cast<PdmObject*>(pdmItem());
|
||||
PdmUiObjectHandle* uiObject = dynamic_cast<PdmUiObjectHandle*>(pdmItem());
|
||||
if (uiObject)
|
||||
{
|
||||
return uiObject->owner();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
} //End of namespace caf
|
||||
+11
-8
@@ -36,17 +36,20 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
|
||||
#include "cafPdmUiEditorHandle.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include <QPointer>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject;
|
||||
class PdmObjectHandle;
|
||||
|
||||
//==================================================================================================
|
||||
/// Abstract class to handle editors for complete PdmObjects
|
||||
@@ -61,15 +64,15 @@ public:
|
||||
QWidget* getOrCreateWidget(QWidget* parent);
|
||||
QWidget* widget() { return m_widget; }
|
||||
|
||||
void setPdmObject(PdmObject* object);
|
||||
PdmObject* pdmObject();
|
||||
void setPdmObject(PdmObjectHandle* object);
|
||||
PdmObjectHandle* pdmObject();
|
||||
|
||||
protected:
|
||||
virtual QWidget* createWidget(QWidget* parent) = 0;
|
||||
virtual void cleanupBeforeSettingPdmObject() {};
|
||||
|
||||
protected:
|
||||
QPointer<QWidget> m_widget;
|
||||
QPointer<QWidget> m_widget;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
#include "cafPdmUiOrdering.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiObjectHandle::PdmUiObjectHandle(PdmObjectHandle* owner, bool giveOwnership)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_owner->addCapability(this, giveOwnership);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiObjectHandle* uiObj(PdmObjectHandle* obj)
|
||||
{
|
||||
if (!obj) return NULL;
|
||||
PdmUiObjectHandle* uiObject = obj->capability<PdmUiObjectHandle>();
|
||||
assert(uiObject);
|
||||
return uiObject;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiObjectHandle::uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
#if 1
|
||||
this->defineUiOrdering(uiConfigName, uiOrdering);
|
||||
if (!uiOrdering.forgetRemainingFields())
|
||||
{
|
||||
// Add the remaining Fields To UiConfig
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
m_owner->fields(fields);
|
||||
for (size_t i = 0; i < fields.size(); ++i)
|
||||
{
|
||||
PdmUiFieldHandle * field = uiField(fields[i]);
|
||||
if (!uiOrdering.contains(field))
|
||||
{
|
||||
uiOrdering.add(field->fieldHandle());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiObjectHandle::editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute)
|
||||
{
|
||||
this->defineEditorAttribute(field, uiConfigName, attribute);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiObjectHandle::objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute)
|
||||
{
|
||||
this->defineObjectEditorAttribute(uiConfigName, attribute);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// This method creates a tree-representation of the object hierarchy starting at this
|
||||
/// object to be used for a tree view.
|
||||
/// This method calls the optional virtual user defined method "defineUiTreeOrdering" to customize the
|
||||
/// order and content of the children directly below each object. If this method does nothing,
|
||||
/// the default behavior applies: Add all fields that contains objects, and their objects.
|
||||
///
|
||||
/// The caller is responsible to delete the returned PdmUiTreeOrdering
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering* PdmUiObjectHandle::uiTreeOrdering(QString uiConfigName /*= ""*/)
|
||||
{
|
||||
assert(this); // This method actually is possible to call on a NULL ptr without getting a crash, so we assert instead.
|
||||
|
||||
PdmUiTreeOrdering* uiTreeOrdering = new PdmUiTreeOrdering(NULL, m_owner);
|
||||
|
||||
expandUiTree(uiTreeOrdering, uiConfigName);
|
||||
|
||||
return uiTreeOrdering;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Adds the direct children of this PdmObject to the PdmUiTree according to
|
||||
/// the default rules. Add all fields that contains objects, and their objects.
|
||||
/// Takes into account the control variables regarding this:
|
||||
/// PdmField::isUiHidden
|
||||
/// PdmField::isUiChildrenHidden
|
||||
/// And whether the fields and objects are already added by the user.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiObjectHandle::addDefaultUiTreeChildren(PdmUiTreeOrdering* uiTreeOrdering)
|
||||
{
|
||||
#if 1
|
||||
if (!uiTreeOrdering->forgetRemainingFields())
|
||||
{
|
||||
// Add the remaining Fields To UiConfig
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
m_owner->fields(fields);
|
||||
|
||||
for (size_t fIdx = 0; fIdx < fields.size(); ++fIdx)
|
||||
{
|
||||
if (fields[fIdx]->hasChildObjects() && !uiTreeOrdering->containsField(fields[fIdx]))
|
||||
{
|
||||
if (uiField(fields[fIdx])->isUiHidden() && !uiField(fields[fIdx])->isUiChildrenHidden())
|
||||
{
|
||||
std::vector<PdmObjectHandle*> children;
|
||||
fields[fIdx]->childObjects(&children);
|
||||
|
||||
for (size_t cIdx = 0; cIdx < children.size(); cIdx++)
|
||||
{
|
||||
if (!uiTreeOrdering->containsObject(children[cIdx]))
|
||||
{
|
||||
uiTreeOrdering->add(children[cIdx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!uiField(fields[fIdx])->isUiHidden())
|
||||
{
|
||||
uiTreeOrdering->add(fields[fIdx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Builds the sPdmUiTree for all the children of @param root recursively, and stores the result
|
||||
/// in root
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiObjectHandle::expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName /*= "" */)
|
||||
{
|
||||
#if 1
|
||||
if (!root || !root->isValid()) return;
|
||||
|
||||
if (root->childCount() > 0)
|
||||
{
|
||||
for (int cIdx = 0; cIdx < root->childCount(); ++cIdx)
|
||||
{
|
||||
PdmUiTreeOrdering* child = root->child(cIdx);
|
||||
if (child->isValid() && !child->ignoreSubTree())
|
||||
{
|
||||
expandUiTree(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
else //( root->childCount() == 0) // This means that no one has tried to expand it.
|
||||
{
|
||||
if (!root->ignoreSubTree())
|
||||
{
|
||||
if (root->isRepresentingField() && !uiField(root->field())->isUiChildrenHidden(uiConfigName))
|
||||
{
|
||||
std::vector<PdmObjectHandle*> fieldsChildObjects;
|
||||
root->field()->childObjects(&fieldsChildObjects);
|
||||
for (size_t cIdx = 0; cIdx < fieldsChildObjects.size(); ++cIdx)
|
||||
{
|
||||
PdmObjectHandle* childObject = fieldsChildObjects[cIdx];
|
||||
if (childObject)
|
||||
{
|
||||
root->appendChild(uiObj(childObject)->uiTreeOrdering(uiConfigName));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (root->isRepresentingObject())
|
||||
{
|
||||
uiObj(root->object())->defineUiTreeOrdering(*root, uiConfigName);
|
||||
uiObj(root->object())->addDefaultUiTreeChildren(root);
|
||||
if (root->childCount())
|
||||
{
|
||||
expandUiTree(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiObjectHandle::updateUiIconFromToggleField()
|
||||
{
|
||||
if (objectToggleField())
|
||||
{
|
||||
PdmUiFieldHandle* uiFieldHandle = uiField(objectToggleField());
|
||||
if (uiFieldHandle)
|
||||
{
|
||||
bool active = uiFieldHandle->uiValue().toBool();
|
||||
updateUiIconFromState(active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace caf
|
||||
@@ -0,0 +1,92 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafPdmObjectCapability.h"
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmUiEditorAttribute;
|
||||
class PdmUiTreeOrdering;
|
||||
class PdmObjectHandle;
|
||||
class PdmUiOrdering;
|
||||
class PdmFieldHandle;
|
||||
class PdmUiEditorAttribute;
|
||||
|
||||
class PdmUiObjectHandle : public PdmUiItem, public PdmObjectCapability
|
||||
{
|
||||
public:
|
||||
PdmUiObjectHandle(PdmObjectHandle* owner, bool giveOwnership);
|
||||
virtual ~PdmUiObjectHandle() { }
|
||||
|
||||
PdmObjectHandle* owner() { return m_owner; }
|
||||
|
||||
/// Method to be called from the Ui classes creating Auto Gui to get the group information
|
||||
/// supplied by the \sa defineUiOrdering method that can be reimplemented
|
||||
void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) ;
|
||||
|
||||
/// Method to be called by Ui displaying a tree representation of the object hierarchy
|
||||
/// Caller must delete the returned object.
|
||||
PdmUiTreeOrdering* uiTreeOrdering(QString uiConfigName = "");
|
||||
/// Helper function to expand a pre-defined tree start
|
||||
static void expandUiTree(PdmUiTreeOrdering* root, QString uiConfigName = "");
|
||||
|
||||
|
||||
/// For a specific field, return editor specific parameters used to customize the editor behavior.
|
||||
void editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute);
|
||||
|
||||
/// Return object editor specific parameters used to customize the editor behavior.
|
||||
void objectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute* attribute);
|
||||
|
||||
/// Field used to control if field change of and object should be covered by undo/redo framework
|
||||
virtual bool useUndoRedoFramework() { return true; }
|
||||
|
||||
void updateUiIconFromToggleField();
|
||||
|
||||
|
||||
// Virtual interface to override in subclasses to support special behaviour if needed
|
||||
public: // Virtual
|
||||
virtual PdmFieldHandle* userDescriptionField() { return NULL; }
|
||||
|
||||
/// Field used to toggle object on/off in UI-related uses of the object (ie checkbox in treeview)
|
||||
virtual PdmFieldHandle* objectToggleField() { 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:
|
||||
/// Override to customize the order and grouping of the Gui.
|
||||
/// Fill up the uiOrdering object with groups and field references to create the gui structure
|
||||
/// If the uiOrdering is empty, it is interpreted as meaning all fields w/o grouping.
|
||||
virtual void defineUiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) {}
|
||||
|
||||
/// Override to customize the tree representations of the object hierarchy.
|
||||
/// If the PdmUiTreeOrdering is empty, it is interpreted as meaning all fields containing child objects in order
|
||||
virtual void defineUiTreeOrdering(PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "") { }
|
||||
|
||||
/// Override to provide editor specific data for the field and uiConfigName
|
||||
virtual void defineEditorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) {}
|
||||
|
||||
/// Override to provide editor specific data for the uiConfigName for the object
|
||||
virtual void defineObjectEditorAttribute(QString uiConfigName, PdmUiEditorAttribute * attribute) {}
|
||||
|
||||
/// This method is intended to be used in macros to make compile time errors
|
||||
// if user uses them on wrong type of objects
|
||||
bool isInheritedFromPdmUiObject() { return true; }
|
||||
|
||||
private:
|
||||
/// Helper method for the TreeItem generation stuff
|
||||
void addDefaultUiTreeChildren(PdmUiTreeOrdering* uiTreeOrdering);
|
||||
|
||||
PdmObjectHandle* m_owner;
|
||||
|
||||
};
|
||||
|
||||
PdmUiObjectHandle* uiObj(PdmObjectHandle* obj);
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
+26
-2
@@ -34,14 +34,18 @@
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cafPdmUiOrdering.h"
|
||||
|
||||
#include "cafPdmDataValueField.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -84,5 +88,25 @@ bool PdmUiOrdering::contains(const PdmUiItem* item)
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiOrdering::add(const PdmFieldHandle* field)
|
||||
{
|
||||
PdmUiFieldHandle* uiItem = uiField(const_cast<PdmFieldHandle*>(field));
|
||||
assert(uiItem);
|
||||
m_ordering.push_back(uiItem);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiOrdering::add(const PdmObjectHandle* obj)
|
||||
{
|
||||
PdmUiObjectHandle* uiItem = uiObj(const_cast<PdmObjectHandle*>(obj));
|
||||
assert(uiItem);
|
||||
m_ordering.push_back(uiItem);
|
||||
}
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
+18
-14
@@ -34,17 +34,19 @@
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmUiGroup;
|
||||
class PdmFieldHandle;
|
||||
class PdmObjectHandle;
|
||||
|
||||
//==================================================================================================
|
||||
/// Class storing the order and grouping of fields and groups of fields etc. to be used in the Gui
|
||||
@@ -56,26 +58,28 @@ public:
|
||||
PdmUiOrdering(): m_forgetRemainingFields(false) { };
|
||||
virtual ~PdmUiOrdering();
|
||||
|
||||
PdmUiGroup* addNewGroup(QString displayName);
|
||||
void add(PdmUiItem* item) { m_ordering.push_back(item); }
|
||||
PdmUiGroup* addNewGroup(QString displayName);
|
||||
//void add(PdmUiItem* item) { m_ordering.push_back(item); }
|
||||
|
||||
/// HACK constness of this class and functions must be revisited
|
||||
void add(const PdmUiItem* item) { m_ordering.push_back(const_cast<PdmUiItem*>(item)); }
|
||||
//void add(const PdmUiItem* item) { m_ordering.push_back(const_cast<PdmUiItem*>(item)); }
|
||||
void add(const PdmFieldHandle* field);
|
||||
void add(const PdmObjectHandle* obj);
|
||||
|
||||
bool forgetRemainingFields() const { return m_forgetRemainingFields; }
|
||||
void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; }
|
||||
bool forgetRemainingFields() const { return m_forgetRemainingFields; }
|
||||
void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; }
|
||||
|
||||
const std::vector<PdmUiItem*>& uiItems() const { return m_ordering; }
|
||||
bool contains(const PdmUiItem* item);
|
||||
const std::vector<PdmUiItem*>& uiItems() const { return m_ordering; }
|
||||
bool contains(const PdmUiItem* item);
|
||||
|
||||
private:
|
||||
// Private copy constructor and assignment to prevent this. (The vectors below will make trouble)
|
||||
PdmUiOrdering(const PdmUiOrdering& other) { }
|
||||
PdmUiOrdering& operator= (const PdmUiOrdering& other) { }
|
||||
PdmUiOrdering& operator= (const PdmUiOrdering& other) { }
|
||||
|
||||
std::vector<PdmUiItem*> m_ordering; ///< The order of groups and fields
|
||||
std::vector<PdmUiGroup*> m_createdGroups; ///< Owned PdmUiGroups, for mem management
|
||||
bool m_forgetRemainingFields;
|
||||
std::vector<PdmUiItem*> m_ordering; ///< The order of groups and fields
|
||||
std::vector<PdmUiGroup*> m_createdGroups; ///< Owned PdmUiGroups, for mem management
|
||||
bool m_forgetRemainingFields;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
@@ -0,0 +1,108 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) Ceetron Solutions AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
#include "cafPdmUiCommandSystemProxy.h"
|
||||
|
||||
#include "cafInternalPdmUiCommandSystemInterface.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace caf {
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiCommandSystemProxy* PdmUiCommandSystemProxy::instance()
|
||||
{
|
||||
static PdmUiCommandSystemProxy staticInstance;
|
||||
|
||||
return &staticInstance;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiCommandSystemProxy::PdmUiCommandSystemProxy()
|
||||
{
|
||||
m_commandInterface = NULL;
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiCommandSystemProxy::setCommandInterface(PdmUiCommandSystemInterface* commandInterface)
|
||||
{
|
||||
m_commandInterface = commandInterface;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiCommandSystemProxy::setUiValueToField(PdmUiFieldHandle* uiFieldHandle, const QVariant& newUiValue)
|
||||
{
|
||||
if (uiFieldHandle)
|
||||
{
|
||||
if (m_commandInterface)
|
||||
{
|
||||
m_commandInterface->fieldChangedCommand(uiFieldHandle->fieldHandle(), newUiValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
uiFieldHandle->setValueFromUi(newUiValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiCommandSystemProxy::populateMenuWithDefaultCommands(const QString& uiConfigName, QMenu* menu)
|
||||
{
|
||||
if (m_commandInterface)
|
||||
{
|
||||
m_commandInterface->populateMenuWithDefaultCommands(uiConfigName, menu);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace caf
|
||||
@@ -0,0 +1,396 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include "cafPdmDataValueField.h"
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmUiEditorHandle.h"
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeOrdering::add(PdmFieldHandle * field)
|
||||
{
|
||||
PdmUiTreeOrdering* child = new PdmUiTreeOrdering(this, field);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeOrdering::add(PdmObjectHandle* object)
|
||||
{
|
||||
PdmUiTreeOrdering* child = new PdmUiTreeOrdering(this, object);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering* PdmUiTreeOrdering::add(const QString & title, const QString& iconResourceName)
|
||||
{
|
||||
PdmUiTreeOrdering* child = new PdmUiTreeOrdering(title, iconResourceName);
|
||||
|
||||
this->appendChild(child);
|
||||
return child;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmUiTreeOrdering::containsField(const PdmFieldHandle* field)
|
||||
{
|
||||
assert (field);
|
||||
for (int cIdx = 0; cIdx < this->childCount(); ++cIdx)
|
||||
{
|
||||
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>(this->child(cIdx)); // What ???
|
||||
|
||||
if (child->m_field == field)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmUiTreeOrdering::containsObject(const PdmObjectHandle* object)
|
||||
{
|
||||
assert (object);
|
||||
for (int cIdx = 0; cIdx < this->childCount(); ++cIdx)
|
||||
{
|
||||
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>(this->child(cIdx)); // What again ???
|
||||
|
||||
if (child->object() == object)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates an new root PdmUiTreeOrdering item, pointing at a PdmObject
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering::PdmUiTreeOrdering(PdmObjectHandle* pdmObject) :
|
||||
m_parentItem(NULL),
|
||||
m_field(NULL),
|
||||
m_forgetRemainingFields(false),
|
||||
m_isToIgnoreSubTree(false),
|
||||
m_uiItem(NULL),
|
||||
m_object(pdmObject),
|
||||
m_treeItemEditor(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates an new root PdmUiTreeOrdering item, pointing at a field
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering::PdmUiTreeOrdering( PdmFieldHandle* pdmField ) :
|
||||
m_parentItem(NULL),
|
||||
m_field(pdmField),
|
||||
m_forgetRemainingFields(false),
|
||||
m_isToIgnoreSubTree(false),
|
||||
m_uiItem(NULL),
|
||||
m_object(NULL),
|
||||
m_treeItemEditor(NULL)
|
||||
{
|
||||
if (pdmField) m_object = pdmField->ownerObject();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates an new root PdmUiTreeOrdering item, as a display item only
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering::PdmUiTreeOrdering(const QString & title, const QString& iconResourceName) :
|
||||
m_parentItem(NULL),
|
||||
m_field(NULL),
|
||||
m_forgetRemainingFields(false),
|
||||
m_isToIgnoreSubTree(false),
|
||||
m_uiItem(NULL),
|
||||
m_object(NULL),
|
||||
m_treeItemEditor(NULL)
|
||||
{
|
||||
m_uiItem = new PdmUiItem();
|
||||
m_uiItem->setUiName(title);
|
||||
m_uiItem->setUiIcon(QIcon(iconResourceName));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added
|
||||
/// at the end of parents existing child list.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent, PdmObjectHandle* pdmObject) :
|
||||
m_parentItem(parent),
|
||||
m_field(NULL),
|
||||
m_forgetRemainingFields(false),
|
||||
m_isToIgnoreSubTree(false),
|
||||
m_uiItem(NULL),
|
||||
m_object(pdmObject),
|
||||
m_treeItemEditor(NULL)
|
||||
{
|
||||
if (m_parentItem)
|
||||
{
|
||||
m_parentItem->m_childItems.push_back( this);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added
|
||||
/// at the end of parents existing child list.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent , PdmFieldHandle* pdmField ) :
|
||||
m_parentItem(parent),
|
||||
m_field(pdmField),
|
||||
m_forgetRemainingFields(false),
|
||||
m_isToIgnoreSubTree(false),
|
||||
m_uiItem(NULL),
|
||||
m_object(NULL),
|
||||
m_treeItemEditor(NULL)
|
||||
{
|
||||
if (m_parentItem)
|
||||
{
|
||||
m_parentItem->m_childItems.push_back( this);
|
||||
}
|
||||
|
||||
if (pdmField) m_object = pdmField->ownerObject();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering::~PdmUiTreeOrdering()
|
||||
{
|
||||
if (m_uiItem)
|
||||
{
|
||||
delete m_uiItem;
|
||||
}
|
||||
|
||||
if (m_treeItemEditor)
|
||||
{
|
||||
delete m_treeItemEditor;
|
||||
}
|
||||
|
||||
qDeleteAll(m_childItems);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectHandle* PdmUiTreeOrdering::object() const
|
||||
{
|
||||
assert(isRepresentingObject()); return m_object;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmFieldHandle* PdmUiTreeOrdering::field() const
|
||||
{
|
||||
assert(isRepresentingField()); return m_field;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiItem* PdmUiTreeOrdering::uiItem() const
|
||||
{
|
||||
assert(isDisplayItemOnly()); return m_uiItem;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiItem* PdmUiTreeOrdering::activeItem() const
|
||||
{
|
||||
if (isRepresentingObject()) return uiObj(m_object);
|
||||
if (isRepresentingField()) return uiField(m_field);
|
||||
if (isDisplayItemOnly()) return m_uiItem;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeOrdering::setEditor(PdmUiEditorHandle* editor)
|
||||
{
|
||||
m_treeItemEditor = editor;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiEditorHandle* PdmUiTreeOrdering::editor()
|
||||
{
|
||||
return m_treeItemEditor;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeOrdering::debugDump(int level) const
|
||||
{
|
||||
for (int i = 0; i < level; ++i)
|
||||
{
|
||||
std::cout << " ";
|
||||
}
|
||||
|
||||
if (isValid())
|
||||
{
|
||||
char type = 'I';
|
||||
if (isRepresentingObject()) type = 'O';
|
||||
if (isRepresentingField()) type = 'F';
|
||||
if (isDisplayItemOnly()) type = 'D';
|
||||
|
||||
std::cout << type << ": " << activeItem()->uiName().toLatin1().data() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "NULL" << std::endl;
|
||||
}
|
||||
|
||||
for (int i = 0; i < childCount(); ++i)
|
||||
{
|
||||
child(i)->debugDump(level+1);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering* PdmUiTreeOrdering::child(int index) const
|
||||
{
|
||||
assert(index < m_childItems.size());
|
||||
return m_childItems.value(index);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int PdmUiTreeOrdering::childCount() const
|
||||
{
|
||||
return m_childItems.count();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering* PdmUiTreeOrdering::parent() const
|
||||
{
|
||||
return m_parentItem;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int PdmUiTreeOrdering::indexInParent() const
|
||||
{
|
||||
if (m_parentItem)
|
||||
{
|
||||
return m_parentItem->m_childItems.indexOf(const_cast<PdmUiTreeOrdering*>(this));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeOrdering::appendChild(PdmUiTreeOrdering* child)
|
||||
{
|
||||
m_childItems.append(child);
|
||||
child->m_parentItem = this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeOrdering::insertChild(int position, PdmUiTreeOrdering* child)
|
||||
{
|
||||
m_childItems.insert(position, child);
|
||||
child->m_parentItem = this;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmUiTreeOrdering::removeChildren(int position, int count)
|
||||
{
|
||||
if (position < 0 || position + count > m_childItems.size())
|
||||
return false;
|
||||
|
||||
for (int row = 0; row < count; ++row)
|
||||
{
|
||||
PdmUiTreeOrdering* uiItem = m_childItems.takeAt(position);
|
||||
|
||||
delete uiItem;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmUiTreeOrdering::removeChildrenNoDelete(int position, int count)
|
||||
{
|
||||
if (position < 0 || position + count > m_childItems.size())
|
||||
return false;
|
||||
|
||||
for (int row = 0; row < count; ++row)
|
||||
{
|
||||
m_childItems.removeAt(position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmFieldHandle;
|
||||
class PdmObjectHandle;
|
||||
class PdmUiEditorHandle;
|
||||
class PdmUiItem;
|
||||
class PdmUiTreeItemEditor;
|
||||
class PdmUiTreeOrdering;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// Class storing a tree structure representation of some PdmObject hierarchy to be used for tree views in the Gui
|
||||
//==================================================================================================
|
||||
|
||||
class PdmUiTreeOrdering
|
||||
{
|
||||
public:
|
||||
PdmUiTreeOrdering(PdmObjectHandle* pdmItem );
|
||||
PdmUiTreeOrdering(PdmFieldHandle* pdmField );
|
||||
PdmUiTreeOrdering(const QString & title, const QString& iconResourceName );
|
||||
|
||||
~PdmUiTreeOrdering();
|
||||
|
||||
void add(PdmFieldHandle * field);
|
||||
void add(PdmObjectHandle* object);
|
||||
PdmUiTreeOrdering* add(const QString & title, const QString& iconResourceName );
|
||||
|
||||
/// If the rest of the fields containing children is supposed to be omitted, setForgetRemainingFileds to true.
|
||||
void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; }
|
||||
/// To stop the tree generation at this level, doIgnoreSubTree to true
|
||||
void setIgnoreSubTree(bool doIgnoreSubTree ) { m_isToIgnoreSubTree = doIgnoreSubTree; }
|
||||
|
||||
// Testing for the PdmItem being represented
|
||||
bool isRepresentingObject() const { return !isRepresentingField() && (m_object != NULL); }
|
||||
bool isRepresentingField() const { return (m_object != NULL) && (m_field != NULL);}
|
||||
bool isDisplayItemOnly() const { return (m_uiItem != NULL); }
|
||||
bool isValid() const { return (this->activeItem() != NULL); }
|
||||
|
||||
// Access to the PdmItem being represented
|
||||
PdmUiItem* activeItem() const;
|
||||
PdmObjectHandle* object() const;
|
||||
PdmFieldHandle* field() const;
|
||||
PdmUiItem* uiItem() const;
|
||||
|
||||
// Tree structure traversal access
|
||||
PdmUiTreeOrdering* child(int index) const;
|
||||
int childCount() const;
|
||||
PdmUiTreeOrdering* parent() const;
|
||||
int indexInParent() const;
|
||||
|
||||
// Debug helper
|
||||
void debugDump(int level) const;
|
||||
|
||||
private:
|
||||
friend class PdmObjectHandle; friend class PdmUiObjectHandle;
|
||||
bool forgetRemainingFields() const { return m_forgetRemainingFields; }
|
||||
bool ignoreSubTree() const { return m_isToIgnoreSubTree; }
|
||||
bool containsField(const PdmFieldHandle* field);
|
||||
bool containsObject(const PdmObjectHandle* object);
|
||||
void appendChild( PdmUiTreeOrdering* child);
|
||||
|
||||
friend class PdmUiTreeViewModel;
|
||||
PdmUiEditorHandle* editor();
|
||||
void setEditor(PdmUiEditorHandle* editor);
|
||||
void insertChild( int position, PdmUiTreeOrdering* child);
|
||||
bool removeChildren(int position, int count);
|
||||
bool removeChildrenNoDelete(int position, int count);
|
||||
|
||||
private:
|
||||
PdmUiTreeOrdering(PdmUiTreeOrdering* parent, PdmObjectHandle* pdmItem );
|
||||
PdmUiTreeOrdering(PdmUiTreeOrdering* parent, PdmFieldHandle* pdmField );
|
||||
|
||||
// Item that we represent
|
||||
PdmPointer<PdmObjectHandle> m_object;
|
||||
PdmFieldHandle* m_field;
|
||||
PdmUiItem* m_uiItem;
|
||||
|
||||
// Tree generation control
|
||||
bool m_forgetRemainingFields;
|
||||
bool m_isToIgnoreSubTree;
|
||||
|
||||
// Editor propagating changes from PdmItem to TreeViewEditor
|
||||
PdmUiEditorHandle* m_treeItemEditor;
|
||||
|
||||
// Tree data
|
||||
QList<PdmUiTreeOrdering*> m_childItems;
|
||||
PdmUiTreeOrdering* m_parentItem;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cafSelectionManager.h"
|
||||
|
||||
#include "cafNotificationCenter.h"
|
||||
#include "cafPdmReferenceHelper.h"
|
||||
#include "cafPdmUiFieldHandle.h"
|
||||
#include "cafPdmUiObjectHandle.h"
|
||||
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
SelectionManager* SelectionManager::instance()
|
||||
{
|
||||
static SelectionManager* singleton = new SelectionManager;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::selectedItems(std::vector<PdmUiItem*>& items, int role /*= SelectionManager::APPLICATION_GLOBAL*/)
|
||||
{
|
||||
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> >& selection = m_selectionForRole[role];
|
||||
|
||||
for (size_t i = 0; i < selection.size(); i++)
|
||||
{
|
||||
if (selection[i].first.notNull())
|
||||
{
|
||||
items.push_back(selection[i].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::setSelectedItems(const std::vector<PdmUiItem*>& items, int role /*= SelectionManager::APPLICATION_GLOBAL*/)
|
||||
{
|
||||
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> >& selection = m_selectionForRole[role];
|
||||
|
||||
selection.clear();
|
||||
|
||||
for (size_t i = 0; i < items.size(); i++)
|
||||
{
|
||||
PdmUiFieldHandle* fieldHandle = dynamic_cast<PdmUiFieldHandle*>(items[i]);
|
||||
if (fieldHandle)
|
||||
{
|
||||
PdmObjectHandle* obj = fieldHandle->fieldHandle()->ownerObject();
|
||||
|
||||
selection.push_back(std::make_pair(obj, fieldHandle));
|
||||
}
|
||||
else
|
||||
{
|
||||
PdmUiObjectHandle* obj = dynamic_cast<PdmUiObjectHandle*>(items[i]);
|
||||
if (obj)
|
||||
{
|
||||
selection.push_back(std::make_pair(obj->owner(), obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notifySelectionChanged();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiItem* SelectionManager::selectedItem(int role /*= SelectionManager::APPLICATION_GLOBAL*/)
|
||||
{
|
||||
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> >& selection = m_selectionForRole[role];
|
||||
|
||||
if (selection.size() == 1)
|
||||
{
|
||||
if (selection[0].first.notNull())
|
||||
{
|
||||
return selection[0].second;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::setSelectedItem(PdmUiItem* item, int role /*= SelectionManager::APPLICATION_GLOBAL*/)
|
||||
{
|
||||
std::vector<PdmUiItem*> singleSelection;
|
||||
singleSelection.push_back(item);
|
||||
|
||||
setSelectedItems(singleSelection, role);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
SelectionManager::SelectionManager()
|
||||
{
|
||||
m_selectionForRole.resize(UNDEFINED);
|
||||
|
||||
m_notificationCenter = NULL;
|
||||
m_activeChildArrayFieldHandle = NULL;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::selectionAsReferences(std::vector<QString>& referenceList, int role) const
|
||||
{
|
||||
// const std::vector<PdmUiItem*>& selection = m_selectionForRole[role];
|
||||
const std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> >& selection = m_selectionForRole[role];
|
||||
|
||||
for (size_t i = 0; i < selection.size(); i++)
|
||||
{
|
||||
if (!selection[i].first.isNull())
|
||||
{
|
||||
PdmUiObjectHandle* pdmObj = dynamic_cast<PdmUiObjectHandle*>(selection[i].second);
|
||||
if (pdmObj)
|
||||
{
|
||||
QString itemRef = PdmReferenceHelper::referenceFromRootToObject(m_rootObject, pdmObj->owner());
|
||||
|
||||
referenceList.push_back(itemRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::setSelectionFromReferences(const std::vector<QString>& referenceList, int role)
|
||||
{
|
||||
std::vector<PdmUiItem*> uiItems;
|
||||
|
||||
for (int i = 0; i < referenceList.size(); i++)
|
||||
{
|
||||
QString reference = referenceList[i];
|
||||
|
||||
PdmObjectHandle* pdmObj = PdmReferenceHelper::objectFromReference(m_rootObject, reference);
|
||||
if (pdmObj)
|
||||
{
|
||||
caf::PdmUiObjectHandle* uiObject = uiObj(pdmObj);
|
||||
if (uiObject)
|
||||
{
|
||||
uiItems.push_back(uiObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setSelectedItems(uiItems, role);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::clearAll()
|
||||
{
|
||||
for (int i = 0; i < m_selectionForRole.size(); i++)
|
||||
{
|
||||
m_selectionForRole[i].clear();
|
||||
}
|
||||
|
||||
notifySelectionChanged();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::clear(int role)
|
||||
{
|
||||
m_selectionForRole[role].clear();
|
||||
|
||||
notifySelectionChanged();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::notifySelectionChanged()
|
||||
{
|
||||
if (m_notificationCenter)
|
||||
{
|
||||
m_notificationCenter->notifyObserversOfSelectionChange();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::setNotificationCenter(NotificationCenter* notificationCenter)
|
||||
{
|
||||
m_notificationCenter = notificationCenter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
NotificationCenter* SelectionManager::notificationCenter()
|
||||
{
|
||||
return m_notificationCenter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::removeObjectFromAllSelections(PdmObjectHandle* pdmObject)
|
||||
{
|
||||
bool doNotifySelectionChanged = false;
|
||||
|
||||
for (int role = 0; role < m_selectionForRole.size(); role++)
|
||||
{
|
||||
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> >& selection = m_selectionForRole[role];
|
||||
|
||||
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> >::iterator iter = selection.begin();
|
||||
while (iter != selection.end())
|
||||
{
|
||||
if (iter->first.notNull())
|
||||
{
|
||||
PdmObjectHandle* selectionObj = dynamic_cast<PdmObjectHandle*>(iter->second);
|
||||
if (selectionObj == pdmObject)
|
||||
{
|
||||
iter = selection.erase(iter);
|
||||
|
||||
doNotifySelectionChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doNotifySelectionChanged)
|
||||
{
|
||||
notifySelectionChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionManager::setPdmRootObject(PdmObjectHandle* root)
|
||||
{
|
||||
m_rootObject = root;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void SelectionManager::setActiveChildArrayFieldHandle(PdmChildArrayFieldHandle* childArray)
|
||||
{
|
||||
m_activeChildArrayFieldHandle = childArray;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmChildArrayFieldHandle* SelectionManager::activeChildArrayFieldHandle()
|
||||
{
|
||||
return m_activeChildArrayFieldHandle;
|
||||
}
|
||||
|
||||
} // end namespace caf
|
||||
@@ -0,0 +1,121 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QString>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmUiItem;
|
||||
class NotificationCenter;
|
||||
class PdmChildArrayFieldHandle;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class SelectionManager
|
||||
{
|
||||
public:
|
||||
enum SelectionRole
|
||||
{
|
||||
APPLICATION_GLOBAL,
|
||||
CURRENT,
|
||||
UNDEFINED
|
||||
};
|
||||
|
||||
public:
|
||||
static SelectionManager* instance();
|
||||
|
||||
void setNotificationCenter(NotificationCenter* notificationCenter);
|
||||
NotificationCenter* notificationCenter();
|
||||
|
||||
void setActiveChildArrayFieldHandle(PdmChildArrayFieldHandle* childArray);
|
||||
PdmChildArrayFieldHandle* activeChildArrayFieldHandle();
|
||||
|
||||
void setPdmRootObject(PdmObjectHandle* root);
|
||||
PdmObjectHandle* pdmRootObject() { return m_rootObject; }
|
||||
|
||||
PdmUiItem* selectedItem(int role = SelectionManager::APPLICATION_GLOBAL);
|
||||
void setSelectedItem(PdmUiItem* item, int role = SelectionManager::APPLICATION_GLOBAL);
|
||||
|
||||
void selectedItems(std::vector<PdmUiItem*>& items, int role = SelectionManager::APPLICATION_GLOBAL);
|
||||
void setSelectedItems(const std::vector<PdmUiItem*>& items, int role = SelectionManager::APPLICATION_GLOBAL);
|
||||
|
||||
void selectionAsReferences(std::vector<QString>& referenceList, int role) const;
|
||||
void setSelectionFromReferences(const std::vector<QString>& referenceList, int role);
|
||||
|
||||
void clearAll();
|
||||
void clear(int role);
|
||||
void removeObjectFromAllSelections(PdmObjectHandle* pdmObject);
|
||||
|
||||
template <typename T>
|
||||
void objectsByType(std::vector<T*>* typedObjects, int role = SelectionManager::APPLICATION_GLOBAL)
|
||||
{
|
||||
std::vector<PdmUiItem*> items;
|
||||
this->selectedItems(items, role);
|
||||
for (size_t i = 0; i < items.size(); i++)
|
||||
{
|
||||
T* obj = dynamic_cast<T*>(items[i]);
|
||||
if (obj) typedObjects->push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
SelectionManager();
|
||||
void notifySelectionChanged();
|
||||
|
||||
private:
|
||||
std::vector < std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> > > m_selectionForRole;
|
||||
|
||||
NotificationCenter* m_notificationCenter;
|
||||
PdmChildArrayFieldHandle* m_activeChildArrayFieldHandle;
|
||||
PdmPointer<PdmObjectHandle> m_rootObject;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // end namespace caf
|
||||
+5
-3
@@ -40,7 +40,7 @@
|
||||
//#include <QAbstractItemModel>
|
||||
#include <QList>
|
||||
#include <assert.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
qDeleteAll(m_childItems);
|
||||
}
|
||||
|
||||
UiTreeItem* child(int row)
|
||||
UiTreeItem* child(int row) const
|
||||
{
|
||||
assert(row < m_childItems.size());
|
||||
return m_childItems.value(row);
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
return m_parentItem;
|
||||
}
|
||||
|
||||
T dataObject()
|
||||
T dataObject() const
|
||||
{
|
||||
return m_dataObject;
|
||||
}
|
||||
@@ -167,6 +167,8 @@ public:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
QList<UiTreeItem*> m_childItems;
|
||||
UiTreeItem* m_parentItem;
|
||||
@@ -1,143 +0,0 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
#include "cafPdmField.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeOrdering::add(PdmFieldHandle * field)
|
||||
{
|
||||
PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, field->ownerObject());
|
||||
to->m_field = field;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeOrdering::add(PdmObject* object)
|
||||
{
|
||||
PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, object);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering* PdmUiTreeOrdering::add(const QString & title, const QString& iconResourceName)
|
||||
{
|
||||
PdmUiTreeOrdering* to = new PdmUiTreeOrdering(this, -1, NULL);
|
||||
|
||||
to->m_uiItem = new PdmUiItem();
|
||||
to->m_uiItem->setUiName(title);
|
||||
to->m_uiItem->setUiIcon(QIcon(iconResourceName));
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmUiTreeOrdering::containsField(const PdmFieldHandle* field)
|
||||
{
|
||||
assert (field);
|
||||
for (int cIdx = 0; cIdx < this->childCount(); ++cIdx)
|
||||
{
|
||||
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>(this->child(cIdx));
|
||||
|
||||
if (child->m_field == field)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmUiTreeOrdering::containsObject(const PdmObject* object)
|
||||
{
|
||||
assert (object);
|
||||
for (int cIdx = 0; cIdx < this->childCount(); ++cIdx)
|
||||
{
|
||||
PdmUiTreeOrdering* child = dynamic_cast<PdmUiTreeOrdering*>(this->child(cIdx));
|
||||
|
||||
if (child->object() == object)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Creates an new PdmUiTreeOrdering item, and adds it to parent. If position is -1, it is added
|
||||
/// at the end of parents existing child list.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering::PdmUiTreeOrdering(PdmUiTreeOrdering* parent /*= NULL*/, int position /*= -1*/, PdmObject* dataObject /*= NULL*/) : PdmUiTreeItem(parent, position, this),
|
||||
m_field(NULL),
|
||||
m_forgetRemainingFields(false),
|
||||
m_isToIgnoreSubTree(false),
|
||||
m_uiItem(NULL),
|
||||
m_object(dataObject)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeOrdering::~PdmUiTreeOrdering()
|
||||
{
|
||||
if (m_uiItem)
|
||||
{
|
||||
delete m_uiItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} //End of namespace caf
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
//##################################################################################################
|
||||
//
|
||||
// Custom Visualization Core library
|
||||
// Copyright (C) 2011-2013 Ceetron AS
|
||||
//
|
||||
// This library may be used under the terms of either the GNU General Public License or
|
||||
// the GNU Lesser General Public License as follows:
|
||||
//
|
||||
// GNU General Public License Usage
|
||||
// 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.
|
||||
//
|
||||
// GNU Lesser General Public License Usage
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation; either version 2.1 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
|
||||
// for more details.
|
||||
//
|
||||
//##################################################################################################
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafUiTreeItem.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject;
|
||||
class PdmFieldHandle;
|
||||
|
||||
class PdmUiTreeOrdering;
|
||||
|
||||
typedef UiTreeItem<PdmUiTreeOrdering* > PdmUiTreeItem;
|
||||
|
||||
//==================================================================================================
|
||||
/// Class storing a tree structure representation of some PdmObject hierarchy to be used for tree views in the Gui
|
||||
//==================================================================================================
|
||||
|
||||
class PdmUiTreeOrdering : public UiTreeItem< PdmUiTreeOrdering* >
|
||||
{
|
||||
public:
|
||||
PdmUiTreeOrdering(PdmUiTreeOrdering* parent = NULL, int position = -1, PdmObject* dataObject = NULL);
|
||||
~PdmUiTreeOrdering();
|
||||
|
||||
void add(PdmFieldHandle * field);
|
||||
void add(PdmObject* object);
|
||||
PdmUiTreeOrdering* add(const QString & title, const QString& iconResourceName );
|
||||
|
||||
/// If the rest of the fields containing children is supposed to be omitted, setForgetRemainingFileds to true.
|
||||
void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; }
|
||||
/// To stop the tree generation at this level, setSubTreeDefined to true
|
||||
void setIgnoreSubTree(bool doIgnoreSubTree ) { m_isToIgnoreSubTree = doIgnoreSubTree; }
|
||||
|
||||
PdmObject* object() const { return m_object; }
|
||||
PdmFieldHandle* field() const { return m_field; }
|
||||
PdmUiItem* uiItem() const { return m_uiItem; }
|
||||
|
||||
private:
|
||||
friend class PdmObject;
|
||||
bool forgetRemainingFields() const { return m_forgetRemainingFields; }
|
||||
bool ignoreSubTree() const { return m_isToIgnoreSubTree; }
|
||||
bool containsField(const PdmFieldHandle* field);
|
||||
bool containsObject(const PdmObject* object);
|
||||
|
||||
private:
|
||||
PdmPointer<PdmObject> m_object;
|
||||
PdmFieldHandle* m_field;
|
||||
PdmUiItem* m_uiItem;
|
||||
|
||||
bool m_forgetRemainingFields;
|
||||
bool m_isToIgnoreSubTree;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project (cafPdmXml)
|
||||
|
||||
# Qt
|
||||
find_package ( Qt4 COMPONENTS QtCore )
|
||||
include (${QT_USE_FILE})
|
||||
|
||||
include_directories (
|
||||
..
|
||||
${cafPdmCore_SOURCE_DIR}
|
||||
)
|
||||
|
||||
set( PROJECT_FILES
|
||||
cafInternalPdmFieldIoHelper.cpp
|
||||
cafInternalPdmFieldIoHelper.h
|
||||
cafInternalPdmStreamOperators.cpp
|
||||
cafInternalPdmStreamOperators.h
|
||||
cafInternalPdmXmlFieldCapability.h
|
||||
cafInternalPdmXmlFieldCapability.inl
|
||||
cafInternalPdmXmlFieldReaderWriter.cpp
|
||||
cafInternalPdmXmlFieldReaderWriter.h
|
||||
cafPdmXmlFieldHandle.cpp
|
||||
cafPdmXmlFieldHandle.h
|
||||
cafPdmXmlObjectHandle.cpp
|
||||
cafPdmXmlObjectHandle.h
|
||||
|
||||
cafPdmXmlObjectHandleMacros.h
|
||||
|
||||
cafPdmDefaultObjectFactory.cpp
|
||||
cafPdmDefaultObjectFactory.h
|
||||
cafPdmObjectFactory.h
|
||||
)
|
||||
|
||||
|
||||
add_library( ${PROJECT_NAME}
|
||||
${PROJECT_FILES}
|
||||
)
|
||||
|
||||
source_group("" FILES ${PROJECT_FILES})
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "cafInternalPdmFieldIoHelper.h"
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
class QXmlStreamReader;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmFieldIOHelper
|
||||
{
|
||||
public:
|
||||
// Utility functions for reading from QXmlStreamReader
|
||||
static void skipCharactersAndComments(QXmlStreamReader& xmlStream);
|
||||
static void skipComments(QXmlStreamReader& xmlStream);
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,42 @@
|
||||
#include <QTextStream>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Specialized read operation for Bool`s
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QTextStream& 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;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
QTextStream& operator << (QTextStream& str, const bool& value)
|
||||
{
|
||||
if (value) str << "True ";
|
||||
else str << "False ";
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Specialized read operation for QDateTimes`s
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#include <QDateTime>
|
||||
QTextStream& operator >> (QTextStream& str, QDateTime& value)
|
||||
{
|
||||
QString text;
|
||||
str >> text;
|
||||
value = QDateTime::fromString(text, "yyyy_MM_dd-HH:mm:ss");
|
||||
return str;
|
||||
}
|
||||
|
||||
QTextStream& operator << (QTextStream& str, const QDateTime& value)
|
||||
{
|
||||
QString text = value.toString("yyyy_MM_dd-HH:mm:ss");
|
||||
str << text;
|
||||
return str;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <QTextStream>
|
||||
|
||||
//==================================================================================================
|
||||
/// QTextStream Stream operator overloading for bool`s
|
||||
/// Prints bool`s as "True"/"False", and reads them too
|
||||
//==================================================================================================
|
||||
|
||||
QTextStream& operator >> (QTextStream& str, bool& value);
|
||||
QTextStream& operator << (QTextStream& str, const bool& value);
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// QTextStream Stream operator overloading for QDateTimes`s
|
||||
///
|
||||
//==================================================================================================
|
||||
//class QDateTime;
|
||||
QTextStream& operator >> (QTextStream& str, QDateTime& value);
|
||||
QTextStream& operator << (QTextStream& str, const QDateTime& value);
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// 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 >
|
||||
QTextStream& operator << (QTextStream& str, const std::vector<T>& sobj)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sobj.size(); ++i)
|
||||
{
|
||||
str << sobj[i] << " ";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
QTextStream& 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);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafInternalPdmXmlFieldReaderWriter.h"
|
||||
#include "cafPdmXmlFieldHandle.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
template < typename FieldType>
|
||||
class PdmFieldXmlCap : public PdmXmlFieldHandle
|
||||
{
|
||||
public:
|
||||
PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; }
|
||||
|
||||
// Xml Serializing
|
||||
public:
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory);
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream);
|
||||
private:
|
||||
FieldType* m_field;
|
||||
};
|
||||
|
||||
|
||||
template <typename DataType> class PdmPtrField;
|
||||
|
||||
template < typename DataType>
|
||||
class PdmFieldXmlCap< PdmPtrField<DataType*> > : public PdmXmlFieldHandle
|
||||
{
|
||||
typedef PdmPtrField<DataType*> FieldType;
|
||||
public:
|
||||
PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_childClassKeyword = DataType::classKeywordStatic(); }
|
||||
|
||||
// Xml Serializing
|
||||
public:
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory);
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream);
|
||||
private:
|
||||
FieldType* m_field;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <typename DataType> class PdmChildField;
|
||||
|
||||
template < typename DataType>
|
||||
class PdmFieldXmlCap< PdmChildField<DataType*> > : public PdmXmlFieldHandle
|
||||
{
|
||||
typedef PdmChildField<DataType*> FieldType;
|
||||
public:
|
||||
PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_childClassKeyword = DataType::classKeywordStatic(); }
|
||||
|
||||
// Xml Serializing
|
||||
public:
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory);
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream);
|
||||
private:
|
||||
FieldType* m_field;
|
||||
};
|
||||
|
||||
|
||||
template <typename DataType> class PdmChildArrayField;
|
||||
|
||||
template < typename DataType>
|
||||
class PdmFieldXmlCap< PdmChildArrayField<DataType*> > : public PdmXmlFieldHandle
|
||||
{
|
||||
typedef PdmChildArrayField<DataType*> FieldType;
|
||||
public:
|
||||
PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_childClassKeyword = DataType::classKeywordStatic();}
|
||||
|
||||
// Xml Serializing
|
||||
public:
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory);
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream);
|
||||
private:
|
||||
FieldType* m_field;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename FieldType>
|
||||
void AddXmlCapabilityToField(FieldType* field)
|
||||
{
|
||||
if(field->template capability< PdmFieldXmlCap<FieldType> >() == NULL)
|
||||
{
|
||||
new PdmFieldXmlCap<FieldType>(field, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafInternalPdmXmlFieldCapability.inl"
|
||||
@@ -0,0 +1,283 @@
|
||||
#include "cafInternalPdmFieldIoHelper.h"
|
||||
#include "cafPdmObjectFactory.h"
|
||||
#include "cafPdmXmlObjectHandle.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
//==================================================================================================
|
||||
/// XML Implementation for PdmFieldXmlCap<> methods
|
||||
///
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FieldType >
|
||||
void caf::PdmFieldXmlCap<FieldType>::readFieldData(QXmlStreamReader& xmlStream,
|
||||
PdmObjectFactory* objectFactory)
|
||||
{
|
||||
this->assertValid();
|
||||
typename FieldType::FieldDataType value;
|
||||
PdmFieldReader<typename FieldType::FieldDataType>::readFieldData(value, xmlStream, objectFactory);
|
||||
m_field->setValue(value);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename FieldType >
|
||||
void caf::PdmFieldXmlCap<FieldType>::writeFieldData(QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
this->assertValid();
|
||||
PdmFieldWriter<typename FieldType::FieldDataType>::writeFieldData(m_field->value(), xmlStream);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
/// XML Implementation for PdmPtrField<>
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename DataType >
|
||||
void caf::PdmFieldXmlCap< caf::PdmPtrField<DataType*> >::readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory*)
|
||||
{
|
||||
this->assertValid();
|
||||
|
||||
PdmFieldIOHelper::skipComments(xmlStream);
|
||||
if (!xmlStream.isCharacters()) return;
|
||||
|
||||
QString dataString = xmlStream.text().toString();
|
||||
|
||||
// Make stream point to end of element
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
|
||||
// This resolving can NOT be done here.
|
||||
// It must be done when we know that the complete hierarchy is read and created,
|
||||
// The object pointed to is not always read and created at this point in time.
|
||||
// We rather need to do something like :
|
||||
// m_refenceString = dataString;
|
||||
// m_isResolved = false;
|
||||
// m_field->setRawPtr(NULL);
|
||||
//
|
||||
// and then we need a traversal of the object hierarchy to resolve all references before initAfterRead.
|
||||
|
||||
PdmObjectHandle* objHandle = PdmReferenceHelper::objectFromFieldReference(m_field, dataString);
|
||||
m_field->setRawPtr(objHandle);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename DataType >
|
||||
void caf::PdmFieldXmlCap< caf::PdmPtrField<DataType*> >::writeFieldData(QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
this->assertValid();
|
||||
|
||||
QString dataString;
|
||||
|
||||
dataString = PdmReferenceHelper::referenceFromFieldToObject(m_field, m_field->m_fieldValue.rawPtr());
|
||||
|
||||
xmlStream.writeCharacters(dataString);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
/// XML Implementation for PdmChildField<>
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename DataType >
|
||||
void caf::PdmFieldXmlCap< caf::PdmChildField<DataType*> >::readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory)
|
||||
{
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
if (!xmlStream.isStartElement())
|
||||
{
|
||||
return; // This happens when the field is "shortcut" empty (written like: <ElementName/>)
|
||||
}
|
||||
|
||||
QString className = xmlStream.name().toString();
|
||||
PdmObjectHandle* obj = NULL;
|
||||
|
||||
// Create an object if needed
|
||||
if (m_field->value() == NULL)
|
||||
{
|
||||
assert(objectFactory);
|
||||
obj = objectFactory->create(className);
|
||||
|
||||
if (obj == NULL)
|
||||
{
|
||||
std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << m_field->keyword().toLatin1().data() << std::endl;
|
||||
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of this field
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(obj);
|
||||
if (!xmlObject || xmlObject->classKeyword() != className)
|
||||
{
|
||||
assert(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword
|
||||
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of this field
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_field->m_fieldValue.setRawPtr(obj);
|
||||
obj->setAsParentField(m_field);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj = m_field->m_fieldValue.rawPtr();
|
||||
}
|
||||
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(obj);
|
||||
if (!xmlObject || xmlObject->classKeyword() != className)
|
||||
{
|
||||
// Error: Field contains different class type than on file
|
||||
std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << m_field->keyword().toLatin1().data() << std::endl;
|
||||
std::cout << " Expected class name: " << xmlObject->classKeyword().toLatin1().data() << std::endl;
|
||||
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of the object we was supposed to read
|
||||
xmlStream.skipCurrentElement(); // Skip to the endelement of this field
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Everything seems ok, so read the contents of the object:
|
||||
|
||||
xmlObject->readFields(xmlStream, objectFactory);
|
||||
|
||||
// Make stream point to endElement of this field
|
||||
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename DataType >
|
||||
void caf::PdmFieldXmlCap< caf::PdmChildField<DataType*> >::writeFieldData(QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
if (m_field->m_fieldValue.rawPtr() == NULL) return;
|
||||
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(m_field->m_fieldValue.rawPtr());
|
||||
if (xmlObject)
|
||||
{
|
||||
QString className = xmlObject->classKeyword();
|
||||
|
||||
xmlStream.writeStartElement("", className);
|
||||
xmlObject->writeFields(xmlStream);
|
||||
xmlStream.writeEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
/// XML Implementation for PdmChildArrayField<>
|
||||
//==================================================================================================
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void caf::PdmFieldXmlCap< caf::PdmChildArrayField<DataType*> >::writeFieldData(QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
typename std::vector< PdmPointer<DataType> >::iterator it;
|
||||
for (it = m_field->m_pointers.begin(); it != m_field->m_pointers.end(); ++it)
|
||||
{
|
||||
if (it->rawPtr() == NULL) continue;
|
||||
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(it->rawPtr());
|
||||
if (xmlObject)
|
||||
{
|
||||
QString className = xmlObject->classKeyword();
|
||||
|
||||
xmlStream.writeStartElement("", className);
|
||||
xmlObject->writeFields(xmlStream);
|
||||
xmlStream.writeEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename DataType>
|
||||
void caf::PdmFieldXmlCap< caf::PdmChildArrayField<DataType*> >::readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory)
|
||||
{
|
||||
m_field->deleteAllChildObjects();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
while (xmlStream.isStartElement())
|
||||
{
|
||||
QString className = xmlStream.name().toString();
|
||||
|
||||
assert(objectFactory);
|
||||
PdmObjectHandle * obj = objectFactory->create(className);
|
||||
|
||||
if (obj == NULL)
|
||||
{
|
||||
// Warning: Unknown className read
|
||||
// Skip to corresponding end element
|
||||
|
||||
std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << m_field->keyword().toLatin1().data() << std::endl;
|
||||
|
||||
// Skip to EndElement of the object
|
||||
xmlStream.skipCurrentElement();
|
||||
|
||||
// Jump off the end element, and head for next start element (or the final EndElement of the field)
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(obj);
|
||||
if (!xmlObject || xmlObject->classKeyword() != className)
|
||||
{
|
||||
assert(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword
|
||||
|
||||
// Skip to EndElement of the object
|
||||
xmlStream.skipCurrentElement();
|
||||
|
||||
// Jump off the end element, and head for next start element (or the final EndElement of the field)
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
xmlObject->readFields(xmlStream, objectFactory);
|
||||
|
||||
m_field->m_pointers.push_back(PdmPointer<DataType>());
|
||||
m_field->m_pointers.back().setRawPtr(obj);
|
||||
obj->setAsParentField(m_field);
|
||||
|
||||
// Jump off the end element, and head for next start element (or the final EndElement of the field)
|
||||
// Qt reports a character token between EndElements and StartElements so skip it
|
||||
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace caf
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "cafInternalPdmXmlFieldReaderWriter.h"
|
||||
|
||||
#include "cafInternalPdmFieldIoHelper.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Specialized read function for QStrings, because the >> operator only can read word by word
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<>
|
||||
void PdmFieldReader<QString>::readFieldData(QString & field, QXmlStreamReader& xmlStream, PdmObjectFactory*)
|
||||
{
|
||||
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
|
||||
@@ -0,0 +1,124 @@
|
||||
#pragma once
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "cafInternalPdmStreamOperators.h"
|
||||
#include "cafPdmReferenceHelper.h"
|
||||
#include "cafInternalPdmFieldIoHelper.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class PdmObjectFactory;
|
||||
template <typename T> class PdmPointer;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// 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 DataType>
|
||||
struct PdmFieldWriter
|
||||
{
|
||||
static void writeFieldData(const DataType & fieldValue, QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
QString dataString;
|
||||
QTextStream data(&dataString, QIODevice::WriteOnly);
|
||||
data << fieldValue;
|
||||
xmlStream.writeCharacters(dataString);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DataType>
|
||||
struct PdmFieldReader
|
||||
{
|
||||
static void readFieldData(DataType & fieldValue, QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// 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(DataType & fieldValue, QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory)
|
||||
{
|
||||
PdmFieldIOHelper::skipComments(xmlStream);
|
||||
if (!xmlStream.isCharacters()) return;
|
||||
|
||||
QString dataString = xmlStream.text().toString();
|
||||
QTextStream data(&dataString, QIODevice::ReadOnly);
|
||||
data >> fieldValue;
|
||||
|
||||
// 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(QString & field, QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory);
|
||||
|
||||
#if 0
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Specialized IO for PdmPointer
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename DataType>
|
||||
struct PdmFieldWriter< PdmPointer<DataType> >
|
||||
{
|
||||
static void writeFieldData(const PdmPointer<DataType> & fieldValue, QXmlStreamWriter& xmlStream, PdmReferenceHelper* referenceHelper)
|
||||
{
|
||||
QString dataString;
|
||||
|
||||
assert(referenceHelper);
|
||||
|
||||
if (fieldValue.isNull())
|
||||
{
|
||||
dataString = "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
dataString = referenceHelper->referenceFromRootToObject(fieldValue.p());
|
||||
}
|
||||
|
||||
xmlStream.writeCharacters(dataString);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DataType>
|
||||
struct PdmFieldReader< PdmPointer<DataType> >
|
||||
{
|
||||
static void readFieldData(PdmPointer<DataType> & fieldValue, QXmlStreamReader& xmlStream, PdmObjectFactory*, PdmReferenceHelper* referenceHelper)
|
||||
{
|
||||
PdmFieldIOHelper::skipComments(xmlStream);
|
||||
if (!xmlStream.isCharacters()) return;
|
||||
|
||||
QString dataString = xmlStream.text().toString();
|
||||
|
||||
// Make stream point to end of element
|
||||
QXmlStreamReader::TokenType type;
|
||||
type = xmlStream.readNext();
|
||||
PdmFieldIOHelper::skipCharactersAndComments(xmlStream);
|
||||
|
||||
if (dataString != "NULL")
|
||||
{
|
||||
assert(referenceHelper);
|
||||
|
||||
PdmObjectHandle* objHandle = referenceHelper->objectFromReference(dataString);
|
||||
fieldValue.setRawPtr(objHandle);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
} // End of namespace caf
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "cafPdmDefaultObjectFactory.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// PdmObjectFactory implementations
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectHandle * PdmDefaultObjectFactory::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;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmDefaultObjectFactory * PdmDefaultObjectFactory::instance()
|
||||
{
|
||||
static PdmDefaultObjectFactory* fact = new PdmDefaultObjectFactory;
|
||||
return fact;
|
||||
}
|
||||
|
||||
} // End of namespace caf
|
||||
+14
-8
@@ -37,12 +37,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObjectFactory.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <assert.h>
|
||||
#include <map>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// "Private" class for implementation of a factory for PdmObjectBase derived objects
|
||||
@@ -50,11 +55,12 @@ class PdmObject;
|
||||
/// This class can be considered private in the Pdm system
|
||||
//==================================================================================================
|
||||
|
||||
class PdmObjectFactory
|
||||
class PdmDefaultObjectFactory : public PdmObjectFactory
|
||||
{
|
||||
public:
|
||||
static PdmObjectFactory * instance();
|
||||
PdmObject * create(const QString& classNameKeyword);
|
||||
static PdmDefaultObjectFactory * instance();
|
||||
|
||||
virtual PdmObjectHandle* create(const QString& classNameKeyword);
|
||||
|
||||
template< typename PdmObjectBaseDerivative >
|
||||
bool registerCreator()
|
||||
@@ -78,8 +84,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
PdmObjectFactory() {}
|
||||
~PdmObjectFactory() { /* Could clean up, but ... */ }
|
||||
PdmDefaultObjectFactory() {}
|
||||
~PdmDefaultObjectFactory() { /* Could clean up, but ... */ }
|
||||
|
||||
// Internal helper classes
|
||||
|
||||
@@ -88,14 +94,14 @@ private:
|
||||
public:
|
||||
PdmObjectCreatorBase() {}
|
||||
virtual ~PdmObjectCreatorBase() {}
|
||||
virtual PdmObject * create() = 0;
|
||||
virtual PdmObjectHandle * create() = 0;
|
||||
};
|
||||
|
||||
template< typename PdmObjectBaseDerivative >
|
||||
class PdmObjectCreator : public PdmObjectCreatorBase
|
||||
{
|
||||
public:
|
||||
virtual PdmObject * create() { return new PdmObjectBaseDerivative(); }
|
||||
virtual PdmObjectHandle * create() { return new PdmObjectBaseDerivative(); }
|
||||
};
|
||||
|
||||
// Map to store factory
|
||||
+14
-26
@@ -36,43 +36,31 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
#include "cafPdmUiEditorHandle.h"
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
namespace caf
|
||||
class QString;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmObject;
|
||||
class PdmObjectHandle;
|
||||
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
/// Abstract class to handle editors for complete PdmObjects
|
||||
//
|
||||
// Factory interface for creating PDM objects derived from PdmObjectHandle based on class name keyword
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
class PdmUiTreeEditorHandle: public PdmUiEditorHandle
|
||||
class PdmObjectFactory
|
||||
{
|
||||
public:
|
||||
PdmUiTreeEditorHandle() {}
|
||||
~PdmUiTreeEditorHandle() {}
|
||||
|
||||
QWidget* getOrCreateWidget(QWidget* parent);
|
||||
QWidget* widget() { return m_widget; }
|
||||
|
||||
void setPdmItemRoot(PdmUiItem* root);
|
||||
PdmUiItem* pdmItemRoot();
|
||||
virtual PdmObjectHandle* create(const QString& classNameKeyword) = 0;
|
||||
|
||||
protected:
|
||||
virtual QWidget* createWidget(QWidget* parent) = 0;
|
||||
virtual void cleanupBeforeSettingPdmObject() {};
|
||||
|
||||
protected:
|
||||
QPointer<QWidget> m_widget;
|
||||
PdmObjectFactory() {}
|
||||
virtual ~PdmObjectFactory() {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
} //End of namespace caf
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "cafPdmXmlFieldHandle.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
#include "cafPdmXmlObjectHandle.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmXmlFieldHandle* xmlField(PdmFieldHandle* field)
|
||||
{
|
||||
if (!field) return NULL;
|
||||
PdmXmlFieldHandle* xmlField = field->capability<PdmXmlFieldHandle>();
|
||||
return xmlField;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmXmlFieldHandle::assertValid() const
|
||||
{
|
||||
|
||||
if (m_owner->keyword().isEmpty())
|
||||
{
|
||||
std::cout << "PdmField: Detected use of non-initialized field. Did you forget to do CAF_PDM_InitField() on this field ?\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!PdmXmlObjectHandle::isValidXmlElementName(m_owner->keyword()))
|
||||
{
|
||||
std::cout << "PdmField: The supplied keyword: \"" << m_owner->keyword().toStdString() << "\" is an invalid XML element name, and will break your file format!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmXmlFieldHandle::PdmXmlFieldHandle(PdmFieldHandle* owner, bool giveOwnership) : m_isIOReadable(true), m_isIOWritable(true)
|
||||
{
|
||||
m_owner = owner;
|
||||
owner->addCapability(this, giveOwnership);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Returns the classKeyword of the child class type, if this field is supposed to contain pointers
|
||||
/// to PdmObjectHandle derived onbjects.
|
||||
/// Returns empty string if the field is not containig some PdmObjectHandle type
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString PdmXmlFieldHandle::childClassKeyword()
|
||||
{
|
||||
return m_childClassKeyword;
|
||||
}
|
||||
|
||||
} // End of namespace caf
|
||||
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmFieldCapability.h"
|
||||
#include <QString>
|
||||
|
||||
class QXmlStreamReader;
|
||||
class QXmlStreamWriter;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmFieldHandle;
|
||||
class PdmObjectFactory;
|
||||
class PdmReferenceHelper;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class PdmXmlFieldHandle : public PdmFieldCapability
|
||||
{
|
||||
public:
|
||||
PdmXmlFieldHandle(PdmFieldHandle* owner , bool giveOwnership);
|
||||
virtual ~PdmXmlFieldHandle() { }
|
||||
|
||||
PdmFieldHandle* fieldHandle() { return m_owner; }
|
||||
private:
|
||||
PdmFieldHandle* m_owner;
|
||||
|
||||
/// Xml Serialization
|
||||
public:
|
||||
virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) = 0;
|
||||
virtual void writeFieldData(QXmlStreamWriter& xmlStream) = 0;
|
||||
|
||||
bool isIOReadable() { return m_isIOReadable; }
|
||||
bool isIOWritable() { return m_isIOWritable; }
|
||||
void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; }
|
||||
void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; }
|
||||
|
||||
QString childClassKeyword();
|
||||
protected:
|
||||
bool assertValid() const;
|
||||
QString m_childClassKeyword; ///< Must be set in constructor of derived XmlFieldHandle
|
||||
|
||||
private:
|
||||
bool m_isIOReadable;
|
||||
bool m_isIOWritable;
|
||||
|
||||
|
||||
};
|
||||
|
||||
PdmXmlFieldHandle* xmlField(PdmFieldHandle* field);
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafInternalPdmXmlFieldCapability.h"
|
||||
@@ -0,0 +1,234 @@
|
||||
#include "cafPdmXmlObjectHandle.h"
|
||||
|
||||
#include "cafPdmObjectHandle.h"
|
||||
#include "cafPdmXmlFieldHandle.h"
|
||||
|
||||
#include "cafPdmFieldHandle.h"
|
||||
|
||||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmXmlObjectHandle::PdmXmlObjectHandle(PdmObjectHandle* owner, bool giveOwnership)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_owner->addCapability(this, giveOwnership);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmXmlObjectHandle* xmlObj(PdmObjectHandle* obj)
|
||||
{
|
||||
if (!obj) return NULL;
|
||||
PdmXmlObjectHandle* xmlObject = obj->capability<PdmXmlObjectHandle>();
|
||||
assert(xmlObject);
|
||||
return xmlObject;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Reads all the fields into this PdmObject
|
||||
/// Assumes xmlStream points to the start element token of the PdmObject for which to read fields.
|
||||
/// ( and not first token of object content)
|
||||
/// This makes attribute based field storage possible.
|
||||
/// Leaves the xmlStream pointing to the EndElement of the PdmObject.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmXmlObjectHandle::readFields(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory)
|
||||
{
|
||||
bool isObjectFinished = false;
|
||||
QXmlStreamReader::TokenType type;
|
||||
while (!isObjectFinished)
|
||||
{
|
||||
type = xmlStream.readNext();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case QXmlStreamReader::StartElement:
|
||||
{
|
||||
QString name = xmlStream.name().toString();
|
||||
|
||||
PdmFieldHandle* fieldHandle = m_owner->findField(name);
|
||||
PdmXmlFieldHandle* xmlFieldHandle = xmlField(fieldHandle);
|
||||
if (xmlFieldHandle)
|
||||
{
|
||||
if (xmlFieldHandle->isIOReadable())
|
||||
{
|
||||
// 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();
|
||||
xmlFieldHandle->readFieldData(xmlStream, objectFactory);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlStream.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Line " << xmlStream.lineNumber() << ": 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.
|
||||
QString name = xmlStream.name().toString(); // For debugging
|
||||
isObjectFinished = true;
|
||||
}
|
||||
break;
|
||||
case QXmlStreamReader::EndDocument:
|
||||
{
|
||||
// End of object.
|
||||
isObjectFinished = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// Just read on
|
||||
// Todo: Error handling
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmXmlObjectHandle::writeFields(QXmlStreamWriter& xmlStream)
|
||||
{
|
||||
std::vector<PdmFieldHandle*> fields;
|
||||
m_owner->fields(fields);
|
||||
for (size_t it = 0; it < fields.size(); ++it)
|
||||
{
|
||||
PdmXmlFieldHandle* field = xmlField(fields[it]);
|
||||
if (field && field->isIOWritable())
|
||||
{
|
||||
QString keyword = field->fieldHandle()->keyword();
|
||||
assert(PdmXmlObjectHandle::isValidXmlElementName(keyword));
|
||||
|
||||
xmlStream.writeStartElement("", keyword);
|
||||
field->writeFieldData(xmlStream);
|
||||
xmlStream.writeEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmXmlObjectHandle::readObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory)
|
||||
{
|
||||
// A valid XML is used to store field data of the object. The format of the XML is like this
|
||||
|
||||
/*
|
||||
<classKeyword>
|
||||
<fieldKeywordA>value</fieldKeywordA>
|
||||
<fieldKeywordB>value</fieldKeywordB>
|
||||
</classKeyword>
|
||||
*/
|
||||
|
||||
QXmlStreamReader inputStream(xmlString);
|
||||
|
||||
QXmlStreamReader::TokenType tt;
|
||||
tt = inputStream.readNext(); // Start of document
|
||||
tt = inputStream.readNext();
|
||||
QString classKeyword = inputStream.name().toString();
|
||||
assert(classKeyword == this->classKeyword());
|
||||
|
||||
this->readFields(inputStream, objectFactory);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmObjectHandle* PdmXmlObjectHandle::readUnknownObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory)
|
||||
{
|
||||
QXmlStreamReader inputStream(xmlString);
|
||||
|
||||
QXmlStreamReader::TokenType tt;
|
||||
tt = inputStream.readNext(); // Start of document
|
||||
tt = inputStream.readNext();
|
||||
QString classKeyword = inputStream.name().toString();
|
||||
PdmObjectHandle* newObject = objectFactory->create(classKeyword);
|
||||
|
||||
xmlObj(newObject)->readFields(inputStream, objectFactory);
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString PdmXmlObjectHandle::writeObjectToXmlString()
|
||||
{
|
||||
QString xmlString;
|
||||
QXmlStreamWriter outputStream(&xmlString);
|
||||
outputStream.setAutoFormatting(true);
|
||||
|
||||
outputStream.writeStartElement("", this->classKeyword());
|
||||
this->writeFields(outputStream);
|
||||
outputStream.writeEndElement();
|
||||
return xmlString;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Check if a string is a valid Xml element name
|
||||
//
|
||||
/// http://www.w3schools.com/xml/xml_elements.asp
|
||||
///
|
||||
/// XML elements must follow these naming rules:
|
||||
/// Names can contain letters, numbers, and other characters
|
||||
/// Names cannot start with a number or punctuation character
|
||||
/// Names cannot start with the letters xml (or XML, or Xml, etc)
|
||||
/// Names cannot contain spaces
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool PdmXmlObjectHandle::isValidXmlElementName(const QString& name)
|
||||
{
|
||||
if (name.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name.size() > 0)
|
||||
{
|
||||
QChar firstChar = name[0];
|
||||
if (firstChar.isDigit() || firstChar == '.')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (name.size() >= 3)
|
||||
{
|
||||
if (name.left(3).compare("xml", Qt::CaseInsensitive) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (name.contains(' '))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // end namespace caf
|
||||
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmObjectCapability.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QXmlStreamReader;
|
||||
class QXmlStreamWriter;
|
||||
|
||||
|
||||
namespace caf
|
||||
{
|
||||
|
||||
class PdmXmlFieldHandle;
|
||||
class PdmObjectHandle;
|
||||
class PdmObjectFactory;
|
||||
class PdmReferenceHelper;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
class PdmXmlObjectHandle : public PdmObjectCapability
|
||||
{
|
||||
public:
|
||||
|
||||
PdmXmlObjectHandle(PdmObjectHandle* owner, bool giveOwnership);
|
||||
virtual ~PdmXmlObjectHandle() { }
|
||||
|
||||
/// The classKeyword method is overridden in subclasses by the CAF_PDM_XML_HEADER_INIT macro
|
||||
virtual QString classKeyword() = 0;
|
||||
|
||||
/// Convenience methods to serialize/de-serialize this particular object (with children)
|
||||
void readObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory);
|
||||
QString writeObjectToXmlString();
|
||||
static PdmObjectHandle* readUnknownObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory);
|
||||
|
||||
// Main XML serialization methods that is used internally by the document serialization system
|
||||
// Not supposed to be used directly.
|
||||
void readFields(QXmlStreamReader& inputStream, PdmObjectFactory* objectFactory);
|
||||
void writeFields(QXmlStreamWriter& outputStream);
|
||||
|
||||
/// Check if a string is a valid Xml element name
|
||||
static bool isValidXmlElementName(const QString& name);
|
||||
|
||||
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() {};
|
||||
|
||||
/// This method is intended to be used in macros to make compile time errors
|
||||
// if user uses them on wrong type of objects
|
||||
bool isInheritedFromPdmXmlSerializable() { return true; }
|
||||
|
||||
private:
|
||||
friend class PdmObjectHandle ; // Only temporary for void PdmObject::addFieldNoDefault( ) accessing findField
|
||||
friend class PdmDocument; // To access setupBeforeSave()
|
||||
friend class PdmObjectGroup; // To access initAfterRead
|
||||
|
||||
PdmObjectHandle* m_owner;
|
||||
};
|
||||
|
||||
PdmXmlObjectHandle* xmlObj(PdmObjectHandle* obj);
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafPdmXmlFieldHandle.h"
|
||||
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmDefaultObjectFactory.h"
|
||||
|
||||
// Taken from gtest.h
|
||||
//
|
||||
// Due to C++ preprocessor weirdness, we need double indirection to
|
||||
// concatenate two tokens when one of them is __LINE__. Writing
|
||||
//
|
||||
// foo ## __LINE__
|
||||
//
|
||||
// will result in the token foo__LINE__, instead of foo followed by
|
||||
// the current line number. For more details, see
|
||||
// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
|
||||
#define PDM_OBJECT_STRING_CONCATENATE(foo, bar) PDM_OBJECT_STRING_CONCATENATE_IMPL_(foo, bar)
|
||||
#define PDM_OBJECT_STRING_CONCATENATE_IMPL_(foo, bar) foo ## bar
|
||||
|
||||
|
||||
/// 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
|
||||
|
||||
// To be renamed CAF_PDM_XML_HEADER_INIT
|
||||
#define CAF_PDM_XML_HEADER_INIT \
|
||||
public: \
|
||||
virtual QString classKeyword() { return classKeywordStatic(); } \
|
||||
static QString classKeywordStatic(); \
|
||||
\
|
||||
static bool Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class()
|
||||
|
||||
|
||||
/// CAF_PDM_XML_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_XML_SOURCE_INIT(ClassName, keyword) \
|
||||
bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \
|
||||
\
|
||||
QString ClassName::classKeywordStatic() { return keyword; } \
|
||||
static bool PDM_OBJECT_STRING_CONCATENATE(pdm_object_factory_init_, __LINE__) = caf::PdmDefaultObjectFactory::instance()->registerCreator<ClassName>()
|
||||
|
||||
|
||||
#define CAF_PDM_XML_InitField(field, keyword) \
|
||||
{ \
|
||||
static bool chekingThePresenceOfHeaderAndSourceInitMacros = \
|
||||
Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class(); \
|
||||
this->isInheritedFromPdmXmlSerializable(); \
|
||||
\
|
||||
AddXmlCapabilityToField((field)); \
|
||||
addField((field), (keyword)); \
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user