Files
envi-code/SourceCode/Code2026/tg_shs/shs_kerncmd/FloorRectReacter.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1367 lines
34 KiB
C++

// FloorRectReacter.cpp : 实现文件
//
#include "stdafx.h"
#include "FloorRectReacter.h"
#include "FloorRectEditDlg.h"
#include "ProjectManager.h"
#include "TCheckFloorRectData.h"
// 全局楼层框反映器
TFloorRectDbReactor *g_pFloorRectDbReactor = NULL;
TFloorRectDocReactor *g_pFloorRectDocReactor = NULL;
// 全局楼层框处理类对象
TFloorRectDealSystem *g_pFloorRectData = NULL;
// 全局控制切换文档标签时,是否修改工程
bool g_bChangeCurProject = true;
// 打开文档
void OpenDoc(void *pData)
{
AcApDocument* pDoc = acDocManager->mdiActiveDocument(); //记录当前文档
if (acDocManager->isApplicationContext())
{
acDocManager->pushResourceHandle(acedGetAcadResourceInstance());
acDocManager->appContextOpenDocument((const TCHAR *)pData);
acDocManager->popResourceHandle();
acDocManager->activateDocument(pDoc); // 这里将文档切换回原来的文档,以便该文档继续执行代码
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Begin TFloorRectDocReactor
void TFloorRectDocReactor::documentCreated(AcApDocument* pDocCreating)
{
if (g_pFloorRectDbReactor == NULL)
{
g_pFloorRectDbReactor = new TFloorRectDbReactor;
}
AcDbDatabase *pDb = pDocCreating->database();
if (pDb != NULL)
{
pDb->addReactor(g_pFloorRectDbReactor);
}
}
void TFloorRectDocReactor::documentToBeDestroyed(AcApDocument* pDocToDestroy)
{
AcDbDatabase *pDb = pDocToDestroy->database();
if (pDb != NULL)
{
pDb->removeReactor(g_pFloorRectDbReactor);
g_pFloorRectDbReactor = NULL;
}
}
// sg add 100514,集成原文档反应器TProjectDocReactor的功能,处理文档切换过程中,对应切换工程
void TFloorRectDocReactor::documentActivated(AcApDocument* pActivatedDoc)
{
if (g_bChangeCurProject)
{
CString sNewFile = DocGetProjectFile();
if (sNewFile != _T("") &&
FindFile(sNewFile) &&
!g_project.Is(sNewFile))
{
if (g_project.Load(sNewFile) && g_projectBar.GetSafeHwnd() != NULL)
g_projectBar.Refresh();
}
}
}
// End TFloorRectDocReactor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Begin TFloorRectDocReactor
// 将实体添加到当前DWG时的处理函数
void TFloorRectDbReactor::objectAppended(const AcDbDatabase* dwg, const AcDbObject* dbObj)
{
// 不使用数据库反映器
if (!g_bMonitorDbAction)
{
return;
}
if (dwg==acdbCurDwg() && NULL!=dbObj) // append
{
// 只处理楼层框对象
if (!dbObj->isKindOf(TDbFloorRect::desc()))
{
return;
}
g_pFloorRectData->ObjectAppended(dbObj);
}
}
void TFloorRectDbReactor::objectModified(const AcDbDatabase* dwg, const AcDbObject* dbObj)
{
// 不使用数据库反映器
if (!g_bMonitorDbAction)
{
return;
}
if (dwg==acdbCurDwg() && NULL!=dbObj) // append
{
// 只处理楼层框对象
if (!dbObj->isKindOf(TDbFloorRect::desc()))
{
return;
}
g_pFloorRectData->ObjectModified(dbObj);
}
}
// 将实体从当前DWG中删除时的处理
void TFloorRectDbReactor::objectErased(const AcDbDatabase* dwg, const AcDbObject* dbObj, Adesk::Boolean pErased)
{
// 不使用数据库反映器
if (!g_bMonitorDbAction)
{
return;
}
if (dwg==acdbCurDwg() && NULL!=dbObj)
{
// 只处理楼层框对象
if (!dbObj->isKindOf(TDbFloorRect::desc()))
{
return;
}
if (pErased == Adesk::kTrue) // erased
{
g_pFloorRectData->ObjectErased(dbObj);
}
else // unerased
{
g_pFloorRectData->ObjectUnerased(dbObj);
}
}
}
// End TFloorRectDbReactor
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Begin TFloorRectItem
TFloorRectItem::TFloorRectItem()
{
m_nRowIndex = -1;
m_csPrompt = _T("");
m_csDwgFile = _T("");
}
void TFloorRectItem::SetFloors(const AcDbIntArray &aryFloors)
{
m_aryFloors = aryFloors;
}
// 获取楼层号
void TFloorRectItem::GetFloors(AcDbIntArray &aryFloors) const
{
aryFloors = m_aryFloors;
}
// 获取提示语
CString TFloorRectItem::GetPrompt() const
{
return m_csPrompt;
}
/////////////////////////////////////////////////////////////////////
// 根据图纸名称,搜索对应行号和工程名称的对象,得到对象ID
bool TFloorRectItem::SetObjIdFromDwg(AcApDocument*& pDoc, bool &bIsOpenAlready)
{
bIsOpenAlready = false;
pDoc = NULL;
if (!FindFile(m_csDwgFile))
{
m_csPrompt = _T("");
return false;
}
AcApDocument *pCurDoc = curDoc();
if (NULL == pCurDoc)
{
m_csPrompt = _T("当前程序未打开图形文件");
return false;
}
// 查询要打开的文档是否已经是打开状态
AcApDocumentIterator *pDocIter = acDocManager->newAcApDocumentIterator();
for (; !pDocIter->done(); pDocIter->step())
{ // 搜索对应的文档指针
if (0 == m_csDwgFile.CompareNoCase(pDocIter->document()->fileName()))
{
pDoc = pDocIter->document();
bIsOpenAlready = true;
break;
}
}
delete pDocIter;
if (NULL == pDoc)
{
TPushMemVar<bool> pushVar(g_bChangeCurProject, false);
// 打开文档
if (acDocManager->isApplicationContext())
{
OpenDoc((void *)(LPCTSTR)m_csDwgFile);
}
else
{
acDocManager->executeInApplicationContext(OpenDoc, (void *)(LPCTSTR)m_csDwgFile);
}
pDocIter = acDocManager->newAcApDocumentIterator();
for (; !pDocIter->done(); pDocIter->step())
{ // 搜索对应的文档指针
if (0 == m_csDwgFile.CompareNoCase(pDocIter->document()->fileName()))
{
pDoc = pDocIter->document();
bIsOpenAlready = false;
break;
}
}
delete pDocIter;
if (NULL == pDoc)
{
m_csPrompt = (_T("不能打开文件%s!"), m_csDwgFile);
return false;
}
}
acDocManager->setCurDocument(pDoc);
// 搜索文件内的所有楼层框
struct resbuf * pResbuf = acutBuildList(RTDXF0, _T("TCH_FLOORRECT"), NULL);
ads_name ssPickSet, ent;
acedSSGet(_T("_X"), NULL, NULL, pResbuf, ssPickSet);
acutRelRb(pResbuf);
long lLen = 0;
acedSSLength(ssPickSet, &lLen);
if (lLen < 1)
{
acedSSFree(ssPickSet);
acDocManager->setCurDocument(pCurDoc);
return false;
}
acDocManager->lockDocument(curDoc());
// 遍历选择集中的楼层框
AcDbObjectId idObj;
bool bRet = false;
for(long i = 0; i < lLen; i++)
{
if (RTNORM == acedSSName(ssPickSet, i, ent))
{
if (Acad::eOk == acdbGetObjectId(idObj, ent))
{
TDbFloorRect *pEnt = NULL;
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbFloorRect, pEnt);
// 查找表格索引号相同的楼层框
if (pEnt->GetTableIndex() == m_nRowIndex)
{
// 楼层框工程名称与当前工程名称相同时
if (g_pFloorRectData->GetProjectName().CompareNoCase(pEnt->GetSpare()) == 0)
{
// 当一张图纸里有多个同工程名称、同行号的楼层框时,优先找到一个与m_idObj不同的id
if (m_idObj.isValid() && idObj.isValid() && m_idObj == idObj)
{
bRet = true;
}
else
{
m_idObj = idObj;
bRet = true;
break;
}
}
else // 修改对象的工程名称
{
m_idObj = idObj;
bRet = true;
if (Acad::eOk == pEnt->upgradeOpen())
{
pEnt->disableUndoRecording(Adesk::kTrue);
pEnt->SetSpare(g_pFloorRectData->GetProjectName());
pEnt->disableUndoRecording(Adesk::kFalse);
pEnt->downgradeOpen();
}
}
}
OPENOBJ_END();
}
}
}
acedSSFree(ssPickSet);
acDocManager->unlockDocument(curDoc());
acDocManager->setCurDocument(pCurDoc);
if (bRet)
{
return true;
}
m_csPrompt = _T("在文件中未搜索到对应的楼层框对象");
return false;
}
/////////////////////////////////////////////////////////////////////
// 与楼层框对象交互
// 设置层高
bool TFloorRectItem::SetHeight(CString csHeight, bool bCloseDoc)
{
AcApDocument *pDoc = NULL; // 打开的文档的指针
bool bIsOpenAlready = true; // 是否文档已经是打开状态
bool bRetVal = false; // 返回值
// 打开文件,得到对应的ID
if (SetObjIdFromDwg(pDoc, bIsOpenAlready))
{
acDocManager->lockDocument(pDoc); // 锁定文档
OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite , TDbFloorRect, pFloorRect);
if (pFloorRect == NULL)
{
m_csPrompt = _T("无法打开楼层框对象!");
bRetVal = false;
}
else
{
pFloorRect->disableUndoRecording(Adesk::kTrue);
double dHeight = _tstof(csHeight);
pFloorRect->SetFloorHeight(dHeight);// 修改楼层框的层高
pFloorRect->disableUndoRecording(Adesk::kFalse);
bRetVal = true;
}
OPENOBJ_END();
acDocManager->unlockDocument(pDoc);
}
// 如果文档是程序中打开的,则关闭
if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database())
{
if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) &&
Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false))
{
acDocManager->activateDocument(pDoc);
}
}
return bRetVal;
}
// 获取层号
bool TFloorRectItem::GetName(CString &csName, bool bCloseDoc)
{
AcApDocument *pDoc = NULL; // 打开的文档的指针
bool bIsOpenAlready = true; // 是否文档已经是打开状态
bool bRetVal = false; // 返回值
// 打开文件,得到对应的ID
if (SetObjIdFromDwg(pDoc, bIsOpenAlready))
{
acDocManager->lockDocument(pDoc);
OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect);
if (NULL == pFloorRect)
{
m_csPrompt = _T("无法打开楼层框对象");
bRetVal = false;
}
else
{
csName = pFloorRect->GetFloorName(); // 得到相应的楼层名称
bRetVal = true;
}
OPENOBJ_END();
acDocManager->unlockDocument(pDoc);
}
// 如果文档是程序中打开的,则关闭
if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database())
{
if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) &&
Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false))
{
acDocManager->activateDocument(pDoc);
}
}
return bRetVal;
}
// 设置层号
bool TFloorRectItem::SetName(CString csName, bool bCloseDoc)
{
AcApDocument *pDoc = NULL; // 打开的文档的指针
bool bIsOpenAlready = true; // 是否文档已经是打开状态
bool bRetVal = false; // 返回值
// 打开文件,得到对应的ID
if (SetObjIdFromDwg(pDoc, bIsOpenAlready))
{
acDocManager->lockDocument(pDoc); // 锁定文档
OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect);
if (pFloorRect == NULL)
{
m_csPrompt = _T("无法打开楼层框对象!");
bRetVal = false;
}
else
{
pFloorRect->disableUndoRecording(Adesk::kTrue);
pFloorRect->SetFloorName(csName);
pFloorRect->disableUndoRecording(Adesk::kFalse);
bRetVal = true;
}
OPENOBJ_END();
acDocManager->unlockDocument(pDoc);
}
// 如果文档是程序中打开的,则关闭
if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database())
{
if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) &&
Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false))
{
acDocManager->activateDocument(pDoc);
}
}
return bRetVal;
}
// 设置行号
bool TFloorRectItem::SetRowIndex(int nRowIndex, bool bCloseDoc)
{
AcApDocument *pDoc = NULL; // 打开的文档的指针
bool bIsOpenAlready = true; // 是否文档已经是打开状态
bool bRetVal = false; // 返回值
// 打开文件,得到对应的ID
if (SetObjIdFromDwg(pDoc, bIsOpenAlready))
{
acDocManager->lockDocument(pDoc); // 锁定文档
OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect);
if (NULL == pFloorRect)
{
m_csPrompt = _T("无法打开楼层框对象!");
bRetVal = false;
}
else
{
m_nRowIndex = nRowIndex;
pFloorRect->disableUndoRecording(Adesk::kTrue);
pFloorRect->SetTableIndex(nRowIndex); // 把索引号写入楼层框对象
pFloorRect->disableUndoRecording(Adesk::kFalse);
bRetVal = true;
}
OPENOBJ_END();
acDocManager->unlockDocument(pDoc);
}
// 如果文档是程序中打开的,则关闭
if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database())
{
if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) &&
Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false))
{
acDocManager->activateDocument(pDoc);
}
}
return bRetVal;
}
// 设置全部数据
bool TFloorRectItem::SetData(CString csHeight, CString csName, int nRowIndex, bool bCloseDoc)
{
AcApDocument *pDoc = NULL; // 打开的文档的指针
bool bIsOpenAlready = true; // 是否文档已经是打开状态
bool bRetVal = false; // 返回值
// 打开文件,得到对应的ID
if (SetObjIdFromDwg(pDoc, bIsOpenAlready))
{
acDocManager->lockDocument(pDoc); // 锁定文档
OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect);
if (pFloorRect == NULL)
{
m_csPrompt = _T("无法打开楼层框对象!");
bRetVal = false;
}
else
{
m_nRowIndex = nRowIndex;
double dHeight = _tstof(csHeight);
pFloorRect->disableUndoRecording(Adesk::kTrue);
pFloorRect->SetFloorHeight(dHeight);
pFloorRect->SetFloorName(csName);
pFloorRect->SetTableIndex(nRowIndex);
pFloorRect->disableUndoRecording(Adesk::kFalse);
bRetVal = true;
}
OPENOBJ_END();
acDocManager->unlockDocument(pDoc);
}
// 如果文档是程序中打开的,则关闭
if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database())
{
if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) &&
Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false))
{
acDocManager->activateDocument(pDoc);
}
}
return bRetVal;
}
/////////////////////////////////////////////////////////////////////
// 以下函数对层高字符串进行检查
// 检查输入楼层高是否合理,自动去掉前后的空格
bool TFloorRectItem::IsHeightLegal(CString &csHeight)
{
XCheckFloorRectData xCheckData;
bool bRet = xCheckData.IsHeightLegal(csHeight);
m_csPrompt = xCheckData.GetPrompt();
return bRet;
}
// 检查层号是否合法,同时给赋值
bool TFloorRectItem::IsNameLegal(CString &csName)
{
XCheckFloorRectData xCheckData;
if (!xCheckData.IsNameLegal(csName))
{
m_csPrompt = xCheckData.GetPrompt();
return false;
}
xCheckData.GetFloors(m_aryFloors);
return true;
}
// End TFloorRectItem
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// Begin TFloorRectDealSystem
TFloorRectDealSystem::TFloorRectDealSystem(const CString &csName)
{
SetProjectName(csName);
m_csPrompt = _T("");
}
TFloorRectDealSystem::~TFloorRectDealSystem()
{
}
// 工程名称
void TFloorRectDealSystem::SetProjectName(const CString &csName)
{
// 根据工程名称,获取不带扩展名的工程名称
int nRet = csName.Find(_T("."), 0);
if (nRet > -1)
{
m_csProjectName = csName.Left(nRet);
}
else // 不带扩展名的情况
{
m_csProjectName = csName;
}
}
// 获取工程名称
CString TFloorRectDealSystem::GetProjectName() const
{
return m_csProjectName;
}
// 获取提示语
CString TFloorRectDealSystem::GetPrompt() const
{
return m_csPrompt;
}
/////////////////////////////////////////////////////////////////////
// 处理对象变化消息,主要处理复制、删除操作,更新楼层表对象
void TFloorRectDealSystem::ObjectAppended(const AcDbObject* dbObj)
{
// 转化为楼层框对象
TDbFloorRect *pFloorRect = (TDbFloorRect *)dbObj;
if (0 > pFloorRect->GetTableIndex() ||
m_csProjectName.CompareNoCase(pFloorRect->GetSpare()) != 0)
{
return;
}
if (pFloorRect->isWriteEnabled())
{
pFloorRect->disableUndoRecording(Adesk::kTrue);
pFloorRect->SetTableIndex(-1);
pFloorRect->disableUndoRecording(Adesk::kFalse);
}
else if (Acad::eOk == pFloorRect->upgradeOpen())
{
pFloorRect->disableUndoRecording(Adesk::kTrue);
pFloorRect->SetTableIndex(-1);
pFloorRect->disableUndoRecording(Adesk::kFalse);
pFloorRect->downgradeOpen();
}
}
void TFloorRectDealSystem::ObjectModified(const AcDbObject* dbObj)
{
TDbFloorRect *pFloorRect = (TDbFloorRect*) dbObj;
if (0 > pFloorRect->GetTableIndex() ||
m_csProjectName.CompareNoCase(pFloorRect->GetSpare()) != 0)
{
return;
}
XCheckFloorRectData xCheckData;
AcDbIntArray aryFloors; // 楼层框对应的楼层号数组
xCheckData.IsNameLegal(CString(pFloorRect->GetFloorName()));
xCheckData.GetFloors(aryFloors);
if (!CheckFloorNoInProject(aryFloors, pFloorRect->GetTableIndex()))
{
AfxMessageBox(m_csPrompt);
}
TFloorTable *pTable = (TFloorTable*)g_projectBar.FindGroupBox(_T("楼层"));
if (NULL != pTable)
{
// 修改工程中的楼层表格
TADSGePoint3d ptCenter = pFloorRect->GetCenter();
TADSGePoint3d ptMin = pFloorRect->GetLowLeft();
TADSGePoint3d ptMax = pFloorRect->GetUpRight();
pTable->SetGridData(pFloorRect->GetTableIndex(), ptMin, ptMax, pFloorRect->GetBase(),
pFloorRect->GetFloorName(), pFloorRect->GetFloorHeight());
// 修改楼层表组和楼层号数组
CString csDwgName;
GetCurDwgFileName(csDwgName.GetBuffer(_MAX_PATH));
csDwgName.ReleaseBuffer();
csDwgName = g_project.GetDwgFullName(csDwgName);
TFloorRectItem item;
item.m_nRowIndex = pFloorRect->GetTableIndex();
item.m_csDwgFile = csDwgName;
item.m_idObj = pFloorRect->objectId();
item.IsNameLegal(CString(pFloorRect->GetFloorName()));
UpdateItem(item);
}
}
void TFloorRectDealSystem::ObjectErased(const AcDbObject* dbObj)
{
// 转化为楼层框对象
TDbFloorRect *pFloorRect = (TDbFloorRect *)dbObj;
int iRowIndex = pFloorRect->GetTableIndex();
if (m_csProjectName.CompareNoCase(pFloorRect->GetSpare()) != 0 ||
iRowIndex < 0)
{
// 实体不属于当前工程或者是已作废(行号为-1)的楼层框,返回
return;
}
// 删除楼层框时将索引行号置为-1,使楼层框与表格断开绑定关系
if (pFloorRect->isWriteEnabled())
{
pFloorRect->disableUndoRecording(Adesk::kTrue);
pFloorRect->SetTableIndex(-1);
pFloorRect->disableUndoRecording(Adesk::kFalse);
}
else if (Acad::eOk == pFloorRect->upgradeOpen())
{
pFloorRect->disableUndoRecording(Adesk::kTrue);
pFloorRect->SetTableIndex(-1);
pFloorRect->disableUndoRecording(Adesk::kFalse);
pFloorRect->downgradeOpen();
}
// 更新楼层表格
TFloorTable *pTable = (TFloorTable*)g_projectBar.FindGroupBox(_T("楼层"));
if (NULL != pTable)
{
// 更新m_aryFloorTable,删除相应行号的记录
RemoveItem(iRowIndex, false);
// 更新删除行之后的楼层框的索引
int iLen = pTable->m_grid.GetRowNum(),
iIndex = -1;
for (int i = iRowIndex + 1; i < iLen; i++)
{
// 对iRowIndex后的所有楼层框对象的行号进行更新
iIndex = FindItem(i);
if (-1 == iIndex)
{
continue;
}
TPushMemVar<BOOL> pushVar(g_bMonitorDbAction, FALSE);
TFloorRectItem *pItem = &m_aryFloorTable.GetAt(iIndex);
pItem->SetRowIndex(i - 1);
pItem->m_nRowIndex = i - 1;
m_aryFloorTable.SetAt(iIndex, *pItem);
}
if (iLen > iRowIndex)
{ // 删除一行
pTable->m_grid.DelRow(iRowIndex);
pTable->m_grid.Refresh();
}
}
}
void TFloorRectDealSystem::ObjectUnerased(const AcDbObject* dbObj)
{
// 转化为楼层框对象
TDbFloorRect *pFloorRect = (TDbFloorRect *)dbObj;
int iRowIndex = pFloorRect->GetTableIndex();
if (m_csProjectName.CompareNoCase(pFloorRect->GetSpare()) != 0 ||
iRowIndex < 0)
{
// 实体不属于当前工程或者是已作废(行号为-1)的楼层框,返回
return;
}
if (pFloorRect->isWriteEnabled())
{
pFloorRect->disableUndoRecording(Adesk::kTrue);
pFloorRect->SetTableIndex(-1);
pFloorRect->disableUndoRecording(Adesk::kFalse);
return;
}
// 更新楼层表格
TFloorTable *pTable = (TFloorTable*)g_projectBar.FindGroupBox(_T("楼层"));
if (NULL != pTable)
{
// 更新添加一行之后的楼层框的索引
int iLen = pTable->m_grid.GetRowNum();
int iIndex = -1;
for (int i = iLen - 1; i >= iRowIndex; i--)
{
// 对iRowIndex后的所有楼层框对象的行号进行更新
iIndex = FindItem(i);
if (-1 == iIndex)
{
continue;
}
TPushMemVar<BOOL> pushVar(g_bMonitorDbAction, FALSE);
TFloorRectItem item = m_aryFloorTable.GetAt(iIndex);
item.SetRowIndex(i + 1);
item.m_nRowIndex = i + 1;
m_aryFloorTable.SetAt(iIndex, item);
}
// 获取图纸名称
XString szFullName, szName;
xg_getvar(_T("DWGPREFIX"), szFullName); // 存储图形文件的驱动器/目录前缀
xg_getvar(_T("DWGNAME"), szName); // 存储用户输入的图形名
szFullName << szName;
// 根据楼层框的参数生成一个对应的楼层表格数据
TFloorGridData *pGridData = new TFloorGridData();
CString szFileName = g_project.GetDwgRelativeName((const TCHAR*)szFullName);
pGridData->m_szName = szFileName;
// 向表格中添加一条记录
pTable->m_grid.InsertRow(iRowIndex);
if (!pTable->m_grid.IsValidRow(iRowIndex))
{
return;
}
pTable->m_grid.GetRow(iRowIndex).SetExtendData((WRowData*) pGridData);
TADSGePoint3d ptCenter = pFloorRect->GetCenter(),
ptMin = pFloorRect->GetLowLeft(),
ptMax = pFloorRect->GetUpRight();
pTable->SetGridData(iRowIndex, ptMin, ptMax, pFloorRect->GetBase(),
pFloorRect->GetFloorName(), pFloorRect->GetFloorHeight());
// 添加一条对应的TFloorRectItem信息
CString csDwgName;
GetCurDwgFileName(csDwgName.GetBuffer(_MAX_PATH));
csDwgName.ReleaseBuffer();
csDwgName = g_project.GetDwgFullName(csDwgName);
TFloorRectItem item;
item.m_nRowIndex = iRowIndex;
item.m_csDwgFile = csDwgName;
item.m_idObj = pFloorRect->objectId();
item.IsNameLegal(CString(pFloorRect->GetFloorName()));
// 添加一条信息,修改楼层框时不响应消息
AddItem(item, false);
}
}
/////////////////////////////////////////////////////////////////////
// 表格数据和楼层框对象的数据交换,主要处理更新操作
// 根据楼层框对象更新工程数据,如果图纸已经打开,就不再进行楼层框ID的搜索以提高效率
bool TFloorRectDealSystem::UpdatePrjFloorFromObj(TProjectFloor *&pFloor, TFloorRectItem &item, bool IsDWGOpen, bool bCloseDoc)
{
if (NULL == pFloor)
{
return false;
}
AcApDocument *pDoc = NULL; // 打开的文档的指针
bool bIsOpenAlready = true; // 是否文档已经是打开状态
if (!IsDWGOpen)
{
if (!item.SetObjIdFromDwg(pDoc, bIsOpenAlready))
{
// 如果文档是程序中打开的,则关闭
if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database())
{
if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) &&
Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false))
{
acDocManager->activateDocument(pDoc);
}
}
m_csPrompt = item.GetPrompt();
return false;
}
}
else
{
AcApDocumentIterator *pDocIter = acDocManager->newAcApDocumentIterator();
for (; !pDocIter->done(); pDocIter->step())
{
// 搜索对应的文档指针
if (0 == item.m_csDwgFile.CompareNoCase(pDocIter->document()->fileName()))
{
pDoc = pDocIter->document();
break;
}
}
delete pDocIter;
}
if (NULL == pDoc)
{
return false;
}
acDocManager->lockDocument(pDoc); // 锁定文档
// 打开楼层框实体,把相关参数写入pFloor
OPENOBJ_BEGIN(item.m_idObj, AcDb::kForRead, TDbFloorRect, pFloorRect);
if (pFloorRect == NULL)
{
m_csPrompt = _T("无法打开楼层框对象");
acDocManager->unlockDocument(pDoc);
return false;
}
pFloor->SetBasePoint(pFloorRect->GetBase());
pFloor->SetRange(pFloorRect->GetLowLeft(), pFloorRect->GetUpRight());
pFloor->SetLayerNo(pFloorRect->GetFloorName());
pFloor->SetHeight(pFloorRect->GetFloorHeight());
OPENOBJ_END();
acDocManager->unlockDocument(pDoc);
// 如果文档是程序中打开的,则关闭
if (bCloseDoc && NULL != pDoc && NULL != pDoc->database())
{
if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) &&
Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false))
{
acDocManager->activateDocument(pDoc);
}
}
return true;
}
// 根据表行数据更新楼层框对象
bool TFloorRectDealSystem::UpdateObjFromRow(short nRow)
{
TFloorRectItem *pFind = NULL;
if (!GetItem(nRow, *pFind)) // 未找到
{
return false;
}
// 找到楼层框,更新数据
TFloorTable *pTable = (TFloorTable*)g_projectBar.FindGroupBox(_T("楼层"));
if (NULL == pTable)
{
m_csPrompt = _T("获取楼层表数据失败! ");
return false;
}
// 获取层高
CString csHeight = pTable->m_grid.GetCell(nRow, 1).GetText();
// 设置层高,首先会检查用户输入是否合理
bool bRet = pFind->IsHeightLegal(csHeight);
if (!bRet)
{
m_csPrompt = pFind->GetPrompt();
return false;
}
// 获取层号
CString csNum = pTable->m_grid.GetCell(nRow, 0).GetText();
// 首先,对单楼层号字符串进行分析,判断输入是否正确,修改行号
bRet = pFind->IsNameLegal(csNum);
if (!bRet)
{
m_csPrompt = pFind->GetPrompt();
return false;
}
// 然后,在全工程中进一步查找,是否存在重复楼层号
AcDbIntArray aryFloors; // 楼层框对应的楼层号数组
pFind->GetFloors(aryFloors);
bRet = CheckFloorNoInProject(aryFloors, nRow);
if (!bRet)
{
return false;
}
pFind->SetData(csNum, csHeight, nRow);
return true;
}
// 更新处理系统
void TFloorRectDealSystem::UpdateDealSystem()
{
// 首先,清空原数据
int i(0),
nLength = (int)m_aryFloorTable.GetSize();
for (i=0; i<nLength; i++)
{
m_aryFloorTable.RemoveAt(0);
}
// 获取楼层表数据
TProjectGroupItem *pTable = GetFloorTable();
if (pTable == NULL)
{
return;
}
i = 0; // 行号
bool bPrompt = false; // 是否提示
CString csPrompt = _T("请检查楼层表中第"); // 提示信息
// 然后,循环赋新值
for (pTable->MoveToFirst();!pTable->IsOut();pTable->MoveToNext())
{
TProjectFloor *pFloor = (TProjectFloor*)pTable->GetCurData();
if (pFloor == NULL)
{
i++;
continue;
}
// 添加新对象
TFloorRectItem item;
item.m_nRowIndex = i;
// 获取图纸名称
CString csDwgName = g_project.GetDwgFullName(pFloor->GetName());
item.m_csDwgFile = csDwgName;
// 从工程中获取层号
CString csFloorNo = pFloor->GetLayerNo();
// 图纸名不为空,但不能找到图纸文件
// 或者在存在表格和楼层框对应关系时,不能在图纸中找到楼层框对象,准备给出提示
if ((!csDwgName.IsEmpty() && !FindFile(csDwgName)) ||
(pFloor->IsFloorInFrame() && !item.GetName(csFloorNo, false)))
{
csPrompt.Format(csPrompt + _T("%d、"), i + 1);
bPrompt = true;
}
// 判断单层输入是否合法,并给数组赋值
if (!item.IsNameLegal(csFloorNo))
{
adsout << _T("\n") << (LPCTSTR)item.GetPrompt();
}
m_aryFloorTable.Add(item);
// 对“<框选>”过的标准层,根据新打开的图纸里的楼层框对象信息,更新tpr文件内容
if (pFloor->IsFloorInFrame())
{
if (UpdatePrjFloorFromObj(pFloor, item, true, false))
{
pTable->SetCurData(pFloor);
}
}
i++;
}
// 判断是否提示不存在的图纸或楼层框
if (bPrompt)
{
csPrompt.TrimRight(_T("、"));
csPrompt += _T("行数据,无法找到指定图纸或框选的楼层范围。");
adsout << _T("\n") << (LPCTSTR)(csPrompt);
}
// 检查整个工程中的重复楼层号
if (!CheckAllFloors())
{
adsout << _T("\n") << (LPCTSTR)m_csPrompt;
}
}
/////////////////////////////////////////////////////////////////////
// 操作楼层表数组的函数
// 在数组中,查找指定数据的下标,未找到时返回-1
int TFloorRectDealSystem::FindItem(short nRow) const
{
int nIndex = -1;
int nLength = (int)m_aryFloorTable.GetSize();
for (int i=0; i<nLength; i++)
{
const TFloorRectItem *pTemp = &m_aryFloorTable.GetAt(i);
if (pTemp->m_nRowIndex == nRow)
{
nIndex = i;
break;
}
}
return nIndex;
}
// 获取一条楼层框数据,未找到时返回false
bool TFloorRectDealSystem::GetItem(short nRow, TFloorRectItem &item)
{
int nIndex = FindItem(nRow);
if (-1 == nIndex) // 没有找到
{
return false;
}
item = m_aryFloorTable.GetAt(nIndex);
return true;
}
// 添加一条楼层框数据
bool TFloorRectDealSystem::AddItem(TFloorRectItem &item, bool bReplace, bool bNotify)
{
int nIndex = FindItem(item.m_nRowIndex);
if (-1 != nIndex)
{
if (bReplace)
{
TPushMemVar<BOOL> pushVar(g_bMonitorDbAction, bNotify);
TFloorRectItem itemTemp = m_aryFloorTable.GetAt(nIndex);
itemTemp.m_idObj = item.m_idObj; // 保证优先找到一个与itemTemp.m_idObj不同的楼层框
if (!itemTemp.SetRowIndex(-1))
{
m_csPrompt = itemTemp.GetPrompt();
}
}
m_aryFloorTable.RemoveAt(nIndex);
}
// 添加数据
m_aryFloorTable.Add(item);
return true;
}
// 根据item里的行号,更新一条楼层框数据
bool TFloorRectDealSystem::UpdateItem(TFloorRectItem &item)
{
int nIndex = FindItem(item.m_nRowIndex);
if (-1 == nIndex) // 未找到则返回
{
return false;
}
// 添加数据
m_aryFloorTable.SetAt(nIndex, item);
return true;
}
// 根据nRow,替换一条楼层框数据
void TFloorRectDealSystem::ReplaceItem(short nRow, TFloorRectItem &item)
{
int nIndex = FindItem(nRow);
if (-1 != nIndex)
{
m_aryFloorTable.RemoveAt(nIndex);
}
m_aryFloorTable.Add(item);
}
// 根据行号删除一条记录
bool TFloorRectDealSystem::RemoveItem(short nRow, bool bDelEnt, bool bNotify, bool bCloseDoc)
{
int nIndex = FindItem(nRow);
if (-1 == nIndex)
{
return false;
}
TFloorRectItem item;
item = m_aryFloorTable.GetAt(nIndex);
if (bDelEnt)
{
AcApDocument *pDoc = NULL; // 打开的文档的指针
bool bIsOpenAlready = true; // 是否文档已经是打开状态
// 打开文件,得到对应的ID
if (item.SetObjIdFromDwg(pDoc, bIsOpenAlready))
{
TPushMemVar<BOOL> pushVar(g_bMonitorDbAction, bNotify);
acDocManager->lockDocument(pDoc);
OPENOBJ_BEGIN(item.m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect);
if (pFloorRect != NULL)
{
pFloorRect->disableUndoRecording(Adesk::kTrue);
pFloorRect->SetTableIndex(-1);
pFloorRect->disableUndoRecording(Adesk::kFalse);
pFloorRect->erase();
}
OPENOBJ_END();
acDocManager->unlockDocument(pDoc);
}
// 如果文档是程序中打开的,则关闭
if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database())
{
if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) &&
Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false))
{
acDocManager->activateDocument(pDoc);
}
}
}
m_aryFloorTable.RemoveAt(nIndex);
return true;
}
/////////////////////////////////////////////////////////////////////
// 在整个工程里,检查是否存在重复楼层号
bool TFloorRectDealSystem::CheckFloorNoInProject(const AcDbIntArray &aryFloors, short nIgnoreRow)
{
// 获取要忽略的楼层框的楼层号
AcDbIntArray aryFloorsIgnore;
int nIndex = FindItem(nIgnoreRow);
if (-1 != nIndex)
{
m_aryFloorTable.GetAt(nIndex).GetFloors(aryFloorsIgnore);
}
AcDbIntArray aryFloorsTotal;
if (!GetFloors(aryFloorsTotal)) // 工程内无楼层数据时,返回true
{
return true;
}
int nLength = aryFloors.logicalLength();
for (int i=0; i<nLength; i++)
{
int nNum = aryFloors[i];
// 在工程中已有楼层号中进行查找,是否存在此楼层号
int nIndex = 0;
if (aryFloorsTotal.find(nNum, nIndex, 0) && !aryFloorsIgnore.find(nNum, nIndex, 0))
{
m_csPrompt = _T("警告: 当前工程中存在重复的楼层号!");
return false;
}
}
return true;
}
// 在整个工程里,检查是否存在重复楼层号
bool TFloorRectDealSystem::CheckAllFloors()
{
m_csPrompt = _T("");
int nRowCount = (int)m_aryFloorTable.GetSize();
if (0 == nRowCount)
{
return true;
}
AcDbIntArray aryTemp, aryFloors;
m_aryFloorTable.GetAt(0).GetFloors(aryFloors); // 获取第1条数组
int nFloorsCount = 0,
nTmpIndex = 0;
for (int i = 1; i < nRowCount; i++)
{
m_aryFloorTable.GetAt(i).GetFloors(aryTemp);
nFloorsCount = aryTemp.length();
for (int j = 0; j < nFloorsCount; j++)
{
if (aryFloors.find(aryTemp.at(j), nTmpIndex))
{
m_csPrompt = _T("警告: 当前工程中存在重复的楼层号!");
return false;
}
}
aryFloors.append(aryTemp);
}
return true;
}
// 获取整个工程中的楼层号数组
bool TFloorRectDealSystem::GetFloors(AcDbIntArray &aryFloors) const
{
int nLen = (int)m_aryFloorTable.GetSize();
if (0 == nLen)
{
return false;
}
AcDbIntArray aryTemp;
for (int i = 0; i < nLen; i++)
{
m_aryFloorTable.GetAt(i).GetFloors(aryTemp);
aryFloors.append(aryTemp);
}
nLen = aryFloors.length();
return (nLen != 0);
}
// 获得全工程里的最大的楼层号,工程内无楼层时,返回0;
int TFloorRectDealSystem::GetMaxFloorNo()
{
AcDbIntArray aryFloors;
if (!GetFloors(aryFloors)) // 工程内无楼层数据时,返回0
{
return 0;
}
int nLen = aryFloors.length(),
nMax = aryFloors.at(0);
for (int i = 1; i < nLen; i++)
{
nMax = max(nMax, aryFloors.at(i));
}
return nMax;
}
// 获得下一个默认楼层号(在最大楼层号基础上加1,并且已屏蔽掉0层)
int TFloorRectDealSystem::GetNextFloorNo()
{
int iMax = GetMaxFloorNo();
if (-1 == iMax)
{
return 1;
}
return ++iMax;
}
// End TFloorRectDocData
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 全局函数
// 初始化楼层框反映器
void InitFloorRectReactor(bool bTrue)
{
if (bTrue)
{
if (g_pFloorRectDocReactor == NULL)
{
g_pFloorRectDocReactor = new TFloorRectDocReactor();
acDocManagerPtr()->addReactor(g_pFloorRectDocReactor);
}
}
else
{
if (g_pFloorRectDocReactor != NULL)
{
acDocManagerPtr()->removeReactor(g_pFloorRectDocReactor);
delete g_pFloorRectDocReactor;
g_pFloorRectDocReactor = NULL;
}
}
}
// 初始化楼层表处理系统
void InitFloorRectDealSystem(bool bTrue)
{
if (bTrue)
{
// 获取工程名称
CString csProjectName;
g_project.GetProjectName(csProjectName);
if (g_pFloorRectData == NULL) // 首次启动软件
{
g_pFloorRectData = new TFloorRectDealSystem(csProjectName);
}
else // 切换工程
{
g_pFloorRectData->SetProjectName(csProjectName);
}
g_pFloorRectData->UpdateDealSystem();
}
else // 退出软件时,清理数据
{
if (g_pFloorRectData != NULL)
{
delete g_pFloorRectData;
g_pFloorRectData = NULL;
}
}
}