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 "vbaselection.hxx"
21 #include <vbahelper/vbahelper.hxx>
22 #include "vbarange.hxx"
23 #include "vbafind.hxx"
24 #include <com/sun/star/text/XTextRange.hpp>
25 #include <com/sun/star/text/XTextTable.hpp>
26 #include <com/sun/star/text/XTextTableCursor.hpp>
27 #include <com/sun/star/table/XCell.hpp>
28 #include <basic/sberrors.hxx>
29 #include <ooo/vba/word/WdUnits.hpp>
30 #include <ooo/vba/word/WdMovementType.hpp>
31 #include <ooo/vba/word/WdGoToItem.hpp>
32 #include <ooo/vba/word/WdGoToDirection.hpp>
33 #include <ooo/vba/word/XBookmark.hpp>
34 #include <ooo/vba/word/XApplication.hpp>
35 #include <ooo/vba/word/WdCollapseDirection.hpp>
36 #include <com/sun/star/text/XPageCursor.hpp>
38 #include <unocoll.hxx>
39 #include "vbatable.hxx"
40 #include <com/sun/star/view/XViewCursor.hpp>
41 #include <com/sun/star/view/XLineCursor.hpp>
42 #include <com/sun/star/text/XWordCursor.hpp>
43 #include <com/sun/star/text/XParagraphCursor.hpp>
44 #include <ooo/vba/word/WdInformation.hpp>
45 #include <ooo/vba/word/WdHeaderFooterIndex.hpp>
46 #include <ooo/vba/word/WdSeekView.hpp>
47 #include "vbainformationhelper.hxx"
48 #include "vbafield.hxx"
49 #include "vbaheaderfooter.hxx"
50 #include "vbaheaderfooterhelper.hxx"
51 #include <vbahelper/vbashaperange.hxx>
52 #include <com/sun/star/drawing/ShapeCollection.hpp>
53 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
54 #include <com/sun/star/drawing/XDrawPage.hpp>
55 #include "vbarows.hxx"
56 #include "vbacolumns.hxx"
57 #include "vbatablehelper.hxx"
58 #include "vbacells.hxx"
59 #include "vbaview.hxx"
60 #include "vbaparagraph.hxx"
61 #include "vbastyle.hxx"
63 #include <tblenum.hxx>
64 #include <sal/log.hxx>
67 using namespace ::ooo::vba
;
68 using namespace ::com::sun::star
;
70 SwVbaSelection::SwVbaSelection( const uno::Reference
< ooo::vba::XHelperInterface
>& rParent
, const uno::Reference
< uno::XComponentContext
>& rContext
, uno::Reference
< frame::XModel
> xModel
) : SwVbaSelection_BASE( rParent
, rContext
), mxModel(std::move( xModel
))
72 mxTextViewCursor
= word::getXTextViewCursor( mxModel
);
75 SwVbaSelection::~SwVbaSelection()
79 uno::Reference
< text::XTextRange
> SwVbaSelection::GetSelectedRange()
81 uno::Reference
< text::XTextRange
> xTextRange
;
82 uno::Reference
< lang::XServiceInfo
> xServiceInfo( mxModel
->getCurrentSelection(), uno::UNO_QUERY_THROW
);
83 if( !xServiceInfo
->supportsService("com.sun.star.text.TextRanges") )
85 throw uno::RuntimeException("Not implemented" );
88 uno::Reference
< container::XIndexAccess
> xTextRanges( xServiceInfo
, uno::UNO_QUERY_THROW
);
89 if( xTextRanges
->getCount() > 0 )
91 // if there are multiple selection, just return the last selected Range.
92 xTextRange
.set( xTextRanges
->getByIndex( xTextRanges
->getCount()-1 ), uno::UNO_QUERY_THROW
);
98 uno::Reference
< word::XRange
> SAL_CALL
99 SwVbaSelection::getRange()
101 uno::Reference
< text::XTextRange
> xTextRange
= GetSelectedRange();
102 uno::Reference
< text::XTextDocument
> xDocument( mxModel
, uno::UNO_QUERY_THROW
);
103 return uno::Reference
< word::XRange
>( new SwVbaRange( this, mxContext
, xDocument
, xTextRange
->getStart(), xTextRange
->getEnd(), mxTextViewCursor
->getText() ) );
107 SwVbaSelection::getText()
109 return getRange()->getText();
113 SwVbaSelection::setText( const OUString
& rText
)
115 getRange()->setText( rText
);
119 SwVbaSelection::TypeText( const OUString
& rText
)
121 // FIXME: handle the property Options.ReplaceSelection, the default value is true
126 SwVbaSelection::HomeKey( const uno::Any
& _unit
, const uno::Any
& _extend
)
128 sal_Int32 nUnit
= word::WdUnits::wdLine
;
129 sal_Int32 nExtend
= word::WdMovementType::wdMove
;
132 bool bExtend
= nExtend
== word::WdMovementType::wdExtend
;
136 case word::WdUnits::wdStory
:
138 // go to the valid text first so that the current view cursor is valid to call gotoRange.
139 word::gotoSelectedObjectAnchor(mxModel
);
140 // go to the begin of the document
141 uno::Reference
< text::XText
> xCurrentText
= word::getCurrentXText( mxModel
);
142 uno::Reference
< text::XTextRange
> xFirstRange
= word::getFirstObjectPosition( xCurrentText
);
143 mxTextViewCursor
->gotoRange( xFirstRange
, bExtend
);
146 case word::WdUnits::wdLine
:
148 // go to the begin of the Line
149 uno::Reference
< view::XLineCursor
> xLineCursor( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
150 xLineCursor
->gotoStartOfLine( bExtend
);
155 throw uno::RuntimeException("Not implemented" );
161 SwVbaSelection::EndKey( const uno::Any
& _unit
, const uno::Any
& _extend
)
163 sal_Int32 nUnit
= word::WdUnits::wdLine
;
164 sal_Int32 nExtend
= word::WdMovementType::wdMove
;
167 bool bExtend
= nExtend
== word::WdMovementType::wdExtend
;
171 case word::WdUnits::wdStory
:
173 // go to the valid text first so that the current view cursor is valid to call gotoRange.
174 word::gotoSelectedObjectAnchor(mxModel
);
175 // go to the end of the document
176 uno::Reference
< text::XText
> xCurrentText
= word::getCurrentXText( mxModel
);
177 uno::Reference
< text::XTextRange
> xEnd
= xCurrentText
->getEnd();
178 mxTextViewCursor
->gotoRange( xEnd
, bExtend
);
181 case word::WdUnits::wdLine
:
183 // go to the end of the Line
184 uno::Reference
< view::XLineCursor
> xLineCursor( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
185 xLineCursor
->gotoEndOfLine( bExtend
);
190 throw uno::RuntimeException("Not implemented" );
196 SwVbaSelection::Delete( const uno::Any
& _unit
, const uno::Any
& _count
)
198 sal_Int32 nUnit
= word::WdUnits::wdLine
;
199 sal_Int32 nCount
= 0;
200 if( _count
.hasValue() )
202 if( _unit
.hasValue() && ( nCount
> 0 ) )
207 case word::WdUnits::wdCharacter
:
211 mxTextViewCursor
->goRight( nCount
, true );
216 throw uno::RuntimeException("Not implemented" );
220 dispatchRequests( mxModel
,".uno:Delete" );
224 SwVbaSelection::Move( const uno::Any
& _unit
, const uno::Any
& _count
, const uno::Any
& _extend
, word::E_DIRECTION eDirection
)
226 sal_Int32 nUnit
= word::WdUnits::wdCharacter
;
227 sal_Int32 nCount
= 1;
228 sal_Int32 nExtend
= word::WdMovementType::wdMove
;
230 if( _unit
.hasValue() )
232 if( _count
.hasValue() )
234 if( _extend
.hasValue() )
240 bool bExpand
= nExtend
!= word::WdMovementType::wdMove
;
244 case word::WdUnits::wdCell
:
246 if( nExtend
== word::WdMovementType::wdExtend
)
248 DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT
, {});
251 NextCell( nCount
, eDirection
);
254 case word::WdUnits::wdLine
:
256 if( eDirection
== word::MOVE_LEFT
|| eDirection
== word::MOVE_RIGHT
)
258 throw uno::RuntimeException("Not implemented" );
260 uno::Reference
< view::XViewCursor
> xViewCursor( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
261 if( eDirection
== word::MOVE_UP
)
262 xViewCursor
->goUp( nCount
, bExpand
);
263 else if( eDirection
== word::MOVE_DOWN
)
264 xViewCursor
->goDown( nCount
, bExpand
);
267 case word::WdUnits::wdCharacter
:
269 if( eDirection
== word::MOVE_UP
|| eDirection
== word::MOVE_DOWN
)
271 throw uno::RuntimeException("Not implemented" );
273 if( word::gotoSelectedObjectAnchor( mxModel
) )
277 uno::Reference
< view::XViewCursor
> xViewCursor( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
278 if( eDirection
== word::MOVE_LEFT
)
280 // if current select is a cellrange or table,
281 // the first count of move should move to the first selected cell.
282 uno::Reference
< text::XTextTableCursor
> xTextTableCursor( mxModel
->getCurrentSelection(), uno::UNO_QUERY
);
283 if ( xTextTableCursor
.is() )
285 uno::Reference
< beans::XPropertySet
> xCursorProps( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
286 uno::Reference
< text::XTextTable
> xTextTable
;
287 xCursorProps
->getPropertyValue("TextTable") >>= xTextTable
;
288 if( xTextTable
.is() )
290 uno::Reference
< text::XTextRange
> xRange( xTextTable
->getCellByName( xTextTableCursor
->getRangeName()), uno::UNO_QUERY_THROW
);
291 mxTextViewCursor
->gotoRange( xRange
->getStart(), bExpand
);
295 xViewCursor
->goLeft( nCount
, bExpand
);
297 else if( eDirection
== word::MOVE_RIGHT
)
298 xViewCursor
->goRight( nCount
, bExpand
);
301 case word::WdUnits::wdWord
:
302 case word::WdUnits::wdParagraph
:
304 uno::Reference
< text::XTextRange
> xRange
= GetSelectedRange();
305 uno::Reference
< text::XText
> xText
= xRange
->getText();
306 uno::Reference
< text::XTextCursor
> xTextCursor
= xText
->createTextCursorByRange( xRange
);
307 if( nUnit
== word::WdUnits::wdParagraph
)
309 if( eDirection
== word::MOVE_LEFT
|| eDirection
== word::MOVE_RIGHT
)
311 throw uno::RuntimeException("Not implemented" );
313 uno::Reference
< text::XParagraphCursor
> xParagraphCursor( xTextCursor
, uno::UNO_QUERY_THROW
);
314 for( sal_Int32 i
=0; i
<nCount
; i
++ )
316 if( ( eDirection
== word::MOVE_UP
) && !xParagraphCursor
->gotoPreviousParagraph( bExpand
) )
318 else if( ( eDirection
== word::MOVE_DOWN
) && !xParagraphCursor
->gotoNextParagraph( bExpand
) )
322 else if( nUnit
== word::WdUnits::wdWord
)
324 if( eDirection
== word::MOVE_UP
|| eDirection
== word::MOVE_DOWN
)
326 throw uno::RuntimeException("Not implemented" );
328 uno::Reference
< text::XWordCursor
> xWordCursor( xTextCursor
, uno::UNO_QUERY_THROW
);
329 for( sal_Int32 i
=0; i
<nCount
; i
++ )
331 if( (eDirection
== word::MOVE_LEFT
) && !xWordCursor
->gotoPreviousWord( bExpand
) )
333 else if( ( eDirection
== word::MOVE_RIGHT
) && !xWordCursor
->gotoNextWord( bExpand
) )
337 mxTextViewCursor
->gotoRange( xTextCursor
->getStart(), false );
338 mxTextViewCursor
->gotoRange( xTextCursor
->getEnd(), true );
343 throw uno::RuntimeException("Not implemented" );
348 void SwVbaSelection::NextCell(sal_Int32 nCount
, word::E_DIRECTION eDirection
)
350 uno::Reference
< beans::XPropertySet
> xCursorProps( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
351 uno::Reference
< text::XTextTable
> xTextTable
;
352 uno::Reference
< table::XCell
> xCell
;
353 xCursorProps
->getPropertyValue("TextTable") >>= xTextTable
;
354 xCursorProps
->getPropertyValue("Cell") >>= xCell
;
355 if( !xTextTable
.is() || !xCell
.is() )
357 DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT
, {});
360 uno::Reference
< beans::XPropertySet
> xCellProps( xCell
, uno::UNO_QUERY_THROW
);
362 xCellProps
->getPropertyValue("CellName") >>= aCellName
;
363 uno::Reference
< text::XTextTableCursor
> xTextTableCursor
= xTextTable
->createCursorByCellName( aCellName
);
364 // move the table cursor
367 case word::MOVE_LEFT
:
369 xTextTableCursor
->goLeft( nCount
, false );
372 case word::MOVE_RIGHT
:
374 xTextTableCursor
->goRight( nCount
, false );
379 xTextTableCursor
->goUp( nCount
, false );
382 case word::MOVE_DOWN
:
384 xTextTableCursor
->goDown( nCount
, false );
389 DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT
, {});
393 // move the view cursor
394 xCell
= xTextTable
->getCellByName( xTextTableCursor
->getRangeName() );
395 mxTextViewCursor
->gotoRange( uno::Reference
< text::XTextRange
>( xCell
, uno::UNO_QUERY_THROW
), false );
399 SwVbaSelection::MoveRight(const uno::Any
& _unit
, const uno::Any
& _count
, const uno::Any
& _extend
)
401 sal_Int32 nCount
= 1;
403 if( _count
.hasValue() )
411 MoveLeft( _unit
, uno::Any( -nCount
), _extend
);
415 Move( _unit
, _count
, _extend
, word::MOVE_RIGHT
);
419 SwVbaSelection::MoveLeft(const uno::Any
& _unit
, const uno::Any
& _count
, const uno::Any
& _extend
)
421 sal_Int32 nCount
= 1;
422 if( _count
.hasValue() )
430 MoveRight( _unit
, uno::Any( -nCount
), _extend
);
434 Move( _unit
, _count
, _extend
, word::MOVE_LEFT
);
438 SwVbaSelection::MoveDown(const uno::Any
& _unit
, const uno::Any
& _count
, const uno::Any
& _extend
)
440 sal_Int32 nCount
= 1;
442 if( _count
.hasValue() )
450 MoveUp( _unit
, uno::Any( -nCount
), _extend
);
454 Move( _unit
, _count
, _extend
, word::MOVE_DOWN
);
458 SwVbaSelection::MoveUp(const uno::Any
& _unit
, const uno::Any
& _count
, const uno::Any
& _extend
)
460 sal_Int32 nCount
= 1;
462 if( _count
.hasValue() )
470 MoveDown( _unit
, uno::Any( -nCount
), _extend
);
474 Move( _unit
, _count
, _extend
, word::MOVE_UP
);
478 SwVbaSelection::TypeParagraph()
480 // #FIXME: if the selection is an entire paragraph, it's replaced
481 // by the new paragraph
482 bool isCollapsed
= mxTextViewCursor
->isCollapsed();
485 mxTextViewCursor
->collapseToStart();
489 SwVbaSelection::InsertParagraph()
491 // #FIXME: the selection should include the new paragraph.
492 getRange()->InsertParagraph();
496 SwVbaSelection::InsertParagraphBefore()
498 getRange()->InsertParagraphBefore();
502 SwVbaSelection::InsertParagraphAfter()
504 getRange()->InsertParagraphAfter();
507 uno::Reference
< word::XParagraphFormat
> SAL_CALL
508 SwVbaSelection::getParagraphFormat()
510 return getRange()->getParagraphFormat();
514 SwVbaSelection::setParagraphFormat( const uno::Reference
< word::XParagraphFormat
>& rParagraphFormat
)
516 return getRange()->setParagraphFormat( rParagraphFormat
);
519 uno::Reference
< word::XFind
> SAL_CALL
520 SwVbaSelection::getFind()
522 uno::Reference
< text::XTextRange
> xTextRange
= GetSelectedRange();
523 uno::Reference
< text::XTextRange
> xStart
= xTextRange
->getStart();
524 uno::Reference
< text::XTextRange
> xEnd
= xTextRange
->getEnd();
525 uno::Reference
< text::XTextRangeCompare
> xTRC( xTextRange
->getText(), uno::UNO_QUERY_THROW
);
526 int n
= xTRC
->compareRegionStarts( xStart
, xEnd
);
530 xTextRange
= GetSelectedRange();
532 return SwVbaFind::GetOrCreateFind(this, mxContext
, mxModel
, xTextRange
);
536 SwVbaSelection::getStyle()
538 return getRange()->getStyle();
542 SwVbaSelection::setStyle( const uno::Any
& rStyle
)
544 uno::Reference
< beans::XPropertySet
> xParaProps( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
545 return SwVbaStyle::setStyle( xParaProps
, rStyle
);
548 uno::Reference
< word::XFont
> SAL_CALL
549 SwVbaSelection::getFont()
551 return getRange()->getFont();
555 SwVbaSelection::TypeBackspace()
557 dispatchRequests( mxModel
,".uno:SwBackspace" );
560 uno::Reference
< word::XRange
> SAL_CALL
SwVbaSelection::GoTo( const uno::Any
& _what
, const uno::Any
& _which
, const uno::Any
& _count
, const uno::Any
& _name
)
563 if( !( _what
>>= nWhat
) )
564 DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT
, {});
567 case word::WdGoToItem::wdGoToBookmark
:
569 uno::Reference
< word::XApplication
> xApplication( Application(), uno::UNO_QUERY_THROW
);
570 uno::Reference
< word::XBookmark
> xBookmark( xApplication
->getActiveDocument()->Bookmarks(_name
), uno::UNO_QUERY_THROW
);
574 case word::WdGoToItem::wdGoToPage
:
576 uno::Reference
< text::XPageCursor
> xPageCursor( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
577 sal_Int32 nCurrPage
= xPageCursor
->getPage();
578 sal_Int32 nLastPage
= word::getPageCount( mxModel
);
579 sal_Int32 nCount
= 0;
580 if( _count
.hasValue() )
582 sal_Int32 nWhich
= 0;
583 if( _which
.hasValue() )
588 case word::WdGoToDirection::wdGoToLast
:
593 case word::WdGoToDirection::wdGoToNext
:
596 nPage
= nCurrPage
+ nCount
;
598 nPage
= nCurrPage
+ 1;
601 case word::WdGoToDirection::wdGoToPrevious
:
604 nPage
= nCurrPage
- nCount
;
606 nPage
= nCurrPage
- 1;
614 if( _name
.hasValue() )
618 sal_Int32 nName
= sName
.toInt32();
624 if( nPage
> nLastPage
)
626 xPageCursor
->jumpToPage( static_cast<sal_Int16
>(nPage
) );
629 case word::WdGoToItem::wdGoToSection
:
631 uno::Reference
< text::XPageCursor
> xPageCursor( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
632 sal_Int32 nCount
= 0;
633 if( _count
.hasValue() )
635 sal_Int32 nWhich
= 0;
636 if( _which
.hasValue() )
641 case word::WdGoToDirection::wdGoToAbsolute
:
643 // currently only support this type
654 throw uno::RuntimeException("Not implemented" );
655 xPageCursor
->jumpToPage( static_cast<sal_Int16
>(nPage
) );
659 throw uno::RuntimeException("Not implemented" );
664 ::sal_Int32 SAL_CALL
SwVbaSelection::getLanguageID()
666 return getRange()->getLanguageID();
669 void SAL_CALL
SwVbaSelection::setLanguageID( ::sal_Int32 _languageid
)
671 getRange()->setLanguageID( _languageid
);
674 uno::Any SAL_CALL
SwVbaSelection::Information( sal_Int32 _type
)
679 case word::WdInformation::wdActiveEndPageNumber
:
681 result
<<= SwVbaInformationHelper::handleWdActiveEndPageNumber( mxTextViewCursor
);
684 case word::WdInformation::wdNumberOfPagesInDocument
:
686 result
<<= SwVbaInformationHelper::handleWdNumberOfPagesInDocument( mxModel
);
689 case word::WdInformation::wdVerticalPositionRelativeToPage
:
691 result
<<= SwVbaInformationHelper::handleWdVerticalPositionRelativeToPage( mxModel
, mxTextViewCursor
);
694 case word::WdInformation::wdWithInTable
:
696 uno::Reference
< beans::XPropertySet
> xCursorProps( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
697 uno::Reference
< text::XTextTable
> xTextTable
;
698 xCursorProps
->getPropertyValue("TextTable") >>= xTextTable
;
699 result
<<= xTextTable
.is();
702 case word::WdInformation::wdHeaderFooterType
:
704 uno::Reference
< word::XView
> xView( new SwVbaView( this, mxContext
, mxModel
) );
705 sal_Int32 nView
= xView
->getSeekView();
706 sal_Int32 nHeaderFooterType
= 0;
709 case word::WdSeekView::wdSeekMainDocument
:
711 nHeaderFooterType
= -1; // not in a header or footer
714 case word::WdSeekView::wdSeekEvenPagesHeader
:
716 nHeaderFooterType
= 0; // even page header
719 case word::WdSeekView::wdSeekPrimaryHeader
:
721 nHeaderFooterType
= 1; // odd page header
724 case word::WdSeekView::wdSeekEvenPagesFooter
:
726 nHeaderFooterType
= 2; // even page footer
729 case word::WdSeekView::wdSeekPrimaryFooter
:
731 nHeaderFooterType
= 3; // odd page footer
734 case word::WdSeekView::wdSeekFirstPageHeader
:
735 case word::WdSeekView::wdSeekFirstPageFooter
:
737 uno::Reference
< beans::XPropertySet
> xCursorProps( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
738 OUString aPageStyleName
;
739 xCursorProps
->getPropertyValue("PageStyleName") >>= aPageStyleName
;
740 bool bFirstPage
= false;
741 if ( aPageStyleName
== "First Page" )
743 if( nView
== word::WdSeekView::wdSeekFirstPageHeader
)
746 nHeaderFooterType
= 4;
748 nHeaderFooterType
= 1;
753 nHeaderFooterType
= 5;
755 nHeaderFooterType
= 3;
761 nHeaderFooterType
= -1;
764 result
<<= nHeaderFooterType
;
768 throw uno::RuntimeException("Not implemented" );
773 void SAL_CALL
SwVbaSelection::InsertBreak( const uno::Any
& _breakType
)
775 getRange()->InsertBreak( _breakType
);
779 SwVbaSelection::Tables( const uno::Any
& aIndex
)
781 // Hacky implementation due to missing api ( and lack of knowledge )
782 // we can only support a selection that is a single table
783 if ( !aIndex
.hasValue() ) // currently we can't support multiple tables in a selection
784 throw uno::RuntimeException();
786 sal_Int32 nIndex
= 0;
792 throw uno::RuntimeException();
794 uno::Reference
< beans::XPropertySet
> xCursorProps( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
795 uno::Reference
< text::XTextTable
> xTextTable
;
796 xCursorProps
->getPropertyValue("TextTable") >>= xTextTable
;
797 if( xTextTable
.is() )
799 uno::Reference
< css::text::XTextDocument
> xTextDoc( mxModel
, uno::UNO_QUERY_THROW
);
800 uno::Reference
< word::XTable
> xVBATable
= new SwVbaTable( mxParent
, mxContext
, xTextDoc
, xTextTable
);
805 // if the current selection is a XTextTableCursor and the index is 1 then we can service this request, otherwise we just have to throw
806 uno::Reference
< text::XTextTableCursor
> xTextTableCursor( mxModel
->getCurrentSelection(), uno::UNO_QUERY_THROW
);
807 SwXTextTableCursor
* pTTCursor
= dynamic_cast< SwXTextTableCursor
* >( xTextTableCursor
.get() );
810 SwFrameFormat
* pFormat
= pTTCursor
->GetFrameFormat();
813 uno::Reference
< text::XTextTable
> xTable
= SwXTextTables::GetObject(*pFormat
);
814 uno::Reference
< css::text::XTextDocument
> xTextDoc( mxModel
, uno::UNO_QUERY_THROW
);
815 uno::Reference
< word::XTable
> xVBATable
= new SwVbaTable( mxParent
, mxContext
, xTextDoc
, xTable
);
824 SwVbaSelection::Fields( const uno::Any
& index
)
826 uno::Reference
< XCollection
> xCol( new SwVbaFields( mxParent
, mxContext
, mxModel
) );
827 if ( index
.hasValue() )
828 return xCol
->Item( index
, uno::Any() );
829 return uno::Any( xCol
);
832 uno::Reference
< word::XHeaderFooter
> SAL_CALL
833 SwVbaSelection::getHeaderFooter()
835 if( HeaderFooterHelper::isHeaderFooter( mxModel
) )
837 uno::Reference
< beans::XPropertySet
> xPageStyleProps( word::getCurrentPageStyle( mxModel
), uno::UNO_QUERY_THROW
);
838 sal_Int32 nIndex
= word::WdHeaderFooterIndex::wdHeaderFooterPrimary
;
839 bool isHeader
= HeaderFooterHelper::isHeader( mxModel
);
840 if( HeaderFooterHelper::isEvenPagesHeader( mxModel
) || HeaderFooterHelper::isEvenPagesFooter( mxModel
) )
841 nIndex
= word::WdHeaderFooterIndex::wdHeaderFooterEvenPages
;
842 else if( HeaderFooterHelper::isFirstPageHeader( mxModel
) || HeaderFooterHelper::isFirstPageFooter( mxModel
) )
843 nIndex
= word::WdHeaderFooterIndex::wdHeaderFooterFirstPage
;
845 return uno::Reference
< word::XHeaderFooter
>( new SwVbaHeaderFooter( this, mxContext
, mxModel
, xPageStyleProps
, isHeader
, nIndex
) );
848 return uno::Reference
< word::XHeaderFooter
>();
852 SwVbaSelection::ShapeRange( )
854 uno::Reference
< drawing::XShapes
> xShapes( mxModel
->getCurrentSelection(), uno::UNO_QUERY
);
857 uno::Reference
< drawing::XShape
> xShape( mxModel
->getCurrentSelection(), uno::UNO_QUERY_THROW
);
858 xShapes
.set( drawing::ShapeCollection::create(mxContext
) );
859 xShapes
->add( xShape
);
862 uno::Reference
< drawing::XDrawPageSupplier
> xDrawPageSupplier( mxModel
, uno::UNO_QUERY_THROW
);
863 uno::Reference
< drawing::XDrawPage
> xDrawPage
= xDrawPageSupplier
->getDrawPage();
864 uno::Reference
< container::XIndexAccess
> xShapesAccess( xShapes
, uno::UNO_QUERY_THROW
);
865 return uno::Any( uno::Reference
< msforms::XShapeRange
>( new ScVbaShapeRange( this, mxContext
, xShapesAccess
, xDrawPage
, mxModel
) ) );
868 ::sal_Int32 SAL_CALL
SwVbaSelection::getStart()
870 return getRange()->getStart();
873 void SAL_CALL
SwVbaSelection::setStart( ::sal_Int32 _start
)
875 getRange()->setStart( _start
);
877 ::sal_Int32 SAL_CALL
SwVbaSelection::getEnd()
879 return getRange()->getEnd();
882 void SAL_CALL
SwVbaSelection::setEnd( ::sal_Int32 _end
)
884 getRange()->setEnd( _end
);
887 void SAL_CALL
SwVbaSelection::SelectRow()
889 uno::Reference
< word::XRows
> xRows( Rows( uno::Any() ), uno::UNO_QUERY_THROW
);
893 void SAL_CALL
SwVbaSelection::SelectColumn()
895 uno::Reference
< word::XColumns
> xColumns( Columns( uno::Any() ), uno::UNO_QUERY_THROW
);
899 uno::Any SAL_CALL
SwVbaSelection::Rows( const uno::Any
& index
)
903 GetSelectedCellRange( sTLName
, sBRName
);
905 sal_Int32 nStartRow
= 0;
906 sal_Int32 nEndRow
= 0;
907 uno::Reference
< text::XTextTable
> xTextTable
= GetXTextTable();
908 SwVbaTableHelper
aTableHelper( xTextTable
);
909 nStartRow
= aTableHelper
.getTabRowIndex( sTLName
);
910 if( !sBRName
.isEmpty() )
912 nEndRow
= aTableHelper
.getTabRowIndex( sBRName
);
919 uno::Reference
< XCollection
> xCol( new SwVbaRows( this, mxContext
, xTextTable
, xTextTable
->getRows(), nStartRow
, nEndRow
) );
920 if ( index
.hasValue() )
921 return xCol
->Item( index
, uno::Any() );
922 return uno::Any( xCol
);
925 uno::Any SAL_CALL
SwVbaSelection::Columns( const uno::Any
& index
)
929 GetSelectedCellRange( sTLName
, sBRName
);
930 sal_Int32 nStartColumn
= 0;
931 sal_Int32 nEndColumn
= 0;
933 uno::Reference
< text::XTextTable
> xTextTable
= GetXTextTable();
934 SwVbaTableHelper
aTableHelper( xTextTable
);
935 nStartColumn
= aTableHelper
.getTabColIndex( sTLName
);
936 if( !sBRName
.isEmpty() )
938 nEndColumn
= aTableHelper
.getTabColIndex( sBRName
);
942 nEndColumn
= nStartColumn
;
945 uno::Reference
< XCollection
> xCol( new SwVbaColumns( this, mxContext
, xTextTable
, xTextTable
->getColumns(), nStartColumn
, nEndColumn
) );
946 if ( index
.hasValue() )
947 return xCol
->Item( index
, uno::Any() );
948 return uno::Any( xCol
);
951 uno::Reference
< text::XTextTable
> SwVbaSelection::GetXTextTable() const
953 uno::Reference
< beans::XPropertySet
> xCursorProps( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
954 uno::Reference
< text::XTextTable
> xTextTable
;
955 xCursorProps
->getPropertyValue("TextTable") >>= xTextTable
;
959 bool SwVbaSelection::IsInTable() const
961 uno::Reference
< text::XTextTable
> xTextTable
= GetXTextTable();
962 return xTextTable
.is();
965 bool SwVbaSelection::HasSelection()
967 uno::Reference
< text::XTextRange
> xStart
= mxTextViewCursor
->getStart();
968 uno::Reference
< text::XTextRange
> xEnd
= mxTextViewCursor
->getEnd();
969 uno::Reference
< text::XTextRangeCompare
> xTRC( mxTextViewCursor
->getText(), uno::UNO_QUERY_THROW
);
970 return xTRC
->compareRegionStarts( xStart
, xEnd
) != 0 || xTRC
->compareRegionEnds( xStart
, xEnd
) != 0;
973 void SwVbaSelection::GetSelectedCellRange( OUString
& sTLName
, OUString
& sBRName
)
975 uno::Reference
< beans::XPropertySet
> xCursorProps( mxTextViewCursor
, uno::UNO_QUERY_THROW
);
976 uno::Reference
< text::XTextTable
> xTextTable
;
977 xCursorProps
->getPropertyValue("TextTable") >>= xTextTable
;
978 if( !xTextTable
.is() )
979 throw uno::RuntimeException( );
981 uno::Reference
< text::XTextTableCursor
> xTextTableCursor( mxModel
->getCurrentSelection(), uno::UNO_QUERY
);
982 if( xTextTableCursor
.is() )
984 const OUString
sRange( xTextTableCursor
->getRangeName() );
985 if (!sRange
.isEmpty())
988 sTLName
= sRange
.getToken(0, ':', nIdx
);
989 sBRName
= sRange
.getToken(0, ':', nIdx
);
992 if( sTLName
.isEmpty() )
994 uno::Reference
< table::XCell
> xCell
;
995 xCursorProps
->getPropertyValue("Cell") >>= xCell
;
998 throw uno::RuntimeException( );
1000 uno::Reference
< beans::XPropertySet
> xCellProps( xCell
, uno::UNO_QUERY_THROW
);
1001 xCellProps
->getPropertyValue("CellName") >>= sTLName
;
1005 uno::Any SAL_CALL
SwVbaSelection::Cells( const uno::Any
& index
)
1009 GetSelectedCellRange( sTLName
, sBRName
);
1010 sal_Int32 nLeft
= 0;
1012 sal_Int32 nRight
= 0;
1013 sal_Int32 nBottom
= 0;
1015 uno::Reference
< text::XTextTable
> xTextTable
= GetXTextTable();
1016 SwVbaTableHelper
aTableHelper( xTextTable
);
1017 nLeft
= aTableHelper
.getTabColIndex( sTLName
);
1018 nTop
= aTableHelper
.getTabRowIndex( sTLName
);
1019 if( !sBRName
.isEmpty() )
1021 nRight
= aTableHelper
.getTabColIndex( sBRName
);
1022 nBottom
= aTableHelper
.getTabRowIndex( sBRName
);
1030 uno::Reference
< XCollection
> xCol( new SwVbaCells( this, mxContext
, xTextTable
, nLeft
, nTop
, nRight
, nBottom
) );
1031 if ( index
.hasValue() )
1032 return xCol
->Item( index
, uno::Any() );
1033 return uno::Any( xCol
);
1036 void SAL_CALL
SwVbaSelection::Copy( )
1038 dispatchRequests( mxModel
,".uno:Copy" );
1041 void SAL_CALL
SwVbaSelection::CopyAsPicture( )
1043 // seems not support in Writer
1047 void SAL_CALL
SwVbaSelection::Paste( )
1049 dispatchRequests( mxModel
,".uno:Paste" );
1052 void SAL_CALL
SwVbaSelection::Collapse( const uno::Any
& Direction
)
1054 if( word::gotoSelectedObjectAnchor( mxModel
) )
1057 sal_Int32 nDirection
= word::WdCollapseDirection::wdCollapseStart
;
1058 if( Direction
.hasValue() )
1059 Direction
>>= nDirection
;
1061 uno::Reference
< text::XTextViewCursor
> xTextViewCursor
= word::getXTextViewCursor( mxModel
);
1062 if( nDirection
== word::WdCollapseDirection::wdCollapseStart
)
1064 // it is inaccurate if current selection is multiple cells, so it needs to go to start
1065 uno::Reference
< text::XTextRange
> xTextRange
= mxTextViewCursor
->getStart();
1066 xTextViewCursor
->gotoRange( xTextRange
, false );
1067 xTextViewCursor
->collapseToStart();
1069 else if( nDirection
== word::WdCollapseDirection::wdCollapseEnd
)
1071 uno::Reference
< text::XTextRange
> xTextRange
= mxTextViewCursor
->getEnd();
1072 xTextViewCursor
->gotoRange( xTextRange
, false );
1073 xTextViewCursor
->collapseToEnd();
1077 throw uno::RuntimeException();
1081 void SAL_CALL
SwVbaSelection::WholeStory( )
1083 uno::Reference
< text::XText
> xText
= word::getCurrentXText( mxModel
);
1084 // FIXME: for i#7747,if the first line is a table, it fails to select all the contents in the story.
1085 // Temporary solution, insert an empty line before the table so that it could select all the contents.
1086 uno::Reference
< container::XEnumerationAccess
> xParaAccess( xText
, uno::UNO_QUERY_THROW
);
1087 uno::Reference
< container::XEnumeration
> xParaEnum
= xParaAccess
->createEnumeration();
1088 if( xParaEnum
->hasMoreElements() )
1090 uno::Reference
< text::XTextTable
> xTextTable( xParaEnum
->nextElement(), uno::UNO_QUERY
);
1091 if( xTextTable
.is() )
1093 // insert an empty line
1094 uno::Reference
< text::XTextRange
> xFirstCellRange
= word::getFirstObjectPosition( xText
);
1095 mxTextViewCursor
->gotoRange( xFirstCellRange
, false );
1096 dispatchRequests( mxModel
,".uno:InsertPara" );
1099 uno::Reference
< text::XTextRange
> xStart
= xText
->getStart();
1100 uno::Reference
< text::XTextRange
> xEnd
= xText
->getEnd();
1101 mxTextViewCursor
->gotoRange( xStart
, false );
1102 mxTextViewCursor
->gotoRange( xEnd
, true );
1105 sal_Bool SAL_CALL
SwVbaSelection::InRange( const uno::Reference
< ::ooo::vba::word::XRange
>& Range
)
1107 return getRange()->InRange( Range
);
1110 void SAL_CALL
SwVbaSelection::SplitTable()
1113 throw uno::RuntimeException();
1115 SwDocShell
* pDocShell
= word::getDocShell( mxModel
);
1118 if (SwFEShell
* pFEShell
= pDocShell
->GetFEShell())
1119 pFEShell
->SplitTable( SplitTable_HeadlineOption::ContentCopy
);
1124 SwVbaSelection::Paragraphs( const uno::Any
& aIndex
)
1126 // Hacky implementation due to missing api ( and lack of knowledge )
1127 // we can only support a selection that is a single paragraph
1128 if ( !aIndex
.hasValue() ) // currently we can't support multiple paragraphs in a selection
1129 throw uno::RuntimeException();
1131 sal_Int32 nIndex
= 0;
1137 throw uno::RuntimeException();
1139 uno::Reference
< text::XTextRange
> xTextRange
= mxTextViewCursor
->getStart();
1140 uno::Reference
< text::XText
> xText
= xTextRange
->getText();
1141 uno::Reference
< text::XParagraphCursor
> xParaCursor( xText
->createTextCursor(), uno::UNO_QUERY_THROW
);
1142 xParaCursor
->gotoStartOfParagraph( false );
1143 xParaCursor
->gotoStartOfParagraph( true );
1145 uno::Reference
< text::XTextDocument
> xTextDoc( mxModel
, uno::UNO_QUERY_THROW
);
1146 uno::Reference
< text::XTextRange
> xParaRange( xParaCursor
, uno::UNO_QUERY_THROW
);
1147 uno::Reference
< word::XParagraph
> xParagraph
= new SwVbaParagraph( mxParent
, mxContext
, xTextDoc
, xParaRange
);
1149 aRet
<<= xParagraph
;
1154 SwVbaSelection::getServiceImplName()
1156 return "SwVbaSelection";
1159 uno::Sequence
< OUString
>
1160 SwVbaSelection::getServiceNames()
1162 static uno::Sequence
< OUString
> const aServiceNames
1164 "ooo.vba.word.Selection"
1166 return aServiceNames
;
1169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */