文字列ベースのラッパーは、ODA Drawings Explorer (ODE) のカスタムオブジェクトプロパティを実装するための主要なメカニズムです。特に、ODE の Common Data Access (CDA) サポートは、OdDbXmlPropCdaBased 文字列 XML ラッパーを通じて実装されています。実装については、Drawing/Examples/Qt/OdaQtPropSystem/DbXmlPropSources.cpp を参照してください。
カスタムエンティティの完全なサポートはCDAに基づくべきですが、このアプローチは手間がかかります。しかし、ODEでいくつかのプロパティを確認したり変更したりできない場合、文字列ラッパーから始める方がはるかに簡単です。
Smileyカスタムエンティティのラッパーを作成する特別な例が提供されています。このサンプルを実行するには、APPLOADコマンドを使用して、ビルドされたOdaQtSmileyProp.txファイルをスタートアップスイートに追加します。「Qt」は、一貫性を保ち、モジュールがODEからロードされるべきであることを示すためだけに名前に含まれています。このモジュールではQtは使用されていません。
新しいカスタムラッパーの追加は、OdPropServicesを使用することで比較的簡単に実装できます。これらのサービスはODEでのみ実装されており、ロードされたモジュールで利用可能です。これらのサービスはKernel SDKの一部ではありません。したがって、それらとリンクすることは問題があります。リンクの必要性を避けるために、モジュールに次のコードを追加してください。
ODRX_NO_CONS_DEFINE_MEMBERS(OdPropServices, OdRxObject);
void ...::initApp()
{
OdPropServices::g_pDesc = OdRxClass::cast(::odrxClassDictionary()->getAt(OD_PROP_SERVICES)).get();
}
void ...::uninitApp()
{
OdPropServices::g_pDesc = NULL;
}
その後、モジュールがODEにロードされている場合、propServices()関数を使用してサービスを取得できます。
static OdPropServices* propServices()
{
OdPropServicesPtr pPropServices = ::odrxSysRegistry()->getAt(OD_PROP_SERVICES);
ODA_ASSERT_ONCE(!pPropServices.isNull()); // is loaded out of ODE
return pPropServices.get();
}
すべての文字列ラッパークラスは、基本クラスOdPropBaseから継承されます。ラッパーを登録した後に追加プロパティを表示するには、getPropertyValues()を独自の追加プロパティの説明でオーバーロードするだけで十分です。
文字列ラッパーの登録または登録解除のキーとして、カスタムエンティティクラスのdesc()->name()を使用します。カスタムクラスのdesc()メソッドがリンクによって利用できない場合は、スマイリーの例のように、その文字列値を直接使用できます。
if (OdPropServices* pPropSrv = propServices())
pPropSrv->registerXmlProp(L"AsdkSmiley",
&OdRxObjectImpl::createObject);
プロパティを取得するために使用されるメソッドは、特別なコンテキストで機能します。元のコンテキストにカテゴリを追加してカテゴリコンテキストを取得し、そこに異なるプロパティを追加できます。メソッドから戻ると、コンテキストデストラクタは、プロパティとその値およびその他の属性の文字列XML記述を形成します。
virtual bool getPropertyValues(OdPropContext& ctx)
{
OdDbEntityPtr pEnt = object();
AsdkSmiley* pSmiley = static_cast(pEnt.get());
OdPropContext ctxSmiley = ctx.addCategory(L"Smiley");
ctxSmiley.addProperty(L"radius", pSmiley->radius(), tDistance)
.comment(L"pop-up text appearing while hovering over the property name"); //.readOnly();
...
return true;
}
編集をサポートするには、次のメソッドをオーバーロードします。
virtual bool setPropertyValue(const OdString& sPath, const OdString& sValue, Action& action)
{
if (sPath == L"Smiley/radius")
{
OdDbEntityPtr pEnt = object(true); // enabled to write
AsdkSmiley* pSmiley = static_cast(pEnt.get());
double dRadius = toDistance(sValue);
pSmiley->setRadius(dRadius);
return true;
}
return false;
}
tCombo型のプロパティの場合、getPropertyPossibleValues()メソッドもオーバーロードし、カテゴリ名とプロパティ名からsPathキーの有効なテキスト値のリストを返します。
さらに、選択されたエンティティのコンボボックスでエンティティの名前をオーバーロードできます。
virtual bool overrideClassName(OdString& sClassName) const
{
sClassName = L"Smiley Custom Entity";
return true;
}
詳細については、ODAドキュメントを参照してください。