LibreOffice Module sc (master)  1
fuconrec.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 <fuconrec.hxx>
21 #include <tabvwsh.hxx>
22 #include <drawview.hxx>
23 
24 #include <editeng/outlobj.hxx>
25 // Create default drawing objects via keyboard
26 #include <svx/svdopath.hxx>
27 #include <svx/svdocapt.hxx>
28 #include <svx/svxids.hrc>
29 #include <svx/strings.hrc>
30 #include <svx/xlnwtit.hxx>
31 #include <svx/xlnstwit.hxx>
32 #include <svx/xlnedwit.hxx>
33 #include <svx/xlnedit.hxx>
34 #include <svx/xlnstit.hxx>
35 #include <svx/dialmgr.hxx>
36 #include <svx/svdomeas.hxx>
37 #include <osl/diagnose.h>
39 
42 
44  SdrModel* pDoc, const SfxRequest& rReq)
45  : FuConstruct(rViewSh, pWin, pViewP, pDoc, rReq)
46 {
47 }
48 
50 {
51 }
52 
57 namespace {
58 
59 ::basegfx::B2DPolyPolygon getPolygon(const char* pResId, const SdrModel& rModel)
60 {
62  XLineEndListRef pLineEndList(rModel.GetLineEndList());
63 
64  if( pLineEndList.is() )
65  {
66  OUString aArrowName( SvxResId(pResId) );
67  tools::Long nCount = pLineEndList->Count();
69  for( nIndex = 0; nIndex < nCount; nIndex++ )
70  {
71  const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nIndex);
72  if( pEntry->GetName() == aArrowName )
73  {
74  aRetval = pEntry->GetLineEnd();
75  break;
76  }
77  }
78  }
79 
80  return aRetval;
81 }
82 
83 }
84 
86 {
87  // remember button state for creation of own MouseEvents
89 
90  bool bReturn = FuConstruct::MouseButtonDown(rMEvt);
91 
92  if ( rMEvt.IsLeft() && !pView->IsAction() )
93  {
94  Point aPos( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
96 
98  {
99  Size aCaptionSize ( 2268, 1134 ); // 4x2cm
100 
101  bReturn = pView->BegCreateCaptionObj( aPos, aCaptionSize );
102 
103  // How do you set the font for writing
104  }
105  else
106  bReturn = pView->BegCreateObj(aPos);
107 
108  SdrObject* pObj = pView->GetCreateObj();
109 
110  if (pObj)
111  {
113  SetLineEnds(aAttr, *pObj, aSfxRequest.GetSlot());
114  pObj->SetMergedItemSet(aAttr);
115  }
116  }
117  return bReturn;
118 }
119 
121 {
122  // remember button state for creation of own MouseEvents
124 
125  bool bReturn = false;
126 
127  if ( pView->IsCreateObj() && rMEvt.IsLeft() )
128  {
129  pView->EndCreateObj(SdrCreateCmd::ForceEnd);
130 
131  if (aSfxRequest.GetSlot() == SID_DRAW_CAPTION_VERTICAL)
132  {
133  // set vertical flag for caption object
134 
135  const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
136  if (rMarkList.GetMark(0))
137  {
138  SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
139  // create OutlinerParaObject now so it can be set to vertical
140  if ( auto pSdrTextObj = dynamic_cast<SdrTextObj*>( pObj) )
141  pSdrTextObj->ForceOutlinerParaObject();
143  if( pOPO && !pOPO->IsVertical() )
144  pOPO->SetVertical( true );
145  }
146  }
147 
148  bReturn = true;
149  }
150  return (FuConstruct::MouseButtonUp(rMEvt) || bReturn);
151 }
152 
154 {
155  SdrObjKind aObjKind;
156 
157  switch (aSfxRequest.GetSlot() )
158  {
159  case SID_DRAW_LINE:
160  case SID_DRAW_XLINE:
161  case SID_LINE_ARROW_END:
162  case SID_LINE_ARROW_CIRCLE:
163  case SID_LINE_ARROW_SQUARE:
164  case SID_LINE_ARROW_START:
165  case SID_LINE_CIRCLE_ARROW:
166  case SID_LINE_SQUARE_ARROW:
167  case SID_LINE_ARROWS:
168  aNewPointer = PointerStyle::DrawLine;
169  aObjKind = OBJ_LINE;
170  break;
171 
172  case SID_DRAW_MEASURELINE:
173  aNewPointer = PointerStyle::DrawLine;
174  aObjKind = OBJ_MEASURE;
175  break;
176 
177  case SID_DRAW_RECT:
178  aNewPointer = PointerStyle::DrawRect;
179  aObjKind = OBJ_RECT;
180  break;
181 
182  case SID_DRAW_ELLIPSE:
183  aNewPointer = PointerStyle::DrawEllipse;
184  aObjKind = OBJ_CIRC;
185  break;
186 
187  case SID_DRAW_CAPTION:
188  case SID_DRAW_CAPTION_VERTICAL:
189  aNewPointer = PointerStyle::DrawCaption;
190  aObjKind = OBJ_CAPTION;
191  break;
192 
193  default:
194  aNewPointer = PointerStyle::Cross;
195  aObjKind = OBJ_RECT;
196  break;
197  }
198 
199  pView->SetCurrentObj(aObjKind);
200 
203 
205 }
206 
207 void FuConstRectangle::SetLineEnds(SfxItemSet& rAttr, const SdrObject& rObj, sal_uInt16 nSlotId)
208 {
209  SdrModel& rModel(rObj.getSdrModelFromSdrObject());
210 
211  if ( !(nSlotId == SID_LINE_ARROW_START ||
212  nSlotId == SID_LINE_ARROW_END ||
213  nSlotId == SID_LINE_ARROWS ||
214  nSlotId == SID_LINE_ARROW_CIRCLE ||
215  nSlotId == SID_LINE_CIRCLE_ARROW ||
216  nSlotId == SID_LINE_ARROW_SQUARE ||
217  nSlotId == SID_LINE_SQUARE_ARROW ||
218  nSlotId == SID_DRAW_MEASURELINE) )
219  return;
220 
221 
222  // set attributes of line start and ends
223 
224  // arrowhead
225  ::basegfx::B2DPolyPolygon aArrow( getPolygon( RID_SVXSTR_ARROW, rModel ) );
226  if( !aArrow.count() )
227  {
228  ::basegfx::B2DPolygon aNewArrow;
229  aNewArrow.append(::basegfx::B2DPoint(10.0, 0.0));
230  aNewArrow.append(::basegfx::B2DPoint(0.0, 30.0));
231  aNewArrow.append(::basegfx::B2DPoint(20.0, 30.0));
232  aNewArrow.setClosed(true);
233  aArrow.append(aNewArrow);
234  }
235 
236  // Circles
237  ::basegfx::B2DPolyPolygon aCircle( getPolygon( RID_SVXSTR_CIRCLE, rModel ) );
238  if( !aCircle.count() )
239  {
240  ::basegfx::B2DPolygon aNewCircle = ::basegfx::utils::createPolygonFromEllipse(::basegfx::B2DPoint(0.0, 0.0), 250.0, 250.0);
241  aNewCircle.setClosed(true);
242  aCircle.append(aNewCircle);
243  }
244 
245  // Square
246  ::basegfx::B2DPolyPolygon aSquare( getPolygon( RID_SVXSTR_SQUARE, rModel ) );
247  if( !aSquare.count() )
248  {
249  ::basegfx::B2DPolygon aNewSquare;
250  aNewSquare.append(::basegfx::B2DPoint(0.0, 0.0));
251  aNewSquare.append(::basegfx::B2DPoint(10.0, 0.0));
252  aNewSquare.append(::basegfx::B2DPoint(10.0, 10.0));
253  aNewSquare.append(::basegfx::B2DPoint(0.0, 10.0));
254  aNewSquare.setClosed(true);
255  aSquare.append(aNewSquare);
256  }
257 
258  SfxItemSet aSet( rModel.GetItemPool() );
259  tools::Long nWidth = 200; // (1/100th mm)
260 
261  // determine line width and calculate with it the line end width
262  if( aSet.GetItemState( XATTR_LINEWIDTH ) != SfxItemState::DONTCARE )
263  {
264  tools::Long nValue = aSet.Get( XATTR_LINEWIDTH ).GetValue();
265  if( nValue > 0 )
266  nWidth = nValue * 3;
267  }
268 
269  switch (nSlotId)
270  {
271  case SID_LINE_ARROWS:
272  case SID_DRAW_MEASURELINE:
273  {
274  // connector with arrow ends
275  rAttr.Put(XLineStartItem(SvxResId(RID_SVXSTR_ARROW), aArrow));
276  rAttr.Put(XLineStartWidthItem(nWidth));
277  rAttr.Put(XLineEndItem(SvxResId(RID_SVXSTR_ARROW), aArrow));
278  rAttr.Put(XLineEndWidthItem(nWidth));
279  }
280  break;
281 
282  case SID_LINE_ARROW_START:
283  case SID_LINE_ARROW_CIRCLE:
284  case SID_LINE_ARROW_SQUARE:
285  {
286  // connector with arrow start
287  rAttr.Put(XLineStartItem(SvxResId(RID_SVXSTR_ARROW), aArrow));
288  rAttr.Put(XLineStartWidthItem(nWidth));
289  }
290  break;
291 
292  case SID_LINE_ARROW_END:
293  case SID_LINE_CIRCLE_ARROW:
294  case SID_LINE_SQUARE_ARROW:
295  {
296  // connector with arrow end
297  rAttr.Put(XLineEndItem(SvxResId(RID_SVXSTR_ARROW), aArrow));
298  rAttr.Put(XLineEndWidthItem(nWidth));
299  }
300  break;
301  }
302 
303  // and again, for the still missing ends
304  switch (nSlotId)
305  {
306  case SID_LINE_ARROW_CIRCLE:
307  {
308  // circle end
309  rAttr.Put(XLineEndItem(SvxResId(RID_SVXSTR_CIRCLE), aCircle));
310  rAttr.Put(XLineEndWidthItem(nWidth));
311  }
312  break;
313 
314  case SID_LINE_CIRCLE_ARROW:
315  {
316  // circle start
317  rAttr.Put(XLineStartItem(SvxResId(RID_SVXSTR_CIRCLE), aCircle));
318  rAttr.Put(XLineStartWidthItem(nWidth));
319  }
320  break;
321 
322  case SID_LINE_ARROW_SQUARE:
323  {
324  // square end
325  rAttr.Put(XLineEndItem(SvxResId(RID_SVXSTR_SQUARE), aSquare));
326  rAttr.Put(XLineEndWidthItem(nWidth));
327  }
328  break;
329 
330  case SID_LINE_SQUARE_ARROW:
331  {
332  // square start
333  rAttr.Put(XLineStartItem(SvxResId(RID_SVXSTR_SQUARE), aSquare));
334  rAttr.Put(XLineStartWidthItem(nWidth));
335  }
336  break;
337  }
338 }
339 
341 {
344 }
345 
346 // Create default drawing objects via keyboard
348 {
350  *pDrDoc,
353 
354  if(pObj)
355  {
356  tools::Rectangle aRect(rRectangle);
357  Point aStart = aRect.TopLeft();
358  Point aEnd = aRect.BottomRight();
359 
360  switch(nID)
361  {
362  case SID_DRAW_LINE:
363  case SID_DRAW_XLINE:
364  case SID_LINE_ARROW_END:
365  case SID_LINE_ARROW_CIRCLE:
366  case SID_LINE_ARROW_SQUARE:
367  case SID_LINE_ARROW_START:
368  case SID_LINE_CIRCLE_ARROW:
369  case SID_LINE_SQUARE_ARROW:
370  case SID_LINE_ARROWS:
371  {
372  if(auto pPathObj = dynamic_cast<SdrPathObj*>( pObj.get() ))
373  {
374  sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2);
375  basegfx::B2DPolygon aPoly;
376  aPoly.append(basegfx::B2DPoint(aStart.X(), nYMiddle));
377  aPoly.append(basegfx::B2DPoint(aEnd.X(), nYMiddle));
378  pPathObj->SetPathPoly(basegfx::B2DPolyPolygon(aPoly));
379  }
380  else
381  {
382  OSL_FAIL("Object is NO line object");
383  }
384 
385  break;
386  }
387 
388  case SID_DRAW_MEASURELINE:
389  {
390  if(auto pMeasureObj = dynamic_cast<SdrMeasureObj*>( pObj.get() ))
391  {
392  sal_Int32 nYMiddle((aRect.Top() + aRect.Bottom()) / 2);
393  pMeasureObj->SetPoint(Point(aStart.X(), nYMiddle), 0);
394  pMeasureObj->SetPoint(Point(aEnd.X(), nYMiddle), 1);
395  }
396 
397  break;
398  }
399 
400  case SID_DRAW_CAPTION:
401  case SID_DRAW_CAPTION_VERTICAL:
402  {
403  if(auto pCaptionObj = dynamic_cast<SdrCaptionObj*>( pObj.get() ))
404  {
405  bool bIsVertical(SID_DRAW_CAPTION_VERTICAL == nID);
406 
407  pCaptionObj->SetVerticalWriting(bIsVertical);
408 
409  if(bIsVertical)
410  {
411  SfxItemSet aSet(pObj->GetMergedItemSet());
414  pObj->SetMergedItemSet(aSet);
415  }
416 
417  // don't set default text, start edit mode instead
418  // (Edit mode is started in ScTabViewShell::ExecDraw, because
419  // it must be handled by FuText)
420 
421  pCaptionObj->SetLogicRect(aRect);
422  pCaptionObj->SetTailPos(
423  aRect.TopLeft() - Point(aRect.GetWidth() / 2, aRect.GetHeight() / 2));
424  }
425  else
426  {
427  OSL_FAIL("Object is NO caption object");
428  }
429 
430  break;
431  }
432 
433  default:
434  {
435  pObj->SetLogicRect(aRect);
436 
437  break;
438  }
439  }
440 
441  SfxItemSet aAttr(pDrDoc->GetItemPool());
442  SetLineEnds(aAttr, *pObj, nID);
443  pObj->SetMergedItemSet(aAttr);
444  }
445 
446  return pObj;
447 }
448 
449 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
Definition: fuconrec.cxx:120
void CaptureMouse()
sal_Int32 nIndex
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
OBJ_RECT
bool EndCreateObj(SdrCreateCmd eCmd)
PointerStyle aOldPointer
Definition: fudraw.hxx:31
FuConstRectangle(ScTabViewShell &rViewSh, vcl::Window *pWin, ScDrawView *pView, SdrModel *pDoc, const SfxRequest &rReq)
Definition: fuconrec.cxx:43
bool BegCreateObj(const Point &rPnt, OutputDevice *pOut=nullptr, short nMinMov=-3)
virtual void Deactivate() override
Definition: fuconrec.cxx:340
OBJ_CIRC
bool IsVertical() const
long Long
OBJ_LINE
constexpr TypedWhichId< XLineWidthItem > XATTR_LINEWIDTH(XATTR_LINE_FIRST+2)
static SdrObject * MakeNewObject(SdrModel &rSdrModel, SdrInventor nInventor, SdrObjKind nObjIdentifier, const tools::Rectangle *pSnapRect=nullptr)
SdrModel * pDrDoc
Definition: fupoor.hxx:45
SdrMark * GetMark(size_t nNum) const
static void SetLineEnds(SfxItemSet &rAttr, const SdrObject &rObj, sal_uInt16 nSlotId)
Definition: fuconrec.cxx:207
Draw rectangle.
Definition: fuconstr.hxx:27
SdrObjKind
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
Definition: fuconstr.cxx:128
sal_uInt16 GetButtons() const
OUString SvxResId(const char *pId)
void SetMouseButtonCode(sal_uInt16 nNew)
Definition: fupoor.hxx:70
int nCount
tools::Long Bottom() const
constexpr tools::Long GetWidth() const
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
XLineEndListRef GetLineEndList() const
ScTabViewShell & rViewShell
Definition: fupoor.hxx:43
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
Definition: fuconstr.cxx:46
const OUString & GetName() const
SdrObject * GetMarkedSdrObj() const
Point BottomRight() const
PointerStyle GetPointer() const
SdrObject * GetCreateObj() const
void SetVertical(bool bNew)
void SetActivePointer(PointerStyle nPointer)
Definition: tabview.cxx:894
OBJ_CAPTION
const SdrMarkList & GetMarkedObjectList() const
SdrModel & getSdrModelFromSdrObject() const
void SetCurrentObj(SdrObjKind nIdent, SdrInventor nInvent=SdrInventor::Default)
SfxRequest aSfxRequest
Definition: fupoor.hxx:47
Point PixelToLogic(const Point &rDevicePt) const
tools::Long Top() const
constexpr Point TopLeft() const
bool IsCreateObj() const
const basegfx::B2DPolyPolygon & GetLineEnd() const
virtual bool IsAction() const override
SDRTEXTHORZADJUST_RIGHT
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void setClosed(bool bNew)
sal_uInt16 GetSlot() const
sal_uInt32 count() const
virtual SdrObjectUniquePtr CreateDefaultObject(const sal_uInt16 nID, const tools::Rectangle &rRectangle) override
Definition: fuconrec.cxx:347
OBJ_MEASURE
bool IsLeft() const
ScDrawView * pView
Definition: fupoor.hxx:42
virtual void Activate() override
Definition: fuconrec.cxx:153
std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr
const Point & GetPosPixel() const
PointerStyle aNewPointer
Definition: fudraw.hxx:30
bool BegCreateCaptionObj(const Point &rPnt, const Size &rObjSiz, OutputDevice *pOut=nullptr, short nMinMov=-3)
const SfxItemPool & GetItemPool() const
SdrObjKind GetCurrentObjIdentifier() const
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
Definition: fuconrec.cxx:85
virtual ~FuConstRectangle() override
Definition: fuconrec.cxx:49
virtual OutlinerParaObject * GetOutlinerParaObject() const
virtual void Activate()
Definition: fupoor.cxx:59
VclPtr< vcl::Window > pWindow
Definition: fupoor.hxx:44
SdrInventor GetCurrentObjInventor() const
sal_Int16 nValue
SDRTEXTVERTADJUST_CENTER
constexpr tools::Long GetHeight() const
virtual void Deactivate()
Definition: fupoor.cxx:63