xref: /trunk/main/sw/source/ui/vba/vbarangehelper.cxx (revision 300d4866)
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