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 "OutlineView.hxx" 32 #include <memory> 33 #include <editeng/forbiddencharacterstable.hxx> 34 #include <sfx2/progress.hxx> 35 #include <vcl/wrkwin.hxx> 36 #include <svx/svxids.hrc> 37 #include "eetext.hxx" 38 #include <editeng/eeitem.hxx> 39 #include <editeng/editstat.hxx> 40 #include <editeng/lrspitem.hxx> 41 #include <svx/svdotext.hxx> 42 #include <sfx2/printer.hxx> 43 #include <sfx2/imagemgr.hxx> 44 #include <sfx2/app.hxx> 45 #include <sfx2/bindings.hxx> 46 #include <svl/itempool.hxx> 47 #include <svl/style.hxx> 48 #include <svx/svdorect.hxx> 49 #include <svx/svdundo.hxx> 50 #include <svl/brdcst.hxx> 51 #include <vcl/msgbox.hxx> 52 #include <editeng/adjitem.hxx> 53 #include <editeng/tstpitem.hxx> 54 #include <editeng/lspcitem.hxx> 55 #include <editeng/numitem.hxx> 56 #include <editeng/outlobj.hxx> 57 #include <editeng/numitem.hxx> 58 #include <editeng/editeng.hxx> 59 60 // #97766# 61 #include <editeng/editobj.hxx> 62 #include <editeng/editund2.hxx> 63 64 #include <editeng/editview.hxx> 65 #include <editeng/svxfont.hxx> 66 #include <editeng/fhgtitem.hxx> 67 68 #include "DrawDocShell.hxx" 69 #include "drawdoc.hxx" 70 #include "Window.hxx" 71 #include "sdpage.hxx" 72 #include "pres.hxx" 73 #include "OutlineViewShell.hxx" 74 #include "app.hrc" 75 #include "glob.hrc" 76 #include "sdresid.hxx" 77 #include "Outliner.hxx" 78 #include "strings.hrc" 79 #include "EventMultiplexer.hxx" 80 #include "ViewShellBase.hxx" 81 #include "undo/undoobjects.hxx" 82 #include "undo/undomanager.hxx" 83 #include "stlsheet.hxx" 84 85 using ::rtl::OUString; 86 using namespace ::com::sun::star::uno; 87 using namespace ::com::sun::star::frame; 88 89 namespace sd { 90 91 // Breite: DIN A 4, zwei Raender zu je 1 cm 92 #define OUTLINE_PAPERWIDTH 19000 93 94 // beim Seitenmanipulation Fortschrittsanzeige, wenn mehr Seiten betroffen 95 // sind als: 96 #define PROCESS_WITH_PROGRESS_THRESHOLD 5 97 98 struct SdParaAndPos 99 { 100 Paragraph* pPara; 101 sal_uInt16 nPos; 102 }; 103 104 TYPEINIT1( OutlineView, ::sd::View ); 105 106 /************************************************************************* 107 |* 108 |* Konstruktor 109 |* 110 \************************************************************************/ 111 112 OutlineView::OutlineView( DrawDocShell* pDocSh, ::Window* pWindow, OutlineViewShell* pOutlineViewSh) 113 : ::sd::View(pDocSh->GetDoc(), pWindow, pOutlineViewSh) 114 , mpOutlineViewShell(pOutlineViewSh) 115 , mpOutliner( mpDoc->GetOutliner(sal_True) ) 116 , mpOldParaOrder(NULL) 117 , mpSelectedParas(NULL) 118 , mnPagesToProcess(0) 119 , mnPagesProcessed(0) 120 , mbFirstPaint(sal_True) 121 , mpProgress(NULL) 122 , mbHighContrastMode( false ) 123 , maDocColor( COL_WHITE ) 124 , mnPageNumberWidthPixel( 0 ) 125 , maLRSpaceItem( 0, 0, 2000, 0, EE_PARA_OUTLLRSPACE ) 126 { 127 sal_Bool bInitOutliner = sal_False; 128 129 if (mpOutliner->GetViewCount() == 0) 130 { 131 // Outliner initialisieren: Referenz-Device setzen 132 bInitOutliner = sal_True; 133 mpOutliner->Init( OUTLINERMODE_OUTLINEVIEW ); 134 /* 135 SfxStyleSheet* pTitleSheet = mpDoc->GetSdPage( 0, PK_STANDARD )->GetStyleSheetForPresObj( PRESOBJ_TITLE ); 136 137 if ( pTitleSheet ) 138 { 139 // set title symbol (level 0) 140 SvxNumBulletItem aNumBulletItem( (const SvxNumBulletItem&) pTitleSheet->GetItemSet().Get(EE_PARA_NUMBULLET) ); 141 SvxNumRule aNumRule(* aNumBulletItem.GetNumRule()); 142 SvxNumberFormat aFormat( aNumRule.GetLevel(0)); 143 Font aBulletFont; 144 const Font* pFont = aFormat.GetBulletFont(); 145 if ( pFont ) // if available take font size and color from style 146 aBulletFont = *pFont; 147 else 148 { 149 aBulletFont.SetColor( COL_AUTO ); 150 aBulletFont.SetHeight( 1552 ); 151 } 152 aBulletFont.SetCharSet(RTL_TEXTENCODING_MS_1252); // and replacing other values by standard 153 aBulletFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "StarSymbol" )) ); 154 aBulletFont.SetWeight(WEIGHT_NORMAL); 155 aBulletFont.SetUnderline(UNDERLINE_NONE); 156 aBulletFont.SetStrikeout(STRIKEOUT_NONE); 157 aBulletFont.SetItalic(ITALIC_NONE); 158 aBulletFont.SetOutline(sal_False); 159 aBulletFont.SetShadow(sal_False); 160 aFormat.SetBulletFont( &aBulletFont ); 161 aFormat.SetBulletChar( 0xE011 ); // StarBats: 0xF000 + 114 162 mpOutliner->OverwriteLevel0Bullet( aFormat ); 163 } 164 */ 165 mpOutliner->SetRefDevice( SD_MOD()->GetRefDevice( *pDocSh ) ); 166 sal_uLong nWidth = OUTLINE_PAPERWIDTH; 167 mpOutliner->SetPaperSize(Size(nWidth, 400000000)); 168 } 169 170 // View in Outliner einfuegen 171 for (sal_uInt16 nView = 0; nView < MAX_OUTLINERVIEWS; nView++) 172 { 173 mpOutlinerView[nView] = NULL; 174 } 175 176 mpOutlinerView[0] = new OutlinerView(mpOutliner, pWindow); 177 Rectangle aNullRect; 178 mpOutlinerView[0]->SetOutputArea(aNullRect); 179 mpOutliner->SetUpdateMode(sal_False); 180 mpOutliner->InsertView(mpOutlinerView[0], LIST_APPEND); 181 182 onUpdateStyleSettings( true ); 183 184 if (bInitOutliner) 185 { 186 // Outliner mit Inhalt fuellen 187 FillOutliner(); 188 } 189 190 Link aLink( LINK(this,OutlineView,EventMultiplexerListener) ); 191 mpOutlineViewShell->GetViewShellBase().GetEventMultiplexer()->AddEventListener( 192 aLink, 193 tools::EventMultiplexerEvent::EID_CURRENT_PAGE 194 | tools::EventMultiplexerEvent::EID_PAGE_ORDER); 195 196 LanguageType eLang = mpOutliner->GetDefaultLanguage(); 197 maPageNumberFont = OutputDevice::GetDefaultFont( DEFAULTFONT_SANS_UNICODE, eLang, 0 ); 198 maPageNumberFont.SetHeight( 500 ); 199 200 maBulletFont.SetColor( COL_AUTO ); 201 maBulletFont.SetHeight( 1000 ); 202 maBulletFont.SetCharSet(RTL_TEXTENCODING_MS_1252); // and replacing other values by standard 203 maBulletFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "StarSymbol" )) ); 204 maBulletFont.SetWeight(WEIGHT_NORMAL); 205 maBulletFont.SetUnderline(UNDERLINE_NONE); 206 maBulletFont.SetStrikeout(STRIKEOUT_NONE); 207 maBulletFont.SetItalic(ITALIC_NONE); 208 maBulletFont.SetOutline(sal_False); 209 maBulletFont.SetShadow(sal_False); 210 211 212 Reference<XFrame> xFrame (mpOutlineViewShell->GetViewShellBase().GetFrame()->GetTopFrame().GetFrameInterface(), UNO_QUERY); 213 214 const OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( ".uno:ShowSlide" )); 215 maSlideImage = GetImage( xFrame, aSlotURL, true, false /* todo, hc mode */ ); 216 217 // Tell undo manager of the document about the undo manager of the 218 // outliner, so that the former can synchronize with the later. 219 sd::UndoManager* pDocUndoMgr = dynamic_cast<sd::UndoManager*>(mpDocSh->GetUndoManager()); 220 if (pDocUndoMgr != NULL) 221 pDocUndoMgr->SetLinkedUndoManager(&mpOutliner->GetUndoManager()); 222 } 223 224 /************************************************************************* 225 |* 226 |* Destruktor, Links restaurieren, Outliner leeren 227 |* 228 \************************************************************************/ 229 230 OutlineView::~OutlineView() 231 { 232 DBG_ASSERT(maDragAndDropModelGuard.get() == 0, "sd::OutlineView::~OutlineView(), prior drag operation not finished correctly!" ); 233 234 Link aLink( LINK(this,OutlineView,EventMultiplexerListener) ); 235 mpOutlineViewShell->GetViewShellBase().GetEventMultiplexer()->RemoveEventListener( aLink ); 236 DisconnectFromApplication(); 237 238 if( mpProgress ) 239 delete mpProgress; 240 241 // OutlinerViews abmelden und zerstoeren 242 for (sal_uInt16 nView = 0; nView < MAX_OUTLINERVIEWS; nView++) 243 { 244 if (mpOutlinerView[nView] != NULL) 245 { 246 mpOutliner->RemoveView( mpOutlinerView[nView] ); 247 delete mpOutlinerView[nView]; 248 mpOutlinerView[nView] = NULL; 249 } 250 } 251 252 if (mpOutliner->GetViewCount() == 0) 253 { 254 // Outliner deinitialisieren: Farbdarstellung einschalten 255 ResetLinks(); 256 sal_uLong nCntrl = mpOutliner->GetControlWord(); 257 mpOutliner->SetUpdateMode(sal_False); // sonst wird bei SetControlWord gezeichnet 258 mpOutliner->SetControlWord(nCntrl & ~EE_CNTRL_NOCOLORS); 259 SvtAccessibilityOptions aOptions; 260 mpOutliner->ForceAutoColor( aOptions.GetIsAutomaticFontColor() ); 261 mpOutliner->Clear(); 262 } 263 264 DBG_ASSERT(!mpSelectedParas, "Absatzliste nicht geloescht"); 265 DBG_ASSERT(!mpOldParaOrder, "Absatzliste nicht geloescht"); 266 } 267 268 269 270 271 void OutlineView::ConnectToApplication (void) 272 { 273 mpOutlineViewShell->GetActiveWindow()->GrabFocus(); 274 Application::AddEventListener(LINK(this, OutlineView, AppEventListenerHdl)); 275 } 276 277 278 279 280 void OutlineView::DisconnectFromApplication (void) 281 { 282 Application::RemoveEventListener(LINK(this, OutlineView, AppEventListenerHdl)); 283 } 284 285 286 287 288 /************************************************************************* 289 |* 290 |* Paint-Methode 291 |* 292 \************************************************************************/ 293 294 void OutlineView::Paint(const Rectangle& rRect, ::sd::Window* pWin) 295 { 296 OutlinerView* pOlView = GetViewByWindow(pWin); 297 298 if (pOlView) 299 { 300 pOlView->HideCursor(); 301 pOlView->Paint(rRect); 302 303 pOlView->ShowCursor(mbFirstPaint); 304 305 /* 306 if( mnPageNumberWidthPixel == 0 ) 307 GetPageNumberWidthPixel(); 308 309 const sal_uLong nParaCount = pOlView->GetOutliner()->GetParagraphCount(); 310 EditView& rEditView = pOlView->GetEditView(); 311 312 Font aOldFont( pWin->GetFont() ); 313 314 const String aBulletStr( sal_Unicode( 0xE011 ) ); 315 pWin->SetFont( maBulletFont); 316 sal_Int32 nBulletWidth = pWin->GetTextWidth(aBulletStr); 317 318 sal_Int32 nPage = 1; 319 for( sal_uLong nPara = 0; nPara < nParaCount; nPara++ ) 320 { 321 Paragraph* pPara = pOlView->GetOutliner()->GetParagraph( nPara ); 322 if( pPara->HasFlag( PARAFLAG_ISPAGE ) ) 323 { 324 pWin->SetFont( maPageNumberFont ); 325 const String aStr( String::CreateFromInt32( nPage++ ) ); 326 Point aPos( rEditView.GetWindowPosTopLeft( (sal_uInt16)nPara ) ); 327 328 sal_Int32 nNumberOffset = pWin->PixelToLogic( Point(mnPageNumberWidthPixel, 0) ).X() - nBulletWidth; 329 sal_Int32 nLineHeight = pOlView->GetOutliner()->GetLineHeight( nPara, 0 ); 330 331 aPos.X() = nNumberOffset; 332 333 Point aPoint( aPos.X() - pWin->GetTextWidth( aStr ), aPos.Y() + ( nLineHeight - maPageNumberFont.GetHeight()) / 2 ); 334 pWin->DrawText( aPoint, aStr ); 335 336 aPoint.X() = aPos.X(); 337 aPoint.Y() = aPos.Y() +( nLineHeight - maBulletFont.GetHeight()) / 2; 338 pWin->SetFont( maBulletFont ); 339 pWin->DrawText( aPoint, aBulletStr ); 340 } 341 } 342 343 pWin->SetFont( aOldFont ); 344 */ 345 mbFirstPaint = sal_False; 346 } 347 } 348 349 void OutlineView::InvalidateSlideNumberArea() 350 { 351 /* 352 for( sal_Int16 nView = 0; nView < MAX_OUTLINERVIEWS; ++nView ) 353 { 354 if (mpOutlinerView[nView] != NULL) 355 { 356 ::Window* pWindow = mpOutlinerView[nView]->GetWindow(); 357 if( pWindow ) 358 { 359 Rectangle aRect( Point(0,0), pWindow->GetOutputSize() ); 360 aRect.nRight = aRect.nLeft + pWindow->PixelToLogic( Point( mnPageNumberWidthPixel, 0 ) ).X() * 2; 361 362 pWindow->Invalidate(aRect); 363 } 364 } 365 } 366 */ 367 } 368 369 /************************************************************************* 370 |* 371 |* Fenster-Groesse hat sich geaendert 372 |* 373 \************************************************************************/ 374 375 void OutlineView::AdjustPosSizePixel(const Point &,const Size &,::sd::Window*) 376 { 377 } 378 379 /************************************************************************* 380 |* 381 |* ein Fenster hinzufuegen 382 |* 383 \************************************************************************/ 384 385 void OutlineView::AddWindowToPaintView(OutputDevice* pWin) 386 { 387 sal_Bool bAdded = sal_False; 388 sal_Bool bValidArea = sal_False; 389 Rectangle aOutputArea; 390 const Color aWhiteColor( COL_WHITE ); 391 sal_uInt16 nView = 0; 392 393 while (nView < MAX_OUTLINERVIEWS && !bAdded) 394 { 395 if (mpOutlinerView[nView] == NULL) 396 { 397 mpOutlinerView[nView] = new OutlinerView(mpOutliner, dynamic_cast< ::sd::Window* >(pWin)); 398 mpOutlinerView[nView]->SetBackgroundColor( aWhiteColor ); 399 mpOutliner->InsertView(mpOutlinerView[nView], LIST_APPEND); 400 bAdded = sal_True; 401 402 if (bValidArea) 403 { 404 mpOutlinerView[nView]->SetOutputArea(aOutputArea); 405 } 406 } 407 else if (!bValidArea) 408 { 409 aOutputArea = mpOutlinerView[nView]->GetOutputArea(); 410 bValidArea = sal_True; 411 } 412 413 nView++; 414 } 415 416 // weisser Hintergrund im Outliner 417 pWin->SetBackground( Wallpaper( aWhiteColor ) ); 418 419 ::sd::View::AddWindowToPaintView(pWin); 420 } 421 422 /************************************************************************* 423 |* 424 |* ein Fenster entfernen 425 |* 426 \************************************************************************/ 427 428 void OutlineView::DeleteWindowFromPaintView(OutputDevice* pWin) 429 { 430 sal_Bool bRemoved = sal_False; 431 sal_uInt16 nView = 0; 432 ::Window* pWindow; 433 434 while (nView < MAX_OUTLINERVIEWS && !bRemoved) 435 { 436 if (mpOutlinerView[nView] != NULL) 437 { 438 pWindow = mpOutlinerView[nView]->GetWindow(); 439 440 if (pWindow == pWin) 441 { 442 mpOutliner->RemoveView( mpOutlinerView[nView] ); 443 delete mpOutlinerView[nView]; 444 mpOutlinerView[nView] = NULL; 445 bRemoved = sal_True; 446 } 447 } 448 449 nView++; 450 } 451 452 ::sd::View::DeleteWindowFromPaintView(pWin); 453 } 454 455 /************************************************************************* 456 |* 457 |* Zeiger der dem Fenster entsprechenden OutlinerView zurueckgeben. 458 |* 459 \************************************************************************/ 460 461 OutlinerView* OutlineView::GetViewByWindow (::Window* pWin) const 462 { 463 OutlinerView* pOlView = NULL; 464 for (sal_uInt16 nView = 0; nView < MAX_OUTLINERVIEWS; nView++) 465 { 466 if (mpOutlinerView[nView] != NULL) 467 { 468 if ( pWin == mpOutlinerView[nView]->GetWindow() ) 469 { 470 pOlView = mpOutlinerView[nView]; 471 } 472 } 473 } 474 return (pOlView); 475 } 476 477 478 /************************************************************************* 479 |* 480 |* Ermittelt den Titel vor einem beliebigen Absatz. 481 |* 482 \************************************************************************/ 483 484 Paragraph* OutlineView::GetPrevTitle(const Paragraph* pPara) 485 { 486 sal_Int32 nPos = mpOutliner->GetAbsPos(const_cast<Paragraph*>(pPara)); 487 488 if (nPos > 0) 489 { 490 while(nPos) 491 { 492 pPara = mpOutliner->GetParagraph(--nPos); 493 if( mpOutliner->HasParaFlag(pPara, PARAFLAG_ISPAGE) ) 494 { 495 return const_cast< Paragraph* >( pPara ); 496 } 497 } 498 499 } 500 return NULL; 501 } 502 503 /************************************************************************* 504 |* 505 |* Ermittelt den Titel nach einem beliebigen Absatz. 506 |* 507 \************************************************************************/ 508 509 Paragraph* OutlineView::GetNextTitle(const Paragraph* pPara) 510 { 511 Paragraph* pResult = const_cast< Paragraph* >( pPara ); 512 513 sal_Int32 nPos = mpOutliner->GetAbsPos(pResult); 514 515 do 516 { 517 pResult = mpOutliner->GetParagraph(++nPos); 518 if( pResult && mpOutliner->HasParaFlag(pResult, PARAFLAG_ISPAGE) ) 519 return pResult; 520 } 521 while( pResult ); 522 523 return NULL; 524 } 525 526 /************************************************************************* 527 |* 528 |* Handler fuer das Einfuegen von Seiten (Absaetzen) 529 |* 530 \************************************************************************/ 531 532 IMPL_LINK( OutlineView, ParagraphInsertedHdl, ::Outliner *, pOutliner ) 533 { 534 // DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::ParagraphInsertedHdl(), model change without undo?!" ); 535 536 // we get calls to this handler during binary insert of drag and drop contents but 537 // we ignore it here and handle it later in OnEndPasteOrDrop() 538 if( maDragAndDropModelGuard.get() == 0 ) 539 { 540 OutlineViewPageChangesGuard aGuard(this); 541 542 Paragraph* pPara = pOutliner->GetHdlParagraph(); 543 544 sal_uInt16 nAbsPos = (sal_uInt16)mpOutliner->GetAbsPos( pPara ); 545 546 UpdateParagraph( nAbsPos ); 547 548 if( (nAbsPos == 0) || mpOutliner->HasParaFlag(pPara,PARAFLAG_ISPAGE) || mpOutliner->HasParaFlag(mpOutliner->GetParagraph( nAbsPos-1 ), PARAFLAG_ISPAGE) ) 549 { 550 InsertSlideForParagraph( pPara ); 551 InvalidateSlideNumberArea(); 552 } 553 } 554 555 return 0; 556 } 557 558 /** creates and inserts an empty slide for the given paragraph */ 559 SdPage* OutlineView::InsertSlideForParagraph( Paragraph* pPara ) 560 { 561 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::InsertSlideForParagraph(), model change without undo?!" ); 562 563 OutlineViewPageChangesGuard aGuard(this); 564 565 mpOutliner->SetParaFlag( pPara, PARAFLAG_ISPAGE ); 566 // wieviele Titel sind vor dem neuen Titelabsatz? 567 sal_uLong nExample = 0L; // Position der "Vorbild"seite 568 sal_uLong nTarget = 0L; // Einfuegeposition 569 while(pPara) 570 { 571 pPara = GetPrevTitle(pPara); 572 if (pPara) 573 nTarget++; 574 } 575 576 577 // was der Outliner nicht kann, muss hier wieder wettgemacht werden: 578 // wenn VOR dem ersten Absatz ein neuer Absatz mit RETURN erzeugt wird, 579 // meldet der Outliner den bereits bestehenden (jetzt nach unten 580 // gerutschten) Absatz als neuen Absatz; nicht darauf reinfallen! 581 if (nTarget == 1) 582 { 583 String aTest(mpOutliner->GetText( mpOutliner->GetParagraph( 0 ) )); 584 if (aTest.Len() == 0) 585 { 586 nTarget = 0; 587 } 588 } 589 590 591 // "Vorbild"seite ist - wenn vorhanden - die Vorgaengerseite 592 if (nTarget > 0) 593 { 594 nExample = nTarget - 1; 595 596 sal_uInt16 nPageCount = mpDoc->GetSdPageCount( PK_STANDARD ); 597 if( nExample >= nPageCount ) 598 nExample = nPageCount - 1; 599 } 600 601 /********************************************************************** 602 * Es wird stets zuerst eine Standardseite und dann eine 603 * Notizseite erzeugt. Es ist sichergestellt, dass auf eine 604 * Standardseite stets die zugehoerige Notizseite folgt. 605 * Vorangestellt ist genau eine Handzettelseite 606 **********************************************************************/ 607 608 // diese Seite hat Vorbildfunktion 609 SdPage* pExample = (SdPage*)mpDoc->GetSdPage((sal_uInt16)nExample, PK_STANDARD); 610 SdPage* pPage = (SdPage*)mpDoc->AllocPage(sal_False); 611 612 pPage->SetLayoutName(pExample->GetLayoutName()); 613 614 // einfuegen (Seite) 615 mpDoc->InsertPage(pPage, (sal_uInt16)(nTarget) * 2 + 1); 616 if( isRecordingUndo() ) 617 AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoNewPage(*pPage)); 618 619 // der Standardseite eine Masterpage zuweisen 620 pPage->TRG_SetMasterPage(pExample->TRG_GetMasterPage()); 621 622 // Seitengroesse setzen 623 pPage->SetSize(pExample->GetSize()); 624 pPage->SetBorder( pExample->GetLftBorder(), 625 pExample->GetUppBorder(), 626 pExample->GetRgtBorder(), 627 pExample->GetLwrBorder() ); 628 629 // neue Praesentationsobjekte anlegen (auf <Titel> oder 630 // <Titel mit Untertitel> folgt <Titel mit Gliederung>, ansonsten 631 // wird das Layout von der Vorgaengerseite uebernommen) 632 AutoLayout eAutoLayout = pExample->GetAutoLayout(); 633 if (eAutoLayout == AUTOLAYOUT_TITLE || 634 eAutoLayout == AUTOLAYOUT_ONLY_TITLE) 635 { 636 pPage->SetAutoLayout(AUTOLAYOUT_ENUM, sal_True); 637 } 638 else 639 { 640 pPage->SetAutoLayout(pExample->GetAutoLayout(), sal_True); 641 } 642 643 /********************************************************************** 644 |* jetzt die Notizseite 645 \*********************************************************************/ 646 pExample = (SdPage*)mpDoc->GetSdPage((sal_uInt16)nExample, PK_NOTES); 647 SdPage* pNotesPage = (SdPage*)mpDoc->AllocPage(sal_False); 648 649 pNotesPage->SetLayoutName(pExample->GetLayoutName()); 650 651 pNotesPage->SetPageKind(PK_NOTES); 652 653 // einfuegen (Notizseite) 654 mpDoc->InsertPage(pNotesPage, (sal_uInt16)(nTarget) * 2 + 2); 655 if( isRecordingUndo() ) 656 AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoNewPage(*pNotesPage)); 657 658 // der Notizseite eine Masterpage zuweisen 659 pNotesPage->TRG_SetMasterPage(pExample->TRG_GetMasterPage()); 660 661 // Seitengroesse setzen, es muss bereits eine Seite vorhanden sein 662 pNotesPage->SetSize(pExample->GetSize()); 663 pNotesPage->SetBorder( pExample->GetLftBorder(), 664 pExample->GetUppBorder(), 665 pExample->GetRgtBorder(), 666 pExample->GetLwrBorder() ); 667 668 // neue Praesentationsobjekte anlegen 669 pNotesPage->SetAutoLayout(pExample->GetAutoLayout(), sal_True); 670 671 mpOutliner->UpdateFields(); 672 673 return pPage; 674 } 675 676 /************************************************************************* 677 |* 678 |* Handler fuer das Loeschen von Seiten (Absaetzen) 679 |* 680 \************************************************************************/ 681 682 IMPL_LINK( OutlineView, ParagraphRemovingHdl, ::Outliner *, pOutliner ) 683 { 684 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::ParagraphRemovingHdl(), model change without undo?!" ); 685 686 OutlineViewPageChangesGuard aGuard(this); 687 688 Paragraph* pPara = pOutliner->GetHdlParagraph(); 689 if( pOutliner->HasParaFlag( pPara, PARAFLAG_ISPAGE ) ) 690 { 691 // wieviele Titel sind vor dem fraglichen Titelabsatz? 692 sal_uLong nPos = 0L; 693 while(pPara) 694 { 695 pPara = GetPrevTitle(pPara); 696 if (pPara) nPos++; 697 } 698 699 // Seite und Notizseite loeschen 700 sal_uInt16 nAbsPos = (sal_uInt16)nPos * 2 + 1; 701 SdrPage* pPage = mpDoc->GetPage(nAbsPos); 702 if( isRecordingUndo() ) 703 AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoDeletePage(*pPage)); 704 mpDoc->RemovePage(nAbsPos); 705 706 nAbsPos = (sal_uInt16)nPos * 2 + 1; 707 pPage = mpDoc->GetPage(nAbsPos); 708 if( isRecordingUndo() ) 709 AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoDeletePage(*pPage)); 710 mpDoc->RemovePage(nAbsPos); 711 712 // ggfs. Fortschrittsanzeige 713 if (mnPagesToProcess) 714 { 715 mnPagesProcessed++; 716 717 if(mpProgress) 718 mpProgress->SetState(mnPagesProcessed); 719 720 if (mnPagesProcessed == mnPagesToProcess) 721 { 722 if(mpProgress) 723 { 724 delete mpProgress; 725 mpProgress = NULL; 726 } 727 mnPagesToProcess = 0; 728 mnPagesProcessed = 0; 729 } 730 } 731 pOutliner->UpdateFields(); 732 } 733 734 InvalidateSlideNumberArea(); 735 736 return 0; 737 } 738 739 /************************************************************************* 740 |* 741 |* Handler fuer das Aendern der Einruecktiefe von Absaetzen (macht ggfs. 742 |* das Einfuegen oder Loeschen von Seiten notwendig) 743 |* 744 \************************************************************************/ 745 746 IMPL_LINK( OutlineView, DepthChangedHdl, ::Outliner *, pOutliner ) 747 { 748 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::DepthChangedHdl(), no undo for model change?!" ); 749 750 OutlineViewPageChangesGuard aGuard(this); 751 752 Paragraph* pPara = pOutliner->GetHdlParagraph(); 753 if( pOutliner->HasParaFlag( pPara, PARAFLAG_ISPAGE ) && ((pOutliner->GetPrevFlags() & PARAFLAG_ISPAGE) == 0) ) 754 { 755 // the current paragraph is transformed into a slide 756 757 mpOutliner->SetDepth( pPara, -1 ); 758 759 // werden da etwa mehrere Level-1-Absaetze auf Level 0 gebracht und 760 // wir sollten eine Fortschrittsanzeige oder Eieruhr aufsetzen und 761 // haben es noch nicht getan? 762 if (mnPagesToProcess == 0) 763 { 764 Window* pActWin = mpOutlineViewShell->GetActiveWindow(); 765 OutlinerView* pOlView = GetViewByWindow(pActWin); 766 List* pList = pOlView->CreateSelectionList(); 767 768 Paragraph* pParagraph = (Paragraph*)pList->First(); 769 while (pParagraph) 770 { 771 if( !pOutliner->HasParaFlag( pParagraph, PARAFLAG_ISPAGE ) && (pOutliner->GetDepth( (sal_uInt16) pOutliner->GetAbsPos( pParagraph ) ) <= 0) ) 772 mnPagesToProcess++; 773 pParagraph = (Paragraph*)pList->Next(); 774 } 775 776 mnPagesToProcess++; // der Absatz, der jetzt schon auf Level 0 777 // steht, gehoert auch dazu 778 mnPagesProcessed = 0; 779 780 if (mnPagesToProcess > PROCESS_WITH_PROGRESS_THRESHOLD) 781 { 782 if( mpProgress ) 783 delete mpProgress; 784 785 const String aStr(SdResId(STR_CREATE_PAGES)); 786 mpProgress = new SfxProgress( GetDocSh(), aStr, mnPagesToProcess ); 787 } 788 else 789 { 790 mpDocSh->SetWaitCursor( sal_True ); 791 } 792 delete pList; 793 } 794 795 ParagraphInsertedHdl(pOutliner); 796 797 mnPagesProcessed++; 798 799 // muss eine Fortschrittsanzeige gepflegt werden? 800 if (mnPagesToProcess > PROCESS_WITH_PROGRESS_THRESHOLD) 801 { 802 if (mpProgress) 803 mpProgress->SetState(mnPagesProcessed); 804 } 805 806 // war das die letzte Seite? 807 if (mnPagesProcessed == mnPagesToProcess) 808 { 809 if (mnPagesToProcess > PROCESS_WITH_PROGRESS_THRESHOLD && mpProgress) 810 { 811 delete mpProgress; 812 mpProgress = NULL; 813 } 814 else 815 mpDocSh->SetWaitCursor( sal_False ); 816 817 mnPagesToProcess = 0; 818 mnPagesProcessed = 0; 819 } 820 pOutliner->UpdateFields(); 821 } 822 else if( !pOutliner->HasParaFlag( pPara, PARAFLAG_ISPAGE ) && ((pOutliner->GetPrevFlags() & PARAFLAG_ISPAGE) != 0) ) 823 { 824 // the paragraph was a page but now becomes a normal paragraph 825 826 // how many titles are before the title paragraph in question? 827 sal_uLong nPos = 0L; 828 Paragraph* pParagraph = pPara; 829 while(pParagraph) 830 { 831 pParagraph = GetPrevTitle(pParagraph); 832 if (pParagraph) 833 nPos++; 834 } 835 // Seite und Notizseite loeschen 836 837 sal_uInt16 nAbsPos = (sal_uInt16)nPos * 2 + 1; 838 SdrPage* pPage = mpDoc->GetPage(nAbsPos); 839 if( isRecordingUndo() ) 840 AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoDeletePage(*pPage)); 841 mpDoc->RemovePage(nAbsPos); 842 843 nAbsPos = (sal_uInt16)nPos * 2 + 1; 844 pPage = mpDoc->GetPage(nAbsPos); 845 if( isRecordingUndo() ) 846 AddUndo(mpDoc->GetSdrUndoFactory().CreateUndoDeletePage(*pPage)); 847 mpDoc->RemovePage(nAbsPos); 848 849 pPage = GetPageForParagraph( pPara ); 850 851 mpOutliner->SetDepth( pPara, (pPage && (static_cast<SdPage*>(pPage)->GetAutoLayout() == AUTOLAYOUT_TITLE)) ? -1 : 0 ); 852 853 // ggfs. Fortschrittsanzeige 854 if (mnPagesToProcess) 855 { 856 mnPagesProcessed++; 857 if (mpProgress) 858 mpProgress->SetState(mnPagesProcessed); 859 860 if (mnPagesProcessed == mnPagesToProcess) 861 { 862 if(mpProgress) 863 { 864 delete mpProgress; 865 mpProgress = NULL; 866 } 867 mnPagesToProcess = 0; 868 mnPagesProcessed = 0; 869 } 870 } 871 pOutliner->UpdateFields(); 872 } 873 else if ( (pOutliner->GetPrevDepth() == 1) && ( pOutliner->GetDepth( (sal_uInt16) pOutliner->GetAbsPos( pPara ) ) == 2 ) ) 874 { 875 // wieviele Titel sind vor dem fraglichen Titelabsatz? 876 sal_Int32 nPos = -1L; 877 878 Paragraph* pParagraph = pPara; 879 while(pParagraph) 880 { 881 pParagraph = GetPrevTitle(pParagraph); 882 if (pParagraph) 883 nPos++; 884 } 885 886 if(nPos >= 0) 887 { 888 SdPage*pPage = (SdPage*)mpDoc->GetSdPage( (sal_uInt16) nPos, PK_STANDARD); 889 890 if(pPage && pPage->GetPresObj(PRESOBJ_TEXT)) 891 pOutliner->SetDepth( pPara, 0 ); 892 } 893 894 } 895 // wieviele Titel sind vor dem fraglichen Titelabsatz? 896 sal_Int32 nPos = -1L; 897 898 Paragraph* pTempPara = pPara; 899 while(pTempPara) 900 { 901 pTempPara = GetPrevTitle(pTempPara); 902 if (pTempPara) 903 nPos++; 904 } 905 906 if( nPos >= 0 ) 907 { 908 SdPage* pPage = (SdPage*) mpDoc->GetSdPage( (sal_uInt16) nPos, PK_STANDARD ); 909 910 if( pPage ) 911 { 912 SfxStyleSheet* pStyleSheet = NULL; 913 sal_uLong nPara = pOutliner->GetAbsPos( pPara ); 914 sal_Int16 nDepth = pOutliner->GetDepth( (sal_uInt16) nPara ); 915 bool bSubTitle = pPage->GetPresObj(PRESOBJ_TEXT) != NULL; 916 917 if( pOutliner->HasParaFlag(pPara, PARAFLAG_ISPAGE) ) 918 { 919 pStyleSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ); 920 } 921 else if( bSubTitle ) 922 { 923 pStyleSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_TEXT ); 924 } 925 else 926 { 927 pStyleSheet = pPage->GetStyleSheetForPresObj( PRESOBJ_OUTLINE ); 928 929 if( nDepth > 0 ) 930 { 931 String aNewStyleSheetName( pStyleSheet->GetName() ); 932 aNewStyleSheetName.Erase( aNewStyleSheetName.Len()-1, 1 ); 933 aNewStyleSheetName += String::CreateFromInt32( nDepth+1 ); 934 SfxStyleSheetBasePool* pStylePool = mpDoc->GetStyleSheetPool(); 935 pStyleSheet = (SfxStyleSheet*) pStylePool->Find( aNewStyleSheetName, pStyleSheet->GetFamily() ); 936 } 937 } 938 939 // before we set the style sheet we need to preserve the bullet item 940 // since all items will be deleted while setting a new style sheet 941 SfxItemSet aOldAttrs( pOutliner->GetParaAttribs( (sal_uInt16)nPara ) ); 942 943 pOutliner->SetStyleSheet( nPara, pStyleSheet ); 944 945 // restore the old bullet item but not if the style changed 946 if ( pOutliner->GetPrevDepth() != -1 && nDepth != -1 && 947 aOldAttrs.GetItemState( EE_PARA_NUMBULLET ) == SFX_ITEM_ON ) 948 { 949 SfxItemSet aAttrs( pOutliner->GetParaAttribs( (sal_uInt16)nPara ) ); 950 aAttrs.Put( *aOldAttrs.GetItem( EE_PARA_NUMBULLET ) ); 951 pOutliner->SetParaAttribs( (sal_uInt16)nPara, aAttrs ); 952 } 953 } 954 } 955 956 InvalidateSlideNumberArea(); 957 958 return 0; 959 } 960 961 /************************************************************************* 962 |* 963 |* Handler fuer StatusEvents 964 |* 965 \************************************************************************/ 966 967 IMPL_LINK( OutlineView, StatusEventHdl, EditStatus *, EMPTYARG ) 968 { 969 ::sd::Window* pWin = mpOutlineViewShell->GetActiveWindow(); 970 OutlinerView* pOutlinerView = GetViewByWindow(pWin); 971 Rectangle aVis = pOutlinerView->GetVisArea(); 972 973 // sal_uLong nWidth = ((SdPage*)mpDoc->GetSdPage(0, PK_STANDARD))->GetSize().Width(); 974 sal_uLong nWidth = OUTLINE_PAPERWIDTH; 975 Rectangle aText = Rectangle(Point(0,0), 976 Size(nWidth, 977 mpOutliner->GetTextHeight())); 978 Rectangle aWin(Point(0,0), pWin->GetOutputSizePixel()); 979 aWin = pWin->PixelToLogic(aWin); 980 981 if (!aVis.IsEmpty()) // nicht beim Oeffnen 982 { 983 aText.Bottom() += aWin.GetHeight(); 984 985 mpOutlineViewShell->InitWindows(Point(0,0), aText.GetSize(), 986 Point(aVis.TopLeft())); 987 mpOutlineViewShell->UpdateScrollBars(); 988 } 989 990 InvalidateSlideNumberArea(); 991 return 0; 992 } 993 994 IMPL_LINK( OutlineView, BeginDropHdl, void *, EMPTYARG ) 995 { 996 DBG_ASSERT(maDragAndDropModelGuard.get() == 0, "sd::OutlineView::BeginDropHdl(), prior drag operation not finished correctly!" ); 997 998 maDragAndDropModelGuard.reset( new OutlineViewModelChangeGuard( *this ) ); 999 return 0; 1000 } 1001 1002 IMPL_LINK( OutlineView, EndDropHdl, void *, EMPTYARG ) 1003 { 1004 maDragAndDropModelGuard.reset(0); 1005 InvalidateSlideNumberArea(); 1006 return 0; 1007 } 1008 1009 /************************************************************************* 1010 |* 1011 |* Handler fuer den Beginn einer Absatzverschiebung 1012 |* 1013 \************************************************************************/ 1014 1015 IMPL_LINK( OutlineView, BeginMovingHdl, ::Outliner *, pOutliner ) 1016 { 1017 DBG_ASSERT(!mpSelectedParas, "Absatzliste nicht geloescht"); 1018 DBG_ASSERT(!mpOldParaOrder, "Absatzliste nicht geloescht"); 1019 1020 OutlineViewPageChangesGuard aGuard(this); 1021 1022 mpOldParaOrder = new List; 1023 1024 // Liste der selektierten Titelabsaetze 1025 mpSelectedParas = mpOutlinerView[0]->CreateSelectionList(); 1026 Paragraph* pPara = static_cast<Paragraph*>(mpSelectedParas->First()); 1027 while (pPara) 1028 { 1029 if( !pOutliner->HasParaFlag(pPara, PARAFLAG_ISPAGE) ) 1030 { 1031 mpSelectedParas->Remove(); 1032 pPara = static_cast<Paragraph*>(mpSelectedParas->GetCurObject()); 1033 } 1034 else 1035 { 1036 pPara = static_cast<Paragraph*>(mpSelectedParas->Next()); 1037 } 1038 } 1039 1040 // Die zu den selektierten Absaetzen auf Ebene 0 gehoerenden Seiten 1041 // selektieren 1042 sal_uInt16 nPos = 0; 1043 sal_uLong nParaPos = 0; 1044 pPara = pOutliner->GetParagraph( 0 ); 1045 1046 while(pPara) 1047 { 1048 if( pOutliner->HasParaFlag(pPara, PARAFLAG_ISPAGE) ) // eine Seite? 1049 { 1050 mpOldParaOrder->Insert(pPara, LIST_APPEND); 1051 SdPage* pPage = mpDoc->GetSdPage(nPos, PK_STANDARD); 1052 pPage->SetSelected(sal_False); 1053 if (mpSelectedParas->Seek(pPara)) // selektiert? 1054 { 1055 pPage->SetSelected(sal_True); 1056 } 1057 nPos++; 1058 } 1059 pPara = pOutliner->GetParagraph( ++nParaPos ); 1060 } 1061 1062 return 0; 1063 } 1064 1065 /************************************************************************* 1066 |* 1067 |* Handler fuer das Ende einer Absatzverschiebung 1068 |* 1069 \************************************************************************/ 1070 1071 IMPL_LINK( OutlineView, EndMovingHdl, ::Outliner *, pOutliner ) 1072 { 1073 OutlineViewPageChangesGuard aGuard(this); 1074 1075 DBG_ASSERT(mpSelectedParas, "keine Absatzliste"); 1076 DBG_ASSERT(mpOldParaOrder, "keine Absatzliste"); 1077 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::EndMovingHdl(), model change without undo?!" ); 1078 1079 // Einfuegeposition anhand des ersten Absatzes suchen 1080 Paragraph* pSearchIt = (Paragraph*)mpSelectedParas->First(); 1081 1082 // den ersten der selektierten Paragraphen in der neuen Ordnung suchen 1083 sal_uInt16 nPosNewOrder = 0; 1084 sal_uLong nParaPos = 0; 1085 Paragraph* pPara = pOutliner->GetParagraph( 0 ); 1086 Paragraph* pPrev = NULL; 1087 while (pPara && pPara != pSearchIt) 1088 { 1089 if( pOutliner->HasParaFlag(pPara, PARAFLAG_ISPAGE) ) 1090 { 1091 nPosNewOrder++; 1092 pPrev = pPara; 1093 } 1094 pPara = pOutliner->GetParagraph( ++nParaPos ); 1095 } 1096 1097 sal_uInt16 nPos = nPosNewOrder; // nPosNewOrder nicht veraendern 1098 if (nPos == 0) 1099 { 1100 nPos = (sal_uInt16)-1; // vor der ersten Seite einfuegen 1101 } 1102 else 1103 { 1104 // den Vorgaenger in der alten Ordnung suchen 1105 nPos = (sal_uInt16)mpOldParaOrder->GetPos(pPrev); 1106 DBG_ASSERT(nPos != 0xffff, "Absatz nicht gefunden"); 1107 } 1108 1109 mpDoc->MovePages(nPos); 1110 1111 // die Seiten wieder deselektieren 1112 sal_uInt16 nPageCount = (sal_uInt16)mpSelectedParas->Count(); 1113 while (nPageCount) 1114 { 1115 SdPage* pPage = mpDoc->GetSdPage(nPosNewOrder, PK_STANDARD); 1116 pPage->SetSelected(sal_False); 1117 nPosNewOrder++; 1118 nPageCount--; 1119 } 1120 1121 pOutliner->UpdateFields(); 1122 1123 delete mpSelectedParas; 1124 mpSelectedParas = NULL; 1125 delete mpOldParaOrder; 1126 mpOldParaOrder = NULL; 1127 1128 InvalidateSlideNumberArea(); 1129 1130 return 0; 1131 } 1132 1133 /************************************************************************* 1134 |* 1135 |* Eine Seite des Models nach dem Titeltextobjekt durchsuchen 1136 |* 1137 \************************************************************************/ 1138 1139 SdrTextObj* OutlineView::GetTitleTextObject(SdrPage* pPage) 1140 { 1141 sal_uLong nObjectCount = pPage->GetObjCount(); 1142 SdrObject* pObject = NULL; 1143 SdrTextObj* pResult = NULL; 1144 1145 for (sal_uLong nObject = 0; nObject < nObjectCount; nObject++) 1146 { 1147 pObject = pPage->GetObj(nObject); 1148 if (pObject->GetObjInventor() == SdrInventor && 1149 pObject->GetObjIdentifier() == OBJ_TITLETEXT) 1150 { 1151 pResult = (SdrTextObj*)pObject; 1152 break; 1153 } 1154 } 1155 return pResult; 1156 } 1157 1158 1159 /************************************************************************* 1160 |* 1161 |* Eine Seite des Models nach dem Gliederungstextobjekt durchsuchen 1162 |* 1163 \************************************************************************/ 1164 1165 SdrTextObj* OutlineView::GetOutlineTextObject(SdrPage* pPage) 1166 { 1167 sal_uLong nObjectCount = pPage->GetObjCount(); 1168 SdrObject* pObject = NULL; 1169 SdrTextObj* pResult = NULL; 1170 1171 for (sal_uLong nObject = 0; nObject < nObjectCount; nObject++) 1172 { 1173 pObject = pPage->GetObj(nObject); 1174 if (pObject->GetObjInventor() == SdrInventor && 1175 pObject->GetObjIdentifier() == OBJ_OUTLINETEXT) 1176 { 1177 pResult = (SdrTextObj*)pObject; 1178 break; 1179 } 1180 } 1181 return pResult; 1182 } 1183 1184 SdrTextObj* OutlineView::CreateTitleTextObject(SdPage* pPage) 1185 { 1186 DBG_ASSERT( GetTitleTextObject(pPage) == 0, "sd::OutlineView::CreateTitleTextObject(), there is already a title text object!" ); 1187 1188 if( pPage->GetAutoLayout() == AUTOLAYOUT_NONE ) 1189 { 1190 // simple case 1191 pPage->SetAutoLayout( AUTOLAYOUT_ONLY_TITLE, true ); 1192 } 1193 else 1194 { 1195 // we already have a layout with a title but the title 1196 // object was deleted, create a new one 1197 pPage->InsertAutoLayoutShape( 0, PRESOBJ_TITLE, false, pPage->GetTitleRect(), true ); 1198 } 1199 1200 return GetTitleTextObject(pPage); 1201 } 1202 1203 SdrTextObj* OutlineView::CreateOutlineTextObject(SdPage* pPage) 1204 { 1205 DBG_ASSERT( GetOutlineTextObject(pPage) == 0, "sd::OutlineView::CreateOutlineTextObject(), there is already a layout text object!" ); 1206 1207 AutoLayout eNewLayout = pPage->GetAutoLayout(); 1208 switch( eNewLayout ) 1209 { 1210 case AUTOLAYOUT_NONE: 1211 case AUTOLAYOUT_ONLY_TITLE: 1212 case AUTOLAYOUT_TITLE: eNewLayout = AUTOLAYOUT_ENUM; break; 1213 1214 case AUTOLAYOUT_CHART: eNewLayout = AUTOLAYOUT_CHARTTEXT; break; 1215 1216 case AUTOLAYOUT_ORG: 1217 case AUTOLAYOUT_TAB: 1218 case AUTOLAYOUT_OBJ: eNewLayout = AUTOLAYOUT_OBJTEXT; break; 1219 default: 1220 break; 1221 } 1222 1223 if( eNewLayout != pPage->GetAutoLayout() ) 1224 { 1225 pPage->SetAutoLayout( eNewLayout, true ); 1226 } 1227 else 1228 { 1229 // we already have a layout with a text but the text 1230 // object was deleted, create a new one 1231 pPage->InsertAutoLayoutShape( 0, 1232 (eNewLayout == AUTOLAYOUT_TITLE) ? PRESOBJ_TEXT : PRESOBJ_OUTLINE, 1233 false, pPage->GetLayoutRect(), true ); 1234 } 1235 1236 return GetOutlineTextObject(pPage); 1237 } 1238 1239 /** updates draw model with all changes from outliner model */ 1240 sal_Bool OutlineView::PrepareClose(sal_Bool) 1241 { 1242 ::sd::UndoManager* pDocUndoMgr = dynamic_cast<sd::UndoManager*>(mpDocSh->GetUndoManager()); 1243 if (pDocUndoMgr != NULL) 1244 pDocUndoMgr->SetLinkedUndoManager(NULL); 1245 1246 mpOutliner->GetUndoManager().Clear(); 1247 1248 const String aUndoStr(SdResId(STR_UNDO_CHANGE_TITLE_AND_LAYOUT)); 1249 BegUndo(aUndoStr); 1250 UpdateDocument(); 1251 EndUndo(); 1252 mpDoc->SetSelected(GetActualPage(), sal_True); 1253 return sal_True; 1254 } 1255 1256 1257 /************************************************************************* 1258 |* 1259 |* Attribute des selektierten Textes setzen 1260 |* 1261 \************************************************************************/ 1262 1263 sal_Bool OutlineView::SetAttributes(const SfxItemSet& rSet, sal_Bool ) 1264 { 1265 sal_Bool bOk = sal_False; 1266 1267 OutlinerView* pOlView = GetViewByWindow(mpOutlineViewShell->GetActiveWindow()); 1268 1269 if (pOlView) 1270 { 1271 pOlView->SetAttribs(rSet); 1272 bOk = sal_True; 1273 } 1274 1275 mpOutlineViewShell->Invalidate (SID_PREVIEW_STATE); 1276 1277 return (bOk); 1278 } 1279 1280 /************************************************************************* 1281 |* 1282 |* Attribute des selektierten Textes erfragen 1283 |* 1284 \************************************************************************/ 1285 1286 sal_Bool OutlineView::GetAttributes( SfxItemSet& rTargetSet, sal_Bool ) const 1287 { 1288 OutlinerView* pOlView = GetViewByWindow( 1289 mpOutlineViewShell->GetActiveWindow()); 1290 DBG_ASSERT(pOlView, "keine OutlinerView gefunden"); 1291 1292 rTargetSet.Put( pOlView->GetAttribs(), sal_False ); 1293 return sal_True; 1294 } 1295 1296 /** creates outliner model from draw model */ 1297 void OutlineView::FillOutliner() 1298 { 1299 mpOutliner->GetUndoManager().Clear(); 1300 mpOutliner->EnableUndo(sal_False); 1301 ResetLinks(); 1302 mpOutliner->SetUpdateMode(false); 1303 1304 Paragraph* pTitleToSelect = NULL; 1305 sal_uLong nPageCount = mpDoc->GetSdPageCount(PK_STANDARD); 1306 1307 // fill outliner with paragraphs from slides title & (outlines|subtitles) 1308 for (sal_uInt16 nPage = 0; nPage < nPageCount; nPage++) 1309 { 1310 SdPage* pPage = (SdPage*)mpDoc->GetSdPage(nPage, PK_STANDARD); 1311 Paragraph * pPara = NULL; 1312 1313 // take text from title shape 1314 SdrTextObj* pTO = GetTitleTextObject(pPage); 1315 if(pTO && !(pTO->IsEmptyPresObj())) 1316 { 1317 OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject(); 1318 if (pOPO) 1319 { 1320 sal_Bool bVertical = pOPO->IsVertical(); 1321 pOPO->SetVertical( sal_False ); 1322 mpOutliner->AddText(*pOPO); 1323 pOPO->SetVertical( bVertical ); 1324 pPara = mpOutliner->GetParagraph( mpOutliner->GetParagraphCount()-1 ); 1325 } 1326 } 1327 1328 if( pPara == 0 ) // no title, insert an empty paragraph 1329 { 1330 pPara = mpOutliner->Insert(String()); 1331 mpOutliner->SetDepth(pPara, -1); 1332 1333 // Keine harten Attribute vom vorherigen Absatz uebernehmen 1334 mpOutliner->SetParaAttribs( (sal_uInt16)mpOutliner->GetAbsPos(pPara), 1335 mpOutliner->GetEmptyItemSet() ); 1336 1337 mpOutliner->SetStyleSheet( mpOutliner->GetAbsPos( pPara ), pPage->GetStyleSheetForPresObj( PRESOBJ_TITLE ) ); 1338 } 1339 1340 mpOutliner->SetParaFlag( pPara, PARAFLAG_ISPAGE ); 1341 1342 sal_uLong nPara = mpOutliner->GetAbsPos( pPara ); 1343 1344 UpdateParagraph( (sal_uInt16)nPara ); 1345 1346 // remember paragraph of currently selected page 1347 if (pPage->IsSelected()) 1348 pTitleToSelect = pPara; 1349 1350 // take text from subtitle or outline 1351 pTO = static_cast<SdrTextObj*>(pPage->GetPresObj(PRESOBJ_TEXT)); 1352 const bool bSubTitle = pTO != 0; 1353 1354 if (!pTO) // if no subtile found, try outline 1355 pTO = GetOutlineTextObject(pPage); 1356 1357 if(pTO && !(pTO->IsEmptyPresObj())) // found some text 1358 { 1359 OutlinerParaObject* pOPO = pTO->GetOutlinerParaObject(); 1360 if (pOPO) 1361 { 1362 sal_uInt16 nParaCount1 = (sal_uInt16)mpOutliner->GetParagraphCount(); 1363 sal_Bool bVertical = pOPO->IsVertical(); 1364 pOPO->SetVertical( sal_False ); 1365 mpOutliner->AddText(*pOPO); 1366 pOPO->SetVertical( bVertical ); 1367 1368 sal_uInt16 nParaCount2 = (sal_uInt16)mpOutliner->GetParagraphCount(); 1369 for (sal_uInt16 n = nParaCount1; n < nParaCount2; n++) 1370 { 1371 if( bSubTitle ) 1372 { 1373 Paragraph* p = mpOutliner->GetParagraph(n); 1374 if(p && mpOutliner->GetDepth( n ) > 0 ) 1375 mpOutliner->SetDepth(p, 0); 1376 } 1377 1378 UpdateParagraph( n ); 1379 } 1380 } 1381 } 1382 } 1383 1384 // place cursor at the start 1385 Paragraph* pFirstPara = mpOutliner->GetParagraph( 0 ); 1386 mpOutlinerView[0]->Select( pFirstPara, sal_True, sal_False ); 1387 mpOutlinerView[0]->Select( pFirstPara, sal_False, sal_False ); 1388 1389 // select title of slide that was selected 1390 if (pTitleToSelect) 1391 mpOutlinerView[0]->Select(pTitleToSelect, sal_True, sal_False); 1392 1393 SetLinks(); 1394 1395 mpOutliner->EnableUndo(sal_True); 1396 1397 mpOutliner->SetUpdateMode(true); 1398 } 1399 1400 /************************************************************************* 1401 |* 1402 |* Handler fuer das Loeschen von Level-0-Absaetzen (Seiten): Warnung 1403 |* 1404 \************************************************************************/ 1405 1406 IMPL_LINK( OutlineView, RemovingPagesHdl, OutlinerView *, EMPTYARG ) 1407 { 1408 sal_uInt16 nNumOfPages = mpOutliner->GetSelPageCount(); 1409 1410 if (nNumOfPages > PROCESS_WITH_PROGRESS_THRESHOLD) 1411 { 1412 mnPagesToProcess = nNumOfPages; 1413 mnPagesProcessed = 0; 1414 } 1415 1416 if (mnPagesToProcess) 1417 { 1418 if( mpProgress ) 1419 delete mpProgress; 1420 1421 String aStr(SdResId(STR_DELETE_PAGES)); 1422 mpProgress = new SfxProgress( GetDocSh(), aStr, mnPagesToProcess ); 1423 } 1424 mpOutliner->UpdateFields(); 1425 1426 InvalidateSlideNumberArea(); 1427 1428 return 1; 1429 } 1430 1431 /************************************************************************* 1432 |* 1433 |* Handler fuer das Einruecken von Level-0-Absaetzen (Seiten): Warnung 1434 |* 1435 \************************************************************************/ 1436 1437 IMPL_LINK_INLINE_START( OutlineView, IndentingPagesHdl, OutlinerView *, pOutlinerView ) 1438 { 1439 return RemovingPagesHdl(pOutlinerView); 1440 } 1441 IMPL_LINK_INLINE_END( OutlineView, IndentingPagesHdl, OutlinerView *, pOutlinerView ) 1442 1443 1444 /** returns the first slide that is selected in the outliner or where 1445 the cursor is located */ 1446 SdPage* OutlineView::GetActualPage() 1447 { 1448 ::sd::Window* pWin = mpOutlineViewShell->GetActiveWindow(); 1449 OutlinerView* pActiveView = GetViewByWindow(pWin); 1450 std::auto_ptr<List> pSelList( static_cast< List* >(pActiveView->CreateSelectionList()) ); 1451 1452 SdPage* pCurrent = GetPageForParagraph(static_cast<Paragraph*>(pSelList->First()) ); 1453 DBG_ASSERT( pCurrent || 1454 (mpDocSh->GetUndoManager() && static_cast< sd::UndoManager *>(mpDocSh->GetUndoManager())->IsDoing()) || 1455 maDragAndDropModelGuard.get(), 1456 "sd::OutlineView::GetActualPage(), no current page?" ); 1457 if( pCurrent ) 1458 return pCurrent; 1459 else 1460 return mpDoc->GetSdPage( 0, PK_STANDARD ); 1461 } 1462 1463 SdPage* OutlineView::GetPageForParagraph( Paragraph* pPara ) 1464 { 1465 if( !mpOutliner->HasParaFlag(pPara,PARAFLAG_ISPAGE) ) 1466 pPara = GetPrevTitle(pPara); 1467 1468 sal_uInt32 nPageToSelect = 0; 1469 while(pPara) 1470 { 1471 pPara = GetPrevTitle(pPara); 1472 if(pPara) 1473 nPageToSelect++; 1474 } 1475 1476 if( nPageToSelect < (sal_uInt32)mpDoc->GetSdPageCount( PK_STANDARD ) ) 1477 return static_cast< SdPage* >( mpDoc->GetSdPage( (sal_uInt16)nPageToSelect, PK_STANDARD) ); 1478 else 1479 return 0; 1480 } 1481 1482 Paragraph* OutlineView::GetParagraphForPage( ::Outliner* pOutl, SdPage* pPage ) 1483 { 1484 // get the number of paragraphs with ident 0 we need to skip before 1485 // we finde the actual page 1486 sal_uInt32 nPagesToSkip = (pPage->GetPageNum() - 1) >> 1; 1487 1488 sal_uInt32 nParaPos = 0; 1489 Paragraph* pPara = pOutl->GetParagraph( 0 ); 1490 while( pPara ) 1491 { 1492 // if this paragraph is a page ... 1493 if( mpOutliner->HasParaFlag(pPara,PARAFLAG_ISPAGE) ) 1494 { 1495 // see if we already skiped enough pages 1496 if( 0 == nPagesToSkip ) 1497 break; // and if so, end the loop 1498 1499 // we skiped another page 1500 nPagesToSkip--; 1501 } 1502 1503 // get next paragraph 1504 pPara = mpOutliner->GetParagraph( ++nParaPos ); 1505 } 1506 1507 return pPara; 1508 } 1509 1510 /** selects the paragraph for the given page at the outliner view*/ 1511 void OutlineView::SetActualPage( SdPage* pActual ) 1512 { 1513 if( pActual && mpOutliner && dynamic_cast<Outliner*> ( mpOutliner )->GetIgnoreCurrentPageChangesLevel()==0 && !mbFirstPaint) 1514 { 1515 // if we found a paragraph, select its text at the outliner view 1516 Paragraph* pPara = GetParagraphForPage( mpOutliner, pActual ); 1517 if( pPara ) 1518 mpOutlinerView[0]->Select( pPara, sal_True, sal_False ); 1519 } 1520 } 1521 1522 /************************************************************************* 1523 |* 1524 |* StyleSheet aus der Selektion besorgen 1525 |* 1526 \************************************************************************/ 1527 1528 SfxStyleSheet* OutlineView::GetStyleSheet() const 1529 { 1530 ::sd::Window* pActWin = mpOutlineViewShell->GetActiveWindow(); 1531 OutlinerView* pOlView = GetViewByWindow(pActWin); 1532 SfxStyleSheet* pResult = pOlView->GetStyleSheet(); 1533 return pResult; 1534 } 1535 1536 1537 1538 /************************************************************************* 1539 |* 1540 |* Seiten als selektiert / nicht selektiert setzen 1541 |* 1542 \************************************************************************/ 1543 1544 void OutlineView::SetSelectedPages() 1545 { 1546 // Liste der selektierten Titelabsaetze 1547 List* pSelParas = mpOutlinerView[0]->CreateSelectionList(); 1548 Paragraph* pPara = (Paragraph*) pSelParas->First(); 1549 1550 while(pPara) 1551 { 1552 if( !mpOutliner->HasParaFlag(pPara, PARAFLAG_ISPAGE) ) 1553 { 1554 pSelParas->Remove(); 1555 pPara = (Paragraph*) pSelParas->GetCurObject(); 1556 } 1557 else 1558 { 1559 pPara = (Paragraph*) pSelParas->Next(); 1560 } 1561 } 1562 1563 // Die zu den selektierten Absaetzen auf Ebene 0 gehoerenden Seiten 1564 // selektieren 1565 sal_uInt16 nPos = 0; 1566 sal_uLong nParaPos = 0; 1567 pPara = mpOutliner->GetParagraph( 0 ); 1568 1569 while(pPara) 1570 { 1571 if( mpOutliner->HasParaFlag(pPara, PARAFLAG_ISPAGE) ) // eine Seite? 1572 { 1573 SdPage* pPage = mpDoc->GetSdPage(nPos, PK_STANDARD); 1574 DBG_ASSERT(pPage!=NULL, 1575 "Trying to select non-existing page OutlineView::SetSelectedPages()"); 1576 if (pPage != NULL) 1577 { 1578 pPage->SetSelected(sal_False); 1579 1580 if (pSelParas->Seek(pPara)) // selektiert? 1581 pPage->SetSelected(sal_True); 1582 } 1583 1584 nPos++; 1585 } 1586 1587 pPara = mpOutliner->GetParagraph( ++nParaPos ); 1588 } 1589 } 1590 1591 1592 /************************************************************************* 1593 |* 1594 |* Neue Links setzen 1595 |* 1596 \************************************************************************/ 1597 1598 void OutlineView::SetLinks() 1599 { 1600 // Benachrichtigungs-Links setzen 1601 mpOutliner->SetParaInsertedHdl(LINK(this, OutlineView, ParagraphInsertedHdl)); 1602 mpOutliner->SetParaRemovingHdl(LINK(this, OutlineView, ParagraphRemovingHdl)); 1603 mpOutliner->SetDepthChangedHdl(LINK(this, OutlineView, DepthChangedHdl)); 1604 mpOutliner->SetBeginMovingHdl(LINK(this, OutlineView, BeginMovingHdl)); 1605 mpOutliner->SetEndMovingHdl(LINK(this, OutlineView, EndMovingHdl)); 1606 mpOutliner->SetRemovingPagesHdl(LINK(this, OutlineView, RemovingPagesHdl)); 1607 mpOutliner->SetIndentingPagesHdl(LINK(this, OutlineView, IndentingPagesHdl)); 1608 mpOutliner->SetStatusEventHdl(LINK(this, OutlineView, StatusEventHdl)); 1609 mpOutliner->SetBeginDropHdl(LINK(this,OutlineView, BeginDropHdl)); 1610 mpOutliner->SetEndDropHdl(LINK(this,OutlineView, EndDropHdl)); 1611 mpOutliner->SetPaintFirstLineHdl(LINK(this,OutlineView,PaintingFirstLineHdl)); 1612 mpOutliner->SetBeginPasteOrDropHdl(LINK(this,OutlineView, BeginPasteOrDropHdl)); 1613 mpOutliner->SetEndPasteOrDropHdl(LINK(this,OutlineView, EndPasteOrDropHdl)); 1614 } 1615 1616 1617 1618 /************************************************************************* 1619 |* 1620 |* Alte Links restaurieren 1621 |* 1622 \************************************************************************/ 1623 1624 void OutlineView::ResetLinks() const 1625 { 1626 // alte Links restaurieren 1627 Link aEmptyLink; 1628 mpOutliner->SetParaInsertedHdl(aEmptyLink); 1629 mpOutliner->SetParaRemovingHdl(aEmptyLink); 1630 mpOutliner->SetDepthChangedHdl(aEmptyLink); 1631 mpOutliner->SetBeginMovingHdl(aEmptyLink); 1632 mpOutliner->SetEndMovingHdl(aEmptyLink); 1633 mpOutliner->SetStatusEventHdl(aEmptyLink); 1634 mpOutliner->SetRemovingPagesHdl(aEmptyLink); 1635 mpOutliner->SetIndentingPagesHdl(aEmptyLink); 1636 mpOutliner->SetDrawPortionHdl(aEmptyLink); 1637 mpOutliner->SetBeginPasteOrDropHdl(aEmptyLink); 1638 mpOutliner->SetEndPasteOrDropHdl(aEmptyLink); 1639 } 1640 1641 /************************************************************************* 1642 |* 1643 |* AcceptDrop 1644 |* 1645 \************************************************************************/ 1646 1647 sal_Int8 OutlineView::AcceptDrop( const AcceptDropEvent&, DropTargetHelper&, ::sd::Window*, sal_uInt16, sal_uInt16) 1648 { 1649 return DND_ACTION_NONE; 1650 } 1651 1652 /************************************************************************* 1653 |* 1654 |* ExecuteDrop 1655 |* 1656 \************************************************************************/ 1657 1658 sal_Int8 OutlineView::ExecuteDrop( const ExecuteDropEvent&, DropTargetHelper&, ::sd::Window*, sal_uInt16, sal_uInt16) 1659 { 1660 return DND_ACTION_NONE; 1661 } 1662 1663 // #97766# Re-implement GetScriptType for this view to get correct results 1664 sal_uInt16 OutlineView::GetScriptType() const 1665 { 1666 sal_uInt16 nScriptType = ::sd::View::GetScriptType(); 1667 1668 if(mpOutliner) 1669 { 1670 OutlinerParaObject* pTempOPObj = mpOutliner->CreateParaObject(); 1671 1672 if(pTempOPObj) 1673 { 1674 nScriptType = pTempOPObj->GetTextObject().GetScriptType(); 1675 delete pTempOPObj; 1676 } 1677 } 1678 1679 return nScriptType; 1680 } 1681 1682 void OutlineView::onUpdateStyleSettings( bool bForceUpdate /* = false */ ) 1683 { 1684 const bool bHighContrastMode = Application::GetSettings().GetStyleSettings().GetHighContrastMode() != 0; 1685 if( bForceUpdate || (mbHighContrastMode != bHighContrastMode) ) 1686 { 1687 if( mpOutliner ) 1688 { 1689 mpOutliner->ForceAutoColor( bHighContrastMode ); 1690 } 1691 mbHighContrastMode = bHighContrastMode; 1692 1693 } 1694 1695 svtools::ColorConfig aColorConfig; 1696 const Color aDocColor( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor ); 1697 if( bForceUpdate || (maDocColor != aDocColor) ) 1698 { 1699 sal_uInt16 nView; 1700 for( nView = 0; nView < MAX_OUTLINERVIEWS; nView++ ) 1701 { 1702 if (mpOutlinerView[nView] != NULL) 1703 { 1704 mpOutlinerView[nView]->SetBackgroundColor( aDocColor ); 1705 1706 ::Window* pWindow = mpOutlinerView[nView]->GetWindow(); 1707 1708 if( pWindow ) 1709 pWindow->SetBackground( Wallpaper( aDocColor ) ); 1710 1711 } 1712 } 1713 1714 if( mpOutliner ) 1715 mpOutliner->SetBackgroundColor( aDocColor ); 1716 1717 maDocColor = aDocColor; 1718 } 1719 } 1720 1721 IMPL_LINK( OutlineView, AppEventListenerHdl, void *, EMPTYARG ) 1722 { 1723 onUpdateStyleSettings(); 1724 return 0; 1725 } 1726 1727 1728 1729 1730 IMPL_LINK(OutlineView, EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent*, pEvent) 1731 { 1732 if (pEvent != NULL) 1733 { 1734 switch (pEvent->meEventId) 1735 { 1736 case tools::EventMultiplexerEvent::EID_CURRENT_PAGE: 1737 SetActualPage(mpOutlineViewShell->GetActualPage()); 1738 InvalidateSlideNumberArea(); 1739 break; 1740 1741 case tools::EventMultiplexerEvent::EID_PAGE_ORDER: 1742 if (mpOutliner != NULL && mpDoc!=NULL && mpOutliner != NULL && dynamic_cast<Outliner*> ( mpOutliner )->GetIgnoreCurrentPageChangesLevel()==0) 1743 { 1744 if (((mpDoc->GetPageCount()-1)%2) == 0) 1745 { 1746 mpOutliner->Clear(); 1747 FillOutliner(); 1748 ::sd::Window* pWindow = mpOutlineViewShell->GetActiveWindow(); 1749 if (pWindow != NULL) 1750 pWindow->Invalidate(); 1751 } 1752 } 1753 break; 1754 } 1755 } 1756 return 0; 1757 } 1758 1759 void OutlineView::IgnoreCurrentPageChanges (bool bIgnoreChanges) 1760 { 1761 if ( mpOutliner ) 1762 { 1763 if (bIgnoreChanges) 1764 dynamic_cast<Outliner*> ( mpOutliner )->IncreIgnoreCurrentPageChangesLevel(); 1765 else 1766 dynamic_cast<Outliner*> ( mpOutliner )->DecreIgnoreCurrentPageChangesLevel(); 1767 } 1768 } 1769 1770 /** call this method before you do anything that can modify the outliner 1771 and or the drawing document model. It will create needed undo actions */ 1772 void OutlineView::BeginModelChange() 1773 { 1774 const String aEmpty; 1775 mpOutliner->GetUndoManager().EnterListAction(aEmpty,aEmpty); 1776 const String aUndoStr(SdResId(STR_UNDO_CHANGE_TITLE_AND_LAYOUT)); 1777 BegUndo(aUndoStr); 1778 } 1779 1780 /** call this method after BeginModelChange(), when all possible model 1781 changes are done. */ 1782 void OutlineView::EndModelChange() 1783 { 1784 UpdateDocument(); 1785 1786 ::svl::IUndoManager* pDocUndoMgr = mpDocSh->GetUndoManager(); 1787 1788 bool bHasUndoActions = pDocUndoMgr->GetUndoActionCount() != 0; 1789 1790 EndUndo(); 1791 1792 DBG_ASSERT( bHasUndoActions == (mpOutliner->GetUndoManager().GetUndoActionCount() != 0), "sd::OutlineView::EndModelChange(), undo actions not in sync!" ); 1793 1794 if( bHasUndoActions ) 1795 { 1796 SfxLinkUndoAction* pLink = new SfxLinkUndoAction(pDocUndoMgr); 1797 mpOutliner->GetUndoManager().AddUndoAction(pLink); 1798 } 1799 1800 mpOutliner->GetUndoManager().LeaveListAction(); 1801 1802 if( bHasUndoActions && mpOutliner->GetEditEngine().HasTriedMergeOnLastAddUndo() ) 1803 TryToMergeUndoActions(); 1804 1805 mpOutlineViewShell->Invalidate( SID_UNDO ); 1806 mpOutlineViewShell->Invalidate( SID_REDO ); 1807 } 1808 1809 /** updates all changes in the outliner model to the draw model */ 1810 void OutlineView::UpdateDocument() 1811 { 1812 const sal_uInt32 nPageCount = mpDoc->GetSdPageCount(PK_STANDARD); 1813 Paragraph* pPara = mpOutliner->GetParagraph( 0 ); 1814 sal_uInt32 nPage; 1815 for (nPage = 0; nPage < nPageCount; nPage++) 1816 { 1817 SdPage* pPage = mpDoc->GetSdPage( (sal_uInt16)nPage, PK_STANDARD); 1818 mpDoc->SetSelected(pPage, sal_False); 1819 1820 mpOutlineViewShell->UpdateTitleObject( pPage, pPara ); 1821 mpOutlineViewShell->UpdateOutlineObject( pPage, pPara ); 1822 1823 if( pPara ) 1824 pPara = GetNextTitle(pPara); 1825 } 1826 1827 DBG_ASSERT( pPara == 0, "sd::OutlineView::UpdateDocument(), slides are out of sync, creating missing ones" ); 1828 while( pPara ) 1829 { 1830 SdPage* pPage = InsertSlideForParagraph( pPara ); 1831 mpDoc->SetSelected(pPage, sal_False); 1832 1833 mpOutlineViewShell->UpdateTitleObject( pPage, pPara ); 1834 mpOutlineViewShell->UpdateOutlineObject( pPage, pPara ); 1835 1836 if( pPara ) 1837 pPara = GetNextTitle(pPara); 1838 } 1839 } 1840 1841 /** merge edit engine undo actions if possible */ 1842 void OutlineView::TryToMergeUndoActions() 1843 { 1844 ::svl::IUndoManager& rOutlineUndo = mpOutliner->GetUndoManager(); 1845 if( rOutlineUndo.GetUndoActionCount() > 1 ) 1846 { 1847 SfxListUndoAction* pListAction = dynamic_cast< SfxListUndoAction* >( rOutlineUndo.GetUndoAction(0) ); 1848 SfxListUndoAction* pPrevListAction = dynamic_cast< SfxListUndoAction* >( rOutlineUndo.GetUndoAction(1) ); 1849 if( pListAction && pPrevListAction ) 1850 { 1851 // find the top EditUndo action in the top undo action list 1852 size_t nAction = pListAction->aUndoActions.size(); 1853 EditUndo* pEditUndo = 0; 1854 while( !pEditUndo && nAction ) 1855 { 1856 pEditUndo = dynamic_cast< EditUndo* >(pListAction->aUndoActions[--nAction].pAction); 1857 } 1858 1859 sal_uInt16 nEditPos = nAction; // we need this later to remove the merged undo actions 1860 1861 // make sure it is the only EditUndo action in the top undo list 1862 while( pEditUndo && nAction ) 1863 { 1864 if( dynamic_cast< EditUndo* >(pListAction->aUndoActions[--nAction].pAction) ) 1865 pEditUndo = 0; 1866 } 1867 1868 // do we have one and only one EditUndo action in the top undo list? 1869 if( pEditUndo ) 1870 { 1871 // yes, see if we can merge it with the prev undo list 1872 1873 nAction = pPrevListAction->aUndoActions.size(); 1874 EditUndo* pPrevEditUndo = 0; 1875 while( !pPrevEditUndo && nAction ) 1876 pPrevEditUndo = dynamic_cast< EditUndo* >(pPrevListAction->aUndoActions[--nAction].pAction); 1877 1878 if( pPrevEditUndo && pPrevEditUndo->Merge( pEditUndo ) ) 1879 { 1880 // ok we merged the only EditUndo of the top undo list with 1881 // the top EditUndo of the previous undo list 1882 1883 // first remove the merged undo action 1884 DBG_ASSERT( pListAction->aUndoActions[nEditPos].pAction == pEditUndo, 1885 "sd::OutlineView::TryToMergeUndoActions(), wrong edit pos!" ); 1886 pListAction->aUndoActions.Remove(nEditPos); 1887 delete pEditUndo; 1888 1889 // now check if we also can merge the draw undo actions 1890 ::svl::IUndoManager* pDocUndoManager = mpDocSh->GetUndoManager(); 1891 if( pDocUndoManager && ( pListAction->aUndoActions.size() == 1 )) 1892 { 1893 SfxLinkUndoAction* pLinkAction = dynamic_cast< SfxLinkUndoAction* >( pListAction->aUndoActions[0].pAction ); 1894 SfxLinkUndoAction* pPrevLinkAction = 0; 1895 1896 if( pLinkAction ) 1897 { 1898 nAction = pPrevListAction->aUndoActions.size(); 1899 while( !pPrevLinkAction && nAction ) 1900 pPrevLinkAction = dynamic_cast< SfxLinkUndoAction* >(pPrevListAction->aUndoActions[--nAction].pAction); 1901 } 1902 1903 if( pLinkAction && pPrevLinkAction && 1904 ( pLinkAction->GetAction() == pDocUndoManager->GetUndoAction(0) ) && 1905 ( pPrevLinkAction->GetAction() == pDocUndoManager->GetUndoAction(1) ) ) 1906 { 1907 SfxListUndoAction* pSourceList = dynamic_cast< SfxListUndoAction* >(pLinkAction->GetAction()); 1908 SfxListUndoAction* pDestinationList = dynamic_cast< SfxListUndoAction* >(pPrevLinkAction->GetAction()); 1909 1910 if( pSourceList && pDestinationList ) 1911 { 1912 sal_uInt16 nCount = pSourceList->aUndoActions.size(); 1913 sal_uInt16 nDestAction = pDestinationList->aUndoActions.size(); 1914 while( nCount-- ) 1915 { 1916 SfxUndoAction* pTemp = pSourceList->aUndoActions[0].pAction; 1917 pSourceList->aUndoActions.Remove(0); 1918 pDestinationList->aUndoActions.Insert( pTemp, nDestAction++ ); 1919 } 1920 pDestinationList->nCurUndoAction = pDestinationList->aUndoActions.size(); 1921 1922 pListAction->aUndoActions.Remove(0); 1923 delete pLinkAction; 1924 1925 pDocUndoManager->RemoveLastUndoAction(); 1926 } 1927 } 1928 } 1929 1930 if ( !pListAction->aUndoActions.empty() ) 1931 { 1932 // now we have to move all remaining doc undo actions from the top undo 1933 // list to the previous undo list and remove the top undo list 1934 1935 size_t nCount = pListAction->aUndoActions.size(); 1936 size_t nDestAction = pPrevListAction->aUndoActions.size(); 1937 while( nCount-- ) 1938 { 1939 SfxUndoAction* pTemp = pListAction->aUndoActions[0].pAction; 1940 pListAction->aUndoActions.Remove(0); 1941 if( pTemp ) 1942 pPrevListAction->aUndoActions.Insert( pTemp, nDestAction++ ); 1943 } 1944 pPrevListAction->nCurUndoAction = pPrevListAction->aUndoActions.size(); 1945 } 1946 1947 rOutlineUndo.RemoveLastUndoAction(); 1948 } 1949 } 1950 } 1951 } 1952 } 1953 1954 IMPL_LINK(OutlineView, PaintingFirstLineHdl, PaintFirstLineInfo*, pInfo) 1955 { 1956 if( pInfo && mpOutliner ) 1957 { 1958 Paragraph* pPara = mpOutliner->GetParagraph( pInfo->mnPara ); 1959 EditEngine& rEditEngine = const_cast< EditEngine& >( mpOutliner->GetEditEngine() ); 1960 1961 Size aImageSize( pInfo->mpOutDev->PixelToLogic( maSlideImage.GetSizePixel() ) ); 1962 Size aOffset( 100, 100 ); 1963 1964 // paint slide number 1965 if( pPara && mpOutliner->HasParaFlag(pPara,PARAFLAG_ISPAGE) ) 1966 { 1967 long nPage = 0; // todo, printing?? 1968 for ( sal_uInt16 n = 0; n <= pInfo->mnPara; n++ ) 1969 { 1970 Paragraph* p = mpOutliner->GetParagraph( n ); 1971 if ( mpOutliner->HasParaFlag(p,PARAFLAG_ISPAGE) ) 1972 nPage++; 1973 } 1974 1975 long nBulletHeight = (long)mpOutliner->GetLineHeight( pInfo->mnPara ); 1976 long nFontHeight = 0; 1977 if ( !rEditEngine.IsFlatMode() ) 1978 { 1979 // const SvxFontHeightItem& rFH = (const SvxFontHeightItem&)rEditEngine.GetParaAttrib( pInfo->mnPara, EE_CHAR_FONTHEIGHT ); 1980 // nBulletHeight = rFH.GetHeight(); 1981 nFontHeight = nBulletHeight / 5; 1982 } 1983 else 1984 { 1985 // const SvxFontHeightItem& rFH = (const SvxFontHeightItem&)rEditEngine.GetEmptyItemSet().Get( EE_CHAR_FONTHEIGHT ); 1986 // nBulletHeight = rFH.GetHeight(); 1987 nFontHeight = (nBulletHeight * 10) / 25; 1988 } 1989 1990 Size aFontSz( 0, nFontHeight ); 1991 1992 Size aOutSize( 2000, nBulletHeight ); 1993 1994 const float fImageHeight = ((float)aOutSize.Height() * (float)4) / (float)7; 1995 const float fImageRatio = (float)aImageSize.Height() / (float)aImageSize.Width(); 1996 aImageSize.Width() = (long)( fImageRatio * fImageHeight ); 1997 aImageSize.Height() = (long)( fImageHeight ); 1998 1999 Point aImagePos( pInfo->mrStartPos ); 2000 aImagePos.X() += aOutSize.Width() - aImageSize.Width() - aOffset.Width() ; 2001 aImagePos.Y() += (aOutSize.Height() - aImageSize.Height()) / 2; 2002 2003 pInfo->mpOutDev->DrawImage( aImagePos, aImageSize, maSlideImage ); 2004 2005 const bool bVertical = mpOutliner->IsVertical(); 2006 const bool bRightToLeftPara = rEditEngine.IsRightToLeft( pInfo->mnPara ); 2007 2008 LanguageType eLang = rEditEngine.GetDefaultLanguage(); 2009 2010 Point aTextPos( aImagePos.X() - aOffset.Width(), pInfo->mrStartPos.Y() ); 2011 Font aNewFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SANS_UNICODE, eLang, 0 ) ); 2012 aNewFont.SetSize( aFontSz ); 2013 // aNewFont.SetAlign( aBulletFont.GetAlign() ); 2014 aNewFont.SetVertical( bVertical ); 2015 aNewFont.SetOrientation( bVertical ? 2700 : 0 ); 2016 aNewFont.SetColor( COL_AUTO ); 2017 pInfo->mpOutDev->SetFont( aNewFont ); 2018 String aPageText = String::CreateFromInt32( nPage ); 2019 Size aTextSz; 2020 aTextSz.Width() = pInfo->mpOutDev->GetTextWidth( aPageText ); 2021 aTextSz.Height() = pInfo->mpOutDev->GetTextHeight(); 2022 // long nBulletHeight = !bVertical ? aBulletArea.GetHeight() : aBulletArea.GetWidth(); 2023 if ( !bVertical ) 2024 { 2025 aTextPos.Y() += (aOutSize.Height() - aTextSz.Height()) / 2; 2026 if ( !bRightToLeftPara ) 2027 { 2028 aTextPos.X() -= aTextSz.Width(); 2029 } 2030 else 2031 { 2032 aTextPos.X() += aTextSz.Width(); 2033 } 2034 } 2035 else 2036 { 2037 aTextPos.Y() -= aTextSz.Width(); 2038 aTextPos.X() += nBulletHeight / 2; 2039 } 2040 pInfo->mpOutDev->DrawText( aTextPos, aPageText ); 2041 } 2042 } 2043 2044 return 0; 2045 } 2046 2047 #if 0 2048 sal_Int32 OutlineView::GetPageNumberWidthPixel() 2049 { 2050 Window* pActWin = mpOutlineViewShell->GetActiveWindow(); 2051 if( pActWin ) 2052 { 2053 Font aOldFont( pActWin->GetFont() ); 2054 pActWin->SetFont( maPageNumberFont ); 2055 Size aSize( pActWin->GetTextWidth( String( RTL_CONSTASCII_USTRINGPARAM("X" ) ) ), 0 ); 2056 sal_Int32 nWidth = pActWin->LogicToPixel( aSize ).Width() * 5; 2057 2058 const String aBulletStr( sal_Unicode( 0xE011 ) ); 2059 pActWin->SetFont( maBulletFont); 2060 2061 aSize.Width() = pActWin->GetTextWidth(aBulletStr); 2062 nWidth += pActWin->LogicToPixel( aSize ).Width(); 2063 2064 pActWin->SetFont( aOldFont ); 2065 2066 mnPageNumberWidthPixel = nWidth; 2067 } 2068 return mnPageNumberWidthPixel; 2069 } 2070 #endif 2071 2072 // -------------------------------------------------------------------- 2073 2074 void OutlineView::UpdateParagraph( sal_uInt16 nPara ) 2075 { 2076 if( mpOutliner ) 2077 { 2078 SfxItemSet aNewAttrs2( mpOutliner->GetParaAttribs( nPara ) ); 2079 aNewAttrs2.Put( maLRSpaceItem ); 2080 mpOutliner->SetParaAttribs( nPara, aNewAttrs2 ); 2081 } 2082 } 2083 2084 // -------------------------------------------------------------------- 2085 2086 void OutlineView::OnBeginPasteOrDrop( PasteOrDropInfos* /*pInfos*/ ) 2087 { 2088 } 2089 2090 /** this is called after a paste or drop operation, make sure that the newly inserted paragraphs 2091 get the correct style sheet and new slides are inserted. */ 2092 void OutlineView::OnEndPasteOrDrop( PasteOrDropInfos* pInfos ) 2093 { 2094 SdPage* pPage = 0; 2095 SfxStyleSheetBasePool* pStylePool = GetDoc()->GetStyleSheetPool(); 2096 2097 for( sal_uInt16 nPara = pInfos->nStartPara; nPara <= pInfos->nEndPara; nPara++ ) 2098 { 2099 Paragraph* pPara = mpOutliner->GetParagraph( nPara ); 2100 2101 bool bPage = mpOutliner->HasParaFlag( pPara, PARAFLAG_ISPAGE ); 2102 2103 if( !bPage ) 2104 { 2105 SdStyleSheet* pStyleSheet = dynamic_cast< SdStyleSheet* >( mpOutliner->GetStyleSheet( nPara ) ); 2106 if( pStyleSheet ) 2107 { 2108 const OUString aName( pStyleSheet->GetApiName() ); 2109 if( aName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("title" ) ) ) 2110 bPage = true; 2111 } 2112 } 2113 2114 if( !pPara ) 2115 continue; // fatality!? 2116 2117 if( bPage && (nPara != pInfos->nStartPara) ) 2118 { 2119 // insert new slide for this paragraph 2120 pPage = InsertSlideForParagraph( pPara ); 2121 } 2122 else 2123 { 2124 // newly inserted non page paragraphs get the outline style 2125 if( !pPage ) 2126 pPage = GetPageForParagraph( pPara ); 2127 2128 if( pPage ) 2129 { 2130 SfxStyleSheet* pStyle = pPage->GetStyleSheetForPresObj( bPage ? PRESOBJ_TITLE : PRESOBJ_OUTLINE ); 2131 2132 if( !bPage ) 2133 { 2134 const sal_Int16 nDepth = mpOutliner->GetDepth( nPara ); 2135 if( nDepth > 0 ) 2136 { 2137 String aStyleSheetName( pStyle->GetName() ); 2138 aStyleSheetName.Erase( aStyleSheetName.Len() - 1, 1 ); 2139 aStyleSheetName += String::CreateFromInt32( nDepth ); 2140 pStyle = static_cast<SfxStyleSheet*>( pStylePool->Find( aStyleSheetName, pStyle->GetFamily() ) ); 2141 DBG_ASSERT( pStyle, "sd::OutlineView::OnEndPasteOrDrop(), Style not found!" ); 2142 } 2143 } 2144 2145 mpOutliner->SetStyleSheet( nPara, pStyle ); 2146 } 2147 2148 UpdateParagraph( nPara ); 2149 } 2150 } 2151 } 2152 2153 // ==================================================================== 2154 2155 2156 OutlineViewModelChangeGuard::OutlineViewModelChangeGuard( OutlineView& rView ) 2157 : mrView( rView ) 2158 { 2159 mrView.BeginModelChange(); 2160 } 2161 2162 OutlineViewModelChangeGuard::~OutlineViewModelChangeGuard() 2163 { 2164 mrView.EndModelChange(); 2165 } 2166 2167 OutlineViewPageChangesGuard::OutlineViewPageChangesGuard( OutlineView* pView ) 2168 : mpView( pView ) 2169 { 2170 if( mpView ) 2171 mpView->IgnoreCurrentPageChanges( true ); 2172 } 2173 2174 OutlineViewPageChangesGuard::~OutlineViewPageChangesGuard() 2175 { 2176 if( mpView ) 2177 mpView->IgnoreCurrentPageChanges( false ); 2178 } 2179 2180 2181 } // end of namespace sd 2182