xref: /trunk/main/sd/source/ui/docshell/docshel2.cxx (revision 5b190011)
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 
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 
169 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 
208 void DrawDocShell::Connect(ViewShell* pViewSh)
209 {
210 	mpViewShell = pViewSh;
211 }
212 
213 /*************************************************************************
214 |*
215 |* ViewShell abmelden
216 |*
217 \************************************************************************/
218 
219 void DrawDocShell::Disconnect(ViewShell* pViewSh)
220 {
221 	if (mpViewShell == pViewSh)
222 	{
223 		mpViewShell = NULL;
224 	}
225 }
226 
227 /*************************************************************************
228 |*
229 |*
230 |*
231 \************************************************************************/
232 
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 
251 Size DrawDocShell::GetFirstPageSize()
252 {
253 	return SfxObjectShell::GetFirstPageSize();
254 }
255 
256 /*************************************************************************
257 |*
258 |* Bitmap einer beliebigen Seite erzeugen
259 |*
260 \************************************************************************/
261 
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 
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 
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 
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