1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/io/XMarkableStream.hpp>
21 #include <com/sun/star/uno/XComponentContext.hpp>
23 #include <toolkit/controls/stdtabcontrollermodel.hxx>
24 #include <toolkit/helper/macros.hxx>
25 #include <toolkit/helper/servicenames.hxx>
26 #include <toolkit/helper/property.hxx>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <cppuhelper/typeprovider.hxx>
29 #include <cppuhelper/queryinterface.hxx>
32 #include <tools/debug.hxx>
34 #define UNOCONTROL_STREAMVERSION (short)2
37 // class UnoControlModelEntryList
39 UnoControlModelEntryList::UnoControlModelEntryList()
43 UnoControlModelEntryList::~UnoControlModelEntryList()
48 void UnoControlModelEntryList::Reset()
50 for ( size_t n
= maList
.size(); n
; )
54 void UnoControlModelEntryList::DestroyEntry( size_t nEntry
)
56 UnoControlModelEntryListBase::iterator it
= maList
.begin();
57 ::std::advance( it
, nEntry
);
62 delete (*it
)->pxControl
;
68 size_t UnoControlModelEntryList::size() const {
72 UnoControlModelEntry
* UnoControlModelEntryList::operator[]( size_t i
) const {
73 return ( i
< maList
.size() ) ? maList
[ i
] : NULL
;
76 void UnoControlModelEntryList::push_back( UnoControlModelEntry
* item
) {
77 maList
.push_back( item
);
80 void UnoControlModelEntryList::insert( size_t i
, UnoControlModelEntry
* item
) {
81 if ( i
< maList
.size() ) {
82 UnoControlModelEntryListBase::iterator it
= maList
.begin();
83 ::std::advance( it
, i
);
84 maList
.insert( it
, item
);
86 maList
.push_back( item
);
92 // class StdTabControllerModel
94 StdTabControllerModel::StdTabControllerModel()
96 mbGroupControl
= true;
99 StdTabControllerModel::~StdTabControllerModel()
103 sal_uInt32
StdTabControllerModel::ImplGetControlCount( const UnoControlModelEntryList
& rList
) const
105 sal_uInt32 nCount
= 0;
106 size_t nEntries
= rList
.size();
107 for ( size_t n
= 0; n
< nEntries
; n
++ )
109 UnoControlModelEntry
* pEntry
= rList
[ n
];
110 if ( pEntry
->bGroup
)
111 nCount
+= ImplGetControlCount( *pEntry
->pGroup
);
118 void StdTabControllerModel::ImplGetControlModels( ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> ** ppRefs
, const UnoControlModelEntryList
& rList
) const
120 size_t nEntries
= rList
.size();
121 for ( size_t n
= 0; n
< nEntries
; n
++ )
123 UnoControlModelEntry
* pEntry
= rList
[ n
];
124 if ( pEntry
->bGroup
)
125 ImplGetControlModels( ppRefs
, *pEntry
->pGroup
);
128 **ppRefs
= *pEntry
->pxControl
;
134 void StdTabControllerModel::ImplSetControlModels( UnoControlModelEntryList
& rList
, const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& Controls
)
136 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> * pRefs
= Controls
.getConstArray();
137 sal_uInt32 nControls
= Controls
.getLength();
138 for ( sal_uInt32 n
= 0; n
< nControls
; n
++ )
140 UnoControlModelEntry
* pNewEntry
= new UnoControlModelEntry
;
141 pNewEntry
->bGroup
= false;
142 pNewEntry
->pxControl
= new ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> ;
143 *pNewEntry
->pxControl
= pRefs
[n
];
144 rList
.push_back( pNewEntry
);
148 sal_uInt32
StdTabControllerModel::ImplGetControlPos( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
>& rCtrl
, const UnoControlModelEntryList
& rList
)
150 for ( size_t n
= rList
.size(); n
; )
152 UnoControlModelEntry
* pEntry
= rList
[ --n
];
153 if ( !pEntry
->bGroup
&& ( *pEntry
->pxControl
== rCtrl
) )
156 return CONTROLPOS_NOTFOUND
;
159 void ImplWriteControls( const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XObjectOutputStream
> & OutStream
, const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& rCtrls
)
161 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XMarkableStream
> xMark( OutStream
, ::com::sun::star::uno::UNO_QUERY
);
162 DBG_ASSERT( xMark
.is(), "write: no XMarkableStream!" );
164 sal_uInt32 nStoredControls
= 0;
165 sal_Int32 nDataBeginMark
= xMark
->createMark();
167 OutStream
->writeLong( 0L ); // DataLen
168 OutStream
->writeLong( 0L ); // nStoredControls
170 sal_uInt32 nCtrls
= rCtrls
.getLength();
171 for ( sal_uInt32 n
= 0; n
< nCtrls
; n
++ )
173 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> xI
= rCtrls
.getConstArray()[n
];
174 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XPersistObject
> xPO( xI
, ::com::sun::star::uno::UNO_QUERY
);
175 DBG_ASSERT( xPO
.is(), "write: Control doesn't support XPersistObject" );
178 OutStream
->writeObject( xPO
);
182 sal_Int32 nDataLen
= xMark
->offsetToMark( nDataBeginMark
);
183 xMark
->jumpToMark( nDataBeginMark
);
184 OutStream
->writeLong( nDataLen
);
185 OutStream
->writeLong( nStoredControls
);
186 xMark
->jumpToFurthest();
187 xMark
->deleteMark(nDataBeginMark
);
190 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > ImplReadControls( const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XObjectInputStream
> & InStream
)
192 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XMarkableStream
> xMark( InStream
, ::com::sun::star::uno::UNO_QUERY
);
193 DBG_ASSERT( xMark
.is(), "write: no XMarkableStream!" );
195 sal_Int32 nDataBeginMark
= xMark
->createMark();
197 sal_Int32 nDataLen
= InStream
->readLong();
198 sal_uInt32 nCtrls
= InStream
->readLong();
200 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aSeq( nCtrls
);
201 for ( sal_uInt32 n
= 0; n
< nCtrls
; n
++ )
203 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XPersistObject
> xObj
= InStream
->readObject();
204 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> xI( xObj
, ::com::sun::star::uno::UNO_QUERY
);
205 aSeq
.getArray()[n
] = xI
;
208 // Skip remainder if more data exists than this version recognizes
209 xMark
->jumpToMark( nDataBeginMark
);
210 InStream
->skipBytes( nDataLen
);
211 xMark
->deleteMark(nDataBeginMark
);
216 // ::com::sun::star::uno::XInterface
217 ::com::sun::star::uno::Any
StdTabControllerModel::queryAggregation( const ::com::sun::star::uno::Type
& rType
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
219 ::com::sun::star::uno::Any aRet
= ::cppu::queryInterface( rType
,
220 (static_cast< ::com::sun::star::awt::XTabControllerModel
* >(this)),
221 (static_cast< ::com::sun::star::lang::XServiceInfo
* >(this)),
222 (static_cast< ::com::sun::star::io::XPersistObject
* >(this)),
223 (static_cast< ::com::sun::star::lang::XTypeProvider
* >(this)) );
224 return (aRet
.hasValue() ? aRet
: OWeakAggObject::queryAggregation( rType
));
227 // ::com::sun::star::lang::XTypeProvider
228 IMPL_XTYPEPROVIDER_START( StdTabControllerModel
)
229 cppu::UnoType
<com::sun::star::awt::XTabControllerModel
>::get(),
230 cppu::UnoType
<com::sun::star::lang::XServiceInfo
>::get(),
231 cppu::UnoType
<com::sun::star::io::XPersistObject
>::get()
232 IMPL_XTYPEPROVIDER_END
234 sal_Bool
StdTabControllerModel::getGroupControl( ) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
236 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
238 return mbGroupControl
;
241 void StdTabControllerModel::setGroupControl( sal_Bool GroupControl
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
243 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
245 mbGroupControl
= GroupControl
;
248 void StdTabControllerModel::setControlModels( const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& Controls
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
250 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
253 ImplSetControlModels( maControls
, Controls
);
256 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > StdTabControllerModel::getControlModels( ) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
258 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
260 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aSeq( ImplGetControlCount( maControls
) );
261 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> * pRefs
= aSeq
.getArray();
262 ImplGetControlModels( &pRefs
, maControls
);
266 void StdTabControllerModel::setGroup( const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& Group
, const OUString
& GroupName
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
268 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
270 // The controls might occur as a flat list and will be grouped.
271 // Nested groups are not possible.
272 // The first element of a group determines its position.
273 UnoControlModelEntry
* pNewEntry
= new UnoControlModelEntry
;
274 pNewEntry
->bGroup
= true;
275 pNewEntry
->pGroup
= new UnoControlModelEntryList
;
276 pNewEntry
->pGroup
->SetName( GroupName
);
277 ImplSetControlModels( *pNewEntry
->pGroup
, Group
);
279 bool bInserted
= false;
280 size_t nElements
= pNewEntry
->pGroup
->size();
281 for ( size_t n
= 0; n
< nElements
; n
++ )
283 UnoControlModelEntry
* pEntry
= (*pNewEntry
->pGroup
)[ n
];
284 if ( !pEntry
->bGroup
)
286 sal_uInt32 nPos
= ImplGetControlPos( *pEntry
->pxControl
, maControls
);
287 // At the beginning, all Controls should be in a flattened list
288 DBG_ASSERT( nPos
!= CONTROLPOS_NOTFOUND
, "setGroup - Element not found" );
289 if ( nPos
!= CONTROLPOS_NOTFOUND
)
291 maControls
.DestroyEntry( nPos
);
294 maControls
.insert( nPos
, pNewEntry
);
301 maControls
.push_back( pNewEntry
);
304 sal_Int32
StdTabControllerModel::getGroupCount( ) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
306 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
308 // Start with only one group layer, even though Model and Impl-methods
309 // work recursively, this is not presented to the outside.
311 sal_Int32 nGroups
= 0;
312 size_t nEntries
= maControls
.size();
313 for ( size_t n
= 0; n
< nEntries
; n
++ )
315 UnoControlModelEntry
* pEntry
= maControls
[ n
];
316 if ( pEntry
->bGroup
)
322 void StdTabControllerModel::getGroup( sal_Int32 nGroup
, ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& rGroup
, OUString
& rName
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
324 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
326 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aSeq
;
328 size_t nEntries
= maControls
.size();
329 for ( size_t n
= 0; n
< nEntries
; n
++ )
331 UnoControlModelEntry
* pEntry
= maControls
[ n
];
332 if ( pEntry
->bGroup
)
334 if ( nG
== (sal_uInt32
)nGroup
)
336 sal_uInt32 nCount
= ImplGetControlCount( *pEntry
->pGroup
);
337 aSeq
= ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >( nCount
);
338 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> * pRefs
= aSeq
.getArray();
339 ImplGetControlModels( &pRefs
, *pEntry
->pGroup
);
340 rName
= pEntry
->pGroup
->GetName();
349 void StdTabControllerModel::getGroupByName( const OUString
& rName
, ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& rGroup
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
351 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
353 sal_uInt32 nGroup
= 0;
354 size_t nEntries
= maControls
.size();
355 for ( size_t n
= 0; n
< nEntries
; n
++ )
357 UnoControlModelEntry
* pEntry
= maControls
[ n
];
358 if ( pEntry
->bGroup
)
360 if ( pEntry
->pGroup
->GetName() == rName
)
363 getGroup( nGroup
, rGroup
, Dummy
);
372 // ::com::sun::star::io::XPersistObject
373 OUString
StdTabControllerModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
375 return OUString::createFromAscii( szServiceName_TabControllerModel
);
378 void StdTabControllerModel::write( const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XObjectOutputStream
>& OutStream
) throw(::com::sun::star::io::IOException
, ::com::sun::star::uno::RuntimeException
, std::exception
)
380 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
382 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XMarkableStream
> xMark( OutStream
, ::com::sun::star::uno::UNO_QUERY
);
383 DBG_ASSERT( xMark
.is(), "write: no XMarkableStream!" );
385 OutStream
->writeShort( UNOCONTROL_STREAMVERSION
);
387 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aCtrls
= getControlModels();
388 ImplWriteControls( OutStream
, aCtrls
);
390 sal_uInt32 nGroups
= getGroupCount();
391 OutStream
->writeLong( nGroups
);
392 for ( sal_uInt32 n
= 0; n
< nGroups
; n
++ )
394 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aGroupCtrls
;
396 getGroup( n
, aGroupCtrls
, aGroupName
);
397 OutStream
->writeUTF( aGroupName
);
398 ImplWriteControls( OutStream
, aGroupCtrls
);
402 void StdTabControllerModel::read( const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XObjectInputStream
>& InStream
) throw(::com::sun::star::io::IOException
, ::com::sun::star::uno::RuntimeException
, std::exception
)
404 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
406 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aSeq
= ImplReadControls( InStream
);
407 setControlModels( aSeq
);
409 sal_uInt32 nGroups
= InStream
->readLong();
410 for ( sal_uInt32 n
= 0; n
< nGroups
; n
++ )
412 OUString aGroupName
= InStream
->readUTF();
413 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aCtrlSeq
= ImplReadControls( InStream
);
414 setGroup( aCtrlSeq
, aGroupName
);
418 OUString
StdTabControllerModel::getImplementationName()
419 throw (css::uno::RuntimeException
, std::exception
)
421 return OUString("stardiv.Toolkit.StdTabControllerModel");
424 sal_Bool
StdTabControllerModel::supportsService(OUString
const & ServiceName
)
425 throw (css::uno::RuntimeException
, std::exception
)
427 return cppu::supportsService(this, ServiceName
);
430 css::uno::Sequence
<OUString
> StdTabControllerModel::getSupportedServiceNames()
431 throw (css::uno::RuntimeException
, std::exception
)
433 return css::uno::Sequence
<OUString
>{
434 OUString::createFromAscii(szServiceName2_TabControllerModel
),
435 "stardiv.vcl.controlmodel.TabController"};
438 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
* SAL_CALL
439 stardiv_Toolkit_StdTabControllerModel_get_implementation(
440 css::uno::XComponentContext
*,
441 css::uno::Sequence
<css::uno::Any
> const &)
443 return cppu::acquire(new StdTabControllerModel());
446 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */