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 position; null is returned if no range can be
39 * constructed.
40 */
getRangeByPosition(const uno::Reference<text::XText> & rText,sal_Int32 _position)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
insertString(uno::Reference<text::XTextRange> & rTextRange,uno::Reference<text::XText> & rText,const rtl::OUString & rStr,sal_Bool _bAbsorb)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
initCursor(const uno::Reference<text::XTextRange> & rTextRange,const uno::Reference<text::XText> & rText)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
getPosition(const uno::Reference<text::XText> & rText,const uno::Reference<text::XTextRange> & rTextRange)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