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