Hi all,
Does anyone have a clue why this very simple code which is trying to set a read-only attribute on a new level results in epic fail?
(for the reference, this code works correctly in V8i)
LevelId levelId = 0; DgnModelRefP modelRef = mdlModelRef_getActive (); if ( SUCCESS == mdlLevel_create ( &levelId, modelRef, L"TestLevel", LEVEL_NULL_CODE ) ) { bool statOld = false, statNew = false; int ret = 0, stat = 0; mdlLevel_getReadOnly ( &statOld, modelRef, levelId ); ret = mdlLevel_setReadOnly ( modelRef, levelId, ! statOld ); // flip state stat = mdlLevelTable_rewrite ( modelRef ); if ( stat ) printf ( "TABLE REWRITE failed, ERROR %d\n", stat ); else printf ( "TABLE REWRITE OK\n" ); mdlLevel_getReadOnly ( &statNew, modelRef, levelId ); if ( ret || statOld == statNew ) { printf ( "EPIC FAIL! error %d, level %lu, state: Read%s\n", ret, levelId, statNew ? "Only" : "Write" ); } else { printf ( "PASSED! level %lu OK\n", levelId ); mdlLevel_setReadOnly ( modelRef, levelId, statOld ); } mdlLevel_delete ( modelRef, levelId ); }
Best Regards,
/Chris
Hi Chris Zakrewsky ,
There may be cases defined in the help where you may want to capture and react to the return code for mdlLevel_getReadOnly; that may have some additional helpful information if it is (currently) silently failing and permitted to proceed.
Although I have not examined mdlLevel_getReadOnly and if the return code does not reveal any hidden issues, I do see some other (internal) code using mdlLevel_isReadOnly; presumably successfully and may be worth a quick check if it provided different/better results.
HTH,Bob
Hi Robert,
mdlLevel_isReadOnly returns SUCCESS.
mdlLevel_setReadOnly also returns SUCCESS but fails silently.
Following (ready to run) code gives following output:
Test:EPIC FAIL! error 0, level 21, state: ReadWrite
if ( *tcb->dgnfilenm ) { LevelId levelId = 0; DgnModelRefP modelRef = mdlModelRef_getActive (); WCharCP levelNameP = L"TestLevel"; printf ( "\nTest:\n" ); if ( SUCCESS == mdlLevel_create ( &levelId, modelRef, levelNameP, LEVEL_NULL_CODE ) ) { bool statOld = false, statNew = false; int readOnlyStat = mdlLevel_getReadOnly ( &statOld, modelRef, levelId ); if ( readOnlyStat ) { WString errText = L""; mdlLevelError_getMessage ( errText, readOnlyStat ); printf ( "WARNING! error %d, level %lu: %S\n", readOnlyStat, levelId, errText.GetWCharCP() ); } mdlErrno = 0; int ret = mdlLevel_setReadOnly ( modelRef, levelId, ! statOld ); // flip state if ( mdlErrno ) { printf ( "FAIL! mdlErrno %d, level %lu\n", ret, levelId ); } if ( ret || statOld == statNew ) { printf ( "EPIC FAIL! error %d, level %lu, state: Read%s\n", ret, levelId, statNew ? "Only" : "Write" ); } else { mdlLevel_getReadOnly ( &statNew, modelRef, levelId ); printf ( "PASSED! level %lu, state: Read%s\n", levelId, statNew ? "Only" : "Write" ); } mdlLevel_delete ( modelRef, levelId ); } else { mdlLevel_getIdFromName ( &levelId, modelRef, LEVEL_NULL_ID, levelNameP ); if ( levelId ) { mdlLevel_delete ( modelRef, levelId ); printf ( "DELETED level %lu: %S\n", levelId, levelNameP ); } } } else printf ( "Oops! No DGN file!\n" );
Cheers,
/Chris Z.
It increasingly looks to me that mdlLevel_getReadOnly is broken.
Because following code:
if ( *tcb->dgnfilenm ) { LevelId levelId = 0; DgnModelRefP modelRef = mdlModelRef_getActive (); WCharCP levelNameP = L"TestLevel1"; printf ( "\nTest:\n" ); DgnFileP fileObjP = mdlModelRef_getDgnFile ( modelRef ); FileLevelCache& levelCache = fileObjP->GetLevelCacheR (); EditLevelHandle level = levelCache.CreateLevel ( levelNameP, LEVEL_NULL_CODE, LEVEL_NULL_ID ); bool statOld = level.GetReadOnly (); levelCache.SetLevelReadOnly ( level, ! statOld ); bool statNew = level.GetReadOnly (); if ( statOld == statNew ) { printf ( "EPIC FAIL! level %lu, state: Read%s\n", level.GetLevelId (), statNew ? "Only" : "Write" ); } else printf ( "PASSED! level %lu, state: Read%s\n", level.GetLevelId (), statNew ? "Only" : "Write" ); if ( LevelCacheErrorCode::None != levelCache.RemoveLevel ( NULL, level ) ) { printf ( "CAN NOT DELETE level %lu: %S\n", levelId, levelNameP ); } else printf ( "DELETED level %lu: %S\n", levelId, levelNameP ); levelCache.SetLevelReadOnly ( level, ! statNew ); if ( LevelCacheErrorCode::None != levelCache.RemoveLevel ( NULL, level ) ) { printf ( "CAN NOT DELETE level %lu: %S\n", levelId, levelNameP ); } else printf ( "DELETED level %lu: %S\n", levelId, levelNameP ); } else printf ( "Oops! No DGN file!\n" );
works correctly!
And produces following output:
Test:PASSED! level 22, state: ReadOnlyCAN NOT DELETE level 22: TestLevel1DELETED level 22: TestLevel1