android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / ui / vba / vbaselection.cxx
blobd983bd2bd2a3cb5885c603becc14f90a82b4e540
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
20 #include <utility>
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>
37 #include <unotbl.hxx>
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"
62 #include <docsh.hxx>
63 #include <tblenum.hxx>
64 #include <sal/log.hxx>
65 #include <fesh.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 );
95 return xTextRange;
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() ) );
106 OUString SAL_CALL
107 SwVbaSelection::getText()
109 return getRange()->getText();
112 void SAL_CALL
113 SwVbaSelection::setText( const OUString& rText )
115 getRange()->setText( rText );
118 void SAL_CALL
119 SwVbaSelection::TypeText( const OUString& rText )
121 // FIXME: handle the property Options.ReplaceSelection, the default value is true
122 setText( rText );
125 void SAL_CALL
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;
130 _unit >>= nUnit;
131 _extend >>= nExtend;
132 bool bExtend = nExtend == word::WdMovementType::wdExtend;
134 switch( nUnit )
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 );
144 break;
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 );
151 break;
153 default:
155 throw uno::RuntimeException("Not implemented" );
160 void SAL_CALL
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;
165 _unit >>= nUnit;
166 _extend >>= nExtend;
167 bool bExtend = nExtend == word::WdMovementType::wdExtend;
169 switch( nUnit )
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 );
179 break;
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 );
186 break;
188 default:
190 throw uno::RuntimeException("Not implemented" );
195 void SAL_CALL
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() )
201 _count >>= nCount;
202 if( _unit.hasValue() && ( nCount > 0 ) )
204 _unit >>= nUnit;
205 switch( nUnit )
207 case word::WdUnits::wdCharacter:
209 if( HasSelection() )
210 nCount--;
211 mxTextViewCursor->goRight( nCount, true );
212 break;
214 default:
216 throw uno::RuntimeException("Not implemented" );
220 dispatchRequests( mxModel,".uno:Delete" );
223 void
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() )
231 _unit >>= nUnit;
232 if( _count.hasValue() )
233 _count >>= nCount;
234 if( _extend.hasValue() )
235 _extend >>= nExtend;
237 if( nCount == 0 )
238 return;
240 bool bExpand = nExtend != word::WdMovementType::wdMove;
242 switch( nUnit )
244 case word::WdUnits::wdCell:
246 if( nExtend == word::WdMovementType::wdExtend )
248 DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
249 return;
251 NextCell( nCount, eDirection );
252 break;
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 );
265 break;
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 ) )
275 nCount--;
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 );
292 nCount--;
295 xViewCursor->goLeft( nCount, bExpand );
297 else if( eDirection == word::MOVE_RIGHT )
298 xViewCursor->goRight( nCount, bExpand );
299 break;
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 ) )
317 break;
318 else if( ( eDirection == word::MOVE_DOWN ) && !xParagraphCursor->gotoNextParagraph( bExpand ) )
319 break;
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 ) )
332 break;
333 else if( ( eDirection == word::MOVE_RIGHT ) && !xWordCursor->gotoNextWord( bExpand ) )
334 break;
337 mxTextViewCursor->gotoRange( xTextCursor->getStart(), false );
338 mxTextViewCursor->gotoRange( xTextCursor->getEnd(), true );
339 break;
341 default:
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, {});
358 return;
360 uno::Reference< beans::XPropertySet > xCellProps( xCell, uno::UNO_QUERY_THROW );
361 OUString aCellName;
362 xCellProps->getPropertyValue("CellName") >>= aCellName;
363 uno::Reference< text::XTextTableCursor > xTextTableCursor = xTextTable->createCursorByCellName( aCellName );
364 // move the table cursor
365 switch( eDirection )
367 case word::MOVE_LEFT:
369 xTextTableCursor->goLeft( nCount, false );
370 break;
372 case word::MOVE_RIGHT:
374 xTextTableCursor->goRight( nCount, false );
375 break;
377 case word::MOVE_UP:
379 xTextTableCursor->goUp( nCount, false );
380 break;
382 case word::MOVE_DOWN:
384 xTextTableCursor->goDown( nCount, false );
385 break;
387 default:
389 DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
390 return;
393 // move the view cursor
394 xCell = xTextTable->getCellByName( xTextTableCursor->getRangeName() );
395 mxTextViewCursor->gotoRange( uno::Reference< text::XTextRange >( xCell, uno::UNO_QUERY_THROW ), false );
398 void SAL_CALL
399 SwVbaSelection::MoveRight(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
401 sal_Int32 nCount = 1;
403 if( _count.hasValue() )
404 _count >>= nCount;
406 if( nCount == 0 )
407 return;
409 if( nCount < 0 )
411 MoveLeft( _unit, uno::Any( -nCount ), _extend );
412 return;
415 Move( _unit, _count, _extend, word::MOVE_RIGHT );
418 void SAL_CALL
419 SwVbaSelection::MoveLeft(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
421 sal_Int32 nCount = 1;
422 if( _count.hasValue() )
423 _count >>= nCount;
425 if( nCount == 0 )
426 return;
428 if( nCount < 0 )
430 MoveRight( _unit, uno::Any( -nCount ), _extend );
431 return;
434 Move( _unit, _count, _extend, word::MOVE_LEFT );
437 void SAL_CALL
438 SwVbaSelection::MoveDown(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
440 sal_Int32 nCount = 1;
442 if( _count.hasValue() )
443 _count >>= nCount;
445 if( nCount == 0 )
446 return;
448 if( nCount < 0 )
450 MoveUp( _unit, uno::Any( -nCount ), _extend );
451 return;
454 Move( _unit, _count, _extend, word::MOVE_DOWN );
457 void SAL_CALL
458 SwVbaSelection::MoveUp(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
460 sal_Int32 nCount = 1;
462 if( _count.hasValue() )
463 _count >>= nCount;
465 if( nCount == 0 )
466 return;
468 if( nCount < 0 )
470 MoveDown( _unit, uno::Any( -nCount ), _extend );
471 return;
474 Move( _unit, _count, _extend, word::MOVE_UP );
477 void SAL_CALL
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();
483 InsertParagraph();
484 if( isCollapsed )
485 mxTextViewCursor->collapseToStart();
488 void SAL_CALL
489 SwVbaSelection::InsertParagraph()
491 // #FIXME: the selection should include the new paragraph.
492 getRange()->InsertParagraph();
495 void SAL_CALL
496 SwVbaSelection::InsertParagraphBefore()
498 getRange()->InsertParagraphBefore();
501 void SAL_CALL
502 SwVbaSelection::InsertParagraphAfter()
504 getRange()->InsertParagraphAfter();
507 uno::Reference< word::XParagraphFormat > SAL_CALL
508 SwVbaSelection::getParagraphFormat()
510 return getRange()->getParagraphFormat();
513 void SAL_CALL
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);
527 if( n == 0 )
529 WholeStory();
530 xTextRange = GetSelectedRange();
532 return SwVbaFind::GetOrCreateFind(this, mxContext, mxModel, xTextRange);
535 uno::Any SAL_CALL
536 SwVbaSelection::getStyle()
538 return getRange()->getStyle();
541 void SAL_CALL
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();
554 void SAL_CALL
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 )
562 sal_Int32 nWhat = 0;
563 if( !( _what >>= nWhat ) )
564 DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
565 switch( nWhat )
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 );
571 xBookmark->Select();
572 break;
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() )
581 _count >>= nCount;
582 sal_Int32 nWhich = 0;
583 if( _which.hasValue() )
584 _which >>= nWhich;
585 sal_Int32 nPage = 0;
586 switch( nWhich )
588 case word::WdGoToDirection::wdGoToLast:
590 nPage = nLastPage;
591 break;
593 case word::WdGoToDirection::wdGoToNext:
595 if( nCount !=0 )
596 nPage = nCurrPage + nCount;
597 else
598 nPage = nCurrPage + 1;
599 break;
601 case word::WdGoToDirection::wdGoToPrevious:
603 if( nCount !=0 )
604 nPage = nCurrPage - nCount;
605 else
606 nPage = nCurrPage - 1;
607 break;
609 default:
611 nPage = nCount;
614 if( _name.hasValue() )
616 OUString sName;
617 _name >>= sName;
618 sal_Int32 nName = sName.toInt32();
619 if( nName !=0 )
620 nPage = nName;
622 if( nPage <= 0 )
623 nPage = 1;
624 if( nPage > nLastPage )
625 nPage = nLastPage;
626 xPageCursor->jumpToPage( static_cast<sal_Int16>(nPage) );
627 break;
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() )
634 _count >>= nCount;
635 sal_Int32 nWhich = 0;
636 if( _which.hasValue() )
637 _which >>= nWhich;
638 sal_Int32 nPage = 0;
639 switch( nWhich )
641 case word::WdGoToDirection::wdGoToAbsolute:
643 // currently only support this type
644 if( nCount == 1 )
645 nPage = 1;
646 break;
648 default:
650 nPage = 0;
653 if( nPage == 0 )
654 throw uno::RuntimeException("Not implemented" );
655 xPageCursor->jumpToPage( static_cast<sal_Int16>(nPage) );
656 break;
658 default:
659 throw uno::RuntimeException("Not implemented" );
661 return getRange();
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 )
676 uno::Any result;
677 switch( _type )
679 case word::WdInformation::wdActiveEndPageNumber:
681 result <<= SwVbaInformationHelper::handleWdActiveEndPageNumber( mxTextViewCursor );
682 break;
684 case word::WdInformation::wdNumberOfPagesInDocument:
686 result <<= SwVbaInformationHelper::handleWdNumberOfPagesInDocument( mxModel );
687 break;
689 case word::WdInformation::wdVerticalPositionRelativeToPage:
691 result <<= SwVbaInformationHelper::handleWdVerticalPositionRelativeToPage( mxModel, mxTextViewCursor );
692 break;
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();
700 break;
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;
707 switch( nView )
709 case word::WdSeekView::wdSeekMainDocument:
711 nHeaderFooterType = -1; // not in a header or footer
712 break;
714 case word::WdSeekView::wdSeekEvenPagesHeader:
716 nHeaderFooterType = 0; // even page header
717 break;
719 case word::WdSeekView::wdSeekPrimaryHeader:
721 nHeaderFooterType = 1; // odd page header
722 break;
724 case word::WdSeekView::wdSeekEvenPagesFooter:
726 nHeaderFooterType = 2; // even page footer
727 break;
729 case word::WdSeekView::wdSeekPrimaryFooter:
731 nHeaderFooterType = 3; // odd page footer
732 break;
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" )
742 bFirstPage = true;
743 if( nView == word::WdSeekView::wdSeekFirstPageHeader )
745 if( bFirstPage )
746 nHeaderFooterType = 4;
747 else
748 nHeaderFooterType = 1;
750 else
752 if( bFirstPage )
753 nHeaderFooterType = 5;
754 else
755 nHeaderFooterType = 3;
757 break;
759 default:
761 nHeaderFooterType = -1;
764 result <<= nHeaderFooterType;
765 break;
767 default:
768 throw uno::RuntimeException("Not implemented" );
770 return result;
773 void SAL_CALL SwVbaSelection::InsertBreak( const uno::Any& _breakType )
775 getRange()->InsertBreak( _breakType );
778 uno::Any SAL_CALL
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;
787 aIndex >>= nIndex;
789 uno::Any aRet;
791 if ( nIndex != 1 )
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 );
801 aRet <<= xVBATable;
802 return aRet;
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() );
808 if ( pTTCursor )
810 SwFrameFormat* pFormat = pTTCursor->GetFrameFormat();
811 if ( pFormat )
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 );
816 aRet <<= xVBATable;
819 return aRet;
823 uno::Any SAL_CALL
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 >();
851 uno::Any SAL_CALL
852 SwVbaSelection::ShapeRange( )
854 uno::Reference< drawing::XShapes > xShapes( mxModel->getCurrentSelection(), uno::UNO_QUERY );
855 if ( !xShapes.is() )
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 );
890 xRows->Select();
893 void SAL_CALL SwVbaSelection::SelectColumn()
895 uno::Reference< word::XColumns > xColumns( Columns( uno::Any() ), uno::UNO_QUERY_THROW );
896 xColumns->Select();
899 uno::Any SAL_CALL SwVbaSelection::Rows( const uno::Any& index )
901 OUString sTLName;
902 OUString sBRName;
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 );
914 else
916 nEndRow = nStartRow;
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 )
927 OUString sTLName;
928 OUString sBRName;
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 );
940 else
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;
956 return 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())
987 sal_Int32 nIdx{0};
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;
996 if( !xCell.is() )
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 )
1007 OUString sTLName;
1008 OUString sBRName;
1009 GetSelectedCellRange( sTLName, sBRName );
1010 sal_Int32 nLeft = 0;
1011 sal_Int32 nTop = 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 );
1024 else
1026 nRight = nLeft;
1027 nBottom = nTop;
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
1044 Copy();
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 ) )
1055 return;
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();
1075 else
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()
1112 if( !IsInTable() )
1113 throw uno::RuntimeException();
1115 SwDocShell* pDocShell = word::getDocShell( mxModel );
1116 if( pDocShell )
1118 if (SwFEShell* pFEShell = pDocShell->GetFEShell())
1119 pFEShell->SplitTable( SplitTable_HeadlineOption::ContentCopy );
1123 uno::Any SAL_CALL
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;
1132 aIndex >>= nIndex;
1134 uno::Any aRet;
1136 if ( nIndex != 1 )
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;
1150 return aRet;
1153 OUString
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: */