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