Hello Andrzej !
> I decided to stay with XAWindow for usage with TabListener, but I
> implemented XWindowListener inside my class. It looks like putting a
> TabListener to the same class will make it a bit crowded with
methods of
> similar names...
OK ... at least it's a design decision made by you. As I've already
mentioned ... why not ! .-)
I was thinking it over and over and hasitating between the option of
adding a new interface or implementing an existing one, but I thought
that things are a bit clearer this way. Maybe there is some third
alternative that would satisfy both needs, I don't know :/
It works - so let it .-)
There is not realy a "best way" to implement it.
So your implementation is usable in the same way, then the other ones.
<snip>
> Done. The createSingleFactory fix came out really helpful.
> Test basic now looks like this :
> Sub Main
>
> taskcreator = createUnoService("foo.AWindow")
> msgbox taskcreator.dbg_supportedInterfaces
>
> frame = taskcreator.createInstance()
> msgbox frame.dbg_supportedInterfaces
>
> frame.getContainerWindow().setVisible(TRUE)
>
> frame1 = taskcreator.createInstance()
> frame1.getContainerWindow ().setVisible(TRUE)
> End Sub
>
Works now. But you retrieve the ParentWindow everytimes a new frame
should be created. That's not neccessary. You can cache it. It's the
same TabControl providing the same TabParentWindow everytimes you are
asking for it.
OK
And further you register yourself as ResizeListener more
then ones on this ParentWindow. That's not needed (and by the way
dangerous) too. Why ?
mess++ I guess ;)
Yes .-)
Your reference exists inside such listener
container more then once (if call addListener() more then once). And
you
will be called back more then once .-)
Means: N times disposing() ... N times activate() ... and so on .-)
There is little mistake. Now you dont create two child windows ... but
you create two frames ... why ?
mess++ and also a little confusion from my part I think. I was trying to
figure out at which point the main window gets created - I understood
later that it's being created somehow by the TabControl, not by me. That
said, I don't really remember why hasn't it been thrown out yet ;-)
It's not created by you ... but you need it to be able to create child
windows. So you have to cache it.
<snip>
Further there is no need to create more then one ResizeListener.
This listener must forward resize events from 1 ParentWindow to X
ChildWindows. There is no need to forward resizes from the ChildWindows
back to e.g. the ParentWindow.
this is done to see if the children are switched properly, as you can
see the children have a different implementation of XWindowListener, the
only thing it does is broadcast a message
that an event has been trigerred on the child.
OK - I've overlooked that. Nice "debug feature" .-)
<snip>
I miss the menu handling and closing the frames ...
I'm working on it :-)
Fine.
But this version is nearly the "Finish" of our last non optional step !
wow, I didn't think it would be *that* simple :-)
As I've already said: UNO can make things simple ...
If the programmer understand the designs behind ...
That's the big part .-)
OK ... there are might some small problems left.
E.g. we know that we will have some trouble with focus handling.
But I thing it's not part of this project to solve these problems.
It seams that WE (means the OOo developers) have to make some further
changes - so it works as aspected.
I have some more remarks on my code, I'm not sure about a couple of things.
* What's the policy for exceptions ? I'd say that if I throw any
exceptions inside my class, which are not related to sam interface
implementation directly, I mean they're not mandatory, but added by me,
those exceptions should be caught by my class too, so there are no
unhandle ones, right?
Policy for exceptions ?
There are no rules defined, which are not defined in other projects too
.-) I'm personaly follow these rules:
1)
Never catch a RuntimeException (and exceptions derived from
RuntimeException). Every interface method is compiled with support
for RuntimeExceptions. Normaly such exceptions will kill the office
process ... but we hope that the user send the ErrorReport back to us,
so we can find the reason for this error. Of course our AutoRecovery
tool should make sure that all opened documents should be saved.
2)
All other exceptions should be catched and handled. Throwing it out can
kill the office. E.g. on solaris such exceptions passing due to an
interface, which does not declare it, will be handled as an "unexpected
one".
3)
Only declared and realy helpfull exceptions should be thrown away.
E.f. NoSuchElementExceptions on a container interface.
* About the mutex locks. I don't think that I understand this properly,
and I like to clean this thing up. You said that whenever I call any
outside services I should unlock, and I should use only copies of ref
counted objects to do so. This pretty much means, that I should lock
only when doing something with a class member, like, say, m_xActiveID =
5; right ?
Yes ... if the class member is not another UNO Service .-)
You should hold the lock alive to:
- read/write simple members (int, string, stl lists)
- and getting copies of more complex (may be UNO service based) objects
(e.g. listener)
Example:
member:
int m_nInt;
::rtl::OUString m_sText;
Reference< XInterface > m_xListener;
// open safe scope
::osl::ResettableMutexGuard aLock(m_aLock);
// allowed
m_nInt = 0;
m_sText += "Test";
Reference< XInterface > xCopy = m_xListener;
// not allowed
m_xListener->callSomething();
aLock.clear();
// safe scope closed
// allowed
xCopy->callSomething();
// not allowed
if (m_nInt == 0)
doSomething();
m_sText += "Test2";
m_xListener->callSomething();
* Further, you said that I should use UNO_QUERY_THROW when querying for
interfaces. Is that a general rule or does it apply only to vital stuff?
But then again - most, if not all, interfaces I query for are vital to
the application :/
UNO_QUERY_THROW should be used if you know that a service MUST(!)
implement this interface (otherwise the service does not full fill it's
own IDL definition) .. and you cant work without that interface.
Then this value force throwing of a RuntimeException, in case the
interface is not available at this service implementation.
You cant use this if a service has defined an optional interface !
Then you have to use UNO_QUERY and check for the return value.
It's a question about coding styles. It's not good to check everything
wich is possible. On the other side its not good to check nothing and
let it crash. But throwing an exception in case an expected interface
does not exists (but is important for your code) can be handled and must
not result into a crash ... but mostly it will .-)
Question: Which of the following code blocks seams to be more
understandable and(!) make the job right ?
void BLOCK_1()
{
Reference< XDesktop > xDesktop(
xSMGR->createInstance("com.sun.star.frame.Desktop"),
UNO_QUERY);
if ( xDesktop.is() )
xDesktop->addTerminateListener(this);
}
void BLOCK_2()
{
Reference< XDesktop > xDesktop(
xSMGR->createInstance("com.sun.star.frame.Desktop"),
UNO_QUERY_THROW);
xDesktop->addTerminateListener(this);
}
I preferr BLOCK_2(). It's clear that the desktop service has to
implement the interface XDesktop. You dont need the check for a valid
reference. And you can be sure that you are registered as listener ...
or the office dies by an unexpected (meanly programming!) error.
You dont need two days to find the problem, why you never will be called
back from the desktop instance .-)
* Finally, I'm not sure about the childWindows parent, I mean the one
setup in the windowDescriptor (wDesc) specifically, is it OK to put the
TabControlParentWindow there ?
Yes. You should move the code, where you get the TabParentWindow from
the TabControl to your lateInit() methd ... cache this parent window as
a member ... and use it everytimes for creating new child windows inside
the mentioned WindowDescriptor.
Regards
Andreas
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]