diff options
Diffstat (limited to '')
-rw-r--r-- | sd/source/ui/docshell/docshel2.cxx | 416 |
1 files changed, 416 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: */ |