Apache OpenOffice (AOO) Bugzilla – Issue 90158
Can't close floating Gallery window when OOo is embedded
Last modified: 2017-05-20 10:48:06 UTC
When an application on Windows "embeds" OOo Writer in a window of its own, and you have last had the Gallery window (Tools:Gallery) open (either floating or docked) in a normal freestanding OOo, the Gallery window is opened too (as floating), and can't be closed. Clicking on the close button of the Gallery window's title bar does nothing. Unfortunately the embedding application is rather huge, and I don't have access to its source code, so I am not able to pick out code from it to reproduce this with a minimal test program. As far as I understand from spending too much time in the debugger, the critical place where the behaviour differs between closing a floating Gallery window of a freestanding OOo and one of an embedded one is in sfx2/source/control/dispatch.cxx, in SfxDispatcher::_FindServer(), around line 2482: // Shell und Slot passen zusammen if ( !( ( bIsContainerSlot && bIsContainerShell ) || ( !bIsContainerSlot && bIsServerShell ) ) ) pSlot = 0; In the embedded case bIsContainerShell=0, bIsContainerSlot=1 and bIsServerShell=1. In the freestanding case again at that point bIsContainerShell=1. This means that in the embeddes case pSlot gets set to 0, and then later: if ( pSlot ) { rServer.SetSlot(pSlot); rServer.SetShellLevel(i); return sal_True; } the condition thus is false. In the freestanding case this is where SfxDispatcher::_FindServer() returns sal_True, which apparently then means that the Gallery window does close. In the embedded case sal_False is returned, and the attempt to close the window is ignored. Hopefully somebody understands the code and what is going on... I think the ideal solution to this would be that docking windows wouldn't be opened at all in an embedded OOo instance, but it would be enough if it was possible to close them at least...
So if I just comment out the code // Shell und Slot passen zusammen if ( !( ( bIsContainerSlot && bIsContainerShell ) || ( !bIsContainerSlot && bIsServerShell ) ) ) pSlot = 0; my problem goes away. Of course, I have no idea what else might change in an undesired way...
This would be a complete disaster as then all other slots that must not be available in embedded objects would work. This is no solution. Perhaps a third category of slots is necessary - neither "container" nor "server". But this will take some work.
Thanks. I suspected it could't be that easy...
So if the code snippet that sets pSlot = 0 is bypassed only if nSlot==SID_GALLERY? (As that is the particular case that have been complained about...) What awful side effects could that have? Yeah, this is a totally ugly solution, but the best I can come up with right now as I don't understand the code well enough to fix it properly. And I am not even ashamed to admit that.
If this is a severe problem for you and you need an urgent fix - you can do that, it won't hurt. This solution of course would become awkward if you had more slots of that kind you would like to handle in the same way, e.g. Navigator, Database Beamer etc. I admit that this is an ugly problem, I already came across it by myself with the "Print" function that also doesn't work when the document is embedded. This is desired if the container also is an OOo document (as printing is meant to be done by the container, not the object) but it may be undesired if the container itself does not support printing at all (because it's a dumb one just made to carry objects). This stems from the OLE protocol on Windows and surely should become redesigned. The problem is that there are different kinds of containers: - OOo documents (using the OOo Embedding API) - other "dumb" UNO Embedding containers (using the same API) - Windows application documents (using OLE2 editing) - "dumb" containers (using OLE2 editing) While in case of the "real" containers (case 1 and 3) some functions (like e.g. Save and Print) should not or must not be available inside the object, some don't need to be in case 1 but then are missed in case 3 (Gallery) or 2 and 4 (even Print could be useful here). Finding a general solution is hard - especially if the used API doesn't offer a way for it (like in case of OLE2). We could surely fix that easily for OOo Embedding (case 2), but not for the OLE2 case. My best idea so far is to make all functions that are OOo specific "server" slots and implement an interceptor for them in the container. This would work for e.g. Gallery, but not for printing as (in my understanding) OLE2 requires that this is left for the container (and OLE2 does not support such interceptions).
Thanks for the long comment.
What is btw the fundamental difference between the "Gallery" dialog and for instance the "Navigator" dialog that makes the toolbar button for "Gallery" appear insensitive (greyed out) in an OLE-embedded OOo, while the toolbar button for "Navigator" works normally (is not greyed out)? This difference presumably is related to the closability; "Gallery" can't be closed by clicking on the close button in its right top corner, but "Navigator" can.
SID_NAVIGATOR is a "server" slot (means: available in OLE objects), SID_GALLERY is a "container" (means: available in OLE containers) slot. Both kinds of slots are available in "normal" mode as well but in case of OLE editing these special categories are used. So a possible fix would be to make SID_GALLERY a "server" slot - but it has the drawback that you can't switch it off when an OLE object is edited that doesn't know about this slot (e.g. Chart or Math and of course all external objects). This is true for SID_NAVIGATOR also BTW. If you wanted to go this way (would be fine for me): in svx/sdi/svx.sdi search for SID_GALLERY and set its property "Container" to FALSE. You must rebuild svx and at least one application (the one you want to test as an embedded object) to see the effect. BTW: you can read more about sfx2 dispatching implementation at http://wiki.services.openoffice.org/wiki/Framework/Article/Implementation_of_the_Dispatch_API_In_SFX2
Reset assigne to the default "issues@openoffice.apache.org".