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
57namespace {
58
59::basegfx::B2DPolyPolygon getPolygon(TranslateId 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() ) );
95 pWindow->CaptureMouse();
96
97 if ( pView->GetCurrentObjIdentifier() == SdrObjKind::Caption )
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 = DynCastSdrTextObj( pObj) )
141 pSdrTextObj->ForceOutlinerParaObject();
143 if( pOPO && !pOPO->IsEffectivelyVertical() )
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 = SdrObjKind::Line;
170 break;
171
172 case SID_DRAW_MEASURELINE:
173 aNewPointer = PointerStyle::DrawLine;
174 aObjKind = SdrObjKind::Measure;
175 break;
176
177 case SID_DRAW_RECT:
178 aNewPointer = PointerStyle::DrawRect;
179 aObjKind = SdrObjKind::Rectangle;
180 break;
181
182 case SID_DRAW_ELLIPSE:
183 aNewPointer = PointerStyle::DrawEllipse;
184 aObjKind = SdrObjKind::CircleOrEllipse;
185 break;
186
187 case SID_DRAW_CAPTION:
188 case SID_DRAW_CAPTION_VERTICAL:
189 aNewPointer = PointerStyle::DrawCaption;
190 aObjKind = SdrObjKind::Caption;
191 break;
192
193 default:
194 aNewPointer = PointerStyle::Cross;
195 aObjKind = SdrObjKind::Rectangle;
196 break;
197 }
198
199 pView->SetCurrentObj(aObjKind);
200
201 aOldPointer = pWindow->GetPointer();
203
205}
206
207void 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);
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 MouseButtonDown(const MouseEvent &rMEvt) override
Definition: fuconrec.cxx:85
virtual ~FuConstRectangle() override
Definition: fuconrec.cxx:49
virtual void Activate() override
Definition: fuconrec.cxx:153
virtual rtl::Reference< SdrObject > CreateDefaultObject(const sal_uInt16 nID, const tools::Rectangle &rRectangle) override
Definition: fuconrec.cxx:347
FuConstRectangle(ScTabViewShell &rViewSh, vcl::Window *pWin, ScDrawView *pView, SdrModel *pDoc, const SfxRequest &rReq)
Definition: fuconrec.cxx:43
static void SetLineEnds(SfxItemSet &rAttr, const SdrObject &rObj, sal_uInt16 nSlotId)
Definition: fuconrec.cxx:207
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
Definition: fuconrec.cxx:120
virtual void Deactivate() override
Definition: fuconrec.cxx:340
Draw rectangle.
Definition: fuconstr.hxx:28
virtual bool MouseButtonUp(const MouseEvent &rMEvt) override
Definition: fuconstr.cxx:128
virtual bool MouseButtonDown(const MouseEvent &rMEvt) override
Definition: fuconstr.cxx:46
PointerStyle aNewPointer
Definition: fudraw.hxx:30
PointerStyle aOldPointer
Definition: fudraw.hxx:31
ScDrawView * pView
Definition: fupoor.hxx:42
virtual void Activate()
Definition: fupoor.cxx:61
void SetMouseButtonCode(sal_uInt16 nNew)
Definition: fupoor.hxx:70
SfxRequest aSfxRequest
Definition: fupoor.hxx:47
SdrModel * pDrDoc
Definition: fupoor.hxx:45
virtual void Deactivate()
Definition: fupoor.cxx:65
ScTabViewShell & rViewShell
Definition: fupoor.hxx:43
VclPtr< vcl::Window > pWindow
Definition: fupoor.hxx:44
sal_uInt16 GetButtons() const
const Point & GetPosPixel() const
bool IsLeft() const
void SetVertical(bool bNew)
bool IsEffectivelyVertical() const
void SetActivePointer(PointerStyle nPointer)
Definition: tabview.cxx:884
bool BegCreateObj(const Point &rPnt, OutputDevice *pOut=nullptr, short nMinMov=-3)
bool IsCreateObj() const
bool EndCreateObj(SdrCreateCmd eCmd)
SdrInventor GetCurrentObjInventor() const
SdrObjKind GetCurrentObjIdentifier() const
virtual bool IsAction() const override
void SetCurrentObj(SdrObjKind nIdent, SdrInventor nInvent=SdrInventor::Default)
SdrObject * GetCreateObj() const
bool BegCreateCaptionObj(const Point &rPnt, const Size &rObjSiz, OutputDevice *pOut=nullptr, short nMinMov=-3)
SdrMark * GetMark(size_t nNum) const
const SdrMarkList & GetMarkedObjectList() const
SdrObject * GetMarkedSdrObj() const
XLineEndListRef GetLineEndList() const
const SfxItemPool & GetItemPool() const
static rtl::Reference< SdrObject > MakeNewObject(SdrModel &rSdrModel, SdrInventor nInventor, SdrObjKind nObjIdentifier, const tools::Rectangle *pSnapRect=nullptr)
virtual OutlinerParaObject * GetOutlinerParaObject() const
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
SdrModel & getSdrModelFromSdrObject() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
sal_uInt16 GetSlot() const
const basegfx::B2DPolyPolygon & GetLineEnd() const
const OUString & GetName() const
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
sal_uInt32 count() const
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
void setClosed(bool bNew)
constexpr tools::Long GetWidth() const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr Point BottomRight() const
constexpr tools::Long GetHeight() const
constexpr tools::Long Bottom() const
int nCount
SVXCORE_DLLPUBLIC OUString SvxResId(TranslateId aId)
sal_Int16 nValue
sal_Int32 nIndex
long Long
SDRTEXTVERTADJUST_CENTER
SDRTEXTHORZADJUST_RIGHT
SVXCORE_DLLPUBLIC SdrTextObj * DynCastSdrTextObj(SdrObject *)
SdrObjKind
constexpr TypedWhichId< XLineWidthItem > XATTR_LINEWIDTH(XATTR_LINE_FIRST+2)