/* -*- 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 "vbaview.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "wordvbahelper.hxx" #include "vbaheaderfooterhelper.hxx" #include using namespace ::ooo::vba; using namespace ::com::sun::star; static const sal_Int32 DEFAULT_BODY_DISTANCE = 500; SwVbaView::SwVbaView( const uno::Reference< ooo::vba::XHelperInterface >& rParent, const uno::Reference< uno::XComponentContext >& rContext, const uno::Reference< frame::XModel >& rModel ) : SwVbaView_BASE( rParent, rContext ), mxModel( rModel ) { uno::Reference< frame::XController > xController = mxModel->getCurrentController(); uno::Reference< text::XTextViewCursorSupplier > xTextViewCursorSupp( xController, uno::UNO_QUERY_THROW ); mxViewCursor = xTextViewCursorSupp->getViewCursor(); uno::Reference< view::XViewSettingsSupplier > xViewSettingSupp( xController, uno::UNO_QUERY_THROW ); mxViewSettings.set( xViewSettingSupp->getViewSettings(), uno::UNO_SET_THROW ); } SwVbaView::~SwVbaView() { } ::sal_Int32 SAL_CALL SwVbaView::getSeekView() { // FIXME: if the view cursor is in table, field, section and frame // handle if the cursor is in table uno::Reference< text::XText > xCurrentText = mxViewCursor->getText(); uno::Reference< beans::XPropertySet > xCursorProps( mxViewCursor, uno::UNO_QUERY_THROW ); uno::Reference< text::XTextContent > xTextContent; while( xCursorProps->getPropertyValue("TextTable") >>= xTextContent ) { xCurrentText = xTextContent->getAnchor()->getText(); xCursorProps.set( xCurrentText->createTextCursor(), uno::UNO_QUERY_THROW ); } uno::Reference< lang::XServiceInfo > xServiceInfo( xCurrentText, uno::UNO_QUERY_THROW ); OUString aImplName = xServiceInfo->getImplementationName(); if ( aImplName == "SwXBodyText" ) { return word::WdSeekView::wdSeekMainDocument; } else if ( aImplName == "SwXHeadFootText" ) { if( HeaderFooterHelper::isHeader( mxModel ) ) { if( HeaderFooterHelper::isFirstPageHeader( mxModel ) ) return word::WdSeekView::wdSeekFirstPageHeader; else if( HeaderFooterHelper::isEvenPagesHeader( mxModel ) ) return word::WdSeekView::wdSeekEvenPagesHeader; else return word::WdSeekView::wdSeekPrimaryHeader; } else { if( HeaderFooterHelper::isFirstPageFooter( mxModel ) ) return word::WdSeekView::wdSeekFirstPageFooter; else if( HeaderFooterHelper::isEvenPagesFooter( mxModel ) ) return word::WdSeekView::wdSeekEvenPagesFooter; else return word::WdSeekView::wdSeekPrimaryFooter; } } else if ( aImplName == "SwXFootnote" ) { if( xServiceInfo->supportsService("com.sun.star.text.Endnote") ) return word::WdSeekView::wdSeekEndnotes; else return word::WdSeekView::wdSeekFootnotes; } return word::WdSeekView::wdSeekMainDocument; } void SAL_CALL SwVbaView::setSeekView( ::sal_Int32 _seekview ) { // FIXME: save the current cursor position, if the cursor is in the main // document, so we can jump back to this position, if the macro sets // the ViewMode back to wdSeekMainDocument word::gotoSelectedObjectAnchor( mxModel ); switch( _seekview ) { case word::WdSeekView::wdSeekFirstPageFooter: case word::WdSeekView::wdSeekFirstPageHeader: case word::WdSeekView::wdSeekCurrentPageFooter: case word::WdSeekView::wdSeekCurrentPageHeader: case word::WdSeekView::wdSeekPrimaryFooter: case word::WdSeekView::wdSeekPrimaryHeader: case word::WdSeekView::wdSeekEvenPagesFooter: case word::WdSeekView::wdSeekEvenPagesHeader: { // need to test mxViewCursor->gotoRange( getHFTextRange( _seekview ), false ); break; } case word::WdSeekView::wdSeekFootnotes: { uno::Reference< text::XFootnotesSupplier > xFootnotesSupp( mxModel, uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xFootnotes( xFootnotesSupp->getFootnotes(), uno::UNO_SET_THROW ); if( xFootnotes->getCount() > 0 ) { uno::Reference< text::XText > xText( xFootnotes->getByIndex(0), uno::UNO_QUERY_THROW ); mxViewCursor->gotoRange( xText->getStart(), false ); } else { DebugHelper::runtimeexception( ERRCODE_BASIC_NO_ACTIVE_OBJECT ); } break; } case word::WdSeekView::wdSeekEndnotes: { uno::Reference< text::XEndnotesSupplier > xEndnotesSupp( mxModel, uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xEndnotes( xEndnotesSupp->getEndnotes(), uno::UNO_SET_THROW ); if( xEndnotes->getCount() > 0 ) { uno::Reference< text::XText > xText( xEndnotes->getByIndex(0), uno::UNO_QUERY_THROW ); mxViewCursor->gotoRange( xText->getStart(), false ); } else { DebugHelper::runtimeexception( ERRCODE_BASIC_NO_ACTIVE_OBJECT ); } break; } case word::WdSeekView::wdSeekMainDocument: { uno::Reference< text::XTextDocument > xTextDocument( mxModel, uno::UNO_QUERY_THROW ); uno::Reference< text::XText > xText = xTextDocument->getText(); mxViewCursor->gotoRange( word::getFirstObjectPosition( xText ), false ); break; } } } ::sal_Int32 SAL_CALL SwVbaView::getSplitSpecial() { return word::WdSpecialPane::wdPaneNone; } void SAL_CALL SwVbaView::setSplitSpecial( ::sal_Int32/* _splitspecial */) { // not support in Writer } sal_Bool SAL_CALL SwVbaView::getTableGridLines() { bool bShowTableGridLine = false; mxViewSettings->getPropertyValue("ShowTableBoundaries") >>= bShowTableGridLine; return bShowTableGridLine; } void SAL_CALL SwVbaView::setTableGridLines( sal_Bool _tablegridlines ) { mxViewSettings->setPropertyValue("ShowTableBoundaries", uno::makeAny( _tablegridlines ) ); } ::sal_Int32 SAL_CALL SwVbaView::getType() { // FIXME: handle wdPrintPreview type bool bOnlineLayout = false; mxViewSettings->getPropertyValue("ShowOnlineLayout") >>= bOnlineLayout; return bOnlineLayout ? word::WdViewType::wdWebView : word::WdViewType::wdPrintView; } void SAL_CALL SwVbaView::setType( ::sal_Int32 _type ) { // FIXME: handle wdPrintPreview type switch( _type ) { case word::WdViewType::wdPrintView: case word::WdViewType::wdNormalView: { mxViewSettings->setPropertyValue("ShowOnlineLayout", uno::makeAny( false ) ); break; } case word::WdViewType::wdWebView: { mxViewSettings->setPropertyValue("ShowOnlineLayout", uno::makeAny( true ) ); break; } case word::WdViewType::wdPrintPreview: { PrintPreviewHelper( uno::Any(),word::getView( mxModel ) ); break; } default: DebugHelper::runtimeexception( ERRCODE_BASIC_NOT_IMPLEMENTED ); } } uno::Reference< text::XTextRange > SwVbaView::getHFTextRange( sal_Int32 nType ) { mxModel->lockControllers(); OUString aPropIsOn; OUString aPropIsShared; OUString aPropBodyDistance; OUString aPropText; switch( nType ) { case word::WdSeekView::wdSeekCurrentPageFooter: case word::WdSeekView::wdSeekFirstPageFooter: case word::WdSeekView::wdSeekPrimaryFooter: case word::WdSeekView::wdSeekEvenPagesFooter: { aPropIsOn = "FooterIsOn"; aPropIsShared = "FooterIsShared"; aPropBodyDistance = "FooterBodyDistance"; aPropText = "FooterText"; break; } case word::WdSeekView::wdSeekCurrentPageHeader: case word::WdSeekView::wdSeekFirstPageHeader: case word::WdSeekView::wdSeekPrimaryHeader: case word::WdSeekView::wdSeekEvenPagesHeader: { aPropIsOn = "HeaderIsOn"; aPropIsShared = "HeaderIsShared"; aPropBodyDistance = "HeaderBodyDistance"; aPropText = "HeaderText"; break; } } uno::Reference< text::XPageCursor > xPageCursor( mxViewCursor, uno::UNO_QUERY_THROW ); if( nType == word::WdSeekView::wdSeekFirstPageFooter || nType == word::WdSeekView::wdSeekFirstPageHeader ) { xPageCursor->jumpToFirstPage(); } uno::Reference< style::XStyle > xStyle; uno::Reference< text::XText > xText; switch( nType ) { case word::WdSeekView::wdSeekPrimaryFooter: case word::WdSeekView::wdSeekPrimaryHeader: case word::WdSeekView::wdSeekEvenPagesFooter: case word::WdSeekView::wdSeekEvenPagesHeader: { // The primary header is the first header of the section. // If the header is not shared between odd and even pages // the odd page's header is the primary header. If the // first page's header is different from the rest of the // document, it is NOT the primary header ( the next primary // header would be on page 3 ) // The even pages' header is only available if the header is // not shared and the current style is applied to a page with // an even page number uno::Reference< beans::XPropertySet > xCursorProps( mxViewCursor, uno::UNO_QUERY_THROW ); OUString aPageStyleName; xCursorProps->getPropertyValue("PageStyleName") >>= aPageStyleName; if ( aPageStyleName == "First Page" ) { // go to the beginning of where the next style is used bool hasNextPage = false; xStyle = word::getCurrentPageStyle( mxModel ); do { hasNextPage = xPageCursor->jumpToNextPage(); } while( hasNextPage && ( xStyle == word::getCurrentPageStyle( mxModel ) ) ); if( !hasNextPage ) DebugHelper::basicexception( ERRCODE_BASIC_BAD_ACTION, OUString() ); } break; } default: { break; } } xStyle = word::getCurrentPageStyle( mxModel ); uno::Reference< beans::XPropertySet > xPageProps( xStyle, uno::UNO_QUERY_THROW ); bool isOn = false; xPageProps->getPropertyValue( aPropIsOn ) >>= isOn; bool isShared = false; xPageProps->getPropertyValue( aPropIsShared ) >>= isShared; if( !isOn ) { xPageProps->setPropertyValue( aPropIsOn, uno::makeAny( true ) ); xPageProps->setPropertyValue( aPropBodyDistance, uno::makeAny( DEFAULT_BODY_DISTANCE ) ); } if( !isShared ) { OUString aTempPropText = aPropText; if( nType == word::WdSeekView::wdSeekEvenPagesFooter || nType == word::WdSeekView::wdSeekEvenPagesHeader ) { aTempPropText += "Left"; } else { aTempPropText += "Right"; } xText.set( xPageProps->getPropertyValue( aTempPropText), uno::UNO_QUERY_THROW ); } else { if( nType == word::WdSeekView::wdSeekEvenPagesFooter || nType == word::WdSeekView::wdSeekEvenPagesHeader ) { DebugHelper::basicexception( ERRCODE_BASIC_BAD_ACTION, OUString() ); } xText.set( xPageProps->getPropertyValue( aPropText ), uno::UNO_QUERY_THROW ); } mxModel->unlockControllers(); if( !xText.is() ) { DebugHelper::basicexception( ERRCODE_BASIC_INTERNAL_ERROR, OUString() ); } uno::Reference< text::XTextRange > xTextRange = word::getFirstObjectPosition( xText ); return xTextRange; } OUString SwVbaView::getServiceImplName() { return "SwVbaView"; } uno::Sequence< OUString > SwVbaView::getServiceNames() { static uno::Sequence< OUString > const aServiceNames { "ooo.vba.word.View" }; return aServiceNames; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */