Hello Andrzej !

Hello all !

I'm just into finishing my *very* productive and exciting evening with the tab browse component :-)
Here's what I did over the last 4,5 hours :


Good job !
The first draft goes to the right directiony.
Of course it has some smaller problems .-)
But that's normal for a draft version.
Please have a look onto my comments below.

* Added lateInit from Andreas, although have some questions here (please see below)

Will be answered below too.

* Defined a couple of methods in the XAWindow interface
* And implemented the XAWindow interface in the component, this involved adding a couple of methods for compliance with XTypeProvider

Here some hints:

a)

Dont derive your class directly from an interface if you use the template cppu::WeakImplHelperX<>. Please adapt the list of interface already used within this template.
E.g.
class YourClass : public ::cppu::WeakImplHelper1< XInterface1 >
class YourClass : public ::cppu::WeakImplHelper2< XInterface1, XInterface2 > and so on. And further dont implement the methods of XInterface/XTypeProvider directly on your class, if you use WeakImplHelper! Because this template does it already for you. And it's not a good idea to have two ref count variables at the same object.

b)

You use a special interface XAWindow to forward resizes of the parent window to the child tab windows. Why not .-) But there is an easier way. You can add yourself (means your cMyWindow instance) as listener on the parent window. Then you have to implement the XWindowListener interface directly. So XAWindow is an indirection ...

* After that I was able to get a new TabListenerImpl(Reference<XInterface> xThis) working from the lateInit. * In TabListener I queried xThis for a XAWindow interface and called showChildWindow, hideChildWindow * Similar thing done in ResizeListener's (of the main window) resized() method.

So what I've got is :
* a main window showing two unaligned simple children windows inside, and a tab control with 2 tabs

Question: Why do you create two tabs everytime ?
It's not needed. You should create only one tab per createInstanceWithContext() request.

Further you should use a singleton mechanism to create the tab control itself one times only. Otherwhise you get n TabControls with 1 document. But we need 1 TabControl with n documents inside. How can it be reached?

You can implement a OneInstance service instance of a MultiService.
Patch your component_getFactory() method. Instead of using the cppu helper method cppu::createSingleFactory() ... you should use cppu::createOneInstanceFactory().

Some further hints:

a)
Please initialize every new created frame with the right window. The parent window of the tab control isnt the right one.

E.g.
XWindow xNewChild = xToolkit->create(...xParentWindow...);
XFrame  xNewFrame = xSMGR->createInstance("css.frame.Frame");
xNewFrame->initialize(xNewChild);

b)
Every new created (and intialized) frame must be added to the desktop container. Otherwhise our search mechanism for frames inside the office will be damaged. And it's needed e.g. to locate already loaded documents instead of opening it twice.

E.g.
XFramesSupplier xSupp(xDesktop, UNO_QUERY);
XFrames xContainer = xSupp->getFrames();
xContainer->append(xNewFrame);
xNewFrame->setCreator(xDesktop);

c)
Every new created child window should get the right size initialy.
Means: instead of using a default, you should use the actual size of the parent window. Otherwhise you open "small documents" inside big windows. And only the first move or resize of the parent window will bring the right size to the tab window.

* clicking the tabs results in hiding / showing of the appropriate child window. * resigin the main window results in resizing the active child window (to the same size as the parent's)

There is a small bug inside your code .-)
Your member m_activeID should be actualized everytime it's needed.
E.g.  initialiazing it inside ctor; actualizing if new tabs was created
And you should check the return value of findChildWindow() before you use it ... or it will crash sometimes .-)

Question regarding lateInit :
I observed that if I don't pass the reference of xThis anywhere outside of the component the object gets destroyed anyway. Is that ok, or did I copy&paste somethin wrong ;-) ? I might of.
I'm getting pretty tired ;-)

Your service will be hold alive by reference.
ParentWindowOfTabControl -> YourResizseListener -> (XAWindow)cMyWindow
If the parent window will be closed it removes your resize listener from it's container ... the listener dies and removes your cMyWindow reference (clearing it's member). So you cMyWindow instance will die too.

Anyway, the code is in here :

http://iapart.net/dav/soc/window_1st_working_RC1/

because the SF project has not yet been registered (SF staff complained about poor project description and rejected the registration. I already filed a patch).

I really like when things go as expected. Well, at least most of the time they did ;-)

Now you should implement the cosmetic changes I've mentioned above and start the next steps:

a) refresh menus on tab activate/deactivate
b) closing all frames (documents) if the tab window is closed

How ?

a)

You must know every created frame (according to the right tab ID).
Here the basic code to get the menu bar of a document.

rem Ask for the LayoutManager of the frame.
rem Use it to retrieve the menubar UIElement from it.
rem Note: If a frame was initialized with a window not
rem supporting the interface XTopWindow
rem a menu bar was not created! That's needed e.g. for the
rem beamer window, which uses child windows ..
rem but replaces the menubar of the outside application window
rem (where it's embedded).
rem In such case you have to create a menu bar UIElement hardly.
        
xFrameProps   = xFrame
xLM           = xFrameProps.getPropertyValue("LayoutManager")
xMenuUIElem   = xLM.getElement("private:resource/menubar/menubar")
if isNull(xMenuUIElem) then
        xLM.createElement("private:resource/menubar/menubar")
        xMenuUIElem = xLM.getElement("private:resource/menubar/menubar")
endif
        
if isNull(xMenuUIElem) then
        msgbox "Error: no menu"
        exit sub
endif

rem Ask the menu bar UIElement for it's XMenubar interface.     
rem and set it on you TabParentWindow
        
xMenuProps = xMenuUIElem
xMenuBar   = xMenuProps.getPropertyValue("XMenuBar")
rem xTopWindow = xTabParentWindow
rem xTopWindow.setMenuBar(xMenuBar)

b)

Add a XTopWindowListener on the TabParentWindow. You will be notified it the parent window is closed. The you should step over the list of all open frames and try to close it. But dont do it by calling XComponent->dispose() or XCloseable->close() ! We need a different APi here ... we must close it by dispatching an URL ".uno:CloseFrame" to every frame.
Why ?
If you close all frames by using the API it will not terminate the office. You have to do it explicitly. But if you use the dispatch API ... the office will be terminated atomaticly if the last frame was closed. You can use the office dispatch helper service to dispatch such URL very easy: (Here a basic script ...)

DispatchHelper = createUnoService("com.sun.star.frame.DispatchHelper")
dim NoArgs() as new com.sun.star.beans.PropertyValue
DispatchHelper.executeDispatch(xFrame, ".uno:CloseFrame", "", 0, NoArgs())


Cheers,
Andrzej

It's nice to see the progress of this project .-)
And it's further nice to see, how easy it can be to adopt the behaviour of OOo by implementing an external(!) UNO component, which can be registered as AddOn on Ooo .-))

Regards
Andreas

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

Reply via email to