Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / uibase / shells / drawsh.cxx
blob23c4dd61872d523319c55d288e8ca695d25a96f4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <svx/svdview.hxx>
21 #include <svx/svdotext.hxx>
22 #include <svl/whiter.hxx>
23 #include <svx/fontwork.hxx>
24 #include <sfx2/request.hxx>
25 #include <sfx2/bindings.hxx>
26 #include <sfx2/objface.hxx>
27 #include <sfx2/viewfrm.hxx>
28 #include <svx/extrusionbar.hxx>
29 #include <svx/fontworkbar.hxx>
30 #include <uitool.hxx>
31 #include <dcontact.hxx>
32 #include <textboxhelper.hxx>
33 #include <wview.hxx>
34 #include <swmodule.hxx>
36 #include <svx/svdoashp.hxx>
37 #include <svx/xfillit0.hxx>
38 #include <vcl/EnumContext.hxx>
39 #include <svx/svdoole2.hxx>
40 #include <sfx2/opengrf.hxx>
41 #include <svx/svdograf.hxx>
42 #include <svx/svdundo.hxx>
43 #include <svx/xbtmpit.hxx>
44 #include <svx/sdasitm.hxx>
45 #include <osl/diagnose.h>
47 #include <swundo.hxx>
48 #include <wrtsh.hxx>
49 #include <cmdid.h>
50 #include <strings.hrc>
51 #include <drwbassh.hxx>
52 #include <drawsh.hxx>
54 #define ShellClass_SwDrawShell
55 #include <sfx2/msg.hxx>
56 #include <swslots.hxx>
58 using namespace ::com::sun::star;
59 using namespace ::com::sun::star::uno;
61 SFX_IMPL_INTERFACE(SwDrawShell, SwDrawBaseShell)
63 void SwDrawShell::InitInterface_Impl()
65 GetStaticInterface()->RegisterPopupMenu("draw");
67 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, SfxVisibilityFlags::Invisible, ToolbarId::Draw_Toolbox_Sw);
69 GetStaticInterface()->RegisterChildWindow(SvxFontWorkChildWindow::GetChildWindowId());
73 // #i123922# check as the name implies
74 SdrObject* SwDrawShell::IsSingleFillableNonOLESelected()
76 SwWrtShell &rSh = GetShell();
77 SdrView* pSdrView = rSh.GetDrawView();
79 if(!pSdrView)
81 return nullptr;
84 if(1 != pSdrView->GetMarkedObjectCount())
86 return nullptr;
89 SdrObject* pPickObj = pSdrView->GetMarkedObjectByIndex(0);
91 if(!pPickObj)
93 return nullptr;
96 if(!pPickObj->IsClosedObj())
98 return nullptr;
101 if(dynamic_cast< SdrOle2Obj* >(pPickObj))
103 return nullptr;
106 return pPickObj;
109 // #i123922# insert given graphic data dependent of the object type in focus
110 void SwDrawShell::InsertPictureFromFile(SdrObject& rObject)
112 SwWrtShell &rSh = GetShell();
113 SdrView* pSdrView = rSh.GetDrawView();
115 if(!pSdrView)
116 return;
118 SvxOpenGraphicDialog aDlg(SwResId(STR_INSERT_GRAPHIC), GetView().GetFrameWeld());
120 if (ERRCODE_NONE != aDlg.Execute())
121 return;
123 Graphic aGraphic;
124 ErrCode nError = aDlg.GetGraphic(aGraphic);
126 if(ERRCODE_NONE != nError)
127 return;
129 const bool bAsLink(aDlg.IsAsLink());
130 SdrObject* pResult = &rObject;
132 rSh.StartUndo(SwUndoId::PASTE_CLIPBOARD);
134 if (SdrGrafObj* pSdrGrafObj = dynamic_cast<SdrGrafObj*>(&rObject))
136 rtl::Reference<SdrGrafObj> pNewGrafObj = SdrObject::Clone(*pSdrGrafObj, pSdrGrafObj->getSdrModelFromSdrObject());
138 pNewGrafObj->SetGraphic(aGraphic);
140 // #i123922# for handling MasterObject and virtual ones correctly, SW
141 // wants us to call ReplaceObject at the page, but that also
142 // triggers the same assertion (I tried it), so stay at the view method
143 pSdrView->ReplaceObjectAtView(&rObject, *pSdrView->GetSdrPageView(), pNewGrafObj.get());
145 // set in all cases - the Clone() will have copied an existing link (!)
146 pNewGrafObj->SetGraphicLink(
147 bAsLink ? aDlg.GetPath() : OUString());
149 pResult = pNewGrafObj.get();
151 else // if(rObject.IsClosedObj() && !dynamic_cast< SdrOle2Obj* >(&rObject))
153 pSdrView->AddUndo(std::make_unique<SdrUndoAttrObj>(rObject));
155 SfxItemSetFixed<XATTR_FILLSTYLE, XATTR_FILLBITMAP> aSet(pSdrView->GetModel().GetItemPool());
157 aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
158 aSet.Put(XFillBitmapItem(OUString(), std::move(aGraphic)));
159 rObject.SetMergedItemSetAndBroadcast(aSet);
162 rSh.EndUndo( SwUndoId::END );
164 if(pResult)
166 // we are done; mark the modified/new object
167 pSdrView->MarkObj(pResult, pSdrView->GetSdrPageView());
171 void SwDrawShell::Execute(SfxRequest &rReq)
173 SwWrtShell &rSh = GetShell();
174 SdrView *pSdrView = rSh.GetDrawView();
175 const SfxItemSet *pArgs = rReq.GetArgs();
176 SfxBindings &rBnd = GetView().GetViewFrame().GetBindings();
177 sal_uInt16 nSlotId = rReq.GetSlot();
178 bool bChanged = pSdrView->GetModel().IsChanged();
180 pSdrView->GetModel().SetChanged(false);
182 const SfxPoolItem* pItem;
183 if(pArgs)
184 pArgs->GetItemState(nSlotId, false, &pItem);
186 bool bMirror = true;
188 switch (nSlotId)
190 case SID_OBJECT_ROTATE:
191 if (rSh.IsObjSelected() && pSdrView->IsRotateAllowed())
193 if (GetView().IsDrawRotate())
194 rSh.SetDragMode(SdrDragMode::Move);
195 else
196 rSh.SetDragMode(SdrDragMode::Rotate);
198 GetView().FlipDrawRotate();
200 break;
201 case SID_MOVE_SHAPE_HANDLE:
203 if (pArgs && pArgs->Count() >= 3)
205 const SfxUInt32Item* handleNumItem = rReq.GetArg<SfxUInt32Item>(FN_PARAM_1);
206 const SfxUInt32Item* newPosXTwips = rReq.GetArg<SfxUInt32Item>(FN_PARAM_2);
207 const SfxUInt32Item* newPosYTwips = rReq.GetArg<SfxUInt32Item>(FN_PARAM_3);
208 const SfxInt32Item* OrdNum = rReq.GetArg<SfxInt32Item>(FN_PARAM_4);
210 const sal_uLong handleNum = handleNumItem->GetValue();
211 const sal_uLong newPosX = newPosXTwips->GetValue();
212 const sal_uLong newPosY = newPosYTwips->GetValue();
213 const Point mPoint(newPosX, newPosY);
214 const SdrHdl* handle = pSdrView->GetHdlList().GetHdl(handleNum);
215 if (!handle)
217 break;
220 if (handle->GetKind() == SdrHdlKind::Anchor || handle->GetKind() == SdrHdlKind::Anchor_TR)
222 rSh.FindAnchorPos(mPoint, /*bMoveIt=*/true);
223 pSdrView->ModelHasChanged();
225 else
226 pSdrView->MoveShapeHandle(handleNum, mPoint, OrdNum ? OrdNum->GetValue() : -1);
229 break;
230 case SID_BEZIER_EDIT:
231 if (GetView().IsDrawRotate())
233 rSh.SetDragMode(SdrDragMode::Move);
234 GetView().FlipDrawRotate();
236 GetView().FlipDrawSelMode();
237 pSdrView->SetFrameDragSingles(GetView().IsDrawSelMode());
238 GetView().AttrChangedNotify(nullptr); // Shell switch
239 break;
241 case SID_OBJECT_HELL:
242 if (rSh.IsObjSelected())
244 rSh.StartUndo( SwUndoId::START );
245 SetWrapMode(FN_FRAME_WRAPTHRU_TRANSP);
246 rSh.SelectionToHell();
247 rSh.EndUndo( SwUndoId::END );
248 rBnd.Invalidate(SID_OBJECT_HEAVEN);
250 break;
252 case SID_OBJECT_HEAVEN:
253 if (rSh.IsObjSelected())
255 rSh.StartUndo( SwUndoId::START );
256 SetWrapMode(FN_FRAME_WRAPTHRU);
257 rSh.SelectionToHeaven();
258 rSh.EndUndo( SwUndoId::END );
259 rBnd.Invalidate(SID_OBJECT_HELL);
261 break;
263 case FN_TOOL_HIERARCHIE:
264 if (rSh.IsObjSelected())
266 rSh.StartUndo( SwUndoId::START );
267 if (rSh.GetLayerId() == SdrLayerID(0))
269 SetWrapMode(FN_FRAME_WRAPTHRU);
270 rSh.SelectionToHeaven();
272 else
274 SetWrapMode(FN_FRAME_WRAPTHRU_TRANSP);
275 rSh.SelectionToHell();
277 rSh.EndUndo( SwUndoId::END );
278 rBnd.Invalidate( SID_OBJECT_HELL );
279 rBnd.Invalidate( SID_OBJECT_HEAVEN );
281 break;
283 case SID_FLIP_VERTICAL:
284 bMirror = false;
285 [[fallthrough]];
286 case SID_FLIP_HORIZONTAL:
287 rSh.MirrorSelection( bMirror );
288 break;
290 case SID_FONTWORK:
292 FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>( &rSh.GetView()) != nullptr );
293 SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) );
294 SfxViewFrame& rVFrame = GetView().GetViewFrame();
295 if (pArgs)
297 rVFrame.SetChildWindow(SvxFontWorkChildWindow::GetChildWindowId(),
298 static_cast<const SfxBoolItem&>((pArgs->Get(SID_FONTWORK))).GetValue());
300 else
301 rVFrame.ToggleChildWindow( SvxFontWorkChildWindow::GetChildWindowId() );
302 rVFrame.GetBindings().Invalidate(SID_FONTWORK);
304 break;
305 case FN_FORMAT_FOOTNOTE_DLG:
307 GetView().ExecFormatFootnote();
308 break;
310 case FN_NUMBERING_OUTLINE_DLG:
312 GetView().ExecNumberingOutline(GetPool());
313 rReq.Done();
315 break;
316 case SID_OPEN_XML_FILTERSETTINGS:
318 HandleOpenXmlFilterSettings(rReq);
320 break;
321 case FN_WORDCOUNT_DIALOG:
323 GetView().UpdateWordCount(this, nSlotId);
325 break;
326 case SID_EXTRUSION_TOGGLE:
327 case SID_EXTRUSION_TILT_DOWN:
328 case SID_EXTRUSION_TILT_UP:
329 case SID_EXTRUSION_TILT_LEFT:
330 case SID_EXTRUSION_TILT_RIGHT:
331 case SID_EXTRUSION_3D_COLOR:
332 case SID_EXTRUSION_DEPTH:
333 case SID_EXTRUSION_DIRECTION:
334 case SID_EXTRUSION_PROJECTION:
335 case SID_EXTRUSION_LIGHTING_DIRECTION:
336 case SID_EXTRUSION_LIGHTING_INTENSITY:
337 case SID_EXTRUSION_SURFACE:
338 case SID_EXTRUSION_DEPTH_FLOATER:
339 case SID_EXTRUSION_DIRECTION_FLOATER:
340 case SID_EXTRUSION_LIGHTING_FLOATER:
341 case SID_EXTRUSION_SURFACE_FLOATER:
342 case SID_EXTRUSION_DEPTH_DIALOG:
343 svx::ExtrusionBar::execute( pSdrView, rReq, rBnd );
344 rReq.Ignore ();
345 break;
347 case SID_FONTWORK_SHAPE:
348 case SID_FONTWORK_SHAPE_TYPE:
349 case SID_FONTWORK_ALIGNMENT:
350 case SID_FONTWORK_SAME_LETTER_HEIGHTS:
351 case SID_FONTWORK_CHARACTER_SPACING:
352 case SID_FONTWORK_KERN_CHARACTER_PAIRS:
353 case SID_FONTWORK_CHARACTER_SPACING_FLOATER:
354 case SID_FONTWORK_ALIGNMENT_FLOATER:
355 case SID_FONTWORK_CHARACTER_SPACING_DIALOG:
356 svx::FontworkBar::execute(*pSdrView, rReq, rBnd);
357 rReq.Ignore ();
358 break;
360 case SID_INSERT_GRAPHIC:
362 // #i123922# check if we can do something
363 SdrObject* pObj = IsSingleFillableNonOLESelected();
365 if(pObj)
367 // ...and if yes, do something
368 InsertPictureFromFile(*pObj);
371 break;
374 case FN_ADD_TEXT_BOX:
376 if (SdrObject* pObj = IsSingleFillableNonOLESelected())
378 SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
379 if (pFrameFormat)
380 SwTextBoxHelper::create(pFrameFormat, pObj, pObj->HasText());
382 break;
384 case FN_REMOVE_TEXT_BOX:
386 if (SdrObject* pObj = IsSingleFillableNonOLESelected())
388 SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
389 if (pFrameFormat)
390 SwTextBoxHelper::destroy(pFrameFormat, pObj);
392 break;
394 default:
395 OSL_ENSURE(false, "wrong dispatcher");
396 return;
398 if (pSdrView->GetModel().IsChanged())
399 rSh.SetModified();
400 else if (bChanged)
401 pSdrView->GetModel().SetChanged();
404 void SwDrawShell::GetState(SfxItemSet& rSet)
406 SwWrtShell &rSh = GetShell();
407 SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
408 SfxWhichIter aIter( rSet );
409 sal_uInt16 nWhich = aIter.FirstWhich();
410 bool bProtected = rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE;
412 if (!bProtected) // Check the parent
413 bProtected |= rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE;
415 while( nWhich )
417 switch( nWhich )
419 case SID_OBJECT_HELL:
420 if ( !rSh.IsObjSelected() || rSh.GetLayerId() == SdrLayerID(0) || bProtected )
421 rSet.DisableItem( nWhich );
422 break;
424 case SID_OBJECT_HEAVEN:
425 if ( !rSh.IsObjSelected() || rSh.GetLayerId() == SdrLayerID(1) || bProtected )
426 rSet.DisableItem( nWhich );
427 break;
429 case FN_TOOL_HIERARCHIE:
430 if ( !rSh.IsObjSelected() || bProtected )
431 rSet.DisableItem( nWhich );
432 break;
434 case SID_OBJECT_ROTATE:
436 const bool bIsRotate = GetView().IsDrawRotate();
437 if ( (!bIsRotate && !pSdrView->IsRotateAllowed()) || bProtected )
438 rSet.DisableItem( nWhich );
439 else
440 rSet.Put( SfxBoolItem( nWhich, bIsRotate ) );
442 break;
444 case SID_BEZIER_EDIT:
445 if (!Disable(rSet, nWhich))
446 rSet.Put( SfxBoolItem( nWhich, !GetView().IsDrawSelMode()));
447 break;
449 case SID_FLIP_VERTICAL:
450 if ( !pSdrView->IsMirrorAllowed() || bProtected )
452 rSet.DisableItem( nWhich );
454 else
456 // TTTT - needs to be adapted in aw080:
457 // state is not kept for drawing objects --> provide not flipped state
458 rSet.Put( SfxBoolItem( nWhich, false ) );
460 break;
462 case SID_FLIP_HORIZONTAL:
463 if ( !pSdrView->IsMirrorAllowed() || bProtected )
465 rSet.DisableItem( nWhich );
467 else
469 // TTTT - needs to be adapted in aw080:
470 // state is not kept for drawing objects --> provide not flipped state
471 rSet.Put( SfxBoolItem( nWhich, false ) );
473 break;
475 case SID_FONTWORK:
477 if (bProtected)
478 rSet.DisableItem( nWhich );
479 else
481 const sal_uInt16 nId = SvxFontWorkChildWindow::GetChildWindowId();
482 rSet.Put(SfxBoolItem( nWhich , GetView().GetViewFrame().HasChildWindow(nId)));
485 break;
487 case SID_INSERT_GRAPHIC:
489 // #i123922# check if we can do something
490 SdrObject* pObj = IsSingleFillableNonOLESelected();
492 if(!pObj)
494 rSet.DisableItem(nWhich);
497 break;
499 case FN_ADD_TEXT_BOX:
501 bool bDisable = true;
502 if (SdrObject* pObj = IsSingleFillableNonOLESelected())
504 SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
505 // Allow creating a TextBox only in case this is a draw format without a TextBox so far.
506 if (pFrameFormat && pFrameFormat->Which() == RES_DRAWFRMFMT && !SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT, pObj))
508 if (SdrObjCustomShape* pCustomShape = dynamic_cast<SdrObjCustomShape*>( pObj) )
510 const SdrCustomShapeGeometryItem& rGeometryItem = pCustomShape->GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY);
511 if (const uno::Any* pAny = rGeometryItem.GetPropertyValueByName("Type"))
512 // But still disallow fontwork shapes.
513 bDisable = pAny->get<OUString>().startsWith("fontwork-");
518 if (bDisable)
519 rSet.DisableItem(nWhich);
520 break;
522 case FN_REMOVE_TEXT_BOX:
524 bool bDisable = true;
525 if (SdrObject* pObj = IsSingleFillableNonOLESelected())
527 SwFrameFormat* pFrameFormat = ::FindFrameFormat(pObj);
528 // Allow removing a TextBox only in case it has one.
529 if (pFrameFormat && SwTextBoxHelper::isTextBox(pFrameFormat, RES_DRAWFRMFMT, pObj))
530 bDisable = false;
533 if (bDisable)
534 rSet.DisableItem(nWhich);
535 break;
538 nWhich = aIter.NextWhich();
540 svx::ExtrusionBar::getState( pSdrView, rSet );
541 svx::FontworkBar::getState( pSdrView, rSet );
544 SwDrawShell::SwDrawShell(SwView &_rView) :
545 SwDrawBaseShell(_rView)
547 SetName("Draw");
549 vcl::EnumContext::Context eContext = vcl::EnumContext::Context::Draw;
551 SwWrtShell &rSh = GetShell();
552 SdrView* pDrView = rSh.GetDrawView();
554 if (pDrView && svx::checkForSelectedFontWork(pDrView))
555 eContext = vcl::EnumContext::Context::DrawFontwork;
557 SfxShell::SetContextName(vcl::EnumContext::GetContextName(eContext));
560 // Edit SfxRequests for FontWork
562 void SwDrawShell::ExecFormText(SfxRequest const & rReq)
564 SwWrtShell &rSh = GetShell();
565 SdrView* pDrView = rSh.GetDrawView();
566 bool bChanged = pDrView->GetModel().IsChanged();
567 pDrView->GetModel().SetChanged(false);
569 const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
571 if ( rMarkList.GetMarkCount() == 1 && rReq.GetArgs() )
573 const SfxItemSet& rSet = *rReq.GetArgs();
575 if ( pDrView->IsTextEdit() )
577 pDrView->SdrEndTextEdit( true );
578 GetView().AttrChangedNotify(nullptr);
581 pDrView->SetAttributes(rSet);
583 if (pDrView->GetModel().IsChanged())
584 rSh.SetModified();
585 else
586 if (bChanged)
587 pDrView->GetModel().SetChanged();
590 //Return status values for FontWork
592 void SwDrawShell::GetFormTextState(SfxItemSet& rSet)
594 SwWrtShell &rSh = GetShell();
595 SdrView* pDrView = rSh.GetDrawView();
596 const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
597 const SdrObject* pObj = nullptr;
599 if ( rMarkList.GetMarkCount() == 1 )
600 pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
602 const SdrTextObj* pTextObj = DynCastSdrTextObj(pObj);
603 const bool bDeactivate(
604 !pObj ||
605 !pTextObj ||
606 !pTextObj->HasText() ||
607 dynamic_cast< const SdrObjCustomShape* >(pObj)); // #121538# no FontWork for CustomShapes
609 if(bDeactivate)
611 rSet.DisableItem(XATTR_FORMTXTSTYLE);
612 rSet.DisableItem(XATTR_FORMTXTADJUST);
613 rSet.DisableItem(XATTR_FORMTXTDISTANCE);
614 rSet.DisableItem(XATTR_FORMTXTSTART);
615 rSet.DisableItem(XATTR_FORMTXTMIRROR);
616 rSet.DisableItem(XATTR_FORMTXTHIDEFORM);
617 rSet.DisableItem(XATTR_FORMTXTOUTLINE);
618 rSet.DisableItem(XATTR_FORMTXTSHADOW);
619 rSet.DisableItem(XATTR_FORMTXTSHDWCOLOR);
620 rSet.DisableItem(XATTR_FORMTXTSHDWXVAL);
621 rSet.DisableItem(XATTR_FORMTXTSHDWYVAL);
623 else
625 pDrView->GetAttributes( rSet );
629 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */