/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using ::sd::framework::FrameworkHelper; 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 = o3tl::make_unique( GetPool(), svl::Items{} ); // 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(nFlags) ); pSet->Put( aPrintItem ); pSet->Put( SfxBoolItem( SID_PRINTER_NOTFOUND_WARN, aPrintItem.GetOptionsPrint().IsWarningPrinter() ) ); pSet->Put( aFlagItem ); mpPrinter = VclPtr::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() { delete mpFontList; OutputDevice* pRefDevice = nullptr; if ( mpDoc->GetPrinterIndependentLayout() == css::document::PrinterIndependentLayout::DISABLED ) pRefDevice = GetPrinter(true); else pRefDevice = SD_MOD()->GetVirtualRefDevice(); mpFontList = new FontList(pRefDevice, nullptr); SvxFontListItem aFontListItem( mpFontList, 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(pNewPrinter); if (pSfxPrinter) { SetPrinter(pSfxPrinter); // container owns printer mbOwnPrinter = false; } } void DrawDocShell::UpdateRefDevice() { if( mpDoc ) { // 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(NEW_DOC); // 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 ) ) && static_cast( pSet->Get( SID_PREVIEW ) ).GetValue() ) { mpDoc->SetStarDrawPreviewMode( true ); } if( SfxItemState::SET == pSet->GetItemState(SID_DOC_STARTPRESENTATION)&& static_cast( 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, SDXMLMODE_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( ::tools::Rectangle( 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 ) { WaitObject* pWait = nullptr; if( mpViewShell ) pWait = new WaitObject( static_cast(mpViewShell->GetActiveWindow()) ); mpDoc->NewOrLoadCompleted( NEW_DOC ); mpDoc->CreateFirstPages(); mpDoc->StopWorkStartupDelay(); // TODO/LATER: nobody is interested in the error code?! ErrCode nError = ERRCODE_NONE; bool bRet = SdXMLFilter( rMedium, *this, SDXMLMODE_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 ) ); } delete pWait; return bRet; } /** * load from 3rd party format */ bool DrawDocShell::ImportFrom(SfxMedium &rMedium, uno::Reference 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; nControlWord &=~ EEControlBits::ULSPACEFIRSTPARA; const_cast(rOutl.GetEditEngine()).SetControlWord( nControlWord ); mpDoc->SetSummationOfParagraphs(); } // Set this flag for MSO formats if (aFilterName.startsWith("MS PowerPoint 97") || aFilterName.startsWith("Impress MS PowerPoint 2007 XML") || aFilterName.startsWith("Impress Office Open XML")) { mpDoc->SetHoriAlignIgnoreTrailingWhitespace(true); } const bool bRet = SfxObjectShell::ImportFrom(rMedium, xInsertPosition); SfxItemSet* pSet = rMedium.GetItemSet(); if( pSet ) { if( SfxItemState::SET == pSet->GetItemState(SID_DOC_STARTPRESENTATION)&& static_cast( 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 ) ) && static_cast( pSet->Get( SID_PREVIEW ) ).GetValue() ) { mpDoc->SetStarDrawPreviewMode( true ); } if( SfxItemState::SET == pSet->GetItemState(SID_DOC_STARTPRESENTATION)&& static_cast( 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, SDXMLMODE_Normal, SOFFICE_FILEFORMAT_60 ).Import( nError ); } else if( aFilterName == "CGM - Computer Graphics Metafile" ) { mpDoc->CreateFirstPages(); mpDoc->StopWorkStartupDelay(); bRet = SdCGMFilter( rMedium, *this ).Import(); } else { mpDoc->CreateFirstPages(); mpDoc->StopWorkStartupDelay(); bRet = SdGRFFilter( rMedium, *this ).Import(); } // Set this flag for MSO formats if (aFilterName.startsWith("MS PowerPoint 97") || aFilterName.startsWith("Impress MS PowerPoint 2007 XML") || aFilterName.startsWith("Impress Office Open XML")) { mpDoc->SetHoriAlignIgnoreTrailingWhitespace(true); } 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, SDXMLMODE_Normal, SotStorage::GetVersion( GetMedium()->GetStorage() ) ).Export(); return bRet; } /** * Writes pools and document to the provided storage */ bool DrawDocShell::SaveAs( SfxMedium& rMedium ) { mpDoc->setDocAccTitle(OUString()); SfxViewFrame* pFrame1 = SfxViewFrame::GetFirst( this ); if (pFrame1) { vcl::Window* pWindow = &pFrame1->GetWindow(); if ( pWindow ) { vcl::Window* pSysWin = pWindow->GetSystemWindow(); if ( pSysWin ) { 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() ) { OutlinerParaObject* pNewText = pOutl->CreateParaObject( 0, pOutl->GetParagraphCount() ); pObj->SetOutlinerParaObject( 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, SDXMLMODE_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 pMediumFilter = rMedium.GetFilter(); const OUString aTypeName( pMediumFilter->GetTypeName() ); std::unique_ptr xFilter; if( aTypeName.indexOf( "graphic_HTML" ) >= 0 ) { xFilter = o3tl::make_unique(rMedium, *this); } else if( aTypeName.indexOf( "MS_PowerPoint_97" ) >= 0 ) { xFilter = o3tl::make_unique(rMedium, *this); static_cast(xFilter.get())->PreSaveBasic(); } else if ( aTypeName.indexOf( "CGM_Computer_Graphics_Metafile" ) >= 0 ) { xFilter = o3tl::make_unique(rMedium, *this); } else if( aTypeName.indexOf( "draw8" ) >= 0 || aTypeName.indexOf( "impress8" ) >= 0 ) { xFilter = o3tl::make_unique(rMedium, *this); } else if( aTypeName.indexOf( "StarOffice_XML_Impress" ) >= 0 || aTypeName.indexOf( "StarOffice_XML_Draw" ) >= 0 ) { xFilter = o3tl::make_unique(rMedium, *this, SDXMLMODE_Normal, SOFFICE_FILEFORMAT_60); } else { xFilter = o3tl::make_unique(rMedium, *this); } if (xFilter) { const SdrSwapGraphicsMode nOldSwapMode = mpDoc->GetSwapGraphicsMode(); mpDoc->SetSwapGraphicsMode( SdrSwapGraphicsMode::TEMP ); if ( mpViewShell ) { ::sd::View* pView = mpViewShell->GetView(); if ( pView->IsTextEdit() ) pView->SdrEndTextEdit(); } bRet = xFilter->Export(); if( !bRet ) mpDoc->SetSwapGraphicsMode( nOldSwapMode ); } } 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(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(const OUString& rBookmark) { if (mpViewShell && dynamic_cast< const DrawViewShell *>( mpViewShell ) != nullptr) { DrawViewShell* pDrawViewShell = static_cast(mpViewShell); ViewShellBase& rBase (mpViewShell->GetViewShellBase()); bool bIsMasterPage = false; sal_uInt16 nPageNumber = SDRPAGE_NOTFOUND; SdrObject* pObj = nullptr; const OUString sInteraction( "action?" ); if ( rBookmark.match( sInteraction ) ) { const OUString sJump( "jump=" ); if ( rBookmark.match( sJump, sInteraction.getLength() ) ) { OUString aDestination( rBookmark.copy( sInteraction.getLength() + sJump.getLength() ) ); if ( aDestination.match( "firstslide" ) ) { nPageNumber = 1; } else if ( aDestination.match( "lastslide" ) ) { nPageNumber = mpDoc->GetPageCount() - 2; } else if ( aDestination.match( "previousslide" ) ) { SdPage* pPage = pDrawViewShell->GetActualPage(); nPageNumber = pPage->GetPageNum(); nPageNumber = nPageNumber > 2 ? nPageNumber - 2 : SDRPAGE_NOTFOUND; } else if ( aDestination.match( "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 a object? pObj = mpDoc->GetObj(rBookmark); if (pObj) { nPageNumber = pObj->GetPage()->GetPageNum(); } } } if (nPageNumber != SDRPAGE_NOTFOUND) { // Jump to the bookmarked page. This is done in three steps. SdPage* pPage; if (bIsMasterPage) pPage = static_cast( mpDoc->GetMasterPage(nPageNumber) ); else pPage = static_cast( 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 pHelper ( FrameworkHelper::Instance(rBase)); pHelper->RequestView( sViewURL, FrameworkHelper::msCenterPaneURL); pHelper->WaitForUpdate(); // Get the new DrawViewShell. mpViewShell = pHelper->GetViewShell(FrameworkHelper::msCenterPaneURL).get(); pDrawViewShell = dynamic_cast(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 xController (rBase.GetController(), UNO_QUERY); if (xController.is()) { Reference 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 (pObj != nullptr) { // show and select object pDrawViewShell->MakeVisible(pObj->GetLogicRect(), *pDrawViewShell->GetActiveWindow()); 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 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; if( rMedium.GetItemSet()->GetItemState(SID_TEMPLATE_NAME, false, reinterpret_cast(& pLayoutItem) ) == SfxItemState::SET ) { 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* , OUString* pFullTypeName, OUString* pShortTypeName, 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 = "Draw 8"; // 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 = "Impress 8"; // HACK: method will be removed with new storage API } } *pShortTypeName = SdResId((meDocType == DocumentType::Draw) ? STR_GRAPHIC_DOCUMENT : STR_IMPRESS_DOCUMENT); } 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 ); } VclPtr DrawDocShell::CreateDocumentInfoDialog( const SfxItemSet &rSet ) { VclPtr pDlg = VclPtr::Create( nullptr, rSet ); DrawDocShell* pDocSh = dynamic_cast< DrawDocShell *>( SfxObjectShell::Current() ); if( pDocSh == this ) { pDlg->AddFontTabPage(); } return pDlg; } 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: */