899 lines
24 KiB
C++
899 lines
24 KiB
C++
#include "StdAfx.h"
|
|
#include "FindAndReplaceUtil.h"
|
|
|
|
extern TARCH_IMPEXP BOOL g_bTextStyleEx;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Zyu add on 101019,抽象类,定义不同类型对象对应的查找替换方法
|
|
CFAREntity::CFAREntity()
|
|
{
|
|
}
|
|
|
|
CFAREntity::~CFAREntity()
|
|
{
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 上华对象的查找替换类
|
|
// 搜索文字
|
|
TTextPosition CFARTDbEntity::FindText(AcDbEntity *pEnt, const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange)
|
|
{
|
|
TTextPosition posFind;
|
|
|
|
TEntityBase *pText = NULL;
|
|
|
|
if (pEnt->isKindOf(TDbEntity::desc()))
|
|
{
|
|
pText = (TEntityBase*)TDbEntity::cast(pEnt);
|
|
}
|
|
else if (pEnt->isKindOf(TDbCurveEntity::desc()))
|
|
{
|
|
pText = (TEntityBase*)TDbCurveEntity::cast(pEnt);
|
|
}
|
|
|
|
if (NULL != pText&& pEnt->isReadEnabled())
|
|
{
|
|
posFind = pText->FindSubText(sSubText, posStart, pRange);
|
|
}
|
|
|
|
return posFind;
|
|
}
|
|
|
|
// 替换文字
|
|
TTextPosition CFARTDbEntity::ReplaceText(AcDbEntity *pEnt, TTextPosition posFind, const TCHAR *szRepText)
|
|
{
|
|
TTextPosition posStart;
|
|
TEntityBase *pText = NULL;
|
|
|
|
if (pEnt->isKindOf(TDbEntity::desc()))
|
|
{
|
|
pText = (TEntityBase*)TDbEntity::cast(pEnt);
|
|
}
|
|
else if (pEnt->isKindOf(TDbCurveEntity::desc()))
|
|
{
|
|
pText = (TEntityBase*)TDbCurveEntity::cast(pEnt);
|
|
}
|
|
|
|
if(NULL != pText && pEnt->isWriteEnabled())
|
|
{
|
|
posStart = pText->ReplaceSubText(posFind, szRepText);
|
|
}
|
|
return posStart;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 块参照的查找替换类
|
|
CFARInsert::CFARInsert()
|
|
{
|
|
m_bFindAttrib = true;
|
|
m_bFindContent = true;
|
|
m_bFindXref = true;
|
|
m_bNoHidden = false;
|
|
}
|
|
|
|
|
|
// 查找文字
|
|
TTextPosition CFARInsert::FindText(AcDbEntity *pEnt, const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange)
|
|
{
|
|
/*
|
|
算法描述:在块参照/外部参照中搜索文字对象的方法(支持查找块属性,支持块嵌套,支持动态块)
|
|
首先要明确的是,在块参照中只存在块属性的实体,块参照通过一个坐标系转换矩阵将对应的块表记录中的实体
|
|
表现出来,块表记录中存在块属性定义,它与块参照中的块属性对应,但在生成块参照之后,属性定义和属性之间就
|
|
不在相关,它们之间唯一的关系在于,当对参照和块表记录进行迭代遍历时,得到它们的顺序是相同的。对于动态块,
|
|
处于不可见性状态下的实体,在块表记录中,是以不可见状态(AcDb::kInvisible)保存的。
|
|
在CFARUtil类中,聚合了所有支持对象的查找替换方法类,当对一个实体进行查找时,首先被CFARUtil类进行分
|
|
析,根据实体类型匹配不同的查找方法,如果是一个块参照/外部参照,将使用如下描述的方法:
|
|
首先得到块参照中的 所有块属性的id,然后打开对应的块表记录,得到所有的块属性定义的id,形成块属性和
|
|
块属性定义的对应关系。
|
|
然后对块表记录进行迭代遍历,在遍历之前,首先要恢复到上一次搜索结束的位置。
|
|
最后,在遍历过程中得到的实体,都要根据其状态和查找选项的设置判断是否进一步查找,如果继续搜索,则创
|
|
建一个新的CFARUtil类来完成工作。
|
|
在这个查找的过程中,如果是嵌套的块,则会出现递归。类成员中的m_arObjId,记录了打开实体的顺序,用于
|
|
恢复上一次查找结束时,对应的实体。
|
|
*/
|
|
// 查找到的位置
|
|
TTextPosition posFind;
|
|
if (pEnt != NULL && pEnt->isReadEnabled())
|
|
{
|
|
// 转为块参照的指针
|
|
AcDbBlockReference *pRef = AcDbBlockReference::cast(pEnt);
|
|
if (NULL != pRef)
|
|
{
|
|
// 查找块属性文字
|
|
if (m_bFindAttrib)
|
|
{
|
|
// 得到块参照的所有属性ID
|
|
GetAttribIds(pRef);
|
|
}
|
|
// 块参照与块表记录中实体的位置转换矩阵
|
|
AcGeMatrix3d matrix = pRef->blockTransform();
|
|
|
|
// 打开块表记录
|
|
OPENOBJ_BEGIN(pRef->blockTableRecord(), AcDb::kForRead, AcDbBlockTableRecord, pBlkRec);
|
|
if (pBlkRec != NULL)
|
|
{
|
|
// 是否继续搜索
|
|
bool bContinue = false;
|
|
// 是否是外部参照
|
|
bool bIsXref = pBlkRec->isFromExternalReference() || pBlkRec->isFromOverlayReference();
|
|
// 不是外部参照或者可以查找外部参照,则继续查找
|
|
bContinue = !bIsXref || m_bFindXref;
|
|
|
|
if (bContinue)
|
|
{
|
|
if (m_bFindAttrib)
|
|
{
|
|
// 得到块表记录的所有属性定义的ID
|
|
GetAttribDefIds(pBlkRec);
|
|
}
|
|
|
|
// 对块表记录进行迭代查看
|
|
AcDbBlockTableRecordIterator *pIter = NULL;
|
|
if (Acad::eOk == pBlkRec->newIterator(pIter))
|
|
{
|
|
// 继续从上一次搜索结束的位置开始查找
|
|
// 调整迭代器指针,指向m_arObjId中的第一个id代表的实体
|
|
AcDbObjectId entId;
|
|
pIter->getEntityId(entId);
|
|
//wlw del 130708 测试信息应该删掉
|
|
SeekBlockRecIter(pIter);
|
|
pIter->getEntityId(entId);
|
|
for (; !pIter->done(); pIter->step())
|
|
{
|
|
AcDbEntity *pEntity = NULL;
|
|
// 打开块表记录中的实体
|
|
if (Acad::eOk == pIter->getEntity(pEntity, AcDb::kForRead))
|
|
{
|
|
// 判断实体是否满足搜索选项要求
|
|
if (ContinueFind(pEntity, bIsXref))
|
|
{
|
|
bool bIsAttrib = pEntity->isKindOf(AcDbAttributeDefinition::desc());
|
|
// 如果pEntity指向的是一个块属性定义,则令指针pEntity指向属性定义在块参照中对应的实体
|
|
if (bIsAttrib)
|
|
{
|
|
AcDbObjectId objIdAttrib;
|
|
// 匹配属性和属性定义的ID
|
|
int iIndex = -1;
|
|
m_arAttribDefId.find(pEntity->id(), iIndex);
|
|
if (iIndex > -1 && iIndex < m_arAttribId.length())
|
|
{
|
|
objIdAttrib = m_arAttribId.at(iIndex);
|
|
}
|
|
if (objIdAttrib.isValid())
|
|
{
|
|
AcDbEntity *pTempEnt = NULL;
|
|
// 打开对应的属性
|
|
if (Acad::eOk == acdbOpenAcDbEntity(pTempEnt, objIdAttrib, AcDb::kForRead))
|
|
{
|
|
pEntity->close();
|
|
pEntity = pTempEnt;
|
|
AcDbAttribute *pAttr = (AcDbAttribute*)pTempEnt;
|
|
CString strAttr = pAttr->textString();
|
|
}
|
|
}
|
|
}
|
|
|
|
// 使用查找替换工具类对pEntity进行进一步的查找
|
|
CFARUtil farUtil;
|
|
farUtil.SetFindOption(true, true, true, m_bNoHidden);
|
|
// 传递当前的id数组,以便进一步恢复现场
|
|
farUtil.SetEntityIds(m_arObjId);
|
|
posFind = farUtil.FindEntText(pEntity, sSubText, posStart, pRange);
|
|
|
|
// 查找成功
|
|
if (!!posFind)
|
|
{
|
|
AcDbObjectId __id = pEntity->id();
|
|
|
|
// 更新id数组
|
|
ClearObjIdArray(m_arObjId);
|
|
m_arObjId.append(farUtil.GetEntityIds());
|
|
m_arObjId.insertAt(0, pEntity->id());
|
|
|
|
// 如果当前的实体不是属性实体,则要将pRang指示框从块表记录
|
|
// 的坐标系转到块参照的坐标系
|
|
if (!bIsAttrib)
|
|
{
|
|
TransformRange(pRange, matrix);
|
|
}
|
|
pEntity->close();
|
|
break;
|
|
}
|
|
}
|
|
ClearObjIdArray(m_arObjId);
|
|
posStart.m_nCookies = 0;
|
|
posStart.m_nTextPos = -1;
|
|
pEntity->close();
|
|
}
|
|
}
|
|
if (pIter->done())
|
|
{
|
|
ClearObjIdArray(m_arAttribId);
|
|
ClearObjIdArray(m_arAttribDefId);
|
|
}
|
|
delete pIter;
|
|
}
|
|
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
return posFind;
|
|
}
|
|
|
|
// 替换文字
|
|
TTextPosition CFARInsert::ReplaceText(AcDbEntity *pEnt, TTextPosition posFind, const TCHAR *szRepText)
|
|
{
|
|
TTextPosition posStart;
|
|
if (m_arObjId.length() != 0 && m_arObjId.last().isValid())
|
|
{
|
|
// 打开ID对应的实体,调用查找替换工具类的方法进行替换
|
|
OPENOBJ_BEGIN(m_arObjId.last(), AcDb::kForWrite, AcDbEntity, pEntity);
|
|
CFARUtil farUtil;
|
|
posStart = farUtil.ReplaceEntText(pEntity, posFind, szRepText);
|
|
OPENOBJ_END();
|
|
}
|
|
return posStart;
|
|
}
|
|
|
|
// 设置实体数组
|
|
void CFARInsert::SetEntityIds(const AcDbObjectIdArray& arObjId)
|
|
{
|
|
m_arObjId.append(arObjId);
|
|
}
|
|
|
|
// 得到实体数组
|
|
const AcDbObjectIdArray& CFARInsert::GetEntityIds() const
|
|
{
|
|
return m_arObjId;
|
|
}
|
|
|
|
// 设置搜索选项
|
|
void CFARInsert::SetFindInsertOption(BOOL bFindAttrib, BOOL bFindContent, BOOL bFindXref, BOOL bNoHidden)
|
|
{
|
|
m_bFindAttrib = bFindAttrib;
|
|
m_bFindContent = bFindContent;
|
|
m_bFindXref = bFindXref;
|
|
m_bNoHidden = bNoHidden;
|
|
}
|
|
|
|
// 根据给出的矩阵关系,转换指示文本范围的线框位置
|
|
void CFARInsert::TransformRange(TTextRange *& pRange, const AcGeMatrix3d &matrix) const
|
|
{
|
|
if (pRange != NULL)
|
|
{
|
|
int iLen = pRange->m_lstRanges.Length();
|
|
for (int i = 0; i < iLen; i++)
|
|
{
|
|
pRange->m_lstRanges.GetAt(i)->TransformBy(matrix);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 得到块参照的所有属性ID
|
|
void CFARInsert::GetAttribIds(AcDbBlockReference *pRef)
|
|
{
|
|
// 如果内容不为空,说明当前是在查找同一实体,不重复进行遍历
|
|
if (m_arAttribId.length() != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbObjectIterator *pObjIter = pRef->attributeIterator();
|
|
for (pObjIter->start(); !pObjIter->done(); pObjIter->step())
|
|
{
|
|
m_arAttribId.append(pObjIter->objectId());
|
|
}
|
|
delete pObjIter;
|
|
}
|
|
|
|
// 得到块表记录中所有属性定义的ID
|
|
void CFARInsert::GetAttribDefIds(AcDbBlockTableRecord *pBlkRec)
|
|
{
|
|
// 如果内容不为空,说明当前是在查找同一实体,不重复进行遍历
|
|
if (m_arAttribDefId.length() != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
AcDbBlockTableRecordIterator *pIter = NULL;
|
|
if (Acad::eOk == pBlkRec->newIterator(pIter))
|
|
{
|
|
AcDbEntity *pEnt = NULL;
|
|
for (pIter->start(); !pIter->done(); pIter->step())
|
|
{
|
|
if (Acad::eOk == pIter->getEntity(pEnt, AcDb::kForRead))
|
|
{
|
|
// 当前实体是属性定义,则添加到数组中
|
|
if (pEnt->isKindOf(AcDbAttributeDefinition::desc()))
|
|
{
|
|
m_arAttribDefId.append(pEnt->objectId());
|
|
}
|
|
pEnt->close();
|
|
}
|
|
}
|
|
delete pIter;
|
|
pIter = NULL;
|
|
}
|
|
}
|
|
|
|
// 调整迭代器指针,指向m_arObjId中的第一个id代表的实体
|
|
bool CFARInsert::SeekBlockRecIter(AcDbBlockTableRecordIterator *pIter)
|
|
{
|
|
Acad::ErrorStatus es = Acad::eOk;
|
|
if (m_arObjId.length() != 0)
|
|
{
|
|
// 取出ID数组中的第一个ID
|
|
AcDbObjectId objId = m_arObjId.first();
|
|
m_arObjId.removeFirst();
|
|
|
|
int iIndex = -1;
|
|
// 如果在属性id数组中存在该id,说明是一个块属性的id,
|
|
// seek迭代器指针到块表记录中对应的属性定义实体
|
|
// m_arAttribId.find(m_arObjId.first(), iIndex);
|
|
m_arAttribId.find(objId, iIndex);
|
|
if (iIndex != -1)
|
|
{
|
|
objId = m_arAttribDefId.at(iIndex);
|
|
}
|
|
|
|
es = pIter->seek(objId);
|
|
|
|
if (Acad::eOk != es)
|
|
{
|
|
for (; !pIter->done(); pIter->step())
|
|
{
|
|
AcDbObjectId objIdTemp;
|
|
if (pIter->getEntityId(objIdTemp) == Acad::eOk)
|
|
{
|
|
if (objId == objIdTemp)
|
|
{
|
|
es = Acad::eOk;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (Acad::eOk == es);
|
|
}
|
|
|
|
// 判断实体是否满足搜索选项要求,不满足返回false
|
|
bool CFARInsert::ContinueFind(AcDbEntity *pEnt, bool bIsXref) const
|
|
{
|
|
bool bContinue = false;
|
|
if (NULL != pEnt && pEnt->isReadEnabled())
|
|
{
|
|
// 是否是属性定义
|
|
bool bIsAttrib = pEnt->isKindOf(AcDbAttributeDefinition::desc());
|
|
if (bIsAttrib)
|
|
{
|
|
bContinue = !!m_bFindAttrib;
|
|
}
|
|
// 所在块是否是外部参照
|
|
else if (bIsXref)
|
|
{
|
|
bContinue = !!m_bFindXref;
|
|
}
|
|
// 是否查找块内容
|
|
else
|
|
{
|
|
bContinue = !!m_bFindContent;
|
|
}
|
|
|
|
// 如果实体是隐藏的并且搜索时要忽略隐藏选项,则不继续搜索
|
|
if (m_bNoHidden && pEnt->visibility() == AcDb::kInvisible)
|
|
{
|
|
bContinue = false;
|
|
}
|
|
}
|
|
|
|
return bContinue;
|
|
}
|
|
|
|
// 重新开始搜索
|
|
void CFARInsert::ResetFind()
|
|
{
|
|
// 清空数组
|
|
ClearObjIdArray(m_arObjId);
|
|
ClearObjIdArray(m_arAttribId);
|
|
ClearObjIdArray(m_arAttribDefId);
|
|
}
|
|
|
|
// 清空id数组
|
|
void CFARInsert::ClearObjIdArray(AcDbObjectIdArray &arObjId)
|
|
{
|
|
int iLen = arObjId.length();
|
|
if (0 != iLen)
|
|
{
|
|
arObjId.removeSubArray(0, iLen - 1);
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 块属性的查找替换类
|
|
CFARInsertAttrib::CFARInsertAttrib()
|
|
{
|
|
m_bNoHidden = false;
|
|
}
|
|
|
|
|
|
TTextPosition CFARInsertAttrib::FindText(AcDbEntity *pEnt, const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange)
|
|
{
|
|
TTextPosition posFind;
|
|
if (pEnt != NULL && pEnt->isReadEnabled())
|
|
{
|
|
AcDbAttribute *pAttrib = AcDbAttribute::cast(pEnt);
|
|
if (NULL != pAttrib)
|
|
{
|
|
// 如果忽略隐藏项并且当前的块属性是隐藏的,则返回
|
|
if (m_bNoHidden && pAttrib->isInvisible())
|
|
{
|
|
return posFind;
|
|
}
|
|
else
|
|
{
|
|
#if (ADS > 17)
|
|
// 是多行的属性,则使用多行文字的查找方法
|
|
if (pAttrib->isMTextAttribute())
|
|
{
|
|
AcDbMText *pMText = pAttrib->getMTextAttribute();
|
|
CFARMText farMText;
|
|
posFind = farMText.FindText(pMText, sSubText, posStart, pRange);
|
|
delete pMText;
|
|
}
|
|
// 否则使用单行文字的查找方法
|
|
else
|
|
#endif
|
|
{
|
|
CFARText farText;
|
|
posFind = farText.FindText(pEnt, sSubText, posStart, pRange);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return posFind;
|
|
}
|
|
|
|
TTextPosition CFARInsertAttrib::ReplaceText(AcDbEntity *pEnt, TTextPosition posFind, const TCHAR *szRepText)
|
|
{
|
|
TTextPosition posStart;
|
|
if (pEnt != NULL && pEnt->isWriteEnabled())
|
|
{
|
|
AcDbAttribute *pAttrib = AcDbAttribute::cast(pEnt);
|
|
if (pAttrib != NULL)
|
|
{
|
|
#if (ADS > 17)
|
|
// 是多行的属性,则使用多行文字的替换方法
|
|
if (pAttrib->isMTextAttribute())
|
|
{
|
|
AcDbMText *pMText = pAttrib->getMTextAttribute();
|
|
CFARMText farMText;
|
|
posStart = farMText.ReplaceText(pMText, posFind, szRepText);
|
|
if (!!posFind)
|
|
{
|
|
pAttrib->setMTextAttribute(pMText);
|
|
}
|
|
}
|
|
// 否则使用单行文字的替换方法
|
|
else
|
|
#endif
|
|
{
|
|
CFARText farText;
|
|
posStart = farText.ReplaceText(pEnt, posFind, szRepText);
|
|
}
|
|
}
|
|
}
|
|
|
|
return posStart;
|
|
}
|
|
|
|
// 设置忽略隐藏项
|
|
void CFARInsertAttrib::SetNoHidden(BOOL bNoHidden)
|
|
{
|
|
m_bNoHidden = bNoHidden;
|
|
}
|
|
|
|
// 单行文字的查找替换类
|
|
TTextPosition CFARText::FindText(AcDbEntity *pEnt, const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange)
|
|
{
|
|
TTextPosition posFind;
|
|
CStringArray arString;
|
|
CString sSrcText(sSubText);
|
|
posStart.m_nCookies = 0;
|
|
XPushMemVar<BOOL> vTemp(g_bTextStyleEx, FALSE);
|
|
TDbText text;
|
|
AcDbText *pText = AcDbText::cast(pEnt);
|
|
// 单行文字转成上华单行文字,再做查找
|
|
if(text.ConvertFrom(pText))
|
|
{
|
|
posFind = text.FindSubText(sSrcText, posStart, pRange);
|
|
}
|
|
|
|
return posFind;
|
|
}
|
|
|
|
TTextPosition CFARText::ReplaceText(AcDbEntity *pEnt, TTextPosition posFind, const TCHAR *szRepText)
|
|
{
|
|
TTextPosition posStart;
|
|
XPushMemVar<BOOL> vTemp(g_bTextStyleEx, FALSE);
|
|
TDbText text;
|
|
AcDbText *pText=AcDbText::cast(pEnt);
|
|
// 单行文字转成上华单行文字,再做替换
|
|
if(text.ConvertFrom(pText))
|
|
{
|
|
posStart = text.ReplaceSubText(posFind, szRepText);
|
|
pText->setTextString((const TCHAR *)text.GetText());
|
|
}
|
|
|
|
return posStart;
|
|
}
|
|
|
|
// 得到单行文字内的字符串
|
|
bool CFARText::GetEntityStrings(AcDbEntity *pEnt, CStringArray &arString)
|
|
{
|
|
AcDbText *pEntity = AcDbText::cast(pEnt);
|
|
if (NULL != pEnt && pEnt->isReadEnabled())
|
|
{
|
|
LPTSTR pszText = pEntity->textString();
|
|
arString.Add(pszText);
|
|
delete[] pszText;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 多行文字的查找替换类
|
|
TTextPosition CFARMText::FindText(AcDbEntity *pEnt, const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange)
|
|
{
|
|
TTextPosition posFind;
|
|
XPushMemVar<BOOL> vTemp(g_bTextStyleEx, FALSE);
|
|
AcDbVoidPtrArray arEnts;
|
|
|
|
// 将多行文字对象炸开成单行文字,再进行查找
|
|
if (Acad::eOk == pEnt->explode(arEnts))
|
|
{
|
|
CFARText farText;
|
|
for (int i = posStart.m_nCookies; i < arEnts.length(); i++)
|
|
{
|
|
posFind = farText.FindText((AcDbEntity*)arEnts.at(i), sSubText, posStart, pRange);
|
|
if (!!posFind)
|
|
{
|
|
posFind.m_nCookies = i;
|
|
posStart.m_nCookies = i;
|
|
posStart.m_nTextPos = posFind.m_nTextPos + 1;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
posStart.m_nTextPos = -1;
|
|
}
|
|
}
|
|
ReleaseEntSet(arEnts);
|
|
}
|
|
return posFind;
|
|
}
|
|
|
|
TTextPosition CFARMText::ReplaceText(AcDbEntity *pEnt, TTextPosition posFind, const TCHAR *szRepText)
|
|
{
|
|
TTextPosition posStart;
|
|
if (!pEnt->isWriteEnabled())
|
|
{
|
|
return posStart;
|
|
}
|
|
|
|
CStringArray arString;
|
|
// 得到多行文字包含的所有字符串
|
|
if (GetEntityStrings(pEnt, arString))
|
|
{
|
|
CString sChange;
|
|
CString sContent;
|
|
// 取出要替换的字符串
|
|
sChange = arString.GetAt(posFind.m_nCookies);
|
|
// 替换文字
|
|
sChange.Delete(posFind.m_nTextPos, (int)posFind.m_nBufLen);
|
|
sChange.Insert(posFind.m_nTextPos, szRepText);
|
|
// 放回被替换的字符串
|
|
arString.SetAt(posFind.m_nCookies, sChange);
|
|
|
|
// 重新组合成AcdbMText格式的字符串
|
|
INT_PTR iLen = arString.GetSize();
|
|
for (int i = 0; i < iLen; i++)
|
|
{
|
|
if (i + 1 != iLen)
|
|
{
|
|
sContent += arString.GetAt(i) + _T("\\P");
|
|
}
|
|
else
|
|
{
|
|
sContent += arString.GetAt(i) ;
|
|
}
|
|
}
|
|
|
|
AcDbMText *pMText = AcDbMText::cast(pEnt);
|
|
|
|
if (pMText != NULL && pMText->isWriteEnabled())
|
|
{
|
|
// 更新字符串内容
|
|
pMText->setContents(sContent);
|
|
|
|
// 修改下一个搜索开始的位置
|
|
posStart.m_nCookies = posFind.m_nCookies;
|
|
posStart.m_nBufLen = _tcslen(szRepText);
|
|
posStart.m_nTextPos = posFind.m_nTextPos + (int)posStart.m_nBufLen;
|
|
}
|
|
}
|
|
return posStart;
|
|
}
|
|
|
|
// 得到多行文字内的字符串
|
|
bool CFARMText::GetEntityStrings(AcDbEntity *pEnt, CStringArray &arString)
|
|
{
|
|
if (pEnt != NULL && pEnt->isReadEnabled())
|
|
{
|
|
AcDbVoidPtrArray arEnts;
|
|
if ( Acad::eOk == pEnt->explode(arEnts))
|
|
{
|
|
int iNum = arEnts.length();
|
|
CFARText farText;
|
|
for (int i = 0; i < iNum; i++)
|
|
{
|
|
AcDbEntity *pEntity = (AcDbEntity*)arEnts.at(i);
|
|
if (pEntity->isKindOf(AcDbText::desc()))
|
|
{
|
|
farText.GetEntityStrings(pEntity, arString);
|
|
}
|
|
}
|
|
ReleaseEntSet(arEnts);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 标注的查找替换类
|
|
TTextPosition CFARDimension::FindText(AcDbEntity *pEnt, const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange)
|
|
{
|
|
TTextPosition posFind;
|
|
AcDbDimension *pDim = AcDbDimension::cast(pEnt);
|
|
if (NULL != pDim)
|
|
{
|
|
AcDbVoidPtrArray arEnts;
|
|
// 炸开标注对象,从其中的多行文字对象中进行查找
|
|
if (Acad::eOk == pDim->explode(arEnts))
|
|
{
|
|
CFARMText farMtext;
|
|
for(int i = 0; i < arEnts.length(); i++)
|
|
{
|
|
AcDbEntity *pEntity = (AcDbEntity*)arEnts.at(i);
|
|
AcDbMText *pText = AcDbMText::cast(pEntity);
|
|
if (NULL != pText)
|
|
{
|
|
posFind = farMtext.FindText(pText, sSubText, posStart, pRange);
|
|
break;
|
|
}
|
|
}
|
|
ReleaseEntSet(arEnts);
|
|
}
|
|
}
|
|
return posFind;
|
|
}
|
|
|
|
TTextPosition CFARDimension::ReplaceText(AcDbEntity *pEnt, TTextPosition posFind, const TCHAR *szRepText)
|
|
{
|
|
TTextPosition posStart;
|
|
AcDbDimension *pDim = AcDbDimension::cast(pEnt);
|
|
if (NULL != pDim && pDim->isWriteEnabled())
|
|
{
|
|
AcDbVoidPtrArray arEnts;
|
|
// 炸开标注对象,替换其中的多行文字对象
|
|
if (Acad::eOk == pDim->explode(arEnts))
|
|
{
|
|
CFARMText farMtext;
|
|
for(int i = 0; i < arEnts.length(); i++)
|
|
{
|
|
AcDbEntity *pEntity = (AcDbEntity*)arEnts.at(i);
|
|
AcDbMText *pText = AcDbMText::cast(pEntity);
|
|
if (NULL != pText)
|
|
{
|
|
posStart = farMtext.ReplaceText(pText, posFind, szRepText);
|
|
if (!!posStart)
|
|
{
|
|
LPTSTR pszContents = pText->contents();
|
|
pDim->setDimensionText(pszContents);
|
|
pDim->recomputeDimBlock();
|
|
delete[] pszContents;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
ReleaseEntSet(arEnts);
|
|
}
|
|
}
|
|
return posStart;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 查找替换工具集
|
|
// 查找文字
|
|
TTextPosition CFARUtil::FindEntText(TEntitySet ent, const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange)
|
|
{
|
|
TTextPosition posFind;
|
|
if(sSubText == NULL)
|
|
return posFind;
|
|
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbEntity, pEnt);
|
|
posFind = FindEntText(pEnt, sSubText, posStart, pRange);
|
|
OPENOBJ_END();
|
|
|
|
return posFind;
|
|
}
|
|
|
|
TTextPosition CFARUtil::FindEntText(AcDbEntity *pEnt, const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange)
|
|
{
|
|
TTextPosition posFind;
|
|
|
|
if (pEnt != NULL && pEnt->isReadEnabled())
|
|
{
|
|
// 忽略隐藏层上的实体
|
|
if (m_bNoHidden)
|
|
{
|
|
if (IsHiddenEntity(pEnt))
|
|
{
|
|
return posFind;
|
|
}
|
|
}
|
|
|
|
// 所有上华对象,使用统一的函数
|
|
if (pEnt->isKindOf(TDbEntity::desc()) || pEnt->isKindOf(TDbCurveEntity::desc()))
|
|
{
|
|
posFind = m_TDbEntity.FindText(pEnt, sSubText, posStart, pRange);
|
|
}
|
|
// 属性定义
|
|
else if (pEnt->isKindOf(AcDbAttribute::desc()))
|
|
{
|
|
posFind = m_InsertAttrib.FindText(pEnt, sSubText, posStart, pRange);
|
|
}
|
|
// 单行文字
|
|
else if (pEnt->isKindOf(AcDbText::desc()))
|
|
{
|
|
posFind = m_Text.FindText(pEnt, sSubText, posStart, pRange);
|
|
}
|
|
// 多行文字
|
|
else if (pEnt->isKindOf(AcDbMText::desc()))
|
|
{
|
|
posFind = m_MText.FindText(pEnt, sSubText, posStart, pRange);
|
|
}
|
|
// 块参照/外部参照
|
|
else if (pEnt->isKindOf(AcDbBlockReference::desc()))
|
|
{
|
|
posFind = m_Insert.FindText(pEnt, sSubText, posStart, pRange);
|
|
}
|
|
// 标注
|
|
else if (pEnt->isKindOf(AcDbDimension::desc()))
|
|
{
|
|
posFind = m_Dimension.FindText(pEnt, sSubText, posStart, pRange);
|
|
}
|
|
}
|
|
|
|
return posFind;
|
|
}
|
|
|
|
// 替换文字
|
|
TTextPosition CFARUtil::ReplaceEntText(TEntitySet ent, TTextPosition posFind, const TCHAR *szRepText)
|
|
{
|
|
TTextPosition posStart;
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AcDbEntity, pEnt);
|
|
if (pEnt != NULL)
|
|
{
|
|
posStart = ReplaceEntText(pEnt, posFind, szRepText);
|
|
}
|
|
OPENOBJ_END();
|
|
return posStart;
|
|
}
|
|
|
|
TTextPosition CFARUtil::ReplaceEntText(AcDbEntity *pEnt, TTextPosition posFind, const TCHAR *szRepText)
|
|
{
|
|
TTextPosition posStart;
|
|
if (NULL != pEnt && pEnt->isWriteEnabled())
|
|
{
|
|
// 上华对象
|
|
if(pEnt->isKindOf(TDbEntity::desc()) || pEnt->isKindOf(TDbCurveEntity::desc()))
|
|
{
|
|
posStart = m_TDbEntity.ReplaceText(pEnt, posFind, szRepText);
|
|
}
|
|
// 块属性
|
|
else if (pEnt->isKindOf(AcDbAttribute::desc()))
|
|
{
|
|
posStart = m_InsertAttrib.ReplaceText(pEnt, posFind, szRepText);
|
|
}
|
|
// 单行文字
|
|
else if(pEnt->isKindOf(AcDbText::desc()))
|
|
{
|
|
posStart = m_Text.ReplaceText(pEnt, posFind, szRepText);
|
|
}
|
|
// 多行文字
|
|
else if (pEnt->isKindOf(AcDbMText::desc()))
|
|
{
|
|
posStart = m_MText.ReplaceText(pEnt, posFind, szRepText);
|
|
}
|
|
// 块参照/外部参照
|
|
else if(pEnt->isKindOf(AcDbBlockReference::desc()))
|
|
{
|
|
posStart = m_Insert.ReplaceText(pEnt, posFind, szRepText);
|
|
}
|
|
// 标注
|
|
else if (pEnt->isKindOf(AcDbDimension::desc()))
|
|
{
|
|
posStart = m_Dimension.ReplaceText(pEnt, posFind, szRepText);
|
|
}
|
|
}
|
|
return posStart;
|
|
}
|
|
|
|
// 设置id数组
|
|
void CFARUtil::SetEntityIds(const AcDbObjectIdArray &arObjId)
|
|
{
|
|
m_Insert.SetEntityIds(arObjId);
|
|
}
|
|
|
|
// 获得id数组
|
|
const AcDbObjectIdArray& CFARUtil::GetEntityIds() const
|
|
{
|
|
return m_Insert.GetEntityIds();
|
|
}
|
|
|
|
// 设置查找选项
|
|
void CFARUtil::SetFindOption(BOOL bFindAttrib, BOOL bFindContent, BOOL bFindXref, BOOL bNoHidden)
|
|
{
|
|
m_Insert.SetFindInsertOption(bFindAttrib, bFindContent, bFindXref, bNoHidden);
|
|
m_InsertAttrib.SetNoHidden(bNoHidden);
|
|
m_bNoHidden = bNoHidden;
|
|
}
|
|
|
|
// 重新开始搜索
|
|
void CFARUtil::ResetFind()
|
|
{
|
|
m_Insert.ResetFind();
|
|
}
|
|
|
|
// 判断实体是否是在关闭或者隐藏层上
|
|
bool CFARUtil::IsHiddenEntity(AcDbEntity *&pEnt)
|
|
{
|
|
// 返回值
|
|
bool bRet = false;
|
|
if (pEnt != NULL && pEnt->isReadEnabled())
|
|
{
|
|
LPTSTR pszLayerName = pEnt->layer();
|
|
// 在记录中查找
|
|
if (!m_mapLayer.Lookup(pszLayerName, bRet))
|
|
{
|
|
// 如果记录中不存在,则打开图层判断,并记录结果
|
|
bRet = IsHiddenLayer(pEnt->layerId());
|
|
m_mapLayer.SetAt(pszLayerName, bRet);
|
|
}
|
|
delete[] pszLayerName;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
// 判断id对应的层是否是关闭或者隐藏层
|
|
bool CFARUtil::IsHiddenLayer(const AcDbObjectId &objIdLayer) const
|
|
{
|
|
if (objIdLayer.isValid())
|
|
{
|
|
OPENOBJ_BEGIN(objIdLayer, AcDb::kForRead, AcDbLayerTableRecord, pLayer);
|
|
if (pLayer != NULL)
|
|
{
|
|
// 判断是否是关闭或者隐藏层
|
|
return (pLayer->isOff() || pLayer->isFrozen());
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
return false;
|
|
}
|