1e1f63238SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3e1f63238SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4e1f63238SAndrew Rist * or more contributor license agreements. See the NOTICE file 5e1f63238SAndrew Rist * distributed with this work for additional information 6e1f63238SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7e1f63238SAndrew Rist * to you under the Apache License, Version 2.0 (the 8e1f63238SAndrew Rist * "License"); you may not use this file except in compliance 9e1f63238SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11e1f63238SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13e1f63238SAndrew Rist * Unless required by applicable law or agreed to in writing, 14e1f63238SAndrew Rist * software distributed under the License is distributed on an 15e1f63238SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16e1f63238SAndrew Rist * KIND, either express or implied. See the License for the 17e1f63238SAndrew Rist * specific language governing permissions and limitations 18e1f63238SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20e1f63238SAndrew Rist *************************************************************/ 21e1f63238SAndrew Rist 22e1f63238SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25*7fef15a0SDamjan Jovanovic #include "precompiled_sample.hxx" 26cdf0e10cSrcweir #include <tools/errcode.hxx> 27cdf0e10cSrcweir #include <basic/sbxobj.hxx> 28cdf0e10cSrcweir #include <basic/sbx.hxx> 29cdf0e10cSrcweir #ifndef __SBX_SBXVARIABLE_HXX //autogen 30cdf0e10cSrcweir #include <basic/sbxvar.hxx> 31cdf0e10cSrcweir #endif 32cdf0e10cSrcweir #ifndef _MSGBOX_HXX //autogen 33cdf0e10cSrcweir #include <vcl/msgbox.hxx> 34cdf0e10cSrcweir #endif 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include "object.hxx" 37cdf0e10cSrcweir #include "collelem.hxx" 38cdf0e10cSrcweir 39cdf0e10cSrcweir // Das Sample-Objekt hat folgende Elemente: 40cdf0e10cSrcweir // 1) Properties: 41cdf0e10cSrcweir // Name der Name 42cdf0e10cSrcweir // Value ein double-Wert, beide bereits als Default drin 43cdf0e10cSrcweir // 2) Methoden: 44cdf0e10cSrcweir // Create Erzeugen eines neuen Unterelements 45cdf0e10cSrcweir // Display Ausgabe eines Textes 46cdf0e10cSrcweir // Square Argument * Argument 47cdf0e10cSrcweir // Event Aufruf eines Basic-Eventhandlers 48cdf0e10cSrcweir // 3) Unterobjekte: 49cdf0e10cSrcweir // Per Create() kann ein neues Unterelement eingerichtet werden, 50cdf0e10cSrcweir // das indiziert werden kann, falls mehrere Objekte gleichen Namens 51cdf0e10cSrcweir // existieren. 52cdf0e10cSrcweir // Diese Implementation ist ein Beispiel fuer eine tabellengesteuerte 53cdf0e10cSrcweir // Version, die sehr viele Elemente enthalten kann. Die Elemente werden 54cdf0e10cSrcweir // je nach Bedarf aus der Tabelle in das Objekt uebernommen. 55cdf0e10cSrcweir // Die Collection findet sich in COLLECTN.*, die in der Collection 56cdf0e10cSrcweir // enthaltenen Objekte in COLLELEM.* 57cdf0e10cSrcweir 58cdf0e10cSrcweir // Das Sample-Objekt wird in ..\app\mybasic.cxx wie folgt in StarBASIC 59cdf0e10cSrcweir // eingebaut: 60cdf0e10cSrcweir 61cdf0e10cSrcweir // MyBasic::MyBasic() : StarBASIC() 62cdf0e10cSrcweir // { 63cdf0e10cSrcweir // AddFactory( new SampleObjectFac() ); 64cdf0e10cSrcweir // } 65cdf0e10cSrcweir 66cdf0e10cSrcweir // Das nArgs-Feld eines Tabelleneintrags ist wie folgt verschluesselt: 67cdf0e10cSrcweir 68cdf0e10cSrcweir #define _ARGSMASK 0x00FF // Bis zu 255 Argumente 69cdf0e10cSrcweir #define _RWMASK 0x0F00 // Maske fuer R/W-Bits 70cdf0e10cSrcweir #define _TYPEMASK 0xF000 // Maske fuer den Typ des Eintrags 71cdf0e10cSrcweir 72cdf0e10cSrcweir #define _READ 0x0100 // kann gelesen werden 73cdf0e10cSrcweir #define _BWRITE 0x0200 // kann as Lvalue verwendet werden 74cdf0e10cSrcweir #define _LVALUE _BWRITE // kann as Lvalue verwendet werden 75cdf0e10cSrcweir #define _READWRITE 0x0300 // beides 76cdf0e10cSrcweir #define _OPT 0x0400 // sal_True: optionaler Parameter 77cdf0e10cSrcweir #define _METHOD 0x1000 // Masken-Bit fuer eine Methode 78cdf0e10cSrcweir #define _PROPERTY 0x2000 // Masken-Bit fuer eine Property 79cdf0e10cSrcweir #define _COLL 0x4000 // Masken-Bit fuer eine Collection 80cdf0e10cSrcweir // Kombination von oberen Bits: 81cdf0e10cSrcweir #define _FUNCTION 0x1100 // Maske fuer Function 82cdf0e10cSrcweir #define _LFUNCTION 0x1300 // Maske fuer Function, die auch als Lvalue geht 83cdf0e10cSrcweir #define _ROPROP 0x2100 // Maske Read Only-Property 84cdf0e10cSrcweir #define _WOPROP 0x2200 // Maske Write Only-Property 85cdf0e10cSrcweir #define _RWPROP 0x2300 // Maske Read/Write-Property 86cdf0e10cSrcweir #define _COLLPROP 0x4100 // Maske Read-Collection-Element 87cdf0e10cSrcweir 88cdf0e10cSrcweir #define COLLNAME "Elements" // Name der Collection, hier mal hart verdrahtet 89cdf0e10cSrcweir 90cdf0e10cSrcweir SampleObject::Methods SampleObject::aMethods[] = { 91cdf0e10cSrcweir // Eine Sample-Methode (der Returnwert ist SbxNULL) 92cdf0e10cSrcweir { "Display", SbxEMPTY, &SampleObject::Display, 1 | _FUNCTION }, 93cdf0e10cSrcweir // Ein Named Parameter 94cdf0e10cSrcweir { "message", SbxSTRING, NULL, 0 }, 95cdf0e10cSrcweir // Eine Sample-Funktion 96cdf0e10cSrcweir { "Square", SbxDOUBLE, &SampleObject::Square, 1 | _FUNCTION }, 97cdf0e10cSrcweir // Ein Named Parameter 98cdf0e10cSrcweir { "value", SbxDOUBLE, NULL, 0 }, 99cdf0e10cSrcweir // Basic-Callback 100cdf0e10cSrcweir { "Event", SbxEMPTY, &SampleObject::Event, 1 | _FUNCTION }, 101cdf0e10cSrcweir // Ein Named Parameter 102cdf0e10cSrcweir { "event", SbxSTRING, NULL, 0 }, 103cdf0e10cSrcweir // Element erzeugen 104cdf0e10cSrcweir { "Create", SbxEMPTY, &SampleObject::Create, 1 | _FUNCTION }, 105cdf0e10cSrcweir // Ein Named Parameter 106cdf0e10cSrcweir { "name", SbxSTRING, NULL, 0 }, 107cdf0e10cSrcweir 108cdf0e10cSrcweir { NULL, SbxNULL, NULL, -1 }}; // Tabellenende 109cdf0e10cSrcweir 110cdf0e10cSrcweir SampleObject::SampleObject( const String& rClass ) : SbxObject( rClass ) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir SetName( String( RTL_CONSTASCII_USTRINGPARAM("Sample") ) ); 113cdf0e10cSrcweir PutDouble( 1.0 ); // Startwert fuer Value 114cdf0e10cSrcweir } 115cdf0e10cSrcweir 116cdf0e10cSrcweir // Suche nach einem Element: 117cdf0e10cSrcweir // Hier wird linear durch die Methodentabelle gegangen, bis eine 118cdf0e10cSrcweir // passende Methode gefunden wurde. 119cdf0e10cSrcweir // Wenn die Methode/Property nicht gefunden wurde, nur NULL ohne 120cdf0e10cSrcweir // Fehlercode zurueckliefern, da so auch eine ganze Chain von 121cdf0e10cSrcweir // Objekten nach der Methode/Property befragt werden kann. 122cdf0e10cSrcweir 123cdf0e10cSrcweir SbxVariable* SampleObject::Find( const String& rName, SbxClassType t ) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir // Ist das Element bereits vorhanden? 126cdf0e10cSrcweir SbxVariable* pRes = SbxObject::Find( rName, t ); 127cdf0e10cSrcweir if( !pRes && t != SbxCLASS_OBJECT ) 128cdf0e10cSrcweir { 129cdf0e10cSrcweir // sonst suchen 130cdf0e10cSrcweir Methods* p = aMethods; 131cdf0e10cSrcweir short nIndex = 0; 132cdf0e10cSrcweir sal_Bool bFound = sal_False; 133cdf0e10cSrcweir while( p->nArgs != -1 ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir if( rName.EqualsIgnoreCaseAscii( p->pName ) ) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir bFound = sal_True; break; 138cdf0e10cSrcweir } 139cdf0e10cSrcweir nIndex += ( p->nArgs & _ARGSMASK ) + 1; 140cdf0e10cSrcweir p = aMethods + nIndex; 141cdf0e10cSrcweir } 142cdf0e10cSrcweir if( bFound ) 143cdf0e10cSrcweir { 144cdf0e10cSrcweir // Args-Felder isolieren: 145cdf0e10cSrcweir short nAccess = ( p->nArgs & _RWMASK ) >> 8; 146cdf0e10cSrcweir short nType = ( p->nArgs & _TYPEMASK ); 147cdf0e10cSrcweir String aName_ = String::CreateFromAscii( p->pName ); 148cdf0e10cSrcweir SbxClassType eCT = SbxCLASS_OBJECT; 149cdf0e10cSrcweir if( nType & _PROPERTY ) 150cdf0e10cSrcweir eCT = SbxCLASS_PROPERTY; 151cdf0e10cSrcweir else if( nType & _METHOD ) 152cdf0e10cSrcweir eCT = SbxCLASS_METHOD; 153cdf0e10cSrcweir pRes = Make( aName_, eCT, p->eType ); 154cdf0e10cSrcweir // Wir setzen den Array-Index + 1, da ja noch andere 155cdf0e10cSrcweir // Standard-Properties existieren, die auch aktiviert 156cdf0e10cSrcweir // werden muessen. 157cdf0e10cSrcweir pRes->SetUserData( nIndex + 1 ); 158cdf0e10cSrcweir pRes->SetFlags( nAccess ); 159cdf0e10cSrcweir } 160cdf0e10cSrcweir } 161cdf0e10cSrcweir return pRes; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir 164cdf0e10cSrcweir // Aktivierung eines Elements oder Anfordern eines Infoblocks 165cdf0e10cSrcweir 166cdf0e10cSrcweir void SampleObject::SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCT, 167cdf0e10cSrcweir const SfxHint& rHint, const TypeId& rHT ) 168cdf0e10cSrcweir { 169cdf0e10cSrcweir const SbxHint* pHint = PTR_CAST(SbxHint,&rHint); 170cdf0e10cSrcweir if( pHint ) 171cdf0e10cSrcweir { 172cdf0e10cSrcweir SbxVariable* pVar = pHint->GetVar(); 173cdf0e10cSrcweir SbxArray* pPar_ = pVar->GetParameters(); 174cdf0e10cSrcweir sal_uInt16 nIndex = (sal_uInt16) pVar->GetUserData(); 175cdf0e10cSrcweir // kein Index: weiterreichen! 176cdf0e10cSrcweir if( nIndex ) 177cdf0e10cSrcweir { 178cdf0e10cSrcweir sal_uIntPtr t = pHint->GetId(); 179cdf0e10cSrcweir if( t == SBX_HINT_INFOWANTED ) 180cdf0e10cSrcweir pVar->SetInfo( GetInfo( (short) pVar->GetUserData() ) ); 181cdf0e10cSrcweir else 182cdf0e10cSrcweir { 183cdf0e10cSrcweir sal_Bool bWrite = sal_False; 184cdf0e10cSrcweir if( t == SBX_HINT_DATACHANGED ) 185cdf0e10cSrcweir bWrite = sal_True; 186cdf0e10cSrcweir if( t == SBX_HINT_DATAWANTED || bWrite ) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir // Parameter-Test fuer Methoden: 189cdf0e10cSrcweir sal_uInt16 nPar = aMethods[ --nIndex ].nArgs & 0x00FF; 190cdf0e10cSrcweir // Element 0 ist der Returnwert 191cdf0e10cSrcweir if( ( !pPar_ && nPar ) 192cdf0e10cSrcweir || ( pPar_->Count() != nPar+1 ) ) 193cdf0e10cSrcweir SetError( SbxERR_WRONG_ARGS ); 194cdf0e10cSrcweir // Alles klar, man kann den Call ausfuehren 195cdf0e10cSrcweir else 196cdf0e10cSrcweir { 197cdf0e10cSrcweir (this->*(aMethods[ nIndex ].pFunc))( pVar, pPar_, bWrite ); 198cdf0e10cSrcweir } 199cdf0e10cSrcweir } 200cdf0e10cSrcweir } 201cdf0e10cSrcweir } 202cdf0e10cSrcweir SbxObject::SFX_NOTIFY( rBC, rBCT, rHint, rHT ); 203cdf0e10cSrcweir } 204cdf0e10cSrcweir } 205cdf0e10cSrcweir 206cdf0e10cSrcweir // Zusammenbau der Infostruktur fuer einzelne Elemente 207cdf0e10cSrcweir 208cdf0e10cSrcweir SbxInfo* SampleObject::GetInfo( short nIdx ) 209cdf0e10cSrcweir { 210cdf0e10cSrcweir Methods* p = &aMethods[ nIdx ]; 211cdf0e10cSrcweir // Wenn mal eine Hilfedatei zur Verfuegung steht: 212cdf0e10cSrcweir // SbxInfo* pInfo_ = new SbxInfo( Hilfedateiname, p->nHelpId ); 213cdf0e10cSrcweir SbxInfo* pInfo_ = new SbxInfo; 214cdf0e10cSrcweir short nPar = p->nArgs & _ARGSMASK; 215cdf0e10cSrcweir for( short i = 0; i < nPar; i++ ) 216cdf0e10cSrcweir { 217cdf0e10cSrcweir p++; 218cdf0e10cSrcweir String aName_ = String::CreateFromAscii( p->pName ); 219cdf0e10cSrcweir sal_uInt16 nFlags_ = ( p->nArgs >> 8 ) & 0x03; 220cdf0e10cSrcweir if( p->nArgs & _OPT ) 221cdf0e10cSrcweir nFlags_ |= SBX_OPTIONAL; 222cdf0e10cSrcweir pInfo_->AddParam( aName_, p->eType, nFlags_ ); 223cdf0e10cSrcweir } 224cdf0e10cSrcweir return pInfo_; 225cdf0e10cSrcweir } 226cdf0e10cSrcweir 227cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////// 228cdf0e10cSrcweir 229cdf0e10cSrcweir // Properties und Methoden legen beim Get (bPut = sal_False) den Returnwert 230cdf0e10cSrcweir // im Element 0 des Argv ab; beim Put (bPut = sal_True) wird der Wert aus 231cdf0e10cSrcweir // Element 0 gespeichert. 232cdf0e10cSrcweir 233cdf0e10cSrcweir // Die Methoden: 234cdf0e10cSrcweir 235cdf0e10cSrcweir void SampleObject::Display( SbxVariable*, SbxArray* pPar_, sal_Bool ) 236cdf0e10cSrcweir { 237cdf0e10cSrcweir // GetString() loest u.U. auch einen Error aus! 238cdf0e10cSrcweir String s( pPar_->Get( 1 )->GetString() ); 239cdf0e10cSrcweir if( !IsError() ) 240cdf0e10cSrcweir InfoBox( NULL, s ).Execute(); 241cdf0e10cSrcweir } 242cdf0e10cSrcweir 243cdf0e10cSrcweir void SampleObject::Square( SbxVariable* pVar, SbxArray* pPar_, sal_Bool ) 244cdf0e10cSrcweir { 245cdf0e10cSrcweir double n = pPar_->Get( 1 )->GetDouble(); 246cdf0e10cSrcweir pVar->PutDouble( n * n ); 247cdf0e10cSrcweir } 248cdf0e10cSrcweir 249cdf0e10cSrcweir // Callback nach BASIC: 250cdf0e10cSrcweir 251cdf0e10cSrcweir void SampleObject::Event( SbxVariable*, SbxArray* pPar_, sal_Bool ) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir Call( pPar_->Get( 1 )->GetString(), NULL ); 254cdf0e10cSrcweir } 255cdf0e10cSrcweir 256cdf0e10cSrcweir // Neues Element anlegen 257cdf0e10cSrcweir 258cdf0e10cSrcweir void SampleObject::Create( SbxVariable* pVar, SbxArray* pPar_, sal_Bool ) 259cdf0e10cSrcweir { 260cdf0e10cSrcweir pVar->PutObject( 261cdf0e10cSrcweir MakeObject( pPar_->Get( 1 )->GetString(), String( RTL_CONSTASCII_USTRINGPARAM("SampleElement") ) ) ); 262cdf0e10cSrcweir } 263cdf0e10cSrcweir 264cdf0e10cSrcweir // Die Factory legt unsere beiden Objekte an. 265cdf0e10cSrcweir 266cdf0e10cSrcweir SbxObject* SampleObjectFac::CreateObject( const String& rClass ) 267cdf0e10cSrcweir { 268cdf0e10cSrcweir if( rClass.EqualsIgnoreCaseAscii( "SampleObject" ) ) 269cdf0e10cSrcweir return new SampleObject( rClass ); 270cdf0e10cSrcweir if( rClass.EqualsIgnoreCaseAscii( "SampleElement" ) ) 271cdf0e10cSrcweir return new SampleElement( rClass ); 272cdf0e10cSrcweir return NULL; 273cdf0e10cSrcweir } 274cdf0e10cSrcweir 275