//OPM calls this function for each property to obtain a list of strings and cookies if they are available.
//For our textstyle property we would like to display all the textstyles currently available in the database.
//This function is declared on the IPerPropertyBrowsing interface. Our IOPMPropertyExtensionImpl
//class implements this member by reading the values in the OPM property map. (You set this up in your
//head file when you use BEGIN_OPMPROP_MAP, OPMPROP_ENTRY, END_OPMPROP_MAP macros.)
//Since we need a dynamic list of entries in this drop down list and a static map cannot implement this, 
//we need to override this function a provide dynamic list of text styles to OPM.
STDMETHODIMP CComPolygon::GetPredefinedStrings(DISPID dispID, CALPOLESTR *pCaStringsOut, CADWORD *pCaCookiesOut)
{
    if (dispID != DISPID_TEXTSTYLENAME)
        return  IOPMPropertyExtensionImpl<CComPolygon>::GetPredefinedStrings(dispID,pCaStringsOut,pCaCookiesOut);
    USES_CONVERSION;
    AcDbTextStyleTable* pTT;
    
    AcDbDatabase *pDb = m_objRef.objectId().database();
    if (NULL == pDb)
        pDb = acdbHostApplicationServices()->workingDatabase();
    
    if (pDb->getTextStyleTable(pTT,AcDb::kForRead)==Acad::eOk)
    {
        AcDbTextStyleTableIterator* pIter;
        if (pTT->newIterator(pIter)==Acad::eOk)
        {
            long size = 0;

            // Clear the array.
            mObjectIdArray.removeAll();

            for (pIter->start();!pIter->done();pIter->step())
                size++;
            pCaStringsOut->pElems = (LPOLESTR *)::CoTaskMemAlloc(sizeof(LPOLESTR) * size);
            pCaCookiesOut->pElems = (DWORD *)::CoTaskMemAlloc(sizeof(DWORD) * size);
            long i=0;
            for (pIter->start();!pIter->done();pIter->step())
            {
                AcDbTextStyleTableRecord* pTTR;
                if (pIter->getRecord(pTTR,AcDb::kForRead)!=Acad::eOk)
                    continue;
                const TCHAR* pName = NULL;
                if (pTTR->getName(pName)==Acad::eOk){
                    //we want to show the name of the textstyle as 
                    //it appears in the database
                    pCaStringsOut->pElems[i] = ::SysAllocString(CT2W(pName));
                    pCaCookiesOut->pElems[i] = mObjectIdArray.append(pTTR->objectId());
                }
                pTTR->close();
                i++;
            }
            pCaStringsOut->cElems = i;
            pCaCookiesOut->cElems = i;
        }
        if (pIter)
            delete pIter;
        pTT->close();
    }
    return S_OK;
}
// AsdkEdReactor is derived from AcEditorReactor
//
void
AsdkEdReactor::beginDeepCloneXlation(AcDbIdMapping& idMap,
    Acad::ErrorStatus* es)
{
    if (idMap.deepCloneContext() == AcDb::kDcWblock
        && getYorN(_T("Wblock all Text Styles")))
    {
        AcDbDatabase *pOrigDb, *pDestDb;
        if (idMap.origDb(pOrigDb) != Acad::eOk)
            return;
        *es = idMap.destDb(pDestDb);
        if (*es != Acad::eOk)
            return;

        AcDbTextStyleTable *pTsTable;
        *es = pOrigDb->getSymbolTable(pTsTable,
            AcDb::kForRead);
        if (*es != Acad::eOk)
            return;

        AcDbTextStyleTableIterator *pTsIter;
        *es = pTsTable->newIterator(pTsIter);
        if (*es != Acad::eOk) {
            pTsTable->close();
            return;
        }
        AcDbTextStyleTableRecord *pTsRecord;
        AcDbObject *pClonedObj;
        for (; !pTsIter->done(); pTsIter->step()) {
            *es = pTsIter->getRecord(pTsRecord,
                AcDb::kForRead);
            if (*es != Acad::eOk) {
                delete pTsIter;
                pTsTable->close();
                return;
            }
            // We don't need to check for already cloned
            // Records.  If the Text Style is already
            // cloned, wblockClone will return Acad::eOk
            // and pCloneObj will be NULL.
            //
            pClonedObj = NULL;
            *es = pTsRecord->wblockClone(pDestDb,
                pClonedObj, idMap, Adesk::kFalse);
            if (*es != Acad::eOk) {
                pTsRecord->close();
                delete pTsIter;
                pTsTable->close();
                return;
            }
            *es = pTsRecord->close();
            if (*es != Acad::eOk) {
                delete pTsIter;
                pTsTable->close();
                return;
            }
            if (pClonedObj != NULL) {
                *es = pClonedObj->close();
                if (*es != Acad::eOk) {
                    delete pTsIter;
                    pTsTable->close();
                    return;
                }
            }
        }
        delete pTsIter;
        *es = pTsTable->close();
    }
}