File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 192, column 9 Use of memory after it is freed |
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 && m_xRowColumnSelectionStart ) | ||||||||
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 && bInsWin && !m_pApplyTempl && !rSh.IsInSelect() && changeMousePointer(aDocPt)) | ||||||||
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
| ||||||||
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
| ||||||||
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 | |
20 | #ifndef INCLUDED_VCL_PTR_HXX |
21 | #define INCLUDED_VCL_PTR_HXX |
22 | |
23 | #include <sal/config.h> |
24 | |
25 | #include <rtl/ref.hxx> |
26 | |
27 | #include <utility> |
28 | #include <type_traits> |
29 | |
30 | #ifdef DBG_UTIL |
31 | #ifndef _WIN32 |
32 | #include <vcl/vclmain.hxx> |
33 | #endif |
34 | #endif |
35 | |
36 | class VclReferenceBase; |
37 | |
38 | namespace vcl::detail { |
39 | |
40 | template<typename> |
41 | constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; } |
42 | |
43 | template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase( |
44 | int (*)[sizeof(T)]) |
45 | { return std::is_base_of<VclReferenceBase, T>::value; } |
46 | |
47 | } // namespace vcl::detail |
48 | |
49 | /** |
50 | * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses. |
51 | * |
52 | * For more details on the design please see vcl/README.lifecycle |
53 | * |
54 | * @param reference_type must be a subclass of vcl::Window |
55 | */ |
56 | template <class reference_type> |
57 | class VclPtr |
58 | { |
59 | static_assert( |
60 | vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>( |
61 | nullptr), |
62 | "template argument type must be derived from VclReferenceBase"); |
63 | |
64 | ::rtl::Reference<reference_type> m_rInnerRef; |
65 | |
66 | public: |
67 | /** Constructor... |
68 | */ |
69 | VclPtr() |
70 | : m_rInnerRef() |
71 | {} |
72 | |
73 | /** Constructor... |
74 | */ |
75 | VclPtr (reference_type * pBody) |
76 | : m_rInnerRef(pBody) |
77 | {} |
78 | |
79 | /** Constructor... that doesn't take a ref. |
80 | */ |
81 | VclPtr (reference_type * pBody, __sal_NoAcquire) |
82 | : m_rInnerRef(pBody, SAL_NO_ACQUIRE) |
83 | {} |
84 | |
85 | /** Up-casting conversion constructor: Copies interface reference. |
86 | |
87 | Does not work for up-casts to ambiguous bases. For the special case of |
88 | up-casting to Reference< XInterface >, see the corresponding conversion |
89 | operator. |
90 | |
91 | @param rRef another reference |
92 | */ |
93 | template< class derived_type > |
94 | VclPtr( |
95 | const VclPtr< derived_type > & rRef, |
96 | typename std::enable_if< |
97 | std::is_base_of<reference_type, derived_type>::value, int>::type |
98 | = 0 ) |
99 | : m_rInnerRef( static_cast<reference_type*>(rRef) ) |
100 | { |
101 | } |
102 | |
103 | #if defined(DBG_UTIL) && !defined(_WIN32) |
104 | virtual ~VclPtr() |
105 | { |
106 | assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain ::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 106, __extension__ __PRETTY_FUNCTION__)); |
107 | // We can be one of the intermediate counts, but if we are the last |
108 | // VclPtr keeping this object alive, then something forgot to call dispose(). |
109 | assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)) |
110 | && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)); |
111 | } |
112 | VclPtr(VclPtr const &) = default; |
113 | VclPtr(VclPtr &&) = default; |
114 | VclPtr & operator =(VclPtr const &) = default; |
115 | VclPtr & operator =(VclPtr &&) = default; |
116 | #endif |
117 | |
118 | /** |
119 | * A construction helper for VclPtr. Since VclPtr types are created |
120 | * with a reference-count of one - to help fit into the existing |
121 | * code-flow; this helps us to construct them easily. |
122 | * |
123 | * For more details on the design please see vcl/README.lifecycle |
124 | * |
125 | * @tparam reference_type must be a subclass of vcl::Window |
126 | */ |
127 | template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg) |
128 | { |
129 | return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ); |
130 | } |
131 | |
132 | /** Probably most common used: handle->someBodyOp(). |
133 | */ |
134 | reference_type * operator->() const |
135 | { |
136 | return m_rInnerRef.get(); |
137 | } |
138 | |
139 | /** Get the body. Can be used instead of operator->(). |
140 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() |
141 | are the same. |
142 | */ |
143 | reference_type * get() const |
144 | { |
145 | return m_rInnerRef.get(); |
146 | } |
147 | |
148 | void set(reference_type *pBody) |
149 | { |
150 | m_rInnerRef.set(pBody); |
151 | } |
152 | |
153 | void reset(reference_type *pBody) |
154 | { |
155 | m_rInnerRef.set(pBody); |
156 | } |
157 | |
158 | /** Up-casting copy assignment operator. |
159 | |
160 | Does not work for up-casts to ambiguous bases. |
161 | |
162 | @param rRef another reference |
163 | */ |
164 | template<typename derived_type> |
165 | typename std::enable_if< |
166 | std::is_base_of<reference_type, derived_type>::value, |
167 | VclPtr &>::type |
168 | operator =(VclPtr<derived_type> const & rRef) |
169 | { |
170 | m_rInnerRef.set(rRef.get()); |
171 | return *this; |
172 | } |
173 | |
174 | VclPtr & operator =(reference_type * pBody) |
175 | { |
176 | m_rInnerRef.set(pBody); |
177 | return *this; |
178 | } |
179 | |
180 | operator reference_type * () const |
181 | { |
182 | return m_rInnerRef.get(); |
183 | } |
184 | |
185 | explicit operator bool () const |
186 | { |
187 | return m_rInnerRef.get() != nullptr; |
188 | } |
189 | |
190 | void clear() |
191 | { |
192 | m_rInnerRef.clear(); |
193 | } |
194 | |
195 | void reset() |
196 | { |
197 | m_rInnerRef.clear(); |
198 | } |
199 | |
200 | void disposeAndClear() |
201 | { |
202 | // hold it alive for the lifetime of this method |
203 | ::rtl::Reference<reference_type> aTmp(m_rInnerRef); |
204 | m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-) |
205 | if (aTmp.get()) { |
206 | aTmp->disposeOnce(); |
207 | } |
208 | } |
209 | |
210 | /** Needed to place VclPtr's into STL collection. |
211 | */ |
212 | bool operator< (const VclPtr<reference_type> & handle) const |
213 | { |
214 | return (m_rInnerRef < handle.m_rInnerRef); |
215 | } |
216 | }; // class VclPtr |
217 | |
218 | template<typename T1, typename T2> |
219 | inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
220 | return p1.get() == p2.get(); |
221 | } |
222 | |
223 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2) |
224 | { |
225 | return p1.get() == p2; |
226 | } |
227 | |
228 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) { |
229 | return p1.get() == p2; |
230 | } |
231 | |
232 | template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2) |
233 | { |
234 | return p1 == p2.get(); |
235 | } |
236 | |
237 | template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) { |
238 | return p1 == p2.get(); |
239 | } |
240 | |
241 | template<typename T1, typename T2> |
242 | inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
243 | return !(p1 == p2); |
244 | } |
245 | |
246 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2) |
247 | { |
248 | return !(p1 == p2); |
249 | } |
250 | |
251 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) { |
252 | return !(p1 == p2); |
253 | } |
254 | |
255 | template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2) |
256 | { |
257 | return !(p1 == p2); |
258 | } |
259 | |
260 | template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) { |
261 | return !(p1 == p2); |
262 | } |
263 | |
264 | /** |
265 | * A construction helper for a temporary VclPtr. Since VclPtr types |
266 | * are created with a reference-count of one - to help fit into |
267 | * the existing code-flow; this helps us to construct them easily. |
268 | * see also VclPtr::Create and ScopedVclPtr |
269 | * |
270 | * For more details on the design please see vcl/README.lifecycle |
271 | * |
272 | * @param reference_type must be a subclass of vcl::Window |
273 | */ |
274 | template <class reference_type> |
275 | class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type> |
276 | { |
277 | public: |
278 | template<typename... Arg> VclPtrInstance(Arg &&... arg) |
279 | : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
280 | { |
281 | } |
282 | |
283 | /** |
284 | * Override and disallow this, to prevent people accidentally calling it and actually |
285 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
286 | */ |
287 | template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete; |
288 | }; |
289 | |
290 | template <class reference_type> |
291 | class ScopedVclPtr : public VclPtr<reference_type> |
292 | { |
293 | public: |
294 | /** Constructor... |
295 | */ |
296 | ScopedVclPtr() |
297 | : VclPtr<reference_type>() |
298 | {} |
299 | |
300 | /** Constructor |
301 | */ |
302 | ScopedVclPtr (reference_type * pBody) |
303 | : VclPtr<reference_type>(pBody) |
304 | {} |
305 | |
306 | /** Copy constructor... |
307 | */ |
308 | ScopedVclPtr (const VclPtr<reference_type> & handle) |
309 | : VclPtr<reference_type>(handle) |
310 | {} |
311 | |
312 | /** |
313 | Assignment that releases the last reference. |
314 | */ |
315 | void disposeAndReset(reference_type *pBody) |
316 | { |
317 | if (pBody != this->get()) { |
318 | VclPtr<reference_type>::disposeAndClear(); |
319 | VclPtr<reference_type>::set(pBody); |
320 | } |
321 | } |
322 | |
323 | /** |
324 | Assignment that releases the last reference. |
325 | */ |
326 | ScopedVclPtr<reference_type>& operator = (reference_type * pBody) |
327 | { |
328 | disposeAndReset(pBody); |
329 | return *this; |
330 | } |
331 | |
332 | /** Up-casting conversion constructor: Copies interface reference. |
333 | |
334 | Does not work for up-casts to ambiguous bases. For the special case of |
335 | up-casting to Reference< XInterface >, see the corresponding conversion |
336 | operator. |
337 | |
338 | @param rRef another reference |
339 | */ |
340 | template< class derived_type > |
341 | ScopedVclPtr( |
342 | const VclPtr< derived_type > & rRef, |
343 | typename std::enable_if< |
344 | std::is_base_of<reference_type, derived_type>::value, int>::type |
345 | = 0 ) |
346 | : VclPtr<reference_type>( rRef ) |
347 | { |
348 | } |
349 | |
350 | /** Up-casting assignment operator. |
351 | |
352 | Does not work for up-casts to ambiguous bases. |
353 | |
354 | @param rRef another VclPtr |
355 | */ |
356 | template<typename derived_type> |
357 | typename std::enable_if< |
358 | std::is_base_of<reference_type, derived_type>::value, |
359 | ScopedVclPtr &>::type |
360 | operator =(VclPtr<derived_type> const & rRef) |
361 | { |
362 | disposeAndReset(rRef.get()); |
363 | return *this; |
364 | } |
365 | |
366 | /** |
367 | * Override and disallow this, to prevent people accidentally calling it and actually |
368 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
369 | */ |
370 | template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete; |
371 | |
372 | ~ScopedVclPtr() |
373 | { |
374 | VclPtr<reference_type>::disposeAndClear(); |
375 | assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get( ) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 375, __extension__ __PRETTY_FUNCTION__)); // make sure there are no lingering references |
376 | } |
377 | |
378 | private: |
379 | // Most likely we don't want this default copy-constructor. |
380 | ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete; |
381 | // And certainly we don't want a default assignment operator. |
382 | ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete; |
383 | // And disallow reset as that doesn't call disposeAndClear on the original reference |
384 | void reset() = delete; |
385 | void reset(reference_type *pBody) = delete; |
386 | |
387 | protected: |
388 | ScopedVclPtr (reference_type * pBody, __sal_NoAcquire) |
389 | : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE) |
390 | {} |
391 | }; |
392 | |
393 | /** |
394 | * A construction helper for ScopedVclPtr. Since VclPtr types are created |
395 | * with a reference-count of one - to help fit into the existing |
396 | * code-flow; this helps us to construct them easily. |
397 | * |
398 | * For more details on the design please see vcl/README.lifecycle |
399 | * |
400 | * @param reference_type must be a subclass of vcl::Window |
401 | */ |
402 | #if defined _MSC_VER |
403 | #pragma warning(push) |
404 | #pragma warning(disable: 4521) // " multiple copy constructors specified" |
405 | #endif |
406 | template <class reference_type> |
407 | class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type> |
408 | { |
409 | public: |
410 | template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg) |
411 | : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
412 | { |
413 | } |
414 | |
415 | /** |
416 | * Override and disallow this, to prevent people accidentally calling it and actually |
417 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
418 | */ |
419 | template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete; |
420 | |
421 | private: |
422 | // Prevent the above perfect forwarding ctor from hijacking (accidental) |
423 | // attempts at ScopedVclPtrInstance copy construction (where the hijacking |
424 | // would typically lead to somewhat obscure error messages); both non-const |
425 | // and const variants are needed here, as the ScopedVclPtr base class has a |
426 | // const--variant copy ctor, so the implicitly declared copy ctor for |
427 | // ScopedVclPtrInstance would also be the const variant, so non-const copy |
428 | // construction attempts would be hijacked by the perfect forwarding ctor; |
429 | // but if we only declared a non-const variant here, the const variant would |
430 | // no longer be implicitly declared (as there would already be an explicitly |
431 | // declared copy ctor), so const copy construction attempts would then be |
432 | // hijacked by the perfect forwarding ctor: |
433 | ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete; |
434 | ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete; |
435 | }; |
436 | #if defined _MSC_VER |
437 | #pragma warning(pop) |
438 | #endif |
439 | |
440 | #endif // INCLUDED_VCL_PTR_HXX |
441 | |
442 | /* 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 | |||||||||
20 | #ifndef INCLUDED_RTL_REF_HXX | ||||||||
21 | #define INCLUDED_RTL_REF_HXX | ||||||||
22 | |||||||||
23 | #include "sal/config.h" | ||||||||
24 | |||||||||
25 | #include <cassert> | ||||||||
26 | #include <cstddef> | ||||||||
27 | #include <functional> | ||||||||
28 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
29 | #include <type_traits> | ||||||||
30 | #endif | ||||||||
31 | |||||||||
32 | #include "sal/types.h" | ||||||||
33 | |||||||||
34 | namespace rtl | ||||||||
35 | { | ||||||||
36 | |||||||||
37 | /** Template reference class for reference type. | ||||||||
38 | */ | ||||||||
39 | template <class reference_type> | ||||||||
40 | class Reference | ||||||||
41 | { | ||||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||||
43 | */ | ||||||||
44 | reference_type * m_pBody; | ||||||||
45 | |||||||||
46 | |||||||||
47 | public: | ||||||||
48 | /** Constructor... | ||||||||
49 | */ | ||||||||
50 | Reference() | ||||||||
51 | : m_pBody (NULL__null) | ||||||||
52 | {} | ||||||||
53 | |||||||||
54 | |||||||||
55 | /** Constructor... | ||||||||
56 | */ | ||||||||
57 | Reference (reference_type * pBody, __sal_NoAcquire) | ||||||||
58 | : m_pBody (pBody) | ||||||||
59 | { | ||||||||
60 | } | ||||||||
61 | |||||||||
62 | /** Constructor... | ||||||||
63 | */ | ||||||||
64 | Reference (reference_type * pBody) | ||||||||
65 | : m_pBody (pBody) | ||||||||
66 | { | ||||||||
67 | if (m_pBody) | ||||||||
68 | m_pBody->acquire(); | ||||||||
69 | } | ||||||||
70 | |||||||||
71 | /** Copy constructor... | ||||||||
72 | */ | ||||||||
73 | Reference (const Reference<reference_type> & handle) | ||||||||
74 | : m_pBody (handle.m_pBody) | ||||||||
75 | { | ||||||||
76 | if (m_pBody) | ||||||||
77 | m_pBody->acquire(); | ||||||||
78 | } | ||||||||
79 | |||||||||
80 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
81 | /** Move constructor... | ||||||||
82 | */ | ||||||||
83 | Reference (Reference<reference_type> && handle) noexcept | ||||||||
84 | : m_pBody (handle.m_pBody) | ||||||||
85 | { | ||||||||
86 | handle.m_pBody = nullptr; | ||||||||
87 | } | ||||||||
88 | #endif | ||||||||
89 | |||||||||
90 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
91 | /** Up-casting conversion constructor: Copies interface reference. | ||||||||
92 | |||||||||
93 | Does not work for up-casts to ambiguous bases. | ||||||||
94 | |||||||||
95 | @param rRef another reference | ||||||||
96 | */ | ||||||||
97 | template< class derived_type > | ||||||||
98 | inline Reference( | ||||||||
99 | const Reference< derived_type > & rRef, | ||||||||
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) | ||||||||
101 | : m_pBody (rRef.get()) | ||||||||
102 | { | ||||||||
103 | if (m_pBody) | ||||||||
104 | m_pBody->acquire(); | ||||||||
105 | } | ||||||||
106 | #endif | ||||||||
107 | |||||||||
108 | /** Destructor... | ||||||||
109 | */ | ||||||||
110 | ~Reference() COVERITY_NOEXCEPT_FALSE | ||||||||
111 | { | ||||||||
112 | if (m_pBody) | ||||||||
113 | m_pBody->release(); | ||||||||
114 | } | ||||||||
115 | |||||||||
116 | /** Set... | ||||||||
117 | Similar to assignment. | ||||||||
118 | */ | ||||||||
119 | Reference<reference_type> & | ||||||||
120 | SAL_CALL set (reference_type * pBody) | ||||||||
121 | { | ||||||||
122 | if (pBody) | ||||||||
123 | pBody->acquire(); | ||||||||
124 | reference_type * const pOld = m_pBody; | ||||||||
125 | m_pBody = pBody; | ||||||||
126 | if (pOld) | ||||||||
127 | pOld->release(); | ||||||||
128 | return *this; | ||||||||
129 | } | ||||||||
130 | |||||||||
131 | /** Assignment. | ||||||||
132 | Unbinds this instance from its body (if bound) and | ||||||||
133 | bind it to the body represented by the handle. | ||||||||
134 | */ | ||||||||
135 | Reference<reference_type> & | ||||||||
136 | SAL_CALL operator= (const Reference<reference_type> & handle) | ||||||||
137 | { | ||||||||
138 | return set( handle.m_pBody ); | ||||||||
139 | } | ||||||||
140 | |||||||||
141 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
142 | /** Assignment. | ||||||||
143 | * Unbinds this instance from its body (if bound), | ||||||||
144 | * bind it to the body represented by the handle, and | ||||||||
145 | * set the body represented by the handle to nullptr. | ||||||||
146 | */ | ||||||||
147 | Reference<reference_type> & | ||||||||
148 | operator= (Reference<reference_type> && handle) | ||||||||
149 | { | ||||||||
150 | // self-movement guts ourself | ||||||||
151 | if (m_pBody) | ||||||||
152 | m_pBody->release(); | ||||||||
153 | m_pBody = handle.m_pBody; | ||||||||
154 | handle.m_pBody = nullptr; | ||||||||
155 | return *this; | ||||||||
156 | } | ||||||||
157 | #endif | ||||||||
158 | |||||||||
159 | /** Assignment... | ||||||||
160 | */ | ||||||||
161 | Reference<reference_type> & | ||||||||
162 | SAL_CALL operator= (reference_type * pBody) | ||||||||
163 | { | ||||||||
164 | return set( pBody ); | ||||||||
165 | } | ||||||||
166 | |||||||||
167 | /** Unbind the body from this handle. | ||||||||
168 | Note that for a handle representing a large body, | ||||||||
169 | "handle.clear().set(new body());" _might_ | ||||||||
170 | perform a little bit better than "handle.set(new body());", | ||||||||
171 | since in the second case two large objects exist in memory | ||||||||
172 | (the old body and the new body). | ||||||||
173 | */ | ||||||||
174 | Reference<reference_type> & SAL_CALL clear() | ||||||||
175 | { | ||||||||
176 | if (m_pBody
| ||||||||
177 | { | ||||||||
178 | reference_type * const pOld = m_pBody; | ||||||||
179 | m_pBody = NULL__null; | ||||||||
180 | pOld->release(); | ||||||||
181 | } | ||||||||
182 | return *this; | ||||||||
183 | } | ||||||||
184 | |||||||||
185 | |||||||||
186 | /** Get the body. Can be used instead of operator->(). | ||||||||
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() | ||||||||
188 | are the same. | ||||||||
189 | */ | ||||||||
190 | reference_type * SAL_CALL get() const | ||||||||
191 | { | ||||||||
192 | return m_pBody; | ||||||||
| |||||||||
193 | } | ||||||||
194 | |||||||||
195 | |||||||||
196 | /** Probably most common used: handle->someBodyOp(). | ||||||||
197 | */ | ||||||||
198 | reference_type * SAL_CALL operator->() const | ||||||||
199 | { | ||||||||
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||||||
201 | return m_pBody; | ||||||||
202 | } | ||||||||
203 | |||||||||
204 | |||||||||
205 | /** Allows (*handle).someBodyOp(). | ||||||||
206 | */ | ||||||||
207 | reference_type & SAL_CALL operator*() const | ||||||||
208 | { | ||||||||
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); | ||||||||
210 | return *m_pBody; | ||||||||
211 | } | ||||||||
212 | |||||||||
213 | |||||||||
214 | /** Returns True if the handle does point to a valid body. | ||||||||
215 | */ | ||||||||
216 | bool SAL_CALL is() const | ||||||||
217 | { | ||||||||
218 | return (m_pBody != NULL__null); | ||||||||
219 | } | ||||||||
220 | |||||||||
221 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
222 | /** Returns True if the handle does point to a valid body. | ||||||||
223 | */ | ||||||||
224 | explicit operator bool() const | ||||||||
225 | { | ||||||||
226 | return is(); | ||||||||
227 | } | ||||||||
228 | #endif | ||||||||
229 | |||||||||
230 | /** Returns True if this points to pBody. | ||||||||
231 | */ | ||||||||
232 | bool SAL_CALL operator== (const reference_type * pBody) const | ||||||||
233 | { | ||||||||
234 | return (m_pBody == pBody); | ||||||||
235 | } | ||||||||
236 | |||||||||
237 | |||||||||
238 | /** Returns True if handle points to the same body. | ||||||||
239 | */ | ||||||||
240 | bool | ||||||||
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const | ||||||||
242 | { | ||||||||
243 | return (m_pBody == handle.m_pBody); | ||||||||
244 | } | ||||||||
245 | |||||||||
246 | |||||||||
247 | /** Needed to place References into STL collection. | ||||||||
248 | */ | ||||||||
249 | bool | ||||||||
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const | ||||||||
251 | { | ||||||||
252 | return (m_pBody != handle.m_pBody); | ||||||||
253 | } | ||||||||
254 | |||||||||
255 | |||||||||
256 | /** Needed to place References into STL collection. | ||||||||
257 | */ | ||||||||
258 | bool | ||||||||
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const | ||||||||
260 | { | ||||||||
261 | return (m_pBody < handle.m_pBody); | ||||||||
262 | } | ||||||||
263 | |||||||||
264 | |||||||||
265 | /** Needed to place References into STL collection. | ||||||||
266 | */ | ||||||||
267 | bool | ||||||||
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const | ||||||||
269 | { | ||||||||
270 | return (m_pBody > handle.m_pBody); | ||||||||
271 | } | ||||||||
272 | }; | ||||||||
273 | |||||||||
274 | } // namespace rtl | ||||||||
275 | |||||||||
276 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
277 | namespace std | ||||||||
278 | { | ||||||||
279 | |||||||||
280 | /// @cond INTERNAL | ||||||||
281 | /** | ||||||||
282 | Make rtl::Reference hashable by default for use in STL containers. | ||||||||
283 | |||||||||
284 | @since LibreOffice 6.3 | ||||||||
285 | */ | ||||||||
286 | template<typename T> | ||||||||
287 | struct hash<::rtl::Reference<T>> | ||||||||
288 | { | ||||||||
289 | std::size_t operator()(::rtl::Reference<T> const & s) const | ||||||||
290 | { return std::size_t(s.get()); } | ||||||||
291 | }; | ||||||||
292 | /// @endcond | ||||||||
293 | |||||||||
294 | } | ||||||||
295 | |||||||||
296 | #endif | ||||||||
297 | |||||||||
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ | ||||||||
299 | |||||||||
300 | /* 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_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |