Quelle unotxdoc.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 <sal/config.h>
#include <officecfg/Office/Common.hxx>
#include <comphelper/dispatchcommand.hxx>
#include <comphelper/propertysequence.hxx>
#include <comphelper/string.hxx>
#include <comphelper/uno3.hxx>
#include <AnnotationWin.hxx>
#include <o3tl/any.hxx>
#include <utility>
#include <vcl/virdev.hxx>
#include <vcl/sysdata.hxx>
#include <vcl/svapp.hxx>
#include <vcl/print.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/lokhelper.hxx>
#include <sfx2/LokControlHandler.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/printer.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/awt/vclxdevice.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sfx2/lokcomponenthelpers.hxx>
#include <sfx2/ipclient.hxx>
#include <editeng/svxacorr.hxx>
#include <editeng/acorrcfg.hxx>
#include <cmdid.h>
#include <swtypes.hxx>
#include <wdocsh.hxx>
#include <wrtsh.hxx>
#include <pview.hxx>
#include <viewsh.hxx>
#include <pvprtdat.hxx>
#include <printdata.hxx>
#include <pagefrm.hxx>
#include <rootfrm.hxx>
#include <svl/stritem.hxx>
#include <unotxdoc.hxx>
#include <svl/numformat.hxx>
#include <svl/numuno.hxx>
#include <fldbas.hxx>
#include <unomap.hxx>
#include <unotextbodyhf.hxx>
#include <unotextrange.hxx>
#include <unotextcursor.hxx>
#include <unosett.hxx>
#include <unocoll.hxx>
#include <unoredlines.hxx>
#include <unosrch.hxx>
#include <sfx2/request.hxx>
#include <sfx2/objsh.hxx>
#include <unoprnms.hxx>
#include <unostyle.hxx>
#include <unodraw.hxx>
#include <svl/eitem.hxx>
#include <unotools/datetime.hxx>
#include <unocrsr.hxx>
#include <unofieldcoll.hxx>
#include <unoidxcoll.hxx>
#include <unocrsrhelper.hxx>
#include <globdoc.hxx>
#include <viewopt.hxx>
#include <unochart.hxx>
#include <charatr.hxx>
#include <svx/xmleohlp.hxx>
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/lang/NotInitializedException.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <com/sun/star/beans/XPropertyAccess.hpp>
#include <com/sun/star/document/RedlineDisplayType.hpp>
#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/script/XInvocation.hpp>
#include <com/sun/star/view/PaperOrientation.hpp>
#include <com/sun/star/view/XSelectionSupplier.hpp>
#include <sfx2/linkmgr.hxx>
#include <svx/unofill.hxx>
#include <swmodule.hxx>
#include <docstat.hxx>
#include <modcfg.hxx>
#include <ndtxt.hxx>
#include <strings.hrc>
#include <bitmaps.hlst>
#include "unodefaults.hxx"
#include "SwXDocumentSettings.hxx"
#include <doc.hxx>
#include <IDocumentSettingAccess.hxx>
#include <IDocumentDeviceAccess.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <IDocumentChartDataProviderAccess.hxx>
#include <IDocumentLinksAdministration.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <IDocumentStatistics.hxx>
#include <IDocumentStylePoolAccess.hxx>
#include <IDocumentState.hxx>
#include <drawdoc.hxx>
#include <SwStyleNameMapper.hxx>
#include <osl/file.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/propertyvalue.hxx>
#include <comphelper/storagehelper.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <sfx2/dispatch.hxx>
#include <swruler.hxx>
#include <docufld.hxx>
#include <EnhancedPDFExportHelper.hxx>
#include <numrule.hxx>
#include <editeng/langitem.hxx>
#include <docary.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <i18nutil/searchopt.hxx>
#include <charfmt.hxx>
#include <fmtcol.hxx>
#include <istyleaccess.hxx>
#include <swatrset.hxx>
#include <view.hxx>
#include <viscrs.hxx>
#include <srcview.hxx>
#include <edtwin.hxx>
#include <swdtflvr.hxx>
#include <PostItMgr.hxx>
#include <svtools/langtab.hxx>
#include <map>
#include <set>
#include <vector>
#include <editeng/eeitem.hxx>
#include <editeng/editeng.hxx>
#include <editeng/editview.hxx>
#include <svx/svdoutl.hxx>
#include <svx/svdview.hxx>
#include <comphelper/interfacecontainer4.hxx>
#include <comphelper/servicehelper.hxx>
#include <memory>
#include <redline.hxx>
#include <DocumentRedlineManager.hxx>
#include <xmloff/odffields.hxx>
#include <tools/json_writer.hxx>
#include <tools/UnitConversion.hxx>
#include <svx/svdpage.hxx>
#include <o3tl/string_view.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <IDocumentOutlineNodes.hxx>
#include <SearchResultLocator.hxx>
#include <textcontentcontrol.hxx>
#include <unocontentcontrol.hxx>
#include <unoport.hxx>
#include <unobookmark.hxx>
#include <unosection.hxx>
#include <unofield.hxx>
#include <unoframe.hxx>
#include <unoxstyle.hxx>
#include <SwXTextDefaults.hxx>
using namespace ::com::sun::star;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::i18n;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::document;
using ::osl::FileBase;
static std::unique_ptr<SwPrintUIOptions> lcl_GetPrintUIOptions(
SwDocShell * pDocShell,
const SfxViewShell * pView )
{
if (!pDocShell)
return nullptr;
const bool bWebDoc = nullptr !=
dynamic_cast <
const SwWebDocShell * >(pDocShell);
const bool bSwSrcView = nullptr !=
dynamic_cast <
const SwSrcView * >(pView);
const SwView * pSwView =
dynamic_cast <
const SwView * >(pView);
const bool bHasSelection = pSwView && pSwView->HasSelection(
false );
// check for any selection, not just text selection
const bool bHasPostIts = sw_GetPostIts(pDocShell->GetDoc()->getIDocumentFieldsAccess()
, nullptr);
// get default values to use in dialog from documents SwPrintData
const SwPrintData &rPrintData = pDocShell->GetDoc()->getIDocumentDeviceAccess().getPrintData();
// Get current page number
sal_uInt16 nCurrentPage = 1;
const SwWrtShell* pSh = pDocShell->GetWrtShell();
const SwRootFrame *pFrame = nullptr;
if (pSh)
{
SwPaM* pShellCursor = pSh->GetCursor();
nCurrentPage = pShellCursor->GetPageNum();
pFrame = pSh->GetLayout();
}
else if (!bSwSrcView)
{
const SwPagePreview* pPreview = dynamic_cast < const SwPagePreview* >(pView);
OSL_ENSURE(pPreview, "Unexpected type of the view shell" );
if (pPreview)
{
nCurrentPage = pPreview->GetSelectedPage();
pFrame = pPreview->GetViewShell()->GetLayout();
}
}
// If blanks are skipped, account for them in initial page range value
if (pFrame && !rPrintData.IsPrintEmptyPages())
{
sal_uInt16 nMax = nCurrentPage;
const SwPageFrame *pPage = dynamic_cast <const SwPageFrame*>(pFrame->Lower());
while (pPage && nMax > 0)
{
nMax--;
if (pPage->getFrameArea().Height() == 0)
nCurrentPage--;
pPage = static_cast <const SwPageFrame*>(pPage->GetNext());
}
}
return std::make_unique<SwPrintUIOptions>( nCurrentPage, bWebDoc, bSwSrcView, bHasSelection, bHasPostIts, rPrintData );
}
static SwTextFormatColl *lcl_GetParaStyle(const UIName& rCollName, SwDoc& rDoc)
{
SwTextFormatColl* pColl = rDoc.FindTextFormatCollByName( rCollName );
if ( !pColl )
{
const sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName(
rCollName, SwGetPoolIdFromName::TxtColl );
if ( USHRT_MAX != nId )
pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( nId );
}
return pColl;
}
static void lcl_DisposeView( SfxViewFrame* pToClose, SwDocShell const * pDocShell )
{
// check if the view frame still exists
SfxViewFrame* pFound = SfxViewFrame::GetFirst( pDocShell, false );
while (pFound)
{
if ( pFound == pToClose)
{
pToClose->DoClose();
break ;
}
pFound = SfxViewFrame::GetNext( *pFound, pDocShell, false );
}
}
class SwXTextDocument::Impl
{
public :
std::mutex m_Mutex; // just for OInterfaceContainerHelper4
::comphelper::OInterfaceContainerHelper4<css::util::XRefreshListener> m_RefreshListeners;
};
const Sequence< sal_Int8 > & SwXTextDocument::getUnoTunnelId()
{
static const comphelper::UnoIdInit theSwXTextDocumentUnoTunnelId;
return theSwXTextDocumentUnoTunnelId.getSeq();
}
sal_Int64 SAL_CALL SwXTextDocument::getSomething( const Sequence< sal_Int8 >& rId )
{
if ( comphelper::isUnoTunnelId<SwXTextDocument>(rId) )
{
return comphelper::getSomething_cast(this );
}
if ( comphelper::isUnoTunnelId<SfxObjectShell>(rId) )
{
return comphelper::getSomething_cast(m_pDocShell);
}
sal_Int64 nRet = SfxBaseModel::getSomething( rId );
if (nRet)
return nRet;
GetNumberFormatter();
auto xNumTunnel = comphelper::query_aggregation<XUnoTunnel>(m_xNumFormatAgg);
return (xNumTunnel.is()) ? xNumTunnel->getSomething(rId) : 0;
}
Any SAL_CALL SwXTextDocument::queryInterface( const uno::Type& rType )
{
Any aRet = SwXTextDocumentBaseClass::queryInterface(rType);
if ( !aRet.hasValue() )
aRet = SfxBaseModel::queryInterface(rType);
if ( !aRet.hasValue() &&
rType == cppu::UnoType<lang::XMultiServiceFactory>::get())
{
Reference<lang::XMultiServiceFactory> xTmp = this ;
aRet <<= xTmp;
}
if ( !aRet.hasValue()
&& rType != cppu::UnoType<css::document::XDocumentEventBroadcaster>::get()
&& rType != cppu::UnoType<css::frame::XController>::get()
&& rType != cppu::UnoType<css::frame::XFrame>::get()
&& rType != cppu::UnoType<css::script::XInvocation>::get()
&& rType != cppu::UnoType<css::beans::XFastPropertySet>::get()
&& rType != cppu::UnoType<css::awt::XWindow>::get())
{
GetNumberFormatter();
if (m_xNumFormatAgg.is())
aRet = m_xNumFormatAgg->queryAggregation(rType);
}
return aRet;
}
void SAL_CALL SwXTextDocument::acquire()noexcept
{
SfxBaseModel::acquire();
}
void SAL_CALL SwXTextDocument::release()noexcept
{
SfxBaseModel::release();
}
Sequence< uno::Type > SAL_CALL SwXTextDocument::getTypes()
{
Sequence< uno::Type > aNumTypes;
GetNumberFormatter();
if (auto xNumProv = comphelper::query_aggregation<XTypeProvider>(m_xNumFormatAgg))
aNumTypes = xNumProv->getTypes();
return comphelper::concatSequences(
SfxBaseModel::getTypes(),
SwXTextDocumentBaseClass::getTypes(),
aNumTypes,
Sequence {
cppu::UnoType<lang::XMultiServiceFactory>::get()});
}
SwXTextDocument::SwXTextDocument(SwDocShell* pShell)
: SwXTextDocumentBaseClass(pShell)
, m_pImpl(new Impl)
,
m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_DOCUMENT)),
m_pDocShell(pShell),
m_pHiddenViewFrame(nullptr),
// #i117783#
m_bApplyPagePrintSettingsFromXPagePrintable( false )
{
}
void SwXTextDocument::ThrowIfInvalid() const
{
if (!m_pDocShell)
throw DisposedException(u"SwXTextDocument not valid" _ustr,
const_cast <SwXTextDocument*>(this )->getXWeak());
}
SwDoc& SwXTextDocument::GetDocOrThrow() const
{
ThrowIfInvalid();
if (SwDoc* pDoc = m_pDocShell->GetDoc())
return *pDoc;
throw css::lang::NotInitializedException(
u"Document not initialized by a call to attachResource() or load()" _ustr,
const_cast <SwXTextDocument*>(this )->getXWeak());
}
SdrModel& SwXTextDocument::getSdrModelFromUnoModel() const
{
return *GetDocOrThrow().getIDocumentDrawModelAccess().GetDrawModel();
}
SwXTextDocument::~SwXTextDocument()
{
InitNewDoc();
if (m_xNumFormatAgg.is())
{
m_xNumFormatAgg->setDelegator({});
m_xNumFormatAgg.clear();
}
m_pPrintUIOptions.reset();
if (m_pRenderData && m_pRenderData->IsViewOptionAdjust())
{ // rhbz#827695: this can happen if the last page is not printed
// the SwViewShell has been deleted already by SwView::~SwView
// FIXME: replace this awful implementation of XRenderable with
// something less insane that has its own view
m_pRenderData->ViewOptionAdjustCrashPreventionKludge();
}
m_pRenderData.reset();
}
SwXDocumentPropertyHelper * SwXTextDocument::GetPropertyHelper ()
{
if (!mxPropertyHelper.is())
{
mxPropertyHelper = new SwXDocumentPropertyHelper(GetDocOrThrow());
}
return mxPropertyHelper.get();
}
void SwXTextDocument::GetNumberFormatter()
{
if (!m_pDocShell)
return ;
if (!m_xNumFormatAgg.is())
{
if ( m_pDocShell->GetDoc() )
{
m_xNumFormatAgg = new SvNumberFormatsSupplierObj(
m_pDocShell->GetDoc()->GetNumberFormatter());
}
if (m_xNumFormatAgg.is())
m_xNumFormatAgg->setDelegator(getXWeak());
}
else
{
auto xNumTunnel = comphelper::query_aggregation<XUnoTunnel>(m_xNumFormatAgg);
auto pNumFormat = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
OSL_ENSURE(pNumFormat, "No number formatter available" );
if (pNumFormat && !pNumFormat->GetNumberFormatter())
pNumFormat->SetNumberFormatter(GetDocOrThrow().GetNumberFormatter());
}
}
Reference< XText > SwXTextDocument::getText()
{
return getBodyText();
}
rtl::Reference< SwXBodyText > SwXTextDocument::getBodyText()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!m_xBodyText.is())
{
m_xBodyText = new SwXBodyText(m_pDocShell->GetDoc());
}
return m_xBodyText;
}
void SwXTextDocument::reformat()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
}
void SwXTextDocument::lockControllers()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
maActionArr.emplace_front(new UnoActionContext(m_pDocShell->GetDoc()));
}
void SwXTextDocument::unlockControllers()
{
SolarMutexGuard aGuard;
if (maActionArr.empty())
throw RuntimeException(u"Nothing to unlock" _ustr);
maActionArr.pop_front();
}
sal_Bool SwXTextDocument::hasControllersLocked()
{
SolarMutexGuard aGuard;
return !maActionArr.empty();
}
Reference< frame::XController > SwXTextDocument::getCurrentController()
{
return SfxBaseModel::getCurrentController();
}
void SwXTextDocument::setCurrentController(const Reference< frame::XController > & xController)
{
SfxBaseModel::setCurrentController(xController);
}
Reference< XInterface > SwXTextDocument::getCurrentSelection()
{
SolarMutexGuard aGuard;
Reference< XInterface > xRef;
if (m_pDocShell)
{
SwView* pView = static_cast <SwView*>(SfxViewShell::GetFirst(true , checkSfxViewShell<SwView>));
while (pView && pView->GetObjectShell() != m_pDocShell)
{
pView = static_cast <SwView*>(SfxViewShell::GetNext(*pView, true , checkSfxViewShell<SwView>));
}
if (pView)
{
Any aRef = pView->GetUNOObject()->getSelection();
aRef >>= xRef;
}
}
return xRef;
}
sal_Bool SwXTextDocument::attachResource(const OUString& aURL, const Sequence< beans::PropertyValue >& aArgs)
{
#if ENABLE_YRS
// this is for new document
for (auto const & rArg : aArgs)
{
if (rArg.Name == "YrsConnect" )
{
m_pDocShell->GetDoc()->getIDocumentState().YrsInitConnector(rArg.Value);
break ;
}
}
#endif
return SfxBaseModel::attachResource(aURL, aArgs);
}
OUString SwXTextDocument::getURL()
{
return SfxBaseModel::getURL();
}
Sequence< beans::PropertyValue > SwXTextDocument::getArgs()
{
return SfxBaseModel::getArgs();
}
void SwXTextDocument::connectController(const Reference< frame::XController > & xController)
{
SfxBaseModel::connectController(xController);
}
void SwXTextDocument::disconnectController(const Reference< frame::XController > & xController)
{
SfxBaseModel::disconnectController(xController);
}
void SwXTextDocument::dispose()
{
// Delete UnoActionContexts before deleting the SwDoc, as the first has unowned pointers to the
// second.
maActionArr.clear();
SfxBaseModel::dispose();
}
void SwXTextDocument::close( sal_Bool bDeliverOwnership )
{
if (m_pDocShell)
{
uno::Sequence< uno::Any > aArgs;
m_pDocShell->CallAutomationDocumentEventSinks( u"Close" _ustr, aArgs );
}
SolarMutexGuard aGuard;
if (m_pDocShell && m_pHiddenViewFrame)
lcl_DisposeView( m_pHiddenViewFrame, m_pDocShell);
SfxBaseModel::close(bDeliverOwnership);
}
void SwXTextDocument::addEventListener(const Reference< lang::XEventListener > & aListener)
{
SfxBaseModel::addEventListener(aListener);
}
void SwXTextDocument::removeEventListener(const Reference< lang::XEventListener > & aListener)
{
SfxBaseModel::removeEventListener(aListener);
}
Reference< XPropertySet > SwXTextDocument::getLineNumberingProperties()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXLineNumberingProperties.is())
{
mxXLineNumberingProperties = new SwXLineNumberingProperties(m_pDocShell->GetDoc());
}
return mxXLineNumberingProperties;
}
Reference< XIndexReplace > SwXTextDocument::getChapterNumberingRules()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXChapterNumbering.is())
{
mxXChapterNumbering = new SwXChapterNumbering(*m_pDocShell);
}
return mxXChapterNumbering;
}
Reference< XIndexAccess > SwXTextDocument::getNumberingRules()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXNumberingRules.is() )
{
mxXNumberingRules = new SwXNumberingRulesCollection( m_pDocShell->GetDoc() );
}
return mxXNumberingRules;
}
Reference< XIndexAccess > SwXTextDocument::getFootnotes()
{
return getSwXFootnotes();
}
rtl::Reference< SwXFootnotes > SwXTextDocument::getSwXFootnotes()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXFootnotes.is())
{
mxXFootnotes = new SwXFootnotes(false , m_pDocShell->GetDoc());
}
return mxXFootnotes;
}
Reference< XPropertySet > SAL_CALL
SwXTextDocument::getFootnoteSettings()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXFootnoteSettings.is())
{
mxXFootnoteSettings = new SwXFootnoteProperties(m_pDocShell->GetDoc());
}
return mxXFootnoteSettings;
}
Reference< XIndexAccess > SwXTextDocument::getEndnotes()
{
return getSwXEndnotes();
}
rtl::Reference< SwXFootnotes > SwXTextDocument::getSwXEndnotes()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXEndnotes.is())
{
mxXEndnotes = new SwXFootnotes(true , m_pDocShell->GetDoc());
}
return mxXEndnotes;
}
Reference< XPropertySet > SwXTextDocument::getEndnoteSettings()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXEndnoteSettings.is())
{
mxXEndnoteSettings = new SwXEndnoteProperties(m_pDocShell->GetDoc());
}
return mxXEndnoteSettings;
}
Reference< XIndexAccess > SwXTextDocument::getContentControls()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXContentControls.is())
{
mxXContentControls = new SwXContentControls(m_pDocShell->GetDoc());
}
return mxXContentControls;
}
Reference< util::XReplaceDescriptor > SwXTextDocument::createReplaceDescriptor()
{
return new SwXTextSearch;
}
SwUnoCursor* SwXTextDocument::CreateCursorForSearch(Reference< XTextCursor > & xCursor)
{
rtl::Reference<SwXTextCursor> pXTextCursor = getBodyText()->CreateTextCursor(true );
xCursor.set( static_cast <text::XWordCursor*>(pXTextCursor.get()) );
auto & rUnoCursor(pXTextCursor->GetCursor());
rUnoCursor.SetRemainInSection(false );
return &rUnoCursor;
}
sal_Int32 SwXTextDocument::replaceAll(const Reference< util::XSearchDescriptor > & xDesc)
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
auto * pSearch = dynamic_cast <SwXTextSearch*>(xDesc.get());
if (!pSearch)
throw DisposedException(u"" _ustr, getXWeak());
Reference< XTextCursor > xCursor;
auto pUnoCursor(CreateCursorForSearch(xCursor));
FindRanges eRanges(FindRanges::InBody|FindRanges::InSelAll);
i18nutil::SearchOptions2 aSearchOpt;
pSearch->FillSearchOptions( aSearchOpt );
SwDocPositions eStart = pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
// Search should take place anywhere
pUnoCursor->SetRemainInSection(false );
sal_Int32 nResult;
UnoActionContext aContext(m_pDocShell->GetDoc());
//try attribute search first
if (pSearch->HasSearchAttributes()||pSearch->HasReplaceAttributes())
{
auto & pool = GetDocOrThrow().GetAttrPool();
SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
RES_PARATR_BEGIN, RES_PARATR_END-1,
RES_FRMATR_BEGIN, RES_FRMATR_END-1> aSearch(pool);
SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END-1,
RES_PARATR_BEGIN, RES_PARATR_END-1,
RES_FRMATR_BEGIN, RES_FRMATR_END-1> aReplace(pool);
pSearch->FillSearchItemSet(aSearch);
pSearch->FillReplaceItemSet(aReplace);
bool bCancel;
nResult = pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
eStart, eEnd, bCancel,
eRanges,
!pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr,
&aReplace );
}
else if (pSearch->m_bStyles)
{
SwTextFormatColl *pSearchColl = lcl_GetParaStyle(UIName(pSearch->m_sSearchText), pUnoCursor->GetDoc());
SwTextFormatColl *pReplaceColl = lcl_GetParaStyle(UIName(pSearch->m_sReplaceText), pUnoCursor->GetDoc());
bool bCancel;
nResult = pUnoCursor->FindFormat(*pSearchColl,
eStart, eEnd, bCancel,
eRanges, pReplaceColl );
}
else
{
//todo/mba: assuming that notes should be omitted
bool bCancel;
nResult = pUnoCursor->Find_Text(aSearchOpt, false /*bSearchInNotes*/,
eStart, eEnd, bCancel,
eRanges,
true );
}
return nResult;
}
Reference< util::XSearchDescriptor > SwXTextDocument::createSearchDescriptor()
{
return new SwXTextSearch;
}
// Used for findAll/First/Next
SwUnoCursor* SwXTextDocument::FindAny(const Reference< util::XSearchDescriptor > & xDesc,
Reference< XTextCursor > & xCursor,
bool bAll,
sal_Int32& nResult,
Reference< XInterface > const & xLastResult)
{
ThrowIfInvalid();
const auto pSearch = dynamic_cast <SwXTextSearch*>(xDesc.get());
if (!pSearch)
return nullptr;
auto pUnoCursor(CreateCursorForSearch(xCursor));
bool bParentInExtra = false ;
if (xLastResult.is())
{
OTextCursorHelper* pPosCursor = dynamic_cast <OTextCursorHelper*>(xLastResult.get());
SwPaM* pCursor = pPosCursor ? pPosCursor->GetPaM() : nullptr;
if (pCursor)
{
*pUnoCursor->GetPoint() = *pCursor->End();
pUnoCursor->DeleteMark();
}
else
{
SwXTextRange* pRange = dynamic_cast <SwXTextRange*>(xLastResult.get());
if (!pRange)
return nullptr;
pRange->GetPositions(*pUnoCursor);
if (pUnoCursor->HasMark())
{
if (*pUnoCursor->GetPoint() < *pUnoCursor->GetMark())
pUnoCursor->Exchange();
pUnoCursor->DeleteMark();
}
}
const SwNode& rRangeNode = pUnoCursor->GetPointNode();
bParentInExtra = rRangeNode.FindFlyStartNode() ||
rRangeNode.FindFootnoteStartNode() ||
rRangeNode.FindHeaderStartNode() ||
rRangeNode.FindFooterStartNode() ;
}
i18nutil::SearchOptions2 aSearchOpt;
pSearch->FillSearchOptions( aSearchOpt );
/**
* The following combinations are allowed:
* - Search in the body: -> FindRanges::InBody
* - Search all in the body: -> FindRanges::InBodyOnly | FindRanges::InSelAll
* - Search in selections: one / all -> FindRanges::InSel [ | FindRanges::InSelAll ]
* - Search outside the body: one / all -> FindRanges::InOther [ | FindRanges::InSelAll ]
* - Search everywhere all: -> FindRanges::InSelAll
*/
FindRanges eRanges(FindRanges::InBody);
if (bParentInExtra)
eRanges = FindRanges::InOther;
if (bAll) //always - everywhere?
eRanges = FindRanges::InSelAll;
SwDocPositions eStart = !bAll ? SwDocPositions::Curr : pSearch->m_bBack ? SwDocPositions::End : SwDocPositions::Start;
SwDocPositions eEnd = pSearch->m_bBack ? SwDocPositions::Start : SwDocPositions::End;
nResult = 0;
for (int nSearchProc = 0; nSearchProc < 2; ++nSearchProc)
{
//try attribute search first
if (pSearch->HasSearchAttributes())
{
SfxItemSetFixed<
RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
RES_TXTATR_INETFMT, RES_TXTATR_CHARFMT,
RES_PARATR_BEGIN, RES_PARATR_END - 1,
RES_FRMATR_BEGIN, RES_FRMATR_END - 1>
aSearch( GetDocOrThrow().GetAttrPool() );
pSearch->FillSearchItemSet(aSearch);
bool bCancel;
nResult = pUnoCursor->FindAttrs(aSearch, !pSearch->m_bStyles,
eStart, eEnd, bCancel,
eRanges,
!pSearch->m_sSearchText.isEmpty() ? &aSearchOpt : nullptr );
}
else if (pSearch->m_bStyles)
{
SwTextFormatColl *pSearchColl = lcl_GetParaStyle(UIName(pSearch->m_sSearchText), pUnoCursor->GetDoc());
//pSearch->sReplaceText
SwTextFormatColl *pReplaceColl = nullptr;
bool bCancel;
nResult = pUnoCursor->FindFormat(*pSearchColl,
eStart, eEnd, bCancel,
eRanges, pReplaceColl );
}
else
{
//todo/mba: assuming that notes should be omitted
bool bCancel;
nResult = pUnoCursor->Find_Text(aSearchOpt, false /*bSearchInNotes*/,
eStart, eEnd, bCancel,
eRanges );
}
if (nResult || (eRanges&(FindRanges::InSelAll|FindRanges::InOther)))
break ;
//second step - find in other
eRanges = FindRanges::InOther;
}
return pUnoCursor;
}
Reference< XIndexAccess >
SwXTextDocument::findAll(const Reference< util::XSearchDescriptor > & xDesc)
{
SolarMutexGuard aGuard;
Reference< XInterface > xTmp;
sal_Int32 nResult = 0;
Reference< XTextCursor > xCursor;
auto pResultCursor(FindAny(xDesc, xCursor, true , nResult, xTmp));
if (!pResultCursor)
throw RuntimeException(u"No result cursor" _ustr);
rtl::Reference< SwXTextRanges > xRet = SwXTextRanges::Create( nResult ? &(*pResultCursor) : nullptr );
return Reference< XIndexAccess >(xRet);
}
Reference< XInterface > SwXTextDocument::findFirst(const Reference< util::XSearchDescriptor > & xDesc)
{
SolarMutexGuard aGuard;
Reference< XInterface > xTmp;
sal_Int32 nResult = 0;
Reference< XTextCursor > xCursor;
auto pResultCursor(FindAny(xDesc, xCursor, false , nResult, xTmp));
if (!pResultCursor)
throw RuntimeException(u"No result cursor" _ustr);
Reference< XInterface > xRet;
if (nResult)
{
const uno::Reference< text::XText > xParent =
::sw::CreateParentXText(GetDocOrThrow(),
*pResultCursor->GetPoint());
xRet = *new SwXTextCursor(xParent, *pResultCursor);
}
return xRet;
}
Reference< XInterface > SwXTextDocument::findNext(const Reference< XInterface > & xStartAt,
const Reference< util::XSearchDescriptor > & xDesc)
{
SolarMutexGuard aGuard;
sal_Int32 nResult = 0;
Reference< XTextCursor > xCursor;
if (!xStartAt.is())
throw RuntimeException(u"xStartAt missing" _ustr);
auto pResultCursor(FindAny(xDesc, xCursor, false , nResult, xStartAt));
if (!pResultCursor)
throw RuntimeException(u"No result cursor" _ustr);
Reference< XInterface > xRet;
if (nResult)
{
const uno::Reference< text::XText > xParent =
::sw::CreateParentXText(GetDocOrThrow(),
*pResultCursor->GetPoint());
xRet = *new SwXTextCursor(xParent, *pResultCursor);
}
return xRet;
}
Sequence< beans::PropertyValue > SwXTextDocument::getPagePrintSettings()
{
SolarMutexGuard aGuard;
Sequence< beans::PropertyValue > aSeq(9);
ThrowIfInvalid();
beans::PropertyValue* pArray = aSeq.getArray();
SwPagePreviewPrtData aData;
const SwPagePreviewPrtData* pData = GetDocOrThrow().GetPreviewPrtData();
if (pData)
aData = *pData;
Any aVal;
aVal <<= aData.GetRow();
pArray[0] = beans::PropertyValue(u"PageRows" _ustr, -1, aVal, PropertyState_DIRECT_VALUE);
aVal <<= aData.GetCol();
pArray[1] = beans::PropertyValue(u"PageColumns" _ustr, -1, aVal, PropertyState_DIRECT_VALUE);
aVal <<= static_cast <sal_Int32>(convertTwipToMm100(aData.GetLeftSpace()));
pArray[2] = beans::PropertyValue(u"LeftMargin" _ustr, -1, aVal, PropertyState_DIRECT_VALUE);
aVal <<= static_cast <sal_Int32>(convertTwipToMm100(aData.GetRightSpace()));
pArray[3] = beans::PropertyValue(u"RightMargin" _ustr, -1, aVal, PropertyState_DIRECT_VALUE);
aVal <<= static_cast <sal_Int32>(convertTwipToMm100(aData.GetTopSpace()));
pArray[4] = beans::PropertyValue(u"TopMargin" _ustr, -1, aVal, PropertyState_DIRECT_VALUE);
aVal <<= static_cast <sal_Int32>(convertTwipToMm100(aData.GetBottomSpace()));
pArray[5] = beans::PropertyValue(u"BottomMargin" _ustr, -1, aVal, PropertyState_DIRECT_VALUE);
aVal <<= static_cast <sal_Int32>(convertTwipToMm100(aData.GetHorzSpace()));
pArray[6] = beans::PropertyValue(u"HoriMargin" _ustr, -1, aVal, PropertyState_DIRECT_VALUE);
aVal <<= static_cast <sal_Int32>(convertTwipToMm100(aData.GetVertSpace()));
pArray[7] = beans::PropertyValue(u"VertMargin" _ustr, -1, aVal, PropertyState_DIRECT_VALUE);
aVal <<= aData.GetLandscape();
pArray[8] = beans::PropertyValue(u"IsLandscape" _ustr, -1, aVal, PropertyState_DIRECT_VALUE);
return aSeq;
}
static sal_uInt32 lcl_Any_To_ULONG(const Any& rValue, bool & bException)
{
bException = false ;
TypeClass eType = rValue.getValueTypeClass();
sal_uInt32 nRet = 0;
if ( eType == TypeClass_UNSIGNED_LONG )
rValue >>= nRet;
else
{
sal_Int32 nVal=0;
bException = !(rValue >>= nVal);
if ( !bException )
nRet = static_cast <sal_uInt32>(nVal);
}
return nRet;
}
static OUString lcl_CreateOutlineString(const size_t nIndex, const SwDoc* pDoc)
{
OUStringBuffer sEntry;
const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
const SwTextNode * pTextNd = rOutlineNodes[ nIndex ]->GetTextNode();
SwNumberTree::tNumberVector aNumVector = pTextNd->GetNumberVector();
if ( pOutlRule && pTextNd->GetNumRule())
for ( int nLevel = 0;
nLevel <= pTextNd->GetActualListLevel();
nLevel++ )
{
tools::Long nVal = aNumVector[nLevel];
nVal ++;
nVal -= pOutlRule->Get(nLevel).GetStart();
sEntry.append( OUString::number(nVal) + "." );
}
if (const SwDocShell* pShell = pDoc->GetDocShell())
{
OUString sOutlineText = pDoc->getIDocumentOutlineNodes().getOutlineText(
nIndex, pShell->GetWrtShell()->GetLayout(), false );
sEntry.append(sOutlineText);
}
return sEntry.makeStringAndClear();
}
void SwXTextDocument::setPagePrintSettings(const Sequence< beans::PropertyValue >& aSettings)
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
SwPagePreviewPrtData aData;
SwDoc& rDoc = GetDocOrThrow();
//if only a few properties are coming, then use the current settings
const SwPagePreviewPrtData* pData = rDoc.GetPreviewPrtData();
if (pData)
aData = *pData;
for (const beans::PropertyValue& rProperty : aSettings)
{
OUString sName = rProperty.Name;
const Any& rVal = rProperty.Value;
bool bException;
sal_uInt32 nVal = lcl_Any_To_ULONG(rVal, bException);
if ( sName == "PageRows" )
{
if (!nVal || nVal > 0xff)
throw RuntimeException(u"Invalid value" _ustr);
aData.SetRow(nVal);
}
else if (sName == "PageColumns" )
{
if (!nVal || nVal > 0xff)
throw RuntimeException(u"Invalid value" _ustr);
aData.SetCol(nVal);
}
else if (sName == "LeftMargin" )
{
aData.SetLeftSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
}
else if (sName == "RightMargin" )
{
aData.SetRightSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
}
else if (sName == "TopMargin" )
{
aData.SetTopSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
}
else if (sName == "BottomMargin" )
{
aData.SetBottomSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
}
else if (sName == "HoriMargin" )
{
aData.SetHorzSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
}
else if (sName == "VertMargin" )
{
aData.SetVertSpace(o3tl::toTwips(nVal, o3tl::Length::mm100));
}
else if (sName == "IsLandscape" )
{
std::optional<const bool > b = o3tl::tryAccess<bool >(rVal);
bException = !b.has_value();
if (b)
{
aData.SetLandscape(*b);
}
}
else
bException = true ;
if (bException)
throw RuntimeException();
}
rDoc.SetPreviewPrtData(&aData);
}
void SwXTextDocument::printPages(const Sequence< beans::PropertyValue >& xOptions)
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
SfxViewFrame* pFrame = SfxViewFrame::LoadHiddenDocument( *m_pDocShell, SfxInterfaceId(7) );
SfxRequest aReq(FN_PRINT_PAGEPREVIEW, SfxCallMode::SYNCHRON,
GetDocOrThrow().GetAttrPool());
aReq.AppendItem(SfxBoolItem(FN_PRINT_PAGEPREVIEW, true ));
for ( const beans::PropertyValue &rProp : xOptions )
{
// get Property-Value from options
Any aValue( rProp.Value );
// FileName-Property?
if ( rProp.Name == UNO_NAME_FILE_NAME )
{
OUString sFileURL;
if ( rProp.Value >>= sFileURL )
{
// Convert the File URL into a system dependent path, as the SalPrinter expects
OUString sSystemPath;
FileBase::getSystemPathFromFileURL ( sFileURL, sSystemPath );
aReq.AppendItem(SfxStringItem( SID_FILE_NAME, sSystemPath ) );
}
else if ( rProp.Value.getValueType() != cppu::UnoType<void >::get() )
throw IllegalArgumentException();
}
// CopyCount-Property
else if ( rProp.Name == UNO_NAME_COPY_COUNT )
{
sal_Int32 nCopies = 0;
aValue >>= nCopies;
aReq.AppendItem(SfxInt16Item( SID_PRINT_COPIES, static_cast <sal_Int16>(nCopies) ) );
}
// Collate-Property
else if ( rProp.Name == UNO_NAME_COLLATE )
{
std::optional<const bool > b = o3tl::tryAccess<bool >(rProp.Value);
if ( !b.has_value() )
throw IllegalArgumentException();
aReq.AppendItem(SfxBoolItem( SID_PRINT_COLLATE, *b ) );
}
// Sort-Property
else if ( rProp.Name == UNO_NAME_SORT )
{
std::optional<const bool > b = o3tl::tryAccess<bool >(rProp.Value);
if ( !b.has_value() )
throw IllegalArgumentException();
aReq.AppendItem(SfxBoolItem( SID_PRINT_SORT, *b ) );
}
// Pages-Property
else if ( rProp.Name == UNO_NAME_PAGES )
{
OUString sTmp;
if ( !(rProp.Value >>= sTmp) )
throw IllegalArgumentException();
aReq.AppendItem( SfxStringItem( SID_PRINT_PAGES, sTmp ) );
}
}
// #i117783#
m_bApplyPagePrintSettingsFromXPagePrintable = true ;
pFrame->GetViewShell()->ExecuteSlot(aReq);
// Frame close
pFrame->DoClose();
}
Reference< XNameAccess > SwXTextDocument::getReferenceMarks()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXReferenceMarks.is())
{
mxXReferenceMarks = new SwXReferenceMarks(m_pDocShell->GetDoc());
}
return mxXReferenceMarks;
}
Reference< XEnumerationAccess > SwXTextDocument::getTextFields()
{
return getSwTextFields();
}
rtl::Reference< SwXTextFieldTypes > SwXTextDocument::getSwTextFields()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXTextFieldTypes.is())
{
mxXTextFieldTypes = new SwXTextFieldTypes(m_pDocShell->GetDoc());
}
return mxXTextFieldTypes;
}
Reference< XNameAccess > SwXTextDocument::getTextFieldMasters()
{
return getSwXTextFieldMasters();
}
rtl::Reference< SwXTextFieldMasters > SwXTextDocument::getSwXTextFieldMasters()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXTextFieldMasters.is())
{
mxXTextFieldMasters = new SwXTextFieldMasters(m_pDocShell->GetDoc());
}
return mxXTextFieldMasters;
}
Reference< XNameAccess > SwXTextDocument::getEmbeddedObjects()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXEmbeddedObjects.is())
{
mxXEmbeddedObjects = new SwXTextEmbeddedObjects(m_pDocShell->GetDoc());
}
return mxXEmbeddedObjects;
}
Reference< XNameAccess > SwXTextDocument::getBookmarks()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXBookmarks.is())
{
mxXBookmarks = new SwXBookmarks(m_pDocShell->GetDoc());
}
return mxXBookmarks;
}
Reference< XNameAccess > SwXTextDocument::getTextSections()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXTextSections.is())
{
mxXTextSections = new SwXTextSections(m_pDocShell->GetDoc());
}
return mxXTextSections;
}
Reference< XNameAccess > SwXTextDocument::getTextTables()
{
return getSwTextTables();
}
rtl::Reference<SwXTextTables> SwXTextDocument::getSwTextTables()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXTextTables.is())
{
mxXTextTables = new SwXTextTables(m_pDocShell->GetDoc());
}
return mxXTextTables;
}
Reference< XNameAccess > SwXTextDocument::getGraphicObjects()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXGraphicObjects.is())
{
mxXGraphicObjects = new SwXTextGraphicObjects(m_pDocShell->GetDoc());
}
return mxXGraphicObjects;
}
Reference< XNameAccess > SwXTextDocument::getTextFrames()
{
return getSwTextFrames();
}
rtl::Reference< SwXTextFrames > SwXTextDocument::getSwTextFrames()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXTextFrames.is())
{
mxXTextFrames = new SwXTextFrames(m_pDocShell->GetDoc());
}
return mxXTextFrames;
}
Reference< XNameAccess > SwXTextDocument::getStyleFamilies()
{
return getSwStyleFamilies();
}
rtl::Reference< SwXStyleFamilies > SwXTextDocument::getSwStyleFamilies()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXStyleFamilies.is())
{
mxXStyleFamilies = new SwXStyleFamilies(*m_pDocShell);
}
return mxXStyleFamilies;
}
uno::Reference< style::XAutoStyles > SwXTextDocument::getAutoStyles( )
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXAutoStyles.is())
{
mxXAutoStyles = new SwXAutoStyles(*m_pDocShell);
}
return mxXAutoStyles;
}
Reference< drawing::XDrawPage > SwXTextDocument::getDrawPage()
{
return getSwDrawPage();
}
rtl::Reference< SwFmDrawPage > SwXTextDocument::getSwDrawPage()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!m_xDrawPage.is())
{
SwDoc& rDoc = GetDocOrThrow();
// #i52858#
SwDrawModel& rModel = rDoc.getIDocumentDrawModelAccess().GetOrCreateDrawModel();
SdrPage* pPage = rModel.GetPage( 0 );
m_xDrawPage = new SwFmDrawPage(&rDoc, pPage);
}
return m_xDrawPage;
}
namespace {
class SwDrawPagesObj : public cppu::WeakImplHelper<
css::drawing::XDrawPages,
css::lang::XServiceInfo>
{
private :
css::uno::Reference< css::drawing::XDrawPageSupplier > m_xDoc;
public :
SwDrawPagesObj(css::uno::Reference< css::drawing::XDrawPageSupplier > xDoc) : m_xDoc(std::move(xDoc)) {}
// XDrawPages
virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL
insertNewByIndex(sal_Int32 /*nIndex*/) override { throw css::lang::NoSupportException(); }
virtual void SAL_CALL remove(const css::uno::Reference< css::drawing::XDrawPage >& /*xPage*/) override
{
throw css::lang::NoSupportException();
}
// XIndexAccess
virtual sal_Int32 SAL_CALL getCount() override { return 1; }
virtual css::uno::Any SAL_CALL getByIndex(sal_Int32 Index) override
{
if (Index != 0)
throw css::lang::IndexOutOfBoundsException(u"Writer documents have only one DrawPage!" _ustr);
return css::uno::Any(m_xDoc->getDrawPage());
}
// XElementAccess
virtual css::uno::Type SAL_CALL getElementType() override
{
return cppu::UnoType<drawing::XDrawPage>::get();
}
virtual sal_Bool SAL_CALL hasElements() override { return true ; }
// XServiceInfo
virtual OUString SAL_CALL getImplementationName() override
{
return u"SwDrawPagesObj" _ustr;
}
virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override
{
return cppu::supportsService(this , ServiceName);
}
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
{
return { u"com.sun.star.drawing.DrawPages" _ustr };
}
};
}
// XDrawPagesSupplier
uno::Reference<drawing::XDrawPages> SAL_CALL SwXTextDocument::getDrawPages()
{
SolarMutexGuard aGuard;
return new SwDrawPagesObj(this );
}
void SwXTextDocument::Invalidate()
{
m_pDocShell = nullptr;
InitNewDoc();
lang::EventObject const ev(getXWeak());
std::unique_lock aGuard(m_pImpl->m_Mutex);
m_pImpl->m_RefreshListeners.disposeAndClear(aGuard, ev);
}
void SwXTextDocument::Reactivate(SwDocShell* pNewDocShell)
{
if (m_pDocShell && m_pDocShell != pNewDocShell)
Invalidate();
m_pDocShell = pNewDocShell;
}
void SwXTextDocument::InitNewDoc()
{
if (auto xNumTunnel = comphelper::query_aggregation<XUnoTunnel>(m_xNumFormatAgg))
{
auto pNumFormat = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(xNumTunnel);
OSL_ENSURE(pNumFormat, "No number formatter available" );
if (pNumFormat)
pNumFormat->SetNumberFormatter(nullptr);
}
// first invalidate all collections, then delete references and Set to zero
if (mxXTextTables.is())
{
mxXTextTables->Invalidate();
mxXTextTables.clear();
}
if (mxXTextFrames.is())
{
mxXTextFrames->Invalidate();
mxXTextFrames.clear();
}
if (mxXGraphicObjects.is())
{
mxXGraphicObjects->Invalidate();
mxXGraphicObjects.clear();
}
if (mxXEmbeddedObjects.is())
{
mxXEmbeddedObjects->Invalidate();
mxXEmbeddedObjects.clear();
}
m_xBodyText.clear();
if (mxXTextFieldTypes.is())
{
mxXTextFieldTypes->Invalidate();
mxXTextFieldTypes.clear();
}
if (mxXTextFieldMasters.is())
{
mxXTextFieldMasters->Invalidate();
mxXTextFieldMasters.clear();
}
if (mxXTextSections.is())
{
mxXTextSections->Invalidate();
mxXTextSections.clear();
}
if (m_xDrawPage.is())
{
// #i91798#, #i91895#
// dispose XDrawPage here. We are the owner and know that it is no longer in a valid condition.
m_xDrawPage->dispose();
m_xDrawPage->InvalidateSwDoc();
m_xDrawPage.clear();
}
if ( mxXNumberingRules.is() )
{
mxXNumberingRules->Invalidate();
mxXNumberingRules.clear();
}
if (mxXFootnotes.is())
{
mxXFootnotes->Invalidate();
mxXFootnotes.clear();
}
if (mxXEndnotes.is())
{
mxXEndnotes->Invalidate();
mxXEndnotes.clear();
}
if (mxXContentControls.is())
{
mxXContentControls->Invalidate();
mxXContentControls.clear();
}
if (mxXDocumentIndexes.is())
{
mxXDocumentIndexes->Invalidate();
mxXDocumentIndexes.clear();
}
if (mxXStyleFamilies.is())
{
mxXStyleFamilies->Invalidate();
mxXStyleFamilies.clear();
}
if (mxXAutoStyles.is())
{
mxXAutoStyles->Invalidate();
mxXAutoStyles.clear();
}
if (mxXBookmarks.is())
{
mxXBookmarks->Invalidate();
mxXBookmarks.clear();
}
if (mxXChapterNumbering.is())
{
mxXChapterNumbering->Invalidate();
mxXChapterNumbering.clear();
}
if (mxXFootnoteSettings.is())
{
mxXFootnoteSettings->Invalidate();
mxXFootnoteSettings.clear();
}
if (mxXEndnoteSettings.is())
{
mxXEndnoteSettings->Invalidate();
mxXEndnoteSettings.clear();
}
if (mxXLineNumberingProperties.is())
{
mxXLineNumberingProperties->Invalidate();
mxXLineNumberingProperties.clear();
}
if (mxXReferenceMarks.is())
{
mxXReferenceMarks->Invalidate();
mxXReferenceMarks.clear();
}
if (mxLinkTargetSupplier.is())
{
mxLinkTargetSupplier->Invalidate();
mxLinkTargetSupplier.clear();
}
if (mxXRedlines.is())
{
mxXRedlines->Invalidate();
mxXRedlines.clear();
}
if (mxPropertyHelper.is())
{
mxPropertyHelper->Invalidate();
mxPropertyHelper.clear();
}
}
css::uno::Reference<css::uno::XInterface> SwXTextDocument::create(
OUString const & rServiceName,
css::uno::Sequence<css::uno::Any> const * arguments)
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
if (nType != SwServiceType::Invalid)
{
return SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
}
if (rServiceName == "com.sun.star.drawing.DashTable" )
{
return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Dash);
}
if (rServiceName == "com.sun.star.drawing.GradientTable" )
{
return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Gradient);
}
if (rServiceName == "com.sun.star.drawing.HatchTable" )
{
return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Hatch);
}
if (rServiceName == "com.sun.star.drawing.BitmapTable" )
{
return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Bitmap);
}
if (rServiceName == "com.sun.star.drawing.TransparencyGradientTable" )
{
return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::TransGradient);
}
if (rServiceName == "com.sun.star.drawing.MarkerTable" )
{
return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Marker);
}
if (rServiceName == "com.sun.star.drawing.Defaults" )
{
return GetPropertyHelper()->GetDrawTable(SwCreateDrawTable::Defaults);
}
if (rServiceName == "com.sun.star.document.Settings" )
{
return Reference<XInterface>(*new SwXDocumentSettings(this ));
}
if (rServiceName == "com.sun.star.document.ImportEmbeddedObjectResolver" )
{
return cppu::getXWeak(
new SvXMLEmbeddedObjectHelper(
*m_pDocShell, SvXMLEmbeddedObjectHelperMode::Read));
}
if (rServiceName == "com.sun.star.text.DocumentSettings" )
{
return Reference<XInterface>(*new SwXDocumentSettings(this ));
}
if (rServiceName == "com.sun.star.chart2.data.DataProvider" )
{
return Reference<XInterface>(
cppu::getXWeak(
m_pDocShell->getIDocumentChartDataProviderAccess().
GetChartDataProvider()));
}
if (!rServiceName.startsWith("com.sun.star." )
|| rServiceName.endsWith(".OLE2Shape" ))
{
// We do not want to insert OLE2 Shapes (e.g.,
// "com.sun.star.drawing.OLE2Shape", ...) like this (by creating them
// with the documents factory and adding the shapes to the draw page);
// for inserting OLE objects the proper way is to use
// "com.sun.star.text.TextEmbeddedObject":
throw ServiceNotRegisteredException();
}
// The XML import is allowed to create instances of
// "com.sun.star.drawing.OLE2Shape"; thus, a temporary service name is
// introduced to make this possible:
OUString aTmpServiceName(rServiceName);
if (rServiceName == "com.sun.star.drawing.temporaryForXMLImportOLE2Shape" )
{
aTmpServiceName = "com.sun.star.drawing.OLE2Shape" ;
}
Reference<XInterface> xTmp(
arguments == nullptr
? SvxFmMSFactory::createInstance(aTmpServiceName)
: SvxFmMSFactory::createInstanceWithArguments(
aTmpServiceName, *arguments));
if (rServiceName == "com.sun.star.drawing.GroupShape"
|| rServiceName == "com.sun.star.drawing.Shape3DSceneObject" )
{
return *new SwXGroupShape(xTmp, m_pDocShell->GetDoc());
}
if (rServiceName.startsWith("com.sun.star.drawing." ))
{
return *new SwXShape(xTmp, m_pDocShell->GetDoc());
}
return xTmp;
}
rtl::Reference<SwXTextField> SwXTextDocument::createTextField(
std::u16string_view rServiceName)
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
assert(nType != SwServiceType::Invalid);
uno::Reference<uno::XInterface> xTmp = SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
rtl::Reference<SwXTextField> xTextField = dynamic_cast <SwXTextField*>(xTmp.get());
assert(xTextField);
return xTextField;
}
rtl::Reference<SwXFieldmark> SwXTextDocument::createFieldmark(
std::u16string_view rServiceName)
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
assert(nType != SwServiceType::Invalid);
uno::Reference<uno::XInterface> xTmp = SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
rtl::Reference<SwXFieldmark> xTextField = dynamic_cast <SwXFieldmark*>(xTmp.get());
assert(xTextField);
return xTextField;
}
rtl::Reference< SwXSection > SwXTextDocument::createSection(std::u16string_view rObjectType)
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
const SwServiceType nType = SwXServiceProvider::GetProviderType(rObjectType);
assert(nType != SwServiceType::Invalid);
auto xTmp = SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
assert(!xTmp || dynamic_cast <SwXDocumentIndex*>(xTmp.get()) || dynamic_cast <SwXTextSection*>(xTmp.get()));
return dynamic_cast <SwXSection*>(xTmp.get());
}
rtl::Reference<SwXFieldMaster> SwXTextDocument::createFieldMaster(
std::u16string_view rServiceName)
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
const SwServiceType nType = SwXServiceProvider::GetProviderType(rServiceName);
assert(nType != SwServiceType::Invalid);
uno::Reference<uno::XInterface> xTmp = SwXServiceProvider::MakeInstance(nType, GetDocOrThrow());
rtl::Reference<SwXFieldMaster> xTextField = dynamic_cast <SwXFieldMaster*>(xTmp.get());
assert(xTextField);
return xTextField;
}
rtl::Reference< SwXDocumentSettings > SwXTextDocument::createDocumentSettings()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return new SwXDocumentSettings(this );
}
rtl::Reference< SwXTextDefaults > SwXTextDocument::createTextDefaults()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return new SwXTextDefaults(&GetDocOrThrow());
}
rtl::Reference< SwXBookmark > SwXTextDocument::createBookmark()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXBookmark::CreateXBookmark(GetDocOrThrow(), nullptr);
}
rtl::Reference< SwXFieldmark > SwXTextDocument::createFieldmark()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXFieldmark::CreateXFieldmark(GetDocOrThrow(), nullptr);
}
rtl::Reference< SwXTextSection > SwXTextDocument::createTextSection()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXTextSection::CreateXTextSection(nullptr, false );
}
rtl::Reference< SwXTextField > SwXTextDocument::createFieldAnnotation()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXTextField::CreateXTextField(&GetDocOrThrow(), nullptr, SwServiceType::FieldTypeAnnotation);
}
rtl::Reference< SwXLineBreak > SwXTextDocument::createLineBreak()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXLineBreak::CreateXLineBreak(nullptr);
}
rtl::Reference< SwXTextFrame > SwXTextDocument::createTextFrame()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXTextFrame::CreateXTextFrame(GetDocOrThrow(), nullptr);
}
rtl::Reference< SwXTextGraphicObject > SwXTextDocument::createTextGraphicObject()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXTextGraphicObject::CreateXTextGraphicObject(GetDocOrThrow(), nullptr);
}
rtl::Reference< SwXStyle > SwXTextDocument::createNumberingStyle()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXStyleFamilies::CreateStyleCharOrParaOrPseudo(SfxStyleFamily::Pseudo, GetDocOrThrow());
}
rtl::Reference< SwXStyle > SwXTextDocument::createCharacterStyle()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXStyleFamilies::CreateStyleCharOrParaOrPseudo(SfxStyleFamily::Char , GetDocOrThrow());
}
rtl::Reference< SwXStyle > SwXTextDocument::createParagraphStyle()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXStyleFamilies::CreateStyleCharOrParaOrPseudo(SfxStyleFamily::Para, GetDocOrThrow());
}
rtl::Reference< SwXPageStyle > SwXTextDocument::createPageStyle()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXStyleFamilies::CreateStylePage(GetDocOrThrow());
}
rtl::Reference< SwXContentControl > SwXTextDocument::createContentControl()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXContentControl::CreateXContentControl(GetDocOrThrow());
}
rtl::Reference< SwXFootnote > SwXTextDocument::createFootnote()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXFootnote::CreateXFootnote(GetDocOrThrow(), nullptr);
}
rtl::Reference< SwXFootnote > SwXTextDocument::createEndnote()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXFootnote::CreateXFootnote(GetDocOrThrow(), nullptr, true );
}
rtl::Reference< SwXTextEmbeddedObject > SwXTextDocument::createTextEmbeddedObject()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return SwXTextEmbeddedObject::CreateXTextEmbeddedObject(GetDocOrThrow(), nullptr);
}
rtl::Reference< SvXMLEmbeddedObjectHelper > SwXTextDocument::createEmbeddedObjectResolver()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
return new SvXMLEmbeddedObjectHelper(*m_pDocShell, SvXMLEmbeddedObjectHelperMode::Read);
}
Reference< XInterface > SwXTextDocument::createInstance(const OUString& rServiceName)
{
return create(rServiceName, nullptr);
}
Reference< XInterface > SwXTextDocument::createInstanceWithArguments(
const OUString& ServiceSpecifier,
const Sequence< Any >& Arguments)
{
return create(ServiceSpecifier, &Arguments);
}
Sequence< OUString > SwXTextDocument::getAvailableServiceNames()
{
static Sequence< OUString > aServices;
if ( !aServices.hasElements() )
{
Sequence< OUString > aRet = SvxFmMSFactory::getAvailableServiceNames();
auto i = comphelper::findValue(aRet, "com.sun.star.drawing.OLE2Shape" );
if (i != -1)
{
auto nLength = aRet.getLength();
aRet.getArray()[i] = aRet[nLength - 1];
aRet.realloc( nLength - 1 );
}
Sequence< OUString > aOwn = SwXServiceProvider::GetAllServiceNames();
aServices = comphelper::concatSequences(aRet, aOwn);
}
return aServices;
}
OUString SwXTextDocument::getImplementationName()
{
return u"SwXTextDocument" _ustr;
/* // Matching the .component information:
return dynamic_cast<SwGlobalDocShell*>( pDocShell ) != nullptr
? OUString("com.sun.star.comp.Writer.GlobalDocument")
: dynamic_cast<SwWebDocShell*>( pDocShell ) != nullptr
? OUString("com.sun.star.comp.Writer.WebDocument")
: OUString("com.sun.star.comp.Writer.TextDocument");
*/
}
sal_Bool SwXTextDocument::supportsService(const OUString& rServiceName)
{
return cppu::supportsService(this , rServiceName);
}
Sequence< OUString > SwXTextDocument::getSupportedServiceNames()
{
bool bWebDoc = (dynamic_cast <SwWebDocShell*>( m_pDocShell) != nullptr );
bool bGlobalDoc = (dynamic_cast <SwGlobalDocShell*>( m_pDocShell) != nullptr );
bool bTextDoc = (!bWebDoc && !bGlobalDoc);
Sequence< OUString > aRet (3);
OUString* pArray = aRet.getArray();
pArray[0] = "com.sun.star.document.OfficeDocument" ;
pArray[1] = "com.sun.star.text.GenericTextDocument" ;
if (bTextDoc)
pArray[2] = "com.sun.star.text.TextDocument" ;
else if (bWebDoc)
pArray[2] = "com.sun.star.text.WebDocument" ;
else if (bGlobalDoc)
pArray[2] = "com.sun.star.text.GlobalDocument" ;
return aRet;
}
Reference< XIndexAccess > SwXTextDocument::getDocumentIndexes()
{
return getSwDocumentIndexes();
}
rtl::Reference< SwXDocumentIndexes > SwXTextDocument::getSwDocumentIndexes()
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
if (!mxXDocumentIndexes.is())
{
mxXDocumentIndexes = new SwXDocumentIndexes(m_pDocShell->GetDoc());
}
return mxXDocumentIndexes;
}
Reference< XPropertySetInfo > SwXTextDocument::getPropertySetInfo()
{
static Reference< XPropertySetInfo > xRet = m_pPropSet->getPropertySetInfo();
return xRet;
}
void SwXTextDocument::setPropertyValue(const OUString& rPropertyName, const Any& aValue)
{
SolarMutexGuard aGuard;
ThrowIfInvalid();
const SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName( rPropertyName);
if (!pEntry)
throw UnknownPropertyException(rPropertyName);
if (pEntry->nFlags & PropertyAttribute::READONLY)
throw PropertyVetoException();
switch (pEntry->nWID)
{
case WID_DOC_CHAR_COUNT :
case WID_DOC_PARA_COUNT :
case WID_DOC_WORD_COUNT :
throw RuntimeException(
u"bad WID" _ustr,
getXWeak());
case WID_DOC_WORD_SEPARATOR :
{
OUString sDelim;
aValue >>= sDelim;
SwModule::get()->GetModuleConfig()->SetWordDelimiter(sDelim);
}
break ;
case WID_DOC_CHANGES_RECORD:
case WID_DOC_CHANGES_SHOW:
{
SwDoc& rDoc = GetDocOrThrow();
sw::DocumentRedlineManager& rRedlineManager = rDoc.GetDocumentRedlineManager();
bool bSet = *o3tl::doAccess<bool >(aValue);
RedlineFlags eMode = rRedlineManager.GetRedlineFlags();
if (WID_DOC_CHANGES_SHOW == pEntry->nWID)
{
eMode |= RedlineFlags(RedlineFlags::ShowInsert | RedlineFlags::ShowDelete);
if ( !bSet )
rRedlineManager.SetHideRedlines(true );
}
else if (WID_DOC_CHANGES_RECORD == pEntry->nWID)
{
eMode = bSet ? eMode|RedlineFlags::On : eMode&~RedlineFlags::On;
}
rRedlineManager.SetRedlineFlags(eMode);
}
break ;
case WID_DOC_CHANGES_PASSWORD:
{
Sequence <sal_Int8> aNew;
if (aValue >>= aNew)
{
auto & rRedlineAccess = GetDocOrThrow().getIDocumentRedlineAccess();
rRedlineAccess.SetRedlinePassword(aNew);
if (aNew.hasElements())
{
RedlineFlags eMode = rRedlineAccess.GetRedlineFlags();
eMode |= RedlineFlags::On;
rRedlineAccess.SetRedlineFlags(eMode);
}
}
}
break ;
case WID_DOC_AUTO_MARK_URL :
{
OUString sURL;
aValue >>= sURL;
GetDocOrThrow().SetTOIAutoMarkURL(sURL);
}
break ;
case WID_DOC_HIDE_TIPS :
SwModule::get()->GetModuleConfig()->SetHideFieldTips(*o3tl::doAccess<bool >(aValue));
break ;
case WID_DOC_REDLINE_DISPLAY:
{
auto & rRedlineAccess = GetDocOrThrow().getIDocumentRedlineAccess();
RedlineFlags eRedMode = rRedlineAccess.GetRedlineFlags();
eRedMode = eRedMode & (~RedlineFlags::ShowMask);
sal_Int16 nSet = 0;
aValue >>= nSet;
switch (nSet)
{
case RedlineDisplayType::NONE: break ;
case RedlineDisplayType::INSERTED: eRedMode |= RedlineFlags::ShowInsert; break ;
case RedlineDisplayType::REMOVED: eRedMode |= RedlineFlags::ShowDelete; break ;
case RedlineDisplayType::
INSERTED_AND_REMOVED: eRedMode |= RedlineFlags::ShowInsert|RedlineFlags::ShowDelete;
break ;
default : throw IllegalArgumentException();
}
rRedlineAccess.SetRedlineFlags(eRedMode);
}
break ;
case WID_DOC_TWO_DIGIT_YEAR:
{
sal_Int16 nYear = 0;
aValue >>= nYear;
SfxRequest aRequest ( SID_ATTR_YEAR2000, SfxCallMode::SLOT, GetDocOrThrow().GetAttrPool());
aRequest.AppendItem(SfxUInt16Item( SID_ATTR_YEAR2000, static_cast < sal_uInt16 > ( nYear ) ) );
m_pDocShell->Execute ( aRequest );
}
break ;
case WID_DOC_AUTOMATIC_CONTROL_FOCUS:
{
auto & rDrawModelAccess = GetDocOrThrow().getIDocumentDrawModelAccess();
bool bAuto = *o3tl::doAccess<bool >(aValue);
// if setting to true, and we don't have an
// SdrModel, then we are changing the default and
// must thus create an SdrModel, if we don't have an
// SdrModel and we are leaving the default at false,
// we don't need to make an SdrModel and can do nothing
// #i52858# - method name changed
SwDrawModel* pDrawDoc
= bAuto ? &rDrawModelAccess.GetOrCreateDrawModel() : rDrawModelAccess.GetDrawModel();
if ( nullptr != pDrawDoc )
pDrawDoc->SetAutoControlFocus( bAuto );
}
break ;
case WID_DOC_APPLY_FORM_DESIGN_MODE:
{
auto & rDrawModelAccess = GetDocOrThrow().getIDocumentDrawModelAccess();
bool bMode = *o3tl::doAccess<bool >(aValue);
// if setting to false, and we don't have an
// SdrModel, then we are changing the default and
// must thus create an SdrModel, if we don't have an
// SdrModel and we are leaving the default at true,
// we don't need to make an SdrModel and can do
// nothing
// #i52858# - method name changed
SwDrawModel* pDrawDoc
= bMode ? rDrawModelAccess.GetDrawModel() : &rDrawModelAccess.GetOrCreateDrawModel();
if ( nullptr != pDrawDoc )
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5 C=94 H=86 G=89
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland
2026-04-04