xref: /trunk/main/svl/source/misc/ownlist.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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