1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "OutlineView.hxx"
23 #include <editeng/forbiddencharacterstable.hxx>
24 #include <sfx2/progress.hxx>
25 #include <vcl/wrkwin.hxx>
26 #include <svx/svxids.hrc>
27 #include <editeng/outliner.hxx>
28 #include <editeng/eeitem.hxx>
29 #include <editeng/editstat.hxx>
30 #include <editeng/lrspitem.hxx>
31 #include <svx/svdotext.hxx>
32 #include <sfx2/printer.hxx>
33 #include <sfx2/imagemgr.hxx>
34 #include <sfx2/app.hxx>
35 #include <sfx2/bindings.hxx>
36 #include <svl/itempool.hxx>
37 #include <svl/style.hxx>
38 #include <svx/svdorect.hxx>
39 #include <svx/svdundo.hxx>
40 #include <svl/brdcst.hxx>
41 #include <vcl/msgbox.hxx>
42 #include <editeng/adjustitem.hxx>
43 #include <editeng/tstpitem.hxx>
44 #include <editeng/lspcitem.hxx>
45 #include <editeng/numitem.hxx>
46 #include <editeng/outlobj.hxx>
47 #include <editeng/editeng.hxx>
49 #include <editeng/editobj.hxx>
50 #include <editeng/editund2.hxx>
52 #include <editeng/editview.hxx>
53 #include <editeng/svxfont.hxx>
54 #include <editeng/fhgtitem.hxx>
56 #include "DrawDocShell.hxx"
57 #include "drawdoc.hxx"
61 #include "OutlineViewShell.hxx"
64 #include "sdresid.hxx"
65 #include "Outliner.hxx"
66 #include "strings.hrc"
67 #include "EventMultiplexer.hxx"
68 #include "ViewShellBase.hxx"
69 #include "undo/undoobjects.hxx"
70 #include "undo/undomanager.hxx"
71 #include "stlsheet.hxx"
73 using namespace ::com::sun::star::uno
;
74 using namespace ::com::sun::star::frame
;
78 // width: DIN A4, two margins à 1 cm each
79 #define OUTLINE_PAPERWIDTH 19000
81 // a progress bar gets displayed when more than
82 // PROCESS_WITH_PROGRESS_THRESHOLD pages are concerned
83 #define PROCESS_WITH_PROGRESS_THRESHOLD 5
91 TYPEINIT1( OutlineView
, ::sd::View
);
94 OutlineView::OutlineView( DrawDocShell
& rDocSh
, ::Window
* pWindow
, OutlineViewShell
& rOutlineViewSh
)
95 : ::sd::View(*rDocSh
.GetDoc(), pWindow
, &rOutlineViewSh
)
96 , mrOutlineViewShell(rOutlineViewSh
)
97 , mrOutliner(*mrDoc
.GetOutliner(sal_True
))
100 , mbFirstPaint(sal_True
)
102 , maDocColor( COL_WHITE
)
103 , maLRSpaceItem( 0, 0, 2000, 0, EE_PARA_OUTLLRSPACE
)
105 sal_Bool bInitOutliner
= sal_False
;
107 if (mrOutliner
.GetViewCount() == 0)
109 // initialize Outliner: set Reference Device
110 bInitOutliner
= sal_True
;
111 mrOutliner
.Init( OUTLINERMODE_OUTLINEVIEW
);
112 mrOutliner
.SetRefDevice( SD_MOD()->GetRefDevice( rDocSh
) );
113 sal_uLong nWidth
= OUTLINE_PAPERWIDTH
;
114 mrOutliner
.SetPaperSize(Size(nWidth
, 400000000));
117 // insert View into Outliner
118 for (sal_uInt16 nView
= 0; nView
< MAX_OUTLINERVIEWS
; nView
++)
120 mpOutlinerView
[nView
] = NULL
;
123 mpOutlinerView
[0] = new OutlinerView(&mrOutliner
, pWindow
);
125 mpOutlinerView
[0]->SetOutputArea(aNullRect
);
126 mrOutliner
.SetUpdateMode(sal_False
);
127 mrOutliner
.InsertView(mpOutlinerView
[0], LIST_APPEND
);
129 onUpdateStyleSettings( true );
133 // fill Outliner with contents
137 Link
aLink( LINK(this,OutlineView
,EventMultiplexerListener
) );
138 mrOutlineViewShell
.GetViewShellBase().GetEventMultiplexer()->AddEventListener(
140 tools::EventMultiplexerEvent::EID_CURRENT_PAGE
141 | tools::EventMultiplexerEvent::EID_PAGE_ORDER
);
143 LanguageType eLang
= mrOutliner
.GetDefaultLanguage();
144 maPageNumberFont
= OutputDevice::GetDefaultFont( DEFAULTFONT_SANS_UNICODE
, eLang
, 0 );
145 maPageNumberFont
.SetHeight( 500 );
147 maBulletFont
.SetColor( COL_AUTO
);
148 maBulletFont
.SetHeight( 1000 );
149 maBulletFont
.SetCharSet(RTL_TEXTENCODING_MS_1252
); // and replacing other values by standard
150 maBulletFont
.SetName( OUString( "StarSymbol" ) );
151 maBulletFont
.SetWeight(WEIGHT_NORMAL
);
152 maBulletFont
.SetUnderline(UNDERLINE_NONE
);
153 maBulletFont
.SetStrikeout(STRIKEOUT_NONE
);
154 maBulletFont
.SetItalic(ITALIC_NONE
);
155 maBulletFont
.SetOutline(sal_False
);
156 maBulletFont
.SetShadow(sal_False
);
159 Reference
<XFrame
> xFrame (mrOutlineViewShell
.GetViewShellBase().GetFrame()->GetTopFrame().GetFrameInterface(), UNO_QUERY
);
161 const OUString
aSlotURL( ".uno:ShowSlide" );
162 maSlideImage
= GetImage( xFrame
, aSlotURL
, true );
164 // Tell undo manager of the document about the undo manager of the
165 // outliner, so that the former can synchronize with the later.
166 sd::UndoManager
* pDocUndoMgr
= dynamic_cast<sd::UndoManager
*>(mpDocSh
->GetUndoManager());
167 if (pDocUndoMgr
!= NULL
)
168 pDocUndoMgr
->SetLinkedUndoManager(&mrOutliner
.GetUndoManager());
172 * Destructor, restore Links, clear Oultiner
174 OutlineView::~OutlineView()
176 DBG_ASSERT(maDragAndDropModelGuard
.get() == 0, "sd::OutlineView::~OutlineView(), prior drag operation not finished correctly!" );
178 Link
aLink( LINK(this,OutlineView
,EventMultiplexerListener
) );
179 mrOutlineViewShell
.GetViewShellBase().GetEventMultiplexer()->RemoveEventListener( aLink
);
180 DisconnectFromApplication();
185 // unregister OutlinerViews and destroy them
186 for (sal_uInt16 nView
= 0; nView
< MAX_OUTLINERVIEWS
; nView
++)
188 if (mpOutlinerView
[nView
] != NULL
)
190 mrOutliner
.RemoveView( mpOutlinerView
[nView
] );
191 delete mpOutlinerView
[nView
];
192 mpOutlinerView
[nView
] = NULL
;
196 if (mrOutliner
.GetViewCount() == 0)
198 // uninitialize Outliner: enable color display
200 sal_uLong nCntrl
= mrOutliner
.GetControlWord();
201 mrOutliner
.SetUpdateMode(sal_False
); // otherwise there will be drawn on SetControlWord
202 mrOutliner
.SetControlWord(nCntrl
& ~EE_CNTRL_NOCOLORS
);
203 SvtAccessibilityOptions aOptions
;
204 mrOutliner
.ForceAutoColor( aOptions
.GetIsAutomaticFontColor() );
212 void OutlineView::ConnectToApplication (void)
214 mrOutlineViewShell
.GetActiveWindow()->GrabFocus();
215 Application::AddEventListener(LINK(this, OutlineView
, AppEventListenerHdl
));
221 void OutlineView::DisconnectFromApplication (void)
223 Application::RemoveEventListener(LINK(this, OutlineView
, AppEventListenerHdl
));
230 void OutlineView::Paint(const Rectangle
& rRect
, ::sd::Window
* pWin
)
232 OutlinerView
* pOlView
= GetViewByWindow(pWin
);
236 pOlView
->HideCursor();
237 pOlView
->Paint(rRect
);
239 pOlView
->ShowCursor(mbFirstPaint
);
241 mbFirstPaint
= sal_False
;
245 void OutlineView::InvalidateSlideNumberArea()
250 * Window size was changed
253 void OutlineView::AdjustPosSizePixel(const Point
&,const Size
&,::sd::Window
*)
258 void OutlineView::AddWindowToPaintView(OutputDevice
* pWin
)
260 sal_Bool bAdded
= sal_False
;
261 sal_Bool bValidArea
= sal_False
;
262 Rectangle aOutputArea
;
263 const Color
aWhiteColor( COL_WHITE
);
264 sal_uInt16 nView
= 0;
266 while (nView
< MAX_OUTLINERVIEWS
&& !bAdded
)
268 if (mpOutlinerView
[nView
] == NULL
)
270 mpOutlinerView
[nView
] = new OutlinerView(&mrOutliner
, dynamic_cast< ::sd::Window
* >(pWin
));
271 mpOutlinerView
[nView
]->SetBackgroundColor( aWhiteColor
);
272 mrOutliner
.InsertView(mpOutlinerView
[nView
], LIST_APPEND
);
277 mpOutlinerView
[nView
]->SetOutputArea(aOutputArea
);
280 else if (!bValidArea
)
282 aOutputArea
= mpOutlinerView
[nView
]->GetOutputArea();
283 bValidArea
= sal_True
;
289 // white background in Outliner
290 pWin
->SetBackground( Wallpaper( aWhiteColor
) );
292 ::sd::View::AddWindowToPaintView(pWin
);
296 void OutlineView::DeleteWindowFromPaintView(OutputDevice
* pWin
)
298 sal_Bool bRemoved
= sal_False
;
299 sal_uInt16 nView
= 0;
302 while (nView
< MAX_OUTLINERVIEWS
&& !bRemoved
)
304 if (mpOutlinerView
[nView
] != NULL
)
306 pWindow
= mpOutlinerView
[nView
]->GetWindow();
310 mrOutliner
.RemoveView( mpOutlinerView
[nView
] );
311 delete mpOutlinerView
[nView
];
312 mpOutlinerView
[nView
] = NULL
;
320 ::sd::View::DeleteWindowFromPaintView(pWin
);
324 * Return a pointer to the OutlinerView corresponding to the window
326 OutlinerView
* OutlineView::GetViewByWindow (::Window
* pWin
) const
328 OutlinerView
* pOlView
= NULL
;
329 for (sal_uInt16 nView
= 0; nView
< MAX_OUTLINERVIEWS
; nView
++)
331 if (mpOutlinerView
[nView
] != NULL
)
333 if ( pWin
== mpOutlinerView
[nView
]->GetWindow() )
335 pOlView
= mpOutlinerView
[nView
];
344 * Return the title before a random paragraph
346 Paragraph
* OutlineView::GetPrevTitle(const Paragraph
* pPara
)
348 sal_Int32 nPos
= mrOutliner
.GetAbsPos(const_cast<Paragraph
*>(pPara
));
354 pPara
= mrOutliner
.GetParagraph(--nPos
);
355 if( mrOutliner
.HasParaFlag(pPara
, PARAFLAG_ISPAGE
) )
357 return const_cast< Paragraph
* >( pPara
);
366 * Return the title after a random paragraph
368 Paragraph
* OutlineView::GetNextTitle(const Paragraph
* pPara
)
370 Paragraph
* pResult
= const_cast< Paragraph
* >( pPara
);
372 sal_Int32 nPos
= mrOutliner
.GetAbsPos(pResult
);
376 pResult
= mrOutliner
.GetParagraph(++nPos
);
377 if( pResult
&& mrOutliner
.HasParaFlag(pResult
, PARAFLAG_ISPAGE
) )
386 * Handler for inserting pages (paragraphs)
388 IMPL_LINK( OutlineView
, ParagraphInsertedHdl
, ::Outliner
*, pOutliner
)
390 // we get calls to this handler during binary insert of drag and drop contents but
391 // we ignore it here and handle it later in OnEndPasteOrDrop()
392 if( maDragAndDropModelGuard
.get() == 0 )
394 OutlineViewPageChangesGuard
aGuard(this);
396 Paragraph
* pPara
= pOutliner
->GetHdlParagraph();
398 sal_Int32 nAbsPos
= mrOutliner
.GetAbsPos( pPara
);
400 UpdateParagraph( nAbsPos
);
402 if( (nAbsPos
== 0) || mrOutliner
.HasParaFlag(pPara
,PARAFLAG_ISPAGE
) || mrOutliner
.HasParaFlag(mrOutliner
.GetParagraph( nAbsPos
-1 ), PARAFLAG_ISPAGE
) )
404 InsertSlideForParagraph( pPara
);
405 InvalidateSlideNumberArea();
412 /** creates and inserts an empty slide for the given paragraph */
413 SdPage
* OutlineView::InsertSlideForParagraph( Paragraph
* pPara
)
415 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::InsertSlideForParagraph(), model change without undo?!" );
417 OutlineViewPageChangesGuard
aGuard(this);
419 mrOutliner
.SetParaFlag( pPara
, PARAFLAG_ISPAGE
);
420 // how many titles are there before the new title paragraph?
421 sal_uLong nExample
= 0L; // position of the "example" page
422 sal_uLong nTarget
= 0L; // position of insertion
425 pPara
= GetPrevTitle(pPara
);
430 // if a new paragraph is created via RETURN before the first paragraph, the
431 // Outliner reports the old paragraph (which was moved down) as a new
435 String
aTest(mrOutliner
.GetText( mrOutliner
.GetParagraph( 0 ) ));
436 if (aTest
.Len() == 0)
443 // the "example" page is the previous page - if it is available
446 nExample
= nTarget
- 1;
448 sal_uInt16 nPageCount
= mrDoc
.GetSdPageCount( PK_STANDARD
);
449 if( nExample
>= nPageCount
)
450 nExample
= nPageCount
- 1;
453 /**********************************************************************
454 * All the time, a standard page is created before a notes page.
455 * It is ensured that after each standard page the corresponding notes page
456 * follows. A handout page is exactly one handout page.
457 **********************************************************************/
459 // this page is exemplary
460 SdPage
* pExample
= (SdPage
*)mrDoc
.GetSdPage((sal_uInt16
)nExample
, PK_STANDARD
);
461 SdPage
* pPage
= (SdPage
*)mrDoc
.AllocPage(sal_False
);
463 pPage
->SetLayoutName(pExample
->GetLayoutName());
466 mrDoc
.InsertPage(pPage
, (sal_uInt16
)(nTarget
) * 2 + 1);
467 if( isRecordingUndo() )
468 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoNewPage(*pPage
));
470 // assign a master page to the standard page
471 pPage
->TRG_SetMasterPage(pExample
->TRG_GetMasterPage());
474 pPage
->SetSize(pExample
->GetSize());
475 pPage
->SetBorder( pExample
->GetLftBorder(),
476 pExample
->GetUppBorder(),
477 pExample
->GetRgtBorder(),
478 pExample
->GetLwrBorder() );
480 // create new presentation objects (after <Title> or <Title with subtitle>
481 // follows <Title with outline>, otherwise apply the layout of the previous
483 AutoLayout eAutoLayout
= pExample
->GetAutoLayout();
484 if (eAutoLayout
== AUTOLAYOUT_TITLE
||
485 eAutoLayout
== AUTOLAYOUT_ONLY_TITLE
)
487 pPage
->SetAutoLayout(AUTOLAYOUT_ENUM
, sal_True
);
491 pPage
->SetAutoLayout(pExample
->GetAutoLayout(), sal_True
);
494 /**********************************************************************
495 |* now the notes page
496 \*********************************************************************/
497 pExample
= (SdPage
*)mrDoc
.GetSdPage((sal_uInt16
)nExample
, PK_NOTES
);
498 SdPage
* pNotesPage
= (SdPage
*)mrDoc
.AllocPage(sal_False
);
500 pNotesPage
->SetLayoutName(pExample
->GetLayoutName());
502 pNotesPage
->SetPageKind(PK_NOTES
);
504 // insert (notes page)
505 mrDoc
.InsertPage(pNotesPage
, (sal_uInt16
)(nTarget
) * 2 + 2);
506 if( isRecordingUndo() )
507 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoNewPage(*pNotesPage
));
509 // assign a master page to the notes page
510 pNotesPage
->TRG_SetMasterPage(pExample
->TRG_GetMasterPage());
512 // set page size, there must be already one page available
513 pNotesPage
->SetSize(pExample
->GetSize());
514 pNotesPage
->SetBorder( pExample
->GetLftBorder(),
515 pExample
->GetUppBorder(),
516 pExample
->GetRgtBorder(),
517 pExample
->GetLwrBorder() );
519 // create presentation objects
520 pNotesPage
->SetAutoLayout(pExample
->GetAutoLayout(), sal_True
);
522 mrOutliner
.UpdateFields();
528 * Handler for deleting pages (paragraphs)
530 IMPL_LINK( OutlineView
, ParagraphRemovingHdl
, ::Outliner
*, pOutliner
)
532 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::ParagraphRemovingHdl(), model change without undo?!" );
534 OutlineViewPageChangesGuard
aGuard(this);
536 Paragraph
* pPara
= pOutliner
->GetHdlParagraph();
537 if( pOutliner
->HasParaFlag( pPara
, PARAFLAG_ISPAGE
) )
539 // how many titles are in front of the title paragraph in question?
543 pPara
= GetPrevTitle(pPara
);
547 // delete page and notes page
548 sal_uInt16 nAbsPos
= (sal_uInt16
)nPos
* 2 + 1;
549 SdrPage
* pPage
= mrDoc
.GetPage(nAbsPos
);
550 if( isRecordingUndo() )
551 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoDeletePage(*pPage
));
552 mrDoc
.RemovePage(nAbsPos
);
554 nAbsPos
= (sal_uInt16
)nPos
* 2 + 1;
555 pPage
= mrDoc
.GetPage(nAbsPos
);
556 if( isRecordingUndo() )
557 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoDeletePage(*pPage
));
558 mrDoc
.RemovePage(nAbsPos
);
560 // progress display if necessary
561 if (mnPagesToProcess
)
566 mpProgress
->SetState(mnPagesProcessed
);
568 if (mnPagesProcessed
== mnPagesToProcess
)
575 mnPagesToProcess
= 0;
576 mnPagesProcessed
= 0;
579 pOutliner
->UpdateFields();
582 InvalidateSlideNumberArea();
588 * Handler for changing the indentation depth of paragraphs (requires inserting
589 * or deleting of pages in some cases)
591 IMPL_LINK( OutlineView
, DepthChangedHdl
, ::Outliner
*, pOutliner
)
593 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::DepthChangedHdl(), no undo for model change?!" );
595 OutlineViewPageChangesGuard
aGuard(this);
597 Paragraph
* pPara
= pOutliner
->GetHdlParagraph();
598 if( pOutliner
->HasParaFlag( pPara
, PARAFLAG_ISPAGE
) && ((pOutliner
->GetPrevFlags() & PARAFLAG_ISPAGE
) == 0) )
600 // the current paragraph is transformed into a slide
602 mrOutliner
.SetDepth( pPara
, -1 );
604 // are multiple level 1 paragraphs being brought to level 0 and we
605 // should start a progress view or a timer and didn't already?
606 if (mnPagesToProcess
== 0)
608 Window
* pActWin
= mrOutlineViewShell
.GetActiveWindow();
609 OutlinerView
* pOlView
= GetViewByWindow(pActWin
);
611 std::vector
<Paragraph
*> aSelList
;
612 pOlView
->CreateSelectionList(aSelList
);
614 Paragraph
*pParagraph
= NULL
;
615 for (std::vector
<Paragraph
*>::const_iterator iter
= aSelList
.begin(); iter
!= aSelList
.end(); ++iter
)
619 if( !pOutliner
->HasParaFlag( pParagraph
, PARAFLAG_ISPAGE
) &&
620 (pOutliner
->GetDepth( pOutliner
->GetAbsPos( pParagraph
) ) <= 0) )
624 mnPagesToProcess
++; // the paragraph being in level 0 already
625 // should be included
626 mnPagesProcessed
= 0;
628 if (mnPagesToProcess
> PROCESS_WITH_PROGRESS_THRESHOLD
)
633 const String
aStr(SdResId(STR_CREATE_PAGES
));
634 mpProgress
= new SfxProgress( GetDocSh(), aStr
, mnPagesToProcess
);
638 mpDocSh
->SetWaitCursor( sal_True
);
642 ParagraphInsertedHdl(pOutliner
);
646 // should there be a progress display?
647 if (mnPagesToProcess
> PROCESS_WITH_PROGRESS_THRESHOLD
)
650 mpProgress
->SetState(mnPagesProcessed
);
653 // was this the last page?
654 if (mnPagesProcessed
== mnPagesToProcess
)
656 if (mnPagesToProcess
> PROCESS_WITH_PROGRESS_THRESHOLD
&& mpProgress
)
662 mpDocSh
->SetWaitCursor( sal_False
);
664 mnPagesToProcess
= 0;
665 mnPagesProcessed
= 0;
667 pOutliner
->UpdateFields();
669 else if( !pOutliner
->HasParaFlag( pPara
, PARAFLAG_ISPAGE
) && ((pOutliner
->GetPrevFlags() & PARAFLAG_ISPAGE
) != 0) )
671 // the paragraph was a page but now becomes a normal paragraph
673 // how many titles are before the title paragraph in question?
675 Paragraph
* pParagraph
= pPara
;
678 pParagraph
= GetPrevTitle(pParagraph
);
682 // delete page and notes page
684 sal_uInt16 nAbsPos
= (sal_uInt16
)nPos
* 2 + 1;
685 SdrPage
* pPage
= mrDoc
.GetPage(nAbsPos
);
686 if( isRecordingUndo() )
687 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoDeletePage(*pPage
));
688 mrDoc
.RemovePage(nAbsPos
);
690 nAbsPos
= (sal_uInt16
)nPos
* 2 + 1;
691 pPage
= mrDoc
.GetPage(nAbsPos
);
692 if( isRecordingUndo() )
693 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoDeletePage(*pPage
));
694 mrDoc
.RemovePage(nAbsPos
);
696 pPage
= GetPageForParagraph( pPara
);
698 mrOutliner
.SetDepth( pPara
, (pPage
&& (static_cast<SdPage
*>(pPage
)->GetAutoLayout() == AUTOLAYOUT_TITLE
)) ? -1 : 0 );
700 // progress display if necessary
701 if (mnPagesToProcess
)
705 mpProgress
->SetState(mnPagesProcessed
);
707 if (mnPagesProcessed
== mnPagesToProcess
)
714 mnPagesToProcess
= 0;
715 mnPagesProcessed
= 0;
718 pOutliner
->UpdateFields();
720 else if ( (pOutliner
->GetPrevDepth() == 1) && ( pOutliner
->GetDepth( pOutliner
->GetAbsPos( pPara
) ) == 2 ) )
722 // how many titles are in front of the title paragraph in question?
723 sal_Int32 nPos
= -1L;
725 Paragraph
* pParagraph
= pPara
;
728 pParagraph
= GetPrevTitle(pParagraph
);
735 SdPage
*pPage
= (SdPage
*)mrDoc
.GetSdPage( (sal_uInt16
) nPos
, PK_STANDARD
);
737 if(pPage
&& pPage
->GetPresObj(PRESOBJ_TEXT
))
738 pOutliner
->SetDepth( pPara
, 0 );
742 // how many titles are in front of the title paragraph in question?
743 sal_Int32 nPos
= -1L;
745 Paragraph
* pTempPara
= pPara
;
748 pTempPara
= GetPrevTitle(pTempPara
);
755 SdPage
* pPage
= (SdPage
*) mrDoc
.GetSdPage( (sal_uInt16
) nPos
, PK_STANDARD
);
759 SfxStyleSheet
* pStyleSheet
= NULL
;
760 sal_Int32 nPara
= pOutliner
->GetAbsPos( pPara
);
761 sal_Int16 nDepth
= pOutliner
->GetDepth( nPara
);
762 bool bSubTitle
= pPage
->GetPresObj(PRESOBJ_TEXT
) != NULL
;
764 if( pOutliner
->HasParaFlag(pPara
, PARAFLAG_ISPAGE
) )
766 pStyleSheet
= pPage
->GetStyleSheetForPresObj( PRESOBJ_TITLE
);
770 pStyleSheet
= pPage
->GetStyleSheetForPresObj( PRESOBJ_TEXT
);
774 pStyleSheet
= pPage
->GetStyleSheetForPresObj( PRESOBJ_OUTLINE
);
778 String
aNewStyleSheetName( pStyleSheet
->GetName() );
779 aNewStyleSheetName
.Erase( aNewStyleSheetName
.Len()-1, 1 );
780 aNewStyleSheetName
+= OUString::number( nDepth
+1 );
781 SfxStyleSheetBasePool
* pStylePool
= mrDoc
.GetStyleSheetPool();
782 pStyleSheet
= (SfxStyleSheet
*) pStylePool
->Find( aNewStyleSheetName
, pStyleSheet
->GetFamily() );
786 // before we set the style sheet we need to preserve the bullet item
787 // since all items will be deleted while setting a new style sheet
788 SfxItemSet
aOldAttrs( pOutliner
->GetParaAttribs( nPara
) );
790 pOutliner
->SetStyleSheet( nPara
, pStyleSheet
);
792 // restore the old bullet item but not if the style changed
793 if ( pOutliner
->GetPrevDepth() != -1 && nDepth
!= -1 &&
794 aOldAttrs
.GetItemState( EE_PARA_NUMBULLET
) == SFX_ITEM_ON
)
796 SfxItemSet
aAttrs( pOutliner
->GetParaAttribs( nPara
) );
797 aAttrs
.Put( *aOldAttrs
.GetItem( EE_PARA_NUMBULLET
) );
798 pOutliner
->SetParaAttribs( nPara
, aAttrs
);
803 InvalidateSlideNumberArea();
809 * Handler for StatusEvents
811 IMPL_LINK_NOARG(OutlineView
, StatusEventHdl
)
813 ::sd::Window
* pWin
= mrOutlineViewShell
.GetActiveWindow();
814 OutlinerView
* pOutlinerView
= GetViewByWindow(pWin
);
815 Rectangle aVis
= pOutlinerView
->GetVisArea();
816 sal_uLong nWidth
= OUTLINE_PAPERWIDTH
;
817 Rectangle aText
= Rectangle(Point(0,0),
819 mrOutliner
.GetTextHeight()));
820 Rectangle
aWin(Point(0,0), pWin
->GetOutputSizePixel());
821 aWin
= pWin
->PixelToLogic(aWin
);
823 if (!aVis
.IsEmpty()) // not when opening
825 aText
.Bottom() += aWin
.GetHeight();
827 mrOutlineViewShell
.InitWindows(Point(0,0), aText
.GetSize(),
828 Point(aVis
.TopLeft()));
829 mrOutlineViewShell
.UpdateScrollBars();
832 InvalidateSlideNumberArea();
836 IMPL_LINK_NOARG(OutlineView
, BeginDropHdl
)
838 DBG_ASSERT(maDragAndDropModelGuard
.get() == 0, "sd::OutlineView::BeginDropHdl(), prior drag operation not finished correctly!" );
840 maDragAndDropModelGuard
.reset( new OutlineViewModelChangeGuard( *this ) );
844 IMPL_LINK_NOARG(OutlineView
, EndDropHdl
)
846 maDragAndDropModelGuard
.reset(0);
847 InvalidateSlideNumberArea();
852 * Handler for the start of a paragraph movement
854 IMPL_LINK( OutlineView
, BeginMovingHdl
, ::Outliner
*, pOutliner
)
856 OutlineViewPageChangesGuard
aGuard(this);
858 // list of selected title paragraphs
859 mpOutlinerView
[0]->CreateSelectionList(maSelectedParas
);
861 for (std::vector
<Paragraph
*>::iterator it
= maSelectedParas
.begin(); it
!= maSelectedParas
.end();)
863 if (!pOutliner
->HasParaFlag(*it
, PARAFLAG_ISPAGE
))
864 it
= maSelectedParas
.erase(it
);
869 // select the pages belonging to the paragraphs on level 0 to select
871 sal_Int32 nParaPos
= 0;
872 Paragraph
* pPara
= pOutliner
->GetParagraph( 0 );
873 std::vector
<Paragraph
*>::const_iterator fiter
;
877 if( pOutliner
->HasParaFlag(pPara
, PARAFLAG_ISPAGE
) ) // one page?
879 maOldParaOrder
.push_back(pPara
);
880 SdPage
* pPage
= mrDoc
.GetSdPage(nPos
, PK_STANDARD
);
882 fiter
= std::find(maSelectedParas
.begin(),maSelectedParas
.end(),pPara
);
884 pPage
->SetSelected(fiter
!= maSelectedParas
.end());
888 pPara
= pOutliner
->GetParagraph( ++nParaPos
);
895 * Handler for the end of a paragraph movement
897 IMPL_LINK( OutlineView
, EndMovingHdl
, ::Outliner
*, pOutliner
)
899 OutlineViewPageChangesGuard
aGuard(this);
901 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::EndMovingHdl(), model change without undo?!" );
903 // look for insertion position via the first paragraph
904 Paragraph
* pSearchIt
= maSelectedParas
.empty() ? NULL
: *(maSelectedParas
.begin());
906 // look for the first of the selected paragraphs in the new ordering
907 sal_uInt16 nPosNewOrder
= 0;
908 sal_Int32 nParaPos
= 0;
909 Paragraph
* pPara
= pOutliner
->GetParagraph( 0 );
910 Paragraph
* pPrev
= NULL
;
911 while (pPara
&& pPara
!= pSearchIt
)
913 if( pOutliner
->HasParaFlag(pPara
, PARAFLAG_ISPAGE
) )
918 pPara
= pOutliner
->GetParagraph( ++nParaPos
);
921 sal_uInt16 nPos
= nPosNewOrder
; // don't change nPosNewOrder
924 nPos
= (sal_uInt16
)-1; // insert before the first page
928 // look for the predecessor in the old ordering
929 std::vector
<Paragraph
*>::const_iterator it
= std::find(maOldParaOrder
.begin(),
930 maOldParaOrder
.end(),
933 if (it
!= maOldParaOrder
.end())
934 nPos
= static_cast<sal_uInt16
>(it
-maOldParaOrder
.begin());
938 DBG_ASSERT(nPos
!= 0xffff, "Paragraph not found");
941 mrDoc
.MovePages(nPos
);
943 // deselect the pages again
944 sal_uInt16 nPageCount
= (sal_uInt16
)maSelectedParas
.size();
947 SdPage
* pPage
= mrDoc
.GetSdPage(nPosNewOrder
, PK_STANDARD
);
948 pPage
->SetSelected(sal_False
);
953 pOutliner
->UpdateFields();
955 maSelectedParas
.clear();
956 maOldParaOrder
.clear();
958 InvalidateSlideNumberArea();
964 * Look for the title text object in one page of the model
966 SdrTextObj
* OutlineView::GetTitleTextObject(SdrPage
* pPage
)
968 sal_uLong nObjectCount
= pPage
->GetObjCount();
969 SdrObject
* pObject
= NULL
;
970 SdrTextObj
* pResult
= NULL
;
972 for (sal_uLong nObject
= 0; nObject
< nObjectCount
; nObject
++)
974 pObject
= pPage
->GetObj(nObject
);
975 if (pObject
->GetObjInventor() == SdrInventor
&&
976 pObject
->GetObjIdentifier() == OBJ_TITLETEXT
)
978 pResult
= (SdrTextObj
*)pObject
;
987 * Look for the outline text object in one page of the model
989 SdrTextObj
* OutlineView::GetOutlineTextObject(SdrPage
* pPage
)
991 sal_uLong nObjectCount
= pPage
->GetObjCount();
992 SdrObject
* pObject
= NULL
;
993 SdrTextObj
* pResult
= NULL
;
995 for (sal_uLong nObject
= 0; nObject
< nObjectCount
; nObject
++)
997 pObject
= pPage
->GetObj(nObject
);
998 if (pObject
->GetObjInventor() == SdrInventor
&&
999 pObject
->GetObjIdentifier() == OBJ_OUTLINETEXT
)
1001 pResult
= (SdrTextObj
*)pObject
;
1008 SdrTextObj
* OutlineView::CreateTitleTextObject(SdPage
* pPage
)
1010 DBG_ASSERT( GetTitleTextObject(pPage
) == 0, "sd::OutlineView::CreateTitleTextObject(), there is already a title text object!" );
1012 if( pPage
->GetAutoLayout() == AUTOLAYOUT_NONE
)
1015 pPage
->SetAutoLayout( AUTOLAYOUT_ONLY_TITLE
, true );
1019 // we already have a layout with a title but the title
1020 // object was deleted, create a new one
1021 pPage
->InsertAutoLayoutShape( 0, PRESOBJ_TITLE
, false, pPage
->GetTitleRect(), true );
1024 return GetTitleTextObject(pPage
);
1027 SdrTextObj
* OutlineView::CreateOutlineTextObject(SdPage
* pPage
)
1029 DBG_ASSERT( GetOutlineTextObject(pPage
) == 0, "sd::OutlineView::CreateOutlineTextObject(), there is already a layout text object!" );
1031 AutoLayout eNewLayout
= pPage
->GetAutoLayout();
1032 switch( eNewLayout
)
1034 case AUTOLAYOUT_NONE
:
1035 case AUTOLAYOUT_ONLY_TITLE
:
1036 case AUTOLAYOUT_TITLE
: eNewLayout
= AUTOLAYOUT_ENUM
; break;
1038 case AUTOLAYOUT_CHART
: eNewLayout
= AUTOLAYOUT_CHARTTEXT
; break;
1040 case AUTOLAYOUT_ORG
:
1041 case AUTOLAYOUT_TAB
:
1042 case AUTOLAYOUT_OBJ
: eNewLayout
= AUTOLAYOUT_OBJTEXT
; break;
1047 if( eNewLayout
!= pPage
->GetAutoLayout() )
1049 pPage
->SetAutoLayout( eNewLayout
, true );
1053 // we already have a layout with a text but the text
1054 // object was deleted, create a new one
1055 pPage
->InsertAutoLayoutShape( 0,
1056 (eNewLayout
== AUTOLAYOUT_TITLE
) ? PRESOBJ_TEXT
: PRESOBJ_OUTLINE
,
1057 false, pPage
->GetLayoutRect(), true );
1060 return GetOutlineTextObject(pPage
);
1063 /** updates draw model with all changes from outliner model */
1064 sal_Bool
OutlineView::PrepareClose(sal_Bool
)
1066 ::sd::UndoManager
* pDocUndoMgr
= dynamic_cast<sd::UndoManager
*>(mpDocSh
->GetUndoManager());
1067 if (pDocUndoMgr
!= NULL
)
1068 pDocUndoMgr
->SetLinkedUndoManager(NULL
);
1070 mrOutliner
.GetUndoManager().Clear();
1072 const String
aUndoStr(SdResId(STR_UNDO_CHANGE_TITLE_AND_LAYOUT
));
1076 mrDoc
.SetSelected(GetActualPage(), sal_True
);
1082 * Set attributes of the selected text
1084 sal_Bool
OutlineView::SetAttributes(const SfxItemSet
& rSet
, sal_Bool
)
1086 sal_Bool bOk
= sal_False
;
1088 OutlinerView
* pOlView
= GetViewByWindow(mrOutlineViewShell
.GetActiveWindow());
1092 pOlView
->SetAttribs(rSet
);
1096 mrOutlineViewShell
.Invalidate (SID_PREVIEW_STATE
);
1102 * Get attributes of the selected text
1104 sal_Bool
OutlineView::GetAttributes( SfxItemSet
& rTargetSet
, sal_Bool
) const
1106 OutlinerView
* pOlView
= GetViewByWindow(
1107 mrOutlineViewShell
.GetActiveWindow());
1108 DBG_ASSERT(pOlView
, "keine OutlinerView gefunden");
1110 rTargetSet
.Put( pOlView
->GetAttribs(), sal_False
);
1114 /** creates outliner model from draw model */
1115 void OutlineView::FillOutliner()
1117 mrOutliner
.GetUndoManager().Clear();
1118 mrOutliner
.EnableUndo(sal_False
);
1120 mrOutliner
.SetUpdateMode(false);
1122 Paragraph
* pTitleToSelect
= NULL
;
1123 sal_uLong nPageCount
= mrDoc
.GetSdPageCount(PK_STANDARD
);
1125 // fill outliner with paragraphs from slides title & (outlines|subtitles)
1126 for (sal_uInt16 nPage
= 0; nPage
< nPageCount
; nPage
++)
1128 SdPage
* pPage
= (SdPage
*)mrDoc
.GetSdPage(nPage
, PK_STANDARD
);
1129 Paragraph
* pPara
= NULL
;
1131 // take text from title shape
1132 SdrTextObj
* pTO
= GetTitleTextObject(pPage
);
1133 if(pTO
&& !(pTO
->IsEmptyPresObj()))
1135 OutlinerParaObject
* pOPO
= pTO
->GetOutlinerParaObject();
1138 sal_Bool bVertical
= pOPO
->IsVertical();
1139 pOPO
->SetVertical( sal_False
);
1140 mrOutliner
.AddText(*pOPO
);
1141 pOPO
->SetVertical( bVertical
);
1142 pPara
= mrOutliner
.GetParagraph( mrOutliner
.GetParagraphCount()-1 );
1146 if( pPara
== 0 ) // no title, insert an empty paragraph
1148 pPara
= mrOutliner
.Insert(String());
1149 mrOutliner
.SetDepth(pPara
, -1);
1151 // do not apply hard attributes from the previous paragraph
1152 mrOutliner
.SetParaAttribs( mrOutliner
.GetAbsPos(pPara
),
1153 mrOutliner
.GetEmptyItemSet() );
1155 mrOutliner
.SetStyleSheet( mrOutliner
.GetAbsPos( pPara
), pPage
->GetStyleSheetForPresObj( PRESOBJ_TITLE
) );
1158 mrOutliner
.SetParaFlag( pPara
, PARAFLAG_ISPAGE
);
1160 sal_Int32 nPara
= mrOutliner
.GetAbsPos( pPara
);
1162 UpdateParagraph( nPara
);
1164 // remember paragraph of currently selected page
1165 if (pPage
->IsSelected())
1166 pTitleToSelect
= pPara
;
1168 // take text from subtitle or outline
1169 pTO
= static_cast<SdrTextObj
*>(pPage
->GetPresObj(PRESOBJ_TEXT
));
1170 const bool bSubTitle
= pTO
!= 0;
1172 if (!pTO
) // if no subtile found, try outline
1173 pTO
= GetOutlineTextObject(pPage
);
1175 if(pTO
&& !(pTO
->IsEmptyPresObj())) // found some text
1177 OutlinerParaObject
* pOPO
= pTO
->GetOutlinerParaObject();
1180 sal_Int32 nParaCount1
= mrOutliner
.GetParagraphCount();
1181 sal_Bool bVertical
= pOPO
->IsVertical();
1182 pOPO
->SetVertical( sal_False
);
1183 mrOutliner
.AddText(*pOPO
);
1184 pOPO
->SetVertical( bVertical
);
1186 sal_Int32 nParaCount2
= mrOutliner
.GetParagraphCount();
1187 for (sal_Int32 n
= nParaCount1
; n
< nParaCount2
; n
++)
1191 Paragraph
* p
= mrOutliner
.GetParagraph(n
);
1192 if(p
&& mrOutliner
.GetDepth( n
) > 0 )
1193 mrOutliner
.SetDepth(p
, 0);
1196 UpdateParagraph( n
);
1202 // place cursor at the start
1203 Paragraph
* pFirstPara
= mrOutliner
.GetParagraph( 0 );
1204 mpOutlinerView
[0]->Select( pFirstPara
, sal_True
, sal_False
);
1205 mpOutlinerView
[0]->Select( pFirstPara
, sal_False
, sal_False
);
1207 // select title of slide that was selected
1209 mpOutlinerView
[0]->Select(pTitleToSelect
, sal_True
, sal_False
);
1213 mrOutliner
.EnableUndo(sal_True
);
1215 mrOutliner
.SetUpdateMode(true);
1219 * Handler for deleting of level 0 paragraphs (pages): Warning
1221 IMPL_LINK_NOARG(OutlineView
, RemovingPagesHdl
)
1223 sal_Int32 nNumOfPages
= mrOutliner
.GetSelPageCount();
1225 if (nNumOfPages
> PROCESS_WITH_PROGRESS_THRESHOLD
)
1227 mnPagesToProcess
= nNumOfPages
;
1228 mnPagesProcessed
= 0;
1231 if (mnPagesToProcess
)
1236 String
aStr(SdResId(STR_DELETE_PAGES
));
1237 mpProgress
= new SfxProgress( GetDocSh(), aStr
, mnPagesToProcess
);
1239 mrOutliner
.UpdateFields();
1241 InvalidateSlideNumberArea();
1247 * Handler for indenting level 0 paragraphs (pages): Warning
1249 IMPL_LINK_INLINE_START( OutlineView
, IndentingPagesHdl
, OutlinerView
*, pOutlinerView
)
1251 return RemovingPagesHdl(pOutlinerView
);
1253 IMPL_LINK_INLINE_END( OutlineView
, IndentingPagesHdl
, OutlinerView
*, pOutlinerView
)
1256 /** returns the first slide that is selected in the outliner or where
1257 the cursor is located */
1258 SdPage
* OutlineView::GetActualPage()
1260 ::sd::Window
* pWin
= mrOutlineViewShell
.GetActiveWindow();
1261 OutlinerView
* pActiveView
= GetViewByWindow(pWin
);
1263 std::vector
<Paragraph
*> aSelList
;
1264 pActiveView
->CreateSelectionList(aSelList
);
1266 Paragraph
*pPar
= aSelList
.empty() ? NULL
: *(aSelList
.begin());
1267 SdPage
* pCurrent
= GetPageForParagraph(pPar
);
1269 DBG_ASSERT( pCurrent
||
1270 (mpDocSh
->GetUndoManager() && static_cast< sd::UndoManager
*>(mpDocSh
->GetUndoManager())->IsDoing()) ||
1271 maDragAndDropModelGuard
.get(),
1272 "sd::OutlineView::GetActualPage(), no current page?" );
1277 return mrDoc
.GetSdPage( 0, PK_STANDARD
);
1280 SdPage
* OutlineView::GetPageForParagraph( Paragraph
* pPara
)
1282 if( !mrOutliner
.HasParaFlag(pPara
,PARAFLAG_ISPAGE
) )
1283 pPara
= GetPrevTitle(pPara
);
1285 sal_uInt32 nPageToSelect
= 0;
1288 pPara
= GetPrevTitle(pPara
);
1293 if( nPageToSelect
< (sal_uInt32
)mrDoc
.GetSdPageCount( PK_STANDARD
) )
1294 return static_cast< SdPage
* >( mrDoc
.GetSdPage( (sal_uInt16
)nPageToSelect
, PK_STANDARD
) );
1299 Paragraph
* OutlineView::GetParagraphForPage( ::Outliner
& rOutl
, SdPage
* pPage
)
1301 // get the number of paragraphs with ident 0 we need to skip before
1302 // we finde the actual page
1303 sal_uInt32 nPagesToSkip
= (pPage
->GetPageNum() - 1) >> 1;
1305 sal_Int32 nParaPos
= 0;
1306 Paragraph
* pPara
= rOutl
.GetParagraph( 0 );
1309 // if this paragraph is a page ...
1310 if( mrOutliner
.HasParaFlag(pPara
,PARAFLAG_ISPAGE
) )
1312 // see if we already skiped enough pages
1313 if( 0 == nPagesToSkip
)
1314 break; // and if so, end the loop
1316 // we skiped another page
1320 // get next paragraph
1321 pPara
= mrOutliner
.GetParagraph( ++nParaPos
);
1327 /** selects the paragraph for the given page at the outliner view*/
1328 void OutlineView::SetActualPage( SdPage
* pActual
)
1330 if( pActual
&& dynamic_cast<Outliner
&>(mrOutliner
).GetIgnoreCurrentPageChangesLevel()==0 && !mbFirstPaint
)
1332 // if we found a paragraph, select its text at the outliner view
1333 Paragraph
* pPara
= GetParagraphForPage( mrOutliner
, pActual
);
1335 mpOutlinerView
[0]->Select( pPara
, sal_True
, sal_False
);
1340 * Get StyleSheet from the selection
1342 SfxStyleSheet
* OutlineView::GetStyleSheet() const
1344 ::sd::Window
* pActWin
= mrOutlineViewShell
.GetActiveWindow();
1345 OutlinerView
* pOlView
= GetViewByWindow(pActWin
);
1346 SfxStyleSheet
* pResult
= pOlView
->GetStyleSheet();
1353 * Mark pages as selected / not selected
1355 void OutlineView::SetSelectedPages()
1357 // list of selected title paragraphs
1358 std::vector
<Paragraph
*> aSelParas
;
1359 mpOutlinerView
[0]->CreateSelectionList(aSelParas
);
1361 for (std::vector
<Paragraph
*>::iterator it
= aSelParas
.begin(); it
!= aSelParas
.end();)
1363 if (!mrOutliner
.HasParaFlag(*it
, PARAFLAG_ISPAGE
))
1364 it
= aSelParas
.erase(it
);
1369 // select the pages belonging to the paragraphs on level 0 to select
1370 sal_uInt16 nPos
= 0;
1371 sal_Int32 nParaPos
= 0;
1372 Paragraph
*pPara
= mrOutliner
.GetParagraph( 0 );
1373 std::vector
<Paragraph
*>::const_iterator fiter
;
1377 if( mrOutliner
.HasParaFlag(pPara
, PARAFLAG_ISPAGE
) ) // one page
1379 SdPage
* pPage
= mrDoc
.GetSdPage(nPos
, PK_STANDARD
);
1380 DBG_ASSERT(pPage
!=NULL
,
1381 "Trying to select non-existing page OutlineView::SetSelectedPages()");
1385 fiter
= std::find(aSelParas
.begin(),aSelParas
.end(),pPara
);
1386 pPage
->SetSelected(fiter
!= aSelParas
.end());
1392 pPara
= mrOutliner
.GetParagraph( ++nParaPos
);
1400 void OutlineView::SetLinks()
1402 // set notification links
1403 mrOutliner
.SetParaInsertedHdl(LINK(this, OutlineView
, ParagraphInsertedHdl
));
1404 mrOutliner
.SetParaRemovingHdl(LINK(this, OutlineView
, ParagraphRemovingHdl
));
1405 mrOutliner
.SetDepthChangedHdl(LINK(this, OutlineView
, DepthChangedHdl
));
1406 mrOutliner
.SetBeginMovingHdl(LINK(this, OutlineView
, BeginMovingHdl
));
1407 mrOutliner
.SetEndMovingHdl(LINK(this, OutlineView
, EndMovingHdl
));
1408 mrOutliner
.SetRemovingPagesHdl(LINK(this, OutlineView
, RemovingPagesHdl
));
1409 mrOutliner
.SetIndentingPagesHdl(LINK(this, OutlineView
, IndentingPagesHdl
));
1410 mrOutliner
.SetStatusEventHdl(LINK(this, OutlineView
, StatusEventHdl
));
1411 mrOutliner
.SetBeginDropHdl(LINK(this,OutlineView
, BeginDropHdl
));
1412 mrOutliner
.SetEndDropHdl(LINK(this,OutlineView
, EndDropHdl
));
1413 mrOutliner
.SetPaintFirstLineHdl(LINK(this,OutlineView
,PaintingFirstLineHdl
));
1414 mrOutliner
.SetBeginPasteOrDropHdl(LINK(this,OutlineView
, BeginPasteOrDropHdl
));
1415 mrOutliner
.SetEndPasteOrDropHdl(LINK(this,OutlineView
, EndPasteOrDropHdl
));
1423 void OutlineView::ResetLinks() const
1426 mrOutliner
.SetParaInsertedHdl(aEmptyLink
);
1427 mrOutliner
.SetParaRemovingHdl(aEmptyLink
);
1428 mrOutliner
.SetDepthChangedHdl(aEmptyLink
);
1429 mrOutliner
.SetBeginMovingHdl(aEmptyLink
);
1430 mrOutliner
.SetEndMovingHdl(aEmptyLink
);
1431 mrOutliner
.SetStatusEventHdl(aEmptyLink
);
1432 mrOutliner
.SetRemovingPagesHdl(aEmptyLink
);
1433 mrOutliner
.SetIndentingPagesHdl(aEmptyLink
);
1434 mrOutliner
.SetDrawPortionHdl(aEmptyLink
);
1435 mrOutliner
.SetBeginPasteOrDropHdl(aEmptyLink
);
1436 mrOutliner
.SetEndPasteOrDropHdl(aEmptyLink
);
1440 sal_Int8
OutlineView::AcceptDrop( const AcceptDropEvent
&, DropTargetHelper
&, ::sd::Window
*, sal_uInt16
, sal_uInt16
)
1442 return DND_ACTION_NONE
;
1446 sal_Int8
OutlineView::ExecuteDrop( const ExecuteDropEvent
&, DropTargetHelper
&, ::sd::Window
*, sal_uInt16
, sal_uInt16
)
1448 return DND_ACTION_NONE
;
1451 // Re-implement GetScriptType for this view to get correct results
1452 sal_uInt16
OutlineView::GetScriptType() const
1454 sal_uInt16 nScriptType
= ::sd::View::GetScriptType();
1456 OutlinerParaObject
* pTempOPObj
= mrOutliner
.CreateParaObject();
1459 nScriptType
= pTempOPObj
->GetTextObject().GetScriptType();
1466 void OutlineView::onUpdateStyleSettings( bool bForceUpdate
/* = false */ )
1468 svtools::ColorConfig aColorConfig
;
1469 const Color
aDocColor( aColorConfig
.GetColorValue( svtools::DOCCOLOR
).nColor
);
1470 if( bForceUpdate
|| (maDocColor
!= aDocColor
) )
1473 for( nView
= 0; nView
< MAX_OUTLINERVIEWS
; nView
++ )
1475 if (mpOutlinerView
[nView
] != NULL
)
1477 mpOutlinerView
[nView
]->SetBackgroundColor( aDocColor
);
1479 ::Window
* pWindow
= mpOutlinerView
[nView
]->GetWindow();
1482 pWindow
->SetBackground( Wallpaper( aDocColor
) );
1487 mrOutliner
.SetBackgroundColor( aDocColor
);
1489 maDocColor
= aDocColor
;
1493 IMPL_LINK_NOARG(OutlineView
, AppEventListenerHdl
)
1495 onUpdateStyleSettings();
1502 IMPL_LINK(OutlineView
, EventMultiplexerListener
, ::sd::tools::EventMultiplexerEvent
*, pEvent
)
1506 switch (pEvent
->meEventId
)
1508 case tools::EventMultiplexerEvent::EID_CURRENT_PAGE
:
1509 SetActualPage(mrOutlineViewShell
.GetActualPage());
1510 InvalidateSlideNumberArea();
1513 case tools::EventMultiplexerEvent::EID_PAGE_ORDER
:
1514 if (dynamic_cast<Outliner
&>(mrOutliner
).GetIgnoreCurrentPageChangesLevel()==0)
1516 if (((mrDoc
.GetPageCount()-1)%2) == 0)
1520 ::sd::Window
* pWindow
= mrOutlineViewShell
.GetActiveWindow();
1521 if (pWindow
!= NULL
)
1522 pWindow
->Invalidate();
1531 void OutlineView::IgnoreCurrentPageChanges (bool bIgnoreChanges
)
1534 dynamic_cast<Outliner
&>(mrOutliner
).IncreIgnoreCurrentPageChangesLevel();
1536 dynamic_cast<Outliner
&>(mrOutliner
).DecreIgnoreCurrentPageChangesLevel();
1539 /** call this method before you do anything that can modify the outliner
1540 and or the drawing document model. It will create needed undo actions */
1541 void OutlineView::BeginModelChange()
1543 const String aEmpty
;
1544 mrOutliner
.GetUndoManager().EnterListAction(aEmpty
,aEmpty
);
1545 const String
aUndoStr(SdResId(STR_UNDO_CHANGE_TITLE_AND_LAYOUT
));
1549 /** call this method after BeginModelChange(), when all possible model
1550 changes are done. */
1551 void OutlineView::EndModelChange()
1555 ::svl::IUndoManager
* pDocUndoMgr
= mpDocSh
->GetUndoManager();
1557 bool bHasUndoActions
= pDocUndoMgr
->GetUndoActionCount() != 0;
1561 DBG_ASSERT( bHasUndoActions
== (mrOutliner
.GetUndoManager().GetUndoActionCount() != 0), "sd::OutlineView::EndModelChange(), undo actions not in sync!" );
1563 mrOutliner
.GetUndoManager().LeaveListAction();
1565 if( bHasUndoActions
&& mrOutliner
.GetEditEngine().HasTriedMergeOnLastAddUndo() )
1566 TryToMergeUndoActions();
1568 mrOutlineViewShell
.Invalidate( SID_UNDO
);
1569 mrOutlineViewShell
.Invalidate( SID_REDO
);
1572 /** updates all changes in the outliner model to the draw model */
1573 void OutlineView::UpdateDocument()
1575 const sal_uInt32 nPageCount
= mrDoc
.GetSdPageCount(PK_STANDARD
);
1576 Paragraph
* pPara
= mrOutliner
.GetParagraph( 0 );
1578 for (nPage
= 0; nPage
< nPageCount
; nPage
++)
1580 SdPage
* pPage
= mrDoc
.GetSdPage( (sal_uInt16
)nPage
, PK_STANDARD
);
1581 mrDoc
.SetSelected(pPage
, sal_False
);
1583 mrOutlineViewShell
.UpdateTitleObject( pPage
, pPara
);
1584 mrOutlineViewShell
.UpdateOutlineObject( pPage
, pPara
);
1587 pPara
= GetNextTitle(pPara
);
1590 DBG_ASSERT( pPara
== 0, "sd::OutlineView::UpdateDocument(), slides are out of sync, creating missing ones" );
1593 SdPage
* pPage
= InsertSlideForParagraph( pPara
);
1594 mrDoc
.SetSelected(pPage
, sal_False
);
1596 mrOutlineViewShell
.UpdateTitleObject( pPage
, pPara
);
1597 mrOutlineViewShell
.UpdateOutlineObject( pPage
, pPara
);
1600 pPara
= GetNextTitle(pPara
);
1604 /** merge edit engine undo actions if possible */
1605 void OutlineView::TryToMergeUndoActions()
1607 ::svl::IUndoManager
& rOutlineUndo
= mrOutliner
.GetUndoManager();
1608 if( rOutlineUndo
.GetUndoActionCount() > 1 )
1610 SfxListUndoAction
* pListAction
= dynamic_cast< SfxListUndoAction
* >( rOutlineUndo
.GetUndoAction(0) );
1611 SfxListUndoAction
* pPrevListAction
= dynamic_cast< SfxListUndoAction
* >( rOutlineUndo
.GetUndoAction(1) );
1612 if( pListAction
&& pPrevListAction
)
1614 // find the top EditUndo action in the top undo action list
1615 size_t nAction
= pListAction
->aUndoActions
.size();
1616 EditUndo
* pEditUndo
= 0;
1617 while( !pEditUndo
&& nAction
)
1619 pEditUndo
= dynamic_cast< EditUndo
* >(pListAction
->aUndoActions
[--nAction
].pAction
);
1622 sal_uInt16 nEditPos
= nAction
; // we need this later to remove the merged undo actions
1624 // make sure it is the only EditUndo action in the top undo list
1625 while( pEditUndo
&& nAction
)
1627 if( dynamic_cast< EditUndo
* >(pListAction
->aUndoActions
[--nAction
].pAction
) )
1631 // do we have one and only one EditUndo action in the top undo list?
1634 // yes, see if we can merge it with the prev undo list
1636 nAction
= pPrevListAction
->aUndoActions
.size();
1637 EditUndo
* pPrevEditUndo
= 0;
1638 while( !pPrevEditUndo
&& nAction
)
1639 pPrevEditUndo
= dynamic_cast< EditUndo
* >(pPrevListAction
->aUndoActions
[--nAction
].pAction
);
1641 if( pPrevEditUndo
&& pPrevEditUndo
->Merge( pEditUndo
) )
1643 // ok we merged the only EditUndo of the top undo list with
1644 // the top EditUndo of the previous undo list
1646 // first remove the merged undo action
1647 DBG_ASSERT( pListAction
->aUndoActions
[nEditPos
].pAction
== pEditUndo
,
1648 "sd::OutlineView::TryToMergeUndoActions(), wrong edit pos!" );
1649 pListAction
->aUndoActions
.Remove(nEditPos
);
1652 // now check if we also can merge the draw undo actions
1653 ::svl::IUndoManager
* pDocUndoManager
= mpDocSh
->GetUndoManager();
1654 if( pDocUndoManager
&& ( pListAction
->aUndoActions
.size() == 1 ))
1656 SfxLinkUndoAction
* pLinkAction
= dynamic_cast< SfxLinkUndoAction
* >( pListAction
->aUndoActions
[0].pAction
);
1657 SfxLinkUndoAction
* pPrevLinkAction
= 0;
1661 nAction
= pPrevListAction
->aUndoActions
.size();
1662 while( !pPrevLinkAction
&& nAction
)
1663 pPrevLinkAction
= dynamic_cast< SfxLinkUndoAction
* >(pPrevListAction
->aUndoActions
[--nAction
].pAction
);
1666 if( pLinkAction
&& pPrevLinkAction
&&
1667 ( pLinkAction
->GetAction() == pDocUndoManager
->GetUndoAction(0) ) &&
1668 ( pPrevLinkAction
->GetAction() == pDocUndoManager
->GetUndoAction(1) ) )
1670 SfxListUndoAction
* pSourceList
= dynamic_cast< SfxListUndoAction
* >(pLinkAction
->GetAction());
1671 SfxListUndoAction
* pDestinationList
= dynamic_cast< SfxListUndoAction
* >(pPrevLinkAction
->GetAction());
1673 if( pSourceList
&& pDestinationList
)
1675 sal_uInt16 nCount
= pSourceList
->aUndoActions
.size();
1676 sal_uInt16 nDestAction
= pDestinationList
->aUndoActions
.size();
1679 SfxUndoAction
* pTemp
= pSourceList
->aUndoActions
[0].pAction
;
1680 pSourceList
->aUndoActions
.Remove(0);
1681 pDestinationList
->aUndoActions
.Insert( pTemp
, nDestAction
++ );
1683 pDestinationList
->nCurUndoAction
= pDestinationList
->aUndoActions
.size();
1685 pListAction
->aUndoActions
.Remove(0);
1688 pDocUndoManager
->RemoveLastUndoAction();
1693 if ( !pListAction
->aUndoActions
.empty() )
1695 // now we have to move all remaining doc undo actions from the top undo
1696 // list to the previous undo list and remove the top undo list
1698 size_t nCount
= pListAction
->aUndoActions
.size();
1699 size_t nDestAction
= pPrevListAction
->aUndoActions
.size();
1702 SfxUndoAction
* pTemp
= pListAction
->aUndoActions
[0].pAction
;
1703 pListAction
->aUndoActions
.Remove(0);
1705 pPrevListAction
->aUndoActions
.Insert( pTemp
, nDestAction
++ );
1707 pPrevListAction
->nCurUndoAction
= pPrevListAction
->aUndoActions
.size();
1710 rOutlineUndo
.RemoveLastUndoAction();
1717 IMPL_LINK(OutlineView
, PaintingFirstLineHdl
, PaintFirstLineInfo
*, pInfo
)
1721 Paragraph
* pPara
= mrOutliner
.GetParagraph( pInfo
->mnPara
);
1722 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( mrOutliner
.GetEditEngine() );
1724 Size
aImageSize( pInfo
->mpOutDev
->PixelToLogic( maSlideImage
.GetSizePixel() ) );
1725 Size
aOffset( 100, 100 );
1727 // paint slide number
1728 if( pPara
&& mrOutliner
.HasParaFlag(pPara
,PARAFLAG_ISPAGE
) )
1730 long nPage
= 0; // todo, printing??
1731 for ( sal_Int32 n
= 0; n
<= pInfo
->mnPara
; n
++ )
1733 Paragraph
* p
= mrOutliner
.GetParagraph( n
);
1734 if ( mrOutliner
.HasParaFlag(p
,PARAFLAG_ISPAGE
) )
1738 long nBulletHeight
= (long)mrOutliner
.GetLineHeight( pInfo
->mnPara
);
1739 long nFontHeight
= 0;
1740 if ( !rEditEngine
.IsFlatMode() )
1742 nFontHeight
= nBulletHeight
/ 5;
1746 nFontHeight
= (nBulletHeight
* 10) / 25;
1749 Size
aFontSz( 0, nFontHeight
);
1751 Size
aOutSize( 2000, nBulletHeight
);
1753 const float fImageHeight
= ((float)aOutSize
.Height() * (float)4) / (float)7;
1754 const float fImageRatio
= (float)aImageSize
.Height() / (float)aImageSize
.Width();
1755 aImageSize
.Width() = (long)( fImageRatio
* fImageHeight
);
1756 aImageSize
.Height() = (long)( fImageHeight
);
1758 Point
aImagePos( pInfo
->mrStartPos
);
1759 aImagePos
.X() += aOutSize
.Width() - aImageSize
.Width() - aOffset
.Width() ;
1760 aImagePos
.Y() += (aOutSize
.Height() - aImageSize
.Height()) / 2;
1762 pInfo
->mpOutDev
->DrawImage( aImagePos
, aImageSize
, maSlideImage
);
1764 const bool bVertical
= mrOutliner
.IsVertical();
1765 const bool bRightToLeftPara
= rEditEngine
.IsRightToLeft( pInfo
->mnPara
);
1767 LanguageType eLang
= rEditEngine
.GetDefaultLanguage();
1769 Point
aTextPos( aImagePos
.X() - aOffset
.Width(), pInfo
->mrStartPos
.Y() );
1770 Font
aNewFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SANS_UNICODE
, eLang
, 0 ) );
1771 aNewFont
.SetSize( aFontSz
);
1772 aNewFont
.SetVertical( bVertical
);
1773 aNewFont
.SetOrientation( bVertical
? 2700 : 0 );
1774 aNewFont
.SetColor( COL_AUTO
);
1775 pInfo
->mpOutDev
->SetFont( aNewFont
);
1776 String aPageText
= OUString::number( nPage
);
1778 aTextSz
.Width() = pInfo
->mpOutDev
->GetTextWidth( aPageText
);
1779 aTextSz
.Height() = pInfo
->mpOutDev
->GetTextHeight();
1782 aTextPos
.Y() += (aOutSize
.Height() - aTextSz
.Height()) / 2;
1783 if ( !bRightToLeftPara
)
1785 aTextPos
.X() -= aTextSz
.Width();
1789 aTextPos
.X() += aTextSz
.Width();
1794 aTextPos
.Y() -= aTextSz
.Width();
1795 aTextPos
.X() += nBulletHeight
/ 2;
1797 pInfo
->mpOutDev
->DrawText( aTextPos
, aPageText
);
1804 // --------------------------------------------------------------------
1806 void OutlineView::UpdateParagraph( sal_Int32 nPara
)
1808 SfxItemSet
aNewAttrs2( mrOutliner
.GetParaAttribs( nPara
) );
1809 aNewAttrs2
.Put( maLRSpaceItem
);
1810 mrOutliner
.SetParaAttribs( nPara
, aNewAttrs2
);
1813 // --------------------------------------------------------------------
1815 void OutlineView::OnBeginPasteOrDrop( PasteOrDropInfos
* /*pInfos*/ )
1819 /** this is called after a paste or drop operation, make sure that the newly inserted paragraphs
1820 get the correct style sheet and new slides are inserted. */
1821 void OutlineView::OnEndPasteOrDrop( PasteOrDropInfos
* pInfos
)
1824 SfxStyleSheetBasePool
* pStylePool
= GetDoc().GetStyleSheetPool();
1826 for( sal_Int32 nPara
= pInfos
->nStartPara
; nPara
<= pInfos
->nEndPara
; nPara
++ )
1828 Paragraph
* pPara
= mrOutliner
.GetParagraph( nPara
);
1830 bool bPage
= mrOutliner
.HasParaFlag( pPara
, PARAFLAG_ISPAGE
);
1834 SdStyleSheet
* pStyleSheet
= dynamic_cast< SdStyleSheet
* >( mrOutliner
.GetStyleSheet( nPara
) );
1837 const OUString
aName( pStyleSheet
->GetApiName() );
1838 if ( aName
== "title" )
1844 continue; // fatality!?
1846 if( bPage
&& (nPara
!= pInfos
->nStartPara
) )
1848 // insert new slide for this paragraph
1849 pPage
= InsertSlideForParagraph( pPara
);
1853 // newly inserted non page paragraphs get the outline style
1855 pPage
= GetPageForParagraph( pPara
);
1859 SfxStyleSheet
* pStyle
= pPage
->GetStyleSheetForPresObj( bPage
? PRESOBJ_TITLE
: PRESOBJ_OUTLINE
);
1863 const sal_Int16 nDepth
= mrOutliner
.GetDepth( nPara
);
1866 String
aStyleSheetName( pStyle
->GetName() );
1867 aStyleSheetName
.Erase( aStyleSheetName
.Len() - 1, 1 );
1868 aStyleSheetName
+= OUString::number( nDepth
);
1869 pStyle
= static_cast<SfxStyleSheet
*>( pStylePool
->Find( aStyleSheetName
, pStyle
->GetFamily() ) );
1870 DBG_ASSERT( pStyle
, "sd::OutlineView::OnEndPasteOrDrop(), Style not found!" );
1874 mrOutliner
.SetStyleSheet( nPara
, pStyle
);
1877 UpdateParagraph( nPara
);
1882 // ====================================================================
1885 OutlineViewModelChangeGuard::OutlineViewModelChangeGuard( OutlineView
& rView
)
1888 mrView
.BeginModelChange();
1891 OutlineViewModelChangeGuard::~OutlineViewModelChangeGuard()
1893 mrView
.EndModelChange();
1896 OutlineViewPageChangesGuard::OutlineViewPageChangesGuard( OutlineView
* pView
)
1900 mpView
->IgnoreCurrentPageChanges( true );
1903 OutlineViewPageChangesGuard::~OutlineViewPageChangesGuard()
1906 mpView
->IgnoreCurrentPageChanges( false );
1910 } // end of namespace sd
1912 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */