[MSCE Update 17.2, C] Why a new level can not be set ReadOnly? (mdlLevel_setReadOnly fail)

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

Parents
  • Hi  ,

    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.

Reply
  • 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.

Children
  • 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: ReadOnly
    CAN NOT DELETE level 22: TestLevel1
    DELETED level 22: TestLevel1

    Cheers,

    /Chris Z.