summaryrefslogtreecommitdiffstats
path: root/sd/source/ui/docshell
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sd/source/ui/docshell
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sd/source/ui/docshell')
-rw-r--r--sd/source/ui/docshell/docshel2.cxx416
-rw-r--r--sd/source/ui/docshell/docshel3.cxx443
-rw-r--r--sd/source/ui/docshell/docshel4.cxx1002
-rw-r--r--sd/source/ui/docshell/docshell.cxx515
-rw-r--r--sd/source/ui/docshell/grdocsh.cxx61
-rw-r--r--sd/source/ui/docshell/sdclient.cxx184
6 files changed, 2621 insertions, 0 deletions
diff --git a/sd/source/ui/docshell/docshel2.cxx b/sd/source/ui/docshell/docshel2.cxx
new file mode 100644
index 000000000..160c64a66
--- /dev/null
+++ b/sd/source/ui/docshell/docshel2.cxx
@@ -0,0 +1,416 @@
+/* -*- 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 <memory>
+#include <DrawDocShell.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svxdlg.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <helpids.h>
+#include <ViewShell.hxx>
+#include <FrameView.hxx>
+#include <drawdoc.hxx>
+#include <sdpage.hxx>
+#include <ClientView.hxx>
+#include <Window.hxx>
+#include <strings.hrc>
+
+#include <sdresid.hxx>
+#include <fupoor.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
+#include <rtl/character.hxx>
+#include <tools/debug.hxx>
+
+namespace sd {
+
+/**
+ * Drawing of DocShell (with the helper class SdDrawViewShell)
+ */
+void DrawDocShell::Draw(OutputDevice* pOut, const JobSetup&, sal_uInt16 nAspect)
+{
+ if (nAspect == ASPECT_THUMBNAIL)
+ {
+ // THUMBNAIL: here we may can set the draft mode
+ }
+
+ std::optional<ClientView> pView( std::in_place, this, pOut );
+
+ pView->SetHlplVisible(false);
+ pView->SetGridVisible(false);
+ pView->SetBordVisible(false);
+ pView->SetPageVisible(false);
+ pView->SetGlueVisible(false);
+
+ SdPage* pSelectedPage = nullptr;
+
+ const std::vector<std::unique_ptr<sd::FrameView>> &rViews = mpDoc->GetFrameViewList();
+ if( !rViews.empty() )
+ {
+ sd::FrameView* pFrameView = rViews[0].get();
+ if( pFrameView->GetPageKind() == PageKind::Standard )
+ {
+ sal_uInt16 nSelectedPage = pFrameView->GetSelectedPage();
+ pSelectedPage = mpDoc->GetSdPage(nSelectedPage, PageKind::Standard);
+ }
+ }
+
+ if( nullptr == pSelectedPage )
+ {
+ SdPage* pPage = nullptr;
+ sal_uInt16 nPageCnt = mpDoc->GetSdPageCount(PageKind::Standard);
+
+ for (sal_uInt16 i = 0; i < nPageCnt; i++)
+ {
+ pPage = mpDoc->GetSdPage(i, PageKind::Standard);
+
+ if ( pPage->IsSelected() )
+ pSelectedPage = pPage;
+ }
+
+ if( nullptr == pSelectedPage )
+ pSelectedPage = mpDoc->GetSdPage(0, PageKind::Standard);
+ }
+
+ ::tools::Rectangle aVisArea = GetVisArea(nAspect);
+ pOut->IntersectClipRegion(aVisArea);
+ pView->ShowSdrPage(pSelectedPage);
+
+ if (pOut->GetOutDevType() == OUTDEV_WINDOW)
+ return;
+
+ MapMode aOldMapMode = pOut->GetMapMode();
+
+ if (pOut->GetOutDevType() == OUTDEV_PRINTER)
+ {
+ MapMode aMapMode = aOldMapMode;
+ Point aOrigin = aMapMode.GetOrigin();
+ aOrigin.AdjustX(1 );
+ aOrigin.AdjustY(1 );
+ aMapMode.SetOrigin(aOrigin);
+ pOut->SetMapMode(aMapMode);
+ }
+
+ vcl::Region aRegion(aVisArea);
+ pView->CompleteRedraw(pOut, aRegion);
+
+ if (pOut->GetOutDevType() == OUTDEV_PRINTER)
+ {
+ pOut->SetMapMode(aOldMapMode);
+ }
+}
+
+::tools::Rectangle DrawDocShell::GetVisArea(sal_uInt16 nAspect) const
+{
+ ::tools::Rectangle aVisArea;
+
+ if( ( ASPECT_THUMBNAIL == nAspect ) || ( ASPECT_DOCPRINT == nAspect ) )
+ {
+ // provide size of first page
+ aVisArea.SetSize(mpDoc->GetSdPage(0, PageKind::Standard)->GetSize());
+ }
+ else
+ {
+ aVisArea = SfxObjectShell::GetVisArea(nAspect);
+ }
+
+ if (aVisArea.IsEmpty() && mpViewShell)
+ {
+ vcl::Window* pWin = mpViewShell->GetActiveWindow();
+
+ if (pWin)
+ {
+ aVisArea = pWin->PixelToLogic(::tools::Rectangle(Point(0,0), pWin->GetOutputSizePixel()));
+ }
+ }
+
+ return aVisArea;
+}
+
+void DrawDocShell::Connect(ViewShell* pViewSh)
+{
+ mpViewShell = pViewSh;
+}
+
+void DrawDocShell::Disconnect(ViewShell const * pViewSh)
+{
+ if (mpViewShell == pViewSh)
+ {
+ mpViewShell = nullptr;
+ }
+}
+
+FrameView* DrawDocShell::GetFrameView()
+{
+ FrameView* pFrameView = nullptr;
+
+ if (mpViewShell)
+ {
+ pFrameView = mpViewShell->GetFrameView();
+ }
+
+ return pFrameView;
+}
+
+/**
+ * Creates a bitmap of an arbitrary page
+ */
+BitmapEx DrawDocShell::GetPagePreviewBitmap(SdPage* pPage)
+{
+ const sal_uInt16 nMaxEdgePixel = 90;
+ MapMode aMapMode( MapUnit::Map100thMM );
+ const Size aSize( pPage->GetSize() );
+ const Point aNullPt;
+ ScopedVclPtrInstance< VirtualDevice > pVDev( *Application::GetDefaultDevice() );
+
+ pVDev->SetMapMode( aMapMode );
+
+ const Size aPixSize( pVDev->LogicToPixel( aSize ) );
+ const sal_uLong nMaxEdgePix = std::max( aPixSize.Width(), aPixSize.Height() );
+ Fraction aFrac( nMaxEdgePixel, nMaxEdgePix );
+
+ aMapMode.SetScaleX( aFrac );
+ aMapMode.SetScaleY( aFrac );
+ pVDev->SetMapMode( aMapMode );
+ pVDev->SetOutputSize( aSize );
+
+ // that we also get the dark lines at the right and bottom page margin
+ aFrac = Fraction( nMaxEdgePixel - 1, nMaxEdgePix );
+ aMapMode.SetScaleX( aFrac );
+ aMapMode.SetScaleY( aFrac );
+ pVDev->SetMapMode( aMapMode );
+
+ std::optional<ClientView> pView( std::in_place, this, pVDev );
+ FrameView* pFrameView = GetFrameView();
+ pView->ShowSdrPage( pPage );
+
+ if ( GetFrameView() )
+ {
+ // initialize the drawing-(screen) attributes
+ pView->SetGridCoarse( pFrameView->GetGridCoarse() );
+ pView->SetGridFine( pFrameView->GetGridFine() );
+ pView->SetSnapGridWidth(pFrameView->GetSnapGridWidthX(), pFrameView->GetSnapGridWidthY());
+ pView->SetGridVisible( pFrameView->IsGridVisible() );
+ pView->SetGridFront( pFrameView->IsGridFront() );
+ pView->SetSnapAngle( pFrameView->GetSnapAngle() );
+ pView->SetGridSnap( pFrameView->IsGridSnap() );
+ pView->SetBordSnap( pFrameView->IsBordSnap() );
+ pView->SetHlplSnap( pFrameView->IsHlplSnap() );
+ pView->SetOFrmSnap( pFrameView->IsOFrmSnap() );
+ pView->SetOPntSnap( pFrameView->IsOPntSnap() );
+ pView->SetOConSnap( pFrameView->IsOConSnap() );
+ pView->SetDragStripes( pFrameView->IsDragStripes() );
+ pView->SetFrameDragSingles( pFrameView->IsFrameDragSingles() );
+ pView->SetSnapMagneticPixel( pFrameView->GetSnapMagneticPixel() );
+ pView->SetMarkedHitMovesAlways( pFrameView->IsMarkedHitMovesAlways() );
+ pView->SetMoveOnlyDragging( pFrameView->IsMoveOnlyDragging() );
+ pView->SetSlantButShear( pFrameView->IsSlantButShear() );
+ pView->SetNoDragXorPolys( pFrameView->IsNoDragXorPolys() );
+ pView->SetCrookNoContortion( pFrameView->IsCrookNoContortion() );
+ pView->SetAngleSnapEnabled( pFrameView->IsAngleSnapEnabled() );
+ pView->SetBigOrtho( pFrameView->IsBigOrtho() );
+ pView->SetOrtho( pFrameView->IsOrtho() );
+
+ SdrPageView* pPageView = pView->GetSdrPageView();
+
+ if (pPageView)
+ {
+ if ( pPageView->GetVisibleLayers() != pFrameView->GetVisibleLayers() )
+ pPageView->SetVisibleLayers( pFrameView->GetVisibleLayers() );
+
+ if ( pPageView->GetPrintableLayers() != pFrameView->GetPrintableLayers() )
+ pPageView->SetPrintableLayers( pFrameView->GetPrintableLayers() );
+
+ if ( pPageView->GetLockedLayers() != pFrameView->GetLockedLayers() )
+ pPageView->SetLockedLayers( pFrameView->GetLockedLayers() );
+
+ pPageView->SetHelpLines( pFrameView->GetStandardHelpLines() );
+ }
+
+ if ( pView->GetActiveLayer() != pFrameView->GetActiveLayer() )
+ pView->SetActiveLayer( pFrameView->GetActiveLayer() );
+ }
+
+ pView->CompleteRedraw( pVDev, vcl::Region(::tools::Rectangle(aNullPt, aSize)) );
+
+ // IsRedrawReady() always gives sal_True while ( !pView->IsRedrawReady() ) {}
+ pView.reset();
+
+ pVDev->SetMapMode( MapMode() );
+
+ BitmapEx aPreview( pVDev->GetBitmapEx( aNullPt, pVDev->GetOutputSizePixel() ) );
+
+ DBG_ASSERT(!aPreview.IsEmpty(), "Preview-Bitmap could not be generated");
+
+ return aPreview;
+}
+
+/**
+ * Checks if the page exists. If so, we force the user to enter a not yet used
+ * name.
+ * @return sal_False if the user cancels the action.
+ */
+bool DrawDocShell::CheckPageName(weld::Window* pWin, OUString& rName)
+{
+ const OUString aStrForDlg( rName );
+ bool bIsNameValid = IsNewPageNameValid( rName, true );
+
+ if( ! bIsNameValid )
+ {
+ OUString aDesc;
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+
+ if (GetDocumentType() == DocumentType::Draw)
+ aDesc = SdResId( STR_WARN_PAGE_EXISTS_DRAW );
+ else
+ aDesc = SdResId( STR_WARN_PAGE_EXISTS );
+
+ ScopedVclPtr<AbstractSvxNameDialog> aNameDlg(pFact->CreateSvxNameDialog(pWin, aStrForDlg, aDesc));
+ aNameDlg->SetEditHelpId( HID_SD_NAMEDIALOG_PAGE );
+
+ aNameDlg->SetCheckNameHdl( LINK( this, DrawDocShell, RenameSlideHdl ) );
+
+ rtl::Reference<FuPoor> xFunc( mpViewShell->GetCurrentFunction() );
+ if( xFunc.is() )
+ xFunc->cancel();
+
+ if( aNameDlg->Execute() == RET_OK )
+ {
+ aNameDlg->GetName( rName );
+ bIsNameValid = IsNewPageNameValid( rName );
+ }
+ }
+
+ return bIsNameValid;
+}
+
+bool DrawDocShell::IsNewPageNameValid( OUString & rInOutPageName, bool bResetStringIfStandardName /* = false */ )
+{
+ bool bCanUseNewName = false;
+
+ // check if name is something like 'Slide n'
+ OUString aStrPage(SdResId(STR_SD_PAGE) + " ");
+
+ bool bIsStandardName = false;
+
+ // prevent also _future_ slide names of the form "'STR_SD_PAGE' + ' ' + '[0-9]+|[a-z]|[A-Z]|[CDILMVX]+|[cdilmvx]+'"
+ // (arabic, lower- and upper case single letter, lower- and upper case roman numbers)
+ if (rInOutPageName.startsWith(aStrPage) &&
+ rInOutPageName.getLength() > aStrPage.getLength())
+ {
+ sal_Int32 nIdx{ aStrPage.getLength() };
+ std::u16string_view sRemainder = o3tl::getToken(rInOutPageName, 0, ' ', nIdx);
+ if (!sRemainder.empty() && sRemainder[0] >= '0' && sRemainder[0] <= '9')
+ {
+ // check for arabic numbering
+
+ size_t nIndex = 1;
+ // skip all following numbers
+ while (nIndex < sRemainder.size() &&
+ sRemainder[nIndex] >= '0' && sRemainder[nIndex] <= '9')
+ {
+ nIndex++;
+ }
+
+ // EOL? Reserved name!
+ if (nIndex >= sRemainder.size())
+ {
+ bIsStandardName = true;
+ }
+ }
+ else if (sRemainder.size() == 1 &&
+ rtl::isAsciiLowerCase(sRemainder[0]))
+ {
+ // lower case, single character: reserved
+ bIsStandardName = true;
+ }
+ else if (sRemainder.size() == 1 &&
+ rtl::isAsciiUpperCase(sRemainder[0]))
+ {
+ // upper case, single character: reserved
+ bIsStandardName = true;
+ }
+ else
+ {
+ // check for upper/lower case roman numbering
+ OUString sReserved("cdilmvx");
+
+ // skip all following characters contained in one reserved class
+ if (sReserved.indexOf(sRemainder[0]) == -1)
+ sReserved = sReserved.toAsciiUpperCase();
+
+ size_t nIndex = 0;
+ while (nIndex < sRemainder.size() &&
+ sReserved.indexOf(sRemainder[nIndex]) != -1)
+ {
+ nIndex++;
+ }
+
+ // EOL? Reserved name!
+ if (nIndex >= sRemainder.size())
+ {
+ bIsStandardName = true;
+ }
+ }
+ }
+
+ if( bIsStandardName )
+ {
+ if( bResetStringIfStandardName )
+ {
+ // this is for insertion of slides from other files with standard
+ // name. They get a new standard name, if the string is set to an
+ // empty one.
+ rInOutPageName.clear();
+ bCanUseNewName = true;
+ }
+ else
+ bCanUseNewName = false;
+ }
+ else
+ {
+ if (!rInOutPageName.isEmpty())
+ {
+ bool bOutDummy;
+ sal_uInt16 nExistingPageNum = mpDoc->GetPageByName( rInOutPageName, bOutDummy );
+ bCanUseNewName = ( nExistingPageNum == SDRPAGE_NOTFOUND );
+ }
+ else
+ bCanUseNewName = false;
+ }
+
+ return bCanUseNewName;
+}
+
+bool DrawDocShell::IsPageNameUnique( std::u16string_view rPageName ) const
+{
+ return mpDoc->IsPageNameUnique(rPageName);
+}
+
+IMPL_LINK( DrawDocShell, RenameSlideHdl, AbstractSvxNameDialog&, rDialog, bool )
+{
+ OUString aNewName;
+ rDialog.GetName( aNewName );
+ return IsNewPageNameValid( aNewName );
+}
+
+} // end of namespace sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/docshell/docshel3.cxx b/sd/source/ui/docshell/docshel3.cxx
new file mode 100644
index 000000000..be045818a
--- /dev/null
+++ b/sd/source/ui/docshell/docshel3.cxx
@@ -0,0 +1,443 @@
+/* -*- 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 <DrawDocShell.hxx>
+
+#include <svx/svxids.hrc>
+
+#include <svx/ofaitem.hxx>
+#include <svl/stritem.hxx>
+#include <svl/srchitem.hxx>
+#include <svl/languageoptions.hxx>
+#include <svtools/langtab.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/sfxdlg.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <vcl/abstdlg.hxx>
+#include <svx/drawitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/outlobj.hxx>
+#include <editeng/editobj.hxx>
+#include <com/sun/star/i18n/TextConversionOption.hpp>
+#include <sfx2/notebookbar/SfxNotebookBar.hxx>
+#include <editeng/editeng.hxx>
+#include <osl/diagnose.h>
+
+#include <sdmod.hxx>
+#include <drawdoc.hxx>
+#include <fusearch.hxx>
+#include <ViewShell.hxx>
+#include <slideshow.hxx>
+#include <fuhhconv.hxx>
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+
+namespace sd {
+
+static void lcl_setLanguageForObj( SdrObject *pObj, LanguageType nLang, bool bLanguageNone )
+{
+ const sal_uInt16 aLangWhichId_EE[3] =
+ {
+ EE_CHAR_LANGUAGE,
+ EE_CHAR_LANGUAGE_CJK,
+ EE_CHAR_LANGUAGE_CTL
+ };
+
+ if( bLanguageNone )
+ nLang = LANGUAGE_NONE;
+
+ if( nLang != LANGUAGE_DONTKNOW )
+ {
+ if( nLang == LANGUAGE_NONE )
+ {
+ for(sal_uInt16 n : aLangWhichId_EE)
+ pObj->SetMergedItem( SvxLanguageItem( nLang, n ) );
+ }
+ else
+ {
+ sal_uInt16 nLangWhichId = 0;
+ SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLang );
+ switch (nScriptType)
+ {
+ case SvtScriptType::LATIN : nLangWhichId = EE_CHAR_LANGUAGE; break;
+ case SvtScriptType::ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
+ case SvtScriptType::COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
+ default:
+ OSL_FAIL("unexpected case" );
+ return;
+ }
+ pObj->SetMergedItem( SvxLanguageItem( nLang, nLangWhichId ) );
+
+ // Reset shape text language to default, so it inherits the shape language set above.
+ OutlinerParaObject* pOutliner = pObj->GetOutlinerParaObject();
+ if (pOutliner)
+ {
+ EditTextObject& rEditTextObject
+ = const_cast<EditTextObject&>(pOutliner->GetTextObject());
+ for (sal_uInt16 n : aLangWhichId_EE)
+ {
+ rEditTextObject.RemoveCharAttribs(n);
+ }
+ }
+ }
+ }
+ else // Reset to default
+ {
+ for(sal_uInt16 n : aLangWhichId_EE)
+ pObj->ClearMergedItem( n );
+ }
+}
+
+static void lcl_setLanguage( const SdDrawDocument *pDoc, std::u16string_view rLanguage, bool bLanguageNone = false )
+{
+ LanguageType nLang = SvtLanguageTable::GetLanguageType( rLanguage );
+
+ // Do it for SdDrawDocument->SetLanguage as well?
+
+ sal_uInt16 nPageCount = pDoc->GetPageCount(); // Pick All Pages
+ for( sal_uInt16 nPage = 0; nPage < nPageCount; nPage++ )
+ {
+ const SdrPage *pPage = pDoc->GetPage( nPage );
+ const size_t nObjCount = pPage->GetObjCount();
+ for( size_t nObj = 0; nObj < nObjCount; ++nObj )
+ {
+ SdrObject *pObj = pPage->GetObj( nObj );
+ if (pObj->GetObjIdentifier() != SdrObjKind::Page)
+ lcl_setLanguageForObj( pObj, nLang, bLanguageNone );
+ }
+ }
+}
+
+/**
+ * Handles SFX-Requests
+ */
+void DrawDocShell::Execute( SfxRequest& rReq )
+{
+ if(mpViewShell && SlideShow::IsRunning( mpViewShell->GetViewShellBase() ))
+ {
+ // during a running presentation no slot will be executed
+ return;
+ }
+
+ switch ( rReq.GetSlot() )
+ {
+ case SID_SEARCH_ITEM:
+ {
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ if (pReqArgs)
+ {
+ const SvxSearchItem & rSearchItem = pReqArgs->Get(SID_SEARCH_ITEM);
+
+ SD_MOD()->SetSearchItem(std::unique_ptr<SvxSearchItem>(rSearchItem.Clone()));
+ }
+
+ rReq.Done();
+ }
+ break;
+
+ case FID_SEARCH_ON:
+ {
+ // no action needed
+ rReq.Done();
+ }
+ break;
+
+ case FID_SEARCH_OFF:
+ {
+ if (mpViewShell)
+ {
+ sd::View* pView = mpViewShell->GetView();
+ if (pView)
+ {
+ auto& rFunctionContext = pView->getSearchContext();
+ rtl::Reference<FuSearch>& xFuSearch(rFunctionContext.getFunctionSearch());
+
+ if (xFuSearch.is())
+ {
+ // End Search&Replace in all docshells
+ SfxObjectShell* pFirstShell = SfxObjectShell::GetFirst();
+ SfxObjectShell* pShell = pFirstShell;
+
+ while (pShell)
+ {
+ auto pDrawDocShell = dynamic_cast<DrawDocShell*>(pShell);
+ if (pDrawDocShell)
+ pDrawDocShell->CancelSearching();
+
+ pShell = SfxObjectShell::GetNext(*pShell);
+
+ if (pShell == pFirstShell)
+ pShell = nullptr;
+ }
+
+ rFunctionContext.resetSearchFunction();
+ Invalidate();
+ rReq.Done();
+ }
+ }
+ }
+ }
+ break;
+
+ case FID_SEARCH_NOW:
+ {
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ if (pReqArgs && mpViewShell)
+ {
+ sd::View* pView = mpViewShell->GetView();
+ if (pView)
+ {
+ rtl::Reference<FuSearch> & xFuSearch = pView->getSearchContext().getFunctionSearch();
+
+ if (!xFuSearch.is())
+ {
+ xFuSearch = rtl::Reference<FuSearch>(
+ FuSearch::createPtr(mpViewShell,
+ mpViewShell->GetActiveWindow(),
+ pView, mpDoc, rReq));
+
+ pView->getSearchContext().setSearchFunction(xFuSearch);
+ }
+
+ if (xFuSearch.is())
+ {
+ const SvxSearchItem& rSearchItem = pReqArgs->Get(SID_SEARCH_ITEM);
+
+ SD_MOD()->SetSearchItem(std::unique_ptr<SvxSearchItem>(rSearchItem.Clone()));
+ xFuSearch->SearchAndReplace(&rSearchItem);
+ }
+ }
+ }
+
+ rReq.Done();
+ }
+ break;
+
+ case SID_CLOSEDOC:
+ {
+ ExecuteSlot(rReq, SfxObjectShell::GetStaticInterface());
+ }
+ break;
+
+ case SID_GET_COLORLIST:
+ {
+ const SvxColorListItem* pColItem = GetItem( SID_COLOR_TABLE );
+ const XColorListRef& pList = pColItem->GetColorList();
+ rReq.SetReturnValue( OfaXColorListItem( SID_GET_COLORLIST, pList ) );
+ }
+ break;
+
+ case SID_VERSION:
+ {
+ ExecuteSlot( rReq, SfxObjectShell::GetStaticInterface() );
+ }
+ break;
+
+ case SID_HANGUL_HANJA_CONVERSION:
+ {
+ if( mpViewShell )
+ {
+ rtl::Reference<FuPoor> aFunc( FuHangulHanjaConversion::Create( mpViewShell, mpViewShell->GetActiveWindow(), mpViewShell->GetView(), mpDoc, rReq ) );
+ static_cast< FuHangulHanjaConversion* >( aFunc.get() )->StartConversion( LANGUAGE_KOREAN, LANGUAGE_KOREAN, nullptr, i18n::TextConversionOption::CHARACTER_BY_CHARACTER, true );
+ }
+ }
+ break;
+
+ case SID_CHINESE_CONVERSION:
+ {
+ if( mpViewShell )
+ {
+ rtl::Reference<FuPoor> aFunc( FuHangulHanjaConversion::Create( mpViewShell, mpViewShell->GetActiveWindow(), mpViewShell->GetView(), mpDoc, rReq ) );
+ static_cast< FuHangulHanjaConversion* >( aFunc.get() )->StartChineseConversion();
+ }
+ }
+ break;
+ case SID_LANGUAGE_STATUS:
+ {
+ OUString aNewLangTxt;
+ const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(SID_LANGUAGE_STATUS);
+ if (pItem)
+ aNewLangTxt = pItem->GetValue();
+
+ if (aNewLangTxt == "*" )
+ {
+ // open the dialog "Tools/Options/Language Settings - Language"
+ if (mpViewShell)
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog( mpViewShell->GetFrameWeld(), SID_LANGUAGE_OPTIONS ));
+ pDlg->Execute();
+ }
+ }
+ else
+ {
+ if( mpViewShell )
+ {
+ // setting the new language...
+ if (!aNewLangTxt.isEmpty())
+ {
+ static const OUStringLiteral aSelectionLangPrefix(u"Current_");
+ static const OUStringLiteral aParagraphLangPrefix(u"Paragraph_");
+ static const OUStringLiteral aDocumentLangPrefix(u"Default_");
+
+ bool bSelection = false;
+ bool bParagraph = false;
+
+ SdDrawDocument* pDoc = mpViewShell->GetDoc();
+ sal_Int32 nPos = -1;
+ if (-1 != (nPos = aNewLangTxt.indexOf( aDocumentLangPrefix )))
+ {
+ aNewLangTxt = aNewLangTxt.replaceAt( nPos, aDocumentLangPrefix.getLength(), u"" );
+
+ if (aNewLangTxt == "LANGUAGE_NONE")
+ lcl_setLanguage( pDoc, u"", true );
+ else if (aNewLangTxt == "RESET_LANGUAGES")
+ lcl_setLanguage( pDoc, u"" );
+ else
+ lcl_setLanguage( pDoc, aNewLangTxt );
+ }
+ else if (-1 != (nPos = aNewLangTxt.indexOf( aSelectionLangPrefix )))
+ {
+ bSelection = true;
+ aNewLangTxt = aNewLangTxt.replaceAt( nPos, aSelectionLangPrefix.getLength(), u"" );
+ }
+ else if (-1 != (nPos = aNewLangTxt.indexOf( aParagraphLangPrefix )))
+ {
+ bParagraph = true;
+ aNewLangTxt = aNewLangTxt.replaceAt( nPos, aParagraphLangPrefix.getLength(), u"" );
+ }
+
+ if (bSelection || bParagraph)
+ {
+ SdrView* pSdrView = mpViewShell->GetDrawView();
+ if (!pSdrView)
+ return;
+
+ EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
+ const LanguageType nLangToUse = SvtLanguageTable::GetLanguageType( aNewLangTxt );
+ SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLangToUse );
+
+ SfxItemSet aAttrs = rEditView.GetEditEngine()->GetEmptyItemSet();
+ if (nScriptType == SvtScriptType::LATIN)
+ aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE ) );
+ if (nScriptType == SvtScriptType::COMPLEX)
+ aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CTL ) );
+ if (nScriptType == SvtScriptType::ASIAN)
+ aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CJK ) );
+ ESelection aOldSel;
+ if (bParagraph)
+ {
+ ESelection aSel = rEditView.GetSelection();
+ aOldSel = aSel;
+ aSel.nStartPos = 0;
+ aSel.nEndPos = EE_TEXTPOS_ALL;
+ rEditView.SetSelection( aSel );
+ }
+
+ rEditView.SetAttribs( aAttrs );
+ if (bParagraph)
+ rEditView.SetSelection( aOldSel );
+ }
+
+ if ( pDoc->GetOnlineSpell() )
+ {
+ pDoc->StartOnlineSpelling();
+ }
+ }
+ }
+ }
+ Broadcast(SfxHint(SfxHintId::LanguageChanged));
+ }
+ break;
+ case SID_SPELLCHECK_IGNORE_ALL:
+ {
+ if (!mpViewShell)
+ return;
+ SdrView* pSdrView = mpViewShell->GetDrawView();
+ if (!pSdrView)
+ return;
+
+ EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
+ OUString sIgnoreText;
+ const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pItem2)
+ sIgnoreText = pItem2->GetValue();
+
+ if(sIgnoreText == "Spelling")
+ {
+ ESelection aOldSel = rEditView.GetSelection();
+ rEditView.SpellIgnoreWord();
+ rEditView.SetSelection( aOldSel );
+ }
+ }
+ break;
+ case SID_SPELLCHECK_APPLY_SUGGESTION:
+ {
+ if (!mpViewShell)
+ return;
+ SdrView* pSdrView = mpViewShell->GetDrawView();
+ if (!pSdrView)
+ return;
+
+ EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
+ OUString sApplyText;
+ const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
+ if (pItem2)
+ sApplyText = pItem2->GetValue();
+
+ static const OUStringLiteral sSpellingRule(u"Spelling_");
+ sal_Int32 nPos = 0;
+ if(-1 != (nPos = sApplyText.indexOf( sSpellingRule )))
+ {
+ sApplyText = sApplyText.replaceAt(nPos, sSpellingRule.getLength(), u"");
+ rEditView.InsertText( sApplyText );
+ }
+ }
+ break;
+
+ case SID_NOTEBOOKBAR:
+ {
+ const SfxStringItem* pFile = rReq.GetArg<SfxStringItem>( SID_NOTEBOOKBAR );
+
+ if ( mpViewShell )
+ {
+ SfxBindings& rBindings( mpViewShell->GetFrame()->GetBindings() );
+
+ if ( sfx2::SfxNotebookBar::IsActive() )
+ sfx2::SfxNotebookBar::ExecMethod( rBindings, pFile ? pFile->GetValue() : "" );
+ else
+ sfx2::SfxNotebookBar::CloseMethod( rBindings );
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+} // end of namespace sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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: */
diff --git a/sd/source/ui/docshell/docshell.cxx b/sd/source/ui/docshell/docshell.cxx
new file mode 100644
index 000000000..78279687a
--- /dev/null
+++ b/sd/source/ui/docshell/docshell.cxx
@@ -0,0 +1,515 @@
+/* -*- 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 <DrawDocShell.hxx>
+
+#include <officecfg/Office/Common.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <sfx2/docfac.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/svxids.hrc>
+#include <svl/srchitem.hxx>
+#include <svx/srchdlg.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svditer.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/eeitem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/printer.hxx>
+#include <svx/drawitem.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svl/whiter.hxx>
+#include <svl/itempool.hxx>
+#include <svl/stritem.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/langtab.hxx>
+#include <comphelper/classids.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/visitem.hxx>
+
+#include <app.hrc>
+#include <sdmod.hxx>
+#include <View.hxx>
+#include <drawdoc.hxx>
+
+#include <ViewShell.hxx>
+#include <unomodel.hxx>
+#include <undo/undomanager.hxx>
+#include <undo/undofactory.hxx>
+#include <OutlineView.hxx>
+#include <ViewShellBase.hxx>
+#include <sfx2/notebookbar/SfxNotebookBar.hxx>
+#include <comphelper/lok.hxx>
+#include <DrawViewShell.hxx>
+#include <sdpage.hxx>
+
+using namespace sd;
+#define ShellClass_DrawDocShell
+#include <sdslots.hxx>
+
+SFX_IMPL_SUPERCLASS_INTERFACE(DrawDocShell, SfxObjectShell);
+
+void DrawDocShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterChildWindow(SvxSearchDialogWrapper::GetChildWindowId());
+}
+
+namespace sd {
+
+/**
+ * slotmaps and definitions of SFX
+ */
+
+SFX_IMPL_OBJECTFACTORY(
+ DrawDocShell,
+ SvGlobalName(SO3_SIMPRESS_CLASSID),
+ "simpress" )
+
+void DrawDocShell::Construct( bool bClipboard )
+{
+ mbInDestruction = false;
+ SetSlotFilter(); // resets the filter
+
+ mbOwnDocument = mpDoc == nullptr;
+ if( mbOwnDocument )
+ mpDoc = new SdDrawDocument(meDocType, this);
+
+ // The document has been created so we can call UpdateRefDevice() to set
+ // the document's ref device.
+ UpdateRefDevice();
+
+ SetBaseModel( new SdXImpressDocument( this, bClipboard ) );
+ SetPool( &mpDoc->GetItemPool() );
+ std::unique_ptr<sd::UndoManager> pUndoManager(new sd::UndoManager);
+ pUndoManager->SetDocShell(this);
+ mpUndoManager = std::move(pUndoManager);
+
+ if (!utl::ConfigManager::IsFuzzing()
+ && officecfg::Office::Common::Undo::Steps::get() < 1)
+ {
+ mpUndoManager->EnableUndo(false); // tdf#108863 disable if 0 steps
+ }
+ mpDoc->SetSdrUndoManager( mpUndoManager.get() );
+ mpDoc->SetSdrUndoFactory( new sd::UndoFactory );
+ UpdateTablePointers();
+ SetStyleFamily(SfxStyleFamily::Pseudo);
+}
+
+DrawDocShell::DrawDocShell(SfxObjectCreateMode eMode,
+ bool bDataObject,
+ DocumentType eDocumentType) :
+ SfxObjectShell( eMode == SfxObjectCreateMode::INTERNAL ? SfxObjectCreateMode::EMBEDDED : eMode),
+ mpDoc(nullptr),
+ mpPrinter(nullptr),
+ mpViewShell(nullptr),
+ meDocType(eDocumentType),
+ mbSdDataObj(bDataObject),
+ mbOwnPrinter(false)
+{
+ Construct( eMode == SfxObjectCreateMode::INTERNAL );
+}
+
+DrawDocShell::DrawDocShell( SfxModelFlags nModelCreationFlags, bool bDataObject, DocumentType eDocumentType ) :
+ SfxObjectShell( nModelCreationFlags ),
+ mpDoc(nullptr),
+ mpPrinter(nullptr),
+ mpViewShell(nullptr),
+ meDocType(eDocumentType),
+ mbSdDataObj(bDataObject),
+ mbOwnPrinter(false)
+{
+ Construct( false );
+}
+
+DrawDocShell::DrawDocShell(SdDrawDocument* pDoc, SfxObjectCreateMode eMode,
+ bool bDataObject,
+ DocumentType eDocumentType) :
+ SfxObjectShell(eMode == SfxObjectCreateMode::INTERNAL ? SfxObjectCreateMode::EMBEDDED : eMode),
+ mpDoc(pDoc),
+ mpPrinter(nullptr),
+ mpViewShell(nullptr),
+ meDocType(eDocumentType),
+ mbSdDataObj(bDataObject),
+ mbOwnPrinter(false)
+{
+ Construct( eMode == SfxObjectCreateMode::INTERNAL );
+}
+
+DrawDocShell::~DrawDocShell()
+{
+ // Tell all listeners that the doc shell is about to be
+ // destroyed. This has been introduced for the PreviewRenderer to
+ // free its view (that uses the item poll of the doc shell) but
+ // may be useful in other places as well.
+ Broadcast(SfxHint(SfxHintId::Dying));
+
+ mbInDestruction = true;
+
+ if (mpViewShell)
+ {
+ auto* pView = mpViewShell->GetView();
+ if (pView)
+ {
+ auto & pSearchContext = pView->getSearchContext();
+ pSearchContext.resetSearchFunction();
+ }
+ }
+
+ mpFontList.reset();
+
+ if( mpDoc )
+ mpDoc->SetSdrUndoManager( nullptr );
+ mpUndoManager.reset();
+
+ if (mbOwnPrinter)
+ mpPrinter.disposeAndClear();
+
+ if( mbOwnDocument )
+ delete mpDoc;
+
+ // that the navigator get informed about the disappearance of the document
+ SfxBoolItem aItem(SID_NAVIGATOR_INIT, true);
+ SfxViewFrame* pFrame = mpViewShell ? mpViewShell->GetFrame() : GetFrame();
+
+ if( !pFrame )
+ pFrame = SfxViewFrame::GetFirst( this );
+
+ if( pFrame )
+ {
+ pFrame->GetDispatcher()->ExecuteList(
+ SID_NAVIGATOR_INIT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
+ { &aItem });
+ }
+}
+
+void DrawDocShell::GetState(SfxItemSet &rSet)
+{
+
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while ( nWhich )
+ {
+ sal_uInt16 nSlotId = SfxItemPool::IsWhich(nWhich)
+ ? GetPool().GetSlotId(nWhich)
+ : nWhich;
+
+ switch ( nSlotId )
+ {
+ case SID_ATTR_CHAR_FONTLIST:
+ rSet.Put( SvxFontListItem( mpFontList.get(), nSlotId ) );
+ break;
+
+ case SID_SEARCH_ITEM:
+ {
+ rSet.Put( *SD_MOD()->GetSearchItem() );
+ }
+ break;
+
+ case SID_CLOSEDOC:
+ GetSlotState(SID_CLOSEDOC, SfxObjectShell::GetInterface(), &rSet);
+ break;
+
+ case SID_SEARCH_OPTIONS:
+ {
+ SearchOptionFlags nOpt = SearchOptionFlags::SEARCH |
+ SearchOptionFlags::WHOLE_WORDS |
+ SearchOptionFlags::BACKWARDS |
+ SearchOptionFlags::REG_EXP |
+ SearchOptionFlags::EXACT |
+ SearchOptionFlags::SIMILARITY |
+ SearchOptionFlags::SELECTION;
+
+ if (!IsReadOnly())
+ {
+ nOpt |= SearchOptionFlags::REPLACE;
+ nOpt |= SearchOptionFlags::REPLACE_ALL;
+ }
+
+ rSet.Put(SfxUInt16Item(nWhich, static_cast<sal_uInt16>(nOpt)));
+ }
+ break;
+
+ case SID_VERSION:
+ {
+ GetSlotState( SID_VERSION, SfxObjectShell::GetInterface(), &rSet );
+ }
+ break;
+
+ case SID_CHINESE_CONVERSION:
+ case SID_HANGUL_HANJA_CONVERSION:
+ {
+ rSet.Put(SfxVisibilityItem(nWhich, SvtCJKOptions::IsAnyEnabled()));
+ }
+ break;
+ case SID_LANGUAGE_STATUS:
+ {
+ SdrObject* pObj = nullptr;
+ bool bLanguageFound = false;
+ OutlinerParaObject* pParaObj = nullptr;
+ LanguageType eLanguage( LANGUAGE_DONTKNOW );
+ sal_uInt16 nCount = mpDoc->GetPageCount();
+ for ( sal_uInt16 itPage = 0; itPage < nCount && !bLanguageFound; itPage++ )
+ {
+ SdrObjListIter aListIter(mpDoc->GetPage(itPage), SdrIterMode::DeepWithGroups);
+ while ( aListIter.IsMore() && !bLanguageFound )
+ {
+ pObj = aListIter.Next();
+ if ( pObj )
+ {
+ pParaObj = pObj->GetOutlinerParaObject();
+ if ( pParaObj )
+ {
+ SdrOutliner aOutliner(&mpDoc->GetPool(), OutlinerMode::TextObject);
+ aOutliner.SetText(*pParaObj);
+ eLanguage = aOutliner.GetLanguage(0, 0);
+ bLanguageFound = eLanguage != LANGUAGE_DONTKNOW;
+ }
+ }
+ }
+ }
+
+ if ( eLanguage == LANGUAGE_DONTKNOW )
+ {
+ eLanguage = mpDoc->GetLanguage( EE_CHAR_LANGUAGE );
+ }
+
+ OUString aLanguage = SvtLanguageTable::GetLanguageString(eLanguage);
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ if (eLanguage == LANGUAGE_DONTKNOW)
+ {
+ aLanguage += ";-";
+ }
+ else
+ {
+ aLanguage += ";" + LanguageTag(eLanguage).getBcp47(false);
+ }
+ }
+ rSet.Put(SfxStringItem(nWhich, aLanguage));
+ }
+ break;
+
+ case SID_NOTEBOOKBAR:
+ {
+ if (mpViewShell)
+ {
+ bool bImpress = mpDoc->GetDocumentType() == DocumentType::Impress;
+ bool bVisible = false;
+ if(bImpress)
+ {
+ bVisible = sfx2::SfxNotebookBar::StateMethod(mpViewShell->GetFrame()->GetBindings(),
+ u"modules/simpress/ui/");
+ }
+ else
+ {
+ bVisible = sfx2::SfxNotebookBar::StateMethod(mpViewShell->GetFrame()->GetBindings(),
+ u"modules/sdraw/ui/");
+ }
+ rSet.Put( SfxBoolItem( SID_NOTEBOOKBAR, bVisible ) );
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ nWhich = aIter.NextWhich();
+ }
+
+ SfxViewFrame* pFrame = SfxViewFrame::Current();
+
+ if (pFrame)
+ {
+ if (rSet.GetItemState(SID_RELOAD) != SfxItemState::UNKNOWN)
+ {
+ pFrame->GetSlotState(SID_RELOAD,
+ pFrame->GetInterface(), &rSet);
+ }
+ }
+}
+
+void DrawDocShell::Activate( bool bMDI)
+{
+ if (bMDI)
+ {
+ ApplySlotFilter();
+ mpDoc->StartOnlineSpelling();
+ }
+}
+
+void DrawDocShell::Deactivate( bool )
+{
+}
+
+SfxUndoManager* DrawDocShell::GetUndoManager()
+{
+ return mpUndoManager.get();
+}
+
+void DrawDocShell::UpdateTablePointers()
+{
+ PutItem( SvxColorListItem( mpDoc->GetColorList(), SID_COLOR_TABLE ) );
+ PutItem( SvxGradientListItem( mpDoc->GetGradientList(), SID_GRADIENT_LIST ) );
+ PutItem( SvxHatchListItem( mpDoc->GetHatchList(), SID_HATCH_LIST ) );
+ PutItem( SvxBitmapListItem( mpDoc->GetBitmapList(), SID_BITMAP_LIST ) );
+ PutItem( SvxPatternListItem( mpDoc->GetPatternList(), SID_PATTERN_LIST ) );
+ PutItem( SvxDashListItem( mpDoc->GetDashList(), SID_DASH_LIST ) );
+ PutItem( SvxLineEndListItem( mpDoc->GetLineEndList(), SID_LINEEND_LIST ) );
+
+ UpdateFontList();
+}
+
+void DrawDocShell::CancelSearching()
+{
+ if (mpViewShell)
+ {
+ auto* pView = mpViewShell->GetView();
+ if (pView)
+ {
+ auto & pSearchContext = pView->getSearchContext();
+ pSearchContext.resetSearchFunction();
+ }
+ }
+}
+
+/**
+ * apply configured slot filters
+ */
+void DrawDocShell::ApplySlotFilter() const
+{
+ SfxViewShell* pTestViewShell = SfxViewShell::GetFirst();
+
+ while( pTestViewShell )
+ {
+ if( pTestViewShell->GetObjectShell()
+ == this
+ && pTestViewShell->GetViewFrame()
+ && pTestViewShell->GetViewFrame()->GetDispatcher() )
+ {
+ SfxDispatcher* pDispatcher = pTestViewShell->GetViewFrame()->GetDispatcher();
+
+ if( !mpFilterSIDs.empty() )
+ pDispatcher->SetSlotFilter( mbFilterEnable ? SfxSlotFilterState::ENABLED : SfxSlotFilterState::DISABLED, mpFilterSIDs );
+ else
+ pDispatcher->SetSlotFilter();
+
+ if( pDispatcher->GetBindings() )
+ pDispatcher->GetBindings()->InvalidateAll( true );
+ }
+
+ pTestViewShell = SfxViewShell::GetNext( *pTestViewShell );
+ }
+}
+
+void DrawDocShell::SetModified( bool bSet /* = true */ )
+{
+ SfxObjectShell::SetModified( bSet );
+
+ // change model state, too
+ // only set the changed state if modification is enabled
+ if( IsEnableSetModified() )
+ {
+ if ( mpDoc )
+ mpDoc->NbcSetChanged( bSet );
+
+ Broadcast( SfxHint( SfxHintId::DocChanged ) );
+ }
+}
+
+/**
+ * Callback for ExecuteSpellPopup()
+ */
+// ExecuteSpellPopup now handled by DrawDocShell. This is necessary
+// to get hands on the outliner and the text object.
+IMPL_LINK(DrawDocShell, OnlineSpellCallback, SpellCallbackInfo&, rInfo, void)
+{
+ SdrObject* pObj = nullptr;
+ SdrOutliner* pOutl = nullptr;
+
+ if(GetViewShell())
+ {
+ pOutl = GetViewShell()->GetView()->GetTextEditOutliner();
+ pObj = GetViewShell()->GetView()->GetTextEditObject();
+ }
+
+ mpDoc->ImpOnlineSpellCallback(&rInfo, pObj, pOutl);
+}
+
+void DrawDocShell::ClearUndoBuffer()
+{
+ // clear possible undo buffers of outliners
+ SfxViewFrame* pSfxViewFrame = SfxViewFrame::GetFirst(this, false);
+ while(pSfxViewFrame)
+ {
+ ViewShellBase* pViewShellBase = dynamic_cast< ViewShellBase* >( pSfxViewFrame->GetViewShell() );
+ if( pViewShellBase )
+ {
+ std::shared_ptr<ViewShell> pViewSh( pViewShellBase->GetMainViewShell() );
+ if( pViewSh )
+ {
+ ::sd::View* pView = pViewSh->GetView();
+ if( pView )
+ {
+ pView->SdrEndTextEdit();
+ sd::OutlineView* pOutlView = dynamic_cast< sd::OutlineView* >( pView );
+ if( pOutlView )
+ {
+ pOutlView->GetOutliner().GetUndoManager().Clear();
+ }
+ }
+ }
+ }
+ pSfxViewFrame = SfxViewFrame::GetNext(*pSfxViewFrame, this, false);
+ }
+
+ SfxUndoManager* pUndoManager = GetUndoManager();
+ if(pUndoManager && pUndoManager->GetUndoActionCount())
+ pUndoManager->Clear();
+}
+
+std::vector<Color> DrawDocShell::GetThemeColors()
+{
+ auto pViewShell = dynamic_cast<sd::DrawViewShell*>(GetViewShell());
+ if (!pViewShell)
+ {
+ return {};
+ }
+
+ SdPage* pPage = pViewShell->getCurrentPage();
+ svx::Theme* pTheme = pPage->getSdrPageProperties().GetTheme();
+ if (!pPage->IsMasterPage())
+ {
+ pTheme = pPage->TRG_GetMasterPage().getSdrPageProperties().GetTheme();
+ }
+
+ if (!pTheme)
+ {
+ return {};
+ }
+
+ return pTheme->GetColors();
+}
+
+} // end of namespace sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/docshell/grdocsh.cxx b/sd/source/ui/docshell/grdocsh.cxx
new file mode 100644
index 000000000..f0f5af956
--- /dev/null
+++ b/sd/source/ui/docshell/grdocsh.cxx
@@ -0,0 +1,61 @@
+/* -*- 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 <svx/svxids.hrc>
+#include <tools/globname.hxx>
+
+#include <comphelper/classids.hxx>
+
+#include <sfx2/objface.hxx>
+
+#include <GraphicDocShell.hxx>
+#include <DrawDocShell.hxx>
+
+using namespace sd;
+#define ShellClass_GraphicDocShell
+#include <sdgslots.hxx>
+
+namespace sd
+{
+SFX_IMPL_SUPERCLASS_INTERFACE(GraphicDocShell, SfxObjectShell)
+
+void GraphicDocShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterChildWindow(SID_SEARCH_DLG);
+}
+
+SFX_IMPL_OBJECTFACTORY(GraphicDocShell, SvGlobalName(SO3_SDRAW_CLASSID_60), "sdraw")
+
+GraphicDocShell::GraphicDocShell(SfxObjectCreateMode eMode)
+ : DrawDocShell(eMode, /*bDataObject*/ true, DocumentType::Draw)
+{
+ SetStyleFamily(SfxStyleFamily::Para);
+}
+
+GraphicDocShell::GraphicDocShell(SfxModelFlags nModelCreationFlags)
+ : DrawDocShell(nModelCreationFlags, /*bDataObject*/ false, DocumentType::Draw)
+{
+ SetStyleFamily(SfxStyleFamily::Para);
+}
+
+GraphicDocShell::~GraphicDocShell() {}
+
+} // end of namespace sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/docshell/sdclient.cxx b/sd/source/ui/docshell/sdclient.cxx
new file mode 100644
index 000000000..02521c257
--- /dev/null
+++ b/sd/source/ui/docshell/sdclient.cxx
@@ -0,0 +1,184 @@
+/* -*- 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 <Client.hxx>
+#include <svx/svdoole2.hxx>
+#include <tools/debug.hxx>
+
+#include <ViewShell.hxx>
+#include <View.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace com::sun::star;
+
+namespace sd {
+
+Client::Client(SdrOle2Obj* pObj, ViewShell* pViewShell, vcl::Window* pWindow) :
+ SfxInPlaceClient(pViewShell->GetViewShell(), pWindow, pObj->GetAspect() ),
+ mpViewShell(pViewShell),
+ pSdrOle2Obj(pObj)
+{
+ SetObject( pObj->GetObjRef() );
+ DBG_ASSERT( GetObject().is(), "No object connected!" );
+}
+
+Client::~Client()
+{
+}
+
+/**
+ * If IP active, then we get this request to increase the visible section of the
+ * object.
+ */
+void Client::RequestNewObjectArea( ::tools::Rectangle& aObjRect )
+{
+ ::sd::View* pView = mpViewShell->GetView();
+
+ bool bSizeProtect = false;
+ bool bPosProtect = false;
+
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+
+ // no need to check for changes, this method is called only if the area really changed
+ bSizeProtect = pObj->IsResizeProtect();
+ bPosProtect = pObj->IsMoveProtect();
+ }
+
+ ::tools::Rectangle aOldRect = GetObjArea();
+ if ( bPosProtect )
+ aObjRect.SetPos( aOldRect.TopLeft() );
+
+ if ( bSizeProtect )
+ aObjRect.SetSize( aOldRect.GetSize() );
+
+ ::tools::Rectangle aWorkArea( pView->GetWorkArea() );
+ if ( aWorkArea.Contains(aObjRect) || bPosProtect || aObjRect == aOldRect )
+ return;
+
+ // correct position
+ Point aPos = aObjRect.TopLeft();
+ Size aSize = aObjRect.GetSize();
+ Point aWorkAreaTL = aWorkArea.TopLeft();
+ Point aWorkAreaBR = aWorkArea.BottomRight();
+
+ aPos.setX( std::max(aPos.X(), aWorkAreaTL.X()) );
+ aPos.setX( std::min(aPos.X(), aWorkAreaBR.X()-aSize.Width()) );
+ aPos.setY( std::max(aPos.Y(), aWorkAreaTL.Y()) );
+ aPos.setY( std::min(aPos.Y(), aWorkAreaBR.Y()-aSize.Height()) );
+
+ aObjRect.SetPos(aPos);
+}
+
+void Client::ObjectAreaChanged()
+{
+ ::sd::View* pView = mpViewShell->GetView();
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ if (rMarkList.GetMarkCount() != 1)
+ return;
+
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrOle2Obj* pObj = dynamic_cast< SdrOle2Obj* >(pMark->GetMarkedSdrObj());
+
+ if(!pObj)
+ return;
+
+ // no need to check for changes, this method is called only if the area really changed
+ ::tools::Rectangle aNewRectangle(GetScaledObjArea());
+
+ // #i118524# if sheared/rotated, center to non-rotated LogicRect
+ pObj->setSuppressSetVisAreaSize(true);
+
+ if(pObj->GetGeoStat().nRotationAngle || pObj->GetGeoStat().nShearAngle)
+ {
+ pObj->SetLogicRect( aNewRectangle );
+
+ const ::tools::Rectangle& rBoundRect = pObj->GetCurrentBoundRect();
+ const Point aDelta(aNewRectangle.Center() - rBoundRect.Center());
+
+ aNewRectangle.Move(aDelta.X(), aDelta.Y());
+ }
+
+ pObj->SetLogicRect( aNewRectangle );
+ pObj->setSuppressSetVisAreaSize(false);
+}
+
+void Client::ViewChanged()
+{
+ if ( GetAspect() == embed::Aspects::MSOLE_ICON )
+ {
+ // the iconified object seems not to need such a scaling handling
+ // since the replacement image and the size a completely controlled by the container
+ // TODO/LATER: when the icon exchange is implemented the scaling handling might be required again here
+
+ pSdrOle2Obj->ActionChanged(); // draw needs it to remove lines in slide preview
+ return;
+ }
+
+ //TODO/LATER: should we try to avoid the recalculation of the visareasize
+ //if we know that it didn't change?
+ if (!mpViewShell->GetActiveWindow())
+ return;
+
+ ::sd::View* pView = mpViewShell->GetView();
+ if (!pView)
+ return;
+
+ ::tools::Rectangle aLogicRect( pSdrOle2Obj->GetLogicRect() );
+ Size aLogicSize( aLogicRect.GetWidth(), aLogicRect.GetHeight() );
+
+ if( pSdrOle2Obj->IsChart() )
+ {
+ //charts never should be stretched see #i84323# for example
+ pSdrOle2Obj->SetLogicRect( ::tools::Rectangle( aLogicRect.TopLeft(), aLogicSize ) );
+ pSdrOle2Obj->BroadcastObjectChange();
+ return;
+ }
+
+ // TODO/LEAN: maybe we can do this without requesting the VisualArea?
+ // working with the visual area might need running state, so the object may switch itself to this state
+ MapMode aMap100( MapUnit::Map100thMM );
+ ::tools::Rectangle aVisArea;
+ Size aSize = pSdrOle2Obj->GetOrigObjSize( &aMap100 );
+
+ aVisArea.SetSize( aSize );
+ Size aScaledSize( static_cast< ::tools::Long >( GetScaleWidth() * Fraction( aVisArea.GetWidth() ) ),
+ static_cast< ::tools::Long >( GetScaleHeight() * Fraction( aVisArea.GetHeight() ) ) );
+
+ // react to the change if the difference is bigger than one pixel
+ Size aPixelDiff =
+ Application::GetDefaultDevice()->LogicToPixel(
+ Size( aLogicRect.GetWidth() - aScaledSize.Width(),
+ aLogicRect.GetHeight() - aScaledSize.Height() ),
+ aMap100 );
+ if( aPixelDiff.Width() || aPixelDiff.Height() )
+ {
+ pSdrOle2Obj->SetLogicRect( ::tools::Rectangle( aLogicRect.TopLeft(), aScaledSize ) );
+ pSdrOle2Obj->BroadcastObjectChange();
+ }
+ else
+ pSdrOle2Obj->ActionChanged();
+}
+
+} // end of namespace sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */