xref: /AOO41X/main/framework/source/tabwin/tabwindow.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_framework.hxx"
30 #include <tabwin/tabwindow.hxx>
31 #include <properties.h>
32 
33 //_________________________________________________________________________________________________________________
34 //	my own includes
35 //_________________________________________________________________________________________________________________
36 #include <threadhelp/resetableguard.hxx>
37 
38 //_________________________________________________________________________________________________________________
39 //	interface includes
40 //_________________________________________________________________________________________________________________
41 #include <com/sun/star/util/XURLTransformer.hpp>
42 #include <com/sun/star/awt/PosSize.hpp>
43 #include <com/sun/star/awt/WindowDescriptor.hpp>
44 #include <com/sun/star/beans/PropertyAttribute.hpp>
45 #include <com/sun/star/lang/DisposedException.hpp>
46 //_________________________________________________________________________________________________________________
47 //	includes of other projects
48 //_________________________________________________________________________________________________________________
49 #include <rtl/ustrbuf.hxx>
50 #include <tools/urlobj.hxx>
51 #include <vcl/svapp.hxx>
52 #include <vcl/window.hxx>
53 #include <vcl/wrkwin.hxx>
54 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
55 #include <toolkit/unohlp.hxx>
56 #endif
57 #include <comphelper/sequenceashashmap.hxx>
58 
59 //_________________________________________________________________________________________________________________
60 //	Defines
61 //_________________________________________________________________________________________________________________
62 //
63 
64 using namespace rtl;
65 using namespace com::sun::star;
66 
67 namespace framework
68 {
69 
70 //*****************************************************************************************************************
71 //	XInterface, XTypeProvider, XServiceInfo
72 //*****************************************************************************************************************
73 DEFINE_XINTERFACE_11                    (   TabWindow										                                   ,
74 											::cppu::OWeakObject                                                                ,
75                                             DIRECT_INTERFACE( css::lang::XTypeProvider								          ),
76                                             DIRECT_INTERFACE( css::lang::XServiceInfo								          ),
77 											DIRECT_INTERFACE( css::lang::XInitialization							          ),
78                                             DIRECT_INTERFACE( css::lang::XComponent                                           ),
79 											DIRECT_INTERFACE( css::awt::XWindowListener								          ),
80                                             DIRECT_INTERFACE( css::awt::XTopWindowListener                                    ),
81                                             DIRECT_INTERFACE( css::awt::XSimpleTabController                                  ),
82 											DERIVED_INTERFACE( css::lang::XEventListener, css::awt::XWindowListener           ),
83 											DIRECT_INTERFACE( css::beans::XMultiPropertySet							          ),
84                                             DIRECT_INTERFACE( css::beans::XFastPropertySet							          ),
85                                             DIRECT_INTERFACE( css::beans::XPropertySet								          )
86 										)
87 
88 DEFINE_XTYPEPROVIDER_11                 (   TabWindow								,
89                                             css::lang::XTypeProvider			    ,
90                                             css::lang::XServiceInfo				    ,
91 											css::lang::XInitialization				,
92                                             css::lang::XComponent                   ,
93 											css::awt::XWindowListener				,
94                                             css::awt::XTopWindowListener            ,
95                                             css::awt::XSimpleTabController          ,
96 											css::lang::XEventListener				,
97                                             css::beans::XMultiPropertySet           ,
98                                             css::beans::XFastPropertySet            ,
99                                             css::beans::XPropertySet
100 										)
101 
102 DEFINE_XSERVICEINFO_MULTISERVICE        (   TabWindow							,
103                                             ::cppu::OWeakObject                 ,
104                                             SERVICENAME_TABWINDOW				,
105 											IMPLEMENTATIONNAME_TABWINDOW
106 										)
107 
108 DEFINE_INIT_SERVICE                     (   TabWindow, {} )
109 
110 TabWindow::TabWindow( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager ) :
111     ThreadHelpBase( &Application::GetSolarMutex() )
112     , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
113     , ::cppu::OPropertySetHelper  ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
114     , m_bInitialized( sal_False )
115     , m_bDisposed( sal_False )
116     , m_nNextTabID( 1 )
117     , m_aTitlePropName( RTL_CONSTASCII_USTRINGPARAM( "Title" ))
118     , m_aPosPropName( RTL_CONSTASCII_USTRINGPARAM( "Position" ))
119     , m_xServiceManager( xServiceManager )
120     , m_aListenerContainer( m_aLock.getShareableOslMutex() )
121 {
122 }
123 
124 TabWindow::~TabWindow()
125 {
126 }
127 
128 //---------------------------------------------------------------------------------------------------------
129 // Helper
130 //---------------------------------------------------------------------------------------------------------
131 
132 void TabWindow::implts_LayoutWindows() const
133 {
134     const sal_Int32 nTabControlHeight = 30;
135 
136     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
137     ResetableGuard aLock( m_aLock );
138     css::uno::Reference< css::awt::XDevice > xDevice( m_xTopWindow, css::uno::UNO_QUERY );
139     css::uno::Reference< css::awt::XWindow > xWindow( m_xTopWindow, css::uno::UNO_QUERY );
140     css::uno::Reference< css::awt::XWindow > xTabControlWindow( m_xTabControlWindow );
141     css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow );
142     aLock.unlock();
143     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
144 
145     // Convert relativ size to output size.
146     if ( xWindow.is() && xDevice.is() )
147     {
148         css::awt::Rectangle  aRectangle  = xWindow->getPosSize();
149         css::awt::DeviceInfo aInfo       = xDevice->getInfo();
150         css::awt::Size       aSize       (  aRectangle.Width  - aInfo.LeftInset - aInfo.RightInset  ,
151                                             aRectangle.Height - aInfo.TopInset  - aInfo.BottomInset );
152 
153         css::awt::Size  aContainerWindowSize;
154         css::awt::Size  aTabControlSize;
155 
156         aContainerWindowSize.Width = aSize.Width;
157         aTabControlSize.Width = aSize.Width;
158 
159         aContainerWindowSize.Height = std::max( sal_Int32( 0 ), aSize.Height - nTabControlHeight );
160         aTabControlSize.Height = nTabControlHeight;
161 
162         xContainerWindow->setPosSize( 0, 0,
163                                       aContainerWindowSize.Width, aContainerWindowSize.Height,
164                                       css::awt::PosSize::POSSIZE );
165         xTabControlWindow->setPosSize( 0, std::max( nTabControlHeight, sal_Int32( aSize.Height - nTabControlHeight)),
166                                        aTabControlSize.Width, aTabControlSize.Height,
167                                        css::awt::PosSize::POSSIZE );
168     }
169 }
170 
171 TabControl* TabWindow::impl_GetTabControl( const css::uno::Reference< css::awt::XWindow >& rTabControlWindow ) const
172 {
173 	Window* pWindow = VCLUnoHelper::GetWindow( rTabControlWindow );
174 	if ( pWindow )
175         return (TabControl *)pWindow;
176     else
177         return NULL;
178 }
179 
180 void TabWindow::impl_SetTitle( const ::rtl::OUString& rTitle )
181 {
182     if ( m_xTopWindow.is() )
183     {
184         Window* pWindow = VCLUnoHelper::GetWindow(
185                             css::uno::Reference< css::awt::XWindow >(
186                                 m_xTopWindow, css::uno::UNO_QUERY ));
187         if ( pWindow )
188             pWindow->SetText( rTitle );
189     }
190 }
191 
192 void TabWindow::implts_SendNotification( Notification eNotify, sal_Int32 ID ) const
193 {
194     ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer(
195                                                         ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >*) NULL ) );
196     if (pContainer!=NULL)
197 	{
198         ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
199         while (pIterator.hasMoreElements())
200         {
201             try
202             {
203                 switch ( eNotify )
204                 {
205                     case NOTIFY_INSERTED:
206                         ((css::awt::XTabListener*)pIterator.next())->inserted( ID );
207                         break;
208                     case NOTIFY_REMOVED:
209                         ((css::awt::XTabListener*)pIterator.next())->removed( ID );
210                         break;
211                     case NOTIFY_ACTIVATED:
212                         ((css::awt::XTabListener*)pIterator.next())->activated( ID );
213                         break;
214                     case NOTIFY_DEACTIVATED:
215                         ((css::awt::XTabListener*)pIterator.next())->deactivated( ID );
216                         break;
217                     default:
218                         break;
219                 }
220             }
221             catch( css::uno::RuntimeException& )
222             {
223                 pIterator.remove();
224             }
225         }
226 	}
227 }
228 
229 void TabWindow::implts_SendNotification( Notification eNotify, sal_Int32 ID, const css::uno::Sequence< css::beans::NamedValue >& rSeq ) const
230 {
231     ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer(
232                                                         ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >*) NULL ) );
233     if (pContainer!=NULL)
234 	{
235         ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
236         while (pIterator.hasMoreElements())
237         {
238             try
239             {
240                 switch ( eNotify )
241                 {
242                     case NOTIFY_CHANGED:
243                         ((css::awt::XTabListener*)pIterator.next())->changed( ID, rSeq );
244                         break;
245                     default:
246                         break;
247                 }
248             }
249             catch( css::uno::RuntimeException& )
250             {
251                 pIterator.remove();
252             }
253         }
254 	}
255 }
256 
257 //---------------------------------------------------------------------------------------------------------
258 // Links
259 //---------------------------------------------------------------------------------------------------------
260 
261 IMPL_LINK( TabWindow, Activate, TabControl*, pTabControl )
262 {
263     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
264     ResetableGuard aLock( m_aLock );
265 
266     sal_Int32 nPageId = pTabControl->GetCurPageId();
267 
268     rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( nPageId ));
269     impl_SetTitle( aTitle );
270     aLock.unlock();
271     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
272 
273     implts_SendNotification( NOTIFY_ACTIVATED, nPageId );
274 
275     return 1;
276 }
277 
278 IMPL_LINK( TabWindow, Deactivate, TabControl*, pTabControl )
279 {
280     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
281     ResetableGuard aLock( m_aLock );
282     sal_Int32 nPageId = pTabControl->GetCurPageId();
283     aLock.unlock();
284     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
285 
286     implts_SendNotification( NOTIFY_DEACTIVATED, nPageId );
287 
288     return 1;
289 }
290 
291 //---------------------------------------------------------------------------------------------------------
292 // XInitilization
293 //---------------------------------------------------------------------------------------------------------
294 
295 void SAL_CALL TabWindow::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
296 throw (css::uno::Exception, css::uno::RuntimeException)
297 {
298     const rtl::OUString aTopWindowArgName( RTL_CONSTASCII_USTRINGPARAM( "TopWindow" ));
299     const rtl::OUString aSizeArgName( RTL_CONSTASCII_USTRINGPARAM( "Size" ));
300 
301     css::awt::Size aDefaultSize( 500, 500 );
302     css::awt::Size aSize( aDefaultSize );
303 
304     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
305     ResetableGuard aLock( m_aLock );
306     sal_Bool                                               bInitalized( m_bInitialized );
307 	css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xServiceManager );
308 	aLock.unlock();
309 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
310 
311     if ( !bInitalized )
312     {
313 		css::beans::PropertyValue				    aPropValue;
314 		css::uno::Reference< css::awt::XTopWindow > xTopWindow;
315         css::uno::Reference< css::awt::XToolkit >   xToolkit;
316         css::awt::WindowDescriptor                  aDescriptor;
317 
318         if ( xSMGR.is() )
319         {
320 			try
321             {
322                 xToolkit = css::uno::Reference< css::awt::XToolkit >(
323                     xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
324             }
325             catch ( css::uno::RuntimeException& )
326             {
327                 throw;
328             }
329             catch ( css::uno::Exception& )
330             {
331             }
332         }
333 
334         for ( int i = 0; i < aArguments.getLength(); i++ )
335         {
336             if ( aArguments[i] >>= aPropValue )
337             {
338                 if ( aPropValue.Name == aTopWindowArgName )
339                     aPropValue.Value >>= xTopWindow;
340                 else if ( aPropValue.Name == aSizeArgName )
341                 {
342                     aPropValue.Value >>= aSize;
343                     if ( aSize.Width <= 0 )
344                         aSize.Width = aDefaultSize.Width;
345                     if ( aSize.Height <= 0 )
346                         aSize.Height = aDefaultSize.Height;
347                 }
348             }
349         }
350 
351         if ( xToolkit.is() )
352         {
353             if ( !xTopWindow.is() )
354             {
355 			    // describe top window properties.
356 			    aDescriptor.Type                =   css::awt::WindowClass_TOP;
357 			    aDescriptor.ParentIndex         =   -1;
358 			    aDescriptor.Parent              =   css::uno::Reference< css::awt::XWindowPeer >();
359                 aDescriptor.Bounds              =   css::awt::Rectangle( 0, 0, aSize.Width, aSize.Height );
360 			    aDescriptor.WindowAttributes    =   0;
361 
362 			    try
363                 {
364                     xTopWindow = css::uno::Reference< css::awt::XTopWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
365                 }
366                 catch ( css::uno::RuntimeException& )
367                 {
368                     throw;
369                 }
370                 catch ( css::uno::Exception& )
371                 {
372                 }
373             }
374 
375             if ( xTopWindow.is() )
376             {
377 	            /* SAFE AREA ----------------------------------------------------------------------------------------------- */
378 			    aLock.lock();
379                 m_bInitialized = sal_True;
380 			    aLock.unlock();
381 	            /* SAFE AREA ----------------------------------------------------------------------------------------------- */
382 
383                 css::uno::Reference< css::awt::XWindow > xWindow( xTopWindow, css::uno::UNO_QUERY );
384                 xWindow->addWindowListener( css::uno::Reference< css::awt::XWindowListener >(
385 				    static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW ));
386 
387                 xTopWindow->addTopWindowListener( css::uno::Reference< css::awt::XTopWindowListener >(
388                     static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW ));
389 
390 				css::uno::Reference< css::awt::XWindow > xContainerWindow;
391 				css::uno::Reference< css::awt::XWindow > xTabControl;
392 
393 				// describe container window properties.
394 				aDescriptor.Type                =   css::awt::WindowClass_SIMPLE;
395 				aDescriptor.ParentIndex         =   -1;
396 				aDescriptor.Parent              =   css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY );
397 				aDescriptor.Bounds              =   css::awt::Rectangle(0,0,0,0);
398 				aDescriptor.WindowAttributes    =   0;
399 
400 				xContainerWindow = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
401 
402 				// create a tab control window properties
403 				aDescriptor.Type				= css::awt::WindowClass_SIMPLE;
404 				aDescriptor.WindowServiceName   = DECLARE_ASCII("tabcontrol");
405 				aDescriptor.ParentIndex			= -1;
406 				aDescriptor.Parent				= css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY );
407 				aDescriptor.Bounds				= css::awt::Rectangle( 0,0,0,0 );
408 				aDescriptor.WindowAttributes	= 0;
409 
410 				xTabControl = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
411 
412 				if ( xContainerWindow.is() && xTabControl.is() )
413 				{
414 	                /* SAFE AREA ----------------------------------------------------------------------------------------------- */
415 					aLock.lock();
416 					m_xTopWindow = xTopWindow;
417                     m_xContainerWindow = xContainerWindow;
418 					m_xTabControlWindow = xTabControl;
419 					aLock.unlock();
420 	                /* SAFE AREA ----------------------------------------------------------------------------------------------- */
421 
422 					xWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE );
423 
424                     vos::OGuard	aGuard( Application::GetSolarMutex() );
425                     Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
426                     if( pWindow )
427                         pWindow->Show( sal_True );
428 
429 					pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
430 					if ( pWindow )
431 						pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE  );
432 
433 					pWindow = VCLUnoHelper::GetWindow( xTabControl );
434 					if ( pWindow )
435                     {
436 						pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE  );
437                         TabControl* pTabControl = (TabControl *)pWindow;
438                         pTabControl->SetActivatePageHdl( LINK( this, TabWindow, Activate ));
439                         pTabControl->SetDeactivatePageHdl( LINK( this, TabWindow, Deactivate ));
440                     }
441 
442                     implts_LayoutWindows();
443 				}
444             }
445         }
446     }
447 }
448 
449 //---------------------------------------------------------------------------------------------------------
450 //	XComponent
451 //---------------------------------------------------------------------------------------------------------
452 void SAL_CALL TabWindow::dispose() throw (css::uno::RuntimeException)
453 {
454     // Send message to all listener and forget her references.
455     css::uno::Reference< css::lang::XComponent > xThis(
456         static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
457     css::lang::EventObject aEvent( xThis );
458 
459     m_aListenerContainer.disposeAndClear( aEvent );
460 
461     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
462 	ResetableGuard aLock( m_aLock );
463     css::uno::Reference< css::awt::XWindow > xTabControlWindow( m_xTabControlWindow );
464     css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow );
465     css::uno::Reference< css::awt::XTopWindow > xTopWindow( m_xTopWindow );
466     m_xTabControlWindow.clear();
467     m_xContainerWindow.clear();
468     m_xTopWindow.clear();
469     aLock.unlock();
470 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
471 
472     css::uno::Reference< css::lang::XComponent > xComponent( xTabControlWindow, css::uno::UNO_QUERY );
473     if ( xComponent.is() )
474         xComponent->dispose();
475 
476     xComponent = css::uno::Reference< css::lang::XComponent >( xContainerWindow, css::uno::UNO_QUERY );
477     if ( xComponent.is() )
478         xComponent->dispose();
479 
480     xComponent = css::uno::Reference< css::lang::XComponent >( xTopWindow, css::uno::UNO_QUERY );
481     if ( xComponent.is() )
482         xComponent->dispose();
483 
484     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
485 	aLock.lock();
486     m_bDisposed = sal_True;
487     aLock.unlock();
488     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
489 }
490 
491 void SAL_CALL TabWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
492 throw (css::uno::RuntimeException)
493 {
494 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
495 	ResetableGuard aLock( m_aLock );
496     if ( m_bDisposed )
497         return;
498     aLock.unlock();
499 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
500 
501     m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
502 }
503 
504 void SAL_CALL TabWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
505 throw (css::uno::RuntimeException)
506 {
507 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
508 	ResetableGuard aLock( m_aLock );
509     if ( m_bDisposed )
510         return;
511     aLock.unlock();
512 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
513 
514     m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
515 }
516 
517 //---------------------------------------------------------------------------------------------------------
518 // XEventListener
519 //---------------------------------------------------------------------------------------------------------
520 void SAL_CALL TabWindow::disposing( const css::lang::EventObject& )
521 throw( css::uno::RuntimeException )
522 {
523 }
524 
525 //---------------------------------------------------------------------------------------------------------
526 // XWindowListener
527 //---------------------------------------------------------------------------------------------------------
528 void SAL_CALL TabWindow::windowResized( const css::awt::WindowEvent& )
529 throw( css::uno::RuntimeException )
530 {
531     implts_LayoutWindows();
532 }
533 
534 void SAL_CALL TabWindow::windowMoved( const css::awt::WindowEvent& )
535 throw( css::uno::RuntimeException )
536 {
537 }
538 
539 void SAL_CALL TabWindow::windowShown( const css::lang::EventObject& )
540 throw( css::uno::RuntimeException )
541 {
542 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
543 	ResetableGuard aLock( m_aLock );
544 
545     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
546     if ( pTabControl )
547         pTabControl->Show();
548 
549     if ( m_xContainerWindow.is() )
550     {
551         Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
552         if ( pWindow )
553             pWindow->Show();
554     }
555 }
556 
557 void SAL_CALL TabWindow::windowHidden( const css::lang::EventObject& )
558 throw( css::uno::RuntimeException )
559 {
560 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
561 	ResetableGuard aLock( m_aLock );
562     if ( m_xContainerWindow.is() )
563     {
564         Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
565         if ( pWindow )
566             pWindow->Hide();
567     }
568 
569     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
570     if ( pTabControl )
571         pTabControl->Hide();
572 }
573 
574 //---------------------------------------------------------------------------------------------------------
575 // XTopWindowListener
576 //---------------------------------------------------------------------------------------------------------
577 void SAL_CALL TabWindow::windowOpened( const css::lang::EventObject& )
578 throw (css::uno::RuntimeException)
579 {
580 }
581 
582 void SAL_CALL TabWindow::windowClosing( const css::lang::EventObject& )
583 throw (css::uno::RuntimeException)
584 {
585     css::uno::Reference< css::lang::XComponent > xComponent( (OWeakObject *)this, css::uno::UNO_QUERY );
586     if ( xComponent.is() )
587         xComponent->dispose();
588 }
589 
590 void SAL_CALL TabWindow::windowClosed( const css::lang::EventObject& )
591 throw (css::uno::RuntimeException)
592 {
593 }
594 
595 void SAL_CALL TabWindow::windowMinimized( const css::lang::EventObject& )
596 throw (css::uno::RuntimeException)
597 {
598 }
599 
600 void SAL_CALL TabWindow::windowNormalized( const css::lang::EventObject& )
601 throw (css::uno::RuntimeException)
602 {
603 }
604 
605 void SAL_CALL TabWindow::windowActivated( const css::lang::EventObject& )
606 throw (css::uno::RuntimeException)
607 {
608 }
609 
610 void SAL_CALL TabWindow::windowDeactivated( const css::lang::EventObject& )
611 throw (css::uno::RuntimeException)
612 {
613 }
614 
615 //---------------------------------------------------------------------------------------------------------
616 //	XSimpleTabController
617 //---------------------------------------------------------------------------------------------------------
618 
619 ::sal_Int32 SAL_CALL TabWindow::insertTab()
620 throw (css::uno::RuntimeException)
621 {
622     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
623     ResetableGuard aLock( m_aLock );
624 
625     if ( m_bDisposed )
626         throw css::lang::DisposedException();
627 
628     sal_Int32 nNextTabID( m_nNextTabID++ );
629 
630     rtl::OUString aTitle;
631     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
632     if ( pTabControl )
633         pTabControl->InsertPage( sal_uInt16( nNextTabID ), aTitle );
634     aLock.unlock();
635     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
636 
637     implts_SendNotification( NOTIFY_INSERTED, nNextTabID );
638 
639     return nNextTabID;
640 }
641 
642 void SAL_CALL TabWindow::removeTab( ::sal_Int32 ID )
643 throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
644 {
645     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
646     ResetableGuard aLock( m_aLock );
647 
648     if ( m_bDisposed )
649         throw css::lang::DisposedException();
650 
651     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
652     if ( pTabControl )
653     {
654         sal_uInt16 nCurTabId = pTabControl->GetCurPageId();
655         sal_uInt16 nPos      = pTabControl->GetPagePos( sal_uInt16( ID ));
656         if ( nPos == TAB_PAGE_NOTFOUND )
657             throw css::lang::IndexOutOfBoundsException();
658         else
659         {
660             pTabControl->RemovePage( sal_uInt16( ID ));
661             nCurTabId = pTabControl->GetCurPageId();
662         }
663         aLock.unlock();
664         /* SAFE AREA ----------------------------------------------------------------------------------------------- */
665 
666         implts_SendNotification( NOTIFY_REMOVED, ID );
667 
668         // activate new tab if old tab was active!
669         nPos = pTabControl->GetPagePos( sal_uInt16( nCurTabId ));
670         if ( nPos != TAB_PAGE_NOTFOUND && nCurTabId != ID )
671             activateTab( nCurTabId );
672     }
673 }
674 
675 void SAL_CALL TabWindow::setTabProps( ::sal_Int32 ID, const css::uno::Sequence< css::beans::NamedValue >& Properties )
676 throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
677 {
678     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
679     ResetableGuard aLock( m_aLock );
680 
681     if ( m_bDisposed )
682         throw css::lang::DisposedException();
683 
684     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
685     if ( pTabControl )
686     {
687         sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
688         if ( nPos == TAB_PAGE_NOTFOUND )
689             throw css::lang::IndexOutOfBoundsException();
690         else
691         {
692             comphelper::SequenceAsHashMap aSeqHashMap( Properties );
693 
694             ::rtl::OUString aTitle  = pTabControl->GetPageText( sal_uInt16( ID ));
695             sal_Int32       nNewPos = nPos;
696 
697             aTitle = aSeqHashMap.getUnpackedValueOrDefault< ::rtl::OUString >(
698                                     m_aTitlePropName, aTitle );
699             pTabControl->SetPageText( sal_uInt16( ID ), aTitle );
700             nNewPos = aSeqHashMap.getUnpackedValueOrDefault< sal_Int32 >(
701                                     m_aPosPropName, nNewPos );
702             if ( nNewPos != sal_Int32( nPos ))
703             {
704                 nPos = sal_uInt16( nNewPos );
705                 if ( nPos >= pTabControl->GetPageCount() )
706                     nPos = TAB_APPEND;
707 
708                 pTabControl->RemovePage( sal_uInt16( ID ));
709                 pTabControl->InsertPage( sal_uInt16( ID ), aTitle, nPos );
710             }
711 
712             /* SAFE AREA ----------------------------------------------------------------------------------------------- */
713             aLock.unlock();
714 
715             css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq = getTabProps( ID );
716             implts_SendNotification( NOTIFY_CHANGED, ID, aNamedValueSeq );
717         }
718     }
719 }
720 
721 css::uno::Sequence< css::beans::NamedValue > SAL_CALL TabWindow::getTabProps( ::sal_Int32 ID )
722 throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
723 {
724     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
725     ResetableGuard aLock( m_aLock );
726 
727     if ( m_bDisposed )
728         throw css::lang::DisposedException();
729 
730     css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq;
731 
732     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
733     if ( pTabControl )
734     {
735         sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
736         if ( nPos == TAB_PAGE_NOTFOUND )
737             throw css::lang::IndexOutOfBoundsException();
738         else
739         {
740             rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID ));
741                           nPos   = pTabControl->GetPagePos( sal_uInt16( ID ));
742 
743             css::uno::Sequence< css::beans::NamedValue > aSeq( 2 );
744             aSeq[0].Name  = m_aTitlePropName;
745             aSeq[0].Value = css::uno::makeAny( aTitle );
746             aSeq[1].Name  = m_aPosPropName;
747             aSeq[1].Value = css::uno::makeAny( sal_Int32( nPos ));
748             return aSeq;
749         }
750     }
751     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
752 
753     return aNamedValueSeq;
754 }
755 
756 void SAL_CALL TabWindow::activateTab( ::sal_Int32 ID )
757 throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
758 {
759     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
760     ResetableGuard aLock( m_aLock );
761 
762     if ( m_bDisposed )
763         throw css::lang::DisposedException();
764 
765     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
766     if ( pTabControl )
767     {
768         sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
769         if ( nPos == TAB_PAGE_NOTFOUND )
770             throw css::lang::IndexOutOfBoundsException();
771         else
772         {
773             sal_Int32 nOldID     = pTabControl->GetCurPageId();
774             rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID ));
775             pTabControl->SetCurPageId( sal_uInt16( ID ));
776             pTabControl->SelectTabPage( sal_uInt16( ID ));
777             impl_SetTitle( aTitle );
778 
779             aLock.unlock();
780             /* SAFE AREA ----------------------------------------------------------------------------------------------- */
781 
782             if ( nOldID != TAB_PAGE_NOTFOUND )
783                 implts_SendNotification( NOTIFY_DEACTIVATED, nOldID );
784             implts_SendNotification( NOTIFY_ACTIVATED, ID );
785         }
786     }
787 }
788 
789 ::sal_Int32 SAL_CALL TabWindow::getActiveTabID()
790 throw (css::uno::RuntimeException)
791 {
792     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
793     ResetableGuard aLock( m_aLock );
794 
795     if ( m_bDisposed )
796         throw css::lang::DisposedException();
797 
798     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
799     if ( pTabControl )
800     {
801         sal_uInt16 nID = pTabControl->GetCurPageId();
802         if ( nID == TAB_PAGE_NOTFOUND )
803             return -1;
804         else
805             return sal_Int32( nID );
806     }
807 
808     return -1;
809     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
810 }
811 
812 void SAL_CALL TabWindow::addTabListener(
813     const css::uno::Reference< css::awt::XTabListener >& xListener )
814 throw (css::uno::RuntimeException)
815 {
816 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
817 	ResetableGuard aLock( m_aLock );
818     if ( m_bDisposed )
819         return;
820     aLock.unlock();
821 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
822 
823     m_aListenerContainer.addInterface(
824         ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener );
825 }
826 
827 void SAL_CALL TabWindow::removeTabListener( const css::uno::Reference< css::awt::XTabListener >& xListener )
828 throw (css::uno::RuntimeException)
829 {
830 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
831 	ResetableGuard aLock( m_aLock );
832     if ( m_bDisposed )
833         return;
834     aLock.unlock();
835 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
836 
837     m_aListenerContainer.removeInterface(
838         ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener );
839 }
840 
841 //---------------------------------------------------------------------------------------------------------
842 //	OPropertySetHelper
843 //---------------------------------------------------------------------------------------------------------
844 
845 // XPropertySet helper
846 sal_Bool SAL_CALL TabWindow::convertFastPropertyValue( css::uno::Any&       aConvertedValue ,
847 													   css::uno::Any&       aOldValue       ,
848                                                        sal_Int32			nHandle         ,
849 													   const css::uno::Any& aValue             )
850 throw( css::lang::IllegalArgumentException )
851 {
852 	//	Initialize state with sal_False !!!
853 	//	(Handle can be invalid)
854 	sal_Bool bReturn = sal_False;
855 
856     switch( nHandle )
857 	{
858         case TABWINDOW_PROPHANDLE_PARENTWINDOW :
859             bReturn = PropHelper::willPropertyBeChanged(
860                         com::sun::star::uno::makeAny( m_xContainerWindow ),
861                         aValue,
862                         aOldValue,
863                         aConvertedValue);
864                 break;
865 
866         case TABWINDOW_PROPHANDLE_TOPWINDOW :
867             bReturn = PropHelper::willPropertyBeChanged(
868                         com::sun::star::uno::makeAny( m_xTopWindow ),
869                         aValue,
870                         aOldValue,
871                         aConvertedValue);
872                 break;
873 	}
874 
875 	// Return state of operation.
876 	return bReturn ;
877 }
878 
879 void SAL_CALL TabWindow::setFastPropertyValue_NoBroadcast( sal_Int32,
880                                                            const css::uno::Any&)
881 throw( css::uno::Exception )
882 {
883 }
884 
885 void SAL_CALL TabWindow::getFastPropertyValue( css::uno::Any& aValue  ,
886                                                sal_Int32      nHandle    ) const
887 {
888     switch( nHandle )
889 	{
890         case TABWINDOW_PROPHANDLE_PARENTWINDOW:
891             aValue <<= m_xContainerWindow;
892             break;
893         case TABWINDOW_PROPHANDLE_TOPWINDOW:
894             aValue <<= m_xTopWindow;
895             break;
896     }
897 }
898 
899 ::cppu::IPropertyArrayHelper& SAL_CALL TabWindow::getInfoHelper()
900 {
901 	// Optimize this method !
902 	// We initialize a static variable only one time. And we don't must use a mutex at every call!
903 	// For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
904     static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
905 
906     if( pInfoHelper == NULL )
907 	{
908 		// Ready for multithreading
909         osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
910 
911 		// Control this pointer again, another instance can be faster then these!
912         if( pInfoHelper == NULL )
913 		{
914 			// Define static member to give structure of properties to baseclass "OPropertySetHelper".
915 			// "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
916 			// "sal_True" say: Table is sorted by name.
917             static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
918 			pInfoHelper = &aInfoHelper;
919 		}
920 	}
921 
922     return(*pInfoHelper);
923 }
924 
925 css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL TabWindow::getPropertySetInfo()
926 throw ( css::uno::RuntimeException )
927 {
928 	// Optimize this method !
929 	// We initialize a static variable only one time. And we don't must use a mutex at every call!
930 	// For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
931     static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = NULL;
932 
933     if( pInfo == NULL )
934 	{
935 		// Ready for multithreading
936 		osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
937 		// Control this pointer again, another instance can be faster then these!
938         if( pInfo == NULL )
939 		{
940 			// Create structure of propertysetinfo for baseclass "OPropertySetHelper".
941 			// (Use method "getInfoHelper()".)
942             static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
943 			pInfo = &xInfo;
944 		}
945 	}
946 
947 	return (*pInfo);
948 }
949 
950 const css::uno::Sequence< css::beans::Property > TabWindow::impl_getStaticPropertyDescriptor()
951 {
952 	// Create a new static property array to initialize sequence!
953 	// Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
954 	// Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
955 	// It's necessary for methods of OPropertySetHelper.
956 	// ATTENTION:
957     //      YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
958 
959     static const com::sun::star::beans::Property pProperties[] =
960 	{
961         com::sun::star::beans::Property( TABWINDOW_PROPNAME_PARENTWINDOW,
962                                          TABWINDOW_PROPHANDLE_PARENTWINDOW,
963                                          ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
964                                          com::sun::star::beans::PropertyAttribute::READONLY  ),
965         com::sun::star::beans::Property( TABWINDOW_PROPNAME_TOPWINDOW,
966                                          TABWINDOW_PROPHANDLE_TOPWINDOW,
967                                          ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
968                                          com::sun::star::beans::PropertyAttribute::READONLY  )
969 	}; 	// Use it to initialize sequence!
970     static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, TABWINDOW_PROPCOUNT );
971 
972 	// Return static "PropertyDescriptor"
973     return lPropertyDescriptor;
974 }
975 
976 }
977