Bug Summary

File:home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx
Warning:line 224, column 68
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name drawview.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SC_DLLIMPLEMENTATION -D SC_INFO_OSVERSION="LINUX" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/liborcus/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/clew/source/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sc/source/core/inc -I /home/maarten/src/libreoffice/core/sc/source/filter/inc -I /home/maarten/src/libreoffice/core/sc/source/ui/inc -I /home/maarten/src/libreoffice/core/sc/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sc/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx

/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx

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 <com/sun/star/embed/XEmbeddedObject.hpp>
21
22#include <svx/svditer.hxx>
23#include <svx/svdograf.hxx>
24#include <svx/svdogrp.hxx>
25#include <svx/svdoole2.hxx>
26#include <svx/svdouno.hxx>
27#include <svx/svdpage.hxx>
28#include <svx/svdpagv.hxx>
29#include <svx/svdundo.hxx>
30#include <svx/svdocapt.hxx>
31#include <svx/sdrpaintwindow.hxx>
32#include <sfx2/bindings.hxx>
33#include <sfx2/viewfrm.hxx>
34#include <svx/sdrundomanager.hxx>
35#include <svx/xfillit0.hxx>
36#include <svx/xbtmpit.hxx>
37#include <comphelper/lok.hxx>
38#include <sfx2/lokhelper.hxx>
39#include <LibreOfficeKit/LibreOfficeKitEnums.h>
40#include <svx/sdr/contact/objectcontactofpageview.hxx>
41#include <svx/sdr/contact/viewobjectcontact.hxx>
42#include <svx/sdr/contact/viewcontact.hxx>
43#include <svx/sdrpagewindow.hxx>
44
45#include <drawview.hxx>
46#include <global.hxx>
47#include <viewdata.hxx>
48#include <document.hxx>
49#include <drawutil.hxx>
50#include <globstr.hrc>
51#include <scresid.hxx>
52#include <tabvwsh.hxx>
53#include <client.hxx>
54#include <scmod.hxx>
55#include <drwlayer.hxx>
56#include <docsh.hxx>
57#include <viewuno.hxx>
58#include <userdat.hxx>
59#include <postit.hxx>
60#include <undocell.hxx>
61#include <gridwin.hxx>
62
63#include <sc.hrc>
64
65using namespace com::sun::star;
66
67#define SC_HANDLESIZE_BIG9 9
68
69void ScDrawView::Construct()
70{
71 EnableExtendedKeyInputDispatcher(false);
72 EnableExtendedMouseEventDispatcher(false);
73
74 SetFrameDragSingles();
75
76 SetMinMoveDistancePixel( 2 );
77 SetHitTolerancePixel( 2 );
78
79 if (pViewData)
80 {
81 SCTAB nViewTab = pViewData->GetTabNo();
82 ShowSdrPage(GetModel()->GetPage(nViewTab));
83
84 bool bEx = pViewData->GetViewShell()->IsDrawSelMode();
85 bool bProt = rDoc.IsTabProtected( nViewTab ) ||
86 pViewData->GetSfxDocShell()->IsReadOnly();
87
88 SdrLayer* pLayer;
89 SdrLayerAdmin& rAdmin = GetModel()->GetLayerAdmin();
90 pLayer = rAdmin.GetLayerPerID(SC_LAYER_BACK);
91 if (pLayer)
92 SetLayerLocked( pLayer->GetName(), bProt || !bEx );
93 pLayer = rAdmin.GetLayerPerID(SC_LAYER_INTERN);
94 if (pLayer)
95 SetLayerLocked( pLayer->GetName() );
96 pLayer = rAdmin.GetLayerPerID(SC_LAYER_FRONT);
97 if (pLayer)
98 {
99 SetLayerLocked( pLayer->GetName(), bProt );
100 SetActiveLayer( pLayer->GetName() ); // set active layer to FRONT
101 }
102 pLayer = rAdmin.GetLayerPerID(SC_LAYER_CONTROLS);
103 if (pLayer)
104 SetLayerLocked( pLayer->GetName(), bProt );
105 pLayer = rAdmin.GetLayerPerID(SC_LAYER_HIDDEN);
106 if (pLayer)
107 {
108 SetLayerLocked( pLayer->GetName(), bProt );
109 SetLayerVisible( pLayer->GetName(), false);
110 }
111
112 SetSwapAsynchron();
113 }
114 else
115 {
116 ShowSdrPage(GetModel()->GetPage(nTab));
117 }
118
119 UpdateUserViewOptions();
120 RecalcScale();
121 UpdateWorkArea();
122
123 bInConstruct = false;
124}
125
126void ScDrawView::ImplClearCalcDropMarker()
127{
128 pDropMarker.reset();
129}
130
131ScDrawView::~ScDrawView()
132{
133 ImplClearCalcDropMarker();
134}
135
136void ScDrawView::AddCustomHdl()
137{
138 const SdrMarkList &rMrkList = GetMarkedObjectList();
139 const size_t nCount = rMrkList.GetMarkCount();
140 for(size_t nPos=0; nPos<nCount; ++nPos )
141 {
142 SdrObject* pObj = rMrkList.GetMark(nPos)->GetMarkedSdrObj();
143 if (ScDrawObjData *pAnchor = ScDrawLayer::GetObjDataTab(pObj, nTab))
144 {
145 if (ScTabView* pView = pViewData->GetView())
146 pView->CreateAnchorHandles(maHdlList, pAnchor->maStart);
147 }
148 }
149}
150
151void ScDrawView::InvalidateAttribs()
152{
153 if (!pViewData) return;
154 SfxBindings& rBindings = pViewData->GetBindings();
155
156 // true status values:
157 rBindings.InvalidateAll( true );
158}
159
160void ScDrawView::InvalidateDrawTextAttrs()
161{
162 if (!pViewData) return;
163 SfxBindings& rBindings = pViewData->GetBindings();
164
165 // cjk/ctl font items have no configured slots,
166 // need no invalidate
167
168 rBindings.Invalidate( SID_ATTR_CHAR_FONT( 10000 + 7 ) );
169 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT( 10000 + 15 ) );
170 rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT( 10000 + 9 ) );
171 rBindings.Invalidate( SID_ATTR_CHAR_POSTURE( 10000 + 8 ) );
172 rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE( 10000 + 14 ) );
173 rBindings.Invalidate( SID_ULINE_VAL_NONE(10000 + 1195) );
174 rBindings.Invalidate( SID_ULINE_VAL_SINGLE(10000 + 1196) );
175 rBindings.Invalidate( SID_ULINE_VAL_DOUBLE(10000 + 1197) );
176 rBindings.Invalidate( SID_ULINE_VAL_DOTTED(10000 + 1198) );
177 rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE( ((10000 + 1499) + 1) + 68 ) );
178 rBindings.Invalidate( SID_ATTR_CHAR_COLOR( 10000 + 17 ) );
179 rBindings.Invalidate( SID_ATTR_CHAR_BACK_COLOR( 10000 + 1153 ) );
180 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_LEFT( 10000 + 28 ) );
181 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_RIGHT( 10000 + 29 ) );
182 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_BLOCK( 10000 + 31 ) );
183 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_CENTER( 10000 + 30 ));
184 rBindings.Invalidate( SID_ALIGNLEFT((((((((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22
)) + 20)) + 29)) + 20))+6)
);
185 rBindings.Invalidate( SID_ALIGNCENTERHOR((((((((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22
)) + 20)) + 29)) + 20))+8)
);
186 rBindings.Invalidate( SID_ALIGNRIGHT((((((((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22
)) + 20)) + 29)) + 20))+7)
);
187 rBindings.Invalidate( SID_ALIGNBLOCK((((((((((((((((((26000 + 200) + 20)) + 20)) + 20)) + 25)) + 22
)) + 20)) + 29)) + 20))+9)
);
188 rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_10( 10000 + 34 ) );
189 rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_15( 10000 + 35 ) );
190 rBindings.Invalidate( SID_ATTR_PARA_LINESPACE_20( 10000 + 36 ) );
191 rBindings.Invalidate( SID_SET_SUPER_SCRIPT( 10000 + 294 ) );
192 rBindings.Invalidate( SID_SET_SUB_SCRIPT( 10000 + 295 ) );
193 rBindings.Invalidate( SID_ATTR_CHAR_KERNING( 10000 + 18 ) );
194 rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT( 10000 + 13 ) );
195 rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED( 10000 + 10 ) );
196 rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT( 10000 + 907 ) );
197 rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM( 10000 + 908 ) );
198 rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT( 10000 + 950 ) );
199 rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT( 10000 + 951 ) );
200 rBindings.Invalidate( SID_TABLE_VERT_NONE( 10000 + 1075 ) );
201 rBindings.Invalidate( SID_TABLE_VERT_CENTER( 10000 + 1074 ) );
202 rBindings.Invalidate( SID_TABLE_VERT_BOTTOM( 10000 + 1073 ) );
203 // pseudo slots for Format menu
204 rBindings.Invalidate( SID_ALIGN_ANY_LEFT( 10000 + 1002 ) );
205 rBindings.Invalidate( SID_ALIGN_ANY_HCENTER( 10000 + 1003 ) );
206 rBindings.Invalidate( SID_ALIGN_ANY_RIGHT( 10000 + 1004 ) );
207 rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED( 10000 + 1005 ) );
208}
209
210void ScDrawView::SetMarkedToLayer( SdrLayerID nLayerNo )
211{
212 if (!AreObjectsMarked())
1
Calling 'SdrMarkView::AreObjectsMarked'
4
Returning from 'SdrMarkView::AreObjectsMarked'
5
Taking false branch
213 return;
214
215 // #i11702# use SdrUndoObjectLayerChange for undo
216 // STR_UNDO_SELATTR is "Attributes" - should use a different text later
217 BegUndo( ScResId( STR_UNDO_SELATTRreinterpret_cast<char const *>("STR_UNDO_SELATTR" "\004"
u8"Attributes")
) );
218
219 const SdrMarkList& rMark = GetMarkedObjectList();
220 const size_t nCount = rMark.GetMarkCount();
221 for (size_t i=0; i<nCount; ++i)
6
Assuming 'i' is < 'nCount'
7
Loop condition is true. Entering loop body
222 {
223 SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj();
8
'pObj' initialized here
224 if ( dynamic_cast<const SdrUnoObj*>( pObj) == nullptr && (pObj->GetLayer() != SC_LAYER_INTERN) )
9
Assuming pointer value is null
10
Called C++ object pointer is null
225 {
226 AddUndo( std::make_unique<SdrUndoObjectLayerChange>( *pObj, pObj->GetLayer(), nLayerNo) );
227 pObj->SetLayer( nLayerNo );
228 }
229 }
230
231 EndUndo();
232
233 // repaint is done in SetLayer
234
235 pViewData->GetDocShell()->SetDrawModified();
236
237 // check mark list now instead of later in a timer
238 CheckMarked();
239 MarkListHasChanged();
240}
241
242bool ScDrawView::HasMarkedControl() const
243{
244 SdrObjListIter aIter( GetMarkedObjectList() );
245 for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
246 if( dynamic_cast<const SdrUnoObj*>( pObj) != nullptr )
247 return true;
248 return false;
249}
250
251bool ScDrawView::HasMarkedInternal() const
252{
253 // internal objects should not be inside a group, but who knows...
254 SdrObjListIter aIter( GetMarkedObjectList() );
255 for( SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next() )
256 if( pObj->GetLayer() == SC_LAYER_INTERN )
257 return true;
258 return false;
259}
260
261void ScDrawView::UpdateWorkArea()
262{
263 SdrPage* pPage = GetModel()->GetPage(static_cast<sal_uInt16>(nTab));
264 if (pPage)
265 {
266 Size aPageSize( pPage->GetSize() );
267 tools::Rectangle aNewArea( Point(), aPageSize );
268 if ( aPageSize.Width() < 0 )
269 {
270 // RTL: from max.negative (left) to zero (right)
271 aNewArea.SetRight( 0 );
272 aNewArea.SetLeft( aPageSize.Width() + 1 );
273 }
274 SetWorkArea( aNewArea );
275 }
276 else
277 {
278 OSL_FAIL("Page not found")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx"
":" "278" ": "), "%s", "Page not found"); } } while (false)
;
279 }
280}
281
282void ScDrawView::DoCut()
283{
284 DoCopy();
285 BegUndo( ScResId( STR_UNDO_CUTreinterpret_cast<char const *>("STR_UNDO_CUT" "\004" u8"Cut"
)
) );
286 DeleteMarked(); // In this View - not affected by 505f change
287 EndUndo();
288}
289
290void ScDrawView::GetScale( Fraction& rFractX, Fraction& rFractY ) const
291{
292 rFractX = aScaleX;
293 rFractY = aScaleY;
294}
295
296void ScDrawView::RecalcScale()
297{
298 double nPPTX;
299 double nPPTY;
300 Fraction aZoomX(1,1);
301 Fraction aZoomY(1,1);
302
303 if (pViewData)
304 {
305 nTab = pViewData->GetTabNo();
306 nPPTX = pViewData->GetPPTX();
307 nPPTY = pViewData->GetPPTY();
308 aZoomX = pViewData->GetZoomX();
309 aZoomY = pViewData->GetZoomY();
310 }
311 else
312 {
313 Point aLogic = pDev->LogicToPixel(Point(1000,1000), MapMode(MapUnit::MapTwip));
314 nPPTX = aLogic.X() / 1000.0;
315 nPPTY = aLogic.Y() / 1000.0;
316 //! Zoom, handed over ???
317 }
318
319 SCCOL nEndCol = 0;
320 SCROW nEndRow = 0;
321 rDoc.GetTableArea( nTab, nEndCol, nEndRow );
322 if (nEndCol<20)
323 nEndCol = 20;
324 if (nEndRow<20)
325 nEndRow = 20;
326
327 ScDrawUtil::CalcScale(
328 rDoc, nTab, 0, 0, nEndCol, nEndRow, pDev, aZoomX, aZoomY, nPPTX, nPPTY,
329 aScaleX, aScaleY);
330
331 // clear all evtl existing GridOffset vectors
332 resetGridOffsetsForAllSdrPageViews();
333
334 SdrPageView* pPV = GetSdrPageView();
335 if ( !(pViewData && pPV) )
336 return;
337
338 if ( SdrPage* pPage = pPV->GetPage() )
339 {
340 const size_t nCount = pPage->GetObjCount();
341 for ( size_t i = 0; i < nCount; ++i )
342 {
343 SdrObject* pObj = pPage->GetObj( i );
344 // Align objects to nearest grid position
345 SyncForGrid( pObj );
346 }
347 }
348}
349
350void ScDrawView::DoConnect(SdrOle2Obj* pOleObj)
351{
352 if ( pViewData )
353 pViewData->GetViewShell()->ConnectObject( pOleObj );
354}
355
356void ScDrawView::MarkListHasChanged()
357{
358 FmFormView::MarkListHasChanged();
359
360 ScTabViewShell* pViewSh = pViewData->GetViewShell();
361
362 // #i110829# remove the cell selection only if drawing objects are selected
363 if ( !bInConstruct && GetMarkedObjectList().GetMarkCount() )
364 {
365 pViewSh->Unmark(); // remove cell selection
366
367 // end cell edit mode if drawing objects are selected
368 SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
->InputEnterHandler();
369 }
370
371 // deactivate IP
372
373 ScModule* pScMod = SC_MOD()( static_cast<ScModule*>(SfxApplication::GetModule(SfxToolsModule
::Calc)) )
;
374 bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF((20000 +5000)+20);
375
376 ScClient* pClient = static_cast<ScClient*>( pViewSh->GetIPClient() );
377 if ( pClient && pClient->IsObjectInPlaceActive() && !bUnoRefDialog )
378 {
379 // do not display the handles for ViewShell::Activate from the Reset2Open
380 pClient->DeactivateObject();
381 // replacing image ole graphics is now done in ScClient::UIActivate
382 }
383
384 // Select Ole object?
385
386 SdrOle2Obj* pOle2Obj = nullptr;
387 SdrGrafObj* pGrafObj = nullptr;
388
389 const SdrMarkList& rMarkList = GetMarkedObjectList();
390 const size_t nMarkCount = rMarkList.GetMarkCount();
391
392 if ( nMarkCount == 0 && !pViewData->GetViewShell()->IsDrawSelMode() && !bInConstruct )
393 {
394 // relock layers that may have been unlocked before
395 LockBackgroundLayer(true);
396 LockInternalLayer();
397 }
398
399 bool bSubShellSet = false;
400 if (nMarkCount == 1)
401 {
402 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
403 if (pObj->GetObjIdentifier() == OBJ_OLE2)
404 {
405 pOle2Obj = static_cast<SdrOle2Obj*>(pObj);
406 if (!ScDocument::IsChart(pObj) )
407 pViewSh->SetOleObjectShell(true);
408 else
409 pViewSh->SetChartShell(true);
410 bSubShellSet = true;
411 }
412 else if (pObj->GetObjIdentifier() == OBJ_GRAF)
413 {
414 pGrafObj = static_cast<SdrGrafObj*>(pObj);
415 pViewSh->SetGraphicShell(true);
416 bSubShellSet = true;
417 }
418 else if (pObj->GetObjIdentifier() == OBJ_MEDIA)
419 {
420 pViewSh->SetMediaShell(true);
421 bSubShellSet = true;
422 }
423 else if (pObj->GetObjIdentifier() != OBJ_TEXT // prevent switching to the drawing shell
424 || !pViewSh->IsDrawTextShell()) // when creating a text object @#70206#
425 {
426 pViewSh->SetDrawShell(true);
427 }
428 }
429
430 if ( nMarkCount && !bSubShellSet )
431 {
432 bool bOnlyControls = true;
433 bool bOnlyGraf = true;
434 for (size_t i=0; i<nMarkCount; ++i)
435 {
436 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
437 if ( dynamic_cast<const SdrObjGroup*>( pObj) != nullptr )
438 {
439 const SdrObjList *pLst = static_cast<SdrObjGroup*>(pObj)->GetSubList();
440 const size_t nListCount = pLst->GetObjCount();
441 if ( nListCount == 0 )
442 {
443 // An empty group (may occur during Undo) is no control or graphics object.
444 // Creating the form shell during undo would lead to problems with the undo manager.
445 bOnlyControls = false;
446 bOnlyGraf = false;
447 }
448 for ( size_t j = 0; j < nListCount; ++j )
449 {
450 SdrObject *pSubObj = pLst->GetObj( j );
451
452 if (dynamic_cast<const SdrUnoObj*>( pSubObj) == nullptr)
453 bOnlyControls = false;
454 if (pSubObj->GetObjIdentifier() != OBJ_GRAF)
455 bOnlyGraf = false;
456
457 if ( !bOnlyControls && !bOnlyGraf ) break;
458 }
459 }
460 else
461 {
462 if (dynamic_cast<const SdrUnoObj*>( pObj) == nullptr)
463 bOnlyControls = false;
464 if (pObj->GetObjIdentifier() != OBJ_GRAF)
465 bOnlyGraf = false;
466 }
467
468 if ( !bOnlyControls && !bOnlyGraf ) break;
469 }
470
471 if(bOnlyControls)
472 {
473 pViewSh->SetDrawFormShell(true); // now UNO controls
474 }
475 else if(bOnlyGraf)
476 {
477 pViewSh->SetGraphicShell(true);
478 }
479 else if(nMarkCount>1)
480 {
481 pViewSh->SetDrawShell(true);
482 }
483 }
484
485 // adjust verbs
486
487 SfxViewFrame* pViewFrame = pViewSh->GetViewFrame();
488 bool bOle = pViewSh->GetViewFrame()->GetFrame().IsInPlace();
489 uno::Sequence< embed::VerbDescriptor > aVerbs;
490 if ( pOle2Obj && !bOle )
491 {
492 const uno::Reference < embed::XEmbeddedObject >& xObj = pOle2Obj->GetObjRef();
493 OSL_ENSURE( xObj.is(), "SdrOle2Obj without ObjRef" )do { if (true && (!(xObj.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx"
":" "493" ": "), "%s", "SdrOle2Obj without ObjRef"); } } while
(false)
;
494 if (xObj.is())
495 aVerbs = xObj->getSupportedVerbs();
496 }
497 pViewSh->SetVerbs( aVerbs );
498
499 // image map editor
500
501 if ( pOle2Obj )
502 UpdateIMap( pOle2Obj );
503 else if ( pGrafObj )
504 UpdateIMap( pGrafObj );
505
506 InvalidateAttribs(); // after the image map editor update
507 InvalidateDrawTextAttrs();
508
509 for(sal_uInt32 a(0); a < PaintWindowCount(); a++)
510 {
511 SdrPaintWindow* pPaintWindow = GetPaintWindow(a);
512 OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
513
514 if(OUTDEV_WINDOW == rOutDev.GetOutDevType())
515 {
516 static_cast<vcl::Window&>(rOutDev).PaintImmediately();
517 }
518 }
519
520 // uno object for view returns drawing objects as selection,
521 // so it must notify its SelectionChangeListeners
522
523 if (pViewFrame)
524 {
525 SfxFrame& rFrame = pViewFrame->GetFrame();
526 uno::Reference<frame::XController> xController = rFrame.GetController();
527 if (xController.is())
528 {
529 ScTabViewObj* pImp = comphelper::getUnoTunnelImplementation<ScTabViewObj>( xController );
530 if (pImp)
531 pImp->SelectionChanged();
532 }
533 }
534
535 // update selection transfer object
536
537 pViewSh->CheckSelectionTransfer();
538
539}
540
541bool ScDrawView::SdrBeginTextEdit(
542 SdrObject* pObj,
543 SdrPageView* pPV,
544 vcl::Window* pWinL,
545 bool bIsNewObj,
546 SdrOutliner* pGivenOutliner,
547 OutlinerView* pGivenOutlinerView,
548 bool bDontDeleteOutliner,
549 bool bOnlyOneView,
550 bool bGrabFocus )
551{
552 const bool bRet = FmFormView::SdrBeginTextEdit(
553 pObj, pPV, pWinL, bIsNewObj,
554 pGivenOutliner, pGivenOutlinerView, bDontDeleteOutliner,
555 bOnlyOneView, bGrabFocus );
556
557 ScTabViewShell* pViewSh = pViewData->GetViewShell();
558
559 if (comphelper::LibreOfficeKit::isActive())
560 {
561 if (OutlinerView* pView = GetTextEditOutlinerView())
562 {
563 tools::Rectangle aRectangle = pView->GetOutputArea();
564 if (pWinL && pWinL->GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
565 aRectangle = OutputDevice::LogicToLogic(aRectangle, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip));
566 OString sRectangle = aRectangle.toString();
567 SfxLokHelper::notifyOtherViews(pViewSh, LOK_CALLBACK_VIEW_LOCK, "rectangle", sRectangle);
568 }
569 }
570
571 if ( pViewSh->GetViewFrame() )
572 {
573 SfxFrame& rFrame = pViewSh->GetViewFrame()->GetFrame();
574 uno::Reference< frame::XController > xController = rFrame.GetController();
575 if (xController.is())
576 {
577 ScTabViewObj* pImp = comphelper::getUnoTunnelImplementation<ScTabViewObj>( xController );
578 if (pImp)
579 pImp->SelectionChanged();
580 }
581 }
582
583 return bRet;
584}
585
586SdrEndTextEditKind ScDrawView::SdrEndTextEdit( bool bDontDeleteReally )
587{
588 const SdrEndTextEditKind eRet = FmFormView::SdrEndTextEdit( bDontDeleteReally );
589
590 ScTabViewShell* pViewSh = pViewData->GetViewShell();
591
592 if (comphelper::LibreOfficeKit::isActive())
593 SfxLokHelper::notifyOtherViews(pViewSh, LOK_CALLBACK_VIEW_LOCK, "rectangle", "EMPTY");
594
595 if ( pViewSh->GetViewFrame() )
596 {
597 SfxFrame& rFrame = pViewSh->GetViewFrame()->GetFrame();
598 uno::Reference< frame::XController > xController = rFrame.GetController();
599 if (xController.is())
600 {
601 ScTabViewObj* pImp = comphelper::getUnoTunnelImplementation<ScTabViewObj>( xController );
602 if (pImp)
603 pImp->SelectionChanged();
604 }
605 }
606
607 return eRet;
608}
609
610void ScDrawView::ModelHasChanged()
611{
612 SdrObject* pEditObj = GetTextEditObject();
613 if ( pEditObj && !pEditObj->IsInserted() && pViewData )
614 {
615 // SdrObjEditView::ModelHasChanged will end text edit in this case,
616 // so make sure the EditEngine's undo manager is no longer used.
617 pViewData->GetViewShell()->SetDrawTextUndo(nullptr);
618 SetCreateMode(); // don't leave FuText in a funny state
619 }
620
621 FmFormView::ModelHasChanged();
622}
623
624void ScDrawView::UpdateUserViewOptions()
625{
626 if (!pViewData)
627 return;
628
629 const ScViewOptions& rOpt = pViewData->GetOptions();
630 const ScGridOptions& rGrid = rOpt.GetGridOptions();
631
632 SetDragStripes( rOpt.GetOption( VOPT_HELPLINES ) );
633 SetMarkHdlSizePixel( SC_HANDLESIZE_BIG9 );
634
635 SetGridVisible( rGrid.GetGridVisible() );
636 SetSnapEnabled( rGrid.GetUseGridSnap() );
637 SetGridSnap( rGrid.GetUseGridSnap() );
638
639 Fraction aFractX( rGrid.GetFieldDrawX(), rGrid.GetFieldDivisionX() + 1 );
640 Fraction aFractY( rGrid.GetFieldDrawY(), rGrid.GetFieldDivisionY() + 1 );
641 SetSnapGridWidth( aFractX, aFractY );
642
643 SetGridCoarse( Size( rGrid.GetFieldDrawX(), rGrid.GetFieldDrawY() ) );
644 SetGridFine( Size( rGrid.GetFieldDrawX() / (rGrid.GetFieldDivisionX() + 1),
645 rGrid.GetFieldDrawY() / (rGrid.GetFieldDivisionY() + 1) ) );
646}
647
648SdrObject* ScDrawView::GetObjectByName(const OUString& rName)
649{
650 SfxObjectShell* pShell = rDoc.GetDocumentShell();
651 if (pShell)
652 {
653 SdrModel* pDrawLayer = GetModel();
654 sal_uInt16 nTabCount = rDoc.GetTableCount();
655 for (sal_uInt16 i=0; i<nTabCount; i++)
656 {
657 SdrPage* pPage = pDrawLayer->GetPage(i);
658 DBG_ASSERT(pPage,"Page ?")do { if (true && (!(pPage))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx"
":" "658" ": "), "%s", "Page ?"); } } while (false)
;
659 if (pPage)
660 {
661 SdrObjListIter aIter( pPage, SdrIterMode::DeepNoGroups );
662 SdrObject* pObject = aIter.Next();
663 while (pObject)
664 {
665 if ( ScDrawLayer::GetVisibleName( pObject ) == rName )
666 {
667 return pObject;
668 }
669 pObject = aIter.Next();
670 }
671 }
672 }
673 }
674 return nullptr;
675}
676
677//realize multi-selection of objects
678
679void ScDrawView::SelectCurrentViewObject( const OUString& rName )
680{
681 sal_uInt16 nObjectTab = 0;
682 SdrObject* pFound = nullptr;
683 SfxObjectShell* pShell = rDoc.GetDocumentShell();
684 if (pShell)
685 {
686 SdrModel* pDrawLayer = GetModel();
687 sal_uInt16 nTabCount = rDoc.GetTableCount();
688 for (sal_uInt16 i=0; i<nTabCount && !pFound; i++)
689 {
690 SdrPage* pPage = pDrawLayer->GetPage(i);
691 DBG_ASSERT(pPage,"Page ?")do { if (true && (!(pPage))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx"
":" "691" ": "), "%s", "Page ?"); } } while (false)
;
692 if (pPage)
693 {
694 SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
695 SdrObject* pObject = aIter.Next();
696 while (pObject && !pFound)
697 {
698 if ( ScDrawLayer::GetVisibleName( pObject ) == rName )
699 {
700 pFound = pObject;
701 nObjectTab = i;
702 }
703 pObject = aIter.Next();
704 }
705 }
706 }
707 }
708 if ( !pFound )
709 return;
710
711 ScTabView* pView = pViewData->GetView();
712 if ( nObjectTab != nTab ) // switch sheet
713 pView->SetTabNo( nObjectTab );
714 DBG_ASSERT( nTab == nObjectTab, "Switching sheets did not work" )do { if (true && (!(nTab == nObjectTab))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx"
":" "714" ": "), "%s", "Switching sheets did not work"); } }
while (false)
;
715 pView->ScrollToObject( pFound );
716 if ( pFound->GetLayer() == SC_LAYER_BACK &&
717 !pViewData->GetViewShell()->IsDrawSelMode() &&
718 !rDoc.IsTabProtected( nTab ) &&
719 !pViewData->GetSfxDocShell()->IsReadOnly() )
720 {
721 SdrLayer* pLayer = GetModel()->GetLayerAdmin().GetLayerPerID(SC_LAYER_BACK);
722 if (pLayer)
723 SetLayerLocked( pLayer->GetName(), false );
724 }
725 SdrPageView* pPV = GetSdrPageView();
726 const bool bUnMark = IsObjMarked(pFound);
727 MarkObj( pFound, pPV, bUnMark);
728}
729
730bool ScDrawView::SelectObject( const OUString& rName )
731{
732 UnmarkAll();
733
734 SCTAB nObjectTab = 0;
735 SdrObject* pFound = nullptr;
736
737 SfxObjectShell* pShell = rDoc.GetDocumentShell();
738 if (pShell)
739 {
740 SdrModel* pDrawLayer = GetModel();
741 SCTAB nTabCount = rDoc.GetTableCount();
742 for (SCTAB i=0; i<nTabCount && !pFound; i++)
743 {
744 SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(i));
745 OSL_ENSURE(pPage,"Page ?")do { if (true && (!(pPage))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx"
":" "745" ": "), "%s", "Page ?"); } } while (false)
;
746 if (pPage)
747 {
748 SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
749 SdrObject* pObject = aIter.Next();
750 while (pObject && !pFound)
751 {
752 if ( ScDrawLayer::GetVisibleName( pObject ) == rName )
753 {
754 pFound = pObject;
755 nObjectTab = i;
756 }
757 pObject = aIter.Next();
758 }
759 }
760 }
761 }
762
763 if ( pFound )
764 {
765 ScTabView* pView = pViewData->GetView();
766 if ( nObjectTab != nTab ) // switch sheet
767 pView->SetTabNo( nObjectTab );
768
769 OSL_ENSURE( nTab == nObjectTab, "Switching sheets did not work" )do { if (true && (!(nTab == nObjectTab))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx"
":" "769" ": "), "%s", "Switching sheets did not work"); } }
while (false)
;
770
771 pView->ScrollToObject( pFound );
772
773 /* To select an object on the background layer, the layer has to
774 be unlocked even if exclusive drawing selection mode is not active
775 (this is reversed in MarkListHasChanged when nothing is selected) */
776 if ( pFound->GetLayer() == SC_LAYER_BACK &&
777 !pViewData->GetViewShell()->IsDrawSelMode() &&
778 !rDoc.IsTabProtected( nTab ) &&
779 !pViewData->GetSfxDocShell()->IsReadOnly() )
780 {
781 LockBackgroundLayer(false);
782 }
783
784 SdrPageView* pPV = GetSdrPageView();
785 MarkObj( pFound, pPV );
786 }
787
788 return ( pFound != nullptr );
789}
790
791//If object is marked , return true , else return false .
792bool ScDrawView::GetObjectIsMarked( const SdrObject* pObject )
793{
794 bool bisMarked = false;
795 if (pObject )
796 {
797 bisMarked = IsObjMarked(pObject);
798 }
799 return bisMarked;
800}
801
802bool ScDrawView::InsertObjectSafe(SdrObject* pObj, SdrPageView& rPV)
803{
804 SdrInsertFlags nOptions=SdrInsertFlags::NONE;
805 // Do not change marks when the ole object is active
806 // (for Drop from ole object would otherwise be deactivated in the middle of ExecuteDrag!)
807
808 if (pViewData)
809 {
810 SfxInPlaceClient* pClient = pViewData->GetViewShell()->GetIPClient();
811 if ( pClient && pClient->IsObjectInPlaceActive() )
812 nOptions |= SdrInsertFlags::DONTMARK;
813 }
814
815 return InsertObjectAtView(pObj, rPV, nOptions);
816}
817
818SdrObject* ScDrawView::GetMarkedNoteCaption( ScDrawObjData** ppCaptData )
819{
820 const SdrMarkList& rMarkList = GetMarkedObjectList();
821 if( pViewData && (rMarkList.GetMarkCount() == 1) )
822 {
823 SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
824 if( ScDrawObjData* pCaptData = ScDrawLayer::GetNoteCaptionData( pObj, pViewData->GetTabNo() ) )
825 {
826 if( ppCaptData ) *ppCaptData = pCaptData;
827 return pObj;
828 }
829 }
830 return nullptr;
831}
832
833void ScDrawView::LockCalcLayer( SdrLayerID nLayer, bool bLock )
834{
835 SdrLayer* pLockLayer = GetModel()->GetLayerAdmin().GetLayerPerID( nLayer );
836 if( pLockLayer && (IsLayerLocked( pLockLayer->GetName() ) != bLock) )
837 SetLayerLocked( pLockLayer->GetName(), bLock );
838}
839
840void ScDrawView::MakeVisible( const tools::Rectangle& rRect, vcl::Window& rWin )
841{
842 //! Evaluate rWin properly
843 //! change zoom if necessary
844
845 if ( pViewData && pViewData->GetActiveWin() == &rWin )
846 pViewData->GetView()->MakeVisible( rRect );
847}
848
849SfxViewShell* ScDrawView::GetSfxViewShell() const
850{
851 return pViewData->GetViewShell();
852}
853
854void ScDrawView::DeleteMarked()
855{
856 // try to delete a note caption object with its cell note in the Calc document
857 ScDrawObjData* pCaptData = nullptr;
858 if( SdrObject* pCaptObj = GetMarkedNoteCaption( &pCaptData ) )
859 {
860 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
861 ScDocShell* pDocShell = pViewData ? pViewData->GetDocShell() : nullptr;
862 SfxUndoManager* pUndoMgr = pDocShell ? pDocShell->GetUndoManager() : nullptr;
863 bool bUndo = pDrawLayer && pDocShell && pUndoMgr && rDoc.IsUndoEnabled();
864
865 // remove the cell note from document, we are its owner now
866 std::unique_ptr<ScPostIt> pNote = rDoc.ReleaseNote( pCaptData->maStart );
867 OSL_ENSURE( pNote, "ScDrawView::DeleteMarked - cell note missing in document" )do { if (true && (!(pNote))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx"
":" "867" ": "), "%s", "ScDrawView::DeleteMarked - cell note missing in document"
); } } while (false)
;
868 if( pNote )
869 {
870 // rescue note data for undo (with pointer to caption object)
871 ScNoteData aNoteData = pNote->GetNoteData();
872 OSL_ENSURE( aNoteData.mxCaption.get() == pCaptObj, "ScDrawView::DeleteMarked - caption object does not match" )do { if (true && (!(aNoteData.mxCaption.get() == pCaptObj
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx"
":" "872" ": "), "%s", "ScDrawView::DeleteMarked - caption object does not match"
); } } while (false)
;
873 // collect the drawing undo action created while deleting the note
874 if( bUndo )
875 pDrawLayer->BeginCalcUndo(false);
876 // delete the note (already removed from document above)
877 pNote.reset();
878 // add the undo action for the note
879 if( bUndo )
880 pUndoMgr->AddUndoAction( std::make_unique<ScUndoReplaceNote>( *pDocShell, pCaptData->maStart, aNoteData, false, pDrawLayer->GetCalcUndo() ) );
881 // repaint the cell to get rid of the note marker
882 if( pDocShell )
883 pDocShell->PostPaintCell( pCaptData->maStart );
884 // done, return now to skip call of FmFormView::DeleteMarked()
885 return;
886 }
887 }
888
889 FmFormView::DeleteMarked();
890}
891
892SdrEndTextEditKind ScDrawView::ScEndTextEdit()
893{
894 bool bIsTextEdit = IsTextEdit();
895 SdrEndTextEditKind eKind = SdrEndTextEdit();
896
897 if (bIsTextEdit)
898 pViewData->GetViewShell()->SetDrawTextUndo(nullptr); // the "normal" undo manager
899
900 return eKind;
901}
902
903void ScDrawView::MarkDropObj( SdrObject* pObj )
904{
905 if ( pDropMarkObj != pObj )
906 {
907 pDropMarkObj = pObj;
908 ImplClearCalcDropMarker();
909
910 if(pDropMarkObj)
911 {
912 pDropMarker.reset( new SdrDropMarkerOverlay(*this, *pDropMarkObj) );
913 }
914 }
915}
916
917// In order to counteract the effects of rounding due to the nature of how the
918// grid positions are calculated and drawn we calculate the offset needed at the
919// current zoom to be applied to an SrdObject when it is drawn in order to make
920// sure that it's position relative to the nearest cell anchor doesn't change.
921// Of course not all shape(s)/control(s) are cell anchored, if the
922// object doesn't have a cell anchor we synthesise a temporary anchor.
923void ScDrawView::SyncForGrid( SdrObject* pObj )
924{
925 // process members of a group shape separately
926 if ( dynamic_cast<const SdrObjGroup*>( pObj) != nullptr )
927 {
928 SdrObjList *pLst = static_cast<SdrObjGroup*>(pObj)->GetSubList();
929 for ( size_t i = 0, nCount = pLst->GetObjCount(); i < nCount; ++i )
930 SyncForGrid( pLst->GetObj( i ) );
931 }
932
933 ScSplitPos eWhich = pViewData->GetActivePart();
934 ScGridWindow* pGridWin = pViewData->GetActiveWin();
935 ScDrawObjData* pData = ScDrawLayer::GetObjData( pObj );
936 if ( !pGridWin )
937 return;
938
939 ScAddress aOldStt;
940 if( pData && pData->maStart.IsValid())
941 {
942 aOldStt = pData->maStart;
943 }
944 else
945 {
946 // Page anchored object so...
947 // synthesise an anchor ( but don't attach it to
948 // the object as we want to maintain page anchoring )
949 ScDrawObjData aAnchor;
950 const tools::Rectangle aObjRect(pObj->GetLogicRect());
951 ScDrawLayer::GetCellAnchorFromPosition(
952 aObjRect,
953 aAnchor,
954 rDoc,
955 GetTab());
956 aOldStt = aAnchor.maStart;
957 }
958 MapMode aDrawMode = pGridWin->GetDrawMapMode();
959 // find pos anchor position
960 Point aOldPos( rDoc.GetColOffset( aOldStt.Col(), aOldStt.Tab() ), rDoc.GetRowOffset( aOldStt.Row(), aOldStt.Tab() ) );
961 aOldPos.setX( sc::TwipsToHMM( aOldPos.X() ) );
962 aOldPos.setY( sc::TwipsToHMM( aOldPos.Y() ) );
963 // find position of same point on the screen ( e.g. grid )
964 Point aCurPos = pViewData->GetScrPos( aOldStt.Col(), aOldStt.Row(), eWhich, true );
965 Point aCurPosHmm = pGridWin->PixelToLogic(aCurPos, aDrawMode );
966 Point aGridOff = aCurPosHmm - aOldPos;
967 // fdo#63878 Fix the X position for RTL Sheet
968 if( rDoc.IsNegativePage( GetTab() ) )
969 aGridOff.setX( aCurPosHmm.getX() + aOldPos.getX() );
970}
971
972void ScDrawView::resetGridOffsetsForAllSdrPageViews()
973{
974 SdrPageView* pPageView(GetSdrPageView());
975
976 if(nullptr == pPageView)
977 return;
978
979 for(sal_uInt32 a(0); a < pPageView->PageWindowCount(); a++)
980 {
981 SdrPageWindow* pPageWindow(pPageView->GetPageWindow(a));
982 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/sc/source/ui/view/drawview.cxx"
, 982, __extension__ __PRETTY_FUNCTION__))
;
983
984 if(nullptr != pPageWindow)
985 {
986 sdr::contact::ObjectContact& rObjectContact(pPageWindow->GetObjectContact());
987
988 if(rObjectContact.supportsGridOffsets())
989 {
990 rObjectContact.resetAllGridOffsets();
991 }
992 }
993 }
994}
995
996bool ScDrawView::calculateGridOffsetForSdrObject(
997 SdrObject& rSdrObject,
998 basegfx::B2DVector& rTarget) const
999{
1000 if (comphelper::LibreOfficeKit::isActive() &&
1001 !comphelper::LibreOfficeKit::isCompatFlagSet(
1002 comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs))
1003 return false;
1004
1005 ScGridWindow* pGridWin(pViewData->GetActiveWin());
1006
1007 if(nullptr == pGridWin)
1008 {
1009 return false;
1010 }
1011
1012 ScDrawObjData* pData(ScDrawLayer::GetObjData(&rSdrObject));
1013 ScAddress aOldStt;
1014
1015 if(nullptr != pData && pData->maStart.IsValid())
1016 {
1017 aOldStt = pData->maStart;
1018 }
1019 else
1020 {
1021 // Page anchored object so...
1022 // synthesise an anchor ( but don't attach it to
1023 // the object as we want to maintain page anchoring )
1024 ScDrawObjData aAnchor;
1025 const tools::Rectangle aObjRect(rSdrObject.GetLogicRect());
1026 ScDrawLayer::GetCellAnchorFromPosition(
1027 aObjRect,
1028 aAnchor,
1029 rDoc,
1030 GetTab());
1031 aOldStt = aAnchor.maStart;
1032 }
1033
1034 MapMode aDrawMode = pGridWin->GetDrawMapMode();
1035
1036 // find pos anchor position
1037 Point aOldPos(rDoc.GetColOffset(aOldStt.Col(), aOldStt.Tab()), rDoc.GetRowOffset(aOldStt.Row(), aOldStt.Tab()));
1038 aOldPos.setX(sc::TwipsToHMM(aOldPos.X()));
1039 aOldPos.setY(sc::TwipsToHMM(aOldPos.Y()));
1040
1041 // find position of same point on the screen ( e.g. grid )
1042 ScSplitPos eWhich(pViewData->GetActivePart());
1043 Point aCurPos(pViewData->GetScrPos(aOldStt.Col(), aOldStt.Row(), eWhich, true));
1044 Point aCurPosHmm(pGridWin->PixelToLogic(aCurPos, aDrawMode));
1045 Point aGridOff(aCurPosHmm - aOldPos);
1046
1047 // fdo#63878 Fix the X position for RTL Sheet
1048 if(rDoc.IsNegativePage(GetTab()))
1049 {
1050 aGridOff.setX(aCurPosHmm.getX() + aOldPos.getX());
1051 }
1052
1053 rTarget.setX(aGridOff.X());
1054 rTarget.setY(aGridOff.Y());
1055 return true;
1056}
1057
1058bool ScDrawView::calculateGridOffsetForB2DRange(
1059 const basegfx::B2DRange& rB2DRange,
1060 basegfx::B2DVector& rTarget) const
1061{
1062 ScGridWindow* pGridWin(pViewData->GetActiveWin());
1063
1064 if(nullptr == pGridWin || rB2DRange.isEmpty())
1065 {
1066 return false;
1067 }
1068
1069 // No SdrObject, so synthesise an anchor ( but don't attach it to
1070 // the object as we want to maintain page anchoring )
1071 ScDrawObjData aAnchor;
1072 const tools::Rectangle aRectangle(
1073 basegfx::fround(rB2DRange.getMinX()), basegfx::fround(rB2DRange.getMinY()),
1074 basegfx::fround(rB2DRange.getMaxX()), basegfx::fround(rB2DRange.getMaxY()));
1075 ScDrawLayer::GetCellAnchorFromPosition(
1076 aRectangle,
1077 aAnchor,
1078 rDoc,
1079 GetTab());
1080 ScAddress aOldStt(aAnchor.maStart);
1081
1082 MapMode aDrawMode = pGridWin->GetDrawMapMode();
1083
1084 // find pos anchor position
1085 Point aOldPos(rDoc.GetColOffset(aOldStt.Col(), aOldStt.Tab()), rDoc.GetRowOffset(aOldStt.Row(), aOldStt.Tab()));
1086 aOldPos.setX(sc::TwipsToHMM(aOldPos.X()));
1087 aOldPos.setY(sc::TwipsToHMM(aOldPos.Y()));
1088
1089 // find position of same point on the screen ( e.g. grid )
1090 ScSplitPos eWhich(pViewData->GetActivePart());
1091 Point aCurPos(pViewData->GetScrPos(aOldStt.Col(), aOldStt.Row(), eWhich, true));
1092 Point aCurPosHmm(pGridWin->PixelToLogic(aCurPos, aDrawMode));
1093 Point aGridOff(aCurPosHmm - aOldPos);
1094
1095 // fdo#63878 Fix the X position for RTL Sheet
1096 if(rDoc.IsNegativePage(GetTab()))
1097 {
1098 aGridOff.setX(aCurPosHmm.getX() + aOldPos.getX());
1099 }
1100
1101 rTarget.setX(aGridOff.X());
1102 rTarget.setY(aGridOff.Y());
1103 return true;
1104}
1105
1106// support enhanced text edit for draw objects
1107SdrUndoManager* ScDrawView::getSdrUndoManagerForEnhancedTextEdit() const
1108{
1109 return dynamic_cast<SdrUndoManager*>(rDoc.GetUndoManager());
1110}
1111
1112// #i123922# helper to apply a Graphic to an existing SdrObject
1113SdrObject* ScDrawView::ApplyGraphicToObject(
1114 SdrObject& rHitObject,
1115 const Graphic& rGraphic,
1116 const OUString& rBeginUndoText,
1117 const OUString& rFile,
1118 const OUString& rFilter)
1119{
1120 if(dynamic_cast< SdrGrafObj* >(&rHitObject))
1121 {
1122 SdrGrafObj* pNewGrafObj(static_cast<SdrGrafObj*>(rHitObject.CloneSdrObject(rHitObject.getSdrModelFromSdrObject())));
1123
1124 pNewGrafObj->SetGraphic(rGraphic);
1125 BegUndo(rBeginUndoText);
1126 ReplaceObjectAtView(&rHitObject, *GetSdrPageView(), pNewGrafObj);
1127
1128 // set in all cases - the Clone() will have copied an existing link (!)
1129 pNewGrafObj->SetGraphicLink( rFile, ""/*TODO?*/, rFilter );
1130
1131 EndUndo();
1132 return pNewGrafObj;
1133 }
1134 else if(rHitObject.IsClosedObj() && !dynamic_cast< SdrOle2Obj* >(&rHitObject))
1135 {
1136 AddUndo(std::make_unique<SdrUndoAttrObj>(rHitObject));
1137
1138 SfxItemSet aSet(GetModel()->GetItemPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLBITMAP>{});
1139
1140 aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
1141 aSet.Put(XFillBitmapItem(OUString(), rGraphic));
1142 rHitObject.SetMergedItemSetAndBroadcast(aSet);
1143 return &rHitObject;
1144 }
1145
1146 return nullptr;
1147}
1148
1149// Own derivation of ObjectContact to allow on-demand calculation of
1150// GridOffset for non-linear ViewToDevice transformation (calc)
1151namespace sdr::contact
1152{
1153 namespace {
1154
1155 class ObjectContactOfScDrawView final : public ObjectContactOfPageView
1156 {
1157 private:
1158 // The ScDrawView to work on
1159 const ScDrawView& mrScDrawView;
1160
1161 public:
1162 explicit ObjectContactOfScDrawView(
1163 const ScDrawView& rScDrawView,
1164 SdrPageWindow& rPageWindow,
1165 const char* pDebugName);
1166
1167 virtual bool supportsGridOffsets() const override;
1168 virtual void calculateGridOffsetForViewOjectContact(
1169 basegfx::B2DVector& rTarget,
1170 const ViewObjectContact& rClient) const override;
1171 virtual void calculateGridOffsetForB2DRange(
1172 basegfx::B2DVector& rTarget,
1173 const basegfx::B2DRange& rB2DRange) const override;
1174 };
1175
1176 }
1177
1178 ObjectContactOfScDrawView::ObjectContactOfScDrawView(
1179 const ScDrawView& rScDrawView,
1180 SdrPageWindow& rPageWindow,
1181 const char* pDebugName)
1182 : ObjectContactOfPageView(rPageWindow, pDebugName),
1183 mrScDrawView(rScDrawView)
1184 {
1185 }
1186
1187 bool ObjectContactOfScDrawView::supportsGridOffsets() const
1188 {
1189 // Except when scPrintTwipsMsgs flag is active,
1190 // Calc in LOK mode directly sets pixel-aligned logical coordinates for draw-objects.
1191 if (comphelper::LibreOfficeKit::isActive() &&
1192 !comphelper::LibreOfficeKit::isCompatFlagSet(
1193 comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs))
1194 return false;
1195
1196 // no GridOffset support for printer
1197 if(isOutputToPrinter())
1198 {
1199 return false;
1200 }
1201
1202 // no GridOffset support for PDF export
1203 if(isOutputToPDFFile())
1204 {
1205 return false;
1206 }
1207
1208 // yes - we support it
1209 return true;
1210 }
1211
1212 void ObjectContactOfScDrawView::calculateGridOffsetForViewOjectContact(
1213 basegfx::B2DVector& rTarget,
1214 const ViewObjectContact& rClient) const
1215 {
1216 // Here the on-demand calculation happens. Try to access the SdrObject involved
1217 SdrObject* pTargetSdrObject(rClient.GetViewContact().TryToGetSdrObject());
1218
1219 if(nullptr != pTargetSdrObject)
1220 {
1221 mrScDrawView.calculateGridOffsetForSdrObject(
1222 *pTargetSdrObject,
1223 rTarget);
1224 }
1225 }
1226
1227 void ObjectContactOfScDrawView::calculateGridOffsetForB2DRange(
1228 basegfx::B2DVector& rTarget,
1229 const basegfx::B2DRange& rB2DRange) const
1230 {
1231 // Here the on-demand calculation happens. Try to access the SdrObject involved
1232 if(!rB2DRange.isEmpty())
1233 {
1234 mrScDrawView.calculateGridOffsetForB2DRange(
1235 rB2DRange,
1236 rTarget);
1237 }
1238 }
1239}
1240
1241// Create own derivation of ObjectContact for calc
1242sdr::contact::ObjectContact* ScDrawView::createViewSpecificObjectContact(
1243 SdrPageWindow& rPageWindow,
1244 const char* pDebugName) const
1245{
1246 return new sdr::contact::ObjectContactOfScDrawView(
1247 *this,
1248 rPageWindow,
1249 pDebugName);
1250}
1251
1252/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/svx/svdmrkv.hxx

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_SVDMRKV_HXX
21#define INCLUDED_SVX_SVDMRKV_HXX
22
23#include <svx/svdmark.hxx>
24#include <svx/svdhdl.hxx>
25#include <svx/svdsnpv.hxx>
26#include <svx/svdtypes.hxx>
27#include <svx/svxdllapi.h>
28#include <o3tl/typed_flags_set.hxx>
29#include <basegfx/range/b2drectangle.hxx>
30
31
32class SfxViewShell;
33
34// The following is not yet implemented, or just partially:
35enum class SdrSearchOptions
36{
37 NONE = 0x0000,
38 DEEP = 0x0001, /* recursive into group objects */
39 ALSOONMASTER = 0x0002, /* MasterPages are also scanned */
40 WHOLEPAGE = 0x0004, /* Not just the ObjList of PageView */
41 TESTMARKABLE = 0x0008, /* just markable objects/points/handles/... */
42 TESTMACRO = 0x0010, /* Just objects with macro */
43 TESTTEXTEDIT = 0x0020, /* Just TextEdit-enabled objects */
44 MARKED = 0x0040, /* Just marked objects/points/... */
45 PASS2BOUND = 0x0080, /* In case of empty search results, then 2nd. try with BoundRectHit */
46 BEFOREMARK = 0x0100, /* if one marked one found, ignore all behind that */
47
48 IMPISMASTER = 0x0200, /* MasterPage is being searched right now */
49 PICKMARKABLE = TESTMARKABLE,
50 PICKTEXTEDIT = DEEP | TESTMARKABLE | TESTTEXTEDIT,
51 PICKMACRO = DEEP | ALSOONMASTER | WHOLEPAGE | TESTMACRO,
52};
53namespace o3tl
54{
55 template<> struct typed_flags<SdrSearchOptions> : is_typed_flags<SdrSearchOptions, 0x03ff> {};
56}
57
58enum class SdrHitKind
59{
60 NONE, // No hit
61 Object, // Hit
62 Handle, // Marking handle
63 HelpLine, // Reference line
64 Gluepoint, // Glue point
65 TextEdit, // Open OutlinerView was hit
66 TextEditObj, // Object for SdrBeginTextEdit (Textbereich)
67 UrlField, // Field in TextObj was hit (while it is currently not edited)
68 Macro, // Object for BegMacroObj
69 MarkedObject, // Marked object (e.g. for dragging)
70 UnmarkedObject, // non-marked Object (e.g. for marking)
71 Cell // hit on a cell inside a table shape (outside of the cells text area)
72};
73
74enum class SdrViewEditMode {
75 Edit, // Also known as arrow or pointer mode
76 Create, // Tool for object creation
77 GluePointEdit // Glue point editing mode
78};
79
80/** options for ImpGetDescriptionString() */
81enum class ImpGetDescriptionOptions
82{
83 NONE = 0,
84 POINTS = 1,
85 GLUEPOINTS = 2,
86};
87
88class ImplMarkingOverlay;
89class MarkingSubSelectionOverlay;
90
91class SVXCORE_DLLPUBLIC__attribute__ ((visibility("default"))) SdrMarkView : public SdrSnapView
92{
93 friend class SdrPageView;
94
95 // #114409#-3 Migrate selections
96 std::unique_ptr<ImplMarkingOverlay> mpMarkObjOverlay;
97 std::unique_ptr<ImplMarkingOverlay> mpMarkPointsOverlay;
98 std::unique_ptr<ImplMarkingOverlay> mpMarkGluePointsOverlay;
99
100 std::unique_ptr<MarkingSubSelectionOverlay> mpMarkingSubSelectionOverlay;
101
102protected:
103 SdrObject* mpMarkedObj; // If not just one object ( i.e. More than one object ) is marked.
104 SdrPageView* mpMarkedPV; // If all marked objects are situated on the same PageView.
105
106 Point maRef1; // Persistent - Rotation center / axis of reflection
107 Point maRef2; // Persistent
108 SdrHdlList maHdlList;
109
110 sdr::ViewSelection maSdrViewSelection;
111
112 std::vector<basegfx::B2DRectangle> maSubSelectionList;
113 tools::Rectangle maMarkedObjRect;
114 tools::Rectangle maMarkedPointsRect;
115 tools::Rectangle maMarkedGluePointsRect;
116
117 static constexpr sal_uInt16 mnFrameHandlesLimit = 50;
118
119 SdrDragMode meDragMode; // Persistent
120 SdrViewEditMode meEditMode; // Persistent
121 SdrViewEditMode meEditMode0; // Persistent
122
123 bool mbDesignMode : 1; // DesignMode for SdrUnoObj
124 bool mbForceFrameHandles : 1; // Persistent - FrameDrag also for single objects
125 bool mbPlusHdlAlways : 1; // Persistent
126 bool mbInsPolyPoint : 1; // at this time InsPolyPointDragging
127 bool mbMarkedObjRectDirty : 1;
128 bool mbMrkPntDirty : 1;
129 bool mbMarkedPointsRectsDirty : 1;
130
131 // flag to completely disable handles at the view
132 bool mbMarkHandlesHidden : 1;
133
134 // Helper to get a possible GridOffset from SdrObject
135 bool getPossibleGridOffsetForSdrObject(
136 basegfx::B2DVector& rOffset,
137 const SdrObject* pObj,
138 const SdrPageView* pPV) const;
139
140 // Helper to get a possible GridOffset from Position
141 bool getPossibleGridOffsetForPosition(
142 basegfx::B2DVector& rOffset,
143 const basegfx::B2DPoint& rPoint,
144 const SdrPageView* pPV) const;
145
146private:
147 SVX_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImpSetPointsRects() const;
148 void UndirtyMrkPnt() const;
149
150 void SetMarkHandlesForLOKit(tools::Rectangle const & rRect, const SfxViewShell* pOtherShell);
151
152protected:
153 virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
154 virtual void ModelHasChanged() override; // Is called by the PaintView
155 virtual void SetMarkHandles(SfxViewShell* pOtherShell); // maHdlList - fill (List of handles)
156 void SetMarkRects(); // Rects at the PageViews
157 void CheckMarked(); // Scan MarkList after Del and Lock Layer ...
158 void AddDragModeHdl(SdrDragMode eMode);
159 virtual bool MouseMove(const MouseEvent& rMEvt, OutputDevice* pWin) override;
160 virtual bool RequestHelp(const HelpEvent& rHEvt) override;
161
162 // add custom handles (used by other apps, e.g. AnchorPos)
163 virtual void AddCustomHdl();
164
165 void ForceRefToMarked();
166 void ForceUndirtyMrkPnt() const { if (mbMrkPntDirty) UndirtyMrkPnt(); }
167
168 virtual SdrObject* CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, SdrSearchOptions nOptions, const SdrLayerIDSet* pMVisLay) const;
169 SdrObject* CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObjList const * pOL, SdrPageView* pPV, SdrSearchOptions nOptions, const SdrLayerIDSet* pMVisLay, SdrObject*& rpRootObj) const;
170 SdrObject* CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObjList const * pOL, SdrPageView* pPV, SdrSearchOptions nOptions, const SdrLayerIDSet* pMVisLay, SdrObject*& rpRootObj,const SdrMarkList * pMarkList) const;
171 bool ImpIsFrameHandles() const;
172 OUString ImpGetDescriptionString(const char* pStrCacheID, ImpGetDescriptionOptions nOpt=ImpGetDescriptionOptions::NONE) const;
173
174 // Generates a string including degrees symbol, from an angel specification in 1/100deg
175 bool ImpMarkPoint(SdrHdl* pHdl, SdrMark* pMark, bool bUnmark);
176 virtual bool MarkPoints(const tools::Rectangle* pRect, bool bUnmark);
177 bool MarkGluePoints(const tools::Rectangle* pRect, bool bUnmark);
178
179 void SetMoveOutside(bool bOn);
180 bool MarkableObjectsExceed( int n ) const;
181
182protected:
183 // #i71538# make constructors of SdrView sub-components protected to avoid incomplete incarnations which may get casted to SdrView
184 SdrMarkView(
185 SdrModel& rSdrModel,
186 OutputDevice* pOut);
187
188 virtual ~SdrMarkView() override;
189
190public:
191 virtual bool IsAction() const override;
192 virtual void MovAction(const Point& rPnt) override;
193 virtual void EndAction() override;
194 virtual void BckAction() override;
195 virtual void BrkAction() override;
196 virtual void TakeActionRect(tools::Rectangle& rRect) const override;
197
198 virtual void ClearPageView() override;
199 virtual void HideSdrPage() override;
200 bool IsObjMarkable(SdrObject const * pObj, SdrPageView const * pPV) const;
201
202 // Returns sal_True if objects, points or glue points are selected by drawing a frame
203 // (as long as the frame is drawn).
204 bool IsMarking() const { return IsMarkObj() || IsMarkPoints() || IsMarkGluePoints(); }
205
206 // Marking objects by drawing of a selection frame
207 void BegMarkObj(const Point& rPnt, bool bUnmark = false);
208 void MovMarkObj(const Point& rPnt);
209 bool EndMarkObj();
210 void BrkMarkObj();
211 bool IsMarkObj() const { return (nullptr != mpMarkObjOverlay); }
212
213 // DragModes: SDRDRAG_CREATE,SdrDragMode::Move,SdrDragMode::Resize,SdrDragMode::Rotate,SdrDragMode::Mirror,SdrDragMode::Shear,SdrDragMode::Crook
214 // Move==Resize
215 // The interface might maybe be changed in the future because of Ortho-Drag
216 void SetDragMode(SdrDragMode eMode);
217 SdrDragMode GetDragMode() const { return meDragMode; }
218 void SetFrameHandles(bool bOn);
219 bool IsFrameHandles() const { return mbForceFrameHandles; }
220
221 // returns true if number of markable objects is greater than 1
222 bool HasMultipleMarkableObjects() const { return MarkableObjectsExceed(1); };
223
224 void SetEditMode(SdrViewEditMode eMode);
225 SdrViewEditMode GetEditMode() const { return meEditMode; }
226
227 void SetEditMode(bool bOn) { SetEditMode(bOn?SdrViewEditMode::Edit:SdrViewEditMode::Create); }
228 bool IsEditMode() const { return meEditMode==SdrViewEditMode::Edit; }
229 void SetCreateMode(bool bOn) { SetEditMode(bOn?SdrViewEditMode::Create:SdrViewEditMode::Edit); }
230 bool IsCreateMode() const { return meEditMode==SdrViewEditMode::Create; }
231 void SetGluePointEditMode(bool bOn) { SetEditMode(bOn?SdrViewEditMode::GluePointEdit:meEditMode0); }
232 bool IsGluePointEditMode() const { return meEditMode==SdrViewEditMode::GluePointEdit; }
233
234 void SetDesignMode(bool bOn = true);
235 bool IsDesignMode() const { return mbDesignMode; }
236
237 void SetFrameDragSingles(bool bOn=true) { SetFrameHandles(bOn); }
238 bool IsFrameDragSingles() const { return IsFrameHandles(); }
239
240 bool HasMarkableObj() const { return MarkableObjectsExceed(0); };
241
242
243// migrate selections
244
245protected:
246 // all available changing methods
247 SdrMarkList& GetMarkedObjectListWriteAccess() { return maSdrViewSelection.GetMarkedObjectListWriteAccess(); }
248
249public:
250 // all available const methods for read access to selection
251 const SdrMarkList& GetMarkedObjectList() const { return maSdrViewSelection.GetMarkedObjectList(); }
252 // returns SAL_MAX_SIZE if not found
253 size_t TryToFindMarkedObject(const SdrObject* pObj) const { return GetMarkedObjectList().FindObject(pObj); }
254 SdrPageView* GetSdrPageViewOfMarkedByIndex(size_t nNum) const { return GetMarkedObjectList().GetMark(nNum)->GetPageView(); }
255 SdrMark* GetSdrMarkByIndex(size_t nNum) const { return GetMarkedObjectList().GetMark(nNum); }
256 SdrObject* GetMarkedObjectByIndex(size_t nNum) const { return GetMarkedObjectList().GetMark(nNum)->GetMarkedSdrObj(); }
257 size_t GetMarkedObjectCount() const { return GetMarkedObjectList().GetMarkCount(); }
258 void SortMarkedObjects() const { GetMarkedObjectList().ForceSort(); }
259 bool AreObjectsMarked() const { return 0 != GetMarkedObjectList().GetMarkCount(); }
2
Assuming the condition is true
3
Returning the value 1, which participates in a condition later
260 OUString const & GetDescriptionOfMarkedObjects() const { return GetMarkedObjectList().GetMarkDescription(); }
261 OUString const & GetDescriptionOfMarkedPoints() const { return GetMarkedObjectList().GetPointMarkDescription(); }
262 OUString const & GetDescriptionOfMarkedGluePoints() const { return GetMarkedObjectList().GetGluePointMarkDescription(); }
263
264 // Get a list of all those links which are connected to marked nodes,
265 // but which are not marked themselves.
266 const SdrMarkList& GetEdgesOfMarkedNodes() const { return maSdrViewSelection.GetEdgesOfMarkedNodes(); }
267 const SdrMarkList& GetMarkedEdgesOfMarkedNodes() const { return maSdrViewSelection.GetMarkedEdgesOfMarkedNodes(); }
268 const std::vector<SdrObject*>& GetTransitiveHullOfMarkedObjects() const { return maSdrViewSelection.GetAllMarkedObjects(); }
269
270
271 // mechanism to complete disable handles at the view. Handles will be hidden and deleted
272 // when set, no new ones created, no interaction allowed. Handles will be recreated and shown
273 // when reset. Default is false.
274 void hideMarkHandles();
275 void showMarkHandles();
276 bool areMarkHandlesHidden() const { return mbMarkHandlesHidden; }
277
278 bool IsMarkedHit(const Point& rPnt, short nTol=-2) const { return IsMarkedObjHit(rPnt,nTol); }
279 bool IsMarkedObjHit(const Point& rPnt, short nTol=-2) const;
280
281 SdrHdl* PickHandle(const Point& rPnt) const;
282
283 // Pick: Supported options for nOptions are:
284 // SdrSearchOptions::DEEP SdrSearchOptions::ALSOONMASTER SdrSearchOptions::TESTMARKABLE SdrSearchOptions::TESTTEXTEDIT
285 // SdrSearchOptions::MARKED
286 // SdrSearchOptions::WHOLEPAGE
287 SdrObject* PickObj(const Point& rPnt, short nTol, SdrPageView*& rpPV, SdrSearchOptions nOptions, SdrObject** ppRootObj, bool* pbHitPassDirect=nullptr) const;
288 SdrObject* PickObj(const Point& rPnt, short nTol, SdrPageView*& rpPV, SdrSearchOptions nOptions=SdrSearchOptions::NONE) const;
289 bool MarkObj(const Point& rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false);
290
291 // Pick: Supported options for nOptions are SdrSearchOptions::PASS2BOUND
292 bool PickMarkedObj(const Point& rPnt, SdrObject*& rpObj, SdrPageView*& rpPV, SdrSearchOptions nOptions) const;
293
294 // Selects the most upper of the marked objects (O1) and scans from there
295 // towards bottom direction, selecting the first non-marked object (O2).
296 // In case of success the marking of O1 is deleted, a marking is created at
297 // O2 and TRUE is returned. With the parameter bPrev=sal_True the scan
298 // direction is turned to the other direction.
299 bool MarkNextObj(bool bPrev=false);
300
301 // Selects the most upper of the marked objects which is hit by rPnt/nTol
302 // and scans from there to bottom direction, selecting the first non-marked
303 // object (O2). In case of success the marking of O1 is deleted, a marking
304 // is created at O2 and sal_True is returned. With the parameter
305 // bPrev=sal_True the scan direction is turned to the other direction.
306 bool MarkNextObj(const Point& rPnt, short nTol, bool bPrev);
307
308 // Mark all objects within a rectangular area
309 // Just objects are marked which are inclosed completely
310 void MarkObj(const tools::Rectangle& rRect, bool bUnmark);
311 void MarkObj(SdrObject* pObj, SdrPageView* pPV, bool bUnmark = false, bool bDoNoSetMarkHdl = false,
312 std::vector<basegfx::B2DRectangle> const & rSubSelections = std::vector<basegfx::B2DRectangle>());
313 void MarkAllObj(SdrPageView* pPV=nullptr); // pPage=NULL => all displayed pages
314 void UnmarkAllObj(SdrPageView const * pPV=nullptr); // pPage=NULL => all displayed pages
315
316 // This function is time-consuming intensive, as the MarkList has to be scanned.
317 bool IsObjMarked(SdrObject const * pObj) const;
318 void UnMarkAll(SdrPageView const * pPV=nullptr) { UnmarkAllObj(pPV); }
319
320 // Request/set the size of the marking handles. Declaration in Pixel.
321 // The value is meant to be the edge length ( link length ).
322 // Pair values are round up to impair values: 3->3, 4->5, 5->5, 6->7, 7->7, ...
323 // Default value is 7, minimum value is 3 Pixels.
324 sal_uInt16 GetMarkHdlSizePixel() const;
325 void SetMarkHdlSizePixel(sal_uInt16 nSiz);
326
327 virtual bool HasMarkablePoints() const;
328 virtual sal_Int32 GetMarkablePointCount() const;
329 virtual bool HasMarkedPoints() const;
330
331 // There might be points which can't be marked:
332 bool IsPointMarkable(const SdrHdl& rHdl) const;
333 virtual bool MarkPoint(SdrHdl& rHdl, bool bUnmark=false);
334
335 /** should only be used from outside svx for special ui elements */
336 bool MarkPointHelper(SdrHdl* pHdl, SdrMark* pMark, bool bUnmark);
337
338 bool UnmarkPoint(SdrHdl& rHdl) { return MarkPoint(rHdl,true); }
339 bool IsPointMarked(const SdrHdl& rHdl) const { ForceUndirtyMrkPnt(); return rHdl.IsSelected(); }
340 bool MarkAllPoints() { return MarkPoints(nullptr,false); }
341 bool UnmarkAllPoints() { return MarkPoints(nullptr,true); }
342
343 // Selects the first marked point (P1) which is hit by rPnt
344 // and from there it searches the first non-marked point(P2).
345 // In case of success the marking of
346 // P1 is deleted, a mark is set at P2.
347 void MarkNextPoint();
348
349 // Search for the number of the suitable handle. In case of empty search result,
350 // SAL_MAX_SIZE is returned.
351 size_t GetHdlNum(SdrHdl const * pHdl) const { return maHdlList.GetHdlNum(pHdl); }
352 SdrHdl* GetHdl(size_t nHdlNum) const { return maHdlList.GetHdl(nHdlNum); }
353 const SdrHdlList& GetHdlList() const { return maHdlList; }
354
355 // Draw a selection frame for marking of points.
356 // This routine will just be started in case that HasMarkablePoints() returns sal_True.
357 bool BegMarkPoints(const Point& rPnt, bool bUnmark = false);
358 void MovMarkPoints(const Point& rPnt);
359 bool EndMarkPoints();
360 void BrkMarkPoints();
361 bool IsMarkPoints() const { return (nullptr != mpMarkPointsOverlay); }
362
363 // Select that additional handles are displayed permanently.
364 void SetPlusHandlesAlwaysVisible(bool bOn);
365 bool IsPlusHandlesAlwaysVisible() const { return mbPlusHdlAlways; }
366
367 bool HasMarkableGluePoints() const;
368 bool HasMarkedGluePoints() const;
369
370 // A gluepoint is clearly identified by the SdrObject
371 // (to which it belongs) as well as by a sal_uInt16 nId (as each SdrObject may consist of
372 // several glue points. Here at the View there is an additional
373 // SdrPageView, which should be defined correctly always.
374 // Alternatively a gluepoint may be characterized by a SdrHdl.
375 // In this case the SdrHdl instance consists of all required information.
376 // And in this case, the glue point are always is marked by enforcement
377 // (Handlers are just situated at marked gluepoints )
378 // Attention: With each change of the glue point status the handle list is re-calculated.
379 // All previously saved SdrHdl* became invalid by this, the same with the point IDs!
380 bool PickGluePoint(const Point& rPnt, SdrObject*& rpObj, sal_uInt16& rnId, SdrPageView*& rpPV) const;
381 bool MarkGluePoint(const SdrObject* pObj, sal_uInt16 nId, bool bUnmark);
382 void UnmarkGluePoint(const SdrObject* pObj, sal_uInt16 nId) { MarkGluePoint(pObj,nId,true); }
383 bool IsGluePointMarked(const SdrObject* pObj, sal_uInt16 nId) const;
384
385 // Get the Hdl (handle) of a marked GluePoint. Non-marked
386 // GluePoints don`t have handles
387 SdrHdl* GetGluePointHdl(const SdrObject* pObj, sal_uInt16 nId) const;
388
389 // Mark all points within this rectangular (View coordinates)
390 bool MarkAllGluePoints() { return MarkGluePoints(nullptr,false); }
391 bool UnmarkAllGluePoints() { return MarkGluePoints(nullptr,true); }
392
393 // Selects the first marked point (P1) which is hit by rPnt
394 // and from there it searches the first non-marked point(P2).
395 // In case of success the marking of
396 // P1 is deleted, a mark is set at P2.
397 void MarkNextGluePoint();
398
399 // Draw a selection frame for glue point marking.
400 // This routine will just be started in case that HasMarkablePoints() returns sal_True.
401 // The GlueEditMode sal_True is disregarded.
402 // bool BegMarkGluePoints(const Point& rPnt, OutputDevice* pOut);
403 bool BegMarkGluePoints(const Point& rPnt, bool bUnmark = false);
404 void MovMarkGluePoints(const Point& rPnt);
405 void EndMarkGluePoints();
406 void BrkMarkGluePoints();
407 bool IsMarkGluePoints() const { return (nullptr != mpMarkGluePointsOverlay); }
408
409 // bRestraintPaint=sal_False causes the handles not to be drawn immediately.
410 // AdjustMarkHdl is just called in case of changes; usually this causes an Invalidate
411 // At the end of a redraw the handles are drawn automatically.
412 // The purpose is to avoid unnecessary flickering. -> This does not yet work, that's why sal_True!
413 void AdjustMarkHdl(SfxViewShell* pOtherShell = nullptr); //HMHBOOL bRestraintPaint=sal_True);
414
415 const tools::Rectangle& GetMarkedObjRect() const; // SnapRects of Objects, without line width
416 tools::Rectangle GetMarkedObjBoundRect() const; // incl. line width, overlapping rags, ...
417 const tools::Rectangle& GetMarkedPointsRect() const; // Enclosing rectangle of all marked points
418 const tools::Rectangle& GetMarkedGluePointsRect() const; // Enclosing rectangle of all marked glue points
419 const tools::Rectangle& GetAllMarkedRect() const { return GetMarkedObjRect(); }
420 tools::Rectangle GetAllMarkedBoundRect() const { return GetMarkedObjBoundRect(); }
421
422 // Will be always called, if the list of marked objects might be changed.
423 // If you override this method, be sure that you call the
424 // methods of the base class!
425 virtual void MarkListHasChanged();
426
427 // Entering (Editing) of a maybe marked object group. If there are several
428 // object groups marked, the most upper group is selected. After that
429 // all member objects of the group are directly accessible. All other
430 // objects may not be processed in the meantime (until the next
431 // LeaveGroup()). With markings which overlaps pages, every page is processed
432 // separately. The method returns sal_True, if at least one group was entered.
433 void EnterMarkedGroup();
434
435 // Rotation center point and start point of the axis of reflection, respectively
436 const Point& GetRef1() const { return maRef1; }
437 void SetRef1(const Point& rPt);
438
439 // End point of the axis of reflection
440 const Point& GetRef2() const { return maRef2; }
441 void SetRef2(const Point& rPt);
442 /// Get access to the view shell owning this draw view, if any.
443 virtual SfxViewShell* GetSfxViewShell() const;
444};
445
446
447// - Hit tolerances:
448// It has to be declared in logical coordinates. So please translate the
449// wanted pixel value with PixelToLogic in Logical values.
450// Taking as example a logical value of 100:
451// - For a horizontal hairline (Object with height 0), the generated data is +/-100, i.e.
452// a vertical area of 200 logical units is sensitive.
453// - For a polygon, a rectangular of the size (200,200) is generated and a
454// touch test between Poly and this Rect is processed.
455// - Objects which respond SdrObject::HasEdit()==TRUE ( e.g. a text frame ),
456// are specially treated: An additional sensitive area with a width of
457// 2*Tol (200 units for this example) is created around the object.
458// When an object is directly hit, the Edit method is called.
459// In opposite, a hit in the surrounding sensitive area enables Dragging.
460
461
462#endif // INCLUDED_SVX_SVDMRKV_HXX
463
464/* vim:set shiftwidth=4 softtabstop=4 expandtab: */