xref: /trunk/main/framework/source/tabwin/tabwindow.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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/helper/vclunohelper.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 relative 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 // XInitialization
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 {
293     const rtl::OUString aTopWindowArgName( RTL_CONSTASCII_USTRINGPARAM( "TopWindow" ));
294     const rtl::OUString aSizeArgName( RTL_CONSTASCII_USTRINGPARAM( "Size" ));
295 
296     css::awt::Size aDefaultSize( 500, 500 );
297     css::awt::Size aSize( aDefaultSize );
298 
299     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
300     ResetableGuard aLock( m_aLock );
301     sal_Bool                                               bInitialized( m_bInitialized );
302     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xServiceManager );
303     aLock.unlock();
304     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
305 
306     if ( !bInitialized )
307     {
308         css::beans::PropertyValue                   aPropValue;
309         css::uno::Reference< css::awt::XTopWindow > xTopWindow;
310         css::uno::Reference< css::awt::XToolkit >   xToolkit;
311         css::awt::WindowDescriptor                  aDescriptor;
312 
313         if ( xSMGR.is() )
314         {
315             try
316             {
317                 xToolkit = css::uno::Reference< css::awt::XToolkit >(
318                     xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
319             }
320             catch ( css::uno::RuntimeException& )
321             {
322                 throw;
323             }
324             catch ( css::uno::Exception& )
325             {
326             }
327         }
328 
329         for ( int i = 0; i < aArguments.getLength(); i++ )
330         {
331             if ( aArguments[i] >>= aPropValue )
332             {
333                 if ( aPropValue.Name == aTopWindowArgName )
334                     aPropValue.Value >>= xTopWindow;
335                 else if ( aPropValue.Name == aSizeArgName )
336                 {
337                     aPropValue.Value >>= aSize;
338                     if ( aSize.Width <= 0 )
339                         aSize.Width = aDefaultSize.Width;
340                     if ( aSize.Height <= 0 )
341                         aSize.Height = aDefaultSize.Height;
342                 }
343             }
344         }
345 
346         if ( xToolkit.is() )
347         {
348             if ( !xTopWindow.is() )
349             {
350                 // describe top window properties.
351                 aDescriptor.Type                =   css::awt::WindowClass_TOP;
352                 aDescriptor.ParentIndex         =   -1;
353                 aDescriptor.Parent              =   css::uno::Reference< css::awt::XWindowPeer >();
354                 aDescriptor.Bounds              =   css::awt::Rectangle( 0, 0, aSize.Width, aSize.Height );
355                 aDescriptor.WindowAttributes    =   0;
356 
357                 try
358                 {
359                     xTopWindow = css::uno::Reference< css::awt::XTopWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
360                 }
361                 catch ( css::uno::RuntimeException& )
362                 {
363                     throw;
364                 }
365                 catch ( css::uno::Exception& )
366                 {
367                 }
368             }
369 
370             if ( xTopWindow.is() )
371             {
372                 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
373                 aLock.lock();
374                 m_bInitialized = sal_True;
375                 aLock.unlock();
376                 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
377 
378                 css::uno::Reference< css::awt::XWindow > xWindow( xTopWindow, css::uno::UNO_QUERY );
379                 xWindow->addWindowListener( css::uno::Reference< css::awt::XWindowListener >(
380                     static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW ));
381 
382                 xTopWindow->addTopWindowListener( css::uno::Reference< css::awt::XTopWindowListener >(
383                     static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW ));
384 
385                 css::uno::Reference< css::awt::XWindow > xContainerWindow;
386                 css::uno::Reference< css::awt::XWindow > xTabControl;
387 
388                 // describe container window properties.
389                 aDescriptor.Type                =   css::awt::WindowClass_SIMPLE;
390                 aDescriptor.ParentIndex         =   -1;
391                 aDescriptor.Parent              =   css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY );
392                 aDescriptor.Bounds              =   css::awt::Rectangle(0,0,0,0);
393                 aDescriptor.WindowAttributes    =   0;
394 
395                 xContainerWindow = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
396 
397                 // create a tab control window properties
398                 aDescriptor.Type                = css::awt::WindowClass_SIMPLE;
399                 aDescriptor.WindowServiceName   = DECLARE_ASCII("tabcontrol");
400                 aDescriptor.ParentIndex         = -1;
401                 aDescriptor.Parent              = css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY );
402                 aDescriptor.Bounds              = css::awt::Rectangle( 0,0,0,0 );
403                 aDescriptor.WindowAttributes    = 0;
404 
405                 xTabControl = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
406 
407                 if ( xContainerWindow.is() && xTabControl.is() )
408                 {
409                     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
410                     aLock.lock();
411                     m_xTopWindow = xTopWindow;
412                     m_xContainerWindow = xContainerWindow;
413                     m_xTabControlWindow = xTabControl;
414                     aLock.unlock();
415                     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
416 
417                     xWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE );
418 
419                     vos::OGuard aGuard( Application::GetSolarMutex() );
420                     Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
421                     if( pWindow )
422                         pWindow->Show( sal_True );
423 
424                     pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
425                     if ( pWindow )
426                         pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE  );
427 
428                     pWindow = VCLUnoHelper::GetWindow( xTabControl );
429                     if ( pWindow )
430                     {
431                         pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE  );
432                         TabControl* pTabControl = (TabControl *)pWindow;
433                         pTabControl->SetActivatePageHdl( LINK( this, TabWindow, Activate ));
434                         pTabControl->SetDeactivatePageHdl( LINK( this, TabWindow, Deactivate ));
435                     }
436 
437                     implts_LayoutWindows();
438                 }
439             }
440         }
441     }
442 }
443 
444 //---------------------------------------------------------------------------------------------------------
445 //  XComponent
446 //---------------------------------------------------------------------------------------------------------
dispose()447 void SAL_CALL TabWindow::dispose()
448 {
449     // Send message to all listener and forget her references.
450     css::uno::Reference< css::lang::XComponent > xThis(
451         static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
452     css::lang::EventObject aEvent( xThis );
453 
454     m_aListenerContainer.disposeAndClear( aEvent );
455 
456     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
457     ResetableGuard aLock( m_aLock );
458     css::uno::Reference< css::awt::XWindow > xTabControlWindow( m_xTabControlWindow );
459     css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow );
460     css::uno::Reference< css::awt::XTopWindow > xTopWindow( m_xTopWindow );
461     m_xTabControlWindow.clear();
462     m_xContainerWindow.clear();
463     m_xTopWindow.clear();
464     aLock.unlock();
465     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
466 
467     css::uno::Reference< css::lang::XComponent > xComponent( xTabControlWindow, css::uno::UNO_QUERY );
468     if ( xComponent.is() )
469         xComponent->dispose();
470 
471     xComponent = css::uno::Reference< css::lang::XComponent >( xContainerWindow, css::uno::UNO_QUERY );
472     if ( xComponent.is() )
473         xComponent->dispose();
474 
475     xComponent = css::uno::Reference< css::lang::XComponent >( xTopWindow, css::uno::UNO_QUERY );
476     if ( xComponent.is() )
477         xComponent->dispose();
478 
479     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
480     aLock.lock();
481     m_bDisposed = sal_True;
482     aLock.unlock();
483     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
484 }
485 
addEventListener(const css::uno::Reference<css::lang::XEventListener> & xListener)486 void SAL_CALL TabWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
487 {
488     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
489     ResetableGuard aLock( m_aLock );
490     if ( m_bDisposed )
491         return;
492     aLock.unlock();
493     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
494 
495     m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
496 }
497 
removeEventListener(const css::uno::Reference<css::lang::XEventListener> & xListener)498 void SAL_CALL TabWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
499 {
500     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
501     ResetableGuard aLock( m_aLock );
502     if ( m_bDisposed )
503         return;
504     aLock.unlock();
505     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
506 
507     m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
508 }
509 
510 //---------------------------------------------------------------------------------------------------------
511 // XEventListener
512 //---------------------------------------------------------------------------------------------------------
disposing(const css::lang::EventObject &)513 void SAL_CALL TabWindow::disposing( const css::lang::EventObject& )
514 {
515 }
516 
517 //---------------------------------------------------------------------------------------------------------
518 // XWindowListener
519 //---------------------------------------------------------------------------------------------------------
windowResized(const css::awt::WindowEvent &)520 void SAL_CALL TabWindow::windowResized( const css::awt::WindowEvent& )
521 {
522     implts_LayoutWindows();
523 }
524 
windowMoved(const css::awt::WindowEvent &)525 void SAL_CALL TabWindow::windowMoved( const css::awt::WindowEvent& )
526 {
527 }
528 
windowShown(const css::lang::EventObject &)529 void SAL_CALL TabWindow::windowShown( const css::lang::EventObject& )
530 {
531     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
532     ResetableGuard aLock( m_aLock );
533 
534     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
535     if ( pTabControl )
536         pTabControl->Show();
537 
538     if ( m_xContainerWindow.is() )
539     {
540         Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
541         if ( pWindow )
542             pWindow->Show();
543     }
544 }
545 
windowHidden(const css::lang::EventObject &)546 void SAL_CALL TabWindow::windowHidden( const css::lang::EventObject& )
547 {
548     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
549     ResetableGuard aLock( m_aLock );
550     if ( m_xContainerWindow.is() )
551     {
552         Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
553         if ( pWindow )
554             pWindow->Hide();
555     }
556 
557     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
558     if ( pTabControl )
559         pTabControl->Hide();
560 }
561 
562 //---------------------------------------------------------------------------------------------------------
563 // XTopWindowListener
564 //---------------------------------------------------------------------------------------------------------
windowOpened(const css::lang::EventObject &)565 void SAL_CALL TabWindow::windowOpened( const css::lang::EventObject& )
566 {
567 }
568 
windowClosing(const css::lang::EventObject &)569 void SAL_CALL TabWindow::windowClosing( const css::lang::EventObject& )
570 {
571     css::uno::Reference< css::lang::XComponent > xComponent( (OWeakObject *)this, css::uno::UNO_QUERY );
572     if ( xComponent.is() )
573         xComponent->dispose();
574 }
575 
windowClosed(const css::lang::EventObject &)576 void SAL_CALL TabWindow::windowClosed( const css::lang::EventObject& )
577 {
578 }
579 
windowMinimized(const css::lang::EventObject &)580 void SAL_CALL TabWindow::windowMinimized( const css::lang::EventObject& )
581 {
582 }
583 
windowNormalized(const css::lang::EventObject &)584 void SAL_CALL TabWindow::windowNormalized( const css::lang::EventObject& )
585 {
586 }
587 
windowActivated(const css::lang::EventObject &)588 void SAL_CALL TabWindow::windowActivated( const css::lang::EventObject& )
589 {
590 }
591 
windowDeactivated(const css::lang::EventObject &)592 void SAL_CALL TabWindow::windowDeactivated( const css::lang::EventObject& )
593 {
594 }
595 
596 //---------------------------------------------------------------------------------------------------------
597 //  XSimpleTabController
598 //---------------------------------------------------------------------------------------------------------
599 
insertTab()600 ::sal_Int32 SAL_CALL TabWindow::insertTab()
601 {
602     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
603     ResetableGuard aLock( m_aLock );
604 
605     if ( m_bDisposed )
606         throw css::lang::DisposedException();
607 
608     sal_Int32 nNextTabID( m_nNextTabID++ );
609 
610     rtl::OUString aTitle;
611     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
612     if ( pTabControl )
613         pTabControl->InsertPage( sal_uInt16( nNextTabID ), aTitle );
614     aLock.unlock();
615     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
616 
617     implts_SendNotification( NOTIFY_INSERTED, nNextTabID );
618 
619     return nNextTabID;
620 }
621 
removeTab(::sal_Int32 ID)622 void SAL_CALL TabWindow::removeTab( ::sal_Int32 ID )
623 {
624     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
625     ResetableGuard aLock( m_aLock );
626 
627     if ( m_bDisposed )
628         throw css::lang::DisposedException();
629 
630     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
631     if ( pTabControl )
632     {
633         sal_uInt16 nCurTabId = pTabControl->GetCurPageId();
634         sal_uInt16 nPos      = pTabControl->GetPagePos( sal_uInt16( ID ));
635         if ( nPos == TAB_PAGE_NOTFOUND )
636             throw css::lang::IndexOutOfBoundsException();
637         else
638         {
639             pTabControl->RemovePage( sal_uInt16( ID ));
640             nCurTabId = pTabControl->GetCurPageId();
641         }
642         aLock.unlock();
643         /* SAFE AREA ----------------------------------------------------------------------------------------------- */
644 
645         implts_SendNotification( NOTIFY_REMOVED, ID );
646 
647         // activate new tab if old tab was active!
648         nPos = pTabControl->GetPagePos( sal_uInt16( nCurTabId ));
649         if ( nPos != TAB_PAGE_NOTFOUND && nCurTabId != ID )
650             activateTab( nCurTabId );
651     }
652 }
653 
setTabProps(::sal_Int32 ID,const css::uno::Sequence<css::beans::NamedValue> & Properties)654 void SAL_CALL TabWindow::setTabProps( ::sal_Int32 ID, const css::uno::Sequence< css::beans::NamedValue >& Properties )
655 {
656     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
657     ResetableGuard aLock( m_aLock );
658 
659     if ( m_bDisposed )
660         throw css::lang::DisposedException();
661 
662     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
663     if ( pTabControl )
664     {
665         sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
666         if ( nPos == TAB_PAGE_NOTFOUND )
667             throw css::lang::IndexOutOfBoundsException();
668         else
669         {
670             comphelper::SequenceAsHashMap aSeqHashMap( Properties );
671 
672             ::rtl::OUString aTitle  = pTabControl->GetPageText( sal_uInt16( ID ));
673             sal_Int32       nNewPos = nPos;
674 
675             aTitle = aSeqHashMap.getUnpackedValueOrDefault< ::rtl::OUString >(
676                                     m_aTitlePropName, aTitle );
677             pTabControl->SetPageText( sal_uInt16( ID ), aTitle );
678             nNewPos = aSeqHashMap.getUnpackedValueOrDefault< sal_Int32 >(
679                                     m_aPosPropName, nNewPos );
680             if ( nNewPos != sal_Int32( nPos ))
681             {
682                 nPos = sal_uInt16( nNewPos );
683                 if ( nPos >= pTabControl->GetPageCount() )
684                     nPos = TAB_APPEND;
685 
686                 pTabControl->RemovePage( sal_uInt16( ID ));
687                 pTabControl->InsertPage( sal_uInt16( ID ), aTitle, nPos );
688             }
689 
690             /* SAFE AREA ----------------------------------------------------------------------------------------------- */
691             aLock.unlock();
692 
693             css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq = getTabProps( ID );
694             implts_SendNotification( NOTIFY_CHANGED, ID, aNamedValueSeq );
695         }
696     }
697 }
698 
getTabProps(::sal_Int32 ID)699 css::uno::Sequence< css::beans::NamedValue > SAL_CALL TabWindow::getTabProps( ::sal_Int32 ID )
700 {
701     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
702     ResetableGuard aLock( m_aLock );
703 
704     if ( m_bDisposed )
705         throw css::lang::DisposedException();
706 
707     css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq;
708 
709     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
710     if ( pTabControl )
711     {
712         sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
713         if ( nPos == TAB_PAGE_NOTFOUND )
714             throw css::lang::IndexOutOfBoundsException();
715         else
716         {
717             rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID ));
718                           nPos   = pTabControl->GetPagePos( sal_uInt16( ID ));
719 
720             css::uno::Sequence< css::beans::NamedValue > aSeq( 2 );
721             aSeq[0].Name  = m_aTitlePropName;
722             aSeq[0].Value = css::uno::makeAny( aTitle );
723             aSeq[1].Name  = m_aPosPropName;
724             aSeq[1].Value = css::uno::makeAny( sal_Int32( nPos ));
725             return aSeq;
726         }
727     }
728     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
729 
730     return aNamedValueSeq;
731 }
732 
activateTab(::sal_Int32 ID)733 void SAL_CALL TabWindow::activateTab( ::sal_Int32 ID )
734 {
735     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
736     ResetableGuard aLock( m_aLock );
737 
738     if ( m_bDisposed )
739         throw css::lang::DisposedException();
740 
741     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
742     if ( pTabControl )
743     {
744         sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
745         if ( nPos == TAB_PAGE_NOTFOUND )
746             throw css::lang::IndexOutOfBoundsException();
747         else
748         {
749             sal_Int32 nOldID     = pTabControl->GetCurPageId();
750             rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID ));
751             pTabControl->SetCurPageId( sal_uInt16( ID ));
752             pTabControl->SelectTabPage( sal_uInt16( ID ));
753             impl_SetTitle( aTitle );
754 
755             aLock.unlock();
756             /* SAFE AREA ----------------------------------------------------------------------------------------------- */
757 
758             if ( nOldID != TAB_PAGE_NOTFOUND )
759                 implts_SendNotification( NOTIFY_DEACTIVATED, nOldID );
760             implts_SendNotification( NOTIFY_ACTIVATED, ID );
761         }
762     }
763 }
764 
getActiveTabID()765 ::sal_Int32 SAL_CALL TabWindow::getActiveTabID()
766 {
767     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
768     ResetableGuard aLock( m_aLock );
769 
770     if ( m_bDisposed )
771         throw css::lang::DisposedException();
772 
773     TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
774     if ( pTabControl )
775     {
776         sal_uInt16 nID = pTabControl->GetCurPageId();
777         if ( nID == TAB_PAGE_NOTFOUND )
778             return -1;
779         else
780             return sal_Int32( nID );
781     }
782 
783     return -1;
784     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
785 }
786 
addTabListener(const css::uno::Reference<css::awt::XTabListener> & xListener)787 void SAL_CALL TabWindow::addTabListener(
788     const css::uno::Reference< css::awt::XTabListener >& xListener )
789 {
790     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
791     ResetableGuard aLock( m_aLock );
792     if ( m_bDisposed )
793         return;
794     aLock.unlock();
795     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
796 
797     m_aListenerContainer.addInterface(
798         ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener );
799 }
800 
removeTabListener(const css::uno::Reference<css::awt::XTabListener> & xListener)801 void SAL_CALL TabWindow::removeTabListener( const css::uno::Reference< css::awt::XTabListener >& xListener )
802 {
803     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
804     ResetableGuard aLock( m_aLock );
805     if ( m_bDisposed )
806         return;
807     aLock.unlock();
808     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
809 
810     m_aListenerContainer.removeInterface(
811         ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener );
812 }
813 
814 //---------------------------------------------------------------------------------------------------------
815 //  OPropertySetHelper
816 //---------------------------------------------------------------------------------------------------------
817 
818 // XPropertySet helper
convertFastPropertyValue(css::uno::Any & aConvertedValue,css::uno::Any & aOldValue,sal_Int32 nHandle,const css::uno::Any & aValue)819 sal_Bool SAL_CALL TabWindow::convertFastPropertyValue( css::uno::Any&       aConvertedValue ,
820                                                        css::uno::Any&       aOldValue       ,
821                                                        sal_Int32            nHandle         ,
822                                                        const css::uno::Any& aValue             )
823 {
824     //  Initialize state with sal_False !!!
825     //  (Handle can be invalid)
826     sal_Bool bReturn = sal_False;
827 
828     switch( nHandle )
829     {
830         case TABWINDOW_PROPHANDLE_PARENTWINDOW :
831             bReturn = PropHelper::willPropertyBeChanged(
832                         com::sun::star::uno::makeAny( m_xContainerWindow ),
833                         aValue,
834                         aOldValue,
835                         aConvertedValue);
836                 break;
837 
838         case TABWINDOW_PROPHANDLE_TOPWINDOW :
839             bReturn = PropHelper::willPropertyBeChanged(
840                         com::sun::star::uno::makeAny( m_xTopWindow ),
841                         aValue,
842                         aOldValue,
843                         aConvertedValue);
844                 break;
845     }
846 
847     // Return state of operation.
848     return bReturn ;
849 }
850 
setFastPropertyValue_NoBroadcast(sal_Int32,const css::uno::Any &)851 void SAL_CALL TabWindow::setFastPropertyValue_NoBroadcast( sal_Int32,
852                                                            const css::uno::Any&)
853 {
854 }
855 
getFastPropertyValue(css::uno::Any & aValue,sal_Int32 nHandle) const856 void SAL_CALL TabWindow::getFastPropertyValue( css::uno::Any& aValue ,
857                                                sal_Int32      nHandle    ) const
858 {
859     switch( nHandle )
860     {
861         case TABWINDOW_PROPHANDLE_PARENTWINDOW:
862             aValue <<= m_xContainerWindow;
863             break;
864         case TABWINDOW_PROPHANDLE_TOPWINDOW:
865             aValue <<= m_xTopWindow;
866             break;
867     }
868 }
869 
getInfoHelper()870 ::cppu::IPropertyArrayHelper& SAL_CALL TabWindow::getInfoHelper()
871 {
872     // Optimize this method !
873     // We initialize a static variable only one time. And we don't need to use a mutex at every call!
874     // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
875     static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
876 
877     if( pInfoHelper == NULL )
878     {
879         // Ready for multithreading
880         osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
881 
882         // Control this pointer again, another instance can be faster then these!
883         if( pInfoHelper == NULL )
884         {
885             // Define static member to give structure of properties to baseclass "OPropertySetHelper".
886             // "impl_getStaticPropertyDescriptor" is a non exported and static function, who will define a static propertytable.
887             // "sal_True" say: Table is sorted by name.
888             static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
889             pInfoHelper = &aInfoHelper;
890         }
891     }
892 
893     return(*pInfoHelper);
894 }
895 
getPropertySetInfo()896 css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL TabWindow::getPropertySetInfo()
897 {
898     // Optimize this method !
899     // We initialize a static variable only one time. And we don't need to use a mutex at every call!
900     // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
901     static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = NULL;
902 
903     if( pInfo == NULL )
904     {
905         // Ready for multithreading
906         osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
907         // Control this pointer again, another instance can be faster then these!
908         if( pInfo == NULL )
909         {
910             // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
911             // (Use method "getInfoHelper()".)
912             static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
913             pInfo = &xInfo;
914         }
915     }
916 
917     return (*pInfo);
918 }
919 
impl_getStaticPropertyDescriptor()920 const css::uno::Sequence< css::beans::Property > TabWindow::impl_getStaticPropertyDescriptor()
921 {
922     // Create a new static property array to initialize sequence!
923     // Table of all predefined properties of this class. It's used from OPropertySetHelper-class!
924     // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
925     // It's necessary for methods of OPropertySetHelper.
926     // ATTENTION:
927     //      YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
928 
929     static const com::sun::star::beans::Property pProperties[] =
930     {
931         com::sun::star::beans::Property( TABWINDOW_PROPNAME_PARENTWINDOW,
932                                          TABWINDOW_PROPHANDLE_PARENTWINDOW,
933                                          ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
934                                          com::sun::star::beans::PropertyAttribute::READONLY  ),
935         com::sun::star::beans::Property( TABWINDOW_PROPNAME_TOPWINDOW,
936                                          TABWINDOW_PROPHANDLE_TOPWINDOW,
937                                          ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
938                                          com::sun::star::beans::PropertyAttribute::READONLY  )
939     };  // Use it to initialize sequence!
940     static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, TABWINDOW_PROPCOUNT );
941 
942     // Return static "PropertyDescriptor"
943     return lPropertyDescriptor;
944 }
945 
946 }
947