Apache OpenOffice (AOO) Bugzilla – Issue 93186
Impress slide not saved correctly
Last modified: 2008-09-09 18:30:25 UTC
1. Load attached Impress document. 2. Copy slide by Ctrl-C then Ctrl-V in slide sorter bar. Copied slide looks exactly like the original. As they should. 3. Save, close, load again. Bug: Now the two slides look differently.
Created attachment 56054 [details] Copy slide and slides look identical: OK. Save, close, reload: slides differ: not OK.
The content.xml in the new document created in step 3 has a seemingly broken tag for the second slide. The <draw:page> tag of the second slide does not have any attributes, unlike the tag of the first slide.
The root cause of this issue is that for the second, copied slide the wrong UNO API wrapper is created. Here is how this happens but beware, this is not for the faint of heart. The copy constructor of the SdrPage class contains the line *this = rSrcPage; which calls the assignment operator at a time when the new object is not yet fully initialized. Especially the virtual function table is not yet properly set up because the constructor of the derived class (SdPage) is yet to be called. Ugly as this is, it gets really bad when the assignment operator eventually triggers a call to createUnoPage(). Because the SdPage constructor has not yet been executed and the vtable is not yet in its final state, the virtual createUnoPage() method is called at the wrong class. Instead of SdPage it is called at SdrPage. As a result an instance of SvxFmDrawPage is created, not SdDrawPage(). This wrong wrapper is then used when the document is saved. Many Impress specific properties are not saved and when the document is loaded again the page with the wrong UNO wrapper looks different. The line *this = rSrcPage; is present since 2004 and one might think that this should have lead to problems earlier. Well, before a recent change the UNO wrappers have been volatile objects that were disposed when not used. Therefore the wrappers have been created with the wrong class all along but did not live long enough to cause any real harm. Only since a recent change the wrappers are kept alive as long as the SdrPage/SdPage objects. So now the wrong wrappers are not disposed and cause this and maybe other problems.
A fix has to get rid of *this = rSrcPage; in the copy constructor of SdrPage. Maybe the copy constructor can be replaced by a Clone() method. Maybe the assignment operator has to be called in a save way.
Seems to be broken between BEA300m2 and BEB300m3.
Broken between DEV300_m22 and DEV300_m23.
Target set to 3.0 because of Issue being a showstopper...
Fixed by disposing an API wrapper that may be created during construction of a new SdrPage object. This will force the next call to getUnoPage() to create a new wrapper, then with a fully constructed vtable in place. When no wrapper is created during construction then the behavior of the new SdrPage object will not change. I decided not to fix the root cause because that needs more time when done properly than we have right now. I will open a separate issue for this. Modified file is /svx/source/svdraw/svdpage.cxx rev. 1.65.34.1
I have opened issue 93212 to tackle the root cause of this issue.
I reviewed the fix and I can confirm that it is a small change that only reproduces the behavior prior to my changes that triggered the buggy code but only in the case of the current issue.
Verified in CWS under Linux.
Please verify.
Verified under Windows, too.
ok in OOo 3.00RC1 -> close