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