xref: /aoo41x/main/basic/source/sample/object.cxx (revision e1f63238)
1*e1f63238SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*e1f63238SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*e1f63238SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*e1f63238SAndrew Rist  * distributed with this work for additional information
6*e1f63238SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*e1f63238SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*e1f63238SAndrew Rist  * "License"); you may not use this file except in compliance
9*e1f63238SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*e1f63238SAndrew Rist  *
11*e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*e1f63238SAndrew Rist  *
13*e1f63238SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*e1f63238SAndrew Rist  * software distributed under the License is distributed on an
15*e1f63238SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*e1f63238SAndrew Rist  * KIND, either express or implied.  See the License for the
17*e1f63238SAndrew Rist  * specific language governing permissions and limitations
18*e1f63238SAndrew Rist  * under the License.
19*e1f63238SAndrew Rist  *
20*e1f63238SAndrew Rist  *************************************************************/
21*e1f63238SAndrew Rist 
22*e1f63238SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_basic.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 
SampleObject(const String & rClass)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 
Find(const String & rName,SbxClassType t)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 
SFX_NOTIFY(SfxBroadcaster & rBC,const TypeId & rBCT,const SfxHint & rHint,const TypeId & rHT)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 
GetInfo(short nIdx)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 
Display(SbxVariable *,SbxArray * pPar_,sal_Bool)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 
Square(SbxVariable * pVar,SbxArray * pPar_,sal_Bool)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 
Event(SbxVariable *,SbxArray * pPar_,sal_Bool)251cdf0e10cSrcweir void SampleObject::Event( SbxVariable*, SbxArray* pPar_, sal_Bool )
252cdf0e10cSrcweir {
253cdf0e10cSrcweir 	Call( pPar_->Get( 1 )->GetString(), NULL );
254cdf0e10cSrcweir }
255cdf0e10cSrcweir 
256cdf0e10cSrcweir // Neues Element anlegen
257cdf0e10cSrcweir 
Create(SbxVariable * pVar,SbxArray * pPar_,sal_Bool)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 
CreateObject(const String & rClass)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