File: | home/maarten/src/libreoffice/core/svx/source/svdraw/svdedtv1.cxx |
Warning: | line 506, column 28 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 < nMarkCount; ++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
| ||||||||
| |||||||||
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
| ||||||||
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 && nWhich) | ||||||||
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 && bLineEndWidthExplicitChange) | ||||||||
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 || SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_XTypedWhichId<SfxInt32Item>( 10000 + 93 ), true ,&pPoolItem)) | ||||||||
1617 | nRotateX = rAttr.Get(SID_ATTR_TRANSFORM_ROT_XTypedWhichId<SfxInt32Item>( 10000 + 93 )).GetValue(); | ||||||||
1618 | |||||||||
1619 | // position rotation point y | ||||||||
1620 | if(bRotate || SfxItemState::SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_YTypedWhichId<SfxInt32Item>( 10000 + 94 ), true ,&pPoolItem)) | ||||||||
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: */ |
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 | #ifndef INCLUDED_SVX_SVDITER_HXX | ||||
21 | #define INCLUDED_SVX_SVDITER_HXX | ||||
22 | |||||
23 | #include <vector> | ||||
24 | |||||
25 | #include <svx/svxdllapi.h> | ||||
26 | |||||
27 | class SdrObjList; | ||||
28 | class SdrObject; | ||||
29 | class SdrPage; | ||||
30 | class SdrMarkList; | ||||
31 | |||||
32 | // SdrObjListIter methods: | ||||
33 | // SdrIterMode::Flat : Flat over the list | ||||
34 | // SdrIterMode::DeepWithGroups : With recursive descent parser, Next() also returns group objects | ||||
35 | // SdrIterMode::DeepNoGroups : With recursive descent parser, Next() returns no group objects | ||||
36 | enum class SdrIterMode { Flat, DeepWithGroups, DeepNoGroups }; | ||||
37 | |||||
38 | class SVXCORE_DLLPUBLIC__attribute__ ((visibility("default"))) SdrObjListIter | ||||
39 | { | ||||
40 | std::vector< const SdrObject* > maObjList; | ||||
41 | size_t mnIndex; | ||||
42 | bool mbReverse; | ||||
43 | bool mbUseZOrder; | ||||
44 | |||||
45 | void ImpProcessObjectList(const SdrObjList& rSdrObjList, SdrIterMode eMode); | ||||
46 | void ImpProcessMarkList(const SdrMarkList& rMarkList, SdrIterMode eMode); | ||||
47 | void ImpProcessObj(const SdrObject& rSdrObject, SdrIterMode eMode); | ||||
48 | |||||
49 | public: | ||||
50 | explicit SdrObjListIter(const SdrObjList* pObjList, SdrIterMode eMode = SdrIterMode::DeepNoGroups, bool bReverse = false); | ||||
51 | explicit SdrObjListIter(const SdrObjList* pObjList, bool bUseZOrder, SdrIterMode eMode = SdrIterMode::DeepNoGroups, bool bReverse = false); | ||||
52 | |||||
53 | /* SJ: the following function can now be used with every | ||||
54 | SdrObject and is no longer limited to group objects */ | ||||
55 | explicit SdrObjListIter(const SdrObject& rSdrObject, SdrIterMode eMode = SdrIterMode::DeepNoGroups, bool bReverse = false); | ||||
56 | explicit SdrObjListIter(const SdrPage* pSdrPage, SdrIterMode eMode = SdrIterMode::DeepNoGroups, bool bReverse = false); | ||||
57 | |||||
58 | /** Iterates over a list of marked objects received from the SdrMarkView. TTTT used in sc */ | ||||
59 | explicit SdrObjListIter(const SdrMarkList& rMarkList, SdrIterMode eMode = SdrIterMode::DeepNoGroups); | ||||
60 | |||||
61 | void Reset() { mnIndex = (mbReverse ? maObjList.size() : 0L); } | ||||
62 | bool IsMore() const { return (mbReverse ? mnIndex != 0 : ( mnIndex < maObjList.size())); } | ||||
63 | SdrObject* Next() | ||||
64 | { | ||||
65 | const size_t idx(mbReverse
| ||||
66 | return (idx < maObjList.size()) ? const_cast< SdrObject* >(maObjList[idx]) : nullptr; | ||||
67 | } | ||||
68 | |||||
69 | size_t Count() { return maObjList.size(); } | ||||
70 | }; | ||||
71 | |||||
72 | #endif // INCLUDED_SVX_SVDITER_HXX | ||||
73 | |||||
74 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |