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