Branch libreoffice-5-0-4
[LibreOffice.git] / toolkit / source / controls / stdtabcontrollermodel.cxx
blob1f2f33cc3ecbfe2fe6332536bdf7eed7c7145304
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
30 #include <rtl/uuid.h>
32 #include <tools/debug.hxx>
34 #define UNOCONTROL_STREAMVERSION (short)2
37 // class UnoControlModelEntryList
39 UnoControlModelEntryList::UnoControlModelEntryList()
43 UnoControlModelEntryList::~UnoControlModelEntryList()
45 Reset();
48 void UnoControlModelEntryList::Reset()
50 for ( size_t n = maList.size(); n; )
51 DestroyEntry( --n );
54 void UnoControlModelEntryList::DestroyEntry( size_t nEntry )
56 UnoControlModelEntryListBase::iterator it = maList.begin();
57 ::std::advance( it, nEntry );
59 if ( (*it)->bGroup )
60 delete (*it)->pGroup;
61 else
62 delete (*it)->pxControl;
64 delete *it;
65 maList.erase( it );
68 size_t UnoControlModelEntryList::size() const {
69 return maList.size();
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 );
85 } else {
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 );
112 else
113 nCount++;
115 return nCount;
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 );
126 else
128 **ppRefs = *pEntry->pxControl;
129 (*ppRefs)++;
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 ) )
154 return n;
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" );
176 if ( xPO.is() )
178 OutStream->writeObject( xPO );
179 nStoredControls++;
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);
212 return aSeq;
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() );
252 maControls.Reset();
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 );
263 return aSeq;
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 );
292 if ( !bInserted )
294 maControls.insert( nPos, pNewEntry );
295 bInserted = true;
300 if ( !bInserted )
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 )
317 nGroups++;
319 return nGroups;
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;
327 sal_uInt32 nG = 0;
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();
341 break;
343 nG++;
346 rGroup = aSeq;
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 )
362 OUString Dummy;
363 getGroup( nGroup, rGroup, Dummy );
364 break;
366 nGroup++;
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;
395 OUString aGroupName;
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: */