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_basic.hxx" 26 27 28 #include <tools/stream.hxx> 29 30 #include <basic/sbx.hxx> 31 #include "sbxres.hxx" 32 33 TYPEINIT1(SbxCollection,SbxObject) 34 TYPEINIT1(SbxStdCollection,SbxCollection) 35 36 static const char* pCount; 37 static const char* pAdd; 38 static const char* pItem; 39 static const char* pRemove; 40 static sal_uInt16 nCountHash = 0, nAddHash, nItemHash, nRemoveHash; 41 42 ///////////////////////////////////////////////////////////////////////// 43 44 SbxCollection::SbxCollection( const XubString& rClass ) 45 : SbxObject( rClass ) 46 { 47 if( !nCountHash ) 48 { 49 pCount = GetSbxRes( STRING_COUNTPROP ); 50 pAdd = GetSbxRes( STRING_ADDMETH ); 51 pItem = GetSbxRes( STRING_ITEMMETH ); 52 pRemove = GetSbxRes( STRING_REMOVEMETH ); 53 nCountHash = MakeHashCode( String::CreateFromAscii( pCount ) ); 54 nAddHash = MakeHashCode( String::CreateFromAscii( pAdd ) ); 55 nItemHash = MakeHashCode( String::CreateFromAscii( pItem ) ); 56 nRemoveHash = MakeHashCode( String::CreateFromAscii( pRemove ) ); 57 } 58 Initialize(); 59 // Fuer Zugriffe auf sich selbst 60 StartListening( GetBroadcaster(), sal_True ); 61 } 62 63 SbxCollection::SbxCollection( const SbxCollection& rColl ) 64 : SvRefBase( rColl ), SbxObject( rColl ) 65 {} 66 67 SbxCollection& SbxCollection::operator=( const SbxCollection& r ) 68 { 69 if( &r != this ) 70 SbxObject::operator=( r ); 71 return *this; 72 } 73 74 SbxCollection::~SbxCollection() 75 {} 76 77 void SbxCollection::Clear() 78 { 79 SbxObject::Clear(); 80 Initialize(); 81 } 82 83 void SbxCollection::Initialize() 84 { 85 SetType( SbxOBJECT ); 86 SetFlag( SBX_FIXED ); 87 ResetFlag( SBX_WRITE ); 88 SbxVariable* p; 89 p = Make( String::CreateFromAscii( pCount ), SbxCLASS_PROPERTY, SbxINTEGER ); 90 p->ResetFlag( SBX_WRITE ); 91 p->SetFlag( SBX_DONTSTORE ); 92 p = Make( String::CreateFromAscii( pAdd ), SbxCLASS_METHOD, SbxEMPTY ); 93 p->SetFlag( SBX_DONTSTORE ); 94 p = Make( String::CreateFromAscii( pItem ), SbxCLASS_METHOD, SbxOBJECT ); 95 p->SetFlag( SBX_DONTSTORE ); 96 p = Make( String::CreateFromAscii( pRemove ), SbxCLASS_METHOD, SbxEMPTY ); 97 p->SetFlag( SBX_DONTSTORE ); 98 } 99 100 SbxVariable* SbxCollection::FindUserData( sal_uInt32 nData ) 101 { 102 if( GetParameters() ) 103 { 104 SbxObject* pObj = (SbxObject*) GetObject(); 105 return pObj ? pObj->FindUserData( nData ) : NULL; 106 } 107 else 108 return SbxObject::FindUserData( nData ); 109 } 110 111 SbxVariable* SbxCollection::Find( const XubString& rName, SbxClassType t ) 112 { 113 if( GetParameters() ) 114 { 115 SbxObject* pObj = (SbxObject*) GetObject(); 116 return pObj ? pObj->Find( rName, t ) : NULL; 117 } 118 else 119 return SbxObject::Find( rName, t ); 120 } 121 122 void SbxCollection::SFX_NOTIFY( SfxBroadcaster& rCst, const TypeId& rId1, 123 const SfxHint& rHint, const TypeId& rId2 ) 124 { 125 const SbxHint* p = PTR_CAST(SbxHint,&rHint); 126 if( p ) 127 { 128 sal_uIntPtr nId = p->GetId(); 129 sal_Bool bRead = sal_Bool( nId == SBX_HINT_DATAWANTED ); 130 sal_Bool bWrite = sal_Bool( nId == SBX_HINT_DATACHANGED ); 131 SbxVariable* pVar = p->GetVar(); 132 SbxArray* pArg = pVar->GetParameters(); 133 if( bRead || bWrite ) 134 { 135 XubString aVarName( pVar->GetName() ); 136 if( pVar == this ) 137 CollItem( pArg ); 138 else if( pVar->GetHashCode() == nCountHash 139 && aVarName.EqualsIgnoreCaseAscii( pCount ) ) 140 pVar->PutLong( pObjs->Count() ); 141 else if( pVar->GetHashCode() == nAddHash 142 && aVarName.EqualsIgnoreCaseAscii( pAdd ) ) 143 CollAdd( pArg ); 144 else if( pVar->GetHashCode() == nItemHash 145 && aVarName.EqualsIgnoreCaseAscii( pItem ) ) 146 CollItem( pArg ); 147 else if( pVar->GetHashCode() == nRemoveHash 148 && aVarName.EqualsIgnoreCaseAscii( pRemove ) ) 149 CollRemove( pArg ); 150 else 151 SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 ); 152 return; 153 } 154 } 155 SbxObject::SFX_NOTIFY( rCst, rId1, rHint, rId2 ); 156 } 157 158 // Default: Argument ist Objekt 159 160 void SbxCollection::CollAdd( SbxArray* pPar_ ) 161 { 162 if( pPar_->Count() != 2 ) 163 SetError( SbxERR_WRONG_ARGS ); 164 else 165 { 166 SbxBase* pObj = pPar_->Get( 1 )->GetObject(); 167 if( !pObj || !( pObj->ISA(SbxObject) ) ) 168 SetError( SbxERR_NOTIMP ); 169 else 170 Insert( (SbxObject*) pObj ); 171 } 172 } 173 174 // Default: Index ab 1 oder der Objektname 175 176 void SbxCollection::CollItem( SbxArray* pPar_ ) 177 { 178 if( pPar_->Count() != 2 ) 179 SetError( SbxERR_WRONG_ARGS ); 180 else 181 { 182 SbxVariable* pRes = NULL; 183 SbxVariable* p = pPar_->Get( 1 ); 184 if( p->GetType() == SbxSTRING ) 185 pRes = Find( p->GetString(), SbxCLASS_OBJECT ); 186 else 187 { 188 short n = p->GetInteger(); 189 if( n >= 1 && n <= (short) pObjs->Count() ) 190 pRes = pObjs->Get( (sal_uInt16) n - 1 ); 191 } 192 if( !pRes ) 193 SetError( SbxERR_BAD_INDEX ); 194 pPar_->Get( 0 )->PutObject( pRes ); 195 } 196 } 197 198 // Default: Index ab 1 199 200 void SbxCollection::CollRemove( SbxArray* pPar_ ) 201 { 202 if( pPar_->Count() != 2 ) 203 SetError( SbxERR_WRONG_ARGS ); 204 else 205 { 206 short n = pPar_->Get( 1 )->GetInteger(); 207 if( n < 1 || n > (short) pObjs->Count() ) 208 SetError( SbxERR_BAD_INDEX ); 209 else 210 Remove( pObjs->Get( (sal_uInt16) n - 1 ) ); 211 } 212 } 213 214 sal_Bool SbxCollection::LoadData( SvStream& rStrm, sal_uInt16 nVer ) 215 { 216 sal_Bool bRes = SbxObject::LoadData( rStrm, nVer ); 217 Initialize(); 218 return bRes; 219 } 220 221 ///////////////////////////////////////////////////////////////////////// 222 223 SbxStdCollection::SbxStdCollection 224 ( const XubString& rClass, const XubString& rElem, sal_Bool b ) 225 : SbxCollection( rClass ), aElemClass( rElem ), 226 bAddRemoveOk( b ) 227 {} 228 229 SbxStdCollection::SbxStdCollection( const SbxStdCollection& r ) 230 : SvRefBase( r ), SbxCollection( r ), 231 aElemClass( r.aElemClass ), bAddRemoveOk( r.bAddRemoveOk ) 232 {} 233 234 SbxStdCollection& SbxStdCollection::operator=( const SbxStdCollection& r ) 235 { 236 if( &r != this ) 237 { 238 if( !r.aElemClass.EqualsIgnoreCaseAscii( aElemClass ) ) 239 SetError( SbxERR_CONVERSION ); 240 else 241 SbxCollection::operator=( r ); 242 } 243 return *this; 244 } 245 246 SbxStdCollection::~SbxStdCollection() 247 {} 248 249 // Default: Fehler, wenn falsches Objekt 250 251 void SbxStdCollection::Insert( SbxVariable* p ) 252 { 253 SbxObject* pObj = PTR_CAST(SbxObject,p); 254 if( pObj && !pObj->IsClass( aElemClass ) ) 255 SetError( SbxERR_BAD_ACTION ); 256 else 257 SbxCollection::Insert( p ); 258 } 259 260 void SbxStdCollection::CollAdd( SbxArray* pPar_ ) 261 { 262 if( !bAddRemoveOk ) 263 SetError( SbxERR_BAD_ACTION ); 264 else 265 SbxCollection::CollAdd( pPar_ ); 266 } 267 268 void SbxStdCollection::CollRemove( SbxArray* pPar_ ) 269 { 270 if( !bAddRemoveOk ) 271 SetError( SbxERR_BAD_ACTION ); 272 else 273 SbxCollection::CollRemove( pPar_ ); 274 } 275 276 sal_Bool SbxStdCollection::LoadData( SvStream& rStrm, sal_uInt16 nVer ) 277 { 278 sal_Bool bRes = SbxCollection::LoadData( rStrm, nVer ); 279 if( bRes ) 280 { 281 rStrm.ReadByteString( aElemClass, RTL_TEXTENCODING_ASCII_US ); 282 rStrm >> bAddRemoveOk; 283 } 284 return bRes; 285 } 286 287 sal_Bool SbxStdCollection::StoreData( SvStream& rStrm ) const 288 { 289 sal_Bool bRes = SbxCollection::StoreData( rStrm ); 290 if( bRes ) 291 { 292 rStrm.WriteByteString( aElemClass, RTL_TEXTENCODING_ASCII_US ); 293 rStrm << bAddRemoveOk; 294 } 295 return bRes; 296 } 297 298