File: | home/maarten/src/libreoffice/core/sc/source/ui/view/drawview.cxx |
Warning: | line 454, column 25 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
| ||||
431 | { | ||||
432 | bool bOnlyControls = true; | ||||
433 | bool bOnlyGraf = true; | ||||
434 | for (size_t i=0; 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
| ||||
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: */ |