572 lines
14 KiB
C++
572 lines
14 KiB
C++
#include "stdafx.h"
|
||
#include "TCheckFloorRectData.h"
|
||
|
||
XCheckFloorRectData::XCheckFloorRectData()
|
||
{
|
||
m_csPrompt = _T("");
|
||
}
|
||
|
||
XCheckFloorRectData::~XCheckFloorRectData()
|
||
{
|
||
m_csPrompt = _T("");
|
||
ClearFloors();
|
||
}
|
||
|
||
// 获取提示语
|
||
CString XCheckFloorRectData::GetPrompt() const
|
||
{
|
||
return m_csPrompt;
|
||
}
|
||
|
||
// 获取楼层号数组
|
||
void XCheckFloorRectData::GetFloors(AcDbIntArray &aryFloors) const
|
||
{
|
||
aryFloors = m_aryFloors;
|
||
}
|
||
|
||
// 检查层高输入是否合法,自动去掉前后的空格
|
||
bool XCheckFloorRectData::IsHeightLegal(CString &csHeight)
|
||
{
|
||
csHeight.TrimLeft(); // 去掉前后的空格
|
||
csHeight.TrimRight();
|
||
|
||
if (csHeight.IsEmpty()) // 输入值为空
|
||
{
|
||
m_csPrompt = _T("警告: 层高不能为空! ");
|
||
return false;
|
||
}
|
||
|
||
TCHAR chTemp;
|
||
short nLength = csHeight.GetLength();
|
||
for (short i = 0; i < nLength; i++)
|
||
{
|
||
chTemp = csHeight.GetAt(i);
|
||
if (chTemp < _T('0') || chTemp > _T('9')) // 只能输入正整数
|
||
{
|
||
m_csPrompt = _T("警告: 请用毫米单位, 以整数输入层高数据! ");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
m_csPrompt = _T(""); // 输出警告提示设置为空
|
||
return true;
|
||
}
|
||
|
||
// 检查层号输入是否合法,部分情况自动修改csName
|
||
bool XCheckFloorRectData::IsNameLegal(CString &csName)
|
||
{
|
||
ClearFloors();
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 1)对“空格”进行处理,去掉前后空格,合并多个空格,同时将间隔类空格,替换为逗号
|
||
DealSpace(_T(" "), csName); // 半角空格
|
||
DealSpace(_T(" "), csName); // 全角空格
|
||
|
||
if (csName.IsEmpty()) // 输入值为空
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能为空! ");
|
||
return false;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 2)判断层号是否是“间断”的情况(全角、半角逗号)
|
||
bool bRet = IsDisconnectNum(_T(","), csName);
|
||
if (bRet) // 含有半角“,”
|
||
{
|
||
m_csPrompt = _T("");
|
||
return true;
|
||
}
|
||
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
bRet = IsDisconnectNum(_T(","), csName);
|
||
if (bRet) // 含有全角“,”
|
||
{
|
||
m_csPrompt = _T("");
|
||
return true;
|
||
}
|
||
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 3)判断层号是否是“连续”的情况(全角、半角波浪线、折断线)
|
||
int nLow(0), nUp(0);
|
||
bRet = IsContinuousNum(csName, nLow, nUp);
|
||
if (bRet) // 是连续的情况
|
||
{
|
||
bRet = AppendNum(nLow, nUp); // 将有效的楼层添加到数组中
|
||
if (!bRet)
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能有重复! ");
|
||
}
|
||
else
|
||
{
|
||
m_csPrompt = _T("");
|
||
}
|
||
|
||
return bRet;
|
||
}
|
||
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 4)判断是否是“只包含一层”的情况
|
||
int nNumber = GetFloorNumber(csName);
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
bRet = AppendNum(nNumber); // 将有效的楼层添加到数组中
|
||
if (!bRet)
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能有重复! ");
|
||
}
|
||
else
|
||
{
|
||
m_csPrompt = _T("");
|
||
}
|
||
return bRet;
|
||
}
|
||
|
||
// 判断是否存在“指定”间断符号连接的楼层号,递归调用
|
||
bool XCheckFloorRectData::IsDisconnectNum(CString csSymb, CString &csName)
|
||
{
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 1)对“空格”进行处理,去掉前后的空格
|
||
csName.TrimLeft();
|
||
csName.TrimRight();
|
||
|
||
if (csName.IsEmpty()) // 输入值为空
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能为空! ");
|
||
return false;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 2)查找指定“间断符号”是否存在
|
||
int nRet = csName.Find(csSymb, 0);
|
||
if (nRet < 0) // 不含有指定间断类连字符csSymb
|
||
{
|
||
m_csPrompt = _T("");
|
||
return false;
|
||
}
|
||
|
||
if (nRet == 0) // 首位必须为数字
|
||
{
|
||
m_csPrompt = _T("警告: 层号连字符仅能在数字之间出现! ");
|
||
return false;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 3)对“连接符左边”的楼层号进一步判断
|
||
CString csLeft = csName.Left(nRet);
|
||
|
||
int nLow(0), nUp(0);
|
||
// 判断是否是连续的楼层号
|
||
if (!IsContinuousNum(csLeft, nLow, nUp)) // 不连续
|
||
{
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//////////只包含一层的情况//////////
|
||
nLow = GetFloorNumber(csLeft);
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (!AppendNum(nLow))
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能有重复! ");
|
||
return false;
|
||
}
|
||
}
|
||
else // 连续
|
||
{
|
||
if (!AppendNum(nLow, nUp))
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能有重复! ");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 4)对“连接符右边”的楼层号,进一步递归判断
|
||
int nLength = csName.GetLength();
|
||
CString csRight = csName.Right(nLength - nRet - 1);
|
||
|
||
//////////判断是否是间断楼层号//////////
|
||
// 注:不支持混合连字符
|
||
if (IsDisconnectNum(csSymb, csRight)) // 间断,递归调用
|
||
{
|
||
csName = csLeft + csSymb + csRight; // 重新合成层号,去掉空格
|
||
return true;
|
||
}
|
||
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//////////判断是否是连续的楼层号//////////
|
||
if (IsContinuousNum(csRight, nLow, nUp)) // 连续
|
||
{
|
||
if (!AppendNum(nLow, nUp))
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能有重复! ");
|
||
return false;
|
||
}
|
||
|
||
csName = csLeft + csSymb + csRight; // 重新合成层号,去掉空格
|
||
return true;
|
||
}
|
||
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
//////////只包含一层的情况//////////
|
||
nLow = GetFloorNumber(csRight);
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (!AppendNum(nLow))
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能有重复! ");
|
||
return false;
|
||
}
|
||
|
||
csName = csLeft + csSymb + csRight; // 重新合成层号,去掉空格
|
||
return true;
|
||
}
|
||
|
||
// 判断是否存在连续的楼层号
|
||
bool XCheckFloorRectData::IsContinuousNum(CString &csName, int &nLow, int &nUp)
|
||
{
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 1)对“空格”进行处理,去掉前后的空格
|
||
csName.TrimLeft();
|
||
csName.TrimRight();
|
||
|
||
if (csName.IsEmpty()) // 输入值为空
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能为空! ");
|
||
return false;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 2)逐个判断层号是否是“连续”的情况(含有全角、半角波浪号、连接线)
|
||
bool bRet = IsContinuousNum(_T("~"), csName, nLow, nUp);
|
||
if (bRet) // 含有半角“~”
|
||
{
|
||
return true;
|
||
}
|
||
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
bRet = IsContinuousNum(_T("~"), csName, nLow, nUp);
|
||
if (bRet) // 含有全角“~”
|
||
{
|
||
return true;
|
||
}
|
||
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
bRet = IsContinuousNum(_T("-"), csName, nLow, nUp);
|
||
if (bRet) // 含有半角“-”
|
||
{
|
||
return true;
|
||
}
|
||
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
bRet = IsContinuousNum(_T("-"), csName, nLow, nUp);
|
||
if (bRet) // 含有全角“-”
|
||
{
|
||
return true;
|
||
}
|
||
|
||
if (!m_csPrompt.IsEmpty()) // 楼层号不符合要求
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return false; // 只包含一层的情况
|
||
}
|
||
|
||
// 判断是否存在指定符号的连续的楼层号
|
||
bool XCheckFloorRectData::IsContinuousNum(CString csSymb, CString &csName, int &nLow, int &nUp)
|
||
{
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 1)查找指定“连续符号”是否存在
|
||
int nRet = csName.Find(csSymb, 0);
|
||
if (nRet < 0) // 不存在间断类连字符
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (nRet == 0) // 符号出现在首位
|
||
{
|
||
if (csSymb==_T("-") || csSymb==_T("-")) // 进一步判断是否是首位的负号
|
||
{
|
||
nRet = csName.Find(csSymb, 1);
|
||
if (nRet < 2) // 不存在间断类连字符
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
else // 波浪号不可能出现在首位
|
||
{
|
||
m_csPrompt = _T("警告: 层号连字符仅能在数字之间出现! ");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 2)以“连续符号”为界,分左、右,转化为数字
|
||
int nLength = csName.GetLength();
|
||
CString csLow = csName.Left(nRet);
|
||
|
||
// Add by Zyu on 100423,如果是全角的连字符,那么连字符占两位。
|
||
if (_T("~") == csSymb || _T("-") == csSymb)
|
||
{
|
||
nRet++;
|
||
}
|
||
|
||
CString csUp = csName.Right(nLength - nRet - 1);
|
||
|
||
// “连接符左边”的楼层号
|
||
nLow = GetFloorNumber(csLow);
|
||
if (!m_csPrompt.IsEmpty())
|
||
{
|
||
return false; // 楼层号不符合要求
|
||
}
|
||
|
||
// “连接符右边”的楼层号
|
||
nUp = GetFloorNumber(csUp);
|
||
if (!m_csPrompt.IsEmpty())
|
||
{
|
||
return false; // 楼层号不符合要求
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 3)对左、右楼层号进行处理,左边为小数,右边为大数
|
||
// 出现负数,自动将连接符号变为“~”,以防止歧义
|
||
if (nLow<0 || nUp<0)
|
||
{
|
||
csSymb = _T("~");
|
||
}
|
||
|
||
if (nLow > nUp) // 下限大于上限,自动交换
|
||
{
|
||
Exchange(nLow, nUp);
|
||
csName = csUp + csSymb + csLow;
|
||
}
|
||
else if (nLow == nUp) // 上限与下限相等,去掉连字符
|
||
{
|
||
csName = csLow;
|
||
}
|
||
else // 上限小于下限
|
||
{
|
||
csName = csLow + csSymb + csUp;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// 检查楼层号是否是正负一到三位数以内的整型数,直接返回楼层号,根据提示是否为空判断是否获取成功
|
||
int XCheckFloorRectData::GetFloorNumber(CString &csName)
|
||
{
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 1)对“空格”进行处理,去掉前后的空格
|
||
csName.TrimLeft();
|
||
csName.TrimRight();
|
||
|
||
if (csName.IsEmpty())
|
||
{
|
||
m_csPrompt = _T("警告: 层号不能为空! "); // 输入值为空
|
||
return 0;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 2)逐位判断是否是数字,首位允许是负号
|
||
TCHAR chTemp;
|
||
short nLength = csName.GetLength();
|
||
for (short i = 0; i < nLength; i++)
|
||
{
|
||
chTemp = csName.GetAt(i);
|
||
if (chTemp < _T('0') || chTemp > _T('9')) // 只允许输入整数
|
||
{
|
||
if (_T('-')==chTemp && i==0)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
m_csPrompt = _T("警告: 层号数据必须为整数! ");
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 3)对楼层号进行进一步判断
|
||
int nNum = _ttoi(csName);
|
||
if (nNum>999 || nNum<-99) // 只允许正负一到三位以内的整数,如:-99≤N≤999
|
||
{
|
||
m_csPrompt = _T("警告: 层号只允许正负一到三位以内的整数! ");
|
||
return 0;
|
||
}
|
||
|
||
if (nNum == 0) // 不允许是0
|
||
{
|
||
m_csPrompt = _T("警告: 层号不允许是0! ");
|
||
return 0;
|
||
}
|
||
|
||
m_csPrompt = _T("");
|
||
return nNum;
|
||
}
|
||
|
||
// 处理空格
|
||
void XCheckFloorRectData::DealSpace(CString csSymb, CString &csName)
|
||
{
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 1)去掉前后的空格
|
||
csName.TrimLeft();
|
||
csName.TrimRight();
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 2)以csSymb为界,分左、右处理
|
||
int nRet = csName.Find(csSymb, 0);
|
||
if (nRet < 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
int nLength = csName.GetLength();
|
||
CString csLeft = csName.Left(nRet),
|
||
csRight = csName.Right(nLength - nRet - 1);
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 3)递归处理多空格
|
||
csRight.TrimLeft();
|
||
DealSpace(csSymb, csRight);
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 4)如果前一位不是数字,自动去掉空格
|
||
TCHAR chTempPre;
|
||
chTempPre = csName.GetAt(nRet-1); // 前一位,注:由于执行过csName.TrimLeft(),首位一定不是空格
|
||
if (chTempPre < _T('0') || chTempPre > _T('9')) // 非数字
|
||
{
|
||
csName = csLeft + csRight;
|
||
return;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 5)判断是否要用逗号替换空格
|
||
TCHAR chTempNext;
|
||
chTempNext = csRight.GetAt(0); // 后一位
|
||
|
||
bool bReplace(false); // 标记是否用逗号替换空格
|
||
if (chTempNext >= _T('0') && chTempNext <= _T('9')) // 数字
|
||
{
|
||
bReplace = true;
|
||
}
|
||
else if (_T('-') == chTempNext) // 负号
|
||
{
|
||
nRet = csRight.Find(_T("-"), 1);
|
||
if (nRet > 0) // 说明chTempNext不是负号,而是连字符,直接去掉空格
|
||
{
|
||
csName = csLeft + csRight;
|
||
return;
|
||
}
|
||
|
||
int nLeft = _ttoi(csLeft);
|
||
if (nLeft < 0) // 进一步判断符号前的数字是否也是负数
|
||
{
|
||
bReplace = true;
|
||
}
|
||
}
|
||
else // 其他符号,自动去掉空格
|
||
{
|
||
csName = csLeft + csRight;
|
||
return;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
// 6)将多个空格合并,并根据需要用逗号替换空格
|
||
if (bReplace)
|
||
{
|
||
csSymb = _T(",");
|
||
}
|
||
csName = csLeft + csSymb + csRight;
|
||
}
|
||
|
||
// 清空数组
|
||
void XCheckFloorRectData::ClearFloors()
|
||
{
|
||
int nLen = m_aryFloors.length();
|
||
if (nLen > 0)
|
||
{
|
||
m_aryFloors.removeSubArray(0, nLen-1);
|
||
}
|
||
}
|
||
|
||
// 向数组中增加楼层号,自动检查,若和aryFloorNum中有重复,返回false。nLow为下限,nUp为上限,自动过滤掉0
|
||
bool XCheckFloorRectData::AppendNum(int nNum)
|
||
{
|
||
int nIndex = 0;
|
||
if (m_aryFloors.find(nNum, nIndex, 0)) // 找到重复楼层
|
||
{
|
||
return false;
|
||
}
|
||
|
||
m_aryFloors.append(nNum); // 添加
|
||
return true;
|
||
}
|
||
|
||
bool XCheckFloorRectData::AppendNum(int nLow, int nUp)
|
||
{
|
||
if (nLow == nUp) // 上限、下限相等,只添加一个
|
||
{
|
||
return AppendNum(nLow);
|
||
}
|
||
|
||
for (int i=nLow; i<=nUp; i++)
|
||
{
|
||
if (i == 0) // 过滤掉0
|
||
{
|
||
i++;
|
||
}
|
||
|
||
if (!AppendNum(i))
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|