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 // ---------------------------------------------------- 43 UnoControlModelEntryList::UnoControlModelEntryList() 44 { 45 } 46 47 UnoControlModelEntryList::~UnoControlModelEntryList() 48 { 49 Reset(); 50 } 51 52 void UnoControlModelEntryList::Reset() 53 { 54 for ( sal_uInt32 n = Count(); n; ) 55 DestroyEntry( --n ); 56 } 57 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 // ---------------------------------------------------- 74 StdTabControllerModel::StdTabControllerModel() 75 { 76 mbGroupControl = sal_True; 77 } 78 79 StdTabControllerModel::~StdTabControllerModel() 80 { 81 } 82 83 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 98 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 114 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 128 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 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 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 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 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 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 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 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 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 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 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 356 ::rtl::OUString StdTabControllerModel::getServiceName( ) throw(::com::sun::star::uno::RuntimeException) 357 { 358 return ::rtl::OUString::createFromAscii( szServiceName_TabControllerModel ); 359 } 360 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 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