1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <hintids.hxx>
21 #include <swtypes.hxx>
22 #include <sfx2/objface.hxx>
23 #include <sfx2/request.hxx>
24 #include <sfx2/bindings.hxx>
25 #include <sfx2/viewfrm.hxx>
26 #include <svl/aeitem.hxx>
27 #include <svx/svdview.hxx>
28 #include <svl/srchitem.hxx>
29 #include <svl/whiter.hxx>
30 #include <svx/swframevalidation.hxx>
31 #include <svx/anchorid.hxx>
32 #include <sfx2/htmlmode.hxx>
33 #include <drawdoc.hxx>
34 #include <uitool.hxx>
35 #include <fmtornt.hxx>
36 #include <cmdid.h>
37 #include <swmodule.hxx>
38 #include <wrtsh.hxx>
39 #include <wview.hxx>
40 #include <edtwin.hxx>
41 #include <viewopt.hxx>
42 #include <dcontact.hxx>
43 #include <frmfmt.hxx>
44 #include <wrap.hxx>
45 #include <drawbase.hxx>
46 #include <drwbassh.hxx>
47 #include <swdtflvr.hxx>
48 #include <svx/svdogrp.hxx>
49 #include <svx/svdpage.hxx>
50 #include <svx/svditer.hxx>
51 #define ShellClass_SwDrawBaseShell
52 #include <sfx2/msg.hxx>
53 #include <svx/svxids.hrc>
54 #include <swslots.hxx>
55 #include <svx/svxdlg.hxx>
56 #include <svx/dialogs.hrc>
57 #include <swabstdlg.hxx>
58 #include <swundo.hxx>
59 #include <com/sun/star/text/HoriOrientation.hpp>
60 #include <com/sun/star/text/VertOrientation.hpp>
61 #include <com/sun/star/text/RelOrientation.hpp>
62 #include <IDocumentDrawModelAccess.hxx>
63 #include <memory>
64 #include <fmtfollowtextflow.hxx>
65
66 using namespace ::com::sun::star;
67
SFX_IMPL_SUPERCLASS_INTERFACE(SwDrawBaseShell,SwBaseShell)68 SFX_IMPL_SUPERCLASS_INTERFACE(SwDrawBaseShell, SwBaseShell)
69
70 void SwDrawBaseShell::InitInterface_Impl()
71 {
72 }
73
74
SwDrawBaseShell(SwView & _rView)75 SwDrawBaseShell::SwDrawBaseShell(SwView &_rView)
76 : SwBaseShell(_rView)
77 {
78 GetShell().NoEdit();
79
80 SwEditWin& rWin = GetView().GetEditWin();
81
82 rWin.SetBezierMode(SID_BEZIER_MOVE);
83
84 if ( !_rView.GetDrawFuncPtr() )
85 _rView.GetEditWin().StdDrawMode( OBJ_NONE, true );
86
87 SwTransferable::CreateSelection( GetShell() );
88 }
89
~SwDrawBaseShell()90 SwDrawBaseShell::~SwDrawBaseShell()
91 {
92 GetView().ExitDraw();
93 GetShell().Edit();
94 SwTransferable::ClearSelection( GetShell() );
95 }
96
Execute(SfxRequest const & rReq)97 void SwDrawBaseShell::Execute(SfxRequest const &rReq)
98 {
99 SwWrtShell *pSh = &GetShell();
100 SdrView* pSdrView = pSh->GetDrawView();
101 const SfxItemSet *pArgs = rReq.GetArgs();
102 sal_uInt16 nSlotId = rReq.GetSlot();
103 bool bChanged = pSdrView->GetModel()->IsChanged();
104 pSdrView->GetModel()->SetChanged(false);
105 const SfxPoolItem* pItem = nullptr;
106 if(pArgs)
107 pArgs->GetItemState(nSlotId, false, &pItem);
108
109 bool bAlignPossible = pSh->IsAlignPossible();
110
111 bool bTopParam = true, bBottomParam = true;
112 bool bDone = false;
113 SfxBindings& rBind = GetView().GetViewFrame()->GetBindings();
114
115 switch (nSlotId)
116 {
117 case FN_DRAW_WRAP_DLG:
118 {
119 if(pSdrView->AreObjectsMarked())
120 {
121 if(!pArgs)
122 {
123 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
124 if( rMarkList.GetMark(0) != nullptr )
125 {
126 SfxItemSet aSet(
127 GetPool(),
128 svl::Items<
129 RES_LR_SPACE, RES_UL_SPACE,
130 RES_SURROUND, RES_SURROUND,
131 RES_ANCHOR, RES_ANCHOR,
132 RES_WRAP_INFLUENCE_ON_OBJPOS, RES_WRAP_INFLUENCE_ON_OBJPOS,
133 SID_HTML_MODE, SID_HTML_MODE,
134 FN_DRAW_WRAP_DLG, FN_DRAW_WRAP_DLG>{});
135
136 aSet.Put(SfxBoolItem(SID_HTML_MODE,
137 0 != ::GetHtmlMode(pSh->GetView().GetDocShell())));
138
139 aSet.Put(SfxInt16Item(FN_DRAW_WRAP_DLG, sal_uInt8(pSh->GetLayerId())));
140
141 pSh->GetObjAttr(aSet);
142 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
143 ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwWrapDlg(GetView().GetFrameWeld(), aSet, pSh));
144
145 if (pDlg->Execute() == RET_OK)
146 {
147 const SfxPoolItem* pWrapItem;
148 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
149 if(SfxItemState::SET == pOutSet->GetItemState(FN_DRAW_WRAP_DLG, false, &pWrapItem))
150 {
151 short nLayer = static_cast<const SfxInt16Item*>(pWrapItem)->GetValue();
152 if (nLayer == 1)
153 pSh->SelectionToHeaven();
154 else
155 pSh->SelectionToHell();
156 }
157
158 pSh->SetObjAttr(*pOutSet);
159 }
160 }
161 }
162 }
163 }
164 break;
165
166 case SID_ATTR_TRANSFORM:
167 {
168 if(pSdrView->AreObjectsMarked())
169 {
170 if(!pArgs)
171 {
172 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
173 if( rMarkList.GetMark(0) != nullptr )
174 {
175 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
176 VclPtr<SfxAbstractTabDialog> pDlg;
177 bool bCaption = false;
178
179 // Allowed anchorages:
180 RndStdIds nAnchor = pSh->GetAnchorId();
181 SvxAnchorIds nAllowedAnchors = SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page;
182 sal_uInt16 nHtmlMode = ::GetHtmlMode(pSh->GetView().GetDocShell());
183
184 if ( pSh->IsFlyInFly() )
185 nAllowedAnchors |= SvxAnchorIds::Fly;
186
187 if (pObj->GetObjIdentifier() == OBJ_CAPTION )
188 bCaption = true;
189
190 if (bCaption)
191 {
192 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
193 VclPtr<AbstractSvxCaptionDialog> pCaptionDlg =
194 pFact->CreateCaptionDialog( rReq.GetFrameWeld(), pSdrView, nAllowedAnchors );
195 pDlg.reset(pCaptionDlg);
196 pCaptionDlg->SetValidateFramePosLink( LINK(this, SwDrawBaseShell, ValidatePosition) );
197 }
198 else
199 {
200 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
201 VclPtr<AbstractSvxTransformTabDialog> pTransform =
202 pFact->CreateSvxTransformTabDialog(rReq.GetFrameWeld(), nullptr, pSdrView, nAllowedAnchors);
203 pDlg.reset(pTransform);
204 pTransform->SetValidateFramePosLink( LINK(this, SwDrawBaseShell, ValidatePosition) );
205 }
206 SfxItemSet aNewAttr(pSdrView->GetGeoAttrFromMarked());
207
208 const sal_uInt16* pRange = pDlg->GetInputRanges( *aNewAttr.GetPool() );
209 SfxItemSet aSet( *aNewAttr.GetPool(), pRange );
210 FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>(&GetView()) != nullptr );
211 SW_MOD()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast< sal_uInt16 >(eMetric)) );
212
213 aSet.Put( aNewAttr, false );
214
215 if (bCaption)
216 pSdrView->GetAttributes( aSet );
217
218 aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
219 bool bRTL;
220 bool bVertL2R;
221 aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT, pSh->IsFrameVertical(true, bRTL, bVertL2R)));
222 aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_IN_RTL_TEXT, bRTL));
223
224 SwFrameFormat* pFrameFormat = FindFrameFormat( pObj );
225
226 aSet.Put( pFrameFormat->GetFormatAttr(RES_FOLLOW_TEXT_FLOW) );
227
228 SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
229 aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, aVOrient.GetVertOrient()));
230 aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, aVOrient.GetRelationOrient() ));
231 aSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, aVOrient.GetPos()));
232
233 SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
234 aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, aHOrient.GetHoriOrient()));
235 aSet.Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, aHOrient.GetRelationOrient() ));
236 aSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, aHOrient.IsPosToggle()));
237 aSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, aHOrient.GetPos()));
238
239 aSet.Put(SfxUInt16Item(SID_HTML_MODE, nHtmlMode));
240
241 pDlg->SetInputSet( &aSet );
242
243 pDlg->StartExecuteAsync([bCaption, bChanged, pDlg, pFrameFormat, pSdrView,
244 pSh, &rMarkList, this](
245 sal_Int32 nResult){
246 if (nResult == RET_OK)
247 {
248 SwFormatVertOrient aVOrientFinal(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
249 SwFormatHoriOrient aHOrientFinal(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
250
251 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
252 pSh->StartAllAction();
253
254 // #i30451#
255 pSh->StartUndo(SwUndoId::INSFMTATTR);
256
257 pSdrView->SetGeoAttrToMarked(*pOutSet);
258
259 if (bCaption)
260 pSdrView->SetAttributes(*pOutSet);
261
262 bool bPosCorr =
263 SfxItemState::SET != pOutSet->GetItemState(
264 SID_ATTR_TRANSFORM_POS_X, false ) &&
265 SfxItemState::SET != pOutSet->GetItemState(
266 SID_ATTR_TRANSFORM_POS_Y, false );
267
268 SfxItemSet aFrameAttrSet(GetPool(), svl::Items<RES_FRMATR_BEGIN, RES_FRMATR_END - 1>{});
269
270 bool bSingleSelection = rMarkList.GetMarkCount() == 1;
271
272 const SfxPoolItem* pAnchorItem;
273 if(SfxItemState::SET == pOutSet->GetItemState(
274 SID_ATTR_TRANSFORM_ANCHOR, false, &pAnchorItem))
275 {
276 if(!bSingleSelection)
277 pSh->ChgAnchor(static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pAnchorItem)
278 ->GetValue()), false, bPosCorr );
279 else
280 {
281 SwFormatAnchor aAnchor(pFrameFormat->GetAnchor());
282 aAnchor.SetType(static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pAnchorItem)->GetValue()));
283 aFrameAttrSet.Put( aAnchor );
284 }
285 }
286 const SfxPoolItem* pHoriOrient = nullptr;
287 const SfxPoolItem* pHoriRelation = nullptr;
288 const SfxPoolItem* pHoriPosition = nullptr;
289 const SfxPoolItem* pHoriMirror = nullptr;
290 pOutSet->GetItemState(SID_ATTR_TRANSFORM_HORI_ORIENT, false, &pHoriOrient);
291 pOutSet->GetItemState(SID_ATTR_TRANSFORM_HORI_RELATION, false, &pHoriRelation);
292 pOutSet->GetItemState(SID_ATTR_TRANSFORM_HORI_POSITION, false, &pHoriPosition);
293 pOutSet->GetItemState(SID_ATTR_TRANSFORM_HORI_MIRROR, false, &pHoriMirror);
294 if(pHoriOrient || pHoriRelation || pHoriPosition || pHoriMirror)
295 {
296 if(pHoriOrient)
297 aHOrientFinal.SetHoriOrient(
298 static_cast<const SfxInt16Item*>(pHoriOrient)->GetValue());
299 if(pHoriRelation)
300 aHOrientFinal.SetRelationOrient(
301 static_cast<const SfxInt16Item*>(pHoriRelation)->GetValue());
302 if(pHoriPosition)
303 aHOrientFinal.SetPos( static_cast<const SfxInt32Item*>(pHoriPosition)->GetValue());
304 if(pHoriMirror)
305 aHOrientFinal.SetPosToggle( static_cast<const SfxBoolItem*>(pHoriMirror)->GetValue());
306 aFrameAttrSet.Put(aHOrientFinal);
307 }
308
309 const SfxPoolItem* pVertOrient = nullptr;
310 const SfxPoolItem* pVertRelation = nullptr;
311 const SfxPoolItem* pVertPosition = nullptr;
312 pOutSet->GetItemState(SID_ATTR_TRANSFORM_VERT_ORIENT, false, &pVertOrient);
313 pOutSet->GetItemState(SID_ATTR_TRANSFORM_VERT_RELATION, false, &pVertRelation);
314 pOutSet->GetItemState(SID_ATTR_TRANSFORM_VERT_POSITION, false, &pVertPosition);
315 if(pVertOrient || pVertRelation || pVertPosition )
316 {
317 if(pVertOrient)
318 aVOrientFinal.SetVertOrient(
319 static_cast<const SfxInt16Item*>(pVertOrient)->GetValue());
320 if(pVertRelation)
321 aVOrientFinal.SetRelationOrient(
322 static_cast<const SfxInt16Item*>(pVertRelation)->GetValue());
323 if(pVertPosition)
324 aVOrientFinal.SetPos( static_cast<const SfxInt32Item*>(pVertPosition)->GetValue());
325 aFrameAttrSet.Put( aVOrientFinal );
326 }
327 const SfxPoolItem* pFollowItem = nullptr;
328 pOutSet->GetItemState(RES_FOLLOW_TEXT_FLOW, false, &pFollowItem);
329 if(pFollowItem)
330 aFrameAttrSet.Put(*pFollowItem);
331
332 if(aFrameAttrSet.Count())
333 pSh->SetDrawingAttr(aFrameAttrSet);
334
335 GetView().GetViewFrame()->GetBindings().InvalidateAll(false);
336
337 // #i30451#
338 pSh->EndUndo( SwUndoId::INSFMTATTR );
339
340 pSh->EndAllAction();
341 }
342
343 if (pSdrView->GetModel()->IsChanged())
344 pSh->SetModified();
345 else if (bChanged)
346 pSdrView->GetModel()->SetChanged();
347
348 pDlg->disposeOnce();
349 });
350 }
351 }
352 else
353 {
354 pSh->StartAllAction();
355 pSdrView->SetGeoAttrToMarked( *pArgs );
356 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
357 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
358 if (pObj)
359 {
360 SwFrameFormat* pFrameFormat = FindFrameFormat(pObj);
361 if (pFrameFormat)
362 {
363 const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
364 // Don't change shape position / size, just update the anchor doc model
365 // position.
366 pSh->ChgAnchor(rAnchor.GetAnchorId(), /*bSameOnly=*/true);
367 }
368 }
369 pSh->EndAllAction();
370 }
371 }
372 }
373 break;
374
375 case SID_DELETE:
376 case FN_BACKSPACE:
377 if (pSh->IsObjSelected() && !pSdrView->IsTextEdit())
378 {
379 bDone = true;
380
381 if( GetView().IsDrawRotate() )
382 {
383 pSh->SetDragMode( SdrDragMode::Move );
384 GetView().FlipDrawRotate();
385 }
386
387 pSh->SetModified();
388 pSh->DelSelectedObj();
389
390 if (rReq.IsAPI() ||
391 GetView().GetEditWin().IsObjectSelect() )
392 {
393 // If basic call, then back to the text shell, because the
394 // Basic otherwise has no possibility to return.
395 if (GetView().GetDrawFuncPtr())
396 {
397 GetView().GetDrawFuncPtr()->Deactivate();
398 GetView().SetDrawFuncPtr(nullptr);
399 }
400 GetView().LeaveDrawCreate(); // Switch to selection mode
401 }
402
403 if (pSh->IsSelFrameMode())
404 {
405 pSh->LeaveSelFrameMode();
406 // #105852# FME
407 }
408 }
409 break;
410
411 case SID_GROUP:
412 if (pSh->IsObjSelected() > 1 && pSh->IsGroupAllowed())
413 {
414 pSh->GroupSelection();
415 rBind.Invalidate(SID_UNGROUP);
416 }
417 break;
418
419 case SID_UNGROUP:
420 if (pSh->IsGroupSelected() && pSh->IsUnGroupAllowed())
421 {
422 pSh->UnGroupSelection();
423 rBind.Invalidate(SID_GROUP);
424 }
425 break;
426
427 case SID_ENTER_GROUP:
428 if (pSh->IsGroupSelected())
429 {
430 pSdrView->EnterMarkedGroup();
431 rBind.InvalidateAll(false);
432 }
433 break;
434
435 case SID_LEAVE_GROUP:
436 if (pSdrView->IsGroupEntered())
437 {
438 pSdrView->LeaveOneGroup();
439 rBind.Invalidate(SID_ENTER_GROUP);
440 rBind.Invalidate(SID_UNGROUP);
441 }
442 break;
443
444 case SID_OBJECT_ALIGN_LEFT:
445 case SID_OBJECT_ALIGN_CENTER:
446 case SID_OBJECT_ALIGN_RIGHT:
447 case SID_OBJECT_ALIGN_UP:
448 case SID_OBJECT_ALIGN_MIDDLE:
449 case SID_OBJECT_ALIGN_DOWN:
450 {
451 if ( bAlignPossible )
452 {
453 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
454 if ( rMarkList.GetMarkCount() == 1 )
455 {
456 sal_Int16 nHorizOrient = -1, nVertOrient = -1;
457
458 switch (nSlotId)
459 {
460 case SID_OBJECT_ALIGN_LEFT:
461 nHorizOrient = text::HoriOrientation::LEFT;
462 break;
463 case SID_OBJECT_ALIGN_CENTER:
464 nHorizOrient = text::HoriOrientation::CENTER;
465 break;
466 case SID_OBJECT_ALIGN_RIGHT:
467 nHorizOrient = text::HoriOrientation::RIGHT;
468 break;
469 case SID_OBJECT_ALIGN_UP:
470 nVertOrient = text::VertOrientation::TOP;
471 break;
472 case SID_OBJECT_ALIGN_MIDDLE:
473 nVertOrient = text::VertOrientation::CENTER;
474 break;
475 case SID_OBJECT_ALIGN_DOWN:
476 nVertOrient = text::VertOrientation::BOTTOM;
477 break;
478 default:
479 break;
480 }
481
482 if (nHorizOrient != -1)
483 {
484 pSh->StartAction();
485 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
486 SwFrameFormat* pFrameFormat = FindFrameFormat( pObj );
487 SwFormatHoriOrient aHOrient(pFrameFormat->GetFormatAttr(RES_HORI_ORIENT));
488 aHOrient.SetHoriOrient( nHorizOrient );
489 pFrameFormat->SetFormatAttr(aHOrient);
490 pSh->EndAction();
491 }
492
493 if (nVertOrient != -1)
494 {
495 pSh->StartAction();
496 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
497 SwFrameFormat* pFrameFormat = FindFrameFormat( pObj );
498 SwFormatVertOrient aVOrient(pFrameFormat->GetFormatAttr(RES_VERT_ORIENT));
499 aVOrient.SetVertOrient( nVertOrient );
500 pFrameFormat->SetFormatAttr(aVOrient);
501 pSh->EndAction();
502 }
503
504 break;
505 }
506
507 pSh->StartAction();
508 switch (nSlotId)
509 {
510 case SID_OBJECT_ALIGN_LEFT:
511 pSdrView->AlignMarkedObjects(SdrHorAlign::Left, SdrVertAlign::NONE);
512 break;
513 case SID_OBJECT_ALIGN_CENTER:
514 pSdrView->AlignMarkedObjects(SdrHorAlign::Center, SdrVertAlign::NONE);
515 break;
516 case SID_OBJECT_ALIGN_RIGHT:
517 pSdrView->AlignMarkedObjects(SdrHorAlign::Right, SdrVertAlign::NONE);
518 break;
519 case SID_OBJECT_ALIGN_UP:
520 pSdrView->AlignMarkedObjects(SdrHorAlign::NONE, SdrVertAlign::Top);
521 break;
522 case SID_OBJECT_ALIGN_MIDDLE:
523 pSdrView->AlignMarkedObjects(SdrHorAlign::NONE, SdrVertAlign::Center);
524 break;
525 case SID_OBJECT_ALIGN_DOWN:
526 pSdrView->AlignMarkedObjects(SdrHorAlign::NONE, SdrVertAlign::Bottom);
527 break;
528 }
529 pSh->EndAction();
530 }
531 }
532 break;
533
534 case FN_FRAME_UP:
535 bTopParam = false;
536 [[fallthrough]];
537 case SID_FRAME_TO_TOP:
538 pSh->SelectionToTop( bTopParam );
539 break;
540
541 case FN_FRAME_DOWN:
542 bBottomParam = false;
543 [[fallthrough]];
544 case SID_FRAME_TO_BOTTOM:
545 pSh->SelectionToBottom( bBottomParam );
546 break;
547
548 case FN_NAME_SHAPE:
549 {
550 bDone = true;
551
552 if(1 == pSdrView->GetMarkedObjectCount())
553 {
554 // #i68101#
555 SdrObject* pSelected = pSdrView->GetMarkedObjectByIndex(0);
556 OSL_ENSURE(pSelected, "DrawViewShell::FuTemp03: nMarkCount, but no object (!)");
557 OUString aName(pSelected->GetName());
558
559 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
560 ScopedVclPtr<AbstractSvxObjectNameDialog> pDlg(pFact->CreateSvxObjectNameDialog(GetView().GetFrameWeld(), aName));
561
562 pDlg->SetCheckNameHdl(LINK(this, SwDrawBaseShell, CheckGroupShapeNameHdl));
563
564 if(RET_OK == pDlg->Execute())
565 {
566 pDlg->GetName(aName);
567 pSelected->SetName(aName);
568 pSh->SetModified();
569 }
570 }
571
572 break;
573 }
574
575 // #i68101#
576 case FN_TITLE_DESCRIPTION_SHAPE:
577 {
578 bDone = true;
579
580 if(1 == pSdrView->GetMarkedObjectCount())
581 {
582 SdrObject* pSelected = pSdrView->GetMarkedObjectByIndex(0);
583 OSL_ENSURE(pSelected, "DrawViewShell::FuTemp03: nMarkCount, but no object (!)");
584 OUString aTitle(pSelected->GetTitle());
585 OUString aDescription(pSelected->GetDescription());
586
587 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
588 ScopedVclPtr<AbstractSvxObjectTitleDescDialog> pDlg(pFact->CreateSvxObjectTitleDescDialog(GetView().GetFrameWeld(),
589 aTitle, aDescription));
590
591 if(RET_OK == pDlg->Execute())
592 {
593 pDlg->GetTitle(aTitle);
594 pDlg->GetDescription(aDescription);
595
596 pSelected->SetTitle(aTitle);
597 pSelected->SetDescription(aDescription);
598
599 pSh->SetModified();
600 }
601 }
602
603 break;
604 }
605
606 default:
607 OSL_ENSURE(false, "wrong Dispatcher");
608 return;
609 }
610 if(!bDone)
611 {
612 if(nSlotId >= SID_OBJECT_ALIGN_LEFT && nSlotId <= SID_OBJECT_ALIGN_DOWN)
613 rBind.Invalidate(SID_ATTR_LONG_LRSPACE);
614 if (pSdrView->GetModel()->IsChanged())
615 pSh->SetModified();
616 else if (bChanged)
617 pSdrView->GetModel()->SetChanged();
618 }
619 }
620
621 // Checks whether a given name is allowed for a group shape
622
IMPL_LINK(SwDrawBaseShell,CheckGroupShapeNameHdl,AbstractSvxObjectNameDialog &,rNameDialog,bool)623 IMPL_LINK( SwDrawBaseShell, CheckGroupShapeNameHdl, AbstractSvxObjectNameDialog&, rNameDialog, bool )
624 {
625 SwWrtShell &rSh = GetShell();
626 SdrView *pSdrView = rSh.GetDrawView();
627 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
628 OSL_ENSURE(rMarkList.GetMarkCount() == 1, "wrong draw selection");
629 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
630 const OUString sCurrentName = pObj->GetName();
631 OUString sNewName;
632 rNameDialog.GetName(sNewName);
633 bool bRet = false;
634 if (sNewName.isEmpty() || sCurrentName == sNewName)
635 bRet = true;
636 else
637 {
638 bRet = true;
639 SwDrawModel* pModel = rSh.getIDocumentDrawModelAccess().GetDrawModel();
640 SdrObjListIter aIter( pModel->GetPage(0), SdrIterMode::DeepWithGroups );
641 while( aIter.IsMore() )
642 {
643 SdrObject* pTempObj = aIter.Next();
644 if ( pObj != pTempObj && pTempObj->GetName() == sNewName )
645 {
646 bRet = false;
647 break;
648 }
649 }
650 }
651 return bRet;
652 }
653
GetState(SfxItemSet & rSet)654 void SwDrawBaseShell::GetState(SfxItemSet& rSet)
655 {
656 SwWrtShell &rSh = GetShell();
657 SdrView* pSdrView = rSh.GetDrawViewWithValidMarkList();
658 SfxWhichIter aIter( rSet );
659 sal_uInt16 nWhich = aIter.FirstWhich();
660 bool bProtected = rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE;
661
662 if (!bProtected) // Look in the parent
663 bProtected |= rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) != FlyProtectFlags::NONE;
664
665 while( nWhich )
666 {
667 switch( nWhich )
668 {
669 case FN_DRAW_WRAP_DLG:
670 case SID_ATTR_TRANSFORM:
671 case SID_FRAME_TO_TOP:
672 case SID_FRAME_TO_BOTTOM:
673 case FN_FRAME_UP:
674 case FN_FRAME_DOWN:
675 case SID_DELETE:
676 case FN_BACKSPACE:
677 if( bProtected || !rSh.IsObjSelected() )
678 rSet.DisableItem( nWhich );
679 break;
680 case SID_GROUP:
681 if ( rSh.IsObjSelected() < 2 || bProtected || !rSh.IsGroupAllowed() )
682 rSet.DisableItem( nWhich );
683 break;
684 case SID_UNGROUP:
685 if ( !rSh.IsGroupSelected() || bProtected || !rSh.IsUnGroupAllowed() )
686 rSet.DisableItem( nWhich );
687 break;
688 case SID_ENTER_GROUP:
689 if ( !rSh.IsGroupSelected() )
690 rSet.DisableItem( nWhich );
691 break;
692 case SID_LEAVE_GROUP:
693 if ( !pSdrView->IsGroupEntered() )
694 rSet.DisableItem( nWhich );
695 break;
696 case SID_OBJECT_ALIGN_LEFT:
697 case SID_OBJECT_ALIGN_CENTER:
698 case SID_OBJECT_ALIGN_RIGHT:
699 case SID_OBJECT_ALIGN_UP:
700 case SID_OBJECT_ALIGN_MIDDLE:
701 case SID_OBJECT_ALIGN_DOWN:
702 case SID_OBJECT_ALIGN:
703 if ( !rSh.IsAlignPossible() || bProtected )
704 rSet.DisableItem( nWhich );
705 else if ( rSh.GetAnchorId() == RndStdIds::FLY_AS_CHAR )
706 {
707 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
708 //if only one object is selected it can only be vertically
709 // aligned because it is character bound
710 if( rMarkList.GetMarkCount() == 1 )
711 {
712 rSet.DisableItem(SID_OBJECT_ALIGN_LEFT);
713 rSet.DisableItem(SID_OBJECT_ALIGN_CENTER);
714 rSet.DisableItem(SID_OBJECT_ALIGN_RIGHT);
715 }
716 }
717 break;
718
719 case FN_NAME_SHAPE :
720 {
721 if(1 != pSdrView->GetMarkedObjectCount())
722 {
723 rSet.DisableItem( nWhich );
724 }
725 }
726 break;
727
728 // #i68101#
729 case FN_TITLE_DESCRIPTION_SHAPE:
730 {
731 const bool bIsWebView(nullptr != dynamic_cast<SwWebView*>(&GetView()));
732
733 if(!bIsWebView && 1 != pSdrView->GetMarkedObjectCount())
734 {
735 rSet.DisableItem( nWhich );
736 }
737 }
738 break;
739 }
740 nWhich = aIter.NextWhich();
741 }
742 }
743
GetDrawAttrStateForIFBX(SfxItemSet & rSet)744 void SwDrawBaseShell::GetDrawAttrStateForIFBX( SfxItemSet& rSet )
745 {
746 SwWrtShell *pSh = &GetShell();
747 SdrView* pSdrView = pSh->GetDrawView();
748 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
749 if( rMarkList.GetMark(0) != nullptr )
750 {
751 SfxItemSet aNewAttr(pSdrView->GetGeoAttrFromMarked());
752 rSet.Put(aNewAttr,false);
753 }
754 }
755
Disable(SfxItemSet & rSet,sal_uInt16 nWhich)756 bool SwDrawBaseShell::Disable(SfxItemSet& rSet, sal_uInt16 nWhich)
757 {
758 bool bDisable = GetShell().IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE;
759
760 if (bDisable)
761 {
762 if (nWhich)
763 rSet.DisableItem( nWhich );
764 else
765 {
766 SfxWhichIter aIter( rSet );
767 nWhich = aIter.FirstWhich();
768 while (nWhich)
769 {
770 rSet.DisableItem( nWhich );
771 nWhich = aIter.NextWhich();
772 }
773 }
774 }
775
776 return bDisable;
777 }
778
DisableState(SfxItemSet & rSet)779 void SwDrawBaseShell::DisableState( SfxItemSet& rSet )
780 {
781 SwWrtShell *pSh = &GetShell();
782 SdrView* pSdrView = pSh->GetDrawView();
783 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
784 const size_t nMarkCount = rMarkList.GetMarkCount();
785 bool bShowArea = true, bShowMeasure = true;
786
787 for (size_t i = 0; i < nMarkCount && i < 50; ++i)
788 {
789 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
790 sal_uInt16 nObjType = pObj->GetObjIdentifier();
791
792 if ( nObjType != OBJ_MEASURE )
793 bShowMeasure = false;
794
795 // If marked object is 2D, disable format area command.
796 if ( nObjType == OBJ_PLIN ||
797 nObjType == OBJ_LINE ||
798 nObjType == OBJ_PATHLINE ||
799 nObjType == OBJ_FREELINE ||
800 nObjType == OBJ_EDGE ||
801 nObjType == OBJ_CARC ||
802 bShowMeasure )
803 bShowArea = false;
804
805 if (!bShowArea && !bShowMeasure)
806 break;
807 }
808
809 if (!bShowArea)
810 rSet.DisableItem(SID_ATTRIBUTES_AREA);
811
812 if (!bShowMeasure)
813 rSet.DisableItem(SID_MEASURE_DLG);
814
815 Disable(rSet);
816
817 }
818
819 // Validate of drawing positions
820
IMPL_LINK(SwDrawBaseShell,ValidatePosition,SvxSwFrameValidation &,rValidation,void)821 IMPL_LINK(SwDrawBaseShell, ValidatePosition, SvxSwFrameValidation&, rValidation, void )
822 {
823 SwWrtShell *pSh = &GetShell();
824 rValidation.nMinHeight = MINFLY;
825 rValidation.nMinWidth = MINFLY;
826
827 SwRect aBoundRect;
828
829 // OD 18.09.2003 #i18732# - adjustment for allowing vertical position
830 // aligned to page for fly frame anchored to paragraph or to character.
831 const RndStdIds eAnchorType = rValidation.nAnchorType;
832 const SwPosition* pContentPos = nullptr;
833 SdrView* pSdrView = pSh->GetDrawView();
834 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
835 if( rMarkList.GetMarkCount() == 1 )
836 {
837 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
838 SwFrameFormat* pFrameFormat = FindFrameFormat( pObj );
839 pContentPos = pFrameFormat->GetAnchor().GetContentAnchor();
840 }
841
842 pSh->CalcBoundRect( aBoundRect, eAnchorType,
843 rValidation.nHRelOrient,
844 rValidation.nVRelOrient,
845 pContentPos,
846 rValidation.bFollowTextFlow,
847 rValidation.bMirror, nullptr, &rValidation.aPercentSize);
848
849 bool bIsInVertical( false );
850 {
851 bool bRTL;
852 bool bVertL2R;
853 bIsInVertical = pSh->IsFrameVertical(true, bRTL, bVertL2R);
854 }
855 if(bIsInVertical)
856 {
857 Point aPos(aBoundRect.Pos());
858 long nTmp = aPos.X();
859 aPos.setX( aPos.Y() );
860 aPos.setY( nTmp );
861 Size aSize(aBoundRect.SSize());
862 nTmp = aSize.Width();
863 aSize.setWidth( aSize.Height() );
864 aSize.setHeight( nTmp );
865 aBoundRect.Chg( aPos, aSize );
866 //exchange width/height to enable correct values
867 nTmp = rValidation.nWidth;
868 rValidation.nWidth = rValidation.nHeight;
869 rValidation.nHeight = nTmp;
870 }
871 if ((eAnchorType == RndStdIds::FLY_AT_PAGE) || (eAnchorType == RndStdIds::FLY_AT_FLY))
872 {
873 // MinimalPosition
874 rValidation.nMinHPos = aBoundRect.Left();
875 rValidation.nMinVPos = aBoundRect.Top();
876 SwTwips nH = rValidation.nHPos;
877 SwTwips nV = rValidation.nVPos;
878
879 if (rValidation.nHPos + rValidation.nWidth > aBoundRect.Right())
880 {
881 if (rValidation.nHoriOrient == text::HoriOrientation::NONE)
882 {
883 rValidation.nHPos -= ((rValidation.nHPos + rValidation.nWidth) - aBoundRect.Right());
884 nH = rValidation.nHPos;
885 }
886 else
887 rValidation.nWidth = aBoundRect.Right() - rValidation.nHPos;
888 }
889
890 if (rValidation.nHPos + rValidation.nWidth > aBoundRect.Right())
891 rValidation.nWidth = aBoundRect.Right() - rValidation.nHPos;
892
893 if (rValidation.nVPos + rValidation.nHeight > aBoundRect.Bottom())
894 {
895 if (rValidation.nVertOrient == text::VertOrientation::NONE)
896 {
897 rValidation.nVPos -= ((rValidation.nVPos + rValidation.nHeight) - aBoundRect.Bottom());
898 nV = rValidation.nVPos;
899 }
900 else
901 rValidation.nHeight = aBoundRect.Bottom() - rValidation.nVPos;
902 }
903
904 if (rValidation.nVPos + rValidation.nHeight > aBoundRect.Bottom())
905 rValidation.nHeight = aBoundRect.Bottom() - rValidation.nVPos;
906
907 if ( rValidation.nVertOrient != text::VertOrientation::NONE )
908 nV = aBoundRect.Top();
909
910 if ( rValidation.nHoriOrient != text::HoriOrientation::NONE )
911 nH = aBoundRect.Left();
912
913 rValidation.nMaxHPos = aBoundRect.Right() - rValidation.nWidth;
914 rValidation.nMaxHeight = aBoundRect.Bottom() - nV;
915
916 rValidation.nMaxVPos = aBoundRect.Bottom() - rValidation.nHeight;
917 rValidation.nMaxWidth = aBoundRect.Right() - nH;
918 }
919 else if ((eAnchorType == RndStdIds::FLY_AT_PARA) || (eAnchorType == RndStdIds::FLY_AT_CHAR))
920 {
921 if (rValidation.nHPos + rValidation.nWidth > aBoundRect.Right())
922 {
923 if (rValidation.nHoriOrient == text::HoriOrientation::NONE)
924 {
925 rValidation.nHPos -= ((rValidation.nHPos + rValidation.nWidth) - aBoundRect.Right());
926 }
927 else
928 rValidation.nWidth = aBoundRect.Right() - rValidation.nHPos;
929 }
930
931 // OD 29.09.2003 #i17567#, #i18732# - consider following the text flow
932 // and alignment at page areas.
933 const bool bMaxVPosAtBottom = !rValidation.bFollowTextFlow ||
934 rValidation.nVRelOrient == text::RelOrientation::PAGE_FRAME ||
935 rValidation.nVRelOrient == text::RelOrientation::PAGE_PRINT_AREA;
936 {
937 SwTwips nTmpMaxVPos = ( bMaxVPosAtBottom
938 ? aBoundRect.Bottom()
939 : aBoundRect.Height() ) -
940 rValidation.nHeight;
941 if ( rValidation.nVPos > nTmpMaxVPos )
942 {
943 if (rValidation.nVertOrient == text::VertOrientation::NONE)
944 {
945 rValidation.nVPos = nTmpMaxVPos;
946 }
947 else
948 {
949 rValidation.nHeight = ( bMaxVPosAtBottom
950 ? aBoundRect.Bottom()
951 : aBoundRect.Height() ) - rValidation.nVPos;
952 }
953 }
954 }
955
956 rValidation.nMinHPos = aBoundRect.Left();
957 rValidation.nMaxHPos = aBoundRect.Right() - rValidation.nWidth;
958
959 rValidation.nMinVPos = aBoundRect.Top();
960 // OD 26.09.2003 #i17567#, #i18732# - determine maximum vertical position
961 if ( bMaxVPosAtBottom )
962 {
963 rValidation.nMaxVPos = aBoundRect.Bottom() - rValidation.nHeight;
964 }
965 else
966 {
967 rValidation.nMaxVPos = aBoundRect.Height() - rValidation.nHeight;
968 }
969
970 // Maximum width height
971 const SwTwips nH = ( rValidation.nHoriOrient != text::HoriOrientation::NONE )
972 ? aBoundRect.Left()
973 : rValidation.nHPos;
974 const SwTwips nV = ( rValidation.nVertOrient != text::VertOrientation::NONE )
975 ? aBoundRect.Top()
976 : rValidation.nVPos;
977 rValidation.nMaxHeight = rValidation.nMaxVPos + rValidation.nHeight - nV;
978 rValidation.nMaxWidth = rValidation.nMaxHPos + rValidation.nWidth - nH;
979 }
980 else if (eAnchorType == RndStdIds::FLY_AS_CHAR)
981 {
982 rValidation.nMinHPos = 0;
983 rValidation.nMaxHPos = 0;
984
985 rValidation.nMaxHeight = aBoundRect.Height();
986 rValidation.nMaxWidth = aBoundRect.Width();
987
988 rValidation.nMaxVPos = aBoundRect.Height();
989 rValidation.nMinVPos = -aBoundRect.Height() + rValidation.nHeight;
990 if (rValidation.nMaxVPos < rValidation.nMinVPos)
991 {
992 rValidation.nMinVPos = rValidation.nMaxVPos;
993 rValidation.nMaxVPos = -aBoundRect.Height();
994 }
995 }
996 if(bIsInVertical)
997 {
998 //restore width/height exchange
999 long nTmp = rValidation.nWidth;
1000 rValidation.nWidth = rValidation.nHeight;
1001 rValidation.nHeight = nTmp;
1002 }
1003
1004 if (rValidation.nMaxWidth < rValidation.nWidth)
1005 rValidation.nWidth = rValidation.nMaxWidth;
1006 if (rValidation.nMaxHeight < rValidation.nHeight)
1007 rValidation.nHeight = rValidation.nMaxHeight;
1008 }
1009
1010 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1011