xref: /aoo41x/main/svl/source/misc/ownlist.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svl.hxx"
30*cdf0e10cSrcweir #include <ctype.h>
31*cdf0e10cSrcweir #include <stdio.h>
32*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValues.hpp>
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include <svl/ownlist.hxx>
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir using namespace com::sun::star;
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir //=========================================================================
39*cdf0e10cSrcweir //============== SvCommandList ============================================
40*cdf0e10cSrcweir //=========================================================================
41*cdf0e10cSrcweir PRV_SV_IMPL_OWNER_LIST(SvCommandList,SvCommand)
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir static String parseString(const String & rCmd, sal_uInt16 * pIndex)
45*cdf0e10cSrcweir {
46*cdf0e10cSrcweir 	String result;
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir 	if(rCmd.GetChar( *pIndex ) == '\"') {
49*cdf0e10cSrcweir 		(*pIndex) ++;
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir 		sal_uInt16 begin = *pIndex;
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir 		while(*pIndex < rCmd.Len() && rCmd.GetChar((*pIndex) ++) != '\"') ;
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir 		result = String(rCmd.Copy(begin, *pIndex - begin - 1));
56*cdf0e10cSrcweir 	}
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir 	return result;
59*cdf0e10cSrcweir }
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir static String parseWord(const String & rCmd, sal_uInt16 * pIndex)
62*cdf0e10cSrcweir {
63*cdf0e10cSrcweir 	sal_uInt16 begin = *pIndex;
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir 	while(*pIndex < rCmd.Len() && !isspace(rCmd.GetChar(*pIndex)) && rCmd.GetChar(*pIndex) != '=')
66*cdf0e10cSrcweir 		(*pIndex) ++;
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir 	return String(rCmd.Copy(begin, *pIndex - begin));
69*cdf0e10cSrcweir }
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir static void eatSpace(const String & rCmd, sal_uInt16 * pIndex)
72*cdf0e10cSrcweir {
73*cdf0e10cSrcweir 	while(*pIndex < rCmd.Len() && isspace(rCmd.GetChar(*pIndex)))
74*cdf0e10cSrcweir 		(*pIndex) ++;
75*cdf0e10cSrcweir }
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir //=========================================================================
79*cdf0e10cSrcweir sal_Bool SvCommandList::AppendCommands
80*cdf0e10cSrcweir (
81*cdf0e10cSrcweir 	const String & rCmd,	/* Dieser Text wird in Kommandos umgesetzt */
82*cdf0e10cSrcweir 	sal_uInt16 * pEaten			/* Anzahl der Zeichen, die gelesen wurden */
83*cdf0e10cSrcweir )
84*cdf0e10cSrcweir /*	[Beschreibung]
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir 	Es wird eine Text geparsed und die einzelnen Kommandos werden an
87*cdf0e10cSrcweir 	die Liste angeh"angt.
88*cdf0e10cSrcweir 
89*cdf0e10cSrcweir 	[R"uckgabewert]
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir 	sal_Bool		sal_True, der Text wurde korrekt geparsed.
92*cdf0e10cSrcweir 				sal_False, der Text wurde nicht korrekt geparsed.
93*cdf0e10cSrcweir */
94*cdf0e10cSrcweir {
95*cdf0e10cSrcweir 	sal_uInt16 index = 0;
96*cdf0e10cSrcweir 	while(index < rCmd.Len())
97*cdf0e10cSrcweir 	{
98*cdf0e10cSrcweir 
99*cdf0e10cSrcweir 		eatSpace(rCmd, &index);
100*cdf0e10cSrcweir 		String name = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index);
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir 		eatSpace(rCmd, &index);
103*cdf0e10cSrcweir 		String value;
104*cdf0e10cSrcweir 		if(index < rCmd.Len() && rCmd.GetChar(index) == '=')
105*cdf0e10cSrcweir 		{
106*cdf0e10cSrcweir 			index ++;
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir 			eatSpace(rCmd, &index);
109*cdf0e10cSrcweir 			value = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index);
110*cdf0e10cSrcweir 		}
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir 		SvCommand * pCmd = new SvCommand(name, value);
113*cdf0e10cSrcweir 		aTypes.Insert(pCmd, LIST_APPEND);
114*cdf0e10cSrcweir 	}
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir 	*pEaten = index;
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir //  	sal_uInt16 nPos = 0;
119*cdf0e10cSrcweir //  	while( nPos < rCmd.Len() )
120*cdf0e10cSrcweir //  	{
121*cdf0e10cSrcweir //  		// ein Zeichen ? Dann faengt hier eine Option an
122*cdf0e10cSrcweir //    		if( isalpha( rCmd[nPos] ) )
123*cdf0e10cSrcweir //  		{
124*cdf0e10cSrcweir //  			String aValue;
125*cdf0e10cSrcweir //  			sal_uInt16 nStt = nPos;
126*cdf0e10cSrcweir //  			register char c;
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir //  			while( nPos < rCmd.Len() &&
129*cdf0e10cSrcweir //  					( isalnum(c=rCmd[nPos]) || '-'==c || '.'==c ) )
130*cdf0e10cSrcweir //  				nPos++;
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir //  			String aToken( rCmd.Copy( nStt, nPos-nStt ) );
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir //  			while( nPos < rCmd.Len() &&
135*cdf0e10cSrcweir //  					( !String::IsPrintable( (c=rCmd[nPos]),
136*cdf0e10cSrcweir //  					RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) )
137*cdf0e10cSrcweir //  				nPos++;
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir //  			// hat die Option auch einen Wert?
140*cdf0e10cSrcweir //  			if( nPos!=rCmd.Len() && '='==c )
141*cdf0e10cSrcweir //  			{
142*cdf0e10cSrcweir //  				nPos++;
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir //  				while( nPos < rCmd.Len() &&
145*cdf0e10cSrcweir //  					 	( !String::IsPrintable( (c=rCmd[nPos]),
146*cdf0e10cSrcweir //  						RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) )
147*cdf0e10cSrcweir //  					nPos++;
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir //  				if( nPos != rCmd.Len() )
150*cdf0e10cSrcweir //  				{
151*cdf0e10cSrcweir //  					sal_uInt16 nLen = 0;
152*cdf0e10cSrcweir //  					nStt = nPos;
153*cdf0e10cSrcweir //  					if( '"' == c )
154*cdf0e10cSrcweir //  					{
155*cdf0e10cSrcweir //  						nPos++; nStt++;
156*cdf0e10cSrcweir //  						while( nPos < rCmd.Len() &&
157*cdf0e10cSrcweir //  					    	 	'"' != rCmd[nPos] )
158*cdf0e10cSrcweir //  							nPos++, nLen++;
159*cdf0e10cSrcweir //  						if( nPos!=rCmd.Len() )
160*cdf0e10cSrcweir //  							nPos++;
161*cdf0e10cSrcweir //  					}
162*cdf0e10cSrcweir //  					else
163*cdf0e10cSrcweir //  						// hier sind wir etwas laxer als der
164*cdf0e10cSrcweir //  						// Standard und erlauben alles druckbare
165*cdf0e10cSrcweir //  						while( nPos < rCmd.Len() &&
166*cdf0e10cSrcweir //  		 				    	String::IsPrintable( (c=rCmd[nPos]),
167*cdf0e10cSrcweir //  								RTL_TEXTENCODING_MS_1252 ) &&
168*cdf0e10cSrcweir //  								!isspace( c ) )
169*cdf0e10cSrcweir //  							nPos++, nLen++;
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir //  					if( nLen )
172*cdf0e10cSrcweir //  						aValue = rCmd( nStt, nLen );
173*cdf0e10cSrcweir //  				}
174*cdf0e10cSrcweir //  			}
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir //  			SvCommand * pCmd = new SvCommand( aToken, aValue );
177*cdf0e10cSrcweir //  		    aTypes.Insert( pCmd, LIST_APPEND );
178*cdf0e10cSrcweir //  		}
179*cdf0e10cSrcweir //  		else
180*cdf0e10cSrcweir //  			// white space un unerwartete Zeichen ignorieren wie
181*cdf0e10cSrcweir //  			nPos++;
182*cdf0e10cSrcweir //  	}
183*cdf0e10cSrcweir //  	*pEaten = nPos;
184*cdf0e10cSrcweir 	return sal_True;
185*cdf0e10cSrcweir }
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir //=========================================================================
188*cdf0e10cSrcweir String SvCommandList::GetCommands() const
189*cdf0e10cSrcweir /*	[Beschreibung]
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir 	Die Kommandos in der Liste werden als Text hintereinander, durch ein
192*cdf0e10cSrcweir 	Leerzeichen getrennt geschrieben. Der Text muss nicht genauso
193*cdf0e10cSrcweir 	aussehen wie der in <SvCommandList::AppendCommands()> "ubergebene.
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir 	[R"uckgabewert]
196*cdf0e10cSrcweir 
197*cdf0e10cSrcweir 	String		Die Kommandos werden zur"uckgegeben.
198*cdf0e10cSrcweir */
199*cdf0e10cSrcweir {
200*cdf0e10cSrcweir 	String aRet;
201*cdf0e10cSrcweir 	for( sal_uLong i = 0; i < aTypes.Count(); i++ )
202*cdf0e10cSrcweir 	{
203*cdf0e10cSrcweir 		if( i != 0 )
204*cdf0e10cSrcweir 			aRet += ' ';
205*cdf0e10cSrcweir 		SvCommand * pCmd = (SvCommand *)aTypes.GetObject( i );
206*cdf0e10cSrcweir 		aRet += pCmd->GetCommand();
207*cdf0e10cSrcweir 		if( pCmd->GetArgument().Len() )
208*cdf0e10cSrcweir 		{
209*cdf0e10cSrcweir 			aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "=\"" ) );
210*cdf0e10cSrcweir 			aRet += pCmd->GetArgument();
211*cdf0e10cSrcweir 			aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "\"" ) );
212*cdf0e10cSrcweir 		}
213*cdf0e10cSrcweir 	}
214*cdf0e10cSrcweir 	return aRet;
215*cdf0e10cSrcweir }
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir //=========================================================================
218*cdf0e10cSrcweir SvCommand & SvCommandList::Append
219*cdf0e10cSrcweir (
220*cdf0e10cSrcweir 	const String & rCommand,	/* das Kommando	*/
221*cdf0e10cSrcweir 	const String & rArg			/* dasArgument des Kommandos */
222*cdf0e10cSrcweir )
223*cdf0e10cSrcweir /*	[Beschreibung]
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir 	Es wird eine Objekt vom Typ SvCommand erzeugt und an die Liste
226*cdf0e10cSrcweir 	angeh"angt.
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir 	[R"uckgabewert]
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir 	SvCommand &		Das erteugte Objekt wird zur"uckgegeben.
231*cdf0e10cSrcweir */
232*cdf0e10cSrcweir {
233*cdf0e10cSrcweir 	SvCommand * pCmd = new SvCommand( rCommand, rArg );
234*cdf0e10cSrcweir 	aTypes.Insert( pCmd, LIST_APPEND );
235*cdf0e10cSrcweir 	return *pCmd;
236*cdf0e10cSrcweir }
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir //=========================================================================
239*cdf0e10cSrcweir SvStream & operator >>
240*cdf0e10cSrcweir (
241*cdf0e10cSrcweir 	SvStream & rStm,     	/* Stream aus dem gelesen wird */
242*cdf0e10cSrcweir 	SvCommandList & rThis	/* Die zu f"ullende Liste */
243*cdf0e10cSrcweir )
244*cdf0e10cSrcweir /*	[Beschreibung]
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir 	Die Liste mit ihren Elementen wird gelesen. Das Format ist:
247*cdf0e10cSrcweir 	1. Anzahl der Elemente
248*cdf0e10cSrcweir 	2. Alle Elemente
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 	[R"uckgabewert]
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir 	SvStream &		Der "ubergebene Stream.
253*cdf0e10cSrcweir */
254*cdf0e10cSrcweir {
255*cdf0e10cSrcweir 	sal_uInt32 nCount = 0;
256*cdf0e10cSrcweir 	rStm >> nCount;
257*cdf0e10cSrcweir 	if( !rStm.GetError() )
258*cdf0e10cSrcweir 	{
259*cdf0e10cSrcweir 		while( nCount-- )
260*cdf0e10cSrcweir 		{
261*cdf0e10cSrcweir 			SvCommand * pCmd = new SvCommand();
262*cdf0e10cSrcweir 			rStm >> *pCmd;
263*cdf0e10cSrcweir 			rThis.aTypes.Insert( pCmd, LIST_APPEND );
264*cdf0e10cSrcweir 		}
265*cdf0e10cSrcweir 	}
266*cdf0e10cSrcweir 	return rStm;
267*cdf0e10cSrcweir }
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir //=========================================================================
270*cdf0e10cSrcweir SvStream & operator <<
271*cdf0e10cSrcweir (
272*cdf0e10cSrcweir 	SvStream & rStm,     		/* Stream in den geschrieben wird */
273*cdf0e10cSrcweir 	const SvCommandList & rThis	/* Die zu schreibende Liste */
274*cdf0e10cSrcweir )
275*cdf0e10cSrcweir /*	[Beschreibung]
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir 	Die Liste mit ihren Elementen wir geschrieben. Das Format ist:
278*cdf0e10cSrcweir 	1. Anzahl der Elemente
279*cdf0e10cSrcweir 	2. Alle Elemente
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir 	[R"uckgabewert]
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir 	SvStream &		Der "ubergebene Stream.
284*cdf0e10cSrcweir */
285*cdf0e10cSrcweir {
286*cdf0e10cSrcweir 	sal_uInt32 nCount = rThis.aTypes.Count();
287*cdf0e10cSrcweir 	rStm << nCount;
288*cdf0e10cSrcweir 
289*cdf0e10cSrcweir 	for( sal_uInt32 i = 0; i < nCount; i++ )
290*cdf0e10cSrcweir 	{
291*cdf0e10cSrcweir 		SvCommand * pCmd = (SvCommand *)rThis.aTypes.GetObject( i );
292*cdf0e10cSrcweir 		rStm << *pCmd;
293*cdf0e10cSrcweir 	}
294*cdf0e10cSrcweir 	return rStm;
295*cdf0e10cSrcweir }
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir sal_Bool SvCommandList::FillFromSequence( const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence )
298*cdf0e10cSrcweir {
299*cdf0e10cSrcweir 	const sal_Int32 nCount = aCommandSequence.getLength();
300*cdf0e10cSrcweir 	String aCommand, aArg;
301*cdf0e10cSrcweir     ::rtl::OUString aApiArg;
302*cdf0e10cSrcweir     for( sal_Int32 nIndex=0; nIndex<nCount; nIndex++ )
303*cdf0e10cSrcweir 	{
304*cdf0e10cSrcweir 		aCommand = aCommandSequence[nIndex].Name;
305*cdf0e10cSrcweir 		if( !( aCommandSequence[nIndex].Value >>= aApiArg ) )
306*cdf0e10cSrcweir 			return sal_False;
307*cdf0e10cSrcweir 		aArg = aApiArg;
308*cdf0e10cSrcweir         Append( aCommand, aArg );
309*cdf0e10cSrcweir 	}
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir     return sal_True;
312*cdf0e10cSrcweir }
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir void SvCommandList::FillSequence( com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence )
315*cdf0e10cSrcweir {
316*cdf0e10cSrcweir     const sal_Int32 nCount = Count();
317*cdf0e10cSrcweir 	aCommandSequence.realloc( nCount );
318*cdf0e10cSrcweir 	for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
319*cdf0e10cSrcweir 	{
320*cdf0e10cSrcweir         const SvCommand& rCommand = (*this)[ nIndex ];
321*cdf0e10cSrcweir 		aCommandSequence[nIndex].Name = rCommand.GetCommand();
322*cdf0e10cSrcweir 		aCommandSequence[nIndex].Handle = -1;
323*cdf0e10cSrcweir         aCommandSequence[nIndex].Value = uno::makeAny( ::rtl::OUString( rCommand.GetArgument() ) );
324*cdf0e10cSrcweir         aCommandSequence[nIndex].State = beans::PropertyState_DIRECT_VALUE;
325*cdf0e10cSrcweir 	}
326*cdf0e10cSrcweir }
327*cdf0e10cSrcweir 
328