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