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 #include "vbarangehelper.hxx" 28 #include <com/sun/star/text/ControlCharacter.hpp> 29 #include <com/sun/star/text/XTextRangeCompare.hpp> 30 31 using namespace ::ooo::vba; 32 using namespace ::com::sun::star; 33 34 /** 35 * get a range in a xText by creating 36 * a cursor that iterates over the text. If the iterating cursor is 37 * equal to the desired position, the range equivalent is returned. 38 * Some special cases are tables that are inside of the text, because the 39 * position has to be adjusted. 40 * @param xText a text where a range position is searched 41 * @param position a position inside o the text 42 * @return a range for the postion; null is returned if no range can be 43 * constructed. 44 */ 45 uno::Reference< text::XTextRange > SwVbaRangeHelper::getRangeByPosition( const uno::Reference< text::XText >& rText, sal_Int32 _position ) throw ( uno::RuntimeException ) 46 { 47 uno::Reference< text::XTextRange > xRange; 48 if( rText.is() ) 49 { 50 sal_Int32 nPos = 0; 51 uno::Reference< text::XTextCursor > xCursor = rText->createTextCursor(); 52 xCursor->collapseToStart(); 53 sal_Bool bCanGo = sal_True; 54 while( !xRange.is() && bCanGo ) 55 { 56 if( _position == nPos ) 57 { 58 xRange = xCursor->getStart(); 59 } 60 else 61 { 62 bCanGo = xCursor->goRight( 1, sal_False ); 63 nPos++; 64 } 65 } 66 } 67 return xRange; 68 } 69 70 71 void SwVbaRangeHelper::insertString( uno::Reference< text::XTextRange >& rTextRange, uno::Reference< text::XText >& rText, const rtl::OUString& rStr, sal_Bool _bAbsorb ) throw ( uno::RuntimeException ) 72 { 73 sal_Int32 nlastIndex = 0; 74 sal_Int32 nIndex = 0; 75 uno::Reference< text::XTextRange > xRange = rTextRange; 76 77 while(( nIndex = rStr.indexOf('\n', nlastIndex)) >= 0 ) 78 { 79 xRange = xRange->getEnd(); 80 if( nlastIndex < ( nIndex - 1 ) ) 81 { 82 rText->insertString( xRange, rStr.copy( nlastIndex, ( nIndex - 1 - nlastIndex ) ), _bAbsorb ); 83 xRange = xRange->getEnd(); 84 } 85 86 rText->insertControlCharacter( xRange, text::ControlCharacter::PARAGRAPH_BREAK, _bAbsorb ); 87 nlastIndex = nIndex + 1; 88 } 89 90 if( nlastIndex < rStr.getLength() ) 91 { 92 xRange = xRange->getEnd(); 93 94 rtl::OUString aWatt = rStr.copy( nlastIndex ); 95 rText->insertString( xRange, aWatt, _bAbsorb ); 96 } 97 } 98 99 uno::Reference< text::XTextCursor > SwVbaRangeHelper::initCursor( const uno::Reference< text::XTextRange >& rTextRange, const uno::Reference< text::XText >& rText ) throw ( uno::RuntimeException ) 100 { 101 uno::Reference< text::XTextCursor > xTextCursor; 102 sal_Bool bGotTextCursor = sal_False; 103 104 try 105 { 106 xTextCursor = rText->createTextCursorByRange( rTextRange ); 107 bGotTextCursor = sal_True; 108 } 109 catch (uno::Exception& e) 110 { 111 DebugHelper::exception(e); 112 } 113 114 if( !bGotTextCursor ) 115 { 116 try 117 { 118 uno::Reference< text::XText > xText = rTextRange->getText(); 119 xTextCursor = xText->createTextCursor(); 120 bGotTextCursor = sal_True; 121 } 122 catch( uno::Exception& e ) 123 { 124 DebugHelper::exception(e); 125 } 126 } 127 128 if( !bGotTextCursor ) 129 { 130 try 131 { 132 xTextCursor = rText->createTextCursor(); 133 bGotTextCursor = sal_True; 134 } 135 catch( uno::Exception& e ) 136 { 137 DebugHelper::exception(e); 138 } 139 } 140 return xTextCursor; 141 } 142 143 sal_Int32 SwVbaRangeHelper::getPosition( const uno::Reference< text::XText >& rText, const uno::Reference< text::XTextRange >& rTextRange ) throw ( uno::RuntimeException ) 144 { 145 sal_Int32 nPosition = -1; 146 if( rText.is() && rTextRange.is() ) 147 { 148 nPosition = 0; 149 uno::Reference< text::XTextCursor > xCursor = rText->createTextCursor(); 150 xCursor->collapseToStart(); 151 uno::Reference< text::XTextRangeCompare > xCompare( rText, uno::UNO_QUERY_THROW ); 152 // compareValue is 0 if the ranges are equal 153 sal_Int32 nCompareValue = xCompare->compareRegionStarts( xCursor->getStart(), rTextRange ); 154 sal_Bool canGo = sal_True; 155 156 while( nCompareValue !=0 && canGo ) 157 { 158 canGo = xCursor->goRight( 1, sal_False ); 159 nCompareValue = xCompare->compareRegionStarts( xCursor->getStart(), rTextRange ); 160 nPosition++; 161 } 162 163 // check fails: no correct position found 164 if( !canGo && nCompareValue != 0 ) 165 { 166 nPosition = -1; 167 } 168 } 169 170 return nPosition; 171 } 172