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