File: | home/maarten/src/libreoffice/core/svx/source/svdraw/svdedtv1.cxx |
Warning: | line 339, column 13 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <basegfx/matrix/b2dhommatrix.hxx> | |||
21 | #include <basegfx/matrix/b2dhommatrixtools.hxx> | |||
22 | #include <editeng/eeitem.hxx> | |||
23 | #include <math.h> | |||
24 | #include <svl/itemiter.hxx> | |||
25 | #include <svl/whiter.hxx> | |||
26 | #include <tools/bigint.hxx> | |||
27 | #include <vcl/svapp.hxx> | |||
28 | #include <vcl/weld.hxx> | |||
29 | ||||
30 | #include <getallcharpropids.hxx> | |||
31 | #include <svx/dialmgr.hxx> | |||
32 | #include <svx/svditer.hxx> | |||
33 | #include <svx/strings.hrc> | |||
34 | ||||
35 | #include <AffineMatrixItem.hxx> | |||
36 | #include <svx/e3dsceneupdater.hxx> | |||
37 | #include <svx/obj3d.hxx> | |||
38 | #include <svx/rectenum.hxx> | |||
39 | #include <svx/sdr/contact/viewcontact.hxx> | |||
40 | #include <svx/sdooitm.hxx> | |||
41 | #include <svx/sderitm.hxx> | |||
42 | #include <svx/sdtagitm.hxx> | |||
43 | #include <svx/svdedtv.hxx> | |||
44 | #include <svx/svdetc.hxx> | |||
45 | #include <svx/svdopath.hxx> | |||
46 | #include <svx/svdpage.hxx> | |||
47 | #include <svx/svdpagv.hxx> | |||
48 | #include <svx/svdtrans.hxx> | |||
49 | #include <svx/svdundo.hxx> | |||
50 | #include <svx/svxids.hrc> | |||
51 | #include <sxallitm.hxx> | |||
52 | #include <sxmovitm.hxx> | |||
53 | #include <sxreaitm.hxx> | |||
54 | #include <sxreoitm.hxx> | |||
55 | #include <sxroaitm.hxx> | |||
56 | #include <sxrooitm.hxx> | |||
57 | #include <sxsalitm.hxx> | |||
58 | #include <sxsoitm.hxx> | |||
59 | #include <sxtraitm.hxx> | |||
60 | #include <svx/xlnedwit.hxx> | |||
61 | #include <svx/xlnstwit.hxx> | |||
62 | #include <svx/xlnwtit.hxx> | |||
63 | #include <svx/xlnclit.hxx> | |||
64 | #include <svx/xflclit.hxx> | |||
65 | #include <svx/xlntrit.hxx> | |||
66 | #include <svx/xfltrit.hxx> | |||
67 | #include <svx/sdprcitm.hxx> | |||
68 | #include <LibreOfficeKit/LibreOfficeKitEnums.h> | |||
69 | #include <rtl/ustring.hxx> | |||
70 | #include <sfx2/viewsh.hxx> | |||
71 | #include <comphelper/lok.hxx> | |||
72 | ||||
73 | // EditView | |||
74 | ||||
75 | ||||
76 | void SdrEditView::SetMarkedObjRect(const tools::Rectangle& rRect) | |||
77 | { | |||
78 | DBG_ASSERT(!rRect.IsEmpty(),"SetMarkedObjRect() with an empty Rect does not make sense.")do { if (true && (!(!rRect.IsEmpty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdedtv1.cxx" ":" "78" ": "), "%s", "SetMarkedObjRect() with an empty Rect does not make sense." ); } } while (false); | |||
79 | if (rRect.IsEmpty()) return; | |||
80 | const size_t nCount=GetMarkedObjectCount(); | |||
81 | if (nCount==0) return; | |||
82 | tools::Rectangle aR0(GetMarkedObjRect()); | |||
83 | DBG_ASSERT(!aR0.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() is empty.")do { if (true && (!(!aR0.IsEmpty()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdedtv1.cxx" ":" "83" ": "), "%s", "SetMarkedObjRect(): GetMarkedObjRect() is empty." ); } } while (false); | |||
84 | if (aR0.IsEmpty()) return; | |||
85 | long x0=aR0.Left(); | |||
86 | long y0=aR0.Top(); | |||
87 | long w0=aR0.Right()-x0; | |||
88 | long h0=aR0.Bottom()-y0; | |||
89 | long x1=rRect.Left(); | |||
90 | long y1=rRect.Top(); | |||
91 | long w1=rRect.Right()-x1; | |||
92 | long h1=rRect.Bottom()-y1; | |||
93 | ||||
94 | const bool bUndo = IsUndoEnabled(); | |||
95 | if( bUndo ) | |||
96 | { | |||
97 | EndTextEditAllViews(); | |||
98 | BegUndo(ImpGetDescriptionString(STR_EditPosSizereinterpret_cast<char const *>("STR_EditPosSize" "\004" u8"Set position and size for %1"))); | |||
99 | } | |||
100 | ||||
101 | for (size_t nm=0; nm<nCount; ++nm) | |||
102 | { | |||
103 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
104 | SdrObject* pO=pM->GetMarkedSdrObj(); | |||
105 | if( bUndo ) | |||
106 | AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); | |||
107 | ||||
108 | tools::Rectangle aR1(pO->GetSnapRect()); | |||
109 | if (!aR1.IsEmpty()) | |||
110 | { | |||
111 | if (aR1==aR0) | |||
112 | { | |||
113 | aR1=rRect; | |||
114 | } | |||
115 | else | |||
116 | { // transform aR1 to aR0 after rRect | |||
117 | aR1.Move(-x0,-y0); | |||
118 | BigInt l(aR1.Left()); | |||
119 | BigInt r(aR1.Right()); | |||
120 | BigInt t(aR1.Top()); | |||
121 | BigInt b(aR1.Bottom()); | |||
122 | if (w0!=0) { | |||
123 | l*=w1; l/=w0; | |||
124 | r*=w1; r/=w0; | |||
125 | } else { | |||
126 | l=0; r=w1; | |||
127 | } | |||
128 | if (h0!=0) { | |||
129 | t*=h1; t/=h0; | |||
130 | b*=h1; b/=h0; | |||
131 | } else { | |||
132 | t=0; b=h1; | |||
133 | } | |||
134 | aR1.SetLeft(long(l) ); | |||
135 | aR1.SetRight(long(r) ); | |||
136 | aR1.SetTop(long(t) ); | |||
137 | aR1.SetBottom(long(b) ); | |||
138 | aR1.Move(x1,y1); | |||
139 | } | |||
140 | pO->SetSnapRect(aR1); | |||
141 | } else { | |||
142 | OSL_FAIL("SetMarkedObjRect(): pObj->GetSnapRect() returns empty Rect")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdedtv1.cxx" ":" "142" ": "), "%s", "SetMarkedObjRect(): pObj->GetSnapRect() returns empty Rect" ); } } while (false); | |||
143 | } | |||
144 | } | |||
145 | if( bUndo ) | |||
146 | EndUndo(); | |||
147 | } | |||
148 | ||||
149 | std::vector< std::unique_ptr<SdrUndoAction> > SdrEditView::CreateConnectorUndo( SdrObject& rO ) | |||
150 | { | |||
151 | std::vector< std::unique_ptr<SdrUndoAction> > vUndoActions; | |||
152 | ||||
153 | if ( rO.GetBroadcaster() ) | |||
154 | { | |||
155 | const SdrPage* pPage = rO.getSdrPageFromSdrObject(); | |||
156 | if ( pPage ) | |||
157 | { | |||
158 | SdrObjListIter aIter(pPage, SdrIterMode::DeepWithGroups); | |||
159 | while( aIter.IsMore() ) | |||
160 | { | |||
161 | SdrObject* pPartObj = aIter.Next(); | |||
162 | if ( dynamic_cast<const SdrEdgeObj*>( pPartObj) != nullptr ) | |||
163 | { | |||
164 | if ( ( pPartObj->GetConnectedNode( false ) == &rO ) || | |||
165 | ( pPartObj->GetConnectedNode( true ) == &rO ) ) | |||
166 | { | |||
167 | vUndoActions.push_back( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pPartObj ) ); | |||
168 | } | |||
169 | } | |||
170 | } | |||
171 | } | |||
172 | } | |||
173 | return vUndoActions; | |||
174 | } | |||
175 | ||||
176 | void SdrEditView::AddUndoActions( std::vector< std::unique_ptr<SdrUndoAction> > aUndoActions ) | |||
177 | { | |||
178 | for (auto & rAction : aUndoActions) | |||
179 | AddUndo( std::move(rAction) ); | |||
180 | } | |||
181 | ||||
182 | void SdrEditView::MoveMarkedObj(const Size& rSiz, bool bCopy) | |||
183 | { | |||
184 | const bool bUndo = IsUndoEnabled(); | |||
185 | ||||
186 | if( bUndo ) | |||
187 | { | |||
188 | EndTextEditAllViews(); | |||
189 | OUString aStr(SvxResId(STR_EditMovereinterpret_cast<char const *>("STR_EditMove" "\004" u8"Move %1" ))); | |||
190 | if (bCopy) | |||
191 | aStr += SvxResId(STR_EditWithCopyreinterpret_cast<char const *>("STR_EditWithCopy" "\004" u8"with copy")); | |||
192 | // needs its own UndoGroup because of its parameters | |||
193 | BegUndo(aStr,GetDescriptionOfMarkedObjects(),SdrRepeatFunc::Move); | |||
194 | } | |||
195 | ||||
196 | if (bCopy) | |||
197 | CopyMarkedObj(); | |||
198 | ||||
199 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
200 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
201 | { | |||
202 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
203 | SdrObject* pO=pM->GetMarkedSdrObj(); | |||
204 | if( bUndo ) | |||
205 | { | |||
206 | AddUndoActions( CreateConnectorUndo( *pO ) ); | |||
207 | AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,rSiz)); | |||
208 | } | |||
209 | pO->Move(rSiz); | |||
210 | } | |||
211 | ||||
212 | if( bUndo ) | |||
213 | EndUndo(); | |||
214 | } | |||
215 | ||||
216 | void SdrEditView::ResizeMarkedObj(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy) | |||
217 | { | |||
218 | const bool bUndo = IsUndoEnabled(); | |||
219 | if( bUndo ) | |||
220 | { | |||
221 | EndTextEditAllViews(); | |||
222 | OUString aStr {ImpGetDescriptionString(STR_EditResizereinterpret_cast<char const *>("STR_EditResize" "\004" u8"Resize %1" ))}; | |||
223 | if (bCopy) | |||
224 | aStr+=SvxResId(STR_EditWithCopyreinterpret_cast<char const *>("STR_EditWithCopy" "\004" u8"with copy")); | |||
225 | BegUndo(aStr); | |||
226 | } | |||
227 | ||||
228 | if (bCopy) | |||
229 | CopyMarkedObj(); | |||
230 | ||||
231 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
232 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
233 | { | |||
234 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
235 | SdrObject* pO=pM->GetMarkedSdrObj(); | |||
236 | if( bUndo ) | |||
237 | { | |||
238 | AddUndoActions( CreateConnectorUndo( *pO ) ); | |||
239 | AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); | |||
240 | } | |||
241 | pO->Resize(rRef,xFact,yFact); | |||
242 | } | |||
243 | ||||
244 | if( bUndo ) | |||
245 | EndUndo(); | |||
246 | } | |||
247 | void SdrEditView::ResizeMultMarkedObj(const Point& rRef, | |||
248 | const Fraction& xFact, | |||
249 | const Fraction& yFact, | |||
250 | const bool bWdh, | |||
251 | const bool bHgt) | |||
252 | { | |||
253 | const bool bUndo = IsUndoEnabled(); | |||
254 | if( bUndo ) | |||
255 | { | |||
256 | EndTextEditAllViews(); | |||
257 | BegUndo(ImpGetDescriptionString(STR_EditResizereinterpret_cast<char const *>("STR_EditResize" "\004" u8"Resize %1" ))); | |||
258 | } | |||
259 | ||||
260 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
261 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
262 | { | |||
263 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
264 | SdrObject* pO=pM->GetMarkedSdrObj(); | |||
265 | if( bUndo ) | |||
266 | { | |||
267 | AddUndoActions( CreateConnectorUndo( *pO ) ); | |||
268 | AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); | |||
269 | } | |||
270 | ||||
271 | Fraction aFrac(1,1); | |||
272 | if (bWdh && bHgt) | |||
273 | pO->Resize(rRef, xFact, yFact); | |||
274 | else if (bWdh) | |||
275 | pO->Resize(rRef, xFact, aFrac); | |||
276 | else if (bHgt) | |||
277 | pO->Resize(rRef, aFrac, yFact); | |||
278 | } | |||
279 | if( bUndo ) | |||
280 | EndUndo(); | |||
281 | } | |||
282 | ||||
283 | long SdrEditView::GetMarkedObjRotate() const | |||
284 | { | |||
285 | long nRetval(0); | |||
286 | ||||
287 | if(GetMarkedObjectCount()) | |||
288 | { | |||
289 | SdrMark* pM = GetSdrMarkByIndex(0); | |||
290 | SdrObject* pO = pM->GetMarkedSdrObj(); | |||
291 | ||||
292 | nRetval = pO->GetRotateAngle(); | |||
293 | } | |||
294 | ||||
295 | return nRetval; | |||
296 | } | |||
297 | ||||
298 | void SdrEditView::RotateMarkedObj(const Point& rRef, long nAngle, bool bCopy) | |||
299 | { | |||
300 | const bool bUndo = IsUndoEnabled(); | |||
301 | if( bUndo ) | |||
302 | { | |||
303 | EndTextEditAllViews(); | |||
304 | OUString aStr {ImpGetDescriptionString(STR_EditRotatereinterpret_cast<char const *>("STR_EditRotate" "\004" u8"Rotate %1" ))}; | |||
305 | if (bCopy) aStr+=SvxResId(STR_EditWithCopyreinterpret_cast<char const *>("STR_EditWithCopy" "\004" u8"with copy")); | |||
306 | BegUndo(aStr); | |||
307 | } | |||
308 | ||||
309 | if (bCopy
| |||
310 | CopyMarkedObj(); | |||
311 | ||||
312 | double nSin = sin(nAngle * F_PI18000(3.14159265358979323846/18000.0)); | |||
313 | double nCos = cos(nAngle * F_PI18000(3.14159265358979323846/18000.0)); | |||
314 | const size_t nMarkCount(GetMarkedObjectCount()); | |||
315 | ||||
316 | if(nMarkCount) | |||
317 | { | |||
318 | std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters; | |||
319 | ||||
320 | for(size_t nm = 0; nm
| |||
321 | { | |||
322 | SdrMark* pM = GetSdrMarkByIndex(nm); | |||
323 | SdrObject* pO = pM->GetMarkedSdrObj(); | |||
324 | ||||
325 | if( bUndo
| |||
326 | { | |||
327 | // extra undo actions for changed connector which now may hold its laid out path (SJ) | |||
328 | AddUndoActions( CreateConnectorUndo( *pO ) ); | |||
329 | ||||
330 | AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); | |||
331 | } | |||
332 | ||||
333 | // set up a scene updater if object is a 3d object | |||
334 | if(dynamic_cast< E3dObject* >(pO)) | |||
335 | { | |||
336 | aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO)); | |||
337 | } | |||
338 | ||||
339 | pO->Rotate(rRef,nAngle,nSin,nCos); | |||
| ||||
340 | } | |||
341 | ||||
342 | // fire scene updaters | |||
343 | while(!aUpdaters.empty()) | |||
344 | { | |||
345 | delete aUpdaters.back(); | |||
346 | aUpdaters.pop_back(); | |||
347 | } | |||
348 | } | |||
349 | ||||
350 | if( bUndo ) | |||
351 | EndUndo(); | |||
352 | } | |||
353 | ||||
354 | void SdrEditView::MirrorMarkedObj(const Point& rRef1, const Point& rRef2, bool bCopy) | |||
355 | { | |||
356 | const bool bUndo = IsUndoEnabled(); | |||
357 | ||||
358 | if( bUndo ) | |||
359 | { | |||
360 | EndTextEditAllViews(); | |||
361 | OUString aStr; | |||
362 | Point aDif(rRef2-rRef1); | |||
363 | if (aDif.X()==0) | |||
364 | aStr = ImpGetDescriptionString(STR_EditMirrorHorireinterpret_cast<char const *>("STR_EditMirrorHori" "\004" u8"Flip %1 horizontal")); | |||
365 | else if (aDif.Y()==0) | |||
366 | aStr = ImpGetDescriptionString(STR_EditMirrorVertreinterpret_cast<char const *>("STR_EditMirrorVert" "\004" u8"Flip %1 vertical")); | |||
367 | else if (std::abs(aDif.X()) == std::abs(aDif.Y())) | |||
368 | aStr = ImpGetDescriptionString(STR_EditMirrorDiagreinterpret_cast<char const *>("STR_EditMirrorDiag" "\004" u8"Flip %1 diagonal")); | |||
369 | else | |||
370 | aStr = ImpGetDescriptionString(STR_EditMirrorFreereinterpret_cast<char const *>("STR_EditMirrorFree" "\004" u8"Flip %1 freehand")); | |||
371 | if (bCopy) aStr+=SvxResId(STR_EditWithCopyreinterpret_cast<char const *>("STR_EditWithCopy" "\004" u8"with copy")); | |||
372 | BegUndo(aStr); | |||
373 | } | |||
374 | ||||
375 | if (bCopy) | |||
376 | CopyMarkedObj(); | |||
377 | ||||
378 | const size_t nMarkCount(GetMarkedObjectCount()); | |||
379 | ||||
380 | if(nMarkCount) | |||
381 | { | |||
382 | std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters; | |||
383 | ||||
384 | for(size_t nm = 0; nm < nMarkCount; ++nm) | |||
385 | { | |||
386 | SdrMark* pM = GetSdrMarkByIndex(nm); | |||
387 | SdrObject* pO = pM->GetMarkedSdrObj(); | |||
388 | ||||
389 | if( bUndo ) | |||
390 | { | |||
391 | // extra undo actions for changed connector which now may hold its laid out path (SJ) | |||
392 | AddUndoActions( CreateConnectorUndo( *pO ) ); | |||
393 | ||||
394 | AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); | |||
395 | } | |||
396 | ||||
397 | // set up a scene updater if object is a 3d object | |||
398 | if(dynamic_cast< E3dObject* >(pO)) | |||
399 | { | |||
400 | aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO)); | |||
401 | } | |||
402 | ||||
403 | pO->Mirror(rRef1,rRef2); | |||
404 | } | |||
405 | ||||
406 | // fire scene updaters | |||
407 | while(!aUpdaters.empty()) | |||
408 | { | |||
409 | delete aUpdaters.back(); | |||
410 | aUpdaters.pop_back(); | |||
411 | } | |||
412 | } | |||
413 | ||||
414 | if( bUndo ) | |||
415 | EndUndo(); | |||
416 | } | |||
417 | ||||
418 | void SdrEditView::MirrorMarkedObjHorizontal() | |||
419 | { | |||
420 | Point aCenter(GetMarkedObjRect().Center()); | |||
421 | Point aPt2(aCenter); | |||
422 | aPt2.AdjustY( 1 ); | |||
423 | MirrorMarkedObj(aCenter,aPt2); | |||
424 | } | |||
425 | ||||
426 | void SdrEditView::MirrorMarkedObjVertical() | |||
427 | { | |||
428 | Point aCenter(GetMarkedObjRect().Center()); | |||
429 | Point aPt2(aCenter); | |||
430 | aPt2.AdjustX( 1 ); | |||
431 | MirrorMarkedObj(aCenter,aPt2); | |||
432 | } | |||
433 | ||||
434 | long SdrEditView::GetMarkedObjShear() const | |||
435 | { | |||
436 | bool b1st=true; | |||
437 | bool bOk=true; | |||
438 | long nAngle=0; | |||
439 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
440 | for (size_t nm=0; nm<nMarkCount && bOk; ++nm) { | |||
441 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
442 | SdrObject* pO=pM->GetMarkedSdrObj(); | |||
443 | long nAngle2=pO->GetShearAngle(); | |||
444 | if (b1st) nAngle=nAngle2; | |||
445 | else if (nAngle2!=nAngle) bOk=false; | |||
446 | b1st=false; | |||
447 | } | |||
448 | if (nAngle>SDRMAXSHEAR8900) nAngle=SDRMAXSHEAR8900; | |||
449 | if (nAngle<-SDRMAXSHEAR8900) nAngle=-SDRMAXSHEAR8900; | |||
450 | if (!bOk) nAngle=0; | |||
451 | return nAngle; | |||
452 | } | |||
453 | ||||
454 | void SdrEditView::ShearMarkedObj(const Point& rRef, long nAngle, bool bVShear, bool bCopy) | |||
455 | { | |||
456 | const bool bUndo = IsUndoEnabled(); | |||
457 | ||||
458 | if( bUndo ) | |||
459 | { | |||
460 | EndTextEditAllViews(); | |||
461 | OUString aStr {ImpGetDescriptionString(STR_EditShearreinterpret_cast<char const *>("STR_EditShear" "\004" u8"Distort %1 (slant)" ))}; | |||
462 | if (bCopy) | |||
463 | aStr+=SvxResId(STR_EditWithCopyreinterpret_cast<char const *>("STR_EditWithCopy" "\004" u8"with copy")); | |||
464 | BegUndo(aStr); | |||
465 | } | |||
466 | ||||
467 | if (bCopy) | |||
468 | CopyMarkedObj(); | |||
469 | ||||
470 | double nTan = tan(nAngle * F_PI18000(3.14159265358979323846/18000.0)); | |||
471 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
472 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
473 | { | |||
474 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
475 | SdrObject* pO=pM->GetMarkedSdrObj(); | |||
476 | if( bUndo ) | |||
477 | { | |||
478 | AddUndoActions( CreateConnectorUndo( *pO ) ); | |||
479 | AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); | |||
480 | } | |||
481 | pO->Shear(rRef,nAngle,nTan,bVShear); | |||
482 | } | |||
483 | ||||
484 | if( bUndo ) | |||
485 | EndUndo(); | |||
486 | } | |||
487 | ||||
488 | void SdrEditView::ImpCrookObj(SdrObject* pO, const Point& rRef, const Point& rRad, | |||
489 | SdrCrookMode eMode, bool bVertical, bool bNoContortion, bool bRotate, const tools::Rectangle& rMarkRect) | |||
490 | { | |||
491 | SdrPathObj* pPath=dynamic_cast<SdrPathObj*>( pO ); | |||
492 | bool bDone = false; | |||
493 | ||||
494 | if(pPath!=nullptr && !bNoContortion) | |||
495 | { | |||
496 | XPolyPolygon aXPP(pPath->GetPathPoly()); | |||
497 | switch (eMode) { | |||
498 | case SdrCrookMode::Rotate : CrookRotatePoly (aXPP,rRef,rRad,bVertical); break; | |||
499 | case SdrCrookMode::Slant : CrookSlantPoly (aXPP,rRef,rRad,bVertical); break; | |||
500 | case SdrCrookMode::Stretch: CrookStretchPoly(aXPP,rRef,rRad,bVertical,rMarkRect); break; | |||
501 | } // switch | |||
502 | pPath->SetPathPoly(aXPP.getB2DPolyPolygon()); | |||
503 | bDone = true; | |||
504 | } | |||
505 | ||||
506 | if(!bDone && !pPath && pO->IsPolyObj() && 0 != pO->GetPointCount()) | |||
507 | { | |||
508 | // for PolyObj's, but NOT for SdrPathObj's, e.g. the measurement object | |||
509 | sal_uInt32 nPointCount(pO->GetPointCount()); | |||
510 | XPolygon aXP(static_cast<sal_uInt16>(nPointCount)); | |||
511 | sal_uInt32 nPtNum; | |||
512 | ||||
513 | for(nPtNum = 0; nPtNum < nPointCount; nPtNum++) | |||
514 | { | |||
515 | Point aPt(pO->GetPoint(nPtNum)); | |||
516 | aXP[static_cast<sal_uInt16>(nPtNum)]=aPt; | |||
517 | } | |||
518 | ||||
519 | switch (eMode) | |||
520 | { | |||
521 | case SdrCrookMode::Rotate : CrookRotatePoly (aXP,rRef,rRad,bVertical); break; | |||
522 | case SdrCrookMode::Slant : CrookSlantPoly (aXP,rRef,rRad,bVertical); break; | |||
523 | case SdrCrookMode::Stretch: CrookStretchPoly(aXP,rRef,rRad,bVertical,rMarkRect); break; | |||
524 | } | |||
525 | ||||
526 | for(nPtNum = 0; nPtNum < nPointCount; nPtNum++) | |||
527 | { | |||
528 | // broadcasting could be optimized here, but for the | |||
529 | // current two points of the measurement object, it's fine | |||
530 | pO->SetPoint(aXP[static_cast<sal_uInt16>(nPtNum)],nPtNum); | |||
531 | } | |||
532 | ||||
533 | bDone = true; | |||
534 | } | |||
535 | ||||
536 | if(bDone) | |||
537 | return; | |||
538 | ||||
539 | // for all others or if bNoContortion | |||
540 | Point aCtr0(pO->GetSnapRect().Center()); | |||
541 | Point aCtr1(aCtr0); | |||
542 | bool bRotOk(false); | |||
543 | double nSin(0.0), nCos(1.0); | |||
544 | double nAngle(0.0); | |||
545 | ||||
546 | if(0 != rRad.X() && 0 != rRad.Y()) | |||
547 | { | |||
548 | bRotOk = bRotate; | |||
549 | ||||
550 | switch (eMode) | |||
551 | { | |||
552 | case SdrCrookMode::Rotate : nAngle=CrookRotateXPoint (aCtr1,nullptr,nullptr,rRef,rRad,nSin,nCos,bVertical); bRotOk=bRotate; break; | |||
553 | case SdrCrookMode::Slant : nAngle=CrookSlantXPoint (aCtr1,nullptr,nullptr,rRef,rRad,nSin,nCos,bVertical); break; | |||
554 | case SdrCrookMode::Stretch: nAngle=CrookStretchXPoint(aCtr1,nullptr,nullptr,rRef,rRad,nSin,nCos,bVertical,rMarkRect); break; | |||
555 | } | |||
556 | } | |||
557 | ||||
558 | aCtr1 -= aCtr0; | |||
559 | ||||
560 | if(bRotOk) | |||
561 | pO->Rotate(aCtr0, FRound(nAngle / F_PI18000(3.14159265358979323846/18000.0)), nSin, nCos); | |||
562 | ||||
563 | pO->Move(Size(aCtr1.X(),aCtr1.Y())); | |||
564 | } | |||
565 | ||||
566 | void SdrEditView::CrookMarkedObj(const Point& rRef, const Point& rRad, SdrCrookMode eMode, | |||
567 | bool bVertical, bool bNoContortion, bool bCopy) | |||
568 | { | |||
569 | tools::Rectangle aMarkRect(GetMarkedObjRect()); | |||
570 | const bool bUndo = IsUndoEnabled(); | |||
571 | ||||
572 | bool bRotate=bNoContortion && eMode==SdrCrookMode::Rotate && IsRotateAllowed(); | |||
573 | ||||
574 | if( bUndo ) | |||
575 | { | |||
576 | EndTextEditAllViews(); | |||
577 | OUString aStr {ImpGetDescriptionString(bNoContortion ? STR_EditCrookreinterpret_cast<char const *>("STR_EditCrook" "\004" u8"Arrange %1 in circle" ) : STR_EditCrookContortionreinterpret_cast<char const *>("STR_EditCrookContortion" "\004" u8"Curve %1 in circle"))}; | |||
578 | if (bCopy) | |||
579 | aStr+=SvxResId(STR_EditWithCopyreinterpret_cast<char const *>("STR_EditWithCopy" "\004" u8"with copy")); | |||
580 | BegUndo(aStr); | |||
581 | } | |||
582 | ||||
583 | if (bCopy) | |||
584 | CopyMarkedObj(); | |||
585 | ||||
586 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
587 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
588 | { | |||
589 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
590 | SdrObject* pO=pM->GetMarkedSdrObj(); | |||
591 | if( bUndo ) | |||
592 | AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); | |||
593 | ||||
594 | const SdrObjList* pOL=pO->GetSubList(); | |||
595 | if (bNoContortion || pOL==nullptr) { | |||
596 | ImpCrookObj(pO,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect); | |||
597 | } else { | |||
598 | SdrObjListIter aIter(pOL,SdrIterMode::DeepNoGroups); | |||
599 | while (aIter.IsMore()) { | |||
600 | SdrObject* pO1=aIter.Next(); | |||
601 | ImpCrookObj(pO1,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect); | |||
602 | } | |||
603 | } | |||
604 | } | |||
605 | ||||
606 | if( bUndo ) | |||
607 | EndUndo(); | |||
608 | } | |||
609 | ||||
610 | void SdrEditView::ImpDistortObj(SdrObject* pO, const tools::Rectangle& rRef, const XPolygon& rDistortedRect, bool bNoContortion) | |||
611 | { | |||
612 | SdrPathObj* pPath = dynamic_cast<SdrPathObj*>( pO ); | |||
613 | ||||
614 | if(!bNoContortion && pPath) | |||
615 | { | |||
616 | XPolyPolygon aXPP(pPath->GetPathPoly()); | |||
617 | aXPP.Distort(rRef, rDistortedRect); | |||
618 | pPath->SetPathPoly(aXPP.getB2DPolyPolygon()); | |||
619 | } | |||
620 | else if(pO->IsPolyObj()) | |||
621 | { | |||
622 | // e. g. for the measurement object | |||
623 | sal_uInt32 nPointCount(pO->GetPointCount()); | |||
624 | XPolygon aXP(static_cast<sal_uInt16>(nPointCount)); | |||
625 | sal_uInt32 nPtNum; | |||
626 | ||||
627 | for(nPtNum = 0; nPtNum < nPointCount; nPtNum++) | |||
628 | { | |||
629 | Point aPt(pO->GetPoint(nPtNum)); | |||
630 | aXP[static_cast<sal_uInt16>(nPtNum)]=aPt; | |||
631 | } | |||
632 | ||||
633 | aXP.Distort(rRef, rDistortedRect); | |||
634 | ||||
635 | for(nPtNum = 0; nPtNum < nPointCount; nPtNum++) | |||
636 | { | |||
637 | // broadcasting could be optimized here, but for the | |||
638 | // current two points of the measurement object it's fine | |||
639 | pO->SetPoint(aXP[static_cast<sal_uInt16>(nPtNum)],nPtNum); | |||
640 | } | |||
641 | } | |||
642 | } | |||
643 | ||||
644 | void SdrEditView::DistortMarkedObj(const tools::Rectangle& rRef, const XPolygon& rDistortedRect, bool bNoContortion, bool bCopy) | |||
645 | { | |||
646 | const bool bUndo = IsUndoEnabled(); | |||
647 | ||||
648 | if( bUndo ) | |||
649 | { | |||
650 | EndTextEditAllViews(); | |||
651 | OUString aStr {ImpGetDescriptionString(STR_EditDistortreinterpret_cast<char const *>("STR_EditDistort" "\004" u8"Distort %1"))}; | |||
652 | if (bCopy) | |||
653 | aStr+=SvxResId(STR_EditWithCopyreinterpret_cast<char const *>("STR_EditWithCopy" "\004" u8"with copy")); | |||
654 | BegUndo(aStr); | |||
655 | } | |||
656 | ||||
657 | if (bCopy) | |||
658 | CopyMarkedObj(); | |||
659 | ||||
660 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
661 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
662 | { | |||
663 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
664 | SdrObject* pO=pM->GetMarkedSdrObj(); | |||
665 | if( bUndo ) | |||
666 | AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO)); | |||
667 | ||||
668 | tools::Rectangle aRefRect(rRef); | |||
669 | const SdrObjList* pOL=pO->GetSubList(); | |||
670 | if (bNoContortion || pOL==nullptr) { | |||
671 | ImpDistortObj(pO,aRefRect,rDistortedRect,bNoContortion); | |||
672 | } else { | |||
673 | SdrObjListIter aIter(pOL,SdrIterMode::DeepNoGroups); | |||
674 | while (aIter.IsMore()) { | |||
675 | SdrObject* pO1=aIter.Next(); | |||
676 | ImpDistortObj(pO1,aRefRect,rDistortedRect,bNoContortion); | |||
677 | } | |||
678 | } | |||
679 | } | |||
680 | if( bUndo ) | |||
681 | EndUndo(); | |||
682 | } | |||
683 | ||||
684 | ||||
685 | void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet& rAttr) | |||
686 | { | |||
687 | // bReplaceAll has no effect here | |||
688 | tools::Rectangle aAllSnapRect(GetMarkedObjRect()); | |||
689 | const SfxPoolItem *pPoolItem=nullptr; | |||
690 | if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,true,&pPoolItem)==SfxItemState::SET) { | |||
691 | long n=static_cast<const SdrTransformRef1XItem*>(pPoolItem)->GetValue(); | |||
692 | SetRef1(Point(n,GetRef1().Y())); | |||
693 | } | |||
694 | if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,true,&pPoolItem)==SfxItemState::SET) { | |||
695 | long n=static_cast<const SdrTransformRef1YItem*>(pPoolItem)->GetValue(); | |||
696 | SetRef1(Point(GetRef1().X(),n)); | |||
697 | } | |||
698 | if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,true,&pPoolItem)==SfxItemState::SET) { | |||
699 | long n=static_cast<const SdrTransformRef2XItem*>(pPoolItem)->GetValue(); | |||
700 | SetRef2(Point(n,GetRef2().Y())); | |||
701 | } | |||
702 | if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,true,&pPoolItem)==SfxItemState::SET) { | |||
703 | long n=static_cast<const SdrTransformRef2YItem*>(pPoolItem)->GetValue(); | |||
704 | SetRef2(Point(GetRef2().X(),n)); | |||
705 | } | |||
706 | long nAllPosX=0; bool bAllPosX=false; | |||
707 | long nAllPosY=0; bool bAllPosY=false; | |||
708 | long nAllWdt=0; bool bAllWdt=false; | |||
709 | long nAllHgt=0; bool bAllHgt=false; | |||
710 | bool bDoIt=false; | |||
711 | if (rAttr.GetItemState(SDRATTR_ALLPOSITIONX,true,&pPoolItem)==SfxItemState::SET) { | |||
712 | nAllPosX=static_cast<const SdrAllPositionXItem*>(pPoolItem)->GetValue(); | |||
713 | bAllPosX=true; bDoIt=true; | |||
714 | } | |||
715 | if (rAttr.GetItemState(SDRATTR_ALLPOSITIONY,true,&pPoolItem)==SfxItemState::SET) { | |||
716 | nAllPosY=static_cast<const SdrAllPositionYItem*>(pPoolItem)->GetValue(); | |||
717 | bAllPosY=true; bDoIt=true; | |||
718 | } | |||
719 | if (rAttr.GetItemState(SDRATTR_ALLSIZEWIDTH,true,&pPoolItem)==SfxItemState::SET) { | |||
720 | nAllWdt=static_cast<const SdrAllSizeWidthItem*>(pPoolItem)->GetValue(); | |||
721 | bAllWdt=true; bDoIt=true; | |||
722 | } | |||
723 | if (rAttr.GetItemState(SDRATTR_ALLSIZEHEIGHT,true,&pPoolItem)==SfxItemState::SET) { | |||
724 | nAllHgt=static_cast<const SdrAllSizeHeightItem*>(pPoolItem)->GetValue(); | |||
725 | bAllHgt=true; bDoIt=true; | |||
726 | } | |||
727 | if (bDoIt
| |||
728 | tools::Rectangle aRect(aAllSnapRect); // TODO: change this for PolyPt's and GluePt's!!! | |||
729 | if (bAllPosX) aRect.Move(nAllPosX-aRect.Left(),0); | |||
730 | if (bAllPosY) aRect.Move(0,nAllPosY-aRect.Top()); | |||
731 | if (bAllWdt) aRect.SetRight(aAllSnapRect.Left()+nAllWdt ); | |||
732 | if (bAllHgt) aRect.SetBottom(aAllSnapRect.Top()+nAllHgt ); | |||
733 | SetMarkedObjRect(aRect); | |||
734 | } | |||
735 | if (rAttr.GetItemState(SDRATTR_RESIZEXALL,true,&pPoolItem)==SfxItemState::SET) { | |||
736 | Fraction aXFact=static_cast<const SdrResizeXAllItem*>(pPoolItem)->GetValue(); | |||
737 | ResizeMarkedObj(aAllSnapRect.TopLeft(),aXFact,Fraction(1,1)); | |||
738 | } | |||
739 | if (rAttr.GetItemState(SDRATTR_RESIZEYALL,true,&pPoolItem)==SfxItemState::SET) { | |||
740 | Fraction aYFact=static_cast<const SdrResizeYAllItem*>(pPoolItem)->GetValue(); | |||
741 | ResizeMarkedObj(aAllSnapRect.TopLeft(),Fraction(1,1),aYFact); | |||
742 | } | |||
743 | if (rAttr.GetItemState(SDRATTR_ROTATEALL,true,&pPoolItem)==SfxItemState::SET) { | |||
744 | long nAngle=static_cast<const SdrRotateAllItem*>(pPoolItem)->GetValue(); | |||
745 | RotateMarkedObj(aAllSnapRect.Center(),nAngle); | |||
746 | } | |||
747 | if (rAttr.GetItemState(SDRATTR_HORZSHEARALL,true,&pPoolItem)==SfxItemState::SET) { | |||
748 | long nAngle=static_cast<const SdrHorzShearAllItem*>(pPoolItem)->GetValue(); | |||
749 | ShearMarkedObj(aAllSnapRect.Center(),nAngle); | |||
750 | } | |||
751 | if (rAttr.GetItemState(SDRATTR_VERTSHEARALL,true,&pPoolItem)==SfxItemState::SET) { | |||
752 | long nAngle=static_cast<const SdrVertShearAllItem*>(pPoolItem)->GetValue(); | |||
753 | ShearMarkedObj(aAllSnapRect.Center(),nAngle,true); | |||
754 | } | |||
755 | ||||
756 | const bool bUndo = IsUndoEnabled(); | |||
757 | ||||
758 | // TODO: check if WhichRange is necessary. | |||
759 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
760 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
761 | { | |||
762 | const SdrMark* pM=GetSdrMarkByIndex(nm); | |||
763 | SdrObject* pObj=pM->GetMarkedSdrObj(); | |||
764 | if( bUndo ) | |||
765 | AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); | |||
766 | ||||
767 | pObj->ApplyNotPersistAttr(rAttr); | |||
768 | } | |||
769 | } | |||
770 | ||||
771 | void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet& rAttr) const | |||
772 | { | |||
773 | // TODO: Take into account the origin and PvPos. | |||
774 | tools::Rectangle aAllSnapRect(GetMarkedObjRect()); // TODO: change this for PolyPt's and GluePt's!!! | |||
775 | long nAllSnapPosX=aAllSnapRect.Left(); | |||
776 | long nAllSnapPosY=aAllSnapRect.Top(); | |||
777 | long nAllSnapWdt=aAllSnapRect.GetWidth()-1; | |||
778 | long nAllSnapHgt=aAllSnapRect.GetHeight()-1; | |||
779 | // TODO: could go into CheckPossibilities | |||
780 | bool bMovProtect = false, bMovProtectDC = false; | |||
781 | bool bSizProtect = false, bSizProtectDC = false; | |||
782 | bool bPrintable = true, bPrintableDC = false; | |||
783 | bool bVisible = true, bVisibleDC = false; | |||
784 | SdrLayerID nLayerId(0); | |||
785 | bool bLayerDC=false; | |||
786 | long nSnapPosX=0; bool bSnapPosXDC=false; | |||
787 | long nSnapPosY=0; bool bSnapPosYDC=false; | |||
788 | long nSnapWdt=0; bool bSnapWdtDC=false; | |||
789 | long nSnapHgt=0; bool bSnapHgtDC=false; | |||
790 | long nLogicWdt=0; bool bLogicWdtDC=false,bLogicWdtDiff=false; | |||
791 | long nLogicHgt=0; bool bLogicHgtDC=false,bLogicHgtDiff=false; | |||
792 | long nRotAngle=0; bool bRotAngleDC=false; | |||
793 | long nShrAngle=0; bool bShrAngleDC=false; | |||
794 | tools::Rectangle aSnapRect; | |||
795 | tools::Rectangle aLogicRect; | |||
796 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
797 | for (size_t nm=0; nm<nMarkCount; ++nm) { | |||
798 | const SdrMark* pM=GetSdrMarkByIndex(nm); | |||
799 | const SdrObject* pObj=pM->GetMarkedSdrObj(); | |||
800 | if (nm==0) { | |||
801 | nLayerId=pObj->GetLayer(); | |||
802 | bMovProtect=pObj->IsMoveProtect(); | |||
803 | bSizProtect=pObj->IsResizeProtect(); | |||
804 | bPrintable =pObj->IsPrintable(); | |||
805 | bVisible = pObj->IsVisible(); | |||
806 | tools::Rectangle aSnapRect2(pObj->GetSnapRect()); | |||
807 | tools::Rectangle aLogicRect2(pObj->GetLogicRect()); | |||
808 | nSnapPosX=aSnapRect2.Left(); | |||
809 | nSnapPosY=aSnapRect2.Top(); | |||
810 | nSnapWdt=aSnapRect2.GetWidth()-1; | |||
811 | nSnapHgt=aSnapRect2.GetHeight()-1; | |||
812 | nLogicWdt=aLogicRect2.GetWidth()-1; | |||
813 | nLogicHgt=aLogicRect2.GetHeight()-1; | |||
814 | bLogicWdtDiff=nLogicWdt!=nSnapWdt; | |||
815 | bLogicHgtDiff=nLogicHgt!=nSnapHgt; | |||
816 | nRotAngle=pObj->GetRotateAngle(); | |||
817 | nShrAngle=pObj->GetShearAngle(); | |||
818 | } else { | |||
819 | if (!bLayerDC && nLayerId !=pObj->GetLayer()) bLayerDC = true; | |||
820 | if (!bMovProtectDC && bMovProtect!=pObj->IsMoveProtect()) bMovProtectDC = true; | |||
821 | if (!bSizProtectDC && bSizProtect!=pObj->IsResizeProtect()) bSizProtectDC = true; | |||
822 | if (!bPrintableDC && bPrintable !=pObj->IsPrintable()) bPrintableDC = true; | |||
823 | if (!bVisibleDC && bVisible !=pObj->IsVisible()) bVisibleDC=true; | |||
824 | if (!bRotAngleDC && nRotAngle !=pObj->GetRotateAngle()) bRotAngleDC=true; | |||
825 | if (!bShrAngleDC && nShrAngle !=pObj->GetShearAngle()) bShrAngleDC=true; | |||
826 | if (!bSnapWdtDC || !bSnapHgtDC || !bSnapPosXDC || !bSnapPosYDC || !bLogicWdtDiff || !bLogicHgtDiff) { | |||
827 | aSnapRect=pObj->GetSnapRect(); | |||
828 | if (nSnapPosX!=aSnapRect.Left()) bSnapPosXDC=true; | |||
829 | if (nSnapPosY!=aSnapRect.Top()) bSnapPosYDC=true; | |||
830 | if (nSnapWdt!=aSnapRect.GetWidth()-1) bSnapWdtDC=true; | |||
831 | if (nSnapHgt!=aSnapRect.GetHeight()-1) bSnapHgtDC=true; | |||
832 | } | |||
833 | if (!bLogicWdtDC || !bLogicHgtDC || !bLogicWdtDiff || !bLogicHgtDiff) { | |||
834 | aLogicRect=pObj->GetLogicRect(); | |||
835 | if (nLogicWdt!=aLogicRect.GetWidth()-1) bLogicWdtDC=true; | |||
836 | if (nLogicHgt!=aLogicRect.GetHeight()-1) bLogicHgtDC=true; | |||
837 | if (!bLogicWdtDiff && aSnapRect.GetWidth()!=aLogicRect.GetWidth()) bLogicWdtDiff=true; | |||
838 | if (!bLogicHgtDiff && aSnapRect.GetHeight()!=aLogicRect.GetHeight()) bLogicHgtDiff=true; | |||
839 | } | |||
840 | } | |||
841 | } | |||
842 | ||||
843 | if (bSnapPosXDC || nAllSnapPosX!=nSnapPosX) rAttr.Put(SdrAllPositionXItem(nAllSnapPosX)); | |||
844 | if (bSnapPosYDC || nAllSnapPosY!=nSnapPosY) rAttr.Put(SdrAllPositionYItem(nAllSnapPosY)); | |||
845 | if (bSnapWdtDC || nAllSnapWdt !=nSnapWdt ) rAttr.Put(SdrAllSizeWidthItem(nAllSnapWdt)); | |||
846 | if (bSnapHgtDC || nAllSnapHgt !=nSnapHgt ) rAttr.Put(SdrAllSizeHeightItem(nAllSnapHgt)); | |||
847 | ||||
848 | // items for pure transformations | |||
849 | rAttr.Put(SdrMoveXItem()); | |||
850 | rAttr.Put(SdrMoveYItem()); | |||
851 | rAttr.Put(SdrResizeXOneItem()); | |||
852 | rAttr.Put(SdrResizeYOneItem()); | |||
853 | rAttr.Put(SdrRotateOneItem()); | |||
854 | rAttr.Put(SdrHorzShearOneItem()); | |||
855 | rAttr.Put(SdrVertShearOneItem()); | |||
856 | ||||
857 | if (nMarkCount>1) { | |||
858 | rAttr.Put(SdrResizeXAllItem()); | |||
859 | rAttr.Put(SdrResizeYAllItem()); | |||
860 | rAttr.Put(SdrRotateAllItem()); | |||
861 | rAttr.Put(SdrHorzShearAllItem()); | |||
862 | rAttr.Put(SdrVertShearAllItem()); | |||
863 | } | |||
864 | ||||
865 | if(meDragMode == SdrDragMode::Rotate || meDragMode == SdrDragMode::Mirror) | |||
866 | { | |||
867 | rAttr.Put(SdrTransformRef1XItem(GetRef1().X())); | |||
868 | rAttr.Put(SdrTransformRef1YItem(GetRef1().Y())); | |||
869 | } | |||
870 | ||||
871 | if(meDragMode == SdrDragMode::Mirror) | |||
872 | { | |||
873 | rAttr.Put(SdrTransformRef2XItem(GetRef2().X())); | |||
874 | rAttr.Put(SdrTransformRef2YItem(GetRef2().Y())); | |||
875 | } | |||
876 | } | |||
877 | ||||
878 | SfxItemSet SdrEditView::GetAttrFromMarked(bool bOnlyHardAttr) const | |||
879 | { | |||
880 | SfxItemSet aSet(mpModel->GetItemPool()); | |||
881 | MergeAttrFromMarked(aSet,bOnlyHardAttr); | |||
882 | //the EE_FEATURE items should not be set with SetAttrToMarked (see error message there) | |||
883 | //so we do not set them here | |||
884 | // #i32448# | |||
885 | // Do not disable, but clear the items. | |||
886 | aSet.ClearItem(EE_FEATURE_TAB); | |||
887 | aSet.ClearItem(EE_FEATURE_LINEBR); | |||
888 | aSet.ClearItem(EE_FEATURE_NOTCONV); | |||
889 | aSet.ClearItem(EE_FEATURE_FIELD); | |||
890 | ||||
891 | return aSet; | |||
892 | } | |||
893 | ||||
894 | void SdrEditView::MergeAttrFromMarked(SfxItemSet& rAttr, bool bOnlyHardAttr) const | |||
895 | { | |||
896 | const size_t nMarkCount(GetMarkedObjectCount()); | |||
897 | ||||
898 | for(size_t a = 0; a < nMarkCount; ++a) | |||
899 | { | |||
900 | // #80277# merging was done wrong in the prev version | |||
901 | const SfxItemSet& rSet = GetMarkedObjectByIndex(a)->GetMergedItemSet(); | |||
902 | SfxWhichIter aIter(rSet); | |||
903 | sal_uInt16 nWhich(aIter.FirstWhich()); | |||
904 | ||||
905 | while(nWhich) | |||
906 | { | |||
907 | if(!bOnlyHardAttr) | |||
908 | { | |||
909 | if(SfxItemState::DONTCARE == rSet.GetItemState(nWhich, false)) | |||
910 | rAttr.InvalidateItem(nWhich); | |||
911 | else | |||
912 | rAttr.MergeValue(rSet.Get(nWhich), true); | |||
913 | } | |||
914 | else if(SfxItemState::SET == rSet.GetItemState(nWhich, false)) | |||
915 | { | |||
916 | const SfxPoolItem& rItem = rSet.Get(nWhich); | |||
917 | rAttr.MergeValue(rItem, true); | |||
918 | } | |||
919 | ||||
920 | if (comphelper::LibreOfficeKit::isActive()) | |||
921 | { | |||
922 | OUString sPayload; | |||
923 | switch(nWhich) | |||
924 | { | |||
925 | case XATTR_LINECOLOR: | |||
926 | { | |||
927 | const SfxPoolItem* pItem = rSet.GetItem(XATTR_LINECOLOR); | |||
928 | if (pItem) | |||
929 | { | |||
930 | Color aColor = static_cast<const XLineColorItem*>(pItem)->GetColorValue(); | |||
931 | sPayload = OUString::number(static_cast<sal_uInt32>(aColor)); | |||
932 | ||||
933 | sPayload = ".uno:XLineColor=" + sPayload; | |||
934 | } | |||
935 | break; | |||
936 | } | |||
937 | ||||
938 | case XATTR_FILLCOLOR: | |||
939 | { | |||
940 | const SfxPoolItem* pItem = rSet.GetItem(XATTR_FILLCOLOR); | |||
941 | if (pItem) | |||
942 | { | |||
943 | Color aColor = static_cast<const XFillColorItem*>(pItem)->GetColorValue(); | |||
944 | sPayload = OUString::number(static_cast<sal_uInt32>(aColor)); | |||
945 | ||||
946 | sPayload = ".uno:FillColor=" + sPayload; | |||
947 | } | |||
948 | break; | |||
949 | } | |||
950 | ||||
951 | case XATTR_FILLTRANSPARENCE: | |||
952 | { | |||
953 | const SfxPoolItem* pItem = rSet.GetItem(XATTR_FILLTRANSPARENCE); | |||
954 | if (pItem) | |||
955 | { | |||
956 | sal_uInt16 nTransparency = static_cast<const SfxUInt16Item*>(pItem)->GetValue(); | |||
957 | sPayload = OUString::number(nTransparency); | |||
958 | ||||
959 | sPayload = ".uno:FillTransparence=" + sPayload; | |||
960 | } | |||
961 | break; | |||
962 | } | |||
963 | ||||
964 | case XATTR_LINETRANSPARENCE: | |||
965 | { | |||
966 | const SfxPoolItem* pItem = rSet.GetItem(XATTR_LINETRANSPARENCE); | |||
967 | if (pItem) | |||
968 | { | |||
969 | sal_uInt16 nTransparency = static_cast<const SfxUInt16Item*>(pItem)->GetValue(); | |||
970 | sPayload = OUString::number(nTransparency); | |||
971 | ||||
972 | sPayload = ".uno:LineTransparence=" + sPayload; | |||
973 | } | |||
974 | break; | |||
975 | } | |||
976 | ||||
977 | case XATTR_LINEWIDTH: | |||
978 | { | |||
979 | const SfxPoolItem* pItem = rSet.GetItem(XATTR_LINEWIDTH); | |||
980 | if (pItem) | |||
981 | { | |||
982 | sal_uInt32 nWidth = static_cast<const XLineWidthItem*>(pItem)->GetValue(); | |||
983 | sPayload = OUString::number(nWidth); | |||
984 | ||||
985 | sPayload = ".uno:LineWidth=" + sPayload; | |||
986 | } | |||
987 | break; | |||
988 | } | |||
989 | ||||
990 | case SDRATTR_SHADOWTRANSPARENCE: | |||
991 | { | |||
992 | const SfxPoolItem* pItem = rSet.GetItem(SDRATTR_SHADOWTRANSPARENCE); | |||
993 | if (pItem) | |||
994 | { | |||
995 | sal_uInt16 nWidth = static_cast<const SfxUInt16Item*>(pItem)->GetValue(); | |||
996 | sPayload = OUString::number(nWidth); | |||
997 | ||||
998 | sPayload = ".uno:FillShadowTransparency=" + sPayload; | |||
999 | } | |||
1000 | break; | |||
1001 | } | |||
1002 | } | |||
1003 | ||||
1004 | if (!sPayload.isEmpty()) | |||
1005 | GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, | |||
1006 | OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11))).getStr()); | |||
1007 | } | |||
1008 | ||||
1009 | nWhich = aIter.NextWhich(); | |||
1010 | } | |||
1011 | } | |||
1012 | } | |||
1013 | ||||
1014 | std::vector<sal_uInt16> GetAllCharPropIds(const SfxItemSet& rSet) | |||
1015 | { | |||
1016 | std::vector<sal_uInt16> aCharWhichIds; | |||
1017 | { | |||
1018 | SfxItemIter aIter(rSet); | |||
1019 | for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem()) | |||
1020 | { | |||
1021 | if (!IsInvalidItem(pItem)) | |||
1022 | { | |||
1023 | sal_uInt16 nWhich = pItem->Which(); | |||
1024 | if (nWhich>=EE_CHAR_START && nWhich<=EE_CHAR_END) | |||
1025 | aCharWhichIds.push_back( nWhich ); | |||
1026 | } | |||
1027 | } | |||
1028 | } | |||
1029 | return aCharWhichIds; | |||
1030 | } | |||
1031 | ||||
1032 | void SdrEditView::SetAttrToMarked(const SfxItemSet& rAttr, bool bReplaceAll) | |||
1033 | { | |||
1034 | if (!AreObjectsMarked()) | |||
1035 | return; | |||
1036 | ||||
1037 | #ifdef DBG_UTIL | |||
1038 | { | |||
1039 | bool bHasEEFeatureItems=false; | |||
1040 | SfxItemIter aIter(rAttr); | |||
1041 | for (const SfxPoolItem* pItem = aIter.GetCurItem(); !bHasEEFeatureItems && pItem; | |||
1042 | pItem = aIter.NextItem()) | |||
1043 | { | |||
1044 | if (!IsInvalidItem(pItem)) { | |||
1045 | sal_uInt16 nW=pItem->Which(); | |||
1046 | if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END) bHasEEFeatureItems=true; | |||
1047 | } | |||
1048 | } | |||
1049 | if(bHasEEFeatureItems) | |||
1050 | { | |||
1051 | std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(nullptr, | |||
1052 | VclMessageType::Info, VclButtonsType::Ok, | |||
1053 | "SdrEditView::SetAttrToMarked(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents.")); | |||
1054 | xInfoBox->run(); | |||
1055 | } | |||
1056 | } | |||
1057 | #endif | |||
1058 | ||||
1059 | // #103836# if the user sets character attributes to the complete shape, | |||
1060 | // we want to remove all hard set character attributes with same | |||
1061 | // which ids from the text. We do that later but here we remember | |||
1062 | // all character attribute which id's that are set. | |||
1063 | std::vector<sal_uInt16> aCharWhichIds(GetAllCharPropIds(rAttr)); | |||
1064 | ||||
1065 | // To make Undo reconstruct text attributes correctly after Format.Standard | |||
1066 | bool bHasEEItems=SearchOutlinerItems(rAttr,bReplaceAll); | |||
1067 | ||||
1068 | // save additional geometry information when paragraph or character attributes | |||
1069 | // are changed and the geometrical shape of the text object might be changed | |||
1070 | bool bPossibleGeomChange(false); | |||
1071 | SfxWhichIter aIter(rAttr); | |||
1072 | sal_uInt16 nWhich = aIter.FirstWhich(); | |||
1073 | while(!bPossibleGeomChange
| |||
1074 | { | |||
1075 | SfxItemState eState = rAttr.GetItemState(nWhich); | |||
1076 | if(eState == SfxItemState::SET) | |||
1077 | { | |||
1078 | if((nWhich >= SDRATTR_TEXT_MINFRAMEHEIGHT && nWhich <= SDRATTR_TEXT_CONTOURFRAME) | |||
1079 | || nWhich == SDRATTR_3DOBJ_PERCENT_DIAGONAL | |||
1080 | || nWhich == SDRATTR_3DOBJ_BACKSCALE | |||
1081 | || nWhich == SDRATTR_3DOBJ_DEPTH | |||
1082 | || nWhich == SDRATTR_3DOBJ_END_ANGLE | |||
1083 | || nWhich == SDRATTR_3DSCENE_DISTANCE) | |||
1084 | { | |||
1085 | bPossibleGeomChange = true; | |||
1086 | } | |||
1087 | } | |||
1088 | nWhich = aIter.NextWhich(); | |||
1089 | } | |||
1090 | ||||
1091 | const bool bUndo = IsUndoEnabled(); | |||
1092 | if( bUndo ) | |||
1093 | { | |||
1094 | EndTextEditAllViews(); | |||
1095 | BegUndo(ImpGetDescriptionString(STR_EditSetAttributesreinterpret_cast<char const *>("STR_EditSetAttributes" "\004" u8"Apply attributes to %1"))); | |||
1096 | } | |||
1097 | ||||
1098 | const size_t nMarkCount(GetMarkedObjectCount()); | |||
1099 | std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters; | |||
1100 | ||||
1101 | // create ItemSet without SfxItemState::DONTCARE. Put() | |||
1102 | // uses its second parameter (bInvalidAsDefault) to | |||
1103 | // remove all such items to set them to default. | |||
1104 | SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges()); | |||
1105 | aAttr.Put(rAttr); | |||
1106 | ||||
1107 | // #i38135# | |||
1108 | bool bResetAnimationTimer(false); | |||
1109 | ||||
1110 | const bool bLineStartWidthExplicitChange(SfxItemState::SET | |||
1111 | == aAttr.GetItemState(XATTR_LINESTARTWIDTH)); | |||
1112 | const bool bLineEndWidthExplicitChange(SfxItemState::SET | |||
1113 | == aAttr.GetItemState(XATTR_LINEENDWIDTH)); | |||
1114 | // check if LineWidth is part of the change | |||
1115 | const bool bAdaptStartEndWidths(!(bLineStartWidthExplicitChange
| |||
1116 | && SfxItemState::SET == aAttr.GetItemState(XATTR_LINEWIDTH)); | |||
1117 | sal_Int32 nNewLineWidth(0); | |||
1118 | ||||
1119 | if(bAdaptStartEndWidths
| |||
1120 | { | |||
1121 | nNewLineWidth = aAttr.Get(XATTR_LINEWIDTH).GetValue(); | |||
1122 | } | |||
1123 | ||||
1124 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
1125 | { | |||
1126 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
1127 | SdrObject* pObj = pM->GetMarkedSdrObj(); | |||
1128 | ||||
1129 | if( bUndo ) | |||
1130 | { | |||
1131 | SdrEdgeObj* pEdgeObj = dynamic_cast< SdrEdgeObj* >( pObj ); | |||
1132 | if ( pEdgeObj ) | |||
1133 | bPossibleGeomChange = true; | |||
1134 | else | |||
1135 | AddUndoActions( CreateConnectorUndo( *pObj ) ); | |||
1136 | } | |||
1137 | ||||
1138 | // new geometry undo | |||
1139 | if(bPossibleGeomChange && bUndo) | |||
1140 | { | |||
1141 | // save position and size of object, too | |||
1142 | AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); | |||
1143 | } | |||
1144 | ||||
1145 | if( bUndo ) | |||
1146 | { | |||
1147 | // #i8508# | |||
1148 | // If this is a text object also rescue the OutlinerParaObject since | |||
1149 | // applying attributes to the object may change text layout when | |||
1150 | // multiple portions exist with multiple formats. If an OutlinerParaObject | |||
1151 | // really exists and needs to be rescued is evaluated in the undo | |||
1152 | // implementation itself. | |||
1153 | const bool bRescueText = dynamic_cast< SdrTextObj* >(pObj) != nullptr; | |||
1154 | ||||
1155 | // add attribute undo | |||
1156 | AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj,false,bHasEEItems || bPossibleGeomChange || bRescueText)); | |||
1157 | } | |||
1158 | ||||
1159 | // set up a scene updater if object is a 3d object | |||
1160 | if(dynamic_cast< E3dObject* >(pObj)) | |||
1161 | { | |||
1162 | aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj)); | |||
1163 | } | |||
1164 | ||||
1165 | sal_Int32 nOldLineWidth(0); | |||
1166 | if (bAdaptStartEndWidths) | |||
1167 | { | |||
1168 | nOldLineWidth = pObj->GetMergedItem(XATTR_LINEWIDTH).GetValue(); | |||
1169 | } | |||
1170 | ||||
1171 | // set attributes at object | |||
1172 | pObj->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll); | |||
1173 | ||||
1174 | if(bAdaptStartEndWidths) | |||
1175 | { | |||
1176 | const SfxItemSet& rSet = pObj->GetMergedItemSet(); | |||
1177 | ||||
1178 | if(nOldLineWidth != nNewLineWidth) | |||
1179 | { | |||
1180 | if(SfxItemState::DONTCARE != rSet.GetItemState(XATTR_LINESTARTWIDTH)) | |||
1181 | { | |||
1182 | const sal_Int32 nValAct(rSet.Get(XATTR_LINESTARTWIDTH).GetValue()); | |||
1183 | const sal_Int32 nValNewStart(std::max(sal_Int32(0), nValAct + (((nNewLineWidth - nOldLineWidth) * 15) / 10))); | |||
1184 | ||||
1185 | pObj->SetMergedItem(XLineStartWidthItem(nValNewStart)); | |||
1186 | } | |||
1187 | ||||
1188 | if(SfxItemState::DONTCARE != rSet.GetItemState(XATTR_LINEENDWIDTH)) | |||
1189 | { | |||
1190 | const sal_Int32 nValAct(rSet.Get(XATTR_LINEENDWIDTH).GetValue()); | |||
1191 | const sal_Int32 nValNewEnd(std::max(sal_Int32(0), nValAct + (((nNewLineWidth - nOldLineWidth) * 15) / 10))); | |||
1192 | ||||
1193 | pObj->SetMergedItem(XLineEndWidthItem(nValNewEnd)); | |||
1194 | } | |||
1195 | } | |||
1196 | } | |||
1197 | ||||
1198 | if(dynamic_cast<const SdrTextObj*>( pObj) != nullptr) | |||
1199 | { | |||
1200 | SdrTextObj* pTextObj = static_cast<SdrTextObj*>(pObj); | |||
1201 | ||||
1202 | if(!aCharWhichIds.empty()) | |||
1203 | { | |||
1204 | tools::Rectangle aOldBoundRect = pTextObj->GetLastBoundRect(); | |||
1205 | ||||
1206 | // #110094#-14 pTextObj->SendRepaintBroadcast(pTextObj->GetBoundRect()); | |||
1207 | pTextObj->RemoveOutlinerCharacterAttribs( aCharWhichIds ); | |||
1208 | ||||
1209 | // object has changed, should be called from | |||
1210 | // RemoveOutlinerCharacterAttribs. This will change when the text | |||
1211 | // object implementation changes. | |||
1212 | pTextObj->SetChanged(); | |||
1213 | ||||
1214 | pTextObj->BroadcastObjectChange(); | |||
1215 | pTextObj->SendUserCall(SdrUserCallType::ChangeAttr, aOldBoundRect); | |||
1216 | } | |||
1217 | } | |||
1218 | ||||
1219 | // #i38495# | |||
1220 | if(!bResetAnimationTimer) | |||
1221 | { | |||
1222 | if(pObj->GetViewContact().isAnimatedInAnyViewObjectContact()) | |||
1223 | { | |||
1224 | bResetAnimationTimer = true; | |||
1225 | } | |||
1226 | } | |||
1227 | } | |||
1228 | ||||
1229 | // fire scene updaters | |||
1230 | while(!aUpdaters.empty()) | |||
1231 | { | |||
1232 | delete aUpdaters.back(); | |||
1233 | aUpdaters.pop_back(); | |||
1234 | } | |||
1235 | ||||
1236 | // #i38135# | |||
1237 | if(bResetAnimationTimer
| |||
1238 | { | |||
1239 | SetAnimationTimer(0); | |||
1240 | } | |||
1241 | ||||
1242 | // better check before what to do: | |||
1243 | // pObj->SetAttr() or SetNotPersistAttr() | |||
1244 | // TODO: missing implementation! | |||
1245 | SetNotPersistAttrToMarked(rAttr); | |||
1246 | ||||
1247 | if( bUndo ) | |||
1248 | EndUndo(); | |||
1249 | } | |||
1250 | ||||
1251 | SfxStyleSheet* SdrEditView::GetStyleSheetFromMarked() const | |||
1252 | { | |||
1253 | SfxStyleSheet* pRet=nullptr; | |||
1254 | bool b1st=true; | |||
1255 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
1256 | for (size_t nm=0; nm<nMarkCount; ++nm) { | |||
1257 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
1258 | SfxStyleSheet* pSS=pM->GetMarkedSdrObj()->GetStyleSheet(); | |||
1259 | if (b1st) pRet=pSS; | |||
1260 | else if (pRet!=pSS) return nullptr; // different stylesheets | |||
1261 | b1st=false; | |||
1262 | } | |||
1263 | return pRet; | |||
1264 | } | |||
1265 | ||||
1266 | void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr) | |||
1267 | { | |||
1268 | if (!AreObjectsMarked()) | |||
1269 | return; | |||
1270 | ||||
1271 | const bool bUndo = IsUndoEnabled(); | |||
1272 | ||||
1273 | if( bUndo ) | |||
1274 | { | |||
1275 | EndTextEditAllViews(); | |||
1276 | OUString aStr; | |||
1277 | if (pStyleSheet!=nullptr) | |||
1278 | aStr = ImpGetDescriptionString(STR_EditSetStylesheetreinterpret_cast<char const *>("STR_EditSetStylesheet" "\004" u8"Apply Styles to %1")); | |||
1279 | else | |||
1280 | aStr = ImpGetDescriptionString(STR_EditDelStylesheetreinterpret_cast<char const *>("STR_EditDelStylesheet" "\004" u8"Remove Style from %1")); | |||
1281 | BegUndo(aStr); | |||
1282 | } | |||
1283 | ||||
1284 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
1285 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
1286 | { | |||
1287 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
1288 | if( bUndo ) | |||
1289 | { | |||
1290 | AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pM->GetMarkedSdrObj())); | |||
1291 | AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pM->GetMarkedSdrObj(),true,true)); | |||
1292 | } | |||
1293 | pM->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); | |||
1294 | } | |||
1295 | ||||
1296 | if( bUndo ) | |||
1297 | EndUndo(); | |||
1298 | } | |||
1299 | ||||
1300 | ||||
1301 | void SdrEditView::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const | |||
1302 | { | |||
1303 | if(GetMarkedObjectCount()) | |||
1304 | { | |||
1305 | rTargetSet.Put(GetAttrFromMarked(bOnlyHardAttr), false); | |||
1306 | } | |||
1307 | else | |||
1308 | { | |||
1309 | SdrMarkView::GetAttributes(rTargetSet, bOnlyHardAttr); | |||
1310 | } | |||
1311 | } | |||
1312 | ||||
1313 | void SdrEditView::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll) | |||
1314 | { | |||
1315 | if (GetMarkedObjectCount()!=0) { | |||
1316 | SetAttrToMarked(rSet,bReplaceAll); | |||
1317 | } else { | |||
1318 | SdrMarkView::SetAttributes(rSet,bReplaceAll); | |||
1319 | } | |||
1320 | } | |||
1321 | ||||
1322 | SfxStyleSheet* SdrEditView::GetStyleSheet() const | |||
1323 | { | |||
1324 | if (GetMarkedObjectCount()!=0) { | |||
1325 | return GetStyleSheetFromMarked(); | |||
1326 | } else { | |||
1327 | return SdrMarkView::GetStyleSheet(); | |||
1328 | } | |||
1329 | } | |||
1330 | ||||
1331 | void SdrEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr) | |||
1332 | { | |||
1333 | if (GetMarkedObjectCount()!=0) { | |||
1334 | SetStyleSheetToMarked(pStyleSheet,bDontRemoveHardAttr); | |||
1335 | } else { | |||
1336 | SdrMarkView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr); | |||
1337 | } | |||
1338 | } | |||
1339 | ||||
1340 | ||||
1341 | SfxItemSet SdrEditView::GetGeoAttrFromMarked() const | |||
1342 | { | |||
1343 | SfxItemSet aRetSet( | |||
1344 | mpModel->GetItemPool(), | |||
1345 | svl::Items< // SID_ATTR_TRANSFORM_... from s:svxids.hrc | |||
1346 | SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS, | |||
1347 | SID_ATTR_TRANSFORM_POS_XTypedWhichId<SfxInt32Item>( 10000 + 88 ), SID_ATTR_TRANSFORM_ANGLETypedWhichId<SfxInt32Item>( 10000 + 95 ), | |||
1348 | SID_ATTR_TRANSFORM_PROTECT_POSTypedWhichId<SfxBoolItem>( 10000 + 236 ), SID_ATTR_TRANSFORM_AUTOHEIGHT( 10000 + 311 )>{}); | |||
1349 | ||||
1350 | if (AreObjectsMarked()) | |||
1351 | { | |||
1352 | SfxItemSet aMarkAttr(GetAttrFromMarked(false)); // because of AutoGrowHeight and corner radius | |||
1353 | tools::Rectangle aRect(GetMarkedObjRect()); | |||
1354 | ||||
1355 | if(GetSdrPageView()) | |||
1356 | { | |||
1357 | GetSdrPageView()->LogicToPagePos(aRect); | |||
1358 | } | |||
1359 | ||||
1360 | // position | |||
1361 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_XTypedWhichId<SfxInt32Item>( 10000 + 88 ),aRect.Left())); | |||
1362 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_YTypedWhichId<SfxInt32Item>( 10000 + 89 ),aRect.Top())); | |||
1363 | ||||
1364 | // size | |||
1365 | long nResizeRefX=aRect.Left(); | |||
1366 | long nResizeRefY=aRect.Top(); | |||
1367 | if (meDragMode==SdrDragMode::Rotate) { // use rotation axis as a reference for resizing, too | |||
1368 | nResizeRefX=maRef1.X(); | |||
1369 | nResizeRefY=maRef1.Y(); | |||
1370 | } | |||
1371 | aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_WIDTHTypedWhichId<SfxUInt32Item>( 10000 + 90 ),aRect.Right()-aRect.Left())); | |||
1372 | aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_HEIGHTTypedWhichId<SfxUInt32Item>( 10000 + 91 ),aRect.Bottom()-aRect.Top())); | |||
1373 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_X( 10000 + 308 ),nResizeRefX)); | |||
1374 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_Y( 10000 + 309 ),nResizeRefY)); | |||
1375 | ||||
1376 | Point aRotateAxe(maRef1); | |||
1377 | ||||
1378 | if(GetSdrPageView()) | |||
1379 | { | |||
1380 | GetSdrPageView()->LogicToPagePos(aRotateAxe); | |||
1381 | } | |||
1382 | ||||
1383 | // rotation | |||
1384 | long nRotateRefX=aRect.Center().X(); | |||
1385 | long nRotateRefY=aRect.Center().Y(); | |||
1386 | if (meDragMode==SdrDragMode::Rotate) { | |||
1387 | nRotateRefX=aRotateAxe.X(); | |||
1388 | nRotateRefY=aRotateAxe.Y(); | |||
1389 | } | |||
1390 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLETypedWhichId<SfxInt32Item>( 10000 + 95 ),GetMarkedObjRotate())); | |||
1391 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_XTypedWhichId<SfxInt32Item>( 10000 + 93 ),nRotateRefX)); | |||
1392 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_YTypedWhichId<SfxInt32Item>( 10000 + 94 ),nRotateRefY)); | |||
1393 | ||||
1394 | // shearing | |||
1395 | long nShearRefX=aRect.Left(); | |||
1396 | long nShearRefY=aRect.Bottom(); | |||
1397 | if (meDragMode==SdrDragMode::Rotate) { // use rotation axis as a reference for shearing, too | |||
1398 | nShearRefX=aRotateAxe.X(); | |||
1399 | nShearRefY=aRotateAxe.Y(); | |||
1400 | } | |||
1401 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR( 10000 + 304 ),GetMarkedObjShear())); | |||
1402 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X( 10000 + 305 ),nShearRefX)); | |||
1403 | aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y( 10000 + 306 ),nShearRefY)); | |||
1404 | ||||
1405 | // check every object whether it is protected | |||
1406 | const SdrMarkList& rMarkList=GetMarkedObjectList(); | |||
1407 | const size_t nMarkCount=rMarkList.GetMarkCount(); | |||
1408 | SdrObject* pObj=rMarkList.GetMark(0)->GetMarkedSdrObj(); | |||
1409 | bool bPosProt=pObj->IsMoveProtect(); | |||
1410 | bool bSizProt=pObj->IsResizeProtect(); | |||
1411 | bool bPosProtDontCare=false; | |||
1412 | bool bSizProtDontCare=false; | |||
1413 | for (size_t i=1; i<nMarkCount && (!bPosProtDontCare || !bSizProtDontCare); ++i) | |||
1414 | { | |||
1415 | pObj=rMarkList.GetMark(i)->GetMarkedSdrObj(); | |||
1416 | if (bPosProt!=pObj->IsMoveProtect()) bPosProtDontCare=true; | |||
1417 | if (bSizProt!=pObj->IsResizeProtect()) bSizProtDontCare=true; | |||
1418 | } | |||
1419 | ||||
1420 | // InvalidateItem sets item to DONT_CARE | |||
1421 | if (bPosProtDontCare) { | |||
1422 | aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_POSTypedWhichId<SfxBoolItem>( 10000 + 236 )); | |||
1423 | } else { | |||
1424 | aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_POSTypedWhichId<SfxBoolItem>( 10000 + 236 ),bPosProt)); | |||
1425 | } | |||
1426 | if (bSizProtDontCare) { | |||
1427 | aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_SIZETypedWhichId<SfxBoolItem>( 10000 + 237 )); | |||
1428 | } else { | |||
1429 | aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_SIZETypedWhichId<SfxBoolItem>( 10000 + 237 ),bSizProt)); | |||
1430 | } | |||
1431 | ||||
1432 | SfxItemState eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWWIDTH); | |||
1433 | bool bAutoGrow=aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWWIDTH).GetValue(); | |||
1434 | if (eState==SfxItemState::DONTCARE) { | |||
1435 | aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOWIDTH( 10000 + 310 )); | |||
1436 | } else if (eState==SfxItemState::SET) { | |||
1437 | aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOWIDTH( 10000 + 310 ),bAutoGrow)); | |||
1438 | } | |||
1439 | ||||
1440 | eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWHEIGHT); | |||
1441 | bAutoGrow=aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWHEIGHT).GetValue(); | |||
1442 | if (eState==SfxItemState::DONTCARE) { | |||
1443 | aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOHEIGHT( 10000 + 311 )); | |||
1444 | } else if (eState==SfxItemState::SET) { | |||
1445 | aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOHEIGHT( 10000 + 311 ),bAutoGrow)); | |||
1446 | } | |||
1447 | ||||
1448 | eState=aMarkAttr.GetItemState(SDRATTR_ECKENRADIUS); | |||
1449 | long nRadius=aMarkAttr.Get(SDRATTR_ECKENRADIUS).GetValue(); | |||
1450 | if (eState==SfxItemState::DONTCARE) { | |||
1451 | aRetSet.InvalidateItem(SDRATTR_ECKENRADIUS); | |||
1452 | } else if (eState==SfxItemState::SET) { | |||
1453 | aRetSet.Put(makeSdrEckenradiusItem(nRadius)); | |||
1454 | } | |||
1455 | ||||
1456 | basegfx::B2DHomMatrix aTransformation; | |||
1457 | ||||
1458 | if(nMarkCount > 1) | |||
1459 | { | |||
1460 | // multiple objects, range is collected in aRect | |||
1461 | aTransformation = basegfx::utils::createScaleTranslateB2DHomMatrix( | |||
1462 | aRect.Left(), aRect.Top(), | |||
1463 | aRect.getWidth(), aRect.getHeight()); | |||
1464 | } | |||
1465 | else | |||
1466 | { | |||
1467 | // single object, get homogen transformation | |||
1468 | basegfx::B2DPolyPolygon aPolyPolygon; | |||
1469 | ||||
1470 | pObj->TRGetBaseGeometry(aTransformation, aPolyPolygon); | |||
1471 | } | |||
1472 | ||||
1473 | if(aTransformation.isIdentity()) | |||
1474 | { | |||
1475 | aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_MATRIX( 10000 + 1131 )); | |||
1476 | } | |||
1477 | else | |||
1478 | { | |||
1479 | css::geometry::AffineMatrix2D aAffineMatrix2D; | |||
1480 | Point aPageOffset(0, 0); | |||
1481 | ||||
1482 | if(GetSdrPageView()) | |||
1483 | { | |||
1484 | aPageOffset = GetSdrPageView()->GetPageOrigin(); | |||
1485 | } | |||
1486 | ||||
1487 | aAffineMatrix2D.m00 = aTransformation.get(0, 0); | |||
1488 | aAffineMatrix2D.m01 = aTransformation.get(0, 1); | |||
1489 | aAffineMatrix2D.m02 = aTransformation.get(0, 2) - aPageOffset.X(); | |||
1490 | aAffineMatrix2D.m10 = aTransformation.get(1, 0); | |||
1491 | aAffineMatrix2D.m11 = aTransformation.get(1, 1); | |||
1492 | aAffineMatrix2D.m12 = aTransformation.get(1, 2) - aPageOffset.Y(); | |||
1493 | ||||
1494 | aRetSet.Put(AffineMatrixItem(&aAffineMatrix2D)); | |||
1495 | } | |||
1496 | } | |||
1497 | ||||
1498 | return aRetSet; | |||
1499 | } | |||
1500 | ||||
1501 | static Point ImpGetPoint(const tools::Rectangle& rRect, RectPoint eRP) | |||
1502 | { | |||
1503 | switch(eRP) { | |||
1504 | case RectPoint::LT: return rRect.TopLeft(); | |||
1505 | case RectPoint::MT: return rRect.TopCenter(); | |||
1506 | case RectPoint::RT: return rRect.TopRight(); | |||
1507 | case RectPoint::LM: return rRect.LeftCenter(); | |||
1508 | case RectPoint::MM: return rRect.Center(); | |||
1509 | case RectPoint::RM: return rRect.RightCenter(); | |||
1510 | case RectPoint::LB: return rRect.BottomLeft(); | |||
1511 | case RectPoint::MB: return rRect.BottomCenter(); | |||
1512 | case RectPoint::RB: return rRect.BottomRight(); | |||
1513 | } | |||
1514 | return Point(); // Should not happen! | |||
1515 | } | |||
1516 | ||||
1517 | void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr) | |||
1518 | { | |||
1519 | const bool bTiledRendering = comphelper::LibreOfficeKit::isActive(); | |||
1520 | ||||
1521 | tools::Rectangle aRect(GetMarkedObjRect()); | |||
1522 | ||||
1523 | if(GetSdrPageView()) | |||
| ||||
1524 | { | |||
1525 | GetSdrPageView()->LogicToPagePos(aRect); | |||
1526 | } | |||
1527 | ||||
1528 | long nOldRotateAngle=GetMarkedObjRotate(); | |||
1529 | long nOldShearAngle=GetMarkedObjShear(); | |||
1530 | const SdrMarkList& rMarkList=GetMarkedObjectList(); | |||
1531 | const size_t nMarkCount=rMarkList.GetMarkCount(); | |||
1532 | SdrObject* pObj=nullptr; | |||
1533 | ||||
1534 | RectPoint eSizePoint=RectPoint::MM; | |||
1535 | long nPosDX=0; | |||
1536 | long nPosDY=0; | |||
1537 | long nSizX=0; | |||
1538 | long nSizY=0; | |||
1539 | long nRotateAngle=0; | |||
1540 | ||||
1541 | bool bModeIsRotate(meDragMode == SdrDragMode::Rotate); | |||
1542 | long nRotateX(0); | |||
1543 | long nRotateY(0); | |||
1544 | long nOldRotateX(0); | |||
1545 | long nOldRotateY(0); | |||
1546 | if(bModeIsRotate
| |||
1547 | { | |||
1548 | Point aRotateAxe(maRef1); | |||
1549 | ||||
1550 | if(GetSdrPageView()) | |||
1551 | { | |||
1552 | GetSdrPageView()->LogicToPagePos(aRotateAxe); | |||
1553 | } | |||
1554 | ||||
1555 | nRotateX = nOldRotateX = aRotateAxe.X(); | |||
1556 | nRotateY = nOldRotateY = aRotateAxe.Y(); | |||
1557 | } | |||
1558 | ||||
1559 | long nShearAngle=0; | |||
1560 | long nShearX=0; | |||
1561 | long nShearY=0; | |||
1562 | bool bShearVert=false; | |||
1563 | ||||
1564 | bool bChgPos=false; | |||
1565 | bool bChgSiz=false; | |||
1566 | bool bChgWdh=false; | |||
1567 | bool bChgHgt=false; | |||
1568 | bool bRotate=false; | |||
1569 | bool bShear =false; | |||
1570 | ||||
1571 | bool bSetAttr=false; | |||
1572 | SfxItemSet aSetAttr(mpModel->GetItemPool()); | |||
1573 | ||||
1574 | const SfxPoolItem* pPoolItem=nullptr; | |||
1575 | ||||
1576 | // position | |||
1577 | if (SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_XTypedWhichId<SfxInt32Item>( 10000 + 88 ),true,&pPoolItem)) { | |||
1578 | nPosDX=static_cast<const SfxInt32Item*>(pPoolItem)->GetValue() - aRect.Left(); | |||
1579 | bChgPos=true; | |||
1580 | } | |||
1581 | if (SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_YTypedWhichId<SfxInt32Item>( 10000 + 89 ),true,&pPoolItem)){ | |||
1582 | nPosDY=static_cast<const SfxInt32Item*>(pPoolItem)->GetValue() - aRect.Top(); | |||
1583 | bChgPos=true; | |||
1584 | } | |||
1585 | // size | |||
1586 | if (SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_WIDTHTypedWhichId<SfxUInt32Item>( 10000 + 90 ),true,&pPoolItem)) { | |||
1587 | nSizX=static_cast<const SfxUInt32Item*>(pPoolItem)->GetValue(); | |||
1588 | bChgSiz=true; | |||
1589 | bChgWdh=true; | |||
1590 | } | |||
1591 | if (SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_HEIGHTTypedWhichId<SfxUInt32Item>( 10000 + 91 ),true,&pPoolItem)) { | |||
1592 | nSizY=static_cast<const SfxUInt32Item*>(pPoolItem)->GetValue(); | |||
1593 | bChgSiz=true; | |||
1594 | bChgHgt=true; | |||
1595 | } | |||
1596 | if (bChgSiz
| |||
1597 | if (bTiledRendering && SfxItemState::SET != rAttr.GetItemState(SID_ATTR_TRANSFORM_SIZE_POINTTypedWhichId<SfxUInt16Item>( 10000 + 92 ), true, &pPoolItem)) | |||
1598 | eSizePoint = RectPoint::LT; | |||
1599 | else | |||
1600 | eSizePoint = static_cast<RectPoint>(rAttr.Get(SID_ATTR_TRANSFORM_SIZE_POINTTypedWhichId<SfxUInt16Item>( 10000 + 92 )).GetValue()); | |||
1601 | } | |||
1602 | ||||
1603 | // rotation | |||
1604 | if (SfxItemState::SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_DELTA_ANGLETypedWhichId<SfxInt32Item>( 10000 + 96 ), true, &pPoolItem)) { | |||
1605 | nRotateAngle = static_cast<const SfxInt32Item*>(pPoolItem)->GetValue(); | |||
1606 | bRotate = (nRotateAngle != 0); | |||
1607 | } | |||
1608 | ||||
1609 | // rotation | |||
1610 | if (SfxItemState::SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_ANGLETypedWhichId<SfxInt32Item>( 10000 + 95 ), true, &pPoolItem)) { | |||
1611 | nRotateAngle = static_cast<const SfxInt32Item*>(pPoolItem)->GetValue() - nOldRotateAngle; | |||
1612 | bRotate = (nRotateAngle != 0); | |||
1613 | } | |||
1614 | ||||
1615 | // position rotation point x | |||
1616 | if(bRotate
| |||
1617 | nRotateX = rAttr.Get(SID_ATTR_TRANSFORM_ROT_XTypedWhichId<SfxInt32Item>( 10000 + 93 )).GetValue(); | |||
1618 | ||||
1619 | // position rotation point y | |||
1620 | if(bRotate
| |||
1621 | nRotateY = rAttr.Get(SID_ATTR_TRANSFORM_ROT_YTypedWhichId<SfxInt32Item>( 10000 + 94 )).GetValue(); | |||
1622 | ||||
1623 | // shearing | |||
1624 | if (SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_SHEAR( 10000 + 304 ),true,&pPoolItem)) { | |||
1625 | long nNewShearAngle=static_cast<const SfxInt32Item*>(pPoolItem)->GetValue(); | |||
1626 | if (nNewShearAngle>SDRMAXSHEAR8900) nNewShearAngle=SDRMAXSHEAR8900; | |||
1627 | if (nNewShearAngle<-SDRMAXSHEAR8900) nNewShearAngle=-SDRMAXSHEAR8900; | |||
1628 | if (nNewShearAngle!=nOldShearAngle) { | |||
1629 | bShearVert=static_cast<const SfxBoolItem&>(rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL( 10000 + 307 ))).GetValue(); | |||
1630 | if (bShearVert) { | |||
1631 | nShearAngle=nNewShearAngle; | |||
1632 | } else { | |||
1633 | if (nNewShearAngle!=0 && nOldShearAngle!=0) { | |||
1634 | // bug fix | |||
1635 | double nOld = tan(static_cast<double>(nOldShearAngle) * F_PI18000(3.14159265358979323846/18000.0)); | |||
1636 | double nNew = tan(static_cast<double>(nNewShearAngle) * F_PI18000(3.14159265358979323846/18000.0)); | |||
1637 | nNew-=nOld; | |||
1638 | nNew = atan(nNew) / F_PI18000(3.14159265358979323846/18000.0); | |||
1639 | nShearAngle=FRound(nNew); | |||
1640 | } else { | |||
1641 | nShearAngle=nNewShearAngle-nOldShearAngle; | |||
1642 | } | |||
1643 | } | |||
1644 | bShear=nShearAngle!=0; | |||
1645 | if (bShear) { | |||
1646 | nShearX=static_cast<const SfxInt32Item&>(rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_X( 10000 + 305 ))).GetValue(); | |||
1647 | nShearY=static_cast<const SfxInt32Item&>(rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_Y( 10000 + 306 ))).GetValue(); | |||
1648 | } | |||
1649 | } | |||
1650 | } | |||
1651 | ||||
1652 | // AutoGrow | |||
1653 | if (SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOWIDTH( 10000 + 310 ),true,&pPoolItem)) { | |||
1654 | bool bAutoGrow=static_cast<const SfxBoolItem*>(pPoolItem)->GetValue(); | |||
1655 | aSetAttr.Put(makeSdrTextAutoGrowWidthItem(bAutoGrow)); | |||
1656 | bSetAttr=true; | |||
1657 | } | |||
1658 | ||||
1659 | if (SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOHEIGHT( 10000 + 311 ),true,&pPoolItem)) { | |||
1660 | bool bAutoGrow=static_cast<const SfxBoolItem*>(pPoolItem)->GetValue(); | |||
1661 | aSetAttr.Put(makeSdrTextAutoGrowHeightItem(bAutoGrow)); | |||
1662 | bSetAttr=true; | |||
1663 | } | |||
1664 | ||||
1665 | // corner radius | |||
1666 | if (m_bEdgeRadiusAllowed && SfxItemState::SET==rAttr.GetItemState(SDRATTR_ECKENRADIUS,true,&pPoolItem)) { | |||
1667 | long nRadius=static_cast<const SdrMetricItem*>(pPoolItem)->GetValue(); | |||
1668 | aSetAttr.Put(makeSdrEckenradiusItem(nRadius)); | |||
1669 | bSetAttr=true; | |||
1670 | } | |||
1671 | ||||
1672 | ForcePossibilities(); | |||
1673 | ||||
1674 | BegUndo(SvxResId(STR_EditTransformreinterpret_cast<char const *>("STR_EditTransform" "\004" u8"Transform %1")),GetDescriptionOfMarkedObjects()); | |||
1675 | ||||
1676 | if (bSetAttr
| |||
1677 | SetAttrToMarked(aSetAttr,false); | |||
1678 | } | |||
1679 | ||||
1680 | // change size and height | |||
1681 | if (bChgSiz && (m_bResizeFreeAllowed || m_bResizePropAllowed)) { | |||
1682 | Fraction aWdt(nSizX,aRect.Right()-aRect.Left()); | |||
1683 | Fraction aHgt(nSizY,aRect.Bottom()-aRect.Top()); | |||
1684 | Point aRef(ImpGetPoint(aRect,eSizePoint)); | |||
1685 | ||||
1686 | if(GetSdrPageView()) | |||
1687 | { | |||
1688 | GetSdrPageView()->PagePosToLogic(aRef); | |||
1689 | } | |||
1690 | ||||
1691 | ResizeMultMarkedObj(aRef, aWdt, aHgt, bChgWdh, bChgHgt); | |||
1692 | } | |||
1693 | ||||
1694 | // rotate | |||
1695 | if (bRotate && (m_bRotateFreeAllowed || m_bRotate90Allowed)) { | |||
1696 | Point aRef(nRotateX,nRotateY); | |||
1697 | ||||
1698 | if(GetSdrPageView()) | |||
1699 | { | |||
1700 | GetSdrPageView()->PagePosToLogic(aRef); | |||
1701 | } | |||
1702 | ||||
1703 | RotateMarkedObj(aRef,nRotateAngle); | |||
1704 | } | |||
1705 | ||||
1706 | // set rotation point position | |||
1707 | if(bModeIsRotate && (nRotateX != nOldRotateX || nRotateY != nOldRotateY)) | |||
1708 | { | |||
1709 | Point aNewRef1(nRotateX, nRotateY); | |||
1710 | ||||
1711 | if(GetSdrPageView()) | |||
1712 | { | |||
1713 | GetSdrPageView()->PagePosToLogic(aNewRef1); | |||
1714 | } | |||
1715 | ||||
1716 | SetRef1(aNewRef1); | |||
1717 | } | |||
1718 | ||||
1719 | // shear | |||
1720 | if (bShear && m_bShearAllowed) { | |||
1721 | Point aRef(nShearX,nShearY); | |||
1722 | ||||
1723 | if(GetSdrPageView()) | |||
1724 | { | |||
1725 | GetSdrPageView()->PagePosToLogic(aRef); | |||
1726 | } | |||
1727 | ||||
1728 | ShearMarkedObj(aRef,nShearAngle,bShearVert); | |||
1729 | ||||
1730 | // #i74358# | |||
1731 | // ShearMarkedObj creates a linear combination of the existing transformation and | |||
1732 | // the new shear to apply. If the object is already transformed (e.g. rotated) the | |||
1733 | // linear combination will not decompose to the same start values again, but to a | |||
1734 | // new combination. Thus it makes no sense to check if the wanted shear is reached | |||
1735 | // or not. Taking out. | |||
1736 | } | |||
1737 | ||||
1738 | // change position | |||
1739 | if (bChgPos && m_bMoveAllowed) { | |||
1740 | MoveMarkedObj(Size(nPosDX,nPosDY)); | |||
1741 | } | |||
1742 | ||||
1743 | // protect position | |||
1744 | if(SfxItemState::SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_POSTypedWhichId<SfxBoolItem>( 10000 + 236 ), true, &pPoolItem)) | |||
1745 | { | |||
1746 | const bool bProtPos(static_cast<const SfxBoolItem*>(pPoolItem)->GetValue()); | |||
1747 | bool bChanged(false); | |||
1748 | ||||
1749 | for(size_t i = 0; i < nMarkCount; ++i) | |||
1750 | { | |||
1751 | pObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); | |||
1752 | ||||
1753 | if(pObj->IsMoveProtect() != bProtPos) | |||
1754 | { | |||
1755 | bChanged = true; | |||
1756 | pObj->SetMoveProtect(bProtPos); | |||
1757 | ||||
1758 | if(bProtPos) | |||
1759 | { | |||
1760 | pObj->SetResizeProtect(true); | |||
1761 | } | |||
1762 | } | |||
1763 | } | |||
1764 | ||||
1765 | if(bChanged) | |||
1766 | { | |||
1767 | m_bMoveProtect = bProtPos; | |||
1768 | ||||
1769 | if(bProtPos) | |||
1770 | { | |||
1771 | m_bResizeProtect = true; | |||
1772 | } | |||
1773 | ||||
1774 | // #i77187# there is no simple method to get the toolbars updated | |||
1775 | // in the application. The App is listening to selection change and i | |||
1776 | // will use it here (even if not true). It's acceptable since changing | |||
1777 | // this model data is pretty rare and only possible using the F4 dialog | |||
1778 | MarkListHasChanged(); | |||
1779 | } | |||
1780 | } | |||
1781 | ||||
1782 | if(!m_bMoveProtect) | |||
1783 | { | |||
1784 | // protect size | |||
1785 | if(SfxItemState::SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_SIZETypedWhichId<SfxBoolItem>( 10000 + 237 ), true, &pPoolItem)) | |||
1786 | { | |||
1787 | const bool bProtSize(static_cast<const SfxBoolItem*>(pPoolItem)->GetValue()); | |||
1788 | bool bChanged(false); | |||
1789 | ||||
1790 | for(size_t i = 0; i < nMarkCount; ++i) | |||
1791 | { | |||
1792 | pObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); | |||
1793 | ||||
1794 | if(pObj->IsResizeProtect() != bProtSize) | |||
1795 | { | |||
1796 | bChanged = true; | |||
1797 | pObj->SetResizeProtect(bProtSize); | |||
1798 | } | |||
1799 | } | |||
1800 | ||||
1801 | if(bChanged) | |||
1802 | { | |||
1803 | m_bResizeProtect = bProtSize; | |||
1804 | ||||
1805 | // #i77187# see above | |||
1806 | MarkListHasChanged(); | |||
1807 | } | |||
1808 | } | |||
1809 | } | |||
1810 | ||||
1811 | EndUndo(); | |||
1812 | } | |||
1813 | ||||
1814 | ||||
1815 | bool SdrEditView::IsAlignPossible() const | |||
1816 | { // at least two selected objects, at least one of them movable | |||
1817 | ForcePossibilities(); | |||
1818 | const size_t nCount=GetMarkedObjectCount(); | |||
1819 | if (nCount==0) return false; // nothing selected! | |||
1820 | if (nCount==1) return m_bMoveAllowed; // align single object to page | |||
1821 | return m_bOneOrMoreMovable; // otherwise: MarkCount>=2 | |||
1822 | } | |||
1823 | ||||
1824 | void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor, SdrVertAlign eVert) | |||
1825 | { | |||
1826 | if (eHor==SdrHorAlign::NONE && eVert==SdrVertAlign::NONE) | |||
1827 | return; | |||
1828 | ||||
1829 | SortMarkedObjects(); | |||
1830 | if (!GetMarkedObjectCount()) | |||
1831 | return; | |||
1832 | ||||
1833 | const bool bUndo = IsUndoEnabled(); | |||
1834 | if( bUndo ) | |||
1835 | { | |||
1836 | EndTextEditAllViews(); | |||
1837 | OUString aStr(GetDescriptionOfMarkedObjects()); | |||
1838 | if (eHor==SdrHorAlign::NONE) | |||
1839 | { | |||
1840 | switch (eVert) | |||
1841 | { | |||
1842 | case SdrVertAlign::Top: | |||
1843 | aStr = ImpGetDescriptionString(STR_EditAlignVTopreinterpret_cast<char const *>("STR_EditAlignVTop" "\004" u8"Align %1 to top")); | |||
1844 | break; | |||
1845 | case SdrVertAlign::Bottom: | |||
1846 | aStr = ImpGetDescriptionString(STR_EditAlignVBottomreinterpret_cast<char const *>("STR_EditAlignVBottom" "\004" u8"Align %1 to bottom")); | |||
1847 | break; | |||
1848 | case SdrVertAlign::Center: | |||
1849 | aStr = ImpGetDescriptionString(STR_EditAlignVCenterreinterpret_cast<char const *>("STR_EditAlignVCenter" "\004" u8"Horizontally center %1")); | |||
1850 | break; | |||
1851 | default: break; | |||
1852 | } | |||
1853 | } | |||
1854 | else if (eVert==SdrVertAlign::NONE) | |||
1855 | { | |||
1856 | switch (eHor) | |||
1857 | { | |||
1858 | case SdrHorAlign::Left: | |||
1859 | aStr = ImpGetDescriptionString(STR_EditAlignHLeftreinterpret_cast<char const *>("STR_EditAlignHLeft" "\004" u8"Align %1 to left")); | |||
1860 | break; | |||
1861 | case SdrHorAlign::Right: | |||
1862 | aStr = ImpGetDescriptionString(STR_EditAlignHRightreinterpret_cast<char const *>("STR_EditAlignHRight" "\004" u8"Align %1 to right")); | |||
1863 | break; | |||
1864 | case SdrHorAlign::Center: | |||
1865 | aStr = ImpGetDescriptionString(STR_EditAlignHCenterreinterpret_cast<char const *>("STR_EditAlignHCenter" "\004" u8"Vertically center %1")); | |||
1866 | break; | |||
1867 | default: break; | |||
1868 | } | |||
1869 | } | |||
1870 | else if (eHor==SdrHorAlign::Center && eVert==SdrVertAlign::Center) | |||
1871 | { | |||
1872 | aStr = ImpGetDescriptionString(STR_EditAlignCenterreinterpret_cast<char const *>("STR_EditAlignCenter" "\004" u8"Center %1")); | |||
1873 | } | |||
1874 | else | |||
1875 | { | |||
1876 | aStr = ImpGetDescriptionString(STR_EditAlignreinterpret_cast<char const *>("STR_EditAlign" "\004" u8"Align %1" )); | |||
1877 | } | |||
1878 | BegUndo(aStr); | |||
1879 | } | |||
1880 | ||||
1881 | tools::Rectangle aBound; | |||
1882 | const size_t nMarkCount=GetMarkedObjectCount(); | |||
1883 | bool bHasFixed=false; | |||
1884 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
1885 | { | |||
1886 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
1887 | SdrObject* pObj=pM->GetMarkedSdrObj(); | |||
1888 | SdrObjTransformInfoRec aInfo; | |||
1889 | pObj->TakeObjInfo(aInfo); | |||
1890 | if (!aInfo.bMoveAllowed || pObj->IsMoveProtect()) | |||
1891 | { | |||
1892 | tools::Rectangle aObjRect(pObj->GetSnapRect()); | |||
1893 | aBound.Union(aObjRect); | |||
1894 | bHasFixed=true; | |||
1895 | } | |||
1896 | } | |||
1897 | if (!bHasFixed) | |||
1898 | { | |||
1899 | if (nMarkCount==1) | |||
1900 | { // align single object to page | |||
1901 | const SdrObject* pObj=GetMarkedObjectByIndex(0); | |||
1902 | const SdrPage* pPage=pObj->getSdrPageFromSdrObject(); | |||
1903 | const SdrPageGridFrameList* pGFL=pPage->GetGridFrameList(GetSdrPageViewOfMarkedByIndex(0),&(pObj->GetSnapRect())); | |||
1904 | const SdrPageGridFrame* pFrame=nullptr; | |||
1905 | if (pGFL!=nullptr && pGFL->GetCount()!=0) | |||
1906 | { // Writer | |||
1907 | pFrame=&((*pGFL)[0]); | |||
1908 | } | |||
1909 | ||||
1910 | if (pFrame!=nullptr) | |||
1911 | { // Writer | |||
1912 | aBound=pFrame->GetUserArea(); | |||
1913 | } | |||
1914 | else | |||
1915 | { | |||
1916 | aBound=tools::Rectangle(pPage->GetLeftBorder(),pPage->GetUpperBorder(), | |||
1917 | pPage->GetWidth()-pPage->GetRightBorder(), | |||
1918 | pPage->GetHeight()-pPage->GetLowerBorder()); | |||
1919 | } | |||
1920 | } | |||
1921 | else | |||
1922 | { | |||
1923 | aBound=GetMarkedObjRect(); | |||
1924 | } | |||
1925 | } | |||
1926 | Point aCenter(aBound.Center()); | |||
1927 | for (size_t nm=0; nm<nMarkCount; ++nm) | |||
1928 | { | |||
1929 | SdrMark* pM=GetSdrMarkByIndex(nm); | |||
1930 | SdrObject* pObj=pM->GetMarkedSdrObj(); | |||
1931 | SdrObjTransformInfoRec aInfo; | |||
1932 | pObj->TakeObjInfo(aInfo); | |||
1933 | if (aInfo.bMoveAllowed && !pObj->IsMoveProtect()) | |||
1934 | { | |||
1935 | long nXMov=0; | |||
1936 | long nYMov=0; | |||
1937 | tools::Rectangle aObjRect(pObj->GetSnapRect()); | |||
1938 | switch (eVert) | |||
1939 | { | |||
1940 | case SdrVertAlign::Top : nYMov=aBound.Top() -aObjRect.Top() ; break; | |||
1941 | case SdrVertAlign::Bottom: nYMov=aBound.Bottom()-aObjRect.Bottom() ; break; | |||
1942 | case SdrVertAlign::Center: nYMov=aCenter.Y() -aObjRect.Center().Y(); break; | |||
1943 | default: break; | |||
1944 | } | |||
1945 | switch (eHor) | |||
1946 | { | |||
1947 | case SdrHorAlign::Left : nXMov=aBound.Left() -aObjRect.Left() ; break; | |||
1948 | case SdrHorAlign::Right : nXMov=aBound.Right() -aObjRect.Right() ; break; | |||
1949 | case SdrHorAlign::Center: nXMov=aCenter.X() -aObjRect.Center().X(); break; | |||
1950 | default: break; | |||
1951 | } | |||
1952 | if (nXMov!=0 || nYMov!=0) | |||
1953 | { | |||
1954 | // SdrEdgeObj needs an extra SdrUndoGeoObj since the | |||
1955 | // connections may need to be saved | |||
1956 | if( bUndo ) | |||
1957 | { | |||
1958 | if( dynamic_cast<SdrEdgeObj*>(pObj) ) | |||
1959 | { | |||
1960 | AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); | |||
1961 | } | |||
1962 | ||||
1963 | AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,Size(nXMov,nYMov))); | |||
1964 | } | |||
1965 | ||||
1966 | pObj->Move(Size(nXMov,nYMov)); | |||
1967 | } | |||
1968 | } | |||
1969 | } | |||
1970 | ||||
1971 | if( bUndo ) | |||
1972 | EndUndo(); | |||
1973 | } | |||
1974 | ||||
1975 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |