414 lines
9.8 KiB
C++
414 lines
9.8 KiB
C++
#pragma once
|
|
|
|
#ifdef EARTHWORM_EXPORT
|
|
#define DLLIMPEXP __declspec(dllexport)
|
|
#else
|
|
#define DLLIMPEXP __declspec(dllimport)
|
|
#endif
|
|
|
|
#include "dbtable.h"
|
|
#include "dbTableStyle.h "
|
|
#include <vector>
|
|
|
|
class DLLIMPEXP MKTABLE
|
|
{
|
|
public:
|
|
typedef std::vector<CString> RowData;
|
|
typedef std::vector<RowData> TableData;
|
|
|
|
public:
|
|
// 查找 AcDbTableStyle ,不存在则创建默认样式
|
|
static AcDbObjectId getTableStyle(LPCTSTR pszTSName);
|
|
|
|
// 查找 AcDbTextStyleTableRecord ,不存在则创建默认样式
|
|
static AcDbObjectId getTextStyle(LPCTSTR pszTSName);
|
|
|
|
// 查找 AcDbLinetypeTableRecord ,不存在则创建默认样式
|
|
static AcDbObjectId getLinetype(LPCTSTR pszLinetypeName);
|
|
|
|
// 取 listCtrl 中 idxs 指定的列,按顺序提取数据
|
|
static bool extractDatasFromListCtrl(CListCtrl &listCtrl
|
|
, std::vector<TableData> &outDatas
|
|
, RowData &headers
|
|
, const std::vector<int> &idxs
|
|
, const int &maxRow);
|
|
|
|
// 通过界面选择 listCtrl 中的列,并返回所选列的索引,包含顺序
|
|
static void selectColumnsFromListCtrl(CHeaderCtrl &headerCtrl
|
|
, std::vector<int> &idxs
|
|
, double &dPScale
|
|
, CString &sTemplate);
|
|
|
|
// 自动根据表格内容调整表格大小
|
|
static void autoSizeTable(AcDbTable *pTable);
|
|
|
|
// 获得表格模板列表
|
|
static void getTableTemplateList(std::vector<CString> &outTemplates);
|
|
|
|
public:
|
|
// 针对数据保存在CListCtrl中的表格,生成 AcDbTable
|
|
static bool makeTable(CListCtrl &listCtrl, LPCTSTR pszTitle, const int &maxRow);
|
|
};
|
|
|
|
|
|
#define _DEFINE_(type, name)\
|
|
void set##name(const type &val)\
|
|
{\
|
|
m_##name = val;\
|
|
m_bUse##name = true;\
|
|
}\
|
|
type m_##name;\
|
|
bool m_bUse##name
|
|
|
|
#define _DEFINE_LINETYPE_PROPERTY_(name, linetype)\
|
|
void set##name(const CellGridLineTypeProperty &val)\
|
|
{\
|
|
m_##name = val;\
|
|
m_bUse##name = true;\
|
|
}\
|
|
CellGridLineTypeProperty m_##name;\
|
|
bool m_bUse##name
|
|
|
|
#define APPLY_MARGIN(v)\
|
|
if (m_bUse##v)\
|
|
{\
|
|
pTS->setMargin(AcDb::kCellMargin##v, m_##v*dPScale, pszCellStyle);\
|
|
}
|
|
|
|
#define APPLY_GRIDLINE_PROPERTY(v)\
|
|
if (m_bUse##v)\
|
|
{\
|
|
pTb->setGrid##v(nRow, nCol, m_type, m_##v);\
|
|
}
|
|
|
|
#define APPLY_GRIDLINE_TYPE(v)\
|
|
for (size_t i = 0; i < m_##v.size(); ++i)\
|
|
{\
|
|
m_##v[i].apply2Table(pTb);\
|
|
}\
|
|
|
|
#define APPLY_CELL_STYLE(v)\
|
|
if (m_bUse##v)\
|
|
{\
|
|
pTS->set##v(m_##v, m_sName);\
|
|
}
|
|
|
|
class MKTABLE;
|
|
namespace TABLE
|
|
{
|
|
struct CellMergeRange
|
|
{
|
|
int m_maxRow, m_minRow, m_maxCol, m_minCol;
|
|
|
|
CellMergeRange(): m_maxRow(-1), m_minRow(-1), m_maxCol(-1), m_minCol(-1) {}
|
|
|
|
CellMergeRange(const CellMergeRange &mg): m_maxRow(mg.m_maxRow)
|
|
, m_minRow(mg.m_minRow)
|
|
, m_maxCol(mg.m_maxCol)
|
|
, m_minCol(mg.m_minCol) { }
|
|
|
|
CellMergeRange(const int &minRow
|
|
, const int &maxRow
|
|
, const int &minCol
|
|
, const int &maxCol)
|
|
: m_maxRow(maxRow)
|
|
, m_minRow(minRow)
|
|
, m_maxCol(maxCol)
|
|
, m_minCol(minCol) { }
|
|
|
|
CellMergeRange& operator=(const CellMergeRange &mg)
|
|
{
|
|
if (this != &mg)
|
|
{
|
|
m_maxRow = mg.m_maxRow;
|
|
m_minRow = mg.m_minRow;
|
|
m_maxCol = mg.m_maxCol;
|
|
m_minCol = mg.m_minCol;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
bool vaild(const int &nRow, const int &nCol)
|
|
{
|
|
// 负数表示从后往前计数,先计算正确位置
|
|
if (m_minRow < 0) m_minRow += nRow;
|
|
if (m_maxRow < 0) m_maxRow += nRow;
|
|
if (m_minCol < 0) m_minCol += nCol;
|
|
if (m_maxCol < 0) m_maxCol += nCol;
|
|
|
|
// 边缘保护调整
|
|
// 最小行/列 小于0,调整为0,即第一行
|
|
if (m_minRow < 0) m_minRow = 0;
|
|
if (m_minCol < 0) m_minCol = 0;
|
|
// 最大行/列 大于总行/列数,调整为总行/列数-1,即最后一行
|
|
if (m_maxRow >= nRow) m_maxRow = nRow - 1;
|
|
if (m_maxCol >= nRow) m_maxCol = nCol - 1;
|
|
|
|
// 最小行/列大于总行/列数
|
|
if (m_minRow > nRow || m_minCol > nCol) return false;
|
|
|
|
// 最大行/列 小于0
|
|
if (m_maxRow < 0 || m_maxCol < 0) return false;
|
|
|
|
// 最小行/列 大于 最大行/列
|
|
if (m_minRow > m_maxRow || m_minCol > m_maxCol) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void apply2Table(AcDbTable *pTb)
|
|
{
|
|
if (vaild(pTb->numRows(), pTb->numColumns()))
|
|
pTb->mergeCells(m_minRow, m_maxRow, m_minCol, m_maxCol);
|
|
}
|
|
};
|
|
typedef std::vector<CellMergeRange> CellMerges;
|
|
|
|
struct CellMargin
|
|
{
|
|
_DEFINE_(double, Left);
|
|
_DEFINE_(double, Right);
|
|
_DEFINE_(double, Top);
|
|
_DEFINE_(double, Bottom);
|
|
_DEFINE_(double, HorzSpacing);
|
|
_DEFINE_(double, VertSpacing);
|
|
|
|
CellMargin(): m_bUseLeft(false)
|
|
, m_bUseRight(false)
|
|
, m_bUseTop(false)
|
|
, m_bUseBottom(false)
|
|
, m_bUseHorzSpacing(false)
|
|
, m_bUseVertSpacing(false) { }
|
|
void apply2TableStyle(AcDbTableStyle *pTS, LPCTSTR pszCellStyle, const double &dPScale)
|
|
{
|
|
APPLY_MARGIN(Left);
|
|
APPLY_MARGIN(Right);
|
|
APPLY_MARGIN(Top);
|
|
APPLY_MARGIN(Bottom);
|
|
APPLY_MARGIN(HorzSpacing);
|
|
APPLY_MARGIN(VertSpacing);
|
|
}
|
|
};
|
|
|
|
struct GridLineTypeProperty
|
|
{
|
|
int m_minRow, m_minCol;
|
|
int m_maxRow, m_maxCol;
|
|
double m_dPScale;
|
|
AcDb::GridLineType m_type;
|
|
_DEFINE_(AcDb::GridLineStyle, LineStyle);
|
|
_DEFINE_(AcDb::LineWeight, LineWeight);
|
|
_DEFINE_(CString, Linetype);
|
|
_DEFINE_(int, Color);
|
|
_DEFINE_(AcDb::Visibility, Visibility);
|
|
_DEFINE_(double, DoubleLineSpacing);
|
|
|
|
GridLineTypeProperty(AcDb::GridLineType type
|
|
, const int &minRow
|
|
, const int &maxRow
|
|
, const int &minCol
|
|
, const int &maxCol
|
|
, const double &dps )
|
|
: m_type(type)
|
|
, m_dPScale(dps)
|
|
, m_minRow(minRow)
|
|
, m_maxRow(maxRow)
|
|
, m_minCol(minCol)
|
|
, m_maxCol(maxCol)
|
|
, m_bUseLinetype(false)
|
|
, m_bUseColor(false)
|
|
, m_bUseLineStyle(false)
|
|
, m_bUseLineWeight(false)
|
|
, m_bUseVisibility(false)
|
|
, m_bUseDoubleLineSpacing(false) { }
|
|
|
|
void apply2Table(AcDbTable *pTb) const
|
|
{
|
|
CellMergeRange tempRange(m_minRow, m_maxRow, m_minCol, m_maxCol);
|
|
|
|
// 先调整范围合法性
|
|
if (!tempRange.vaild(pTb->numRows(), pTb->numColumns())) return;
|
|
|
|
int minRow = tempRange.m_minRow;
|
|
int maxRow = tempRange.m_maxRow;
|
|
int minCol = tempRange.m_minCol;
|
|
int maxCol = tempRange.m_maxCol;
|
|
|
|
for (int nRow(minRow); nRow <= maxRow; ++nRow)
|
|
{
|
|
for (int nCol(minCol); nCol <= maxCol; ++nCol)
|
|
{
|
|
APPLY_GRIDLINE_PROPERTY(LineStyle);
|
|
APPLY_GRIDLINE_PROPERTY(LineWeight);
|
|
APPLY_GRIDLINE_PROPERTY(Visibility);
|
|
|
|
if (m_bUseDoubleLineSpacing)
|
|
{
|
|
pTb->setGridDoubleLineSpacing(nRow
|
|
, nCol
|
|
, m_type
|
|
, m_DoubleLineSpacing * m_dPScale);
|
|
}
|
|
|
|
if (m_bUseColor)
|
|
{
|
|
AcCmColor clr;
|
|
clr.setColorIndex(m_Color);
|
|
pTb->setGridColor(m_type, nRow, nCol, clr);
|
|
}
|
|
|
|
if (m_bUseLinetype)
|
|
{
|
|
AcDbObjectId id(MKTABLE::getTextStyle(m_Linetype));
|
|
if (id.isValid())
|
|
pTb->setGridLinetype(nRow, nCol, m_type, id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
typedef std::vector<GridLineTypeProperty> GridLineTypePropertys;
|
|
|
|
struct GridLineType
|
|
{
|
|
_DEFINE_(GridLineTypePropertys, HorzTop);
|
|
_DEFINE_(GridLineTypePropertys, HorzInside);
|
|
_DEFINE_(GridLineTypePropertys, HorzBottom);
|
|
_DEFINE_(GridLineTypePropertys, VertLeft);
|
|
_DEFINE_(GridLineTypePropertys, VertInside);
|
|
_DEFINE_(GridLineTypePropertys, VertRight);
|
|
_DEFINE_(GridLineTypePropertys, HorzGridLineTypes);
|
|
_DEFINE_(GridLineTypePropertys, VertGridLineTypes);
|
|
_DEFINE_(GridLineTypePropertys, OuterGridLineTypes);
|
|
_DEFINE_(GridLineTypePropertys, InnerGridLineTypes);
|
|
_DEFINE_(GridLineTypePropertys, AllGridLineTypes);
|
|
GridLineType(){ }
|
|
|
|
void apply2Table(AcDbTable *pTb) const
|
|
{
|
|
APPLY_GRIDLINE_TYPE(HorzTop);
|
|
APPLY_GRIDLINE_TYPE(HorzInside);
|
|
APPLY_GRIDLINE_TYPE(HorzBottom);
|
|
APPLY_GRIDLINE_TYPE(VertLeft);
|
|
APPLY_GRIDLINE_TYPE(VertInside);
|
|
APPLY_GRIDLINE_TYPE(VertRight);
|
|
APPLY_GRIDLINE_TYPE(HorzGridLineTypes);
|
|
APPLY_GRIDLINE_TYPE(VertGridLineTypes);
|
|
APPLY_GRIDLINE_TYPE(OuterGridLineTypes);
|
|
APPLY_GRIDLINE_TYPE(InnerGridLineTypes);
|
|
APPLY_GRIDLINE_TYPE(AllGridLineTypes);
|
|
}
|
|
};
|
|
|
|
struct CellStyle
|
|
{
|
|
CString m_sName;
|
|
|
|
_DEFINE_(CString, TextStyle);
|
|
_DEFINE_(double, TextHeight);
|
|
_DEFINE_(double, Rotation);
|
|
_DEFINE_(int, Color);
|
|
_DEFINE_(int, BackgroundColor);
|
|
_DEFINE_(AcDb::CellAlignment, Alignment);
|
|
_DEFINE_(CellMargin, Margin);
|
|
_DEFINE_(bool, enableMergeAll);
|
|
|
|
CellStyle(): m_sName(_T(""))
|
|
, m_bUseColor(false)
|
|
, m_bUseBackgroundColor(false)
|
|
, m_bUseTextStyle(false)
|
|
, m_bUseTextHeight(false)
|
|
, m_bUseRotation(false)
|
|
, m_bUseMargin(false)
|
|
, m_bUseenableMergeAll(false)
|
|
, m_bUseAlignment(false) { }
|
|
|
|
void apply2CellStyle(AcDbTableStyle *pTS, const double &dPScale)
|
|
{
|
|
AcStringArray cellnames;
|
|
pTS->getCellStyles(cellnames);
|
|
if (cellnames.find((LPCTSTR)m_sName) == -1)
|
|
{
|
|
if (pTS->createCellStyle(m_sName) != Acad::eOk)
|
|
return;
|
|
}
|
|
|
|
APPLY_CELL_STYLE(Alignment);
|
|
APPLY_CELL_STYLE(Rotation);
|
|
|
|
if (m_bUseTextHeight)
|
|
{
|
|
pTS->setTextHeight(m_TextHeight * dPScale, m_sName);
|
|
}
|
|
|
|
if (m_bUseColor)
|
|
{
|
|
AcCmColor clr;
|
|
clr.setColorIndex(m_Color);
|
|
pTS->setColor(clr, m_sName);
|
|
}
|
|
|
|
if (m_bUseBackgroundColor)
|
|
{
|
|
AcCmColor clr;
|
|
clr.setColorIndex(m_BackgroundColor);
|
|
pTS->setBackgroundColor(clr, m_sName);
|
|
}
|
|
|
|
if (m_bUseTextStyle)
|
|
{
|
|
AcDbObjectId tsId = MKTABLE::getTextStyle(m_TextStyle);
|
|
if (tsId.isValid())
|
|
pTS->setTextStyle(tsId, m_sName);
|
|
}
|
|
|
|
if (m_bUseenableMergeAll)
|
|
pTS->enableMergeAll(m_enableMergeAll, m_sName);
|
|
|
|
if (m_bUseMargin)
|
|
{
|
|
m_Margin.apply2TableStyle(pTS, m_sName, dPScale);
|
|
}
|
|
}
|
|
};
|
|
typedef std::map<CString, CellStyle> CellStyles;
|
|
|
|
struct Cell
|
|
{
|
|
int row;
|
|
int col;
|
|
CString text;
|
|
CString style;
|
|
void apply2Table(AcDbTable *pTb) const
|
|
{
|
|
if (!pTb) return;
|
|
pTb->setTextString(row, col, text);
|
|
if (!style.IsEmpty())
|
|
pTb->setCellStyle(row, col, style);
|
|
}
|
|
};
|
|
typedef std::vector<Cell> Cells, CellRowData;
|
|
typedef std::vector<Cells> CellTableData;
|
|
|
|
struct TableStyle
|
|
{
|
|
CString m_sName;
|
|
std::map<CString, CellStyle> m_cellStyles;
|
|
};
|
|
typedef std::map<CString, TableStyle> TableStyles;
|
|
|
|
struct DataContent
|
|
{
|
|
// 默认单元格样式,一定要设置,只能是_TITLE,_DATA,_HEADER
|
|
// 因为这三种样式是 AcDbTableStyle 自带并且无法删除的
|
|
CString m_defCellStyle;
|
|
|
|
CellTableData m_tableData;
|
|
|
|
DataContent(LPCTSTR def): m_defCellStyle(def) {}
|
|
|
|
};
|
|
typedef std::map<CString, DataContent> DataContents;
|
|
}
|
|
|