Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/sw/source/ui/vba/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 38 kB image not shown  

Quelle  vbaselection.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "vbaselection.hxx"
#include <utility>
#include <vbahelper/vbahelper.hxx>
#include "vbarange.hxx"
#include "vbafind.hxx"
#include <com/sun/star/text/XTextRange.hpp>
#include <com/sun/star/text/XTextTable.hpp>
#include <com/sun/star/text/XTextTableCursor.hpp>
#include <com/sun/star/table/XCell.hpp>
#include <basic/sberrors.hxx>
#include <ooo/vba/word/WdUnits.hpp>
#include <ooo/vba/word/WdMovementType.hpp>
#include <ooo/vba/word/WdGoToItem.hpp>
#include <ooo/vba/word/WdGoToDirection.hpp>
#include <ooo/vba/word/XBookmark.hpp>
#include <ooo/vba/word/XApplication.hpp>
#include <ooo/vba/word/WdCollapseDirection.hpp>
#include <com/sun/star/text/XPageCursor.hpp>
#include <unotbl.hxx>
#include <unocoll.hxx>
#include "vbatable.hxx"
#include <com/sun/star/view/XViewCursor.hpp>
#include <com/sun/star/view/XLineCursor.hpp>
#include <com/sun/star/text/XWordCursor.hpp>
#include <com/sun/star/text/XParagraphCursor.hpp>
#include <ooo/vba/word/WdInformation.hpp>
#include <ooo/vba/word/WdHeaderFooterIndex.hpp>
#include <ooo/vba/word/WdSeekView.hpp>
#include "vbainformationhelper.hxx"
#include "vbafield.hxx"
#include "vbaheaderfooter.hxx"
#include "vbaheaderfooterhelper.hxx"
#include <vbahelper/vbashaperange.hxx>
#include <com/sun/star/drawing/ShapeCollection.hpp>
#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include "vbarows.hxx"
#include "vbacolumns.hxx"
#include "vbatablehelper.hxx"
#include "vbacells.hxx"
#include "vbaview.hxx"
#include "vbaparagraph.hxx"
#include "vbastyle.hxx"
#include <docsh.hxx>
#include <tblenum.hxx>
#include <sal/log.hxx>
#include <fesh.hxx>
#include <unotxdoc.hxx>
#include <unodraw.hxx>
#include <unobasestyle.hxx>

using namespace ::ooo::vba;
using namespace ::com::sun::star;

SwVbaSelection::SwVbaSelection( const uno::Reference< ooo::vba::XHelperInterface >& ;rParent,
                                const uno::Reference< uno::XComponentContext >& rContext,
                                rtl::Reference< SwXTextDocument > xModel )
: SwVbaSelection_BASE( rParent, rContext ),
  mxModel(std::move( xModel ))
{
    mxTextViewCursor = word::getXTextViewCursor( mxModel );
}

SwVbaSelection::~SwVbaSelection()
{
}

uno::Reference< text::XTextRange > SwVbaSelection::GetSelectedRange()
{
    uno::Reference< text::XTextRange > xTextRange;
    uno::Reference< lang::XServiceInfo > xServiceInfo( mxModel->getCurrentSelection(), uno::UNO_QUERY_THROW );
    if( !xServiceInfo->supportsService(u"com.sun.star.text.TextRanges"_ustr) )
    {
        throw uno::RuntimeException(u"Not implemented"_ustr );
    }

    uno::Reference< container::XIndexAccess > xTextRanges( xServiceInfo, uno::UNO_QUERY_THROW );
    if( xTextRanges->getCount() > 0 )
    {
        // if there are multiple selection, just return the last selected Range.
        xTextRange.set( xTextRanges->getByIndex( xTextRanges->getCount()-1 ), uno::UNO_QUERY_THROW );
    }

    return xTextRange;
}

uno::Reference< word::XRange > SAL_CALL
SwVbaSelection::getRange()
{
    uno::Reference< text::XTextRange > xTextRange = GetSelectedRange();
    return uno::Reference< word::XRange >( new SwVbaRange( this, mxContext, mxModel, xTextRange->getStart(), xTextRange->getEnd(), mxTextViewCursor->getText() ) );
}

OUString SAL_CALL
SwVbaSelection::getText()
{
    return getRange()->getText();
}

void SAL_CALL
SwVbaSelection::setText( const OUString& rText )
{
    getRange()->setText( rText );
}

void SAL_CALL
SwVbaSelection::TypeText( const OUString& rText )
{
    // FIXME: handle the property Options.ReplaceSelection, the default value is true
    setText( rText );
}

void SAL_CALL
SwVbaSelection::HomeKey( const uno::Any& _unit, const uno::Any& _extend )
{
    sal_Int32 nUnit = word::WdUnits::wdLine;
    sal_Int32 nExtend = word::WdMovementType::wdMove;
    _unit >>= nUnit;
    _extend >>= nExtend;
    bool bExtend = nExtend == word::WdMovementType::wdExtend;

    switch( nUnit )
    {
        case word::WdUnits::wdStory:
        {
            // go to the valid text first so that the current view cursor is valid to call gotoRange.
            word::gotoSelectedObjectAnchor(mxModel);
            // go to the begin of the document
            uno::Reference< text::XText > xCurrentText = word::getCurrentXText( mxModel );
            uno::Reference< text::XTextRange > xFirstRange = word::getFirstObjectPosition( xCurrentText );
            mxTextViewCursor->gotoRange( xFirstRange, bExtend );
            break;
        }
        case word::WdUnits::wdLine:
        {
            // go to the begin of the Line
            uno::Reference< view::XLineCursor > xLineCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
            xLineCursor->gotoStartOfLine( bExtend );
            break;
        }
        default:
        {
            throw uno::RuntimeException(u"Not implemented"_ustr );
        }
    }
}

void SAL_CALL
SwVbaSelection::EndKey( const uno::Any& _unit, const uno::Any& _extend )
{
    sal_Int32 nUnit = word::WdUnits::wdLine;
    sal_Int32 nExtend = word::WdMovementType::wdMove;
    _unit >>= nUnit;
    _extend >>= nExtend;
    bool bExtend = nExtend == word::WdMovementType::wdExtend;

    switch( nUnit )
    {
        case word::WdUnits::wdStory:
        {
            // go to the valid text first so that the current view cursor is valid to call gotoRange.
            word::gotoSelectedObjectAnchor(mxModel);
            // go to the end of the document
            uno::Reference< text::XText > xCurrentText = word::getCurrentXText( mxModel );
            uno::Reference< text::XTextRange > xEnd = xCurrentText->getEnd();
            mxTextViewCursor->gotoRange( xEnd, bExtend );
            break;
        }
        case word::WdUnits::wdLine:
        {
            // go to the end of the Line
            uno::Reference< view::XLineCursor > xLineCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
            xLineCursor->gotoEndOfLine( bExtend );
            break;
        }
        default:
        {
            throw uno::RuntimeException(u"Not implemented"_ustr );
        }
    }
}

void SAL_CALL
SwVbaSelection::Deleteconst uno::Any& _unit, const uno::Any& _count )
{
    sal_Int32 nUnit = word::WdUnits::wdLine;
    sal_Int32 nCount = 0;
    if( _count.hasValue() )
        _count >>= nCount;
    if( _unit.hasValue() && ( nCount > 0 ) )
    {
        _unit >>= nUnit;
        switch( nUnit )
        {
            case word::WdUnits::wdCharacter:
            {
                if( HasSelection() )
                    nCount--;
                mxTextViewCursor->goRight( nCount, true );
                break;
            }
            default:
            {
                throw uno::RuntimeException(u"Not implemented"_ustr );
            }
        }
    }
    dispatchRequests( static_cast<SfxBaseModel*>(mxModel.get()), u".uno:Delete"_ustr );
}

void
SwVbaSelection::Move( const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend, word::E_DIRECTION eDirection )
{
    sal_Int32 nUnit = word::WdUnits::wdCharacter;
    sal_Int32 nCount = 1;
    sal_Int32 nExtend = word::WdMovementType::wdMove;

    if( _unit.hasValue() )
        _unit >>= nUnit;
    if( _count.hasValue() )
        _count >>= nCount;
    if( _extend.hasValue() )
        _extend >>= nExtend;

    if( nCount == 0 )
        return;

    bool bExpand = nExtend != word::WdMovementType::wdMove;

    switch( nUnit )
    {
        case word::WdUnits::wdCell:
        {
            if(  nExtend == word::WdMovementType::wdExtend )
            {
                DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
                return;
            }
            NextCell( nCount, eDirection );
            break;
        }
        case word::WdUnits::wdLine:
        {
            if( eDirection == word::MOVE_LEFT || eDirection == word::MOVE_RIGHT )
            {
                throw uno::RuntimeException(u"Not implemented"_ustr );
            }
            uno::Reference< view::XViewCursor > xViewCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
            if( eDirection == word::MOVE_UP )
                xViewCursor->goUp( nCount, bExpand );
            else if( eDirection == word::MOVE_DOWN )
                xViewCursor->goDown( nCount, bExpand );
            break;
        }
        case word::WdUnits::wdCharacter:
        {
            if( eDirection == word::MOVE_UP || eDirection == word::MOVE_DOWN )
            {
                throw uno::RuntimeException(u"Not implemented"_ustr );
            }
            if( word::gotoSelectedObjectAnchor( mxModel ) )
            {
                nCount--;
            }
            uno::Reference< view::XViewCursor > xViewCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
            if( eDirection == word::MOVE_LEFT )
            {
                // if current select is a cellrange or table,
                // the first count of move should move to the first selected cell.
                uno::Reference< text::XTextTableCursor > xTextTableCursor( mxModel->getCurrentSelection(), uno::UNO_QUERY );
                if ( xTextTableCursor.is() )
                {
                    uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
                    uno::Reference< text::XTextTable > xTextTable;
                    xCursorProps->getPropertyValue(u"TextTable"_ustr) >>= xTextTable;
                    if( xTextTable.is() )
                    {
                        uno::Reference< text::XTextRange > xRange( xTextTable->getCellByName( xTextTableCursor->getRangeName()), uno::UNO_QUERY_THROW );
                        mxTextViewCursor->gotoRange( xRange->getStart(), bExpand );
                        nCount--;
                    }
                }
                xViewCursor->goLeft( nCount, bExpand );
            }
            else if( eDirection == word::MOVE_RIGHT )
                xViewCursor->goRight( nCount, bExpand );
            break;
        }
        case word::WdUnits::wdWord:
        case word::WdUnits::wdParagraph:
        {
            uno::Reference< text::XTextRange > xRange = GetSelectedRange();
            uno::Reference< text::XText > xText = xRange->getText();
            uno::Reference< text::XTextCursor > xTextCursor = xText->createTextCursorByRange( xRange );
            if( nUnit == word::WdUnits::wdParagraph )
            {
                if( eDirection == word::MOVE_LEFT || eDirection == word::MOVE_RIGHT )
                {
                    throw uno::RuntimeException(u"Not implemented"_ustr );
                }
                uno::Reference< text::XParagraphCursor > xParagraphCursor( xTextCursor, uno::UNO_QUERY_THROW );
                for( sal_Int32 i=0; i<nCount; i++ )
                {
                    if( ( eDirection == word::MOVE_UP ) && !xParagraphCursor->gotoPreviousParagraph( bExpand ) )
                        break;
                    else if( ( eDirection == word::MOVE_DOWN ) && !xParagraphCursor->gotoNextParagraph( bExpand ) )
                        break;
                }
            }
            else if( nUnit == word::WdUnits::wdWord )
            {
                if( eDirection == word::MOVE_UP || eDirection == word::MOVE_DOWN )
                {
                    throw uno::RuntimeException(u"Not implemented"_ustr );
                }
                uno::Reference< text::XWordCursor > xWordCursor( xTextCursor, uno::UNO_QUERY_THROW );
                for( sal_Int32 i=0; i<nCount; i++ )
                {
                    if( (eDirection == word::MOVE_LEFT ) && !xWordCursor->gotoPreviousWord( bExpand ) )
                        break;
                    else if( ( eDirection == word::MOVE_RIGHT ) && !xWordCursor->gotoNextWord( bExpand ) )
                        break;
                }
            }
            mxTextViewCursor->gotoRange( xTextCursor->getStart(), false );
            mxTextViewCursor->gotoRange( xTextCursor->getEnd(), true );
            break;
        }
        default:
        {
            throw uno::RuntimeException(u"Not implemented"_ustr );
        }
    }
}

void SwVbaSelection::NextCell(sal_Int32 nCount, word::E_DIRECTION eDirection)
{
    uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
    uno::Reference< text::XTextTable > xTextTable;
    uno::Reference< table::XCell > xCell;
    xCursorProps->getPropertyValue(u"TextTable"_ustr) >>= xTextTable;
    xCursorProps->getPropertyValue(u"Cell"_ustr) >>= xCell;
    if( !xTextTable.is() || !xCell.is() )
    {
        DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
        return;
    }
    uno::Reference< beans::XPropertySet > xCellProps( xCell, uno::UNO_QUERY_THROW );
    OUString aCellName;
    xCellProps->getPropertyValue(u"CellName"_ustr) >>= aCellName;
    uno::Reference< text::XTextTableCursor > xTextTableCursor = xTextTable->createCursorByCellName( aCellName );
    // move the table cursor
    switch( eDirection )
    {
        case word::MOVE_LEFT:
        {
            xTextTableCursor->goLeft( nCount, false );
            break;
        }
        case word::MOVE_RIGHT:
        {
            xTextTableCursor->goRight( nCount, false );
            break;
        }
        case word::MOVE_UP:
        {
            xTextTableCursor->goUp( nCount, false );
            break;
        }
        case word::MOVE_DOWN:
        {
            xTextTableCursor->goDown( nCount, false );
            break;
        }
        default:
        {
            DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
            return;
        }
    }
    // move the view cursor
    xCell = xTextTable->getCellByName( xTextTableCursor->getRangeName() );
    mxTextViewCursor->gotoRange( uno::Reference< text::XTextRange >( xCell, uno::UNO_QUERY_THROW ), false );
}

void SAL_CALL
SwVbaSelection::MoveRight(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
{
    sal_Int32 nCount = 1;

    if( _count.hasValue() )
        _count >>= nCount;

    if( nCount == 0 )
        return;

    if( nCount < 0 )
    {
        MoveLeft( _unit, uno::Any( -nCount ), _extend );
        return;
    }

    Move( _unit, _count, _extend, word::MOVE_RIGHT );
}

void SAL_CALL
SwVbaSelection::MoveLeft(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
{
    sal_Int32 nCount = 1;
    if( _count.hasValue() )
        _count >>= nCount;

    if( nCount == 0 )
        return;

    if( nCount < 0 )
    {
        MoveRight( _unit, uno::Any( -nCount ), _extend );
        return;
    }

    Move( _unit, _count, _extend, word::MOVE_LEFT );
}

void SAL_CALL
SwVbaSelection::MoveDown(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
{
    sal_Int32 nCount = 1;

    if( _count.hasValue() )
        _count >>= nCount;

    if( nCount == 0 )
        return;

    if( nCount < 0 )
    {
        MoveUp( _unit, uno::Any( -nCount ), _extend );
        return;
    }

    Move( _unit, _count, _extend, word::MOVE_DOWN );
}

void SAL_CALL
SwVbaSelection::MoveUp(const uno::Any& _unit, const uno::Any& _count, const uno::Any& _extend)
{
    sal_Int32 nCount = 1;

    if( _count.hasValue() )
        _count >>= nCount;

    if( nCount == 0 )
        return;

    if( nCount < 0 )
    {
        MoveDown( _unit, uno::Any( -nCount ), _extend );
        return;
    }

    Move( _unit, _count, _extend, word::MOVE_UP );
}

void SAL_CALL
SwVbaSelection::TypeParagraph()
{
    // #FIXME: if the selection is an entire paragraph, it's replaced
    // by the new paragraph
    bool isCollapsed = mxTextViewCursor->isCollapsed();
    InsertParagraph();
    if( isCollapsed )
        mxTextViewCursor->collapseToStart();
}

void SAL_CALL
SwVbaSelection::InsertParagraph()
{
    // #FIXME: the selection should include the new paragraph.
    getRange()->InsertParagraph();
}

void SAL_CALL
SwVbaSelection::InsertParagraphBefore()
{
    getRange()->InsertParagraphBefore();
}

void SAL_CALL
SwVbaSelection::InsertParagraphAfter()
{
    getRange()->InsertParagraphAfter();
}

uno::Reference< word::XParagraphFormat > SAL_CALL
SwVbaSelection::getParagraphFormat()
{
    return getRange()->getParagraphFormat();
}

void SAL_CALL
SwVbaSelection::setParagraphFormat( const uno::Reference< word::XParagraphFormat >& ;rParagraphFormat )
{
    return getRange()->setParagraphFormat( rParagraphFormat );
}

uno::Reference< word::XFind > SAL_CALL
SwVbaSelection::getFind()
{
    uno::Reference< text::XTextRange > xTextRange = GetSelectedRange();
    uno::Reference< text::XTextRange > xStart = xTextRange->getStart();
    uno::Reference< text::XTextRange > xEnd = xTextRange->getEnd();
    uno::Reference< text::XTextRangeCompare > xTRC( xTextRange->getText(), uno::UNO_QUERY_THROW );
    int n = xTRC->compareRegionStarts( xStart, xEnd);
    if( n == 0 )
    {
        WholeStory();
        xTextRange = GetSelectedRange();
    }
    return SwVbaFind::GetOrCreateFind(this, mxContext, mxModel, xTextRange);
}

uno::Any SAL_CALL
SwVbaSelection::getStyle()
{
    return getRange()->getStyle();
}

void SAL_CALL
SwVbaSelection::setStyle( const uno::Any& rStyle )
{
    uno::Reference< beans::XPropertySet > xParaProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
    return SwVbaStyle::setStyle( xParaProps, rStyle );
}

uno::Reference< word::XFont > SAL_CALL
SwVbaSelection::getFont()
{
    return getRange()->getFont();
}

void SAL_CALL
SwVbaSelection::TypeBackspace()
{
    dispatchRequests( static_cast<SfxBaseModel*>(mxModel.get()), u".uno:SwBackspace"_ustr );
}

uno::Reference< word::XRange > SAL_CALL SwVbaSelection::GoToconst uno::Any& _what, const uno::Any& _which, const uno::Any& _count, const uno::Any& _name )
{
    sal_Int32 nWhat = 0;
    if( !( _what >>= nWhat ) )
         DebugHelper::basicexception(ERRCODE_BASIC_BAD_ARGUMENT, {});
    switch( nWhat )
    {
        case word::WdGoToItem::wdGoToBookmark:
        {
            uno::Reference< word::XApplication > xApplication( Application(), uno::UNO_QUERY_THROW );
            uno::Reference< word::XBookmark > xBookmark( xApplication->getActiveDocument()->Bookmarks(_name), uno::UNO_QUERY_THROW );
            xBookmark->Select();
            break;
        }
        case word::WdGoToItem::wdGoToPage:
        {
            uno::Reference< text::XPageCursor > xPageCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
            sal_Int32 nCurrPage = xPageCursor->getPage();
            sal_Int32 nLastPage = word::getPageCount( mxModel );
            sal_Int32 nCount = 0;
            if( _count.hasValue() )
                _count >>= nCount;
            sal_Int32 nWhich = 0;
            if( _which.hasValue() )
                _which >>= nWhich;
            sal_Int32 nPage = 0;
            switch( nWhich )
            {
               case word::WdGoToDirection::wdGoToLast:
               {
                   nPage = nLastPage;
                   break;
               }
               case word::WdGoToDirection::wdGoToNext:
               {
                   if( nCount !=0 )
                       nPage = nCurrPage + nCount;
                   else
                       nPage = nCurrPage + 1;
                   break;
               }
               case word::WdGoToDirection::wdGoToPrevious:
               {
                   if( nCount !=0 )
                       nPage = nCurrPage - nCount;
                   else
                       nPage = nCurrPage - 1;
                   break;
               }
               default:
               {
                   nPage = nCount;
               }
            }
            if( _name.hasValue() )
            {
                OUString sName;
                _name >>= sName;
                sal_Int32 nName = sName.toInt32();
                if( nName !=0 )
                    nPage = nName;
            }
            if( nPage <= 0 )
               nPage = 1;
            if( nPage > nLastPage )
               nPage = nLastPage;
            xPageCursor->jumpToPage( static_cast<sal_Int16>(nPage) );
            break;
        }
        case word::WdGoToItem::wdGoToSection:
        {
            uno::Reference< text::XPageCursor > xPageCursor( mxTextViewCursor, uno::UNO_QUERY_THROW );
            sal_Int32 nCount = 0;
            if( _count.hasValue() )
                _count >>= nCount;
            sal_Int32 nWhich = 0;
            if( _which.hasValue() )
                _which >>= nWhich;
            sal_Int32 nPage = 0;
            switch( nWhich )
            {
               case word::WdGoToDirection::wdGoToAbsolute:
               {
                    // currently only support this type
                    if( nCount == 1 )
                        nPage = 1;
                    break;
               }
               default:
               {
                    nPage = 0;
               }
            }
            if( nPage == 0 )
                throw uno::RuntimeException(u"Not implemented"_ustr );
            xPageCursor->jumpToPage( static_cast<sal_Int16>(nPage) );
            break;
        }
        default:
            throw uno::RuntimeException(u"Not implemented"_ustr );
    }
    return getRange();
}

::sal_Int32 SAL_CALL SwVbaSelection::getLanguageID()
{
    return getRange()->getLanguageID();
}

void SAL_CALL SwVbaSelection::setLanguageID( ::sal_Int32 _languageid )
{
    getRange()->setLanguageID( _languageid );
}

uno::Any SAL_CALL SwVbaSelection::Information( sal_Int32 _type )
{
    uno::Any result;
    switch( _type )
    {
        case word::WdInformation::wdActiveEndPageNumber:
        {
            result <<= SwVbaInformationHelper::handleWdActiveEndPageNumber( mxTextViewCursor );
            break;
        }
        case word::WdInformation::wdNumberOfPagesInDocument:
        {
            result <<= SwVbaInformationHelper::handleWdNumberOfPagesInDocument( mxModel );
            break;
        }
        case word::WdInformation::wdVerticalPositionRelativeToPage:
        {
            result <<= SwVbaInformationHelper::handleWdVerticalPositionRelativeToPage( mxModel, mxTextViewCursor );
            break;
        }
        case word::WdInformation::wdWithInTable:
        {
            uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
            uno::Reference< text::XTextTable > xTextTable;
            xCursorProps->getPropertyValue(u"TextTable"_ustr) >>= xTextTable;
            result <<= xTextTable.is();
            break;
        }
        case word::WdInformation::wdHeaderFooterType:
        {
            uno::Reference< word::XView > xView( new SwVbaView( this, mxContext, mxModel ) );
            sal_Int32 nView = xView->getSeekView();
            sal_Int32 nHeaderFooterType = 0;
            switch( nView )
            {
                case word::WdSeekView::wdSeekMainDocument:
                {
                    nHeaderFooterType = -1; // not in a header or footer
                    break;
                }
                case word::WdSeekView::wdSeekEvenPagesHeader:
                {
                    nHeaderFooterType = 0; // even page header
                    break;
                }
                case word::WdSeekView::wdSeekPrimaryHeader:
                {
                    nHeaderFooterType = 1; // odd page header
                    break;
                }
                case word::WdSeekView::wdSeekEvenPagesFooter:
                {
                    nHeaderFooterType = 2; // even page footer
                    break;
                }
                case word::WdSeekView::wdSeekPrimaryFooter:
                {
                    nHeaderFooterType = 3; // odd page footer
                    break;
                }
                case word::WdSeekView::wdSeekFirstPageHeader:
                case word::WdSeekView::wdSeekFirstPageFooter:
                {
                    uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
                    OUString aPageStyleName;
                    xCursorProps->getPropertyValue(u"PageStyleName"_ustr) >>= aPageStyleName;
                    bool bFirstPage = false;
                    if ( aPageStyleName == "First Page" )
                        bFirstPage = true;
                    if( nView == word::WdSeekView::wdSeekFirstPageHeader )
                    {
                        if( bFirstPage )
                            nHeaderFooterType = 4;
                        else
                            nHeaderFooterType = 1;
                    }
                    else
                    {
                        if( bFirstPage )
                            nHeaderFooterType = 5;
                        else
                            nHeaderFooterType = 3;
                    }
                    break;
                }
                default:
                {
                    nHeaderFooterType = -1;
                }
            }
            result <<= nHeaderFooterType;
            break;
        }
        default:
            throw uno::RuntimeException(u"Not implemented"_ustr );
    }
    return result;
}

void SAL_CALL SwVbaSelection::InsertBreak( const uno::Any& _breakType )
{
    getRange()->InsertBreak( _breakType );
}

uno::Any SAL_CALL
SwVbaSelection::Tables( const uno::Any& aIndex )
{
    // Hacky implementation due to missing api ( and lack of knowledge )
    // we can only support a selection that is a single table
    if ( !aIndex.hasValue() ) // currently we can't support multiple tables in a selection
       throw uno::RuntimeException();

    sal_Int32 nIndex = 0;
    aIndex >>= nIndex;

    uno::Any aRet;

    if ( nIndex != 1 )
       throw uno::RuntimeException();

    uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
    uno::Reference< text::XTextTable > xTextTable;
    xCursorProps->getPropertyValue(u"TextTable"_ustr) >>= xTextTable;
    if( xTextTable.is() )
    {
            uno::Reference< word::XTable > xVBATable = new SwVbaTable( mxParent, mxContext, mxModel, xTextTable );
            aRet <<= xVBATable;
            return aRet;
    }

    // if the current selection is a XTextTableCursor and the index is 1 then we can service this request, otherwise we just have to throw
    uno::Reference< text::XTextTableCursor > xTextTableCursor( mxModel->getCurrentSelection(), uno::UNO_QUERY_THROW );
    SwXTextTableCursor* pTTCursor = dynamic_cast< SwXTextTableCursor* >( xTextTableCursor.get() );
    if ( pTTCursor )
    {
        SwFrameFormat* pFormat = pTTCursor->GetFrameFormat();
        if ( pFormat )
        {
            rtl::Reference< SwXTextTable > xTable = SwXTextTables::GetObject(*pFormat);
            uno::Reference< word::XTable > xVBATable = new SwVbaTable( mxParent, mxContext, mxModel, xTable );
            aRet <<= xVBATable;
        }
    }
    return aRet;

}

uno::Any SAL_CALL
SwVbaSelection::Fields( const uno::Any& index )
{
    uno::Reference< XCollection > xCol( new SwVbaFields( mxParent, mxContext, mxModel ) );
    if ( index.hasValue() )
        return xCol->Item( index, uno::Any() );
    return uno::Any( xCol );
}

uno::Reference< word::XHeaderFooter > SAL_CALL
SwVbaSelection::getHeaderFooter()
{
    if( HeaderFooterHelper::isHeaderFooter( mxModel ) )
    {
        rtl::Reference< SwXBaseStyle > xPageStyleProps( word::getCurrentPageStyle( mxModel ) );
        sal_Int32 nIndex = word::WdHeaderFooterIndex::wdHeaderFooterPrimary;
        bool isHeader = HeaderFooterHelper::isHeader( mxModel );
        if( HeaderFooterHelper::isEvenPagesHeader( mxModel ) || HeaderFooterHelper::isEvenPagesFooter( mxModel ) )
            nIndex = word::WdHeaderFooterIndex::wdHeaderFooterEvenPages;
        else if( HeaderFooterHelper::isFirstPageHeader( mxModel ) || HeaderFooterHelper::isFirstPageFooter( mxModel ) )
            nIndex = word::WdHeaderFooterIndex::wdHeaderFooterFirstPage;

        return uno::Reference< word::XHeaderFooter >( new SwVbaHeaderFooter( this, mxContext, mxModel, xPageStyleProps, isHeader, nIndex ) );

    }
    return uno::Reference< word::XHeaderFooter >();
}

uno::Any SAL_CALL
SwVbaSelection::ShapeRange( )
{
    uno::Reference< drawing::XShapes > xShapes( mxModel->getCurrentSelection(), uno::UNO_QUERY );
    if ( !xShapes.is() )
    {
        uno::Reference< drawing::XShape > xShape( mxModel->getCurrentSelection(), uno::UNO_QUERY_THROW );
        xShapes.set( drawing::ShapeCollection::create(mxContext) );
        xShapes->add( xShape );
    }

    rtl::Reference< SwFmDrawPage > xDrawPage = mxModel->getSwDrawPage();
    uno::Reference< container::XIndexAccess > xShapesAccess( xShapes, uno::UNO_QUERY_THROW );
    return uno::Any( uno::Reference< msforms::XShapeRange >( new ScVbaShapeRange( this, mxContext, xShapesAccess, xDrawPage, static_cast<SfxBaseModel*>(mxModel.get()) ) ) );
}

::sal_Int32 SAL_CALL SwVbaSelection::getStart()
{
    return getRange()->getStart();
}

void SAL_CALL SwVbaSelection::setStart( ::sal_Int32 _start )
{
    getRange()->setStart( _start );
}
::sal_Int32 SAL_CALL SwVbaSelection::getEnd()
{
    return getRange()->getEnd();
}

void SAL_CALL SwVbaSelection::setEnd( ::sal_Int32 _end )
{
    getRange()->setEnd( _end );
}

void SAL_CALL SwVbaSelection::SelectRow()
{
    uno::Reference< word::XRows > xRows( Rows( uno::Any() ), uno::UNO_QUERY_THROW );
    xRows->Select();
}

void SAL_CALL SwVbaSelection::SelectColumn()
{
    uno::Reference< word::XColumns > xColumns( Columns( uno::Any() ), uno::UNO_QUERY_THROW );
    xColumns->Select();
}

uno::Any SAL_CALL SwVbaSelection::Rows( const uno::Any& index )
{
    OUString sTLName;
    OUString sBRName;
    GetSelectedCellRange( sTLName, sBRName );

    sal_Int32 nStartRow = 0;
    sal_Int32 nEndRow = 0;
    uno::Reference< text::XTextTable > xTextTable = GetXTextTable();
    SwVbaTableHelper aTableHelper( xTextTable );
    nStartRow = aTableHelper.getTabRowIndex( sTLName );
    if( !sBRName.isEmpty() )
    {
        nEndRow = aTableHelper.getTabRowIndex( sBRName );
    }
    else
    {
        nEndRow = nStartRow;
    }

    uno::Reference< XCollection > xCol( new SwVbaRows( this, mxContext, xTextTable, xTextTable->getRows(), nStartRow, nEndRow ) );
    if ( index.hasValue() )
        return xCol->Item( index, uno::Any() );
    return uno::Any( xCol );
}

uno::Any SAL_CALL SwVbaSelection::Columns( const uno::Any& index )
{
    OUString sTLName;
    OUString sBRName;
    GetSelectedCellRange( sTLName, sBRName );
    sal_Int32 nStartColumn = 0;
    sal_Int32 nEndColumn = 0;

    uno::Reference< text::XTextTable > xTextTable = GetXTextTable();
    SwVbaTableHelper aTableHelper( xTextTable );
    nStartColumn = aTableHelper.getTabColIndex( sTLName );
    if( !sBRName.isEmpty() )
    {
        nEndColumn = aTableHelper.getTabColIndex( sBRName );
    }
    else
    {
        nEndColumn = nStartColumn;
    }

    uno::Reference< XCollection > xCol( new SwVbaColumns( this, mxContext, xTextTable, xTextTable->getColumns(), nStartColumn, nEndColumn ) );
    if ( index.hasValue() )
        return xCol->Item( index, uno::Any() );
    return uno::Any( xCol );
}

uno::Reference< text::XTextTable > SwVbaSelection::GetXTextTable() const
{
    uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
    uno::Reference< text::XTextTable > xTextTable;
    xCursorProps->getPropertyValue(u"TextTable"_ustr) >>= xTextTable;
    return xTextTable;
}

bool SwVbaSelection::IsInTable() const
{
    uno::Reference< text::XTextTable > xTextTable = GetXTextTable();
    return xTextTable.is();
}

bool SwVbaSelection::HasSelection()
{
    uno::Reference< text::XTextRange > xStart = mxTextViewCursor->getStart();
    uno::Reference< text::XTextRange > xEnd = mxTextViewCursor->getEnd();
    uno::Reference< text::XTextRangeCompare > xTRC( mxTextViewCursor->getText(), uno::UNO_QUERY_THROW );
    return xTRC->compareRegionStarts( xStart, xEnd ) != 0 || xTRC->compareRegionEnds( xStart, xEnd ) != 0;
}

void SwVbaSelection::GetSelectedCellRange( OUString& sTLName, OUString& sBRName )
{
    uno::Reference< beans::XPropertySet > xCursorProps( mxTextViewCursor, uno::UNO_QUERY_THROW );
    uno::Reference< text::XTextTable > xTextTable;
    xCursorProps->getPropertyValue(u"TextTable"_ustr) >>= xTextTable;
    if( !xTextTable.is() )
        throw uno::RuntimeException( );

    uno::Reference< text::XTextTableCursor > xTextTableCursor( mxModel->getCurrentSelection(), uno::UNO_QUERY );
    if( xTextTableCursor.is() )
    {
        const OUString sRange( xTextTableCursor->getRangeName() );
        if (!sRange.isEmpty())
        {
            sal_Int32 nIdx{0};
            sTLName = sRange.getToken(0, ':', nIdx);
            sBRName = sRange.getToken(0, ':', nIdx);
        }
    }
    if( sTLName.isEmpty() )
    {
        uno::Reference< table::XCell > xCell;
        xCursorProps->getPropertyValue(u"Cell"_ustr) >>= xCell;
        if( !xCell.is() )
        {
            throw uno::RuntimeException( );
        }
        uno::Reference< beans::XPropertySet > xCellProps( xCell, uno::UNO_QUERY_THROW );
        xCellProps->getPropertyValue(u"CellName"_ustr) >>= sTLName;
    }
}

uno::Any SAL_CALL SwVbaSelection::Cells( const uno::Any& index )
{
    OUString sTLName;
    OUString sBRName;
    GetSelectedCellRange( sTLName, sBRName );
    sal_Int32 nLeft = 0;
    sal_Int32 nTop = 0;
    sal_Int32 nRight = 0;
    sal_Int32 nBottom = 0;

    uno::Reference< text::XTextTable > xTextTable = GetXTextTable();
    SwVbaTableHelper aTableHelper( xTextTable );
    nLeft = aTableHelper.getTabColIndex( sTLName );
    nTop = aTableHelper.getTabRowIndex( sTLName );
    if( !sBRName.isEmpty() )
    {
        nRight = aTableHelper.getTabColIndex( sBRName );
        nBottom = aTableHelper.getTabRowIndex( sBRName );
    }
    else
    {
        nRight = nLeft;
        nBottom = nTop;
    }

    uno::Reference< XCollection > xCol( new SwVbaCells( this, mxContext, xTextTable, nLeft, nTop, nRight, nBottom ) );
    if ( index.hasValue() )
        return xCol->Item( index, uno::Any() );
    return uno::Any( xCol );
}

void SAL_CALL SwVbaSelection::Copy(  )
{
    dispatchRequests( static_cast<SfxBaseModel*>(mxModel.get()), u".uno:Copy"_ustr );
}

void SAL_CALL SwVbaSelection::CopyAsPicture(  )
{
    // seems not support in Writer
    Copy();
}

void SAL_CALL SwVbaSelection::Paste(  )
{
    dispatchRequests( static_cast<SfxBaseModel*>(mxModel.get()), u".uno:Paste"_ustr );
}

void SAL_CALL SwVbaSelection::Collapse( const uno::Any& Direction )
{
    if( word::gotoSelectedObjectAnchor( mxModel ) )
        return;

    sal_Int32 nDirection = word::WdCollapseDirection::wdCollapseStart;
    if( Direction.hasValue() )
        Direction >>= nDirection;

    uno::Reference< text::XTextViewCursor > xTextViewCursor = word::getXTextViewCursor( mxModel );
    if( nDirection == word::WdCollapseDirection::wdCollapseStart )
    {
        // it is inaccurate if current selection is multiple cells, so it needs to go to start
        uno::Reference< text::XTextRange > xTextRange = mxTextViewCursor->getStart();
        xTextViewCursor->gotoRange( xTextRange, false );
        xTextViewCursor->collapseToStart();
    }
    else if( nDirection == word::WdCollapseDirection::wdCollapseEnd )
    {
        uno::Reference< text::XTextRange > xTextRange = mxTextViewCursor->getEnd();
        xTextViewCursor->gotoRange( xTextRange, false );
        xTextViewCursor->collapseToEnd();
    }
    else
    {
        throw uno::RuntimeException();
    }
}

void SAL_CALL SwVbaSelection::WholeStory(  )
{
    uno::Reference< text::XText > xText = word::getCurrentXText( mxModel );
    // FIXME: for i#7747,if the first line is a table, it fails to select all the contents in the story.
    // Temporary solution, insert an empty line before the table so that it could select all the contents.
    uno::Reference< container::XEnumerationAccess > xParaAccess( xText, uno::UNO_QUERY_THROW );
    uno::Reference< container::XEnumeration> xParaEnum = xParaAccess->createEnumeration();
    if( xParaEnum->hasMoreElements() )
    {
        uno::Reference< text::XTextTable > xTextTable( xParaEnum->nextElement(), uno::UNO_QUERY );
        if( xTextTable.is() )
        {
            // insert an empty line
            uno::Reference< text::XTextRange > xFirstCellRange = word::getFirstObjectPosition( xText );
            mxTextViewCursor->gotoRange( xFirstCellRange, false );
            dispatchRequests( static_cast<SfxBaseModel*>(mxModel.get()), u".uno:InsertPara"_ustr );
        }
    }
    uno::Reference< text::XTextRange > xStart = xText->getStart();
    uno::Reference< text::XTextRange > xEnd = xText->getEnd();
    mxTextViewCursor->gotoRange( xStart, false );
    mxTextViewCursor->gotoRange( xEnd, true );
}

sal_Bool SAL_CALL SwVbaSelection::InRange( const uno::Reference< ::ooo::vba::word::XRange >& Range )
{
    return getRange()->InRange( Range );
}

void SAL_CALL SwVbaSelection::SplitTable()
{
    if( !IsInTable() )
        throw uno::RuntimeException();

    SwDocShell* pDocShell = mxModel->GetDocShell();
    if( pDocShell )
    {
        if (SwFEShell* pFEShell = pDocShell->GetFEShell())
            pFEShell->SplitTable( SplitTable_HeadlineOption::ContentCopy );
    }
}

uno::Any SAL_CALL
SwVbaSelection::Paragraphs( const uno::Any& aIndex )
{
    // Hacky implementation due to missing api ( and lack of knowledge )
    // we can only support a selection that is a single paragraph
    if ( !aIndex.hasValue() ) // currently we can't support multiple paragraphs in a selection
       throw uno::RuntimeException();

    sal_Int32 nIndex = 0;
    aIndex >>= nIndex;

    uno::Any aRet;

    if ( nIndex != 1 )
       throw uno::RuntimeException();

    uno::Reference< text::XTextRange > xTextRange = mxTextViewCursor->getStart();
    uno::Reference< text::XText > xText = xTextRange->getText();
    uno::Reference< text::XParagraphCursor > xParaCursor( xText->createTextCursor(), uno::UNO_QUERY_THROW );
    xParaCursor->gotoStartOfParagraph( false );
    xParaCursor->gotoStartOfParagraph( true );

    uno::Reference< text::XTextRange > xParaRange( xParaCursor, uno::UNO_QUERY_THROW );
    uno::Reference< word::XParagraph > xParagraph = new SwVbaParagraph( mxParent, mxContext, mxModel, xParaRange );

    aRet <<= xParagraph;
    return aRet;
}

OUString
SwVbaSelection::getServiceImplName()
{
    return u"SwVbaSelection"_ustr;
}

uno::Sequence< OUString >
SwVbaSelection::getServiceNames()
{
    static uno::Sequence< OUString > const aServiceNames
    {
        u"ooo.vba.word.Selection"_ustr
    };
    return aServiceNames;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.