On 8/8/05, Andreas Schlüns <[EMAIL PROTECTED]> wrote:
Hello Andrzej !


Good job !

Thanks :-)

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.

OK, I'm trying to get those done right now, but have some questions.


> * 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.

OK, I was wondering why did I have to implement all those methods, does deriving from XAWindow
somehow overwrite the inheritance of WeakImplHelper<XTypeProvider, XServiceInfo > ?

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 ...

So I guess I'll drop the XAWindow inheritance totally ;-)



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

Yes, that's the confusing part. It's garbage that stayed in the
code from the very first XWindow tests. It's for creating tabs
and corresponding windows for demo purposes and should be
moved to the basic code.

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().

OK, so the TabControl should be like a static class member?
I mean as in : common for all instances ?

I'm a bit confused with the design concept here. I'll explain how
I understand what should be happening now:

1. We have a cMyWindow class which draws the parent window,
adds a control m_xTabControl derived from SimpleTabController
which gets a XTabListener attached later on.
2. We add child windows to the cMyWindow with a addChildWindow()
(this is currently done during initialization of cMyWindow which makes a
pretty bad mess and will be corrected and moved to basic ASAP)
3. in addChildWindow() we do :
   - create an appropriate tab and assing the ID to the window's reference (by a sChildWindow struct)
   - add the struct to our list
   - make the new window active
   - resize appropriately
4. We listen for resize events on the m_xTabControl's parent window and resize the active child

So, as far as this is right, I believe that the m_xTabControl should be a singleton, right ?
Or should the whole cMyWindow be ?

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);

OK

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);

OK

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.

Yes, I left that like this on purpose - to see that both windows are properly handled
by the component. It'll be corrected.


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 .-)

OK, I thought about throwing IndexOutOfBounds if the ID is not found by
findChildWindow(), I guess that would be enough if I caught it inside the functions
using findChildWindow()?


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.

Right now it's held alive by the TabListener and ResizeListener, I think ;-)

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

a) refresh menus on tab activate/deactivate

what menus !? :-) where ?

b) closing all frames (documents) if the tab window is closed

(...)

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())

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 .-))

Same here. I really enjoy this. The UNO has a really great design

Regards
Andreas

Andrzej.


Reply via email to