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