1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26
27 #include "DrawDocShell.hxx"
28 #include <vcl/msgbox.hxx>
29 #include <svx/svdpagv.hxx>
30 #include <svx/svxdlg.hxx>
31 #include <svx/dialogs.hrc>
32
33 #include "helpids.h"
34 #include "ViewShell.hxx"
35 #include "drawview.hxx"
36 #ifndef SD_FRAMW_VIEW_HXX
37 #include "FrameView.hxx"
38 #endif
39 #include "drawdoc.hxx"
40 #include "sdpage.hxx"
41 #include "View.hxx"
42 #include "ClientView.hxx"
43 #ifndef SD_WINDOW_SHELL_HXX
44 #include "Window.hxx"
45 #endif
46 #include "strings.hrc"
47 #include "res_bmp.hrc"
48 #include "sdresid.hxx"
49 #include "strmname.h"
50 #include "fupoor.hxx"
51 #include <vcl/svapp.hxx>
52 #include <vcl/virdev.hxx>
53
54 namespace sd {
55
56 /*************************************************************************
57 |*
58 |* Zeichnen der DocShell (mittels der Hilfsklasse SdDrawViewShell)
59 |*
60 \************************************************************************/
61
Draw(OutputDevice * pOut,const JobSetup &,sal_uInt16 nAspect)62 void DrawDocShell::Draw(OutputDevice* pOut, const JobSetup&, sal_uInt16 nAspect)
63 {
64 if (nAspect == ASPECT_THUMBNAIL)
65 {
66 /**********************************************************************
67 * THUMBNAIL: Hier koennte ev. einmal der Draft-Mode gesetzt werden
68 **********************************************************************/
69 }
70
71 ClientView* pView = new ClientView(this, pOut, NULL);
72
73 pView->SetHlplVisible(sal_False);
74 pView->SetGridVisible(sal_False);
75 pView->SetBordVisible(sal_False);
76 pView->SetPageVisible(sal_False);
77 pView->SetGlueVisible(sal_False);
78
79 SdPage* pSelectedPage = NULL;
80
81 List* pFrameViewList = mpDoc->GetFrameViewList();
82 if( pFrameViewList && pFrameViewList->Count() )
83 {
84 FrameView* pFrameView = (FrameView*)pFrameViewList->GetObject(0);
85 if( pFrameView && pFrameView->GetPageKind() == PK_STANDARD )
86 {
87 sal_uInt16 nSelectedPage = pFrameView->GetSelectedPage();
88 pSelectedPage = mpDoc->GetSdPage(nSelectedPage, PK_STANDARD);
89 }
90 }
91
92 if( NULL == pSelectedPage )
93 {
94 SdPage* pPage = NULL;
95 sal_uInt16 nSelectedPage = 0;
96 sal_uInt16 nPageCnt = (sal_uInt16) mpDoc->GetSdPageCount(PK_STANDARD);
97
98 for (sal_uInt16 i = 0; i < nPageCnt; i++)
99 {
100 pPage = mpDoc->GetSdPage(i, PK_STANDARD);
101
102 if ( pPage->IsSelected() )
103 {
104 nSelectedPage = i;
105 pSelectedPage = pPage;
106 }
107 }
108
109 if( NULL == pSelectedPage )
110 pSelectedPage = mpDoc->GetSdPage(0, PK_STANDARD);
111 }
112
113 Rectangle aVisArea = GetVisArea(nAspect);
114 pOut->IntersectClipRegion(aVisArea);
115 pView->ShowSdrPage(pSelectedPage);
116
117 if (pOut->GetOutDevType() != OUTDEV_WINDOW)
118 {
119 MapMode aOldMapMode = pOut->GetMapMode();
120
121 if (pOut->GetOutDevType() == OUTDEV_PRINTER)
122 {
123 MapMode aMapMode = aOldMapMode;
124 Point aOrigin = aMapMode.GetOrigin();
125 aOrigin.X() += 1;
126 aOrigin.Y() += 1;
127 aMapMode.SetOrigin(aOrigin);
128 pOut->SetMapMode(aMapMode);
129 }
130
131 Region aRegion(aVisArea);
132 pView->CompleteRedraw(pOut, aRegion);
133
134 if (pOut->GetOutDevType() == OUTDEV_PRINTER)
135 {
136 pOut->SetMapMode(aOldMapMode);
137 }
138 }
139
140 delete pView;
141
142 // Fuer Testzwecke: Bitte nicht entfernen!
143 //
144 // GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
145 //
146 // if( pMtf )
147 // {
148 // String aURLStr;
149 //
150 // if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( String( RTL_CONSTASCII_USTRINGPARAM( "d:\\gdi.mtf" ) ), aURLStr ) )
151 // {
152 // SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_WRITE | STREAM_TRUNC );
153 //
154 // if( pOStm )
155 // {
156 // *pOStm << *pMtf;
157 // delete pOStm;
158 // }
159 // }
160 // }
161 }
162
163 /*************************************************************************
164 |*
165 |*
166 |*
167 \************************************************************************/
168
GetVisArea(sal_uInt16 nAspect) const169 Rectangle DrawDocShell::GetVisArea(sal_uInt16 nAspect) const
170 {
171 Rectangle aVisArea;
172
173 if( ( ASPECT_THUMBNAIL == nAspect ) || ( ASPECT_DOCPRINT == nAspect ) )
174 {
175 // Groesse der ersten Seite herausgeben
176 MapMode aSrcMapMode(MAP_PIXEL);
177 MapMode aDstMapMode(MAP_100TH_MM);
178 Size aSize = mpDoc->GetSdPage(0, PK_STANDARD)->GetSize();
179 aSrcMapMode.SetMapUnit(MAP_100TH_MM);
180
181 aSize = Application::GetDefaultDevice()->LogicToLogic(aSize, &aSrcMapMode, &aDstMapMode);
182 aVisArea.SetSize(aSize);
183 }
184 else
185 {
186 aVisArea = SfxObjectShell::GetVisArea(nAspect);
187 }
188
189 if (aVisArea.IsEmpty() && mpViewShell)
190 {
191 Window* pWin = mpViewShell->GetActiveWindow();
192
193 if (pWin)
194 {
195 aVisArea = pWin->PixelToLogic(Rectangle(Point(0,0), pWin->GetOutputSizePixel()));
196 }
197 }
198
199 return (aVisArea);
200 }
201
202 /*************************************************************************
203 |*
204 |* ViewShell anmelden
205 |*
206 \************************************************************************/
207
Connect(ViewShell * pViewSh)208 void DrawDocShell::Connect(ViewShell* pViewSh)
209 {
210 mpViewShell = pViewSh;
211 }
212
213 /*************************************************************************
214 |*
215 |* ViewShell abmelden
216 |*
217 \************************************************************************/
218
Disconnect(ViewShell * pViewSh)219 void DrawDocShell::Disconnect(ViewShell* pViewSh)
220 {
221 if (mpViewShell == pViewSh)
222 {
223 mpViewShell = NULL;
224 }
225 }
226
227 /*************************************************************************
228 |*
229 |*
230 |*
231 \************************************************************************/
232
GetFrameView()233 FrameView* DrawDocShell::GetFrameView()
234 {
235 FrameView* pFrameView = NULL;
236
237 if (mpViewShell)
238 {
239 pFrameView = mpViewShell->GetFrameView();
240 }
241
242 return(pFrameView);
243 }
244
245 /*************************************************************************
246 |*
247 |* Groesse der ersten Seite zurueckgeben
248 |*
249 \************************************************************************/
250
GetFirstPageSize()251 Size DrawDocShell::GetFirstPageSize()
252 {
253 return SfxObjectShell::GetFirstPageSize();
254 }
255
256 /*************************************************************************
257 |*
258 |* Bitmap einer beliebigen Seite erzeugen
259 |*
260 \************************************************************************/
261
GetPagePreviewBitmap(SdPage * pPage,sal_uInt16 nMaxEdgePixel)262 Bitmap DrawDocShell::GetPagePreviewBitmap(SdPage* pPage, sal_uInt16 nMaxEdgePixel)
263 {
264 MapMode aMapMode( MAP_100TH_MM );
265 const Size aSize( pPage->GetSize() );
266 const Point aNullPt;
267 VirtualDevice aVDev( *Application::GetDefaultDevice() );
268
269 aVDev.SetMapMode( aMapMode );
270
271 const Size aPixSize( aVDev.LogicToPixel( aSize ) );
272 const sal_uLong nMaxEdgePix = Max( aPixSize.Width(), aPixSize.Height() );
273 Fraction aFrac( nMaxEdgePixel, nMaxEdgePix );
274
275 aMapMode.SetScaleX( aFrac );
276 aMapMode.SetScaleY( aFrac );
277 aVDev.SetMapMode( aMapMode );
278 aVDev.SetOutputSize( aSize );
279
280 // damit die dunklen Linien am rechten und unteren Seitenrans mitkommen
281 aFrac = Fraction( nMaxEdgePixel - 1, nMaxEdgePix );
282 aMapMode.SetScaleX( aFrac );
283 aMapMode.SetScaleY( aFrac );
284 aVDev.SetMapMode( aMapMode );
285
286 ClientView* pView = new ClientView( this, &aVDev, NULL );
287 FrameView* pFrameView = GetFrameView();
288 pView->ShowSdrPage( pPage );
289
290 if ( GetFrameView() )
291 {
292 // Initialisierungen der Zeichen-(Bildschirm-)Attribute
293 pView->SetGridCoarse( pFrameView->GetGridCoarse() );
294 pView->SetGridFine( pFrameView->GetGridFine() );
295 pView->SetSnapGridWidth(pFrameView->GetSnapGridWidthX(), pFrameView->GetSnapGridWidthY());
296 pView->SetGridVisible( pFrameView->IsGridVisible() );
297 pView->SetGridFront( pFrameView->IsGridFront() );
298 pView->SetSnapAngle( pFrameView->GetSnapAngle() );
299 pView->SetGridSnap( pFrameView->IsGridSnap() );
300 pView->SetBordSnap( pFrameView->IsBordSnap() );
301 pView->SetHlplSnap( pFrameView->IsHlplSnap() );
302 pView->SetOFrmSnap( pFrameView->IsOFrmSnap() );
303 pView->SetOPntSnap( pFrameView->IsOPntSnap() );
304 pView->SetOConSnap( pFrameView->IsOConSnap() );
305 pView->SetDragStripes( pFrameView->IsDragStripes() );
306 pView->SetFrameDragSingles( pFrameView->IsFrameDragSingles() );
307 pView->SetSnapMagneticPixel( pFrameView->GetSnapMagneticPixel() );
308 pView->SetMarkedHitMovesAlways( pFrameView->IsMarkedHitMovesAlways() );
309 pView->SetMoveOnlyDragging( pFrameView->IsMoveOnlyDragging() );
310 pView->SetSlantButShear( pFrameView->IsSlantButShear() );
311 pView->SetNoDragXorPolys( pFrameView->IsNoDragXorPolys() );
312 pView->SetCrookNoContortion( pFrameView->IsCrookNoContortion() );
313 pView->SetAngleSnapEnabled( pFrameView->IsAngleSnapEnabled() );
314 pView->SetBigOrtho( pFrameView->IsBigOrtho() );
315 pView->SetOrtho( pFrameView->IsOrtho() );
316
317 SdrPageView* pPageView = pView->GetSdrPageView();
318
319 if (pPageView)
320 {
321 if ( pPageView->GetVisibleLayers() != pFrameView->GetVisibleLayers() )
322 pPageView->SetVisibleLayers( pFrameView->GetVisibleLayers() );
323
324 if ( pPageView->GetPrintableLayers() != pFrameView->GetPrintableLayers() )
325 pPageView->SetPrintableLayers( pFrameView->GetPrintableLayers() );
326
327 if ( pPageView->GetLockedLayers() != pFrameView->GetLockedLayers() )
328 pPageView->SetLockedLayers( pFrameView->GetLockedLayers() );
329
330 // if ( pPageView->GetHelpLines() != pFrameView->GetHelpLines() )
331 pPageView->SetHelpLines( pFrameView->GetStandardHelpLines() );
332 }
333
334 if ( pView->GetActiveLayer() != pFrameView->GetActiveLayer() )
335 pView->SetActiveLayer( pFrameView->GetActiveLayer() );
336 }
337
338 pView->CompleteRedraw( &aVDev, Rectangle( aNullPt, aSize ) );
339
340 // #111097# IsRedrawReady() always gives sal_True while ( !pView->IsRedrawReady() ) {}
341 delete pView;
342
343 aVDev.SetMapMode( MapMode() );
344
345 Bitmap aPreview( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) );
346
347 DBG_ASSERT(!!aPreview, "Vorschau-Bitmap konnte nicht erzeugt werden");
348
349 return aPreview;
350 }
351
352
353 /*************************************************************************
354 |*
355 |* Pruefen, ob die Seite vorhanden ist und dann den Anwender zwingen einen
356 |* noch nicht vorhandenen Namen einzugeben. Wird sal_False zurueckgegeben,
357 |* wurde die Aktion vom Anwender abgebrochen.
358 |*
359 \************************************************************************/
360
CheckPageName(::Window * pWin,String & rName)361 sal_Bool DrawDocShell::CheckPageName (::Window* pWin, String& rName )
362 {
363 const String aStrForDlg( rName );
364 bool bIsNameValid = IsNewPageNameValid( rName, true );
365
366 if( ! bIsNameValid )
367 {
368 String aDesc( SdResId( STR_WARN_PAGE_EXISTS ) );
369 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
370 AbstractSvxNameDialog* aNameDlg = pFact ? pFact->CreateSvxNameDialog( pWin, aStrForDlg, aDesc ) : 0;
371 if( aNameDlg )
372 {
373 aNameDlg->SetEditHelpId( HID_SD_NAMEDIALOG_PAGE );
374
375 if( mpViewShell )
376 aNameDlg->SetCheckNameHdl( LINK( this, DrawDocShell, RenameSlideHdl ) );
377
378 FunctionReference xFunc( mpViewShell->GetCurrentFunction() );
379 if( xFunc.is() )
380 xFunc->cancel();
381
382 if( aNameDlg->Execute() == RET_OK )
383 {
384 aNameDlg->GetName( rName );
385 bIsNameValid = IsNewPageNameValid( rName );
386 }
387 delete aNameDlg;
388 }
389 }
390
391 return ( bIsNameValid ? sal_True : sal_False );
392 }
393
IsNewPageNameValid(String & rInOutPageName,bool bResetStringIfStandardName)394 bool DrawDocShell::IsNewPageNameValid( String & rInOutPageName, bool bResetStringIfStandardName /* = false */ )
395 {
396 bool bCanUseNewName = false;
397
398 // check if name is something like 'Slide n'
399 String aStrPage( SdResId( STR_SD_PAGE ) );
400 aStrPage += ' ';
401
402 bool bIsStandardName = false;
403
404 // prevent also _future_ slide names of the form "'STR_SD_PAGE' + ' ' + '[0-9]+|[a-z]|[A-Z]|[CDILMVX]+|[cdilmvx]+'"
405 // (arabic, lower- and upper case single letter, lower- and upper case roman numbers)
406 if( 0 == rInOutPageName.Search( aStrPage ) )
407 {
408 if( rInOutPageName.GetToken( 1, sal_Unicode(' ') ).GetChar(0) >= '0' &&
409 rInOutPageName.GetToken( 1, sal_Unicode(' ') ).GetChar(0) <= '9' )
410 {
411 // check for arabic numbering
412
413 // gobble up all following numbers
414 String sRemainder = rInOutPageName.GetToken( 1, sal_Unicode(' ') );
415 while( sRemainder.Len() &&
416 sRemainder.GetChar(0) >= '0' &&
417 sRemainder.GetChar(0) <= '9' )
418 {
419 // trim by one
420 sRemainder.Erase(0, 1);
421 }
422
423 // EOL? Reserved name!
424 if( !sRemainder.Len() )
425 {
426 bIsStandardName = true;
427 }
428 }
429 else if( rInOutPageName.GetToken( 1, sal_Unicode(' ') ).GetChar(0) >= 'a' &&
430 rInOutPageName.GetToken( 1, sal_Unicode(' ') ).GetChar(0) <= 'z' &&
431 rInOutPageName.GetToken( 1, sal_Unicode(' ') ).Len() == 1 )
432 {
433 // lower case, single character: reserved
434 bIsStandardName = true;
435 }
436 else if( rInOutPageName.GetToken( 1, sal_Unicode(' ') ).GetChar(0) >= 'A' &&
437 rInOutPageName.GetToken( 1, sal_Unicode(' ') ).GetChar(0) <= 'Z' &&
438 rInOutPageName.GetToken( 1, sal_Unicode(' ') ).Len() == 1 )
439 {
440 // upper case, single character: reserved
441 bIsStandardName = true;
442 }
443 else
444 {
445 // check for upper/lower case roman numbering
446 String sReserved( String::CreateFromAscii( "cdilmvx" ) );
447
448 // gobble up all following characters contained in one reserved class
449 String sRemainder = rInOutPageName.GetToken( 1, sal_Unicode(' ') );
450 if( sReserved.Search( sRemainder.GetChar(0) ) == STRING_NOTFOUND )
451 sReserved.ToUpperAscii();
452
453 while( sReserved.Search( sRemainder.GetChar(0) ) != STRING_NOTFOUND )
454 {
455 // trim by one
456 sRemainder.Erase(0, 1);
457 }
458
459 // EOL? Reserved name!
460 if( !sRemainder.Len() )
461 {
462 bIsStandardName = true;
463 }
464 }
465 }
466
467 if( bIsStandardName )
468 {
469 if( bResetStringIfStandardName )
470 {
471 // this is for insertion of slides from other files with standard
472 // name. They get a new standard name, if the string is set to an
473 // empty one.
474 rInOutPageName = String();
475 bCanUseNewName = true;
476 }
477 else
478 bCanUseNewName = false;
479 }
480 else
481 {
482 if( rInOutPageName.Len() > 0 )
483 {
484 sal_Bool bOutDummy;
485 sal_uInt16 nExistingPageNum = mpDoc->GetPageByName( rInOutPageName, bOutDummy );
486 bCanUseNewName = ( nExistingPageNum == SDRPAGE_NOTFOUND );
487 }
488 else
489 bCanUseNewName = false;
490 }
491
492 return bCanUseNewName;
493 }
494
IMPL_LINK(DrawDocShell,RenameSlideHdl,AbstractSvxNameDialog *,pDialog)495 IMPL_LINK( DrawDocShell, RenameSlideHdl, AbstractSvxNameDialog*, pDialog )
496 {
497 if( ! pDialog )
498 return 0;
499
500 String aNewName;
501 pDialog->GetName( aNewName );
502
503 return IsNewPageNameValid( aNewName );
504 }
505 } // end of namespace sd
506