Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sd / source / ui / docshell / docshel2.cxx
blob2eed71680ac592f5bee079412547e184eacade12
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <DrawDocShell.hxx>
22 #include <svx/svdpagv.hxx>
23 #include <svx/svxdlg.hxx>
24 #include <svx/dialogs.hrc>
26 #include <helpids.h>
27 #include <ViewShell.hxx>
28 #include <drawview.hxx>
29 #include <FrameView.hxx>
30 #include <drawdoc.hxx>
31 #include <sdpage.hxx>
32 #include <View.hxx>
33 #include <ClientView.hxx>
34 #include <Window.hxx>
35 #include <strings.hrc>
37 #include <sdresid.hxx>
38 #include <strmname.h>
39 #include <fupoor.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/virdev.hxx>
43 namespace sd {
45 /**
46 * Drawing of DocShell (with the helper class SdDrawViewShell)
48 void DrawDocShell::Draw(OutputDevice* pOut, const JobSetup&, sal_uInt16 nAspect)
50 if (nAspect == ASPECT_THUMBNAIL)
52 // THUMBNAIL: here we may can set the draft mode
55 std::unique_ptr<ClientView> pView( new ClientView(this, pOut) );
57 pView->SetHlplVisible(false);
58 pView->SetGridVisible(false);
59 pView->SetBordVisible(false);
60 pView->SetPageVisible(false);
61 pView->SetGlueVisible(false);
63 SdPage* pSelectedPage = nullptr;
65 const std::vector<std::unique_ptr<sd::FrameView>> &rViews = mpDoc->GetFrameViewList();
66 if( !rViews.empty() )
68 sd::FrameView* pFrameView = rViews[0].get();
69 if( pFrameView->GetPageKind() == PageKind::Standard )
71 sal_uInt16 nSelectedPage = pFrameView->GetSelectedPage();
72 pSelectedPage = mpDoc->GetSdPage(nSelectedPage, PageKind::Standard);
76 if( nullptr == pSelectedPage )
78 SdPage* pPage = nullptr;
79 sal_uInt16 nPageCnt = mpDoc->GetSdPageCount(PageKind::Standard);
81 for (sal_uInt16 i = 0; i < nPageCnt; i++)
83 pPage = mpDoc->GetSdPage(i, PageKind::Standard);
85 if ( pPage->IsSelected() )
86 pSelectedPage = pPage;
89 if( nullptr == pSelectedPage )
90 pSelectedPage = mpDoc->GetSdPage(0, PageKind::Standard);
93 ::tools::Rectangle aVisArea = GetVisArea(nAspect);
94 pOut->IntersectClipRegion(aVisArea);
95 pView->ShowSdrPage(pSelectedPage);
97 if (pOut->GetOutDevType() != OUTDEV_WINDOW)
99 MapMode aOldMapMode = pOut->GetMapMode();
101 if (pOut->GetOutDevType() == OUTDEV_PRINTER)
103 MapMode aMapMode = aOldMapMode;
104 Point aOrigin = aMapMode.GetOrigin();
105 aOrigin.AdjustX(1 );
106 aOrigin.AdjustY(1 );
107 aMapMode.SetOrigin(aOrigin);
108 pOut->SetMapMode(aMapMode);
111 vcl::Region aRegion(aVisArea);
112 pView->CompleteRedraw(pOut, aRegion);
114 if (pOut->GetOutDevType() == OUTDEV_PRINTER)
116 pOut->SetMapMode(aOldMapMode);
121 ::tools::Rectangle DrawDocShell::GetVisArea(sal_uInt16 nAspect) const
123 ::tools::Rectangle aVisArea;
125 if( ( ASPECT_THUMBNAIL == nAspect ) || ( ASPECT_DOCPRINT == nAspect ) )
127 // provide size of first page
128 MapMode aSrcMapMode(MapUnit::MapPixel);
129 MapMode aDstMapMode(MapUnit::Map100thMM);
130 Size aSize = mpDoc->GetSdPage(0, PageKind::Standard)->GetSize();
131 aSrcMapMode.SetMapUnit(MapUnit::Map100thMM);
133 aSize = Application::GetDefaultDevice()->LogicToLogic(aSize, &aSrcMapMode, &aDstMapMode);
134 aVisArea.SetSize(aSize);
136 else
138 aVisArea = SfxObjectShell::GetVisArea(nAspect);
141 if (aVisArea.IsEmpty() && mpViewShell)
143 vcl::Window* pWin = mpViewShell->GetActiveWindow();
145 if (pWin)
147 aVisArea = pWin->PixelToLogic(::tools::Rectangle(Point(0,0), pWin->GetOutputSizePixel()));
151 return aVisArea;
154 void DrawDocShell::Connect(ViewShell* pViewSh)
156 mpViewShell = pViewSh;
159 void DrawDocShell::Disconnect(ViewShell const * pViewSh)
161 if (mpViewShell == pViewSh)
163 mpViewShell = nullptr;
167 FrameView* DrawDocShell::GetFrameView()
169 FrameView* pFrameView = nullptr;
171 if (mpViewShell)
173 pFrameView = mpViewShell->GetFrameView();
176 return pFrameView;
180 * Creates a bitmap of an arbitrary page
182 Bitmap DrawDocShell::GetPagePreviewBitmap(SdPage* pPage)
184 const sal_uInt16 nMaxEdgePixel = 90;
185 MapMode aMapMode( MapUnit::Map100thMM );
186 const Size aSize( pPage->GetSize() );
187 const Point aNullPt;
188 ScopedVclPtrInstance< VirtualDevice > pVDev( *Application::GetDefaultDevice() );
190 pVDev->SetMapMode( aMapMode );
192 const Size aPixSize( pVDev->LogicToPixel( aSize ) );
193 const sal_uLong nMaxEdgePix = std::max( aPixSize.Width(), aPixSize.Height() );
194 Fraction aFrac( nMaxEdgePixel, nMaxEdgePix );
196 aMapMode.SetScaleX( aFrac );
197 aMapMode.SetScaleY( aFrac );
198 pVDev->SetMapMode( aMapMode );
199 pVDev->SetOutputSize( aSize );
201 // that we also get the dark lines at the right and bottom page margin
202 aFrac = Fraction( nMaxEdgePixel - 1, nMaxEdgePix );
203 aMapMode.SetScaleX( aFrac );
204 aMapMode.SetScaleY( aFrac );
205 pVDev->SetMapMode( aMapMode );
207 ClientView* pView = new ClientView( this, pVDev );
208 FrameView* pFrameView = GetFrameView();
209 pView->ShowSdrPage( pPage );
211 if ( GetFrameView() )
213 // initialize the drawing-(screen) attributes
214 pView->SetGridCoarse( pFrameView->GetGridCoarse() );
215 pView->SetGridFine( pFrameView->GetGridFine() );
216 pView->SetSnapGridWidth(pFrameView->GetSnapGridWidthX(), pFrameView->GetSnapGridWidthY());
217 pView->SetGridVisible( pFrameView->IsGridVisible() );
218 pView->SetGridFront( pFrameView->IsGridFront() );
219 pView->SetSnapAngle( pFrameView->GetSnapAngle() );
220 pView->SetGridSnap( pFrameView->IsGridSnap() );
221 pView->SetBordSnap( pFrameView->IsBordSnap() );
222 pView->SetHlplSnap( pFrameView->IsHlplSnap() );
223 pView->SetOFrmSnap( pFrameView->IsOFrmSnap() );
224 pView->SetOPntSnap( pFrameView->IsOPntSnap() );
225 pView->SetOConSnap( pFrameView->IsOConSnap() );
226 pView->SetDragStripes( pFrameView->IsDragStripes() );
227 pView->SetFrameDragSingles( pFrameView->IsFrameDragSingles() );
228 pView->SetSnapMagneticPixel( pFrameView->GetSnapMagneticPixel() );
229 pView->SetMarkedHitMovesAlways( pFrameView->IsMarkedHitMovesAlways() );
230 pView->SetMoveOnlyDragging( pFrameView->IsMoveOnlyDragging() );
231 pView->SetSlantButShear( pFrameView->IsSlantButShear() );
232 pView->SetNoDragXorPolys( pFrameView->IsNoDragXorPolys() );
233 pView->SetCrookNoContortion( pFrameView->IsCrookNoContortion() );
234 pView->SetAngleSnapEnabled( pFrameView->IsAngleSnapEnabled() );
235 pView->SetBigOrtho( pFrameView->IsBigOrtho() );
236 pView->SetOrtho( pFrameView->IsOrtho() );
238 SdrPageView* pPageView = pView->GetSdrPageView();
240 if (pPageView)
242 if ( pPageView->GetVisibleLayers() != pFrameView->GetVisibleLayers() )
243 pPageView->SetVisibleLayers( pFrameView->GetVisibleLayers() );
245 if ( pPageView->GetPrintableLayers() != pFrameView->GetPrintableLayers() )
246 pPageView->SetPrintableLayers( pFrameView->GetPrintableLayers() );
248 if ( pPageView->GetLockedLayers() != pFrameView->GetLockedLayers() )
249 pPageView->SetLockedLayers( pFrameView->GetLockedLayers() );
251 pPageView->SetHelpLines( pFrameView->GetStandardHelpLines() );
254 if ( pView->GetActiveLayer() != pFrameView->GetActiveLayer() )
255 pView->SetActiveLayer( pFrameView->GetActiveLayer() );
258 pView->CompleteRedraw( pVDev, vcl::Region(::tools::Rectangle(aNullPt, aSize)) );
260 // IsRedrawReady() always gives sal_True while ( !pView->IsRedrawReady() ) {}
261 delete pView;
263 pVDev->SetMapMode( MapMode() );
265 Bitmap aPreview( pVDev->GetBitmap( aNullPt, pVDev->GetOutputSizePixel() ) );
267 DBG_ASSERT(!!aPreview, "Preview-Bitmap could not be generated");
269 return aPreview;
273 * Checks if the page exists. If so, we force the user to enter a not yet used
274 * name.
275 * @return sal_False if the user cancels the action.
277 bool DrawDocShell::CheckPageName(weld::Window* pWin, OUString& rName)
279 const OUString aStrForDlg( rName );
280 bool bIsNameValid = IsNewPageNameValid( rName, true );
282 if( ! bIsNameValid )
284 OUString aDesc( SdResId( STR_WARN_PAGE_EXISTS ) );
285 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
286 if( pFact )
288 ScopedVclPtr<AbstractSvxNameDialog> aNameDlg(pFact->CreateSvxNameDialog(pWin, aStrForDlg, aDesc));
289 aNameDlg->SetEditHelpId( HID_SD_NAMEDIALOG_PAGE );
291 aNameDlg->SetCheckNameHdl( LINK( this, DrawDocShell, RenameSlideHdl ) );
293 rtl::Reference<FuPoor> xFunc( mpViewShell->GetCurrentFunction() );
294 if( xFunc.is() )
295 xFunc->cancel();
297 if( aNameDlg->Execute() == RET_OK )
299 aNameDlg->GetName( rName );
300 bIsNameValid = IsNewPageNameValid( rName );
305 return bIsNameValid;
308 bool DrawDocShell::IsNewPageNameValid( OUString & rInOutPageName, bool bResetStringIfStandardName /* = false */ )
310 bool bCanUseNewName = false;
312 // check if name is something like 'Slide n'
313 OUString aStrPage(SdResId(STR_SD_PAGE) + " ");
315 bool bIsStandardName = false;
317 // prevent also _future_ slide names of the form "'STR_SD_PAGE' + ' ' + '[0-9]+|[a-z]|[A-Z]|[CDILMVX]+|[cdilmvx]+'"
318 // (arabic, lower- and upper case single letter, lower- and upper case roman numbers)
319 if (rInOutPageName.startsWith(aStrPage) &&
320 rInOutPageName.getLength() > aStrPage.getLength())
322 OUString sRemainder = rInOutPageName.getToken(1, ' ');
323 if (sRemainder[0] >= '0' && sRemainder[0] <= '9')
325 // check for arabic numbering
327 sal_Int32 nIndex = 1;
328 // skip all following numbers
329 while (nIndex < sRemainder.getLength() &&
330 sRemainder[nIndex] >= '0' && sRemainder[nIndex] <= '9')
332 nIndex++;
335 // EOL? Reserved name!
336 if (nIndex >= sRemainder.getLength())
338 bIsStandardName = true;
341 else if (sRemainder.getLength() == 1 &&
342 rtl::isAsciiLowerCase(sRemainder[0]))
344 // lower case, single character: reserved
345 bIsStandardName = true;
347 else if (sRemainder.getLength() == 1 &&
348 rtl::isAsciiUpperCase(sRemainder[0]))
350 // upper case, single character: reserved
351 bIsStandardName = true;
353 else
355 // check for upper/lower case roman numbering
356 OUString sReserved("cdilmvx");
358 // skip all following characters contained in one reserved class
359 if (sReserved.indexOf(sRemainder[0]) == -1)
360 sReserved = sReserved.toAsciiUpperCase();
362 sal_Int32 nIndex = 0;
363 while (nIndex < sRemainder.getLength() &&
364 sReserved.indexOf(sRemainder[nIndex]) != -1)
366 nIndex++;
369 // EOL? Reserved name!
370 if (nIndex >= sRemainder.getLength())
372 bIsStandardName = true;
377 if( bIsStandardName )
379 if( bResetStringIfStandardName )
381 // this is for insertion of slides from other files with standard
382 // name. They get a new standard name, if the string is set to an
383 // empty one.
384 rInOutPageName.clear();
385 bCanUseNewName = true;
387 else
388 bCanUseNewName = false;
390 else
392 if (!rInOutPageName.isEmpty())
394 bool bOutDummy;
395 sal_uInt16 nExistingPageNum = mpDoc->GetPageByName( rInOutPageName, bOutDummy );
396 bCanUseNewName = ( nExistingPageNum == SDRPAGE_NOTFOUND );
398 else
399 bCanUseNewName = false;
402 return bCanUseNewName;
405 bool DrawDocShell::IsPageNameUnique( const OUString & rPageName ) const
407 return mpDoc->IsPageNameUnique(rPageName);
410 IMPL_LINK( DrawDocShell, RenameSlideHdl, AbstractSvxNameDialog&, rDialog, bool )
412 OUString aNewName;
413 rDialog.GetName( aNewName );
414 return IsNewPageNameValid( aNewName );
417 } // end of namespace sd
419 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */