File: | home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx |
Warning: | line 950, column 41 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 <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 | ||||
65 | using namespace com::sun::star; | |||
66 | ||||
67 | #define SC_HANDLESIZE_BIG9 9 | |||
68 | ||||
69 | void 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 | ||||
126 | void ScDrawView::ImplClearCalcDropMarker() | |||
127 | { | |||
128 | pDropMarker.reset(); | |||
129 | } | |||
130 | ||||
131 | ScDrawView::~ScDrawView() | |||
132 | { | |||
133 | ImplClearCalcDropMarker(); | |||
134 | } | |||
135 | ||||
136 | void 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 | ||||
151 | void ScDrawView::InvalidateAttribs() | |||
152 | { | |||
153 | if (!pViewData) return; | |||
154 | SfxBindings& rBindings = pViewData->GetBindings(); | |||
155 | ||||
156 | // true status values: | |||
157 | rBindings.InvalidateAll( true ); | |||
158 | } | |||
159 | ||||
160 | void 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 | ||||
210 | void ScDrawView::SetMarkedToLayer( SdrLayerID nLayerNo ) | |||
211 | { | |||
212 | if (!AreObjectsMarked()) | |||
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) | |||
222 | { | |||
223 | SdrObject* pObj = rMark.GetMark(i)->GetMarkedSdrObj(); | |||
224 | if ( dynamic_cast<const SdrUnoObj*>( pObj) == nullptr && (pObj->GetLayer() != SC_LAYER_INTERN) ) | |||
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 | ||||
242 | bool 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 | ||||
251 | bool 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 | ||||
261 | void 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 | ||||
282 | void 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 | ||||
290 | void ScDrawView::GetScale( Fraction& rFractX, Fraction& rFractY ) const | |||
291 | { | |||
292 | rFractX = aScaleX; | |||
293 | rFractY = aScaleY; | |||
294 | } | |||
295 | ||||
296 | void 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 | ||||
350 | void ScDrawView::DoConnect(SdrOle2Obj* pOleObj) | |||
351 | { | |||
352 | if ( pViewData ) | |||
353 | pViewData->GetViewShell()->ConnectObject( pOleObj ); | |||
354 | } | |||
355 | ||||
356 | void 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 | ||||
541 | bool 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 | ||||
586 | SdrEndTextEditKind 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 | ||||
610 | void 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 | ||||
624 | void 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 | ||||
648 | SdrObject* 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 | ||||
679 | void 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 | ||||
730 | bool 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 . | |||
792 | bool ScDrawView::GetObjectIsMarked( const SdrObject* pObject ) | |||
793 | { | |||
794 | bool bisMarked = false; | |||
795 | if (pObject ) | |||
796 | { | |||
797 | bisMarked = IsObjMarked(pObject); | |||
798 | } | |||
799 | return bisMarked; | |||
800 | } | |||
801 | ||||
802 | bool 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 | ||||
818 | SdrObject* 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 | ||||
833 | void 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 | ||||
840 | void 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 | ||||
849 | SfxViewShell* ScDrawView::GetSfxViewShell() const | |||
850 | { | |||
851 | return pViewData->GetViewShell(); | |||
852 | } | |||
853 | ||||
854 | void 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 | ||||
892 | SdrEndTextEditKind 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 | ||||
903 | void 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. | |||
923 | void 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 | ||||
972 | void 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 | ||||
996 | bool 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 | ||||
1058 | bool 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 | |||
1107 | SdrUndoManager* ScDrawView::getSdrUndoManagerForEnhancedTextEdit() const | |||
1108 | { | |||
1109 | return dynamic_cast<SdrUndoManager*>(rDoc.GetUndoManager()); | |||
1110 | } | |||
1111 | ||||
1112 | // #i123922# helper to apply a Graphic to an existing SdrObject | |||
1113 | SdrObject* 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) | |||
1151 | namespace 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 | |||
1242 | sdr::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: */ |