xref: /AOO41X/main/sw/source/ui/vba/vbarangehelper.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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