1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_toolkit.hxx"
26 #include <com/sun/star/io/XMarkableStream.hpp>
27
28 #include <toolkit/controls/stdtabcontrollermodel.hxx>
29 #include <toolkit/helper/macros.hxx>
30 #include <toolkit/helper/servicenames.hxx>
31 #include <toolkit/helper/property.hxx>
32 #include <cppuhelper/typeprovider.hxx>
33 #include <rtl/memory.h>
34 #include <rtl/uuid.h>
35
36 #include <tools/debug.hxx>
37
38 #define UNOCONTROL_STREAMVERSION (short)2
39
40 // ----------------------------------------------------
41 // class UnoControlModelEntryList
42 // ----------------------------------------------------
UnoControlModelEntryList()43 UnoControlModelEntryList::UnoControlModelEntryList()
44 {
45 }
46
~UnoControlModelEntryList()47 UnoControlModelEntryList::~UnoControlModelEntryList()
48 {
49 Reset();
50 }
51
Reset()52 void UnoControlModelEntryList::Reset()
53 {
54 for ( sal_uInt32 n = Count(); n; )
55 DestroyEntry( --n );
56 }
57
DestroyEntry(sal_uInt32 nEntry)58 void UnoControlModelEntryList::DestroyEntry( sal_uInt32 nEntry )
59 {
60 UnoControlModelEntry* pEntry = GetObject( nEntry );
61
62 if ( pEntry->bGroup )
63 delete pEntry->pGroup;
64 else
65 delete pEntry->pxControl;
66
67 Remove( nEntry );
68 delete pEntry;
69 }
70
71 // ----------------------------------------------------
72 // class StdTabControllerModel
73 // ----------------------------------------------------
StdTabControllerModel()74 StdTabControllerModel::StdTabControllerModel()
75 {
76 mbGroupControl = sal_True;
77 }
78
~StdTabControllerModel()79 StdTabControllerModel::~StdTabControllerModel()
80 {
81 }
82
ImplGetControlCount(const UnoControlModelEntryList & rList) const83 sal_uInt32 StdTabControllerModel::ImplGetControlCount( const UnoControlModelEntryList& rList ) const
84 {
85 sal_uInt32 nCount = 0;
86 sal_uInt32 nEntries = rList.Count();
87 for ( sal_uInt32 n = 0; n < nEntries; n++ )
88 {
89 UnoControlModelEntry* pEntry = rList.GetObject( n );
90 if ( pEntry->bGroup )
91 nCount += ImplGetControlCount( *pEntry->pGroup );
92 else
93 nCount++;
94 }
95 return nCount;
96 }
97
ImplGetControlModels(::com::sun::star::uno::Reference<::com::sun::star::awt::XControlModel> ** ppRefs,const UnoControlModelEntryList & rList) const98 void StdTabControllerModel::ImplGetControlModels( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > ** ppRefs, const UnoControlModelEntryList& rList ) const
99 {
100 sal_uInt32 nEntries = rList.Count();
101 for ( sal_uInt32 n = 0; n < nEntries; n++ )
102 {
103 UnoControlModelEntry* pEntry = rList.GetObject( n );
104 if ( pEntry->bGroup )
105 ImplGetControlModels( ppRefs, *pEntry->pGroup );
106 else
107 {
108 **ppRefs = *pEntry->pxControl;
109 (*ppRefs)++;
110 }
111 }
112 }
113
ImplSetControlModels(UnoControlModelEntryList & rList,const::com::sun::star::uno::Sequence<::com::sun::star::uno::Reference<::com::sun::star::awt::XControlModel>> & Controls) const114 void StdTabControllerModel::ImplSetControlModels( UnoControlModelEntryList& rList, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >& Controls ) const
115 {
116 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > * pRefs = Controls.getConstArray();
117 sal_uInt32 nControls = Controls.getLength();
118 for ( sal_uInt32 n = 0; n < nControls; n++ )
119 {
120 UnoControlModelEntry* pNewEntry = new UnoControlModelEntry;
121 pNewEntry->bGroup = sal_False;
122 pNewEntry->pxControl = new ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > ;
123 *pNewEntry->pxControl = pRefs[n];
124 rList.Insert( pNewEntry, LIST_APPEND );
125 }
126 }
127
ImplGetControlPos(const::com::sun::star::uno::Reference<::com::sun::star::awt::XControlModel> xCtrl,const UnoControlModelEntryList & rList) const128 sal_uInt32 StdTabControllerModel::ImplGetControlPos( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xCtrl, const UnoControlModelEntryList& rList ) const
129 {
130 for ( sal_uInt32 n = rList.Count(); n; )
131 {
132 UnoControlModelEntry* pEntry = rList.GetObject( --n );
133 if ( !pEntry->bGroup && ( *pEntry->pxControl == xCtrl ) )
134 return n;
135 }
136 return CONTROLPOS_NOTFOUND;
137 }
138
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)139 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 )
140 {
141 ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( OutStream, ::com::sun::star::uno::UNO_QUERY );
142 DBG_ASSERT( xMark.is(), "write: no XMarkableStream!" );
143
144 sal_uInt32 nStoredControls = 0;
145 sal_Int32 nDataBeginMark = xMark->createMark();
146
147 OutStream->writeLong( 0L ); // DataLen
148 OutStream->writeLong( 0L ); // nStoredControls
149
150 sal_uInt32 nCtrls = rCtrls.getLength();
151 for ( sal_uInt32 n = 0; n < nCtrls; n++ )
152 {
153 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xI = rCtrls.getConstArray()[n];
154 ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject > xPO( xI, ::com::sun::star::uno::UNO_QUERY );
155 DBG_ASSERT( xPO.is(), "write: Control doesn't support XPersistObject" );
156 if ( xPO.is() )
157 {
158 OutStream->writeObject( xPO );
159 nStoredControls++;
160 }
161 }
162 sal_Int32 nDataLen = xMark->offsetToMark( nDataBeginMark );
163 xMark->jumpToMark( nDataBeginMark );
164 OutStream->writeLong( nDataLen );
165 OutStream->writeLong( nStoredControls );
166 xMark->jumpToFurthest();
167 xMark->deleteMark(nDataBeginMark);
168 }
169
ImplReadControls(const::com::sun::star::uno::Reference<::com::sun::star::io::XObjectInputStream> & InStream)170 ::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 )
171 {
172 ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( InStream, ::com::sun::star::uno::UNO_QUERY );
173 DBG_ASSERT( xMark.is(), "write: no XMarkableStream!" );
174
175 sal_Int32 nDataBeginMark = xMark->createMark();
176
177 sal_Int32 nDataLen = InStream->readLong();
178 sal_uInt32 nCtrls = InStream->readLong();
179
180 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq( nCtrls );
181 for ( sal_uInt32 n = 0; n < nCtrls; n++ )
182 {
183 ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject > xObj = InStream->readObject();
184 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > xI( xObj, ::com::sun::star::uno::UNO_QUERY );
185 aSeq.getArray()[n] = xI;
186 }
187
188 // Falls bereits mehr drinsteht als diese Version kennt:
189 xMark->jumpToMark( nDataBeginMark );
190 InStream->skipBytes( nDataLen );
191 xMark->deleteMark(nDataBeginMark);
192 return aSeq;
193 }
194
195
196 // ::com::sun::star::uno::XInterface
queryAggregation(const::com::sun::star::uno::Type & rType)197 ::com::sun::star::uno::Any StdTabControllerModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
198 {
199 ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
200 SAL_STATIC_CAST( ::com::sun::star::awt::XTabControllerModel*, this ),
201 SAL_STATIC_CAST( ::com::sun::star::lang::XServiceInfo*, this ),
202 SAL_STATIC_CAST( ::com::sun::star::io::XPersistObject*, this ),
203 SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) );
204 return (aRet.hasValue() ? aRet : OWeakAggObject::queryAggregation( rType ));
205 }
206
207 // ::com::sun::star::lang::XTypeProvider
208 IMPL_XTYPEPROVIDER_START( StdTabControllerModel )
209 getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabControllerModel>* ) NULL ),
210 getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XServiceInfo>* ) NULL ),
211 getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::io::XPersistObject>* ) NULL )
212 IMPL_XTYPEPROVIDER_END
213
214 sal_Bool StdTabControllerModel::getGroupControl( ) throw(::com::sun::star::uno::RuntimeException)
215 {
216 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
217
218 return mbGroupControl;
219 }
220
setGroupControl(sal_Bool GroupControl)221 void StdTabControllerModel::setGroupControl( sal_Bool GroupControl ) throw(::com::sun::star::uno::RuntimeException)
222 {
223 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
224
225 mbGroupControl = GroupControl;
226 }
227
setControlModels(const::com::sun::star::uno::Sequence<::com::sun::star::uno::Reference<::com::sun::star::awt::XControlModel>> & Controls)228 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)
229 {
230 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
231
232 maControls.Reset();
233 ImplSetControlModels( maControls, Controls );
234 }
235
getControlModels()236 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > StdTabControllerModel::getControlModels( ) throw(::com::sun::star::uno::RuntimeException)
237 {
238 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
239
240 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq( ImplGetControlCount( maControls ) );
241 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > * pRefs = aSeq.getArray();
242 ImplGetControlModels( &pRefs, maControls );
243 return aSeq;
244 }
245
setGroup(const::com::sun::star::uno::Sequence<::com::sun::star::uno::Reference<::com::sun::star::awt::XControlModel>> & Group,const::rtl::OUString & GroupName)246 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)
247 {
248 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
249
250 // Die Controls stehen eventuel flach in der Liste und werden jetzt gruppiert.
251 // Verschachtelte Gruppen sind erstmal nicht moeglich...
252 // Das erste Element der Gruppe welches auch schon in der flachen Liste
253 // stand bestimmt die Position der Gruppe.
254
255 UnoControlModelEntry* pNewEntry = new UnoControlModelEntry;
256 pNewEntry->bGroup = sal_True;
257 pNewEntry->pGroup = new UnoControlModelEntryList;
258 pNewEntry->pGroup->SetName( GroupName );
259 ImplSetControlModels( *pNewEntry->pGroup, Group );
260
261 sal_Bool bInserted = sal_False;
262 sal_uInt32 nElements = pNewEntry->pGroup->Count();
263 for ( sal_uInt32 n = 0; n < nElements; n++ )
264 {
265 UnoControlModelEntry* pEntry = pNewEntry->pGroup->GetObject( n );
266 if ( !pEntry->bGroup )
267 {
268 sal_uInt32 nPos = ImplGetControlPos( *pEntry->pxControl, maControls );
269 // Eigentlich sollten alle Controls vorher in der flachen Liste stehen
270 DBG_ASSERT( nPos != CONTROLPOS_NOTFOUND, "setGroup - Element not found" );
271 if ( nPos != CONTROLPOS_NOTFOUND )
272 {
273 maControls.DestroyEntry( nPos );
274 if ( !bInserted )
275 {
276 maControls.Insert( pNewEntry, nPos );
277 bInserted = sal_True;
278 }
279 }
280 }
281 }
282 if ( !bInserted )
283 maControls.Insert( pNewEntry, LIST_APPEND );
284 }
285
getGroupCount()286 sal_Int32 StdTabControllerModel::getGroupCount( ) throw(::com::sun::star::uno::RuntimeException)
287 {
288 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
289
290 // erstmal nur eine Ebene...
291 // Das Model und die Impl-Methoden arbeiten zwar rekursiv, aber das wird
292 // erstmal nich nach aussen gegeben.
293
294 sal_Int32 nGroups = 0;
295 sal_uInt32 nEntries = maControls.Count();
296 for ( sal_uInt32 n = 0; n < nEntries; n++ )
297 {
298 UnoControlModelEntry* pEntry = maControls.GetObject( n );
299 if ( pEntry->bGroup )
300 nGroups++;
301 }
302 return nGroups;
303 }
304
getGroup(sal_Int32 nGroup,::com::sun::star::uno::Sequence<::com::sun::star::uno::Reference<::com::sun::star::awt::XControlModel>> & rGroup,::rtl::OUString & rName)305 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)
306 {
307 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
308
309 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq;
310 sal_uInt32 nG = 0;
311 sal_uInt32 nEntries = maControls.Count();
312 for ( sal_uInt32 n = 0; n < nEntries; n++ )
313 {
314 UnoControlModelEntry* pEntry = maControls.GetObject( n );
315 if ( pEntry->bGroup )
316 {
317 if ( nG == (sal_uInt32)nGroup )
318 {
319 sal_uInt32 nCount = ImplGetControlCount( *pEntry->pGroup );
320 aSeq = ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > >( nCount );
321 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > * pRefs = aSeq.getArray();
322 ImplGetControlModels( &pRefs, *pEntry->pGroup );
323 rName = pEntry->pGroup->GetName();
324 break;
325 }
326 nG++;
327 }
328 }
329 rGroup = aSeq;
330 }
331
getGroupByName(const::rtl::OUString & rName,::com::sun::star::uno::Sequence<::com::sun::star::uno::Reference<::com::sun::star::awt::XControlModel>> & rGroup)332 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)
333 {
334 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
335
336 sal_uInt32 nGroup = 0;
337 sal_uInt32 nEntries = maControls.Count();
338 for ( sal_uInt32 n = 0; n < nEntries; n++ )
339 {
340 UnoControlModelEntry* pEntry = maControls.GetObject( n );
341 if ( pEntry->bGroup )
342 {
343 if ( pEntry->pGroup->GetName() == rName )
344 {
345 ::rtl::OUString Dummy;
346 getGroup( nGroup, rGroup, Dummy );
347 break;
348 }
349 nGroup++;
350 }
351 }
352 }
353
354
355 // ::com::sun::star::io::XPersistObject
getServiceName()356 ::rtl::OUString StdTabControllerModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException)
357 {
358 return ::rtl::OUString::createFromAscii( szServiceName_TabControllerModel );
359 }
360
write(const::com::sun::star::uno::Reference<::com::sun::star::io::XObjectOutputStream> & OutStream)361 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)
362 {
363 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
364
365 ::com::sun::star::uno::Reference< ::com::sun::star::io::XMarkableStream > xMark( OutStream, ::com::sun::star::uno::UNO_QUERY );
366 DBG_ASSERT( xMark.is(), "write: no XMarkableStream!" );
367
368 OutStream->writeShort( UNOCONTROL_STREAMVERSION );
369
370 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aCtrls = getControlModels();
371 ImplWriteControls( OutStream, aCtrls );
372
373 sal_uInt32 nGroups = getGroupCount();
374 OutStream->writeLong( nGroups );
375 for ( sal_uInt32 n = 0; n < nGroups; n++ )
376 {
377 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aGroupCtrls;
378 ::rtl::OUString aGroupName;
379 getGroup( n, aGroupCtrls, aGroupName );
380 OutStream->writeUTF( aGroupName );
381 ImplWriteControls( OutStream, aGroupCtrls );
382 }
383 }
384
read(const::com::sun::star::uno::Reference<::com::sun::star::io::XObjectInputStream> & InStream)385 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)
386 {
387 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
388
389 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aSeq = ImplReadControls( InStream );
390 setControlModels( aSeq );
391
392 sal_uInt32 nGroups = InStream->readLong();
393 for ( sal_uInt32 n = 0; n < nGroups; n++ )
394 {
395 ::rtl::OUString aGroupName = InStream->readUTF();
396 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > > aCtrlSeq = ImplReadControls( InStream );
397 setGroup( aCtrlSeq, aGroupName );
398 }
399 }
400
401
402
403
404
405