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