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