File: | home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx |
Warning: | line 4137, 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 <swtypes.hxx> | ||||
21 | #include <hintids.hxx> | ||||
22 | #include <com/sun/star/accessibility/XAccessible.hpp> | ||||
23 | #include <comphelper/string.hxx> | ||||
24 | #include <com/sun/star/i18n/XBreakIterator.hpp> | ||||
25 | #include <com/sun/star/i18n/ScriptType.hpp> | ||||
26 | #include <com/sun/star/i18n/InputSequenceCheckMode.hpp> | ||||
27 | #include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp> | ||||
28 | |||||
29 | #include <com/sun/star/i18n/UnicodeScript.hpp> | ||||
30 | #include <com/sun/star/i18n/CalendarFieldIndex.hpp> | ||||
31 | #include <com/sun/star/ui/ContextMenuExecuteEvent.hpp> | ||||
32 | |||||
33 | #include <vcl/inputctx.hxx> | ||||
34 | #include <vcl/help.hxx> | ||||
35 | #include <vcl/weld.hxx> | ||||
36 | #include <vcl/ptrstyle.hxx> | ||||
37 | #include <svl/macitem.hxx> | ||||
38 | #include <unotools/securityoptions.hxx> | ||||
39 | #include <basic/sbxvar.hxx> | ||||
40 | #include <svl/ctloptions.hxx> | ||||
41 | #include <basic/sbx.hxx> | ||||
42 | #include <svl/eitem.hxx> | ||||
43 | #include <svl/stritem.hxx> | ||||
44 | #include <sfx2/ipclient.hxx> | ||||
45 | #include <sfx2/viewfrm.hxx> | ||||
46 | #include <sfx2/request.hxx> | ||||
47 | #include <sfx2/bindings.hxx> | ||||
48 | #include <sfx2/dispatch.hxx> | ||||
49 | #include <svl/ptitem.hxx> | ||||
50 | #include <editeng/sizeitem.hxx> | ||||
51 | #include <editeng/langitem.hxx> | ||||
52 | #include <svx/svdview.hxx> | ||||
53 | #include <svx/svdhdl.hxx> | ||||
54 | #include <svx/svdoutl.hxx> | ||||
55 | #include <editeng/editeng.hxx> | ||||
56 | #include <editeng/editview.hxx> | ||||
57 | #include <editeng/svxacorr.hxx> | ||||
58 | #include <editeng/flditem.hxx> | ||||
59 | #include <editeng/colritem.hxx> | ||||
60 | #include <unotools/charclass.hxx> | ||||
61 | #include <unotools/datetime.hxx> | ||||
62 | |||||
63 | #include <comphelper/lok.hxx> | ||||
64 | #include <sfx2/lokhelper.hxx> | ||||
65 | |||||
66 | #include <editeng/acorrcfg.hxx> | ||||
67 | #include <SwSmartTagMgr.hxx> | ||||
68 | #include <edtdd.hxx> | ||||
69 | #include <edtwin.hxx> | ||||
70 | #include <view.hxx> | ||||
71 | #include <wrtsh.hxx> | ||||
72 | #include <IDocumentDrawModelAccess.hxx> | ||||
73 | #include <IDocumentUndoRedo.hxx> | ||||
74 | #include <textboxhelper.hxx> | ||||
75 | #include <dcontact.hxx> | ||||
76 | #include <fldbas.hxx> | ||||
77 | #include <swmodule.hxx> | ||||
78 | #include <docsh.hxx> | ||||
79 | #include <viewopt.hxx> | ||||
80 | #include <drawbase.hxx> | ||||
81 | #include <dselect.hxx> | ||||
82 | #include <textsh.hxx> | ||||
83 | #include <shdwcrsr.hxx> | ||||
84 | #include <txatbase.hxx> | ||||
85 | #include <fmtanchr.hxx> | ||||
86 | #include <fmtornt.hxx> | ||||
87 | #include <fmthdft.hxx> | ||||
88 | #include <frmfmt.hxx> | ||||
89 | #include <modcfg.hxx> | ||||
90 | #include <fmtcol.hxx> | ||||
91 | #include <wview.hxx> | ||||
92 | #include <gloslst.hxx> | ||||
93 | #include <inputwin.hxx> | ||||
94 | #include <gloshdl.hxx> | ||||
95 | #include <swundo.hxx> | ||||
96 | #include <drwtxtsh.hxx> | ||||
97 | #include <fchrfmt.hxx> | ||||
98 | #include "romenu.hxx" | ||||
99 | #include <initui.hxx> | ||||
100 | #include <frmatr.hxx> | ||||
101 | #include <extinput.hxx> | ||||
102 | #include <acmplwrd.hxx> | ||||
103 | #include <swcalwrp.hxx> | ||||
104 | #include <swdtflvr.hxx> | ||||
105 | #include <breakit.hxx> | ||||
106 | #include <checkit.hxx> | ||||
107 | #include <pagefrm.hxx> | ||||
108 | |||||
109 | #include <helpids.h> | ||||
110 | #include <cmdid.h> | ||||
111 | #include <uitool.hxx> | ||||
112 | #include <fmtfollowtextflow.hxx> | ||||
113 | #include <toolkit/helper/vclunohelper.hxx> | ||||
114 | #include <charfmt.hxx> | ||||
115 | #include <numrule.hxx> | ||||
116 | #include <pagedesc.hxx> | ||||
117 | #include <svtools/ruler.hxx> | ||||
118 | #include <formatclipboard.hxx> | ||||
119 | #include <vcl/svapp.hxx> | ||||
120 | #include <wordcountdialog.hxx> | ||||
121 | #include <fmtfld.hxx> | ||||
122 | |||||
123 | #include <IMark.hxx> | ||||
124 | #include <doc.hxx> | ||||
125 | #include <xmloff/odffields.hxx> | ||||
126 | |||||
127 | #include <PostItMgr.hxx> | ||||
128 | #include <FrameControlsManager.hxx> | ||||
129 | #include <AnnotationWin.hxx> | ||||
130 | |||||
131 | #include <algorithm> | ||||
132 | #include <vector> | ||||
133 | |||||
134 | #include <rootfrm.hxx> | ||||
135 | |||||
136 | #include <unotools/syslocaleoptions.hxx> | ||||
137 | #include <i18nlangtag/mslangid.hxx> | ||||
138 | #include <salhelper/singletonref.hxx> | ||||
139 | #include <sfx2/event.hxx> | ||||
140 | #include <memory> | ||||
141 | |||||
142 | #include <IDocumentOutlineNodes.hxx> | ||||
143 | #include <ndtxt.hxx> | ||||
144 | #include <cntfrm.hxx> | ||||
145 | #include <txtfrm.hxx> | ||||
146 | #include <strings.hrc> | ||||
147 | |||||
148 | using namespace sw::mark; | ||||
149 | using namespace ::com::sun::star; | ||||
150 | |||||
151 | /** | ||||
152 | * Globals | ||||
153 | */ | ||||
154 | static bool g_bInputLanguageSwitched = false; | ||||
155 | |||||
156 | // Usually in MouseButtonUp a selection is revoked when the selection is | ||||
157 | // not currently being pulled open. Unfortunately in MouseButtonDown there | ||||
158 | // is being selected at double/triple click. That selection is completely | ||||
159 | // finished in the Handler and thus can't be distinguished in the Up. | ||||
160 | // To resolve this g_bHoldSelection is set in Down and evaluated in Up. | ||||
161 | static bool g_bHoldSelection = false; | ||||
162 | |||||
163 | bool g_bFrameDrag = false; | ||||
164 | static bool g_bValidCursorPos = false; | ||||
165 | static bool g_bModePushed = false; | ||||
166 | bool g_bDDTimerStarted = false; | ||||
167 | bool g_bFlushCharBuffer = false; | ||||
168 | bool g_bDDINetAttr = false; | ||||
169 | static SdrHdlKind g_eSdrMoveHdl = SdrHdlKind::User; | ||||
170 | |||||
171 | QuickHelpData* SwEditWin::m_pQuickHlpData = nullptr; | ||||
172 | |||||
173 | long SwEditWin::m_nDDStartPosY = 0; | ||||
174 | long SwEditWin::m_nDDStartPosX = 0; | ||||
175 | |||||
176 | static SfxShell* lcl_GetTextShellFromDispatcher( SwView const & rView ); | ||||
177 | |||||
178 | /// Check if the selected shape has a TextBox: if so, go into that instead. | ||||
179 | static bool lcl_goIntoTextBox(SwEditWin& rEditWin, SwWrtShell& rSh) | ||||
180 | { | ||||
181 | SdrMark* pMark = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0); | ||||
182 | if (!pMark) | ||||
183 | return false; | ||||
184 | |||||
185 | SdrObject* pSdrObject = pMark->GetMarkedSdrObj(); | ||||
186 | SwFrameFormat* pObjectFormat = ::FindFrameFormat(pSdrObject); | ||||
187 | if (SwFrameFormat* pTextBoxFormat = SwTextBoxHelper::getOtherTextBoxFormat(pObjectFormat, RES_DRAWFRMFMT)) | ||||
188 | { | ||||
189 | SdrObject* pTextBox = pTextBoxFormat->FindRealSdrObject(); | ||||
190 | SdrView* pSdrView = rSh.GetDrawView(); | ||||
191 | // Unmark the shape. | ||||
192 | pSdrView->UnmarkAllObj(); | ||||
193 | // Mark the textbox. | ||||
194 | rSh.SelectObj(Point(), SW_ALLOW_TEXTBOX8, pTextBox); | ||||
195 | // Clear the DrawFuncPtr. | ||||
196 | rEditWin.StopInsFrame(); | ||||
197 | return true; | ||||
198 | } | ||||
199 | return false; | ||||
200 | } | ||||
201 | |||||
202 | class SwAnchorMarker | ||||
203 | { | ||||
204 | SdrHdl* pHdl; | ||||
205 | Point aHdlPos; | ||||
206 | Point aLastPos; | ||||
207 | bool bTopRightHandle; | ||||
208 | public: | ||||
209 | explicit SwAnchorMarker( SdrHdl* pH ) | ||||
210 | : pHdl( pH ) | ||||
211 | , aHdlPos( pH->GetPos() ) | ||||
212 | , aLastPos( pH->GetPos() ) | ||||
213 | , bTopRightHandle( pH->GetKind() == SdrHdlKind::Anchor_TR ) | ||||
214 | {} | ||||
215 | const Point& GetLastPos() const { return aLastPos; } | ||||
216 | void SetLastPos( const Point& rNew ) { aLastPos = rNew; } | ||||
217 | void SetPos( const Point& rNew ) { pHdl->SetPos( rNew ); } | ||||
218 | const Point& GetHdlPos() const { return aHdlPos; } | ||||
219 | SdrHdl* GetHdl() const { return pHdl; } | ||||
220 | void ChgHdl( SdrHdl* pNew ) | ||||
221 | { | ||||
222 | pHdl = pNew; | ||||
223 | if ( pHdl ) | ||||
224 | { | ||||
225 | bTopRightHandle = (pHdl->GetKind() == SdrHdlKind::Anchor_TR); | ||||
226 | } | ||||
227 | } | ||||
228 | Point GetPosForHitTest( const OutputDevice& rOut ) | ||||
229 | { | ||||
230 | Point aHitTestPos( pHdl->GetPos() ); | ||||
231 | aHitTestPos = rOut.LogicToPixel( aHitTestPos ); | ||||
232 | if ( bTopRightHandle ) | ||||
233 | { | ||||
234 | aHitTestPos += Point( -1, 1 ); | ||||
235 | } | ||||
236 | else | ||||
237 | { | ||||
238 | aHitTestPos += Point( 1, 1 ); | ||||
239 | } | ||||
240 | aHitTestPos = rOut.PixelToLogic( aHitTestPos ); | ||||
241 | |||||
242 | return aHitTestPos; | ||||
243 | } | ||||
244 | }; | ||||
245 | |||||
246 | /// Assists with auto-completion of AutoComplete words and AutoText names. | ||||
247 | struct QuickHelpData | ||||
248 | { | ||||
249 | /// Strings that at least partially match an input word, and match length. | ||||
250 | std::vector<std::pair<OUString, sal_uInt16>> m_aHelpStrings; | ||||
251 | /// Index of the current help string. | ||||
252 | sal_uInt16 nCurArrPos; | ||||
253 | static constexpr sal_uInt16 nNoPos = std::numeric_limits<sal_uInt16>::max(); | ||||
254 | |||||
255 | /// Help data stores AutoText names rather than AutoComplete words. | ||||
256 | bool m_bIsAutoText; | ||||
257 | /// Display help string as a tip rather than inline. | ||||
258 | bool m_bIsTip; | ||||
259 | /// Tip ID when a help string is displayed as a tip. | ||||
260 | void* nTipId; | ||||
261 | /// Append a space character to the displayed help string (if appropriate). | ||||
262 | bool m_bAppendSpace; | ||||
263 | |||||
264 | /// Help string is currently displayed. | ||||
265 | bool m_bIsDisplayed; | ||||
266 | |||||
267 | QuickHelpData() { ClearContent(); } | ||||
268 | |||||
269 | void Move( QuickHelpData& rCpy ); | ||||
270 | void ClearContent(); | ||||
271 | void Start(SwWrtShell& rSh, bool bRestart); | ||||
272 | void Stop( SwWrtShell& rSh ); | ||||
273 | |||||
274 | bool HasContent() const { return !m_aHelpStrings.empty() && nCurArrPos != nNoPos; } | ||||
275 | const OUString& CurStr() const { return m_aHelpStrings[nCurArrPos].first; } | ||||
276 | sal_uInt16 CurLen() const { return m_aHelpStrings[nCurArrPos].second; } | ||||
277 | |||||
278 | /// Next help string. | ||||
279 | void Next( bool bEndLess ) | ||||
280 | { | ||||
281 | if( ++nCurArrPos >= m_aHelpStrings.size() ) | ||||
282 | nCurArrPos = (bEndLess && !m_bIsAutoText ) ? 0 : nCurArrPos-1; | ||||
283 | } | ||||
284 | /// Previous help string. | ||||
285 | void Previous( bool bEndLess ) | ||||
286 | { | ||||
287 | if( 0 == nCurArrPos-- ) | ||||
288 | nCurArrPos = (bEndLess && !m_bIsAutoText ) ? m_aHelpStrings.size()-1 : 0; | ||||
289 | } | ||||
290 | |||||
291 | // Fills internal structures with hopefully helpful information. | ||||
292 | void FillStrArr( SwWrtShell const & rSh, const OUString& rWord ); | ||||
293 | void SortAndFilter(const OUString &rOrigWord); | ||||
294 | }; | ||||
295 | |||||
296 | /** | ||||
297 | * Avoid minimal movement shiver | ||||
298 | */ | ||||
299 | #define HIT_PIX2 2 /* hit tolerance in pixel */ | ||||
300 | #define MIN_MOVE4 4 | ||||
301 | |||||
302 | static bool IsMinMove(const Point &rStartPos, const Point &rLPt) | ||||
303 | { | ||||
304 | return std::abs(rStartPos.X() - rLPt.X()) > MIN_MOVE4 || | ||||
305 | std::abs(rStartPos.Y() - rLPt.Y()) > MIN_MOVE4; | ||||
306 | } | ||||
307 | |||||
308 | /** | ||||
309 | * For MouseButtonDown - determine whether a DrawObject | ||||
310 | * a NO SwgFrame was hit! Shift/Ctrl should only result | ||||
311 | * in selecting, with DrawObjects; at SwgFlys to trigger | ||||
312 | * hyperlinks if applicable (Download/NewWindow!) | ||||
313 | */ | ||||
314 | static bool IsDrawObjSelectable( const SwWrtShell& rSh, const Point& rPt ) | ||||
315 | { | ||||
316 | bool bRet = true; | ||||
317 | SdrObject* pObj; | ||||
318 | switch( rSh.GetObjCntType( rPt, pObj )) | ||||
319 | { | ||||
320 | case OBJCNT_NONE: | ||||
321 | case OBJCNT_FLY: | ||||
322 | case OBJCNT_GRF: | ||||
323 | case OBJCNT_OLE: | ||||
324 | bRet = false; | ||||
325 | break; | ||||
326 | default:; //prevent warning | ||||
327 | } | ||||
328 | return bRet; | ||||
329 | } | ||||
330 | |||||
331 | /* | ||||
332 | * Switch pointer | ||||
333 | */ | ||||
334 | void SwEditWin::UpdatePointer(const Point &rLPt, sal_uInt16 nModifier ) | ||||
335 | { | ||||
336 | SetQuickHelpText(OUString()); | ||||
337 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
338 | if( m_pApplyTempl ) | ||||
339 | { | ||||
340 | PointerStyle eStyle = PointerStyle::Fill; | ||||
341 | if ( rSh.IsOverReadOnlyPos( rLPt ) ) | ||||
342 | { | ||||
343 | m_pUserMarker.reset(); | ||||
344 | |||||
345 | eStyle = PointerStyle::NotAllowed; | ||||
346 | } | ||||
347 | else | ||||
348 | { | ||||
349 | SwRect aRect; | ||||
350 | SwRect* pRect = &aRect; | ||||
351 | const SwFrameFormat* pFormat = nullptr; | ||||
352 | |||||
353 | bool bFrameIsValidTarget = false; | ||||
354 | if( m_pApplyTempl->m_pFormatClipboard ) | ||||
355 | bFrameIsValidTarget = m_pApplyTempl->m_pFormatClipboard->HasContentForThisType( SelectionType::Frame ); | ||||
356 | else if( !m_pApplyTempl->nColor ) | ||||
357 | bFrameIsValidTarget = ( m_pApplyTempl->eType == SfxStyleFamily::Frame ); | ||||
358 | |||||
359 | if( bFrameIsValidTarget && | ||||
360 | nullptr !=(pFormat = rSh.GetFormatFromObj( rLPt, &pRect )) && | ||||
361 | dynamic_cast<const SwFlyFrameFormat*>( pFormat) ) | ||||
362 | { | ||||
363 | //turn on highlight for frame | ||||
364 | tools::Rectangle aTmp( pRect->SVRect() ); | ||||
365 | |||||
366 | if ( !m_pUserMarker ) | ||||
367 | { | ||||
368 | m_pUserMarker.reset(new SdrDropMarkerOverlay( *rSh.GetDrawView(), aTmp )); | ||||
369 | } | ||||
370 | } | ||||
371 | else | ||||
372 | { | ||||
373 | m_pUserMarker.reset(); | ||||
374 | } | ||||
375 | |||||
376 | rSh.SwCursorShell::SetVisibleCursor( rLPt ); | ||||
377 | } | ||||
378 | SetPointer( eStyle ); | ||||
379 | return; | ||||
380 | } | ||||
381 | |||||
382 | if( !rSh.VisArea().Width() ) | ||||
383 | return; | ||||
384 | |||||
385 | CurrShell aCurr(&rSh); | ||||
386 | |||||
387 | if ( IsChainMode() ) | ||||
388 | { | ||||
389 | SwRect aRect; | ||||
390 | SwChainRet nChainable = rSh.Chainable( aRect, *rSh.GetFlyFrameFormat(), rLPt ); | ||||
391 | PointerStyle eStyle = nChainable != SwChainRet::OK | ||||
392 | ? PointerStyle::ChainNotAllowed : PointerStyle::Chain; | ||||
393 | if ( nChainable == SwChainRet::OK ) | ||||
394 | { | ||||
395 | tools::Rectangle aTmp( aRect.SVRect() ); | ||||
396 | |||||
397 | if ( !m_pUserMarker ) | ||||
398 | { | ||||
399 | m_pUserMarker.reset(new SdrDropMarkerOverlay( *rSh.GetDrawView(), aTmp )); | ||||
400 | } | ||||
401 | } | ||||
402 | else | ||||
403 | { | ||||
404 | m_pUserMarker.reset(); | ||||
405 | } | ||||
406 | |||||
407 | SetPointer( eStyle ); | ||||
408 | return; | ||||
409 | } | ||||
410 | |||||
411 | bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly(); | ||||
412 | if ( !bExecHyperlinks ) | ||||
413 | { | ||||
414 | SvtSecurityOptions aSecOpts; | ||||
415 | const bool bSecureOption = aSecOpts.IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink ); | ||||
416 | if ( ( bSecureOption && nModifier == KEY_MOD1 ) || | ||||
417 | ( !bSecureOption && nModifier != KEY_MOD1 ) ) | ||||
418 | bExecHyperlinks = true; | ||||
419 | } | ||||
420 | |||||
421 | const bool bExecSmarttags = nModifier == KEY_MOD1; | ||||
422 | |||||
423 | SdrView *pSdrView = rSh.GetDrawView(); | ||||
424 | bool bPrefSdrPointer = false; | ||||
425 | bool bHitHandle = false; | ||||
426 | bool bCntAtPos = false; | ||||
427 | bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() && | ||||
428 | rSh.IsCursorReadonly(); | ||||
429 | m_aActHitType = SdrHitKind::NONE; | ||||
430 | PointerStyle eStyle = PointerStyle::Text; | ||||
431 | if ( !pSdrView ) | ||||
432 | bCntAtPos = true; | ||||
433 | else if ( (bHitHandle = (pSdrView->PickHandle(rLPt) != nullptr)) ) | ||||
434 | { | ||||
435 | m_aActHitType = SdrHitKind::Object; | ||||
436 | bPrefSdrPointer = true; | ||||
437 | } | ||||
438 | else | ||||
439 | { | ||||
440 | const bool bNotInSelObj = !rSh.IsInsideSelectedObj( rLPt ); | ||||
441 | if ( m_rView.GetDrawFuncPtr() && !m_bInsDraw && bNotInSelObj ) | ||||
442 | { | ||||
443 | m_aActHitType = SdrHitKind::Object; | ||||
444 | if (IsObjectSelect()) | ||||
445 | eStyle = PointerStyle::Arrow; | ||||
446 | else | ||||
447 | bPrefSdrPointer = true; | ||||
448 | } | ||||
449 | else | ||||
450 | { | ||||
451 | SdrPageView* pPV = nullptr; | ||||
452 | pSdrView->SetHitTolerancePixel( HIT_PIX2 ); | ||||
453 | SdrObject* pObj = (bNotInSelObj && bExecHyperlinks) ? | ||||
454 | pSdrView->PickObj(rLPt, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::PICKMACRO) : | ||||
455 | nullptr; | ||||
456 | if (pObj) | ||||
457 | { | ||||
458 | SdrObjMacroHitRec aTmp; | ||||
459 | aTmp.aPos = rLPt; | ||||
460 | aTmp.pPageView = pPV; | ||||
461 | SetPointer( pObj->GetMacroPointer( aTmp ) ); | ||||
462 | return; | ||||
463 | } | ||||
464 | else | ||||
465 | { | ||||
466 | // dvo: IsObjSelectable() eventually calls SdrView::PickObj, so | ||||
467 | // apparently this is used to determine whether this is a | ||||
468 | // drawling layer object or not. | ||||
469 | if ( rSh.IsObjSelectable( rLPt ) ) | ||||
470 | { | ||||
471 | if (pSdrView->IsTextEdit()) | ||||
472 | { | ||||
473 | m_aActHitType = SdrHitKind::NONE; | ||||
474 | bPrefSdrPointer = true; | ||||
475 | } | ||||
476 | else | ||||
477 | { | ||||
478 | SdrViewEvent aVEvt; | ||||
479 | SdrHitKind eHit = pSdrView->PickAnything(rLPt, aVEvt); | ||||
480 | |||||
481 | if (eHit == SdrHitKind::UrlField && bExecHyperlinks) | ||||
482 | { | ||||
483 | m_aActHitType = SdrHitKind::Object; | ||||
484 | bPrefSdrPointer = true; | ||||
485 | } | ||||
486 | else | ||||
487 | { | ||||
488 | // if we're over a selected object, we show an | ||||
489 | // ARROW by default. We only show a MOVE if 1) the | ||||
490 | // object is selected, and 2) it may be moved | ||||
491 | // (i.e., position is not protected). | ||||
492 | bool bMovable = | ||||
493 | (!bNotInSelObj) && | ||||
494 | (rSh.IsObjSelected() || rSh.IsFrameSelected()) && | ||||
495 | (rSh.IsSelObjProtected(FlyProtectFlags::Pos) == FlyProtectFlags::NONE); | ||||
496 | |||||
497 | SdrObject* pSelectableObj = rSh.GetObjAt(rLPt); | ||||
498 | // Don't update pointer if this is a background image only. | ||||
499 | if (pSelectableObj->GetLayer() != rSh.GetDoc()->getIDocumentDrawModelAccess().GetHellId()) | ||||
500 | eStyle = bMovable ? PointerStyle::Move : PointerStyle::Arrow; | ||||
501 | m_aActHitType = SdrHitKind::Object; | ||||
502 | } | ||||
503 | } | ||||
504 | } | ||||
505 | else | ||||
506 | { | ||||
507 | if ( rSh.IsFrameSelected() && !bNotInSelObj ) | ||||
508 | { | ||||
509 | // dvo: this branch appears to be dead and should be | ||||
510 | // removed in a future version. Reason: The condition | ||||
511 | // !bNotInSelObj means that this branch will only be | ||||
512 | // executed in the cursor points inside a selected | ||||
513 | // object. However, if this is the case, the previous | ||||
514 | // if( rSh.IsObjSelectable(rLPt) ) must always be true: | ||||
515 | // rLPt is inside a selected object, then obviously | ||||
516 | // rLPt is over a selectable object. | ||||
517 | if (rSh.IsSelObjProtected(FlyProtectFlags::Size) != FlyProtectFlags::NONE) | ||||
518 | eStyle = PointerStyle::NotAllowed; | ||||
519 | else | ||||
520 | eStyle = PointerStyle::Move; | ||||
521 | m_aActHitType = SdrHitKind::Object; | ||||
522 | } | ||||
523 | else | ||||
524 | { | ||||
525 | if ( m_rView.GetDrawFuncPtr() ) | ||||
526 | bPrefSdrPointer = true; | ||||
527 | else | ||||
528 | bCntAtPos = true; | ||||
529 | } | ||||
530 | } | ||||
531 | } | ||||
532 | } | ||||
533 | } | ||||
534 | if ( bPrefSdrPointer ) | ||||
535 | { | ||||
536 | if (bIsDocReadOnly || (rSh.IsObjSelected() && rSh.IsSelObjProtected(FlyProtectFlags::Content) != FlyProtectFlags::NONE)) | ||||
537 | SetPointer( PointerStyle::NotAllowed ); | ||||
538 | else | ||||
539 | { | ||||
540 | if (m_rView.GetDrawFuncPtr() && m_rView.GetDrawFuncPtr()->IsInsertForm() && !bHitHandle) | ||||
541 | SetPointer( PointerStyle::DrawRect ); | ||||
542 | else | ||||
543 | SetPointer( pSdrView->GetPreferredPointer( rLPt, rSh.GetOut() ) ); | ||||
544 | } | ||||
545 | } | ||||
546 | else | ||||
547 | { | ||||
548 | if( !rSh.IsPageAtPos( rLPt ) || m_pAnchorMarker ) | ||||
549 | eStyle = PointerStyle::Arrow; | ||||
550 | else | ||||
551 | { | ||||
552 | // Even if we already have something, prefer URLs if possible. | ||||
553 | SwContentAtPos aUrlPos(IsAttrAtPos::InetAttr); | ||||
554 | if (bCntAtPos || rSh.GetContentAtPos(rLPt, aUrlPos)) | ||||
555 | { | ||||
556 | SwContentAtPos aSwContentAtPos( | ||||
557 | IsAttrAtPos::Field | | ||||
558 | IsAttrAtPos::ClickField | | ||||
559 | IsAttrAtPos::InetAttr | | ||||
560 | IsAttrAtPos::Ftn | | ||||
561 | IsAttrAtPos::SmartTag | | ||||
562 | IsAttrAtPos::Outline); | ||||
563 | if( rSh.GetContentAtPos( rLPt, aSwContentAtPos) ) | ||||
564 | { | ||||
565 | if (IsAttrAtPos::Outline == aSwContentAtPos.eContentAtPos) | ||||
566 | { | ||||
567 | if (nModifier == KEY_MOD1 | ||||
568 | && GetView().GetWrtShell().GetViewOptions()->IsShowOutlineContentVisibilityButton()) | ||||
569 | { | ||||
570 | eStyle = PointerStyle::RefHand; | ||||
571 | // set quick help | ||||
572 | if(aSwContentAtPos.aFnd.pNode && aSwContentAtPos.aFnd.pNode->IsTextNode()) | ||||
573 | { | ||||
574 | const SwNodes& rNds = GetView().GetWrtShell().GetDoc()->GetNodes(); | ||||
575 | SwOutlineNodes::size_type nPos; | ||||
576 | rNds.GetOutLineNds().Seek_Entry(aSwContentAtPos.aFnd.pNode->GetTextNode(), &nPos); | ||||
577 | SwOutlineNodes::size_type nOutlineNodesCount | ||||
578 | = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount(); | ||||
579 | int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos); | ||||
580 | OUString sQuickHelp(SwResId(STR_ClICK_OUTLINE_CONTENT_TOGGLE_VISIBILITYreinterpret_cast<char const *>("STR_CLICK_OUTLINE_CONTENT_TOGGLE_VISIBILITY" "\004" u8"Click to Toggle Outline Content Visibility"))); | ||||
581 | if (nPos + 1 < nOutlineNodesCount | ||||
582 | && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos + 1) > nLevel) | ||||
583 | sQuickHelp += " (" + SwResId(STR_CLICK_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXTreinterpret_cast<char const *>("STR_CLICK_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT" "\004" u8"right-click to include sub levels")) + ")"; | ||||
584 | SetQuickHelpText(sQuickHelp); | ||||
585 | } | ||||
586 | } | ||||
587 | } | ||||
588 | // Is edit inline input field | ||||
589 | else if (IsAttrAtPos::Field == aSwContentAtPos.eContentAtPos | ||||
590 | && aSwContentAtPos.pFndTextAttr != nullptr | ||||
591 | && aSwContentAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD) | ||||
592 | { | ||||
593 | const SwField *pCursorField = rSh.CursorInsideInputField() ? rSh.GetCurField( true ) : nullptr; | ||||
594 | if (!(pCursorField && pCursorField == aSwContentAtPos.pFndTextAttr->GetFormatField().GetField())) | ||||
595 | eStyle = PointerStyle::RefHand; | ||||
596 | } | ||||
597 | else | ||||
598 | { | ||||
599 | const bool bClickToFollow = IsAttrAtPos::InetAttr == aSwContentAtPos.eContentAtPos || | ||||
600 | IsAttrAtPos::SmartTag == aSwContentAtPos.eContentAtPos; | ||||
601 | if( !bClickToFollow || | ||||
602 | (IsAttrAtPos::InetAttr == aSwContentAtPos.eContentAtPos && bExecHyperlinks) || | ||||
603 | (IsAttrAtPos::SmartTag == aSwContentAtPos.eContentAtPos && bExecSmarttags) ) | ||||
604 | eStyle = PointerStyle::RefHand; | ||||
605 | } | ||||
606 | } | ||||
607 | } | ||||
608 | } | ||||
609 | |||||
610 | // which kind of text pointer have we to show - horz / vert - ? | ||||
611 | if( PointerStyle::Text == eStyle && rSh.IsInVerticalText( &rLPt )) | ||||
612 | eStyle = PointerStyle::TextVertical; | ||||
613 | else if (rSh.GetViewOptions()->CanHideWhitespace() && | ||||
614 | rSh.GetLayout()->IsBetweenPages(rLPt)) | ||||
615 | { | ||||
616 | if (rSh.GetViewOptions()->IsHideWhitespaceMode()) | ||||
617 | eStyle = PointerStyle::ShowWhitespace; | ||||
618 | else | ||||
619 | eStyle = PointerStyle::HideWhitespace; | ||||
620 | } | ||||
621 | |||||
622 | SetPointer( eStyle ); | ||||
623 | } | ||||
624 | } | ||||
625 | |||||
626 | /** | ||||
627 | * Increase timer for selection | ||||
628 | */ | ||||
629 | IMPL_LINK_NOARG(SwEditWin, TimerHandler, Timer *, void)void SwEditWin::LinkStubTimerHandler(void * instance, Timer * data) { return static_cast<SwEditWin *>(instance)-> TimerHandler(data); } void SwEditWin::TimerHandler(__attribute__ ((unused)) Timer *) | ||||
630 | { | ||||
631 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
632 | Point aModPt( m_aMovePos ); | ||||
633 | const SwRect aOldVis( rSh.VisArea() ); | ||||
634 | bool bDone = false; | ||||
635 | |||||
636 | if ( !rSh.VisArea().IsInside( aModPt ) ) | ||||
637 | { | ||||
638 | if ( m_bInsDraw ) | ||||
639 | { | ||||
640 | const int nMaxScroll = 40; | ||||
641 | m_rView.Scroll( tools::Rectangle(aModPt,Size(1,1)), nMaxScroll, nMaxScroll); | ||||
642 | bDone = true; | ||||
643 | } | ||||
644 | else if ( g_bFrameDrag ) | ||||
645 | { | ||||
646 | rSh.Drag(&aModPt, false); | ||||
647 | bDone = true; | ||||
648 | } | ||||
649 | if ( !bDone ) | ||||
650 | aModPt = rSh.GetContentPos( aModPt,aModPt.Y() > rSh.VisArea().Bottom() ); | ||||
651 | } | ||||
652 | if ( !bDone && !(g_bFrameDrag || m_bInsDraw) ) | ||||
653 | { | ||||
654 | if ( m_xRowColumnSelectionStart ) | ||||
655 | { | ||||
656 | Point aPos( aModPt ); | ||||
657 | rSh.SelectTableRowCol( *m_xRowColumnSelectionStart, &aPos, m_bIsRowDrag ); | ||||
658 | } | ||||
659 | else | ||||
660 | rSh.CallSetCursor( &aModPt, false ); | ||||
661 | |||||
662 | // It can be that a "jump" over a table cannot be accomplished like | ||||
663 | // that. So we jump over the table by Up/Down here. | ||||
664 | const SwRect& rVisArea = rSh.VisArea(); | ||||
665 | if( aOldVis == rVisArea && !rSh.IsStartOfDoc() && !rSh.IsEndOfDoc() ) | ||||
666 | { | ||||
667 | // take the center point of VisArea to | ||||
668 | // decide in which direction the user want. | ||||
669 | if( aModPt.Y() < ( rVisArea.Top() + rVisArea.Height() / 2 ) ) | ||||
670 | rSh.Up( true ); | ||||
671 | else | ||||
672 | rSh.Down( true ); | ||||
673 | } | ||||
674 | } | ||||
675 | |||||
676 | m_aMovePos += rSh.VisArea().Pos() - aOldVis.Pos(); | ||||
677 | JustifyAreaTimer(); | ||||
678 | } | ||||
679 | |||||
680 | void SwEditWin::JustifyAreaTimer() | ||||
681 | { | ||||
682 | const tools::Rectangle &rVisArea = GetView().GetVisArea(); | ||||
683 | #ifdef UNX1 | ||||
684 | const long coMinLen = 100; | ||||
685 | #else | ||||
686 | const long coMinLen = 50; | ||||
687 | #endif | ||||
688 | long const nTimeout = 800, | ||||
689 | nDiff = std::max( | ||||
690 | std::max( m_aMovePos.Y() - rVisArea.Bottom(), rVisArea.Top() - m_aMovePos.Y() ), | ||||
691 | std::max( m_aMovePos.X() - rVisArea.Right(), rVisArea.Left() - m_aMovePos.X())); | ||||
692 | m_aTimer.SetTimeout( std::max( coMinLen, nTimeout - nDiff*2L) ); | ||||
693 | } | ||||
694 | |||||
695 | void SwEditWin::LeaveArea(const Point &rPos) | ||||
696 | { | ||||
697 | m_aMovePos = rPos; | ||||
698 | JustifyAreaTimer(); | ||||
699 | if( !m_aTimer.IsActive() ) | ||||
700 | m_aTimer.Start(); | ||||
701 | m_pShadCursor.reset(); | ||||
702 | } | ||||
703 | |||||
704 | inline void SwEditWin::EnterArea() | ||||
705 | { | ||||
706 | m_aTimer.Stop(); | ||||
707 | } | ||||
708 | |||||
709 | /** | ||||
710 | * Insert mode for frames | ||||
711 | */ | ||||
712 | void SwEditWin::InsFrame(sal_uInt16 nCols) | ||||
713 | { | ||||
714 | StdDrawMode( OBJ_NONE, false ); | ||||
715 | m_bInsFrame = true; | ||||
716 | m_nInsFrameColCount = nCols; | ||||
717 | } | ||||
718 | |||||
719 | void SwEditWin::StdDrawMode( SdrObjKind eSdrObjectKind, bool bObjSelect ) | ||||
720 | { | ||||
721 | SetSdrDrawMode( eSdrObjectKind ); | ||||
722 | |||||
723 | if (bObjSelect) | ||||
724 | m_rView.SetDrawFuncPtr(std::make_unique<DrawSelection>( &m_rView.GetWrtShell(), this, &m_rView )); | ||||
725 | else | ||||
726 | m_rView.SetDrawFuncPtr(std::make_unique<SwDrawBase>( &m_rView.GetWrtShell(), this, &m_rView )); | ||||
727 | |||||
728 | m_rView.SetSelDrawSlot(); | ||||
729 | SetSdrDrawMode( eSdrObjectKind ); | ||||
730 | if (bObjSelect) | ||||
731 | m_rView.GetDrawFuncPtr()->Activate( SID_OBJECT_SELECT( 10000 + 128 ) ); | ||||
732 | else | ||||
733 | m_rView.GetDrawFuncPtr()->Activate( sal::static_int_cast< sal_uInt16 >(eSdrObjectKind) ); | ||||
734 | m_bInsFrame = false; | ||||
735 | m_nInsFrameColCount = 1; | ||||
736 | } | ||||
737 | |||||
738 | void SwEditWin::StopInsFrame() | ||||
739 | { | ||||
740 | if (m_rView.GetDrawFuncPtr()) | ||||
741 | { | ||||
742 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
743 | m_rView.SetDrawFuncPtr(nullptr); | ||||
744 | } | ||||
745 | m_rView.LeaveDrawCreate(); // leave construction mode | ||||
746 | m_bInsFrame = false; | ||||
747 | m_nInsFrameColCount = 1; | ||||
748 | } | ||||
749 | |||||
750 | bool SwEditWin::IsInputSequenceCheckingRequired( const OUString &rText, const SwPaM& rCursor ) | ||||
751 | { | ||||
752 | const SvtCTLOptions& rCTLOptions = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetCTLOptions(); | ||||
753 | if ( !rCTLOptions.IsCTLFontEnabled() || | ||||
754 | !rCTLOptions.IsCTLSequenceChecking() ) | ||||
755 | return false; | ||||
756 | |||||
757 | if ( 0 == rCursor.Start()->nContent.GetIndex() ) /* first char needs not to be checked */ | ||||
758 | return false; | ||||
759 | |||||
760 | SwBreakIt *pBreakIter = SwBreakIt::Get(); | ||||
761 | uno::Reference < i18n::XBreakIterator > xBI = pBreakIter->GetBreakIter(); | ||||
762 | assert(xBI.is())(static_cast <bool> (xBI.is()) ? void (0) : __assert_fail ("xBI.is()", "/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" , 762, __extension__ __PRETTY_FUNCTION__)); | ||||
763 | long nCTLScriptPos = -1; | ||||
764 | |||||
765 | if (xBI->getScriptType( rText, 0 ) == i18n::ScriptType::COMPLEX) | ||||
766 | nCTLScriptPos = 0; | ||||
767 | else | ||||
768 | nCTLScriptPos = xBI->nextScript( rText, 0, i18n::ScriptType::COMPLEX ); | ||||
769 | |||||
770 | return (0 <= nCTLScriptPos && nCTLScriptPos <= rText.getLength()); | ||||
771 | } | ||||
772 | |||||
773 | //return INVALID_HINT if language should not be explicitly overridden, the correct | ||||
774 | //HintId to use for the eBufferLanguage otherwise | ||||
775 | static sal_uInt16 lcl_isNonDefaultLanguage(LanguageType eBufferLanguage, SwView const & rView, | ||||
776 | const OUString &rInBuffer) | ||||
777 | { | ||||
778 | sal_uInt16 nWhich = INVALID_HINT; | ||||
779 | |||||
780 | //If the option to IgnoreLanguageChange is set, short-circuit this method | ||||
781 | //which results in the document/paragraph language remaining the same | ||||
782 | //despite a change to the keyboard/input language | ||||
783 | SvtSysLocaleOptions aSysLocaleOptions; | ||||
784 | if(aSysLocaleOptions.IsIgnoreLanguageChange()) | ||||
785 | { | ||||
786 | return INVALID_HINT; | ||||
787 | } | ||||
788 | |||||
789 | bool bLang = true; | ||||
790 | if(eBufferLanguage != LANGUAGE_DONTKNOWLanguageType(0x03FF)) | ||||
791 | { | ||||
792 | switch( SvtLanguageOptions::GetI18NScriptTypeOfLanguage( eBufferLanguage )) | ||||
793 | { | ||||
794 | case i18n::ScriptType::ASIAN: nWhich = RES_CHRATR_CJK_LANGUAGE; break; | ||||
795 | case i18n::ScriptType::COMPLEX: nWhich = RES_CHRATR_CTL_LANGUAGE; break; | ||||
796 | case i18n::ScriptType::LATIN: nWhich = RES_CHRATR_LANGUAGE; break; | ||||
797 | default: bLang = false; | ||||
798 | } | ||||
799 | if(bLang) | ||||
800 | { | ||||
801 | SfxItemSet aLangSet(rView.GetPool(), {{nWhich, nWhich}}); | ||||
802 | SwWrtShell& rSh = rView.GetWrtShell(); | ||||
803 | rSh.GetCurAttr(aLangSet); | ||||
804 | if(SfxItemState::DEFAULT <= aLangSet.GetItemState(nWhich)) | ||||
805 | { | ||||
806 | LanguageType eLang = static_cast<const SvxLanguageItem&>(aLangSet.Get(nWhich)).GetLanguage(); | ||||
807 | if ( eLang == eBufferLanguage ) | ||||
808 | { | ||||
809 | // current language attribute equal to language reported from system | ||||
810 | bLang = false; | ||||
811 | } | ||||
812 | else if ( !g_bInputLanguageSwitched && RES_CHRATR_LANGUAGE == nWhich ) | ||||
813 | { | ||||
814 | // special case: switching between two "LATIN" languages | ||||
815 | // In case the current keyboard setting might be suitable | ||||
816 | // for both languages we can't safely assume that the user | ||||
817 | // wants to use the language reported from the system, | ||||
818 | // except if we knew that it was explicitly switched (thus | ||||
819 | // the check for "bInputLangeSwitched"). | ||||
820 | |||||
821 | // The language reported by the system could be just the | ||||
822 | // system default language that the user is not even aware | ||||
823 | // of, because no language selection tool is installed at | ||||
824 | // all. In this case the OOo language should get preference | ||||
825 | // as it might have been selected by the user explicitly. | ||||
826 | |||||
827 | // Usually this case happens if the OOo language is | ||||
828 | // different to the system language but the system keyboard | ||||
829 | // is still suitable for the OOo language (e.g. writing | ||||
830 | // English texts with a German keyboard). | ||||
831 | |||||
832 | // For non-latin keyboards overwriting the attribute is | ||||
833 | // still valid. We do this for cyrillic and greek ATM. In | ||||
834 | // future versions of OOo this should be replaced by a | ||||
835 | // configuration switch that allows to give the preference | ||||
836 | // to the OOo setting or the system setting explicitly | ||||
837 | // and/or a better handling of the script type. | ||||
838 | i18n::UnicodeScript eType = !rInBuffer.isEmpty() ? | ||||
839 | GetAppCharClass().getScript( rInBuffer, 0 ) : | ||||
840 | i18n::UnicodeScript_kScriptCount; | ||||
841 | |||||
842 | bool bSystemIsNonLatin = false; | ||||
843 | switch ( eType ) | ||||
844 | { | ||||
845 | case i18n::UnicodeScript_kGreek: | ||||
846 | case i18n::UnicodeScript_kCyrillic: | ||||
847 | // in case other UnicodeScripts require special | ||||
848 | // keyboards they can be added here | ||||
849 | bSystemIsNonLatin = true; | ||||
850 | break; | ||||
851 | default: | ||||
852 | break; | ||||
853 | } | ||||
854 | |||||
855 | bool bOOoLangIsNonLatin = MsLangId::isNonLatinWestern( eLang); | ||||
856 | |||||
857 | bLang = (bSystemIsNonLatin != bOOoLangIsNonLatin); | ||||
858 | } | ||||
859 | } | ||||
860 | } | ||||
861 | } | ||||
862 | return bLang ? nWhich : INVALID_HINT; | ||||
863 | } | ||||
864 | |||||
865 | /** | ||||
866 | * Character buffer is inserted into the document | ||||
867 | */ | ||||
868 | void SwEditWin::FlushInBuffer() | ||||
869 | { | ||||
870 | if ( m_aInBuffer.isEmpty() ) | ||||
871 | return; | ||||
872 | |||||
873 | SwWrtShell& rSh = m_rView.GetWrtShell(); | ||||
874 | |||||
875 | // generate new sequence input checker if not already done | ||||
876 | if ( !pCheckIt ) | ||||
877 | pCheckIt = new SwCheckIt; | ||||
878 | |||||
879 | uno::Reference < i18n::XExtendedInputSequenceChecker > xISC = pCheckIt->xCheck; | ||||
880 | if ( xISC.is() && IsInputSequenceCheckingRequired( m_aInBuffer, *rSh.GetCursor() ) ) | ||||
881 | { | ||||
882 | |||||
883 | // apply (Thai) input sequence checking/correction | ||||
884 | |||||
885 | rSh.Push(); // push current cursor to stack | ||||
886 | |||||
887 | // get text from the beginning (i.e left side) of current selection | ||||
888 | // to the start of the paragraph | ||||
889 | rSh.NormalizePam(); // make point be the first (left) one | ||||
890 | if (!rSh.GetCursor()->HasMark()) | ||||
891 | rSh.GetCursor()->SetMark(); | ||||
892 | rSh.GetCursor()->GetMark()->nContent = 0; | ||||
893 | |||||
894 | const OUString aOldText( rSh.GetCursor()->GetText() ); | ||||
895 | const sal_Int32 nOldLen = aOldText.getLength(); | ||||
896 | |||||
897 | SvtCTLOptions& rCTLOptions = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetCTLOptions(); | ||||
898 | |||||
899 | sal_Int32 nExpandSelection = 0; | ||||
900 | if (nOldLen > 0) | ||||
901 | { | ||||
902 | sal_Int32 nTmpPos = nOldLen; | ||||
903 | sal_Int16 nCheckMode = rCTLOptions.IsCTLSequenceCheckingRestricted() ? | ||||
904 | i18n::InputSequenceCheckMode::STRICT : i18n::InputSequenceCheckMode::BASIC; | ||||
905 | |||||
906 | OUString aNewText( aOldText ); | ||||
907 | if (rCTLOptions.IsCTLSequenceCheckingTypeAndReplace()) | ||||
908 | { | ||||
909 | for( sal_Int32 k = 0; k < m_aInBuffer.getLength(); ++k) | ||||
910 | { | ||||
911 | const sal_Unicode cChar = m_aInBuffer[k]; | ||||
912 | const sal_Int32 nPrevPos =xISC->correctInputSequence( aNewText, nTmpPos - 1, cChar, nCheckMode ); | ||||
913 | |||||
914 | // valid sequence or sequence could be corrected: | ||||
915 | if (nPrevPos != aNewText.getLength()) | ||||
916 | nTmpPos = nPrevPos + 1; | ||||
917 | } | ||||
918 | |||||
919 | // find position of first character that has changed | ||||
920 | sal_Int32 nNewLen = aNewText.getLength(); | ||||
921 | const sal_Unicode *pOldText = aOldText.getStr(); | ||||
922 | const sal_Unicode *pNewText = aNewText.getStr(); | ||||
923 | sal_Int32 nChgPos = 0; | ||||
924 | while ( nChgPos < nOldLen && nChgPos < nNewLen && | ||||
925 | pOldText[nChgPos] == pNewText[nChgPos] ) | ||||
926 | ++nChgPos; | ||||
927 | |||||
928 | const sal_Int32 nChgLen = nNewLen - nChgPos; | ||||
929 | if (nChgLen) | ||||
930 | { | ||||
931 | m_aInBuffer = aNewText.copy( nChgPos, nChgLen ); | ||||
932 | nExpandSelection = nOldLen - nChgPos; | ||||
933 | } | ||||
934 | else | ||||
935 | m_aInBuffer.clear(); | ||||
936 | } | ||||
937 | else | ||||
938 | { | ||||
939 | for( sal_Int32 k = 0; k < m_aInBuffer.getLength(); ++k ) | ||||
940 | { | ||||
941 | const sal_Unicode cChar = m_aInBuffer[k]; | ||||
942 | if (xISC->checkInputSequence( aNewText, nTmpPos - 1, cChar, nCheckMode )) | ||||
943 | { | ||||
944 | // character can be inserted: | ||||
945 | aNewText += OUStringChar( cChar ); | ||||
946 | ++nTmpPos; | ||||
947 | } | ||||
948 | } | ||||
949 | m_aInBuffer = aNewText.copy( aOldText.getLength() ); // copy new text to be inserted to buffer | ||||
950 | } | ||||
951 | } | ||||
952 | |||||
953 | // at this point now we will insert the buffer text 'normally' some lines below... | ||||
954 | |||||
955 | rSh.Pop(SwCursorShell::PopMode::DeleteCurrent); | ||||
956 | |||||
957 | if (m_aInBuffer.isEmpty()) | ||||
958 | return; | ||||
959 | |||||
960 | // if text prior to the original selection needs to be changed | ||||
961 | // as well, we now expand the selection accordingly. | ||||
962 | SwPaM &rCursor = *rSh.GetCursor(); | ||||
963 | const sal_Int32 nCursorStartPos = rCursor.Start()->nContent.GetIndex(); | ||||
964 | OSL_ENSURE( nCursorStartPos >= nExpandSelection, "cannot expand selection as specified!!" )do { if (true && (!(nCursorStartPos >= nExpandSelection ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "964" ": "), "%s", "cannot expand selection as specified!!" ); } } while (false); | ||||
965 | if (nExpandSelection && nCursorStartPos >= nExpandSelection) | ||||
966 | { | ||||
967 | if (!rCursor.HasMark()) | ||||
968 | rCursor.SetMark(); | ||||
969 | rCursor.Start()->nContent -= nExpandSelection; | ||||
970 | } | ||||
971 | } | ||||
972 | |||||
973 | uno::Reference< frame::XDispatchRecorder > xRecorder = | ||||
974 | m_rView.GetViewFrame()->GetBindings().GetRecorder(); | ||||
975 | if ( xRecorder.is() ) | ||||
976 | { | ||||
977 | // determine shell | ||||
978 | SfxShell *pSfxShell = lcl_GetTextShellFromDispatcher( m_rView ); | ||||
979 | // generate request and record | ||||
980 | if (pSfxShell) | ||||
981 | { | ||||
982 | SfxRequest aReq( m_rView.GetViewFrame(), FN_INSERT_STRING((20000 + 300)+31) ); | ||||
983 | aReq.AppendItem( SfxStringItem( FN_INSERT_STRING((20000 + 300)+31), m_aInBuffer ) ); | ||||
984 | aReq.Done(); | ||||
985 | } | ||||
986 | } | ||||
987 | |||||
988 | sal_uInt16 nWhich = lcl_isNonDefaultLanguage(m_eBufferLanguage, m_rView, m_aInBuffer); | ||||
989 | if (nWhich != INVALID_HINT ) | ||||
990 | { | ||||
991 | SvxLanguageItem aLangItem( m_eBufferLanguage, nWhich ); | ||||
992 | rSh.SetAttrItem( aLangItem ); | ||||
993 | } | ||||
994 | |||||
995 | rSh.Insert( m_aInBuffer ); | ||||
996 | m_eBufferLanguage = LANGUAGE_DONTKNOWLanguageType(0x03FF); | ||||
997 | m_aInBuffer.clear(); | ||||
998 | g_bFlushCharBuffer = false; | ||||
999 | |||||
1000 | } | ||||
1001 | |||||
1002 | #define MOVE_LEFT_SMALL0 0 | ||||
1003 | #define MOVE_UP_SMALL1 1 | ||||
1004 | #define MOVE_RIGHT_BIG2 2 | ||||
1005 | #define MOVE_DOWN_BIG3 3 | ||||
1006 | #define MOVE_LEFT_BIG4 4 | ||||
1007 | #define MOVE_UP_BIG5 5 | ||||
1008 | #define MOVE_RIGHT_SMALL6 6 | ||||
1009 | #define MOVE_DOWN_SMALL7 7 | ||||
1010 | |||||
1011 | // #i121236# Support for shift key in writer | ||||
1012 | #define MOVE_LEFT_HUGE8 8 | ||||
1013 | #define MOVE_UP_HUGE9 9 | ||||
1014 | #define MOVE_RIGHT_HUGE10 10 | ||||
1015 | #define MOVE_DOWN_HUGE11 11 | ||||
1016 | |||||
1017 | void SwEditWin::ChangeFly( sal_uInt8 nDir, bool bWeb ) | ||||
1018 | { | ||||
1019 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
1020 | SwRect aTmp = rSh.GetFlyRect(); | ||||
1021 | if( !aTmp.HasArea() || | ||||
1022 | rSh.IsSelObjProtected( FlyProtectFlags::Pos ) != FlyProtectFlags::NONE ) | ||||
1023 | return; | ||||
1024 | |||||
1025 | SfxItemSet aSet( | ||||
1026 | rSh.GetAttrPool(), | ||||
1027 | svl::Items< | ||||
1028 | RES_FRM_SIZE, RES_FRM_SIZE, | ||||
1029 | RES_PROTECT, RES_PROTECT, | ||||
1030 | RES_VERT_ORIENT, RES_ANCHOR, | ||||
1031 | RES_COL, RES_COL, | ||||
1032 | RES_FOLLOW_TEXT_FLOW, RES_FOLLOW_TEXT_FLOW>{}); | ||||
1033 | rSh.GetFlyFrameAttr( aSet ); | ||||
1034 | RndStdIds eAnchorId = aSet.Get(RES_ANCHOR).GetAnchorId(); | ||||
1035 | Size aSnap; | ||||
1036 | bool bHuge(MOVE_LEFT_HUGE8 == nDir || | ||||
1037 | MOVE_UP_HUGE9 == nDir || | ||||
1038 | MOVE_RIGHT_HUGE10 == nDir || | ||||
1039 | MOVE_DOWN_HUGE11 == nDir); | ||||
1040 | |||||
1041 | if(MOVE_LEFT_SMALL0 == nDir || | ||||
1042 | MOVE_UP_SMALL1 == nDir || | ||||
1043 | MOVE_RIGHT_SMALL6 == nDir || | ||||
1044 | MOVE_DOWN_SMALL7 == nDir ) | ||||
1045 | { | ||||
1046 | aSnap = PixelToLogic(Size(1,1)); | ||||
1047 | } | ||||
1048 | else | ||||
1049 | { | ||||
1050 | aSnap = rSh.GetViewOptions()->GetSnapSize(); | ||||
1051 | short nDiv = rSh.GetViewOptions()->GetDivisionX(); | ||||
1052 | if ( nDiv > 0 ) | ||||
1053 | aSnap.setWidth( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Width()) / nDiv ) ); | ||||
1054 | nDiv = rSh.GetViewOptions()->GetDivisionY(); | ||||
1055 | if ( nDiv > 0 ) | ||||
1056 | aSnap.setHeight( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Height()) / nDiv ) ); | ||||
1057 | } | ||||
1058 | |||||
1059 | if(bHuge) | ||||
1060 | { | ||||
1061 | // #i121236# 567twips == 1cm, but just take three times the normal snap | ||||
1062 | aSnap = Size(aSnap.Width() * 3, aSnap.Height() * 3); | ||||
1063 | } | ||||
1064 | |||||
1065 | SwRect aBoundRect; | ||||
1066 | Point aRefPoint; | ||||
1067 | // adjustment for allowing vertical position | ||||
1068 | // aligned to page for fly frame anchored to paragraph or to character. | ||||
1069 | { | ||||
1070 | const SwFormatVertOrient& aVert( aSet.Get(RES_VERT_ORIENT) ); | ||||
1071 | const bool bFollowTextFlow = | ||||
1072 | aSet.Get(RES_FOLLOW_TEXT_FLOW).GetValue(); | ||||
1073 | const SwPosition* pToCharContentPos = aSet.Get(RES_ANCHOR).GetContentAnchor(); | ||||
1074 | rSh.CalcBoundRect( aBoundRect, eAnchorId, | ||||
1075 | text::RelOrientation::FRAME, aVert.GetRelationOrient(), | ||||
1076 | pToCharContentPos, bFollowTextFlow, | ||||
1077 | false, &aRefPoint ); | ||||
1078 | } | ||||
1079 | long nLeft = std::min( aTmp.Left() - aBoundRect.Left(), aSnap.Width() ); | ||||
1080 | long nRight = std::min( aBoundRect.Right() - aTmp.Right(), aSnap.Width() ); | ||||
1081 | long nUp = std::min( aTmp.Top() - aBoundRect.Top(), aSnap.Height() ); | ||||
1082 | long nDown = std::min( aBoundRect.Bottom() - aTmp.Bottom(), aSnap.Height() ); | ||||
1083 | |||||
1084 | switch ( nDir ) | ||||
1085 | { | ||||
1086 | case MOVE_LEFT_BIG4: | ||||
1087 | case MOVE_LEFT_HUGE8: | ||||
1088 | case MOVE_LEFT_SMALL0: aTmp.Left( aTmp.Left() - nLeft ); | ||||
1089 | break; | ||||
1090 | |||||
1091 | case MOVE_UP_BIG5: | ||||
1092 | case MOVE_UP_HUGE9: | ||||
1093 | case MOVE_UP_SMALL1: aTmp.Top( aTmp.Top() - nUp ); | ||||
1094 | break; | ||||
1095 | |||||
1096 | case MOVE_RIGHT_SMALL6: | ||||
1097 | if( aTmp.Width() < aSnap.Width() + MINFLY23 ) | ||||
1098 | break; | ||||
1099 | nRight = aSnap.Width(); | ||||
1100 | [[fallthrough]]; | ||||
1101 | case MOVE_RIGHT_HUGE10: | ||||
1102 | case MOVE_RIGHT_BIG2: aTmp.Left( aTmp.Left() + nRight ); | ||||
1103 | break; | ||||
1104 | |||||
1105 | case MOVE_DOWN_SMALL7: | ||||
1106 | if( aTmp.Height() < aSnap.Height() + MINFLY23 ) | ||||
1107 | break; | ||||
1108 | nDown = aSnap.Height(); | ||||
1109 | [[fallthrough]]; | ||||
1110 | case MOVE_DOWN_HUGE11: | ||||
1111 | case MOVE_DOWN_BIG3: aTmp.Top( aTmp.Top() + nDown ); | ||||
1112 | break; | ||||
1113 | |||||
1114 | default: OSL_ENSURE(true, "ChangeFly: Unknown direction." )do { if (true && (!(true))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "1114" ": "), "%s", "ChangeFly: Unknown direction."); } } while (false); | ||||
1115 | } | ||||
1116 | bool bSet = false; | ||||
1117 | if ((RndStdIds::FLY_AS_CHAR == eAnchorId) && ( nDir % 2 )) | ||||
1118 | { | ||||
1119 | long aDiff = aTmp.Top() - aRefPoint.Y(); | ||||
1120 | if( aDiff > 0 ) | ||||
1121 | aDiff = 0; | ||||
1122 | else if ( aDiff < -aTmp.Height() ) | ||||
1123 | aDiff = -aTmp.Height(); | ||||
1124 | SwFormatVertOrient aVert( aSet.Get(RES_VERT_ORIENT) ); | ||||
1125 | sal_Int16 eNew; | ||||
1126 | if( bWeb ) | ||||
1127 | { | ||||
1128 | eNew = aVert.GetVertOrient(); | ||||
1129 | bool bDown = 0 != ( nDir & 0x02 ); | ||||
1130 | switch( eNew ) | ||||
1131 | { | ||||
1132 | case text::VertOrientation::CHAR_TOP: | ||||
1133 | if( bDown ) eNew = text::VertOrientation::CENTER; | ||||
1134 | break; | ||||
1135 | case text::VertOrientation::CENTER: | ||||
1136 | eNew = bDown ? text::VertOrientation::TOP : text::VertOrientation::CHAR_TOP; | ||||
1137 | break; | ||||
1138 | case text::VertOrientation::TOP: | ||||
1139 | if( !bDown ) eNew = text::VertOrientation::CENTER; | ||||
1140 | break; | ||||
1141 | case text::VertOrientation::LINE_TOP: | ||||
1142 | if( bDown ) eNew = text::VertOrientation::LINE_CENTER; | ||||
1143 | break; | ||||
1144 | case text::VertOrientation::LINE_CENTER: | ||||
1145 | eNew = bDown ? text::VertOrientation::LINE_BOTTOM : text::VertOrientation::LINE_TOP; | ||||
1146 | break; | ||||
1147 | case text::VertOrientation::LINE_BOTTOM: | ||||
1148 | if( !bDown ) eNew = text::VertOrientation::LINE_CENTER; | ||||
1149 | break; | ||||
1150 | default:; //prevent warning | ||||
1151 | } | ||||
1152 | } | ||||
1153 | else | ||||
1154 | { | ||||
1155 | aVert.SetPos( aDiff ); | ||||
1156 | eNew = text::VertOrientation::NONE; | ||||
1157 | } | ||||
1158 | aVert.SetVertOrient( eNew ); | ||||
1159 | aSet.Put( aVert ); | ||||
1160 | bSet = true; | ||||
1161 | } | ||||
1162 | if (bWeb && (RndStdIds::FLY_AT_PARA == eAnchorId) | ||||
1163 | && ( nDir==MOVE_LEFT_SMALL0 || nDir==MOVE_RIGHT_BIG2 )) | ||||
1164 | { | ||||
1165 | SwFormatHoriOrient aHori( aSet.Get(RES_HORI_ORIENT) ); | ||||
1166 | sal_Int16 eNew; | ||||
1167 | eNew = aHori.GetHoriOrient(); | ||||
1168 | switch( eNew ) | ||||
1169 | { | ||||
1170 | case text::HoriOrientation::RIGHT: | ||||
1171 | if( nDir==MOVE_LEFT_SMALL0 ) | ||||
1172 | eNew = text::HoriOrientation::LEFT; | ||||
1173 | break; | ||||
1174 | case text::HoriOrientation::LEFT: | ||||
1175 | if( nDir==MOVE_RIGHT_BIG2 ) | ||||
1176 | eNew = text::HoriOrientation::RIGHT; | ||||
1177 | break; | ||||
1178 | default:; //prevent warning | ||||
1179 | } | ||||
1180 | if( eNew != aHori.GetHoriOrient() ) | ||||
1181 | { | ||||
1182 | aHori.SetHoriOrient( eNew ); | ||||
1183 | aSet.Put( aHori ); | ||||
1184 | bSet = true; | ||||
1185 | } | ||||
1186 | } | ||||
1187 | rSh.StartAllAction(); | ||||
1188 | if( bSet ) | ||||
1189 | rSh.SetFlyFrameAttr( aSet ); | ||||
1190 | bool bSetPos = (RndStdIds::FLY_AS_CHAR != eAnchorId); | ||||
1191 | if(bSetPos && bWeb) | ||||
1192 | { | ||||
1193 | bSetPos = RndStdIds::FLY_AT_PAGE == eAnchorId; | ||||
1194 | } | ||||
1195 | if( bSetPos ) | ||||
1196 | rSh.SetFlyPos( aTmp.Pos() ); | ||||
1197 | rSh.EndAllAction(); | ||||
1198 | |||||
1199 | } | ||||
1200 | |||||
1201 | void SwEditWin::ChangeDrawing( sal_uInt8 nDir ) | ||||
1202 | { | ||||
1203 | // start undo action in order to get only one | ||||
1204 | // undo action for this change. | ||||
1205 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
1206 | rSh.StartUndo(); | ||||
1207 | |||||
1208 | long nX = 0; | ||||
1209 | long nY = 0; | ||||
1210 | const bool bOnePixel( | ||||
1211 | MOVE_LEFT_SMALL0 == nDir || | ||||
1212 | MOVE_UP_SMALL1 == nDir || | ||||
1213 | MOVE_RIGHT_SMALL6 == nDir || | ||||
1214 | MOVE_DOWN_SMALL7 == nDir); | ||||
1215 | const bool bHuge( | ||||
1216 | MOVE_LEFT_HUGE8 == nDir || | ||||
1217 | MOVE_UP_HUGE9 == nDir || | ||||
1218 | MOVE_RIGHT_HUGE10 == nDir || | ||||
1219 | MOVE_DOWN_HUGE11 == nDir); | ||||
1220 | SwMove nAnchorDir = SwMove::UP; | ||||
1221 | switch(nDir) | ||||
1222 | { | ||||
1223 | case MOVE_LEFT_SMALL0: | ||||
1224 | case MOVE_LEFT_HUGE8: | ||||
1225 | case MOVE_LEFT_BIG4: | ||||
1226 | nX = -1; | ||||
1227 | nAnchorDir = SwMove::LEFT; | ||||
1228 | break; | ||||
1229 | case MOVE_UP_SMALL1: | ||||
1230 | case MOVE_UP_HUGE9: | ||||
1231 | case MOVE_UP_BIG5: | ||||
1232 | nY = -1; | ||||
1233 | break; | ||||
1234 | case MOVE_RIGHT_SMALL6: | ||||
1235 | case MOVE_RIGHT_HUGE10: | ||||
1236 | case MOVE_RIGHT_BIG2: | ||||
1237 | nX = +1; | ||||
1238 | nAnchorDir = SwMove::RIGHT; | ||||
1239 | break; | ||||
1240 | case MOVE_DOWN_SMALL7: | ||||
1241 | case MOVE_DOWN_HUGE11: | ||||
1242 | case MOVE_DOWN_BIG3: | ||||
1243 | nY = +1; | ||||
1244 | nAnchorDir = SwMove::DOWN; | ||||
1245 | break; | ||||
1246 | } | ||||
1247 | |||||
1248 | if(0 != nX || 0 != nY) | ||||
1249 | { | ||||
1250 | FlyProtectFlags nProtect = rSh.IsSelObjProtected( FlyProtectFlags::Pos|FlyProtectFlags::Size ); | ||||
1251 | Size aSnap( rSh.GetViewOptions()->GetSnapSize() ); | ||||
1252 | short nDiv = rSh.GetViewOptions()->GetDivisionX(); | ||||
1253 | if ( nDiv > 0 ) | ||||
1254 | aSnap.setWidth( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Width()) / nDiv ) ); | ||||
1255 | nDiv = rSh.GetViewOptions()->GetDivisionY(); | ||||
1256 | if ( nDiv > 0 ) | ||||
1257 | aSnap.setHeight( std::max( sal_uLong(1), static_cast<sal_uLong>(aSnap.Height()) / nDiv ) ); | ||||
1258 | |||||
1259 | if(bOnePixel) | ||||
1260 | { | ||||
1261 | aSnap = PixelToLogic(Size(1,1)); | ||||
1262 | } | ||||
1263 | else if(bHuge) | ||||
1264 | { | ||||
1265 | // #i121236# 567twips == 1cm, but just take three times the normal snap | ||||
1266 | aSnap = Size(aSnap.Width() * 3, aSnap.Height() * 3); | ||||
1267 | } | ||||
1268 | |||||
1269 | nX *= aSnap.Width(); | ||||
1270 | nY *= aSnap.Height(); | ||||
1271 | |||||
1272 | SdrView *pSdrView = rSh.GetDrawView(); | ||||
1273 | const SdrHdlList& rHdlList = pSdrView->GetHdlList(); | ||||
1274 | SdrHdl* pHdl = rHdlList.GetFocusHdl(); | ||||
1275 | rSh.StartAllAction(); | ||||
1276 | if(nullptr == pHdl) | ||||
1277 | { | ||||
1278 | // now move the selected draw objects | ||||
1279 | // if the object's position is not protected | ||||
1280 | if(!(nProtect&FlyProtectFlags::Pos)) | ||||
1281 | { | ||||
1282 | // Check if object is anchored as character and move direction | ||||
1283 | bool bDummy1, bDummy2; | ||||
1284 | const bool bVertAnchor = rSh.IsFrameVertical( true, bDummy1, bDummy2 ); | ||||
1285 | bool bHoriMove = !bVertAnchor == !( nDir % 2 ); | ||||
1286 | bool bMoveAllowed = | ||||
1287 | !bHoriMove || (rSh.GetAnchorId() != RndStdIds::FLY_AS_CHAR); | ||||
1288 | if ( bMoveAllowed ) | ||||
1289 | { | ||||
1290 | pSdrView->MoveAllMarked(Size(nX, nY)); | ||||
1291 | rSh.SetModified(); | ||||
1292 | } | ||||
1293 | } | ||||
1294 | } | ||||
1295 | else | ||||
1296 | { | ||||
1297 | // move handle with index nHandleIndex | ||||
1298 | if (nX || nY) | ||||
1299 | { | ||||
1300 | if( SdrHdlKind::Anchor == pHdl->GetKind() || | ||||
1301 | SdrHdlKind::Anchor_TR == pHdl->GetKind() ) | ||||
1302 | { | ||||
1303 | // anchor move cannot be allowed when position is protected | ||||
1304 | if(!(nProtect&FlyProtectFlags::Pos)) | ||||
1305 | rSh.MoveAnchor( nAnchorDir ); | ||||
1306 | } | ||||
1307 | //now resize if size is protected | ||||
1308 | else if(!(nProtect&FlyProtectFlags::Size)) | ||||
1309 | { | ||||
1310 | // now move the Handle (nX, nY) | ||||
1311 | Point aStartPoint(pHdl->GetPos()); | ||||
1312 | Point aEndPoint(pHdl->GetPos() + Point(nX, nY)); | ||||
1313 | const SdrDragStat& rDragStat = pSdrView->GetDragStat(); | ||||
1314 | |||||
1315 | // start dragging | ||||
1316 | pSdrView->BegDragObj(aStartPoint, nullptr, pHdl, 0); | ||||
1317 | |||||
1318 | if(pSdrView->IsDragObj()) | ||||
1319 | { | ||||
1320 | bool bWasNoSnap = rDragStat.IsNoSnap(); | ||||
1321 | bool bWasSnapEnabled = pSdrView->IsSnapEnabled(); | ||||
1322 | |||||
1323 | // switch snapping off | ||||
1324 | if(!bWasNoSnap) | ||||
1325 | const_cast<SdrDragStat&>(rDragStat).SetNoSnap(); | ||||
1326 | if(bWasSnapEnabled) | ||||
1327 | pSdrView->SetSnapEnabled(false); | ||||
1328 | |||||
1329 | pSdrView->MovAction(aEndPoint); | ||||
1330 | pSdrView->EndDragObj(); | ||||
1331 | rSh.SetModified(); | ||||
1332 | |||||
1333 | // restore snap | ||||
1334 | if(!bWasNoSnap) | ||||
1335 | const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap); | ||||
1336 | if(bWasSnapEnabled) | ||||
1337 | pSdrView->SetSnapEnabled(bWasSnapEnabled); | ||||
1338 | } | ||||
1339 | } | ||||
1340 | } | ||||
1341 | } | ||||
1342 | rSh.EndAllAction(); | ||||
1343 | } | ||||
1344 | |||||
1345 | rSh.EndUndo(); | ||||
1346 | } | ||||
1347 | |||||
1348 | /** | ||||
1349 | * KeyEvents | ||||
1350 | */ | ||||
1351 | void SwEditWin::KeyInput(const KeyEvent &rKEvt) | ||||
1352 | { | ||||
1353 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
1354 | |||||
1355 | if (comphelper::LibreOfficeKit::isActive() && m_rView.GetPostItMgr()) | ||||
1356 | { | ||||
1357 | if (vcl::Window* pWindow = m_rView.GetPostItMgr()->GetActiveSidebarWin()) | ||||
1358 | { | ||||
1359 | pWindow->KeyInput(rKEvt); | ||||
1360 | return; | ||||
1361 | } | ||||
1362 | } | ||||
1363 | |||||
1364 | if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) | ||||
1365 | { | ||||
1366 | // not allowed if outline content is folded | ||||
1367 | sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode(); | ||||
1368 | if ((rSh.IsSttPara() && (nKey == KEY_BACKSPACE || nKey == KEY_LEFT)) | ||||
1369 | || (rSh.IsEndOfPara() && (nKey == KEY_DELETE || nKey == KEY_RETURN || nKey == KEY_RIGHT))) | ||||
1370 | { | ||||
1371 | SwContentNode* pContentNode = rSh.GetCurrentShellCursor().GetContentNode(); | ||||
1372 | SwOutlineNodes::size_type nPos; | ||||
1373 | if (rSh.GetDoc()->GetNodes().GetOutLineNds().Seek_Entry(pContentNode, &nPos)) | ||||
1374 | { | ||||
1375 | bool bOutlineContentVisibleAttr = true; | ||||
1376 | pContentNode->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); | ||||
1377 | if (!bOutlineContentVisibleAttr) | ||||
1378 | return; // outline node is folded | ||||
1379 | if (rSh.IsSttPara() && (nKey == KEY_BACKSPACE || nKey == KEY_LEFT) && (nPos-1 != SwOutlineNodes::npos)) | ||||
1380 | { | ||||
1381 | bOutlineContentVisibleAttr = true; | ||||
1382 | rSh.GetDoc()->GetNodes().GetOutLineNds()[nPos-1]->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); | ||||
1383 | if (!bOutlineContentVisibleAttr) | ||||
1384 | return; // previous outline node is folded | ||||
1385 | } | ||||
1386 | } | ||||
1387 | } | ||||
1388 | } | ||||
1389 | |||||
1390 | if( rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE && | ||||
1391 | m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard ) | ||||
1392 | { | ||||
1393 | m_pApplyTempl->m_pFormatClipboard->Erase(); | ||||
1394 | SetApplyTemplate(SwApplyTemplate()); | ||||
1395 | m_rView.GetViewFrame()->GetBindings().Invalidate(SID_FORMATPAINTBRUSHTypedWhichId<SfxBoolItem>(5000 + 715)); | ||||
1396 | } | ||||
1397 | else if ( rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE && | ||||
1398 | rSh.IsHeaderFooterEdit( ) ) | ||||
1399 | { | ||||
1400 | bool bHeader = bool(FrameTypeFlags::HEADER & rSh.GetFrameType(nullptr,false)); | ||||
1401 | if ( bHeader ) | ||||
1402 | rSh.SttPg(); | ||||
1403 | else | ||||
1404 | rSh.EndPg(); | ||||
1405 | rSh.ToggleHeaderFooterEdit(); | ||||
1406 | } | ||||
1407 | |||||
1408 | SfxObjectShell *pObjSh = m_rView.GetViewFrame()->GetObjectShell(); | ||||
1409 | if ( m_bLockInput || (pObjSh && pObjSh->GetProgress()) ) | ||||
1410 | // When the progress bar is active or a progress is | ||||
1411 | // running on a document, no order is being taken | ||||
1412 | return; | ||||
1413 | |||||
1414 | m_pShadCursor.reset(); | ||||
1415 | m_aKeyInputFlushTimer.Stop(); | ||||
1416 | |||||
1417 | bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() && | ||||
1418 | rSh.IsCursorReadonly(); | ||||
1419 | |||||
1420 | //if the language changes the buffer must be flushed | ||||
1421 | LanguageType eNewLanguage = GetInputLanguage(); | ||||
1422 | if(!bIsDocReadOnly && m_eBufferLanguage != eNewLanguage && !m_aInBuffer.isEmpty()) | ||||
1423 | { | ||||
1424 | FlushInBuffer(); | ||||
1425 | } | ||||
1426 | m_eBufferLanguage = eNewLanguage; | ||||
1427 | |||||
1428 | QuickHelpData aTmpQHD; | ||||
1429 | if( m_pQuickHlpData->m_bIsDisplayed ) | ||||
1430 | { | ||||
1431 | aTmpQHD.Move( *m_pQuickHlpData ); | ||||
1432 | m_pQuickHlpData->Stop( rSh ); | ||||
1433 | } | ||||
1434 | |||||
1435 | // OS:the DrawView also needs a readonly-Flag as well | ||||
1436 | if ( !bIsDocReadOnly && rSh.GetDrawView() && rSh.GetDrawView()->KeyInput( rKEvt, this ) ) | ||||
1437 | { | ||||
1438 | rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll( false ); | ||||
1439 | rSh.SetModified(); | ||||
1440 | return; // Event evaluated by SdrView | ||||
1441 | } | ||||
1442 | |||||
1443 | if ( m_rView.GetDrawFuncPtr() && m_bInsFrame ) | ||||
1444 | { | ||||
1445 | StopInsFrame(); | ||||
1446 | rSh.Edit(); | ||||
1447 | } | ||||
1448 | |||||
1449 | bool bFlushBuffer = false; | ||||
1450 | bool bNormalChar = false; | ||||
1451 | bool bAppendSpace = m_pQuickHlpData->m_bAppendSpace; | ||||
1452 | m_pQuickHlpData->m_bAppendSpace = false; | ||||
1453 | |||||
1454 | if ( getenv("SW_DEBUG") && rKEvt.GetKeyCode().GetCode() == KEY_F12 ) | ||||
1455 | { | ||||
1456 | if( rKEvt.GetKeyCode().IsShift()) | ||||
1457 | { | ||||
1458 | GetView().GetDocShell()->GetDoc()->dumpAsXml(); | ||||
1459 | return; | ||||
1460 | } | ||||
1461 | else | ||||
1462 | { | ||||
1463 | SwRootFrame* pLayout = GetView().GetDocShell()->GetWrtShell()->GetLayout(); | ||||
1464 | pLayout->dumpAsXml( ); | ||||
1465 | return; | ||||
1466 | } | ||||
1467 | } | ||||
1468 | |||||
1469 | KeyEvent aKeyEvent( rKEvt ); | ||||
1470 | // look for vertical mappings | ||||
1471 | if( !bIsDocReadOnly && !rSh.IsSelFrameMode() && !rSh.IsObjSelected() ) | ||||
1472 | { | ||||
1473 | // must changed from switch to if, because the Linux | ||||
1474 | // compiler has problem with the code. Has to remove if the new general | ||||
1475 | // handler exist. | ||||
1476 | sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode(); | ||||
1477 | |||||
1478 | if( KEY_UP == nKey || KEY_DOWN == nKey || | ||||
1479 | KEY_LEFT == nKey || KEY_RIGHT == nKey ) | ||||
1480 | { | ||||
1481 | // In general, we want to map the direction keys if we are inside | ||||
1482 | // some vertical formatted text. | ||||
1483 | // 1. Exception: For a table cursor in a horizontal table, the | ||||
1484 | // directions should never be mapped. | ||||
1485 | // 2. Exception: For a table cursor in a vertical table, the | ||||
1486 | // directions should always be mapped. | ||||
1487 | const bool bVertText = rSh.IsInVerticalText(); | ||||
1488 | const bool bTableCursor = rSh.GetTableCursor(); | ||||
1489 | const bool bVertTable = rSh.IsTableVertical(); | ||||
1490 | if( ( bVertText && ( !bTableCursor || bVertTable ) ) || | ||||
1491 | ( bTableCursor && bVertTable ) ) | ||||
1492 | { | ||||
1493 | SvxFrameDirection eDirection = rSh.GetTextDirection(); | ||||
1494 | if (eDirection == SvxFrameDirection::Vertical_LR_BT) | ||||
1495 | { | ||||
1496 | // Map from physical to logical, so rotate clockwise. | ||||
1497 | if (KEY_UP == nKey) | ||||
1498 | nKey = KEY_RIGHT; | ||||
1499 | else if (KEY_DOWN == nKey) | ||||
1500 | nKey = KEY_LEFT; | ||||
1501 | else if (KEY_LEFT == nKey) | ||||
1502 | nKey = KEY_UP; | ||||
1503 | else /* KEY_RIGHT == nKey */ | ||||
1504 | nKey = KEY_DOWN; | ||||
1505 | } | ||||
1506 | else | ||||
1507 | { | ||||
1508 | // Attempt to integrate cursor travelling for mongolian layout does not work. | ||||
1509 | // Thus, back to previous mapping of cursor keys to direction keys. | ||||
1510 | if( KEY_UP == nKey ) nKey = KEY_LEFT; | ||||
1511 | else if( KEY_DOWN == nKey ) nKey = KEY_RIGHT; | ||||
1512 | else if( KEY_LEFT == nKey ) nKey = KEY_DOWN; | ||||
1513 | else /* KEY_RIGHT == nKey */ nKey = KEY_UP; | ||||
1514 | } | ||||
1515 | } | ||||
1516 | |||||
1517 | if ( rSh.IsInRightToLeftText() ) | ||||
1518 | { | ||||
1519 | if( KEY_LEFT == nKey ) nKey = KEY_RIGHT; | ||||
1520 | else if( KEY_RIGHT == nKey ) nKey = KEY_LEFT; | ||||
1521 | } | ||||
1522 | |||||
1523 | aKeyEvent = KeyEvent( rKEvt.GetCharCode(), | ||||
1524 | vcl::KeyCode( nKey, rKEvt.GetKeyCode().GetModifier() ), | ||||
1525 | rKEvt.GetRepeat() ); | ||||
1526 | } | ||||
1527 | } | ||||
1528 | |||||
1529 | const vcl::KeyCode& rKeyCode = aKeyEvent.GetKeyCode(); | ||||
1530 | sal_Unicode aCh = aKeyEvent.GetCharCode(); | ||||
1531 | |||||
1532 | // enable switching to notes anchor with Ctrl - Alt - Page Up/Down | ||||
1533 | // pressing this inside a note will switch to next/previous note | ||||
1534 | if ((rKeyCode.IsMod1() && rKeyCode.IsMod2()) && ((rKeyCode.GetCode() == KEY_PAGEUP) || (rKeyCode.GetCode() == KEY_PAGEDOWN))) | ||||
1535 | { | ||||
1536 | const bool bNext = rKeyCode.GetCode()==KEY_PAGEDOWN; | ||||
1537 | const SwFieldType* pFieldType = rSh.GetFieldType( 0, SwFieldIds::Postit ); | ||||
1538 | rSh.MoveFieldType( pFieldType, bNext ); | ||||
1539 | return; | ||||
1540 | } | ||||
1541 | |||||
1542 | const SwFrameFormat* pFlyFormat = rSh.GetFlyFrameFormat(); | ||||
1543 | if( pFlyFormat ) | ||||
1544 | { | ||||
1545 | SvMacroItemId nEvent; | ||||
1546 | |||||
1547 | if( 32 <= aCh && | ||||
1548 | 0 == (( KEY_MOD1 | KEY_MOD2 ) & rKeyCode.GetModifier() )) | ||||
1549 | nEvent = SvMacroItemId::SwFrmKeyInputAlpha; | ||||
1550 | else | ||||
1551 | nEvent = SvMacroItemId::SwFrmKeyInputNoAlpha; | ||||
1552 | |||||
1553 | const SvxMacro* pMacro = pFlyFormat->GetMacro().GetMacroTable().Get( nEvent ); | ||||
1554 | if( pMacro ) | ||||
1555 | { | ||||
1556 | SbxArrayRef xArgs = new SbxArray; | ||||
1557 | SbxVariableRef xVar = new SbxVariable; | ||||
1558 | xVar->PutString( pFlyFormat->GetName() ); | ||||
1559 | xArgs->Put32( xVar.get(), 1 ); | ||||
1560 | |||||
1561 | xVar = new SbxVariable; | ||||
1562 | if( SvMacroItemId::SwFrmKeyInputAlpha == nEvent ) | ||||
1563 | xVar->PutChar( aCh ); | ||||
1564 | else | ||||
1565 | xVar->PutUShort( rKeyCode.GetModifier() | rKeyCode.GetCode() ); | ||||
1566 | xArgs->Put32( xVar.get(), 2 ); | ||||
1567 | |||||
1568 | OUString sRet; | ||||
1569 | rSh.ExecMacro( *pMacro, &sRet, xArgs.get() ); | ||||
1570 | if( !sRet.isEmpty() && sRet.toInt32()!=0 ) | ||||
1571 | return ; | ||||
1572 | } | ||||
1573 | } | ||||
1574 | SelectionType nLclSelectionType; | ||||
1575 | //A is converted to 1 | ||||
1576 | if( rKeyCode.GetFullCode() == (KEY_A | KEY_MOD1 |KEY_SHIFT) | ||||
1577 | && rSh.HasDrawView() && | ||||
1578 | (bool(nLclSelectionType = rSh.GetSelectionType()) && | ||||
1579 | ((nLclSelectionType & (SelectionType::Frame|SelectionType::Graphic)) || | ||||
1580 | ((nLclSelectionType & (SelectionType::DrawObject|SelectionType::DbForm)) && | ||||
1581 | rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1)))) | ||||
1582 | { | ||||
1583 | SdrHdlList& rHdlList = const_cast<SdrHdlList&>(rSh.GetDrawView()->GetHdlList()); | ||||
1584 | SdrHdl* pAnchor = rHdlList.GetHdl(SdrHdlKind::Anchor); | ||||
1585 | if ( ! pAnchor ) | ||||
1586 | pAnchor = rHdlList.GetHdl(SdrHdlKind::Anchor_TR); | ||||
1587 | if(pAnchor) | ||||
1588 | rHdlList.SetFocusHdl(pAnchor); | ||||
1589 | return; | ||||
1590 | } | ||||
1591 | |||||
1592 | SvxAutoCorrCfg* pACfg = nullptr; | ||||
1593 | SvxAutoCorrect* pACorr = nullptr; | ||||
1594 | |||||
1595 | uno::Reference< frame::XDispatchRecorder > xRecorder = | ||||
1596 | m_rView.GetViewFrame()->GetBindings().GetRecorder(); | ||||
1597 | if ( !xRecorder.is() ) | ||||
1598 | { | ||||
1599 | pACfg = &SvxAutoCorrCfg::Get(); | ||||
1600 | pACorr = pACfg->GetAutoCorrect(); | ||||
1601 | } | ||||
1602 | |||||
1603 | SwModuleOptions* pModOpt = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetModuleConfig(); | ||||
1604 | |||||
1605 | OUString sFormulaEntry; | ||||
1606 | |||||
1607 | enum class SwKeyState { CheckKey, InsChar, InsTab, | ||||
1608 | NoNum, NumOff, NumOrNoNum, NumDown, NumUp, | ||||
1609 | NumIndentInc, NumIndentDec, | ||||
1610 | |||||
1611 | OutlineLvOff, | ||||
1612 | NextCell, PrevCell, OutlineUp, OutlineDown, | ||||
1613 | GlossaryExpand, NextPrevGlossary, | ||||
1614 | AutoFormatByInput, | ||||
1615 | NextObject, PrevObject, | ||||
1616 | KeyToView, | ||||
1617 | LaunchOLEObject, GoIntoFly, GoIntoDrawing, | ||||
1618 | EnterDrawHandleMode, | ||||
1619 | CheckDocReadOnlyKeys, | ||||
1620 | CheckAutoCorrect, EditFormula, | ||||
1621 | ColLeftBig, ColRightBig, | ||||
1622 | ColLeftSmall, ColRightSmall, | ||||
1623 | ColBottomBig, | ||||
1624 | ColBottomSmall, | ||||
1625 | CellLeftBig, CellRightBig, | ||||
1626 | CellLeftSmall, CellRightSmall, | ||||
1627 | CellTopBig, CellBottomBig, | ||||
1628 | CellTopSmall, CellBottomSmall, | ||||
1629 | |||||
1630 | Fly_Change, Draw_Change, | ||||
1631 | SpecialInsert, | ||||
1632 | EnterCharCell, | ||||
1633 | GotoNextFieldMark, | ||||
1634 | GotoPrevFieldMark, | ||||
1635 | End }; | ||||
1636 | |||||
1637 | SwKeyState eKeyState = bIsDocReadOnly ? SwKeyState::CheckDocReadOnlyKeys : SwKeyState::CheckKey; | ||||
1638 | SwKeyState eNextKeyState = SwKeyState::End; | ||||
1639 | sal_uInt8 nDir = 0; | ||||
1640 | |||||
1641 | if (m_nKS_NUMDOWN_Count > 0) | ||||
1642 | m_nKS_NUMDOWN_Count--; | ||||
1643 | |||||
1644 | if (m_nKS_NUMINDENTINC_Count > 0) | ||||
1645 | m_nKS_NUMINDENTINC_Count--; | ||||
1646 | |||||
1647 | while( SwKeyState::End != eKeyState ) | ||||
1648 | { | ||||
1649 | SwKeyState eFlyState = SwKeyState::KeyToView; | ||||
1650 | |||||
1651 | switch( eKeyState ) | ||||
1652 | { | ||||
1653 | case SwKeyState::CheckKey: | ||||
1654 | eKeyState = SwKeyState::KeyToView; // default forward to View | ||||
1655 | |||||
1656 | #if OSL_DEBUG_LEVEL1 > 1 | ||||
1657 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
1658 | // for switching cursor behaviour in ReadOnly regions | ||||
1659 | if( 0x7210 == rKeyCode.GetFullCode() ) | ||||
1660 | rSh.SetReadOnlyAvailable( !rSh.IsReadOnlyAvailable() ); | ||||
1661 | else | ||||
1662 | //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||||
1663 | #endif | ||||
1664 | |||||
1665 | if (!comphelper::LibreOfficeKit::isActive() && | ||||
1666 | !rKeyCode.IsMod2() && '=' == aCh && | ||||
1667 | !rSh.IsTableMode() && rSh.GetTableFormat() && | ||||
1668 | rSh.IsSttPara() && | ||||
1669 | !rSh.HasReadonlySel()) | ||||
1670 | { | ||||
1671 | // at the beginning of the table's cell a '=' -> | ||||
1672 | // call EditRow (F2-functionality) | ||||
1673 | // [Avoid this for LibreOfficeKit, as the separate input window | ||||
1674 | // steals the focus & things go wrong - the user never gets | ||||
1675 | // the focus back.] | ||||
1676 | rSh.Push(); | ||||
1677 | if( !rSh.MoveSection( GoCurrSection, fnSectionStart) && | ||||
1678 | !rSh.IsTableBoxTextFormat() ) | ||||
1679 | { | ||||
1680 | // is at the beginning of the box | ||||
1681 | eKeyState = SwKeyState::EditFormula; | ||||
1682 | if( rSh.HasMark() ) | ||||
1683 | rSh.SwapPam(); | ||||
1684 | else | ||||
1685 | rSh.SttSelect(); | ||||
1686 | rSh.MoveSection( GoCurrSection, fnSectionEnd ); | ||||
1687 | rSh.Pop(); | ||||
1688 | rSh.EndSelect(); | ||||
1689 | sFormulaEntry = "="; | ||||
1690 | } | ||||
1691 | else | ||||
1692 | rSh.Pop(SwCursorShell::PopMode::DeleteCurrent); | ||||
1693 | } | ||||
1694 | else | ||||
1695 | { | ||||
1696 | if( pACorr && aTmpQHD.HasContent() && !rSh.HasSelection() && | ||||
1697 | !rSh.HasReadonlySel() && !aTmpQHD.m_bIsAutoText && | ||||
1698 | pACorr->GetSwFlags().nAutoCmpltExpandKey == | ||||
1699 | (rKeyCode.GetModifier() | rKeyCode.GetCode()) ) | ||||
1700 | { | ||||
1701 | eKeyState = SwKeyState::GlossaryExpand; | ||||
1702 | break; | ||||
1703 | } | ||||
1704 | |||||
1705 | switch( rKeyCode.GetModifier() | rKeyCode.GetCode() ) | ||||
1706 | { | ||||
1707 | case KEY_RIGHT | KEY_MOD2: | ||||
1708 | eKeyState = SwKeyState::ColRightBig; | ||||
1709 | eFlyState = SwKeyState::Fly_Change; | ||||
1710 | nDir = MOVE_RIGHT_SMALL6; | ||||
1711 | goto KEYINPUT_CHECKTABLE; | ||||
1712 | |||||
1713 | case KEY_LEFT | KEY_MOD2: | ||||
1714 | eKeyState = SwKeyState::ColRightSmall; | ||||
1715 | eFlyState = SwKeyState::Fly_Change; | ||||
1716 | nDir = MOVE_LEFT_SMALL0; | ||||
1717 | goto KEYINPUT_CHECKTABLE; | ||||
1718 | |||||
1719 | case KEY_RIGHT | KEY_MOD2 | KEY_SHIFT: | ||||
1720 | eKeyState = SwKeyState::ColLeftSmall; | ||||
1721 | goto KEYINPUT_CHECKTABLE; | ||||
1722 | |||||
1723 | case KEY_LEFT | KEY_MOD2 | KEY_SHIFT: | ||||
1724 | eKeyState = SwKeyState::ColLeftBig; | ||||
1725 | goto KEYINPUT_CHECKTABLE; | ||||
1726 | |||||
1727 | case KEY_RIGHT | KEY_MOD2 | KEY_MOD1: | ||||
1728 | eKeyState = SwKeyState::CellRightBig; | ||||
1729 | goto KEYINPUT_CHECKTABLE; | ||||
1730 | |||||
1731 | case KEY_LEFT | KEY_MOD2 | KEY_MOD1: | ||||
1732 | eKeyState = SwKeyState::CellRightSmall; | ||||
1733 | goto KEYINPUT_CHECKTABLE; | ||||
1734 | |||||
1735 | case KEY_RIGHT | KEY_MOD2 | KEY_SHIFT | KEY_MOD1: | ||||
1736 | eKeyState = SwKeyState::CellLeftSmall; | ||||
1737 | goto KEYINPUT_CHECKTABLE; | ||||
1738 | |||||
1739 | case KEY_LEFT | KEY_MOD2 | KEY_SHIFT | KEY_MOD1: | ||||
1740 | eKeyState = SwKeyState::CellLeftBig; | ||||
1741 | goto KEYINPUT_CHECKTABLE; | ||||
1742 | |||||
1743 | case KEY_UP | KEY_MOD2: | ||||
1744 | eKeyState = SwKeyState::ColBottomSmall; | ||||
1745 | eFlyState = SwKeyState::Fly_Change; | ||||
1746 | nDir = MOVE_UP_SMALL1; | ||||
1747 | goto KEYINPUT_CHECKTABLE; | ||||
1748 | |||||
1749 | case KEY_DOWN | KEY_MOD2: | ||||
1750 | eKeyState = SwKeyState::ColBottomBig; | ||||
1751 | eFlyState = SwKeyState::Fly_Change; | ||||
1752 | nDir = MOVE_DOWN_SMALL7; | ||||
1753 | goto KEYINPUT_CHECKTABLE; | ||||
1754 | |||||
1755 | case KEY_UP | KEY_MOD2 | KEY_MOD1: | ||||
1756 | eKeyState = SwKeyState::CellBottomSmall; | ||||
1757 | goto KEYINPUT_CHECKTABLE; | ||||
1758 | |||||
1759 | case KEY_DOWN | KEY_MOD2 | KEY_MOD1: | ||||
1760 | eKeyState = SwKeyState::CellBottomBig; | ||||
1761 | goto KEYINPUT_CHECKTABLE; | ||||
1762 | |||||
1763 | case KEY_UP | KEY_MOD2 | KEY_SHIFT | KEY_MOD1: | ||||
1764 | eKeyState = SwKeyState::CellTopBig; | ||||
1765 | goto KEYINPUT_CHECKTABLE; | ||||
1766 | |||||
1767 | case KEY_DOWN | KEY_MOD2 | KEY_SHIFT | KEY_MOD1: | ||||
1768 | eKeyState = SwKeyState::CellTopSmall; | ||||
1769 | goto KEYINPUT_CHECKTABLE; | ||||
1770 | |||||
1771 | KEYINPUT_CHECKTABLE: | ||||
1772 | if( rSh.IsTableMode() || !rSh.GetTableFormat() ) | ||||
1773 | { | ||||
1774 | if(!pFlyFormat && SwKeyState::KeyToView != eFlyState && | ||||
1775 | (rSh.GetSelectionType() & (SelectionType::DrawObject|SelectionType::DbForm)) && | ||||
1776 | rSh.GetDrawView()->AreObjectsMarked()) | ||||
1777 | eKeyState = SwKeyState::Draw_Change; | ||||
1778 | |||||
1779 | if( pFlyFormat ) | ||||
1780 | eKeyState = eFlyState; | ||||
1781 | else if( SwKeyState::Draw_Change != eKeyState) | ||||
1782 | eKeyState = SwKeyState::EnterCharCell; | ||||
1783 | } | ||||
1784 | break; | ||||
1785 | |||||
1786 | // huge object move | ||||
1787 | case KEY_RIGHT | KEY_SHIFT: | ||||
1788 | case KEY_LEFT | KEY_SHIFT: | ||||
1789 | case KEY_UP | KEY_SHIFT: | ||||
1790 | case KEY_DOWN | KEY_SHIFT: | ||||
1791 | { | ||||
1792 | const SelectionType nSelectionType = rSh.GetSelectionType(); | ||||
1793 | if ( ( pFlyFormat | ||||
1794 | && ( nSelectionType & (SelectionType::Frame|SelectionType::Ole|SelectionType::Graphic) ) ) | ||||
1795 | || ( ( nSelectionType & (SelectionType::DrawObject|SelectionType::DbForm) ) | ||||
1796 | && rSh.GetDrawView()->AreObjectsMarked() ) ) | ||||
1797 | { | ||||
1798 | eKeyState = pFlyFormat ? SwKeyState::Fly_Change : SwKeyState::Draw_Change; | ||||
1799 | switch ( rKeyCode.GetCode() ) | ||||
1800 | { | ||||
1801 | case KEY_RIGHT: nDir = MOVE_RIGHT_HUGE10; break; | ||||
1802 | case KEY_LEFT: nDir = MOVE_LEFT_HUGE8; break; | ||||
1803 | case KEY_UP: nDir = MOVE_UP_HUGE9; break; | ||||
1804 | case KEY_DOWN: nDir = MOVE_DOWN_HUGE11; break; | ||||
1805 | } | ||||
1806 | } | ||||
1807 | break; | ||||
1808 | } | ||||
1809 | |||||
1810 | case KEY_LEFT: | ||||
1811 | case KEY_LEFT | KEY_MOD1: | ||||
1812 | { | ||||
1813 | bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1); | ||||
1814 | if(!bMod1) | ||||
1815 | { | ||||
1816 | eFlyState = SwKeyState::Fly_Change; | ||||
1817 | nDir = MOVE_LEFT_BIG4; | ||||
1818 | } | ||||
1819 | goto KEYINPUT_CHECKTABLE_INSDEL; | ||||
1820 | } | ||||
1821 | case KEY_RIGHT | KEY_MOD1: | ||||
1822 | { | ||||
1823 | goto KEYINPUT_CHECKTABLE_INSDEL; | ||||
1824 | } | ||||
1825 | case KEY_UP: | ||||
1826 | case KEY_UP | KEY_MOD1: | ||||
1827 | { | ||||
1828 | bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1); | ||||
1829 | if(!bMod1) | ||||
1830 | { | ||||
1831 | eFlyState = SwKeyState::Fly_Change; | ||||
1832 | nDir = MOVE_UP_BIG5; | ||||
1833 | } | ||||
1834 | goto KEYINPUT_CHECKTABLE_INSDEL; | ||||
1835 | } | ||||
1836 | case KEY_DOWN: | ||||
1837 | case KEY_DOWN | KEY_MOD1: | ||||
1838 | { | ||||
1839 | bool bMod1 = 0 != (rKeyCode.GetModifier() & KEY_MOD1); | ||||
1840 | if(!bMod1) | ||||
1841 | { | ||||
1842 | eFlyState = SwKeyState::Fly_Change; | ||||
1843 | nDir = MOVE_DOWN_BIG3; | ||||
1844 | } | ||||
1845 | goto KEYINPUT_CHECKTABLE_INSDEL; | ||||
1846 | } | ||||
1847 | |||||
1848 | KEYINPUT_CHECKTABLE_INSDEL: | ||||
1849 | if( rSh.IsTableMode() || !rSh.GetTableFormat() ) | ||||
1850 | { | ||||
1851 | const SelectionType nSelectionType = rSh.GetSelectionType(); | ||||
1852 | |||||
1853 | eKeyState = SwKeyState::KeyToView; | ||||
1854 | if(SwKeyState::KeyToView != eFlyState) | ||||
1855 | { | ||||
1856 | if((nSelectionType & (SelectionType::DrawObject|SelectionType::DbForm)) && | ||||
1857 | rSh.GetDrawView()->AreObjectsMarked()) | ||||
1858 | eKeyState = SwKeyState::Draw_Change; | ||||
1859 | else if(nSelectionType & (SelectionType::Frame|SelectionType::Ole|SelectionType::Graphic)) | ||||
1860 | eKeyState = SwKeyState::Fly_Change; | ||||
1861 | } | ||||
1862 | } | ||||
1863 | break; | ||||
1864 | |||||
1865 | |||||
1866 | case KEY_DELETE: | ||||
1867 | if ( !rSh.HasReadonlySel() || rSh.CursorInsideInputField()) | ||||
1868 | { | ||||
1869 | if (rSh.IsInFrontOfLabel() && rSh.NumOrNoNum()) | ||||
1870 | eKeyState = SwKeyState::NumOrNoNum; | ||||
1871 | } | ||||
1872 | else if (!rSh.IsCursorInParagraphMetadataField()) | ||||
1873 | { | ||||
1874 | std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui")); | ||||
1875 | std::unique_ptr<weld::MessageDialog> xInfo(xBuilder->weld_message_dialog("InfoReadonlyDialog")); | ||||
1876 | xInfo->run(); | ||||
1877 | eKeyState = SwKeyState::End; | ||||
1878 | } | ||||
1879 | break; | ||||
1880 | |||||
1881 | case KEY_RETURN: | ||||
1882 | { | ||||
1883 | if ( !rSh.HasReadonlySel() | ||||
1884 | && !rSh.CursorInsideInputField() ) | ||||
1885 | { | ||||
1886 | const SelectionType nSelectionType = rSh.GetSelectionType(); | ||||
1887 | if(nSelectionType & SelectionType::Ole) | ||||
1888 | eKeyState = SwKeyState::LaunchOLEObject; | ||||
1889 | else if(nSelectionType & SelectionType::Frame) | ||||
1890 | eKeyState = SwKeyState::GoIntoFly; | ||||
1891 | else if((nSelectionType & SelectionType::DrawObject) && | ||||
1892 | !(nSelectionType & SelectionType::DrawObjectEditMode) && | ||||
1893 | rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1) | ||||
1894 | { | ||||
1895 | eKeyState = SwKeyState::GoIntoDrawing; | ||||
1896 | if (lcl_goIntoTextBox(*this, rSh)) | ||||
1897 | eKeyState = SwKeyState::GoIntoFly; | ||||
1898 | } | ||||
1899 | else if( aTmpQHD.HasContent() && !rSh.HasSelection() && | ||||
1900 | aTmpQHD.m_bIsAutoText ) | ||||
1901 | eKeyState = SwKeyState::GlossaryExpand; | ||||
1902 | |||||
1903 | //RETURN and empty paragraph in numbering -> end numbering | ||||
1904 | else if( m_aInBuffer.isEmpty() && | ||||
1905 | rSh.GetNumRuleAtCurrCursorPos() && | ||||
1906 | !rSh.GetNumRuleAtCurrCursorPos()->IsOutlineRule() && | ||||
1907 | !rSh.HasSelection() && | ||||
1908 | rSh.IsSttPara() && rSh.IsEndPara() ) | ||||
1909 | { | ||||
1910 | eKeyState = SwKeyState::NumOff; | ||||
1911 | eNextKeyState = SwKeyState::OutlineLvOff; | ||||
1912 | } | ||||
1913 | //RETURN for new paragraph with AutoFormatting | ||||
1914 | else if( pACfg && pACfg->IsAutoFormatByInput() && | ||||
1915 | !(nSelectionType & (SelectionType::Graphic | | ||||
1916 | SelectionType::Ole | SelectionType::Frame | | ||||
1917 | SelectionType::TableCell | SelectionType::DrawObject | | ||||
1918 | SelectionType::DrawObjectEditMode)) ) | ||||
1919 | { | ||||
1920 | eKeyState = SwKeyState::AutoFormatByInput; | ||||
1921 | } | ||||
1922 | else | ||||
1923 | { | ||||
1924 | eNextKeyState = eKeyState; | ||||
1925 | eKeyState = SwKeyState::CheckAutoCorrect; | ||||
1926 | } | ||||
1927 | } | ||||
1928 | } | ||||
1929 | break; | ||||
1930 | case KEY_RETURN | KEY_MOD2: | ||||
1931 | { | ||||
1932 | if ( !rSh.HasReadonlySel() | ||||
1933 | && !rSh.IsSttPara() | ||||
1934 | && rSh.GetNumRuleAtCurrCursorPos() | ||||
1935 | && !rSh.CursorInsideInputField() ) | ||||
1936 | { | ||||
1937 | eKeyState = SwKeyState::NoNum; | ||||
1938 | } | ||||
1939 | else if( rSh.CanSpecialInsert() ) | ||||
1940 | eKeyState = SwKeyState::SpecialInsert; | ||||
1941 | } | ||||
1942 | break; | ||||
1943 | case KEY_BACKSPACE: | ||||
1944 | case KEY_BACKSPACE | KEY_SHIFT: | ||||
1945 | if ( !rSh.HasReadonlySel() || rSh.CursorInsideInputField()) | ||||
1946 | { | ||||
1947 | bool bDone = false; | ||||
1948 | // try to add comment for code snip: | ||||
1949 | // Remove the paragraph indent, if the cursor is at the | ||||
1950 | // beginning of a paragraph, there is no selection | ||||
1951 | // and no numbering rule found at the current paragraph | ||||
1952 | // Also try to remove indent, if current paragraph | ||||
1953 | // has numbering rule, but isn't counted and only | ||||
1954 | // key <backspace> is hit. | ||||
1955 | const bool bOnlyBackspaceKey( KEY_BACKSPACE == rKeyCode.GetFullCode() ); | ||||
1956 | if ( rSh.IsSttPara() | ||||
1957 | && !rSh.HasSelection() | ||||
1958 | && ( rSh.GetNumRuleAtCurrCursorPos() == nullptr | ||||
1959 | || ( rSh.IsNoNum() && bOnlyBackspaceKey ) ) ) | ||||
1960 | { | ||||
1961 | bDone = rSh.TryRemoveIndent(); | ||||
1962 | } | ||||
1963 | |||||
1964 | if (bDone) | ||||
1965 | eKeyState = SwKeyState::End; | ||||
1966 | else | ||||
1967 | { | ||||
1968 | if ( rSh.IsSttPara() && !rSh.IsNoNum() ) | ||||
1969 | { | ||||
1970 | if (m_nKS_NUMDOWN_Count > 0 && | ||||
1971 | 0 < rSh.GetNumLevel()) | ||||
1972 | { | ||||
1973 | eKeyState = SwKeyState::NumUp; | ||||
1974 | m_nKS_NUMDOWN_Count = 2; | ||||
1975 | bDone = true; | ||||
1976 | } | ||||
1977 | else if (m_nKS_NUMINDENTINC_Count > 0) | ||||
1978 | { | ||||
1979 | eKeyState = SwKeyState::NumIndentDec; | ||||
1980 | m_nKS_NUMINDENTINC_Count = 2; | ||||
1981 | bDone = true; | ||||
1982 | } | ||||
1983 | } | ||||
1984 | |||||
1985 | // If the cursor is in an empty paragraph, which has | ||||
1986 | // a numbering, but not the outline numbering, and | ||||
1987 | // there is no selection, the numbering has to be | ||||
1988 | // deleted on key <Backspace>. | ||||
1989 | // Otherwise method <SwEditShell::NumOrNoNum(..)> | ||||
1990 | // should only change the <IsCounted()> state of | ||||
1991 | // the current paragraph depending of the key. | ||||
1992 | // On <backspace> it is set to <false>, | ||||
1993 | // on <shift-backspace> it is set to <true>. | ||||
1994 | // Thus, assure that method <SwEditShell::NumOrNum(..)> | ||||
1995 | // is only called for the intended purpose. | ||||
1996 | if ( !bDone && rSh.IsSttPara() ) | ||||
1997 | { | ||||
1998 | bool bCallNumOrNoNum( false ); | ||||
1999 | if ( bOnlyBackspaceKey && !rSh.IsNoNum() ) | ||||
2000 | { | ||||
2001 | bCallNumOrNoNum = true; | ||||
2002 | } | ||||
2003 | else if ( !bOnlyBackspaceKey && rSh.IsNoNum() ) | ||||
2004 | { | ||||
2005 | bCallNumOrNoNum = true; | ||||
2006 | } | ||||
2007 | else if ( bOnlyBackspaceKey | ||||
2008 | && rSh.IsSttPara() | ||||
2009 | && rSh.IsEndPara() | ||||
2010 | && !rSh.HasSelection() ) | ||||
2011 | { | ||||
2012 | const SwNumRule* pCurrNumRule( rSh.GetNumRuleAtCurrCursorPos() ); | ||||
2013 | if ( pCurrNumRule != nullptr | ||||
2014 | && pCurrNumRule != rSh.GetOutlineNumRule() ) | ||||
2015 | { | ||||
2016 | bCallNumOrNoNum = true; | ||||
2017 | } | ||||
2018 | } | ||||
2019 | if ( bCallNumOrNoNum | ||||
2020 | && rSh.NumOrNoNum( !bOnlyBackspaceKey ) ) | ||||
2021 | { | ||||
2022 | eKeyState = SwKeyState::NumOrNoNum; | ||||
2023 | } | ||||
2024 | } | ||||
2025 | } | ||||
2026 | } | ||||
2027 | else if (!rSh.IsCursorInParagraphMetadataField()) | ||||
2028 | { | ||||
2029 | std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui")); | ||||
2030 | std::unique_ptr<weld::MessageDialog> xInfo(xBuilder->weld_message_dialog("InfoReadonlyDialog")); | ||||
2031 | xInfo->run(); | ||||
2032 | eKeyState = SwKeyState::End; | ||||
2033 | } | ||||
2034 | break; | ||||
2035 | |||||
2036 | case KEY_RIGHT: | ||||
2037 | { | ||||
2038 | eFlyState = SwKeyState::Fly_Change; | ||||
2039 | nDir = MOVE_RIGHT_BIG2; | ||||
2040 | goto KEYINPUT_CHECKTABLE_INSDEL; | ||||
2041 | } | ||||
2042 | case KEY_TAB: | ||||
2043 | { | ||||
2044 | |||||
2045 | if (rSh.IsFormProtected() || rSh.GetCurrentFieldmark() || rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENTu'\x0006') | ||||
2046 | { | ||||
2047 | eKeyState = SwKeyState::GotoNextFieldMark; | ||||
2048 | } | ||||
2049 | else if ( !rSh.IsMultiSelection() && rSh.CursorInsideInputField() ) | ||||
2050 | { | ||||
2051 | GetView().GetViewFrame()->GetDispatcher()->Execute( FN_GOTO_NEXT_INPUTFLD((20000 + 100) + 47) ); | ||||
2052 | eKeyState = SwKeyState::End; | ||||
2053 | } | ||||
2054 | else if( rSh.GetNumRuleAtCurrCursorPos() | ||||
2055 | && rSh.IsSttOfPara() | ||||
2056 | && !rSh.HasReadonlySel() ) | ||||
2057 | { | ||||
2058 | if ( !rSh.IsMultiSelection() | ||||
2059 | && rSh.IsFirstOfNumRuleAtCursorPos() | ||||
2060 | && numfunc::ChangeIndentOnTabAtFirstPosOfFirstListItem() ) | ||||
2061 | eKeyState = SwKeyState::NumIndentInc; | ||||
2062 | else | ||||
2063 | { | ||||
2064 | if (numfunc::NumDownChangesIndent(rSh)) | ||||
2065 | { | ||||
2066 | eKeyState = SwKeyState::NumDown; | ||||
2067 | } | ||||
2068 | else | ||||
2069 | { | ||||
2070 | eKeyState = SwKeyState::InsTab; | ||||
2071 | } | ||||
2072 | } | ||||
2073 | } | ||||
2074 | else if ( rSh.GetTableFormat() ) | ||||
2075 | { | ||||
2076 | if( rSh.HasSelection() || rSh.HasReadonlySel() ) | ||||
2077 | eKeyState = SwKeyState::NextCell; | ||||
2078 | else | ||||
2079 | { | ||||
2080 | eKeyState = SwKeyState::CheckAutoCorrect; | ||||
2081 | eNextKeyState = SwKeyState::NextCell; | ||||
2082 | } | ||||
2083 | } | ||||
2084 | else if ( rSh.GetSelectionType() & | ||||
2085 | (SelectionType::Graphic | | ||||
2086 | SelectionType::Frame | | ||||
2087 | SelectionType::Ole | | ||||
2088 | SelectionType::DrawObject | | ||||
2089 | SelectionType::DbForm)) | ||||
2090 | |||||
2091 | eKeyState = SwKeyState::NextObject; | ||||
2092 | else | ||||
2093 | { | ||||
2094 | eKeyState = SwKeyState::InsTab; | ||||
2095 | if( rSh.IsSttOfPara() && !rSh.HasReadonlySel() ) | ||||
2096 | { | ||||
2097 | SwTextFormatColl* pColl = rSh.GetCurTextFormatColl(); | ||||
2098 | if( pColl && | ||||
2099 | |||||
2100 | pColl->IsAssignedToListLevelOfOutlineStyle() | ||||
2101 | && MAXLEVEL-1 > pColl->GetAssignedOutlineStyleLevel() ) | ||||
2102 | eKeyState = SwKeyState::OutlineDown; | ||||
2103 | } | ||||
2104 | } | ||||
2105 | } | ||||
2106 | break; | ||||
2107 | case KEY_TAB | KEY_SHIFT: | ||||
2108 | { | ||||
2109 | if (rSh.IsFormProtected() || rSh.GetCurrentFieldmark()|| rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENTu'\x0006') | ||||
2110 | { | ||||
2111 | eKeyState = SwKeyState::GotoPrevFieldMark; | ||||
2112 | } | ||||
2113 | else if ( !rSh.IsMultiSelection() && rSh.CursorInsideInputField() ) | ||||
2114 | { | ||||
2115 | GetView().GetViewFrame()->GetDispatcher()->Execute( FN_GOTO_PREV_INPUTFLD((20000 + 100) + 48) ); | ||||
2116 | eKeyState = SwKeyState::End; | ||||
2117 | } | ||||
2118 | else if( rSh.GetNumRuleAtCurrCursorPos() | ||||
2119 | && rSh.IsSttOfPara() | ||||
2120 | && !rSh.HasReadonlySel() ) | ||||
2121 | { | ||||
2122 | if ( !rSh.IsMultiSelection() | ||||
2123 | && rSh.IsFirstOfNumRuleAtCursorPos() | ||||
2124 | && numfunc::ChangeIndentOnTabAtFirstPosOfFirstListItem() ) | ||||
2125 | eKeyState = SwKeyState::NumIndentDec; | ||||
2126 | else | ||||
2127 | eKeyState = SwKeyState::NumUp; | ||||
2128 | } | ||||
2129 | else if ( rSh.GetTableFormat() ) | ||||
2130 | { | ||||
2131 | if( rSh.HasSelection() || rSh.HasReadonlySel() ) | ||||
2132 | eKeyState = SwKeyState::PrevCell; | ||||
2133 | else | ||||
2134 | { | ||||
2135 | eKeyState = SwKeyState::CheckAutoCorrect; | ||||
2136 | eNextKeyState = SwKeyState::PrevCell; | ||||
2137 | } | ||||
2138 | } | ||||
2139 | else if ( rSh.GetSelectionType() & | ||||
2140 | (SelectionType::Graphic | | ||||
2141 | SelectionType::Frame | | ||||
2142 | SelectionType::Ole | | ||||
2143 | SelectionType::DrawObject | | ||||
2144 | SelectionType::DbForm)) | ||||
2145 | |||||
2146 | eKeyState = SwKeyState::PrevObject; | ||||
2147 | else | ||||
2148 | { | ||||
2149 | eKeyState = SwKeyState::End; | ||||
2150 | if( rSh.IsSttOfPara() && !rSh.HasReadonlySel() ) | ||||
2151 | { | ||||
2152 | SwTextFormatColl* pColl = rSh.GetCurTextFormatColl(); | ||||
2153 | if( pColl && | ||||
2154 | pColl->IsAssignedToListLevelOfOutlineStyle() && | ||||
2155 | 0 < pColl->GetAssignedOutlineStyleLevel()) | ||||
2156 | eKeyState = SwKeyState::OutlineUp; | ||||
2157 | } | ||||
2158 | } | ||||
2159 | } | ||||
2160 | break; | ||||
2161 | case KEY_TAB | KEY_MOD1: | ||||
2162 | case KEY_TAB | KEY_MOD2: | ||||
2163 | if( !rSh.HasReadonlySel() ) | ||||
2164 | { | ||||
2165 | if( aTmpQHD.HasContent() && !rSh.HasSelection() ) | ||||
2166 | { | ||||
2167 | // Next auto-complete suggestion | ||||
2168 | aTmpQHD.Next( pACorr && | ||||
2169 | pACorr->GetSwFlags().bAutoCmpltEndless ); | ||||
2170 | eKeyState = SwKeyState::NextPrevGlossary; | ||||
2171 | } | ||||
2172 | else if( rSh.GetTableFormat() ) | ||||
2173 | eKeyState = SwKeyState::InsTab; | ||||
2174 | else if((rSh.GetSelectionType() & | ||||
2175 | (SelectionType::DrawObject|SelectionType::DbForm| | ||||
2176 | SelectionType::Frame|SelectionType::Ole|SelectionType::Graphic)) && | ||||
2177 | rSh.GetDrawView()->AreObjectsMarked()) | ||||
2178 | eKeyState = SwKeyState::EnterDrawHandleMode; | ||||
2179 | else | ||||
2180 | { | ||||
2181 | eKeyState = SwKeyState::InsTab; | ||||
2182 | } | ||||
2183 | } | ||||
2184 | break; | ||||
2185 | |||||
2186 | case KEY_TAB | KEY_MOD1 | KEY_SHIFT: | ||||
2187 | { | ||||
2188 | if( aTmpQHD.HasContent() && !rSh.HasSelection() && | ||||
2189 | !rSh.HasReadonlySel() ) | ||||
2190 | { | ||||
2191 | // Previous auto-complete suggestion. | ||||
2192 | aTmpQHD.Previous( pACorr && | ||||
2193 | pACorr->GetSwFlags().bAutoCmpltEndless ); | ||||
2194 | eKeyState = SwKeyState::NextPrevGlossary; | ||||
2195 | } | ||||
2196 | else if((rSh.GetSelectionType() & (SelectionType::DrawObject|SelectionType::DbForm| | ||||
2197 | SelectionType::Frame|SelectionType::Ole|SelectionType::Graphic)) && | ||||
2198 | rSh.GetDrawView()->AreObjectsMarked()) | ||||
2199 | { | ||||
2200 | eKeyState = SwKeyState::EnterDrawHandleMode; | ||||
2201 | } | ||||
2202 | } | ||||
2203 | break; | ||||
2204 | case KEY_F2 : | ||||
2205 | if( !rSh.HasReadonlySel() ) | ||||
2206 | { | ||||
2207 | const SelectionType nSelectionType = rSh.GetSelectionType(); | ||||
2208 | if(nSelectionType & SelectionType::Frame) | ||||
2209 | eKeyState = SwKeyState::GoIntoFly; | ||||
2210 | else if(nSelectionType & SelectionType::DrawObject) | ||||
2211 | { | ||||
2212 | eKeyState = SwKeyState::GoIntoDrawing; | ||||
2213 | if (lcl_goIntoTextBox(*this, rSh)) | ||||
2214 | eKeyState = SwKeyState::GoIntoFly; | ||||
2215 | } | ||||
2216 | } | ||||
2217 | break; | ||||
2218 | } | ||||
2219 | } | ||||
2220 | break; | ||||
2221 | case SwKeyState::CheckDocReadOnlyKeys: | ||||
2222 | { | ||||
2223 | eKeyState = SwKeyState::KeyToView; | ||||
2224 | switch( rKeyCode.GetModifier() | rKeyCode.GetCode() ) | ||||
2225 | { | ||||
2226 | case KEY_TAB: | ||||
2227 | case KEY_TAB | KEY_SHIFT: | ||||
2228 | bNormalChar = false; | ||||
2229 | eKeyState = SwKeyState::End; | ||||
2230 | if ( rSh.GetSelectionType() & | ||||
2231 | (SelectionType::Graphic | | ||||
2232 | SelectionType::Frame | | ||||
2233 | SelectionType::Ole | | ||||
2234 | SelectionType::DrawObject | | ||||
2235 | SelectionType::DbForm)) | ||||
2236 | |||||
2237 | { | ||||
2238 | eKeyState = (rKeyCode.GetModifier() & KEY_SHIFT) ? | ||||
2239 | SwKeyState::PrevObject : SwKeyState::NextObject; | ||||
2240 | } | ||||
2241 | else if ( !rSh.IsMultiSelection() && rSh.CursorInsideInputField() ) | ||||
2242 | { | ||||
2243 | GetView().GetViewFrame()->GetDispatcher()->Execute( | ||||
2244 | KEY_SHIFT != rKeyCode.GetModifier() ? FN_GOTO_NEXT_INPUTFLD((20000 + 100) + 47) : FN_GOTO_PREV_INPUTFLD((20000 + 100) + 48) ); | ||||
2245 | } | ||||
2246 | else | ||||
2247 | { | ||||
2248 | rSh.SelectNextPrevHyperlink( KEY_SHIFT != rKeyCode.GetModifier() ); | ||||
2249 | } | ||||
2250 | break; | ||||
2251 | case KEY_RETURN: | ||||
2252 | { | ||||
2253 | const SelectionType nSelectionType = rSh.GetSelectionType(); | ||||
2254 | if(nSelectionType & SelectionType::Frame) | ||||
2255 | eKeyState = SwKeyState::GoIntoFly; | ||||
2256 | else | ||||
2257 | { | ||||
2258 | SfxItemSet aSet(rSh.GetAttrPool(), svl::Items<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT>{}); | ||||
2259 | rSh.GetCurAttr(aSet); | ||||
2260 | if(SfxItemState::SET == aSet.GetItemState(RES_TXTATR_INETFMT, false)) | ||||
2261 | { | ||||
2262 | const SfxPoolItem& rItem = aSet.Get(RES_TXTATR_INETFMT); | ||||
2263 | bNormalChar = false; | ||||
2264 | eKeyState = SwKeyState::End; | ||||
2265 | rSh.ClickToINetAttr(static_cast<const SwFormatINetFormat&>(rItem)); | ||||
2266 | } | ||||
2267 | } | ||||
2268 | } | ||||
2269 | break; | ||||
2270 | } | ||||
2271 | } | ||||
2272 | break; | ||||
2273 | |||||
2274 | case SwKeyState::EnterCharCell: | ||||
2275 | { | ||||
2276 | eKeyState = SwKeyState::KeyToView; | ||||
2277 | switch ( rKeyCode.GetModifier() | rKeyCode.GetCode() ) | ||||
2278 | { | ||||
2279 | case KEY_RIGHT | KEY_MOD2: | ||||
2280 | rSh.Right( CRSR_SKIP_CHARS, false, 1, false ); | ||||
2281 | eKeyState = SwKeyState::End; | ||||
2282 | FlushInBuffer(); | ||||
2283 | break; | ||||
2284 | case KEY_LEFT | KEY_MOD2: | ||||
2285 | rSh.Left( CRSR_SKIP_CHARS, false, 1, false ); | ||||
2286 | eKeyState = SwKeyState::End; | ||||
2287 | FlushInBuffer(); | ||||
2288 | break; | ||||
2289 | } | ||||
2290 | } | ||||
2291 | break; | ||||
2292 | |||||
2293 | case SwKeyState::KeyToView: | ||||
2294 | { | ||||
2295 | eKeyState = SwKeyState::End; | ||||
2296 | bNormalChar = | ||||
2297 | !rKeyCode.IsMod2() && | ||||
2298 | rKeyCode.GetModifier() != KEY_MOD1 && | ||||
2299 | rKeyCode.GetModifier() != (KEY_MOD1|KEY_SHIFT) && | ||||
2300 | SW_ISPRINTABLE( aCh ); | ||||
2301 | |||||
2302 | if( bNormalChar && rSh.IsInFrontOfLabel() ) | ||||
2303 | { | ||||
2304 | rSh.NumOrNoNum(); | ||||
2305 | } | ||||
2306 | |||||
2307 | if( !m_aInBuffer.isEmpty() && ( !bNormalChar || bIsDocReadOnly )) | ||||
2308 | FlushInBuffer(); | ||||
2309 | |||||
2310 | if (rSh.HasReadonlySel() | ||||
2311 | && ( rKeyCode.GetFunction() == KeyFuncType::PASTE | ||||
2312 | || rKeyCode.GetFunction() == KeyFuncType::CUT)) | ||||
2313 | { | ||||
2314 | auto xInfo(std::make_shared<weld::GenericDialogController>(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui", "InfoReadonlyDialog")); | ||||
2315 | weld::DialogController::runAsync(xInfo, [](int) {}); | ||||
2316 | eKeyState = SwKeyState::End; | ||||
2317 | } | ||||
2318 | else if( m_rView.KeyInput( aKeyEvent ) ) | ||||
2319 | { | ||||
2320 | bFlushBuffer = true; | ||||
2321 | bNormalChar = false; | ||||
2322 | } | ||||
2323 | else | ||||
2324 | { | ||||
2325 | // Because Sfx accelerators are only called when they were | ||||
2326 | // enabled at the last status update, copy has to called | ||||
2327 | // 'forcefully' by us if necessary. | ||||
2328 | if( rKeyCode.GetFunction() == KeyFuncType::COPY ) | ||||
2329 | GetView().GetViewFrame()->GetBindings().Execute(SID_COPY(5000 + 711)); | ||||
2330 | |||||
2331 | if( !bIsDocReadOnly && bNormalChar ) | ||||
2332 | { | ||||
2333 | const SelectionType nSelectionType = rSh.GetSelectionType(); | ||||
2334 | const bool bDrawObject = (nSelectionType & SelectionType::DrawObject) && | ||||
2335 | !(nSelectionType & SelectionType::DrawObjectEditMode) && | ||||
2336 | rSh.GetDrawView()->GetMarkedObjectList().GetMarkCount() == 1; | ||||
2337 | |||||
2338 | bool bTextBox = false; | ||||
2339 | if (bDrawObject && lcl_goIntoTextBox(*this, rSh)) | ||||
2340 | // A draw shape was selected, but it has a TextBox, | ||||
2341 | // start editing that instead when the normal | ||||
2342 | // character is pressed. | ||||
2343 | bTextBox = true; | ||||
2344 | |||||
2345 | if (bDrawObject && !bTextBox) | ||||
2346 | { | ||||
2347 | SdrObject* pObj = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); | ||||
2348 | if(pObj) | ||||
2349 | { | ||||
2350 | EnterDrawTextMode(pObj->GetLogicRect().Center()); | ||||
2351 | if ( dynamic_cast< const SwDrawTextShell *>( m_rView.GetCurShell() ) != nullptr ) | ||||
2352 | static_cast<SwDrawTextShell*>(m_rView.GetCurShell())->Init(); | ||||
2353 | rSh.GetDrawView()->KeyInput( rKEvt, this ); | ||||
2354 | } | ||||
2355 | } | ||||
2356 | else if (nSelectionType & SelectionType::Frame || bTextBox) | ||||
2357 | { | ||||
2358 | rSh.UnSelectFrame(); | ||||
2359 | rSh.LeaveSelFrameMode(); | ||||
2360 | m_rView.AttrChangedNotify(nullptr); | ||||
2361 | rSh.MoveSection( GoCurrSection, fnSectionEnd ); | ||||
2362 | } | ||||
2363 | eKeyState = SwKeyState::InsChar; | ||||
2364 | } | ||||
2365 | else | ||||
2366 | { | ||||
2367 | bNormalChar = false; | ||||
2368 | Window::KeyInput( aKeyEvent ); | ||||
2369 | } | ||||
2370 | } | ||||
2371 | } | ||||
2372 | break; | ||||
2373 | case SwKeyState::LaunchOLEObject: | ||||
2374 | { | ||||
2375 | rSh.LaunchOLEObj(); | ||||
2376 | eKeyState = SwKeyState::End; | ||||
2377 | } | ||||
2378 | break; | ||||
2379 | case SwKeyState::GoIntoFly: | ||||
2380 | { | ||||
2381 | rSh.UnSelectFrame(); | ||||
2382 | rSh.LeaveSelFrameMode(); | ||||
2383 | m_rView.AttrChangedNotify(nullptr); | ||||
2384 | rSh.MoveSection( GoCurrSection, fnSectionEnd ); | ||||
2385 | eKeyState = SwKeyState::End; | ||||
2386 | } | ||||
2387 | break; | ||||
2388 | case SwKeyState::GoIntoDrawing: | ||||
2389 | { | ||||
2390 | if (SdrMark* pMark = rSh.GetDrawView()->GetMarkedObjectList().GetMark(0)) | ||||
2391 | { | ||||
2392 | SdrObject* pObj = pMark->GetMarkedSdrObj(); | ||||
2393 | if(pObj) | ||||
2394 | { | ||||
2395 | EnterDrawTextMode(pObj->GetLogicRect().Center()); | ||||
2396 | if (dynamic_cast< const SwDrawTextShell *>( m_rView.GetCurShell() ) != nullptr ) | ||||
2397 | static_cast<SwDrawTextShell*>(m_rView.GetCurShell())->Init(); | ||||
2398 | } | ||||
2399 | } | ||||
2400 | eKeyState = SwKeyState::End; | ||||
2401 | } | ||||
2402 | break; | ||||
2403 | case SwKeyState::EnterDrawHandleMode: | ||||
2404 | { | ||||
2405 | const SdrHdlList& rHdlList = rSh.GetDrawView()->GetHdlList(); | ||||
2406 | bool bForward(!aKeyEvent.GetKeyCode().IsShift()); | ||||
2407 | |||||
2408 | const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl(bForward); | ||||
2409 | eKeyState = SwKeyState::End; | ||||
2410 | } | ||||
2411 | break; | ||||
2412 | case SwKeyState::InsTab: | ||||
2413 | if( dynamic_cast<const SwWebView*>( &m_rView) != nullptr) // no Tab for WebView | ||||
2414 | { | ||||
2415 | // then it should be passed along | ||||
2416 | Window::KeyInput( aKeyEvent ); | ||||
2417 | eKeyState = SwKeyState::End; | ||||
2418 | break; | ||||
2419 | } | ||||
2420 | aCh = '\t'; | ||||
2421 | [[fallthrough]]; | ||||
2422 | case SwKeyState::InsChar: | ||||
2423 | if (rSh.GetChar(false)==CH_TXT_ATR_FORMELEMENTu'\x0006') | ||||
2424 | { | ||||
2425 | ::sw::mark::ICheckboxFieldmark* pFieldmark = | ||||
2426 | dynamic_cast< ::sw::mark::ICheckboxFieldmark* > | ||||
2427 | (rSh.GetCurrentFieldmark()); | ||||
2428 | OSL_ENSURE(pFieldmark,do { if (true && (!(pFieldmark))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "2429" ": "), "%s", "Where is my FieldMark??"); } } while (false) | ||||
2429 | "Where is my FieldMark??")do { if (true && (!(pFieldmark))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "2429" ": "), "%s", "Where is my FieldMark??"); } } while (false); | ||||
2430 | if(pFieldmark) | ||||
2431 | { | ||||
2432 | pFieldmark->SetChecked(!pFieldmark->IsChecked()); | ||||
2433 | OSL_ENSURE(pFieldmark->IsExpanded(),do { if (true && (!(pFieldmark->IsExpanded()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "2434" ": "), "%s", "where is the otherpos?"); } } while (false) | ||||
2434 | "where is the otherpos?")do { if (true && (!(pFieldmark->IsExpanded()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "2434" ": "), "%s", "where is the otherpos?"); } } while (false); | ||||
2435 | if (pFieldmark->IsExpanded()) | ||||
2436 | { | ||||
2437 | rSh.CalcLayout(); | ||||
2438 | } | ||||
2439 | } | ||||
2440 | eKeyState = SwKeyState::End; | ||||
2441 | } | ||||
2442 | else if ( !rSh.HasReadonlySel() | ||||
2443 | || rSh.CursorInsideInputField() ) | ||||
2444 | { | ||||
2445 | const bool bIsNormalChar = | ||||
2446 | GetAppCharClass().isLetterNumeric( OUString( aCh ), 0 ); | ||||
2447 | if( bAppendSpace && bIsNormalChar && | ||||
2448 | (!m_aInBuffer.isEmpty() || !rSh.IsSttPara() || !rSh.IsEndPara() )) | ||||
2449 | { | ||||
2450 | // insert a blank ahead of the character. this ends up | ||||
2451 | // between the expanded text and the new "non-word-separator". | ||||
2452 | m_aInBuffer += " "; | ||||
2453 | } | ||||
2454 | |||||
2455 | const bool bIsAutoCorrectChar = SvxAutoCorrect::IsAutoCorrectChar( aCh ); | ||||
2456 | if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || rSh.IsNbspRunNext() ) && | ||||
2457 | pACfg->IsAutoFormatByInput() && | ||||
2458 | (( pACorr->IsAutoCorrFlag( ACFlags::ChgWeightUnderl ) && | ||||
2459 | ( '*' == aCh || '_' == aCh ) ) || | ||||
2460 | ( pACorr->IsAutoCorrFlag( ACFlags::ChgQuotes ) && ('\"' == aCh ))|| | ||||
2461 | ( pACorr->IsAutoCorrFlag( ACFlags::ChgSglQuotes ) && ( '\'' == aCh)))) | ||||
2462 | { | ||||
2463 | FlushInBuffer(); | ||||
2464 | rSh.AutoCorrect( *pACorr, aCh ); | ||||
2465 | if( '\"' != aCh && '\'' != aCh ) // only call when "*_"! | ||||
2466 | rSh.UpdateAttr(); | ||||
2467 | } | ||||
2468 | else if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || rSh.IsNbspRunNext() ) && | ||||
2469 | pACfg->IsAutoFormatByInput() && | ||||
2470 | pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord | | ||||
2471 | ACFlags::ChgOrdinalNumber | ACFlags::AddNonBrkSpace | | ||||
2472 | ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | | ||||
2473 | ACFlags::Autocorrect | ACFlags::TransliterateRTL ) && | ||||
2474 | '\"' != aCh && '\'' != aCh && '*' != aCh && '_' != aCh | ||||
2475 | ) | ||||
2476 | { | ||||
2477 | FlushInBuffer(); | ||||
2478 | rSh.AutoCorrect( *pACorr, aCh ); | ||||
2479 | } | ||||
2480 | else | ||||
2481 | { | ||||
2482 | OUStringBuffer aBuf(m_aInBuffer); | ||||
2483 | comphelper::string::padToLength(aBuf, | ||||
2484 | m_aInBuffer.getLength() + aKeyEvent.GetRepeat() + 1, aCh); | ||||
2485 | m_aInBuffer = aBuf.makeStringAndClear(); | ||||
2486 | g_bFlushCharBuffer = Application::AnyInput( VclInputFlags::KEYBOARD ); | ||||
2487 | bFlushBuffer = !g_bFlushCharBuffer; | ||||
2488 | if( g_bFlushCharBuffer ) | ||||
2489 | m_aKeyInputFlushTimer.Start(); | ||||
2490 | } | ||||
2491 | eKeyState = SwKeyState::End; | ||||
2492 | } | ||||
2493 | else | ||||
2494 | { | ||||
2495 | auto xInfo(std::make_shared<weld::GenericDialogController>(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui", "InfoReadonlyDialog")); | ||||
2496 | weld::DialogController::runAsync(xInfo, [](int) {}); | ||||
2497 | eKeyState = SwKeyState::End; | ||||
2498 | } | ||||
2499 | break; | ||||
2500 | |||||
2501 | case SwKeyState::CheckAutoCorrect: | ||||
2502 | { | ||||
2503 | if( pACorr && pACfg->IsAutoFormatByInput() && | ||||
2504 | pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord | | ||||
2505 | ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL | | ||||
2506 | ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | | ||||
2507 | ACFlags::Autocorrect ) && | ||||
2508 | !rSh.HasReadonlySel() ) | ||||
2509 | { | ||||
2510 | FlushInBuffer(); | ||||
2511 | rSh.AutoCorrect( *pACorr, u'\0' ); | ||||
2512 | } | ||||
2513 | eKeyState = eNextKeyState; | ||||
2514 | } | ||||
2515 | break; | ||||
2516 | |||||
2517 | default: | ||||
2518 | { | ||||
2519 | sal_uInt16 nSlotId = 0; | ||||
2520 | FlushInBuffer(); | ||||
2521 | switch( eKeyState ) | ||||
2522 | { | ||||
2523 | case SwKeyState::SpecialInsert: | ||||
2524 | rSh.DoSpecialInsert(); | ||||
2525 | break; | ||||
2526 | |||||
2527 | case SwKeyState::NoNum: | ||||
2528 | rSh.NoNum(); | ||||
2529 | break; | ||||
2530 | |||||
2531 | case SwKeyState::NumOff: | ||||
2532 | // shell change - so record in advance | ||||
2533 | rSh.DelNumRules(); | ||||
2534 | break; | ||||
2535 | case SwKeyState::OutlineLvOff: // delete autofmt outlinelevel later | ||||
2536 | break; | ||||
2537 | |||||
2538 | case SwKeyState::NumDown: | ||||
2539 | rSh.NumUpDown(); | ||||
2540 | m_nKS_NUMDOWN_Count = 2; | ||||
2541 | break; | ||||
2542 | case SwKeyState::NumUp: | ||||
2543 | rSh.NumUpDown( false ); | ||||
2544 | break; | ||||
2545 | |||||
2546 | case SwKeyState::NumIndentInc: | ||||
2547 | rSh.ChangeIndentOfAllListLevels(360); | ||||
2548 | m_nKS_NUMINDENTINC_Count = 2; | ||||
2549 | break; | ||||
2550 | |||||
2551 | case SwKeyState::GotoNextFieldMark: | ||||
2552 | { | ||||
2553 | ::sw::mark::IFieldmark const * const pFieldmark = rSh.GetFieldmarkAfter(); | ||||
2554 | if(pFieldmark) rSh.GotoFieldmark(pFieldmark); | ||||
2555 | } | ||||
2556 | break; | ||||
2557 | |||||
2558 | case SwKeyState::GotoPrevFieldMark: | ||||
2559 | { | ||||
2560 | ::sw::mark::IFieldmark const * const pFieldmark = rSh.GetFieldmarkBefore(); | ||||
2561 | if( pFieldmark ) | ||||
2562 | rSh.GotoFieldmark(pFieldmark); | ||||
2563 | } | ||||
2564 | break; | ||||
2565 | |||||
2566 | case SwKeyState::NumIndentDec: | ||||
2567 | rSh.ChangeIndentOfAllListLevels(-360); | ||||
2568 | break; | ||||
2569 | |||||
2570 | case SwKeyState::OutlineDown: | ||||
2571 | rSh.OutlineUpDown(); | ||||
2572 | break; | ||||
2573 | case SwKeyState::OutlineUp: | ||||
2574 | rSh.OutlineUpDown( -1 ); | ||||
2575 | break; | ||||
2576 | |||||
2577 | case SwKeyState::NextCell: | ||||
2578 | // always 'flush' in tables | ||||
2579 | rSh.GoNextCell(!rSh.HasReadonlySel()); | ||||
2580 | nSlotId = FN_GOTO_NEXT_CELL((20000 + 400) + 145); | ||||
2581 | break; | ||||
2582 | case SwKeyState::PrevCell: | ||||
2583 | rSh.GoPrevCell(); | ||||
2584 | nSlotId = FN_GOTO_PREV_CELL((20000 + 400) + 146); | ||||
2585 | break; | ||||
2586 | case SwKeyState::AutoFormatByInput: | ||||
2587 | rSh.SplitNode( true ); | ||||
2588 | break; | ||||
2589 | |||||
2590 | case SwKeyState::NextObject: | ||||
2591 | case SwKeyState::PrevObject: | ||||
2592 | if(rSh.GotoObj( SwKeyState::NextObject == eKeyState, GotoObjFlags::Any)) | ||||
2593 | { | ||||
2594 | if( rSh.IsFrameSelected() && | ||||
2595 | m_rView.GetDrawFuncPtr() ) | ||||
2596 | { | ||||
2597 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
2598 | m_rView.SetDrawFuncPtr(nullptr); | ||||
2599 | m_rView.LeaveDrawCreate(); | ||||
2600 | m_rView.AttrChangedNotify(nullptr); | ||||
2601 | } | ||||
2602 | rSh.HideCursor(); | ||||
2603 | rSh.EnterSelFrameMode(); | ||||
2604 | } | ||||
2605 | break; | ||||
2606 | case SwKeyState::GlossaryExpand: | ||||
2607 | { | ||||
2608 | // replace the word or abbreviation with the auto text | ||||
2609 | rSh.StartUndo( SwUndoId::START ); | ||||
2610 | |||||
2611 | OUString sFnd(aTmpQHD.CurStr()); | ||||
2612 | if( aTmpQHD.m_bIsAutoText ) | ||||
2613 | { | ||||
2614 | SwGlossaryList* pList = ::GetGlossaryList(); | ||||
2615 | OUString sShrtNm; | ||||
2616 | OUString sGroup; | ||||
2617 | if(pList->GetShortName( sFnd, sShrtNm, sGroup)) | ||||
2618 | { | ||||
2619 | rSh.SttSelect(); | ||||
2620 | rSh.ExtendSelection(false, aTmpQHD.CurLen()); | ||||
2621 | SwGlossaryHdl* pGlosHdl = GetView().GetGlosHdl(); | ||||
2622 | pGlosHdl->SetCurGroup(sGroup, true); | ||||
2623 | pGlosHdl->InsertGlossary( sShrtNm); | ||||
2624 | m_pQuickHlpData->m_bAppendSpace = true; | ||||
2625 | } | ||||
2626 | } | ||||
2627 | else | ||||
2628 | { | ||||
2629 | sFnd = sFnd.copy(aTmpQHD.CurLen()); | ||||
2630 | rSh.Insert( sFnd ); | ||||
2631 | m_pQuickHlpData->m_bAppendSpace = !pACorr || | ||||
2632 | pACorr->GetSwFlags().bAutoCmpltAppendBlanc; | ||||
2633 | } | ||||
2634 | rSh.EndUndo( SwUndoId::END ); | ||||
2635 | } | ||||
2636 | break; | ||||
2637 | |||||
2638 | case SwKeyState::NextPrevGlossary: | ||||
2639 | m_pQuickHlpData->Move( aTmpQHD ); | ||||
2640 | m_pQuickHlpData->Start(rSh, false); | ||||
2641 | break; | ||||
2642 | |||||
2643 | case SwKeyState::EditFormula: | ||||
2644 | { | ||||
2645 | const sal_uInt16 nId = SwInputChild::GetChildWindowId(); | ||||
2646 | |||||
2647 | SfxViewFrame* pVFrame = GetView().GetViewFrame(); | ||||
2648 | pVFrame->ToggleChildWindow( nId ); | ||||
2649 | SwInputChild* pChildWin = static_cast<SwInputChild*>(pVFrame-> | ||||
2650 | GetChildWindow( nId )); | ||||
2651 | if( pChildWin ) | ||||
2652 | pChildWin->SetFormula( sFormulaEntry ); | ||||
2653 | } | ||||
2654 | break; | ||||
2655 | |||||
2656 | case SwKeyState::ColLeftBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColLeft|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() ); break; | ||||
2657 | case SwKeyState::ColRightBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColRight|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() ); break; | ||||
2658 | case SwKeyState::ColLeftSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColLeft, pModOpt->GetTableHMove() ); break; | ||||
2659 | case SwKeyState::ColRightSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::ColRight, pModOpt->GetTableHMove() ); break; | ||||
2660 | case SwKeyState::ColBottomBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::RowBottom|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableVMove() ); break; | ||||
2661 | case SwKeyState::ColBottomSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::RowBottom, pModOpt->GetTableVMove() ); break; | ||||
2662 | case SwKeyState::CellLeftBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellLeft|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() ); break; | ||||
2663 | case SwKeyState::CellRightBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellRight|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableHMove() ); break; | ||||
2664 | case SwKeyState::CellLeftSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellLeft, pModOpt->GetTableHMove() ); break; | ||||
2665 | case SwKeyState::CellRightSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellRight, pModOpt->GetTableHMove() ); break; | ||||
2666 | case SwKeyState::CellTopBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellTop|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableVMove() ); break; | ||||
2667 | case SwKeyState::CellBottomBig: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellBottom|TableChgWidthHeightType::BiggerMode, pModOpt->GetTableVMove() ); break; | ||||
2668 | case SwKeyState::CellTopSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellTop, pModOpt->GetTableVMove() ); break; | ||||
2669 | case SwKeyState::CellBottomSmall: rSh.SetColRowWidthHeight( TableChgWidthHeightType::CellBottom, pModOpt->GetTableVMove() ); break; | ||||
2670 | |||||
2671 | case SwKeyState::Fly_Change: | ||||
2672 | { | ||||
2673 | SdrView *pSdrView = rSh.GetDrawView(); | ||||
2674 | const SdrHdlList& rHdlList = pSdrView->GetHdlList(); | ||||
2675 | if(rHdlList.GetFocusHdl()) | ||||
2676 | ChangeDrawing( nDir ); | ||||
2677 | else | ||||
2678 | ChangeFly( nDir, dynamic_cast<const SwWebView*>( &m_rView) != nullptr ); | ||||
2679 | } | ||||
2680 | break; | ||||
2681 | case SwKeyState::Draw_Change : | ||||
2682 | ChangeDrawing( nDir ); | ||||
2683 | break; | ||||
2684 | default: | ||||
2685 | break; | ||||
2686 | } | ||||
2687 | if( nSlotId && m_rView.GetViewFrame()->GetBindings().GetRecorder().is() ) | ||||
2688 | { | ||||
2689 | SfxRequest aReq(m_rView.GetViewFrame(), nSlotId ); | ||||
2690 | aReq.Done(); | ||||
2691 | } | ||||
2692 | eKeyState = SwKeyState::End; | ||||
2693 | } | ||||
2694 | } | ||||
2695 | } | ||||
2696 | |||||
2697 | // x11 backend doesn't like not having this | ||||
2698 | if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) | ||||
2699 | GetFrameControlsManager().SetOutlineContentVisibilityButtons(); | ||||
2700 | |||||
2701 | // update the page number in the statusbar | ||||
2702 | sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode(); | ||||
2703 | if( KEY_UP == nKey || KEY_DOWN == nKey || KEY_PAGEUP == nKey || KEY_PAGEDOWN == nKey ) | ||||
2704 | GetView().GetViewFrame()->GetBindings().Update( FN_STAT_PAGE((20000 + 1180) + 1) ); | ||||
2705 | |||||
2706 | // in case the buffered characters are inserted | ||||
2707 | if( bFlushBuffer && !m_aInBuffer.isEmpty() ) | ||||
2708 | { | ||||
2709 | // bFlushCharBuffer was not reset here | ||||
2710 | // why not? | ||||
2711 | bool bSave = g_bFlushCharBuffer; | ||||
2712 | FlushInBuffer(); | ||||
2713 | g_bFlushCharBuffer = bSave; | ||||
2714 | |||||
2715 | // maybe show Tip-Help | ||||
2716 | if (bNormalChar) | ||||
2717 | { | ||||
2718 | const bool bAutoTextShown | ||||
2719 | = pACfg && pACfg->IsAutoTextTip() && ShowAutoText(rSh.GetChunkForAutoText()); | ||||
2720 | if (!bAutoTextShown && pACorr && pACorr->GetSwFlags().bAutoCompleteWords) | ||||
2721 | ShowAutoCorrectQuickHelp(rSh.GetPrevAutoCorrWord(*pACorr), *pACorr); | ||||
2722 | } | ||||
2723 | } | ||||
2724 | |||||
2725 | // get the word count dialog to update itself | ||||
2726 | SwWordCountWrapper *pWrdCnt = static_cast<SwWordCountWrapper*>(GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId())); | ||||
2727 | if( pWrdCnt ) | ||||
2728 | pWrdCnt->UpdateCounts(); | ||||
2729 | |||||
2730 | } | ||||
2731 | |||||
2732 | /** | ||||
2733 | * MouseEvents | ||||
2734 | */ | ||||
2735 | void SwEditWin::RstMBDownFlags() | ||||
2736 | { | ||||
2737 | // Not on all systems a MouseButtonUp is used ahead | ||||
2738 | // of the modal dialog (like on WINDOWS). | ||||
2739 | // So reset the statuses here and release the mouse | ||||
2740 | // for the dialog. | ||||
2741 | m_bMBPressed = false; | ||||
2742 | g_bNoInterrupt = false; | ||||
2743 | EnterArea(); | ||||
2744 | ReleaseMouse(); | ||||
2745 | } | ||||
2746 | |||||
2747 | /** | ||||
2748 | * Determines if the current position has a clickable url over a background | ||||
2749 | * frame. In that case, ctrl-click should select the url, not the frame. | ||||
2750 | */ | ||||
2751 | static bool lcl_urlOverBackground(SwWrtShell& rSh, const Point& rDocPos) | ||||
2752 | { | ||||
2753 | SwContentAtPos aSwContentAtPos(IsAttrAtPos::InetAttr); | ||||
2754 | SdrObject* pSelectableObj = rSh.GetObjAt(rDocPos); | ||||
2755 | |||||
2756 | return rSh.GetContentAtPos(rDocPos, aSwContentAtPos) && pSelectableObj->GetLayer() == rSh.GetDoc()->getIDocumentDrawModelAccess().GetHellId(); | ||||
2757 | } | ||||
2758 | |||||
2759 | void SwEditWin::MoveCursor( SwWrtShell &rSh, const Point& rDocPos, | ||||
2760 | const bool bOnlyText, bool bLockView ) | ||||
2761 | { | ||||
2762 | const bool bTmpNoInterrupt = g_bNoInterrupt; | ||||
2763 | g_bNoInterrupt = false; | ||||
2764 | |||||
2765 | int nTmpSetCursor = 0; | ||||
2766 | |||||
2767 | if( !rSh.IsViewLocked() && bLockView ) | ||||
2768 | rSh.LockView( true ); | ||||
2769 | else | ||||
2770 | bLockView = false; | ||||
2771 | |||||
2772 | { | ||||
2773 | // only temporary generate move context because otherwise | ||||
2774 | // the query to the content form doesn't work!!! | ||||
2775 | SwMvContext aMvContext( &rSh ); | ||||
2776 | nTmpSetCursor = rSh.CallSetCursor(&rDocPos, bOnlyText); | ||||
2777 | g_bValidCursorPos = !(CRSR_POSCHG & nTmpSetCursor); | ||||
2778 | } | ||||
2779 | |||||
2780 | // notify the edit window that from now on we do not use the input language | ||||
2781 | if ( !(CRSR_POSOLD & nTmpSetCursor) ) | ||||
2782 | SetUseInputLanguage( false ); | ||||
2783 | |||||
2784 | if( bLockView ) | ||||
2785 | rSh.LockView( false ); | ||||
2786 | |||||
2787 | g_bNoInterrupt = bTmpNoInterrupt; | ||||
2788 | } | ||||
2789 | |||||
2790 | void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) | ||||
2791 | { | ||||
2792 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
2793 | const SwField *pCursorField = rSh.CursorInsideInputField() ? rSh.GetCurField( true ) : nullptr; | ||||
2794 | |||||
2795 | // We have to check if a context menu is shown and we have an UI | ||||
2796 | // active inplace client. In that case we have to ignore the mouse | ||||
2797 | // button down event. Otherwise we would crash (context menu has been | ||||
2798 | // opened by inplace client and we would deactivate the inplace client, | ||||
2799 | // the context menu is closed by VCL asynchronously which in the end | ||||
2800 | // would work on deleted objects or the context menu has no parent anymore) | ||||
2801 | SfxInPlaceClient* pIPClient = rSh.GetSfxViewShell()->GetIPClient(); | ||||
2802 | bool bIsOleActive = ( pIPClient && pIPClient->IsObjectInPlaceActive() ); | ||||
2803 | |||||
2804 | if ( bIsOleActive && PopupMenu::IsInExecute() ) | ||||
2805 | return; | ||||
2806 | |||||
2807 | MouseEvent rMEvt(_rMEvt); | ||||
2808 | |||||
2809 | if (m_rView.GetPostItMgr()->IsHit(rMEvt.GetPosPixel())) | ||||
2810 | return; | ||||
2811 | |||||
2812 | if (comphelper::LibreOfficeKit::isActive()) | ||||
2813 | { | ||||
2814 | if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel())) | ||||
2815 | { | ||||
2816 | pWindow->MouseButtonDown(rMEvt); | ||||
2817 | return; | ||||
2818 | } | ||||
2819 | } | ||||
2820 | |||||
2821 | m_rView.GetPostItMgr()->SetActiveSidebarWin(nullptr); | ||||
2822 | |||||
2823 | GrabFocus(); | ||||
2824 | |||||
2825 | //ignore key modifiers for format paintbrush | ||||
2826 | { | ||||
2827 | bool bExecFormatPaintbrush = m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard | ||||
2828 | && m_pApplyTempl->m_pFormatClipboard->HasContent(); | ||||
2829 | if( bExecFormatPaintbrush ) | ||||
2830 | rMEvt = MouseEvent( _rMEvt.GetPosPixel(), _rMEvt.GetClicks(), | ||||
2831 | _rMEvt.GetMode(), _rMEvt.GetButtons() ); | ||||
2832 | } | ||||
2833 | |||||
2834 | m_bWasShdwCursor = nullptr != m_pShadCursor; | ||||
2835 | m_pShadCursor.reset(); | ||||
2836 | |||||
2837 | const Point aDocPos( PixelToLogic( rMEvt.GetPosPixel() ) ); | ||||
2838 | |||||
2839 | FrameControlType eControl; | ||||
2840 | bool bOverFly = false; | ||||
2841 | bool bPageAnchored = false; | ||||
2842 | bool bOverHeaderFooterFly = IsOverHeaderFooterFly( aDocPos, eControl, bOverFly, bPageAnchored ); | ||||
2843 | |||||
2844 | bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly(); | ||||
2845 | if (bOverHeaderFooterFly && (!bIsDocReadOnly && rSh.GetCurField())) | ||||
2846 | // We have a field here, that should have priority over header/footer fly. | ||||
2847 | bOverHeaderFooterFly = false; | ||||
2848 | |||||
2849 | // Are we clicking on a blank header/footer area? | ||||
2850 | if ( IsInHeaderFooter( aDocPos, eControl ) || bOverHeaderFooterFly ) | ||||
2851 | { | ||||
2852 | const SwPageFrame* pPageFrame = rSh.GetLayout()->GetPageAtPos( aDocPos ); | ||||
2853 | |||||
2854 | // Is it active? | ||||
2855 | bool bActive = true; | ||||
2856 | const SwPageDesc* pDesc = pPageFrame->GetPageDesc(); | ||||
2857 | |||||
2858 | const SwFrameFormat* pFormat = pDesc->GetLeftFormat(); | ||||
2859 | if ( pPageFrame->OnRightPage() ) | ||||
2860 | pFormat = pDesc->GetRightFormat(); | ||||
2861 | |||||
2862 | if ( pFormat ) | ||||
2863 | { | ||||
2864 | if ( eControl == FrameControlType::Header ) | ||||
2865 | bActive = pFormat->GetHeader().IsActive(); | ||||
2866 | else | ||||
2867 | bActive = pFormat->GetFooter().IsActive(); | ||||
2868 | } | ||||
2869 | |||||
2870 | if ( !bActive ) | ||||
2871 | { | ||||
2872 | // When in Hide-Whitespace mode, we don't want header | ||||
2873 | // and footer controls. | ||||
2874 | if (!rSh.GetViewOptions()->IsHideWhitespaceMode()) | ||||
2875 | { | ||||
2876 | SwPaM aPam(*rSh.GetCurrentShellCursor().GetPoint()); | ||||
2877 | const bool bWasInHeader = aPam.GetPoint()->nNode.GetNode().FindHeaderStartNode() != nullptr; | ||||
2878 | const bool bWasInFooter = aPam.GetPoint()->nNode.GetNode().FindFooterStartNode() != nullptr; | ||||
2879 | |||||
2880 | // Is the cursor in a part like similar to the one we clicked on? For example, | ||||
2881 | // if the cursor is in a header and we click on an empty header... don't change anything to | ||||
2882 | // keep consistent behaviour due to header edit mode (and the same for the footer as well). | ||||
2883 | |||||
2884 | // Otherwise, we hide the header/footer control if a separator is shown, and vice versa. | ||||
2885 | if (!(bWasInHeader && eControl == FrameControlType::Header) && | ||||
2886 | !(bWasInFooter && eControl == FrameControlType::Footer)) | ||||
2887 | { | ||||
2888 | const bool bSeparatorWasVisible = rSh.IsShowHeaderFooterSeparator(eControl); | ||||
2889 | rSh.SetShowHeaderFooterSeparator(eControl, !bSeparatorWasVisible); | ||||
2890 | |||||
2891 | // Repaint everything | ||||
2892 | Invalidate(); | ||||
2893 | |||||
2894 | // tdf#84929. If the footer control had not been showing, do not change the cursor position, | ||||
2895 | // because the user may have scrolled to turn on the separator control and | ||||
2896 | // if the cursor cannot be positioned on-screen, then the user would need to scroll back again to use the control. | ||||
2897 | // This should only be done for the footer. The cursor can always be re-positioned near the header. tdf#134023. | ||||
2898 | if ( eControl == FrameControlType::Footer && !bSeparatorWasVisible | ||||
2899 | && rSh.GetViewOptions()->IsUseHeaderFooterMenu() && !Application::IsHeadlessModeEnabled() ) | ||||
2900 | return; | ||||
2901 | } | ||||
2902 | } | ||||
2903 | } | ||||
2904 | else | ||||
2905 | { | ||||
2906 | // Make sure we have the proper Header/Footer separators shown | ||||
2907 | // as these may be changed if clicking on an empty Header/Footer | ||||
2908 | rSh.SetShowHeaderFooterSeparator( FrameControlType::Header, eControl == FrameControlType::Header ); | ||||
2909 | rSh.SetShowHeaderFooterSeparator( FrameControlType::Footer, eControl == FrameControlType::Footer ); | ||||
2910 | |||||
2911 | if ( !rSh.IsHeaderFooterEdit() ) | ||||
2912 | { | ||||
2913 | rSh.ToggleHeaderFooterEdit(); | ||||
2914 | |||||
2915 | // Repaint everything | ||||
2916 | rSh.GetWin()->Invalidate(); | ||||
2917 | } | ||||
2918 | } | ||||
2919 | } | ||||
2920 | else | ||||
2921 | { | ||||
2922 | if ( rSh.IsHeaderFooterEdit( ) ) | ||||
2923 | rSh.ToggleHeaderFooterEdit( ); | ||||
2924 | else | ||||
2925 | { | ||||
2926 | // Make sure that the separators are hidden | ||||
2927 | rSh.SetShowHeaderFooterSeparator( FrameControlType::Header, false ); | ||||
2928 | rSh.SetShowHeaderFooterSeparator( FrameControlType::Footer, false ); | ||||
2929 | |||||
2930 | // Repaint everything | ||||
2931 | // FIXME fdo#67358 for unknown reasons this causes painting | ||||
2932 | // problems when resizing table columns, so disable it | ||||
2933 | // rSh.GetWin()->Invalidate(); | ||||
2934 | } | ||||
2935 | |||||
2936 | // Toggle Hide-Whitespace if between pages. | ||||
2937 | if (rSh.GetViewOptions()->CanHideWhitespace() && | ||||
2938 | rSh.GetLayout()->IsBetweenPages(aDocPos)) | ||||
2939 | { | ||||
2940 | if (_rMEvt.GetClicks() >= 2) | ||||
2941 | { | ||||
2942 | SwViewOption aOpt(*rSh.GetViewOptions()); | ||||
2943 | aOpt.SetHideWhitespaceMode(!aOpt.IsHideWhitespaceMode()); | ||||
2944 | rSh.ApplyViewOptions(aOpt); | ||||
2945 | } | ||||
2946 | |||||
2947 | return; | ||||
2948 | } | ||||
2949 | } | ||||
2950 | |||||
2951 | if ( IsChainMode() ) | ||||
2952 | { | ||||
2953 | SetChainMode( false ); | ||||
2954 | SwRect aDummy; | ||||
2955 | SwFlyFrameFormat *pFormat = static_cast<SwFlyFrameFormat*>(rSh.GetFlyFrameFormat()); | ||||
2956 | if ( rSh.Chainable( aDummy, *pFormat, aDocPos ) == SwChainRet::OK ) | ||||
2957 | rSh.Chain( *pFormat, aDocPos ); | ||||
2958 | UpdatePointer( aDocPos, rMEvt.GetModifier() ); | ||||
2959 | return; | ||||
2960 | } | ||||
2961 | |||||
2962 | // After GrabFocus a shell should be pushed. That should actually | ||||
2963 | // work but in practice ... | ||||
2964 | m_rView.SelectShellForDrop(); | ||||
2965 | |||||
2966 | bool bCallBase = true; | ||||
2967 | |||||
2968 | if( m_pQuickHlpData->m_bIsDisplayed ) | ||||
2969 | m_pQuickHlpData->Stop( rSh ); | ||||
2970 | m_pQuickHlpData->m_bAppendSpace = false; | ||||
2971 | |||||
2972 | if( rSh.FinishOLEObj() ) | ||||
2973 | return; // end InPlace and the click doesn't count anymore | ||||
2974 | |||||
2975 | CurrShell aCurr( &rSh ); | ||||
2976 | |||||
2977 | SdrView *pSdrView = rSh.GetDrawView(); | ||||
2978 | if ( pSdrView ) | ||||
2979 | { | ||||
2980 | if (pSdrView->MouseButtonDown( rMEvt, this ) ) | ||||
2981 | { | ||||
2982 | rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll(false); | ||||
2983 | return; // SdrView's event evaluated | ||||
2984 | } | ||||
2985 | } | ||||
2986 | |||||
2987 | m_bIsInMove = false; | ||||
2988 | m_aStartPos = rMEvt.GetPosPixel(); | ||||
2989 | m_aRszMvHdlPt.setX( 0 ); | ||||
2990 | m_aRszMvHdlPt.setY( 0 ); | ||||
2991 | |||||
2992 | SwTab nMouseTabCol = SwTab::COL_NONE; | ||||
2993 | const bool bTmp = !rSh.IsDrawCreate() && !m_pApplyTempl && !rSh.IsInSelect() && | ||||
2994 | rMEvt.GetClicks() == 1 && MOUSE_LEFT(sal_uInt16(0x0001)) == rMEvt.GetButtons(); | ||||
2995 | if ( bTmp && | ||||
2996 | SwTab::COL_NONE != (nMouseTabCol = rSh.WhichMouseTabCol( aDocPos ) ) && | ||||
2997 | !rSh.IsObjSelectable( aDocPos ) ) | ||||
2998 | { | ||||
2999 | // Enhanced table selection | ||||
3000 | if ( SwTab::SEL_HORI <= nMouseTabCol && SwTab::COLSEL_VERT >= nMouseTabCol ) | ||||
3001 | { | ||||
3002 | rSh.EnterStdMode(); | ||||
3003 | rSh.SelectTableRowCol( aDocPos ); | ||||
3004 | if( SwTab::SEL_HORI != nMouseTabCol && SwTab::SEL_HORI_RTL != nMouseTabCol) | ||||
3005 | { | ||||
3006 | m_xRowColumnSelectionStart = aDocPos; | ||||
3007 | m_bIsRowDrag = SwTab::ROWSEL_HORI == nMouseTabCol|| | ||||
3008 | SwTab::ROWSEL_HORI_RTL == nMouseTabCol || | ||||
3009 | SwTab::COLSEL_VERT == nMouseTabCol; | ||||
3010 | m_bMBPressed = true; | ||||
3011 | CaptureMouse(); | ||||
3012 | } | ||||
3013 | return; | ||||
3014 | } | ||||
3015 | |||||
3016 | if ( !rSh.IsTableMode() ) | ||||
3017 | { | ||||
3018 | // comes from table columns out of the document. | ||||
3019 | if(SwTab::COL_VERT == nMouseTabCol || SwTab::COL_HORI == nMouseTabCol) | ||||
3020 | m_rView.SetTabColFromDoc( true ); | ||||
3021 | else | ||||
3022 | m_rView.SetTabRowFromDoc( true ); | ||||
3023 | |||||
3024 | m_rView.SetTabColFromDocPos( aDocPos ); | ||||
3025 | m_rView.InvalidateRulerPos(); | ||||
3026 | SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings(); | ||||
3027 | rBind.Update(); | ||||
3028 | if ( RulerColumnDrag( rMEvt, | ||||
3029 | (SwTab::COL_VERT == nMouseTabCol || SwTab::ROW_HORI == nMouseTabCol)) ) | ||||
3030 | { | ||||
3031 | m_rView.SetTabColFromDoc( false ); | ||||
3032 | m_rView.SetTabRowFromDoc( false ); | ||||
3033 | m_rView.InvalidateRulerPos(); | ||||
3034 | rBind.Update(); | ||||
3035 | bCallBase = false; | ||||
3036 | } | ||||
3037 | else | ||||
3038 | { | ||||
3039 | return; | ||||
3040 | } | ||||
3041 | } | ||||
3042 | } | ||||
3043 | else if (bTmp && | ||||
3044 | rSh.IsNumLabel(aDocPos)) | ||||
3045 | { | ||||
3046 | SwTextNode* pNodeAtPos = rSh.GetNumRuleNodeAtPos( aDocPos ); | ||||
3047 | m_rView.SetNumRuleNodeFromDoc( pNodeAtPos ); | ||||
3048 | m_rView.InvalidateRulerPos(); | ||||
3049 | SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings(); | ||||
3050 | rBind.Update(); | ||||
3051 | |||||
3052 | if ( RulerMarginDrag( rMEvt, | ||||
3053 | SwFEShell::IsVerticalModeAtNdAndPos( *pNodeAtPos, aDocPos ) ) ) | ||||
3054 | { | ||||
3055 | m_rView.SetNumRuleNodeFromDoc( nullptr ); | ||||
3056 | m_rView.InvalidateRulerPos(); | ||||
3057 | rBind.Update(); | ||||
3058 | bCallBase = false; | ||||
3059 | } | ||||
3060 | else | ||||
3061 | { | ||||
3062 | // Make sure the pointer is set to 0, otherwise it may point to | ||||
3063 | // nowhere after deleting the corresponding text node. | ||||
3064 | m_rView.SetNumRuleNodeFromDoc( nullptr ); | ||||
3065 | return; | ||||
3066 | } | ||||
3067 | } | ||||
3068 | |||||
3069 | if ( rSh.IsInSelect() ) | ||||
3070 | rSh.EndSelect(); | ||||
3071 | |||||
3072 | // query against LEFT because otherwise for example also a right | ||||
3073 | // click releases the selection. | ||||
3074 | if ( MOUSE_LEFT(sal_uInt16(0x0001)) == rMEvt.GetButtons() ) | ||||
3075 | { | ||||
3076 | bool bOnlyText = false; | ||||
3077 | m_bMBPressed = true; | ||||
3078 | g_bNoInterrupt = true; | ||||
3079 | m_nKS_NUMDOWN_Count = 0; | ||||
3080 | |||||
3081 | CaptureMouse(); | ||||
3082 | |||||
3083 | // reset cursor position if applicable | ||||
3084 | rSh.ResetCursorStack(); | ||||
3085 | |||||
3086 | switch ( rMEvt.GetModifier() + rMEvt.GetButtons() ) | ||||
3087 | { | ||||
3088 | case MOUSE_LEFT(sal_uInt16(0x0001)): | ||||
3089 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_SHIFT: | ||||
3090 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_MOD2: | ||||
3091 | if( rSh.IsObjSelected() ) | ||||
3092 | { | ||||
3093 | SdrHdl* pHdl; | ||||
3094 | if( !bIsDocReadOnly && | ||||
3095 | !m_pAnchorMarker && | ||||
3096 | pSdrView && | ||||
3097 | nullptr != ( pHdl = pSdrView->PickHandle(aDocPos) ) && | ||||
3098 | ( pHdl->GetKind() == SdrHdlKind::Anchor || | ||||
3099 | pHdl->GetKind() == SdrHdlKind::Anchor_TR ) ) | ||||
3100 | { | ||||
3101 | // #i121463# Set selected during drag | ||||
3102 | pHdl->SetSelected(); | ||||
3103 | m_pAnchorMarker.reset( new SwAnchorMarker( pHdl ) ); | ||||
3104 | UpdatePointer( aDocPos, rMEvt.GetModifier() ); | ||||
3105 | return; | ||||
3106 | } | ||||
3107 | } | ||||
3108 | if ( EnterDrawMode( rMEvt, aDocPos ) ) | ||||
3109 | { | ||||
3110 | g_bNoInterrupt = false; | ||||
3111 | return; | ||||
3112 | } | ||||
3113 | else if ( m_rView.GetDrawFuncPtr() && m_bInsFrame ) | ||||
3114 | { | ||||
3115 | StopInsFrame(); | ||||
3116 | rSh.Edit(); | ||||
3117 | } | ||||
3118 | |||||
3119 | // Without SHIFT because otherwise Toggle doesn't work at selection | ||||
3120 | if (rMEvt.GetClicks() == 1) | ||||
3121 | { | ||||
3122 | if ( rSh.IsSelFrameMode()) | ||||
3123 | { | ||||
3124 | SdrHdl* pHdl = rSh.GetDrawView()->PickHandle(aDocPos); | ||||
3125 | bool bHitHandle = pHdl && pHdl->GetKind() != SdrHdlKind::Anchor && | ||||
3126 | pHdl->GetKind() != SdrHdlKind::Anchor_TR; | ||||
3127 | |||||
3128 | if ((rSh.IsInsideSelectedObj(aDocPos) || bHitHandle) && | ||||
3129 | (rMEvt.GetModifier() != KEY_SHIFT || bHitHandle)) | ||||
3130 | { | ||||
3131 | rSh.EnterSelFrameMode( &aDocPos ); | ||||
3132 | if ( !m_pApplyTempl ) | ||||
3133 | { | ||||
3134 | // only if no position to size was hit. | ||||
3135 | if (!bHitHandle) | ||||
3136 | { | ||||
3137 | StartDDTimer(); | ||||
3138 | SwEditWin::m_nDDStartPosY = aDocPos.Y(); | ||||
3139 | SwEditWin::m_nDDStartPosX = aDocPos.X(); | ||||
3140 | } | ||||
3141 | g_bFrameDrag = true; | ||||
3142 | } | ||||
3143 | g_bNoInterrupt = false; | ||||
3144 | return; | ||||
3145 | } | ||||
3146 | } | ||||
3147 | } | ||||
3148 | } | ||||
3149 | |||||
3150 | bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly(); | ||||
3151 | if ( !bExecHyperlinks ) | ||||
3152 | { | ||||
3153 | SvtSecurityOptions aSecOpts; | ||||
3154 | const bool bSecureOption = aSecOpts.IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink ); | ||||
3155 | if ( ( bSecureOption && rMEvt.GetModifier() == KEY_MOD1 ) || | ||||
3156 | ( !bSecureOption && rMEvt.GetModifier() != KEY_MOD1 ) ) | ||||
3157 | bExecHyperlinks = true; | ||||
3158 | } | ||||
3159 | |||||
3160 | // Enhanced selection | ||||
3161 | sal_uInt8 nNumberOfClicks = static_cast< sal_uInt8 >(rMEvt.GetClicks() % 4); | ||||
3162 | if ( 0 == nNumberOfClicks && 0 < rMEvt.GetClicks() ) | ||||
3163 | nNumberOfClicks = 4; | ||||
3164 | |||||
3165 | bool bExecDrawTextLink = false; | ||||
3166 | |||||
3167 | switch ( rMEvt.GetModifier() + rMEvt.GetButtons() ) | ||||
3168 | { | ||||
3169 | case MOUSE_LEFT(sal_uInt16(0x0001)): | ||||
3170 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_MOD1: | ||||
3171 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_MOD2: | ||||
3172 | { | ||||
3173 | |||||
3174 | // fdo#79604: first, check if a link has been clicked - do not | ||||
3175 | // select fly in this case! | ||||
3176 | if (1 == nNumberOfClicks) | ||||
3177 | { | ||||
3178 | UpdatePointer( aDocPos, rMEvt.GetModifier() ); | ||||
3179 | SwEditWin::m_nDDStartPosY = aDocPos.Y(); | ||||
3180 | SwEditWin::m_nDDStartPosX = aDocPos.X(); | ||||
3181 | |||||
3182 | // hit a URL in DrawText object? | ||||
3183 | if (bExecHyperlinks && pSdrView) | ||||
3184 | { | ||||
3185 | SdrViewEvent aVEvt; | ||||
3186 | pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); | ||||
3187 | |||||
3188 | if (aVEvt.eEvent == SdrEventKind::ExecuteUrl) | ||||
3189 | bExecDrawTextLink = true; | ||||
3190 | } | ||||
3191 | } | ||||
3192 | |||||
3193 | if (1 == nNumberOfClicks && !bExecDrawTextLink) | ||||
3194 | { | ||||
3195 | // only try to select frame, if pointer already was | ||||
3196 | // switched accordingly | ||||
3197 | if ( m_aActHitType != SdrHitKind::NONE && !rSh.IsSelFrameMode() && | ||||
3198 | !GetView().GetViewFrame()->GetDispatcher()->IsLocked()) | ||||
3199 | { | ||||
3200 | // Test if there is a draw object at that position and if it should be selected. | ||||
3201 | bool bShould = rSh.ShouldObjectBeSelected(aDocPos); | ||||
3202 | |||||
3203 | if(bShould) | ||||
3204 | { | ||||
3205 | m_rView.NoRotate(); | ||||
3206 | rSh.HideCursor(); | ||||
3207 | |||||
3208 | bool bUnLockView = !rSh.IsViewLocked(); | ||||
3209 | rSh.LockView( true ); | ||||
3210 | bool bSelObj = rSh.SelectObj( aDocPos, | ||||
3211 | rMEvt.IsMod1() ? SW_ENTER_GROUP2 : 0); | ||||
3212 | if( bUnLockView ) | ||||
3213 | rSh.LockView( false ); | ||||
3214 | |||||
3215 | if( bSelObj ) | ||||
3216 | { | ||||
3217 | // if the frame was deselected in the macro | ||||
3218 | // the cursor just has to be displayed again | ||||
3219 | if( FrameTypeFlags::NONE == rSh.GetSelFrameType() ) | ||||
3220 | rSh.ShowCursor(); | ||||
3221 | else | ||||
3222 | { | ||||
3223 | if (rSh.IsFrameSelected() && m_rView.GetDrawFuncPtr()) | ||||
3224 | { | ||||
3225 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
3226 | m_rView.SetDrawFuncPtr(nullptr); | ||||
3227 | m_rView.LeaveDrawCreate(); | ||||
3228 | m_rView.AttrChangedNotify(nullptr); | ||||
3229 | } | ||||
3230 | |||||
3231 | rSh.EnterSelFrameMode( &aDocPos ); | ||||
3232 | g_bFrameDrag = true; | ||||
3233 | UpdatePointer( aDocPos, rMEvt.GetModifier() ); | ||||
3234 | } | ||||
3235 | return; | ||||
3236 | } | ||||
3237 | else | ||||
3238 | bOnlyText = rSh.IsObjSelectable( aDocPos ); | ||||
3239 | |||||
3240 | if (!m_rView.GetDrawFuncPtr()) | ||||
3241 | rSh.ShowCursor(); | ||||
3242 | } | ||||
3243 | else | ||||
3244 | bOnlyText = KEY_MOD1 != rMEvt.GetModifier(); | ||||
3245 | } | ||||
3246 | else if ( rSh.IsSelFrameMode() && | ||||
3247 | (m_aActHitType == SdrHitKind::NONE || | ||||
3248 | !rSh.IsInsideSelectedObj( aDocPos ))) | ||||
3249 | { | ||||
3250 | m_rView.NoRotate(); | ||||
3251 | SdrHdl *pHdl; | ||||
3252 | if( !bIsDocReadOnly && !m_pAnchorMarker && nullptr != | ||||
3253 | ( pHdl = pSdrView->PickHandle(aDocPos) ) && | ||||
3254 | ( pHdl->GetKind() == SdrHdlKind::Anchor || | ||||
3255 | pHdl->GetKind() == SdrHdlKind::Anchor_TR ) ) | ||||
3256 | { | ||||
3257 | m_pAnchorMarker.reset( new SwAnchorMarker( pHdl ) ); | ||||
3258 | UpdatePointer( aDocPos, rMEvt.GetModifier() ); | ||||
3259 | return; | ||||
3260 | } | ||||
3261 | else | ||||
3262 | { | ||||
3263 | bool bUnLockView = !rSh.IsViewLocked(); | ||||
3264 | rSh.LockView( true ); | ||||
3265 | sal_uInt8 nFlag = rMEvt.IsShift() ? SW_ADD_SELECT1 :0; | ||||
3266 | if( rMEvt.IsMod1() ) | ||||
3267 | nFlag = nFlag | SW_ENTER_GROUP2; | ||||
3268 | |||||
3269 | if ( rSh.IsSelFrameMode() ) | ||||
3270 | { | ||||
3271 | rSh.UnSelectFrame(); | ||||
3272 | rSh.LeaveSelFrameMode(); | ||||
3273 | m_rView.AttrChangedNotify(nullptr); | ||||
3274 | } | ||||
3275 | |||||
3276 | bool bSelObj = rSh.SelectObj( aDocPos, nFlag ); | ||||
3277 | if( bUnLockView ) | ||||
3278 | rSh.LockView( false ); | ||||
3279 | |||||
3280 | if( !bSelObj ) | ||||
3281 | { | ||||
3282 | // move cursor here so that it is not drawn in the | ||||
3283 | // frame first; ShowCursor() happens in LeaveSelFrameMode() | ||||
3284 | g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false)); | ||||
3285 | rSh.LeaveSelFrameMode(); | ||||
3286 | m_rView.AttrChangedNotify(nullptr); | ||||
3287 | bCallBase = false; | ||||
3288 | } | ||||
3289 | else | ||||
3290 | { | ||||
3291 | rSh.HideCursor(); | ||||
3292 | rSh.EnterSelFrameMode( &aDocPos ); | ||||
3293 | rSh.SelFlyGrabCursor(); | ||||
3294 | rSh.MakeSelVisible(); | ||||
3295 | g_bFrameDrag = true; | ||||
3296 | if( rSh.IsFrameSelected() && | ||||
3297 | m_rView.GetDrawFuncPtr() ) | ||||
3298 | { | ||||
3299 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
3300 | m_rView.SetDrawFuncPtr(nullptr); | ||||
3301 | m_rView.LeaveDrawCreate(); | ||||
3302 | m_rView.AttrChangedNotify(nullptr); | ||||
3303 | } | ||||
3304 | UpdatePointer( aDocPos, rMEvt.GetModifier() ); | ||||
3305 | return; | ||||
3306 | } | ||||
3307 | } | ||||
3308 | } | ||||
3309 | } | ||||
3310 | |||||
3311 | switch ( nNumberOfClicks ) | ||||
3312 | { | ||||
3313 | case 1: | ||||
3314 | break; | ||||
3315 | case 2: | ||||
3316 | { | ||||
3317 | g_bFrameDrag = false; | ||||
3318 | if ( !bIsDocReadOnly && rSh.IsInsideSelectedObj(aDocPos) && | ||||
3319 | FlyProtectFlags::NONE == rSh.IsSelObjProtected( FlyProtectFlags::Content|FlyProtectFlags::Parent ) ) | ||||
3320 | { | ||||
3321 | /* This is no good: on the one hand GetSelectionType is used as flag field | ||||
3322 | * (take a look into the GetSelectionType method) and on the other hand the | ||||
3323 | * return value is used in a switch without proper masking (very nice), this must lead to trouble | ||||
3324 | */ | ||||
3325 | switch ( rSh.GetSelectionType() & ~SelectionType( SelectionType::FontWork | SelectionType::ExtrudedCustomShape ) ) | ||||
3326 | { | ||||
3327 | case SelectionType::Graphic: | ||||
3328 | RstMBDownFlags(); | ||||
3329 | if (!comphelper::LibreOfficeKit::isActive()) | ||||
3330 | { | ||||
3331 | GetView().GetViewFrame()->GetBindings().Execute( | ||||
3332 | FN_FORMAT_GRAFIC_DLG((20000 + 400) + 58), nullptr, | ||||
3333 | SfxCallMode::RECORD|SfxCallMode::SLOT); | ||||
3334 | } | ||||
3335 | return; | ||||
3336 | |||||
3337 | // double click on OLE object --> OLE-InPlace | ||||
3338 | case SelectionType::Ole: | ||||
3339 | if (rSh.IsSelObjProtected(FlyProtectFlags::Content) == FlyProtectFlags::NONE) | ||||
3340 | { | ||||
3341 | RstMBDownFlags(); | ||||
3342 | rSh.LaunchOLEObj(); | ||||
3343 | } | ||||
3344 | return; | ||||
3345 | |||||
3346 | case SelectionType::Frame: | ||||
3347 | RstMBDownFlags(); | ||||
3348 | if (!comphelper::LibreOfficeKit::isActive()) | ||||
3349 | { | ||||
3350 | GetView().GetViewFrame()->GetBindings().Execute( | ||||
3351 | FN_FORMAT_FRAME_DLG((20000 + 400) + 56), nullptr, | ||||
3352 | SfxCallMode::RECORD|SfxCallMode::SLOT); | ||||
3353 | } | ||||
3354 | return; | ||||
3355 | |||||
3356 | case SelectionType::DrawObject: | ||||
3357 | RstMBDownFlags(); | ||||
3358 | EnterDrawTextMode(aDocPos); | ||||
3359 | if ( dynamic_cast< const SwDrawTextShell *>( m_rView.GetCurShell() ) != nullptr ) | ||||
3360 | static_cast<SwDrawTextShell*>(m_rView.GetCurShell())->Init(); | ||||
3361 | return; | ||||
3362 | |||||
3363 | default: break; | ||||
3364 | } | ||||
3365 | } | ||||
3366 | |||||
3367 | // if the cursor position was corrected or if a Fly | ||||
3368 | // was selected in ReadOnlyMode, no word selection, except when tiled rendering. | ||||
3369 | if ((!g_bValidCursorPos || rSh.IsFrameSelected()) && !comphelper::LibreOfficeKit::isActive()) | ||||
3370 | return; | ||||
3371 | |||||
3372 | SwField *pField; | ||||
3373 | bool bFootnote = false; | ||||
3374 | |||||
3375 | if( !bIsDocReadOnly && | ||||
3376 | (nullptr != (pField = rSh.GetCurField(true)) || | ||||
3377 | ( bFootnote = rSh.GetCurFootnote() ) ) ) | ||||
3378 | { | ||||
3379 | RstMBDownFlags(); | ||||
3380 | if( bFootnote ) | ||||
3381 | GetView().GetViewFrame()->GetBindings().Execute( FN_EDIT_FOOTNOTE((20000 + 100) + 62) ); | ||||
3382 | else | ||||
3383 | { | ||||
3384 | SwFieldTypesEnum nTypeId = pField->GetTypeId(); | ||||
3385 | SfxViewFrame* pVFrame = GetView().GetViewFrame(); | ||||
3386 | switch( nTypeId ) | ||||
3387 | { | ||||
3388 | case SwFieldTypesEnum::Postit: | ||||
3389 | case SwFieldTypesEnum::Script: | ||||
3390 | { | ||||
3391 | // if it's a Readonly region, status has to be enabled | ||||
3392 | sal_uInt16 nSlot = SwFieldTypesEnum::Postit == nTypeId ? FN_POSTIT((20000 + 300) + 29) : FN_JAVAEDIT((20000 + 1400) + 10); | ||||
3393 | SfxBoolItem aItem(nSlot, true); | ||||
3394 | pVFrame->GetBindings().SetState(aItem); | ||||
3395 | pVFrame->GetBindings().Execute(nSlot); | ||||
3396 | break; | ||||
3397 | } | ||||
3398 | case SwFieldTypesEnum::Authority : | ||||
3399 | pVFrame->GetBindings().Execute(FN_EDIT_AUTH_ENTRY_DLG((20000 + 1800) + 33)); | ||||
3400 | break; | ||||
3401 | case SwFieldTypesEnum::Input: | ||||
3402 | case SwFieldTypesEnum::Dropdown: | ||||
3403 | case SwFieldTypesEnum::SetInput: | ||||
3404 | pVFrame->GetBindings().Execute(FN_UPDATE_INPUTFIELDS((20000 + 100) + 43)); | ||||
3405 | break; | ||||
3406 | default: | ||||
3407 | pVFrame->GetBindings().Execute(FN_EDIT_FIELD((20000 + 100) + 4 )); | ||||
3408 | } | ||||
3409 | } | ||||
3410 | return; | ||||
3411 | } | ||||
3412 | // in extended mode double and triple | ||||
3413 | // click has no effect. | ||||
3414 | if ( rSh.IsExtMode() || rSh.IsBlockMode() ) | ||||
3415 | return; | ||||
3416 | |||||
3417 | // select word, AdditionalMode if applicable | ||||
3418 | if ( KEY_MOD1 == rMEvt.GetModifier() && !rSh.IsAddMode() ) | ||||
3419 | { | ||||
3420 | rSh.EnterAddMode(); | ||||
3421 | rSh.SelWrd( &aDocPos ); | ||||
3422 | rSh.LeaveAddMode(); | ||||
3423 | } | ||||
3424 | else | ||||
3425 | { | ||||
3426 | if (!rSh.SelWrd(&aDocPos) && comphelper::LibreOfficeKit::isActive()) | ||||
3427 | // Double click did not select any word: try to | ||||
3428 | // select the current cell in case we are in a | ||||
3429 | // table. | ||||
3430 | rSh.SelTableBox(); | ||||
3431 | } | ||||
3432 | |||||
3433 | SwContentAtPos aContentAtPos(IsAttrAtPos::FormControl); | ||||
3434 | if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) && | ||||
3435 | aContentAtPos.aFnd.pFieldmark != nullptr) | ||||
3436 | { | ||||
3437 | IFieldmark *pFieldBM = const_cast< IFieldmark* > ( aContentAtPos.aFnd.pFieldmark ); | ||||
3438 | if ( pFieldBM->GetFieldname( ) == ODF_FORMDROPDOWN"vnd.oasis.opendocument.field.FORMDROPDOWN" || pFieldBM->GetFieldname( ) == ODF_FORMDATE"vnd.oasis.opendocument.field.FORMDATE" ) | ||||
3439 | { | ||||
3440 | RstMBDownFlags(); | ||||
3441 | rSh.getIDocumentMarkAccess()->ClearFieldActivation(); | ||||
3442 | GetView().GetViewFrame()->GetBindings().Execute(SID_FM_CTL_PROPERTIES( 10000 + 613 )); | ||||
3443 | return; | ||||
3444 | } | ||||
3445 | } | ||||
3446 | |||||
3447 | g_bHoldSelection = true; | ||||
3448 | return; | ||||
3449 | } | ||||
3450 | case 3: | ||||
3451 | case 4: | ||||
3452 | { | ||||
3453 | g_bFrameDrag = false; | ||||
3454 | // in extended mode double and triple | ||||
3455 | // click has no effect. | ||||
3456 | if ( rSh.IsExtMode() ) | ||||
3457 | return; | ||||
3458 | |||||
3459 | // if the cursor position was corrected or if a Fly | ||||
3460 | // was selected in ReadOnlyMode, no word selection. | ||||
3461 | if ( !g_bValidCursorPos || rSh.IsFrameSelected() ) | ||||
3462 | return; | ||||
3463 | |||||
3464 | // select line, AdditionalMode if applicable | ||||
3465 | const bool bMod = KEY_MOD1 == rMEvt.GetModifier() && | ||||
3466 | !rSh.IsAddMode(); | ||||
3467 | |||||
3468 | if ( bMod ) | ||||
3469 | rSh.EnterAddMode(); | ||||
3470 | |||||
3471 | // Enhanced selection | ||||
3472 | if ( 3 == nNumberOfClicks ) | ||||
3473 | rSh.SelSentence( &aDocPos ); | ||||
3474 | else | ||||
3475 | rSh.SelPara( &aDocPos ); | ||||
3476 | |||||
3477 | if ( bMod ) | ||||
3478 | rSh.LeaveAddMode(); | ||||
3479 | |||||
3480 | g_bHoldSelection = true; | ||||
3481 | return; | ||||
3482 | } | ||||
3483 | |||||
3484 | default: | ||||
3485 | return; | ||||
3486 | } | ||||
3487 | |||||
3488 | [[fallthrough]]; | ||||
3489 | } | ||||
3490 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_SHIFT: | ||||
3491 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_SHIFT + KEY_MOD1: | ||||
3492 | { | ||||
3493 | bool bLockView = m_bWasShdwCursor; | ||||
3494 | |||||
3495 | switch ( rMEvt.GetModifier() ) | ||||
3496 | { | ||||
3497 | case KEY_MOD1 + KEY_SHIFT: | ||||
3498 | { | ||||
3499 | if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) ) | ||||
3500 | { | ||||
3501 | m_rView.NoRotate(); | ||||
3502 | rSh.HideCursor(); | ||||
3503 | if ( rSh.IsSelFrameMode() ) | ||||
3504 | rSh.SelectObj(aDocPos, SW_ADD_SELECT1 | SW_ENTER_GROUP2); | ||||
3505 | else | ||||
3506 | { if ( rSh.SelectObj( aDocPos, SW_ADD_SELECT1 | SW_ENTER_GROUP2 ) ) | ||||
3507 | { | ||||
3508 | rSh.EnterSelFrameMode( &aDocPos ); | ||||
3509 | SwEditWin::m_nDDStartPosY = aDocPos.Y(); | ||||
3510 | SwEditWin::m_nDDStartPosX = aDocPos.X(); | ||||
3511 | g_bFrameDrag = true; | ||||
3512 | return; | ||||
3513 | } | ||||
3514 | } | ||||
3515 | } | ||||
3516 | else if( rSh.IsSelFrameMode() && | ||||
3517 | rSh.GetDrawView()->PickHandle( aDocPos )) | ||||
3518 | { | ||||
3519 | g_bFrameDrag = true; | ||||
3520 | g_bNoInterrupt = false; | ||||
3521 | return; | ||||
3522 | } | ||||
3523 | } | ||||
3524 | break; | ||||
3525 | case KEY_MOD1: | ||||
3526 | if ( !bExecDrawTextLink ) | ||||
3527 | { | ||||
3528 | if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) | ||||
3529 | { | ||||
3530 | SwContentAtPos aContentAtPos(IsAttrAtPos::Outline); | ||||
3531 | if(rSh.GetContentAtPos(aDocPos, aContentAtPos)) | ||||
3532 | { | ||||
3533 | // move cursor to outline para start and toggle outline content visibility | ||||
3534 | MoveCursor(rSh, aDocPos, bOnlyText, bLockView); | ||||
3535 | SwPaM aPam(*rSh.GetCurrentShellCursor().GetPoint()); | ||||
3536 | SwOutlineNodes::size_type nPos; | ||||
3537 | if (rSh.GetNodes().GetOutLineNds().Seek_Entry( &aPam.GetPoint()->nNode.GetNode(), &nPos)) | ||||
3538 | rSh.ToggleOutlineContentVisibility(nPos); | ||||
3539 | return; | ||||
3540 | } | ||||
3541 | } | ||||
3542 | if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) && !lcl_urlOverBackground( rSh, aDocPos ) ) | ||||
3543 | { | ||||
3544 | m_rView.NoRotate(); | ||||
3545 | rSh.HideCursor(); | ||||
3546 | if ( rSh.IsSelFrameMode() ) | ||||
3547 | rSh.SelectObj(aDocPos, SW_ENTER_GROUP2); | ||||
3548 | else | ||||
3549 | { if ( rSh.SelectObj( aDocPos, SW_ENTER_GROUP2 ) ) | ||||
3550 | { | ||||
3551 | rSh.EnterSelFrameMode( &aDocPos ); | ||||
3552 | SwEditWin::m_nDDStartPosY = aDocPos.Y(); | ||||
3553 | SwEditWin::m_nDDStartPosX = aDocPos.X(); | ||||
3554 | g_bFrameDrag = true; | ||||
3555 | return; | ||||
3556 | } | ||||
3557 | } | ||||
3558 | } | ||||
3559 | else if( rSh.IsSelFrameMode() && | ||||
3560 | rSh.GetDrawView()->PickHandle( aDocPos )) | ||||
3561 | { | ||||
3562 | g_bFrameDrag = true; | ||||
3563 | g_bNoInterrupt = false; | ||||
3564 | return; | ||||
3565 | } | ||||
3566 | else | ||||
3567 | { | ||||
3568 | if ( !rSh.IsAddMode() && !rSh.IsExtMode() && !rSh.IsBlockMode() ) | ||||
3569 | { | ||||
3570 | rSh.PushMode(); | ||||
3571 | g_bModePushed = true; | ||||
3572 | |||||
3573 | bool bUnLockView = !rSh.IsViewLocked(); | ||||
3574 | rSh.LockView( true ); | ||||
3575 | rSh.EnterAddMode(); | ||||
3576 | if( bUnLockView ) | ||||
3577 | rSh.LockView( false ); | ||||
3578 | } | ||||
3579 | bCallBase = false; | ||||
3580 | } | ||||
3581 | } | ||||
3582 | break; | ||||
3583 | case KEY_MOD2: | ||||
3584 | { | ||||
3585 | if ( !rSh.IsAddMode() && !rSh.IsExtMode() && !rSh.IsBlockMode() ) | ||||
3586 | { | ||||
3587 | rSh.PushMode(); | ||||
3588 | g_bModePushed = true; | ||||
3589 | bool bUnLockView = !rSh.IsViewLocked(); | ||||
3590 | rSh.LockView( true ); | ||||
3591 | rSh.EnterBlockMode(); | ||||
3592 | if( bUnLockView ) | ||||
3593 | rSh.LockView( false ); | ||||
3594 | } | ||||
3595 | bCallBase = false; | ||||
3596 | } | ||||
3597 | break; | ||||
3598 | case KEY_SHIFT: | ||||
3599 | { | ||||
3600 | if ( !m_bInsDraw && IsDrawObjSelectable( rSh, aDocPos ) ) | ||||
3601 | { | ||||
3602 | m_rView.NoRotate(); | ||||
3603 | rSh.HideCursor(); | ||||
3604 | if ( rSh.IsSelFrameMode() ) | ||||
3605 | { | ||||
3606 | rSh.SelectObj(aDocPos, SW_ADD_SELECT1); | ||||
3607 | |||||
3608 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); | ||||
3609 | if (rMarkList.GetMark(0) == nullptr) | ||||
3610 | { | ||||
3611 | rSh.LeaveSelFrameMode(); | ||||
3612 | m_rView.AttrChangedNotify(nullptr); | ||||
3613 | g_bFrameDrag = false; | ||||
3614 | } | ||||
3615 | } | ||||
3616 | else | ||||
3617 | { if ( rSh.SelectObj( aDocPos ) ) | ||||
3618 | { | ||||
3619 | rSh.EnterSelFrameMode( &aDocPos ); | ||||
3620 | SwEditWin::m_nDDStartPosY = aDocPos.Y(); | ||||
3621 | SwEditWin::m_nDDStartPosX = aDocPos.X(); | ||||
3622 | g_bFrameDrag = true; | ||||
3623 | return; | ||||
3624 | } | ||||
3625 | } | ||||
3626 | } | ||||
3627 | else | ||||
3628 | { | ||||
3629 | if ( rSh.IsSelFrameMode() && | ||||
3630 | rSh.IsInsideSelectedObj( aDocPos ) ) | ||||
3631 | { | ||||
3632 | rSh.EnterSelFrameMode( &aDocPos ); | ||||
3633 | SwEditWin::m_nDDStartPosY = aDocPos.Y(); | ||||
3634 | SwEditWin::m_nDDStartPosX = aDocPos.X(); | ||||
3635 | g_bFrameDrag = true; | ||||
3636 | return; | ||||
3637 | } | ||||
3638 | if ( rSh.IsSelFrameMode() ) | ||||
3639 | { | ||||
3640 | rSh.UnSelectFrame(); | ||||
3641 | rSh.LeaveSelFrameMode(); | ||||
3642 | m_rView.AttrChangedNotify(nullptr); | ||||
3643 | g_bFrameDrag = false; | ||||
3644 | } | ||||
3645 | if ( !rSh.IsExtMode() ) | ||||
3646 | { | ||||
3647 | // don't start a selection when an | ||||
3648 | // URL field or a graphic is clicked | ||||
3649 | bool bSttSelect = rSh.HasSelection() || | ||||
3650 | PointerStyle::RefHand != GetPointer(); | ||||
3651 | |||||
3652 | if( !bSttSelect ) | ||||
3653 | { | ||||
3654 | bSttSelect = true; | ||||
3655 | if( bExecHyperlinks ) | ||||
3656 | { | ||||
3657 | SwContentAtPos aContentAtPos( | ||||
3658 | IsAttrAtPos::Ftn | | ||||
3659 | IsAttrAtPos::InetAttr ); | ||||
3660 | |||||
3661 | if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) ) | ||||
3662 | { | ||||
3663 | if( !rSh.IsViewLocked() && | ||||
3664 | !rSh.IsReadOnlyAvailable() && | ||||
3665 | aContentAtPos.IsInProtectSect() ) | ||||
3666 | bLockView = true; | ||||
3667 | |||||
3668 | bSttSelect = false; | ||||
3669 | } | ||||
3670 | else if( rSh.IsURLGrfAtPos( aDocPos )) | ||||
3671 | bSttSelect = false; | ||||
3672 | } | ||||
3673 | } | ||||
3674 | |||||
3675 | if( bSttSelect ) | ||||
3676 | rSh.SttSelect(); | ||||
3677 | } | ||||
3678 | } | ||||
3679 | bCallBase = false; | ||||
3680 | break; | ||||
3681 | } | ||||
3682 | default: | ||||
3683 | if( !rSh.IsViewLocked() ) | ||||
3684 | { | ||||
3685 | SwContentAtPos aContentAtPos( IsAttrAtPos::ClickField | | ||||
3686 | IsAttrAtPos::InetAttr ); | ||||
3687 | if( rSh.GetContentAtPos( aDocPos, aContentAtPos ) && | ||||
3688 | !rSh.IsReadOnlyAvailable() && | ||||
3689 | aContentAtPos.IsInProtectSect() ) | ||||
3690 | bLockView = true; | ||||
3691 | } | ||||
3692 | } | ||||
3693 | |||||
3694 | if ( rSh.IsGCAttr() ) | ||||
3695 | { | ||||
3696 | rSh.GCAttr(); | ||||
3697 | rSh.ClearGCAttr(); | ||||
3698 | } | ||||
3699 | |||||
3700 | SwContentAtPos aFieldAtPos(IsAttrAtPos::Field); | ||||
3701 | bool bEditableFieldClicked = false; | ||||
3702 | |||||
3703 | // Are we clicking on a field? | ||||
3704 | if (rSh.GetContentAtPos(aDocPos, aFieldAtPos)) | ||||
3705 | { | ||||
3706 | bool bEditableField = (aFieldAtPos.pFndTextAttr != nullptr | ||||
3707 | && aFieldAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD); | ||||
3708 | |||||
3709 | if (!bEditableField) | ||||
3710 | { | ||||
3711 | rSh.CallSetCursor(&aDocPos, bOnlyText); | ||||
3712 | // Unfortunately the cursor may be on field | ||||
3713 | // position or on position after field depending on which | ||||
3714 | // half of the field was clicked on. | ||||
3715 | SwTextAttr const*const pTextField(aFieldAtPos.pFndTextAttr); | ||||
3716 | if (pTextField && rSh.GetCurrentShellCursor().GetPoint()->nContent | ||||
3717 | .GetIndex() != pTextField->GetStart()) | ||||
3718 | { | ||||
3719 | assert(rSh.GetCurrentShellCursor().GetPoint()->nContent(static_cast <bool> (rSh.GetCurrentShellCursor().GetPoint ()->nContent .GetIndex() == (pTextField->GetStart() + 1 )) ? void (0) : __assert_fail ("rSh.GetCurrentShellCursor().GetPoint()->nContent .GetIndex() == (pTextField->GetStart() + 1)" , "/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" , 3720, __extension__ __PRETTY_FUNCTION__)) | ||||
3720 | .GetIndex() == (pTextField->GetStart() + 1))(static_cast <bool> (rSh.GetCurrentShellCursor().GetPoint ()->nContent .GetIndex() == (pTextField->GetStart() + 1 )) ? void (0) : __assert_fail ("rSh.GetCurrentShellCursor().GetPoint()->nContent .GetIndex() == (pTextField->GetStart() + 1)" , "/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" , 3720, __extension__ __PRETTY_FUNCTION__)); | ||||
3721 | rSh.Left( CRSR_SKIP_CHARS, false, 1, false ); | ||||
3722 | } | ||||
3723 | // don't go into the !bOverSelect block below - it moves | ||||
3724 | // the cursor | ||||
3725 | break; | ||||
3726 | } | ||||
3727 | else | ||||
3728 | { | ||||
3729 | bEditableFieldClicked = true; | ||||
3730 | } | ||||
3731 | } | ||||
3732 | |||||
3733 | bool bOverSelect = rSh.TestCurrPam( aDocPos ); | ||||
3734 | bool bOverURLGrf = false; | ||||
3735 | if( !bOverSelect ) | ||||
3736 | bOverURLGrf = bOverSelect = nullptr != rSh.IsURLGrfAtPos( aDocPos ); | ||||
3737 | |||||
3738 | if ( !bOverSelect || rSh.IsInSelect() ) | ||||
3739 | { | ||||
3740 | MoveCursor( rSh, aDocPos, bOnlyText, bLockView ); | ||||
3741 | bCallBase = false; | ||||
3742 | } | ||||
3743 | if (!bOverURLGrf && !bExecDrawTextLink && !bOnlyText) | ||||
3744 | { | ||||
3745 | const SelectionType nSelType = rSh.GetSelectionType(); | ||||
3746 | // Check in general, if an object is selectable at given position. | ||||
3747 | // Thus, also text fly frames in background become selectable via Ctrl-Click. | ||||
3748 | if ( ( nSelType & SelectionType::Ole || | ||||
3749 | nSelType & SelectionType::Graphic || | ||||
3750 | rSh.IsObjSelectable( aDocPos ) ) && !lcl_urlOverBackground( rSh, aDocPos ) ) | ||||
3751 | { | ||||
3752 | SwMvContext aMvContext( &rSh ); | ||||
3753 | rSh.EnterSelFrameMode(); | ||||
3754 | bCallBase = false; | ||||
3755 | } | ||||
3756 | } | ||||
3757 | if ( !bOverSelect && bEditableFieldClicked && (!pCursorField || | ||||
3758 | pCursorField != aFieldAtPos.pFndTextAttr->GetFormatField().GetField())) | ||||
3759 | { | ||||
3760 | // select content of Input Field, but exclude CH_TXT_ATR_INPUTFIELDSTART | ||||
3761 | // and CH_TXT_ATR_INPUTFIELDEND | ||||
3762 | rSh.SttSelect(); | ||||
3763 | rSh.SelectText( aFieldAtPos.pFndTextAttr->GetStart() + 1, | ||||
3764 | *(aFieldAtPos.pFndTextAttr->End()) - 1 ); | ||||
3765 | } | ||||
3766 | // don't reset here any longer so that, in case through MouseMove | ||||
3767 | // with pressed Ctrl key a multiple-selection should happen, | ||||
3768 | // the previous selection is not released in Drag. | ||||
3769 | break; | ||||
3770 | } | ||||
3771 | } | ||||
3772 | } | ||||
3773 | else if (MOUSE_RIGHT(sal_uInt16(0x0004)) == rMEvt.GetButtons()) | ||||
3774 | { | ||||
3775 | if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton() && rMEvt.GetModifier() == KEY_MOD1) | ||||
3776 | { | ||||
3777 | SwContentAtPos aContentAtPos(IsAttrAtPos::Outline); | ||||
3778 | if(rSh.GetContentAtPos(aDocPos, aContentAtPos)) | ||||
3779 | { | ||||
3780 | // move cursor to para start toggle outline content visibility and set the same visibility for subs | ||||
3781 | MoveCursor(rSh, aDocPos, false, true); | ||||
3782 | SwPaM aPam(*rSh.GetCurrentShellCursor().GetPoint()); | ||||
3783 | SwOutlineNodes::size_type nPos; | ||||
3784 | if (rSh.GetNodes().GetOutLineNds().Seek_Entry(&aPam.GetPoint()->nNode.GetNode(), &nPos)) | ||||
3785 | { | ||||
3786 | SwOutlineNodes::size_type nOutlineNodesCount = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount(); | ||||
3787 | int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos); | ||||
3788 | bool bFold = rSh.IsOutlineContentFolded(nPos); | ||||
3789 | do | ||||
3790 | { | ||||
3791 | if (rSh.IsOutlineContentFolded(nPos) == bFold) | ||||
3792 | rSh.ToggleOutlineContentVisibility(nPos); | ||||
3793 | } while (++nPos < nOutlineNodesCount | ||||
3794 | && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nLevel); | ||||
3795 | return; | ||||
3796 | } | ||||
3797 | } | ||||
3798 | } | ||||
3799 | else if ( !rMEvt.GetModifier() | ||||
3800 | && static_cast< sal_uInt8 >(rMEvt.GetClicks() % 4) == 1 | ||||
3801 | && !rSh.TestCurrPam( aDocPos ) ) | ||||
3802 | { | ||||
3803 | SwContentAtPos aFieldAtPos(IsAttrAtPos::Field); | ||||
3804 | |||||
3805 | // Are we clicking on a field? | ||||
3806 | if (g_bValidCursorPos | ||||
3807 | && rSh.GetContentAtPos(aDocPos, aFieldAtPos) | ||||
3808 | && aFieldAtPos.pFndTextAttr != nullptr | ||||
3809 | && aFieldAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD | ||||
3810 | && (!pCursorField || pCursorField != aFieldAtPos.pFndTextAttr->GetFormatField().GetField())) | ||||
3811 | { | ||||
3812 | // Move the cursor | ||||
3813 | MoveCursor( rSh, aDocPos, rSh.IsObjSelectable( aDocPos ), m_bWasShdwCursor ); | ||||
3814 | bCallBase = false; | ||||
3815 | |||||
3816 | // select content of Input Field, but exclude CH_TXT_ATR_INPUTFIELDSTART | ||||
3817 | // and CH_TXT_ATR_INPUTFIELDEND | ||||
3818 | rSh.SttSelect(); | ||||
3819 | rSh.SelectText( aFieldAtPos.pFndTextAttr->GetStart() + 1, | ||||
3820 | *(aFieldAtPos.pFndTextAttr->End()) - 1 ); | ||||
3821 | } | ||||
3822 | } | ||||
3823 | } | ||||
3824 | |||||
3825 | if (bCallBase) | ||||
3826 | Window::MouseButtonDown(rMEvt); | ||||
3827 | } | ||||
3828 | |||||
3829 | bool SwEditWin::changeMousePointer(Point const & rDocPoint) | ||||
3830 | { | ||||
3831 | SwWrtShell & rShell = m_rView.GetWrtShell(); | ||||
3832 | |||||
3833 | SwTab nMouseTabCol; | ||||
3834 | if ( SwTab::COL_NONE != (nMouseTabCol = rShell.WhichMouseTabCol( rDocPoint ) ) && | ||||
3835 | !rShell.IsObjSelectable( rDocPoint ) ) | ||||
3836 | { | ||||
3837 | PointerStyle nPointer = PointerStyle::Null; | ||||
3838 | bool bChkTableSel = false; | ||||
3839 | |||||
3840 | switch ( nMouseTabCol ) | ||||
3841 | { | ||||
3842 | case SwTab::COL_VERT : | ||||
3843 | case SwTab::ROW_HORI : | ||||
3844 | nPointer = PointerStyle::VSizeBar; | ||||
3845 | bChkTableSel = true; | ||||
3846 | break; | ||||
3847 | case SwTab::ROW_VERT : | ||||
3848 | case SwTab::COL_HORI : | ||||
3849 | nPointer = PointerStyle::HSizeBar; | ||||
3850 | bChkTableSel = true; | ||||
3851 | break; | ||||
3852 | // Enhanced table selection | ||||
3853 | case SwTab::SEL_HORI : | ||||
3854 | nPointer = PointerStyle::TabSelectSE; | ||||
3855 | break; | ||||
3856 | case SwTab::SEL_HORI_RTL : | ||||
3857 | case SwTab::SEL_VERT : | ||||
3858 | nPointer = PointerStyle::TabSelectSW; | ||||
3859 | break; | ||||
3860 | case SwTab::COLSEL_HORI : | ||||
3861 | case SwTab::ROWSEL_VERT : | ||||
3862 | nPointer = PointerStyle::TabSelectS; | ||||
3863 | break; | ||||
3864 | case SwTab::ROWSEL_HORI : | ||||
3865 | nPointer = PointerStyle::TabSelectE; | ||||
3866 | break; | ||||
3867 | case SwTab::ROWSEL_HORI_RTL : | ||||
3868 | case SwTab::COLSEL_VERT : | ||||
3869 | nPointer = PointerStyle::TabSelectW; | ||||
3870 | break; | ||||
3871 | default: break; // prevent compiler warning | ||||
3872 | } | ||||
3873 | |||||
3874 | if ( PointerStyle::Null != nPointer && | ||||
3875 | // i#35543 - Enhanced table selection is explicitly allowed in table mode | ||||
3876 | ( !bChkTableSel || !rShell.IsTableMode() ) && | ||||
3877 | !comphelper::LibreOfficeKit::isActive() ) | ||||
3878 | { | ||||
3879 | SetPointer( nPointer ); | ||||
3880 | } | ||||
3881 | |||||
3882 | return true; | ||||
3883 | } | ||||
3884 | else if (rShell.IsNumLabel(rDocPoint, RULER_MOUSE_MARGINWIDTH)) | ||||
3885 | { | ||||
3886 | // i#42921 - consider vertical mode | ||||
3887 | SwTextNode* pNodeAtPos = rShell.GetNumRuleNodeAtPos( rDocPoint ); | ||||
3888 | const PointerStyle nPointer = | ||||
3889 | SwFEShell::IsVerticalModeAtNdAndPos( *pNodeAtPos, rDocPoint ) | ||||
3890 | ? PointerStyle::VSizeBar | ||||
3891 | : PointerStyle::HSizeBar; | ||||
3892 | SetPointer( nPointer ); | ||||
3893 | |||||
3894 | return true; | ||||
3895 | } | ||||
3896 | return false; | ||||
3897 | } | ||||
3898 | |||||
3899 | void SwEditWin::MouseMove(const MouseEvent& _rMEvt) | ||||
3900 | { | ||||
3901 | MouseEvent rMEvt(_rMEvt); | ||||
3902 | |||||
3903 | if (comphelper::LibreOfficeKit::isActive()) | ||||
| |||||
3904 | { | ||||
3905 | if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel())) | ||||
3906 | { | ||||
3907 | pWindow->MouseMove(rMEvt); | ||||
3908 | return; | ||||
3909 | } | ||||
3910 | } | ||||
3911 | |||||
3912 | //ignore key modifiers for format paintbrush | ||||
3913 | { | ||||
3914 | bool bExecFormatPaintbrush = m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard | ||||
3915 | && m_pApplyTempl->m_pFormatClipboard->HasContent(); | ||||
3916 | if( bExecFormatPaintbrush
| ||||
3917 | rMEvt = MouseEvent( _rMEvt.GetPosPixel(), _rMEvt.GetClicks(), | ||||
3918 | _rMEvt.GetMode(), _rMEvt.GetButtons() ); | ||||
3919 | } | ||||
3920 | |||||
3921 | // as long as an action is running the MouseMove should be disconnected | ||||
3922 | // otherwise bug 40102 occurs | ||||
3923 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
3924 | if( rSh.ActionPend() ) | ||||
3925 | return ; | ||||
3926 | |||||
3927 | if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) | ||||
3928 | { | ||||
3929 | // add/remove outline collapse button | ||||
3930 | SwContentAtPos aSwContentAtPos(IsAttrAtPos::Outline); | ||||
3931 | if (rSh.GetContentAtPos(PixelToLogic(rMEvt.GetPosPixel()), aSwContentAtPos)) | ||||
3932 | { | ||||
3933 | if(aSwContentAtPos.aFnd.pNode && aSwContentAtPos.aFnd.pNode->IsTextNode()) | ||||
3934 | { | ||||
3935 | const SwNodes& rNds = rSh.GetDoc()->GetNodes(); | ||||
3936 | SwOutlineNodes::size_type nPos; | ||||
3937 | SwContentFrame* pContentFrame = aSwContentAtPos.aFnd.pNode->GetTextNode()->getLayoutFrame(nullptr); | ||||
3938 | if (pContentFrame != m_pSavedOutlineFrame) | ||||
3939 | { | ||||
3940 | // remove collapse button when saved frame is not frame at mouse position | ||||
3941 | if (m_pSavedOutlineFrame && /* is it possible that m_pSavedOutlineFrame is removed? */ !m_pSavedOutlineFrame->IsInDtor() && | ||||
3942 | rNds.GetOutLineNds().Seek_Entry(static_cast<SwTextFrame*>(m_pSavedOutlineFrame)->GetTextNodeFirst(), &nPos) && | ||||
3943 | !rSh.IsOutlineContentFolded(nPos)) | ||||
3944 | { | ||||
3945 | GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame); | ||||
3946 | } | ||||
3947 | m_pSavedOutlineFrame = pContentFrame; | ||||
3948 | } | ||||
3949 | // show collapse button | ||||
3950 | if (rNds.GetOutLineNds().Seek_Entry(aSwContentAtPos.aFnd.pNode->GetTextNode(), &nPos) && | ||||
3951 | !rSh.IsOutlineContentFolded(nPos)) | ||||
3952 | { | ||||
3953 | GetFrameControlsManager().SetOutlineContentVisibilityButton(aSwContentAtPos.aFnd.pNode->GetTextNode()); | ||||
3954 | } | ||||
3955 | } | ||||
3956 | } | ||||
3957 | else if (m_pSavedOutlineFrame && !m_pSavedOutlineFrame->IsInDtor()) | ||||
3958 | { | ||||
3959 | // current pointer pos is not over an outline frame | ||||
3960 | // previous frame was an outline frame | ||||
3961 | // remove collapse button if showing | ||||
3962 | const SwNodes& rNds = rSh.GetDoc()->GetNodes(); | ||||
3963 | SwOutlineNodes::size_type nPos; | ||||
3964 | if (rNds.GetOutLineNds().Seek_Entry(static_cast<SwTextFrame*>(m_pSavedOutlineFrame)->GetTextNodeFirst(), &nPos) && | ||||
3965 | !rSh.IsOutlineContentFolded(nPos)) | ||||
3966 | { | ||||
3967 | GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame); | ||||
3968 | } | ||||
3969 | m_pSavedOutlineFrame = nullptr; | ||||
3970 | } | ||||
3971 | } | ||||
3972 | |||||
3973 | if( m_pShadCursor && 0 != (rMEvt.GetModifier() + rMEvt.GetButtons() ) ) | ||||
3974 | { | ||||
3975 | m_pShadCursor.reset(); | ||||
3976 | } | ||||
3977 | |||||
3978 | bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly(); | ||||
3979 | |||||
3980 | CurrShell aCurr( &rSh ); | ||||
3981 | |||||
3982 | //aPixPt == Point in Pixel, relative to ChildWin | ||||
3983 | //aDocPt == Point in Twips, document coordinates | ||||
3984 | const Point aPixPt( rMEvt.GetPosPixel() ); | ||||
3985 | const Point aDocPt( PixelToLogic( aPixPt ) ); | ||||
3986 | |||||
3987 | if ( IsChainMode() ) | ||||
3988 | { | ||||
3989 | UpdatePointer( aDocPt, rMEvt.GetModifier() ); | ||||
3990 | return; | ||||
3991 | } | ||||
3992 | |||||
3993 | SdrView *pSdrView = rSh.GetDrawView(); | ||||
3994 | |||||
3995 | const SwCallMouseEvent aLastCallEvent( m_aSaveCallEvent ); | ||||
3996 | m_aSaveCallEvent.Clear(); | ||||
3997 | |||||
3998 | if ( !bIsDocReadOnly && pSdrView && pSdrView->MouseMove(rMEvt,this) ) | ||||
3999 | { | ||||
4000 | SetPointer( PointerStyle::Text ); | ||||
4001 | return; // evaluate SdrView's event | ||||
4002 | } | ||||
4003 | |||||
4004 | const Point aOldPt( rSh.VisArea().Pos() ); | ||||
4005 | const bool bInsWin = rSh.VisArea().IsInside( aDocPt ) || comphelper::LibreOfficeKit::isActive(); | ||||
4006 | |||||
4007 | if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) | ||||
4008 | { | ||||
4009 | if (m_pSavedOutlineFrame && !bInsWin) | ||||
4010 | { | ||||
4011 | // the mouse pointer has left the building | ||||
4012 | // 86 the collapse button if showing | ||||
4013 | const SwNodes& rNds = rSh.GetDoc()->GetNodes(); | ||||
4014 | SwOutlineNodes::size_type nPos; | ||||
4015 | rNds.GetOutLineNds().Seek_Entry(static_cast<SwTextFrame*>(m_pSavedOutlineFrame)->GetTextNodeFirst(), &nPos); | ||||
4016 | if (!rSh.IsOutlineContentFolded(nPos)) | ||||
4017 | GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame); | ||||
4018 | m_pSavedOutlineFrame = nullptr; | ||||
4019 | } | ||||
4020 | } | ||||
4021 | |||||
4022 | if( m_pShadCursor && !bInsWin ) | ||||
4023 | { | ||||
4024 | m_pShadCursor.reset(); | ||||
4025 | } | ||||
4026 | |||||
4027 | if( bInsWin
| ||||
4028 | { | ||||
4029 | EnterArea(); | ||||
4030 | Point aPos( aDocPt ); | ||||
4031 | if( rSh.SelectTableRowCol( *m_xRowColumnSelectionStart, &aPos, m_bIsRowDrag )) | ||||
4032 | return; | ||||
4033 | } | ||||
4034 | |||||
4035 | // position is necessary for OS/2 because obviously after a MB-Down | ||||
4036 | // a MB-Move is called immediately. | ||||
4037 | if( g_bDDTimerStarted ) | ||||
4038 | { | ||||
4039 | Point aDD( SwEditWin::m_nDDStartPosX, SwEditWin::m_nDDStartPosY ); | ||||
4040 | aDD = LogicToPixel( aDD ); | ||||
4041 | tools::Rectangle aRect( aDD.X()-3, aDD.Y()-3, aDD.X()+3, aDD.Y()+3 ); | ||||
4042 | if ( !aRect.IsInside( aPixPt ) ) | ||||
4043 | StopDDTimer( &rSh, aDocPt ); | ||||
4044 | } | ||||
4045 | |||||
4046 | if(m_rView.GetDrawFuncPtr()) | ||||
4047 | { | ||||
4048 | if( m_bInsDraw ) | ||||
4049 | { | ||||
4050 | m_rView.GetDrawFuncPtr()->MouseMove( rMEvt ); | ||||
4051 | if ( !bInsWin ) | ||||
4052 | { | ||||
4053 | Point aTmp( aDocPt ); | ||||
4054 | aTmp += rSh.VisArea().Pos() - aOldPt; | ||||
4055 | LeaveArea( aTmp ); | ||||
4056 | } | ||||
4057 | else | ||||
4058 | EnterArea(); | ||||
4059 | return; | ||||
4060 | } | ||||
4061 | else if(!rSh.IsFrameSelected() && !rSh.IsObjSelected()) | ||||
4062 | { | ||||
4063 | SfxBindings &rBnd = rSh.GetView().GetViewFrame()->GetBindings(); | ||||
4064 | Point aRelPos = rSh.GetRelativePagePosition(aDocPt); | ||||
4065 | if(aRelPos.X() >= 0) | ||||
4066 | { | ||||
4067 | FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &GetView()) != nullptr ); | ||||
4068 | SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->PutItem(SfxUInt16Item(SID_ATTR_METRICTypedWhichId<SfxUInt16Item>(((((10000 + 1499) + 1) + 499 ) + 1) + 8), static_cast< sal_uInt16 >(eMetric))); | ||||
4069 | const SfxPointItem aTmp1( SID_ATTR_POSITIONTypedWhichId<SfxPointItem>( 10000 + 223 ), aRelPos ); | ||||
4070 | rBnd.SetState( aTmp1 ); | ||||
4071 | } | ||||
4072 | else | ||||
4073 | { | ||||
4074 | rBnd.Invalidate(SID_ATTR_POSITIONTypedWhichId<SfxPointItem>( 10000 + 223 )); | ||||
4075 | } | ||||
4076 | rBnd.Invalidate(SID_ATTR_SIZETypedWhichId<SvxSizeItem>( 10000 + 224 )); | ||||
4077 | const SfxStringItem aCell( SID_TABLE_CELL( 10000 + 225 ), OUString() ); | ||||
4078 | rBnd.SetState( aCell ); | ||||
4079 | } | ||||
4080 | } | ||||
4081 | |||||
4082 | // determine if we only change the mouse pointer and return | ||||
4083 | if (!bIsDocReadOnly
| ||||
4084 | { | ||||
4085 | return; | ||||
4086 | } | ||||
4087 | |||||
4088 | bool bDelShadCursor = true; | ||||
4089 | |||||
4090 | switch ( rMEvt.GetModifier() + rMEvt.GetButtons() ) | ||||
4091 | { | ||||
4092 | case MOUSE_LEFT(sal_uInt16(0x0001)): | ||||
4093 | if( m_pAnchorMarker ) | ||||
4094 | { | ||||
4095 | // Now we need to refresh the SdrHdl pointer of m_pAnchorMarker. | ||||
4096 | // This looks a little bit tricky, but it solves the following | ||||
4097 | // problem: the m_pAnchorMarker contains a pointer to an SdrHdl, | ||||
4098 | // if the FindAnchorPos-call cause a scrolling of the visible | ||||
4099 | // area, it's possible that the SdrHdl will be destroyed and a | ||||
4100 | // new one will initialized at the original position(GetHdlPos). | ||||
4101 | // So the m_pAnchorMarker has to find the right SdrHdl, if it's | ||||
4102 | // the old one, it will find it with position aOld, if this one | ||||
4103 | // is destroyed, it will find a new one at position GetHdlPos(). | ||||
4104 | |||||
4105 | const Point aOld = m_pAnchorMarker->GetPosForHitTest( *(rSh.GetOut()) ); | ||||
4106 | Point aNew = rSh.FindAnchorPos( aDocPt ); | ||||
4107 | SdrHdl* pHdl; | ||||
4108 | if( pSdrView && (nullptr!=( pHdl = pSdrView->PickHandle( aOld ) )|| | ||||
4109 | nullptr !=(pHdl = pSdrView->PickHandle( m_pAnchorMarker->GetHdlPos()) ) ) && | ||||
4110 | ( pHdl->GetKind() == SdrHdlKind::Anchor || | ||||
4111 | pHdl->GetKind() == SdrHdlKind::Anchor_TR ) ) | ||||
4112 | { | ||||
4113 | m_pAnchorMarker->ChgHdl( pHdl ); | ||||
4114 | if( aNew.X() || aNew.Y() ) | ||||
4115 | { | ||||
4116 | m_pAnchorMarker->SetPos( aNew ); | ||||
4117 | m_pAnchorMarker->SetLastPos( aDocPt ); | ||||
4118 | } | ||||
4119 | } | ||||
4120 | else | ||||
4121 | { | ||||
4122 | m_pAnchorMarker.reset(); | ||||
4123 | } | ||||
4124 | } | ||||
4125 | if ( m_bInsDraw ) | ||||
4126 | { | ||||
4127 | if ( !m_bMBPressed ) | ||||
4128 | break; | ||||
4129 | if ( m_bIsInMove || IsMinMove( m_aStartPos, aPixPt ) ) | ||||
4130 | { | ||||
4131 | if ( !bInsWin
| ||||
4132 | LeaveArea( aDocPt ); | ||||
4133 | else | ||||
4134 | EnterArea(); | ||||
4135 | if ( m_rView.GetDrawFuncPtr() ) | ||||
4136 | { | ||||
4137 | pSdrView->SetOrtho(false); | ||||
| |||||
4138 | m_rView.GetDrawFuncPtr()->MouseMove( rMEvt ); | ||||
4139 | } | ||||
4140 | m_bIsInMove = true; | ||||
4141 | } | ||||
4142 | return; | ||||
4143 | } | ||||
4144 | |||||
4145 | { | ||||
4146 | SwWordCountWrapper *pWrdCnt = static_cast<SwWordCountWrapper*>(GetView().GetViewFrame()->GetChildWindow(SwWordCountWrapper::GetChildWindowId())); | ||||
4147 | if (pWrdCnt) | ||||
4148 | pWrdCnt->UpdateCounts(); | ||||
4149 | } | ||||
4150 | [[fallthrough]]; | ||||
4151 | |||||
4152 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_SHIFT: | ||||
4153 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_SHIFT + KEY_MOD1: | ||||
4154 | if ( !m_bMBPressed ) | ||||
4155 | break; | ||||
4156 | [[fallthrough]]; | ||||
4157 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_MOD1: | ||||
4158 | if ( g_bFrameDrag && rSh.IsSelFrameMode() ) | ||||
4159 | { | ||||
4160 | if( !m_bMBPressed ) | ||||
4161 | break; | ||||
4162 | |||||
4163 | if ( m_bIsInMove || IsMinMove( m_aStartPos, aPixPt ) ) | ||||
4164 | { | ||||
4165 | // event processing for resizing | ||||
4166 | if (pSdrView && pSdrView->AreObjectsMarked()) | ||||
4167 | { | ||||
4168 | const Point aSttPt( PixelToLogic( m_aStartPos ) ); | ||||
4169 | |||||
4170 | // can we start? | ||||
4171 | if( SdrHdlKind::User == g_eSdrMoveHdl ) | ||||
4172 | { | ||||
4173 | SdrHdl* pHdl = pSdrView->PickHandle( aSttPt ); | ||||
4174 | g_eSdrMoveHdl = pHdl ? pHdl->GetKind() : SdrHdlKind::Move; | ||||
4175 | } | ||||
4176 | |||||
4177 | const SwFrameFormat *const pFlyFormat(rSh.GetFlyFrameFormat()); | ||||
4178 | const SvxMacro* pMacro = nullptr; | ||||
4179 | |||||
4180 | SvMacroItemId nEvent = SdrHdlKind::Move == g_eSdrMoveHdl | ||||
4181 | ? SvMacroItemId::SwFrmMove | ||||
4182 | : SvMacroItemId::SwFrmResize; | ||||
4183 | |||||
4184 | if (nullptr != pFlyFormat) | ||||
4185 | pMacro = pFlyFormat->GetMacro().GetMacroTable().Get(nEvent); | ||||
4186 | if (nullptr != pMacro && | ||||
4187 | // or notify only e.g. every 20 Twip? | ||||
4188 | m_aRszMvHdlPt != aDocPt ) | ||||
4189 | { | ||||
4190 | m_aRszMvHdlPt = aDocPt; | ||||
4191 | sal_uInt32 nPos = 0; | ||||
4192 | SbxArrayRef xArgs = new SbxArray; | ||||
4193 | SbxVariableRef xVar = new SbxVariable; | ||||
4194 | xVar->PutString( pFlyFormat->GetName() ); | ||||
4195 | xArgs->Put32( xVar.get(), ++nPos ); | ||||
4196 | |||||
4197 | if( SvMacroItemId::SwFrmResize == nEvent ) | ||||
4198 | { | ||||
4199 | xVar = new SbxVariable; | ||||
4200 | xVar->PutUShort( static_cast< sal_uInt16 >(g_eSdrMoveHdl) ); | ||||
4201 | xArgs->Put32( xVar.get(), ++nPos ); | ||||
4202 | } | ||||
4203 | |||||
4204 | xVar = new SbxVariable; | ||||
4205 | xVar->PutLong( aDocPt.X() - aSttPt.X() ); | ||||
4206 | xArgs->Put32( xVar.get(), ++nPos ); | ||||
4207 | xVar = new SbxVariable; | ||||
4208 | xVar->PutLong( aDocPt.Y() - aSttPt.Y() ); | ||||
4209 | xArgs->Put32( xVar.get(), ++nPos ); | ||||
4210 | |||||
4211 | OUString sRet; | ||||
4212 | |||||
4213 | ReleaseMouse(); | ||||
4214 | |||||
4215 | rSh.ExecMacro( *pMacro, &sRet, xArgs.get() ); | ||||
4216 | |||||
4217 | CaptureMouse(); | ||||
4218 | |||||
4219 | if( !sRet.isEmpty() && sRet.toInt32()!=0 ) | ||||
4220 | return ; | ||||
4221 | } | ||||
4222 | } | ||||
4223 | // event processing for resizing | ||||
4224 | |||||
4225 | if( bIsDocReadOnly ) | ||||
4226 | break; | ||||
4227 | |||||
4228 | bool bResizeKeepRatio = rSh.GetSelectionType() & SelectionType::Graphic || | ||||
4229 | rSh.GetSelectionType() & SelectionType::Media || | ||||
4230 | rSh.GetSelectionType() & SelectionType::Ole; | ||||
4231 | bool bisResize = g_eSdrMoveHdl != SdrHdlKind::Move; | ||||
4232 | |||||
4233 | if (pSdrView) | ||||
4234 | { | ||||
4235 | // Resize proportionally when media is selected and the user drags on a corner | ||||
4236 | const Point aSttPt(PixelToLogic(m_aStartPos)); | ||||
4237 | SdrHdl* pHdl = pSdrView->PickHandle(aSttPt); | ||||
4238 | if (pHdl) | ||||
4239 | bResizeKeepRatio = bResizeKeepRatio && pHdl->IsCornerHdl(); | ||||
4240 | |||||
4241 | if (pSdrView->GetDragMode() == SdrDragMode::Crop) | ||||
4242 | bisResize = false; | ||||
4243 | if (rMEvt.IsShift()) | ||||
4244 | { | ||||
4245 | pSdrView->SetAngleSnapEnabled(!bResizeKeepRatio); | ||||
4246 | if (bisResize) | ||||
4247 | pSdrView->SetOrtho(!bResizeKeepRatio); | ||||
4248 | else | ||||
4249 | pSdrView->SetOrtho(true); | ||||
4250 | } | ||||
4251 | else | ||||
4252 | { | ||||
4253 | pSdrView->SetAngleSnapEnabled(bResizeKeepRatio); | ||||
4254 | if (bisResize) | ||||
4255 | pSdrView->SetOrtho(bResizeKeepRatio); | ||||
4256 | else | ||||
4257 | pSdrView->SetOrtho(false); | ||||
4258 | } | ||||
4259 | } | ||||
4260 | |||||
4261 | rSh.Drag( &aDocPt, rMEvt.IsShift() ); | ||||
4262 | m_bIsInMove = true; | ||||
4263 | } | ||||
4264 | else if( bIsDocReadOnly ) | ||||
4265 | break; | ||||
4266 | |||||
4267 | if ( !bInsWin ) | ||||
4268 | { | ||||
4269 | Point aTmp( aDocPt ); | ||||
4270 | aTmp += rSh.VisArea().Pos() - aOldPt; | ||||
4271 | LeaveArea( aTmp ); | ||||
4272 | } | ||||
4273 | else if(m_bIsInMove) | ||||
4274 | EnterArea(); | ||||
4275 | return; | ||||
4276 | } | ||||
4277 | if ( !rSh.IsSelFrameMode() && !g_bDDINetAttr && | ||||
4278 | (IsMinMove( m_aStartPos,aPixPt ) || m_bIsInMove) && | ||||
4279 | (rSh.IsInSelect() || !rSh.TestCurrPam( aDocPt )) ) | ||||
4280 | { | ||||
4281 | if ( pSdrView ) | ||||
4282 | { | ||||
4283 | if ( rMEvt.IsShift() ) | ||||
4284 | pSdrView->SetOrtho(true); | ||||
4285 | else | ||||
4286 | pSdrView->SetOrtho(false); | ||||
4287 | } | ||||
4288 | if ( !bInsWin ) | ||||
4289 | { | ||||
4290 | Point aTmp( aDocPt ); | ||||
4291 | aTmp += rSh.VisArea().Pos() - aOldPt; | ||||
4292 | LeaveArea( aTmp ); | ||||
4293 | } | ||||
4294 | else | ||||
4295 | { | ||||
4296 | if( !rMEvt.IsSynthetic() && | ||||
4297 | ( MOUSE_LEFT(sal_uInt16(0x0001)) != rMEvt.GetButtons() || | ||||
4298 | KEY_MOD1 != rMEvt.GetModifier() || | ||||
4299 | !rSh.Is_FnDragEQBeginDrag() || | ||||
4300 | rSh.IsAddMode() ) ) | ||||
4301 | { | ||||
4302 | rSh.Drag( &aDocPt, false ); | ||||
4303 | |||||
4304 | g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPt, false)); | ||||
4305 | EnterArea(); | ||||
4306 | } | ||||
4307 | } | ||||
4308 | } | ||||
4309 | g_bDDINetAttr = false; | ||||
4310 | break; | ||||
4311 | case 0: | ||||
4312 | { | ||||
4313 | if ( m_pApplyTempl ) | ||||
4314 | { | ||||
4315 | UpdatePointer(aDocPt); // maybe a frame has to be marked here | ||||
4316 | break; | ||||
4317 | } | ||||
4318 | // change ui if mouse is over SwPostItField | ||||
4319 | // TODO: do the same thing for redlines IsAttrAtPos::Redline | ||||
4320 | SwContentAtPos aContentAtPos( IsAttrAtPos::Field); | ||||
4321 | if (rSh.GetContentAtPos(aDocPt, aContentAtPos, false)) | ||||
4322 | { | ||||
4323 | const SwField* pField = aContentAtPos.aFnd.pField; | ||||
4324 | if (pField->Which()== SwFieldIds::Postit) | ||||
4325 | { | ||||
4326 | m_rView.GetPostItMgr()->SetShadowState(reinterpret_cast<const SwPostItField*>(pField),false); | ||||
4327 | } | ||||
4328 | else | ||||
4329 | m_rView.GetPostItMgr()->SetShadowState(nullptr,false); | ||||
4330 | } | ||||
4331 | else | ||||
4332 | m_rView.GetPostItMgr()->SetShadowState(nullptr,false); | ||||
4333 | [[fallthrough]]; | ||||
4334 | } | ||||
4335 | case KEY_SHIFT: | ||||
4336 | case KEY_MOD2: | ||||
4337 | case KEY_MOD1: | ||||
4338 | if ( !m_bInsDraw ) | ||||
4339 | { | ||||
4340 | bool bTstShdwCursor = true; | ||||
4341 | |||||
4342 | UpdatePointer( aDocPt, rMEvt.GetModifier() ); | ||||
4343 | |||||
4344 | const SwFrameFormat* pFormat = nullptr; | ||||
4345 | const SwFormatINetFormat* pINet = nullptr; | ||||
4346 | SwContentAtPos aContentAtPos( IsAttrAtPos::InetAttr ); | ||||
4347 | if( rSh.GetContentAtPos( aDocPt, aContentAtPos ) ) | ||||
4348 | pINet = static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr); | ||||
4349 | |||||
4350 | const void* pTmp = pINet; | ||||
4351 | |||||
4352 | if( pINet || | ||||
4353 | nullptr != ( pTmp = pFormat = rSh.GetFormatFromAnyObj( aDocPt ))) | ||||
4354 | { | ||||
4355 | bTstShdwCursor = false; | ||||
4356 | if( pTmp == pINet ) | ||||
4357 | m_aSaveCallEvent.Set( pINet ); | ||||
4358 | else | ||||
4359 | { | ||||
4360 | IMapObject* pIMapObj = pFormat->GetIMapObject( aDocPt ); | ||||
4361 | if( pIMapObj ) | ||||
4362 | m_aSaveCallEvent.Set( pFormat, pIMapObj ); | ||||
4363 | else | ||||
4364 | m_aSaveCallEvent.Set( EVENT_OBJECT_URLITEM, pFormat ); | ||||
4365 | } | ||||
4366 | |||||
4367 | // should be over an InternetField with an | ||||
4368 | // embedded macro? | ||||
4369 | if( m_aSaveCallEvent != aLastCallEvent ) | ||||
4370 | { | ||||
4371 | if( aLastCallEvent.HasEvent() ) | ||||
4372 | rSh.CallEvent( SvMacroItemId::OnMouseOut, | ||||
4373 | aLastCallEvent, true ); | ||||
4374 | // 0 says that the object doesn't have any table | ||||
4375 | if( !rSh.CallEvent( SvMacroItemId::OnMouseOver, | ||||
4376 | m_aSaveCallEvent )) | ||||
4377 | m_aSaveCallEvent.Clear(); | ||||
4378 | } | ||||
4379 | } | ||||
4380 | else if( aLastCallEvent.HasEvent() ) | ||||
4381 | { | ||||
4382 | // cursor was on an object | ||||
4383 | rSh.CallEvent( SvMacroItemId::OnMouseOut, | ||||
4384 | aLastCallEvent, true ); | ||||
4385 | } | ||||
4386 | |||||
4387 | if( bTstShdwCursor && bInsWin && !bIsDocReadOnly && | ||||
4388 | !m_bInsFrame && | ||||
4389 | !rSh.GetViewOptions()->getBrowseMode() && | ||||
4390 | rSh.GetViewOptions()->IsShadowCursor() && | ||||
4391 | !(rMEvt.GetModifier() + rMEvt.GetButtons()) && | ||||
4392 | !rSh.HasSelection() && !GetConnectMetaFile() ) | ||||
4393 | { | ||||
4394 | SwRect aRect; | ||||
4395 | sal_Int16 eOrient; | ||||
4396 | SwFillMode eMode = rSh.GetViewOptions()->GetShdwCursorFillMode(); | ||||
4397 | if( rSh.GetShadowCursorPos( aDocPt, eMode, aRect, eOrient )) | ||||
4398 | { | ||||
4399 | if( !m_pShadCursor ) | ||||
4400 | m_pShadCursor.reset( new SwShadowCursor( *this, | ||||
4401 | SwViewOption::GetDirectCursorColor() ) ); | ||||
4402 | if( text::HoriOrientation::RIGHT != eOrient && text::HoriOrientation::CENTER != eOrient ) | ||||
4403 | eOrient = text::HoriOrientation::LEFT; | ||||
4404 | m_pShadCursor->SetPos( aRect.Pos(), aRect.Height(), static_cast< sal_uInt16 >(eOrient) ); | ||||
4405 | bDelShadCursor = false; | ||||
4406 | } | ||||
4407 | } | ||||
4408 | } | ||||
4409 | break; | ||||
4410 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_MOD2: | ||||
4411 | if( rSh.IsBlockMode() && !rMEvt.IsSynthetic() ) | ||||
4412 | { | ||||
4413 | rSh.Drag( &aDocPt, false ); | ||||
4414 | g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPt, false)); | ||||
4415 | EnterArea(); | ||||
4416 | } | ||||
4417 | break; | ||||
4418 | } | ||||
4419 | |||||
4420 | if( bDelShadCursor && m_pShadCursor ) | ||||
4421 | { | ||||
4422 | m_pShadCursor.reset(); | ||||
4423 | } | ||||
4424 | m_bWasShdwCursor = false; | ||||
4425 | } | ||||
4426 | |||||
4427 | /** | ||||
4428 | * Button Up | ||||
4429 | */ | ||||
4430 | void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt) | ||||
4431 | { | ||||
4432 | if (comphelper::LibreOfficeKit::isActive()) | ||||
4433 | { | ||||
4434 | if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel())) | ||||
4435 | { | ||||
4436 | pWindow->MouseButtonUp(rMEvt); | ||||
4437 | return; | ||||
4438 | } | ||||
4439 | } | ||||
4440 | |||||
4441 | bool bCallBase = true; | ||||
4442 | |||||
4443 | bool bCallShadowCursor = m_bWasShdwCursor; | ||||
4444 | m_bWasShdwCursor = false; | ||||
4445 | if( m_pShadCursor ) | ||||
4446 | { | ||||
4447 | m_pShadCursor.reset(); | ||||
4448 | } | ||||
4449 | |||||
4450 | m_xRowColumnSelectionStart.reset(); | ||||
4451 | |||||
4452 | SdrHdlKind eOldSdrMoveHdl = g_eSdrMoveHdl; | ||||
4453 | g_eSdrMoveHdl = SdrHdlKind::User; // for MoveEvents - reset again | ||||
4454 | |||||
4455 | // preventively reset | ||||
4456 | m_rView.SetTabColFromDoc( false ); | ||||
4457 | m_rView.SetNumRuleNodeFromDoc(nullptr); | ||||
4458 | |||||
4459 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
4460 | CurrShell aCurr( &rSh ); | ||||
4461 | SdrView *pSdrView = rSh.GetDrawView(); | ||||
4462 | if ( pSdrView ) | ||||
4463 | { | ||||
4464 | // tdf34555: ortho was always reset before being used in EndSdrDrag | ||||
4465 | // Now, it is reset only if not in Crop mode. | ||||
4466 | if (pSdrView->GetDragMode() != SdrDragMode::Crop && !rMEvt.IsShift()) | ||||
4467 | pSdrView->SetOrtho(false); | ||||
4468 | |||||
4469 | if ( pSdrView->MouseButtonUp( rMEvt,this ) ) | ||||
4470 | { | ||||
4471 | rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll(false); | ||||
4472 | return; // SdrView's event evaluated | ||||
4473 | } | ||||
4474 | } | ||||
4475 | // only process MouseButtonUp when the Down went to that windows as well. | ||||
4476 | if ( !m_bMBPressed ) | ||||
4477 | { | ||||
4478 | // Undo for the watering can is already in CommandHdl | ||||
4479 | // that's the way it should be! | ||||
4480 | |||||
4481 | return; | ||||
4482 | } | ||||
4483 | |||||
4484 | Point aDocPt( PixelToLogic( rMEvt.GetPosPixel() ) ); | ||||
4485 | |||||
4486 | if ( g_bDDTimerStarted ) | ||||
4487 | { | ||||
4488 | StopDDTimer( &rSh, aDocPt ); | ||||
4489 | m_bMBPressed = false; | ||||
4490 | if ( rSh.IsSelFrameMode() ) | ||||
4491 | { | ||||
4492 | rSh.EndDrag( &aDocPt, false ); | ||||
4493 | g_bFrameDrag = false; | ||||
4494 | } | ||||
4495 | g_bNoInterrupt = false; | ||||
4496 | const Point aDocPos( PixelToLogic( rMEvt.GetPosPixel() ) ); | ||||
4497 | if ((PixelToLogic(m_aStartPos).Y() == (aDocPos.Y())) && (PixelToLogic(m_aStartPos).X() == (aDocPos.X())))//To make sure it was not moved | ||||
4498 | { | ||||
4499 | SdrPageView* pPV = nullptr; | ||||
4500 | SdrObject* pObj = pSdrView ? pSdrView->PickObj(aDocPos, pSdrView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER) : nullptr; | ||||
4501 | if (pObj) | ||||
4502 | { | ||||
4503 | SwFrameFormat* pFormat = GetUserCall(pObj)->GetFormat(); | ||||
4504 | SwFrameFormat* pShapeFormat = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT); | ||||
4505 | if (!pShapeFormat) | ||||
4506 | { | ||||
4507 | pSdrView->UnmarkAllObj(); | ||||
4508 | pSdrView->MarkObj(pObj,pPV); | ||||
4509 | } | ||||
4510 | else | ||||
4511 | { | ||||
4512 | // If the fly frame is a textbox of a shape, then select the shape instead. | ||||
4513 | SdrObject* pShape = pShapeFormat->FindSdrObject(); | ||||
4514 | pSdrView->UnmarkAllObj(); | ||||
4515 | pSdrView->MarkObj(pShape, pPV); | ||||
4516 | } | ||||
4517 | } | ||||
4518 | } | ||||
4519 | ReleaseMouse(); | ||||
4520 | return; | ||||
4521 | } | ||||
4522 | |||||
4523 | if( m_pAnchorMarker ) | ||||
4524 | { | ||||
4525 | if(m_pAnchorMarker->GetHdl()) | ||||
4526 | { | ||||
4527 | // #i121463# delete selected after drag | ||||
4528 | m_pAnchorMarker->GetHdl()->SetSelected(false); | ||||
4529 | } | ||||
4530 | |||||
4531 | Point aPnt( m_pAnchorMarker->GetLastPos() ); | ||||
4532 | m_pAnchorMarker.reset(); | ||||
4533 | if( aPnt.X() || aPnt.Y() ) | ||||
4534 | rSh.FindAnchorPos( aPnt, true ); | ||||
4535 | } | ||||
4536 | if ( m_bInsDraw && m_rView.GetDrawFuncPtr() ) | ||||
4537 | { | ||||
4538 | if ( m_rView.GetDrawFuncPtr()->MouseButtonUp( rMEvt ) ) | ||||
4539 | { | ||||
4540 | if (m_rView.GetDrawFuncPtr()) // could have been destroyed in MouseButtonUp | ||||
4541 | { | ||||
4542 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
4543 | |||||
4544 | if (!m_rView.IsDrawMode()) | ||||
4545 | { | ||||
4546 | m_rView.SetDrawFuncPtr(nullptr); | ||||
4547 | SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings(); | ||||
4548 | rBind.Invalidate( SID_ATTR_SIZETypedWhichId<SvxSizeItem>( 10000 + 224 ) ); | ||||
4549 | rBind.Invalidate( SID_TABLE_CELL( 10000 + 225 ) ); | ||||
4550 | } | ||||
4551 | } | ||||
4552 | |||||
4553 | if ( rSh.IsObjSelected() ) | ||||
4554 | { | ||||
4555 | rSh.EnterSelFrameMode(); | ||||
4556 | if (!m_rView.GetDrawFuncPtr()) | ||||
4557 | StdDrawMode( OBJ_NONE, true ); | ||||
4558 | } | ||||
4559 | else if ( rSh.IsFrameSelected() ) | ||||
4560 | { | ||||
4561 | rSh.EnterSelFrameMode(); | ||||
4562 | StopInsFrame(); | ||||
4563 | } | ||||
4564 | else | ||||
4565 | { | ||||
4566 | const Point aDocPos( PixelToLogic( m_aStartPos ) ); | ||||
4567 | g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false)); | ||||
4568 | rSh.Edit(); | ||||
4569 | } | ||||
4570 | |||||
4571 | m_rView.AttrChangedNotify(nullptr); | ||||
4572 | } | ||||
4573 | else if (rMEvt.GetButtons() == MOUSE_RIGHT(sal_uInt16(0x0004)) && rSh.IsDrawCreate()) | ||||
4574 | m_rView.GetDrawFuncPtr()->BreakCreate(); // abort drawing | ||||
4575 | |||||
4576 | g_bNoInterrupt = false; | ||||
4577 | if (IsMouseCaptured()) | ||||
4578 | ReleaseMouse(); | ||||
4579 | return; | ||||
4580 | } | ||||
4581 | bool bPopMode = false; | ||||
4582 | switch ( rMEvt.GetModifier() + rMEvt.GetButtons() ) | ||||
4583 | { | ||||
4584 | case MOUSE_LEFT(sal_uInt16(0x0001)): | ||||
4585 | if ( m_bInsDraw && rSh.IsDrawCreate() ) | ||||
4586 | { | ||||
4587 | if ( m_rView.GetDrawFuncPtr() && m_rView.GetDrawFuncPtr()->MouseButtonUp(rMEvt) ) | ||||
4588 | { | ||||
4589 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
4590 | m_rView.AttrChangedNotify(nullptr); | ||||
4591 | if ( rSh.IsObjSelected() ) | ||||
4592 | rSh.EnterSelFrameMode(); | ||||
4593 | if ( m_rView.GetDrawFuncPtr() && m_bInsFrame ) | ||||
4594 | StopInsFrame(); | ||||
4595 | } | ||||
4596 | bCallBase = false; | ||||
4597 | break; | ||||
4598 | } | ||||
4599 | [[fallthrough]]; | ||||
4600 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_MOD1: | ||||
4601 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_MOD2: | ||||
4602 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_SHIFT + KEY_MOD1: | ||||
4603 | if ( g_bFrameDrag && rSh.IsSelFrameMode() ) | ||||
4604 | { | ||||
4605 | if ( rMEvt.IsMod1() ) // copy and don't move. | ||||
4606 | { | ||||
4607 | // abort drag, use internal Copy instead | ||||
4608 | tools::Rectangle aRect; | ||||
4609 | rSh.GetDrawView()->TakeActionRect( aRect ); | ||||
4610 | if (!aRect.IsEmpty()) | ||||
4611 | { | ||||
4612 | rSh.BreakDrag(); | ||||
4613 | Point aEndPt, aSttPt; | ||||
4614 | if ( rSh.GetSelFrameType() & FrameTypeFlags::FLY_ATCNT ) | ||||
4615 | { | ||||
4616 | aEndPt = aRect.TopLeft(); | ||||
4617 | aSttPt = rSh.GetDrawView()->GetAllMarkedRect().TopLeft(); | ||||
4618 | } | ||||
4619 | else | ||||
4620 | { | ||||
4621 | aEndPt = aRect.Center(); | ||||
4622 | aSttPt = rSh.GetDrawView()->GetAllMarkedRect().Center(); | ||||
4623 | } | ||||
4624 | if ( aSttPt != aEndPt ) | ||||
4625 | { | ||||
4626 | rSh.StartUndo( SwUndoId::UI_DRAG_AND_COPY ); | ||||
4627 | rSh.Copy(rSh, aSttPt, aEndPt); | ||||
4628 | rSh.EndUndo( SwUndoId::UI_DRAG_AND_COPY ); | ||||
4629 | } | ||||
4630 | } | ||||
4631 | else { | ||||
4632 | rSh.EndDrag( &aDocPt, false ); | ||||
4633 | } | ||||
4634 | } | ||||
4635 | else | ||||
4636 | { | ||||
4637 | { | ||||
4638 | const SwFrameFormat *const pFlyFormat(rSh.GetFlyFrameFormat()); | ||||
4639 | const SvxMacro* pMacro = nullptr; | ||||
4640 | |||||
4641 | SvMacroItemId nEvent = SdrHdlKind::Move == eOldSdrMoveHdl | ||||
4642 | ? SvMacroItemId::SwFrmMove | ||||
4643 | : SvMacroItemId::SwFrmResize; | ||||
4644 | |||||
4645 | if (nullptr != pFlyFormat) | ||||
4646 | pMacro = pFlyFormat->GetMacro().GetMacroTable().Get(nEvent); | ||||
4647 | if (nullptr != pMacro) | ||||
4648 | { | ||||
4649 | const Point aSttPt( PixelToLogic( m_aStartPos ) ); | ||||
4650 | m_aRszMvHdlPt = aDocPt; | ||||
4651 | sal_uInt32 nPos = 0; | ||||
4652 | SbxArrayRef xArgs = new SbxArray; | ||||
4653 | SbxVariableRef xVar = new SbxVariable; | ||||
4654 | xVar->PutString( pFlyFormat->GetName() ); | ||||
4655 | xArgs->Put32( xVar.get(), ++nPos ); | ||||
4656 | |||||
4657 | if( SvMacroItemId::SwFrmResize == nEvent ) | ||||
4658 | { | ||||
4659 | xVar = new SbxVariable; | ||||
4660 | xVar->PutUShort( static_cast< sal_uInt16 >(eOldSdrMoveHdl) ); | ||||
4661 | xArgs->Put32( xVar.get(), ++nPos ); | ||||
4662 | } | ||||
4663 | |||||
4664 | xVar = new SbxVariable; | ||||
4665 | xVar->PutLong( aDocPt.X() - aSttPt.X() ); | ||||
4666 | xArgs->Put32( xVar.get(), ++nPos ); | ||||
4667 | xVar = new SbxVariable; | ||||
4668 | xVar->PutLong( aDocPt.Y() - aSttPt.Y() ); | ||||
4669 | xArgs->Put32( xVar.get(), ++nPos ); | ||||
4670 | |||||
4671 | xVar = new SbxVariable; | ||||
4672 | xVar->PutUShort( 1 ); | ||||
4673 | xArgs->Put32( xVar.get(), ++nPos ); | ||||
4674 | |||||
4675 | ReleaseMouse(); | ||||
4676 | |||||
4677 | rSh.ExecMacro( *pMacro, nullptr, xArgs.get() ); | ||||
4678 | |||||
4679 | CaptureMouse(); | ||||
4680 | } | ||||
4681 | } | ||||
4682 | rSh.EndDrag( &aDocPt, false ); | ||||
4683 | } | ||||
4684 | g_bFrameDrag = false; | ||||
4685 | bCallBase = false; | ||||
4686 | break; | ||||
4687 | } | ||||
4688 | bPopMode = true; | ||||
4689 | [[fallthrough]]; | ||||
4690 | case MOUSE_LEFT(sal_uInt16(0x0001)) + KEY_SHIFT: | ||||
4691 | if (rSh.IsSelFrameMode()) | ||||
4692 | { | ||||
4693 | |||||
4694 | rSh.EndDrag( &aDocPt, false ); | ||||
4695 | g_bFrameDrag = false; | ||||
4696 | bCallBase = false; | ||||
4697 | break; | ||||
4698 | } | ||||
4699 | |||||
4700 | if( g_bHoldSelection ) | ||||
4701 | { | ||||
4702 | // the EndDrag should be called in any case | ||||
4703 | g_bHoldSelection = false; | ||||
4704 | rSh.EndDrag( &aDocPt, false ); | ||||
4705 | } | ||||
4706 | else | ||||
4707 | { | ||||
4708 | SwContentAtPos aFieldAtPos ( IsAttrAtPos::Field ); | ||||
4709 | if ( !rSh.IsInSelect() && rSh.TestCurrPam( aDocPt ) && | ||||
4710 | !rSh.GetContentAtPos( aDocPt, aFieldAtPos ) ) | ||||
4711 | { | ||||
4712 | const bool bTmpNoInterrupt = g_bNoInterrupt; | ||||
4713 | g_bNoInterrupt = false; | ||||
4714 | { // create only temporary move context because otherwise | ||||
4715 | // the query to the content form doesn't work!!! | ||||
4716 | SwMvContext aMvContext( &rSh ); | ||||
4717 | const Point aDocPos( PixelToLogic( m_aStartPos ) ); | ||||
4718 | g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false)); | ||||
4719 | } | ||||
4720 | g_bNoInterrupt = bTmpNoInterrupt; | ||||
4721 | |||||
4722 | } | ||||
4723 | else | ||||
4724 | { | ||||
4725 | bool bInSel = rSh.IsInSelect(); | ||||
4726 | rSh.EndDrag( &aDocPt, false ); | ||||
4727 | |||||
4728 | // Internetfield? --> call link (load doc!!) | ||||
4729 | if( !bInSel ) | ||||
4730 | { | ||||
4731 | LoadUrlFlags nFilter = LoadUrlFlags::NONE; | ||||
4732 | if( KEY_MOD1 == rMEvt.GetModifier() ) | ||||
4733 | nFilter |= LoadUrlFlags::NewView; | ||||
4734 | |||||
4735 | bool bExecHyperlinks = m_rView.GetDocShell()->IsReadOnly(); | ||||
4736 | if ( !bExecHyperlinks ) | ||||
4737 | { | ||||
4738 | SvtSecurityOptions aSecOpts; | ||||
4739 | const bool bSecureOption = aSecOpts.IsOptionSet( SvtSecurityOptions::EOption::CtrlClickHyperlink ); | ||||
4740 | if ( ( bSecureOption && rMEvt.GetModifier() == KEY_MOD1 ) || | ||||
4741 | ( !bSecureOption && rMEvt.GetModifier() != KEY_MOD1 ) ) | ||||
4742 | bExecHyperlinks = true; | ||||
4743 | } | ||||
4744 | |||||
4745 | const bool bExecSmarttags = rMEvt.GetModifier() == KEY_MOD1; | ||||
4746 | |||||
4747 | if(m_pApplyTempl) | ||||
4748 | bExecHyperlinks = false; | ||||
4749 | |||||
4750 | SwContentAtPos aContentAtPos( IsAttrAtPos::Field | | ||||
4751 | IsAttrAtPos::InetAttr | | ||||
4752 | IsAttrAtPos::SmartTag | IsAttrAtPos::FormControl); | ||||
4753 | |||||
4754 | if( rSh.GetContentAtPos( aDocPt, aContentAtPos ) ) | ||||
4755 | { | ||||
4756 | // Do it again if we're not on a field/hyperlink to update the cursor accordingly | ||||
4757 | if ( IsAttrAtPos::Field != aContentAtPos.eContentAtPos | ||||
4758 | && IsAttrAtPos::InetAttr != aContentAtPos.eContentAtPos ) | ||||
4759 | rSh.GetContentAtPos( aDocPt, aContentAtPos, true ); | ||||
4760 | |||||
4761 | bool bViewLocked = rSh.IsViewLocked(); | ||||
4762 | if( !bViewLocked && !rSh.IsReadOnlyAvailable() && | ||||
4763 | aContentAtPos.IsInProtectSect() ) | ||||
4764 | rSh.LockView( true ); | ||||
4765 | |||||
4766 | ReleaseMouse(); | ||||
4767 | |||||
4768 | if( IsAttrAtPos::Field == aContentAtPos.eContentAtPos ) | ||||
4769 | { | ||||
4770 | bool bAddMode(false); | ||||
4771 | // AdditionalMode if applicable | ||||
4772 | if (KEY_MOD1 == rMEvt.GetModifier() | ||||
4773 | && !rSh.IsAddMode()) | ||||
4774 | { | ||||
4775 | bAddMode = true; | ||||
4776 | rSh.EnterAddMode(); | ||||
4777 | } | ||||
4778 | if ( aContentAtPos.pFndTextAttr != nullptr | ||||
4779 | && aContentAtPos.pFndTextAttr->Which() == RES_TXTATR_INPUTFIELD ) | ||||
4780 | { | ||||
4781 | if (!rSh.IsInSelect()) | ||||
4782 | { | ||||
4783 | // create only temporary move context because otherwise | ||||
4784 | // the query to the content form doesn't work!!! | ||||
4785 | SwMvContext aMvContext( &rSh ); | ||||
4786 | const Point aDocPos( PixelToLogic( m_aStartPos ) ); | ||||
4787 | g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false)); | ||||
4788 | } | ||||
4789 | else | ||||
4790 | { | ||||
4791 | g_bValidCursorPos = true; | ||||
4792 | } | ||||
4793 | } | ||||
4794 | else | ||||
4795 | { | ||||
4796 | rSh.ClickToField( *aContentAtPos.aFnd.pField ); | ||||
4797 | // a bit of a mystery what this is good for? | ||||
4798 | // in this case we assume it's valid since we | ||||
4799 | // just selected a field | ||||
4800 | g_bValidCursorPos = true; | ||||
4801 | } | ||||
4802 | if (bAddMode) | ||||
4803 | { | ||||
4804 | rSh.LeaveAddMode(); | ||||
4805 | } | ||||
4806 | } | ||||
4807 | else if ( IsAttrAtPos::SmartTag == aContentAtPos.eContentAtPos ) | ||||
4808 | { | ||||
4809 | // execute smarttag menu | ||||
4810 | if ( bExecSmarttags && SwSmartTagMgr::Get().IsSmartTagsEnabled() ) | ||||
4811 | m_rView.ExecSmartTagPopup( aDocPt ); | ||||
4812 | } | ||||
4813 | else if ( IsAttrAtPos::FormControl == aContentAtPos.eContentAtPos ) | ||||
4814 | { | ||||
4815 | OSL_ENSURE( aContentAtPos.aFnd.pFieldmark != nullptr, "where is my field ptr???")do { if (true && (!(aContentAtPos.aFnd.pFieldmark != nullptr ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "4815" ": "), "%s", "where is my field ptr???"); } } while (false); | ||||
4816 | if ( aContentAtPos.aFnd.pFieldmark != nullptr) | ||||
4817 | { | ||||
4818 | IFieldmark *fieldBM = const_cast< IFieldmark* > ( aContentAtPos.aFnd.pFieldmark ); | ||||
4819 | if ( fieldBM->GetFieldname( ) == ODF_FORMCHECKBOX"vnd.oasis.opendocument.field.FORMCHECKBOX" ) | ||||
4820 | { | ||||
4821 | ICheckboxFieldmark& rCheckboxFm = dynamic_cast<ICheckboxFieldmark&>(*fieldBM); | ||||
4822 | rCheckboxFm.SetChecked(!rCheckboxFm.IsChecked()); | ||||
4823 | rCheckboxFm.Invalidate(); | ||||
4824 | rSh.InvalidateWindows( m_rView.GetVisArea() ); | ||||
4825 | } | ||||
4826 | } | ||||
4827 | } | ||||
4828 | else if ( IsAttrAtPos::InetAttr == aContentAtPos.eContentAtPos ) | ||||
4829 | { | ||||
4830 | if (comphelper::LibreOfficeKit::isActive()) | ||||
4831 | { | ||||
4832 | OUString val((*static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr)).GetValue()); | ||||
4833 | if (val.startsWith("#")) | ||||
4834 | bExecHyperlinks = true; | ||||
4835 | } | ||||
4836 | if ( bExecHyperlinks && aContentAtPos.aFnd.pAttr ) | ||||
4837 | rSh.ClickToINetAttr( *static_cast<const SwFormatINetFormat*>(aContentAtPos.aFnd.pAttr), nFilter ); | ||||
4838 | } | ||||
4839 | |||||
4840 | rSh.LockView( bViewLocked ); | ||||
4841 | bCallShadowCursor = false; | ||||
4842 | } | ||||
4843 | else | ||||
4844 | { | ||||
4845 | aContentAtPos = SwContentAtPos( IsAttrAtPos::Ftn ); | ||||
4846 | if( !rSh.GetContentAtPos( aDocPt, aContentAtPos, true ) && bExecHyperlinks ) | ||||
4847 | { | ||||
4848 | SdrViewEvent aVEvt; | ||||
4849 | |||||
4850 | if (pSdrView) | ||||
4851 | pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); | ||||
4852 | |||||
4853 | if (pSdrView && aVEvt.eEvent == SdrEventKind::ExecuteUrl) | ||||
4854 | { | ||||
4855 | // hit URL field | ||||
4856 | const SvxURLField *pField = aVEvt.pURLField; | ||||
4857 | if (pField) | ||||
4858 | { | ||||
4859 | const OUString& sURL(pField->GetURL()); | ||||
4860 | const OUString& sTarget(pField->GetTargetFrame()); | ||||
4861 | ::LoadURL(rSh, sURL, nFilter, sTarget); | ||||
4862 | } | ||||
4863 | bCallShadowCursor = false; | ||||
4864 | } | ||||
4865 | else | ||||
4866 | { | ||||
4867 | // hit graphic | ||||
4868 | ReleaseMouse(); | ||||
4869 | if( rSh.ClickToINetGrf( aDocPt, nFilter )) | ||||
4870 | bCallShadowCursor = false; | ||||
4871 | } | ||||
4872 | } | ||||
4873 | } | ||||
4874 | |||||
4875 | if( bCallShadowCursor && | ||||
4876 | rSh.GetViewOptions()->IsShadowCursor() && | ||||
4877 | MOUSE_LEFT(sal_uInt16(0x0001)) == (rMEvt.GetModifier() + rMEvt.GetButtons()) && | ||||
4878 | !rSh.HasSelection() && | ||||
4879 | !GetConnectMetaFile() && | ||||
4880 | rSh.VisArea().IsInside( aDocPt )) | ||||
4881 | { | ||||
4882 | SwUndoId nLastUndoId(SwUndoId::EMPTY); | ||||
4883 | if (rSh.GetLastUndoInfo(nullptr, & nLastUndoId)) | ||||
4884 | { | ||||
4885 | if (SwUndoId::INS_FROM_SHADOWCRSR == nLastUndoId) | ||||
4886 | { | ||||
4887 | rSh.Undo(); | ||||
4888 | } | ||||
4889 | } | ||||
4890 | SwFillMode eMode = rSh.GetViewOptions()->GetShdwCursorFillMode(); | ||||
4891 | rSh.SetShadowCursorPos( aDocPt, eMode ); | ||||
4892 | } | ||||
4893 | } | ||||
4894 | } | ||||
4895 | bCallBase = false; | ||||
4896 | |||||
4897 | } | ||||
4898 | |||||
4899 | // reset pushed mode in Down again if applicable | ||||
4900 | if ( bPopMode && g_bModePushed ) | ||||
4901 | { | ||||
4902 | rSh.PopMode(); | ||||
4903 | g_bModePushed = false; | ||||
4904 | bCallBase = false; | ||||
4905 | } | ||||
4906 | break; | ||||
4907 | |||||
4908 | default: | ||||
4909 | ReleaseMouse(); | ||||
4910 | return; | ||||
4911 | } | ||||
4912 | |||||
4913 | if( m_pApplyTempl ) | ||||
4914 | { | ||||
4915 | SelectionType eSelection = rSh.GetSelectionType(); | ||||
4916 | SwFormatClipboard* pFormatClipboard = m_pApplyTempl->m_pFormatClipboard; | ||||
4917 | if( pFormatClipboard )//apply format paintbrush | ||||
4918 | { | ||||
4919 | //get some parameters | ||||
4920 | SwWrtShell& rWrtShell = m_rView.GetWrtShell(); | ||||
4921 | SfxStyleSheetBasePool* pPool=nullptr; | ||||
4922 | bool bNoCharacterFormats = false; | ||||
4923 | bool bNoParagraphFormats = true; | ||||
4924 | { | ||||
4925 | SwDocShell* pDocSh = m_rView.GetDocShell(); | ||||
4926 | if(pDocSh) | ||||
4927 | pPool = pDocSh->GetStyleSheetPool(); | ||||
4928 | if( (rMEvt.GetModifier()&KEY_MOD1) && (rMEvt.GetModifier()&KEY_SHIFT) ) | ||||
4929 | { | ||||
4930 | bNoCharacterFormats = true; | ||||
4931 | bNoParagraphFormats = false; | ||||
4932 | } | ||||
4933 | else if( rMEvt.GetModifier() & KEY_MOD1 ) | ||||
4934 | bNoParagraphFormats = false; | ||||
4935 | } | ||||
4936 | //execute paste | ||||
4937 | pFormatClipboard->Paste( rWrtShell, pPool, bNoCharacterFormats, bNoParagraphFormats ); | ||||
4938 | |||||
4939 | //if the clipboard is empty after paste remove the ApplyTemplate | ||||
4940 | if(!pFormatClipboard->HasContent()) | ||||
4941 | SetApplyTemplate(SwApplyTemplate()); | ||||
4942 | |||||
4943 | //tdf#38101 remove temporary highlighting | ||||
4944 | m_pUserMarker.reset(); | ||||
4945 | } | ||||
4946 | else if( m_pApplyTempl->nColor ) | ||||
4947 | { | ||||
4948 | sal_uInt16 nId = 0; | ||||
4949 | switch( m_pApplyTempl->nColor ) | ||||
4950 | { | ||||
4951 | case SID_ATTR_CHAR_COLOR_EXT(10000 + 488): | ||||
4952 | nId = RES_CHRATR_COLOR; | ||||
4953 | break; | ||||
4954 | case SID_ATTR_CHAR_COLOR_BACKGROUND_EXT(10000 + 490): | ||||
4955 | nId = RES_CHRATR_BACKGROUND; | ||||
4956 | break; | ||||
4957 | } | ||||
4958 | if( nId && (SelectionType::Text|SelectionType::Table) & eSelection) | ||||
4959 | { | ||||
4960 | if( rSh.IsSelection() && !rSh.HasReadonlySel() ) | ||||
4961 | { | ||||
4962 | m_pApplyTempl->nUndo = | ||||
4963 | std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount()); | ||||
4964 | if (nId == RES_CHRATR_BACKGROUND) | ||||
4965 | ApplyCharBackground(m_aWaterCanTextBackColor, rSh); | ||||
4966 | else | ||||
4967 | rSh.SetAttrItem( SvxColorItem( m_aWaterCanTextColor, nId ) ); | ||||
4968 | rSh.UnSetVisibleCursor(); | ||||
4969 | rSh.EnterStdMode(); | ||||
4970 | rSh.SetVisibleCursor(aDocPt); | ||||
4971 | bCallBase = false; | ||||
4972 | m_aTemplateTimer.Stop(); | ||||
4973 | } | ||||
4974 | else if(rMEvt.GetClicks() == 1) | ||||
4975 | { | ||||
4976 | // no selection -> so turn off watering can | ||||
4977 | m_aTemplateTimer.Start(); | ||||
4978 | } | ||||
4979 | } | ||||
4980 | } | ||||
4981 | else | ||||
4982 | { | ||||
4983 | OUString aStyleName; | ||||
4984 | switch ( m_pApplyTempl->eType ) | ||||
4985 | { | ||||
4986 | case SfxStyleFamily::Para: | ||||
4987 | if( (( SelectionType::Text | SelectionType::Table ) | ||||
4988 | & eSelection ) && !rSh.HasReadonlySel() ) | ||||
4989 | { | ||||
4990 | rSh.SetTextFormatColl( m_pApplyTempl->aColl.pTextColl ); | ||||
4991 | m_pApplyTempl->nUndo = | ||||
4992 | std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount()); | ||||
4993 | bCallBase = false; | ||||
4994 | if ( m_pApplyTempl->aColl.pTextColl ) | ||||
4995 | aStyleName = m_pApplyTempl->aColl.pTextColl->GetName(); | ||||
4996 | } | ||||
4997 | break; | ||||
4998 | case SfxStyleFamily::Char: | ||||
4999 | if( (( SelectionType::Text | SelectionType::Table ) | ||||
5000 | & eSelection ) && !rSh.HasReadonlySel() ) | ||||
5001 | { | ||||
5002 | rSh.SetAttrItem( SwFormatCharFormat(m_pApplyTempl->aColl.pCharFormat) ); | ||||
5003 | rSh.UnSetVisibleCursor(); | ||||
5004 | rSh.EnterStdMode(); | ||||
5005 | rSh.SetVisibleCursor(aDocPt); | ||||
5006 | m_pApplyTempl->nUndo = | ||||
5007 | std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount()); | ||||
5008 | bCallBase = false; | ||||
5009 | if ( m_pApplyTempl->aColl.pCharFormat ) | ||||
5010 | aStyleName = m_pApplyTempl->aColl.pCharFormat->GetName(); | ||||
5011 | } | ||||
5012 | break; | ||||
5013 | case SfxStyleFamily::Frame : | ||||
5014 | { | ||||
5015 | const SwFrameFormat* pFormat = rSh.GetFormatFromObj( aDocPt ); | ||||
5016 | if(dynamic_cast<const SwFlyFrameFormat*>( pFormat) ) | ||||
5017 | { | ||||
5018 | rSh.SetFrameFormat( m_pApplyTempl->aColl.pFrameFormat, false, &aDocPt ); | ||||
5019 | m_pApplyTempl->nUndo = | ||||
5020 | std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount()); | ||||
5021 | bCallBase = false; | ||||
5022 | if( m_pApplyTempl->aColl.pFrameFormat ) | ||||
5023 | aStyleName = m_pApplyTempl->aColl.pFrameFormat->GetName(); | ||||
5024 | } | ||||
5025 | break; | ||||
5026 | } | ||||
5027 | case SfxStyleFamily::Page: | ||||
5028 | // no Undo with page templates | ||||
5029 | rSh.ChgCurPageDesc( *m_pApplyTempl->aColl.pPageDesc ); | ||||
5030 | if ( m_pApplyTempl->aColl.pPageDesc ) | ||||
5031 | aStyleName = m_pApplyTempl->aColl.pPageDesc->GetName(); | ||||
5032 | m_pApplyTempl->nUndo = | ||||
5033 | std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount()); | ||||
5034 | bCallBase = false; | ||||
5035 | break; | ||||
5036 | case SfxStyleFamily::Pseudo: | ||||
5037 | if( !rSh.HasReadonlySel() ) | ||||
5038 | { | ||||
5039 | rSh.SetCurNumRule( *m_pApplyTempl->aColl.pNumRule, | ||||
5040 | false, | ||||
5041 | m_pApplyTempl->aColl.pNumRule->GetDefaultListId() ); | ||||
5042 | bCallBase = false; | ||||
5043 | m_pApplyTempl->nUndo = | ||||
5044 | std::min(m_pApplyTempl->nUndo, rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount()); | ||||
5045 | if( m_pApplyTempl->aColl.pNumRule ) | ||||
5046 | aStyleName = m_pApplyTempl->aColl.pNumRule->GetName(); | ||||
5047 | } | ||||
5048 | break; | ||||
5049 | default: break; | ||||
5050 | } | ||||
5051 | |||||
5052 | uno::Reference< frame::XDispatchRecorder > xRecorder = | ||||
5053 | m_rView.GetViewFrame()->GetBindings().GetRecorder(); | ||||
5054 | if ( !aStyleName.isEmpty() && xRecorder.is() ) | ||||
5055 | { | ||||
5056 | SfxShell *pSfxShell = lcl_GetTextShellFromDispatcher( m_rView ); | ||||
5057 | if ( pSfxShell ) | ||||
5058 | { | ||||
5059 | SfxRequest aReq( m_rView.GetViewFrame(), SID_STYLE_APPLY(5000 + 552) ); | ||||
5060 | aReq.AppendItem( SfxStringItem( SID_STYLE_APPLY(5000 + 552), aStyleName ) ); | ||||
5061 | aReq.AppendItem( SfxUInt16Item( SID_STYLE_FAMILYTypedWhichId<SfxUInt16Item>(5000 + 553), static_cast<sal_uInt16>(m_pApplyTempl->eType) ) ); | ||||
5062 | aReq.Done(); | ||||
5063 | } | ||||
5064 | } | ||||
5065 | } | ||||
5066 | |||||
5067 | } | ||||
5068 | ReleaseMouse(); | ||||
5069 | // Only processed MouseEvents arrive here; only at these this mode can | ||||
5070 | // be reset. | ||||
5071 | m_bMBPressed = false; | ||||
5072 | |||||
5073 | // Make this call just to be sure. Selecting has finished surely by now. | ||||
5074 | // Otherwise the timeout's timer could give problems. | ||||
5075 | EnterArea(); | ||||
5076 | g_bNoInterrupt = false; | ||||
5077 | |||||
5078 | if (bCallBase) | ||||
5079 | Window::MouseButtonUp(rMEvt); | ||||
5080 | |||||
5081 | if (!(pSdrView && rMEvt.GetClicks() == 1 && comphelper::LibreOfficeKit::isActive())) | ||||
5082 | return; | ||||
5083 | |||||
5084 | // When tiled rendering, single click on a shape text starts editing already. | ||||
5085 | SdrViewEvent aViewEvent; | ||||
5086 | SdrHitKind eHit = pSdrView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONUP, aViewEvent); | ||||
5087 | const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList(); | ||||
5088 | if (eHit == SdrHitKind::TextEditObj && rMarkList.GetMarkCount() == 1) | ||||
5089 | { | ||||
5090 | if (SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj()) | ||||
5091 | { | ||||
5092 | EnterDrawTextMode(pObj->GetLogicRect().Center()); | ||||
5093 | if ( dynamic_cast< const SwDrawTextShell *>( m_rView.GetCurShell() ) != nullptr ) | ||||
5094 | static_cast<SwDrawTextShell*>(m_rView.GetCurShell())->Init(); | ||||
5095 | } | ||||
5096 | } | ||||
5097 | } | ||||
5098 | |||||
5099 | /** | ||||
5100 | * Apply template | ||||
5101 | */ | ||||
5102 | void SwEditWin::SetApplyTemplate(const SwApplyTemplate &rTempl) | ||||
5103 | { | ||||
5104 | static bool bIdle = false; | ||||
5105 | m_pApplyTempl.reset(); | ||||
5106 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
5107 | |||||
5108 | if(rTempl.m_pFormatClipboard) | ||||
5109 | { | ||||
5110 | m_pApplyTempl.reset(new SwApplyTemplate( rTempl )); | ||||
5111 | m_pApplyTempl->nUndo = rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount(); | ||||
5112 | SetPointer( PointerStyle::Fill );//@todo #i20119# maybe better a new brush pointer here in future | ||||
5113 | rSh.NoEdit( false ); | ||||
5114 | bIdle = rSh.GetViewOptions()->IsIdle(); | ||||
5115 | rSh.GetViewOptions()->SetIdle( false ); | ||||
5116 | } | ||||
5117 | else if(rTempl.nColor) | ||||
5118 | { | ||||
5119 | m_pApplyTempl.reset(new SwApplyTemplate( rTempl )); | ||||
5120 | m_pApplyTempl->nUndo = rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount(); | ||||
5121 | SetPointer( PointerStyle::Fill ); | ||||
5122 | rSh.NoEdit( false ); | ||||
5123 | bIdle = rSh.GetViewOptions()->IsIdle(); | ||||
5124 | rSh.GetViewOptions()->SetIdle( false ); | ||||
5125 | } | ||||
5126 | else if( rTempl.eType != SfxStyleFamily::None ) | ||||
5127 | { | ||||
5128 | m_pApplyTempl.reset(new SwApplyTemplate( rTempl )); | ||||
5129 | m_pApplyTempl->nUndo = rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount(); | ||||
5130 | SetPointer( PointerStyle::Fill ); | ||||
5131 | rSh.NoEdit( false ); | ||||
5132 | bIdle = rSh.GetViewOptions()->IsIdle(); | ||||
5133 | rSh.GetViewOptions()->SetIdle( false ); | ||||
5134 | } | ||||
5135 | else | ||||
5136 | { | ||||
5137 | SetPointer( PointerStyle::Text ); | ||||
5138 | rSh.UnSetVisibleCursor(); | ||||
5139 | |||||
5140 | rSh.GetViewOptions()->SetIdle( bIdle ); | ||||
5141 | if ( !rSh.IsSelFrameMode() ) | ||||
5142 | rSh.Edit(); | ||||
5143 | } | ||||
5144 | |||||
5145 | static sal_uInt16 aInva[] = | ||||
5146 | { | ||||
5147 | SID_STYLE_WATERCAN(5000 + 554), | ||||
5148 | SID_ATTR_CHAR_COLOR_EXT(10000 + 488), | ||||
5149 | SID_ATTR_CHAR_COLOR_BACKGROUND_EXT(10000 + 490), | ||||
5150 | 0 | ||||
5151 | }; | ||||
5152 | m_rView.GetViewFrame()->GetBindings().Invalidate(aInva); | ||||
5153 | } | ||||
5154 | |||||
5155 | /** | ||||
5156 | * Ctor | ||||
5157 | */ | ||||
5158 | SwEditWin::SwEditWin(vcl::Window *pParent, SwView &rMyView): | ||||
5159 | Window(pParent, WinBits(WB_CLIPCHILDREN | WB_DIALOGCONTROL)), | ||||
5160 | DropTargetHelper( this ), | ||||
5161 | DragSourceHelper( this ), | ||||
5162 | |||||
5163 | m_eBufferLanguage(LANGUAGE_DONTKNOWLanguageType(0x03FF)), | ||||
5164 | m_pUserMarkerObj( nullptr ), | ||||
5165 | |||||
5166 | m_rView( rMyView ), | ||||
5167 | |||||
5168 | m_aActHitType(SdrHitKind::NONE), | ||||
5169 | m_nDropFormat( SotClipboardFormatId::NONE ), | ||||
5170 | m_nDropAction( 0 ), | ||||
5171 | m_nDropDestination( SotExchangeDest::NONE ), | ||||
5172 | |||||
5173 | m_eBezierMode(SID_BEZIER_INSERT( 10000 + 119 )), | ||||
5174 | m_nInsFrameColCount( 1 ), | ||||
5175 | m_eDrawMode(OBJ_NONE), | ||||
5176 | |||||
5177 | m_bMBPressed(false), | ||||
5178 | m_bInsDraw(false), | ||||
5179 | m_bInsFrame(false), | ||||
5180 | m_bIsInMove(false), | ||||
5181 | m_bIsInDrag(false), | ||||
5182 | m_bOldIdle(false), | ||||
5183 | m_bOldIdleSet(false), | ||||
5184 | m_bChainMode(false), | ||||
5185 | m_bWasShdwCursor(false), | ||||
5186 | m_bLockInput(false), | ||||
5187 | m_bIsRowDrag(false), | ||||
5188 | m_bUseInputLanguage(false), | ||||
5189 | m_bObjectSelect(false), | ||||
5190 | m_nKS_NUMDOWN_Count(0), | ||||
5191 | m_nKS_NUMINDENTINC_Count(0), | ||||
5192 | m_pFrameControlsManager(new SwFrameControlsManager(this)) | ||||
5193 | { | ||||
5194 | set_id("writer_edit"); | ||||
5195 | SetHelpId(HID_EDIT_WIN"SW_HID_EDIT_WIN"); | ||||
5196 | EnableChildTransparentMode(); | ||||
5197 | SetDialogControlFlags( DialogControlFlags::Return | DialogControlFlags::WantFocus ); | ||||
5198 | |||||
5199 | m_bMBPressed = m_bInsDraw = m_bInsFrame = | ||||
5200 | m_bIsInDrag = m_bOldIdle = m_bOldIdleSet = m_bChainMode = m_bWasShdwCursor = false; | ||||
5201 | // initially use the input language | ||||
5202 | m_bUseInputLanguage = true; | ||||
5203 | |||||
5204 | SetMapMode(MapMode(MapUnit::MapTwip)); | ||||
5205 | |||||
5206 | SetPointer( PointerStyle::Text ); | ||||
5207 | m_aTimer.SetInvokeHandler(LINK(this, SwEditWin, TimerHandler)::tools::detail::makeLink( ::tools::detail::castTo<SwEditWin *>(this), &SwEditWin::LinkStubTimerHandler)); | ||||
5208 | |||||
5209 | m_aKeyInputFlushTimer.SetTimeout( 200 ); | ||||
5210 | m_aKeyInputFlushTimer.SetInvokeHandler(LINK(this, SwEditWin, KeyInputFlushHandler)::tools::detail::makeLink( ::tools::detail::castTo<SwEditWin *>(this), &SwEditWin::LinkStubKeyInputFlushHandler)); | ||||
5211 | |||||
5212 | // TemplatePointer for colors should be reset without | ||||
5213 | // selection after single click, but not after double-click (tdf#122442) | ||||
5214 | m_aTemplateTimer.SetTimeout(GetSettings().GetMouseSettings().GetDoubleClickTime()); | ||||
5215 | m_aTemplateTimer.SetInvokeHandler(LINK(this, SwEditWin, TemplateTimerHdl)::tools::detail::makeLink( ::tools::detail::castTo<SwEditWin *>(this), &SwEditWin::LinkStubTemplateTimerHdl)); | ||||
5216 | |||||
5217 | // temporary solution!!! Should set the font of the current | ||||
5218 | // insert position at every cursor movement! | ||||
5219 | if( !rMyView.GetDocShell()->IsReadOnly() ) | ||||
5220 | { | ||||
5221 | vcl::Font aFont; | ||||
5222 | SetInputContext( InputContext( aFont, InputContextFlags::Text | | ||||
5223 | InputContextFlags::ExtText ) ); | ||||
5224 | } | ||||
5225 | } | ||||
5226 | |||||
5227 | SwEditWin::~SwEditWin() | ||||
5228 | { | ||||
5229 | disposeOnce(); | ||||
5230 | } | ||||
5231 | |||||
5232 | void SwEditWin::dispose() | ||||
5233 | { | ||||
5234 | m_pShadCursor.reset(); | ||||
5235 | |||||
5236 | if( m_pQuickHlpData->m_bIsDisplayed && m_rView.GetWrtShellPtr() ) | ||||
5237 | m_pQuickHlpData->Stop( m_rView.GetWrtShell() ); | ||||
5238 | g_bExecuteDrag = false; | ||||
5239 | m_pApplyTempl.reset(); | ||||
5240 | |||||
5241 | m_rView.SetDrawFuncPtr(nullptr); | ||||
5242 | |||||
5243 | m_pUserMarker.reset(); | ||||
5244 | |||||
5245 | m_pAnchorMarker.reset(); | ||||
5246 | |||||
5247 | m_pFrameControlsManager->dispose(); | ||||
5248 | m_pFrameControlsManager.reset(); | ||||
5249 | |||||
5250 | DragSourceHelper::dispose(); | ||||
5251 | DropTargetHelper::dispose(); | ||||
5252 | vcl::Window::dispose(); | ||||
5253 | } | ||||
5254 | |||||
5255 | /** | ||||
5256 | * Turn on DrawTextEditMode | ||||
5257 | */ | ||||
5258 | void SwEditWin::EnterDrawTextMode( const Point& aDocPos ) | ||||
5259 | { | ||||
5260 | if ( m_rView.EnterDrawTextMode(aDocPos) ) | ||||
5261 | { | ||||
5262 | if (m_rView.GetDrawFuncPtr()) | ||||
5263 | { | ||||
5264 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
5265 | m_rView.SetDrawFuncPtr(nullptr); | ||||
5266 | m_rView.LeaveDrawCreate(); | ||||
5267 | } | ||||
5268 | m_rView.NoRotate(); | ||||
5269 | m_rView.AttrChangedNotify(nullptr); | ||||
5270 | } | ||||
5271 | } | ||||
5272 | |||||
5273 | /** | ||||
5274 | * Turn on DrawMode | ||||
5275 | */ | ||||
5276 | bool SwEditWin::EnterDrawMode(const MouseEvent& rMEvt, const Point& aDocPos) | ||||
5277 | { | ||||
5278 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
5279 | SdrView *pSdrView = rSh.GetDrawView(); | ||||
5280 | |||||
5281 | if ( m_rView.GetDrawFuncPtr() ) | ||||
5282 | { | ||||
5283 | if (rSh.IsDrawCreate()) | ||||
5284 | return true; | ||||
5285 | |||||
5286 | bool bRet = m_rView.GetDrawFuncPtr()->MouseButtonDown( rMEvt ); | ||||
5287 | m_rView.AttrChangedNotify(nullptr); | ||||
5288 | return bRet; | ||||
5289 | } | ||||
5290 | |||||
5291 | if ( pSdrView && pSdrView->IsTextEdit() ) | ||||
5292 | { | ||||
5293 | bool bUnLockView = !rSh.IsViewLocked(); | ||||
5294 | rSh.LockView( true ); | ||||
5295 | |||||
5296 | rSh.EndTextEdit(); // clicked aside, end Edit | ||||
5297 | rSh.SelectObj( aDocPos ); | ||||
5298 | if ( !rSh.IsObjSelected() && !rSh.IsFrameSelected() ) | ||||
5299 | rSh.LeaveSelFrameMode(); | ||||
5300 | else | ||||
5301 | { | ||||
5302 | SwEditWin::m_nDDStartPosY = aDocPos.Y(); | ||||
5303 | SwEditWin::m_nDDStartPosX = aDocPos.X(); | ||||
5304 | g_bFrameDrag = true; | ||||
5305 | } | ||||
5306 | if( bUnLockView ) | ||||
5307 | rSh.LockView( false ); | ||||
5308 | m_rView.AttrChangedNotify(nullptr); | ||||
5309 | return true; | ||||
5310 | } | ||||
5311 | return false; | ||||
5312 | } | ||||
5313 | |||||
5314 | bool SwEditWin::IsDrawSelMode() const | ||||
5315 | { | ||||
5316 | return IsObjectSelect(); | ||||
5317 | } | ||||
5318 | |||||
5319 | void SwEditWin::GetFocus() | ||||
5320 | { | ||||
5321 | if ( m_rView.GetPostItMgr()->HasActiveSidebarWin() ) | ||||
5322 | { | ||||
5323 | m_rView.GetPostItMgr()->GrabFocusOnActiveSidebarWin(); | ||||
5324 | } | ||||
5325 | else | ||||
5326 | { | ||||
5327 | m_rView.GotFocus(); | ||||
5328 | Window::GetFocus(); | ||||
5329 | m_rView.GetWrtShell().InvalidateAccessibleFocus(); | ||||
5330 | } | ||||
5331 | } | ||||
5332 | |||||
5333 | void SwEditWin::LoseFocus() | ||||
5334 | { | ||||
5335 | if (m_rView.GetWrtShellPtr()) | ||||
5336 | m_rView.GetWrtShell().InvalidateAccessibleFocus(); | ||||
5337 | Window::LoseFocus(); | ||||
5338 | if( m_pQuickHlpData && m_pQuickHlpData->m_bIsDisplayed ) | ||||
5339 | m_pQuickHlpData->Stop( m_rView.GetWrtShell() ); | ||||
5340 | } | ||||
5341 | |||||
5342 | void SwEditWin::Command( const CommandEvent& rCEvt ) | ||||
5343 | { | ||||
5344 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
5345 | |||||
5346 | if ( !m_rView.GetViewFrame() ) | ||||
5347 | { | ||||
5348 | // If ViewFrame dies shortly, no popup anymore! | ||||
5349 | Window::Command(rCEvt); | ||||
5350 | return; | ||||
5351 | } | ||||
5352 | |||||
5353 | // The command event is send to the window after a possible context | ||||
5354 | // menu from an inplace client has been closed. Now we have the chance | ||||
5355 | // to deactivate the inplace client without any problem regarding parent | ||||
5356 | // windows and code on the stack. | ||||
5357 | SfxInPlaceClient* pIPClient = rSh.GetSfxViewShell()->GetIPClient(); | ||||
5358 | bool bIsOleActive = ( pIPClient && pIPClient->IsObjectInPlaceActive() ); | ||||
5359 | if ( bIsOleActive && ( rCEvt.GetCommand() == CommandEventId::ContextMenu )) | ||||
5360 | { | ||||
5361 | rSh.FinishOLEObj(); | ||||
5362 | return; | ||||
5363 | } | ||||
5364 | |||||
5365 | bool bCallBase = true; | ||||
5366 | |||||
5367 | switch ( rCEvt.GetCommand() ) | ||||
5368 | { | ||||
5369 | case CommandEventId::ContextMenu: | ||||
5370 | { | ||||
5371 | const sal_uInt16 nId = SwInputChild::GetChildWindowId(); | ||||
5372 | SwInputChild* pChildWin = static_cast<SwInputChild*>(GetView().GetViewFrame()-> | ||||
5373 | GetChildWindow( nId )); | ||||
5374 | |||||
5375 | if (m_rView.GetPostItMgr()->IsHit(rCEvt.GetMousePosPixel())) | ||||
5376 | return; | ||||
5377 | |||||
5378 | Point aDocPos( PixelToLogic( rCEvt.GetMousePosPixel() ) ); | ||||
5379 | if ( !rCEvt.IsMouseEvent() ) | ||||
5380 | aDocPos = rSh.GetCharRect().Center(); | ||||
5381 | |||||
5382 | // Don't trigger the command on a frame anchored to header/footer is not editing it | ||||
5383 | FrameControlType eControl; | ||||
5384 | bool bOverFly = false; | ||||
5385 | bool bPageAnchored = false; | ||||
5386 | bool bOverHeaderFooterFly = IsOverHeaderFooterFly( aDocPos, eControl, bOverFly, bPageAnchored ); | ||||
5387 | // !bOverHeaderFooterFly doesn't mean we have a frame to select | ||||
5388 | if ( !bPageAnchored && rCEvt.IsMouseEvent( ) && | ||||
5389 | ( ( rSh.IsHeaderFooterEdit( ) && !bOverHeaderFooterFly && bOverFly ) || | ||||
5390 | ( !rSh.IsHeaderFooterEdit( ) && bOverHeaderFooterFly ) ) ) | ||||
5391 | { | ||||
5392 | return; | ||||
5393 | } | ||||
5394 | |||||
5395 | if((!pChildWin || pChildWin->GetView() != &m_rView) && | ||||
5396 | !rSh.IsDrawCreate() && !IsDrawAction()) | ||||
5397 | { | ||||
5398 | CurrShell aCurr( &rSh ); | ||||
5399 | if (!m_pApplyTempl) | ||||
5400 | { | ||||
5401 | if (g_bNoInterrupt) | ||||
5402 | { | ||||
5403 | ReleaseMouse(); | ||||
5404 | g_bNoInterrupt = false; | ||||
5405 | m_bMBPressed = false; | ||||
5406 | } | ||||
5407 | if ( rCEvt.IsMouseEvent() ) | ||||
5408 | { | ||||
5409 | SelectMenuPosition(rSh, rCEvt.GetMousePosPixel()); | ||||
5410 | m_rView.StopShellTimer(); | ||||
5411 | } | ||||
5412 | const Point aPixPos = LogicToPixel( aDocPos ); | ||||
5413 | |||||
5414 | if ( m_rView.GetDocShell()->IsReadOnly() ) | ||||
5415 | { | ||||
5416 | SwReadOnlyPopup aROPopup(aDocPos, m_rView); | ||||
5417 | |||||
5418 | ui::ContextMenuExecuteEvent aEvent; | ||||
5419 | aEvent.SourceWindow = VCLUnoHelper::GetInterface( this ); | ||||
5420 | aEvent.ExecutePosition.X = aPixPos.X(); | ||||
5421 | aEvent.ExecutePosition.Y = aPixPos.Y(); | ||||
5422 | ScopedVclPtr<Menu> pMenu; | ||||
5423 | if (GetView().TryContextMenuInterception(aROPopup.GetMenu(), "private:resource/ReadonlyContextMenu", pMenu, aEvent)) | ||||
5424 | { | ||||
5425 | if ( pMenu ) | ||||
5426 | { | ||||
5427 | sal_uInt16 nExecId = static_cast<PopupMenu*>(pMenu.get())->Execute(this, aPixPos); | ||||
5428 | if( !::ExecuteMenuCommand( *static_cast<PopupMenu*>(pMenu.get()), *m_rView.GetViewFrame(), nExecId )) | ||||
5429 | aROPopup.Execute(this, nExecId); | ||||
5430 | } | ||||
5431 | else | ||||
5432 | aROPopup.Execute(this, aPixPos); | ||||
5433 | } | ||||
5434 | } | ||||
5435 | else if ( !m_rView.ExecSpellPopup( aDocPos ) ) | ||||
5436 | SfxDispatcher::ExecutePopup(this, &aPixPos); | ||||
5437 | } | ||||
5438 | else if (m_pApplyTempl->nUndo < rSh.GetDoc()->GetIDocumentUndoRedo().GetUndoActionCount()) | ||||
5439 | { | ||||
5440 | // Undo until we reach the point when we entered this context. | ||||
5441 | rSh.Do(SwWrtShell::UNDO); | ||||
5442 | } | ||||
5443 | bCallBase = false; | ||||
5444 | } | ||||
5445 | } | ||||
5446 | break; | ||||
5447 | |||||
5448 | case CommandEventId::Wheel: | ||||
5449 | case CommandEventId::StartAutoScroll: | ||||
5450 | case CommandEventId::AutoScroll: | ||||
5451 | if (m_pSavedOutlineFrame && rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) | ||||
5452 | { | ||||
5453 | GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame); | ||||
5454 | m_pSavedOutlineFrame = nullptr; | ||||
5455 | } | ||||
5456 | m_pShadCursor.reset(); | ||||
5457 | bCallBase = !m_rView.HandleWheelCommands( rCEvt ); | ||||
5458 | break; | ||||
5459 | |||||
5460 | case CommandEventId::LongPress: | ||||
5461 | case CommandEventId::Swipe: //nothing yet | ||||
5462 | break; | ||||
5463 | |||||
5464 | case CommandEventId::StartExtTextInput: | ||||
5465 | { | ||||
5466 | bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() && | ||||
5467 | rSh.IsCursorReadonly(); | ||||
5468 | if(!bIsDocReadOnly) | ||||
5469 | { | ||||
5470 | if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() ) | ||||
5471 | { | ||||
5472 | bCallBase = false; | ||||
5473 | rSh.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt ); | ||||
5474 | } | ||||
5475 | else | ||||
5476 | { | ||||
5477 | if( rSh.HasSelection() ) | ||||
5478 | rSh.DelRight(); | ||||
5479 | |||||
5480 | bCallBase = false; | ||||
5481 | LanguageType eInputLanguage = GetInputLanguage(); | ||||
5482 | rSh.CreateExtTextInput(eInputLanguage); | ||||
5483 | } | ||||
5484 | } | ||||
5485 | break; | ||||
5486 | } | ||||
5487 | case CommandEventId::EndExtTextInput: | ||||
5488 | { | ||||
5489 | bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() && | ||||
5490 | rSh.IsCursorReadonly(); | ||||
5491 | if(!bIsDocReadOnly) | ||||
5492 | { | ||||
5493 | if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() ) | ||||
5494 | { | ||||
5495 | bCallBase = false; | ||||
5496 | rSh.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt ); | ||||
5497 | } | ||||
5498 | else | ||||
5499 | { | ||||
5500 | bCallBase = false; | ||||
5501 | OUString sRecord = rSh.DeleteExtTextInput(); | ||||
5502 | uno::Reference< frame::XDispatchRecorder > xRecorder = | ||||
5503 | m_rView.GetViewFrame()->GetBindings().GetRecorder(); | ||||
5504 | |||||
5505 | if ( !sRecord.isEmpty() ) | ||||
5506 | { | ||||
5507 | // convert quotes in IME text | ||||
5508 | // works on the last input character, this is especially in Korean text often done | ||||
5509 | // quotes that are inside of the string are not replaced! | ||||
5510 | const sal_Unicode aCh = sRecord[sRecord.getLength() - 1]; | ||||
5511 | SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get(); | ||||
5512 | SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect(); | ||||
5513 | if(pACorr && | ||||
5514 | (( pACorr->IsAutoCorrFlag( ACFlags::ChgQuotes ) && ('\"' == aCh ))|| | ||||
5515 | ( pACorr->IsAutoCorrFlag( ACFlags::ChgSglQuotes ) && ( '\'' == aCh)))) | ||||
5516 | { | ||||
5517 | rSh.DelLeft(); | ||||
5518 | rSh.AutoCorrect( *pACorr, aCh ); | ||||
5519 | } | ||||
5520 | |||||
5521 | if ( xRecorder.is() ) | ||||
5522 | { | ||||
5523 | // determine Shell | ||||
5524 | SfxShell *pSfxShell = lcl_GetTextShellFromDispatcher( m_rView ); | ||||
5525 | // generate request and record | ||||
5526 | if (pSfxShell) | ||||
5527 | { | ||||
5528 | SfxRequest aReq( m_rView.GetViewFrame(), FN_INSERT_STRING((20000 + 300)+31) ); | ||||
5529 | aReq.AppendItem( SfxStringItem( FN_INSERT_STRING((20000 + 300)+31), sRecord ) ); | ||||
5530 | aReq.Done(); | ||||
5531 | } | ||||
5532 | } | ||||
5533 | } | ||||
5534 | } | ||||
5535 | } | ||||
5536 | } | ||||
5537 | break; | ||||
5538 | case CommandEventId::ExtTextInput: | ||||
5539 | { | ||||
5540 | bool bIsDocReadOnly = m_rView.GetDocShell()->IsReadOnly() && | ||||
5541 | rSh.IsCursorReadonly(); | ||||
5542 | if(!bIsDocReadOnly) | ||||
5543 | { | ||||
5544 | if( m_pQuickHlpData->m_bIsDisplayed ) | ||||
5545 | m_pQuickHlpData->Stop( rSh ); | ||||
5546 | |||||
5547 | if( rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit() ) | ||||
5548 | { | ||||
5549 | bCallBase = false; | ||||
5550 | rSh.GetDrawView()->GetTextEditOutlinerView()->Command( rCEvt ); | ||||
5551 | } | ||||
5552 | else | ||||
5553 | { | ||||
5554 | const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData(); | ||||
5555 | if( pData ) | ||||
5556 | { | ||||
5557 | bCallBase = false; | ||||
5558 | rSh.SetExtTextInputData( *pData ); | ||||
5559 | } | ||||
5560 | } | ||||
5561 | uno::Reference< frame::XDispatchRecorder > xRecorder = | ||||
5562 | m_rView.GetViewFrame()->GetBindings().GetRecorder(); | ||||
5563 | if(!xRecorder.is()) | ||||
5564 | { | ||||
5565 | SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get(); | ||||
5566 | if (!rACfg.IsAutoTextTip() || !ShowAutoText(rSh.GetChunkForAutoText())) | ||||
5567 | { | ||||
5568 | SvxAutoCorrect* pACorr = rACfg.GetAutoCorrect(); | ||||
5569 | if (pACorr && pACorr->GetSwFlags().bAutoCompleteWords) | ||||
5570 | ShowAutoCorrectQuickHelp(rSh.GetPrevAutoCorrWord(*pACorr), *pACorr); | ||||
5571 | } | ||||
5572 | } | ||||
5573 | } | ||||
5574 | } | ||||
5575 | break; | ||||
5576 | case CommandEventId::CursorPos: | ||||
5577 | // will be handled by the base class | ||||
5578 | break; | ||||
5579 | |||||
5580 | case CommandEventId::PasteSelection: | ||||
5581 | if( !m_rView.GetDocShell()->IsReadOnly() ) | ||||
5582 | { | ||||
5583 | TransferableDataHelper aDataHelper( | ||||
5584 | TransferableDataHelper::CreateFromSelection( this )); | ||||
5585 | if( !aDataHelper.GetXTransferable().is() ) | ||||
5586 | break; | ||||
5587 | |||||
5588 | SotExchangeDest nDropDestination = GetDropDestination( rCEvt.GetMousePosPixel() ); | ||||
5589 | if( !bool(nDropDestination) ) | ||||
5590 | break; | ||||
5591 | SotClipboardFormatId nDropFormat; | ||||
5592 | sal_uInt8 nEventAction, nDropAction; | ||||
5593 | SotExchangeActionFlags nActionFlags; | ||||
5594 | nDropAction = SotExchange::GetExchangeAction( | ||||
5595 | aDataHelper.GetDataFlavorExVector(), | ||||
5596 | nDropDestination, EXCHG_IN_ACTION_COPY(sal_uInt8(css::datatransfer::dnd::DNDConstants::ACTION_COPY) ), | ||||
5597 | EXCHG_IN_ACTION_COPY(sal_uInt8(css::datatransfer::dnd::DNDConstants::ACTION_COPY) ), nDropFormat, | ||||
5598 | nEventAction, | ||||
5599 | SotClipboardFormatId::NONE, nullptr, | ||||
5600 | &nActionFlags ); | ||||
5601 | if( EXCHG_INOUT_ACTION_NONE(sal_uInt8(css::datatransfer::dnd::DNDConstants::ACTION_NONE) ) != nDropAction ) | ||||
5602 | { | ||||
5603 | const Point aDocPt( PixelToLogic( rCEvt.GetMousePosPixel() ) ); | ||||
5604 | SwTransferable::PasteData( aDataHelper, rSh, nDropAction, nActionFlags, | ||||
5605 | nDropFormat, nDropDestination, false, | ||||
5606 | false, &aDocPt, EXCHG_IN_ACTION_COPY(sal_uInt8(css::datatransfer::dnd::DNDConstants::ACTION_COPY) ), | ||||
5607 | true ); | ||||
5608 | } | ||||
5609 | } | ||||
5610 | break; | ||||
5611 | case CommandEventId::ModKeyChange : | ||||
5612 | { | ||||
5613 | const CommandModKeyData* pCommandData = rCEvt.GetModKeyData(); | ||||
5614 | if (!pCommandData->IsDown() && pCommandData->IsMod1() && !pCommandData->IsMod2()) | ||||
5615 | { | ||||
5616 | sal_uInt16 nSlot = 0; | ||||
5617 | if(pCommandData->IsLeftShift() && !pCommandData->IsRightShift()) | ||||
5618 | nSlot = SID_ATTR_PARA_LEFT_TO_RIGHT( 10000 + 950 ); | ||||
5619 | else if(!pCommandData->IsLeftShift() && pCommandData->IsRightShift()) | ||||
5620 | nSlot = SID_ATTR_PARA_RIGHT_TO_LEFT( 10000 + 951 ); | ||||
5621 | if(nSlot && SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetCTLOptions().IsCTLFontEnabled()) | ||||
5622 | GetView().GetViewFrame()->GetDispatcher()->Execute(nSlot); | ||||
5623 | } | ||||
5624 | } | ||||
5625 | break; | ||||
5626 | case CommandEventId::InputLanguageChange : | ||||
5627 | // i#42732 - update state of fontname if input language changes | ||||
5628 | g_bInputLanguageSwitched = true; | ||||
5629 | SetUseInputLanguage( true ); | ||||
5630 | break; | ||||
5631 | case CommandEventId::SelectionChange: | ||||
5632 | { | ||||
5633 | const CommandSelectionChangeData *pData = rCEvt.GetSelectionChangeData(); | ||||
5634 | rSh.SttCursorMove(); | ||||
5635 | rSh.GoStartSentence(); | ||||
5636 | rSh.GetCursor()->GetPoint()->nContent += sal::static_int_cast<sal_uInt16, sal_uLong>(pData->GetStart()); | ||||
5637 | rSh.SetMark(); | ||||
5638 | rSh.GetCursor()->GetMark()->nContent += sal::static_int_cast<sal_uInt16, sal_uLong>(pData->GetEnd() - pData->GetStart()); | ||||
5639 | rSh.EndCursorMove( true ); | ||||
5640 | } | ||||
5641 | break; | ||||
5642 | case CommandEventId::PrepareReconversion: | ||||
5643 | if( rSh.HasSelection() ) | ||||
5644 | { | ||||
5645 | SwPaM *pCursor = rSh.GetCursor(); | ||||
5646 | |||||
5647 | if( rSh.IsMultiSelection() ) | ||||
5648 | { | ||||
5649 | if (pCursor && !pCursor->HasMark() && | ||||
5650 | pCursor->GetPoint() == pCursor->GetMark()) | ||||
5651 | { | ||||
5652 | rSh.GoPrevCursor(); | ||||
5653 | pCursor = rSh.GetCursor(); | ||||
5654 | } | ||||
5655 | |||||
5656 | // Cancel all selections other than the last selected one. | ||||
5657 | while( rSh.GetCursor()->GetNext() != rSh.GetCursor() ) | ||||
5658 | delete rSh.GetCursor()->GetNext(); | ||||
5659 | } | ||||
5660 | |||||
5661 | if( pCursor ) | ||||
5662 | { | ||||
5663 | sal_uLong nPosNodeIdx = pCursor->GetPoint()->nNode.GetIndex(); | ||||
5664 | const sal_Int32 nPosIdx = pCursor->GetPoint()->nContent.GetIndex(); | ||||
5665 | sal_uLong nMarkNodeIdx = pCursor->GetMark()->nNode.GetIndex(); | ||||
5666 | const sal_Int32 nMarkIdx = pCursor->GetMark()->nContent.GetIndex(); | ||||
5667 | |||||
5668 | if( !rSh.GetCursor()->HasMark() ) | ||||
5669 | rSh.GetCursor()->SetMark(); | ||||
5670 | |||||
5671 | rSh.SttCursorMove(); | ||||
5672 | |||||
5673 | if( nPosNodeIdx < nMarkNodeIdx ) | ||||
5674 | { | ||||
5675 | rSh.GetCursor()->GetPoint()->nNode = nPosNodeIdx; | ||||
5676 | rSh.GetCursor()->GetPoint()->nContent = nPosIdx; | ||||
5677 | rSh.GetCursor()->GetMark()->nNode = nPosNodeIdx; | ||||
5678 | rSh.GetCursor()->GetMark()->nContent = | ||||
5679 | rSh.GetCursor()->GetContentNode()->Len(); | ||||
5680 | } | ||||
5681 | else if( nPosNodeIdx == nMarkNodeIdx ) | ||||
5682 | { | ||||
5683 | rSh.GetCursor()->GetPoint()->nNode = nPosNodeIdx; | ||||
5684 | rSh.GetCursor()->GetPoint()->nContent = nPosIdx; | ||||
5685 | rSh.GetCursor()->GetMark()->nNode = nMarkNodeIdx; | ||||
5686 | rSh.GetCursor()->GetMark()->nContent = nMarkIdx; | ||||
5687 | } | ||||
5688 | else | ||||
5689 | { | ||||
5690 | rSh.GetCursor()->GetMark()->nNode = nMarkNodeIdx; | ||||
5691 | rSh.GetCursor()->GetMark()->nContent = nMarkIdx; | ||||
5692 | rSh.GetCursor()->GetPoint()->nNode = nMarkNodeIdx; | ||||
5693 | rSh.GetCursor()->GetPoint()->nContent = | ||||
5694 | rSh.GetCursor()->GetContentNode( false )->Len(); | ||||
5695 | } | ||||
5696 | |||||
5697 | rSh.EndCursorMove( true ); | ||||
5698 | } | ||||
5699 | } | ||||
5700 | break; | ||||
5701 | case CommandEventId::QueryCharPosition: | ||||
5702 | { | ||||
5703 | bool bVertical = rSh.IsInVerticalText(); | ||||
5704 | const SwPosition& rPos = *rSh.GetCursor()->GetPoint(); | ||||
5705 | SwDocShell* pDocSh = m_rView.GetDocShell(); | ||||
5706 | SwDoc *pDoc = pDocSh->GetDoc(); | ||||
5707 | SwExtTextInput* pInput = pDoc->GetExtTextInput( rPos.nNode.GetNode(), rPos.nContent.GetIndex() ); | ||||
5708 | if ( pInput ) | ||||
5709 | { | ||||
5710 | const SwPosition& rStart = *pInput->Start(); | ||||
5711 | const SwPosition& rEnd = *pInput->End(); | ||||
5712 | int nSize = 0; | ||||
5713 | for ( SwIndex nIndex = rStart.nContent; nIndex < rEnd.nContent; ++nIndex ) | ||||
5714 | { | ||||
5715 | ++nSize; | ||||
5716 | } | ||||
5717 | vcl::Window& rWin = rSh.GetView().GetEditWin(); | ||||
5718 | if ( nSize == 0 ) | ||||
5719 | { | ||||
5720 | // When the composition does not exist, use Caret rect instead. | ||||
5721 | const SwRect& aCaretRect ( rSh.GetCharRect() ); | ||||
5722 | tools::Rectangle aRect( aCaretRect.Left(), aCaretRect.Top(), aCaretRect.Right(), aCaretRect.Bottom() ); | ||||
5723 | rWin.SetCompositionCharRect( &aRect, 1, bVertical ); | ||||
5724 | } | ||||
5725 | else | ||||
5726 | { | ||||
5727 | std::unique_ptr<tools::Rectangle[]> aRects(new tools::Rectangle[ nSize ]); | ||||
5728 | int nRectIndex = 0; | ||||
5729 | for ( SwIndex nIndex = rStart.nContent; nIndex < rEnd.nContent; ++nIndex ) | ||||
5730 | { | ||||
5731 | const SwPosition aPos( rStart.nNode, nIndex ); | ||||
5732 | SwRect aRect ( rSh.GetCharRect() ); | ||||
5733 | rSh.GetCharRectAt( aRect, &aPos ); | ||||
5734 | aRects[ nRectIndex ] = tools::Rectangle( aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom() ); | ||||
5735 | ++nRectIndex; | ||||
5736 | } | ||||
5737 | rWin.SetCompositionCharRect( aRects.get(), nSize, bVertical ); | ||||
5738 | } | ||||
5739 | } | ||||
5740 | bCallBase = false; | ||||
5741 | } | ||||
5742 | break; | ||||
5743 | default: | ||||
5744 | SAL_WARN("sw.ui", "unknown command.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ui")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "unknown command.") == 1) { ::sal_detail_log( (:: SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ui"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "5744" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "unknown command."), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "unknown command."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ui"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "5744" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "unknown command.") == 1) { ::sal_detail_log( (:: SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ui"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "5744" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "unknown command."), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "unknown command."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ui"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "5744" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||
5745 | break; | ||||
5746 | } | ||||
5747 | if (bCallBase) | ||||
5748 | Window::Command(rCEvt); | ||||
5749 | } | ||||
5750 | |||||
5751 | /* i#18686 select the object/cursor at the mouse | ||||
5752 | position of the context menu request */ | ||||
5753 | void SwEditWin::SelectMenuPosition(SwWrtShell& rSh, const Point& rMousePos ) | ||||
5754 | { | ||||
5755 | const Point aDocPos( PixelToLogic( rMousePos ) ); | ||||
5756 | const bool bIsInsideSelectedObj( rSh.IsInsideSelectedObj( aDocPos ) ); | ||||
5757 | //create a synthetic mouse event out of the coordinates | ||||
5758 | MouseEvent aMEvt(rMousePos); | ||||
5759 | SdrView *pSdrView = rSh.GetDrawView(); | ||||
5760 | if ( pSdrView ) | ||||
5761 | { | ||||
5762 | // no close of insert_draw and reset of | ||||
5763 | // draw mode, if context menu position is inside a selected object. | ||||
5764 | if ( !bIsInsideSelectedObj && m_rView.GetDrawFuncPtr() ) | ||||
5765 | { | ||||
5766 | |||||
5767 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
5768 | m_rView.SetDrawFuncPtr(nullptr); | ||||
5769 | m_rView.LeaveDrawCreate(); | ||||
5770 | SfxBindings& rBind = m_rView.GetViewFrame()->GetBindings(); | ||||
5771 | rBind.Invalidate( SID_ATTR_SIZETypedWhichId<SvxSizeItem>( 10000 + 224 ) ); | ||||
5772 | rBind.Invalidate( SID_TABLE_CELL( 10000 + 225 ) ); | ||||
5773 | } | ||||
5774 | |||||
5775 | // if draw text is active and there's a text selection | ||||
5776 | // at the mouse position then do nothing | ||||
5777 | if(rSh.GetSelectionType() & SelectionType::DrawObjectEditMode) | ||||
5778 | { | ||||
5779 | OutlinerView* pOLV = pSdrView->GetTextEditOutlinerView(); | ||||
5780 | ESelection aSelection = pOLV->GetSelection(); | ||||
5781 | if(!aSelection.IsZero()) | ||||
5782 | { | ||||
5783 | SdrOutliner* pOutliner = pSdrView->GetTextEditOutliner(); | ||||
5784 | bool bVertical = pOutliner->IsVertical(); | ||||
5785 | const EditEngine& rEditEng = pOutliner->GetEditEngine(); | ||||
5786 | Point aEEPos(aDocPos); | ||||
5787 | const tools::Rectangle& rOutputArea = pOLV->GetOutputArea(); | ||||
5788 | // regard vertical mode | ||||
5789 | if(bVertical) | ||||
5790 | { | ||||
5791 | aEEPos -= rOutputArea.TopRight(); | ||||
5792 | //invert the horizontal direction and exchange X and Y | ||||
5793 | long nTemp = -aEEPos.X(); | ||||
5794 | aEEPos.setX( aEEPos.Y() ); | ||||
5795 | aEEPos.setY( nTemp ); | ||||
5796 | } | ||||
5797 | else | ||||
5798 | aEEPos -= rOutputArea.TopLeft(); | ||||
5799 | |||||
5800 | EPosition aDocPosition = rEditEng.FindDocPosition(aEEPos); | ||||
5801 | ESelection aCompare(aDocPosition.nPara, aDocPosition.nIndex); | ||||
5802 | // make it a forward selection - otherwise the IsLess/IsGreater do not work :-( | ||||
5803 | aSelection.Adjust(); | ||||
5804 | if(!(aCompare < aSelection) && !(aCompare > aSelection)) | ||||
5805 | { | ||||
5806 | return; | ||||
5807 | } | ||||
5808 | } | ||||
5809 | |||||
5810 | } | ||||
5811 | |||||
5812 | if (pSdrView->MouseButtonDown( aMEvt, this ) ) | ||||
5813 | { | ||||
5814 | pSdrView->MouseButtonUp( aMEvt, this ); | ||||
5815 | rSh.GetView().GetViewFrame()->GetBindings().InvalidateAll(false); | ||||
5816 | return; | ||||
5817 | } | ||||
5818 | } | ||||
5819 | rSh.ResetCursorStack(); | ||||
5820 | |||||
5821 | if ( EnterDrawMode( aMEvt, aDocPos ) ) | ||||
5822 | { | ||||
5823 | return; | ||||
5824 | } | ||||
5825 | if ( m_rView.GetDrawFuncPtr() && m_bInsFrame ) | ||||
5826 | { | ||||
5827 | StopInsFrame(); | ||||
5828 | rSh.Edit(); | ||||
5829 | } | ||||
5830 | |||||
5831 | UpdatePointer( aDocPos ); | ||||
5832 | |||||
5833 | if( !rSh.IsSelFrameMode() && | ||||
5834 | !GetView().GetViewFrame()->GetDispatcher()->IsLocked() ) | ||||
5835 | { | ||||
5836 | // Test if there is a draw object at that position and if it should be selected. | ||||
5837 | bool bShould = rSh.ShouldObjectBeSelected(aDocPos); | ||||
5838 | |||||
5839 | if(bShould) | ||||
5840 | { | ||||
5841 | m_rView.NoRotate(); | ||||
5842 | rSh.HideCursor(); | ||||
5843 | |||||
5844 | bool bUnLockView = !rSh.IsViewLocked(); | ||||
5845 | rSh.LockView( true ); | ||||
5846 | bool bSelObj = rSh.SelectObj( aDocPos ); | ||||
5847 | if( bUnLockView ) | ||||
5848 | rSh.LockView( false ); | ||||
5849 | |||||
5850 | if( bSelObj ) | ||||
5851 | { | ||||
5852 | // in case the frame was deselected in the macro | ||||
5853 | // just the cursor has to be displayed again. | ||||
5854 | if( FrameTypeFlags::NONE == rSh.GetSelFrameType() ) | ||||
5855 | rSh.ShowCursor(); | ||||
5856 | else | ||||
5857 | { | ||||
5858 | if (rSh.IsFrameSelected() && m_rView.GetDrawFuncPtr()) | ||||
5859 | { | ||||
5860 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
5861 | m_rView.SetDrawFuncPtr(nullptr); | ||||
5862 | m_rView.LeaveDrawCreate(); | ||||
5863 | m_rView.AttrChangedNotify(nullptr); | ||||
5864 | } | ||||
5865 | |||||
5866 | rSh.EnterSelFrameMode( &aDocPos ); | ||||
5867 | g_bFrameDrag = true; | ||||
5868 | UpdatePointer( aDocPos ); | ||||
5869 | return; | ||||
5870 | } | ||||
5871 | } | ||||
5872 | |||||
5873 | if (!m_rView.GetDrawFuncPtr()) | ||||
5874 | rSh.ShowCursor(); | ||||
5875 | } | ||||
5876 | } | ||||
5877 | else if ( rSh.IsSelFrameMode() && | ||||
5878 | (m_aActHitType == SdrHitKind::NONE || | ||||
5879 | !bIsInsideSelectedObj)) | ||||
5880 | { | ||||
5881 | m_rView.NoRotate(); | ||||
5882 | bool bUnLockView = !rSh.IsViewLocked(); | ||||
5883 | rSh.LockView( true ); | ||||
5884 | |||||
5885 | if ( rSh.IsSelFrameMode() ) | ||||
5886 | { | ||||
5887 | rSh.UnSelectFrame(); | ||||
5888 | rSh.LeaveSelFrameMode(); | ||||
5889 | m_rView.AttrChangedNotify(nullptr); | ||||
5890 | } | ||||
5891 | |||||
5892 | bool bSelObj = rSh.SelectObj( aDocPos, 0/*nFlag*/ ); | ||||
5893 | if( bUnLockView ) | ||||
5894 | rSh.LockView( false ); | ||||
5895 | |||||
5896 | if( !bSelObj ) | ||||
5897 | { | ||||
5898 | // move cursor here so that it is not drawn in the | ||||
5899 | // frame at first; ShowCursor() happens in LeaveSelFrameMode() | ||||
5900 | g_bValidCursorPos = !(CRSR_POSCHG & rSh.CallSetCursor(&aDocPos, false)); | ||||
5901 | rSh.LeaveSelFrameMode(); | ||||
5902 | m_rView.LeaveDrawCreate(); | ||||
5903 | m_rView.AttrChangedNotify(nullptr); | ||||
5904 | } | ||||
5905 | else | ||||
5906 | { | ||||
5907 | rSh.HideCursor(); | ||||
5908 | rSh.EnterSelFrameMode( &aDocPos ); | ||||
5909 | rSh.SelFlyGrabCursor(); | ||||
5910 | rSh.MakeSelVisible(); | ||||
5911 | g_bFrameDrag = true; | ||||
5912 | if( rSh.IsFrameSelected() && | ||||
5913 | m_rView.GetDrawFuncPtr() ) | ||||
5914 | { | ||||
5915 | m_rView.GetDrawFuncPtr()->Deactivate(); | ||||
5916 | m_rView.SetDrawFuncPtr(nullptr); | ||||
5917 | m_rView.LeaveDrawCreate(); | ||||
5918 | m_rView.AttrChangedNotify(nullptr); | ||||
5919 | } | ||||
5920 | UpdatePointer( aDocPos ); | ||||
5921 | } | ||||
5922 | } | ||||
5923 | else if ( rSh.IsSelFrameMode() && bIsInsideSelectedObj ) | ||||
5924 | { | ||||
5925 | // Object at the mouse cursor is already selected - do nothing | ||||
5926 | return; | ||||
5927 | } | ||||
5928 | |||||
5929 | if ( rSh.IsGCAttr() ) | ||||
5930 | { | ||||
5931 | rSh.GCAttr(); | ||||
5932 | rSh.ClearGCAttr(); | ||||
5933 | } | ||||
5934 | |||||
5935 | bool bOverSelect = rSh.TestCurrPam( aDocPos ); | ||||
5936 | bool bOverURLGrf = false; | ||||
5937 | if( !bOverSelect ) | ||||
5938 | bOverURLGrf = bOverSelect = nullptr != rSh.IsURLGrfAtPos( aDocPos ); | ||||
5939 | |||||
5940 | if ( !bOverSelect ) | ||||
5941 | { | ||||
5942 | // create only temporary move context because otherwise | ||||
5943 | // the query against the content form doesn't work!!! | ||||
5944 | SwMvContext aMvContext( &rSh ); | ||||
5945 | rSh.CallSetCursor(&aDocPos, false); | ||||
5946 | } | ||||
5947 | if( !bOverURLGrf ) | ||||
5948 | { | ||||
5949 | const SelectionType nSelType = rSh.GetSelectionType(); | ||||
5950 | if( nSelType == SelectionType::Ole || | ||||
5951 | nSelType == SelectionType::Graphic ) | ||||
5952 | { | ||||
5953 | SwMvContext aMvContext( &rSh ); | ||||
5954 | if( !rSh.IsFrameSelected() ) | ||||
5955 | rSh.GotoNextFly(); | ||||
5956 | rSh.EnterSelFrameMode(); | ||||
5957 | } | ||||
5958 | } | ||||
5959 | } | ||||
5960 | |||||
5961 | static SfxShell* lcl_GetTextShellFromDispatcher( SwView const & rView ) | ||||
5962 | { | ||||
5963 | // determine Shell | ||||
5964 | SfxShell* pShell; | ||||
5965 | SfxDispatcher* pDispatcher = rView.GetViewFrame()->GetDispatcher(); | ||||
5966 | for(sal_uInt16 i = 0; true; ++i ) | ||||
5967 | { | ||||
5968 | pShell = pDispatcher->GetShell( i ); | ||||
5969 | if( !pShell || dynamic_cast< const SwTextShell *>( pShell ) != nullptr ) | ||||
5970 | break; | ||||
5971 | } | ||||
5972 | return pShell; | ||||
5973 | } | ||||
5974 | |||||
5975 | IMPL_LINK_NOARG(SwEditWin, KeyInputFlushHandler, Timer *, void)void SwEditWin::LinkStubKeyInputFlushHandler(void * instance, Timer * data) { return static_cast<SwEditWin *>(instance )->KeyInputFlushHandler(data); } void SwEditWin::KeyInputFlushHandler (__attribute__ ((unused)) Timer *) | ||||
5976 | { | ||||
5977 | FlushInBuffer(); | ||||
5978 | } | ||||
5979 | |||||
5980 | void SwEditWin::InitStaticData() | ||||
5981 | { | ||||
5982 | m_pQuickHlpData = new QuickHelpData(); | ||||
5983 | } | ||||
5984 | |||||
5985 | void SwEditWin::FinitStaticData() | ||||
5986 | { | ||||
5987 | delete m_pQuickHlpData; | ||||
5988 | } | ||||
5989 | /* i#3370 - remove quick help to prevent saving | ||||
5990 | * of autocorrection suggestions */ | ||||
5991 | void SwEditWin::StopQuickHelp() | ||||
5992 | { | ||||
5993 | if( HasFocus() && m_pQuickHlpData && m_pQuickHlpData->m_bIsDisplayed ) | ||||
5994 | m_pQuickHlpData->Stop( m_rView.GetWrtShell() ); | ||||
5995 | } | ||||
5996 | |||||
5997 | IMPL_LINK_NOARG(SwEditWin, TemplateTimerHdl, Timer *, void)void SwEditWin::LinkStubTemplateTimerHdl(void * instance, Timer * data) { return static_cast<SwEditWin *>(instance)-> TemplateTimerHdl(data); } void SwEditWin::TemplateTimerHdl(__attribute__ ((unused)) Timer *) | ||||
5998 | { | ||||
5999 | SetApplyTemplate(SwApplyTemplate()); | ||||
6000 | } | ||||
6001 | |||||
6002 | void SwEditWin::SetChainMode( bool bOn ) | ||||
6003 | { | ||||
6004 | if ( !m_bChainMode ) | ||||
6005 | StopInsFrame(); | ||||
6006 | |||||
6007 | m_pUserMarker.reset(); | ||||
6008 | |||||
6009 | m_bChainMode = bOn; | ||||
6010 | |||||
6011 | static sal_uInt16 aInva[] = | ||||
6012 | { | ||||
6013 | FN_FRAME_CHAIN((20000 + 1600) + 136), FN_FRAME_UNCHAIN((20000 + 1600) + 137), 0 | ||||
6014 | }; | ||||
6015 | m_rView.GetViewFrame()->GetBindings().Invalidate(aInva); | ||||
6016 | } | ||||
6017 | |||||
6018 | uno::Reference< css::accessibility::XAccessible > SwEditWin::CreateAccessible() | ||||
6019 | { | ||||
6020 | SolarMutexGuard aGuard; // this should have happened already!!! | ||||
6021 | SwWrtShell *pSh = m_rView.GetWrtShellPtr(); | ||||
6022 | OSL_ENSURE( pSh, "no writer shell, no accessible object" )do { if (true && (!(pSh))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" ":" "6022" ": "), "%s", "no writer shell, no accessible object" ); } } while (false); | ||||
6023 | uno::Reference< | ||||
6024 | css::accessibility::XAccessible > xAcc; | ||||
6025 | if( pSh ) | ||||
6026 | xAcc = pSh->CreateAccessible(); | ||||
6027 | |||||
6028 | return xAcc; | ||||
6029 | } | ||||
6030 | |||||
6031 | void QuickHelpData::Move( QuickHelpData& rCpy ) | ||||
6032 | { | ||||
6033 | m_aHelpStrings.clear(); | ||||
6034 | m_aHelpStrings.swap( rCpy.m_aHelpStrings ); | ||||
6035 | |||||
6036 | m_bIsDisplayed = rCpy.m_bIsDisplayed; | ||||
6037 | nCurArrPos = rCpy.nCurArrPos; | ||||
6038 | m_bAppendSpace = rCpy.m_bAppendSpace; | ||||
6039 | m_bIsTip = rCpy.m_bIsTip; | ||||
6040 | m_bIsAutoText = rCpy.m_bIsAutoText; | ||||
6041 | } | ||||
6042 | |||||
6043 | void QuickHelpData::ClearContent() | ||||
6044 | { | ||||
6045 | nCurArrPos = nNoPos; | ||||
6046 | m_bIsDisplayed = m_bAppendSpace = false; | ||||
6047 | nTipId = nullptr; | ||||
6048 | m_aHelpStrings.clear(); | ||||
6049 | m_bIsTip = true; | ||||
6050 | m_bIsAutoText = true; | ||||
6051 | } | ||||
6052 | |||||
6053 | void QuickHelpData::Start(SwWrtShell& rSh, const bool bRestart) | ||||
6054 | { | ||||
6055 | if (bRestart) | ||||
6056 | { | ||||
6057 | nCurArrPos = 0; | ||||
6058 | } | ||||
6059 | m_bIsDisplayed = true; | ||||
6060 | |||||
6061 | vcl::Window& rWin = rSh.GetView().GetEditWin(); | ||||
6062 | if( m_bIsTip ) | ||||
6063 | { | ||||
6064 | Point aPt( rWin.OutputToScreenPixel( rWin.LogicToPixel( | ||||
6065 | rSh.GetCharRect().Pos() ))); | ||||
6066 | aPt.AdjustY( -3 ); | ||||
6067 | nTipId = Help::ShowPopover(&rWin, tools::Rectangle( aPt, Size( 1, 1 )), | ||||
6068 | CurStr(), | ||||
6069 | QuickHelpFlags::Left | QuickHelpFlags::Bottom); | ||||
6070 | } | ||||
6071 | else | ||||
6072 | { | ||||
6073 | OUString sStr(CurStr()); | ||||
6074 | sStr = sStr.copy(CurLen()); | ||||
6075 | sal_uInt16 nL = sStr.getLength(); | ||||
6076 | const ExtTextInputAttr nVal = ExtTextInputAttr::DottedUnderline | | ||||
6077 | ExtTextInputAttr::Highlight; | ||||
6078 | const std::vector<ExtTextInputAttr> aAttrs( nL, nVal ); | ||||
6079 | CommandExtTextInputData aCETID( sStr, aAttrs.data(), nL, | ||||
6080 | 0, false ); | ||||
6081 | |||||
6082 | //fdo#33092. If the current input language is the default | ||||
6083 | //language that text would appear in if typed, then don't | ||||
6084 | //force a language on for the ExtTextInput. | ||||
6085 | LanguageType eInputLanguage = rWin.GetInputLanguage(); | ||||
6086 | if (lcl_isNonDefaultLanguage(eInputLanguage, | ||||
6087 | rSh.GetView(), sStr) == INVALID_HINT) | ||||
6088 | { | ||||
6089 | eInputLanguage = LANGUAGE_DONTKNOWLanguageType(0x03FF); | ||||
6090 | } | ||||
6091 | |||||
6092 | rSh.CreateExtTextInput(eInputLanguage); | ||||
6093 | rSh.SetExtTextInputData( aCETID ); | ||||
6094 | } | ||||
6095 | } | ||||
6096 | |||||
6097 | void QuickHelpData::Stop( SwWrtShell& rSh ) | ||||
6098 | { | ||||
6099 | if( !m_bIsTip ) | ||||
6100 | rSh.DeleteExtTextInput( false ); | ||||
6101 | else if( nTipId ) | ||||
6102 | { | ||||
6103 | vcl::Window& rWin = rSh.GetView().GetEditWin(); | ||||
6104 | Help::HidePopover(&rWin, nTipId); | ||||
6105 | } | ||||
6106 | ClearContent(); | ||||
6107 | } | ||||
6108 | |||||
6109 | void QuickHelpData::FillStrArr( SwWrtShell const & rSh, const OUString& rWord ) | ||||
6110 | { | ||||
6111 | enum Capitalization { CASE_LOWER, CASE_UPPER, CASE_SENTENCE, CASE_OTHER }; | ||||
6112 | |||||
6113 | // Determine word capitalization | ||||
6114 | const CharClass& rCC = GetAppCharClass(); | ||||
6115 | const OUString sWordLower = rCC.lowercase( rWord ); | ||||
6116 | Capitalization aWordCase = CASE_OTHER; | ||||
6117 | if ( !rWord.isEmpty() ) | ||||
6118 | { | ||||
6119 | if ( rWord[0] == sWordLower[0] ) | ||||
6120 | { | ||||
6121 | if ( rWord == sWordLower ) | ||||
6122 | aWordCase = CASE_LOWER; | ||||
6123 | } | ||||
6124 | else | ||||
6125 | { | ||||
6126 | // First character is not lower case i.e. assume upper or title case | ||||
6127 | OUString sWordSentence = sWordLower.replaceAt( 0, 1, OUString(rWord[0]) ); | ||||
6128 | if ( rWord == sWordSentence ) | ||||
6129 | aWordCase = CASE_SENTENCE; | ||||
6130 | else | ||||
6131 | { | ||||
6132 | if ( rWord == rCC.uppercase( rWord ) ) | ||||
6133 | aWordCase = CASE_UPPER; | ||||
6134 | } | ||||
6135 | } | ||||
6136 | } | ||||
6137 | |||||
6138 | salhelper::SingletonRef<SwCalendarWrapper>* pCalendar = s_getCalendarWrapper(); | ||||
6139 | (*pCalendar)->LoadDefaultCalendar( rSh.GetCurLang() ); | ||||
6140 | |||||
6141 | // Add matching calendar month and day names | ||||
6142 | for ( const auto& aNames : { (*pCalendar)->getMonths(), (*pCalendar)->getDays() } ) | ||||
6143 | { | ||||
6144 | for ( const auto& rName : aNames ) | ||||
6145 | { | ||||
6146 | const OUString& rStr( rName.FullName ); | ||||
6147 | // Check string longer than word and case insensitive match | ||||
6148 | if( rStr.getLength() > rWord.getLength() && | ||||
6149 | rCC.lowercase( rStr, 0, rWord.getLength() ) == sWordLower ) | ||||
6150 | { | ||||
6151 | OUString sStr; | ||||
6152 | |||||
6153 | //fdo#61251 if it's an exact match, ensure unchanged replacement | ||||
6154 | //exists as a candidate | ||||
6155 | if (rStr.startsWith(rWord)) | ||||
6156 | m_aHelpStrings.emplace_back(rStr, rWord.getLength()); | ||||
6157 | else | ||||
6158 | sStr = rStr; // to be added if no case conversion is performed below | ||||
6159 | |||||
6160 | if ( aWordCase == CASE_LOWER ) | ||||
6161 | sStr = rCC.lowercase(rStr); | ||||
6162 | else if ( aWordCase == CASE_SENTENCE ) | ||||
6163 | sStr = rCC.lowercase(rStr).replaceAt(0, 1, OUString(rStr[0])); | ||||
6164 | else if ( aWordCase == CASE_UPPER ) | ||||
6165 | sStr = rCC.uppercase(rStr); | ||||
6166 | |||||
6167 | if (!sStr.isEmpty()) | ||||
6168 | m_aHelpStrings.emplace_back(sStr, rWord.getLength()); | ||||
6169 | } | ||||
6170 | } | ||||
6171 | } | ||||
6172 | |||||
6173 | // Add matching current date in ISO 8601 format, for example 2016-01-30 | ||||
6174 | OUString rStrToday; | ||||
6175 | |||||
6176 | // do not suggest for single years, for example for "2016", | ||||
6177 | // only for "201" or "2016-..." (to avoid unintentional text | ||||
6178 | // insertion at line ending, for example typing "30 January 2016") | ||||
6179 | if (!rWord.isEmpty() && rWord.getLength() != 4 && rWord[0] == '2') | ||||
6180 | { | ||||
6181 | rStrToday = utl::toISO8601(DateTime(Date(Date::SYSTEM)).GetUNODateTime()); | ||||
6182 | if (rStrToday.startsWith(rWord)) | ||||
6183 | m_aHelpStrings.emplace_back(rStrToday, rWord.getLength()); | ||||
6184 | } | ||||
6185 | |||||
6186 | // Add matching words from AutoCompleteWord list | ||||
6187 | const SwAutoCompleteWord& rACList = SwEditShell::GetAutoCompleteWords(); | ||||
6188 | std::vector<OUString> strings; | ||||
6189 | |||||
6190 | if ( !rACList.GetWordsMatching( rWord, strings ) ) | ||||
6191 | return; | ||||
6192 | |||||
6193 | for (const OUString & aCompletedString : strings) | ||||
6194 | { | ||||
6195 | // when we have a matching current date, avoid to suggest | ||||
6196 | // other words with the same matching starting characters, | ||||
6197 | // for example 2016-01-3 instead of 2016-01-30 | ||||
6198 | if (!rStrToday.isEmpty() && aCompletedString.startsWith(rWord)) | ||||
6199 | continue; | ||||
6200 | |||||
6201 | OUString sStr; | ||||
6202 | |||||
6203 | //fdo#61251 if it's an exact match, ensure unchanged replacement | ||||
6204 | //exists as a candidate | ||||
6205 | if (aCompletedString.startsWith(rWord)) | ||||
6206 | m_aHelpStrings.emplace_back(aCompletedString, rWord.getLength()); | ||||
6207 | else | ||||
6208 | sStr = aCompletedString; // to be added if no case conversion is performed below | ||||
6209 | |||||
6210 | if (aWordCase == CASE_LOWER) | ||||
6211 | sStr = rCC.lowercase(aCompletedString); | ||||
6212 | else if (aWordCase == CASE_SENTENCE) | ||||
6213 | sStr = rCC.lowercase(aCompletedString) | ||||
6214 | .replaceAt(0, 1, OUString(aCompletedString[0])); | ||||
6215 | else if (aWordCase == CASE_UPPER) | ||||
6216 | sStr = rCC.uppercase(aCompletedString); | ||||
6217 | |||||
6218 | if (!sStr.isEmpty()) | ||||
6219 | m_aHelpStrings.emplace_back(aCompletedString, rWord.getLength()); | ||||
6220 | } | ||||
6221 | } | ||||
6222 | |||||
6223 | namespace { | ||||
6224 | |||||
6225 | class CompareIgnoreCaseAsciiFavorExact | ||||
6226 | { | ||||
6227 | const OUString &m_rOrigWord; | ||||
6228 | public: | ||||
6229 | explicit CompareIgnoreCaseAsciiFavorExact(const OUString& rOrigWord) | ||||
6230 | : m_rOrigWord(rOrigWord) | ||||
6231 | { | ||||
6232 | } | ||||
6233 | |||||
6234 | bool operator()(const std::pair<OUString, sal_uInt16>& s1, | ||||
6235 | const std::pair<OUString, sal_uInt16>& s2) const | ||||
6236 | { | ||||
6237 | int nRet = s1.first.compareToIgnoreAsciiCase(s2.first); | ||||
6238 | if (nRet == 0) | ||||
6239 | { | ||||
6240 | //fdo#61251 sort stuff that starts with the exact rOrigWord before | ||||
6241 | //another ignore-case candidate | ||||
6242 | int n1StartsWithOrig = s1.first.startsWith(m_rOrigWord) ? 0 : 1; | ||||
6243 | int n2StartsWithOrig = s2.first.startsWith(m_rOrigWord) ? 0 : 1; | ||||
6244 | return n1StartsWithOrig < n2StartsWithOrig; | ||||
6245 | } | ||||
6246 | return nRet < 0; | ||||
6247 | } | ||||
6248 | }; | ||||
6249 | |||||
6250 | struct EqualIgnoreCaseAscii | ||||
6251 | { | ||||
6252 | bool operator()(const std::pair<OUString, sal_uInt16>& s1, | ||||
6253 | const std::pair<OUString, sal_uInt16>& s2) const | ||||
6254 | { | ||||
6255 | return s1.first.equalsIgnoreAsciiCase(s2.first); | ||||
6256 | } | ||||
6257 | }; | ||||
6258 | |||||
6259 | } // anonymous namespace | ||||
6260 | |||||
6261 | // TODO Implement an i18n aware sort | ||||
6262 | void QuickHelpData::SortAndFilter(const OUString &rOrigWord) | ||||
6263 | { | ||||
6264 | std::sort( m_aHelpStrings.begin(), | ||||
6265 | m_aHelpStrings.end(), | ||||
6266 | CompareIgnoreCaseAsciiFavorExact(rOrigWord) ); | ||||
6267 | |||||
6268 | const auto& it | ||||
6269 | = std::unique(m_aHelpStrings.begin(), m_aHelpStrings.end(), EqualIgnoreCaseAscii()); | ||||
6270 | m_aHelpStrings.erase( it, m_aHelpStrings.end() ); | ||||
6271 | |||||
6272 | nCurArrPos = 0; | ||||
6273 | } | ||||
6274 | |||||
6275 | // For a given chunk of typed text between 3 and 9 characters long that may start at a word boundary | ||||
6276 | // or in a whitespace and may include whitespaces, SwEditShell::GetChunkForAutoTextcreates a list of | ||||
6277 | // possible candidates for long AutoText names. Let's say, we have typed text "lorem ipsum dr f"; | ||||
6278 | // and the cursor is right after the "f". SwEditShell::GetChunkForAutoText would take " dr f", | ||||
6279 | // since it's the longest chunk to the left of the cursor no longer than 9 characters, not starting | ||||
6280 | // in the middle of a word. Then it would create this list from it (in this order, longest first): | ||||
6281 | // " dr f" | ||||
6282 | // " dr f" | ||||
6283 | // "dr f" | ||||
6284 | // It cannot add "r f", because it starts in the middle of the word "dr"; also it cannot give " f", | ||||
6285 | // because it's only 2 characters long. | ||||
6286 | // Now the result of SwEditShell::GetChunkForAutoText is passed here to SwEditWin::ShowAutoText, and | ||||
6287 | // then to SwGlossaryList::HasLongName, where all existing autotext entries' long names are tested | ||||
6288 | // if they start with one of the list elements. The matches are sorted according the position of the | ||||
6289 | // candidate that matched first, then alphabetically inside the group of suggestions for a given | ||||
6290 | // candidate. Say, if we have these AutoText entry long names: | ||||
6291 | // "Dr Frodo" | ||||
6292 | // "Dr Credo" | ||||
6293 | // "Or Bilbo" | ||||
6294 | // "dr foo" | ||||
6295 | // " Dr Fuzz" | ||||
6296 | // " dr Faust" | ||||
6297 | // the resulting list would be: | ||||
6298 | // " Dr Fuzz" -> matches the first (longest) item in the candidates list | ||||
6299 | // " dr Faust" -> matches the second candidate item | ||||
6300 | // "Dr Foo" -> first item of the two matching the third candidate; alphabetically sorted | ||||
6301 | // "Dr Frodo" -> second item of the two matching the third candidate; alphabetically sorted | ||||
6302 | // Each of the resulting suggestions knows the length of the candidate it replaces, so accepting the | ||||
6303 | // first suggestion would replace 6 characters before cursor, while tabbing to and accepting the | ||||
6304 | // last suggestion would replace only 4 characters to the left of cursor. | ||||
6305 | bool SwEditWin::ShowAutoText(const std::vector<OUString>& rChunkCandidates) | ||||
6306 | { | ||||
6307 | m_pQuickHlpData->ClearContent(); | ||||
6308 | if (!rChunkCandidates.empty()) | ||||
6309 | { | ||||
6310 | SwGlossaryList* pList = ::GetGlossaryList(); | ||||
6311 | pList->HasLongName(rChunkCandidates, m_pQuickHlpData->m_aHelpStrings); | ||||
6312 | } | ||||
6313 | |||||
6314 | if (!m_pQuickHlpData->m_aHelpStrings.empty()) | ||||
6315 | { | ||||
6316 | m_pQuickHlpData->Start(m_rView.GetWrtShell(), true); | ||||
6317 | } | ||||
6318 | return !m_pQuickHlpData->m_aHelpStrings.empty(); | ||||
6319 | } | ||||
6320 | |||||
6321 | void SwEditWin::ShowAutoCorrectQuickHelp( | ||||
6322 | const OUString& rWord, SvxAutoCorrect& rACorr ) | ||||
6323 | { | ||||
6324 | if (rWord.isEmpty()) | ||||
6325 | return; | ||||
6326 | SwWrtShell& rSh = m_rView.GetWrtShell(); | ||||
6327 | m_pQuickHlpData->ClearContent(); | ||||
6328 | |||||
6329 | if( m_pQuickHlpData->m_aHelpStrings.empty() && | ||||
6330 | rACorr.GetSwFlags().bAutoCompleteWords ) | ||||
6331 | { | ||||
6332 | m_pQuickHlpData->m_bIsAutoText = false; | ||||
6333 | m_pQuickHlpData->m_bIsTip = rACorr.GetSwFlags().bAutoCmpltShowAsTip; | ||||
6334 | |||||
6335 | // Get the necessary data to show help text. | ||||
6336 | m_pQuickHlpData->FillStrArr( rSh, rWord ); | ||||
6337 | } | ||||
6338 | |||||
6339 | if( !m_pQuickHlpData->m_aHelpStrings.empty() ) | ||||
6340 | { | ||||
6341 | m_pQuickHlpData->SortAndFilter(rWord); | ||||
6342 | m_pQuickHlpData->Start(rSh, true); | ||||
6343 | } | ||||
6344 | } | ||||
6345 | |||||
6346 | bool SwEditWin::IsInHeaderFooter( const Point &rDocPt, FrameControlType &rControl ) const | ||||
6347 | { | ||||
6348 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
6349 | const SwPageFrame* pPageFrame = rSh.GetLayout()->GetPageAtPos( rDocPt ); | ||||
6350 | |||||
6351 | if ( pPageFrame && pPageFrame->IsOverHeaderFooterArea( rDocPt, rControl ) ) | ||||
6352 | return true; | ||||
6353 | |||||
6354 | if ( rSh.IsShowHeaderFooterSeparator( FrameControlType::Header ) || rSh.IsShowHeaderFooterSeparator( FrameControlType::Footer ) ) | ||||
6355 | { | ||||
6356 | SwFrameControlsManager &rMgr = rSh.GetView().GetEditWin().GetFrameControlsManager(); | ||||
6357 | Point aPoint( LogicToPixel( rDocPt ) ); | ||||
6358 | |||||
6359 | if ( rSh.IsShowHeaderFooterSeparator( FrameControlType::Header ) ) | ||||
6360 | { | ||||
6361 | SwFrameControlPtr pControl = rMgr.GetControl( FrameControlType::Header, pPageFrame ); | ||||
6362 | if ( pControl && pControl->Contains( aPoint ) ) | ||||
6363 | { | ||||
6364 | rControl = FrameControlType::Header; | ||||
6365 | return true; | ||||
6366 | } | ||||
6367 | } | ||||
6368 | |||||
6369 | if ( rSh.IsShowHeaderFooterSeparator( FrameControlType::Footer ) ) | ||||
6370 | { | ||||
6371 | SwFrameControlPtr pControl = rMgr.GetControl( FrameControlType::Footer, pPageFrame ); | ||||
6372 | if ( pControl && pControl->Contains( aPoint ) ) | ||||
6373 | { | ||||
6374 | rControl = FrameControlType::Footer; | ||||
6375 | return true; | ||||
6376 | } | ||||
6377 | } | ||||
6378 | } | ||||
6379 | |||||
6380 | return false; | ||||
6381 | } | ||||
6382 | |||||
6383 | bool SwEditWin::IsOverHeaderFooterFly( const Point& rDocPos, FrameControlType& rControl, bool& bOverFly, bool& bPageAnchored ) const | ||||
6384 | { | ||||
6385 | bool bRet = false; | ||||
6386 | Point aPt( rDocPos ); | ||||
6387 | SwWrtShell &rSh = m_rView.GetWrtShell(); | ||||
6388 | SwPaM aPam( *rSh.GetCurrentShellCursor().GetPoint() ); | ||||
6389 | rSh.GetLayout()->GetModelPositionForViewPoint( aPam.GetPoint(), aPt, nullptr, true ); | ||||
6390 | |||||
6391 | const SwStartNode* pStartFly = aPam.GetPoint()->nNode.GetNode().FindFlyStartNode(); | ||||
6392 | if ( pStartFly ) | ||||
6393 | { | ||||
6394 | bOverFly = true; | ||||
6395 | SwFrameFormat* pFlyFormat = pStartFly->GetFlyFormat( ); | ||||
6396 | if ( pFlyFormat ) | ||||
6397 | { | ||||
6398 | const SwPosition* pAnchor = pFlyFormat->GetAnchor( ).GetContentAnchor( ); | ||||
6399 | if ( pAnchor ) | ||||
6400 | { | ||||
6401 | bool bInHeader = pAnchor->nNode.GetNode( ).FindHeaderStartNode( ) != nullptr; | ||||
6402 | bool bInFooter = pAnchor->nNode.GetNode( ).FindFooterStartNode( ) != nullptr; | ||||
6403 | |||||
6404 | bRet = bInHeader || bInFooter; | ||||
6405 | if ( bInHeader ) | ||||
6406 | rControl = FrameControlType::Header; | ||||
6407 | else if ( bInFooter ) | ||||
6408 | rControl = FrameControlType::Footer; | ||||
6409 | } | ||||
6410 | else | ||||
6411 | bPageAnchored = pFlyFormat->GetAnchor( ).GetAnchorId( ) == RndStdIds::FLY_AT_PAGE; | ||||
6412 | } | ||||
6413 | } | ||||
6414 | else | ||||
6415 | bOverFly = false; | ||||
6416 | return bRet; | ||||
6417 | } | ||||
6418 | |||||
6419 | void SwEditWin::SetUseInputLanguage( bool bNew ) | ||||
6420 | { | ||||
6421 | if ( bNew || m_bUseInputLanguage ) | ||||
6422 | { | ||||
6423 | SfxBindings& rBind = GetView().GetViewFrame()->GetBindings(); | ||||
6424 | rBind.Invalidate( SID_ATTR_CHAR_FONT( 10000 + 7 ) ); | ||||
6425 | rBind.Invalidate( SID_ATTR_CHAR_FONTHEIGHT( 10000 + 15 ) ); | ||||
6426 | } | ||||
6427 | m_bUseInputLanguage = bNew; | ||||
6428 | } | ||||
6429 | |||||
6430 | OUString SwEditWin::GetSurroundingText() const | ||||
6431 | { | ||||
6432 | OUString sReturn; | ||||
6433 | SwWrtShell& rSh = m_rView.GetWrtShell(); | ||||
6434 | if( rSh.HasSelection() && !rSh.IsMultiSelection() && rSh.IsSelOnePara() ) | ||||
6435 | rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR ); | ||||
6436 | else if( !rSh.HasSelection() ) | ||||
6437 | { | ||||
6438 | SwPosition *pPos = rSh.GetCursor()->GetPoint(); | ||||
6439 | const sal_Int32 nPos = pPos->nContent.GetIndex(); | ||||
6440 | |||||
6441 | // get the sentence around the cursor | ||||
6442 | rSh.HideCursor(); | ||||
6443 | rSh.GoStartSentence(); | ||||
6444 | rSh.SetMark(); | ||||
6445 | rSh.GoEndSentence(); | ||||
6446 | rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR ); | ||||
6447 | |||||
6448 | pPos->nContent = nPos; | ||||
6449 | rSh.ClearMark(); | ||||
6450 | rSh.HideCursor(); | ||||
6451 | } | ||||
6452 | |||||
6453 | return sReturn; | ||||
6454 | } | ||||
6455 | |||||
6456 | Selection SwEditWin::GetSurroundingTextSelection() const | ||||
6457 | { | ||||
6458 | SwWrtShell& rSh = m_rView.GetWrtShell(); | ||||
6459 | if( rSh.HasSelection() ) | ||||
6460 | { | ||||
6461 | OUString sReturn; | ||||
6462 | rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR ); | ||||
6463 | return Selection( 0, sReturn.getLength() ); | ||||
6464 | } | ||||
6465 | else | ||||
6466 | { | ||||
6467 | // Return the position of the visible cursor in the sentence | ||||
6468 | // around the visible cursor. | ||||
6469 | SwPosition *pPos = rSh.GetCursor()->GetPoint(); | ||||
6470 | const sal_Int32 nPos = pPos->nContent.GetIndex(); | ||||
6471 | |||||
6472 | rSh.HideCursor(); | ||||
6473 | rSh.GoStartSentence(); | ||||
6474 | const sal_Int32 nStartPos = rSh.GetCursor()->GetPoint()->nContent.GetIndex(); | ||||
6475 | |||||
6476 | pPos->nContent = nPos; | ||||
6477 | rSh.ClearMark(); | ||||
6478 | rSh.ShowCursor(); | ||||
6479 | |||||
6480 | return Selection( nPos - nStartPos, nPos - nStartPos ); | ||||
6481 | } | ||||
6482 | } | ||||
6483 | |||||
6484 | void SwEditWin::LogicInvalidate(const tools::Rectangle* pRectangle) | ||||
6485 | { | ||||
6486 | OString sRectangle; | ||||
6487 | if (!pRectangle) | ||||
6488 | sRectangle = "EMPTY"; | ||||
6489 | else | ||||
6490 | sRectangle = pRectangle->toString(); | ||||
6491 | |||||
6492 | SfxLokHelper::notifyInvalidation(&m_rView, sRectangle); | ||||
6493 | } | ||||
6494 | |||||
6495 | void SwEditWin::LogicMouseButtonDown(const MouseEvent& rMouseEvent) | ||||
6496 | { | ||||
6497 | // When we're not doing tiled rendering, then positions must be passed as pixels. | ||||
6498 | assert(comphelper::LibreOfficeKit::isActive())(static_cast <bool> (comphelper::LibreOfficeKit::isActive ()) ? void (0) : __assert_fail ("comphelper::LibreOfficeKit::isActive()" , "/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" , 6498, __extension__ __PRETTY_FUNCTION__)); | ||||
6499 | |||||
6500 | Point aPoint = GetPointerPosPixel(); | ||||
6501 | SetLastMousePos(rMouseEvent.GetPosPixel()); | ||||
6502 | |||||
6503 | MouseButtonDown(rMouseEvent); | ||||
6504 | |||||
6505 | SetPointerPosPixel(aPoint); | ||||
6506 | } | ||||
6507 | |||||
6508 | void SwEditWin::LogicMouseButtonUp(const MouseEvent& rMouseEvent) | ||||
6509 | { | ||||
6510 | // When we're not doing tiled rendering, then positions must be passed as pixels. | ||||
6511 | assert(comphelper::LibreOfficeKit::isActive())(static_cast <bool> (comphelper::LibreOfficeKit::isActive ()) ? void (0) : __assert_fail ("comphelper::LibreOfficeKit::isActive()" , "/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" , 6511, __extension__ __PRETTY_FUNCTION__)); | ||||
6512 | |||||
6513 | Point aPoint = GetPointerPosPixel(); | ||||
6514 | SetLastMousePos(rMouseEvent.GetPosPixel()); | ||||
6515 | |||||
6516 | MouseButtonUp(rMouseEvent); | ||||
6517 | |||||
6518 | SetPointerPosPixel(aPoint); | ||||
6519 | } | ||||
6520 | |||||
6521 | void SwEditWin::LogicMouseMove(const MouseEvent& rMouseEvent) | ||||
6522 | { | ||||
6523 | // When we're not doing tiled rendering, then positions must be passed as pixels. | ||||
6524 | assert(comphelper::LibreOfficeKit::isActive())(static_cast <bool> (comphelper::LibreOfficeKit::isActive ()) ? void (0) : __assert_fail ("comphelper::LibreOfficeKit::isActive()" , "/home/maarten/src/libreoffice/core/sw/source/uibase/docvw/edtwin.cxx" , 6524, __extension__ __PRETTY_FUNCTION__)); | ||||
6525 | |||||
6526 | Point aPoint = GetPointerPosPixel(); | ||||
6527 | SetLastMousePos(rMouseEvent.GetPosPixel()); | ||||
6528 | |||||
6529 | MouseMove(rMouseEvent); | ||||
6530 | |||||
6531 | SetPointerPosPixel(aPoint); | ||||
6532 | } | ||||
6533 | |||||
6534 | void SwEditWin::SetCursorTwipPosition(const Point& rPosition, bool bPoint, bool bClearMark) | ||||
6535 | { | ||||
6536 | if (SdrView* pSdrView = m_rView.GetWrtShell().GetDrawView()) | ||||
6537 | { | ||||
6538 | // Editing shape text, then route the call to editeng. | ||||
6539 | if (pSdrView->GetTextEditObject()) | ||||
6540 | { | ||||
6541 | EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView(); | ||||
6542 | rEditView.SetCursorLogicPosition(rPosition, bPoint, bClearMark); | ||||
6543 | return; | ||||
6544 | } | ||||
6545 | } | ||||
6546 | |||||
6547 | if (m_rView.GetPostItMgr()) | ||||
6548 | { | ||||
6549 | if (sw::annotation::SwAnnotationWin* pWin = m_rView.GetPostItMgr()->GetActiveSidebarWin()) | ||||
6550 | { | ||||
6551 | // Editing postit text. | ||||
6552 | pWin->SetCursorLogicPosition(rPosition, bPoint, bClearMark); | ||||
6553 | return; | ||||
6554 | } | ||||
6555 | } | ||||
6556 | |||||
6557 | // Not an SwWrtShell, as that would make SwCursorShell::GetCursor() inaccessible. | ||||
6558 | SwEditShell& rShell = m_rView.GetWrtShell(); | ||||
6559 | |||||
6560 | bool bCreateSelection = false; | ||||
6561 | { | ||||
6562 | SwMvContext aMvContext(&rShell); | ||||
6563 | if (bClearMark) | ||||
6564 | rShell.ClearMark(); | ||||
6565 | else | ||||
6566 | bCreateSelection = !rShell.HasMark(); | ||||
6567 | |||||
6568 | if (bCreateSelection) | ||||
6569 | m_rView.GetWrtShell().SttSelect(); | ||||
6570 | |||||
6571 | // If the mark is to be updated, then exchange the point and mark before | ||||
6572 | // and after, as we can't easily set the mark. | ||||
6573 | if (!bPoint) | ||||
6574 | rShell.getShellCursor(/*bBlock=*/false)->Exchange(); | ||||
6575 | rShell.SetCursor(rPosition); | ||||
6576 | if (!bPoint) | ||||
6577 | rShell.getShellCursor(/*bBlock=*/false)->Exchange(); | ||||
6578 | } | ||||
6579 | |||||
6580 | if (bCreateSelection) | ||||
6581 | m_rView.GetWrtShell().EndSelect(); | ||||
6582 | } | ||||
6583 | |||||
6584 | void SwEditWin::SetGraphicTwipPosition(bool bStart, const Point& rPosition) | ||||
6585 | { | ||||
6586 | if (bStart) | ||||
6587 | { | ||||
6588 | MouseEvent aClickEvent(rPosition, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT(sal_uInt16(0x0001))); | ||||
6589 | MouseButtonDown(aClickEvent); | ||||
6590 | MouseEvent aMoveEvent(Point(rPosition.getX() + MIN_MOVE4 + 1, rPosition.getY()), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT(sal_uInt16(0x0001))); | ||||
6591 | MouseMove(aMoveEvent); | ||||
6592 | } | ||||
6593 | else | ||||
6594 | { | ||||
6595 | MouseEvent aMoveEvent(Point(rPosition.getX() - MIN_MOVE4 - 1, rPosition.getY()), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT(sal_uInt16(0x0001))); | ||||
6596 | MouseMove(aMoveEvent); | ||||
6597 | MouseEvent aClickEvent(rPosition, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT(sal_uInt16(0x0001))); | ||||
6598 | MouseButtonUp(aClickEvent); | ||||
6599 | } | ||||
6600 | } | ||||
6601 | |||||
6602 | void SwEditWin::SetOutlineContentVisibilityButtons() | ||||
6603 | { | ||||
6604 | SwWrtShell& rSh = m_rView.GetWrtShell(); | ||||
6605 | const SwOutlineNodes& rOutlineNodes = rSh.GetDoc()->GetNodes().GetOutLineNds(); | ||||
6606 | if (!rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) | ||||
6607 | { | ||||
6608 | for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNodes.size(); ++nPos) | ||||
6609 | { | ||||
6610 | bool bOutlineContentVisibleAttr = true; | ||||
6611 | rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); | ||||
6612 | if (!bOutlineContentVisibleAttr) | ||||
6613 | { | ||||
6614 | // unfold and then set outline content visible attr to false for persistence | ||||
6615 | rSh.ToggleOutlineContentVisibility(nPos); | ||||
6616 | rOutlineNodes[nPos]->GetTextNode()->SetAttrOutlineContentVisible(false); | ||||
6617 | } | ||||
6618 | } | ||||
6619 | GetFrameControlsManager().HideControls(FrameControlType::Outline); | ||||
6620 | } | ||||
6621 | else | ||||
6622 | { | ||||
6623 | for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNodes.size(); ++nPos) | ||||
6624 | { | ||||
6625 | bool bOutlineContentVisibleAttr = true; | ||||
6626 | rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); | ||||
6627 | if (!bOutlineContentVisibleAttr) | ||||
6628 | rSh.ToggleOutlineContentVisibility(nPos, true); | ||||
6629 | } | ||||
6630 | } | ||||
6631 | GetView().Invalidate(); // set state of dependent slots (FN_TOGGLE_OUTLINE_CONTENT_VISIBILITY) | ||||
6632 | } | ||||
6633 | |||||
6634 | SwFrameControlsManager& SwEditWin::GetFrameControlsManager() | ||||
6635 | { | ||||
6636 | return *m_pFrameControlsManager; | ||||
6637 | } | ||||
6638 | |||||
6639 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_SW_INC_VIEWSH_HXX |
20 | #define INCLUDED_SW_INC_VIEWSH_HXX |
21 | |
22 | #include "swdllapi.h" |
23 | #include "swtypes.hxx" |
24 | #include "ring.hxx" |
25 | #include "swrect.hxx" |
26 | #include <memory> |
27 | #include <stack> |
28 | #include <vcl/mapmod.hxx> |
29 | #include <vcl/vclptr.hxx> |
30 | #include <vcl/lazydelete.hxx> |
31 | #include <vcl/window.hxx> |
32 | |
33 | namespace com::sun::star::accessibility { class XAccessible; } |
34 | class SwDoc; |
35 | class IDocumentSettingAccess; |
36 | class IDocumentDeviceAccess; |
37 | class IDocumentMarkAccess; |
38 | class IDocumentDrawModelAccess; |
39 | class IDocumentRedlineAccess; |
40 | class IDocumentLayoutAccess; |
41 | class IDocumentContentOperations; |
42 | class IDocumentStylePoolAccess; |
43 | class IDocumentStatistics; |
44 | class IDocumentUndoRedo; |
45 | class IDocumentListItems; |
46 | class IDocumentOutlineNodes; |
47 | class SfxPrinter; |
48 | class SwRootFrame; |
49 | class SwNodes; |
50 | class SdrView; |
51 | class SfxItemPool; |
52 | class SfxViewShell; |
53 | class SwViewOption; |
54 | class SwViewShellImp; |
55 | class SwPrintData; |
56 | struct ShellResource; |
57 | class SwRegionRects; |
58 | class SvtAccessibilityOptions; |
59 | class SwPagePreviewLayout; |
60 | class SwTextFrame; |
61 | |
62 | struct SwAccessibilityOptions; |
63 | namespace vcl { class Region; } |
64 | class SwPostItMgr; |
65 | class SdrPaintWindow; |
66 | class SwAccessibleMap; |
67 | enum class Orientation; |
68 | |
69 | namespace vcl |
70 | { |
71 | typedef OutputDevice RenderContext; |
72 | } |
73 | |
74 | // Define for flags needed in ctor or layers below. |
75 | // Currently the Preview flag is needed for DrawPage. |
76 | #define VSHELLFLAG_ISPREVIEW(long(0x1)) (long(0x1)) |
77 | #define VSHELLFLAG_SHARELAYOUT(long(0x2)) (long(0x2)) |
78 | typedef std::shared_ptr<SwRootFrame> SwRootFramePtr; |
79 | |
80 | typedef struct _xmlTextWriter* xmlTextWriterPtr; |
81 | |
82 | class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwViewShell : public sw::Ring<SwViewShell> |
83 | { |
84 | friend void SetOutDev( SwViewShell *pSh, OutputDevice *pOut ); |
85 | friend void SetOutDevAndWin( SwViewShell *pSh, OutputDevice *pOut, |
86 | vcl::Window *pWin, sal_uInt16 nZoom ); |
87 | |
88 | friend class SwViewShellImp; |
89 | friend class SwLayIdle; |
90 | |
91 | // For setting visible area for page preview paint. |
92 | friend class SwPagePreviewLayout; |
93 | |
94 | // Set SwVisArea in order to enable clean formatting before printing. |
95 | friend void SetSwVisArea( SwViewShell *pSh, const SwRect & ); |
96 | |
97 | std::unique_ptr<BitmapEx> m_xReplaceBmp; ///< replaced display of still loaded images |
98 | std::unique_ptr<BitmapEx> m_xErrorBmp; ///< error display of missed images |
99 | |
100 | static bool mbLstAct; // true if EndAction of last Shell |
101 | // i.e. if the EndActions of the other |
102 | // Shells on the document are through. |
103 | |
104 | Point maPrtOffset; // Offset for Printer, |
105 | // non-printable margin. |
106 | Size maBrowseBorder; // Border for frame documents. |
107 | SwRect maInvalidRect; |
108 | |
109 | SfxViewShell *mpSfxViewShell; |
110 | std::unique_ptr<SwViewShellImp> |
111 | mpImp; // Core-internals of SwViewShell. |
112 | // The pointer is never 0. |
113 | |
114 | VclPtr<vcl::Window> mpWin; ///< = 0 during printing or pdf export |
115 | VclPtr<OutputDevice> mpOut; ///< Window, Printer, VirtDev, ... |
116 | |
117 | std::unique_ptr<SwViewOption> mpOpt; |
118 | std::unique_ptr<SwAccessibilityOptions> mpAccOptions; |
119 | |
120 | bool mbDocSizeChgd :1; // For DocChgNotify(): Announce new DocSize |
121 | // at EndAction to DocMDI. |
122 | bool mbPaintWorks :1; // Normal Painting if true, |
123 | // remember Paint if false. |
124 | bool mbPaintInProgress :1; // Block any double paint. |
125 | bool mbViewLocked :1; // Lock visible range; |
126 | // in this case MakeVisible is ineffectual. |
127 | bool mbInEndAction :1; // Avoid problems, cf. viewsh.cxx. |
128 | bool mbPreview :1; // If true it is a Preview-SwViewShell. |
129 | bool mbFrameView :1; // If true it is a (HTML-)Frame. |
130 | bool mbEnableSmooth :1; // Disable SmoothScroll, e.g. for drag |
131 | // of scrollbars. |
132 | bool mbEndActionByVirDev:1; // Paints from EndAction always via virtual device |
133 | // (e.g. when browsing). |
134 | bool mbShowHeaderSeparator:1; ///< Flag to say that we are showing the header control |
135 | bool mbShowFooterSeparator:1; ///< Flag to say that we are showing the footer control |
136 | bool mbHeaderFooterEdit:1; ///< Flag to say that we are editing header or footer (according to the bShow(Header|Footer)Separator above) |
137 | |
138 | // boolean, indicating that class in constructor. |
139 | bool mbInConstructor:1; |
140 | |
141 | SdrPaintWindow* mpTargetPaintWindow; |
142 | VclPtr<OutputDevice> mpBufferedOut; |
143 | |
144 | SwRootFramePtr mpLayout; |
145 | |
146 | // Initialization; called by the diverse constructors. |
147 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void Init( const SwViewOption *pNewOpt ); |
148 | |
149 | inline void ResetInvalidRect(); |
150 | |
151 | |
152 | |
153 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void PaintDesktop(vcl::RenderContext& rRenderContext, const SwRect&); // Collect values for painting of desktop |
154 | // and calling. |
155 | // PaintDesktop split. This pars is also used by PreviewPage. |
156 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void PaintDesktop_(const SwRegionRects &rRegion); |
157 | |
158 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) bool CheckInvalidForPaint( const SwRect & ); // Direct Paint or rather |
159 | // trigger an action. |
160 | |
161 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void PrepareForPrint( const SwPrintData &rOptions, bool bIsPDFExport = false ); |
162 | |
163 | SAL_DLLPRIVATE__attribute__ ((visibility("hidden"))) void ImplApplyViewOptions( const SwViewOption &rOpt ); |
164 | |
165 | protected: |
166 | static ShellResource* mpShellRes; ///< Resources for the Shell. |
167 | static vcl::DeleteOnDeinit< std::shared_ptr<weld::Window> > mpCareDialog; ///< Avoid this window. |
168 | |
169 | SwRect maVisArea; ///< The modern version of VisArea. |
170 | tools::Rectangle maLOKVisibleArea;///< The visible area in the LibreOfficeKit client. |
171 | rtl::Reference<SwDoc> mxDoc; ///< The document; never 0. |
172 | |
173 | sal_uInt16 mnStartAction; ///< != 0 if at least one Action is active. |
174 | sal_uInt16 mnLockPaint; ///< != 0 if Paint is locked. |
175 | bool mbSelectAll; ///< Special select all mode: whole document selected, even if doc starts with table. |
176 | |
177 | /// The virtual device we paint to will end up on the screen. |
178 | bool mbOutputToWindow; |
179 | |
180 | public: |
181 | |
182 | SwViewShellImp *Imp() { return mpImp.get(); } |
183 | const SwViewShellImp *Imp() const { return mpImp.get(); } |
184 | |
185 | const SwNodes& GetNodes() const; |
186 | |
187 | // After change of printer; by Doc. |
188 | void InitPrt( OutputDevice *pOutDev ); |
189 | |
190 | // Bracketing of actions belonging together. |
191 | inline void StartAction(); |
192 | void ImplStartAction(); |
193 | inline void EndAction( const bool bIdleEnd = false ); |
194 | void ImplEndAction( const bool bIdleEnd ); |
195 | sal_uInt16 ActionCount() const { return mnStartAction; } |
196 | bool ActionPend() const { return mnStartAction != 0; } |
197 | bool IsInEndAction() const { return mbInEndAction; } |
198 | |
199 | void SetEndActionByVirDev( bool b ) { mbEndActionByVirDev = b; } |
200 | bool IsEndActionByVirDev() const { return mbEndActionByVirDev; } |
201 | |
202 | // The ActionCount for all Shells is temporarily set to zero and then |
203 | // restored at the RootFrame via UNO. |
204 | void SetRestoreActions(sal_uInt16 nSet); |
205 | sal_uInt16 GetRestoreActions() const; |
206 | |
207 | bool HasInvalidRect() const { return maInvalidRect.HasArea(); } |
208 | void ChgHyphenation() { Reformat(); } |
209 | void ChgNumberDigits(); |
210 | |
211 | bool AddPaintRect( const SwRect &rRect ); |
212 | |
213 | void InvalidateWindows( const SwRect &rRect ); |
214 | |
215 | /// Invalidates complete Layout (ApplyViewOption). |
216 | void Reformat(); |
217 | |
218 | // #i72754# set of Pre/PostPaints with lock counter and initial target OutDev |
219 | protected: |
220 | std::stack<vcl::Region> mPrePostPaintRegions; // acts also as a lock counter (empty == not locked) |
221 | VclPtr<OutputDevice> mpPrePostOutDev; |
222 | MapMode maPrePostMapMode; |
223 | public: |
224 | void PrePaint(); |
225 | void DLPrePaint2(const vcl::Region& rRegion); |
226 | void DLPostPaint2(bool bPaintFormLayer); |
227 | const MapMode& getPrePostMapMode() const { return maPrePostMapMode; } |
228 | |
229 | virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle &rRect); |
230 | |
231 | /** Paint tile. |
232 | |
233 | Sets the pOut so that the rRect is always painted over the entire |
234 | pOut, ie. starts in 0,0 and ends in width/height. |
235 | */ |
236 | void PaintTile(VirtualDevice &rDevice, int contextWidth, int contextHeight, int tilePosX, int tilePosY, long tileWidth, long tileHeight); |
237 | |
238 | bool IsPaintInProgress() const { return mbPaintInProgress; } |
239 | bool IsDrawingLayerPaintInProgress() const { return !mPrePostPaintRegions.empty(); } |
240 | |
241 | // Notification that visible area has been changed. |
242 | // VisArea is reset, after that scrolling takes place. |
243 | // The passed rect is situated on pixel borders |
244 | // in order to avoid pixel errors when scrolling. |
245 | virtual void VisPortChgd( const SwRect & ); |
246 | bool SmoothScroll( long lXDiff, long lYDiff, const tools::Rectangle* );//Browser |
247 | void EnableSmooth( bool b ) { mbEnableSmooth = b; } |
248 | |
249 | const SwRect& VisArea() const; |
250 | |
251 | /// The visible area in the client (set by setClientVisibleArea). |
252 | const tools::Rectangle & getLOKVisibleArea() const { return maLOKVisibleArea; } |
253 | void setLOKVisibleArea(const tools::Rectangle& rArea) { maLOKVisibleArea = rArea; } |
254 | |
255 | // If necessary scroll until passed Rect is situated in visible sector. |
256 | void MakeVisible( const SwRect & ); |
257 | |
258 | // At nearest occasion pass new document size to UI. |
259 | void SizeChgNotify(); |
260 | void UISizeNotify(); // Passing of current size. |
261 | |
262 | Point GetPagePos( sal_uInt16 nPageNum ) const; |
263 | |
264 | sal_uInt16 GetNumPages() const; // Ask count of current pages from layout. |
265 | bool IsDummyPage( sal_uInt16 nPageNum ) const; // An empty page? |
266 | |
267 | // Invalidate first visible page for all Shells in ring. |
268 | void SetFirstVisPageInvalid(); |
269 | |
270 | SwRootFrame *GetLayout() const; |
271 | bool IsNewLayout() const; // Has Layout been loaded or created? |
272 | |
273 | Size GetDocSize() const; // Get document size. |
274 | |
275 | virtual void CalcLayout(); // Force complete formatting of layout. |
276 | |
277 | sal_uInt16 GetPageCount() const; |
278 | |
279 | Size GetPageSize( sal_uInt16 nPageNum, bool bSkipEmptyPages ) const; |
280 | |
281 | SwDoc *GetDoc() const { return mxDoc.get(); } //Never 0. |
282 | |
283 | /** Provides access to the document setting interface |
284 | */ |
285 | const IDocumentSettingAccess& getIDocumentSettingAccess() const; |
286 | IDocumentSettingAccess& getIDocumentSettingAccess(); |
287 | |
288 | /** Provides access to the document device interface |
289 | */ |
290 | const IDocumentDeviceAccess& getIDocumentDeviceAccess() const; |
291 | IDocumentDeviceAccess& getIDocumentDeviceAccess(); |
292 | |
293 | /** Provides access to the document bookmark interface |
294 | */ |
295 | const IDocumentMarkAccess* getIDocumentMarkAccess() const; |
296 | IDocumentMarkAccess* getIDocumentMarkAccess(); |
297 | |
298 | /** Provides access to the document draw model interface |
299 | */ |
300 | const IDocumentDrawModelAccess& getIDocumentDrawModelAccess() const; |
301 | IDocumentDrawModelAccess& getIDocumentDrawModelAccess(); |
302 | |
303 | /** Provides access to the document redline interface |
304 | */ |
305 | const IDocumentRedlineAccess& getIDocumentRedlineAccess() const; |
306 | IDocumentRedlineAccess& getIDocumentRedlineAccess(); |
307 | |
308 | /** Provides access to the document layout interface |
309 | */ |
310 | const IDocumentLayoutAccess& getIDocumentLayoutAccess() const; |
311 | IDocumentLayoutAccess& getIDocumentLayoutAccess(); |
312 | |
313 | /** Provides access to the content operations interface |
314 | */ |
315 | IDocumentContentOperations& getIDocumentContentOperations(); |
316 | |
317 | /** Provides access to the document style pool interface |
318 | */ |
319 | IDocumentStylePoolAccess& getIDocumentStylePoolAccess(); |
320 | |
321 | /** Provides access to the document statistics interface |
322 | */ |
323 | const IDocumentStatistics& getIDocumentStatistics() const; |
324 | |
325 | /** Provides access to the document undo/redo interface |
326 | */ |
327 | IDocumentUndoRedo const& GetIDocumentUndoRedo() const; |
328 | IDocumentUndoRedo & GetIDocumentUndoRedo(); |
329 | |
330 | const IDocumentListItems* getIDocumentListItemsAccess() const; |
331 | const IDocumentOutlineNodes* getIDocumentOutlineNodesAccess() const; |
332 | |
333 | // 1. GetRefDev: Either the printer or the virtual device from the doc |
334 | // 2. GetWin: Available if we not printing |
335 | // 3. GetOut: Printer, Window or Virtual device |
336 | vcl::RenderContext& GetRefDev() const; |
337 | vcl::Window* GetWin() const { return mpWin; } |
338 | vcl::RenderContext* GetOut() const { return mpOut; } |
339 | |
340 | void SetWin(vcl::Window* win) { mpWin = win; } |
341 | void SetOut(vcl::RenderContext* pOut) { mpOut = pOut; } |
342 | static bool IsLstEndAction() { return SwViewShell::mbLstAct; } |
343 | |
344 | // Change of all page descriptors. |
345 | void ChgAllPageOrientation( Orientation eOri ); |
346 | void ChgAllPageSize( Size const &rSz ); |
347 | |
348 | // Printing of one page. |
349 | // bIsPDFExport == true is: do PDF Export (no printing!) |
350 | bool PrintOrPDFExport( OutputDevice *pOutDev, |
351 | SwPrintData const& rPrintData, |
352 | sal_Int32 nRenderer, /* offset in vector of pages to print */ |
353 | bool bIsPDFExport ); |
354 | |
355 | // Printing of one brochure page. |
356 | void PrintProspect( OutputDevice *pOutDev, const SwPrintData &rPrintData, |
357 | sal_Int32 nRenderer /* offset in vector of page pairs for prospect printing */ ); |
358 | |
359 | // Printing for OLE 2.0. |
360 | static void PrtOle2( SwDoc *pDoc, const SwViewOption *pOpt, const SwPrintData& rOptions, |
361 | vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ); |
362 | |
363 | // Fill temporary doc with selected text for Print or PDF export. |
364 | void FillPrtDoc( SwDoc& rPrtDoc, const SfxPrinter* pPrt ); |
365 | |
366 | // Called internally for Shell. Formats pages. |
367 | void CalcPagesForPrint( sal_uInt16 nMax ); |
368 | |
369 | // All about fields. |
370 | void UpdateFields(bool bCloseDB = false); |
371 | bool IsAnyFieldInDoc() const; |
372 | // Update all charts, for that exists any table. |
373 | void UpdateAllCharts(); |
374 | bool HasCharts() const; |
375 | |
376 | // DOCUMENT COMPATIBILITY FLAGS START |
377 | |
378 | // Add or maximize paragraph spacing? |
379 | void SetParaSpaceMax( bool bNew ); |
380 | |
381 | // Add or maximize paragraph spacing? |
382 | void SetParaSpaceMaxAtPages( bool bNew ); |
383 | |
384 | // Compatible behaviour of tabs. |
385 | void SetTabCompat( bool bNew ); |
386 | |
387 | // Font metric attribute "External Leading" should be considered. |
388 | void SetAddExtLeading( bool bNew ); |
389 | |
390 | // Formatting by virtual device or printer. |
391 | void SetUseVirDev( bool bNew ); |
392 | |
393 | // Adding paragraph and table spacing at bottom |
394 | // of table cells. |
395 | void SetAddParaSpacingToTableCells( bool _bAddParaSpacingToTableCells ); |
396 | |
397 | // Former formatting of text lines with |
398 | // proportional line spacing or not. |
399 | void SetUseFormerLineSpacing( bool _bUseFormerLineSpacing ); |
400 | |
401 | // Former object positioning. |
402 | void SetUseFormerObjectPositioning( bool _bUseFormerObjPos ); |
403 | |
404 | void SetConsiderWrapOnObjPos( bool _bConsiderWrapOnObjPos ); |
405 | |
406 | void SetUseFormerTextWrapping( bool _bUseFormerTextWrapping ); |
407 | |
408 | void SetDoNotJustifyLinesWithManualBreak( bool _bDoNotJustifyLinesWithManualBreak ); |
409 | |
410 | void SetProtectForm( bool _bProtectForm ); |
411 | |
412 | void SetMsWordCompTrailingBlanks( bool _bMsWordCompTrailingBlanks ); |
413 | |
414 | void SetSubtractFlysAnchoredAtFlys(bool bSubtractFlysAnchoredAtFlys); |
415 | |
416 | void SetEmptyDbFieldHidesPara(bool bEmptyDbFieldHidesPara); |
417 | |
418 | // DOCUMENT COMPATIBILITY FLAGS END |
419 | |
420 | // Calls Idle-formatter of Layout. |
421 | void LayoutIdle(); |
422 | |
423 | const SwViewOption *GetViewOptions() const { return mpOpt.get(); } |
424 | virtual void ApplyViewOptions( const SwViewOption &rOpt ); |
425 | void SetUIOptions( const SwViewOption &rOpt ); |
426 | virtual void SetReadonlyOption(bool bSet); // Set readonly-bit of ViewOptions. |
427 | void SetPDFExportOption(bool bSet); // Set/reset PDF export mode. |
428 | void SetPrtFormatOption(bool bSet); // Set PrtFormat-Bit of ViewOptions. |
429 | void SetReadonlySelectionOption(bool bSet); // Change the selection mode in readonly docs. |
430 | |
431 | const SwAccessibilityOptions* GetAccessibilityOptions() const { return mpAccOptions.get();} |
432 | |
433 | static void SetShellRes( ShellResource* pRes ) { mpShellRes = pRes; } |
434 | static ShellResource* GetShellRes(); |
435 | |
436 | static weld::Window* CareChildWin(SwViewShell const & rVSh); |
437 | static void SetCareDialog(const std::shared_ptr<weld::Window>& rNew); |
438 | static weld::Window* GetCareDialog(SwViewShell const & rVSh) |
439 | { return (*mpCareDialog.get()) ? mpCareDialog.get()->get() : CareChildWin(rVSh); } |
440 | |
441 | SfxViewShell *GetSfxViewShell() const { return mpSfxViewShell; } |
442 | void SetSfxViewShell(SfxViewShell *pNew) { mpSfxViewShell = pNew; } |
443 | |
444 | // Selection of Draw Engine has been changed. |
445 | virtual void DrawSelChanged(); |
446 | |
447 | SwPagePreviewLayout* PagePreviewLayout(); |
448 | |
449 | /** adjust view options for page preview |
450 | |
451 | Because page preview should show the document as it is printed - |
452 | page preview is print preview -, the view options are adjusted to the |
453 | same as for printing. |
454 | |
455 | @param _rPrintOptions |
456 | input parameter - constant reference to print options, to which the |
457 | view option will be adjusted. |
458 | */ |
459 | void AdjustOptionsForPagePreview( SwPrintData const& rPrintOptions ); |
460 | |
461 | bool IsViewLocked() const { return mbViewLocked; } |
462 | void LockView( bool b ) { mbViewLocked = b; } |
463 | |
464 | inline void LockPaint(); |
465 | void ImplLockPaint(); |
466 | inline void UnlockPaint( bool bVirDev = false ); |
467 | void ImplUnlockPaint( bool bVirDev ); |
468 | bool IsPaintLocked() const { return mnLockPaint != 0; } |
469 | |
470 | // Get/set DrawView and PageView. |
471 | bool HasDrawView() const; |
472 | void MakeDrawView(); |
473 | |
474 | // Are we dragging draw shapes around. |
475 | bool HasDrawViewDrag() const; |
476 | |
477 | // DrawView may be used at UI. |
478 | SdrView *GetDrawView(); |
479 | const SdrView *GetDrawView() const { return const_cast<SwViewShell*>(this)->GetDrawView(); } |
480 | |
481 | // Take care that MarkList is up-to-date in any case (Bug 57153). |
482 | SdrView *GetDrawViewWithValidMarkList(); |
483 | |
484 | // Query attribute pool. |
485 | inline const SfxItemPool& GetAttrPool() const; |
486 | SfxItemPool& GetAttrPool(); |
487 | |
488 | bool IsPreview() const { return mbPreview; } |
489 | |
490 | bool IsFrameView() const { return mbFrameView; } |
491 | |
492 | // Invalidates pages and contents. |
493 | // When bSizeChanged==true, adds/removes |
494 | // headers and footers as necessary. |
495 | void InvalidateLayout(bool bSizeChanged); |
496 | |
497 | const Size& GetBrowseBorder() const; |
498 | sal_Int32 GetBrowseWidth() const; |
499 | void SetBrowseBorder( const Size& rNew ); |
500 | |
501 | css::uno::Reference< css::accessibility::XAccessible > CreateAccessible(); |
502 | |
503 | css::uno::Reference< css::accessibility::XAccessible > CreateAccessiblePreview(); |
504 | |
505 | void ShowPreviewSelection( sal_uInt16 nSelPage ); |
506 | void InvalidateAccessibleFocus(); |
507 | |
508 | // Apply Accessibility options. |
509 | void ApplyAccessibilityOptions(SvtAccessibilityOptions const & rAccessibilityOptions); |
510 | |
511 | /** invalidate CONTENT_FLOWS_FROM/_TO relation for paragraphs |
512 | |
513 | @param _pFromTextFrame |
514 | input parameter - paragraph frame, for which the relation CONTENT_FLOWS_FROM |
515 | has to be invalidated. |
516 | If NULL, no CONTENT_FLOWS_FROM relation has to be invalidated |
517 | |
518 | @param _pToTextFrame |
519 | input parameter - paragraph frame, for which the relation CONTENT_FLOWS_TO |
520 | has to be invalidated. |
521 | If NULL, no CONTENT_FLOWS_TO relation has to be invalidated |
522 | */ |
523 | void InvalidateAccessibleParaFlowRelation( const SwTextFrame* _pFromTextFrame, |
524 | const SwTextFrame* _pToTextFrame ); |
525 | |
526 | /** invalidate text selection for paragraphs |
527 | */ |
528 | void InvalidateAccessibleParaTextSelection(); |
529 | |
530 | /** invalidate attributes for paragraphs and paragraph's characters |
531 | |
532 | usage also for changes of the attributes of |
533 | paragraph's characters. |
534 | |
535 | @param rTextFrame |
536 | input parameter - paragraph frame, whose attributes have changed |
537 | */ |
538 | void InvalidateAccessibleParaAttrs( const SwTextFrame& rTextFrame ); |
539 | |
540 | SwAccessibleMap* GetAccessibleMap(); |
541 | |
542 | SwViewShell( SwViewShell&, vcl::Window *pWin, OutputDevice *pOut = nullptr, |
543 | long nFlags = 0 ); |
544 | SwViewShell( SwDoc& rDoc, vcl::Window *pWin, |
545 | const SwViewOption *pOpt, OutputDevice *pOut = nullptr, |
546 | long nFlags = 0 ); |
547 | virtual ~SwViewShell() override; |
548 | |
549 | sal_Int32 GetPageNumAndSetOffsetForPDF( OutputDevice& rOut, const SwRect& rRect ) const; |
550 | |
551 | bool IsInConstructor() const { return mbInConstructor; } |
552 | |
553 | const BitmapEx& GetReplacementBitmap(bool bIsErrorState); |
554 | void DeleteReplacementBitmaps(); |
555 | |
556 | const SwPostItMgr* GetPostItMgr() const { return const_cast<SwViewShell*>(this)->GetPostItMgr(); } |
557 | SwPostItMgr* GetPostItMgr(); |
558 | |
559 | /// Acts both for headers / footers, depending on the bShow(Header|Footer)Separator flags |
560 | void ToggleHeaderFooterEdit(); |
561 | /// Acts both for headers / footers, depending on the bShow(Header|Footer)Separator flags |
562 | bool IsHeaderFooterEdit() const { return mbHeaderFooterEdit; } |
563 | bool IsShowHeaderFooterSeparator( FrameControlType eControl ) { return (eControl == FrameControlType::Header)? mbShowHeaderSeparator: mbShowFooterSeparator; } |
564 | virtual void SetShowHeaderFooterSeparator( FrameControlType eControl, bool bShow ); |
565 | bool IsSelectAll() const { return mbSelectAll; } |
566 | |
567 | void setOutputToWindow(bool bOutputToWindow); |
568 | bool isOutputToWindow() const; |
569 | |
570 | virtual void dumpAsXml(xmlTextWriterPtr pWriter) const; |
571 | }; |
572 | |
573 | // manages global ShellPointer |
574 | class CurrShell |
575 | { |
576 | public: |
577 | SwViewShell *pPrev; |
578 | SwRootFrame *pRoot; |
579 | |
580 | CurrShell( SwViewShell *pNew ); |
581 | ~CurrShell(); |
582 | }; |
583 | |
584 | inline void SwViewShell::ResetInvalidRect() |
585 | { |
586 | maInvalidRect.Clear(); |
587 | } |
588 | |
589 | inline void SwViewShell::StartAction() |
590 | { |
591 | if ( !mnStartAction++ ) |
592 | ImplStartAction(); |
593 | } |
594 | inline void SwViewShell::EndAction( const bool bIdleEnd ) |
595 | { |
596 | if( 0 == (mnStartAction - 1) ) |
597 | ImplEndAction( bIdleEnd ); |
598 | --mnStartAction; |
599 | } |
600 | |
601 | inline void SwViewShell::LockPaint() |
602 | { |
603 | if ( !mnLockPaint++ ) |
604 | ImplLockPaint(); |
605 | } |
606 | inline void SwViewShell::UnlockPaint( bool bVirDev ) |
607 | { |
608 | if ( 0 == --mnLockPaint ) |
609 | ImplUnlockPaint( bVirDev ); |
610 | } |
611 | inline const SfxItemPool& SwViewShell::GetAttrPool() const |
612 | { |
613 | return const_cast<SwViewShell*>(this)->GetAttrPool(); |
614 | } |
615 | |
616 | #endif // INCLUDED_SW_INC_VIEWSH_HXX |
617 | |
618 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |