📄 asdktable.cpp
字号:
// (C) Copyright 2003-2006 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
// Last modified date: 03 Dec 2003
#include "StdAfx.h"
#if defined(_DEBUG) && !defined(AC_FULL_DEBUG)
#error _DEBUG should not be defined except in internal Adesk debug builds
#endif
// Header File
#include "asdktable.h"
//-----------------------------------------------------------------------------
//----- Clean up routines
void deleteFieldData(FieldData *pFldData)
{
// delete char pointers since they were created on the heap
for (int i = 0; i < pFldData->length(); i++) delete[](TCHAR *)pFldData->at(i);
delete pFldData;
}
void deleteRowData(RowData *pRwData)
{
// delete pointers
for (int i = 0; i < pRwData->length(); i++) deleteFieldData(pRwData->at(i));
delete pRwData;
}
void deleteHdrRwMap(HdrRwMap *pHdrRw)
{
HdrRwMap::const_iterator itr = pHdrRw->begin();
while(!(itr == pHdrRw->end()))
{
delete[] itr->second;
delete[] itr->first;
itr++;
}
delete pHdrRw;
}
//-----------------------------------------------------------------------------
//----- Add entity to the database
Acad::ErrorStatus addEntToDwg(AcDbDatabase *pDb, AcDbEntity *pEnt )
{
Acad::ErrorStatus es;
if( pEnt )
{
AcDbBlockTable *pBtbl = NULL;
es = pDb->getBlockTable(pBtbl, AcDb::kForRead );
if( pBtbl )
{
AcDbBlockTableRecord *pBtblRcd = NULL;
Acad::ErrorStatus openStatus = pBtbl->getAt( ACDB_MODEL_SPACE, pBtblRcd, AcDb::kForWrite );
if( pBtbl )
es = pBtbl->close();
if( pBtblRcd )
{
es = pBtblRcd->appendAcDbEntity( pEnt );
pBtblRcd->close();
}
}
}
return es;
}
//-----------------------------------------------------------------------------
//----- Select entity on the screen
AcDbEntity* selectEntity(const TCHAR *pPrompt)
{
AcDbEntity *pEnt = NULL;
AcDbObjectId mId;
ads_point mPt;
ads_name mEname;
if ( RTNORM == acedEntSel(pPrompt, mEname, mPt))
{
if ( Acad::eOk == acdbGetObjectId(mId, mEname ))
{
if ( Acad::eOk == acdbOpenAcDbEntity(pEnt, mId, AcDb::kForWrite))
return pEnt;
}
}
return pEnt;
}
//-----------------------------------------------------------------------------
//----- Main function to create a new table for a given block definition
void buildTableFromBlock(const TCHAR *pBlkName, const TCHAR *pStyleName, bool bLink)
{
// To hold table data
RowData *pRwData = new RowData();
if (Acad::eOk == generateTableFromBlock(pBlkName, pRwData,bLink))
{
// Create the table
AcDbTable *pTbl = NULL;
// Note that first two rows contain data for title and header
// Hence use the third row for the correct column length
if(Acad::eOk == createTable(pTbl,pStyleName,pRwData->at(2)->length(),pRwData->length()))
{
// Populate the table with data
populateTable(pTbl, pRwData);
// Add the Table Object to the Model Space of the current drawing
if(Acad::eOk == addEntToDwg(acdbHostApplicationServices()->workingDatabase(),pTbl))
{
// Merge cells
mergeCellsForTitleAndHeader(pTbl,pBlkName);
// Fit the columns
fitColumnWidth(pTbl,200); // 200 - arbitrary upper limit value
// Fit the rows
fitRowHeight(pTbl,50); // 50 - arbitrary upper limit value
// Ask for the pick point
ads_point pt;
if(RTNORM == acedGetPoint(NULL,_T("\nSelect insertion point: "),pt))
{
pTbl->setPosition(AcGePoint3d(pt[X],pt[Y],pt[Z]));
}
// Close the table
pTbl->close();
}
else
{
// Clean up, if pTbl is not added to the model space
delete pTbl;
}
}
else
{
acutPrintf(_T("\nUnable to create new table"));
}
}
// Clean up
deleteRowData(pRwData);
}
//-----------------------------------------------------------------------------
//----- Main function to update existing table
void updateExistingTable(const TCHAR *pBlkName, const TCHAR *pStyleName, bool bLink)
{
AcDbTable *pTbl = NULL;
if(NULL == (pTbl = AcDbTable::cast(selectEntity(_T("\nSelect table to be updated...")))))
PRTMSGRET(_T("Selected entity was not a table"))
// To hold table data
RowData *pRwData = new RowData();
if (Acad::eOk == generateTableFromBlock(pBlkName, pRwData,bLink))
{
if(Acad::eOk == updateTable(pTbl,pStyleName,pRwData->at(2)->length(),pRwData->length()))
{
// Populate the table with data
populateTable(pTbl, pRwData);
// Merge cells
mergeCellsForTitleAndHeader(pTbl,pBlkName);
// Fit the columns
fitColumnWidth(pTbl,200);
// Fit the rows
fitRowHeight(pTbl,100);
}
else
{
acutPrintf(_T("\nUnable to update new table"));
}
}
// Close the entity
pTbl->close();
// Clean up
delete pRwData;
}
//-----------------------------------------------------------------------------
//----- Create new Table Style
Acad::ErrorStatus addTableStyle(const TCHAR *pStyleName)
{
AcDbDictionary *pDict = NULL;
acdbHostApplicationServices()->workingDatabase()->getTableStyleDictionary(pDict,AcDb::kForRead);
// Check if the Table Style is already existing
if(pDict->has(pStyleName))
{
pDict->close();
acdbFail(_T("Table Style already available"));
PRTMSGRETES(Acad::eCreateInvalidName);
}
// Create new Table Style
AcDbTableStyle *pTblStyle = new AcDbTableStyle();
pDict->upgradeOpen();
// You can also use the utility function postTableStyleToDb()
AcDbObjectId mObjId;
Acad::ErrorStatus es;
if(Acad::eOk != (es = pDict->setAt(pStyleName,pTblStyle,mObjId)))
{
pDict->close();
delete pTblStyle;
acdbFail(_T("\nUnable to add new Table Style"));
PRTMSGRETES(es);
}
// Close the dictionary
pDict->close();
// Settings for the new Table Style
pTblStyle->setFlowDirection(AcDb::kTtoB);
pTblStyle->setName(pStyleName);
// Set the title color
AcCmColor col;
col.setColorIndex(1); // Red color
pTblStyle->setColor(col,AcDb::kTitleRow);
// Set the header color
col.setColorIndex(2); // Yellow color
pTblStyle->setColor(col,AcDb::kHeaderRow);
// Alignment kMiddleCenter for all rows
pTblStyle->setAlignment(AcDb::kMiddleCenter,AcDb::kAllRows);
pTblStyle->close();
return Acad::eOk;
}
//-----------------------------------------------------------------------------
//----- Create a new table
Acad::ErrorStatus createTable(AcDbTable *&pTbl,const TCHAR *pTblStyle,
const int nColLen, const int nRowLen)
{
pTbl = new AcDbTable();
Acad::ErrorStatus es;
// Set the Table Style
AcDbDictionary *pDict = NULL;
AcDbObjectId idTblStyle;
acdbHostApplicationServices()->workingDatabase()->getTableStyleDictionary(pDict,AcDb::kForRead);
es = pDict->getAt(pTblStyle,idTblStyle);
pDict->close();
if(Acad::eOk == es) pTbl->setTableStyle(idTblStyle);
pTbl->setNumColumns(nColLen);
pTbl->setNumRows(nRowLen); // you can also use insertRows() at later point
pTbl->generateLayout(); // Very very important, else expect crashes later on
return es;
}
//-----------------------------------------------------------------------------
//----- Update existing table
Acad::ErrorStatus updateTable(AcDbTable *&pTbl, const TCHAR *pTblStyle ,
const int nColLen, const int nRowLen)
{
// Sanity check
if ((NULL == pTbl) || (!pTbl->isWriteEnabled())) PRTMSGRETES(Acad::eNotOpenForWrite)
Acad::ErrorStatus es;
// Set the Table Style
AcDbDictionary *pDict = NULL;
AcDbObjectId idTblStyle;
acdbHostApplicationServices()->workingDatabase()->getTableStyleDictionary(pDict,AcDb::kForRead);
es = pDict->getAt(pTblStyle,idTblStyle);
pDict->close();
if(Acad::eOk == es) pTbl->setTableStyle(idTblStyle);
// Clear existing rows and columns
// On existing table we cannot use setNumRows and setNumColumns
return setTableColAndRows(pTbl,nColLen,nRowLen);
}
//-----------------------------------------------------------------------------
//-----
Acad::ErrorStatus setTableColAndRows(AcDbTable *&pTbl, int nColLen, int nRowLen)
{
Acad::ErrorStatus es;
// Sanity check
if ((NULL == pTbl) || (!pTbl->isWriteEnabled())) PRTMSGRETES(Acad::eNotOpenForWrite)
// It is not possible to clear the column and row number on existing table
// Cannot use setNumColumns on a existing table, it will return eNotApplicable
// Delete the columns and rows and then recreate,but again cannot really delete all the rows and columns
if(1 < pTbl->numRows())
{
es = pTbl->deleteRows(1,pTbl->numRows() - 1);// Leave one row
}
if(1 < pTbl->numColumns())
{
es = pTbl->deleteColumns(1,pTbl->numColumns() - 1);// Leave one column
}
pTbl->generateLayout();
// Insert columns
es = pTbl->insertColumns(1,pTbl->columnWidth(0),nColLen - 1);
// Insert rows
es = pTbl->insertRows(1,pTbl->rowHeight(0),nRowLen - 1);
return pTbl->generateLayout();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -