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
OutlineView(DrawDocShell * pDocSh,::Window * pWindow,OutlineViewShell * pOutlineViewSh)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
~OutlineView()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
ConnectToApplication(void)267 void OutlineView::ConnectToApplication (void)
268 {
269 mpOutlineViewShell->GetActiveWindow()->GrabFocus();
270 Application::AddEventListener(LINK(this, OutlineView, AppEventListenerHdl));
271 }
272
273
274
275
DisconnectFromApplication(void)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
Paint(const Rectangle & rRect,::sd::Window * pWin)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
InvalidateSlideNumberArea()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
AdjustPosSizePixel(const Point &,const Size &,::sd::Window *)371 void OutlineView::AdjustPosSizePixel(const Point &,const Size &,::sd::Window*)
372 {
373 }
374
375 /*************************************************************************
376 |*
377 |* ein Fenster hinzufuegen
378 |*
379 \************************************************************************/
380
AddWindowToPaintView(OutputDevice * pWin)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
DeleteWindowFromPaintView(OutputDevice * pWin)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
GetViewByWindow(::Window * pWin) const457 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
GetPrevTitle(const Paragraph * pPara)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
GetNextTitle(const Paragraph * pPara)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
IMPL_LINK(OutlineView,ParagraphInsertedHdl,::Outliner *,pOutliner)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 */
InsertSlideForParagraph(Paragraph * pPara)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
IMPL_LINK(OutlineView,ParagraphRemovingHdl,::Outliner *,pOutliner)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
IMPL_LINK(OutlineView,DepthChangedHdl,::Outliner *,pOutliner)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
IMPL_LINK(OutlineView,StatusEventHdl,EditStatus *,EMPTYARG)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
IMPL_LINK(OutlineView,BeginDropHdl,void *,EMPTYARG)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
IMPL_LINK(OutlineView,EndDropHdl,void *,EMPTYARG)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
IMPL_LINK(OutlineView,BeginMovingHdl,::Outliner *,pOutliner)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
IMPL_LINK(OutlineView,EndMovingHdl,::Outliner *,pOutliner)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
GetTitleTextObject(SdrPage * pPage)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
GetOutlineTextObject(SdrPage * pPage)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
CreateTitleTextObject(SdPage * pPage)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
CreateOutlineTextObject(SdPage * pPage)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 */
PrepareClose(sal_Bool)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
SetAttributes(const SfxItemSet & rSet,sal_Bool)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
GetAttributes(SfxItemSet & rTargetSet,sal_Bool) const1282 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 */
FillOutliner()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_uInt16 nParaCount1 = (sal_uInt16)mpOutliner->GetParagraphCount();
1359 sal_Bool bVertical = pOPO->IsVertical();
1360 pOPO->SetVertical( sal_False );
1361 mpOutliner->AddText(*pOPO);
1362 pOPO->SetVertical( bVertical );
1363
1364 sal_uInt16 nParaCount2 = (sal_uInt16)mpOutliner->GetParagraphCount();
1365 for (sal_uInt16 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
IMPL_LINK(OutlineView,RemovingPagesHdl,OutlinerView *,EMPTYARG)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
IMPL_LINK_INLINE_START(OutlineView,IndentingPagesHdl,OutlinerView *,pOutlinerView)1433 IMPL_LINK_INLINE_START( OutlineView, IndentingPagesHdl, OutlinerView *, pOutlinerView )
1434 {
1435 return RemovingPagesHdl(pOutlinerView);
1436 }
IMPL_LINK_INLINE_END(OutlineView,IndentingPagesHdl,OutlinerView *,pOutlinerView)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
GetPageForParagraph(Paragraph * pPara)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
GetParagraphForPage(::Outliner * pOutl,SdPage * pPage)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*/
SetActualPage(SdPage * pActual)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
GetStyleSheet() const1524 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
SetSelectedPages()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
SetLinks()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
ResetLinks() const1620 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
AcceptDrop(const AcceptDropEvent &,DropTargetHelper &,::sd::Window *,sal_uInt16,sal_uInt16)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
ExecuteDrop(const ExecuteDropEvent &,DropTargetHelper &,::sd::Window *,sal_uInt16,sal_uInt16)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
GetScriptType() const1660 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
onUpdateStyleSettings(bool bForceUpdate)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
IMPL_LINK(OutlineView,AppEventListenerHdl,void *,EMPTYARG)1717 IMPL_LINK( OutlineView, AppEventListenerHdl, void *, EMPTYARG )
1718 {
1719 onUpdateStyleSettings();
1720 return 0;
1721 }
1722
1723
1724
1725
IMPL_LINK(OutlineView,EventMultiplexerListener,::sd::tools::EventMultiplexerEvent *,pEvent)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
IgnoreCurrentPageChanges(bool bIgnoreChanges)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 */
BeginModelChange()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. */
EndModelChange()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 */
UpdateDocument()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 */
TryToMergeUndoActions()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
IMPL_LINK(OutlineView,PaintingFirstLineHdl,PaintFirstLineInfo *,pInfo)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
UpdateParagraph(sal_uInt16 nPara)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
OnBeginPasteOrDrop(PasteOrDropInfos *)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. */
OnEndPasteOrDrop(PasteOrDropInfos * pInfos)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
OutlineViewModelChangeGuard(OutlineView & rView)2152 OutlineViewModelChangeGuard::OutlineViewModelChangeGuard( OutlineView& rView )
2153 : mrView( rView )
2154 {
2155 mrView.BeginModelChange();
2156 }
2157
~OutlineViewModelChangeGuard()2158 OutlineViewModelChangeGuard::~OutlineViewModelChangeGuard()
2159 {
2160 mrView.EndModelChange();
2161 }
2162
OutlineViewPageChangesGuard(OutlineView * pView)2163 OutlineViewPageChangesGuard::OutlineViewPageChangesGuard( OutlineView* pView )
2164 : mpView( pView )
2165 {
2166 if( mpView )
2167 mpView->IgnoreCurrentPageChanges( true );
2168 }
2169
~OutlineViewPageChangesGuard()2170 OutlineViewPageChangesGuard::~OutlineViewPageChangesGuard()
2171 {
2172 if( mpView )
2173 mpView->IgnoreCurrentPageChanges( false );
2174 }
2175
2176
2177 } // end of namespace sd
2178