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 <com/sun/star/embed/EmbedMisc.hpp>
22 #include "scitems.hxx"
23 #include <editeng/eeitem.hxx>
24 #include <editeng/sizeitem.hxx>
25 #include <svx/svdpagv.hxx>
26 #include <svx/xdef.hxx>
27 #include <sfx2/app.hxx>
28 #include <sfx2/objsh.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <svl/ptitem.hxx>
31 #include <svl/whiter.hxx>
32 #include <svx/svdobj.hxx>
33 #include <svx/svdouno.hxx>
34 #include <svx/extrusionbar.hxx>
35 #include <svx/fontworkbar.hxx>
36 #include <svx/sidebar/SelectionChangeHandler.hxx>
37 #include <svx/sidebar/SelectionAnalyzer.hxx>
38 #include <svx/sidebar/ContextChangeEventMultiplexer.hxx>
41 #include "drawview.hxx"
42 #include "viewdata.hxx"
44 #include "tabvwsh.hxx"
45 #include "document.hxx"
46 #include "drwlayer.hxx"
47 #include "userdat.hxx"
48 #include "drtxtob.hxx"
49 #include <gridwin.hxx>
50 #include <svx/svdoole2.hxx>
51 #include <svx/svdocapt.hxx>
53 #include <boost/bind.hpp>
55 using namespace com::sun::star
;
57 ScDrawShell::ScDrawShell( ScViewData
* pData
) :
58 SfxShell(pData
->GetViewShell()),
60 mpSelectionChangeHandler(new svx::sidebar::SelectionChangeHandler(
61 ::boost::bind(&ScDrawShell::GetSidebarContextName
, this),
62 GetFrame()->GetFrame().GetController(),
63 sfx2::sidebar::EnumContext::Context_Cell
))
65 SetPool( &pViewData
->GetScDrawView()->GetModel()->GetItemPool() );
66 ::svl::IUndoManager
* pMgr
= pViewData
->GetSfxDocShell()->GetUndoManager();
67 SetUndoManager( pMgr
);
68 if ( !pViewData
->GetDocument()->IsUndoEnabled() )
70 pMgr
->SetMaxUndoActionCount( 0 );
72 SetHelpId( HID_SCSHELL_DRAWSH
);
73 SetName(OUString("Drawing"));
75 mpSelectionChangeHandler
->Connect();
78 ScDrawShell::~ScDrawShell()
80 mpSelectionChangeHandler
->Disconnect();
83 void ScDrawShell::GetState( SfxItemSet
& rSet
) // Zustaende / Toggles
85 ScDrawView
* pView
= pViewData
->GetScDrawView();
86 SdrDragMode eMode
= pView
->GetDragMode();
88 rSet
.Put( SfxBoolItem( SID_OBJECT_ROTATE
, eMode
== SDRDRAG_ROTATE
) );
89 rSet
.Put( SfxBoolItem( SID_OBJECT_MIRROR
, eMode
== SDRDRAG_MIRROR
) );
90 rSet
.Put( SfxBoolItem( SID_BEZIER_EDIT
, !pView
->IsFrameDragSingles() ) );
92 sal_uInt16 nFWId
= ScGetFontWorkId();
93 SfxViewFrame
* pViewFrm
= pViewData
->GetViewShell()->GetViewFrame();
94 rSet
.Put(SfxBoolItem(SID_FONTWORK
, pViewFrm
->HasChildWindow(nFWId
)));
96 // Notes always default to Page anchor.
97 bool bDisableAnchor
= false;
98 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
99 if ( rMarkList
.GetMarkCount() == 1 )
101 SdrObject
* pObj
= rMarkList
.GetMark( 0 )->GetMarkedSdrObj();
102 if( ScDrawLayer::IsNoteCaption( pObj
) )
104 bDisableAnchor
= true;
105 rSet
.DisableItem( SID_ANCHOR_PAGE
);
106 rSet
.DisableItem( SID_ANCHOR_CELL
);
110 if ( !bDisableAnchor
)
112 switch( pView
->GetAnchorType() )
115 rSet
.Put( SfxBoolItem( SID_ANCHOR_PAGE
, true ) );
116 rSet
.Put( SfxBoolItem( SID_ANCHOR_CELL
, false ) );
120 rSet
.Put( SfxBoolItem( SID_ANCHOR_PAGE
, false ) );
121 rSet
.Put( SfxBoolItem( SID_ANCHOR_CELL
, true ) );
125 rSet
.Put( SfxBoolItem( SID_ANCHOR_PAGE
, false ) );
126 rSet
.Put( SfxBoolItem( SID_ANCHOR_CELL
, false ) );
132 void ScDrawShell::GetDrawFuncState( SfxItemSet
& rSet
) // Funktionen disablen
134 ScDrawView
* pView
= pViewData
->GetScDrawView();
136 // call IsMirrorAllowed first to make sure ForcePossibilities (and thus CheckMarked)
137 // is called before GetMarkCount, so the nMarkCount value is valid for the rest of this method.
138 if (!pView
->IsMirrorAllowed(true,true))
140 rSet
.DisableItem( SID_MIRROR_HORIZONTAL
);
141 rSet
.DisableItem( SID_MIRROR_VERTICAL
);
142 rSet
.DisableItem( SID_FLIP_HORIZONTAL
);
143 rSet
.DisableItem( SID_FLIP_VERTICAL
);
146 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
147 const size_t nMarkCount
= rMarkList
.GetMarkCount();
149 if ( nMarkCount
<= 1 || !pView
->IsGroupPossible() )
150 rSet
.DisableItem( SID_GROUP
);
151 if ( nMarkCount
== 0 || !pView
->IsUnGroupPossible() )
152 rSet
.DisableItem( SID_UNGROUP
);
153 if ( nMarkCount
!= 1 || !pView
->IsGroupEnterPossible() )
154 rSet
.DisableItem( SID_ENTER_GROUP
);
155 if ( !pView
->IsGroupEntered() )
156 rSet
.DisableItem( SID_LEAVE_GROUP
);
158 if ( nMarkCount
<= 1 ) // nichts oder nur ein Objekt selektiert
161 rSet
.DisableItem( SID_OBJECT_ALIGN_LEFT
); // keine Ausrichtung an der Seite
162 rSet
.DisableItem( SID_OBJECT_ALIGN_CENTER
);
163 rSet
.DisableItem( SID_OBJECT_ALIGN_RIGHT
);
164 rSet
.DisableItem( SID_OBJECT_ALIGN_UP
);
165 rSet
.DisableItem( SID_OBJECT_ALIGN_MIDDLE
);
166 rSet
.DisableItem( SID_OBJECT_ALIGN_DOWN
);
168 // pseudo slots for Format menu
169 rSet
.DisableItem( SID_ALIGN_ANY_LEFT
);
170 rSet
.DisableItem( SID_ALIGN_ANY_HCENTER
);
171 rSet
.DisableItem( SID_ALIGN_ANY_RIGHT
);
172 rSet
.DisableItem( SID_ALIGN_ANY_TOP
);
173 rSet
.DisableItem( SID_ALIGN_ANY_VCENTER
);
174 rSet
.DisableItem( SID_ALIGN_ANY_BOTTOM
);
177 // do not change layer of form controls
178 // #i83729# do not change layer of cell notes (on internal layer)
179 if ( !nMarkCount
|| pView
->HasMarkedControl() || pView
->HasMarkedInternal() )
181 rSet
.DisableItem( SID_OBJECT_HEAVEN
);
182 rSet
.DisableItem( SID_OBJECT_HELL
);
186 if(AreAllObjectsOnLayer(SC_LAYER_FRONT
,rMarkList
))
188 rSet
.DisableItem( SID_OBJECT_HEAVEN
);
190 else if(AreAllObjectsOnLayer(SC_LAYER_BACK
,rMarkList
))
192 rSet
.DisableItem( SID_OBJECT_HELL
);
196 bool bCanRename
= false;
197 if ( nMarkCount
> 1 )
199 // no hypelink options for a selected group
200 rSet
.DisableItem( SID_DRAW_HLINK_EDIT
);
201 rSet
.DisableItem( SID_DRAW_HLINK_DELETE
);
202 rSet
.DisableItem( SID_OPEN_HYPERLINK
);
204 else if ( nMarkCount
== 1 )
206 SdrObject
* pObj
= rMarkList
.GetMark( 0 )->GetMarkedSdrObj();
207 ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( pObj
);
208 if ( !pInfo
|| pInfo
->GetHlink().isEmpty() )
210 rSet
.DisableItem( SID_DRAW_HLINK_DELETE
);
211 rSet
.DisableItem( SID_OPEN_HYPERLINK
);
213 SdrLayerID nLayerID
= pObj
->GetLayer();
214 if ( nLayerID
!= SC_LAYER_INTERN
)
215 bCanRename
= true; // #i51351# anything except internal objects can be renamed
217 // #91929#; don't show original size entry if not possible
218 sal_uInt16 nObjType
= pObj
->GetObjIdentifier();
219 if ( nObjType
== OBJ_OLE2
)
221 SdrOle2Obj
* pOleObj
= static_cast<SdrOle2Obj
*>(rMarkList
.GetMark( 0 )->GetMarkedSdrObj());
222 if (pOleObj
->GetObjRef().is() &&
223 ((pOleObj
->GetObjRef()->getStatus( pOleObj
->GetAspect() ) & embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE
) ) )
224 //TODO/LATER: why different slots in Draw and Calc?
225 rSet
.DisableItem(SID_ORIGINALSIZE
);
227 else if ( nObjType
== OBJ_CAPTION
)
229 if ( nLayerID
== SC_LAYER_INTERN
)
231 // SdrCaptionObj() Notes cannot be cut/copy in isolation from
233 rSet
.DisableItem( SID_CUT
);
234 rSet
.DisableItem( SID_COPY
);
235 // Notes always default to Page anchor.
236 rSet
.DisableItem( SID_ANCHOR_TOGGLE
);
243 rSet
.DisableItem( SID_RENAME_OBJECT
);
244 rSet
.DisableItem( SID_TITLE_DESCRIPTION_OBJECT
);
247 if ( !nMarkCount
) // nichts selektiert
250 rSet
.DisableItem( SID_FRAME_UP
);
251 rSet
.DisableItem( SID_FRAME_DOWN
);
252 rSet
.DisableItem( SID_FRAME_TO_TOP
);
253 rSet
.DisableItem( SID_FRAME_TO_BOTTOM
);
254 // Clipboard / loeschen
255 rSet
.DisableItem( SID_DELETE
);
256 rSet
.DisableItem( SID_DELETE_CONTENTS
);
257 rSet
.DisableItem( SID_CUT
);
258 rSet
.DisableItem( SID_COPY
);
260 rSet
.DisableItem( SID_ANCHOR_TOGGLE
);
261 rSet
.DisableItem( SID_ORIGINALSIZE
);
262 rSet
.DisableItem( SID_ATTR_TRANSFORM
);
265 if ( rSet
.GetItemState( SID_ENABLE_HYPHENATION
) != SfxItemState::UNKNOWN
)
267 SfxItemSet
aAttrs( pView
->GetModel()->GetItemPool() );
268 pView
->GetAttributes( aAttrs
);
269 if( aAttrs
.GetItemState( EE_PARA_HYPHENATE
) >= SfxItemState::DEFAULT
)
271 bool bValue
= static_cast<const SfxBoolItem
&>( aAttrs
.Get( EE_PARA_HYPHENATE
) ).GetValue();
272 rSet
.Put( SfxBoolItem( SID_ENABLE_HYPHENATION
, bValue
) );
276 svx::ExtrusionBar::getState( pView
, rSet
);
277 svx::FontworkBar::getState( pView
, rSet
);
280 // Attribute fuer Drawing-Objekte
282 void ScDrawShell::GetDrawAttrState( SfxItemSet
& rSet
)
284 Point aMousePos
= pViewData
->GetMousePosPixel();
285 vcl::Window
* pWindow
= pViewData
->GetActiveWin();
286 ScDrawView
* pDrView
= pViewData
->GetScDrawView();
287 Point aPos
= pWindow
->PixelToLogic(aMousePos
);
288 bool bHasMarked
= pDrView
->AreObjectsMarked();
292 rSet
.Put( pDrView
->GetAttrFromMarked(false), false );
296 rSet
.Put( pDrView
->GetDefaultAttr() );
299 SdrPageView
* pPV
= pDrView
->GetSdrPageView();
302 // #i52073# when a sheet with an active OLE object is deleted,
303 // the slot state is queried without an active page view
305 // Items for position and size (see ScGridWindow::UpdateStatusPosSize, #108137#)
307 // #i34458# The SvxSizeItem in SID_TABLE_CELL is no longer needed by
308 // SvxPosSizeStatusBarControl, it's enough to have it in SID_ATTR_SIZE.
310 bool bActionItem
= false;
311 if ( pDrView
->IsAction() ) // action rectangle
314 pDrView
->TakeActionRect( aRect
);
315 if ( !aRect
.IsEmpty() )
317 pPV
->LogicToPagePos(aRect
);
318 rSet
.Put( SfxPointItem( SID_ATTR_POSITION
, aRect
.TopLeft() ) );
319 Size
aSize( aRect
.Right() - aRect
.Left(), aRect
.Bottom() - aRect
.Top() );
320 rSet
.Put( SvxSizeItem( SID_ATTR_SIZE
, aSize
) );
326 if ( pDrView
->AreObjectsMarked() ) // selected objects
328 Rectangle aRect
= pDrView
->GetAllMarkedRect();
329 pPV
->LogicToPagePos(aRect
);
330 rSet
.Put( SfxPointItem( SID_ATTR_POSITION
, aRect
.TopLeft() ) );
331 Size
aSize( aRect
.Right() - aRect
.Left(), aRect
.Bottom() - aRect
.Top() );
332 rSet
.Put( SvxSizeItem( SID_ATTR_SIZE
, aSize
) );
334 else // mouse position
336 // aPos is initialized above
337 pPV
->LogicToPagePos(aPos
);
338 rSet
.Put( SfxPointItem( SID_ATTR_POSITION
, aPos
) );
339 rSet
.Put( SvxSizeItem( SID_ATTR_SIZE
, Size( 0, 0 ) ) );
345 void ScDrawShell::GetAttrFuncState(SfxItemSet
&rSet
)
347 // Dialoge fuer Draw-Attribute disablen, wenn noetig
349 ScDrawView
* pDrView
= pViewData
->GetScDrawView();
350 SfxItemSet aViewSet
= pDrView
->GetAttrFromMarked(false);
352 if ( aViewSet
.GetItemState( XATTR_LINESTYLE
) == SfxItemState::DEFAULT
)
354 rSet
.DisableItem( SID_ATTRIBUTES_LINE
);
355 rSet
.DisableItem( SID_ATTR_LINEEND_STYLE
); // Tbx-Controller
358 if ( aViewSet
.GetItemState( XATTR_FILLSTYLE
) == SfxItemState::DEFAULT
)
359 rSet
.DisableItem( SID_ATTRIBUTES_AREA
);
362 bool ScDrawShell::AreAllObjectsOnLayer(sal_uInt16 nLayerNo
,const SdrMarkList
& rMark
)
365 const size_t nCount
= rMark
.GetMarkCount();
366 for (size_t i
=0; i
<nCount
; ++i
)
368 SdrObject
* pObj
= rMark
.GetMark(i
)->GetMarkedSdrObj();
369 if ( !pObj
->ISA(SdrUnoObj
) )
371 if(nLayerNo
!=pObj
->GetLayer())
381 void ScDrawShell::GetDrawAttrStateForIFBX( SfxItemSet
& rSet
)
383 ScDrawView
* pView
= pViewData
->GetScDrawView();
384 const SdrMarkList
& rMarkList
= pView
->GetMarkedObjectList();
386 if( rMarkList
.GetMark(0) != 0 )
388 SfxItemSet
aNewAttr(pView
->GetGeoAttrFromMarked());
389 rSet
.Put(aNewAttr
, false);
393 void ScDrawShell::Activate (const bool bMDI
)
397 ContextChangeEventMultiplexer::NotifyContextChange(
398 GetFrame()->GetFrame().GetController(),
399 ::sfx2::sidebar::EnumContext::GetContextEnum(
400 GetSidebarContextName()));
403 ::rtl::OUString
ScDrawShell::GetSidebarContextName()
405 return sfx2::sidebar::EnumContext::GetContextName(
406 svx::sidebar::SelectionAnalyzer::GetContextForSelection_SC(
407 GetDrawView()->GetMarkedObjectList()));
410 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */