Andrzej Wytyczak-Partyka wrote:
Hi Andreas !

I'm fighting with those damn listeners right now, this is really hard.
I have some remarks on this.
1. When I close a document inside the Tab, the tab is not removed.
    That could be fixed by keeping the FrameActionListener on the
    child frame and listening on COMPONENT_DETACHING events.
    This way whenever user closes a document opened inside a tab
    the tab itself closes too. I think that would also work with the File->
    mechanism.

COMPONENT_DETACHING is definetly wrong. It does not describe closing of the frame. After such COMPONENT_DETACHING a COMPONENT_ATTACHING can follow. That can happen incase the same is reused for loading another component (document).

You have to listen as XCloseListener on every frame you created for a callback notifyClosing(). Only here you can be sure, that a frame will be closed. And only here you should remove your tab.

Question: How do you close the document inside the tab ?


2. Whenever a Component is disposed it calls the disposing() method
    of listeners attached to it. Those listeners should then clear all the
references to this component, but there's no need to call removeEventListener()
    because that will be done inside the component itself. So, I added an
    event listener to the frame component, to check if it's being disposed.

If you are registered as e.g. XCloseListener on a frame, there is no need to register yourself as XEventListener too. Because XCloseListener is derived from XEventListener. And after XCloseListenr::notifyClosing() a XEventListener::disposing() will be called automaticly.

OK - I see. For your purpose it's enough to react on disposing() call's sent by the frame. Because there is not realy a different between notifyClosing() and disposing(). In both cases the frame will die ... and you have to veto against that.

It would be different in case your tabbed environment wishes to stop closing of frames. But I dont see any reason here doing so.

=> forget the XCloseListener .. listen for disposing() events on frames only


3. When the TopWindow's close button is hit the TopWindow listener - me - is notified with disposing(), so I go through the list of frames and issue the dispatch command .uno:FrameClose. But ! I don't get the notifyClosing from any frame, nor is the disposing method of the EventListener listinening on the frames called ! So I think there's
    something wrong with my dispatch. It looks like this :

Reference< ::css::frame::XDispatchHelper > xDispatch(
m_xServiceManager->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.frame.DispatchHelper")),
                                                        UNO_QUERY_THROW);

Reference< XDispatchProvider > xDP((*childListIter).m_cFrame, UNO_QUERY_THROW);

xDispatch->executeDispatch(xDP, ::rtl::OUString::createFromAscii(".uno:CloseFrame"), ::rtl::OUString::createFromAscii(""), 0, Sequence< ::css::beans::PropertyValue >()
                                        );


For me the dispatch code looks fine. For debugging purposes you can try to close frames direct using the XCloseable API ...
You must get a notifyClosing() and disposing() event !

4. When the File->Exit is hit the notifyClosing() is called properly, I have some other
    problems here, but I'm still woking on it.

So you get this event on closing frames. Here my question again:
How do you clos your frames for testing ... using menu/toolbar ...?

5. I have some problems with m_refCount, after cleaning everything up it's still up to 3,
    and that's even if I force the child frames to dispose :-/
    I can't find the reason for this yet.

That can be reasoned by your listener registrations.
If e.g. all frames was closed manually (e.g. by using File->Close inside every open frame) nobody will be responsible to close the TabControl and it's windows. So your object will be registered e.g. as XTopWindowListener and XWindowListener there.
You hold the TabControl alive ... and the TabControl holds you.
Such ring-references can be killed by dispose() e.g. the TabControl explicitly.


OK ... here the set of listener interfaces and callbacks, which should be implemented by your component:

a)
m_xTabParentWindow => XWindowListener::windowResized()
to resize all child windows if the parent window was changed by the user.

b)
every cFrame instance => XFrameActionListener::frameAction(COMPONENT_ATTACHED)
to retrieve a XMenuBar object there and cache it.

c)
every cFrame instance => XFrameActionListener::frameAction(COMPONENT_REATTACHED) to update a cached XMenuBar in case a new document was loaded into the same frame

d)
every cFrame instance => XFrameActionListener::frameAction(COMPONENT_DETTACHED)
to forget the cached XMenuBar (nothing more!)

e)
every cFrame instance =>
XEventListener::disposing()
Note: Because you are already XFrameActionListener on every frame, there is no need to register yourself as XEventListener there again.
Inside the disposing() callback youhas to locate the tab and your
internal tab-info structure. Release it only - dont call dispose() there.

f)
m_xTopWindow => XEventListener::disposing()
to know that the user will close the application.
Here you do the following:
You call XDesktop::terminate() on the m_xDesktop instance (instead of try to close all frames manually using the dispatch .-)
That will close all open documents (means frames).
Every closed frame will call you with disposing(xFrame).
(see e) what you has to do then ...)
If terminate() returns TRUE, you call dispose() on your m_xTabControl member. That will call you back within XEventListener::disposing() for
- you registration on m_xTopWindow
- and your registration on m_xTabParentWindow
Forget these member references then.

Normaly then all listener registrations should be gone.
all frames/documents should be closed ...
and the office itself should start it's real termination.


Regards,
Andrzej

Have fun .-)
Andreas

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to