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