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