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