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 .
20 #include "OutlineView.hxx"
21 #include <editeng/forbiddencharacterstable.hxx>
22 #include <sfx2/progress.hxx>
23 #include <vcl/wrkwin.hxx>
24 #include <svx/svxids.hrc>
25 #include <editeng/outliner.hxx>
26 #include <editeng/eeitem.hxx>
27 #include <editeng/editstat.hxx>
28 #include <editeng/lrspitem.hxx>
29 #include <svx/svdotext.hxx>
30 #include <sfx2/printer.hxx>
31 #include <sfx2/imagemgr.hxx>
32 #include <sfx2/app.hxx>
33 #include <sfx2/bindings.hxx>
34 #include <svl/itempool.hxx>
35 #include <svl/style.hxx>
36 #include <svx/svdorect.hxx>
37 #include <svx/svdundo.hxx>
38 #include <vcl/msgbox.hxx>
39 #include <editeng/adjustitem.hxx>
40 #include <editeng/tstpitem.hxx>
41 #include <editeng/lspcitem.hxx>
42 #include <editeng/numitem.hxx>
43 #include <editeng/outlobj.hxx>
44 #include <editeng/editeng.hxx>
46 #include <editeng/editobj.hxx>
47 #include <editeng/editund2.hxx>
49 #include <editeng/editview.hxx>
50 #include <editeng/svxfont.hxx>
51 #include <editeng/fhgtitem.hxx>
53 #include "DrawDocShell.hxx"
54 #include "drawdoc.hxx"
58 #include "OutlineViewShell.hxx"
61 #include "sdresid.hxx"
62 #include "Outliner.hxx"
63 #include "strings.hrc"
64 #include "EventMultiplexer.hxx"
65 #include "ViewShellBase.hxx"
66 #include "ViewShellManager.hxx"
67 #include "undo/undoobjects.hxx"
68 #include "undo/undomanager.hxx"
69 #include "stlsheet.hxx"
71 using namespace ::com::sun::star::uno
;
72 using namespace ::com::sun::star::frame
;
76 // a progress bar gets displayed when more than
77 // PROCESS_WITH_PROGRESS_THRESHOLD pages are concerned
78 #define PROCESS_WITH_PROGRESS_THRESHOLD 5
88 TYPEINIT1( OutlineView
, ::sd::View
);
90 OutlineView::OutlineView( DrawDocShell
& rDocSh
, vcl::Window
* pWindow
, OutlineViewShell
& rOutlineViewShell
)
91 : ::sd::View(*rDocSh
.GetDoc(), pWindow
, &rOutlineViewShell
)
92 , mrOutlineViewShell(rOutlineViewShell
)
93 , mrOutliner(*mrDoc
.GetOutliner(true))
98 , maDocColor( COL_WHITE
)
99 , maLRSpaceItem( 0, 0, 2000, 0, EE_PARA_OUTLLRSPACE
)
101 bool bInitOutliner
= false;
103 if (mrOutliner
.GetViewCount() == 0)
105 // initialize Outliner: set Reference Device
106 bInitOutliner
= true;
107 mrOutliner
.Init( OUTLINERMODE_OUTLINEVIEW
);
108 mrOutliner
.SetRefDevice( SD_MOD()->GetRefDevice( rDocSh
) );
109 //viewsize without the width of the image and number in front
110 mnPaperWidth
= (mrOutlineViewShell
.GetActiveWindow()->GetViewSize().Width() - 4000);
111 mrOutliner
.SetPaperSize(Size(mnPaperWidth
, 400000000));
114 // insert View into Outliner
115 for (sal_uInt16 nView
= 0; nView
< MAX_OUTLINERVIEWS
; nView
++)
117 mpOutlinerView
[nView
] = NULL
;
120 mpOutlinerView
[0] = new OutlinerView(&mrOutliner
, pWindow
);
122 mpOutlinerView
[0]->SetOutputArea(aNullRect
);
123 mrOutliner
.SetUpdateMode(false);
124 mrOutliner
.InsertView(mpOutlinerView
[0], EE_APPEND
);
126 onUpdateStyleSettings( true );
130 // fill Outliner with contents
134 Link
<> aLink( LINK(this,OutlineView
,EventMultiplexerListener
) );
135 mrOutlineViewShell
.GetViewShellBase().GetEventMultiplexer()->AddEventListener(
137 tools::EventMultiplexerEvent::EID_CURRENT_PAGE
138 | tools::EventMultiplexerEvent::EID_PAGE_ORDER
);
140 LanguageType eLang
= mrOutliner
.GetDefaultLanguage();
141 maPageNumberFont
= OutputDevice::GetDefaultFont( DefaultFontType::SANS_UNICODE
, eLang
, GetDefaultFontFlags::NONE
);
142 maPageNumberFont
.SetHeight( 500 );
144 maBulletFont
.SetColor( COL_AUTO
);
145 maBulletFont
.SetHeight( 1000 );
146 maBulletFont
.SetCharSet(RTL_TEXTENCODING_MS_1252
); // and replacing other values by standard
147 maBulletFont
.SetName( OUString( "StarSymbol" ) );
148 maBulletFont
.SetWeight(WEIGHT_NORMAL
);
149 maBulletFont
.SetUnderline(UNDERLINE_NONE
);
150 maBulletFont
.SetStrikeout(STRIKEOUT_NONE
);
151 maBulletFont
.SetItalic(ITALIC_NONE
);
152 maBulletFont
.SetOutline(false);
153 maBulletFont
.SetShadow(false);
155 Reference
<XFrame
> xFrame (mrOutlineViewShell
.GetViewShellBase().GetFrame()->GetTopFrame().GetFrameInterface(), UNO_QUERY
);
157 const OUString
aSlotURL( ".uno:ShowSlide" );
158 maSlideImage
= GetImage( xFrame
, aSlotURL
, true );
160 // Tell undo manager of the document about the undo manager of the
161 // outliner, so that the former can synchronize with the later.
162 sd::UndoManager
* pDocUndoMgr
= dynamic_cast<sd::UndoManager
*>(mpDocSh
->GetUndoManager());
163 if (pDocUndoMgr
!= NULL
)
164 pDocUndoMgr
->SetLinkedUndoManager(&mrOutliner
.GetUndoManager());
168 * Destructor, restore Links, clear Oultiner
170 OutlineView::~OutlineView()
172 DBG_ASSERT(maDragAndDropModelGuard
.get() == 0, "sd::OutlineView::~OutlineView(), prior drag operation not finished correctly!" );
174 Link
<> aLink( LINK(this,OutlineView
,EventMultiplexerListener
) );
175 mrOutlineViewShell
.GetViewShellBase().GetEventMultiplexer()->RemoveEventListener( aLink
);
176 DisconnectFromApplication();
181 // unregister OutlinerViews and destroy them
182 for (sal_uInt16 nView
= 0; nView
< MAX_OUTLINERVIEWS
; nView
++)
184 if (mpOutlinerView
[nView
] != NULL
)
186 mrOutliner
.RemoveView( mpOutlinerView
[nView
] );
187 delete mpOutlinerView
[nView
];
188 mpOutlinerView
[nView
] = NULL
;
192 if (mrOutliner
.GetViewCount() == 0)
194 // uninitialize Outliner: enable color display
196 EEControlBits nCntrl
= mrOutliner
.GetControlWord();
197 mrOutliner
.SetUpdateMode(false); // otherwise there will be drawn on SetControlWord
198 mrOutliner
.SetControlWord(nCntrl
& ~EEControlBits::NOCOLORS
);
199 SvtAccessibilityOptions aOptions
;
200 mrOutliner
.ForceAutoColor( aOptions
.GetIsAutomaticFontColor() );
205 void OutlineView::ConnectToApplication()
207 // When the mode is switched to outline the main view shell grabs focus.
208 // This is done for getting cut/copy/paste commands on slides in the left
209 // pane (slide sorter view shell) to work properly.
210 SfxShell
* pTopViewShell
= mrOutlineViewShell
.GetViewShellBase().GetViewShellManager()->GetTopViewShell();
211 if (pTopViewShell
&& pTopViewShell
== &mrOutlineViewShell
)
213 mrOutlineViewShell
.GetActiveWindow()->GrabFocus();
216 Application::AddEventListener(LINK(this, OutlineView
, AppEventListenerHdl
));
219 void OutlineView::DisconnectFromApplication()
221 Application::RemoveEventListener(LINK(this, OutlineView
, AppEventListenerHdl
));
224 void OutlineView::Paint(const Rectangle
& rRect
, ::sd::Window
* pWin
)
226 OutlinerView
* pOlView
= GetViewByWindow(pWin
);
230 pOlView
->HideCursor();
231 pOlView
->Paint(rRect
);
233 pOlView
->ShowCursor(mbFirstPaint
);
235 mbFirstPaint
= false;
239 void OutlineView::AddWindowToPaintView(OutputDevice
* pWin
, vcl::Window
* pWindow
)
242 bool bValidArea
= false;
243 Rectangle aOutputArea
;
244 const Color
aWhiteColor( COL_WHITE
);
245 sal_uInt16 nView
= 0;
247 while (nView
< MAX_OUTLINERVIEWS
&& !bAdded
)
249 if (mpOutlinerView
[nView
] == NULL
)
251 mpOutlinerView
[nView
] = new OutlinerView(&mrOutliner
, dynamic_cast< ::sd::Window
* >(pWin
));
252 mpOutlinerView
[nView
]->SetBackgroundColor( aWhiteColor
);
253 mrOutliner
.InsertView(mpOutlinerView
[nView
], EE_APPEND
);
258 mpOutlinerView
[nView
]->SetOutputArea(aOutputArea
);
261 else if (!bValidArea
)
263 aOutputArea
= mpOutlinerView
[nView
]->GetOutputArea();
270 // white background in Outliner
271 pWin
->SetBackground( Wallpaper( aWhiteColor
) );
273 ::sd::View::AddWindowToPaintView(pWin
, pWindow
);
276 void OutlineView::DeleteWindowFromPaintView(OutputDevice
* pWin
)
278 bool bRemoved
= false;
279 sal_uInt16 nView
= 0;
280 vcl::Window
* pWindow
;
282 while (nView
< MAX_OUTLINERVIEWS
&& !bRemoved
)
284 if (mpOutlinerView
[nView
] != NULL
)
286 pWindow
= mpOutlinerView
[nView
]->GetWindow();
290 mrOutliner
.RemoveView( mpOutlinerView
[nView
] );
291 delete mpOutlinerView
[nView
];
292 mpOutlinerView
[nView
] = NULL
;
300 ::sd::View::DeleteWindowFromPaintView(pWin
);
304 * Return a pointer to the OutlinerView corresponding to the window
306 OutlinerView
* OutlineView::GetViewByWindow (vcl::Window
* pWin
) const
308 OutlinerView
* pOlView
= NULL
;
309 for (sal_uInt16 nView
= 0; nView
< MAX_OUTLINERVIEWS
; nView
++)
311 if (mpOutlinerView
[nView
] != NULL
)
313 if ( pWin
== mpOutlinerView
[nView
]->GetWindow() )
315 pOlView
= mpOutlinerView
[nView
];
323 * Return the title before a random paragraph
325 Paragraph
* OutlineView::GetPrevTitle(const Paragraph
* pPara
)
327 sal_Int32 nPos
= mrOutliner
.GetAbsPos(const_cast<Paragraph
*>(pPara
));
333 pPara
= mrOutliner
.GetParagraph(--nPos
);
334 if( ::Outliner::HasParaFlag(pPara
, ParaFlag::ISPAGE
) )
336 return const_cast< Paragraph
* >( pPara
);
345 * Return the title after a random paragraph
347 Paragraph
* OutlineView::GetNextTitle(const Paragraph
* pPara
)
349 Paragraph
* pResult
= const_cast< Paragraph
* >( pPara
);
351 sal_Int32 nPos
= mrOutliner
.GetAbsPos(pResult
);
355 pResult
= mrOutliner
.GetParagraph(++nPos
);
356 if( pResult
&& ::Outliner::HasParaFlag(pResult
, ParaFlag::ISPAGE
) )
365 * Handler for inserting pages (paragraphs)
367 IMPL_LINK( OutlineView
, ParagraphInsertedHdl
, ::Outliner
*, pOutliner
)
369 // we get calls to this handler during binary insert of drag and drop contents but
370 // we ignore it here and handle it later in OnEndPasteOrDrop()
371 if( maDragAndDropModelGuard
.get() == 0 )
373 OutlineViewPageChangesGuard
aGuard(this);
375 Paragraph
* pPara
= pOutliner
->GetHdlParagraph();
377 sal_Int32 nAbsPos
= mrOutliner
.GetAbsPos( pPara
);
379 UpdateParagraph( nAbsPos
);
381 if( (nAbsPos
== 0) ||
382 ::Outliner::HasParaFlag(pPara
,ParaFlag::ISPAGE
) ||
383 ::Outliner::HasParaFlag(mrOutliner
.GetParagraph( nAbsPos
-1 ), ParaFlag::ISPAGE
) )
385 InsertSlideForParagraph( pPara
);
392 /** creates and inserts an empty slide for the given paragraph */
393 SdPage
* OutlineView::InsertSlideForParagraph( Paragraph
* pPara
)
395 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::InsertSlideForParagraph(), model change without undo?!" );
397 OutlineViewPageChangesGuard
aGuard(this);
399 mrOutliner
.SetParaFlag( pPara
, ParaFlag::ISPAGE
);
400 // how many titles are there before the new title paragraph?
401 sal_uLong nExample
= 0L; // position of the "example" page
402 sal_uLong nTarget
= 0L; // position of insertion
405 pPara
= GetPrevTitle(pPara
);
410 // if a new paragraph is created via RETURN before the first paragraph, the
411 // Outliner reports the old paragraph (which was moved down) as a new
415 OUString aTest
= mrOutliner
.GetText(mrOutliner
.GetParagraph(0));
422 // the "example" page is the previous page - if it is available
425 nExample
= nTarget
- 1;
427 sal_uInt16 nPageCount
= mrDoc
.GetSdPageCount( PK_STANDARD
);
428 if( nExample
>= nPageCount
)
429 nExample
= nPageCount
- 1;
432 /**********************************************************************
433 * All the time, a standard page is created before a notes page.
434 * It is ensured that after each standard page the corresponding notes page
435 * follows. A handout page is exactly one handout page.
436 **********************************************************************/
438 // this page is exemplary
439 SdPage
* pExample
= mrDoc
.GetSdPage((sal_uInt16
)nExample
, PK_STANDARD
);
440 SdPage
* pPage
= mrDoc
.AllocSdPage(false);
442 pPage
->SetLayoutName(pExample
->GetLayoutName());
445 mrDoc
.InsertPage(pPage
, (sal_uInt16
)(nTarget
) * 2 + 1);
446 if( isRecordingUndo() )
447 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoNewPage(*pPage
));
449 // assign a master page to the standard page
450 pPage
->TRG_SetMasterPage(pExample
->TRG_GetMasterPage());
453 pPage
->SetSize(pExample
->GetSize());
454 pPage
->SetBorder( pExample
->GetLftBorder(),
455 pExample
->GetUppBorder(),
456 pExample
->GetRgtBorder(),
457 pExample
->GetLwrBorder() );
459 // create new presentation objects (after <Title> or <Title with subtitle>
460 // follows <Title with outline>, otherwise apply the layout of the previous
462 AutoLayout eAutoLayout
= pExample
->GetAutoLayout();
463 if (eAutoLayout
== AUTOLAYOUT_TITLE
||
464 eAutoLayout
== AUTOLAYOUT_ONLY_TITLE
)
466 pPage
->SetAutoLayout(AUTOLAYOUT_ENUM
, true);
470 pPage
->SetAutoLayout(pExample
->GetAutoLayout(), true);
473 /**********************************************************************
474 |* now the notes page
475 \*********************************************************************/
476 pExample
= mrDoc
.GetSdPage((sal_uInt16
)nExample
, PK_NOTES
);
477 SdPage
* pNotesPage
= mrDoc
.AllocSdPage(false);
479 pNotesPage
->SetLayoutName(pExample
->GetLayoutName());
481 pNotesPage
->SetPageKind(PK_NOTES
);
483 // insert (notes page)
484 mrDoc
.InsertPage(pNotesPage
, (sal_uInt16
)(nTarget
) * 2 + 2);
485 if( isRecordingUndo() )
486 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoNewPage(*pNotesPage
));
488 // assign a master page to the notes page
489 pNotesPage
->TRG_SetMasterPage(pExample
->TRG_GetMasterPage());
491 // set page size, there must be already one page available
492 pNotesPage
->SetSize(pExample
->GetSize());
493 pNotesPage
->SetBorder( pExample
->GetLftBorder(),
494 pExample
->GetUppBorder(),
495 pExample
->GetRgtBorder(),
496 pExample
->GetLwrBorder() );
498 // create presentation objects
499 pNotesPage
->SetAutoLayout(pExample
->GetAutoLayout(), true);
501 mrOutliner
.UpdateFields();
507 * Handler for deleting pages (paragraphs)
509 IMPL_LINK( OutlineView
, ParagraphRemovingHdl
, ::Outliner
*, pOutliner
)
511 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::ParagraphRemovingHdl(), model change without undo?!" );
513 OutlineViewPageChangesGuard
aGuard(this);
515 Paragraph
* pPara
= pOutliner
->GetHdlParagraph();
516 if( ::Outliner::HasParaFlag( pPara
, ParaFlag::ISPAGE
) )
518 // how many titles are in front of the title paragraph in question?
522 pPara
= GetPrevTitle(pPara
);
526 // delete page and notes page
527 sal_uInt16 nAbsPos
= (sal_uInt16
)nPos
* 2 + 1;
528 SdrPage
* pPage
= mrDoc
.GetPage(nAbsPos
);
529 if( isRecordingUndo() )
530 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoDeletePage(*pPage
));
531 mrDoc
.RemovePage(nAbsPos
);
533 nAbsPos
= (sal_uInt16
)nPos
* 2 + 1;
534 pPage
= mrDoc
.GetPage(nAbsPos
);
535 if( isRecordingUndo() )
536 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoDeletePage(*pPage
));
537 mrDoc
.RemovePage(nAbsPos
);
539 // progress display if necessary
540 if (mnPagesToProcess
)
545 mpProgress
->SetState(mnPagesProcessed
);
547 if (mnPagesProcessed
== mnPagesToProcess
)
554 mnPagesToProcess
= 0;
555 mnPagesProcessed
= 0;
558 pOutliner
->UpdateFields();
565 * Handler for changing the indentation depth of paragraphs (requires inserting
566 * or deleting of pages in some cases)
568 IMPL_LINK( OutlineView
, DepthChangedHdl
, ::Outliner
*, pOutliner
)
570 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::DepthChangedHdl(), no undo for model change?!" );
572 OutlineViewPageChangesGuard
aGuard(this);
574 Paragraph
* pPara
= pOutliner
->GetHdlParagraph();
575 if( ::Outliner::HasParaFlag( pPara
, ParaFlag::ISPAGE
) && ((pOutliner
->GetPrevFlags() & ParaFlag::ISPAGE
) == ParaFlag::NONE
) )
577 // the current paragraph is transformed into a slide
579 mrOutliner
.SetDepth( pPara
, -1 );
581 // are multiple level 1 paragraphs being brought to level 0 and we
582 // should start a progress view or a timer and didn't already?
583 if (mnPagesToProcess
== 0)
585 Window
* pActWin
= mrOutlineViewShell
.GetActiveWindow();
586 OutlinerView
* pOlView
= GetViewByWindow(pActWin
);
588 std::vector
<Paragraph
*> aSelList
;
589 pOlView
->CreateSelectionList(aSelList
);
591 Paragraph
*pParagraph
= NULL
;
592 for (std::vector
<Paragraph
*>::const_iterator iter
= aSelList
.begin(); iter
!= aSelList
.end(); ++iter
)
596 if( !::Outliner::HasParaFlag( pParagraph
, ParaFlag::ISPAGE
) &&
597 (pOutliner
->GetDepth( pOutliner
->GetAbsPos( pParagraph
) ) <= 0) )
601 mnPagesToProcess
++; // the paragraph being in level 0 already
602 // should be included
603 mnPagesProcessed
= 0;
605 if (mnPagesToProcess
> PROCESS_WITH_PROGRESS_THRESHOLD
)
610 mpProgress
= new SfxProgress( GetDocSh(), SD_RESSTR(STR_CREATE_PAGES
), mnPagesToProcess
);
614 mpDocSh
->SetWaitCursor( true );
618 ParagraphInsertedHdl(pOutliner
);
622 // should there be a progress display?
623 if (mnPagesToProcess
> PROCESS_WITH_PROGRESS_THRESHOLD
)
626 mpProgress
->SetState(mnPagesProcessed
);
629 // was this the last page?
630 if (mnPagesProcessed
== mnPagesToProcess
)
632 if (mnPagesToProcess
> PROCESS_WITH_PROGRESS_THRESHOLD
&& mpProgress
)
638 mpDocSh
->SetWaitCursor( false );
640 mnPagesToProcess
= 0;
641 mnPagesProcessed
= 0;
643 pOutliner
->UpdateFields();
645 else if( !::Outliner::HasParaFlag( pPara
, ParaFlag::ISPAGE
) && ((pOutliner
->GetPrevFlags() & ParaFlag::ISPAGE
) != ParaFlag::NONE
) )
647 // the paragraph was a page but now becomes a normal paragraph
649 // how many titles are before the title paragraph in question?
651 Paragraph
* pParagraph
= pPara
;
654 pParagraph
= GetPrevTitle(pParagraph
);
658 // delete page and notes page
660 sal_uInt16 nAbsPos
= (sal_uInt16
)nPos
* 2 + 1;
661 SdrPage
* pPage
= mrDoc
.GetPage(nAbsPos
);
662 if( isRecordingUndo() )
663 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoDeletePage(*pPage
));
664 mrDoc
.RemovePage(nAbsPos
);
666 nAbsPos
= (sal_uInt16
)nPos
* 2 + 1;
667 pPage
= mrDoc
.GetPage(nAbsPos
);
668 if( isRecordingUndo() )
669 AddUndo(mrDoc
.GetSdrUndoFactory().CreateUndoDeletePage(*pPage
));
670 mrDoc
.RemovePage(nAbsPos
);
672 pPage
= GetPageForParagraph( pPara
);
674 mrOutliner
.SetDepth( pPara
, (pPage
&& (static_cast<SdPage
*>(pPage
)->GetAutoLayout() == AUTOLAYOUT_TITLE
)) ? -1 : 0 );
676 // progress display if necessary
677 if (mnPagesToProcess
)
681 mpProgress
->SetState(mnPagesProcessed
);
683 if (mnPagesProcessed
== mnPagesToProcess
)
690 mnPagesToProcess
= 0;
691 mnPagesProcessed
= 0;
694 pOutliner
->UpdateFields();
696 else if ( (pOutliner
->GetPrevDepth() == 1) && ( pOutliner
->GetDepth( pOutliner
->GetAbsPos( pPara
) ) == 2 ) )
698 // how many titles are in front of the title paragraph in question?
699 sal_Int32 nPos
= -1L;
701 Paragraph
* pParagraph
= pPara
;
704 pParagraph
= GetPrevTitle(pParagraph
);
711 SdPage
*pPage
= mrDoc
.GetSdPage( (sal_uInt16
) nPos
, PK_STANDARD
);
713 if(pPage
&& pPage
->GetPresObj(PRESOBJ_TEXT
))
714 pOutliner
->SetDepth( pPara
, 0 );
718 // how many titles are in front of the title paragraph in question?
719 sal_Int32 nPos
= -1L;
721 Paragraph
* pTempPara
= pPara
;
724 pTempPara
= GetPrevTitle(pTempPara
);
731 SdPage
* pPage
= mrDoc
.GetSdPage( (sal_uInt16
) nPos
, PK_STANDARD
);
735 SfxStyleSheet
* pStyleSheet
= NULL
;
736 sal_Int32 nPara
= pOutliner
->GetAbsPos( pPara
);
737 sal_Int16 nDepth
= pOutliner
->GetDepth( nPara
);
738 bool bSubTitle
= pPage
->GetPresObj(PRESOBJ_TEXT
) != NULL
;
740 if( ::Outliner::HasParaFlag(pPara
, ParaFlag::ISPAGE
) )
742 pStyleSheet
= pPage
->GetStyleSheetForPresObj( PRESOBJ_TITLE
);
746 pStyleSheet
= pPage
->GetStyleSheetForPresObj( PRESOBJ_TEXT
);
750 pStyleSheet
= pPage
->GetStyleSheetForPresObj( PRESOBJ_OUTLINE
);
754 OUString aNewStyleSheetName
= pStyleSheet
->GetName();
755 if (!aNewStyleSheetName
.isEmpty())
756 aNewStyleSheetName
= aNewStyleSheetName
.copy(0, aNewStyleSheetName
.getLength() - 1);
757 aNewStyleSheetName
+= OUString::number( nDepth
+1 );
758 SfxStyleSheetBasePool
* pStylePool
= mrDoc
.GetStyleSheetPool();
759 pStyleSheet
= static_cast<SfxStyleSheet
*>( pStylePool
->Find( aNewStyleSheetName
, pStyleSheet
->GetFamily() ) );
763 // before we set the style sheet we need to preserve the bullet item
764 // since all items will be deleted while setting a new style sheet
765 SfxItemSet
aOldAttrs( pOutliner
->GetParaAttribs( nPara
) );
767 pOutliner
->SetStyleSheet( nPara
, pStyleSheet
);
769 // restore the old bullet item but not if the style changed
770 if ( pOutliner
->GetPrevDepth() != -1 && nDepth
!= -1 &&
771 aOldAttrs
.GetItemState( EE_PARA_NUMBULLET
) == SfxItemState::SET
)
773 SfxItemSet
aAttrs( pOutliner
->GetParaAttribs( nPara
) );
774 aAttrs
.Put( *aOldAttrs
.GetItem( EE_PARA_NUMBULLET
) );
775 pOutliner
->SetParaAttribs( nPara
, aAttrs
);
784 * Handler for StatusEvents
786 IMPL_LINK_NOARG(OutlineView
, StatusEventHdl
)
788 ::sd::Window
* pWin
= mrOutlineViewShell
.GetActiveWindow();
789 OutlinerView
* pOutlinerView
= GetViewByWindow(pWin
);
790 Rectangle aVis
= pOutlinerView
->GetVisArea();
791 Rectangle aText
= Rectangle(Point(0,0),
793 mrOutliner
.GetTextHeight()));
794 Rectangle
aWin(Point(0,0), pWin
->GetOutputSizePixel());
795 aWin
= pWin
->PixelToLogic(aWin
);
797 if (!aVis
.IsEmpty()) // not when opening
799 if (aWin
.GetHeight() > aText
.Bottom())
800 aText
.Bottom() = aWin
.GetHeight();
802 mrOutlineViewShell
.InitWindows(Point(0,0), aText
.GetSize(),
803 Point(aVis
.TopLeft()));
804 mrOutlineViewShell
.UpdateScrollBars();
810 IMPL_LINK_NOARG(OutlineView
, BeginDropHdl
)
812 DBG_ASSERT(maDragAndDropModelGuard
.get() == 0, "sd::OutlineView::BeginDropHdl(), prior drag operation not finished correctly!" );
814 maDragAndDropModelGuard
.reset( new OutlineViewModelChangeGuard( *this ) );
818 IMPL_LINK_NOARG(OutlineView
, EndDropHdl
)
820 maDragAndDropModelGuard
.reset(0);
825 * Handler for the start of a paragraph movement
827 IMPL_LINK( OutlineView
, BeginMovingHdl
, ::Outliner
*, pOutliner
)
829 OutlineViewPageChangesGuard
aGuard(this);
831 // list of selected title paragraphs
832 mpOutlinerView
[0]->CreateSelectionList(maSelectedParas
);
834 for (std::vector
<Paragraph
*>::iterator it
= maSelectedParas
.begin(); it
!= maSelectedParas
.end();)
836 if (!::Outliner::HasParaFlag(*it
, ParaFlag::ISPAGE
))
837 it
= maSelectedParas
.erase(it
);
842 // select the pages belonging to the paragraphs on level 0 to select
844 sal_Int32 nParaPos
= 0;
845 Paragraph
* pPara
= pOutliner
->GetParagraph( 0 );
846 std::vector
<Paragraph
*>::const_iterator fiter
;
850 if( ::Outliner::HasParaFlag(pPara
, ParaFlag::ISPAGE
) ) // one page?
852 maOldParaOrder
.push_back(pPara
);
853 SdPage
* pPage
= mrDoc
.GetSdPage(nPos
, PK_STANDARD
);
855 fiter
= std::find(maSelectedParas
.begin(),maSelectedParas
.end(),pPara
);
857 pPage
->SetSelected(fiter
!= maSelectedParas
.end());
861 pPara
= pOutliner
->GetParagraph( ++nParaPos
);
868 * Handler for the end of a paragraph movement
870 IMPL_LINK( OutlineView
, EndMovingHdl
, ::Outliner
*, pOutliner
)
872 OutlineViewPageChangesGuard
aGuard(this);
874 DBG_ASSERT( isRecordingUndo(), "sd::OutlineView::EndMovingHdl(), model change without undo?!" );
876 // look for insertion position via the first paragraph
877 Paragraph
* pSearchIt
= maSelectedParas
.empty() ? NULL
: *(maSelectedParas
.begin());
879 // look for the first of the selected paragraphs in the new ordering
880 sal_uInt16 nPosNewOrder
= 0;
881 sal_Int32 nParaPos
= 0;
882 Paragraph
* pPara
= pOutliner
->GetParagraph( 0 );
883 Paragraph
* pPrev
= NULL
;
884 while (pPara
&& pPara
!= pSearchIt
)
886 if( ::Outliner::HasParaFlag(pPara
, ParaFlag::ISPAGE
) )
891 pPara
= pOutliner
->GetParagraph( ++nParaPos
);
894 sal_uInt16 nPos
= nPosNewOrder
; // don't change nPosNewOrder
897 nPos
= (sal_uInt16
)-1; // insert before the first page
901 // look for the predecessor in the old ordering
902 std::vector
<Paragraph
*>::const_iterator it
= std::find(maOldParaOrder
.begin(),
903 maOldParaOrder
.end(),
906 if (it
!= maOldParaOrder
.end())
907 nPos
= static_cast<sal_uInt16
>(it
-maOldParaOrder
.begin());
911 DBG_ASSERT(nPos
!= 0xffff, "Paragraph not found");
914 mrDoc
.MovePages(nPos
);
916 // deselect the pages again
917 sal_uInt16 nPageCount
= (sal_uInt16
)maSelectedParas
.size();
920 SdPage
* pPage
= mrDoc
.GetSdPage(nPosNewOrder
, PK_STANDARD
);
921 pPage
->SetSelected(false);
926 pOutliner
->UpdateFields();
928 maSelectedParas
.clear();
929 maOldParaOrder
.clear();
935 * Look for the title text object in one page of the model
937 SdrTextObj
* OutlineView::GetTitleTextObject(SdrPage
* pPage
)
939 const size_t nObjectCount
= pPage
->GetObjCount();
940 SdrTextObj
* pResult
= NULL
;
942 for (size_t nObject
= 0; nObject
< nObjectCount
; ++nObject
)
944 SdrObject
* pObject
= pPage
->GetObj(nObject
);
945 if (pObject
->GetObjInventor() == SdrInventor
&&
946 pObject
->GetObjIdentifier() == OBJ_TITLETEXT
)
948 pResult
= static_cast<SdrTextObj
*>(pObject
);
956 * Look for the outline text object in one page of the model
958 SdrTextObj
* OutlineView::GetOutlineTextObject(SdrPage
* pPage
)
960 const size_t nObjectCount
= pPage
->GetObjCount();
961 SdrTextObj
* pResult
= NULL
;
963 for (size_t nObject
= 0; nObject
< nObjectCount
; ++nObject
)
965 SdrObject
* pObject
= pPage
->GetObj(nObject
);
966 if (pObject
->GetObjInventor() == SdrInventor
&&
967 pObject
->GetObjIdentifier() == OBJ_OUTLINETEXT
)
969 pResult
= static_cast<SdrTextObj
*>(pObject
);
976 SdrTextObj
* OutlineView::CreateTitleTextObject(SdPage
* pPage
)
978 DBG_ASSERT( GetTitleTextObject(pPage
) == 0, "sd::OutlineView::CreateTitleTextObject(), there is already a title text object!" );
980 if( pPage
->GetAutoLayout() == AUTOLAYOUT_NONE
)
983 pPage
->SetAutoLayout( AUTOLAYOUT_ONLY_TITLE
, true );
987 // we already have a layout with a title but the title
988 // object was deleted, create a new one
989 pPage
->InsertAutoLayoutShape( 0, PRESOBJ_TITLE
, false, pPage
->GetTitleRect(), true );
992 return GetTitleTextObject(pPage
);
995 SdrTextObj
* OutlineView::CreateOutlineTextObject(SdPage
* pPage
)
997 DBG_ASSERT( GetOutlineTextObject(pPage
) == 0, "sd::OutlineView::CreateOutlineTextObject(), there is already a layout text object!" );
999 AutoLayout eNewLayout
= pPage
->GetAutoLayout();
1000 switch( eNewLayout
)
1002 case AUTOLAYOUT_NONE
:
1003 case AUTOLAYOUT_ONLY_TITLE
:
1004 case AUTOLAYOUT_TITLE
: eNewLayout
= AUTOLAYOUT_ENUM
; break;
1006 case AUTOLAYOUT_CHART
: eNewLayout
= AUTOLAYOUT_CHARTTEXT
; break;
1008 case AUTOLAYOUT_ORG
:
1009 case AUTOLAYOUT_TAB
:
1010 case AUTOLAYOUT_OBJ
: eNewLayout
= AUTOLAYOUT_OBJTEXT
; break;
1015 if( eNewLayout
!= pPage
->GetAutoLayout() )
1017 pPage
->SetAutoLayout( eNewLayout
, true );
1021 // we already have a layout with a text but the text
1022 // object was deleted, create a new one
1023 pPage
->InsertAutoLayoutShape( 0,
1025 false, pPage
->GetLayoutRect(), true );
1028 return GetOutlineTextObject(pPage
);
1031 /** updates draw model with all changes from outliner model */
1032 bool OutlineView::PrepareClose(bool)
1034 ::sd::UndoManager
* pDocUndoMgr
= dynamic_cast<sd::UndoManager
*>(mpDocSh
->GetUndoManager());
1035 if (pDocUndoMgr
!= NULL
)
1036 pDocUndoMgr
->SetLinkedUndoManager(NULL
);
1038 mrOutliner
.GetUndoManager().Clear();
1040 BegUndo(SD_RESSTR(STR_UNDO_CHANGE_TITLE_AND_LAYOUT
));
1043 mrDoc
.SetSelected(GetActualPage(), true);
1048 * Set attributes of the selected text
1050 bool OutlineView::SetAttributes(const SfxItemSet
& rSet
, bool )
1054 OutlinerView
* pOlView
= GetViewByWindow(mrOutlineViewShell
.GetActiveWindow());
1058 pOlView
->SetAttribs(rSet
);
1062 mrOutlineViewShell
.Invalidate (SID_PREVIEW_STATE
);
1068 * Get attributes of the selected text
1070 bool OutlineView::GetAttributes( SfxItemSet
& rTargetSet
, bool ) const
1072 OutlinerView
* pOlView
= GetViewByWindow(
1073 mrOutlineViewShell
.GetActiveWindow());
1074 assert(pOlView
&& "keine OutlinerView gefunden");
1076 rTargetSet
.Put( pOlView
->GetAttribs(), false );
1080 /** creates outliner model from draw model */
1081 void OutlineView::FillOutliner()
1083 mrOutliner
.GetUndoManager().Clear();
1084 mrOutliner
.EnableUndo(false);
1086 mrOutliner
.SetUpdateMode(false);
1088 Paragraph
* pTitleToSelect
= NULL
;
1089 sal_uLong nPageCount
= mrDoc
.GetSdPageCount(PK_STANDARD
);
1091 // fill outliner with paragraphs from slides title & (outlines|subtitles)
1092 for (sal_uInt16 nPage
= 0; nPage
< nPageCount
; nPage
++)
1094 SdPage
* pPage
= mrDoc
.GetSdPage(nPage
, PK_STANDARD
);
1095 Paragraph
* pPara
= NULL
;
1097 // take text from title shape
1098 SdrTextObj
* pTO
= GetTitleTextObject(pPage
);
1099 if(pTO
&& !(pTO
->IsEmptyPresObj()))
1101 OutlinerParaObject
* pOPO
= pTO
->GetOutlinerParaObject();
1104 bool bVertical
= pOPO
->IsVertical();
1105 pOPO
->SetVertical( false );
1106 mrOutliner
.AddText(*pOPO
);
1107 pOPO
->SetVertical( bVertical
);
1108 pPara
= mrOutliner
.GetParagraph( mrOutliner
.GetParagraphCount()-1 );
1112 if( pPara
== 0 ) // no title, insert an empty paragraph
1114 pPara
= mrOutliner
.Insert(OUString());
1115 mrOutliner
.SetDepth(pPara
, -1);
1117 // do not apply hard attributes from the previous paragraph
1118 mrOutliner
.SetParaAttribs( mrOutliner
.GetAbsPos(pPara
),
1119 mrOutliner
.GetEmptyItemSet() );
1121 mrOutliner
.SetStyleSheet( mrOutliner
.GetAbsPos( pPara
), pPage
->GetStyleSheetForPresObj( PRESOBJ_TITLE
) );
1124 mrOutliner
.SetParaFlag( pPara
, ParaFlag::ISPAGE
);
1126 sal_Int32 nPara
= mrOutliner
.GetAbsPos( pPara
);
1128 UpdateParagraph( nPara
);
1130 // remember paragraph of currently selected page
1131 if (pPage
->IsSelected())
1132 pTitleToSelect
= pPara
;
1134 // take text from subtitle or outline
1135 pTO
= static_cast<SdrTextObj
*>(pPage
->GetPresObj(PRESOBJ_TEXT
));
1136 const bool bSubTitle
= pTO
!= 0;
1138 if (!pTO
) // if no subtile found, try outline
1139 pTO
= GetOutlineTextObject(pPage
);
1141 if(pTO
&& !(pTO
->IsEmptyPresObj())) // found some text
1143 OutlinerParaObject
* pOPO
= pTO
->GetOutlinerParaObject();
1146 sal_Int32 nParaCount1
= mrOutliner
.GetParagraphCount();
1147 bool bVertical
= pOPO
->IsVertical();
1148 pOPO
->SetVertical( false );
1149 mrOutliner
.AddText(*pOPO
);
1150 pOPO
->SetVertical( bVertical
);
1152 sal_Int32 nParaCount2
= mrOutliner
.GetParagraphCount();
1153 for (sal_Int32 n
= nParaCount1
; n
< nParaCount2
; n
++)
1157 Paragraph
* p
= mrOutliner
.GetParagraph(n
);
1158 if(p
&& mrOutliner
.GetDepth( n
) > 0 )
1159 mrOutliner
.SetDepth(p
, 0);
1162 UpdateParagraph( n
);
1168 // place cursor at the start
1169 Paragraph
* pFirstPara
= mrOutliner
.GetParagraph( 0 );
1170 mpOutlinerView
[0]->Select( pFirstPara
, true, false );
1171 mpOutlinerView
[0]->Select( pFirstPara
, false, false );
1173 // select title of slide that was selected
1175 mpOutlinerView
[0]->Select(pTitleToSelect
, true, false);
1179 mrOutliner
.EnableUndo(true);
1181 mrOutliner
.SetUpdateMode(true);
1185 * Handler for deleting of level 0 paragraphs (pages): Warning
1187 IMPL_LINK_NOARG(OutlineView
, RemovingPagesHdl
)
1189 sal_Int32 nNumOfPages
= mrOutliner
.GetSelPageCount();
1191 if (nNumOfPages
> PROCESS_WITH_PROGRESS_THRESHOLD
)
1193 mnPagesToProcess
= nNumOfPages
;
1194 mnPagesProcessed
= 0;
1197 if (mnPagesToProcess
)
1202 mpProgress
= new SfxProgress( GetDocSh(), SD_RESSTR(STR_DELETE_PAGES
), mnPagesToProcess
);
1204 mrOutliner
.UpdateFields();
1210 * Handler for indenting level 0 paragraphs (pages): Warning
1212 IMPL_LINK( OutlineView
, IndentingPagesHdl
, OutlinerView
*, pOutlinerView
)
1214 return RemovingPagesHdl(pOutlinerView
);
1217 /** returns the first slide that is selected in the outliner or where
1218 the cursor is located */
1219 SdPage
* OutlineView::GetActualPage()
1221 ::sd::Window
* pWin
= mrOutlineViewShell
.GetActiveWindow();
1222 OutlinerView
* pActiveView
= GetViewByWindow(pWin
);
1224 std::vector
<Paragraph
*> aSelList
;
1225 pActiveView
->CreateSelectionList(aSelList
);
1227 Paragraph
*pPar
= aSelList
.empty() ? NULL
: *(aSelList
.begin());
1228 SdPage
* pCurrent
= GetPageForParagraph(pPar
);
1230 DBG_ASSERT( pCurrent
||
1231 (mpDocSh
->GetUndoManager() && static_cast< sd::UndoManager
*>(mpDocSh
->GetUndoManager())->IsDoing()) ||
1232 maDragAndDropModelGuard
.get(),
1233 "sd::OutlineView::GetActualPage(), no current page?" );
1238 return mrDoc
.GetSdPage( 0, PK_STANDARD
);
1241 SdPage
* OutlineView::GetPageForParagraph( Paragraph
* pPara
)
1243 if( !::Outliner::HasParaFlag(pPara
,ParaFlag::ISPAGE
) )
1244 pPara
= GetPrevTitle(pPara
);
1246 sal_uInt32 nPageToSelect
= 0;
1249 pPara
= GetPrevTitle(pPara
);
1254 if( nPageToSelect
< (sal_uInt32
)mrDoc
.GetSdPageCount( PK_STANDARD
) )
1255 return static_cast< SdPage
* >( mrDoc
.GetSdPage( (sal_uInt16
)nPageToSelect
, PK_STANDARD
) );
1260 Paragraph
* OutlineView::GetParagraphForPage( ::Outliner
& rOutl
, SdPage
* pPage
)
1262 // get the number of paragraphs with ident 0 we need to skip before
1263 // we finde the actual page
1264 sal_uInt32 nPagesToSkip
= (pPage
->GetPageNum() - 1) >> 1;
1266 sal_Int32 nParaPos
= 0;
1267 Paragraph
* pPara
= rOutl
.GetParagraph( 0 );
1270 // if this paragraph is a page ...
1271 if( ::Outliner::HasParaFlag(pPara
,ParaFlag::ISPAGE
) )
1273 // see if we already skipped enough pages
1274 if( 0 == nPagesToSkip
)
1275 break; // and if so, end the loop
1277 // we skipped another page
1281 // get next paragraph
1282 pPara
= mrOutliner
.GetParagraph( ++nParaPos
);
1288 /** selects the paragraph for the given page at the outliner view*/
1289 void OutlineView::SetActualPage( SdPage
* pActual
)
1291 if( pActual
&& dynamic_cast<Outliner
&>(mrOutliner
).GetIgnoreCurrentPageChangesLevel()==0 && !mbFirstPaint
)
1293 // if we found a paragraph, select its text at the outliner view
1294 Paragraph
* pPara
= GetParagraphForPage( mrOutliner
, pActual
);
1296 mpOutlinerView
[0]->Select( pPara
, true, false );
1301 * Get StyleSheet from the selection
1303 SfxStyleSheet
* OutlineView::GetStyleSheet() const
1305 ::sd::Window
* pActWin
= mrOutlineViewShell
.GetActiveWindow();
1306 OutlinerView
* pOlView
= GetViewByWindow(pActWin
);
1307 SfxStyleSheet
* pResult
= pOlView
->GetStyleSheet();
1312 * Mark pages as selected / not selected
1314 void OutlineView::SetSelectedPages()
1316 // list of selected title paragraphs
1317 std::vector
<Paragraph
*> aSelParas
;
1318 mpOutlinerView
[0]->CreateSelectionList(aSelParas
);
1320 for (std::vector
<Paragraph
*>::iterator it
= aSelParas
.begin(); it
!= aSelParas
.end();)
1322 if (!::Outliner::HasParaFlag(*it
, ParaFlag::ISPAGE
))
1323 it
= aSelParas
.erase(it
);
1328 // select the pages belonging to the paragraphs on level 0 to select
1329 sal_uInt16 nPos
= 0;
1330 sal_Int32 nParaPos
= 0;
1331 Paragraph
*pPara
= mrOutliner
.GetParagraph( 0 );
1332 std::vector
<Paragraph
*>::const_iterator fiter
;
1336 if( ::Outliner::HasParaFlag(pPara
, ParaFlag::ISPAGE
) ) // one page
1338 SdPage
* pPage
= mrDoc
.GetSdPage(nPos
, PK_STANDARD
);
1339 DBG_ASSERT(pPage
!=NULL
,
1340 "Trying to select non-existing page OutlineView::SetSelectedPages()");
1344 fiter
= std::find(aSelParas
.begin(),aSelParas
.end(),pPara
);
1345 pPage
->SetSelected(fiter
!= aSelParas
.end());
1351 pPara
= mrOutliner
.GetParagraph( ++nParaPos
);
1358 void OutlineView::SetLinks()
1360 // set notification links
1361 mrOutliner
.SetParaInsertedHdl(LINK(this, OutlineView
, ParagraphInsertedHdl
));
1362 mrOutliner
.SetParaRemovingHdl(LINK(this, OutlineView
, ParagraphRemovingHdl
));
1363 mrOutliner
.SetDepthChangedHdl(LINK(this, OutlineView
, DepthChangedHdl
));
1364 mrOutliner
.SetBeginMovingHdl(LINK(this, OutlineView
, BeginMovingHdl
));
1365 mrOutliner
.SetEndMovingHdl(LINK(this, OutlineView
, EndMovingHdl
));
1366 mrOutliner
.SetRemovingPagesHdl(LINK(this, OutlineView
, RemovingPagesHdl
));
1367 mrOutliner
.SetIndentingPagesHdl(LINK(this, OutlineView
, IndentingPagesHdl
));
1368 mrOutliner
.SetStatusEventHdl(LINK(this, OutlineView
, StatusEventHdl
));
1369 mrOutliner
.SetBeginDropHdl(LINK(this,OutlineView
, BeginDropHdl
));
1370 mrOutliner
.SetEndDropHdl(LINK(this,OutlineView
, EndDropHdl
));
1371 mrOutliner
.SetPaintFirstLineHdl(LINK(this,OutlineView
,PaintingFirstLineHdl
));
1372 mrOutliner
.SetBeginPasteOrDropHdl(LINK(this,OutlineView
, BeginPasteOrDropHdl
));
1373 mrOutliner
.SetEndPasteOrDropHdl(LINK(this,OutlineView
, EndPasteOrDropHdl
));
1379 void OutlineView::ResetLinks() const
1382 mrOutliner
.SetParaInsertedHdl(aEmptyLink
);
1383 mrOutliner
.SetParaRemovingHdl(aEmptyLink
);
1384 mrOutliner
.SetDepthChangedHdl(aEmptyLink
);
1385 mrOutliner
.SetBeginMovingHdl(aEmptyLink
);
1386 mrOutliner
.SetEndMovingHdl(aEmptyLink
);
1387 mrOutliner
.SetStatusEventHdl(aEmptyLink
);
1388 mrOutliner
.SetRemovingPagesHdl(aEmptyLink
);
1389 mrOutliner
.SetIndentingPagesHdl(aEmptyLink
);
1390 mrOutliner
.SetDrawPortionHdl(aEmptyLink
);
1391 mrOutliner
.SetBeginPasteOrDropHdl(aEmptyLink
);
1392 mrOutliner
.SetEndPasteOrDropHdl(aEmptyLink
);
1395 sal_Int8
OutlineView::AcceptDrop( const AcceptDropEvent
&, DropTargetHelper
&, ::sd::Window
*, sal_uInt16
, sal_uInt16
)
1397 return DND_ACTION_NONE
;
1400 sal_Int8
OutlineView::ExecuteDrop( const ExecuteDropEvent
&, DropTargetHelper
&, ::sd::Window
*, sal_uInt16
, sal_uInt16
)
1402 return DND_ACTION_NONE
;
1405 // Re-implement GetScriptType for this view to get correct results
1406 SvtScriptType
OutlineView::GetScriptType() const
1408 SvtScriptType nScriptType
= ::sd::View::GetScriptType();
1410 OutlinerParaObject
* pTempOPObj
= mrOutliner
.CreateParaObject();
1413 nScriptType
= pTempOPObj
->GetTextObject().GetScriptType();
1420 void OutlineView::onUpdateStyleSettings( bool bForceUpdate
/* = false */ )
1422 svtools::ColorConfig aColorConfig
;
1423 const Color
aDocColor( aColorConfig
.GetColorValue( svtools::DOCCOLOR
).nColor
);
1424 if( bForceUpdate
|| (maDocColor
!= aDocColor
) )
1427 for( nView
= 0; nView
< MAX_OUTLINERVIEWS
; nView
++ )
1429 if (mpOutlinerView
[nView
] != NULL
)
1431 mpOutlinerView
[nView
]->SetBackgroundColor( aDocColor
);
1433 vcl::Window
* pWindow
= mpOutlinerView
[nView
]->GetWindow();
1436 pWindow
->SetBackground( Wallpaper( aDocColor
) );
1441 mrOutliner
.SetBackgroundColor( aDocColor
);
1443 maDocColor
= aDocColor
;
1447 IMPL_LINK_NOARG(OutlineView
, AppEventListenerHdl
)
1449 onUpdateStyleSettings();
1453 IMPL_LINK(OutlineView
, EventMultiplexerListener
, ::sd::tools::EventMultiplexerEvent
*, pEvent
)
1457 switch (pEvent
->meEventId
)
1459 case tools::EventMultiplexerEvent::EID_CURRENT_PAGE
:
1460 SetActualPage(mrOutlineViewShell
.GetActualPage());
1463 case tools::EventMultiplexerEvent::EID_PAGE_ORDER
:
1464 if (dynamic_cast<Outliner
&>(mrOutliner
).GetIgnoreCurrentPageChangesLevel()==0)
1466 if (((mrDoc
.GetPageCount()-1)%2) == 0)
1470 ::sd::Window
* pWindow
= mrOutlineViewShell
.GetActiveWindow();
1471 if (pWindow
!= NULL
)
1472 pWindow
->Invalidate();
1481 void OutlineView::IgnoreCurrentPageChanges (bool bIgnoreChanges
)
1484 dynamic_cast<Outliner
&>(mrOutliner
).IncreIgnoreCurrentPageChangesLevel();
1486 dynamic_cast<Outliner
&>(mrOutliner
).DecreIgnoreCurrentPageChangesLevel();
1489 /** call this method before you do anything that can modify the outliner
1490 and or the drawing document model. It will create needed undo actions */
1491 void OutlineView::BeginModelChange()
1493 mrOutliner
.GetUndoManager().EnterListAction("", "");
1494 BegUndo(SD_RESSTR(STR_UNDO_CHANGE_TITLE_AND_LAYOUT
));
1497 /** call this method after BeginModelChange(), when all possible model
1498 changes are done. */
1499 void OutlineView::EndModelChange()
1503 ::svl::IUndoManager
* pDocUndoMgr
= mpDocSh
->GetUndoManager();
1505 bool bHasUndoActions
= pDocUndoMgr
->GetUndoActionCount() != 0;
1509 DBG_ASSERT( bHasUndoActions
== (mrOutliner
.GetUndoManager().GetUndoActionCount() != 0), "sd::OutlineView::EndModelChange(), undo actions not in sync!" );
1511 mrOutliner
.GetUndoManager().LeaveListAction();
1513 if( bHasUndoActions
&& mrOutliner
.GetEditEngine().HasTriedMergeOnLastAddUndo() )
1514 TryToMergeUndoActions();
1516 mrOutlineViewShell
.Invalidate( SID_UNDO
);
1517 mrOutlineViewShell
.Invalidate( SID_REDO
);
1520 /** updates all changes in the outliner model to the draw model */
1521 void OutlineView::UpdateDocument()
1523 OutlineViewPageChangesGuard
aGuard(this);
1525 const sal_uInt32 nPageCount
= mrDoc
.GetSdPageCount(PK_STANDARD
);
1526 Paragraph
* pPara
= mrOutliner
.GetParagraph( 0 );
1528 for (nPage
= 0; nPage
< nPageCount
; nPage
++)
1530 SdPage
* pPage
= mrDoc
.GetSdPage( (sal_uInt16
)nPage
, PK_STANDARD
);
1531 mrDoc
.SetSelected(pPage
, false);
1533 mrOutlineViewShell
.UpdateTitleObject( pPage
, pPara
);
1534 mrOutlineViewShell
.UpdateOutlineObject( pPage
, pPara
);
1537 pPara
= GetNextTitle(pPara
);
1540 DBG_ASSERT( pPara
== 0, "sd::OutlineView::UpdateDocument(), slides are out of sync, creating missing ones" );
1543 SdPage
* pPage
= InsertSlideForParagraph( pPara
);
1544 mrDoc
.SetSelected(pPage
, false);
1546 mrOutlineViewShell
.UpdateTitleObject( pPage
, pPara
);
1547 mrOutlineViewShell
.UpdateOutlineObject( pPage
, pPara
);
1550 pPara
= GetNextTitle(pPara
);
1554 /** merge edit engine undo actions if possible */
1555 void OutlineView::TryToMergeUndoActions()
1557 ::svl::IUndoManager
& rOutlineUndo
= mrOutliner
.GetUndoManager();
1558 if( rOutlineUndo
.GetUndoActionCount() > 1 )
1560 SfxListUndoAction
* pListAction
= dynamic_cast< SfxListUndoAction
* >( rOutlineUndo
.GetUndoAction(0) );
1561 SfxListUndoAction
* pPrevListAction
= dynamic_cast< SfxListUndoAction
* >( rOutlineUndo
.GetUndoAction(1) );
1562 if( pListAction
&& pPrevListAction
)
1564 // find the top EditUndo action in the top undo action list
1565 size_t nAction
= pListAction
->aUndoActions
.size();
1566 EditUndo
* pEditUndo
= 0;
1567 while( !pEditUndo
&& nAction
)
1569 pEditUndo
= dynamic_cast< EditUndo
* >(pListAction
->aUndoActions
.GetUndoAction(--nAction
));
1572 sal_uInt16 nEditPos
= nAction
; // we need this later to remove the merged undo actions
1574 // make sure it is the only EditUndo action in the top undo list
1575 while( pEditUndo
&& nAction
)
1577 if( dynamic_cast< EditUndo
* >(pListAction
->aUndoActions
.GetUndoAction(--nAction
)) )
1581 // do we have one and only one EditUndo action in the top undo list?
1584 // yes, see if we can merge it with the prev undo list
1586 nAction
= pPrevListAction
->aUndoActions
.size();
1587 EditUndo
* pPrevEditUndo
= 0;
1588 while( !pPrevEditUndo
&& nAction
)
1589 pPrevEditUndo
= dynamic_cast< EditUndo
* >(pPrevListAction
->aUndoActions
.GetUndoAction(--nAction
));
1591 if( pPrevEditUndo
&& pPrevEditUndo
->Merge( pEditUndo
) )
1593 // ok we merged the only EditUndo of the top undo list with
1594 // the top EditUndo of the previous undo list
1596 // first remove the merged undo action
1597 DBG_ASSERT( pListAction
->aUndoActions
.GetUndoAction(nEditPos
) == pEditUndo
,
1598 "sd::OutlineView::TryToMergeUndoActions(), wrong edit pos!" );
1599 pListAction
->aUndoActions
.Remove(nEditPos
);
1602 // now check if we also can merge the draw undo actions
1603 ::svl::IUndoManager
* pDocUndoManager
= mpDocSh
->GetUndoManager();
1604 if( pDocUndoManager
&& ( pListAction
->aUndoActions
.size() == 1 ))
1606 SfxLinkUndoAction
* pLinkAction
= dynamic_cast< SfxLinkUndoAction
* >( pListAction
->aUndoActions
.GetUndoAction(0) );
1607 SfxLinkUndoAction
* pPrevLinkAction
= 0;
1611 nAction
= pPrevListAction
->aUndoActions
.size();
1612 while( !pPrevLinkAction
&& nAction
)
1613 pPrevLinkAction
= dynamic_cast< SfxLinkUndoAction
* >(pPrevListAction
->aUndoActions
.GetUndoAction(--nAction
));
1616 if( pLinkAction
&& pPrevLinkAction
&&
1617 ( pLinkAction
->GetAction() == pDocUndoManager
->GetUndoAction(0) ) &&
1618 ( pPrevLinkAction
->GetAction() == pDocUndoManager
->GetUndoAction(1) ) )
1620 SfxListUndoAction
* pSourceList
= dynamic_cast< SfxListUndoAction
* >(pLinkAction
->GetAction());
1621 SfxListUndoAction
* pDestinationList
= dynamic_cast< SfxListUndoAction
* >(pPrevLinkAction
->GetAction());
1623 if( pSourceList
&& pDestinationList
)
1625 sal_uInt16 nCount
= pSourceList
->aUndoActions
.size();
1626 sal_uInt16 nDestAction
= pDestinationList
->aUndoActions
.size();
1629 SfxUndoAction
* pTemp
= pSourceList
->aUndoActions
.GetUndoAction(0);
1630 pSourceList
->aUndoActions
.Remove(0);
1631 pDestinationList
->aUndoActions
.Insert( pTemp
, nDestAction
++ );
1633 pDestinationList
->nCurUndoAction
= pDestinationList
->aUndoActions
.size();
1635 pListAction
->aUndoActions
.Remove(0);
1638 pDocUndoManager
->RemoveLastUndoAction();
1643 if ( !pListAction
->aUndoActions
.empty() )
1645 // now we have to move all remaining doc undo actions from the top undo
1646 // list to the previous undo list and remove the top undo list
1648 size_t nCount
= pListAction
->aUndoActions
.size();
1649 size_t nDestAction
= pPrevListAction
->aUndoActions
.size();
1652 SfxUndoAction
* pTemp
= pListAction
->aUndoActions
.GetUndoAction(0);
1653 pListAction
->aUndoActions
.Remove(0);
1655 pPrevListAction
->aUndoActions
.Insert( pTemp
, nDestAction
++ );
1657 pPrevListAction
->nCurUndoAction
= pPrevListAction
->aUndoActions
.size();
1660 rOutlineUndo
.RemoveLastUndoAction();
1667 IMPL_LINK(OutlineView
, PaintingFirstLineHdl
, PaintFirstLineInfo
*, pInfo
)
1671 Paragraph
* pPara
= mrOutliner
.GetParagraph( pInfo
->mnPara
);
1672 EditEngine
& rEditEngine
= const_cast< EditEngine
& >( mrOutliner
.GetEditEngine() );
1674 Size
aImageSize( pInfo
->mpOutDev
->PixelToLogic( maSlideImage
.GetSizePixel() ) );
1675 Size
aOffset( 100, 100 );
1677 // paint slide number
1678 if( pPara
&& ::Outliner::HasParaFlag(pPara
,ParaFlag::ISPAGE
) )
1680 long nPage
= 0; // todo, printing??
1681 for ( sal_Int32 n
= 0; n
<= pInfo
->mnPara
; n
++ )
1683 Paragraph
* p
= mrOutliner
.GetParagraph( n
);
1684 if ( ::Outliner::HasParaFlag(p
,ParaFlag::ISPAGE
) )
1688 long nBulletHeight
= (long)mrOutliner
.GetLineHeight( pInfo
->mnPara
);
1689 long nFontHeight
= 0;
1690 if ( !rEditEngine
.IsFlatMode() )
1692 nFontHeight
= nBulletHeight
/ 5;
1696 nFontHeight
= (nBulletHeight
* 10) / 25;
1699 Size
aFontSz( 0, nFontHeight
);
1701 Size
aOutSize( 2000, nBulletHeight
);
1703 const float fImageHeight
= ((float)aOutSize
.Height() * (float)4) / (float)7;
1704 if (aImageSize
.Width() != 0)
1706 const float fImageRatio
= (float)aImageSize
.Height() / (float)aImageSize
.Width();
1707 aImageSize
.Width() = (long)( fImageRatio
* fImageHeight
);
1709 aImageSize
.Height() = (long)( fImageHeight
);
1711 Point
aImagePos( pInfo
->mrStartPos
);
1712 aImagePos
.X() += aOutSize
.Width() - aImageSize
.Width() - aOffset
.Width() ;
1713 aImagePos
.Y() += (aOutSize
.Height() - aImageSize
.Height()) / 2;
1715 pInfo
->mpOutDev
->DrawImage( aImagePos
, aImageSize
, maSlideImage
);
1717 const bool bVertical
= mrOutliner
.IsVertical();
1718 const bool bRightToLeftPara
= rEditEngine
.IsRightToLeft( pInfo
->mnPara
);
1720 LanguageType eLang
= rEditEngine
.GetDefaultLanguage();
1722 Point
aTextPos( aImagePos
.X() - aOffset
.Width(), pInfo
->mrStartPos
.Y() );
1723 vcl::Font
aNewFont( OutputDevice::GetDefaultFont( DefaultFontType::SANS_UNICODE
, eLang
, GetDefaultFontFlags::NONE
) );
1724 aNewFont
.SetSize( aFontSz
);
1725 aNewFont
.SetVertical( bVertical
);
1726 aNewFont
.SetOrientation( bVertical
? 2700 : 0 );
1727 aNewFont
.SetColor( COL_AUTO
);
1728 pInfo
->mpOutDev
->SetFont( aNewFont
);
1729 OUString aPageText
= OUString::number( nPage
);
1731 aTextSz
.Width() = pInfo
->mpOutDev
->GetTextWidth( aPageText
);
1732 aTextSz
.Height() = pInfo
->mpOutDev
->GetTextHeight();
1735 aTextPos
.Y() += (aOutSize
.Height() - aTextSz
.Height()) / 2;
1736 if ( !bRightToLeftPara
)
1738 aTextPos
.X() -= aTextSz
.Width();
1742 aTextPos
.X() += aTextSz
.Width();
1747 aTextPos
.Y() -= aTextSz
.Width();
1748 aTextPos
.X() += nBulletHeight
/ 2;
1750 pInfo
->mpOutDev
->DrawText( aTextPos
, aPageText
);
1757 void OutlineView::UpdateParagraph( sal_Int32 nPara
)
1759 SfxItemSet
aNewAttrs2( mrOutliner
.GetParaAttribs( nPara
) );
1760 aNewAttrs2
.Put( maLRSpaceItem
);
1761 mrOutliner
.SetParaAttribs( nPara
, aNewAttrs2
);
1764 void OutlineView::OnBeginPasteOrDrop( PasteOrDropInfos
* /*pInfos*/ )
1768 /** this is called after a paste or drop operation, make sure that the newly inserted paragraphs
1769 get the correct style sheet and new slides are inserted. */
1770 void OutlineView::OnEndPasteOrDrop( PasteOrDropInfos
* pInfos
)
1773 SfxStyleSheetBasePool
* pStylePool
= GetDoc().GetStyleSheetPool();
1775 for( sal_Int32 nPara
= pInfos
->nStartPara
; nPara
<= pInfos
->nEndPara
; nPara
++ )
1777 Paragraph
* pPara
= mrOutliner
.GetParagraph( nPara
);
1779 bool bPage
= ::Outliner::HasParaFlag( pPara
, ParaFlag::ISPAGE
);
1783 SdStyleSheet
* pStyleSheet
= dynamic_cast< SdStyleSheet
* >( mrOutliner
.GetStyleSheet( nPara
) );
1786 const OUString
aName( pStyleSheet
->GetApiName() );
1787 if ( aName
== "title" )
1793 continue; // fatality!?
1795 if( bPage
&& (nPara
!= pInfos
->nStartPara
) )
1797 // insert new slide for this paragraph
1798 pPage
= InsertSlideForParagraph( pPara
);
1802 // newly inserted non page paragraphs get the outline style
1804 pPage
= GetPageForParagraph( pPara
);
1808 SfxStyleSheet
* pStyle
= pPage
->GetStyleSheetForPresObj( bPage
? PRESOBJ_TITLE
: PRESOBJ_OUTLINE
);
1812 const sal_Int16 nDepth
= mrOutliner
.GetDepth( nPara
);
1815 OUString aStyleSheetName
= pStyle
->GetName();
1816 if (!aStyleSheetName
.isEmpty())
1817 aStyleSheetName
= aStyleSheetName
.copy(0, aStyleSheetName
.getLength() - 1);
1818 aStyleSheetName
+= OUString::number( nDepth
);
1819 pStyle
= static_cast<SfxStyleSheet
*>( pStylePool
->Find( aStyleSheetName
, pStyle
->GetFamily() ) );
1820 DBG_ASSERT( pStyle
, "sd::OutlineView::OnEndPasteOrDrop(), Style not found!" );
1824 mrOutliner
.SetStyleSheet( nPara
, pStyle
);
1827 UpdateParagraph( nPara
);
1832 // - OutlineViewModelChangeGuard -
1834 OutlineViewModelChangeGuard::OutlineViewModelChangeGuard( OutlineView
& rView
)
1837 mrView
.BeginModelChange();
1840 OutlineViewModelChangeGuard::~OutlineViewModelChangeGuard()
1842 mrView
.EndModelChange();
1845 // - OutlineViewPageChangesGuard -
1847 OutlineViewPageChangesGuard::OutlineViewPageChangesGuard( OutlineView
* pView
)
1851 mpView
->IgnoreCurrentPageChanges( true );
1854 OutlineViewPageChangesGuard::~OutlineViewPageChangesGuard()
1857 mpView
->IgnoreCurrentPageChanges( false );
1860 } // end of namespace sd
1862 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */