LibreOffice Module sw (master)  1
drawdlg.cxx
Go to the documentation of this file.
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 <sfx2/request.hxx>
21 #include <sfx2/dispatch.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <svx/svdview.hxx>
24 
25 #include <view.hxx>
26 #include <wrtsh.hxx>
27 #include <cmdid.h>
28 
29 #include <drawsh.hxx>
30 #include <svx/svxdlg.hxx>
31 #include <svx/dialogs.hrc>
32 #include <memory>
33 #include <svl/stritem.hxx>
34 #include <svx/xlnclit.hxx>
35 #include <svx/xflclit.hxx>
36 #include <svx/chrtitem.hxx>
37 #include <svx/xlnwtit.hxx>
38 #include <svx/xflgrit.hxx>
39 #include <svx/xflftrit.hxx>
40 #include <svx/xfltrit.hxx>
41 #include <comphelper/lok.hxx>
42 #include <textboxhelper.hxx>
43 
44 using namespace com::sun::star::drawing;
45 
47 {
48  SwWrtShell* pSh = &GetShell();
49  SdrView* pView = pSh->GetDrawView();
50  SdrModel* pDoc = pView->GetModel();
51  bool bChanged = pDoc->IsChanged();
52  pDoc->SetChanged(false);
53 
54  SfxItemSet aNewAttr( pDoc->GetItemPool() );
55  pView->GetAttributes( aNewAttr );
56 
57  GetView().NoRotate();
58 
59  switch (rReq.GetSlot())
60  {
62  {
64  ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateTextTabDialog(rReq.GetFrameWeld(), &aNewAttr, pView));
65  sal_uInt16 nResult = pDlg->Execute();
66 
67  if (nResult == RET_OK)
68  {
69  if (pView->AreObjectsMarked())
70  {
71  pSh->StartAction();
72  pView->SetAttributes(*pDlg->GetOutputItemSet());
73  auto vMarkedObjs = pView->GetMarkedObjects();
74  for (auto pObj : vMarkedObjs)
75  {
76  // If the shape has textframe, set its params as well.
79  }
80  rReq.Done(*(pDlg->GetOutputItemSet()));
81  pSh->EndAction();
82  }
83  }
84  }
85  break;
86 
87  case SID_MEASURE_DLG:
88  {
89  bool bHasMarked = pView->AreObjectsMarked();
90 
93  aNewAttr, pView, RID_SVXPAGE_MEASURE));
94  if (pDlg->Execute() == RET_OK)
95  {
96  pSh->StartAction();
97  if (bHasMarked)
98  pView->SetAttrToMarked(*pDlg->GetOutputItemSet(), false);
99  else
100  pView->SetDefaultAttr(*pDlg->GetOutputItemSet(), false);
101  pSh->EndAction();
102  }
103  }
104  break;
105 
106  case SID_ATTRIBUTES_AREA:
107  {
108  bool bHasMarked = pView->AreObjectsMarked();
109 
112  &aNewAttr,
113  pDoc,
114  true));
115 
116  pDlg->StartExecuteAsync([bChanged, bHasMarked, pDoc, pDlg, pSh, pView, this](
117  sal_Int32 nResult){
118  pDoc->SetChanged(false);
119 
120  if (nResult == RET_OK)
121  {
122  pSh->StartAction();
123  if (bHasMarked)
124  pView->SetAttributes(*pDlg->GetOutputItemSet());
125  else
126  pView->SetDefaultAttr(*pDlg->GetOutputItemSet(), false);
127  pSh->EndAction();
128 
129  static sal_uInt16 aInval[] =
130  {
131  SID_ATTR_FILL_STYLE,
132  SID_ATTR_FILL_COLOR,
133  SID_ATTR_FILL_TRANSPARENCE,
134  SID_ATTR_FILL_FLOATTRANSPARENCE,
135  0
136  };
137  SfxBindings &rBnd = GetView().GetViewFrame()->GetBindings();
138  rBnd.Invalidate(aInval);
139  rBnd.Update(SID_ATTR_FILL_STYLE);
140  rBnd.Update(SID_ATTR_FILL_COLOR);
141  rBnd.Update(SID_ATTR_FILL_TRANSPARENCE);
142  rBnd.Update(SID_ATTR_FILL_FLOATTRANSPARENCE);
143  }
144 
145  if (pDoc->IsChanged())
146  GetShell().SetModified();
147  else if (bChanged)
148  pDoc->SetChanged();
149 
150  pDlg->disposeOnce();
151  });
152  }
153  break;
154 
155  case SID_ATTRIBUTES_LINE:
156  {
157  bool bHasMarked = pView->AreObjectsMarked();
158 
159  const SdrObject* pObj = nullptr;
160  const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
161  if( rMarkList.GetMarkCount() == 1 )
162  pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
163 
166  &aNewAttr,
167  pDoc,
168  pObj,
169  bHasMarked));
170 
171  pDlg->StartExecuteAsync([bChanged, bHasMarked, pDoc, pDlg, pSh, pView, this](
172  sal_Int32 nResult){
173  pDoc->SetChanged(false);
174 
175  if (nResult == RET_OK)
176  {
177  pSh->StartAction();
178  if(bHasMarked)
179  pView->SetAttrToMarked(*pDlg->GetOutputItemSet(), false);
180  else
181  pView->SetDefaultAttr(*pDlg->GetOutputItemSet(), false);
182  pSh->EndAction();
183 
184  static sal_uInt16 aInval[] =
185  {
186  SID_ATTR_LINE_STYLE, // ( SID_SVX_START + 169 )
187  SID_ATTR_LINE_DASH, // ( SID_SVX_START + 170 )
188  SID_ATTR_LINE_WIDTH, // ( SID_SVX_START + 171 )
189  SID_ATTR_LINE_COLOR, // ( SID_SVX_START + 172 )
190  SID_ATTR_LINE_START, // ( SID_SVX_START + 173 )
191  SID_ATTR_LINE_END, // ( SID_SVX_START + 174 )
192  SID_ATTR_LINE_TRANSPARENCE, // (SID_SVX_START+1107)
193  SID_ATTR_LINE_JOINT, // (SID_SVX_START+1110)
194  SID_ATTR_LINE_CAP, // (SID_SVX_START+1111)
195  0
196  };
197 
198  GetView().GetViewFrame()->GetBindings().Invalidate(aInval);
199  }
200 
201  if (pDoc->IsChanged())
202  GetShell().SetModified();
203  else if (bChanged)
204  pDoc->SetChanged();
205 
206  pDlg->disposeOnce();
207  });
208  }
209  break;
210 
211  default:
212  break;
213  }
214 
215  if (pDoc->IsChanged())
216  GetShell().SetModified();
217  else if (bChanged)
218  pDoc->SetChanged();
219 }
220 
221 namespace
222 {
223  void lcl_convertStringArguments(sal_uInt16 nSlot, const std::unique_ptr<SfxItemSet>& pArgs)
224  {
225  Color aColor;
226  const SfxPoolItem* pItem = nullptr;
227 
228  if (SfxItemState::SET == pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pItem))
229  {
230  OUString sColor = static_cast<const SfxStringItem*>(pItem)->GetValue();
231 
232  if (sColor == "transparent")
233  aColor = COL_TRANSPARENT;
234  else
235  aColor = Color(ColorTransparency, sColor.toInt32(16));
236 
237  switch (nSlot)
238  {
239  case SID_ATTR_LINE_COLOR:
240  {
241  XLineColorItem aLineColorItem(OUString(), aColor);
242  pArgs->Put(aLineColorItem);
243  break;
244  }
245 
246  case SID_ATTR_FILL_COLOR:
247  {
248  XFillColorItem aFillColorItem(OUString(), aColor);
249  pArgs->Put(aFillColorItem);
250  break;
251  }
252  }
253  }
254  else if (SfxItemState::SET == pArgs->GetItemState(SID_ATTR_LINE_WIDTH_ARG, false, &pItem))
255  {
256  double fValue = static_cast<const SvxDoubleItem*>(pItem)->GetValue();
257  // FIXME: different units...
258  int nPow = 100;
259  int nValue = fValue * nPow;
260 
261  XLineWidthItem aItem(nValue);
262  pArgs->Put(aItem);
263  }
264  if (SfxItemState::SET == pArgs->GetItemState(SID_FILL_GRADIENT_JSON, false, &pItem))
265  {
266  const SfxStringItem* pJSON = static_cast<const SfxStringItem*>(pItem);
267  if (pJSON)
268  {
269  XGradient aGradient = XGradient::fromJSON(pJSON->GetValue());
270  XFillGradientItem aItem(aGradient);
271  pArgs->Put(aItem);
272  }
273  }
274  }
275 }
276 
278 {
279  SwWrtShell* pSh = &GetShell();
280  SdrView* pView = pSh->GetDrawView();
281  const SfxItemSet* pArgs = rReq.GetArgs();
282  bool bChanged = pView->GetModel()->IsChanged();
283  pView->GetModel()->SetChanged(false);
284 
285  GetView().NoRotate();
286 
287  if (pArgs)
288  {
289  if(pView->AreObjectsMarked())
290  {
291  std::unique_ptr<SfxItemSet> pNewArgs = pArgs->Clone();
292  lcl_convertStringArguments(rReq.GetSlot(), pNewArgs);
293  pView->SetAttrToMarked(*pNewArgs, false);
294  }
295  else
296  pView->SetDefaultAttr(*rReq.GetArgs(), false);
297  }
298  else
299  {
300  SfxDispatcher* pDis = pSh->GetView().GetViewFrame()->GetDispatcher();
301  switch (rReq.GetSlot())
302  {
303  case SID_ATTR_FILL_STYLE:
304  case SID_ATTR_FILL_COLOR:
305  case SID_ATTR_FILL_GRADIENT:
306  case SID_ATTR_FILL_HATCH:
307  case SID_ATTR_FILL_BITMAP:
308  case SID_ATTR_FILL_TRANSPARENCE:
309  case SID_ATTR_FILL_FLOATTRANSPARENCE:
310  pDis->Execute(SID_ATTRIBUTES_AREA);
311  break;
312  case SID_ATTR_LINE_STYLE:
313  case SID_ATTR_LINE_DASH:
314  case SID_ATTR_LINE_WIDTH:
315  case SID_ATTR_LINE_COLOR:
316  case SID_ATTR_LINE_TRANSPARENCE:
317  case SID_ATTR_LINE_JOINT:
318  case SID_ATTR_LINE_CAP:
319  pDis->Execute(SID_ATTRIBUTES_LINE);
320  break;
321  }
322  }
323  if (pView->GetModel()->IsChanged())
324  GetShell().SetModified();
325  else
326  if (bChanged)
327  pView->GetModel()->SetChanged();
328 }
329 
331 {
332  // Transparent fill options are None, Solid, Linear, Axial, Radial, Elliptical, Quadratic, Square.
333  // But this is represented across two items namely XFillTransparenceItem (for None and Solid)
334  // and XFillFloatTransparenceItem (for the rest). To simplify the representation in LOKit case let's
335  // use XFillFloatTransparenceItem to carry the information of XFillTransparenceItem when gradients
336  // are disabled. When gradient transparency is disabled, all fields of XFillFloatTransparenceItem are invalid
337  // and not used. So convert XFillTransparenceItem's constant transparency percentage as an intensity
338  // and assign this to the XFillFloatTransparenceItem's start-intensity and end-intensity fields.
339  // Now the LOK clients need only listen to statechange messages of XFillFloatTransparenceItem
340  // to get fill-transparency settings instead of listening to two separate items.
341 
342  XFillFloatTransparenceItem* pFillFloatTranspItem =
343  const_cast<XFillFloatTransparenceItem*>
345  if (!pFillFloatTranspItem || pFillFloatTranspItem->IsEnabled())
346  return;
347 
348  const XFillTransparenceItem* pFillTranspItem =
350 
351  if (!pFillTranspItem)
352  return;
353 
354  XGradient aTmpGradient = pFillFloatTranspItem->GetGradientValue();
355  sal_uInt16 nTranspPercent = pFillTranspItem->GetValue();
356  // Encode transparency percentage as intensity
357  sal_uInt16 nIntensity = 100 - std::min<sal_uInt16>
358  (std::max<sal_uInt16>(nTranspPercent, 0), 100);
359  aTmpGradient.SetStartIntens(nIntensity);
360  aTmpGradient.SetEndIntens(nIntensity);
361  pFillFloatTranspItem->SetGradientValue(aTmpGradient);
362 }
363 
365 {
366  SdrView* pSdrView = GetShell().GetDrawView();
367 
368  if (pSdrView->AreObjectsMarked())
369  {
370  bool bDisable = Disable( rSet );
371 
372  if( !bDisable )
373  {
374  SfxItemSet aSet(rSet);
376  pSdrView->GetAttributes(aSet);
377  if (const SfxPoolItem* pItem = nullptr;
378  aSet.GetItemState(SDRATTR_TEXTCOLUMNS_NUMBER, false, &pItem)
379  >= SfxItemState::DEFAULT
380  && pItem)
381  {
382  aSet.Put(pItem->CloneSetWhich(SID_ATTR_TEXTCOLUMNS_NUMBER));
383  }
384  if (const SfxPoolItem* pItem = nullptr;
385  aSet.GetItemState(SDRATTR_TEXTCOLUMNS_SPACING, false, &pItem)
386  >= SfxItemState::DEFAULT
387  && pItem)
388  {
389  aSet.Put(pItem->CloneSetWhich(SID_ATTR_TEXTCOLUMNS_SPACING));
390  }
391  rSet.Put(aSet, false);
394  }
395  }
396  else
397  rSet.Put(pSdrView->GetDefaultAttr());
398 }
399 
400 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxViewFrame * GetViewFrame() const
size_t GetMarkCount() const
SdrView * GetDrawView()
Definition: vnew.cxx:373
virtual const SfxItemSet * GetOutputItemSet() const =0
std::string GetValue
static XGradient fromJSON(const OUString &rJSON)
static bool hasTextFrame(const SdrObject *pObj)
Returns true if the SdrObject has a SwTextFrame otherwise false.
SfxDispatcher * GetDispatcher()
bool AreObjectsMarked() const
static SvxAbstractDialogFactory * Create()
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
void GetDrawAttrState(SfxItemSet &rSet)
Definition: drawdlg.cxx:364
void Done(bool bRemove=false)
SdrMark * GetMark(size_t nNum) const
void ExecDrawAttrArgs(SfxRequest const &rReq)
Definition: drawdlg.cxx:277
constexpr TypedWhichId< SdrMetricItem > SDRATTR_TEXTCOLUMNS_SPACING(SDRATTR_TEXTCOLUMNS_FIRST+1)
const SfxItemSet * GetArgs() const
void Invalidate(sal_uInt16 nId)
Used by the UI to modify the document model.
Definition: wrtsh.hxx:93
void SetAttrToMarked(const SfxItemSet &rAttr, bool bReplaceAll)
void MergeRange(sal_uInt16 nFrom, sal_uInt16 nTo)
const SwView & GetView() const
Definition: wrtsh.hxx:431
virtual VclPtr< SfxAbstractDialog > CreateSfxDialog(weld::Window *pParent, const SfxItemSet &rAttr, const SdrView *pView, sal_uInt32 nResId)=0
const SfxItemSet & GetDefaultAttr() const
virtual void SetChanged(bool bFlg=true)
const OUStringLiteral sColor
void SetEndIntens(sal_uInt16 nNewIntens)
SdrObject * GetMarkedSdrObj() const
static void updateTextBoxMargin(SdrObject *pObj)
Copy shape attributes to the text frame.
constexpr TypedWhichId< XFillTransparenceItem > XATTR_FILLTRANSPARENCE(XATTR_FILL_FIRST+5)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Shell * GetShell()
const XGradient & GetGradientValue() const
void SetGradientValue(const XGradient &rNew)
const OUString & GetValue() const
const SdrMarkList & GetMarkedObjectList() const
bool SetAttributes(const SfxItemSet &rSet, bool bReplaceAll=false)
#define FN_DRAWTEXT_ATTR_DLG
Definition: cmdid.h:240
void SetDefaultAttr(const SfxItemSet &rAttr, bool bReplaceAll)
std::unique_ptr< SfxPoolItem > CloneSetWhich(sal_uInt16 nNewWhich) const
bool IsChanged() const
void StartAction()
Definition: crsrsh.cxx:227
virtual VclPtr< SfxAbstractTabDialog > CreateTextTabDialog(weld::Window *pParent, const SfxItemSet *pAttrSet, SdrView *pView)=0
void SetStartIntens(sal_uInt16 nNewIntens)
weld::Window * GetFrameWeld() const
void Update(sal_uInt16 nId)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_uInt16 GetSlot() const
void ExecDrawDlg(SfxRequest &rReq)
Definition: drawdlg.cxx:46
constexpr TypedWhichId< XFillFloatTransparenceItem > XATTR_FILLFLOATTRANSPARENCE(XATTR_FILL_FIRST+11)
virtual std::unique_ptr< SfxItemSet > Clone(bool bItems=true, SfxItemPool *pToPool=nullptr) const
virtual VclPtr< AbstractSvxAreaTabDialog > CreateSvxAreaTabDialog(weld::Window *pParent, const SfxItemSet *pAttr, SdrModel *pModel, bool bShadow)=0
void GetAttributes(SfxItemSet &rTargetSet, bool bOnlyHardAttr=false) const
RET_OK
constexpr TypedWhichId< SfxInt16Item > SDRATTR_TEXTCOLUMNS_NUMBER(SDRATTR_TEXTCOLUMNS_FIRST+0)
const SfxItemPool & GetItemPool() const
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
::std::vector< SdrObject * > GetMarkedObjects() const
static void lcl_unifyFillTransparencyItems(const SfxItemSet &rSet)
Definition: drawdlg.cxx:330
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
SdrModel * GetModel() const
virtual VclPtr< SfxAbstractTabDialog > CreateSvxLineTabDialog(weld::Window *pParent, const SfxItemSet *pAttr, SdrModel *pModel, const SdrObject *pObj, bool bHasObj)=0
sal_Int16 nValue
void EndAction(const bool bIdleEnd=false)
Definition: crsrsh.cxx:244