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>
22 #include <toolkit/controls/stdtabcontrollermodel.hxx>
23 #include <toolkit/helper/macros.hxx>
24 #include <toolkit/helper/servicenames.hxx>
25 #include <toolkit/helper/property.hxx>
26 #include <cppuhelper/typeprovider.hxx>
29 #include <tools/debug.hxx>
31 #define UNOCONTROL_STREAMVERSION (short)2
33 // ----------------------------------------------------
34 // class UnoControlModelEntryList
35 // ----------------------------------------------------
36 UnoControlModelEntryList::UnoControlModelEntryList()
40 UnoControlModelEntryList::~UnoControlModelEntryList()
45 void UnoControlModelEntryList::Reset()
47 for ( size_t n
= maList
.size(); n
; )
51 void UnoControlModelEntryList::DestroyEntry( size_t nEntry
)
53 UnoControlModelEntryListBase::iterator it
= maList
.begin();
54 ::std::advance( it
, nEntry
);
59 delete (*it
)->pxControl
;
65 size_t UnoControlModelEntryList::size() const {
69 UnoControlModelEntry
* UnoControlModelEntryList::operator[]( size_t i
) const {
70 return ( i
< maList
.size() ) ? maList
[ i
] : NULL
;
73 void UnoControlModelEntryList::push_back( UnoControlModelEntry
* item
) {
74 maList
.push_back( item
);
77 void UnoControlModelEntryList::insert( size_t i
, UnoControlModelEntry
* item
) {
78 if ( i
< maList
.size() ) {
79 UnoControlModelEntryListBase::iterator it
= maList
.begin();
80 ::std::advance( it
, i
);
81 maList
.insert( it
, item
);
83 maList
.push_back( item
);
88 // ----------------------------------------------------
89 // class StdTabControllerModel
90 // ----------------------------------------------------
91 StdTabControllerModel::StdTabControllerModel()
93 mbGroupControl
= sal_True
;
96 StdTabControllerModel::~StdTabControllerModel()
100 sal_uInt32
StdTabControllerModel::ImplGetControlCount( const UnoControlModelEntryList
& rList
) const
102 sal_uInt32 nCount
= 0;
103 size_t nEntries
= rList
.size();
104 for ( size_t n
= 0; n
< nEntries
; n
++ )
106 UnoControlModelEntry
* pEntry
= rList
[ n
];
107 if ( pEntry
->bGroup
)
108 nCount
+= ImplGetControlCount( *pEntry
->pGroup
);
115 void StdTabControllerModel::ImplGetControlModels( ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> ** ppRefs
, const UnoControlModelEntryList
& rList
) const
117 size_t nEntries
= rList
.size();
118 for ( size_t n
= 0; n
< nEntries
; n
++ )
120 UnoControlModelEntry
* pEntry
= rList
[ n
];
121 if ( pEntry
->bGroup
)
122 ImplGetControlModels( ppRefs
, *pEntry
->pGroup
);
125 **ppRefs
= *pEntry
->pxControl
;
131 void StdTabControllerModel::ImplSetControlModels( UnoControlModelEntryList
& rList
, const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& Controls
) const
133 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> * pRefs
= Controls
.getConstArray();
134 sal_uInt32 nControls
= Controls
.getLength();
135 for ( sal_uInt32 n
= 0; n
< nControls
; n
++ )
137 UnoControlModelEntry
* pNewEntry
= new UnoControlModelEntry
;
138 pNewEntry
->bGroup
= sal_False
;
139 pNewEntry
->pxControl
= new ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> ;
140 *pNewEntry
->pxControl
= pRefs
[n
];
141 rList
.push_back( pNewEntry
);
145 sal_uInt32
StdTabControllerModel::ImplGetControlPos( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> xCtrl
, const UnoControlModelEntryList
& rList
) const
147 for ( size_t n
= rList
.size(); n
; )
149 UnoControlModelEntry
* pEntry
= rList
[ --n
];
150 if ( !pEntry
->bGroup
&& ( *pEntry
->pxControl
== xCtrl
) )
153 return CONTROLPOS_NOTFOUND
;
156 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
)
158 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XMarkableStream
> xMark( OutStream
, ::com::sun::star::uno::UNO_QUERY
);
159 DBG_ASSERT( xMark
.is(), "write: no XMarkableStream!" );
161 sal_uInt32 nStoredControls
= 0;
162 sal_Int32 nDataBeginMark
= xMark
->createMark();
164 OutStream
->writeLong( 0L ); // DataLen
165 OutStream
->writeLong( 0L ); // nStoredControls
167 sal_uInt32 nCtrls
= rCtrls
.getLength();
168 for ( sal_uInt32 n
= 0; n
< nCtrls
; n
++ )
170 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> xI
= rCtrls
.getConstArray()[n
];
171 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XPersistObject
> xPO( xI
, ::com::sun::star::uno::UNO_QUERY
);
172 DBG_ASSERT( xPO
.is(), "write: Control doesn't support XPersistObject" );
175 OutStream
->writeObject( xPO
);
179 sal_Int32 nDataLen
= xMark
->offsetToMark( nDataBeginMark
);
180 xMark
->jumpToMark( nDataBeginMark
);
181 OutStream
->writeLong( nDataLen
);
182 OutStream
->writeLong( nStoredControls
);
183 xMark
->jumpToFurthest();
184 xMark
->deleteMark(nDataBeginMark
);
187 ::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
)
189 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XMarkableStream
> xMark( InStream
, ::com::sun::star::uno::UNO_QUERY
);
190 DBG_ASSERT( xMark
.is(), "write: no XMarkableStream!" );
192 sal_Int32 nDataBeginMark
= xMark
->createMark();
194 sal_Int32 nDataLen
= InStream
->readLong();
195 sal_uInt32 nCtrls
= InStream
->readLong();
197 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aSeq( nCtrls
);
198 for ( sal_uInt32 n
= 0; n
< nCtrls
; n
++ )
200 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XPersistObject
> xObj
= InStream
->readObject();
201 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> xI( xObj
, ::com::sun::star::uno::UNO_QUERY
);
202 aSeq
.getArray()[n
] = xI
;
205 // Skip remainder if more data exists than this version recognizes
206 xMark
->jumpToMark( nDataBeginMark
);
207 InStream
->skipBytes( nDataLen
);
208 xMark
->deleteMark(nDataBeginMark
);
213 // ::com::sun::star::uno::XInterface
214 ::com::sun::star::uno::Any
StdTabControllerModel::queryAggregation( const ::com::sun::star::uno::Type
& rType
) throw(::com::sun::star::uno::RuntimeException
)
216 ::com::sun::star::uno::Any aRet
= ::cppu::queryInterface( rType
,
217 (static_cast< ::com::sun::star::awt::XTabControllerModel
* >(this)),
218 (static_cast< ::com::sun::star::lang::XServiceInfo
* >(this)),
219 (static_cast< ::com::sun::star::io::XPersistObject
* >(this)),
220 (static_cast< ::com::sun::star::lang::XTypeProvider
* >(this)) );
221 return (aRet
.hasValue() ? aRet
: OWeakAggObject::queryAggregation( rType
));
224 // ::com::sun::star::lang::XTypeProvider
225 IMPL_XTYPEPROVIDER_START( StdTabControllerModel
)
226 getCppuType( ( ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XTabControllerModel
>* ) NULL
),
227 getCppuType( ( ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XServiceInfo
>* ) NULL
),
228 getCppuType( ( ::com::sun::star::uno::Reference
< ::com::sun::star::io::XPersistObject
>* ) NULL
)
229 IMPL_XTYPEPROVIDER_END
231 sal_Bool
StdTabControllerModel::getGroupControl( ) throw(::com::sun::star::uno::RuntimeException
)
233 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
235 return mbGroupControl
;
238 void StdTabControllerModel::setGroupControl( sal_Bool GroupControl
) throw(::com::sun::star::uno::RuntimeException
)
240 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
242 mbGroupControl
= GroupControl
;
245 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
)
247 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
250 ImplSetControlModels( maControls
, Controls
);
253 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > StdTabControllerModel::getControlModels( ) throw(::com::sun::star::uno::RuntimeException
)
255 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
257 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aSeq( ImplGetControlCount( maControls
) );
258 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> * pRefs
= aSeq
.getArray();
259 ImplGetControlModels( &pRefs
, maControls
);
263 void StdTabControllerModel::setGroup( const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& Group
, const ::rtl::OUString
& GroupName
) throw(::com::sun::star::uno::RuntimeException
)
265 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
267 // The controls might occur as a flat list and will be grouped.
268 // Nested groups are not possible.
269 // The first element of a group determines its position.
270 UnoControlModelEntry
* pNewEntry
= new UnoControlModelEntry
;
271 pNewEntry
->bGroup
= sal_True
;
272 pNewEntry
->pGroup
= new UnoControlModelEntryList
;
273 pNewEntry
->pGroup
->SetName( GroupName
);
274 ImplSetControlModels( *pNewEntry
->pGroup
, Group
);
276 sal_Bool bInserted
= sal_False
;
277 size_t nElements
= pNewEntry
->pGroup
->size();
278 for ( size_t n
= 0; n
< nElements
; n
++ )
280 UnoControlModelEntry
* pEntry
= (*pNewEntry
->pGroup
)[ n
];
281 if ( !pEntry
->bGroup
)
283 sal_uInt32 nPos
= ImplGetControlPos( *pEntry
->pxControl
, maControls
);
284 // At the beginning, all Controls should be in a flattened list
285 DBG_ASSERT( nPos
!= CONTROLPOS_NOTFOUND
, "setGroup - Element not found" );
286 if ( nPos
!= CONTROLPOS_NOTFOUND
)
288 maControls
.DestroyEntry( nPos
);
291 maControls
.insert( nPos
, pNewEntry
);
292 bInserted
= sal_True
;
298 maControls
.push_back( pNewEntry
);
301 sal_Int32
StdTabControllerModel::getGroupCount( ) throw(::com::sun::star::uno::RuntimeException
)
303 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
305 // Start with only one group layer, even though Model and Impl-methods
306 // work recursively, this is not presented to the outside.
308 sal_Int32 nGroups
= 0;
309 size_t nEntries
= maControls
.size();
310 for ( size_t n
= 0; n
< nEntries
; n
++ )
312 UnoControlModelEntry
* pEntry
= maControls
[ n
];
313 if ( pEntry
->bGroup
)
319 void StdTabControllerModel::getGroup( sal_Int32 nGroup
, ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& rGroup
, ::rtl::OUString
& rName
) throw(::com::sun::star::uno::RuntimeException
)
321 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
323 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aSeq
;
325 size_t nEntries
= maControls
.size();
326 for ( size_t n
= 0; n
< nEntries
; n
++ )
328 UnoControlModelEntry
* pEntry
= maControls
[ n
];
329 if ( pEntry
->bGroup
)
331 if ( nG
== (sal_uInt32
)nGroup
)
333 sal_uInt32 nCount
= ImplGetControlCount( *pEntry
->pGroup
);
334 aSeq
= ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >( nCount
);
335 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> * pRefs
= aSeq
.getArray();
336 ImplGetControlModels( &pRefs
, *pEntry
->pGroup
);
337 rName
= pEntry
->pGroup
->GetName();
346 void StdTabControllerModel::getGroupByName( const ::rtl::OUString
& rName
, ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> >& rGroup
) throw(::com::sun::star::uno::RuntimeException
)
348 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
350 sal_uInt32 nGroup
= 0;
351 size_t nEntries
= maControls
.size();
352 for ( size_t n
= 0; n
< nEntries
; n
++ )
354 UnoControlModelEntry
* pEntry
= maControls
[ n
];
355 if ( pEntry
->bGroup
)
357 if ( pEntry
->pGroup
->GetName() == rName
)
359 ::rtl::OUString Dummy
;
360 getGroup( nGroup
, rGroup
, Dummy
);
369 // ::com::sun::star::io::XPersistObject
370 ::rtl::OUString
StdTabControllerModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException
)
372 return ::rtl::OUString::createFromAscii( szServiceName_TabControllerModel
);
375 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
)
377 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
379 ::com::sun::star::uno::Reference
< ::com::sun::star::io::XMarkableStream
> xMark( OutStream
, ::com::sun::star::uno::UNO_QUERY
);
380 DBG_ASSERT( xMark
.is(), "write: no XMarkableStream!" );
382 OutStream
->writeShort( UNOCONTROL_STREAMVERSION
);
384 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aCtrls
= getControlModels();
385 ImplWriteControls( OutStream
, aCtrls
);
387 sal_uInt32 nGroups
= getGroupCount();
388 OutStream
->writeLong( nGroups
);
389 for ( sal_uInt32 n
= 0; n
< nGroups
; n
++ )
391 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aGroupCtrls
;
392 ::rtl::OUString aGroupName
;
393 getGroup( n
, aGroupCtrls
, aGroupName
);
394 OutStream
->writeUTF( aGroupName
);
395 ImplWriteControls( OutStream
, aGroupCtrls
);
399 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
)
401 ::osl::Guard
< ::osl::Mutex
> aGuard( GetMutex() );
403 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aSeq
= ImplReadControls( InStream
);
404 setControlModels( aSeq
);
406 sal_uInt32 nGroups
= InStream
->readLong();
407 for ( sal_uInt32 n
= 0; n
< nGroups
; n
++ )
409 ::rtl::OUString aGroupName
= InStream
->readUTF();
410 ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XControlModel
> > aCtrlSeq
= ImplReadControls( InStream
);
411 setGroup( aCtrlSeq
, aGroupName
);
419 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */