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