1) Create new database (.odb file) 2) Create a macro in the database, e.g.: Sub Tst() MsgBox "Tst" End Tst() 3) Create a dialog in the database 4) save as e.g. foo.odb 5) exit LibreOffice 6) Launch LibreOffice 7) Open foo.odb 8) Run the macro; this forces the loading of the "Standard" Basic library of the .odb file. DO NOT load the Dialog library in any way. 9) Make a change to the database: e.g. create a new report. 10) "File/save" (or the equivalent toolbar button) does not do anything If one either does not run any macro (not load the basic library) or loads the Dialog library, then the save works. I traced this back to: In dbaccess/source/core/dataaccess/ModelImpl.[hc]xx, m_xDialogLibraries is set (as a reference), but the library is NOT LOADED. On save: - ODatabaseDocument::store calls - ODatabaseDocument::impl_storeToStorage_throw calls - ODatabaseDocument::impl_writeStorage_throw calls - ODatabaseModelImpl::storeLibraryContainersTo has this code: if ( m_xDialogLibraries.is() ) m_xDialogLibraries->storeLibrariesToStorage( _rxToRootStorage ); That is, it calls SfxDialogLibraryContainer::storeLibrariesToStorage (baisc/source/uno/dlgcont.cxx) as soon as m_xDialogLibraries is a valid reference. Then: - SfxDialogLibraryContainer::storeLibrariesToStorage iterates over the libraries - within a library (variable xLib) it iterates over the dialogs in that library: Sequence< OUString > sDialogs = xLib->getElementNames(); sal_Int32 nDialogs( sDialogs.getLength() ); for ( sal_Int32 j=0; j < nDialogs; ++j ) { // Each Dialog has an associated xISP Reference< io::XInputStreamProvider > xISP; xLib->getByName( sDialogs[ j ] ) >>= xISP; And here you have it: getByName is called on xLib, but xLib is not loaded. Meaning (in file basic/source/uno/namecont.cxx): - SfxLibraryContainer::getByName calls - SfxLibrary::getByName The first thing that SfxLibrary::getByName does is impl_checkLoaded(); which raises WrappedTargetException (with an empty message!), because the library is not loaded. I see three places where this can be "fixed" and I'm not sure which is the "right fix". Please advise. 1) Remove call to impl_checkLoaded() from SfxLibrary::getByName Then it returns a NULL reference, and SfxDialogLibraryContainer::storeLibrariesToStorage handles that well: xLib->getByName( sDialogs[ j ] ) >>= xISP; if ( xISP.is() ) 2) Add to SfxDialogLibraryContainer::storeLibrariesToStorage before the code above: if ( ! xLib->isLibraryLoaded(sDialogs[ j ]) ) { continue; } 3) Change ODatabaseModelImpl::storeLibraryContainersTo from if ( m_xDialogLibraries.is() ) m_xDialogLibraries->storeLibrariesToStorage( _rxToRootStorage ); to if ( m_xDialogLibraries.is() && m_xDialogLibraries->isModified() ) m_xDialogLibraries->storeLibrariesToStorage( _rxToRootStorage ); And the same for m_xBasicLibraries, obviously. Analysis: I have a bad feeling about number "3)"; it corrects this specific bug, but it may still be the case that some Dialog libraries are modified and others are not loaded... and then we are in trouble again. Number 1) essentially changes the guarantees given by getByName; it was guaranteed to return a valid Reference or throw an exception, and now it can return a NULL reference, which can break existing code. OTOH, if some other code somewhere _also_ calls getByName without _first_ checking whether the library is loaded (but properly checks whether it got a valid reference afterwards), it will also fix that yet undiscovered bug :) Number 2) has the symmetric advantages and disadvantages of number 1)... It won't make previously valid code invalid (the guarantees given by getByName don't change), but it lets responsibility to check for isLibraryLoaded _before_ to callers of getByName, which is a recipe for future similar bugs IMHO.
Created attachment 50199 [details] Solution #1
Created attachment 50204 [details] Solution #2
Created attachment 50206 [details] load library before getting it Sorry, I got on a completely wrong track in my previous thoughts. A comment shows that this code expects the libraries to already be loaded. As this is not the case, here is a patch that ... simply loads the library before getting it. The only small thing I'm not 100% sure of is whether this load should or should not go under scope of the "if xLib.is()".
@ Lionel:since you propose a patch, pls mail to the dev-list and attach the patch
Created attachment 50310 [details] testcase
I reproduced with master, a clone as of earlier today 17 August 2011. Precise reproduction instructions: - start LO with Macro Security to Medium (or Low) - open testcase attached to this bug - when asked click on button "enable macros" - a MessageBox saying "Main! Main!" pops up - click "OK" to dismiss - click on "Reports" (left part of screen, last entry) - right-click on "Report11" - choose "delete" in the pop-up menu - confirm by clicking on button "delete" - click on "save" toolbar button (floppy disk image) Notice that the toolbar button does not get deactivated. Exit LO; discard changes. Open LO again, notice Report11 is still there.
Since I cloned, someone pushed my patch, so fixed in master, commit 03e9161e2eca9d389d7ce419495538c31f6aed31.