Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include "DrawDocShell.hxx"
22 : #include <vcl/msgbox.hxx>
23 : #include <svx/svdpagv.hxx>
24 : #include <svx/svxdlg.hxx>
25 : #include <svx/dialogs.hrc>
26 :
27 : #include "helpids.h"
28 : #include "ViewShell.hxx"
29 : #include "drawview.hxx"
30 : #include "FrameView.hxx"
31 : #include "drawdoc.hxx"
32 : #include "sdpage.hxx"
33 : #include "View.hxx"
34 : #include "ClientView.hxx"
35 : #include "Window.hxx"
36 : #include "strings.hrc"
37 : #include "res_bmp.hrc"
38 : #include "sdresid.hxx"
39 : #include "strmname.h"
40 : #include "fupoor.hxx"
41 : #include <vcl/svapp.hxx>
42 : #include <vcl/virdev.hxx>
43 : #include <comphelper/string.hxx>
44 :
45 : namespace sd {
46 :
47 : /**
48 : * Drawing of DocShell (with the helper class SdDrawViewShell)
49 : */
50 0 : void DrawDocShell::Draw(OutputDevice* pOut, const JobSetup&, sal_uInt16 nAspect)
51 : {
52 : if (nAspect == ASPECT_THUMBNAIL)
53 : {
54 : // THUMBNAIL: here we may can set the draft mode
55 : }
56 :
57 0 : ClientView* pView = new ClientView(this, pOut, NULL);
58 :
59 0 : pView->SetHlplVisible(false);
60 0 : pView->SetGridVisible(false);
61 0 : pView->SetBordVisible(false);
62 0 : pView->SetPageVisible(false);
63 0 : pView->SetGlueVisible(false);
64 :
65 0 : SdPage* pSelectedPage = NULL;
66 :
67 0 : const std::vector<sd::FrameView*> &rViews = mpDoc->GetFrameViewList();
68 0 : if( !rViews.empty() )
69 : {
70 0 : sd::FrameView* pFrameView = rViews[0];
71 0 : if( pFrameView->GetPageKind() == PK_STANDARD )
72 : {
73 0 : sal_uInt16 nSelectedPage = pFrameView->GetSelectedPage();
74 0 : pSelectedPage = mpDoc->GetSdPage(nSelectedPage, PK_STANDARD);
75 : }
76 : }
77 :
78 0 : if( NULL == pSelectedPage )
79 : {
80 0 : SdPage* pPage = NULL;
81 0 : sal_uInt16 nPageCnt = (sal_uInt16) mpDoc->GetSdPageCount(PK_STANDARD);
82 :
83 0 : for (sal_uInt16 i = 0; i < nPageCnt; i++)
84 : {
85 0 : pPage = mpDoc->GetSdPage(i, PK_STANDARD);
86 :
87 0 : if ( pPage->IsSelected() )
88 0 : pSelectedPage = pPage;
89 : }
90 :
91 0 : if( NULL == pSelectedPage )
92 0 : pSelectedPage = mpDoc->GetSdPage(0, PK_STANDARD);
93 : }
94 :
95 0 : Rectangle aVisArea = GetVisArea(nAspect);
96 0 : pOut->IntersectClipRegion(aVisArea);
97 0 : pView->ShowSdrPage(pSelectedPage);
98 :
99 0 : if (pOut->GetOutDevType() != OUTDEV_WINDOW)
100 : {
101 0 : MapMode aOldMapMode = pOut->GetMapMode();
102 :
103 0 : if (pOut->GetOutDevType() == OUTDEV_PRINTER)
104 : {
105 0 : MapMode aMapMode = aOldMapMode;
106 0 : Point aOrigin = aMapMode.GetOrigin();
107 0 : aOrigin.X() += 1;
108 0 : aOrigin.Y() += 1;
109 0 : aMapMode.SetOrigin(aOrigin);
110 0 : pOut->SetMapMode(aMapMode);
111 : }
112 :
113 0 : Region aRegion(aVisArea);
114 0 : pView->CompleteRedraw(pOut, aRegion);
115 :
116 0 : if (pOut->GetOutDevType() == OUTDEV_PRINTER)
117 : {
118 0 : pOut->SetMapMode(aOldMapMode);
119 0 : }
120 : }
121 :
122 0 : delete pView;
123 :
124 0 : }
125 :
126 0 : Rectangle DrawDocShell::GetVisArea(sal_uInt16 nAspect) const
127 : {
128 0 : Rectangle aVisArea;
129 :
130 0 : if( ( ASPECT_THUMBNAIL == nAspect ) || ( ASPECT_DOCPRINT == nAspect ) )
131 : {
132 : // provide size of first page
133 0 : MapMode aSrcMapMode(MAP_PIXEL);
134 0 : MapMode aDstMapMode(MAP_100TH_MM);
135 0 : Size aSize = mpDoc->GetSdPage(0, PK_STANDARD)->GetSize();
136 0 : aSrcMapMode.SetMapUnit(MAP_100TH_MM);
137 :
138 0 : aSize = Application::GetDefaultDevice()->LogicToLogic(aSize, &aSrcMapMode, &aDstMapMode);
139 0 : aVisArea.SetSize(aSize);
140 : }
141 : else
142 : {
143 0 : aVisArea = SfxObjectShell::GetVisArea(nAspect);
144 : }
145 :
146 0 : if (aVisArea.IsEmpty() && mpViewShell)
147 : {
148 0 : Window* pWin = mpViewShell->GetActiveWindow();
149 :
150 0 : if (pWin)
151 : {
152 0 : aVisArea = pWin->PixelToLogic(Rectangle(Point(0,0), pWin->GetOutputSizePixel()));
153 : }
154 : }
155 :
156 0 : return (aVisArea);
157 : }
158 :
159 0 : void DrawDocShell::Connect(ViewShell* pViewSh)
160 : {
161 0 : mpViewShell = pViewSh;
162 0 : }
163 :
164 0 : void DrawDocShell::Disconnect(ViewShell* pViewSh)
165 : {
166 0 : if (mpViewShell == pViewSh)
167 : {
168 0 : mpViewShell = NULL;
169 : }
170 0 : }
171 :
172 0 : FrameView* DrawDocShell::GetFrameView()
173 : {
174 0 : FrameView* pFrameView = NULL;
175 :
176 0 : if (mpViewShell)
177 : {
178 0 : pFrameView = mpViewShell->GetFrameView();
179 : }
180 :
181 0 : return(pFrameView);
182 : }
183 :
184 0 : Size DrawDocShell::GetFirstPageSize()
185 : {
186 0 : return SfxObjectShell::GetFirstPageSize();
187 : }
188 :
189 : /**
190 : * Creates a bitmap of an arbitrary page
191 : */
192 0 : Bitmap DrawDocShell::GetPagePreviewBitmap(SdPage* pPage, sal_uInt16 nMaxEdgePixel)
193 : {
194 0 : MapMode aMapMode( MAP_100TH_MM );
195 0 : const Size aSize( pPage->GetSize() );
196 0 : const Point aNullPt;
197 0 : VirtualDevice aVDev( *Application::GetDefaultDevice() );
198 :
199 0 : aVDev.SetMapMode( aMapMode );
200 :
201 0 : const Size aPixSize( aVDev.LogicToPixel( aSize ) );
202 0 : const sal_uLong nMaxEdgePix = std::max( aPixSize.Width(), aPixSize.Height() );
203 0 : Fraction aFrac( nMaxEdgePixel, nMaxEdgePix );
204 :
205 0 : aMapMode.SetScaleX( aFrac );
206 0 : aMapMode.SetScaleY( aFrac );
207 0 : aVDev.SetMapMode( aMapMode );
208 0 : aVDev.SetOutputSize( aSize );
209 :
210 : // that we also get the dark lines at the right and bottom page margin
211 0 : aFrac = Fraction( nMaxEdgePixel - 1, nMaxEdgePix );
212 0 : aMapMode.SetScaleX( aFrac );
213 0 : aMapMode.SetScaleY( aFrac );
214 0 : aVDev.SetMapMode( aMapMode );
215 :
216 0 : ClientView* pView = new ClientView( this, &aVDev, NULL );
217 0 : FrameView* pFrameView = GetFrameView();
218 0 : pView->ShowSdrPage( pPage );
219 :
220 0 : if ( GetFrameView() )
221 : {
222 : // initialize the drawing-(screen) attributes
223 0 : pView->SetGridCoarse( pFrameView->GetGridCoarse() );
224 0 : pView->SetGridFine( pFrameView->GetGridFine() );
225 0 : pView->SetSnapGridWidth(pFrameView->GetSnapGridWidthX(), pFrameView->GetSnapGridWidthY());
226 0 : pView->SetGridVisible( pFrameView->IsGridVisible() );
227 0 : pView->SetGridFront( pFrameView->IsGridFront() );
228 0 : pView->SetSnapAngle( pFrameView->GetSnapAngle() );
229 0 : pView->SetGridSnap( pFrameView->IsGridSnap() );
230 0 : pView->SetBordSnap( pFrameView->IsBordSnap() );
231 0 : pView->SetHlplSnap( pFrameView->IsHlplSnap() );
232 0 : pView->SetOFrmSnap( pFrameView->IsOFrmSnap() );
233 0 : pView->SetOPntSnap( pFrameView->IsOPntSnap() );
234 0 : pView->SetOConSnap( pFrameView->IsOConSnap() );
235 0 : pView->SetDragStripes( pFrameView->IsDragStripes() );
236 0 : pView->SetFrameDragSingles( pFrameView->IsFrameDragSingles() );
237 0 : pView->SetSnapMagneticPixel( pFrameView->GetSnapMagneticPixel() );
238 0 : pView->SetMarkedHitMovesAlways( pFrameView->IsMarkedHitMovesAlways() );
239 0 : pView->SetMoveOnlyDragging( pFrameView->IsMoveOnlyDragging() );
240 0 : pView->SetSlantButShear( pFrameView->IsSlantButShear() );
241 0 : pView->SetNoDragXorPolys( pFrameView->IsNoDragXorPolys() );
242 0 : pView->SetCrookNoContortion( pFrameView->IsCrookNoContortion() );
243 0 : pView->SetAngleSnapEnabled( pFrameView->IsAngleSnapEnabled() );
244 0 : pView->SetBigOrtho( pFrameView->IsBigOrtho() );
245 0 : pView->SetOrtho( pFrameView->IsOrtho() );
246 :
247 0 : SdrPageView* pPageView = pView->GetSdrPageView();
248 :
249 0 : if (pPageView)
250 : {
251 0 : if ( pPageView->GetVisibleLayers() != pFrameView->GetVisibleLayers() )
252 0 : pPageView->SetVisibleLayers( pFrameView->GetVisibleLayers() );
253 :
254 0 : if ( pPageView->GetPrintableLayers() != pFrameView->GetPrintableLayers() )
255 0 : pPageView->SetPrintableLayers( pFrameView->GetPrintableLayers() );
256 :
257 0 : if ( pPageView->GetLockedLayers() != pFrameView->GetLockedLayers() )
258 0 : pPageView->SetLockedLayers( pFrameView->GetLockedLayers() );
259 :
260 0 : pPageView->SetHelpLines( pFrameView->GetStandardHelpLines() );
261 : }
262 :
263 0 : if ( pView->GetActiveLayer() != pFrameView->GetActiveLayer() )
264 0 : pView->SetActiveLayer( pFrameView->GetActiveLayer() );
265 : }
266 :
267 0 : pView->CompleteRedraw( &aVDev, Region(Rectangle(aNullPt, aSize)) );
268 :
269 : // IsRedrawReady() always gives sal_True while ( !pView->IsRedrawReady() ) {}
270 0 : delete pView;
271 :
272 0 : aVDev.SetMapMode( MapMode() );
273 :
274 0 : Bitmap aPreview( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
275 :
276 : DBG_ASSERT(!!aPreview, "Preview-Bitmap could not be generated");
277 :
278 0 : return aPreview;
279 : }
280 :
281 :
282 : /**
283 : * Checks if the page exists. If so, we force the user to enter a not yet used
284 : * name.
285 : * @return sal_False if the user cancels the action.
286 : */
287 0 : sal_Bool DrawDocShell::CheckPageName (::Window* pWin, OUString& rName )
288 : {
289 0 : const OUString aStrForDlg( rName );
290 0 : bool bIsNameValid = IsNewPageNameValid( rName, true );
291 :
292 0 : if( ! bIsNameValid )
293 : {
294 0 : OUString aDesc( SD_RESSTR( STR_WARN_PAGE_EXISTS ) );
295 0 : SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
296 0 : AbstractSvxNameDialog* aNameDlg = pFact ? pFact->CreateSvxNameDialog( pWin, aStrForDlg, aDesc ) : 0;
297 0 : if( aNameDlg )
298 : {
299 0 : aNameDlg->SetEditHelpId( HID_SD_NAMEDIALOG_PAGE );
300 :
301 0 : if( mpViewShell )
302 0 : aNameDlg->SetCheckNameHdl( LINK( this, DrawDocShell, RenameSlideHdl ) );
303 :
304 0 : rtl::Reference<FuPoor> xFunc( mpViewShell->GetCurrentFunction() );
305 0 : if( xFunc.is() )
306 0 : xFunc->cancel();
307 :
308 0 : if( aNameDlg->Execute() == RET_OK )
309 : {
310 0 : aNameDlg->GetName( rName );
311 0 : bIsNameValid = IsNewPageNameValid( rName );
312 : }
313 0 : delete aNameDlg;
314 0 : }
315 : }
316 :
317 0 : return ( bIsNameValid ? sal_True : sal_False );
318 : }
319 :
320 0 : bool DrawDocShell::IsNewPageNameValid( OUString & rInOutPageName, bool bResetStringIfStandardName /* = false */ )
321 : {
322 0 : bool bCanUseNewName = false;
323 :
324 : // check if name is something like 'Slide n'
325 0 : OUString aStrPage(SD_RESSTR(STR_SD_PAGE) + " ");
326 :
327 0 : bool bIsStandardName = false;
328 :
329 : // prevent also _future_ slide names of the form "'STR_SD_PAGE' + ' ' + '[0-9]+|[a-z]|[A-Z]|[CDILMVX]+|[cdilmvx]+'"
330 : // (arabic, lower- and upper case single letter, lower- and upper case roman numbers)
331 0 : if (rInOutPageName.startsWith(aStrPage) &&
332 0 : rInOutPageName.getLength() > aStrPage.getLength())
333 : {
334 0 : OUString sRemainder = rInOutPageName.getToken(1, ' ');
335 0 : if (sRemainder[0] >= '0' && sRemainder[0] <= '9')
336 : {
337 : // check for arabic numbering
338 :
339 0 : sal_Int32 nIndex = 1;
340 : // skip all following numbers
341 0 : while (nIndex < sRemainder.getLength() &&
342 0 : sRemainder[nIndex] >= '0' && sRemainder[nIndex] <= '9')
343 : {
344 0 : nIndex++;
345 : }
346 :
347 : // EOL? Reserved name!
348 0 : if (nIndex >= sRemainder.getLength())
349 : {
350 0 : bIsStandardName = true;
351 : }
352 : }
353 0 : else if (sRemainder.getLength() == 1 &&
354 0 : comphelper::string::islowerAscii(sRemainder[0]))
355 : {
356 : // lower case, single character: reserved
357 0 : bIsStandardName = true;
358 : }
359 0 : else if (sRemainder.getLength() == 1 &&
360 0 : comphelper::string::isupperAscii(sRemainder[0]))
361 : {
362 : // upper case, single character: reserved
363 0 : bIsStandardName = true;
364 : }
365 : else
366 : {
367 : // check for upper/lower case roman numbering
368 0 : OUString sReserved("cdilmvx");
369 :
370 : // skip all following characters contained in one reserved class
371 0 : if (sReserved.indexOf(sRemainder[0]) == -1)
372 0 : sReserved = sReserved.toAsciiUpperCase();
373 :
374 0 : sal_Int32 nIndex = 0;
375 0 : while (nIndex < sRemainder.getLength() &&
376 0 : sReserved.indexOf(sRemainder[nIndex]) != -1)
377 : {
378 0 : nIndex++;
379 : }
380 :
381 : // EOL? Reserved name!
382 0 : if (nIndex >= sRemainder.getLength())
383 : {
384 0 : bIsStandardName = true;
385 0 : }
386 0 : }
387 : }
388 :
389 0 : if( bIsStandardName )
390 : {
391 0 : if( bResetStringIfStandardName )
392 : {
393 : // this is for insertion of slides from other files with standard
394 : // name. They get a new standard name, if the string is set to an
395 : // empty one.
396 0 : rInOutPageName = OUString();
397 0 : bCanUseNewName = true;
398 : }
399 : else
400 0 : bCanUseNewName = false;
401 : }
402 : else
403 : {
404 0 : if (!rInOutPageName.isEmpty())
405 : {
406 : sal_Bool bOutDummy;
407 0 : sal_uInt16 nExistingPageNum = mpDoc->GetPageByName( rInOutPageName, bOutDummy );
408 0 : bCanUseNewName = ( nExistingPageNum == SDRPAGE_NOTFOUND );
409 : }
410 : else
411 0 : bCanUseNewName = false;
412 : }
413 :
414 0 : return bCanUseNewName;
415 : }
416 :
417 0 : IMPL_LINK( DrawDocShell, RenameSlideHdl, AbstractSvxNameDialog*, pDialog )
418 : {
419 0 : if( ! pDialog )
420 0 : return long(false);
421 :
422 0 : OUString aNewName;
423 0 : pDialog->GetName( aNewName );
424 :
425 0 : return long(IsNewPageNameValid( aNewName ));
426 : }
427 0 : } // end of namespace sd
428 :
429 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|