Files
envi-code/SourceCode/Code2026/tg_shs/shs_utility/Project.cpp
T
2026-09-28 15:28:50 +08:00

850 lines
19 KiB
C++

#include "stdafx.h"
#include "acdocman.h"
TUTIL_IMPEXP TProject g_project;
///////////////////////////////////////////////////////////
// 取得楼层数据库的DBF文件名称
TUTIL_IMPEXP int GetProjectDbf(XString &m_sDbfFile)
{
XString sDwgPrefix, sDwgPrefix1;
xg_getvar(_T("DWGPREFIX"), sDwgPrefix);
XString sTemp(256);
sTemp << sDwgPrefix << _T("building.dbf");
m_sDbfFile = sTemp;
if (!FindFile(m_sDbfFile))
{
FieldInfo fields[4];
fields[0] = FieldInfo(_T("floor"), _T('C'), 64);
fields[1] = FieldInfo(_T("dwgfile"), _T('C'), 64);
fields[2] = FieldInfo(_T("height"), _T('N'), 10);
CodeBase db;
XDbfTable *pTable = db.Create(m_sDbfFile, fields, 4);
if (pTable != NULL)
{
adsout << _T("\n不能创建") << sTemp;
return RTERROR;
}
}
return RTNORM;
}
///////////////////////////////////////////////////////////
// 把形如“1,2~6,9”的串离散为1,2,3,4,5,6,9
// Status:没有仔细分析字符的合法性
TUTIL_IMPEXP BOOL StrToIntList(const TCHAR* pszDesc, DList<int> &lstResult)
{
int i = 1;
TCHAR szWord[256] = _T("");
while(CT_strnth(pszDesc, i, szWord))
{
TCHAR *pSep = _tcschr(szWord, _T('~'));
if (pSep==NULL && *szWord!=_T('-'))
pSep = _tcschr(szWord, _T('-'));
if (pSep)
{
int nTo = _ttoi(pSep + 1);
*pSep = EOS;
int nFrom = _ttoi(szWord);
if (nFrom >= nTo)
return FALSE;
for (int n=nFrom; n<=nTo; n++)
{
for (int j=0; j<lstResult.Length(); j++)
{
if (*lstResult[j] == n) // Already exist
return FALSE;
}
lstResult.Append(new int(n));
}
}
else
{
int n = _ttoi(szWord);
for (int j=0; j<lstResult.Length(); j++)
{
if (*lstResult[j] == n) // Already exist
return FALSE;
}
lstResult.Append(new int(n));
}
i++;
}
return lstResult.Length()>0;
}
///////////////////////////////////////////////////////////
TUTIL_IMPEXP int GetFloorData(const TCHAR *sDwgPrefix, XDbfTable &grp, DList<XFloorData> &lstFloors)
{
for (grp.MoveFirst(); !grp.IsEOF(); grp.MoveNext())
{
int nHeight;
CString sDwg, sFloor;
GET_FIELD((&grp), _T("floor"), sFloor);
GET_FIELD((&grp), _T("dwgfile"), sDwg);
GET_FIELD((&grp), _T("height"), nHeight);
if (!sFloor || !sDwg)
{
adsout << /*UMSG*/_T("\n项目数据库有错!");
return RTERROR;
}
XString sFullDwgName(256);
sFullDwgName << sDwgPrefix << sDwg;
// if (dlg.m_bUseExpl3d) sFullDwgName << _T("_3D");
sFullDwgName << _T(".DWG");
if (!FindFile(sFullDwgName))
{
adsout << /*UMSG*/_T("\n标准层模型'") << sFullDwgName << _T("'不存在!");
return RTERROR;
}
DList<int> lstIndexes;
if (!StrToIntList(sFloor, lstIndexes))
{
adsout << /*UMSG*/_T("\n楼层的描述有错!");
return RTERROR;
}
for (int i=0; i<lstIndexes.Length(); i++)
{
int nIdx = *lstIndexes[i];
if (lstFloors.FindNode(&nIdx, XFloorData::CompareForFind))
{
adsout << /*UMSG*/_T("\n有重复楼层号出现!");
return RTERROR;
}
lstFloors.Append(new XFloorData(nIdx, sFullDwgName, nHeight));
}
}
return RTNORM;
}
///////////////////////////////////////////////////////////
TUTIL_IMPEXP int GetFloorData(XDbfTable &grp, DList<XFloorData> &lstFloors)
{
XString sDwgPrefix;
xg_getvar(_T("DWGPREFIX"), sDwgPrefix);
return GetFloorData(sDwgPrefix, grp, lstFloors);
}
///////////////////////////////////////////////////////////
TUTIL_IMPEXP int CheckFloorData(DList<XFloorData> &lstFloors)
{
if (!lstFloors)
return RTERROR;
lstFloors.QuickSort(XFloorData::CompareForSort);
int nFirst = lstFloors[0]->m_nIndex;
for (int i=0; i<lstFloors.Length(); i++)
{
int nFloorNum = nFirst+i;
if (nFirst<0 && nFloorNum>=0) // 有地下室时没有0层
nFloorNum++;
if (lstFloors[i]->m_nIndex != nFloorNum)
{
adsout << /*UMSG*/_T("\n缺少第") << nFloorNum << _T("层数据!");
return RTERROR;
}
}
return RTNORM;
}
///////////////////////////////////////////////////////////
bool HasFloorInFrame(const DList<XFloorData>&floors)
{
for (long i=0;i<floors.Length();i++)
{
if (floors[i].m_bFloorInFrame)
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int XFloorData::CompareForSort(const XFloorData *p1, const XFloorData *p2)
{
if (p1->m_nIndex > p2->m_nIndex)
return 1;
if (p1->m_nIndex < p2->m_nIndex)
return -1;
return 0;
}
int XFloorData::CompareForFind(const XFloorData *p1, const void *p2)
{
int idx2 = *(const int *)p2;
if (p1->m_nIndex > idx2)
return 1;
if (p1->m_nIndex < idx2)
return -1;
return 0;
}
bool XFloorData::IsSameData(const XFloorData&f)const
{
if (f.m_sDwgFile==m_sDwgFile && f.m_bFloorInFrame && m_bFloorInFrame)
{
if (m_bFloorInFrame)
return f.m_ptMin==m_ptMin && f.m_ptMax==m_ptMax;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CArchive& TProjectItem::operator >>(CArchive&ar)const // ok
{
return ar<<GetType()<<m_sName; // 保存类型和名称
}
CArchive& TProjectItem::operator <<(CArchive&ar) // ok
{
return ar>>m_sName; // 只读名称,类型提前读
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TProjectItemEx::SetData(char *pData,int size) // ok
{
m_iByteSize = size;
if (m_pBuf != NULL)
{
delete[] m_pBuf;
m_pBuf = NULL;
}
m_pBuf = pData;
}
CArchive& TProjectItemEx::operator >>(CArchive&ar)const // ok
{
TProjectItem::operator >>(ar);
ar<<GetLength();
for (int i=0;i<GetLength();i++)
{
ar<<(*this)[i];
}
return ar;
}
CArchive& TProjectItemEx::operator <<(CArchive&ar) // ok
{
TProjectItem::operator <<(ar);
if (m_pBuf != NULL)
delete[] m_pBuf;
if (GetLength() > 0)
m_pBuf = new char[GetLength()];
else
m_pBuf = NULL;
ar>>m_iByteSize;
for (int i=0; i<GetLength(); i++)
{
ar>>(*this)[i];
}
return ar;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CArchive& TProjectGroupItem::operator >>(CArchive&ar)const // ok
{
TProjectItem::operator>>(ar);
ar<<GetLength();
for (long i=0;i<GetLength();i++)
GetPData(i)>>ar;
return ar;
}
CArchive& TProjectGroupItem::operator <<(CArchive&ar) // ok
{
Clear();
TProjectItem::operator<<(ar);
long num;
ar>>num;
for (long i=0;i<num;i++)
{
int type;
ar>>type;
TProjectItem*pItem = NULL;
switch(type)
{
case TYPE_PJ_ITEM:
pItem = new TProjectItem;
break;
case TYPE_PJ_GROUP:
pItem = new TProjectGroupItem;
break;
case TYPE_PJ_FLOOR:
pItem = new TProjectFloor;
break;
case TYPE_PJ_FILE:
pItem = new TProjectFile;
break;
case TYPE_PROJECT:
pItem = new TProject;
break;
case TYPE_PJ_ITEM_EX:
pItem = new TProjectItemEx;
break;
default:
throw type;
}
*pItem<<ar;
AddTail(pItem);
}
return ar;
}
// flag==0:全部查找,flag==1:只找节点,flag==2:只找目录
TProjectItem* TProjectGroupItem::FindItem(CString sName,bool bFindSubGroup,int flag) // ok
{
for (MoveToFirst();!IsOut();MoveToNext())
{
if (flag == 0)
{
if (GetCurData()->GetName() == sName)
return GetCurData();
else if (bFindSubGroup && GetCurData()->IsGroup())
{
TProjectGroupItem* pGroup = (TProjectGroupItem*)GetCurData();
TProjectItem* pItem = pGroup->FindItem(sName, bFindSubGroup, flag);
if (pItem != NULL)
return pItem;
}
}
else if (flag == 1)
{
if (!GetCurData()->IsGroup() && GetCurData()->GetName() == sName)
return GetCurData();
else if (bFindSubGroup && GetCurData()->IsGroup())
{
TProjectGroupItem* pGroup = (TProjectGroupItem*)GetCurData();
TProjectItem* pItem = pGroup->FindItem(sName, bFindSubGroup, flag);
if (pItem != NULL)
return pItem;
}
}
else
{
if (GetCurData()->IsGroup() && GetCurData()->GetName() == sName)
return GetCurData();
else if (bFindSubGroup && GetCurData()->IsGroup())
{
TProjectGroupItem* pGroup = (TProjectGroupItem*)GetCurData();
TProjectItem* pItem = pGroup->FindItem(sName, bFindSubGroup, flag);
if (pItem != NULL)
return pItem;
}
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int TProjectFile::s_iVersion = 0;
CArchive& TProjectFile::operator >>(CArchive&ar)const // ok
{
TProjectItem::operator >>(ar);
return ar<<s_iVersion;
}
CArchive& TProjectFile::operator <<(CArchive&ar) // ok
{
TProjectItem::operator <<(ar);
int ver;
ar>>ver;
if (ver>s_iVersion)
throw 0;
return ar;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int TProjectFloor::s_iVersion = 0;
CArchive& TProjectFloor::operator>>(CArchive&ar)const // ok
{
TProjectItem::operator>>(ar);
ar<<s_iVersion;
return ar<<m_sLayerNo<<m_fHeight<<m_iFlag
<<m_ptBase.x<<m_ptBase.y<<m_ptMin.x<<m_ptMin.y<<m_ptMax.x<<m_ptMax.y;
}
CArchive& TProjectFloor::operator<<(CArchive&ar) // ok
{
TProjectItem::operator<<(ar);
int ver;
ar>>ver;
if (ver>s_iVersion)
throw 0;
return ar>>m_sLayerNo>>m_fHeight>>m_iFlag>>
m_ptBase.x>>m_ptBase.y>>m_ptMin.x>>m_ptMin.y>>m_ptMax.x>>m_ptMax.y;
}
bool TProjectFloor::IsInclude(XPoint pt)const // ok
{
if (IsFloorInFrame())
{
if (pt.x<m_ptMin.x-1E-6)
return false;
if (pt.y<m_ptMin.y-1E-6)
return false;
if (pt.x>m_ptMax.x+1E-6)
return false;
if (pt.y>m_ptMax.y+1E-6)
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int TProject::s_iVersion = 0;
CArchive& TProject::operator>>(CArchive&ar)const
{
TProjectGroupItem::operator>>(ar);
ar<<s_iVersion;
return ar;
}
CArchive& TProject::operator<<(CArchive&ar)
{
TProjectGroupItem::operator<<(ar);
int ver;
ar>>ver;
if (ver>s_iVersion)
throw 0;
return ar;
}
TProject::~TProject() // ok
{
m_pTGExportWnd = m_pTGProjectBarWnd = NULL;
}
CString TProject::GetDwgFullName(CString szName)const
{
if (szName == _T(""))
return _T("");
if (szName.Find(_T(":")) != 1)
{
CString szPath;
GetFilePath(szPath);
szName = szPath + szName + _T(".dwg");
}
else
szName += _T(".dwg");
return szName;
}
CString TProject::GetDwgRelativeName(CString szFullName)const
{
if (szFullName == _T(""))
return szFullName;
CString szPath;
GetFilePath(szPath);
CString szTemp = szFullName;
szTemp.MakeLower();
szPath.MakeLower();
if (szTemp.Find(szPath) == 0)
szFullName = szFullName.Right(szFullName.GetLength() - szPath.GetLength());
szFullName = szFullName.Left(szFullName.GetLength()-4);
return szFullName;
}
void TProject::New(CString sFile,int flag) // ok
{
if (m_sFileFullName != _T(""))
Save();
Clear();
//...重设数据
m_sFileFullName = sFile;
if ((flag&HIDE_DWGSET) == 0) // 有图纸集
AddTail(new TProjectGroupItem(_T("图纸")));
if ((flag&HIDE_FLOOR) == 0) // 有楼层表
AddTail(new TProjectGroupItem(_T("楼层")));
}
extern BOOL g_bDisableEcho=FALSE;//是否提示
bool TProject::Load(CString sFile) // ok
{
if (m_sFileFullName != _T(""))
Save();
CFile file;
if (!file.Open(sFile,CFile::modeRead))
{
if (!g_bDisableEcho)
{
CString sDesc;
sDesc.Format(_T("无法打开工程文件:%s!"),sFile);
AfxMessageBox(sDesc);
}
return false;
}
m_sFileFullName = _T("");
CArchive ar(&file,CArchive::load);
try
{
int type;
ar>>type;
*this<<ar;
}
catch(...)
{
if (!g_bDisableEcho)
{
CString sDesc;
sDesc.Format(_T("读取工程文件:%s错误!\n你可能需要安装高版本上华软件,或文件已经损坏!"),sFile);
AfxMessageBox(sDesc);
}
return false;
}
m_sFileFullName = sFile;
return true;
}
bool TProject::Save()const // ok
{
CFile file;
if (!file.Open(m_sFileFullName,CFile::modeWrite|CFile::modeCreate))
{
CString sDesc;
sDesc.Format(_T("无法保存工程文件:%s!"),m_sFileFullName);
AfxMessageBox(sDesc);
return false;
}
file.SetLength(0);
file.Flush();
CArchive ar(&file,CArchive::store);
try
{
*this>>ar;
}
catch(...)
{
CString sDesc;
sDesc.Format(_T("保存工程文件:%s失败!"),m_sFileFullName);
AfxMessageBox(sDesc);
return false;
}
return true;
}
int TProject::GetFloorData(DList<XFloorData> &lstFloors)
{
TProjectGroupItem*pFloorTable = GetGroup(_T("楼层"));
if (pFloorTable == NULL)
return RTERROR;
for (pFloorTable->MoveToFirst(); !pFloorTable->IsOut();pFloorTable->MoveToNext())
{
TProjectFloor *pFloor = (TProjectFloor*)pFloorTable->GetCurData();
CString sFullDwgName = GetDwgFullName(pFloor->GetName());
if (!FindFile(sFullDwgName))
{
adsout<< _T("\n标准层模型") << (const TCHAR*)sFullDwgName << _T("不存在!");
return RTERROR;
}
DList<int> lstIndex;
if (!pFloor->GetLayerIndexList(lstIndex))
{
adsout<<_T("\n楼层号输入有误!");
return RTERROR;
}
for (int i=0; i<lstIndex.Length(); i++)
{
if (lstFloors.FindNode(lstIndex[i], XFloorData::CompareForFind))
{
adsout << _T("\n有重复楼层号出现!");
return RTERROR;
}
XFloorData*pXFloor = new XFloorData(*lstIndex[i], sFullDwgName,(int)pFloor->GetHeight());
pXFloor->m_bFloorInFrame = pFloor->IsFloorInFrame();
pXFloor->m_ptBase = pFloor->GetBasePoint();
pFloor->GetRange(pXFloor->m_ptMin, pXFloor->m_ptMax);
lstFloors.Append(pXFloor);
}
}
return RTNORM;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
Adesk::Boolean acedPostCommand(const TCHAR * );
bool WritePrjToDwg(const TCHAR* sPrjFile,const TCHAR *sFile)
{
AcApDocumentIterator*pIter = acDocManager->newAcApDocumentIterator();
if (pIter != NULL)
{
AcApDocument *pOldDoc = curDoc();
for (; !pIter->done(); pIter->step())
{
AcApDocument*pDoc = pIter->document();
if (pDoc->isReadOnly())
continue;
if (_tcsicmp(pDoc->fileName(), sFile) == 0)
{
acDocManager->activateDocument(pDoc);
acDocManager->lockDocument(curDoc(), AcAp::kWrite, NULL, NULL, true);
DocSetProjectFile(sPrjFile);
acDocManager->unlockDocument(curDoc());
acedPostCommand(_T("QSAVE\n"));
acDocManager->activateDocument(pOldDoc);
delete pIter;
return true;
}
}
delete pIter;
}
AcDbDatabase db(false, true);
#if ADS < 21
if (db.readDwgFile(sFile, _SH_DENYNO, false) != Acad::eOk)
#else
if (db.readDwgFile(sFile, AcDbDatabase::kForReadAndAllShare, false) != Acad::eOk)
#endif
return false;
TDbConfig *pCfg = GetDwgGlobal(AcDb::kForWrite, &db);
if (pCfg != NULL)
{
pCfg->SetProjectFile(sPrjFile);
pCfg->close();
acDocManager->lockDocument(curDoc(), AcAp::kWrite, NULL, NULL, true);
bool bRet = db.saveAs(sFile) == Acad::eOk;
acDocManager->unlockDocument(curDoc());
return bRet;
}
return false;
}
///////////////////////////////////////////////////////////
// 打开工程文件,不存在则尝试新建
bool OpenProjectDwg(CString szFullName)
{
static bool bIn = false;
if (bIn)
return false;
bIn = true;
if (szFullName == _T(""))
{
bIn = false;
return false;
}
// 如已经打开则只需切换当前文档
AcApDocumentIterator *pIter = acDocManager->newAcApDocumentIterator();
if (pIter != NULL)
{
for (; !pIter->done(); pIter->step())
{
AcApDocument*pDoc = pIter->document();
if (_tcsicmp(pDoc->fileName(), szFullName) == 0)
{
if (curDoc() != pDoc)
acDocManager->activateDocument(pDoc);
bIn = false;
return true;
}
}
delete pIter;
}
//需要打开或新建
Acad::ErrorStatus es = acDocManager->appContextOpenDocument(szFullName);
if (es == Acad::eOk)
{
bIn = false;
return true;
}
else if (!FindFile(szFullName))
{
// 文件不存在尝试新建文件
XString sDwt;
if (FindFile(_T("acad.dwt"),sDwt))
{
if (acDocManager->appContextNewDocument(sDwt) == Acad::eOk)
{
acDocManager->lockDocument(curDoc(), AcAp::kWrite, NULL, NULL, true);
if (acdbCurDwg()->saveAs(szFullName) == Acad::eOk &&
DocSetProjectFile(g_project.GetFileFullName()))
{
acDocManager->unlockDocument(curDoc());
bIn = false;
return true;//成功新建
}
acDocManager->unlockDocument(curDoc());
}
else
AfxMessageBox(XString(_T("新建文件:%s!失败!"), szFullName));
}
else
AfxMessageBox(XString(_T("新建文件:%s失败!未找到:acad.dwt模板文件"), szFullName));
}
else
AfxMessageBox(XString(_T("无法打开:%s!可能是高版本文件"), szFullName));
bIn = false;
return false;
}
///////////////////////////////////////////////////////////
bool GetFloorFiles(XStringList &lstFiles)
{
DualList<CString> sFiles;
TProjectGroupItem* pFloorTable = GetFloorTable();
if (pFloorTable == NULL)
return false;
for (pFloorTable->MoveToFirst(); !pFloorTable->IsOut(); pFloorTable->MoveToNext())
sFiles.FindOrAddTail(g_project.GetDwgFullName(pFloorTable->GetCurData()->GetName()));
for (sFiles.MoveToFirst(); !sFiles.IsOut(); sFiles.MoveToNext())
lstFiles.Append(tstrnew(sFiles.GetCurData()));
return true;
}
///////////////////////////////////////////////////////////
int GetFloorData(DList<XFloorData> &lstFloors)
{
TProjectGroupItem *pFloorTable = GetFloorTable();
if (pFloorTable == NULL)
return RTERROR;
for (pFloorTable->MoveToFirst(); !pFloorTable->IsOut();pFloorTable->MoveToNext())
{
TProjectFloor *pFloor = (TProjectFloor*)pFloorTable->GetCurData();
CString sFullDwgName = g_project.GetDwgFullName(pFloor->GetName());
if (!FindFile(sFullDwgName))
{
adsout<< _T("\n标准层模型") << (const TCHAR*)sFullDwgName << _T("不存在!");
return RTERROR;
}
DList<int> lstIndex;
if (!pFloor->GetLayerIndexList(lstIndex))
{
adsout<<_T("\n楼层号输入有误!");
return RTERROR;
}
for (int i=0; i<lstIndex.Length(); i++)
{
if (lstFloors.FindNode(lstIndex[i], XFloorData::CompareForFind))
{
adsout << _T("\n有重复楼层号出现!");
return RTERROR;
}
XFloorData *pXFloor = new XFloorData(*lstIndex[i], sFullDwgName,(int)pFloor->GetHeight());
pXFloor->m_bFloorInFrame = pFloor->IsFloorInFrame();
pXFloor->m_ptBase = pFloor->GetBasePoint();
pFloor->GetRange(pXFloor->m_ptMin, pXFloor->m_ptMax);
lstFloors.Append(pXFloor);
}
}
return RTNORM;
}
///////////////////////////////////////////////////////////
// 返回指定图纸中,指定点所在的楼层框
TProjectFloor* HitTestFloor(const TCHAR* sDwg, XPoint pt) // ok
{
TProjectGroupItem* pTable = GetFloorTable();
if (pTable != NULL)
{
for (pTable->MoveToFirst(); !pTable->IsOut(); pTable->MoveToNext())
{
TProjectFloor* pFloor = (TProjectFloor*)pTable->GetCurData();
CString sFullName = g_project.GetDwgFullName(pFloor->GetName());
if (_tcsicmp(sFullName, sDwg) == 0 && pFloor->IsInclude(pt))
return pFloor;
}
}
return NULL;
}