You might find that when trying to assign a plot style to a layer using AcDbLayerTableRecord::setPlotStyleName(), it returns "eKeyNotFound" sometimes?
This is because PlotStyles and plotStyleNames are not the same. PlotStyleNames are just entries in the plotStyleName Dictionary (ACAD_PLOTSTYLENAME). They do not rely on the plotStyles in the STB files, nor are they automatically generated by plotStyles. The intent is the opposite of what you might think; the plotStyleName is used as a lookup name when AutoCAD looks for a plotStyle.
When setPlotStyleName returns "Acad::eKeyNotFound", it is indicating that there is no such entry in the plotStyleName Dictionary. To create a desired entry in this dictionary, you can use the AcDbDatabase::getPlotStyleNameDictionary() method to get a pointer to the plotStyleName dictionary (it is an object of class AcDbDictionaryWithDefault type that is derived from AcDbDictionary). You then need to create a new AcDbPlaceHolder object and add it to the plotStyleName dictionary using your desired plotStyleName as the entry's key.
Notice that the plotStyleName dictionary has a default entry "Normal" of AcDbPlaceHolder class. And the setPlotStyleName function returns an error status if the plot style cannot be found in the current plot style table (as this case), or if the drawing's PlotStyleMode is set to use color-based plot styles.
The following code shows how to do this:
static void setNewPlotStyleName()
{
AcDbDatabase* pDb = curDoc()->database();
AcDbDictionaryWithDefault* pDict = NULL;
Acad::ErrorStatus es = pDb->getPlotStyleNameDictionary(pDict,
AcDb::kForWrite);
if(es != Acad::eOk)
return;
AcDbPlaceHolder* pNewHolder = new AcDbPlaceHolder;
if(!pNewHolder)
{
pDict->close();
return;
}
AcDbObjectId newId;
const TCHAR newStyleName[] = _T("Sample plot style name");
es = pDict->setAt(newStyleName, pNewHolder, newId);
if(es != Acad::eOk)
{
delete pNewHolder;
pDict->close();
return;
}
// close the new object
pNewHolder->close();
// set the defaultId to be the new one
// you don't have to do this but this is to demonstrate
// that you can
es = pDict->setDefaultId(newId);
if(es != Acad::eOk)
{
// since it is already database resident
// we can only erase it
es = acdbOpenAcDbObject((AcDbObject *&)pNewHolder, newId,
AcDb::kForWrite);
assert(es == Acad::eOk);
pNewHolder->erase();
pNewHolder->close();
pDict->close();
return;
}
pDict->close();
// open the current layer table record
AcDbLayerTableRecordPointer pLayerBtr(pDb->clayer(),
AcDb::kForWrite);
es = pLayerBtr.openStatus();
if(es == Acad::eOk)
{
// set its plot style name
es = pLayerBtr->setPlotStyleName(newStyleName);
if(es != Acad::eOk)
acutPrintf(_T("Error setting plot style name %s."),
newStyleName);
}
}
//// This should always work as long as
// someone has not altered the "Normal" name programmatically.
// Again this is for companion demonstration purpose.
//
static void setDefaultPlotStyleName()
{
const TCHAR styleName[] = _T("normal");
AcDbDatabase* pDb = curDoc()->database();
// open the current layer table record
AcDbLayerTableRecordPointer pLayerBtr(pDb->clayer(),
AcDb::kForWrite);
Acad::ErrorStatus es = pLayerBtr.openStatus();
if(es == Acad::eOk)
{
// set its plot style name
es = pLayerBtr->setPlotStyleName(styleName);
if(es != Acad::eOk)
acutPrintf(_T("Error setting plot style name %s."),
styleName);
}
}
