1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
21 #include "DrawDocShell.hxx"
22 #include <vcl/msgbox.hxx>
23 #include <svx/svdpagv.hxx>
24 #include <svx/svxdlg.hxx>
25 #include <svx/dialogs.hrc>
28 #include "ViewShell.hxx"
29 #include "drawview.hxx"
30 #include "FrameView.hxx"
31 #include "drawdoc.hxx"
34 #include "ClientView.hxx"
36 #include "strings.hrc"
37 #include "res_bmp.hrc"
38 #include "sdresid.hxx"
41 #include <vcl/svapp.hxx>
42 #include <vcl/virdev.hxx>
43 #include <comphelper/string.hxx>
48 * Drawing of DocShell (with the helper class SdDrawViewShell)
50 void DrawDocShell::Draw(OutputDevice
* pOut
, const JobSetup
&, sal_uInt16 nAspect
)
52 if (nAspect
== ASPECT_THUMBNAIL
)
54 // THUMBNAIL: here we may can set the draft mode
57 ClientView
* pView
= new ClientView(this, pOut
, NULL
);
59 pView
->SetHlplVisible(sal_False
);
60 pView
->SetGridVisible(sal_False
);
61 pView
->SetBordVisible(sal_False
);
62 pView
->SetPageVisible(sal_False
);
63 pView
->SetGlueVisible(sal_False
);
65 SdPage
* pSelectedPage
= NULL
;
67 const std::vector
<sd::FrameView
*> &rViews
= mpDoc
->GetFrameViewList();
70 sd::FrameView
* pFrameView
= rViews
[0];
71 if( pFrameView
->GetPageKind() == PK_STANDARD
)
73 sal_uInt16 nSelectedPage
= pFrameView
->GetSelectedPage();
74 pSelectedPage
= mpDoc
->GetSdPage(nSelectedPage
, PK_STANDARD
);
78 if( NULL
== pSelectedPage
)
81 sal_uInt16 nPageCnt
= (sal_uInt16
) mpDoc
->GetSdPageCount(PK_STANDARD
);
83 for (sal_uInt16 i
= 0; i
< nPageCnt
; i
++)
85 pPage
= mpDoc
->GetSdPage(i
, PK_STANDARD
);
87 if ( pPage
->IsSelected() )
88 pSelectedPage
= pPage
;
91 if( NULL
== pSelectedPage
)
92 pSelectedPage
= mpDoc
->GetSdPage(0, PK_STANDARD
);
95 Rectangle aVisArea
= GetVisArea(nAspect
);
96 pOut
->IntersectClipRegion(aVisArea
);
97 pView
->ShowSdrPage(pSelectedPage
);
99 if (pOut
->GetOutDevType() != OUTDEV_WINDOW
)
101 MapMode aOldMapMode
= pOut
->GetMapMode();
103 if (pOut
->GetOutDevType() == OUTDEV_PRINTER
)
105 MapMode aMapMode
= aOldMapMode
;
106 Point aOrigin
= aMapMode
.GetOrigin();
109 aMapMode
.SetOrigin(aOrigin
);
110 pOut
->SetMapMode(aMapMode
);
113 Region
aRegion(aVisArea
);
114 pView
->CompleteRedraw(pOut
, aRegion
);
116 if (pOut
->GetOutDevType() == OUTDEV_PRINTER
)
118 pOut
->SetMapMode(aOldMapMode
);
126 Rectangle
DrawDocShell::GetVisArea(sal_uInt16 nAspect
) const
130 if( ( ASPECT_THUMBNAIL
== nAspect
) || ( ASPECT_DOCPRINT
== nAspect
) )
132 // provide size of first page
133 MapMode
aSrcMapMode(MAP_PIXEL
);
134 MapMode
aDstMapMode(MAP_100TH_MM
);
135 Size aSize
= mpDoc
->GetSdPage(0, PK_STANDARD
)->GetSize();
136 aSrcMapMode
.SetMapUnit(MAP_100TH_MM
);
138 aSize
= Application::GetDefaultDevice()->LogicToLogic(aSize
, &aSrcMapMode
, &aDstMapMode
);
139 aVisArea
.SetSize(aSize
);
143 aVisArea
= SfxObjectShell::GetVisArea(nAspect
);
146 if (aVisArea
.IsEmpty() && mpViewShell
)
148 Window
* pWin
= mpViewShell
->GetActiveWindow();
152 aVisArea
= pWin
->PixelToLogic(Rectangle(Point(0,0), pWin
->GetOutputSizePixel()));
159 void DrawDocShell::Connect(ViewShell
* pViewSh
)
161 mpViewShell
= pViewSh
;
164 void DrawDocShell::Disconnect(ViewShell
* pViewSh
)
166 if (mpViewShell
== pViewSh
)
172 FrameView
* DrawDocShell::GetFrameView()
174 FrameView
* pFrameView
= NULL
;
178 pFrameView
= mpViewShell
->GetFrameView();
184 Size
DrawDocShell::GetFirstPageSize()
186 return SfxObjectShell::GetFirstPageSize();
190 * Creates a bitmap of an arbitrary page
192 Bitmap
DrawDocShell::GetPagePreviewBitmap(SdPage
* pPage
, sal_uInt16 nMaxEdgePixel
)
194 MapMode
aMapMode( MAP_100TH_MM
);
195 const Size
aSize( pPage
->GetSize() );
197 VirtualDevice
aVDev( *Application::GetDefaultDevice() );
199 aVDev
.SetMapMode( aMapMode
);
201 const Size
aPixSize( aVDev
.LogicToPixel( aSize
) );
202 const sal_uLong nMaxEdgePix
= std::max( aPixSize
.Width(), aPixSize
.Height() );
203 Fraction
aFrac( nMaxEdgePixel
, nMaxEdgePix
);
205 aMapMode
.SetScaleX( aFrac
);
206 aMapMode
.SetScaleY( aFrac
);
207 aVDev
.SetMapMode( aMapMode
);
208 aVDev
.SetOutputSize( aSize
);
210 // that we also get the dark lines at the right and bottom page margin
211 aFrac
= Fraction( nMaxEdgePixel
- 1, nMaxEdgePix
);
212 aMapMode
.SetScaleX( aFrac
);
213 aMapMode
.SetScaleY( aFrac
);
214 aVDev
.SetMapMode( aMapMode
);
216 ClientView
* pView
= new ClientView( this, &aVDev
, NULL
);
217 FrameView
* pFrameView
= GetFrameView();
218 pView
->ShowSdrPage( pPage
);
220 if ( GetFrameView() )
222 // initialize the drawing-(screen) attributes
223 pView
->SetGridCoarse( pFrameView
->GetGridCoarse() );
224 pView
->SetGridFine( pFrameView
->GetGridFine() );
225 pView
->SetSnapGridWidth(pFrameView
->GetSnapGridWidthX(), pFrameView
->GetSnapGridWidthY());
226 pView
->SetGridVisible( pFrameView
->IsGridVisible() );
227 pView
->SetGridFront( pFrameView
->IsGridFront() );
228 pView
->SetSnapAngle( pFrameView
->GetSnapAngle() );
229 pView
->SetGridSnap( pFrameView
->IsGridSnap() );
230 pView
->SetBordSnap( pFrameView
->IsBordSnap() );
231 pView
->SetHlplSnap( pFrameView
->IsHlplSnap() );
232 pView
->SetOFrmSnap( pFrameView
->IsOFrmSnap() );
233 pView
->SetOPntSnap( pFrameView
->IsOPntSnap() );
234 pView
->SetOConSnap( pFrameView
->IsOConSnap() );
235 pView
->SetDragStripes( pFrameView
->IsDragStripes() );
236 pView
->SetFrameDragSingles( pFrameView
->IsFrameDragSingles() );
237 pView
->SetSnapMagneticPixel( pFrameView
->GetSnapMagneticPixel() );
238 pView
->SetMarkedHitMovesAlways( pFrameView
->IsMarkedHitMovesAlways() );
239 pView
->SetMoveOnlyDragging( pFrameView
->IsMoveOnlyDragging() );
240 pView
->SetSlantButShear( pFrameView
->IsSlantButShear() );
241 pView
->SetNoDragXorPolys( pFrameView
->IsNoDragXorPolys() );
242 pView
->SetCrookNoContortion( pFrameView
->IsCrookNoContortion() );
243 pView
->SetAngleSnapEnabled( pFrameView
->IsAngleSnapEnabled() );
244 pView
->SetBigOrtho( pFrameView
->IsBigOrtho() );
245 pView
->SetOrtho( pFrameView
->IsOrtho() );
247 SdrPageView
* pPageView
= pView
->GetSdrPageView();
251 if ( pPageView
->GetVisibleLayers() != pFrameView
->GetVisibleLayers() )
252 pPageView
->SetVisibleLayers( pFrameView
->GetVisibleLayers() );
254 if ( pPageView
->GetPrintableLayers() != pFrameView
->GetPrintableLayers() )
255 pPageView
->SetPrintableLayers( pFrameView
->GetPrintableLayers() );
257 if ( pPageView
->GetLockedLayers() != pFrameView
->GetLockedLayers() )
258 pPageView
->SetLockedLayers( pFrameView
->GetLockedLayers() );
260 pPageView
->SetHelpLines( pFrameView
->GetStandardHelpLines() );
263 if ( pView
->GetActiveLayer() != pFrameView
->GetActiveLayer() )
264 pView
->SetActiveLayer( pFrameView
->GetActiveLayer() );
267 pView
->CompleteRedraw( &aVDev
, Region(Rectangle(aNullPt
, aSize
)) );
269 // IsRedrawReady() always gives sal_True while ( !pView->IsRedrawReady() ) {}
272 aVDev
.SetMapMode( MapMode() );
274 Bitmap
aPreview( aVDev
.GetBitmap( aNullPt
, aVDev
.GetOutputSizePixel() ) );
276 DBG_ASSERT(!!aPreview
, "Preview-Bitmap could not be generated");
283 * Checks if the page exists. If so, we force the user to enter a not yet used
285 * @return sal_False if the user cancels the action.
287 sal_Bool
DrawDocShell::CheckPageName (::Window
* pWin
, String
& rName
)
289 const String
aStrForDlg( rName
);
290 bool bIsNameValid
= IsNewPageNameValid( rName
, true );
294 String
aDesc( SdResId( STR_WARN_PAGE_EXISTS
) );
295 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
296 AbstractSvxNameDialog
* aNameDlg
= pFact
? pFact
->CreateSvxNameDialog( pWin
, aStrForDlg
, aDesc
) : 0;
299 aNameDlg
->SetEditHelpId( HID_SD_NAMEDIALOG_PAGE
);
302 aNameDlg
->SetCheckNameHdl( LINK( this, DrawDocShell
, RenameSlideHdl
) );
304 FunctionReference
xFunc( mpViewShell
->GetCurrentFunction() );
308 if( aNameDlg
->Execute() == RET_OK
)
310 aNameDlg
->GetName( rName
);
311 bIsNameValid
= IsNewPageNameValid( rName
);
317 return ( bIsNameValid
? sal_True
: sal_False
);
320 bool DrawDocShell::IsNewPageNameValid( String
& rInOutPageName
, bool bResetStringIfStandardName
/* = false */ )
322 bool bCanUseNewName
= false;
324 // check if name is something like 'Slide n'
325 String
aStrPage( SdResId( STR_SD_PAGE
) );
328 bool bIsStandardName
= false;
330 // prevent also _future_ slide names of the form "'STR_SD_PAGE' + ' ' + '[0-9]+|[a-z]|[A-Z]|[CDILMVX]+|[cdilmvx]+'"
331 // (arabic, lower- and upper case single letter, lower- and upper case roman numbers)
332 if( 0 == rInOutPageName
.Search( aStrPage
) )
334 if( rInOutPageName
.GetToken( 1, sal_Unicode(' ') ).GetChar(0) >= '0' &&
335 rInOutPageName
.GetToken( 1, sal_Unicode(' ') ).GetChar(0) <= '9' )
337 // check for arabic numbering
339 // gobble up all following numbers
340 String sRemainder
= rInOutPageName
.GetToken( 1, sal_Unicode(' ') );
341 while( sRemainder
.Len() &&
342 sRemainder
.GetChar(0) >= '0' &&
343 sRemainder
.GetChar(0) <= '9' )
346 sRemainder
.Erase(0, 1);
349 // EOL? Reserved name!
350 if( !sRemainder
.Len() )
352 bIsStandardName
= true;
355 else if( rInOutPageName
.GetToken( 1, sal_Unicode(' ') ).Len() == 1 &&
356 comphelper::string::islowerAscii(rInOutPageName
.GetToken( 1, sal_Unicode(' ') ).GetChar(0) ) )
358 // lower case, single character: reserved
359 bIsStandardName
= true;
361 else if( rInOutPageName
.GetToken( 1, sal_Unicode(' ') ).Len() == 1 &&
362 comphelper::string::isupperAscii(rInOutPageName
.GetToken( 1, sal_Unicode(' ') ).GetChar(0) ) )
364 // upper case, single character: reserved
365 bIsStandardName
= true;
369 // check for upper/lower case roman numbering
370 String
sReserved( OUString("cdilmvx") );
372 // gobble up all following characters contained in one reserved class
373 String sRemainder
= rInOutPageName
.GetToken( 1, sal_Unicode(' ') );
374 if( sReserved
.Search( sRemainder
.GetChar(0) ) == STRING_NOTFOUND
)
375 sReserved
.ToUpperAscii();
377 while( sReserved
.Search( sRemainder
.GetChar(0) ) != STRING_NOTFOUND
)
380 sRemainder
.Erase(0, 1);
383 // EOL? Reserved name!
384 if( !sRemainder
.Len() )
386 bIsStandardName
= true;
391 if( bIsStandardName
)
393 if( bResetStringIfStandardName
)
395 // this is for insertion of slides from other files with standard
396 // name. They get a new standard name, if the string is set to an
398 rInOutPageName
= String();
399 bCanUseNewName
= true;
402 bCanUseNewName
= false;
406 if( rInOutPageName
.Len() > 0 )
409 sal_uInt16 nExistingPageNum
= mpDoc
->GetPageByName( rInOutPageName
, bOutDummy
);
410 bCanUseNewName
= ( nExistingPageNum
== SDRPAGE_NOTFOUND
);
413 bCanUseNewName
= false;
416 return bCanUseNewName
;
419 IMPL_LINK( DrawDocShell
, RenameSlideHdl
, AbstractSvxNameDialog
*, pDialog
)
425 pDialog
->GetName( aNewName
);
427 return IsNewPageNameValid( aNewName
);
429 } // end of namespace sd
431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */