File: | home/maarten/src/libreoffice/core/sw/source/uibase/uiview/viewdraw.cxx |
Warning: | line 559, column 5 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 <hintids.hxx> | |||
21 | #include <svl/itempool.hxx> | |||
22 | #include <svl/stritem.hxx> | |||
23 | #include <svx/svdobj.hxx> | |||
24 | #include <svx/svdview.hxx> | |||
25 | #include <svx/svdpage.hxx> | |||
26 | #include <editeng/outliner.hxx> | |||
27 | #include <svx/fmview.hxx> | |||
28 | #include <svx/dataaccessdescriptor.hxx> | |||
29 | #include <sfx2/viewfrm.hxx> | |||
30 | #include <doc.hxx> | |||
31 | #include <IDocumentDeviceAccess.hxx> | |||
32 | #include <textboxhelper.hxx> | |||
33 | #include <editeng/langitem.hxx> | |||
34 | #include <svx/fontworkbar.hxx> | |||
35 | #include <svx/fontworkgallery.hxx> | |||
36 | #include <editeng/eeitem.hxx> | |||
37 | #include <svx/svdogrp.hxx> | |||
38 | #include <svx/svdetc.hxx> | |||
39 | #include <editeng/editstat.hxx> | |||
40 | #include <sfx2/request.hxx> | |||
41 | #include <sfx2/bindings.hxx> | |||
42 | #include <sfx2/dispatch.hxx> | |||
43 | #include <svx/svdoutl.hxx> | |||
44 | #include <vcl/ptrstyle.hxx> | |||
45 | ||||
46 | #include <view.hxx> | |||
47 | #include <wrtsh.hxx> | |||
48 | #include <viewopt.hxx> | |||
49 | #include <cmdid.h> | |||
50 | #include <drwbassh.hxx> | |||
51 | #include <beziersh.hxx> | |||
52 | #include <conrect.hxx> | |||
53 | #include <conpoly.hxx> | |||
54 | #include <conarc.hxx> | |||
55 | #include <conform.hxx> | |||
56 | #include <concustomshape.hxx> | |||
57 | #include <dselect.hxx> | |||
58 | #include <edtwin.hxx> | |||
59 | ||||
60 | #include <dcontact.hxx> | |||
61 | ||||
62 | #include <svx/svdpagv.hxx> | |||
63 | #include <svx/extrusionbar.hxx> | |||
64 | #include <comphelper/lok.hxx> | |||
65 | #include <sfx2/lokhelper.hxx> | |||
66 | #include <LibreOfficeKit/LibreOfficeKitEnums.h> | |||
67 | ||||
68 | using namespace ::com::sun::star; | |||
69 | ||||
70 | // Execute Drawing-Ids | |||
71 | ||||
72 | void SwView::ExecDraw(SfxRequest& rReq) | |||
73 | { | |||
74 | const SfxItemSet *pArgs = rReq.GetArgs(); | |||
75 | const SfxPoolItem* pItem; | |||
76 | const SfxStringItem* pStringItem = nullptr; | |||
77 | SdrView *pSdrView = m_pWrtShell->GetDrawView(); | |||
78 | bool bDeselect = false; | |||
79 | ||||
80 | sal_uInt16 nSlotId = rReq.GetSlot(); | |||
81 | if(pArgs && SfxItemState::SET == pArgs->GetItemState(GetPool().GetWhich(nSlotId), false, &pItem)) | |||
82 | pStringItem = dynamic_cast< const SfxStringItem*>(pItem); | |||
83 | ||||
84 | if (nSlotId == SID_OBJECT_SELECT( 10000 + 128 ) && m_nFormSfxId == nSlotId) | |||
85 | { | |||
86 | bDeselect = true; | |||
87 | } | |||
88 | else if (nSlotId == SID_FM_CREATE_CONTROL( 10000 + 628 )) | |||
89 | { | |||
90 | const SfxUInt16Item* pIdentifierItem = rReq.GetArg<SfxUInt16Item>(SID_FM_CONTROL_IDENTIFIER( 10000 + 631 )); | |||
91 | if( pIdentifierItem ) | |||
92 | { | |||
93 | sal_uInt16 nNewId = pIdentifierItem->GetValue(); | |||
94 | if (nNewId == m_nFormSfxId) | |||
95 | { | |||
96 | bDeselect = true; | |||
97 | GetViewFrame()->GetDispatcher()->Execute(SID_FM_LEAVE_CREATE( 10000 + 726 )); // Button should popping out | |||
98 | } | |||
99 | } | |||
100 | } | |||
101 | else if (nSlotId == SID_FM_CREATE_FIELDCONTROL( 10000 + 765 )) | |||
102 | { | |||
103 | FmFormView* pFormView = dynamic_cast<FmFormView*>(pSdrView); | |||
104 | if (pFormView) | |||
105 | { | |||
106 | const SfxUnoAnyItem* pDescriptorItem = rReq.GetArg<SfxUnoAnyItem>(SID_FM_DATACCESS_DESCRIPTOR( 10000 + 766 )); | |||
107 | OSL_ENSURE( pDescriptorItem, "SwView::ExecDraw(SID_FM_CREATE_FIELDCONTROL): invalid request args!" )do { if (true && (!(pDescriptorItem))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/viewdraw.cxx" ":" "107" ": "), "%s", "SwView::ExecDraw(SID_FM_CREATE_FIELDCONTROL): invalid request args!" ); } } while (false); | |||
108 | if( pDescriptorItem ) | |||
109 | { | |||
110 | svx::ODataAccessDescriptor aDescriptor( pDescriptorItem->GetValue() ); | |||
111 | SdrObjectUniquePtr pObj = pFormView->CreateFieldControl( aDescriptor ); | |||
112 | ||||
113 | if ( pObj ) | |||
114 | { | |||
115 | Size aDocSize(m_pWrtShell->GetDocSize()); | |||
116 | const SwRect& rVisArea = m_pWrtShell->VisArea(); | |||
117 | Point aStartPos = rVisArea.Center(); | |||
118 | if(rVisArea.Width() > aDocSize.Width()) | |||
119 | aStartPos.setX( aDocSize.Width() / 2 + rVisArea.Left() ); | |||
120 | if(rVisArea.Height() > aDocSize.Height()) | |||
121 | aStartPos.setY( aDocSize.Height() / 2 + rVisArea.Top() ); | |||
122 | ||||
123 | //determine the size of the object | |||
124 | if(pObj->IsGroupObject()) | |||
125 | { | |||
126 | const tools::Rectangle& rBoundRect = static_cast<SdrObjGroup*>(pObj.get())->GetCurrentBoundRect(); | |||
127 | aStartPos.AdjustX( -(rBoundRect.GetWidth()/2) ); | |||
128 | aStartPos.AdjustY( -(rBoundRect.GetHeight()/2) ); | |||
129 | } | |||
130 | ||||
131 | // TODO: unmark all other | |||
132 | m_pWrtShell->EnterStdMode(); | |||
133 | m_pWrtShell->SwFEShell::InsertDrawObj( *(pObj.release()), aStartPos ); | |||
134 | } | |||
135 | } | |||
136 | } | |||
137 | } | |||
138 | else if ( nSlotId == SID_FONTWORK_GALLERY_FLOATER( 10000 + 977 ) ) | |||
139 | { | |||
140 | vcl::Window& rWin = m_pWrtShell->GetView().GetViewFrame()->GetWindow(); | |||
141 | ||||
142 | rWin.EnterWait(); | |||
143 | ||||
144 | if( !m_pWrtShell->HasDrawView() ) | |||
145 | m_pWrtShell->MakeDrawView(); | |||
146 | ||||
147 | pSdrView = m_pWrtShell->GetDrawView(); | |||
148 | if (pSdrView) | |||
149 | { | |||
150 | SdrObject* pObj = nullptr; | |||
151 | svx::FontWorkGalleryDialog aDlg(rWin.GetFrameWeld(), *pSdrView); | |||
152 | aDlg.SetSdrObjectRef( &pObj, pSdrView->GetModel() ); | |||
153 | aDlg.run(); | |||
154 | if ( pObj ) | |||
155 | { | |||
156 | Size aDocSize( m_pWrtShell->GetDocSize() ); | |||
157 | const SwRect& rVisArea = m_pWrtShell->VisArea(); | |||
158 | Point aPos( rVisArea.Center() ); | |||
159 | Size aSize; | |||
160 | Size aPrefSize( pObj->GetSnapRect().GetSize() ); | |||
161 | ||||
162 | if( rVisArea.Width() > aDocSize.Width()) | |||
163 | aPos.setX( aDocSize.Width() / 2 + rVisArea.Left() ); | |||
164 | ||||
165 | if(rVisArea.Height() > aDocSize.Height()) | |||
166 | aPos.setY( aDocSize.Height() / 2 + rVisArea.Top() ); | |||
167 | ||||
168 | if( aPrefSize.Width() && aPrefSize.Height() ) | |||
169 | aSize = rWin.PixelToLogic(aPrefSize, MapMode(MapUnit::MapTwip)); | |||
170 | else | |||
171 | aSize = Size( 2835, 2835 ); | |||
172 | ||||
173 | m_pWrtShell->EnterStdMode(); | |||
174 | m_pWrtShell->SwFEShell::InsertDrawObj( *pObj, aPos ); | |||
175 | rReq.Ignore (); | |||
176 | } | |||
177 | } | |||
178 | rWin.LeaveWait(); | |||
179 | } | |||
180 | else if ( m_nFormSfxId != USHRT_MAX(32767 *2 +1) ) | |||
181 | GetViewFrame()->GetDispatcher()->Execute( SID_FM_LEAVE_CREATE( 10000 + 726 ) ); | |||
182 | ||||
183 | if( nSlotId == SID_DRAW_CS_ID( 10000 + 1053 ) ) | |||
184 | { | |||
185 | //deselect if same custom shape is selected again | |||
186 | SwDrawBase* pFuncPtr = GetDrawFuncPtr(); | |||
187 | if( pFuncPtr && pFuncPtr->GetSlotId() == SID_DRAW_CS_ID( 10000 + 1053 ) ) | |||
188 | { | |||
189 | ConstCustomShape* pConstCustomShape = static_cast<ConstCustomShape*>(pFuncPtr); | |||
190 | OUString aNew = ConstCustomShape::GetShapeTypeFromRequest( rReq ); | |||
191 | const OUString& aOld = pConstCustomShape->GetShapeType(); | |||
192 | if( aNew == aOld ) | |||
193 | { | |||
194 | bDeselect = true; | |||
195 | } | |||
196 | } | |||
197 | } | |||
198 | ||||
199 | //deselect if same shape is selected again (but different custom shapes do have same slot id) | |||
200 | if ( bDeselect || (nSlotId == m_nDrawSfxId && | |||
201 | (!pStringItem || (pStringItem->GetValue() == m_sDrawCustom)) | |||
202 | && (nSlotId != SID_DRAW_CS_ID( 10000 + 1053 )) ) ) | |||
203 | { | |||
204 | if (GetDrawFuncPtr()) | |||
205 | { | |||
206 | GetDrawFuncPtr()->Deactivate(); | |||
207 | SetDrawFuncPtr(nullptr); | |||
208 | } | |||
209 | ||||
210 | if (m_pWrtShell->IsObjSelected() && !m_pWrtShell->IsSelFrameMode()) | |||
211 | m_pWrtShell->EnterSelFrameMode(); | |||
212 | LeaveDrawCreate(); | |||
213 | ||||
214 | AttrChangedNotify(nullptr); | |||
215 | return; | |||
216 | } | |||
217 | ||||
218 | LeaveDrawCreate(); | |||
219 | ||||
220 | if (m_pWrtShell->IsFrameSelected()) | |||
221 | m_pWrtShell->EnterStdMode(); // because bug #45639 | |||
222 | ||||
223 | std::unique_ptr<SwDrawBase> pFuncPtr; | |||
224 | ||||
225 | // for LibreOfficeKit - choosing a shape should construct it directly | |||
226 | bool bCreateDirectly = false; | |||
227 | ||||
228 | switch (nSlotId) | |||
229 | { | |||
230 | case SID_OBJECT_SELECT( 10000 + 128 ): | |||
231 | case SID_DRAW_SELECT( 10000 + 255 ): | |||
232 | pFuncPtr.reset( new DrawSelection(m_pWrtShell.get(), m_pEditWin, this) ); | |||
233 | m_nDrawSfxId = m_nFormSfxId = SID_OBJECT_SELECT( 10000 + 128 ); | |||
234 | m_sDrawCustom.clear(); | |||
235 | break; | |||
236 | ||||
237 | case SID_LINE_ARROW_END( 10000 + 1166 ): | |||
238 | case SID_LINE_ARROW_CIRCLE( 10000 + 1159 ): | |||
239 | case SID_LINE_ARROW_SQUARE( 10000 + 1160 ): | |||
240 | case SID_LINE_ARROW_START( 10000 + 1165 ): | |||
241 | case SID_LINE_CIRCLE_ARROW( 10000 + 1161 ): | |||
242 | case SID_LINE_SQUARE_ARROW( 10000 + 1162 ): | |||
243 | case SID_LINE_ARROWS( 10000 + 1163 ): | |||
244 | case SID_DRAW_LINE( 10000 + 102 ): | |||
245 | case SID_DRAW_XLINE( 10000 + 103 ): | |||
246 | case SID_DRAW_MEASURELINE( 10000 + 1167 ): | |||
247 | case SID_DRAW_RECT( 10000 + 104 ): | |||
248 | case SID_DRAW_ELLIPSE( 10000 + 110 ): | |||
249 | case SID_DRAW_TEXT( 10000 + 253 ): | |||
250 | case SID_DRAW_TEXT_VERTICAL( 10000 + 905 ): | |||
251 | case SID_DRAW_TEXT_MARQUEE( 10000 + 465 ): | |||
252 | case SID_DRAW_CAPTION( 10000 + 254 ): | |||
253 | case SID_DRAW_CAPTION_VERTICAL( 10000 + 906 ): | |||
254 | pFuncPtr.reset( new ConstRectangle(m_pWrtShell.get(), m_pEditWin, this) ); | |||
255 | m_nDrawSfxId = nSlotId; | |||
256 | m_sDrawCustom.clear(); | |||
257 | break; | |||
258 | ||||
259 | case SID_DRAW_XPOLYGON_NOFILL( 10000 + 396 ): | |||
260 | case SID_DRAW_XPOLYGON( 10000 + 394 ): | |||
261 | case SID_DRAW_POLYGON_NOFILL( 10000 + 395 ): | |||
262 | case SID_DRAW_POLYGON( 10000 + 117 ): | |||
263 | case SID_DRAW_BEZIER_NOFILL( 10000 + 397 ): | |||
264 | case SID_DRAW_BEZIER_FILL( 10000 + 118 ): | |||
265 | case SID_DRAW_FREELINE_NOFILL( 10000 + 464 ): | |||
266 | case SID_DRAW_FREELINE( 10000 + 463 ): | |||
267 | pFuncPtr.reset( new ConstPolygon(m_pWrtShell.get(), m_pEditWin, this) ); | |||
268 | m_nDrawSfxId = nSlotId; | |||
269 | m_sDrawCustom.clear(); | |||
270 | break; | |||
271 | ||||
272 | case SID_DRAW_ARC( 10000 + 114 ): | |||
273 | case SID_DRAW_PIE( 10000 + 112 ): | |||
274 | case SID_DRAW_CIRCLECUT( 10000 + 115 ): | |||
275 | pFuncPtr.reset( new ConstArc(m_pWrtShell.get(), m_pEditWin, this) ); | |||
276 | m_nDrawSfxId = nSlotId; | |||
277 | m_sDrawCustom.clear(); | |||
278 | break; | |||
279 | ||||
280 | case SID_FM_CREATE_CONTROL( 10000 + 628 ): | |||
281 | { | |||
282 | const SfxUInt16Item* pIdentifierItem = rReq.GetArg<SfxUInt16Item>(SID_FM_CONTROL_IDENTIFIER( 10000 + 631 )); | |||
283 | if( pIdentifierItem ) | |||
284 | nSlotId = pIdentifierItem->GetValue(); | |||
285 | pFuncPtr.reset( new ConstFormControl(m_pWrtShell.get(), m_pEditWin, this) ); | |||
286 | m_nFormSfxId = nSlotId; | |||
287 | } | |||
288 | break; | |||
289 | ||||
290 | case SID_DRAWTBX_CS_BASIC( 10000 + 1047 ) : | |||
291 | case SID_DRAWTBX_CS_SYMBOL( 10000 + 1048 ) : | |||
292 | case SID_DRAWTBX_CS_ARROW( 10000 + 1049 ) : | |||
293 | case SID_DRAWTBX_CS_FLOWCHART( 10000 + 1050 ) : | |||
294 | case SID_DRAWTBX_CS_CALLOUT( 10000 + 1051 ) : | |||
295 | case SID_DRAWTBX_CS_STAR( 10000 + 1052 ) : | |||
296 | case SID_DRAW_CS_ID( 10000 + 1053 ) : | |||
297 | { | |||
298 | pFuncPtr.reset( new ConstCustomShape(m_pWrtShell.get(), m_pEditWin, this, rReq ) ); | |||
299 | ||||
300 | bCreateDirectly = comphelper::LibreOfficeKit::isActive(); | |||
301 | ||||
302 | m_nDrawSfxId = nSlotId; | |||
303 | if ( nSlotId != SID_DRAW_CS_ID( 10000 + 1053 ) ) | |||
304 | { | |||
305 | if ( pStringItem ) | |||
306 | { | |||
307 | m_sDrawCustom = pStringItem->GetValue(); | |||
308 | SfxBindings& rBind = GetViewFrame()->GetBindings(); | |||
309 | rBind.Invalidate( nSlotId ); | |||
310 | rBind.Update( nSlotId ); | |||
311 | } | |||
312 | } | |||
313 | } | |||
314 | break; | |||
315 | ||||
316 | default: | |||
317 | break; | |||
318 | } | |||
319 | ||||
320 | GetViewFrame()->GetBindings().Invalidate(SID_ATTRIBUTES_AREA( 10000 + 142 )); | |||
321 | ||||
322 | bool bEndTextEdit = true; | |||
323 | if (pFuncPtr) | |||
324 | { | |||
325 | if (GetDrawFuncPtr()) | |||
326 | { | |||
327 | GetDrawFuncPtr()->Deactivate(); | |||
328 | } | |||
329 | ||||
330 | auto pTempFuncPtr = pFuncPtr.get(); | |||
331 | SetDrawFuncPtr(std::move(pFuncPtr)); | |||
332 | AttrChangedNotify(nullptr); | |||
333 | ||||
334 | pTempFuncPtr->Activate(nSlotId); | |||
335 | NoRotate(); | |||
336 | if(rReq.GetModifier() == KEY_MOD1 || bCreateDirectly) | |||
337 | { | |||
338 | if(SID_OBJECT_SELECT( 10000 + 128 ) == m_nDrawSfxId ) | |||
339 | { | |||
340 | m_pWrtShell->GotoObj(true); | |||
341 | } | |||
342 | else if (dynamic_cast<ConstCustomShape*>(pTempFuncPtr)) | |||
343 | { | |||
344 | pTempFuncPtr->CreateDefaultObject(); | |||
345 | } | |||
346 | else | |||
347 | { | |||
348 | pTempFuncPtr->CreateDefaultObject(); | |||
349 | pTempFuncPtr->Deactivate(); | |||
350 | SetDrawFuncPtr(nullptr); | |||
351 | LeaveDrawCreate(); | |||
352 | m_pWrtShell->EnterStdMode(); | |||
353 | SdrView *pTmpSdrView = m_pWrtShell->GetDrawView(); | |||
354 | const SdrMarkList& rMarkList = pTmpSdrView->GetMarkedObjectList(); | |||
355 | if(rMarkList.GetMarkCount() == 1 && | |||
356 | (SID_DRAW_TEXT( 10000 + 253 ) == nSlotId || SID_DRAW_TEXT_VERTICAL( 10000 + 905 ) == nSlotId || | |||
357 | SID_DRAW_TEXT_MARQUEE( 10000 + 465 ) == nSlotId )) | |||
358 | { | |||
359 | SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); | |||
360 | BeginTextEdit(pObj); | |||
361 | bEndTextEdit = false; | |||
362 | } | |||
363 | } | |||
364 | } | |||
365 | } | |||
366 | else | |||
367 | { | |||
368 | if (m_pWrtShell->IsObjSelected() && !m_pWrtShell->IsSelFrameMode()) | |||
369 | m_pWrtShell->EnterSelFrameMode(); | |||
370 | } | |||
371 | ||||
372 | if(bEndTextEdit && pSdrView && pSdrView->IsTextEdit()) | |||
373 | pSdrView->SdrEndTextEdit( true ); | |||
374 | ||||
375 | AttrChangedNotify(nullptr); | |||
376 | } | |||
377 | ||||
378 | // End drawing | |||
379 | ||||
380 | void SwView::ExitDraw() | |||
381 | { | |||
382 | NoRotate(); | |||
383 | ||||
384 | if(!m_pShell) | |||
385 | return; | |||
386 | ||||
387 | // the shell may be invalid at close/reload/SwitchToViewShell | |||
388 | SfxDispatcher* pDispatch = GetViewFrame()->GetDispatcher(); | |||
389 | sal_uInt16 nIdx = 0; | |||
390 | SfxShell* pTest = nullptr; | |||
391 | do | |||
392 | { | |||
393 | pTest = pDispatch->GetShell(nIdx++); | |||
394 | } | |||
395 | while( pTest && pTest != this && pTest != m_pShell); | |||
396 | if(!(pTest == m_pShell && | |||
397 | // don't call LeaveSelFrameMode() etc. for the below, | |||
398 | // because objects may still be selected: | |||
399 | dynamic_cast< const SwDrawBaseShell *>( m_pShell ) == nullptr && | |||
400 | dynamic_cast< const SwBezierShell *>( m_pShell ) == nullptr && | |||
401 | dynamic_cast< const svx::ExtrusionBar *>( m_pShell ) == nullptr && | |||
402 | dynamic_cast< const svx::FontworkBar *>( m_pShell ) == nullptr)) | |||
403 | return; | |||
404 | ||||
405 | SdrView *pSdrView = m_pWrtShell->GetDrawView(); | |||
406 | ||||
407 | if (pSdrView && pSdrView->IsGroupEntered()) | |||
408 | { | |||
409 | pSdrView->LeaveOneGroup(); | |||
410 | pSdrView->UnmarkAll(); | |||
411 | GetViewFrame()->GetBindings().Invalidate(SID_ENTER_GROUP(27000 +96)); | |||
412 | } | |||
413 | ||||
414 | if (GetDrawFuncPtr()) | |||
415 | { | |||
416 | if (m_pWrtShell->IsSelFrameMode()) | |||
417 | m_pWrtShell->LeaveSelFrameMode(); | |||
418 | GetDrawFuncPtr()->Deactivate(); | |||
419 | ||||
420 | SetDrawFuncPtr(nullptr); | |||
421 | LeaveDrawCreate(); | |||
422 | ||||
423 | GetViewFrame()->GetBindings().Invalidate(SID_INSERT_DRAW( 10000 + 244 )); | |||
424 | } | |||
425 | GetEditWin().SetPointer(PointerStyle::Text); | |||
426 | } | |||
427 | ||||
428 | // Disable rotate mode | |||
429 | ||||
430 | void SwView::NoRotate() | |||
431 | { | |||
432 | if (IsDrawRotate()) | |||
433 | { | |||
434 | m_pWrtShell->SetDragMode(SdrDragMode::Move); | |||
435 | FlipDrawRotate(); | |||
436 | ||||
437 | const SfxBoolItem aTmp( SID_OBJECT_ROTATETypedWhichId<SfxBoolItem>( 10000 + 129 ), false ); | |||
438 | GetViewFrame()->GetBindings().SetState( aTmp ); | |||
439 | } | |||
440 | } | |||
441 | ||||
442 | // Enable DrawTextEditMode | |||
443 | ||||
444 | static bool lcl_isTextBox(SdrObject const * pObject) | |||
445 | { | |||
446 | if (SwDrawContact* pDrawContact = static_cast<SwDrawContact*>(pObject->GetUserCall())) | |||
447 | { | |||
448 | if (SwFrameFormat* pFormat = pDrawContact->GetFormat()) | |||
449 | return SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT); | |||
450 | } | |||
451 | return false; | |||
452 | } | |||
453 | ||||
454 | bool SwView::EnterDrawTextMode(const Point& aDocPos) | |||
455 | { | |||
456 | SwWrtShell *pSh = &GetWrtShell(); | |||
457 | SdrView *pSdrView = pSh->GetDrawView(); | |||
458 | OSL_ENSURE( pSdrView, "EnterDrawTextMode without DrawView?" )do { if (true && (!(pSdrView))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/viewdraw.cxx" ":" "458" ": "), "%s", "EnterDrawTextMode without DrawView?" ); } } while (false); | |||
459 | ||||
460 | bool bReturn = false; | |||
461 | ||||
462 | sal_uInt16 nOld = pSdrView->GetHitTolerancePixel(); | |||
463 | pSdrView->SetHitTolerancePixel( 2 ); | |||
464 | ||||
465 | SdrObject* pObj = nullptr; | |||
466 | SdrPageView* pPV = nullptr; | |||
467 | if (pSdrView->IsMarkedHit(aDocPos) && !pSdrView->PickHandle(aDocPos) && IsTextTool()) | |||
468 | pObj = pSdrView->PickObj(aDocPos, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::PICKTEXTEDIT); | |||
469 | ||||
470 | if (pObj && | |||
471 | // To allow SwDrawVirtObj text objects to be activated, allow their type, too. | |||
472 | ( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr || | |||
473 | ( dynamic_cast< const SwDrawVirtObj *>( pObj ) != nullptr && | |||
474 | dynamic_cast< const SdrTextObj *>(&static_cast<SwDrawVirtObj*>(pObj)->GetReferencedObj() ) != nullptr ) ) && | |||
475 | ||||
476 | m_pWrtShell->IsSelObjProtected(FlyProtectFlags::Content) == FlyProtectFlags::NONE) | |||
477 | { | |||
478 | // Refuse to edit editeng text of the shape if it has textbox attached. | |||
479 | if (!lcl_isTextBox(pObj)) | |||
480 | bReturn = BeginTextEdit( pObj, pPV, m_pEditWin ); | |||
481 | } | |||
482 | ||||
483 | pSdrView->SetHitTolerancePixel( nOld ); | |||
484 | ||||
485 | return bReturn; | |||
486 | } | |||
487 | ||||
488 | bool SwView::EnterShapeDrawTextMode(SdrObject* pObject) | |||
489 | { | |||
490 | SdrView* pSdrView = GetWrtShell().GetDrawView(); | |||
491 | SdrPageView* pPageView = pSdrView->GetSdrPageView(); | |||
492 | return BeginTextEdit(pObject, pPageView, m_pEditWin); | |||
| ||||
493 | } | |||
494 | ||||
495 | // Enable DrawTextEditMode | |||
496 | ||||
497 | bool SwView::BeginTextEdit(SdrObject* pObj, SdrPageView* pPV, vcl::Window* pWin, | |||
498 | bool bIsNewObj, bool bSetSelectionToStart) | |||
499 | { | |||
500 | SwWrtShell *pSh = &GetWrtShell(); | |||
501 | SdrView *pSdrView = pSh->GetDrawView(); | |||
502 | std::unique_ptr<SdrOutliner> pOutliner = ::SdrMakeOutliner(OutlinerMode::TextObject, *pSdrView->GetModel()); | |||
503 | uno::Reference< linguistic2::XSpellChecker1 > xSpell( ::GetSpellChecker() ); | |||
504 | if (pOutliner) | |||
505 | { | |||
506 | pOutliner->SetRefDevice(pSh->getIDocumentDeviceAccess().getReferenceDevice(false)); | |||
507 | pOutliner->SetSpeller(xSpell); | |||
508 | uno::Reference<linguistic2::XHyphenator> xHyphenator( ::GetHyphenator() ); | |||
509 | pOutliner->SetHyphenator( xHyphenator ); | |||
510 | pSh->SetCalcFieldValueHdl(pOutliner.get()); | |||
511 | ||||
512 | EEControlBits nCntrl = pOutliner->GetControlWord(); | |||
513 | nCntrl |= EEControlBits::ALLOWBIGOBJS; | |||
514 | ||||
515 | const SwViewOption *pOpt = pSh->GetViewOptions(); | |||
516 | ||||
517 | if (SwViewOption::IsFieldShadings()) | |||
518 | nCntrl |= EEControlBits::MARKFIELDS; | |||
519 | else | |||
520 | nCntrl &= ~EEControlBits::MARKFIELDS; | |||
521 | ||||
522 | if (pOpt->IsOnlineSpell()) | |||
523 | nCntrl |= EEControlBits::ONLINESPELLING; | |||
524 | else | |||
525 | nCntrl &= ~EEControlBits::ONLINESPELLING; | |||
526 | ||||
527 | pOutliner->SetControlWord(nCntrl); | |||
528 | const SfxPoolItem& rItem = pSh->GetDoc()->GetDefault(RES_CHRATR_LANGUAGE); | |||
529 | pOutliner->SetDefaultLanguage(static_cast<const SvxLanguageItem&>(rItem).GetLanguage()); | |||
530 | ||||
531 | if( bIsNewObj ) | |||
532 | pOutliner->SetVertical( SID_DRAW_TEXT_VERTICAL( 10000 + 905 ) == m_nDrawSfxId || | |||
533 | SID_DRAW_CAPTION_VERTICAL( 10000 + 906 ) == m_nDrawSfxId ); | |||
534 | ||||
535 | // set default horizontal text direction at outliner | |||
536 | EEHorizontalTextDirection aDefHoriTextDir = | |||
537 | pSh->IsShapeDefaultHoriTextDirR2L() ? EEHorizontalTextDirection::R2L : EEHorizontalTextDirection::L2R; | |||
538 | pOutliner->SetDefaultHorizontalTextDirection( aDefHoriTextDir ); | |||
539 | } | |||
540 | ||||
541 | // To allow editing the referenced object from a SwDrawVirtObj here | |||
542 | // the original needs to be fetched eventually. This ATM activates the | |||
543 | // text edit mode for the original object. | |||
544 | SdrObject* pToBeActivated = pObj; | |||
545 | ||||
546 | // Always the original object is edited. To allow the TextEdit to happen | |||
547 | // where the VirtObj is positioned, on demand an occurring offset is set at | |||
548 | // the TextEdit object. That offset is used for creating and managing the | |||
549 | // OutlinerView. | |||
550 | Point aNewTextEditOffset(0, 0); | |||
551 | ||||
552 | if (SwDrawVirtObj* pVirtObj = dynamic_cast<SwDrawVirtObj *>(pObj)) | |||
553 | { | |||
554 | pToBeActivated = &const_cast<SdrObject&>(pVirtObj->GetReferencedObj()); | |||
555 | aNewTextEditOffset = pVirtObj->GetOffset(); | |||
556 | } | |||
557 | ||||
558 | // set in each case, thus it will be correct for all objects | |||
559 | static_cast<SdrTextObj*>(pToBeActivated)->SetTextEditOffset(aNewTextEditOffset); | |||
| ||||
560 | ||||
561 | bool bRet(pSdrView->SdrBeginTextEdit( pToBeActivated, pPV, pWin, true, pOutliner.release(), nullptr, false, false, false )); | |||
562 | ||||
563 | // #i7672# | |||
564 | // Since SdrBeginTextEdit actually creates the OutlinerView and thus also | |||
565 | // sets the background color, an own background color needs to be set | |||
566 | // after TextEditing was started. This is now done here. | |||
567 | if(bRet) | |||
568 | { | |||
569 | OutlinerView* pView = pSdrView->GetTextEditOutlinerView(); | |||
570 | ||||
571 | if(pView) | |||
572 | { | |||
573 | Color aBackground(pSh->GetShapeBackgrd()); | |||
574 | pView->SetBackgroundColor(aBackground); | |||
575 | } | |||
576 | ||||
577 | // editing should start at the end of text, spell checking at the beginning ... | |||
578 | ESelection aNewSelection(EE_PARA_NOT_FOUND((sal_Int32) 0x7FFFFFFF), EE_INDEX_NOT_FOUND((sal_Int32) 0x7FFFFFFF), EE_PARA_NOT_FOUND((sal_Int32) 0x7FFFFFFF), EE_INDEX_NOT_FOUND((sal_Int32) 0x7FFFFFFF)); | |||
579 | if (bSetSelectionToStart) | |||
580 | aNewSelection = ESelection(); | |||
581 | if (pView) | |||
582 | { | |||
583 | pView->SetSelection(aNewSelection); | |||
584 | ||||
585 | if (comphelper::LibreOfficeKit::isActive()) | |||
586 | { | |||
587 | OString sRect = pView->GetOutputArea().toString(); | |||
588 | SfxLokHelper::notifyOtherViews(this, LOK_CALLBACK_VIEW_LOCK, "rectangle", sRect); | |||
589 | } | |||
590 | } | |||
591 | } | |||
592 | ||||
593 | return bRet; | |||
594 | } | |||
595 | ||||
596 | // Is a DrawTextObject selected? | |||
597 | ||||
598 | bool SwView::IsTextTool() const | |||
599 | { | |||
600 | sal_uInt16 nId; | |||
601 | SdrInventor nInvent; | |||
602 | SdrView *pSdrView = GetWrtShell().GetDrawView(); | |||
603 | OSL_ENSURE( pSdrView, "IsTextTool without DrawView?" )do { if (true && (!(pSdrView))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/viewdraw.cxx" ":" "603" ": "), "%s", "IsTextTool without DrawView?"); } } while (false); | |||
604 | ||||
605 | if (pSdrView->IsCreateMode()) | |||
606 | pSdrView->SetCreateMode(false); | |||
607 | ||||
608 | pSdrView->TakeCurrentObj(nId,nInvent); | |||
609 | return nInvent == SdrInventor::Default; | |||
610 | } | |||
611 | ||||
612 | SdrView* SwView::GetDrawView() const | |||
613 | { | |||
614 | return GetWrtShell().GetDrawView(); | |||
615 | } | |||
616 | ||||
617 | bool SwView::IsBezierEditMode() const | |||
618 | { | |||
619 | return (!IsDrawSelMode() && GetWrtShell().GetDrawView()->HasMarkablePoints()); | |||
620 | } | |||
621 | ||||
622 | bool SwView::IsFormMode() const | |||
623 | { | |||
624 | if (GetDrawFuncPtr() && GetDrawFuncPtr()->IsCreateObj()) | |||
625 | { | |||
626 | return GetDrawFuncPtr()->IsInsertForm(); | |||
627 | } | |||
628 | ||||
629 | return AreOnlyFormsSelected(); | |||
630 | } | |||
631 | ||||
632 | void SwView::SetDrawFuncPtr(std::unique_ptr<SwDrawBase> pFuncPtr) | |||
633 | { | |||
634 | m_pDrawActual = std::move(pFuncPtr); | |||
635 | } | |||
636 | ||||
637 | void SwView::SetSelDrawSlot() | |||
638 | { | |||
639 | m_nDrawSfxId = SID_OBJECT_SELECT( 10000 + 128 ); | |||
640 | m_sDrawCustom.clear(); | |||
641 | } | |||
642 | ||||
643 | bool SwView::AreOnlyFormsSelected() const | |||
644 | { | |||
645 | if ( GetWrtShell().IsFrameSelected() ) | |||
646 | return false; | |||
647 | ||||
648 | bool bForm = true; | |||
649 | ||||
650 | SdrView* pSdrView = GetWrtShell().GetDrawView(); | |||
651 | ||||
652 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); | |||
653 | const size_t nCount = rMarkList.GetMarkCount(); | |||
654 | ||||
655 | if (nCount) | |||
656 | { | |||
657 | for (size_t i = 0; i < nCount; ++i) | |||
658 | { | |||
659 | // Except controls, are still normal draw objects selected? | |||
660 | SdrObject *pSdrObj = rMarkList.GetMark(i)->GetMarkedSdrObj(); | |||
661 | if (!pSdrObj) | |||
662 | continue; | |||
663 | ||||
664 | if (!HasOnlyObj(pSdrObj, SdrInventor::FmForm)) | |||
665 | { | |||
666 | bForm = false; | |||
667 | break; | |||
668 | } | |||
669 | } | |||
670 | } | |||
671 | else | |||
672 | bForm = false; | |||
673 | ||||
674 | return bForm; | |||
675 | } | |||
676 | ||||
677 | bool SwView::HasOnlyObj(SdrObject const *pSdrObj, SdrInventor eObjInventor) const | |||
678 | { | |||
679 | bool bRet = false; | |||
680 | ||||
681 | if (pSdrObj->IsGroupObject()) | |||
682 | { | |||
683 | SdrObjList* pList = pSdrObj->GetSubList(); | |||
684 | const size_t nCnt = pList->GetObjCount(); | |||
685 | ||||
686 | for (size_t i = 0; i < nCnt; ++i) | |||
687 | { | |||
688 | bRet = HasOnlyObj(pList->GetObj(i), eObjInventor); | |||
689 | if (!bRet) | |||
690 | break; | |||
691 | } | |||
692 | } | |||
693 | else if (eObjInventor == pSdrObj->GetObjInventor()) | |||
694 | return true; | |||
695 | ||||
696 | return bRet; | |||
697 | } | |||
698 | ||||
699 | //#i87414# mod | |||
700 | IMPL_LINK(SwView, OnlineSpellCallback, SpellCallbackInfo&, rInfo, void)void SwView::LinkStubOnlineSpellCallback(void * instance, SpellCallbackInfo & data) { return static_cast<SwView *>(instance)-> OnlineSpellCallback(data); } void SwView::OnlineSpellCallback (SpellCallbackInfo& rInfo) | |||
701 | { | |||
702 | if (rInfo.nCommand == SpellCallbackCommand::STARTSPELLDLG) | |||
703 | GetViewFrame()->GetDispatcher()->Execute( FN_SPELL_GRAMMAR_DIALOG((20000 + 2200) + 105), SfxCallMode::ASYNCHRON); | |||
704 | else if (rInfo.nCommand == SpellCallbackCommand::AUTOCORRECT_OPTIONS) | |||
705 | GetViewFrame()->GetDispatcher()->Execute( SID_AUTO_CORRECT_DLG(10000 + 424), SfxCallMode::ASYNCHRON ); | |||
706 | } | |||
707 | ||||
708 | bool SwView::ExecDrwTextSpellPopup(const Point& rPt) | |||
709 | { | |||
710 | bool bRet = false; | |||
711 | SdrView *pSdrView = m_pWrtShell->GetDrawView(); | |||
712 | OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); | |||
713 | Point aPos( GetEditWin().LogicToPixel( rPt ) ); | |||
714 | ||||
715 | if (pOLV->IsWrongSpelledWordAtPos( aPos )) | |||
716 | { | |||
717 | bRet = true; | |||
718 | Link<SpellCallbackInfo&,void> aLink = LINK(this, SwView, OnlineSpellCallback)::tools::detail::makeLink( ::tools::detail::castTo<SwView * >(this), &SwView::LinkStubOnlineSpellCallback); | |||
719 | pOLV->ExecuteSpellPopup( aPos,&aLink ); | |||
720 | } | |||
721 | return bRet; | |||
722 | } | |||
723 | ||||
724 | bool SwView::IsDrawTextHyphenate() | |||
725 | { | |||
726 | SdrView *pSdrView = m_pWrtShell->GetDrawView(); | |||
727 | bool bHyphenate = false; | |||
728 | ||||
729 | SfxItemSet aNewAttr( pSdrView->GetModel()->GetItemPool(), | |||
730 | svl::Items<EE_PARA_HYPHENATE, EE_PARA_HYPHENATE>{} ); | |||
731 | pSdrView->GetAttributes( aNewAttr ); | |||
732 | if( aNewAttr.GetItemState( EE_PARA_HYPHENATE ) >= SfxItemState::DEFAULT ) | |||
733 | bHyphenate = aNewAttr.Get( EE_PARA_HYPHENATE ).GetValue(); | |||
734 | ||||
735 | return bHyphenate; | |||
736 | } | |||
737 | ||||
738 | void SwView::HyphenateDrawText() | |||
739 | { | |||
740 | SdrView *pSdrView = m_pWrtShell->GetDrawView(); | |||
741 | bool bHyphenate = IsDrawTextHyphenate(); | |||
742 | ||||
743 | SfxItemSet aSet( GetPool(), svl::Items<EE_PARA_HYPHENATE, EE_PARA_HYPHENATE>{} ); | |||
744 | aSet.Put( SfxBoolItem( EE_PARA_HYPHENATE, !bHyphenate ) ); | |||
745 | pSdrView->SetAttributes( aSet ); | |||
746 | GetViewFrame()->GetBindings().Invalidate(FN_HYPHENATE_OPT_DLG((20000 + 600) + 5 )); | |||
747 | } | |||
748 | ||||
749 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |