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