1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 /** 23 * AccEditableText.cpp : Implementation of CUAccCOMApp and DLL registration. 24 */ 25 #include "stdafx.h" 26 #include "UAccCOM2.h" 27 #include "AccEditableText.h" 28 #include <com/sun/star/accessibility/XAccessible.hpp> 29 #include <com/sun/star/accessibility/XAccessibleContext.hpp> 30 #include <com/sun/star/accessibility/XAccessibleText.hpp> 31 #include <com/sun/star/awt/FontSlant.hpp> 32 #include <com/sun/star/beans/PropertyValue.hpp> 33 #include <com/sun/star/style/LineSpacing.hpp> 34 #include <com/sun/star/style/TabStop.hpp> 35 #include <vector> 36 37 using namespace com::sun::star::accessibility; 38 using namespace com::sun::star::uno; 39 using namespace com::sun::star::awt; 40 using namespace com::sun::star::beans; 41 using namespace std; 42 43 /** 44 * Copys a range of text to the clipboard. 45 * 46 * @param startOffset the start offset of copying. 47 * @param endOffset the end offset of copying. 48 * @param success the boolean result to be returned. 49 */ 50 STDMETHODIMP CAccEditableText::copyText(long startOffset, long endOffset) 51 { 52 53 CHECK_ENABLE_INF 54 55 ENTER_PROTECTED_BLOCK 56 57 // #CHECK XInterface# 58 if(!pRXEdtTxt.is()) 59 { 60 return E_FAIL; 61 } 62 63 if ( GetXInterface()->copyText( startOffset, endOffset ) ) 64 return S_OK; 65 66 return E_FAIL; 67 68 LEAVE_PROTECTED_BLOCK 69 } 70 71 /** 72 * Deletes a range of text. 73 * 74 * @param startOffset the start offset of deleting. 75 * @param endOffset the end offset of deleting. 76 * @param success the boolean result to be returned. 77 */ 78 STDMETHODIMP CAccEditableText::deleteText(long startOffset, long endOffset) 79 { 80 81 CHECK_ENABLE_INF 82 83 ENTER_PROTECTED_BLOCK 84 85 if( !pRXEdtTxt.is() ) 86 return E_FAIL; 87 88 if( GetXInterface()->deleteText( startOffset, endOffset ) ) 89 return S_OK; 90 91 return E_FAIL; 92 93 LEAVE_PROTECTED_BLOCK 94 } 95 96 /** 97 * Inserts text at a specified offset. 98 * 99 * @param offset the offset of inserting. 100 * @param text the text to be inserted. 101 * @param success the boolean result to be returned. 102 */ 103 STDMETHODIMP CAccEditableText::insertText(long offset, BSTR * text) 104 { 105 106 CHECK_ENABLE_INF 107 108 ENTER_PROTECTED_BLOCK 109 110 if (text == NULL) 111 return E_INVALIDARG; 112 113 if( !pRXEdtTxt.is() ) 114 return E_FAIL; 115 116 ::rtl::OUString ouStr(*text); 117 118 if( GetXInterface()->insertText( ouStr, offset ) ) 119 return S_OK; 120 121 return E_FAIL; 122 123 LEAVE_PROTECTED_BLOCK 124 } 125 126 /** 127 * Cuts a range of text to the clipboard. 128 * 129 * @param startOffset the start offset of cuting. 130 * @param endOffset the end offset of cuting. 131 * @param success the boolean result to be returned. 132 */ 133 STDMETHODIMP CAccEditableText::cutText(long startOffset, long endOffset) 134 { 135 136 CHECK_ENABLE_INF 137 138 ENTER_PROTECTED_BLOCK 139 140 if( !pRXEdtTxt.is() ) 141 return E_FAIL; 142 143 if( GetXInterface()->cutText( startOffset, endOffset ) ) 144 return S_OK; 145 146 return E_FAIL; 147 148 LEAVE_PROTECTED_BLOCK 149 } 150 151 /** 152 * Pastes text from clipboard at specified offset. 153 * 154 * @param offset the offset of pasting. 155 * @param success the boolean result to be returned. 156 */ 157 STDMETHODIMP CAccEditableText::pasteText(long offset) 158 { 159 160 CHECK_ENABLE_INF 161 162 ENTER_PROTECTED_BLOCK 163 164 if( !pRXEdtTxt.is() ) 165 return E_FAIL; 166 167 if( GetXInterface()->pasteText( offset ) ) 168 return S_OK; 169 170 return E_FAIL; 171 172 LEAVE_PROTECTED_BLOCK 173 } 174 175 /** 176 * Replaces range of text with new text. 177 * 178 * @param startOffset the start offset of replacing. 179 * @param endOffset the end offset of replacing. 180 * @param text the replacing text. 181 * @param success the boolean result to be returned. 182 */ 183 STDMETHODIMP CAccEditableText::replaceText(long startOffset, long endOffset, BSTR * text) 184 { 185 186 CHECK_ENABLE_INF 187 188 ENTER_PROTECTED_BLOCK 189 190 // #CHECK# 191 if (text == NULL) 192 return E_INVALIDARG; 193 if( !pRXEdtTxt.is() ) 194 return E_FAIL; 195 196 ::rtl::OUString ouStr(*text); 197 198 if( GetXInterface()->replaceText( startOffset,endOffset, ouStr) ) 199 return S_OK; 200 return E_FAIL; 201 202 LEAVE_PROTECTED_BLOCK 203 } 204 205 /** 206 * Sets attributes of range of text. 207 * 208 * @param startOffset the start offset. 209 * @param endOffset the end offset. 210 * @param attributes the attribute text. 211 * @param success the boolean result to be returned. 212 */ 213 STDMETHODIMP CAccEditableText::setAttributes(long startOffset, long endOffset, BSTR * attributes) 214 { 215 216 CHECK_ENABLE_INF 217 218 ENTER_PROTECTED_BLOCK 219 220 // #CHECK# 221 if (attributes == NULL) 222 return E_INVALIDARG; 223 if( !pRXEdtTxt.is() ) 224 return E_FAIL; 225 226 ::rtl::OUString ouStr(*attributes); 227 228 sal_Int32 nIndex = 0; 229 sal_Unicode cTok = ';'; 230 vector< ::rtl::OUString > vecAttr; 231 do 232 { 233 ::rtl::OUString ouToken = ouStr.getToken(0, cTok, nIndex); 234 vecAttr.push_back(ouToken); 235 } 236 while(nIndex >= 0); 237 238 Sequence< PropertyValue > beanSeq(vecAttr.size()); 239 for(unsigned int i = 0; i < vecAttr.size(); i ++) 240 { 241 ::rtl::OUString attr = vecAttr[i]; 242 sal_Int32 nPos = attr.indexOf(':'); 243 if(nPos > -1) 244 { 245 ::rtl::OUString attrName = attr.copy(0, nPos); 246 ::rtl::OUString attrValue = attr.copy(nPos + 1, attr.getLength() - nPos - 1); 247 beanSeq[i].Name = attrName; 248 get_AnyFromOLECHAR(attrName, attrValue, beanSeq[i].Value); 249 } 250 } 251 252 if( GetXInterface()->setAttributes( startOffset,endOffset, beanSeq) ) 253 return S_OK; 254 255 return E_FAIL; 256 257 LEAVE_PROTECTED_BLOCK 258 } 259 260 /** 261 * Convert attributes string to Any type. 262 * Reference to infra\accessibility\bridge\org\openoffice\java\accessibility\AccessibleTextImpl.java 263 * 264 * @param ouName the string of attribute name. 265 * @param ouValue the string of attribute value. 266 * @param rAny the Any object to be returned. 267 */ 268 void CAccEditableText::get_AnyFromOLECHAR(const ::rtl::OUString &ouName, const ::rtl::OUString &ouValue, Any &rAny) 269 { 270 if(ouName.compareTo(L"CharBackColor") == 0 || 271 ouName.compareTo(L"CharColor") == 0 || 272 ouName.compareTo(L"ParaAdjust") == 0 || 273 ouName.compareTo(L"ParaFirstLineIndent") == 0 || 274 ouName.compareTo(L"ParaLeftMargin") == 0 || 275 ouName.compareTo(L"ParaRightMargin") == 0 || 276 ouName.compareTo(L"ParaTopMargin") == 0 || 277 ouName.compareTo(L"ParaBottomMargin") == 0 || 278 ouName.compareTo(L"CharFontPitch") == 0) 279 { 280 // Convert to int. 281 // NOTE: CharFontPitch is not implemented in java file. 282 sal_Int32 nValue = ouValue.toInt32(); 283 rAny.setValue(&nValue, getCppuType((sal_Int32 *)0)); 284 } 285 else if(ouName.compareTo(L"CharShadowed") == 0 || 286 ouName.compareTo(L"CharContoured") == 0) 287 { 288 // Convert to boolean. 289 boolean nValue = (boolean)ouValue.toBoolean(); 290 rAny.setValue(&nValue, getCppuType((sal_Bool *)sal_False)); 291 } 292 else if(ouName.compareTo(L"CharEscapement") == 0 || 293 ouName.compareTo(L"CharStrikeout") == 0 || 294 ouName.compareTo(L"CharUnderline") == 0 || 295 ouName.compareTo(L"CharFontPitch") == 0) 296 { 297 // Convert to short. 298 short nValue = (short)ouValue.toInt32(); 299 rAny.setValue(&nValue, getCppuType((short *)0)); 300 } 301 else if(ouName.compareTo(L"CharHeight") == 0 || 302 ouName.compareTo(L"CharWeight") == 0) 303 { 304 // Convert to float. 305 float fValue = ouValue.toFloat(); 306 rAny.setValue(&fValue, getCppuType((float *)0)); 307 } 308 else if(ouName.compareTo(L"CharFontName") == 0) 309 { 310 // Convert to string. 311 rAny.setValue(&ouValue, getCppuType((::rtl::OUString *)0)); 312 } 313 else if(ouName.compareTo(L"CharPosture") == 0) 314 { 315 // Convert to FontSlant. 316 ::com::sun::star::awt::FontSlant fontSlant = (::com::sun::star::awt::FontSlant)ouValue.toInt32(); 317 rAny.setValue(&fontSlant, getCppuType((::com::sun::star::awt::FontSlant*)0)); 318 } 319 else if(ouName.compareTo(L"ParaTabStops") == 0) 320 { 321 // 322 // Convert to the Sequence with TabStop element. 323 vector< ::com::sun::star::style::TabStop > vecTabStop; 324 ::com::sun::star::style::TabStop tabStop; 325 ::rtl::OUString ouSubValue; 326 sal_Int32 nIndex = 0; 327 sal_Int32 pos = 0, posComma = 0; 328 329 do 330 { 331 // Position. 332 pos = ouValue.indexOf(L"Position=", pos); 333 if(pos != -1) 334 { 335 posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "Position=". 336 if(posComma != -1) 337 { 338 ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9); 339 tabStop.Position = ouSubValue.toInt32(); 340 pos = posComma + 1; 341 342 // TabAlign. 343 pos = ouValue.indexOf(L"TabAlign=", pos); 344 if(pos != -1) 345 { 346 posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "TabAlign=". 347 if(posComma != -1) 348 { 349 ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9); 350 tabStop.Alignment = (::com::sun::star::style::TabAlign)ouSubValue.toInt32(); 351 pos = posComma + 1; 352 353 // DecimalChar. 354 pos = ouValue.indexOf(L"DecimalChar=", pos); 355 if(pos != -1) 356 { 357 posComma = ouValue.indexOf(',', pos + 11); // 11 = length of "TabAlign=". 358 if(posComma != -1) 359 { 360 ouSubValue = ouValue.copy(pos + 11, posComma - pos - 11); 361 tabStop.DecimalChar = (sal_Unicode)ouSubValue.toChar(); 362 pos = posComma + 1; 363 364 // FillChar. 365 pos = ouValue.indexOf(L"FillChar=", pos); 366 if(pos != -1) 367 { 368 posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "TabAlign=". 369 if(posComma != -1) 370 { 371 ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9); 372 tabStop.DecimalChar = (sal_Unicode)ouSubValue.toChar(); 373 pos = posComma + 1; 374 375 // Complete TabStop element. 376 vecTabStop.push_back(tabStop); 377 } 378 else 379 break; // No match comma. 380 } 381 else 382 break; // No match FillChar. 383 } 384 else 385 break; // No match comma. 386 } 387 else 388 break; // No match DecimalChar. 389 } 390 else 391 break; // No match comma. 392 } 393 else 394 break; // No match TabAlign. 395 } 396 else 397 break; // No match comma. 398 } 399 else 400 break; // No match Position. 401 } 402 while(pos < ouValue.getLength()); 403 404 // 405 // Dump into Sequence. 406 int iSeqLen = (vecTabStop.size() == 0) ? 1 : vecTabStop.size(); 407 Sequence< ::com::sun::star::style::TabStop > seqTabStop(iSeqLen); 408 409 if(vecTabStop.size() != 0) 410 { 411 // Dump every element. 412 for(int i = 0; i < iSeqLen; i ++) 413 { 414 seqTabStop[i] = vecTabStop[i]; 415 } 416 } 417 else 418 { 419 // Create default value. 420 seqTabStop[0].Position = 0; 421 seqTabStop[0].Alignment = ::com::sun::star::style::TabAlign_DEFAULT; 422 seqTabStop[0].DecimalChar = '.'; 423 seqTabStop[0].FillChar = ' '; 424 } 425 426 // Assign to Any object. 427 rAny.setValue(&seqTabStop, getCppuType((Sequence< ::com::sun::star::style::TabStop >*)0)); 428 } 429 else if(ouName.compareTo(L"ParaLineSpacing") == 0) 430 { 431 // Parse value string. 432 ::com::sun::star::style::LineSpacing lineSpacing; 433 ::rtl::OUString ouSubValue; 434 sal_Int32 pos = 0, posComma = 0; 435 436 pos = ouValue.indexOf(L"Mode=", pos); 437 if(pos != -1) 438 { 439 posComma = ouValue.indexOf(',', pos + 5); // 5 = length of "Mode=". 440 if(posComma != -1) 441 { 442 ouSubValue = ouValue.copy(pos + 5, posComma - pos - 5); 443 lineSpacing.Mode = (sal_Int16)ouSubValue.toInt32(); 444 pos = posComma + 1; 445 446 pos = ouValue.indexOf(L"Height=", pos); 447 if(pos != -1) 448 { 449 ouSubValue = ouValue.copy(pos + 7, ouValue.getLength() - pos - 7); 450 lineSpacing.Height = (sal_Int16)ouSubValue.toInt32(); 451 } 452 else 453 { 454 lineSpacing.Height = (sal_Int16)100; // Default height. 455 } 456 } 457 else 458 { 459 lineSpacing.Height = (sal_Int16)100; // Default height. 460 } 461 } 462 else 463 { 464 // Default Mode and Height. 465 lineSpacing.Mode = (sal_Int16)0; 466 lineSpacing.Height = (sal_Int16)100; // Default height. 467 } 468 469 // Convert to Any object. 470 rAny.setValue(&lineSpacing, getCppuType((::com::sun::star::style::LineSpacing* )0)); 471 } 472 else 473 { 474 // Do nothing. 475 sal_Int32 nDefault = 0; 476 rAny.setValue(&nDefault, getCppuType((sal_Int32 *)0)); 477 } 478 } 479 480 /** 481 * Overide of IUNOXWrapper. 482 * 483 * @param pXInterface the pointer of UNO interface. 484 */ 485 STDMETHODIMP CAccEditableText::put_XInterface(long pXInterface) 486 { 487 488 489 ENTER_PROTECTED_BLOCK 490 491 CUNOXWrapper::put_XInterface(pXInterface); 492 //special query. 493 if(pUNOInterface == NULL) 494 return E_FAIL; 495 Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext(); 496 if( !pRContext.is() ) 497 { 498 return E_FAIL; 499 } 500 Reference<XAccessibleEditableText> pRXI(pRContext,UNO_QUERY); 501 if( !pRXI.is() ) 502 pRXEdtTxt = NULL; 503 else 504 pRXEdtTxt = pRXI.get(); 505 return S_OK; 506 507 LEAVE_PROTECTED_BLOCK 508 } 509