1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include "vbarangehelper.hxx"
20 #include <vbahelper/vbahelper.hxx>
21 #include <com/sun/star/text/ControlCharacter.hpp>
22 #include <com/sun/star/text/XTextRangeCompare.hpp>
23 #include <com/sun/star/text/XBookmarksSupplier.hpp>
25 using namespace ::ooo::vba
;
26 using namespace ::com::sun::star
;
29 * get a range in a xText by creating
30 * a cursor that iterates over the text. If the iterating cursor is
31 * equal to the desired position, the range equivalent is returned.
32 * Some special cases are tables that are inside of the text, because the
33 * position has to be adjusted.
34 * @param xText a text where a range position is searched
35 * @param position a position inside o the text
36 * @return a range for the position; null is returned if no range can be
39 uno::Reference
< text::XTextRange
> SwVbaRangeHelper::getRangeByPosition( const uno::Reference
< text::XText
>& rText
, sal_Int32 _position
)
41 uno::Reference
< text::XTextRange
> xRange
;
45 uno::Reference
< text::XTextCursor
> xCursor
= rText
->createTextCursor();
46 xCursor
->collapseToStart();
48 while( !xRange
.is() && bCanGo
)
50 if( _position
== nPos
)
52 xRange
= xCursor
->getStart();
56 bCanGo
= xCursor
->goRight( 1, false );
64 void SwVbaRangeHelper::insertString( uno::Reference
< text::XTextRange
> const & rTextRange
, uno::Reference
< text::XText
> const & rText
, std::u16string_view aStr
, bool _bAbsorb
)
66 size_t nlastIndex
= 0;
68 uno::Reference
< text::XTextRange
> xRange
= rTextRange
;
70 while( ( nIndex
= aStr
.find('\n', nlastIndex
)) != std::u16string_view::npos
)
72 xRange
= xRange
->getEnd();
73 if( nlastIndex
< ( nIndex
- 1 ) )
75 rText
->insertString( xRange
, OUString(aStr
.substr( nlastIndex
, ( nIndex
- 1 - nlastIndex
) )), _bAbsorb
);
76 xRange
= xRange
->getEnd();
79 rText
->insertControlCharacter( xRange
, text::ControlCharacter::PARAGRAPH_BREAK
, _bAbsorb
);
80 nlastIndex
= nIndex
+ 1;
83 if( nlastIndex
< aStr
.size() )
85 xRange
= xRange
->getEnd();
87 OUString
aWatt( aStr
.substr( nlastIndex
) );
88 rText
->insertString( xRange
, aWatt
, _bAbsorb
);
92 uno::Reference
< text::XTextCursor
> SwVbaRangeHelper::initCursor( const uno::Reference
< text::XTextRange
>& rTextRange
,
93 const uno::Reference
< text::XText
>& rText
)
95 uno::Reference
< text::XTextCursor
> xTextCursor
;
96 bool bGotTextCursor
= false;
100 xTextCursor
= rText
->createTextCursorByRange( rTextRange
);
101 bGotTextCursor
= true;
103 catch (const uno::Exception
& e
)
105 DebugHelper::basicexception(e
);
108 if( !bGotTextCursor
|| !xTextCursor
.is() )
112 uno::Reference
< text::XText
> xText
= rTextRange
->getText();
113 xTextCursor
= xText
->createTextCursor();
114 bGotTextCursor
= true;
116 catch (const uno::Exception
& e
)
118 DebugHelper::basicexception(e
);
122 if( !bGotTextCursor
|| !xTextCursor
.is() )
126 xTextCursor
= rText
->createTextCursor();
128 catch (const uno::Exception
& e
)
130 DebugHelper::basicexception(e
);
136 sal_Int32
SwVbaRangeHelper::getPosition( const uno::Reference
< text::XText
>& rText
, const uno::Reference
< text::XTextRange
>& rTextRange
)
138 sal_Int32 nPosition
= -1;
139 if( rText
.is() && rTextRange
.is() )
142 uno::Reference
< text::XTextCursor
> xCursor
= rText
->createTextCursor();
143 xCursor
->collapseToStart();
144 uno::Reference
< text::XTextRangeCompare
> xCompare( rText
, uno::UNO_QUERY_THROW
);
145 // compareValue is 0 if the ranges are equal
146 sal_Int32 nCompareValue
= xCompare
->compareRegionStarts( xCursor
->getStart(), rTextRange
);
149 while( nCompareValue
!=0 && canGo
)
151 canGo
= xCursor
->goRight( 1, false );
152 nCompareValue
= xCompare
->compareRegionStarts( xCursor
->getStart(), rTextRange
);
156 // check fails: no correct position found
157 if( !canGo
&& nCompareValue
!= 0 )
166 uno::Reference
< text::XTextContent
> SwVbaRangeHelper::findBookmarkByPosition( const uno::Reference
< text::XTextDocument
>& xTextDoc
, const uno::Reference
< text::XTextRange
>& xTextRange
)
168 uno::Reference
< text::XBookmarksSupplier
> xBookmarksSupplier( xTextDoc
, uno::UNO_QUERY_THROW
);
169 uno::Reference
< container::XIndexAccess
> xIndexAccess( xBookmarksSupplier
->getBookmarks(), uno::UNO_QUERY_THROW
);
170 for( sal_Int32 index
= 0; index
< xIndexAccess
->getCount(); index
++ )
172 uno::Reference
< text::XTextContent
> xBookmark( xIndexAccess
->getByIndex( index
), uno::UNO_QUERY_THROW
);
173 uno::Reference
< text::XTextRange
> xBkAnchor
= xBookmark
->getAnchor();
174 uno::Reference
< text::XTextRangeCompare
> xCompare( xBkAnchor
->getText(), uno::UNO_QUERY_THROW
);
175 if( xCompare
->compareRegionStarts( xBkAnchor
->getStart(), xBkAnchor
->getEnd() ) == 0 )
179 if( xCompare
->compareRegionStarts( xTextRange
, xBkAnchor
->getStart() ) == 0 )
182 catch (const uno::Exception
&)
188 return uno::Reference
< text::XTextContent
>();
191 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */