📄 asdktable.cpp
字号:
//-----------------------------------------------------------------------------
//----- Populate the new table
void populateTable(AcDbTable *&pTbl, const RowData *pRwData)
{
// Sanity check
if ((NULL == pTbl) || (!pTbl->isWriteEnabled()) ||
(NULL == pRwData) || (0 == pRwData->length())) PRTMSGRET(_T("eNotOpenForWrite"))
if ((pRwData->at(2)->length() != pTbl->numColumns()) ||
(pRwData->length() != pTbl->numRows()))PRTMSGRET(_T("Table and data does not match"))
// Populate the table / Rows
for(int nCtr1 = 0;nCtr1 < pRwData->length();nCtr1++)
{
FieldData *pColData = pRwData->at(nCtr1);
for(int nCtr2 = 0;nCtr2 < pColData->length();nCtr2++)
{
pTbl->setTextString(nCtr1,nCtr2,pColData->at(nCtr2));
}
}
}
//-----------------------------------------------------------------------------
//----- Generate data for the selected Block
Acad::ErrorStatus generateTableFromBlock(const TCHAR *pBlkName, RowData *&pRwData, bool bLink)
{
// Sanity check
if((NULL == pRwData) || (NULL == pBlkName))PRTMSGRETES(Acad::eNotApplicable)
AcDbBlockTable *pBT = NULL;
AcDbBlockTableRecord *pBTR = NULL;
Acad::ErrorStatus es;
// Get the block table
PRTMSGRETES(acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBT,AcDb::kForRead));
// Get the blocktablerecord
es = pBT->getAt(pBlkName,pBTR,AcDb::kForRead);
pBT->close();
PRTMSGRETES(es)
// Check for all attributes
if (!pBTR->hasAttributeDefinitions())
{
pBTR->close();
PRTMSGRETES(Acad::eNotApplicable)
}
// Iterate for all attribute definitions
// Build the header, this means find out how many attribute definitions are available
AcDbBlockTableRecordIterator *pBTRItr = NULL;
pBTR->newIterator(pBTRItr);
// Add Data
// Add Title in first row
FieldData *pTitleData = new FieldData();
TCHAR *pTitle = new TCHAR[256];
memset(pTitle,0,256 * sizeof(TCHAR));
_stprintf(pTitle,_T("Block Name: %s"),pBlkName);
pTitleData->append(pTitle);
pRwData->append(pTitleData);
// Add header data in second row
FieldData *pHdrData = new FieldData();
// First column is Sl number
pHdrData->append(_tcsdup(_T("Sl.No.")));
// Second column is Block Reference Handle number
pHdrData->append(_tcsdup(_T("Block Handle")));
// Get the remaining Column names from the block definition's AcDbAttributeDefinition
while (!pBTRItr->done())
{
AcDbEntity *pEnt = NULL;
pBTRItr->getEntity(pEnt,AcDb::kForRead);
AcDbAttributeDefinition *pAttDef = NULL;
pAttDef = AcDbAttributeDefinition::cast(pEnt);
if(NULL != pAttDef)
{
if (Adesk::kFalse == pAttDef->isConstant())
{
pHdrData->append(pAttDef->tag()); // Append the attribute TAG for header
}
}
pEnt->close();
pBTRItr->step();
}
pRwData->append(pHdrData);
// Clean up
delete pBTRItr;
// Get the attribute data for every block reference
AcDbObjectIdArray idObjs;
pBTR->getBlockReferenceIds(idObjs,true);
// Done with the block table record
pBTR->close();
// Some sanity check, check if the block references are in anonymous blocks
for(int nCtr1 = 0;nCtr1 < idObjs.length(); nCtr1++)
{
bool bValid = true;
AcDbBlockReference *pBlkRef = NULL;
if(Acad::eOk == acdbOpenObject((AcDbEntity *&)pBlkRef,idObjs.at(nCtr1),AcDb::kForRead,false))
{
AcDbObject *pObj = NULL;
if(Acad::eOk == acdbOpenObject(pObj,pBlkRef->ownerId(),AcDb::kForRead,false))
{
if (!pObj->objectId().isValid()) bValid = false;
AcDbBlockTableRecord *pBTR;
if(NULL != (pBTR = AcDbBlockTableRecord::cast(pObj)))
{
const TCHAR *pName;
pBTR->getName(pName);
if((!pBTR->isLayout()) && (_T('*') == (int)*pName)) bValid = false;
}
pObj->close();
}
pBlkRef->close();
}
if(!bValid) idObjs.remove(idObjs.at(nCtr1));
}
if(0 == idObjs.length())
{
acutPrintf(_T("\nNo block references found"));
return Acad::eNotApplicable;
}
// Start iterating all the valid block references for the attribute data
int nSlNoCtr = 1;
for(int nCtr1 = 0;nCtr1 < idObjs.length(); nCtr1++)
{
AcDbBlockReference *pBlkRef = NULL;
if(Acad::eOk == acdbOpenObject((AcDbEntity *&)pBlkRef,idObjs.at(nCtr1),AcDb::kForRead,false))
{
FieldData *pFldData = new FieldData();
// Add the Sl No
TCHAR *pSlNo = new TCHAR[8];
memset(pSlNo,0,8 * sizeof(TCHAR));
_stprintf(pSlNo,_T("%d"),nSlNoCtr);
pFldData->append(pSlNo);
// Add the block reference handle
TCHAR *pHndNo = new TCHAR[17];
memset(pHndNo,0,17 * sizeof(TCHAR));
AcDbHandle hnd;
pBlkRef->getAcDbHandle(hnd);
hnd.getIntoAsciiBuffer(pHndNo);
pFldData->append(pHndNo);
// Get the attribute data from the block reference. Create attribute name<->value map
// this is required to fill data in correct sequence
// irrespective of how we read the attributes
HdrRwMap *pHdrRw = new HdrRwMap();
AcDbObjectIterator *pAttItr = NULL;
pAttItr = pBlkRef->attributeIterator();
while (!pAttItr->done())
{
AcDbAttribute *pAtt;
if (Acad::eOk == acdbOpenObject((AcDbEntity *&)pAtt,pAttItr->objectId(),AcDb::kForRead))
{
// If link is true then add a field
if(bLink)
{
TCHAR *pAcFld = new TCHAR[512];
memset(pAcFld,0,512 * sizeof(TCHAR));
_stprintf(pAcFld,_T("%%<\\AcObjProp Object(%%<\\_ObjId %d>%%).TextString>%%"),pAttItr->objectId().asOldId());
pHdrRw->insert(Char_Pair(pAtt->tag(),pAcFld));
}
else
{
pHdrRw->insert(Char_Pair(pAtt->tag(),pAtt->textString()));
}
pAtt->close();
}
pAttItr->step();
}
// Note start filling in from index 2 as we already filled the first two column data
for(int nCtr2 = 2; nCtr2 < pHdrData->length();nCtr2++)
{
HdrRwMap::const_iterator itr = pHdrRw->begin();
while(!(itr == pHdrRw->end()))
{
if(!_tcscmp(itr->first,pHdrData->at(nCtr2))) break;
itr++;
}
// Duplicate the string as the pHdrRw will be deleted within this function scope
TCHAR *pAttText = _tcsdup(itr->second);
pFldData->append((NULL == pAttText?_T("-"):pAttText));
}
pRwData->append(pFldData);
nSlNoCtr++; // Increment the block reference counter
pBlkRef->close(); // Close the block reference
delete pAttItr; // Clean up
deleteHdrRwMap(pHdrRw);
}
}
return Acad::eOk;
}
//-----------------------------------------------------------------------------
//----- Merge cells
Acad::ErrorStatus mergeCellsForTitleAndHeader(AcDbTable *&pTbl, const TCHAR *pBlkName)
{
// Sanity check
if ((NULL == pTbl) || (!pTbl->isWriteEnabled())) PRTMSGRETES(Acad::eNotOpenForWrite)
// Merge Title row. Note that when you create table using UI the title row is merged
// automatically but when adding using API, we will have to explicitly merge the cells
pTbl->mergeCells(0,0,0,pTbl->numColumns() - 1);
// Merge for showing header
// Still more sanity check, we will merge third and fourth row
if (3 > pTbl->numRows()) return Acad::eNotApplicable;
// Lets add a row and then merge
pTbl->insertRows(1,pTbl->rowHeight(1));
// Merge the cells in steps
pTbl->mergeCells(1,1,0,1);
pTbl->mergeCells(1,1,2,pTbl->numColumns() - 1);
// Type in the 'Attributes'
pTbl->setTextString(1,2,_T("Attributes"));
// Show the block in the cell 1,0
// Set the block id
AcDbBlockTable *pBT = NULL;
AcDbBlockTableRecord *pBTR = NULL;
// Get the block table
acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBT,AcDb::kForRead);
// Get the blocktablerecordid
AcDbObjectId objId;
pBT->getAt(pBlkName,objId);
pBT->close();
pTbl->setBlockTableRecordId(1,0,objId,true);
// Lets copy the header rows properties to the third row
// since we cannot specify a row to be a header row
AcCmColor col = pTbl->contentColor(AcDb::kHeaderRow);
AcDbObjectId objID = pTbl->textStyle(AcDb::kHeaderRow);
double nHt = pTbl->textHeight(AcDb::kHeaderRow);
for(int nCtr1 = 0;nCtr1 < pTbl->numColumns(); nCtr1++)
{
pTbl->setContentColor(2,nCtr1,col);
pTbl->setTextStyle(objID);
pTbl->setTextHeight(nHt);
}
pTbl->recomputeTableBlock();
return Acad::eOk;
}
//-----------------------------------------------------------------------------
//----- Fit column width with text width
Acad::ErrorStatus fitColumnWidth(AcDbTable *&pTbl,double maxWidth)
{
// Sanity check
if ((NULL == pTbl) || (!pTbl->isWriteEnabled())) PRTMSGRETES(Acad::eNotOpenForWrite)
for(int nCtr1 = 0;nCtr1 < pTbl->numColumns();nCtr1++)
{
double nWidth;
for(int nCtr2 = 2;nCtr2 < pTbl->numRows();nCtr2++) // Include the second header row
{
// Get the textstyle for the data cells
AcGiTextStyle txtStyle;
fromAcDbTextStyle(txtStyle,pTbl->textStyle(nCtr2,nCtr1));
txtStyle.setTextSize(pTbl->textHeight(nCtr2,nCtr1));
// Get the text width
AcGePoint2d pt = txtStyle.extents(pTbl->textString(nCtr2,nCtr1),Adesk::kTrue,-1,Adesk::kFalse);
if (2 == nCtr2)
nWidth = pt.x;
else
nWidth = (pt.x > nWidth?pt.x:nWidth);
}
// Set the column width as we should have the widest width by now
pTbl->setColumnWidth(nCtr1,(nWidth > maxWidth?maxWidth:nWidth) * 1.2);
}
pTbl->recomputeTableBlock();
return Acad::eOk;
}
//-----------------------------------------------------------------------------
//----- Fit row height with text height
Acad::ErrorStatus fitRowHeight(AcDbTable *&pTbl,double maxHeight)
{
// Sanity check
if ((NULL == pTbl) || (!pTbl->isWriteEnabled())) PRTMSGRETES(Acad::eNotOpenForWrite)
for(int nCtr1 = 0;nCtr1 < pTbl->numRows();nCtr1++) // Include all the rows
{
double nHeight = pTbl->textHeight(nCtr1,0); // Height of the first column
for(int nCtr2 = 1;nCtr2 < pTbl->numColumns();nCtr2++)
{
// Get the text height for this cell
double nCurHeight = pTbl->textHeight(nCtr1,nCtr2);
nHeight = (nCurHeight > nHeight?nCurHeight:nHeight);
}
// Set the row height with the maximum height
pTbl->setRowHeight(nCtr1,(nHeight > maxHeight?maxHeight:nHeight) * 3);
}
pTbl->recomputeTableBlock();
return Acad::eOk;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -