1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: drawview.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
33 #include <sfx2/dispatch.hxx>
34 #ifndef _MSGBOX_HXX //autogen
35 #include <vcl/msgbox.hxx>
37 #include <svx/svdpagv.hxx>
38 #include <sfx2/request.hxx>
39 #include <svtools/style.hxx>
40 #include <svx/outliner.hxx>
41 #ifndef _VIEW3D_HXX //autogen
42 #include <svx/view3d.hxx>
44 #ifndef _SVXIDS_HRC //autogen
45 #include <svx/svxids.hrc>
47 #include <svx/svdotext.hxx>
48 #include <svx/svdograf.hxx>
49 #include <svx/svdogrp.hxx>
50 #include <svx/svdorect.hxx>
51 #include <svtools/poolitem.hxx>
52 #include <svx/eeitem.hxx>
53 #include <svx/bulitem.hxx>
54 #include <svtools/itempool.hxx>
55 #include <svx/numitem.hxx>
56 #include <svtools/whiter.hxx>
58 #include <sfx2/viewfrm.hxx>
59 #include <sfx2/objface.hxx>
60 #include "stlsheet.hxx"
62 #include <svx/svdoutl.hxx>
64 #include <svx/svdstr.hrc>
65 #include <svx/dialmgr.hxx>
68 #include "strings.hrc"
71 #include "drawview.hxx"
72 #include "drawdoc.hxx"
73 #include "DrawDocShell.hxx"
75 #include "DrawViewShell.hxx"
77 #include "sdresid.hxx"
81 #include "FrameView.hxx"
83 #include "anminfo.hxx"
84 #include "slideshow.hxx"
85 #include <vcl/virdev.hxx>
86 #include <svx/sdrpaintwindow.hxx>
87 #include <svx/sdr/contact/viewobjectcontact.hxx>
88 #include <svx/sdr/contact/viewcontact.hxx>
89 #include <svx/sdr/contact/displayinfo.hxx>
91 #include "undo/undomanager.hxx"
93 using namespace ::com::sun::star
;
97 TYPEINIT1(DrawView
, View
);
99 /*************************************************************************
102 |* zeigt die erste Seite des Dokuments auf Position 0,0 an;
103 |* falls noch keine Seite vorhanden ist, wird eine erzeugt
105 \************************************************************************/
107 DrawView::DrawView( DrawDocShell
* pDocSh
, OutputDevice
* pOutDev
, DrawViewShell
* pShell
)
108 : ::sd::View(pDocSh
->GetDoc(), pOutDev
, pShell
)
110 , mpDrawViewShell(pShell
)
114 SetCurrentObj(OBJ_RECT
, SdrInventor
);
117 /*************************************************************************
121 \************************************************************************/
123 DrawView::~DrawView()
128 /*************************************************************************
130 |* virtuelle Methode von SdrView, wird bei Selektionsaenderung gerufen
132 \************************************************************************/
134 void DrawView::MarkListHasChanged()
136 ::sd::View::MarkListHasChanged();
139 mpDrawViewShell
->SelectionHasChanged();
142 /*************************************************************************
144 |* virtuelle Methode von SdrView, wird bei Modelaenderung gerufen
146 \************************************************************************/
148 void DrawView::ModelHasChanged()
150 ::sd::View::ModelHasChanged();
152 // den Gestalter zur Neudarstellung zwingen
153 SfxStyleSheetBasePool
* pSSPool
= mpDoc
->GetStyleSheetPool();
154 pSSPool
->Broadcast(SfxStyleSheetPoolHint(SFX_STYLESHEETPOOL_CHANGES
));
156 if( mpDrawViewShell
)
157 mpDrawViewShell
->ModelHasChanged();
161 /*************************************************************************
163 |* Attribute auf Titel- und Gliederungtext und Hintergrundrechteck einer
164 |* Masterpage in Vorlagen umlenken, sonst an Basisklasse weitergeben
166 \************************************************************************/
168 BOOL
DrawView::SetAttributes(const SfxItemSet
& rSet
,
173 // wird eine Masterpage bearbeitet?
174 if ( mpDrawViewShell
&& mpDrawViewShell
->GetEditMode() == EM_MASTERPAGE
)
176 SfxStyleSheetBasePool
* pStShPool
= mpDoc
->GetStyleSheetPool();
177 SdPage
& rPage
= *mpDrawViewShell
->getCurrentPage();
178 String aLayoutName
= rPage
.GetName();
179 SdrTextObj
* pEditObject
= static_cast< SdrTextObj
* >( GetTextEditObject() );
184 String
aTemplateName(aLayoutName
);
186 UINT32 nInv
= pEditObject
->GetObjInventor();
188 if (nInv
== SdrInventor
)
190 UINT16 eObjKind
= pEditObject
->GetObjIdentifier();
191 PresObjKind ePresObjKind
= rPage
.GetPresObjKind(pEditObject
);
193 if ( ePresObjKind
== PRESOBJ_TITLE
||
194 ePresObjKind
== PRESOBJ_NOTES
)
196 // Presentation object (except outline)
197 SfxStyleSheet
* pSheet
= rPage
.GetStyleSheetForPresObj( ePresObjKind
);
198 DBG_ASSERT(pSheet
, "StyleSheet nicht gefunden");
200 SfxItemSet
aTempSet( pSheet
->GetItemSet() );
201 aTempSet
.Put( rSet
);
202 aTempSet
.ClearInvalidItems();
205 StyleSheetUndoAction
* pAction
= new StyleSheetUndoAction(mpDoc
, pSheet
, &aTempSet
);
206 mpDocSh
->GetUndoManager()->AddUndoAction(pAction
);
208 pSheet
->GetItemSet().Put(aTempSet
);
209 pSheet
->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED
));
212 else if (eObjKind
== OBJ_OUTLINETEXT
)
214 // Presentation object outline
215 OutlinerView
* pOV
= GetTextEditOutlinerView();
216 ::Outliner
* pOutliner
= pOV
->GetOutliner();
217 List
* pList
= (List
*)pOV
->CreateSelectionList();
218 aTemplateName
+= String(SdResId(STR_LAYOUT_OUTLINE
));
220 pOutliner
->SetUpdateMode(FALSE
);
221 mpDocSh
->SetWaitCursor( TRUE
);
223 // Platzhalter durch Vorlagennamen ersetzen
224 String
aComment(SdResId(STR_UNDO_CHANGE_PRES_OBJECT
));
225 xub_StrLen nPos
= aComment
.Search( (sal_Unicode
)'$' );
226 aComment
.Erase(nPos
, 1);
227 aComment
.Insert( String((SdResId(STR_PSEUDOSHEET_OUTLINE
))), nPos
);
228 mpDocSh
->GetUndoManager()->EnterListAction( aComment
, String() );
230 Paragraph
* pPara
= (Paragraph
*)pList
->Last();
233 ULONG nParaPos
= pOutliner
->GetAbsPos( pPara
);
234 sal_Int16 nDepth
= pOutliner
->GetDepth( (USHORT
) nParaPos
);
235 String
aName(rPage
.GetLayoutName());
236 aName
+= (sal_Unicode
)(' ');
237 aName
+= String::CreateFromInt32( (nDepth
<= 0) ? 1 : nDepth
+ 1 );
238 SfxStyleSheet
* pSheet
= (SfxStyleSheet
*)pStShPool
->Find(aName
, SD_STYLE_FAMILY_MASTERPAGE
);
239 DBG_ASSERT(pSheet
, "StyleSheet nicht gefunden");
241 SfxItemSet
aTempSet( pSheet
->GetItemSet() );
242 aTempSet
.Put( rSet
);
243 aTempSet
.ClearInvalidItems();
245 if( nDepth
> 0 && aTempSet
.GetItemState( EE_PARA_NUMBULLET
) == SFX_ITEM_ON
)
247 // no SvxNumBulletItem in outline level 1 to 8!
248 aTempSet
.ClearItem( EE_PARA_NUMBULLET
);
252 StyleSheetUndoAction
* pAction
= new StyleSheetUndoAction(mpDoc
, pSheet
, &aTempSet
);
253 mpDocSh
->GetUndoManager()->AddUndoAction(pAction
);
255 pSheet
->GetItemSet().Put(aTempSet
);
256 pSheet
->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED
));
258 // now also broadcast any child sheets
260 for( nChild
= nDepth
+ 1; nChild
< 9; nChild
++ )
262 String
aSheetName(rPage
.GetLayoutName());
263 aSheetName
+= (sal_Unicode
)(' ');
264 aSheetName
+= String::CreateFromInt32( nChild
<= 0 ? 1 : nChild
+ 1 );
265 SfxStyleSheet
* pOutlSheet
= static_cast< SfxStyleSheet
* >(pStShPool
->Find(aSheetName
, SD_STYLE_FAMILY_MASTERPAGE
));
268 pOutlSheet
->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED
));
271 pPara
= (Paragraph
*)pList
->Prev();
273 if( !pPara
&& nDepth
> 0 && rSet
.GetItemState( EE_PARA_NUMBULLET
) == SFX_ITEM_ON
&&
274 pOutliner
->GetDepth( (USHORT
) pOutliner
->GetAbsPos( (Paragraph
*) pList
->First() ) ) > 0 )
275 pPara
= pOutliner
->GetParagraph( 0 ); // Put NumBulletItem in outline level 1
278 mpDocSh
->SetWaitCursor( FALSE
);
279 pOV
->GetOutliner()->SetUpdateMode(TRUE
);
281 mpDocSh
->GetUndoManager()->LeaveListAction();
288 bOk
= ::sd::View::SetAttributes(rSet
, bReplaceAll
);
295 const SdrMarkList
& rList
= GetMarkedObjectList();
296 ULONG nMarkCount
= rList
.GetMarkCount();
297 for (ULONG nMark
= 0; nMark
< nMarkCount
; nMark
++)
299 SdrObject
* pObject
= rList
.GetMark(nMark
)->GetMarkedSdrObj();
300 UINT32 nInv
= pObject
->GetObjInventor();
302 if (nInv
== SdrInventor
)
304 UINT16 eObjKind
= pObject
->GetObjIdentifier();
305 PresObjKind ePresObjKind
= rPage
.GetPresObjKind(pObject
);
306 String
aTemplateName(aLayoutName
);
308 if (ePresObjKind
== PRESOBJ_TITLE
||
309 ePresObjKind
== PRESOBJ_NOTES
||
310 ePresObjKind
== PRESOBJ_BACKGROUND
)
312 // Presentation object (except outline)
313 SfxStyleSheet
* pSheet
= rPage
.GetStyleSheetForPresObj( ePresObjKind
);
314 DBG_ASSERT(pSheet
, "StyleSheet not found");
316 SfxItemSet
aTempSet( pSheet
->GetItemSet() );
317 aTempSet
.Put( rSet
);
318 aTempSet
.ClearInvalidItems();
321 StyleSheetUndoAction
* pAction
= new StyleSheetUndoAction(mpDoc
, pSheet
, &aTempSet
);
322 mpDocSh
->GetUndoManager()->AddUndoAction(pAction
);
324 pSheet
->GetItemSet().Put(aTempSet
,false);
325 pSheet
->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED
));
328 else if (eObjKind
== OBJ_OUTLINETEXT
)
330 // Presentation object outline
331 aTemplateName
+= String(SdResId(STR_LAYOUT_OUTLINE
));
332 for (USHORT nLevel
= 9; nLevel
> 0; nLevel
--)
334 String
aName(rPage
.GetLayoutName());
335 aName
+= (sal_Unicode
)(' ');
336 aName
+= String::CreateFromInt32( (sal_Int32
)nLevel
);
337 SfxStyleSheet
* pSheet
= (SfxStyleSheet
*)pStShPool
->
338 Find(aName
, SD_STYLE_FAMILY_MASTERPAGE
);
339 DBG_ASSERT(pSheet
, "StyleSheet nicht gefunden");
341 SfxItemSet
aTempSet( pSheet
->GetItemSet() );
345 // for all levels over 1, clear all items that will be
346 // hard set to level 1
347 SfxWhichIter
aWhichIter(rSet
);
348 sal_uInt16
nWhich(aWhichIter
.FirstWhich());
351 if( SFX_ITEM_ON
== rSet
.GetItemState( nWhich
) )
352 aTempSet
.ClearItem( nWhich
);
353 nWhich
= aWhichIter
.NextWhich();
359 // put the items hard into level one
360 aTempSet
.Put( rSet
);
363 aTempSet
.ClearInvalidItems();
366 StyleSheetUndoAction
* pAction
= new StyleSheetUndoAction(mpDoc
, pSheet
, &aTempSet
);
367 mpDocSh
->GetUndoManager()->AddUndoAction(pAction
);
369 pSheet
->GetItemSet().Set(aTempSet
,false);
370 pSheet
->Broadcast(SfxSimpleHint(SFX_HINT_DATACHANGED
));
373 // remove all hard set items from shape that are now set in style
374 SfxWhichIter
aWhichIter(rSet
);
375 sal_uInt16
nWhich(aWhichIter
.FirstWhich());
378 if( SFX_ITEM_ON
== rSet
.GetItemState( nWhich
) )
379 pObject
->ClearMergedItem( nWhich
);
380 nWhich
= aWhichIter
.NextWhich();
389 bOk
= ::sd::View::SetAttributes(rSet
, bReplaceAll
);
392 else // nicht auf der Masterpage
394 bOk
= ::sd::View::SetAttributes(rSet
, bReplaceAll
);
400 /*************************************************************************
402 |* Notify fuer Aenderung der Seitenanordnung
404 \************************************************************************/
406 void DrawView::Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
408 if ( mpDrawViewShell
&& rHint
.ISA(SdrHint
) )
410 SdrHintKind eHintKind
= ( (SdrHint
&) rHint
).GetKind();
412 if ( mnPOCHSmph
== 0 && eHintKind
== HINT_PAGEORDERCHG
)
414 mpDrawViewShell
->ResetActualPage();
416 else if ( eHintKind
== HINT_LAYERCHG
|| eHintKind
== HINT_LAYERORDERCHG
)
418 mpDrawViewShell
->ResetActualLayer();
421 // #94278# switch to that page when it's not a master page
422 if(HINT_SWITCHTOPAGE
== eHintKind
)
424 const SdrPage
* pPage
= ((const SdrHint
&)rHint
).GetPage();
426 if(pPage
&& !pPage
->IsMasterPage())
428 if(mpDrawViewShell
->GetActualPage() != pPage
)
430 sal_uInt16 nPageNum
= (pPage
->GetPageNum() - 1) / 2; // Sdr --> Sd
431 mpDrawViewShell
->SwitchPage(nPageNum
);
437 ::sd::View::Notify(rBC
, rHint
);
440 /*************************************************************************
442 |* PageOrderChangedHint blockieren/freigeben
444 \************************************************************************/
446 void DrawView::BlockPageOrderChangedHint(BOOL bBlock
)
452 DBG_ASSERT(mnPOCHSmph
, "Zaehlerunterlauf");
457 /*************************************************************************
459 |* StyleSheet-Setzen auf der Masterpage abfangen, wenn Praesentationsobjekte
462 \************************************************************************/
464 BOOL
DrawView::SetStyleSheet(SfxStyleSheet
* pStyleSheet
, BOOL bDontRemoveHardAttr
)
468 // wird eine Masterpage bearbeitet?
469 if (mpDrawViewShell
&& mpDrawViewShell
->GetEditMode() == EM_MASTERPAGE
)
471 if (IsPresObjSelected(FALSE
, TRUE
))
474 InfoBox(mpDrawViewShell
->GetActiveWindow(),
475 String(SdResId(STR_ACTION_NOTPOSSIBLE
))).Execute();
480 bResult
= ::sd::View::SetStyleSheet(pStyleSheet
, bDontRemoveHardAttr
);
485 bResult
= ::sd::View::SetStyleSheet(pStyleSheet
, bDontRemoveHardAttr
);
490 /*************************************************************************
492 |* Paint-Methode: das Ereignis wird an die View weitergeleitet
494 \************************************************************************/
496 void DrawView::CompleteRedraw(OutputDevice
* pOutDev
, const Region
& rReg
, sdr::contact::ViewObjectContactRedirector
* pRedirector
/*=0L*/)
504 BOOL bStandardPaint
= TRUE
;
506 SdDrawDocument
* pDoc
= mpDocShell
->GetDoc();
507 if( pDoc
&& pDoc
->GetDocumentType() == DOCUMENT_TYPE_IMPRESS
)
509 rtl::Reference
< sd::SlideShow
> xSlideshow( SlideShow::GetSlideShow( pDoc
) );
510 if(xSlideshow
.is() && xSlideshow
->isRunning())
512 OutputDevice
* pShowWindow
= ( OutputDevice
* )xSlideshow
->getShowWindow();
513 if( (pShowWindow
== pOutDev
) || (xSlideshow
->getAnimationMode() == ANIMATIONMODE_PREVIEW
) )
515 if( pShowWindow
== pOutDev
)
517 bStandardPaint
= FALSE
;
524 ::sd::View::CompleteRedraw(pOutDev
, rReg
, pRedirector
);
528 /*************************************************************************
530 |* Paint-Event during running slide show
532 \************************************************************************/
534 void DrawView::PresPaint(const Region
& rRegion
)
538 rtl::Reference
< SlideShow
> xSlideshow( SlideShow::GetSlideShow( GetDoc() ) );
539 if( xSlideshow
.is() && xSlideshow
->isRunning() )
540 xSlideshow
->paint( rRegion
.GetBoundRect() );
544 /*************************************************************************
545 |* entscheidet, ob ein Objekt markiert werden kann (z. B. noch nicht
546 |* erschienene Animationsobjekte in der Diashow)
547 \************************************************************************/
549 BOOL
DrawView::IsObjMarkable(SdrObject
* pObj
, SdrPageView
* pPV
) const
551 return FmFormView::IsObjMarkable(pObj
, pPV
);;
554 /*************************************************************************
556 |* Uebergebenen Bereich sichtbar machen (es wird ggf. gescrollt)
558 \************************************************************************/
560 void DrawView::MakeVisible(const Rectangle
& rRect
, ::Window
& rWin
)
562 if (!rRect
.IsEmpty())
564 mpDrawViewShell
->MakeVisible(rRect
, rWin
);
567 /*************************************************************************
569 |* Seite wird gehided
571 \************************************************************************/
573 void DrawView::HideSdrPage()
577 mpDrawViewShell
->HidePage();
580 ::sd::View::HideSdrPage();
583 SdrObject
* DrawView::GetMaxToBtmObj(SdrObject
* pObj
) const
587 SdPage
* pPage
= (SdPage
*)pObj
->GetPage();
588 if( pPage
&& pPage
->IsMasterPage() )
589 return pPage
->GetPresObj( PRESOBJ_BACKGROUND
) ;
594 void DrawView::DeleteMarked()
596 sd::UndoManager
* pUndoManager
= mpDoc
->GetUndoManager();
597 DBG_ASSERT( pUndoManager
, "sd::DrawView::DeleteMarked(), ui action without undo manager!?" );
601 String
aUndo( SVX_RES(STR_EditDelete
) );
602 String
aSearchString(RTL_CONSTASCII_USTRINGPARAM("%1"));
603 aUndo
.SearchAndReplace(aSearchString
, GetDescriptionOfMarkedObjects());
604 pUndoManager
->EnterListAction(aUndo
, aUndo
);
609 const SdrMarkList
& rList
= GetMarkedObjectList();
610 ULONG nMarkCount
= rList
.GetMarkCount();
611 for (ULONG nMark
= 0; nMark
< nMarkCount
; nMark
++)
613 SdrObject
* pObj
= rList
.GetMark(nMark
)->GetMarkedSdrObj();
614 if( pObj
&& !pObj
->IsEmptyPresObj() && pObj
->GetUserCall() )
616 pPage
= dynamic_cast< SdPage
* >( pObj
->GetPage() );
617 PresObjKind ePresObjKind
;
618 if( pPage
&& ((ePresObjKind
= pPage
->GetPresObjKind(pObj
)) != PRESOBJ_NONE
))
620 SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >( pObj
);
621 bool bVertical
= pTextObj
&& pTextObj
->IsVerticalWriting();
622 Rectangle
aRect( pObj
->GetLogicRect() );
623 pPage
->InsertAutoLayoutShape( 0, ePresObjKind
, bVertical
, aRect
, true );
628 ::sd::View::DeleteMarked();
631 pPage
->SetAutoLayout( pPage
->GetAutoLayout() );
634 pUndoManager
->LeaveListAction();
637 } // end of namespace sd