xref: /aoo41x/main/svl/source/misc/ownlist.cxx (revision cdf0e10c)
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_svl.hxx"
30 #include <ctype.h>
31 #include <stdio.h>
32 #include <com/sun/star/beans/PropertyValues.hpp>
33 
34 #include <svl/ownlist.hxx>
35 
36 using namespace com::sun::star;
37 
38 //=========================================================================
39 //============== SvCommandList ============================================
40 //=========================================================================
41 PRV_SV_IMPL_OWNER_LIST(SvCommandList,SvCommand)
42 
43 
44 static String parseString(const String & rCmd, sal_uInt16 * pIndex)
45 {
46 	String result;
47 
48 	if(rCmd.GetChar( *pIndex ) == '\"') {
49 		(*pIndex) ++;
50 
51 		sal_uInt16 begin = *pIndex;
52 
53 		while(*pIndex < rCmd.Len() && rCmd.GetChar((*pIndex) ++) != '\"') ;
54 
55 		result = String(rCmd.Copy(begin, *pIndex - begin - 1));
56 	}
57 
58 	return result;
59 }
60 
61 static String parseWord(const String & rCmd, sal_uInt16 * pIndex)
62 {
63 	sal_uInt16 begin = *pIndex;
64 
65 	while(*pIndex < rCmd.Len() && !isspace(rCmd.GetChar(*pIndex)) && rCmd.GetChar(*pIndex) != '=')
66 		(*pIndex) ++;
67 
68 	return String(rCmd.Copy(begin, *pIndex - begin));
69 }
70 
71 static void eatSpace(const String & rCmd, sal_uInt16 * pIndex)
72 {
73 	while(*pIndex < rCmd.Len() && isspace(rCmd.GetChar(*pIndex)))
74 		(*pIndex) ++;
75 }
76 
77 
78 //=========================================================================
79 sal_Bool SvCommandList::AppendCommands
80 (
81 	const String & rCmd,	/* Dieser Text wird in Kommandos umgesetzt */
82 	sal_uInt16 * pEaten			/* Anzahl der Zeichen, die gelesen wurden */
83 )
84 /*	[Beschreibung]
85 
86 	Es wird eine Text geparsed und die einzelnen Kommandos werden an
87 	die Liste angeh"angt.
88 
89 	[R"uckgabewert]
90 
91 	sal_Bool		sal_True, der Text wurde korrekt geparsed.
92 				sal_False, der Text wurde nicht korrekt geparsed.
93 */
94 {
95 	sal_uInt16 index = 0;
96 	while(index < rCmd.Len())
97 	{
98 
99 		eatSpace(rCmd, &index);
100 		String name = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index);
101 
102 		eatSpace(rCmd, &index);
103 		String value;
104 		if(index < rCmd.Len() && rCmd.GetChar(index) == '=')
105 		{
106 			index ++;
107 
108 			eatSpace(rCmd, &index);
109 			value = (rCmd.GetChar(index) == '\"') ? parseString(rCmd, &index) : parseWord(rCmd, &index);
110 		}
111 
112 		SvCommand * pCmd = new SvCommand(name, value);
113 		aTypes.Insert(pCmd, LIST_APPEND);
114 	}
115 
116 	*pEaten = index;
117 
118 //  	sal_uInt16 nPos = 0;
119 //  	while( nPos < rCmd.Len() )
120 //  	{
121 //  		// ein Zeichen ? Dann faengt hier eine Option an
122 //    		if( isalpha( rCmd[nPos] ) )
123 //  		{
124 //  			String aValue;
125 //  			sal_uInt16 nStt = nPos;
126 //  			register char c;
127 
128 //  			while( nPos < rCmd.Len() &&
129 //  					( isalnum(c=rCmd[nPos]) || '-'==c || '.'==c ) )
130 //  				nPos++;
131 
132 //  			String aToken( rCmd.Copy( nStt, nPos-nStt ) );
133 
134 //  			while( nPos < rCmd.Len() &&
135 //  					( !String::IsPrintable( (c=rCmd[nPos]),
136 //  					RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) )
137 //  				nPos++;
138 
139 //  			// hat die Option auch einen Wert?
140 //  			if( nPos!=rCmd.Len() && '='==c )
141 //  			{
142 //  				nPos++;
143 
144 //  				while( nPos < rCmd.Len() &&
145 //  					 	( !String::IsPrintable( (c=rCmd[nPos]),
146 //  						RTL_TEXTENCODING_MS_1252 ) || isspace(c) ) )
147 //  					nPos++;
148 
149 //  				if( nPos != rCmd.Len() )
150 //  				{
151 //  					sal_uInt16 nLen = 0;
152 //  					nStt = nPos;
153 //  					if( '"' == c )
154 //  					{
155 //  						nPos++; nStt++;
156 //  						while( nPos < rCmd.Len() &&
157 //  					    	 	'"' != rCmd[nPos] )
158 //  							nPos++, nLen++;
159 //  						if( nPos!=rCmd.Len() )
160 //  							nPos++;
161 //  					}
162 //  					else
163 //  						// hier sind wir etwas laxer als der
164 //  						// Standard und erlauben alles druckbare
165 //  						while( nPos < rCmd.Len() &&
166 //  		 				    	String::IsPrintable( (c=rCmd[nPos]),
167 //  								RTL_TEXTENCODING_MS_1252 ) &&
168 //  								!isspace( c ) )
169 //  							nPos++, nLen++;
170 
171 //  					if( nLen )
172 //  						aValue = rCmd( nStt, nLen );
173 //  				}
174 //  			}
175 
176 //  			SvCommand * pCmd = new SvCommand( aToken, aValue );
177 //  		    aTypes.Insert( pCmd, LIST_APPEND );
178 //  		}
179 //  		else
180 //  			// white space un unerwartete Zeichen ignorieren wie
181 //  			nPos++;
182 //  	}
183 //  	*pEaten = nPos;
184 	return sal_True;
185 }
186 
187 //=========================================================================
188 String SvCommandList::GetCommands() const
189 /*	[Beschreibung]
190 
191 	Die Kommandos in der Liste werden als Text hintereinander, durch ein
192 	Leerzeichen getrennt geschrieben. Der Text muss nicht genauso
193 	aussehen wie der in <SvCommandList::AppendCommands()> "ubergebene.
194 
195 	[R"uckgabewert]
196 
197 	String		Die Kommandos werden zur"uckgegeben.
198 */
199 {
200 	String aRet;
201 	for( sal_uLong i = 0; i < aTypes.Count(); i++ )
202 	{
203 		if( i != 0 )
204 			aRet += ' ';
205 		SvCommand * pCmd = (SvCommand *)aTypes.GetObject( i );
206 		aRet += pCmd->GetCommand();
207 		if( pCmd->GetArgument().Len() )
208 		{
209 			aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "=\"" ) );
210 			aRet += pCmd->GetArgument();
211 			aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "\"" ) );
212 		}
213 	}
214 	return aRet;
215 }
216 
217 //=========================================================================
218 SvCommand & SvCommandList::Append
219 (
220 	const String & rCommand,	/* das Kommando	*/
221 	const String & rArg			/* dasArgument des Kommandos */
222 )
223 /*	[Beschreibung]
224 
225 	Es wird eine Objekt vom Typ SvCommand erzeugt und an die Liste
226 	angeh"angt.
227 
228 	[R"uckgabewert]
229 
230 	SvCommand &		Das erteugte Objekt wird zur"uckgegeben.
231 */
232 {
233 	SvCommand * pCmd = new SvCommand( rCommand, rArg );
234 	aTypes.Insert( pCmd, LIST_APPEND );
235 	return *pCmd;
236 }
237 
238 //=========================================================================
239 SvStream & operator >>
240 (
241 	SvStream & rStm,     	/* Stream aus dem gelesen wird */
242 	SvCommandList & rThis	/* Die zu f"ullende Liste */
243 )
244 /*	[Beschreibung]
245 
246 	Die Liste mit ihren Elementen wird gelesen. Das Format ist:
247 	1. Anzahl der Elemente
248 	2. Alle Elemente
249 
250 	[R"uckgabewert]
251 
252 	SvStream &		Der "ubergebene Stream.
253 */
254 {
255 	sal_uInt32 nCount = 0;
256 	rStm >> nCount;
257 	if( !rStm.GetError() )
258 	{
259 		while( nCount-- )
260 		{
261 			SvCommand * pCmd = new SvCommand();
262 			rStm >> *pCmd;
263 			rThis.aTypes.Insert( pCmd, LIST_APPEND );
264 		}
265 	}
266 	return rStm;
267 }
268 
269 //=========================================================================
270 SvStream & operator <<
271 (
272 	SvStream & rStm,     		/* Stream in den geschrieben wird */
273 	const SvCommandList & rThis	/* Die zu schreibende Liste */
274 )
275 /*	[Beschreibung]
276 
277 	Die Liste mit ihren Elementen wir geschrieben. Das Format ist:
278 	1. Anzahl der Elemente
279 	2. Alle Elemente
280 
281 	[R"uckgabewert]
282 
283 	SvStream &		Der "ubergebene Stream.
284 */
285 {
286 	sal_uInt32 nCount = rThis.aTypes.Count();
287 	rStm << nCount;
288 
289 	for( sal_uInt32 i = 0; i < nCount; i++ )
290 	{
291 		SvCommand * pCmd = (SvCommand *)rThis.aTypes.GetObject( i );
292 		rStm << *pCmd;
293 	}
294 	return rStm;
295 }
296 
297 sal_Bool SvCommandList::FillFromSequence( const com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence )
298 {
299 	const sal_Int32 nCount = aCommandSequence.getLength();
300 	String aCommand, aArg;
301     ::rtl::OUString aApiArg;
302     for( sal_Int32 nIndex=0; nIndex<nCount; nIndex++ )
303 	{
304 		aCommand = aCommandSequence[nIndex].Name;
305 		if( !( aCommandSequence[nIndex].Value >>= aApiArg ) )
306 			return sal_False;
307 		aArg = aApiArg;
308         Append( aCommand, aArg );
309 	}
310 
311     return sal_True;
312 }
313 
314 void SvCommandList::FillSequence( com::sun::star::uno::Sequence < com::sun::star::beans::PropertyValue >& aCommandSequence )
315 {
316     const sal_Int32 nCount = Count();
317 	aCommandSequence.realloc( nCount );
318 	for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
319 	{
320         const SvCommand& rCommand = (*this)[ nIndex ];
321 		aCommandSequence[nIndex].Name = rCommand.GetCommand();
322 		aCommandSequence[nIndex].Handle = -1;
323         aCommandSequence[nIndex].Value = uno::makeAny( ::rtl::OUString( rCommand.GetArgument() ) );
324         aCommandSequence[nIndex].State = beans::PropertyState_DIRECT_VALUE;
325 	}
326 }
327 
328