File: | home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx |
Warning: | line 389, column 20 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 <editeng/outlobj.hxx> | |||
21 | ||||
22 | #include <svx/strings.hrc> | |||
23 | #include <svx/dialmgr.hxx> | |||
24 | #include <svx/svdpagv.hxx> | |||
25 | #include <svx/svdmrkv.hxx> | |||
26 | #include <svx/svdedxv.hxx> | |||
27 | #include <svx/svdobj.hxx> | |||
28 | #include <svx/svdopath.hxx> | |||
29 | #include <svx/svdograf.hxx> | |||
30 | #include <svx/svdomedia.hxx> | |||
31 | #include <svx/svdetc.hxx> | |||
32 | ||||
33 | #include <svx/svdoutl.hxx> | |||
34 | #include <svx/svdview.hxx> | |||
35 | #include <editeng/flditem.hxx> | |||
36 | #include <svx/obj3d.hxx> | |||
37 | #include <svx/svddrgmt.hxx> | |||
38 | #include <svx/svdotable.hxx> | |||
39 | #include <tools/debug.hxx> | |||
40 | #include <svx/sdr/overlay/overlaypolypolygon.hxx> | |||
41 | #include <svx/sdr/overlay/overlaymanager.hxx> | |||
42 | #include <svx/sdrpaintwindow.hxx> | |||
43 | #include <svx/sdrpagewindow.hxx> | |||
44 | #include <svx/sdrhittesthelper.hxx> | |||
45 | #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> | |||
46 | #include <svx/sdr/contact/objectcontactofpageview.hxx> | |||
47 | #include <sal/log.hxx> | |||
48 | #include <vcl/ptrstyle.hxx> | |||
49 | ||||
50 | ||||
51 | SdrViewEvent::SdrViewEvent() | |||
52 | : pHdl(nullptr), | |||
53 | pObj(nullptr), | |||
54 | pRootObj(nullptr), | |||
55 | pPV(nullptr), | |||
56 | pURLField(nullptr), | |||
57 | eHit(SdrHitKind::NONE), | |||
58 | eEvent(SdrEventKind::NONE), | |||
59 | nMouseClicks(0), | |||
60 | nMouseMode(MouseEventModifiers::NONE), | |||
61 | nMouseCode(0), | |||
62 | nHlplIdx(0), | |||
63 | nGlueId(0), | |||
64 | bMouseDown(false), | |||
65 | bMouseUp(false), | |||
66 | bIsAction(false), | |||
67 | bIsTextEdit(false), | |||
68 | bAddMark(false), | |||
69 | bUnmark(false), | |||
70 | bPrevNextMark(false), | |||
71 | bMarkPrev(false) | |||
72 | { | |||
73 | } | |||
74 | ||||
75 | SdrViewEvent::~SdrViewEvent() | |||
76 | { | |||
77 | } | |||
78 | ||||
79 | ||||
80 | // helper class for all D&D overlays | |||
81 | ||||
82 | void SdrDropMarkerOverlay::ImplCreateOverlays( | |||
83 | const SdrView& rView, | |||
84 | const basegfx::B2DPolyPolygon& rLinePolyPolygon) | |||
85 | { | |||
86 | for(sal_uInt32 a(0); a < rView.PaintWindowCount(); a++) | |||
87 | { | |||
88 | SdrPaintWindow* pCandidate = rView.GetPaintWindow(a); | |||
89 | const rtl::Reference< sdr::overlay::OverlayManager >& xTargetOverlay = pCandidate->GetOverlayManager(); | |||
90 | ||||
91 | if (xTargetOverlay.is()) | |||
92 | { | |||
93 | std::unique_ptr<sdr::overlay::OverlayPolyPolygonStripedAndFilled> pNew(new sdr::overlay::OverlayPolyPolygonStripedAndFilled( | |||
94 | rLinePolyPolygon)); | |||
95 | ||||
96 | xTargetOverlay->add(*pNew); | |||
97 | maObjects.append(std::move(pNew)); | |||
98 | } | |||
99 | } | |||
100 | } | |||
101 | ||||
102 | SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const SdrObject& rObject) | |||
103 | { | |||
104 | ImplCreateOverlays( | |||
105 | rView, | |||
106 | rObject.TakeXorPoly()); | |||
107 | } | |||
108 | ||||
109 | SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const tools::Rectangle& rRectangle) | |||
110 | { | |||
111 | basegfx::B2DPolygon aB2DPolygon; | |||
112 | ||||
113 | aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top())); | |||
114 | aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top())); | |||
115 | aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom())); | |||
116 | aB2DPolygon.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom())); | |||
117 | aB2DPolygon.setClosed(true); | |||
118 | ||||
119 | ImplCreateOverlays( | |||
120 | rView, | |||
121 | basegfx::B2DPolyPolygon(aB2DPolygon)); | |||
122 | } | |||
123 | ||||
124 | SdrDropMarkerOverlay::SdrDropMarkerOverlay(const SdrView& rView, const Point& rStart, const Point& rEnd) | |||
125 | { | |||
126 | basegfx::B2DPolygon aB2DPolygon; | |||
127 | ||||
128 | aB2DPolygon.append(basegfx::B2DPoint(rStart.X(), rStart.Y())); | |||
129 | aB2DPolygon.append(basegfx::B2DPoint(rEnd.X(), rEnd.Y())); | |||
130 | aB2DPolygon.setClosed(true); | |||
131 | ||||
132 | ImplCreateOverlays( | |||
133 | rView, | |||
134 | basegfx::B2DPolyPolygon(aB2DPolygon)); | |||
135 | } | |||
136 | ||||
137 | SdrDropMarkerOverlay::~SdrDropMarkerOverlay() | |||
138 | { | |||
139 | // The OverlayObjects are cleared using the destructor of OverlayObjectList. | |||
140 | // That destructor calls clear() at the list which removes all objects from the | |||
141 | // OverlayManager and deletes them. | |||
142 | } | |||
143 | ||||
144 | SdrView::SdrView( | |||
145 | SdrModel& rSdrModel, | |||
146 | OutputDevice* pOut) | |||
147 | : SdrCreateView(rSdrModel, pOut), | |||
148 | bNoExtendedMouseDispatcher(false), | |||
149 | bNoExtendedKeyDispatcher(false), | |||
150 | mbMasterPagePaintCaching(false) | |||
151 | { | |||
152 | maAccessibilityOptions.AddListener(this); | |||
153 | onAccessibilityOptionsChanged(); | |||
154 | } | |||
155 | ||||
156 | SdrView::~SdrView() | |||
157 | { | |||
158 | maAccessibilityOptions.RemoveListener(this); | |||
159 | } | |||
160 | ||||
161 | bool SdrView::KeyInput(const KeyEvent& rKEvt, vcl::Window* pWin) | |||
162 | { | |||
163 | SetActualWin(pWin); | |||
164 | bool bRet = SdrCreateView::KeyInput(rKEvt,pWin); | |||
165 | if (!bRet && !IsExtendedKeyInputDispatcherEnabled()) { | |||
166 | bRet = true; | |||
167 | switch (rKEvt.GetKeyCode().GetFullFunction()) { | |||
168 | case KeyFuncType::DELETE: DeleteMarked(); break; | |||
169 | case KeyFuncType::UNDO: mpModel->Undo(); break; | |||
170 | case KeyFuncType::REDO: mpModel->Redo(); break; | |||
171 | default: { | |||
172 | switch (rKEvt.GetKeyCode().GetFullCode()) { | |||
173 | case KEY_ESCAPE: { | |||
174 | if (IsTextEdit()) SdrEndTextEdit(); | |||
175 | if (IsAction()) BrkAction(); | |||
176 | if (pWin!=nullptr) pWin->ReleaseMouse(); | |||
177 | } break; | |||
178 | case KEY_DELETE: DeleteMarked(); break; | |||
179 | case KEY_UNDO: case KEY_BACKSPACE+KEY_MOD2: mpModel->Undo(); break; | |||
180 | case KEY_BACKSPACE+KEY_MOD2+KEY_SHIFT: mpModel->Redo(); break; | |||
181 | case KEY_REPEAT: case KEY_BACKSPACE+KEY_MOD2+KEY_MOD1: mpModel->Repeat(*this); break; | |||
182 | case KEY_MOD1+KEY_A: MarkAll(); break; | |||
183 | default: bRet=false; | |||
184 | } // switch | |||
185 | } | |||
186 | } // switch | |||
187 | if (bRet && pWin!=nullptr) { | |||
188 | pWin->SetPointer(GetPreferredPointer( | |||
189 | pWin->PixelToLogic(pWin->ScreenToOutputPixel( pWin->GetPointerPosPixel() ) ), | |||
190 | pWin, | |||
191 | rKEvt.GetKeyCode().GetModifier())); | |||
192 | } | |||
193 | } | |||
194 | return bRet; | |||
195 | } | |||
196 | ||||
197 | bool SdrView::MouseButtonDown(const MouseEvent& rMEvt, OutputDevice* pWin) | |||
198 | { | |||
199 | SetActualWin(pWin); | |||
200 | if (rMEvt.IsLeft()) maDragStat.SetMouseDown(true); | |||
201 | bool bRet = SdrCreateView::MouseButtonDown(rMEvt,pWin); | |||
202 | if (!bRet && !IsExtendedMouseEventDispatcherEnabled()) { | |||
203 | SdrViewEvent aVEvt; | |||
204 | PickAnything(rMEvt,SdrMouseEventKind::BUTTONDOWN,aVEvt); | |||
205 | bRet = DoMouseEvent(aVEvt); | |||
206 | } | |||
207 | return bRet; | |||
208 | } | |||
209 | ||||
210 | bool SdrView::MouseButtonUp(const MouseEvent& rMEvt, OutputDevice* pWin) | |||
211 | { | |||
212 | SetActualWin(pWin); | |||
213 | if (rMEvt.IsLeft()) maDragStat.SetMouseDown(false); | |||
214 | bool bAction = IsAction(); | |||
215 | bool bRet = !bAction && SdrCreateView::MouseButtonUp(rMEvt,pWin); | |||
216 | if (!bRet && !IsExtendedMouseEventDispatcherEnabled()) { | |||
217 | SdrViewEvent aVEvt; | |||
218 | PickAnything(rMEvt,SdrMouseEventKind::BUTTONUP,aVEvt); | |||
219 | bRet = DoMouseEvent(aVEvt); | |||
220 | } | |||
221 | return bRet; | |||
222 | } | |||
223 | ||||
224 | bool SdrView::MouseMove(const MouseEvent& rMEvt, OutputDevice* pWin) | |||
225 | { | |||
226 | SetActualWin(pWin); | |||
227 | maDragStat.SetMouseDown(rMEvt.IsLeft()); | |||
228 | bool bRet = SdrCreateView::MouseMove(rMEvt,pWin); | |||
229 | if (!IsExtendedMouseEventDispatcherEnabled() && !IsTextEditInSelectionMode()) { | |||
230 | SdrViewEvent aVEvt; | |||
231 | PickAnything(rMEvt,SdrMouseEventKind::MOVE,aVEvt); | |||
232 | if (DoMouseEvent(aVEvt)) bRet=true; | |||
233 | } | |||
234 | ||||
235 | return bRet; | |||
236 | } | |||
237 | ||||
238 | bool SdrView::Command(const CommandEvent& rCEvt, vcl::Window* pWin) | |||
239 | { | |||
240 | SetActualWin(pWin); | |||
241 | bool bRet = SdrCreateView::Command(rCEvt,pWin); | |||
242 | return bRet; | |||
243 | } | |||
244 | ||||
245 | void SdrView::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const | |||
246 | { | |||
247 | SdrCreateView::GetAttributes(rTargetSet, bOnlyHardAttr); | |||
248 | } | |||
249 | ||||
250 | SdrHitKind SdrView::PickAnything(const MouseEvent& rMEvt, SdrMouseEventKind nEventKind, SdrViewEvent& rVEvt) const | |||
251 | { | |||
252 | rVEvt.bMouseDown=nEventKind==SdrMouseEventKind::BUTTONDOWN; | |||
253 | rVEvt.bMouseUp=nEventKind==SdrMouseEventKind::BUTTONUP; | |||
254 | rVEvt.nMouseClicks=rMEvt.GetClicks(); | |||
255 | rVEvt.nMouseMode=rMEvt.GetMode(); | |||
256 | rVEvt.nMouseCode=rMEvt.GetButtons() | rMEvt.GetModifier(); | |||
257 | const OutputDevice* pOut=mpActualOutDev; | |||
258 | if (pOut==nullptr) | |||
259 | { | |||
260 | pOut = GetFirstOutputDevice(); | |||
261 | } | |||
262 | Point aPnt(rMEvt.GetPosPixel()); | |||
263 | if (pOut!=nullptr) aPnt=pOut->PixelToLogic(aPnt); | |||
264 | rVEvt.aLogicPos=aPnt; | |||
265 | return PickAnything(aPnt,rVEvt); | |||
266 | } | |||
267 | ||||
268 | // Dragging with the Mouse (Move) | |||
269 | // Example when creating a rectangle: MouseDown has to happen without a ModKey, | |||
270 | // else we usually force a selection (see below). | |||
271 | // When pressing Shift, Ctrl and Alt at the same time while doing a MouseMove, | |||
272 | // a centered, not snapped square is created. | |||
273 | // The dual allocation of Ortho and Shift won't usually create a problem, as the | |||
274 | // two functions are in most cases mutually exclusive. Only shearing (the kind | |||
275 | // that happens when contorting, not when rotating) can use both functions at | |||
276 | // the same time. To get around this, the user can use e. g. help lines. | |||
277 | #define MODKEY_NoSnapbCtrl bCtrl /* temporarily disable snapping */ | |||
278 | #define MODKEY_OrthobShift bShift /* ortho */ | |||
279 | #define MODKEY_CenterbAlt bAlt /* create/resize centeredly */ | |||
280 | #define MODKEY_AngleSnapbShift bShift | |||
281 | #define MODKEY_CopyDragbCtrl bCtrl /* drag and copy */ | |||
282 | ||||
283 | // click somewhere (MouseDown) | |||
284 | #define MODKEY_PolyPolybAlt bAlt /* new Poly at InsPt and at Create */ | |||
285 | #define MODKEY_MultiMarkbShift bShift /* MarkObj without doing UnmarkAll first */ | |||
286 | #define MODKEY_UnmarkbAlt bAlt /* deselect with a dragged frame */ | |||
287 | #define MODKEY_ForceMarkbCtrl bCtrl /* force dragging a frame, even if there's an object at cursor position */ | |||
288 | #define MODKEY_DeepMarkbAlt bAlt /* MarkNextObj */ | |||
289 | #define MODKEY_DeepBackwbShift bShift /* MarkNextObj but backwards */ | |||
290 | ||||
291 | SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) const | |||
292 | { | |||
293 | const OutputDevice* pOut=mpActualOutDev; | |||
294 | if (pOut==nullptr) | |||
| ||||
295 | { | |||
296 | pOut = GetFirstOutputDevice(); | |||
297 | } | |||
298 | ||||
299 | // #i73628# Use a non-changeable copy of he logic position | |||
300 | const Point aLocalLogicPosition(rLogicPos); | |||
301 | ||||
302 | bool bEditMode=IsEditMode(); | |||
303 | bool bPointMode=bEditMode
| |||
304 | bool bGluePointMode=IsGluePointEditMode(); | |||
305 | bool bInsPolyPt=bPointMode
| |||
306 | bool bInsGluePt=bGluePointMode
| |||
307 | bool bIsTextEdit=IsTextEdit(); | |||
308 | bool bTextEditHit=IsTextEditHit(aLocalLogicPosition); | |||
309 | bool bTextEditSel=IsTextEditInSelectionMode(); | |||
310 | bool bShift=(rVEvt.nMouseCode & KEY_SHIFT) !=0; | |||
311 | bool bCtrl=(rVEvt.nMouseCode & KEY_MOD1) !=0; | |||
312 | bool bAlt=(rVEvt.nMouseCode & KEY_MOD2) !=0; | |||
313 | SdrHitKind eHit=SdrHitKind::NONE; | |||
314 | SdrHdl* pHdl=pOut!=nullptr && !bTextEditSel ? PickHandle(aLocalLogicPosition) : nullptr; | |||
315 | SdrPageView* pPV=nullptr; | |||
316 | SdrObject* pObj=nullptr; | |||
317 | SdrObject* pHitObj=nullptr; | |||
318 | bool bHitPassDirect=true; | |||
319 | sal_uInt16 nHlplIdx=0; | |||
320 | sal_uInt16 nGlueId=0; | |||
321 | if (bTextEditHit || bTextEditSel
| |||
322 | { | |||
323 | eHit=SdrHitKind::TextEdit; | |||
324 | } | |||
325 | else if (pHdl!=nullptr) | |||
326 | { | |||
327 | eHit=SdrHitKind::Handle; // handle is hit: highest priority | |||
328 | } | |||
329 | else if (bEditMode
| |||
330 | { | |||
331 | eHit=SdrHitKind::HelpLine; // help line in the foreground hit: can be moved now | |||
332 | } | |||
333 | else if (bGluePointMode
| |||
334 | { | |||
335 | eHit=SdrHitKind::Gluepoint; // deselected glue point hit | |||
336 | } | |||
337 | else if ((pHitObj = PickObj(aLocalLogicPosition,mnHitTolLog,pPV,SdrSearchOptions::DEEP|SdrSearchOptions::MARKED,&pObj,&bHitPassDirect))) | |||
338 | { | |||
339 | eHit=SdrHitKind::MarkedObject; | |||
340 | sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( pObj ); | |||
341 | if( pTableObj ) | |||
342 | { | |||
343 | sal_Int32 nX = 0, nY = 0; | |||
344 | switch( pTableObj->CheckTableHit( aLocalLogicPosition, nX, nY ) ) | |||
345 | { | |||
346 | case sdr::table::TableHitKind::Cell: | |||
347 | eHit = SdrHitKind::Cell; | |||
348 | break; | |||
349 | case sdr::table::TableHitKind::CellTextArea: | |||
350 | eHit = SdrHitKind::TextEditObj; | |||
351 | break; | |||
352 | default: | |||
353 | break; | |||
354 | } | |||
355 | } | |||
356 | } | |||
357 | else if ((pHitObj = PickObj(aLocalLogicPosition,mnHitTolLog,pPV,SdrSearchOptions::DEEP|SdrSearchOptions::ALSOONMASTER|SdrSearchOptions::WHOLEPAGE,&pObj,&bHitPassDirect))) | |||
358 | { | |||
359 | // MasterPages and WholePage for Macro and URL | |||
360 | eHit=SdrHitKind::UnmarkedObject; | |||
361 | sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( pObj ); | |||
362 | if( pTableObj ) | |||
363 | { | |||
364 | sal_Int32 nX = 0, nY = 0; | |||
365 | switch( pTableObj->CheckTableHit( aLocalLogicPosition, nX, nY, mnHitTolLog ) ) | |||
366 | { | |||
367 | case sdr::table::TableHitKind::Cell: | |||
368 | eHit = SdrHitKind::Cell; | |||
369 | break; | |||
370 | case sdr::table::TableHitKind::CellTextArea: | |||
371 | // Keep state on UnmarkedObject to allow the below | |||
372 | // 'check for URL field' to be executed, else popups | |||
373 | // for e.g. URL links when hoovering and clicking | |||
374 | // them will not work. Tried several other changes, | |||
375 | // but this one safely keeps existing behaviour as-is. | |||
376 | eHit = SdrHitKind::UnmarkedObject; | |||
377 | break; | |||
378 | default: | |||
379 | break; | |||
380 | } | |||
381 | } | |||
382 | } | |||
383 | else if (bEditMode && IsHlplVisible() && !IsHlplFront() && pOut!=nullptr && PickHelpLine(aLocalLogicPosition,mnHitTolLog,*pOut,nHlplIdx,pPV)) | |||
384 | { | |||
385 | eHit=SdrHitKind::HelpLine; // help line in foreground hit: can be moved now | |||
386 | } | |||
387 | if (eHit
| |||
388 | { | |||
389 | bool bRoot=pObj->HasMacro(); | |||
| ||||
390 | bool bDeep=pObj!=pHitObj && pHitObj->HasMacro(); | |||
391 | bool bMid=false; // Have we hit upon a grouped group with a macro? | |||
392 | SdrObject* pMidObj=nullptr; | |||
393 | if (pObj!=pHitObj) | |||
394 | { | |||
395 | SdrObject* pObjTmp=pHitObj->getParentSdrObjectFromSdrObject(); | |||
396 | if (pObjTmp==pObj) pObjTmp=nullptr; | |||
397 | while (pObjTmp!=nullptr) | |||
398 | { | |||
399 | if (pObjTmp->HasMacro()) | |||
400 | { | |||
401 | bMid=true; | |||
402 | pMidObj=pObjTmp; | |||
403 | } | |||
404 | pObjTmp=pObjTmp->getParentSdrObjectFromSdrObject(); | |||
405 | if (pObjTmp==pObj) pObjTmp=nullptr; | |||
406 | } | |||
407 | } | |||
408 | ||||
409 | if (bDeep || bMid || bRoot) | |||
410 | { | |||
411 | SdrObjMacroHitRec aHitRec; | |||
412 | aHitRec.aPos=aLocalLogicPosition; | |||
413 | aHitRec.nTol=mnHitTolLog; | |||
414 | aHitRec.pVisiLayer=&pPV->GetVisibleLayers(); | |||
415 | aHitRec.pPageView=pPV; | |||
416 | if (bDeep) bDeep=pHitObj->IsMacroHit(aHitRec); | |||
417 | if (bMid ) bMid =pMidObj->IsMacroHit(aHitRec); | |||
418 | if (bRoot) bRoot=pObj->IsMacroHit(aHitRec); | |||
419 | if (bRoot || bMid || bDeep) | |||
420 | { | |||
421 | // Priorities: 1. Root, 2. Mid, 3. Deep | |||
422 | rVEvt.pRootObj=pObj; | |||
423 | if (!bRoot) pObj=pMidObj; | |||
424 | if (!bRoot && !bMid) pObj=pHitObj; | |||
425 | eHit=SdrHitKind::Macro; | |||
426 | } | |||
427 | } | |||
428 | } | |||
429 | // check for URL field | |||
430 | if (eHit==SdrHitKind::UnmarkedObject) | |||
431 | { | |||
432 | SdrTextObj* pTextObj=dynamic_cast<SdrTextObj*>( pHitObj ); | |||
433 | if (pTextObj!=nullptr && pTextObj->HasText()) | |||
434 | { | |||
435 | // use the primitive-based HitTest which is more accurate anyways. It | |||
436 | // will correctly handle rotated/mirrored/sheared/scaled text and can | |||
437 | // now return a HitContainer containing the primitive hierarchy of the | |||
438 | // primitive that triggered the hit. The first entry is that primitive, | |||
439 | // the others are the full stack of primitives leading to that one which | |||
440 | // includes grouping primitives (like TextHierarchyPrimitives we deed here) | |||
441 | // but also all decomposed ones which lead to the creation of that primitive | |||
442 | drawinglayer::primitive2d::Primitive2DContainer aHitContainer; | |||
443 | const bool bTEHit(pPV && SdrObjectPrimitiveHit(*pTextObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true, &aHitContainer)); | |||
444 | ||||
445 | if (bTEHit && !aHitContainer.empty()) | |||
446 | { | |||
447 | // search for TextHierarchyFieldPrimitive2D which contains the needed information | |||
448 | // about a possible URLField | |||
449 | const drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D* pTextHierarchyFieldPrimitive2D = nullptr; | |||
450 | ||||
451 | for (const drawinglayer::primitive2d::Primitive2DReference& xReference : aHitContainer) | |||
452 | { | |||
453 | if (xReference.is()) | |||
454 | { | |||
455 | // try to cast to drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D implementation | |||
456 | pTextHierarchyFieldPrimitive2D = dynamic_cast<const drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D*>(xReference.get()); | |||
457 | ||||
458 | if (pTextHierarchyFieldPrimitive2D) | |||
459 | { | |||
460 | break; | |||
461 | } | |||
462 | } | |||
463 | } | |||
464 | ||||
465 | if (nullptr != pTextHierarchyFieldPrimitive2D) | |||
466 | { | |||
467 | if (drawinglayer::primitive2d::FieldType::FIELD_TYPE_URL == pTextHierarchyFieldPrimitive2D->getType()) | |||
468 | { | |||
469 | // problem with the old code is that a *pointer* to an instance of | |||
470 | // SvxURLField is set in the Event which is per se not good since that | |||
471 | // data comes from a temporary EditEngine's data and could vanish any | |||
472 | // moment. Have to replace for now with a static instance that gets | |||
473 | // filled/initialized from the original data held in the TextHierarchyField- | |||
474 | // Primitive2D (see impTextBreakupHandler::impCheckFieldPrimitive). | |||
475 | // Unfortunately things like 'TargetFrame' are still used in Calc, so this | |||
476 | // can currently not get replaced. For the future the Name/Value vector or | |||
477 | // the TextHierarchyFieldPrimitive2D itself should/will be used for handling | |||
478 | // that data | |||
479 | static SvxURLField aSvxURLField; | |||
480 | ||||
481 | aSvxURLField.SetURL(pTextHierarchyFieldPrimitive2D->getValue("URL")); | |||
482 | aSvxURLField.SetRepresentation(pTextHierarchyFieldPrimitive2D->getValue("Representation")); | |||
483 | aSvxURLField.SetTargetFrame(pTextHierarchyFieldPrimitive2D->getValue("TargetFrame")); | |||
484 | const OUString aFormat(pTextHierarchyFieldPrimitive2D->getValue("SvxURLFormat")); | |||
485 | ||||
486 | if (!aFormat.isEmpty()) | |||
487 | { | |||
488 | aSvxURLField.SetFormat(static_cast<SvxURLFormat>(aFormat.toInt32())); | |||
489 | } | |||
490 | ||||
491 | // set HitKind and pointer to local static instance in the Event | |||
492 | // to comply to old stuff | |||
493 | eHit = SdrHitKind::UrlField; | |||
494 | rVEvt.pURLField = &aSvxURLField; | |||
495 | } | |||
496 | } | |||
497 | } | |||
498 | } | |||
499 | } | |||
500 | ||||
501 | if (bHitPassDirect && | |||
502 | (eHit==SdrHitKind::MarkedObject || eHit==SdrHitKind::UnmarkedObject) && | |||
503 | (IsTextTool() || (IsEditMode() && IsQuickTextEditMode())) && pHitObj->HasTextEdit()) | |||
504 | { | |||
505 | // Around the TextEditArea there's a border to select without going into text edit mode. | |||
506 | tools::Rectangle aBoundRect(pHitObj->GetCurrentBoundRect()); | |||
507 | ||||
508 | // Force to SnapRect when Fontwork | |||
509 | if( dynamic_cast<const SdrTextObj*>( pHitObj) != nullptr && static_cast<SdrTextObj*>(pHitObj)->IsFontwork()) | |||
510 | { | |||
511 | aBoundRect = pHitObj->GetSnapRect(); | |||
512 | } | |||
513 | ||||
514 | sal_Int32 nTolerance(mnHitTolLog); | |||
515 | bool bBoundRectHit(false); | |||
516 | ||||
517 | if(pOut) | |||
518 | { | |||
519 | nTolerance = pOut->PixelToLogic(Size(2, 0)).Width(); | |||
520 | } | |||
521 | ||||
522 | if( (aLocalLogicPosition.X() >= aBoundRect.Left() - nTolerance && aLocalLogicPosition.X() <= aBoundRect.Left() + nTolerance) | |||
523 | || (aLocalLogicPosition.X() >= aBoundRect.Right() - nTolerance && aLocalLogicPosition.X() <= aBoundRect.Right() + nTolerance) | |||
524 | || (aLocalLogicPosition.Y() >= aBoundRect.Top() - nTolerance && aLocalLogicPosition.Y() <= aBoundRect.Top() + nTolerance) | |||
525 | || (aLocalLogicPosition.Y() >= aBoundRect.Bottom() - nTolerance && aLocalLogicPosition.Y() <= aBoundRect.Bottom() + nTolerance)) | |||
526 | { | |||
527 | bBoundRectHit = true; | |||
528 | } | |||
529 | ||||
530 | if(!bBoundRectHit) | |||
531 | { | |||
532 | bool bTEHit(pPV && | |||
533 | SdrObjectPrimitiveHit(*pHitObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true)); | |||
534 | ||||
535 | // TextEdit attached to an object in a locked layer | |||
536 | if (pPV->GetLockedLayers().IsSet(pHitObj->GetLayer())) | |||
537 | { | |||
538 | bTEHit=false; | |||
539 | } | |||
540 | ||||
541 | if (bTEHit) | |||
542 | { | |||
543 | rVEvt.pRootObj=pObj; | |||
544 | pObj=pHitObj; | |||
545 | eHit=SdrHitKind::TextEditObj; | |||
546 | } | |||
547 | } | |||
548 | } | |||
549 | if (!bHitPassDirect && eHit==SdrHitKind::UnmarkedObject) { | |||
550 | eHit=SdrHitKind::NONE; | |||
551 | pObj=nullptr; | |||
552 | pPV=nullptr; | |||
553 | } | |||
554 | bool bMouseLeft=(rVEvt.nMouseCode&MOUSE_LEFT(sal_uInt16(0x0001)))!=0; | |||
555 | bool bMouseRight=(rVEvt.nMouseCode&MOUSE_RIGHT(sal_uInt16(0x0004)))!=0; | |||
556 | bool bMouseDown=rVEvt.bMouseDown; | |||
557 | bool bMouseUp=rVEvt.bMouseUp; | |||
558 | SdrEventKind eEvent=SdrEventKind::NONE; | |||
559 | bool bIsAction=IsAction(); | |||
560 | ||||
561 | if (bIsAction) | |||
562 | { | |||
563 | if (bMouseDown) | |||
564 | { | |||
565 | if (bMouseRight) eEvent=SdrEventKind::BackAction; | |||
566 | } | |||
567 | else if (bMouseUp) | |||
568 | { | |||
569 | if (bMouseLeft) | |||
570 | { | |||
571 | eEvent=SdrEventKind::EndAction; | |||
572 | if (IsDragObj()) | |||
573 | { | |||
574 | eEvent=SdrEventKind::EndDrag; | |||
575 | } | |||
576 | else if (IsCreateObj() || IsInsObjPoint()) | |||
577 | { | |||
578 | eEvent=IsCreateObj() ? SdrEventKind::EndCreate : SdrEventKind::EndInsertObjPoint; | |||
579 | } | |||
580 | else if (IsMarking()) | |||
581 | { | |||
582 | eEvent=SdrEventKind::EndMark; | |||
583 | if (!maDragStat.IsMinMoved()) | |||
584 | { | |||
585 | eEvent=SdrEventKind::BrkMark; | |||
586 | rVEvt.bAddMark=MODKEY_MultiMarkbShift; | |||
587 | } | |||
588 | } | |||
589 | } | |||
590 | } | |||
591 | else | |||
592 | { | |||
593 | eEvent=SdrEventKind::MoveAction; | |||
594 | } | |||
595 | } | |||
596 | else if (eHit==SdrHitKind::TextEdit) | |||
597 | { | |||
598 | eEvent=SdrEventKind::TextEdit; | |||
599 | } | |||
600 | else if (bMouseDown && bMouseLeft) | |||
601 | { | |||
602 | if (rVEvt.nMouseClicks==2 && rVEvt.nMouseCode==MOUSE_LEFT(sal_uInt16(0x0001)) && pObj!=nullptr && pHitObj!=nullptr && pHitObj->HasTextEdit() && eHit==SdrHitKind::MarkedObject) | |||
603 | { | |||
604 | rVEvt.pRootObj=pObj; | |||
605 | pObj=pHitObj; | |||
606 | eEvent=SdrEventKind::BeginTextEdit; | |||
607 | } | |||
608 | else if (MODKEY_ForceMarkbCtrl && eHit!=SdrHitKind::UrlField) | |||
609 | { | |||
610 | eEvent=SdrEventKind::BeginMark; // AddMark,Unmark */ | |||
611 | } | |||
612 | else if (eHit==SdrHitKind::HelpLine) | |||
613 | { | |||
614 | eEvent=SdrEventKind::BeginDragHelpline; // nothing, actually | |||
615 | } | |||
616 | else if (eHit==SdrHitKind::Gluepoint) | |||
617 | { | |||
618 | eEvent=SdrEventKind::MarkGluePoint; // AddMark+Drag | |||
619 | rVEvt.bAddMark=MODKEY_MultiMarkbShift || MODKEY_DeepMarkbAlt; // if not hit with Deep | |||
620 | } | |||
621 | else if (eHit==SdrHitKind::Handle) | |||
622 | { | |||
623 | eEvent=SdrEventKind::BeginDragObj; // Mark+Drag,AddMark+Drag,DeepMark+Drag,Unmark | |||
624 | bool bGlue=pHdl->GetKind()==SdrHdlKind::Glue; | |||
625 | bool bPoly=!bGlue && IsPointMarkable(*pHdl); | |||
626 | bool bMarked=bGlue || (bPoly && pHdl->IsSelected()); | |||
627 | if (bGlue || bPoly) | |||
628 | { | |||
629 | eEvent=bGlue ? SdrEventKind::MarkGluePoint : SdrEventKind::MarkPoint; | |||
630 | if (MODKEY_DeepMarkbAlt) | |||
631 | { | |||
632 | rVEvt.bAddMark=true; | |||
633 | rVEvt.bPrevNextMark=true; | |||
634 | rVEvt.bMarkPrev=MODKEY_DeepBackwbShift; | |||
635 | } | |||
636 | else if (MODKEY_MultiMarkbShift) | |||
637 | { | |||
638 | rVEvt.bAddMark=true; | |||
639 | rVEvt.bUnmark=bMarked; // Toggle | |||
640 | if (bGlue) | |||
641 | { | |||
642 | pObj=pHdl->GetObj(); | |||
643 | nGlueId=static_cast<sal_uInt16>(pHdl->GetObjHdlNum()); | |||
644 | } | |||
645 | } | |||
646 | else if (bMarked) | |||
647 | { | |||
648 | eEvent=SdrEventKind::BeginDragObj; // don't change MarkState, only change Drag | |||
649 | } | |||
650 | } | |||
651 | } | |||
652 | else if (bInsPolyPt && (MODKEY_PolyPolybAlt || (!MODKEY_MultiMarkbShift && !MODKEY_DeepMarkbAlt))) | |||
653 | { | |||
654 | eEvent=SdrEventKind::BeginInsertObjPoint; | |||
655 | } | |||
656 | else if (bInsGluePt && !MODKEY_MultiMarkbShift && !MODKEY_DeepMarkbAlt) | |||
657 | { | |||
658 | eEvent=SdrEventKind::BeginInsertGluePoint; | |||
659 | } | |||
660 | else if (eHit==SdrHitKind::TextEditObj) | |||
661 | { | |||
662 | eEvent=SdrEventKind::BeginTextEdit; // AddMark+Drag,DeepMark+Drag,Unmark | |||
663 | if (MODKEY_MultiMarkbShift || MODKEY_DeepMarkbAlt) | |||
664 | { // if not hit with Deep | |||
665 | eEvent=SdrEventKind::MarkObj; | |||
666 | } | |||
667 | } | |||
668 | else if (eHit==SdrHitKind::Macro) | |||
669 | { | |||
670 | eEvent=SdrEventKind::BeginMacroObj; // AddMark+Drag | |||
671 | if (MODKEY_MultiMarkbShift || MODKEY_DeepMarkbAlt) | |||
672 | { // if not hit with Deep | |||
673 | eEvent=SdrEventKind::MarkObj; | |||
674 | } | |||
675 | } | |||
676 | else if (eHit==SdrHitKind::UrlField) | |||
677 | { | |||
678 | eEvent=SdrEventKind::ExecuteUrl; // AddMark+Drag | |||
679 | if (MODKEY_MultiMarkbShift || MODKEY_DeepMarkbAlt) | |||
680 | { // if not hit with Deep | |||
681 | eEvent=SdrEventKind::MarkObj; | |||
682 | } | |||
683 | } | |||
684 | else if (eHit==SdrHitKind::MarkedObject) | |||
685 | { | |||
686 | eEvent=SdrEventKind::BeginDragObj; // DeepMark+Drag,Unmark | |||
687 | ||||
688 | if (MODKEY_MultiMarkbShift || MODKEY_DeepMarkbAlt) | |||
689 | { // if not hit with Deep | |||
690 | eEvent=SdrEventKind::MarkObj; | |||
691 | } | |||
692 | } | |||
693 | else if (IsCreateMode()) | |||
694 | { | |||
695 | eEvent=SdrEventKind::BeginCreateObj; // nothing, actually | |||
696 | } | |||
697 | else if (eHit==SdrHitKind::UnmarkedObject) | |||
698 | { | |||
699 | eEvent=SdrEventKind::MarkObj; // AddMark+Drag | |||
700 | } | |||
701 | else | |||
702 | { | |||
703 | eEvent=SdrEventKind::BeginMark; | |||
704 | } | |||
705 | ||||
706 | if (eEvent==SdrEventKind::MarkObj) | |||
707 | { | |||
708 | rVEvt.bAddMark=MODKEY_MultiMarkbShift || MODKEY_DeepMarkbAlt; // if not hit with Deep | |||
709 | rVEvt.bPrevNextMark=MODKEY_DeepMarkbAlt; | |||
710 | rVEvt.bMarkPrev=MODKEY_DeepMarkbAlt && MODKEY_DeepBackwbShift; | |||
711 | } | |||
712 | if (eEvent==SdrEventKind::BeginMark) | |||
713 | { | |||
714 | rVEvt.bAddMark=MODKEY_MultiMarkbShift; | |||
715 | rVEvt.bUnmark=MODKEY_UnmarkbAlt; | |||
716 | } | |||
717 | } | |||
718 | rVEvt.bIsAction=bIsAction; | |||
719 | rVEvt.bIsTextEdit=bIsTextEdit; | |||
720 | rVEvt.aLogicPos=aLocalLogicPosition; | |||
721 | rVEvt.pHdl=pHdl; | |||
722 | rVEvt.pObj=pObj; | |||
723 | if(rVEvt.pRootObj==nullptr) | |||
724 | rVEvt.pRootObj=pObj; | |||
725 | rVEvt.pPV=pPV; | |||
726 | rVEvt.nHlplIdx=nHlplIdx; | |||
727 | rVEvt.nGlueId=nGlueId; | |||
728 | rVEvt.eHit=eHit; | |||
729 | rVEvt.eEvent=eEvent; | |||
730 | #ifdef DGB_UTIL | |||
731 | if (rVEvt.pRootObj!=NULL__null) { | |||
732 | if (rVEvt.pRootObj->getParentSdrObjListFromSdrObject()!=rVEvt.pPV->GetObjList()) { | |||
733 | OSL_FAIL("SdrView::PickAnything(): pRootObj->getParentSdrObjListFromSdrObject()!=pPV->GetObjList() !")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "733" ": "), "%s", "SdrView::PickAnything(): pRootObj->getParentSdrObjListFromSdrObject()!=pPV->GetObjList() !" ); } } while (false); | |||
734 | } | |||
735 | } | |||
736 | #endif | |||
737 | return eHit; | |||
738 | } | |||
739 | ||||
740 | bool SdrView::DoMouseEvent(const SdrViewEvent& rVEvt) | |||
741 | { | |||
742 | bool bRet=false; | |||
743 | SdrHitKind eHit=rVEvt.eHit; | |||
744 | Point aLogicPos(rVEvt.aLogicPos); | |||
745 | ||||
746 | bool bShift=(rVEvt.nMouseCode & KEY_SHIFT) !=0; | |||
747 | bool bCtrl=(rVEvt.nMouseCode & KEY_MOD1) !=0; | |||
748 | bool bAlt=(rVEvt.nMouseCode & KEY_MOD2) !=0; | |||
749 | bool bMouseLeft=(rVEvt.nMouseCode&MOUSE_LEFT(sal_uInt16(0x0001)))!=0; | |||
750 | bool bMouseDown=rVEvt.bMouseDown; | |||
751 | bool bMouseUp=rVEvt.bMouseUp; | |||
752 | if (bMouseDown) { | |||
753 | if (bMouseLeft) maDragStat.SetMouseDown(true); | |||
754 | } else if (bMouseUp) { | |||
755 | if (bMouseLeft) maDragStat.SetMouseDown(false); | |||
756 | } else { // else, MouseMove | |||
757 | maDragStat.SetMouseDown(bMouseLeft); | |||
758 | } | |||
759 | ||||
760 | #ifdef MODKEY_NoSnapbCtrl | |||
761 | SetSnapEnabled(!MODKEY_NoSnapbCtrl); | |||
762 | #endif | |||
763 | #ifdef MODKEY_OrthobShift | |||
764 | SetOrtho(MODKEY_OrthobShift!=IsOrthoDesired()); | |||
765 | #endif | |||
766 | #ifdef MODKEY_AngleSnapbShift | |||
767 | SetAngleSnapEnabled(MODKEY_AngleSnapbShift); | |||
768 | #endif | |||
769 | #ifdef MODKEY_CopyDragbCtrl | |||
770 | SetDragWithCopy(MODKEY_CopyDragbCtrl); | |||
771 | #endif | |||
772 | #ifdef MODKEY_CenterbAlt | |||
773 | SetCreate1stPointAsCenter(MODKEY_CenterbAlt); | |||
774 | SetResizeAtCenter(MODKEY_CenterbAlt); | |||
775 | SetCrookAtCenter(MODKEY_CenterbAlt); | |||
776 | #endif | |||
777 | if (bMouseLeft && bMouseDown && rVEvt.bIsTextEdit && (eHit==SdrHitKind::UnmarkedObject || eHit==SdrHitKind::NONE)) { | |||
778 | SdrEndTextEdit(); // User has clicked beneath object, exit edit mode. | |||
779 | // pHdl is invalid, then, that shouldn't matter, though, as we expect | |||
780 | // pHdl==NULL (because of eHit). | |||
781 | } | |||
782 | switch (rVEvt.eEvent) { | |||
783 | case SdrEventKind::NONE: bRet=false; break; | |||
784 | case SdrEventKind::TextEdit: bRet=false; break; // Events handled by the OutlinerView are not taken into account here. | |||
785 | case SdrEventKind::MoveAction: MovAction(aLogicPos); bRet=true; break; | |||
786 | case SdrEventKind::EndAction: EndAction(); bRet=true; break; | |||
787 | case SdrEventKind::BackAction: BckAction(); bRet=true; break; | |||
788 | case SdrEventKind::EndMark : EndAction(); bRet=true; break; | |||
789 | case SdrEventKind::BrkMark : { | |||
790 | BrkAction(); | |||
791 | if (!MarkObj(aLogicPos,mnHitTolLog,rVEvt.bAddMark)) { | |||
792 | // No object hit. Do the following: | |||
793 | // 1. deselect any selected glue points | |||
794 | // 2. deselect any selected polygon points | |||
795 | // 3. deselect any selected objects | |||
796 | if (!rVEvt.bAddMark) UnmarkAll(); | |||
797 | } | |||
798 | bRet=true; | |||
799 | } break; | |||
800 | case SdrEventKind::EndCreate: { // if necessary, MarkObj | |||
801 | SdrCreateCmd eCmd=SdrCreateCmd::NextPoint; | |||
802 | if (MODKEY_PolyPolybAlt) eCmd=SdrCreateCmd::NextObject; | |||
803 | if (rVEvt.nMouseClicks>1) eCmd=SdrCreateCmd::ForceEnd; | |||
804 | if (!EndCreateObj(eCmd)) { // Don't evaluate event for Create? -> Select | |||
805 | if (eHit==SdrHitKind::UnmarkedObject || eHit==SdrHitKind::TextEdit) { | |||
806 | MarkObj(rVEvt.pRootObj,rVEvt.pPV); | |||
807 | if (eHit==SdrHitKind::TextEdit) | |||
808 | { | |||
809 | bool bRet2(mpActualOutDev && OUTDEV_WINDOW == mpActualOutDev->GetOutDevType() && | |||
810 | SdrBeginTextEdit(rVEvt.pObj, rVEvt.pPV, static_cast<vcl::Window*>(mpActualOutDev.get()))); | |||
811 | ||||
812 | if(bRet2) | |||
813 | { | |||
814 | MouseEvent aMEvt(mpActualOutDev->LogicToPixel(aLogicPos), | |||
815 | 1,rVEvt.nMouseMode,rVEvt.nMouseCode,rVEvt.nMouseCode); | |||
816 | ||||
817 | OutlinerView* pOLV=GetTextEditOutlinerView(); | |||
818 | if (pOLV!=nullptr) { | |||
819 | pOLV->MouseButtonDown(aMEvt); // event for the Outliner, but without double-click | |||
820 | pOLV->MouseButtonUp(aMEvt); // event for the Outliner, but without double-click | |||
821 | } | |||
822 | } | |||
823 | } | |||
824 | bRet=true; // object is selected and (if necessary) TextEdit is started | |||
825 | } else bRet=false; // canceled Create, nothing else | |||
826 | } else bRet=true; // return true for EndCreate | |||
827 | } break; | |||
828 | case SdrEventKind::EndDrag: { | |||
829 | bRet=EndDragObj(IsDragWithCopy()); | |||
830 | ForceMarkedObjToAnotherPage(); // TODO: Undo+bracing missing! | |||
831 | } break; | |||
832 | case SdrEventKind::MarkObj: { // + (if applicable) BegDrag | |||
833 | if (!rVEvt.bAddMark) UnmarkAllObj(); | |||
834 | bool bUnmark=rVEvt.bUnmark; | |||
835 | if (rVEvt.bPrevNextMark) { | |||
836 | bRet=MarkNextObj(aLogicPos,mnHitTolLog,rVEvt.bMarkPrev); | |||
837 | } else { | |||
838 | SortMarkedObjects(); | |||
839 | const size_t nCount0=GetMarkedObjectCount(); | |||
840 | bRet=MarkObj(aLogicPos,mnHitTolLog,rVEvt.bAddMark); | |||
841 | SortMarkedObjects(); | |||
842 | const size_t nCount1=GetMarkedObjectCount(); | |||
843 | bUnmark=nCount1<nCount0; | |||
844 | } | |||
845 | if (!bUnmark) { | |||
846 | BegDragObj(aLogicPos,nullptr,nullptr,mnMinMovLog); | |||
847 | bRet=true; | |||
848 | } | |||
849 | } break; | |||
850 | case SdrEventKind::MarkPoint: { // + (if applicable) BegDrag | |||
851 | if (!rVEvt.bAddMark) UnmarkAllPoints(); | |||
852 | if (rVEvt.bPrevNextMark) { | |||
853 | MarkNextPoint(); | |||
854 | bRet=false; | |||
855 | } else { | |||
856 | bRet=MarkPoint(*rVEvt.pHdl,rVEvt.bUnmark); | |||
857 | } | |||
858 | if (!rVEvt.bUnmark && !rVEvt.bPrevNextMark) { | |||
859 | BegDragObj(aLogicPos,nullptr,rVEvt.pHdl,mnMinMovLog); | |||
860 | bRet=true; | |||
861 | } | |||
862 | } break; | |||
863 | case SdrEventKind::MarkGluePoint: { // + (if applicable) BegDrag | |||
864 | if (!rVEvt.bAddMark) UnmarkAllGluePoints(); | |||
865 | if (rVEvt.bPrevNextMark) { | |||
866 | MarkNextGluePoint(); | |||
867 | bRet=false; | |||
868 | } else { | |||
869 | bRet=MarkGluePoint(rVEvt.pObj,rVEvt.nGlueId,rVEvt.bUnmark); | |||
870 | } | |||
871 | if (!rVEvt.bUnmark && !rVEvt.bPrevNextMark) { | |||
872 | SdrHdl* pHdl=GetGluePointHdl(rVEvt.pObj,rVEvt.nGlueId); | |||
873 | BegDragObj(aLogicPos,nullptr,pHdl,mnMinMovLog); | |||
874 | bRet=true; | |||
875 | } | |||
876 | } break; | |||
877 | case SdrEventKind::BeginMark: bRet=BegMark(aLogicPos,rVEvt.bAddMark,rVEvt.bUnmark); break; | |||
878 | case SdrEventKind::BeginInsertObjPoint: bRet = BegInsObjPoint(aLogicPos, MODKEY_PolyPolybAlt); break; | |||
879 | case SdrEventKind::EndInsertObjPoint: { | |||
880 | SdrCreateCmd eCmd=SdrCreateCmd::NextPoint; | |||
881 | if (MODKEY_PolyPolybAlt) eCmd=SdrCreateCmd::NextObject; | |||
882 | if (rVEvt.nMouseClicks>1) eCmd=SdrCreateCmd::ForceEnd; | |||
883 | EndInsObjPoint(eCmd); | |||
884 | bRet=true; | |||
885 | } break; | |||
886 | case SdrEventKind::BeginInsertGluePoint: bRet=BegInsGluePoint(aLogicPos); break; | |||
887 | case SdrEventKind::BeginDragHelpline: bRet=BegDragHelpLine(rVEvt.nHlplIdx,rVEvt.pPV); break; | |||
888 | case SdrEventKind::BeginDragObj: bRet=BegDragObj(aLogicPos,nullptr,rVEvt.pHdl,mnMinMovLog); break; | |||
889 | case SdrEventKind::BeginCreateObj: { | |||
890 | if (nCurrentInvent==SdrInventor::Default && nCurrentIdent==OBJ_CAPTION) { | |||
891 | long nHgt=SdrEngineDefaults::GetFontHeight(); | |||
892 | bRet=BegCreateCaptionObj(aLogicPos,Size(5*nHgt,2*nHgt)); | |||
893 | } else bRet=BegCreateObj(aLogicPos); | |||
894 | } break; | |||
895 | case SdrEventKind::BeginMacroObj: { | |||
896 | BegMacroObj(aLogicPos,mnHitTolLog,rVEvt.pObj,rVEvt.pPV,static_cast<vcl::Window*>(mpActualOutDev.get())); | |||
897 | bRet=false; | |||
898 | } break; | |||
899 | case SdrEventKind::BeginTextEdit: { | |||
900 | if (!IsObjMarked(rVEvt.pObj)) { | |||
901 | UnmarkAllObj(); | |||
902 | MarkObj(rVEvt.pRootObj,rVEvt.pPV); | |||
903 | } | |||
904 | ||||
905 | bRet = mpActualOutDev && OUTDEV_WINDOW == mpActualOutDev->GetOutDevType()&& | |||
906 | SdrBeginTextEdit(rVEvt.pObj, rVEvt.pPV, static_cast<vcl::Window*>(mpActualOutDev.get())); | |||
907 | ||||
908 | if(bRet) | |||
909 | { | |||
910 | MouseEvent aMEvt(mpActualOutDev->LogicToPixel(aLogicPos), | |||
911 | 1,rVEvt.nMouseMode,rVEvt.nMouseCode,rVEvt.nMouseCode); | |||
912 | OutlinerView* pOLV=GetTextEditOutlinerView(); | |||
913 | if (pOLV!=nullptr) pOLV->MouseButtonDown(aMEvt); // event for the Outliner, but without double-click | |||
914 | } | |||
915 | } break; | |||
916 | default: break; | |||
917 | } // switch | |||
918 | if (bRet && mpActualOutDev && mpActualOutDev->GetOutDevType()==OUTDEV_WINDOW) { | |||
919 | vcl::Window* pWin=static_cast<vcl::Window*>(mpActualOutDev.get()); | |||
920 | // left mouse button pressed? | |||
921 | bool bLeftDown=(rVEvt.nMouseCode&MOUSE_LEFT(sal_uInt16(0x0001)))!=0 && rVEvt.bMouseDown; | |||
922 | // left mouse button released? | |||
923 | bool bLeftUp=(rVEvt.nMouseCode&MOUSE_LEFT(sal_uInt16(0x0001)))!=0 && rVEvt.bMouseUp; | |||
924 | // left mouse button pressed or held? | |||
925 | bool bLeftDown1=(rVEvt.nMouseCode&MOUSE_LEFT(sal_uInt16(0x0001)))!=0 && !rVEvt.bMouseUp; | |||
926 | pWin->SetPointer(GetPreferredPointer(rVEvt.aLogicPos,pWin, | |||
927 | rVEvt.nMouseCode & (KEY_SHIFT|KEY_MOD1|KEY_MOD2),bLeftDown1)); | |||
928 | bool bAction=IsAction(); | |||
929 | if (bLeftDown && bAction) | |||
930 | pWin->CaptureMouse(); | |||
931 | else if (bLeftUp || (rVEvt.bIsAction && !bAction)) | |||
932 | pWin->ReleaseMouse(); | |||
933 | } | |||
934 | return bRet; | |||
935 | } | |||
936 | ||||
937 | PointerStyle SdrView::GetPreferredPointer(const Point& rMousePos, const OutputDevice* pOut, sal_uInt16 nModifier, bool bLeftDown) const | |||
938 | { | |||
939 | // Actions | |||
940 | if (IsCreateObj()) | |||
941 | { | |||
942 | return pCurrentCreate->GetCreatePointer(); | |||
943 | } | |||
944 | if (mpCurrentSdrDragMethod) | |||
945 | { | |||
946 | return mpCurrentSdrDragMethod->GetSdrDragPointer(); | |||
947 | } | |||
948 | if (IsMarkObj() || IsMarkPoints() || IsMarkGluePoints() || IsSetPageOrg()) return PointerStyle::Arrow; | |||
949 | if (IsDragHelpLine()) return GetDraggedHelpLinePointer(); | |||
950 | if (IsMacroObj()) { | |||
951 | SdrObjMacroHitRec aHitRec; | |||
952 | aHitRec.aPos=pOut->LogicToPixel(rMousePos); | |||
953 | aHitRec.nTol=nMacroTol; | |||
954 | aHitRec.pVisiLayer=&pMacroPV->GetVisibleLayers(); | |||
955 | aHitRec.pPageView=pMacroPV; | |||
956 | return pMacroObj->GetMacroPointer(aHitRec); | |||
957 | } | |||
958 | ||||
959 | // TextEdit, ObjEdit, Macro | |||
960 | if (IsTextEdit() && (IsTextEditInSelectionMode() || IsTextEditHit(rMousePos))) | |||
961 | { | |||
962 | if(!pOut || IsTextEditInSelectionMode()) | |||
963 | { | |||
964 | if(pTextEditOutliner->IsVertical()) | |||
965 | return PointerStyle::TextVertical; | |||
966 | else | |||
967 | return PointerStyle::Text; | |||
968 | } | |||
969 | // Outliner should return something here... | |||
970 | Point aPos(pOut->LogicToPixel(rMousePos)); | |||
971 | PointerStyle aPointer(pTextEditOutlinerView->GetPointer(aPos)); | |||
972 | if (aPointer==PointerStyle::Arrow) | |||
973 | { | |||
974 | if(pTextEditOutliner->IsVertical()) | |||
975 | aPointer = PointerStyle::TextVertical; | |||
976 | else | |||
977 | aPointer = PointerStyle::Text; | |||
978 | } | |||
979 | return aPointer; | |||
980 | } | |||
981 | ||||
982 | SdrViewEvent aVEvt; | |||
983 | aVEvt.nMouseCode=(nModifier&(KEY_SHIFT|KEY_MOD1|KEY_MOD2))|MOUSE_LEFT(sal_uInt16(0x0001)); // to see what would happen on MouseLeftDown | |||
984 | aVEvt.bMouseDown=!bLeftDown; // What if ..? | |||
985 | aVEvt.bMouseUp=bLeftDown; // What if ..? | |||
986 | if (pOut!=nullptr) | |||
987 | const_cast<SdrView*>(this)->SetActualWin(pOut); | |||
988 | SdrHitKind eHit=PickAnything(rMousePos,aVEvt); | |||
989 | SdrEventKind eEvent=aVEvt.eEvent; | |||
990 | switch (eEvent) | |||
991 | { | |||
992 | case SdrEventKind::BeginCreateObj: | |||
993 | return aCurrentCreatePointer; | |||
994 | case SdrEventKind::MarkObj: | |||
995 | return PointerStyle::Move; | |||
996 | case SdrEventKind::BeginMark: | |||
997 | return PointerStyle::Arrow; | |||
998 | case SdrEventKind::MarkPoint: | |||
999 | case SdrEventKind::MarkGluePoint: | |||
1000 | return PointerStyle::MovePoint; | |||
1001 | case SdrEventKind::BeginInsertObjPoint: | |||
1002 | case SdrEventKind::BeginInsertGluePoint: | |||
1003 | return PointerStyle::Cross; | |||
1004 | case SdrEventKind::ExecuteUrl: | |||
1005 | return PointerStyle::RefHand; | |||
1006 | case SdrEventKind::BeginMacroObj: | |||
1007 | { | |||
1008 | SdrObjMacroHitRec aHitRec; | |||
1009 | aHitRec.aPos=aVEvt.aLogicPos; | |||
1010 | aHitRec.nTol=mnHitTolLog; | |||
1011 | aHitRec.pVisiLayer=&aVEvt.pPV->GetVisibleLayers(); | |||
1012 | aHitRec.pPageView=aVEvt.pPV; | |||
1013 | return aVEvt.pObj->GetMacroPointer(aHitRec); | |||
1014 | } | |||
1015 | default: break; | |||
1016 | } // switch | |||
1017 | ||||
1018 | switch(eHit) | |||
1019 | { | |||
1020 | case SdrHitKind::Cell: | |||
1021 | return PointerStyle::Arrow; | |||
1022 | case SdrHitKind::HelpLine : | |||
1023 | return aVEvt.pPV->GetHelpLines()[aVEvt.nHlplIdx].GetPointer(); | |||
1024 | case SdrHitKind::Gluepoint: | |||
1025 | return PointerStyle::MovePoint; | |||
1026 | case SdrHitKind::TextEdit : | |||
1027 | case SdrHitKind::TextEditObj: | |||
1028 | { | |||
1029 | SdrTextObj* pText = dynamic_cast< SdrTextObj* >( aVEvt.pObj ); | |||
1030 | if(pText && pText->HasText()) | |||
1031 | { | |||
1032 | OutlinerParaObject* pParaObj = pText->GetOutlinerParaObject(); | |||
1033 | if(pParaObj && pParaObj->IsVertical()) | |||
1034 | return PointerStyle::TextVertical; | |||
1035 | } | |||
1036 | return PointerStyle::Text; | |||
1037 | } | |||
1038 | default: break; | |||
1039 | } | |||
1040 | ||||
1041 | bool bMarkHit=eHit==SdrHitKind::MarkedObject; | |||
1042 | SdrHdl* pHdl=aVEvt.pHdl; | |||
1043 | // now check the pointers for dragging | |||
1044 | if (pHdl!=nullptr || bMarkHit) { | |||
1045 | SdrHdlKind eHdl= pHdl!=nullptr ? pHdl->GetKind() : SdrHdlKind::Move; | |||
1046 | bool bCorner=pHdl!=nullptr && pHdl->IsCornerHdl(); | |||
1047 | bool bVertex=pHdl!=nullptr && pHdl->IsVertexHdl(); | |||
1048 | bool bMov=eHdl==SdrHdlKind::Move; | |||
1049 | if (bMov && (meDragMode==SdrDragMode::Move || meDragMode==SdrDragMode::Resize || mbMarkedHitMovesAlways)) { | |||
1050 | if (!IsMoveAllowed()) return PointerStyle::Arrow; // because double click or drag & drop is possible | |||
1051 | return PointerStyle::Move; | |||
1052 | } | |||
1053 | switch (meDragMode) { | |||
1054 | case SdrDragMode::Rotate: { | |||
1055 | if ((bCorner || bMov) && !IsRotateAllowed(true)) | |||
1056 | return PointerStyle::NotAllowed; | |||
1057 | ||||
1058 | // are 3D objects selected? | |||
1059 | bool b3DObjSelected = false; | |||
1060 | for (size_t a=0; !b3DObjSelected && a<GetMarkedObjectCount(); ++a) { | |||
1061 | SdrObject* pObj = GetMarkedObjectByIndex(a); | |||
1062 | if(dynamic_cast<const E3dObject* >(pObj) != nullptr) | |||
1063 | b3DObjSelected = true; | |||
1064 | } | |||
1065 | // If we have a 3D object, go on despite !IsShearAllowed, | |||
1066 | // because then we have a rotation instead of a shear. | |||
1067 | if (bVertex && !IsShearAllowed() && !b3DObjSelected) | |||
1068 | return PointerStyle::NotAllowed; | |||
1069 | if (bMov) | |||
1070 | return PointerStyle::Rotate; | |||
1071 | } break; | |||
1072 | case SdrDragMode::Shear: { | |||
1073 | if (bCorner) { | |||
1074 | if (!IsDistortAllowed(true) && !IsDistortAllowed()) return PointerStyle::NotAllowed; | |||
1075 | else return PointerStyle::RefHand; | |||
1076 | } | |||
1077 | if (bVertex && !IsShearAllowed()) return PointerStyle::NotAllowed; | |||
1078 | if (bMov) { | |||
1079 | if (!IsMoveAllowed()) return PointerStyle::Arrow; // because double click or drag & drop is possible | |||
1080 | return PointerStyle::Move; | |||
1081 | } | |||
1082 | } break; | |||
1083 | case SdrDragMode::Mirror: { | |||
1084 | if (bCorner || bVertex || bMov) { | |||
1085 | SdrHdl* pH1=maHdlList.GetHdl(SdrHdlKind::Ref1); | |||
1086 | SdrHdl* pH2=maHdlList.GetHdl(SdrHdlKind::Ref2); | |||
1087 | bool b90=false; | |||
1088 | bool b45=false; | |||
1089 | if (pH1!=nullptr && pH2!=nullptr) { | |||
1090 | Point aDif = pH2->GetPos()-pH1->GetPos(); | |||
1091 | b90=(aDif.X()==0) || aDif.Y()==0; | |||
1092 | b45=b90 || (std::abs(aDif.X())==std::abs(aDif.Y())); | |||
1093 | } | |||
1094 | bool bNo=false; | |||
1095 | if (!IsMirrorAllowed(true,true)) bNo=true; // any mirroring is forbidden | |||
1096 | if (!IsMirrorAllowed() && !b45) bNo=true; // mirroring freely is forbidden | |||
1097 | if (!IsMirrorAllowed(true) && !b90) bNo=true; // mirroring horizontally/vertically is allowed | |||
1098 | if (bNo) return PointerStyle::NotAllowed; | |||
1099 | if (b90) { | |||
1100 | return PointerStyle::Mirror; | |||
1101 | } | |||
1102 | return PointerStyle::Mirror; | |||
1103 | } | |||
1104 | } break; | |||
1105 | ||||
1106 | case SdrDragMode::Transparence: | |||
1107 | { | |||
1108 | if(!IsTransparenceAllowed()) | |||
1109 | return PointerStyle::NotAllowed; | |||
1110 | ||||
1111 | return PointerStyle::RefHand; | |||
1112 | } | |||
1113 | ||||
1114 | case SdrDragMode::Gradient: | |||
1115 | { | |||
1116 | if(!IsGradientAllowed()) | |||
1117 | return PointerStyle::NotAllowed; | |||
1118 | ||||
1119 | return PointerStyle::RefHand; | |||
1120 | } | |||
1121 | ||||
1122 | case SdrDragMode::Crook: { | |||
1123 | if (bCorner || bVertex || bMov) { | |||
1124 | if (!IsCrookAllowed(true) && !IsCrookAllowed()) return PointerStyle::NotAllowed; | |||
1125 | return PointerStyle::Crook; | |||
1126 | } | |||
1127 | break; | |||
1128 | } | |||
1129 | ||||
1130 | case SdrDragMode::Crop: | |||
1131 | { | |||
1132 | return PointerStyle::Crop; | |||
1133 | } | |||
1134 | ||||
1135 | default: { | |||
1136 | if ((bCorner || bVertex) && !IsResizeAllowed(true)) return PointerStyle::NotAllowed; | |||
1137 | } | |||
1138 | } | |||
1139 | if (pHdl!=nullptr) return pHdl->GetPointer(); | |||
1140 | if (bMov) { | |||
1141 | if (!IsMoveAllowed()) return PointerStyle::Arrow; // because double click or drag & drop is possible | |||
1142 | return PointerStyle::Move; | |||
1143 | } | |||
1144 | } | |||
1145 | if (meEditMode==SdrViewEditMode::Create) return aCurrentCreatePointer; | |||
1146 | return PointerStyle::Arrow; | |||
1147 | } | |||
1148 | ||||
1149 | #define STR_NOTHING"nothing" "nothing" | |||
1150 | OUString SdrView::GetStatusText() | |||
1151 | { | |||
1152 | OUString aName; | |||
1153 | OUString aStr = STR_NOTHING"nothing"; | |||
1154 | ||||
1155 | if (pCurrentCreate!=nullptr) | |||
1156 | { | |||
1157 | aStr=pCurrentCreate->getSpecialDragComment(maDragStat); | |||
1158 | ||||
1159 | if(aStr.isEmpty()) | |||
1160 | { | |||
1161 | aName = pCurrentCreate->TakeObjNameSingul(); | |||
1162 | aStr = SvxResId(STR_ViewCreateObjreinterpret_cast<char const *>("STR_ViewCreateObj" "\004" u8"Create %1")); | |||
1163 | } | |||
1164 | } | |||
1165 | else if (mpCurrentSdrDragMethod) | |||
1166 | { | |||
1167 | if (mbInsPolyPoint || IsInsertGluePoint()) | |||
1168 | { | |||
1169 | aStr=maInsPointUndoStr; | |||
1170 | } | |||
1171 | else | |||
1172 | { | |||
1173 | if (maDragStat.IsMinMoved()) | |||
1174 | { | |||
1175 | SAL_INFO(do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "svx.svdraw")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "(" << this << ") " << mpCurrentSdrDragMethod.get()) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.svdraw"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "(" << this << ") " << mpCurrentSdrDragMethod.get()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "(" << this << ") " << mpCurrentSdrDragMethod.get(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.svdraw"), ( "/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "(" << this << ") " << mpCurrentSdrDragMethod .get()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("svx.svdraw"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "(" << this << ") " << mpCurrentSdrDragMethod.get()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "(" << this << ") " << mpCurrentSdrDragMethod.get(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.svdraw"), ( "/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1176 | "svx.svdraw",do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "svx.svdraw")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "(" << this << ") " << mpCurrentSdrDragMethod.get()) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.svdraw"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "(" << this << ") " << mpCurrentSdrDragMethod.get()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "(" << this << ") " << mpCurrentSdrDragMethod.get(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.svdraw"), ( "/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "(" << this << ") " << mpCurrentSdrDragMethod .get()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("svx.svdraw"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "(" << this << ") " << mpCurrentSdrDragMethod.get()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "(" << this << ") " << mpCurrentSdrDragMethod.get(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.svdraw"), ( "/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1177 | "(" << this << ") " << mpCurrentSdrDragMethod.get())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "svx.svdraw")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "(" << this << ") " << mpCurrentSdrDragMethod.get()) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.svdraw"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "(" << this << ") " << mpCurrentSdrDragMethod.get()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "(" << this << ") " << mpCurrentSdrDragMethod.get(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.svdraw"), ( "/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "(" << this << ") " << mpCurrentSdrDragMethod .get()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("svx.svdraw"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "(" << this << ") " << mpCurrentSdrDragMethod.get()), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "(" << this << ") " << mpCurrentSdrDragMethod.get(); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("svx.svdraw"), ( "/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1177" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1178 | aStr = mpCurrentSdrDragMethod->GetSdrDragComment(); | |||
1179 | } | |||
1180 | } | |||
1181 | } | |||
1182 | else if(IsMarkObj()) | |||
1183 | { | |||
1184 | if(AreObjectsMarked()) | |||
1185 | { | |||
1186 | aStr = SvxResId(STR_ViewMarkMoreObjsreinterpret_cast<char const *>("STR_ViewMarkMoreObjs" "\004" u8"Mark additional objects")); | |||
1187 | } | |||
1188 | else | |||
1189 | { | |||
1190 | aStr = SvxResId(STR_ViewMarkObjsreinterpret_cast<char const *>("STR_ViewMarkObjs" "\004" u8"Mark objects")); | |||
1191 | } | |||
1192 | } | |||
1193 | else if(IsMarkPoints()) | |||
1194 | { | |||
1195 | if(HasMarkedPoints()) | |||
1196 | { | |||
1197 | aStr = SvxResId(STR_ViewMarkMorePointsreinterpret_cast<char const *>("STR_ViewMarkMorePoints" "\004" u8"Mark additional points")); | |||
1198 | } | |||
1199 | else | |||
1200 | { | |||
1201 | aStr = SvxResId(STR_ViewMarkPointsreinterpret_cast<char const *>("STR_ViewMarkPoints" "\004" u8"Mark points")); | |||
1202 | } | |||
1203 | } else if (IsMarkGluePoints()) | |||
1204 | { | |||
1205 | if(HasMarkedGluePoints()) | |||
1206 | { | |||
1207 | aStr = SvxResId(STR_ViewMarkMoreGluePointsreinterpret_cast<char const *>("STR_ViewMarkMoreGluePoints" "\004" u8"Mark additional glue points")); | |||
1208 | } | |||
1209 | else | |||
1210 | { | |||
1211 | aStr = SvxResId(STR_ViewMarkGluePointsreinterpret_cast<char const *>("STR_ViewMarkGluePoints" "\004" u8"Mark glue points")); | |||
1212 | } | |||
1213 | } | |||
1214 | else if (IsTextEdit() && pTextEditOutlinerView!=nullptr) { | |||
1215 | aStr=SvxResId(STR_ViewTextEditreinterpret_cast<char const *>("STR_ViewTextEdit" "\004" u8"TextEdit: Paragraph %1, Row %2, Column %3")); // "TextEdit - Row y, Column x"; | |||
1216 | ESelection aSel(pTextEditOutlinerView->GetSelection()); | |||
1217 | long nPar=aSel.nEndPara,nLin=0,nCol=aSel.nEndPos; | |||
1218 | if (aSel.nEndPara>0) { | |||
1219 | for (sal_Int32 nParaNum=0; nParaNum<aSel.nEndPara; nParaNum++) { | |||
1220 | nLin+=pTextEditOutliner->GetLineCount(nParaNum); | |||
1221 | } | |||
1222 | } | |||
1223 | // A little imperfection: | |||
1224 | // At the end of a line of any multi-line paragraph, we display the | |||
1225 | // position of the next line of the same paragraph, if there is one. | |||
1226 | sal_uInt16 nParaLine = 0; | |||
1227 | sal_uLong nParaLineCount = pTextEditOutliner->GetLineCount(aSel.nEndPara); | |||
1228 | bool bBrk = false; | |||
1229 | while (!bBrk) | |||
1230 | { | |||
1231 | sal_uInt16 nLen = pTextEditOutliner->GetLineLen(aSel.nEndPara, nParaLine); | |||
1232 | bool bLastLine = (nParaLine == nParaLineCount - 1); | |||
1233 | if (nCol>nLen || (!bLastLine && nCol == nLen)) | |||
1234 | { | |||
1235 | nCol -= nLen; | |||
1236 | nLin++; | |||
1237 | nParaLine++; | |||
1238 | } | |||
1239 | else | |||
1240 | bBrk = true; | |||
1241 | ||||
1242 | if (nLen == 0) | |||
1243 | bBrk = true; // to be sure | |||
1244 | } | |||
1245 | ||||
1246 | aStr = aStr.replaceFirst("%1", OUString::number(nPar + 1)); | |||
1247 | aStr = aStr.replaceFirst("%2", OUString::number(nLin + 1)); | |||
1248 | aStr = aStr.replaceFirst("%3", OUString::number(nCol + 1)); | |||
1249 | ||||
1250 | #ifdef DBG_UTIL | |||
1251 | aStr += ", Level " + OUString::number( pTextEditOutliner->GetDepth( aSel.nEndPara ) ); | |||
1252 | #endif | |||
1253 | } | |||
1254 | ||||
1255 | if(aStr == STR_NOTHING"nothing") | |||
1256 | { | |||
1257 | if (AreObjectsMarked()) { | |||
1258 | aStr = ImpGetDescriptionString(STR_ViewMarkedreinterpret_cast<char const *>("STR_ViewMarked" "\004" u8"%1 selected" )); | |||
1259 | if (IsGluePointEditMode()) { | |||
1260 | if (HasMarkedGluePoints()) { | |||
1261 | aStr = ImpGetDescriptionString(STR_ViewMarkedreinterpret_cast<char const *>("STR_ViewMarked" "\004" u8"%1 selected" ), ImpGetDescriptionOptions::GLUEPOINTS); | |||
1262 | } | |||
1263 | } else { | |||
1264 | if (HasMarkedPoints()) { | |||
1265 | aStr = ImpGetDescriptionString(STR_ViewMarkedreinterpret_cast<char const *>("STR_ViewMarked" "\004" u8"%1 selected" ), ImpGetDescriptionOptions::POINTS); | |||
1266 | } | |||
1267 | } | |||
1268 | } else { | |||
1269 | aStr.clear(); | |||
1270 | } | |||
1271 | } | |||
1272 | else if(!aName.isEmpty()) | |||
1273 | { | |||
1274 | aStr = aStr.replaceFirst("%1", aName); | |||
1275 | } | |||
1276 | ||||
1277 | if(!aStr.isEmpty()) | |||
1278 | { | |||
1279 | // capitalize first letter | |||
1280 | aStr = aStr.replaceAt(0, 1, OUString(aStr[0]).toAsciiUpperCase()); | |||
1281 | } | |||
1282 | return aStr; | |||
1283 | } | |||
1284 | ||||
1285 | SdrViewContext SdrView::GetContext() const | |||
1286 | { | |||
1287 | if( IsGluePointEditMode() ) | |||
1288 | return SdrViewContext::GluePointEdit; | |||
1289 | ||||
1290 | const size_t nMarkCount = GetMarkedObjectCount(); | |||
1291 | ||||
1292 | if( HasMarkablePoints() && !IsFrameHandles() ) | |||
1293 | { | |||
1294 | bool bPath=true; | |||
1295 | for( size_t nMarkNum = 0; nMarkNum < nMarkCount && bPath; ++nMarkNum ) | |||
1296 | if (dynamic_cast<const SdrPathObj*>(GetMarkedObjectByIndex(nMarkNum)) == nullptr) | |||
1297 | bPath=false; | |||
1298 | ||||
1299 | if( bPath ) | |||
1300 | return SdrViewContext::PointEdit; | |||
1301 | } | |||
1302 | ||||
1303 | if( GetMarkedObjectCount() ) | |||
1304 | { | |||
1305 | bool bGraf = true, bMedia = true, bTable = true; | |||
1306 | ||||
1307 | for( size_t nMarkNum = 0; nMarkNum < nMarkCount && ( bGraf || bMedia ); ++nMarkNum ) | |||
1308 | { | |||
1309 | const SdrObject* pMarkObj = GetMarkedObjectByIndex( nMarkNum ); | |||
1310 | DBG_ASSERT( pMarkObj, "SdrView::GetContext(), null pointer in mark list!" )do { if (true && (!(pMarkObj))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" ":" "1310" ": "), "%s", "SdrView::GetContext(), null pointer in mark list!" ); } } while (false); | |||
1311 | ||||
1312 | if( !pMarkObj ) | |||
1313 | continue; | |||
1314 | ||||
1315 | if( dynamic_cast<const SdrGrafObj*>( pMarkObj) == nullptr ) | |||
1316 | bGraf = false; | |||
1317 | ||||
1318 | if( dynamic_cast<const SdrMediaObj*>( pMarkObj) == nullptr ) | |||
1319 | bMedia = false; | |||
1320 | ||||
1321 | if( dynamic_cast<const sdr::table::SdrTableObj* >( pMarkObj ) == nullptr ) | |||
1322 | bTable = false; | |||
1323 | } | |||
1324 | ||||
1325 | if( bGraf ) | |||
1326 | return SdrViewContext::Graphic; | |||
1327 | else if( bMedia ) | |||
1328 | return SdrViewContext::Media; | |||
1329 | else if( bTable ) | |||
1330 | return SdrViewContext::Table; | |||
1331 | } | |||
1332 | ||||
1333 | return SdrViewContext::Standard; | |||
1334 | } | |||
1335 | ||||
1336 | void SdrView::MarkAll() | |||
1337 | { | |||
1338 | if (IsTextEdit()) { | |||
1339 | GetTextEditOutlinerView()->SetSelection(ESelection(0,0,EE_PARA_ALL((sal_Int32) 0x7FFFFFFF),EE_TEXTPOS_ALL((sal_Int32) 0x7FFFFFFF))); | |||
1340 | } else if (IsGluePointEditMode()) MarkAllGluePoints(); | |||
1341 | else if (HasMarkablePoints()) MarkAllPoints(); | |||
1342 | else MarkAllObj(); | |||
1343 | } | |||
1344 | ||||
1345 | void SdrView::UnmarkAll() | |||
1346 | { | |||
1347 | if (IsTextEdit()) { | |||
1348 | ESelection eSel=GetTextEditOutlinerView()->GetSelection(); | |||
1349 | eSel.nStartPara=eSel.nEndPara; | |||
1350 | eSel.nStartPos=eSel.nEndPos; | |||
1351 | GetTextEditOutlinerView()->SetSelection(eSel); | |||
1352 | } else if (HasMarkedGluePoints()) UnmarkAllGluePoints(); | |||
1353 | else if (HasMarkedPoints()) UnmarkAllPoints(); // Marked, not Markable! | |||
1354 | else UnmarkAllObj(); | |||
1355 | } | |||
1356 | ||||
1357 | const tools::Rectangle& SdrView::GetMarkedRect() const | |||
1358 | { | |||
1359 | if (IsGluePointEditMode() && HasMarkedGluePoints()) { | |||
1360 | return GetMarkedGluePointsRect(); | |||
1361 | } | |||
1362 | if (HasMarkedPoints()) { | |||
1363 | return GetMarkedPointsRect(); | |||
1364 | } | |||
1365 | return GetMarkedObjRect(); | |||
1366 | } | |||
1367 | ||||
1368 | void SdrView::DeleteMarked() | |||
1369 | { | |||
1370 | if (IsTextEdit()) | |||
1371 | { | |||
1372 | SdrObjEditView::KeyInput(KeyEvent(0,vcl::KeyCode(KeyFuncType::DELETE)),pTextEditWin); | |||
1373 | } | |||
1374 | else | |||
1375 | { | |||
1376 | if( mxSelectionController.is() && mxSelectionController->DeleteMarked() ) | |||
1377 | { | |||
1378 | // action already performed by current selection controller, do nothing | |||
1379 | } | |||
1380 | else if (IsGluePointEditMode() && HasMarkedGluePoints()) | |||
1381 | { | |||
1382 | DeleteMarkedGluePoints(); | |||
1383 | } | |||
1384 | else if (GetContext()==SdrViewContext::PointEdit && HasMarkedPoints()) | |||
1385 | { | |||
1386 | DeleteMarkedPoints(); | |||
1387 | } | |||
1388 | else | |||
1389 | { | |||
1390 | DeleteMarkedObj(); | |||
1391 | } | |||
1392 | } | |||
1393 | } | |||
1394 | ||||
1395 | bool SdrView::BegMark(const Point& rPnt, bool bAddMark, bool bUnmark) | |||
1396 | { | |||
1397 | if (bUnmark) bAddMark=true; | |||
1398 | if (IsGluePointEditMode()) { | |||
1399 | if (!bAddMark) UnmarkAllGluePoints(); | |||
1400 | return BegMarkGluePoints(rPnt,bUnmark); | |||
1401 | } else if (HasMarkablePoints()) { | |||
1402 | if (!bAddMark) UnmarkAllPoints(); | |||
1403 | return BegMarkPoints(rPnt,bUnmark); | |||
1404 | } else { | |||
1405 | if (!bAddMark) UnmarkAllObj(); | |||
1406 | BegMarkObj(rPnt,bUnmark); | |||
1407 | return true; | |||
1408 | } | |||
1409 | } | |||
1410 | ||||
1411 | void SdrView::ConfigurationChanged( ::utl::ConfigurationBroadcaster*p, ConfigurationHints nHint) | |||
1412 | { | |||
1413 | onAccessibilityOptionsChanged(); | |||
1414 | SdrCreateView::ConfigurationChanged(p, nHint); | |||
1415 | } | |||
1416 | ||||
1417 | ||||
1418 | /** method is called whenever the global SvtAccessibilityOptions is changed */ | |||
1419 | void SdrView::onAccessibilityOptionsChanged() | |||
1420 | { | |||
1421 | } | |||
1422 | ||||
1423 | void SdrView::SetMasterPagePaintCaching(bool bOn) | |||
1424 | { | |||
1425 | if(mbMasterPagePaintCaching == bOn) | |||
1426 | return; | |||
1427 | ||||
1428 | mbMasterPagePaintCaching = bOn; | |||
1429 | ||||
1430 | // reset at all SdrPageWindows | |||
1431 | SdrPageView* pPageView = GetSdrPageView(); | |||
1432 | ||||
1433 | if(!pPageView) | |||
1434 | return; | |||
1435 | ||||
1436 | for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++) | |||
1437 | { | |||
1438 | SdrPageWindow* pPageWindow = pPageView->GetPageWindow(b); | |||
1439 | assert(pPageWindow && "SdrView::SetMasterPagePaintCaching: Corrupt SdrPageWindow list (!)")(static_cast <bool> (pPageWindow && "SdrView::SetMasterPagePaintCaching: Corrupt SdrPageWindow list (!)" ) ? void (0) : __assert_fail ("pPageWindow && \"SdrView::SetMasterPagePaintCaching: Corrupt SdrPageWindow list (!)\"" , "/home/maarten/src/libreoffice/core/svx/source/svdraw/svdview.cxx" , 1439, __extension__ __PRETTY_FUNCTION__)); | |||
1440 | ||||
1441 | // force deletion of ObjectContact, so at re-display all VOCs | |||
1442 | // will be re-created with updated flag setting | |||
1443 | pPageWindow->ResetObjectContact(); | |||
1444 | } | |||
1445 | ||||
1446 | // force redraw of this view | |||
1447 | pPageView->InvalidateAllWin(); | |||
1448 | } | |||
1449 | ||||
1450 | // Default ObjectContact is ObjectContactOfPageView | |||
1451 | sdr::contact::ObjectContact* SdrView::createViewSpecificObjectContact( | |||
1452 | SdrPageWindow& rPageWindow, | |||
1453 | const char* pDebugName) const | |||
1454 | { | |||
1455 | return new sdr::contact::ObjectContactOfPageView(rPageWindow, pDebugName); | |||
1456 | } | |||
1457 | ||||
1458 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |