diff options
Diffstat (limited to 'sd/source/ui/docshell/docshel4.cxx')
-rw-r--r-- | sd/source/ui/docshell/docshel4.cxx | 1002 |
1 files changed, 1002 insertions, 0 deletions
diff --git a/sd/source/ui/docshell/docshel4.cxx b/sd/source/ui/docshell/docshel4.cxx new file mode 100644 index 000000000..6fe599e44 --- /dev/null +++ b/sd/source/ui/docshell/docshel4.cxx @@ -0,0 +1,1002 @@ +/* -*- 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 <sal/log.hxx> + +#include <memory> +#include <utility> + +#include <DrawDocShell.hxx> +#include <com/sun/star/document/PrinterIndependentLayout.hpp> +#include <editeng/outlobj.hxx> +#include <tools/urlobj.hxx> +#include <svx/svxids.hrc> +#include <editeng/editeng.hxx> +#include <editeng/editstat.hxx> +#include <editeng/flstitem.hxx> +#include <svl/flagitem.hxx> +#include <sot/storage.hxx> +#include <sfx2/dinfdlg.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> +#include <sfx2/dispatch.hxx> +#include <svx/svdotext.hxx> +#include <sfx2/printer.hxx> +#include <svtools/ctrltool.hxx> +#include <comphelper/classids.hxx> +#include <sot/formats.hxx> +#include <sfx2/viewfrm.hxx> +#include <vcl/syswin.hxx> +#include <com/sun/star/drawing/XDrawPage.hpp> +#include <com/sun/star/drawing/XDrawView.hpp> + +#include <app.hrc> +#include <strings.hrc> +#include <FrameView.hxx> +#include <optsitem.hxx> +#include <Outliner.hxx> +#include <sdattr.hrc> +#include <drawdoc.hxx> +#include <ViewShell.hxx> +#include <sdmod.hxx> +#include <View.hxx> +#include <EffectMigration.hxx> +#include <CustomAnimationEffect.hxx> +#include <sdpage.hxx> +#include <sdresid.hxx> +#include <DrawViewShell.hxx> +#include <ViewShellBase.hxx> +#include <OutlineView.hxx> +#include <OutlineViewShell.hxx> +#include <sdxmlwrp.hxx> +#include <sdpptwrp.hxx> +#include <sdcgmfilter.hxx> +#include <sdgrffilter.hxx> +#include <sdhtmlfilter.hxx> +#include <sdpdffilter.hxx> +#include <framework/FrameworkHelper.hxx> +#include <o3tl/string_view.hxx> + +#include <sfx2/zoomitem.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using ::sd::framework::FrameworkHelper; + +// PowerPoint-Filter +constexpr OUStringLiteral pFilterPowerPoint97( u"MS PowerPoint 97" ); +constexpr OUStringLiteral pFilterPowerPoint97Template( u"MS PowerPoint 97 Vorlage" ); +constexpr OUStringLiteral pFilterPowerPoint97AutoPlay( u"MS PowerPoint 97 AutoPlay" ); + +namespace sd { + +/** + * Creates (if necessary) and returns a SfxPrinter + */ +SfxPrinter* DrawDocShell::GetPrinter(bool bCreate) +{ + if (bCreate && !mpPrinter) + { + // create ItemSet with special pool area + auto pSet = std::make_unique<SfxItemSetFixed< + SID_PRINTER_NOTFOUND_WARN, SID_PRINTER_NOTFOUND_WARN, + SID_PRINTER_CHANGESTODOC, SID_PRINTER_CHANGESTODOC, + ATTR_OPTIONS_PRINT, ATTR_OPTIONS_PRINT>>( GetPool() ); + // set PrintOptionsSet + SdOptionsPrintItem aPrintItem( SD_MOD()->GetSdOptions(mpDoc->GetDocumentType()) ); + SfxFlagItem aFlagItem( SID_PRINTER_CHANGESTODOC ); + SfxPrinterChangeFlags nFlags = + (aPrintItem.GetOptionsPrint().IsWarningSize() ? SfxPrinterChangeFlags::CHG_SIZE : SfxPrinterChangeFlags::NONE) | + (aPrintItem.GetOptionsPrint().IsWarningOrientation() ? SfxPrinterChangeFlags::CHG_ORIENTATION : SfxPrinterChangeFlags::NONE); + aFlagItem.SetValue( static_cast<int>(nFlags) ); + + pSet->Put( aPrintItem ); + pSet->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aPrintItem.GetOptionsPrint().IsWarningPrinter() ) ); + pSet->Put( aFlagItem ); + + mpPrinter = VclPtr<SfxPrinter>::Create(std::move(pSet)); + mbOwnPrinter = true; + + // set output quality + sal_uInt16 nQuality = aPrintItem.GetOptionsPrint().GetOutputQuality(); + + DrawModeFlags nMode = DrawModeFlags::Default; + // 1 == Grayscale, 2 == Black & White (with grayscale images) + if( nQuality == 1 ) + nMode = DrawModeFlags::GrayLine | DrawModeFlags::GrayFill | DrawModeFlags::GrayText | DrawModeFlags::GrayBitmap | DrawModeFlags::GrayGradient; + else if( nQuality == 2 ) + nMode = DrawModeFlags::BlackLine | DrawModeFlags::WhiteFill | DrawModeFlags::BlackText | DrawModeFlags::GrayBitmap | DrawModeFlags::WhiteGradient; + + mpPrinter->SetDrawMode( nMode ); + + MapMode aMM (mpPrinter->GetMapMode()); + aMM.SetMapUnit(MapUnit::Map100thMM); + mpPrinter->SetMapMode(aMM); + UpdateRefDevice(); + } + return mpPrinter; +} + +/** + * Set new SfxPrinter (transfer of ownership) + */ +void DrawDocShell::SetPrinter(SfxPrinter *pNewPrinter) +{ + if ( mpViewShell ) + { + ::sd::View* pView = mpViewShell->GetView(); + if ( pView->IsTextEdit() ) + pView->SdrEndTextEdit(); + } + + if ( mpPrinter && mbOwnPrinter && (mpPrinter.get() != pNewPrinter) ) + mpPrinter.disposeAndClear(); + + mpPrinter = pNewPrinter; + mbOwnPrinter = true; + if ( mpDoc->GetPrinterIndependentLayout() == css::document::PrinterIndependentLayout::DISABLED ) + UpdateFontList(); + UpdateRefDevice(); +} + +void DrawDocShell::UpdateFontList() +{ + mpFontList.reset(); + OutputDevice* pRefDevice = nullptr; + if ( mpDoc->GetPrinterIndependentLayout() == css::document::PrinterIndependentLayout::DISABLED ) + pRefDevice = GetPrinter(true); + else + pRefDevice = SD_MOD()->GetVirtualRefDevice(); + mpFontList.reset( new FontList(pRefDevice, nullptr) ); + SvxFontListItem aFontListItem( mpFontList.get(), SID_ATTR_CHAR_FONTLIST ); + PutItem( aFontListItem ); +} + +Printer* DrawDocShell::GetDocumentPrinter() +{ + return GetPrinter(false); +} + +void DrawDocShell::OnDocumentPrinterChanged(Printer* pNewPrinter) +{ + // if we already have a printer, see if it's the same + if( mpPrinter ) + { + // easy case + if( mpPrinter == pNewPrinter ) + return; + + // compare if it's the same printer with the same job setup + if( (mpPrinter->GetName() == pNewPrinter->GetName()) && + (mpPrinter->GetJobSetup() == pNewPrinter->GetJobSetup())) + return; + } + + SfxPrinter* const pSfxPrinter = dynamic_cast<SfxPrinter*>(pNewPrinter); + if (pSfxPrinter) + { + SetPrinter(pSfxPrinter); + + // container owns printer + mbOwnPrinter = false; + } +} + +void DrawDocShell::UpdateRefDevice() +{ + if( !mpDoc ) + return; + + // Determine the device for which the output will be formatted. + VclPtr< OutputDevice > pRefDevice; + switch (mpDoc->GetPrinterIndependentLayout()) + { + case css::document::PrinterIndependentLayout::DISABLED: + pRefDevice = mpPrinter.get(); + break; + + case css::document::PrinterIndependentLayout::ENABLED: + pRefDevice = SD_MOD()->GetVirtualRefDevice(); + break; + + default: + // We are confronted with an invalid or un-implemented + // layout mode. Use the printer as formatting device + // as a fall-back. + SAL_WARN( "sd", "DrawDocShell::UpdateRefDevice(): Unexpected printer layout mode"); + + pRefDevice = mpPrinter.get(); + break; + } + mpDoc->SetRefDevice( pRefDevice.get() ); + + SdOutliner* pOutl = mpDoc->GetOutliner( false ); + + if( pOutl ) + pOutl->SetRefDevice( pRefDevice ); + + SdOutliner* pInternalOutl = mpDoc->GetInternalOutliner( false ); + + if( pInternalOutl ) + pInternalOutl->SetRefDevice( pRefDevice ); +} + +/** + * Creates new document, opens streams + */ +bool DrawDocShell::InitNew( const css::uno::Reference< css::embed::XStorage >& xStorage ) +{ + bool bRet = SfxObjectShell::InitNew( xStorage ); + + ::tools::Rectangle aVisArea( Point(0, 0), Size(14100, 10000) ); + SetVisArea(aVisArea); + + if (bRet) + { + if( !mbSdDataObj ) + mpDoc->NewOrLoadCompleted(DocCreationMode::New); // otherwise calling + // NewOrLoadCompleted(NEW_LOADED) in + // SdDrawDocument::AllocModel() + } + return bRet; +} + +/** + * loads pools and document + */ +bool DrawDocShell::Load( SfxMedium& rMedium ) +{ + // If this is an ODF file being loaded, then by default, use legacy processing + // for tdf#99729 (if required, it will be overridden in *::ReadUserDataSequence()) + if (IsOwnStorageFormat(rMedium)) + { + mpDoc->SetAnchoredTextOverflowLegacy(true); + } + + bool bRet = false; + bool bStartPresentation = false; + ErrCode nError = ERRCODE_NONE; + + SfxItemSet* pSet = rMedium.GetItemSet(); + + if( pSet ) + { + if( ( SfxItemState::SET == pSet->GetItemState(SID_PREVIEW ) ) && pSet->Get( SID_PREVIEW ).GetValue() ) + { + mpDoc->SetStarDrawPreviewMode( true ); + } + + if( SfxItemState::SET == pSet->GetItemState(SID_DOC_STARTPRESENTATION)&& + pSet->Get( SID_DOC_STARTPRESENTATION ).GetValue() ) + { + bStartPresentation = true; + mpDoc->SetStartWithPresentation( true ); + } + } + + bRet = SfxObjectShell::Load( rMedium ); + if (bRet) + { + comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); + bRet = SdXMLFilter( rMedium, *this, SdXMLFilterMode::Normal, SotStorage::GetVersion( rMedium.GetStorage() ) ).Import( nError ); + } + + if( bRet ) + { + // for legacy markup in OOoXML filter, convert the animations now + EffectMigration::DocumentLoaded(*GetDoc()); + UpdateTablePointers(); + + // If we're an embedded OLE object, use tight bounds + // for our visArea. No point in showing the user lots of empty + // space. Had to remove the check for empty VisArea below, + // since XML load always sets a VisArea before. + //TODO/LATER: looks a little bit strange! + if( ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED ) && SfxObjectShell::GetVisArea( ASPECT_CONTENT ).IsEmpty() ) + { + SdPage* pPage = mpDoc->GetSdPage( 0, PageKind::Standard ); + + if( pPage ) + SetVisArea( pPage->GetAllObjBoundRect() ); + } + + FinishedLoading(); + + const INetURLObject aUrl; + SfxObjectShell::SetAutoLoad( aUrl, 0, false ); + } + else + { + if( nError == ERRCODE_IO_BROKENPACKAGE ) + SetError(ERRCODE_IO_BROKENPACKAGE); + + // TODO/LATER: correct error handling?! + //pStore->SetError(SVSTREAM_WRONGVERSION); + else + SetError(ERRCODE_ABORT); + } + + // tell SFX to change viewshell when in preview mode + if( IsPreview() || bStartPresentation ) + { + SfxItemSet *pMediumSet = GetMedium()->GetItemSet(); + if( pMediumSet ) + pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID, bStartPresentation ? 1 : 5 ) ); + } + + return bRet; +} + +/** + * loads content for organizer + */ +bool DrawDocShell::LoadFrom( SfxMedium& rMedium ) +{ + std::unique_ptr<weld::WaitObject> pWait; + if( mpViewShell ) + pWait.reset(new weld::WaitObject(mpViewShell->GetFrameWeld())); + + mpDoc->NewOrLoadCompleted( DocCreationMode::New ); + mpDoc->CreateFirstPages(); + mpDoc->StopWorkStartupDelay(); + + // TODO/LATER: nobody is interested in the error code?! + ErrCode nError = ERRCODE_NONE; + bool bRet = SdXMLFilter( rMedium, *this, SdXMLFilterMode::Organizer, SotStorage::GetVersion( rMedium.GetStorage() ) ).Import( nError ); + + // tell SFX to change viewshell when in preview mode + if( IsPreview() ) + { + SfxItemSet *pSet = GetMedium()->GetItemSet(); + + if( pSet ) + pSet->Put( SfxUInt16Item( SID_VIEW_ID, 5 ) ); + } + + return bRet; +} + +/** + * load from 3rd party format + */ +bool DrawDocShell::ImportFrom(SfxMedium &rMedium, + uno::Reference<text::XTextRange> const& xInsertPosition) +{ + const OUString aFilterName( rMedium.GetFilter()->GetFilterName() ); + if (aFilterName == "Impress MS PowerPoint 2007 XML" || + aFilterName == "Impress MS PowerPoint 2007 XML AutoPlay" || + aFilterName == "Impress MS PowerPoint 2007 XML VBA") + { + // As this is a MSFT format, we should use the "MS Compat" + // mode for spacing before and after paragraphs. + + // This is copied from what is done for .ppt import in + // ImplSdPPTImport::Import() in sd/source/filter/ppt/pptin.cxx + // in. We need to tell both the edit engine of the draw outliner, + // and the document, to do "summation of paragraphs". + SdrOutliner& rOutl = mpDoc->GetDrawOutliner(); + EEControlBits nControlWord = rOutl.GetEditEngine().GetControlWord(); + nControlWord |= EEControlBits::ULSPACESUMMATION; + const_cast<EditEngine&>(rOutl.GetEditEngine()).SetControlWord( nControlWord ); + + mpDoc->SetSummationOfParagraphs(); + } + + if (aFilterName == "Impress MS PowerPoint 2007 XML" || + aFilterName == "Impress MS PowerPoint 2007 XML AutoPlay" || + aFilterName == "Impress MS PowerPoint 2007 XML VBA" || + aFilterName == "Impress Office Open XML") + { + // We need to be able to set the default tab size for each text object. + // This is possible at the moment only for the whole document. See + // TextParagraphPropertiesContext constructor. So default tab width + // of the LibreOffice is 1270 but MSO is 2540 on general settings. + mpDoc->SetDefaultTabulator( 2540 ); + } + + const bool bRet = SfxObjectShell::ImportFrom(rMedium, xInsertPosition); + + SfxItemSet* pSet = rMedium.GetItemSet(); + if( pSet ) + { + if( SfxItemState::SET == pSet->GetItemState(SID_DOC_STARTPRESENTATION)&& + pSet->Get( SID_DOC_STARTPRESENTATION ).GetValue() ) + { + mpDoc->SetStartWithPresentation( true ); + + // tell SFX to change viewshell when in preview mode + if( IsPreview() ) + { + SfxItemSet *pMediumSet = GetMedium()->GetItemSet(); + if( pMediumSet ) + pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID, 1 ) ); + } + } + } + + return bRet; +} + +/** + * load from a foreign format + */ +bool DrawDocShell::ConvertFrom( SfxMedium& rMedium ) +{ + const OUString aFilterName( rMedium.GetFilter()->GetFilterName() ); + bool bRet = false; + bool bStartPresentation = false; + + SetWaitCursor( true ); + + SfxItemSet* pSet = rMedium.GetItemSet(); + if( pSet ) + { + if( ( SfxItemState::SET == pSet->GetItemState(SID_PREVIEW ) ) && pSet->Get( SID_PREVIEW ).GetValue() ) + { + mpDoc->SetStarDrawPreviewMode( true ); + } + + if( SfxItemState::SET == pSet->GetItemState(SID_DOC_STARTPRESENTATION)&& + pSet->Get( SID_DOC_STARTPRESENTATION ).GetValue() ) + { + bStartPresentation = true; + mpDoc->SetStartWithPresentation( true ); + } + } + + if( aFilterName == pFilterPowerPoint97 + || aFilterName == pFilterPowerPoint97Template + || aFilterName == pFilterPowerPoint97AutoPlay) + { + mpDoc->StopWorkStartupDelay(); + bRet = SdPPTFilter( rMedium, *this ).Import(); + } + else if (aFilterName.indexOf("impress8") >= 0 || + aFilterName.indexOf("draw8") >= 0) + { + // TODO/LATER: nobody is interested in the error code?! + mpDoc->CreateFirstPages(); + mpDoc->StopWorkStartupDelay(); + ErrCode nError = ERRCODE_NONE; + bRet = SdXMLFilter( rMedium, *this ).Import( nError ); + + } + else if (aFilterName.indexOf("StarOffice XML (Draw)") >= 0 || + aFilterName.indexOf("StarOffice XML (Impress)") >= 0) + { + // TODO/LATER: nobody is interested in the error code?! + mpDoc->CreateFirstPages(); + mpDoc->StopWorkStartupDelay(); + ErrCode nError = ERRCODE_NONE; + bRet = SdXMLFilter( rMedium, *this, SdXMLFilterMode::Normal, SOFFICE_FILEFORMAT_60 ).Import( nError ); + } + else if (aFilterName == "CGM - Computer Graphics Metafile") + { + mpDoc->CreateFirstPages(); + mpDoc->StopWorkStartupDelay(); + bRet = SdCGMFilter( rMedium, *this ).Import(); + } + else if (aFilterName == "draw_pdf_import") + { + mpDoc->CreateFirstPages(); + mpDoc->StopWorkStartupDelay(); + bRet = SdPdfFilter(rMedium, *this).Import(); + } + else + { + mpDoc->CreateFirstPages(); + mpDoc->StopWorkStartupDelay(); + bRet = SdGRFFilter( rMedium, *this ).Import(); + } + + FinishedLoading(); + + // tell SFX to change viewshell when in preview mode + if( IsPreview() ) + { + SfxItemSet *pMediumSet = GetMedium()->GetItemSet(); + + if( pMediumSet ) + pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID, 5 ) ); + } + SetWaitCursor( false ); + + // tell SFX to change viewshell when in preview mode + if( IsPreview() || bStartPresentation ) + { + SfxItemSet *pMediumSet = GetMedium()->GetItemSet(); + if( pMediumSet ) + pMediumSet->Put( SfxUInt16Item( SID_VIEW_ID, bStartPresentation ? 1 : 5 ) ); + } + + return bRet; +} + +/** + * Writes pools and document to the open streams + */ +bool DrawDocShell::Save() +{ + mpDoc->StopWorkStartupDelay(); + + //TODO/LATER: why this?! + if( GetCreateMode() == SfxObjectCreateMode::STANDARD ) + SfxObjectShell::SetVisArea( ::tools::Rectangle() ); + + bool bRet = SfxObjectShell::Save(); + + if( bRet ) + bRet = SdXMLFilter( *GetMedium(), *this, SdXMLFilterMode::Normal, SotStorage::GetVersion( GetMedium()->GetStorage() ) ).Export(); + + return bRet; +} + +/** + * Writes pools and document to the provided storage + */ +bool DrawDocShell::SaveAs( SfxMedium& rMedium ) +{ + mpDoc->setDocAccTitle(OUString()); + if (SfxViewFrame* pFrame1 = SfxViewFrame::GetFirst(this)) + { + if (vcl::Window* pSysWin = pFrame1->GetWindow().GetSystemWindow()) + { + pSysWin->SetAccessibleName(OUString()); + } + } + mpDoc->StopWorkStartupDelay(); + + //With custom animation, if Outliner is modified, update text before saving + if( mpViewShell ) + { + SdPage* pPage = mpViewShell->getCurrentPage(); + if( pPage && pPage->getMainSequence()->getCount() ) + { + SdrObject* pObj = mpViewShell->GetView()->GetTextEditObject(); + SdrOutliner* pOutl = mpViewShell->GetView()->GetTextEditOutliner(); + if( pObj && pOutl && pOutl->IsModified() ) + { + std::optional<OutlinerParaObject> pNewText = pOutl->CreateParaObject( 0, pOutl->GetParagraphCount() ); + pObj->SetOutlinerParaObject( std::move(pNewText) ); + pOutl->ClearModifyFlag(); + } + } + } + + //TODO/LATER: why this?! + if( GetCreateMode() == SfxObjectCreateMode::STANDARD ) + SfxObjectShell::SetVisArea( ::tools::Rectangle() ); + + bool bRet = SfxObjectShell::SaveAs( rMedium ); + + if( bRet ) + bRet = SdXMLFilter( rMedium, *this, SdXMLFilterMode::Normal, SotStorage::GetVersion( rMedium.GetStorage() ) ).Export(); + + if( GetError() == ERRCODE_NONE ) + SetError(ERRCODE_NONE); + + return bRet; +} + +/** + * save to foreign format + */ +bool DrawDocShell::ConvertTo( SfxMedium& rMedium ) +{ + bool bRet = false; + + if( mpDoc->GetPageCount() ) + { + std::shared_ptr<const SfxFilter> pMediumFilter = rMedium.GetFilter(); + const OUString aTypeName( pMediumFilter->GetTypeName() ); + std::unique_ptr<SdFilter> xFilter; + + if( aTypeName.indexOf( "graphic_HTML" ) >= 0 ) + { + xFilter = std::make_unique<SdHTMLFilter>(rMedium, *this); + } + else if( aTypeName.indexOf( "MS_PowerPoint_97" ) >= 0 ) + { + xFilter = std::make_unique<SdPPTFilter>(rMedium, *this); + static_cast<SdPPTFilter*>(xFilter.get())->PreSaveBasic(); + } + else if ( aTypeName.indexOf( "CGM_Computer_Graphics_Metafile" ) >= 0 ) + { + xFilter = std::make_unique<SdCGMFilter>(rMedium, *this); + } + else if( aTypeName.indexOf( "draw8" ) >= 0 || + aTypeName.indexOf( "impress8" ) >= 0 ) + { + xFilter = std::make_unique<SdXMLFilter>(rMedium, *this); + } + else if( aTypeName.indexOf( "StarOffice_XML_Impress" ) >= 0 || + aTypeName.indexOf( "StarOffice_XML_Draw" ) >= 0 ) + { + xFilter = std::make_unique<SdXMLFilter>(rMedium, *this, SdXMLFilterMode::Normal, SOFFICE_FILEFORMAT_60); + } + else + { + xFilter = std::make_unique<SdGRFFilter>(rMedium, *this); + } + + if (xFilter) + { + if ( mpViewShell ) + { + ::sd::View* pView = mpViewShell->GetView(); + if ( pView->IsTextEdit() ) + pView->SdrEndTextEdit(); + } + + bRet = xFilter->Export(); + } + } + + return bRet; +} + +/** + * Reopen own streams to ensure that nobody else can prevent use from opening + * them. + */ +bool DrawDocShell::SaveCompleted( const css::uno::Reference< css::embed::XStorage >& xStorage ) +{ + bool bRet = false; + + if( SfxObjectShell::SaveCompleted(xStorage) ) + { + mpDoc->NbcSetChanged( false ); + + if( mpViewShell ) + { + if( dynamic_cast< OutlineViewShell *>( mpViewShell ) != nullptr ) + static_cast<OutlineView*>(mpViewShell->GetView()) + ->GetOutliner().ClearModifyFlag(); + + SdrOutliner* pOutl = mpViewShell->GetView()->GetTextEditOutliner(); + if( pOutl ) + { + SdrObject* pObj = mpViewShell->GetView()->GetTextEditObject(); + if( pObj ) + pObj->NbcSetOutlinerParaObject( pOutl->CreateParaObject() ); + + pOutl->ClearModifyFlag(); + } + } + + bRet = true; + + SfxViewFrame* pFrame = ( mpViewShell && mpViewShell->GetViewFrame() ) ? + mpViewShell->GetViewFrame() : + SfxViewFrame::Current(); + + if( pFrame ) + pFrame->GetBindings().Invalidate( SID_NAVIGATOR_STATE, true ); + } + return bRet; +} + +SfxStyleSheetBasePool* DrawDocShell::GetStyleSheetPool() +{ + return mpDoc->GetStyleSheetPool(); +} + +void DrawDocShell::GotoBookmark(std::u16string_view rBookmark) +{ + auto pDrawViewShell = dynamic_cast<DrawViewShell *>( mpViewShell ); + if (!pDrawViewShell) + return; + + ViewShellBase& rBase (mpViewShell->GetViewShellBase()); + + bool bIsMasterPage = false; + sal_uInt16 nPageNumber = SDRPAGE_NOTFOUND; + SdrObject* pObj = nullptr; + + static constexpr std::u16string_view sInteraction( u"action?" ); + if ( o3tl::starts_with(rBookmark, sInteraction ) ) + { + static constexpr std::u16string_view sJump( u"jump=" ); + if ( o3tl::starts_with(rBookmark.substr( sInteraction.size() ), sJump ) ) + { + std::u16string_view aDestination( rBookmark.substr( sInteraction.size() + sJump.size() ) ); + if ( o3tl::starts_with(aDestination, u"firstslide" ) ) + { + nPageNumber = 1; + } + else if ( o3tl::starts_with(aDestination, u"lastslide" ) ) + { + nPageNumber = mpDoc->GetPageCount() - 2; + } + else if ( o3tl::starts_with(aDestination, u"previousslide" ) ) + { + SdPage* pPage = pDrawViewShell->GetActualPage(); + nPageNumber = pPage->GetPageNum(); + nPageNumber = nPageNumber > 2 ? nPageNumber - 2 : SDRPAGE_NOTFOUND; + } + else if ( o3tl::starts_with(aDestination, u"nextslide" ) ) + { + SdPage* pPage = pDrawViewShell->GetActualPage(); + nPageNumber = pPage->GetPageNum() + 2; + if ( nPageNumber >= mpDoc->GetPageCount() ) + nPageNumber = SDRPAGE_NOTFOUND; + } + } + } + else + { + // Is the bookmark a page? + nPageNumber = mpDoc->GetPageByName( rBookmark, bIsMasterPage ); + + if (nPageNumber == SDRPAGE_NOTFOUND) + { + // Is the bookmark an object? + pObj = mpDoc->GetObj(rBookmark); + + if (pObj) + { + nPageNumber = pObj->getSdrPageFromSdrObject()->GetPageNum(); + } + } + } + if (nPageNumber != SDRPAGE_NOTFOUND) + { + // Jump to the bookmarked page. This is done in three steps. + + SdPage* pPage; + if (bIsMasterPage) + pPage = static_cast<SdPage*>( mpDoc->GetMasterPage(nPageNumber) ); + else + pPage = static_cast<SdPage*>( mpDoc->GetPage(nPageNumber) ); + + // 1.) Change the view shell to the edit view, the notes view, + // or the handout view. + PageKind eNewPageKind = pPage->GetPageKind(); + + if( (eNewPageKind != PageKind::Standard) && (mpDoc->GetDocumentType() == DocumentType::Draw) ) + return; + + if (eNewPageKind != pDrawViewShell->GetPageKind()) + { + // change work area + GetFrameView()->SetPageKind(eNewPageKind); + OUString sViewURL; + switch (eNewPageKind) + { + case PageKind::Standard: + sViewURL = FrameworkHelper::msImpressViewURL; + break; + case PageKind::Notes: + sViewURL = FrameworkHelper::msNotesViewURL; + break; + case PageKind::Handout: + sViewURL = FrameworkHelper::msHandoutViewURL; + break; + default: + break; + } + if (!sViewURL.isEmpty()) + { + std::shared_ptr<FrameworkHelper> pHelper ( + FrameworkHelper::Instance(rBase)); + pHelper->RequestView( + sViewURL, + FrameworkHelper::msCenterPaneURL); + pHelper->WaitForUpdate(); + + // Get the new DrawViewShell. + mpViewShell = pHelper->GetViewShell(FrameworkHelper::msCenterPaneURL).get(); + pDrawViewShell = dynamic_cast<sd::DrawViewShell*>(mpViewShell); + } + else + { + pDrawViewShell = nullptr; + } + } + + if (pDrawViewShell != nullptr) + { + setEditMode(pDrawViewShell, bIsMasterPage); + + // Make the bookmarked page the current page. This is done + // by using the API because this takes care of all the + // little things to be done. Especially writing the view + // data to the frame view. + sal_uInt16 nSdPgNum = (nPageNumber - 1) / 2; + Reference<drawing::XDrawView> xController (rBase.GetController(), UNO_QUERY); + if (xController.is()) + { + Reference<drawing::XDrawPage> xDrawPage (pPage->getUnoPage(), UNO_QUERY); + xController->setCurrentPage (xDrawPage); + } + else + { + // As a fall back switch to the page via the core. + DBG_ASSERT (xController.is(), + "DrawDocShell::GotoBookmark: can't switch page via API"); + pDrawViewShell->SwitchPage(nSdPgNum); + } + + if (pDrawViewShell->GetDispatcher()) + { + // show page + SvxZoomItem aZoom; + aZoom.SetType( SvxZoomType::WHOLEPAGE ); + pDrawViewShell->GetDispatcher()->ExecuteList(SID_ATTR_ZOOM, SfxCallMode::ASYNCHRON, { &aZoom }); + } + + if (pObj != nullptr) + { + // select object + pDrawViewShell->GetView()->UnmarkAll(); + pDrawViewShell->GetView()->MarkObj( + pObj, + pDrawViewShell->GetView()->GetSdrPageView()); + } + } + } + + SfxBindings& rBindings = ((pDrawViewShell && pDrawViewShell->GetViewFrame()!=nullptr) + ? pDrawViewShell->GetViewFrame() + : SfxViewFrame::Current() )->GetBindings(); + + rBindings.Invalidate(SID_NAVIGATOR_STATE, true); + rBindings.Invalidate(SID_NAVIGATOR_PAGENAME); +} + +/** + * If it should become a document template. + */ +bool DrawDocShell::SaveAsOwnFormat( SfxMedium& rMedium ) +{ + + std::shared_ptr<const SfxFilter> pFilter = rMedium.GetFilter(); + + if (pFilter->IsOwnTemplateFormat()) + { + /* now the StarDraw specialty: + we assign known layout names to the layout template of the first + page, we set the layout names of the affected masterpages and pages. + We inform all text objects of the affected standard, note and + masterpages about the name change. + */ + + OUString aLayoutName; + + SfxStringItem const * pLayoutItem = rMedium.GetItemSet()->GetItemIfSet(SID_TEMPLATE_NAME, false); + if( pLayoutItem ) + { + aLayoutName = pLayoutItem->GetValue(); + } + else + { + INetURLObject aURL( rMedium.GetName() ); + aURL.removeExtension(); + aLayoutName = aURL.getName(); + } + + if (aLayoutName.isEmpty()) + { + sal_uInt32 nCount = mpDoc->GetMasterSdPageCount(PageKind::Standard); + for (sal_uInt32 i = 0; i < nCount; ++i) + { + OUString aOldPageLayoutName = mpDoc->GetMasterSdPage(i, PageKind::Standard)->GetLayoutName(); + OUString aNewLayoutName = aLayoutName; + // Don't add suffix for the first master page + if( i > 0 ) + aNewLayoutName += OUString::number(i); + + mpDoc->RenameLayoutTemplate(aOldPageLayoutName, aNewLayoutName); + } + } + } + + return SfxObjectShell::SaveAsOwnFormat(rMedium); +} + +void DrawDocShell::FillClass(SvGlobalName* pClassName, + SotClipboardFormatId* pFormat, + OUString* pFullTypeName, + sal_Int32 nFileFormat, + bool bTemplate /* = false */) const +{ + if (nFileFormat == SOFFICE_FILEFORMAT_60) + { + if ( meDocType == DocumentType::Draw ) + { + *pClassName = SvGlobalName(SO3_SDRAW_CLASSID_60); + *pFormat = SotClipboardFormatId::STARDRAW_60; + *pFullTypeName = SdResId(STR_GRAPHIC_DOCUMENT_FULLTYPE_60); + } + else + { + *pClassName = SvGlobalName(SO3_SIMPRESS_CLASSID_60); + *pFormat = SotClipboardFormatId::STARIMPRESS_60; + *pFullTypeName = SdResId(STR_IMPRESS_DOCUMENT_FULLTYPE_60); + } + } + else if (nFileFormat == SOFFICE_FILEFORMAT_8) + { + if ( meDocType == DocumentType::Draw ) + { + *pClassName = SvGlobalName(SO3_SDRAW_CLASSID_60); + *pFormat = bTemplate ? SotClipboardFormatId::STARDRAW_8_TEMPLATE : SotClipboardFormatId::STARDRAW_8; + *pFullTypeName = SdResId(STR_GRAPHIC_DOCUMENT_FULLTYPE_80); // HACK: method will be removed with new storage API + } + else + { + *pClassName = SvGlobalName(SO3_SIMPRESS_CLASSID_60); + *pFormat = bTemplate ? SotClipboardFormatId::STARIMPRESS_8_TEMPLATE : SotClipboardFormatId::STARIMPRESS_8; + *pFullTypeName = SdResId(STR_IMPRESS_DOCUMENT_FULLTYPE_80); // HACK: method will be removed with new storage API + } + } +} + +OutputDevice* DrawDocShell::GetDocumentRefDev() +{ + OutputDevice* pReferenceDevice = SfxObjectShell::GetDocumentRefDev (); + // Only when our parent does not have a reference device then we return + // our own. + if (pReferenceDevice == nullptr && mpDoc != nullptr) + pReferenceDevice = mpDoc->GetRefDevice (); + return pReferenceDevice; +} + +/** executes the SID_OPENDOC slot to let the framework open a document + with the given URL and this document as a referer */ +void DrawDocShell::OpenBookmark( const OUString& rBookmarkURL ) +{ + SfxStringItem aStrItem( SID_FILE_NAME, rBookmarkURL ); + SfxStringItem aReferer( SID_REFERER, GetMedium()->GetName() ); + const SfxPoolItem* ppArgs[] = { &aStrItem, &aReferer, nullptr }; + ( mpViewShell ? mpViewShell->GetViewFrame() : SfxViewFrame::Current() )->GetBindings().Execute( SID_OPENHYPERLINK, ppArgs ); +} + +std::shared_ptr<SfxDocumentInfoDialog> DrawDocShell::CreateDocumentInfoDialog(weld::Window* pParent, const SfxItemSet &rSet) +{ + std::shared_ptr<SfxDocumentInfoDialog> xDlg = std::make_shared<SfxDocumentInfoDialog>(pParent, rSet); + DrawDocShell* pDocSh = dynamic_cast<DrawDocShell*>(SfxObjectShell::Current()); + if( pDocSh == this ) + { + xDlg->AddFontTabPage(); + } + return xDlg; +} + +void DrawDocShell::setEditMode(DrawViewShell* pDrawViewShell, bool isMasterPage) +{ + // Set the edit mode to either the normal edit mode or the + // master page mode. + EditMode eNewEditMode = EditMode::Page; + if (isMasterPage) + { + eNewEditMode = EditMode::MasterPage; + } + + if (eNewEditMode != pDrawViewShell->GetEditMode()) + { + // Set EditMode + pDrawViewShell->ChangeEditMode(eNewEditMode, false); + } +} +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |