LibreOffice Module vcl (master)  1
edit.cxx
Go to the documentation of this file.
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 <vcl/builder.hxx>
21 #include <vcl/event.hxx>
22 #include <vcl/cursor.hxx>
23 #include <vcl/menu.hxx>
24 #include <vcl/toolkit/edit.hxx>
25 #include <vcl/weld.hxx>
26 #include <vcl/specialchars.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/settings.hxx>
29 #include <vcl/uitest/uiobject.hxx>
30 #include <vcl/ptrstyle.hxx>
31 
32 #include <window.h>
33 #include <svdata.hxx>
34 #include <strings.hrc>
35 #include <controldata.hxx>
36 
37 #include <com/sun/star/i18n/BreakIterator.hpp>
38 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
39 #include <com/sun/star/i18n/WordType.hpp>
40 #include <com/sun/star/datatransfer/XTransferable.hpp>
41 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
42 
43 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
44 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
45 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
46 
47 #include <com/sun/star/i18n/InputSequenceChecker.hpp>
48 #include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
49 #include <com/sun/star/i18n/ScriptType.hpp>
50 
51 #include <com/sun/star/uno/Any.hxx>
52 
54 #include <comphelper/string.hxx>
55 
56 #include <sot/exchange.hxx>
57 #include <sot/formats.hxx>
58 #include <sal/macros.h>
59 #include <sal/log.hxx>
60 
62 #include <vcl/unohelp2.hxx>
63 #include <o3tl/safeint.hxx>
64 #include <officecfg/Office/Common.hxx>
65 
66 #include <algorithm>
67 #include <memory>
68 #include <string_view>
69 
70 using namespace ::com::sun::star;
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::lang;
73 
74 // - Redo
75 // - if Tracking-Cancel recreate DefaultSelection
76 
78 
79 #define EDIT_ALIGN_LEFT 1
80 #define EDIT_ALIGN_CENTER 2
81 #define EDIT_ALIGN_RIGHT 3
82 
83 #define EDIT_DEL_LEFT 1
84 #define EDIT_DEL_RIGHT 2
85 
86 #define EDIT_DELMODE_SIMPLE 11
87 #define EDIT_DELMODE_RESTOFWORD 12
88 #define EDIT_DELMODE_RESTOFCONTENT 13
89 
90 struct DDInfo
91 {
94  sal_Int32 nDropPos;
97  bool bVisCursor;
99 
101  {
102  aCursor.SetStyle( CURSOR_SHADOW );
103  nDropPos = 0;
104  bStarterOfDD = false;
105  bDroppedInMe = false;
106  bVisCursor = false;
107  bIsStringSupported = false;
108  }
109 };
110 
112 {
114  std::unique_ptr<ExtTextInputAttr[]>
116  sal_Int32 nPos;
117  sal_Int32 nLen;
118  bool bCursor;
120 
121  Impl_IMEInfos(sal_Int32 nPos, const OUString& rOldTextAfterStartPos);
122 
123  void CopyAttribs(const ExtTextInputAttr* pA, sal_Int32 nL);
124  void DestroyAttribs();
125 };
126 
127 Impl_IMEInfos::Impl_IMEInfos(sal_Int32 nP, const OUString& rOldTextAfterStartPos)
128  : aOldTextAfterStartPos(rOldTextAfterStartPos),
129  nPos(nP),
130  nLen(0),
131  bCursor(true),
132  bWasCursorOverwrite(false)
133 {
134 }
135 
136 void Impl_IMEInfos::CopyAttribs(const ExtTextInputAttr* pA, sal_Int32 nL)
137 {
138  nLen = nL;
139  pAttribs.reset(new ExtTextInputAttr[ nL ]);
140  memcpy( pAttribs.get(), pA, nL*sizeof(ExtTextInputAttr) );
141 }
142 
144 {
145  pAttribs.reset();
146  nLen = 0;
147 }
148 
150  : Control( nType )
151 {
153 }
154 
155 Edit::Edit( vcl::Window* pParent, WinBits nStyle )
156  : Control( WindowType::EDIT )
157 {
159  ImplInit( pParent, nStyle );
160 }
161 
162 void Edit::SetWidthInChars(sal_Int32 nWidthInChars)
163 {
164  if (mnWidthInChars != nWidthInChars)
165  {
166  mnWidthInChars = nWidthInChars;
167  queue_resize();
168  }
169 }
170 
171 void Edit::setMaxWidthChars(sal_Int32 nWidth)
172 {
173  if (nWidth != mnMaxWidthChars)
174  {
175  mnMaxWidthChars = nWidth;
176  queue_resize();
177  }
178 }
179 
180 bool Edit::set_property(const OString &rKey, const OUString &rValue)
181 {
182  if (rKey == "width-chars")
183  SetWidthInChars(rValue.toInt32());
184  else if (rKey == "max-width-chars")
185  setMaxWidthChars(rValue.toInt32());
186  else if (rKey == "max-length")
187  {
188  sal_Int32 nTextLen = rValue.toInt32();
189  SetMaxTextLen(nTextLen == 0 ? EDIT_NOLIMIT : nTextLen);
190  }
191  else if (rKey == "editable")
192  {
193  SetReadOnly(!toBool(rValue));
194  }
195  else if (rKey == "overwrite-mode")
196  {
197  SetInsertMode(!toBool(rValue));
198  }
199  else if (rKey == "visibility")
200  {
201  mbPassword = false;
202  if (!toBool(rValue))
203  mbPassword = true;
204  }
205  else if (rKey == "placeholder-text")
206  SetPlaceholderText(rValue);
207  else if (rKey == "shadow-type")
208  {
209  if (GetStyle() & WB_BORDER)
211  }
212  else
213  return Control::set_property(rKey, rValue);
214  return true;
215 }
216 
218 {
219  disposeOnce();
220 }
221 
223 {
224  mpUIBuilder.reset();
225  mpDDInfo.reset();
226 
227  vcl::Cursor* pCursor = GetCursor();
228  if ( pCursor )
229  {
230  SetCursor( nullptr );
231  delete pCursor;
232  }
233 
234  mpIMEInfos.reset();
235 
236  if ( mxDnDListener.is() )
237  {
238  if ( GetDragGestureRecognizer().is() )
239  {
240  uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
241  GetDragGestureRecognizer()->removeDragGestureListener( xDGL );
242  }
243  if ( GetDropTarget().is() )
244  {
245  uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( mxDnDListener, uno::UNO_QUERY );
246  GetDropTarget()->removeDropTargetListener( xDTL );
247  }
248 
249  mxDnDListener->disposing( lang::EventObject() ); // #95154# #96585# Empty Source means it's the Client
250  mxDnDListener.clear();
251  }
252 
253  SetType(WindowType::WINDOW);
254 
257 }
258 
260 {
262  mpFilterText = nullptr;
263  mnXOffset = 0;
266  mnWidthInChars = -1;
267  mnMaxWidthChars = -1;
268  mbInternModified = false;
269  mbReadOnly = false;
270  mbInsertMode = true;
271  mbClickedInSelection = false;
272  mbActivePopup = false;
273  mbIsSubEdit = false;
274  mbForceControlBackground = false;
275  mbPassword = false;
276  mpDDInfo = nullptr;
277  mpIMEInfos = nullptr;
278  mcEchoChar = 0;
279 
280  // no default mirroring for Edit controls
281  // note: controls that use a subedit will revert this (SpinField, ComboBox)
282  EnableRTL( false );
283 
285  mxDnDListener = pDnDWrapper;
286 }
287 
288 bool Edit::ImplUseNativeBorder(vcl::RenderContext const & rRenderContext, WinBits nStyle)
289 {
290  bool bRet = rRenderContext.IsNativeControlSupported(ImplGetNativeControlType(),
292  && ((nStyle & WB_BORDER) && !(nStyle & WB_NOBORDER));
293  if (!bRet && mbIsSubEdit)
294  {
295  vcl::Window* pWindow = GetParent();
296  nStyle = pWindow->GetStyle();
299  && ((nStyle & WB_BORDER) && !(nStyle & WB_NOBORDER));
300  }
301  return bRet;
302 }
303 
304 void Edit::ImplInit(vcl::Window* pParent, WinBits nStyle)
305 {
306  nStyle = ImplInitStyle(nStyle);
307 
308  if (!(nStyle & (WB_CENTER | WB_RIGHT)))
309  nStyle |= WB_LEFT;
310 
311  Control::ImplInit(pParent, nStyle, nullptr);
312 
313  mbReadOnly = (nStyle & WB_READONLY) != 0;
314 
316 
317  // hack: right align until keyinput and cursor travelling works
318  if( IsRTLEnabled() )
320 
321  if ( nStyle & WB_RIGHT )
323  else if ( nStyle & WB_CENTER )
325 
326  SetCursor( new vcl::Cursor );
327 
329  ApplySettings(*this);
330 
331  uno::Reference< datatransfer::dnd::XDragGestureListener> xDGL( mxDnDListener, uno::UNO_QUERY );
332  uno::Reference< datatransfer::dnd::XDragGestureRecognizer > xDGR = GetDragGestureRecognizer();
333  if ( xDGR.is() )
334  {
335  xDGR->addDragGestureListener( xDGL );
336  uno::Reference< datatransfer::dnd::XDropTargetListener> xDTL( mxDnDListener, uno::UNO_QUERY );
337  GetDropTarget()->addDropTargetListener( xDTL );
338  GetDropTarget()->setActive( true );
339  GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE );
340  }
341 }
342 
344 {
345  if ( !(nStyle & WB_NOTABSTOP) )
346  nStyle |= WB_TABSTOP;
347  if ( !(nStyle & WB_NOGROUP) )
348  nStyle |= WB_GROUP;
349 
350  return nStyle;
351 }
352 
353 bool Edit::IsCharInput( const KeyEvent& rKeyEvent )
354 {
355  // In the future we must use new Unicode functions for this
356  sal_Unicode cCharCode = rKeyEvent.GetCharCode();
357  return ((cCharCode >= 32) && (cCharCode != 127) &&
358  !rKeyEvent.GetKeyCode().IsMod3() &&
359  !rKeyEvent.GetKeyCode().IsMod2() &&
360  !rKeyEvent.GetKeyCode().IsMod1() );
361 }
362 
364 {
365  Control::ApplySettings(rRenderContext);
366 
367  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
368 
369  const vcl::Font& aFont = rStyleSettings.GetFieldFont();
370  ApplyControlFont(rRenderContext, aFont);
371 
373 
374  Color aTextColor = rStyleSettings.GetFieldTextColor();
375  ApplyControlForeground(rRenderContext, aTextColor);
376 
377  if (IsControlBackground())
378  {
379  rRenderContext.SetBackground(GetControlBackground());
380  rRenderContext.SetFillColor(GetControlBackground());
381 
382  if (ImplUseNativeBorder(rRenderContext, GetStyle()))
383  {
384  // indicates that no non-native drawing of background should take place
385  mpWindowImpl->mnNativeBackground = ControlPart::Entire;
386  }
387  }
388  else if (ImplUseNativeBorder(rRenderContext, GetStyle()))
389  {
390  // Transparent background
391  rRenderContext.SetBackground();
392  rRenderContext.SetFillColor();
393  }
394  else
395  {
396  rRenderContext.SetBackground(rStyleSettings.GetFieldColor());
397  rRenderContext.SetFillColor(rStyleSettings.GetFieldColor());
398  }
399 }
400 
402 {
403  // MT 09/2002: nExtraOffsetX should become a member, instead of checking every time,
404  // but I need an incompatible update for this...
405  // #94095# Use extra offset only when edit has a border
406  long nExtraOffset = 0;
407  if( ( GetStyle() & WB_BORDER ) || ( mbIsSubEdit && ( GetParent()->GetStyle() & WB_BORDER ) ) )
408  nExtraOffset = 2;
409 
410  return nExtraOffset;
411 }
412 
414 {
415  long nExtraOffset = 0;
417  if (eCtrlType != ControlType::EditboxNoBorder)
418  {
419  // add some space between text entry and border
420  nExtraOffset = 2;
421  }
422  return nExtraOffset;
423 }
424 
425 OUString Edit::ImplGetText() const
426 {
427  if ( mcEchoChar || mbPassword )
428  {
429  sal_Unicode cEchoChar;
430  if ( mcEchoChar )
431  cEchoChar = mcEchoChar;
432  else
433  cEchoChar = u'\x2022';
434  OUStringBuffer aText;
435  comphelper::string::padToLength(aText, maText.getLength(), cEchoChar);
436  return aText.makeStringAndClear();
437  }
438  else
439  return maText.toString();
440 }
441 
443 {
444  if( IsPaintTransparent() )
445  {
446  Invalidate();
447  // FIXME: this is currently only on macOS
448  if( ImplGetSVData()->maNWFData.mbNoFocusRects )
450  }
451  else
452  Invalidate();
453 }
454 
456 {
457  if ( GetStyle() & WB_TOP )
458  return ImplGetExtraXOffset();
459  else if ( GetStyle() & WB_BOTTOM )
461  return ( GetOutputSizePixel().Height() - GetTextHeight() ) / 2;
462 }
463 
464 void Edit::ImplRepaint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRectangle)
465 {
466  if (!IsReallyVisible())
467  return;
468 
469  ApplySettings(rRenderContext);
470 
471  const OUString aText = ImplGetText();
472  const sal_Int32 nLen = aText.getLength();
473 
474  long nDXBuffer[256];
475  std::unique_ptr<long[]> pDXBuffer;
476  long* pDX = nDXBuffer;
477 
478  if (nLen)
479  {
480  if (o3tl::make_unsigned(2 * nLen) > SAL_N_ELEMENTS(nDXBuffer))
481  {
482  pDXBuffer.reset(new long[2 * (nLen + 1)]);
483  pDX = pDXBuffer.get();
484  }
485 
486  GetCaretPositions(aText, pDX, 0, nLen);
487  }
488 
489  long nTH = GetTextHeight();
491 
492  vcl::Cursor* pCursor = GetCursor();
493  bool bVisCursor = pCursor && pCursor->IsVisible();
494  if (pCursor)
495  pCursor->Hide();
496 
497  ImplClearBackground(rRenderContext, rRectangle, 0, GetOutputSizePixel().Width()-1);
498 
499  bool bPaintPlaceholderText = aText.isEmpty() && !maPlaceholderText.isEmpty();
500 
501  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
502 
503  if (!IsEnabled() || bPaintPlaceholderText)
504  rRenderContext.SetTextColor(rStyleSettings.GetDisableColor());
505 
506  // Set background color of the normal text
508  {
509  // check if we need to set ControlBackground even in NWF case
511  rRenderContext.SetLineColor();
512  rRenderContext.SetFillColor(GetControlBackground());
514  rRenderContext.Pop();
515 
516  rRenderContext.SetTextFillColor(GetControlBackground());
517  }
518  else if (IsPaintTransparent() || ImplUseNativeBorder(rRenderContext, GetStyle()))
519  rRenderContext.SetTextFillColor();
520  else
521  rRenderContext.SetTextFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor());
522 
523  ImplPaintBorder(rRenderContext);
524 
525  bool bDrawSelection = maSelection.Len() && (HasFocus() || (GetStyle() & WB_NOHIDESELECTION) || mbActivePopup);
526 
527  aPos.setX( mnXOffset + ImplGetExtraXOffset() );
528  if (bPaintPlaceholderText)
529  {
530  rRenderContext.DrawText(aPos, maPlaceholderText);
531  }
532  else if (!bDrawSelection && !mpIMEInfos)
533  {
534  rRenderContext.DrawText(aPos, aText, 0, nLen);
535  }
536  else
537  {
538  // save graphics state
539  rRenderContext.Push();
540  // first calculate highlighted and non highlighted clip regions
541  vcl::Region aHighlightClipRegion;
542  vcl::Region aNormalClipRegion;
543  Selection aTmpSel(maSelection);
544  aTmpSel.Justify();
545  // selection is highlighted
546  for(sal_Int32 i = 0; i < nLen; ++i)
547  {
548  tools::Rectangle aRect(aPos, Size(10, nTH));
549  aRect.SetLeft( pDX[2 * i] + mnXOffset + ImplGetExtraXOffset() );
550  aRect.SetRight( pDX[2 * i + 1] + mnXOffset + ImplGetExtraXOffset() );
551  aRect.Justify();
552  bool bHighlight = false;
553  if (i >= aTmpSel.Min() && i < aTmpSel.Max())
554  bHighlight = true;
555 
556  if (mpIMEInfos && mpIMEInfos->pAttribs &&
557  i >= mpIMEInfos->nPos && i < (mpIMEInfos->nPos+mpIMEInfos->nLen) &&
558  (mpIMEInfos->pAttribs[i - mpIMEInfos->nPos] & ExtTextInputAttr::Highlight))
559  {
560  bHighlight = true;
561  }
562 
563  if (bHighlight)
564  aHighlightClipRegion.Union(aRect);
565  else
566  aNormalClipRegion.Union(aRect);
567  }
568  // draw normal text
569  Color aNormalTextColor = rRenderContext.GetTextColor();
570  rRenderContext.SetClipRegion(aNormalClipRegion);
571 
572  if (IsPaintTransparent())
573  rRenderContext.SetTextFillColor();
574  else
575  {
576  // Set background color when part of the text is selected
577  if (ImplUseNativeBorder(rRenderContext, GetStyle()))
578  {
580  rRenderContext.SetTextFillColor(GetControlBackground());
581  else
582  rRenderContext.SetTextFillColor();
583  }
584  else
585  {
586  rRenderContext.SetTextFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor());
587  }
588  }
589  rRenderContext.DrawText(aPos, aText, 0, nLen);
590 
591  // draw highlighted text
592  rRenderContext.SetClipRegion(aHighlightClipRegion);
593  rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
594  rRenderContext.SetTextFillColor(rStyleSettings.GetHighlightColor());
595  rRenderContext.DrawText(aPos, aText, 0, nLen);
596 
597  // if IME info exists loop over portions and output different font attributes
598  if (mpIMEInfos && mpIMEInfos->pAttribs)
599  {
600  for(int n = 0; n < 2; n++)
601  {
602  vcl::Region aRegion;
603  if (n == 0)
604  {
605  rRenderContext.SetTextColor(aNormalTextColor);
606  if (IsPaintTransparent())
607  rRenderContext.SetTextFillColor();
608  else
609  rRenderContext.SetTextFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor());
610  aRegion = aNormalClipRegion;
611  }
612  else
613  {
614  rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
615  rRenderContext.SetTextFillColor(rStyleSettings.GetHighlightColor());
616  aRegion = aHighlightClipRegion;
617  }
618 
619  for(int i = 0; i < mpIMEInfos->nLen; )
620  {
621  ExtTextInputAttr nAttr = mpIMEInfos->pAttribs[i];
622  vcl::Region aClip;
623  int nIndex = i;
624  while (nIndex < mpIMEInfos->nLen && mpIMEInfos->pAttribs[nIndex] == nAttr) // #112631# check nIndex before using it
625  {
626  tools::Rectangle aRect( aPos, Size( 10, nTH ) );
627  aRect.SetLeft( pDX[2 * (nIndex + mpIMEInfos->nPos)] + mnXOffset + ImplGetExtraXOffset() );
628  aRect.SetRight( pDX[2 * (nIndex + mpIMEInfos->nPos) + 1] + mnXOffset + ImplGetExtraXOffset() );
629  aRect.Justify();
630  aClip.Union(aRect);
631  nIndex++;
632  }
633  i = nIndex;
634  aClip.Intersect(aRegion);
635  if (!aClip.IsEmpty() && nAttr != ExtTextInputAttr::NONE)
636  {
637  vcl::Font aFont = rRenderContext.GetFont();
638  if (nAttr & ExtTextInputAttr::Underline)
640  else if (nAttr & ExtTextInputAttr::BoldUnderline)
642  else if (nAttr & ExtTextInputAttr::DottedUnderline)
644  else if (nAttr & ExtTextInputAttr::DashDotUnderline)
646  else if (nAttr & ExtTextInputAttr::GrayWaveline)
647  {
649  rRenderContext.SetTextLineColor(COL_LIGHTGRAY);
650  }
651  rRenderContext.SetFont(aFont);
652 
653  if (nAttr & ExtTextInputAttr::RedText)
654  rRenderContext.SetTextColor(COL_RED);
655  else if (nAttr & ExtTextInputAttr::HalfToneText)
656  rRenderContext.SetTextColor(COL_LIGHTGRAY);
657 
658  rRenderContext.SetClipRegion(aClip);
659  rRenderContext.DrawText(aPos, aText, 0, nLen);
660  }
661  }
662  }
663  }
664 
665  // restore graphics state
666  rRenderContext.Pop();
667  }
668 
669  if (bVisCursor && (!mpIMEInfos || mpIMEInfos->bCursor))
670  pCursor->Show();
671 }
672 
673 void Edit::ImplDelete( const Selection& rSelection, sal_uInt8 nDirection, sal_uInt8 nMode )
674 {
675  const sal_Int32 nTextLen = ImplGetText().getLength();
676 
677  // deleting possible?
678  if ( !rSelection.Len() &&
679  (((rSelection.Min() == 0) && (nDirection == EDIT_DEL_LEFT)) ||
680  ((rSelection.Max() == nTextLen) && (nDirection == EDIT_DEL_RIGHT))) )
681  return;
682 
684 
685  Selection aSelection( rSelection );
686  aSelection.Justify();
687 
688  if ( !aSelection.Len() )
689  {
690  uno::Reference < i18n::XBreakIterator > xBI = ImplGetBreakIterator();
691  if ( nDirection == EDIT_DEL_LEFT )
692  {
693  if ( nMode == EDIT_DELMODE_RESTOFWORD )
694  {
695  i18n::Boundary aBoundary = xBI->getWordBoundary( maText.toString(), aSelection.Min(),
696  GetSettings().GetLanguageTag().getLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, true );
697  auto startPos = aBoundary.startPos;
698  if ( startPos == aSelection.Min() )
699  {
700  aBoundary = xBI->previousWord( maText.toString(), aSelection.Min(),
701  GetSettings().GetLanguageTag().getLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
702  startPos = std::max(aBoundary.startPos, sal_Int32(0));
703  }
704  aSelection.Min() = startPos;
705  }
706  else if ( nMode == EDIT_DELMODE_RESTOFCONTENT )
707  {
708  aSelection.Min() = 0;
709  }
710  else
711  {
712  sal_Int32 nCount = 1;
713  aSelection.Min() = xBI->previousCharacters( maText.toString(), aSelection.Min(),
714  GetSettings().GetLanguageTag().getLocale(), i18n::CharacterIteratorMode::SKIPCHARACTER, nCount, nCount );
715  }
716  }
717  else
718  {
719  if ( nMode == EDIT_DELMODE_RESTOFWORD )
720  {
721  i18n::Boundary aBoundary = xBI->nextWord( maText.toString(), aSelection.Max(),
722  GetSettings().GetLanguageTag().getLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
723  aSelection.Max() = aBoundary.startPos;
724  }
725  else if ( nMode == EDIT_DELMODE_RESTOFCONTENT )
726  {
727  aSelection.Max() = nTextLen;
728  }
729  else
730  {
731  sal_Int32 nCount = 1;
732  aSelection.Max() = xBI->nextCharacters( maText.toString(), aSelection.Max(),
733  GetSettings().GetLanguageTag().getLocale(), i18n::CharacterIteratorMode::SKIPCHARACTER, nCount, nCount );
734  }
735  }
736  }
737 
738  const auto nSelectionMin = aSelection.Min();
739  maText.remove( nSelectionMin, aSelection.Len() );
740  maSelection.Min() = nSelectionMin;
741  maSelection.Max() = nSelectionMin;
743  mbInternModified = true;
744 }
745 
746 OUString Edit::ImplGetValidString( const OUString& rString )
747 {
748  OUString aValidString = rString.replaceAll("\n", "").replaceAll("\r", "");
749  aValidString = aValidString.replace('\t', ' ');
750  return aValidString;
751 }
752 
753 uno::Reference <i18n::XBreakIterator> const& Edit::ImplGetBreakIterator()
754 {
755  if (!mxBreakIterator)
756  mxBreakIterator = i18n::BreakIterator::create(::comphelper::getProcessComponentContext());
757  return mxBreakIterator;
758 }
759 
760 uno::Reference <i18n::XExtendedInputSequenceChecker> const& Edit::ImplGetInputSequenceChecker()
761 {
762  if (!mxISC.is())
763  mxISC = i18n::InputSequenceChecker::create(::comphelper::getProcessComponentContext());
764  return mxISC;
765 }
766 
768 {
769  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent, VclMessageType::Warning,
770  VclButtonsType::Ok, VclResId(SV_EDIT_WARNING_STR)));
771  xBox->run();
772 }
773 
774 bool Edit::ImplTruncateToMaxLen( OUString& rStr, sal_Int32 nSelectionLen ) const
775 {
776  bool bWasTruncated = false;
777  if (maText.getLength() - nSelectionLen > mnMaxTextLen - rStr.getLength())
778  {
779  sal_Int32 nErasePos = mnMaxTextLen - maText.getLength() + nSelectionLen;
780  rStr = rStr.copy( 0, nErasePos );
781  bWasTruncated = true;
782  }
783  return bWasTruncated;
784 }
785 
786 void Edit::ImplInsertText( const OUString& rStr, const Selection* pNewSel, bool bIsUserInput )
787 {
788  Selection aSelection( maSelection );
789  aSelection.Justify();
790 
791  OUString aNewText( ImplGetValidString( rStr ) );
792 
793  // as below, if there's no selection, but we're in overwrite mode and not beyond
794  // the end of the existing text then that's like a selection of 1
795  auto nSelectionLen = aSelection.Len();
796  if (!nSelectionLen && !mbInsertMode && aSelection.Max() < maText.getLength())
797  nSelectionLen = 1;
798  ImplTruncateToMaxLen( aNewText, nSelectionLen );
799 
801 
802  if ( aSelection.Len() )
803  maText.remove( aSelection.Min(), aSelection.Len() );
804  else if (!mbInsertMode && aSelection.Max() < maText.getLength())
805  maText.remove( aSelection.Max(), 1 );
806 
807  // take care of input-sequence-checking now
808  if (bIsUserInput && !rStr.isEmpty())
809  {
810  SAL_WARN_IF( rStr.getLength() != 1, "vcl", "unexpected string length. User input is expected to provide 1 char only!" );
811 
812  // determine if input-sequence-checking should be applied or not
813 
814  uno::Reference < i18n::XBreakIterator > xBI = ImplGetBreakIterator();
815  bool bIsInputSequenceChecking = rStr.getLength() == 1 &&
816  officecfg::Office::Common::I18N::CTL::CTLFont::get() &&
817  officecfg::Office::Common::I18N::CTL::CTLSequenceChecking::get() &&
818  aSelection.Min() > 0 && /* first char needs not to be checked */
819  xBI.is() && i18n::ScriptType::COMPLEX == xBI->getScriptType( rStr, 0 );
820 
821  if (bIsInputSequenceChecking)
822  {
823  uno::Reference < i18n::XExtendedInputSequenceChecker > xISC = ImplGetInputSequenceChecker();
824  if (xISC.is())
825  {
826  sal_Unicode cChar = rStr[0];
827  sal_Int32 nTmpPos = aSelection.Min();
828  sal_Int16 nCheckMode = officecfg::Office::Common::I18N::CTL::CTLSequenceCheckingRestricted::get()?
829  i18n::InputSequenceCheckMode::STRICT : i18n::InputSequenceCheckMode::BASIC;
830 
831  // the text that needs to be checked is only the one
832  // before the current cursor position
833  const OUString aOldText( maText.getStr(), nTmpPos);
834  OUString aTmpText( aOldText );
835  if (officecfg::Office::Common::I18N::CTL::CTLSequenceCheckingTypeAndReplace::get())
836  {
837  xISC->correctInputSequence( aTmpText, nTmpPos - 1, cChar, nCheckMode );
838 
839  // find position of first character that has changed
840  sal_Int32 nOldLen = aOldText.getLength();
841  sal_Int32 nTmpLen = aTmpText.getLength();
842  const sal_Unicode *pOldTxt = aOldText.getStr();
843  const sal_Unicode *pTmpTxt = aTmpText.getStr();
844  sal_Int32 nChgPos = 0;
845  while ( nChgPos < nOldLen && nChgPos < nTmpLen &&
846  pOldTxt[nChgPos] == pTmpTxt[nChgPos] )
847  ++nChgPos;
848 
849  const OUString aChgText( aTmpText.copy( nChgPos ) );
850 
851  // remove text from first pos to be changed to current pos
852  maText.remove( nChgPos, nTmpPos - nChgPos );
853 
854  if (!aChgText.isEmpty())
855  {
856  aNewText = aChgText;
857  aSelection.Min() = nChgPos; // position for new text to be inserted
858  }
859  else
860  aNewText.clear();
861  }
862  else
863  {
864  // should the character be ignored (i.e. not get inserted) ?
865  if (!xISC->checkInputSequence( aOldText, nTmpPos - 1, cChar, nCheckMode ))
866  aNewText.clear();
867  }
868  }
869  }
870 
871  // at this point now we will insert the non-empty text 'normally' some lines below...
872  }
873 
874  if ( !aNewText.isEmpty() )
875  maText.insert( aSelection.Min(), aNewText );
876 
877  if ( !pNewSel )
878  {
879  maSelection.Min() = aSelection.Min() + aNewText.getLength();
881  }
882  else
883  {
884  maSelection = *pNewSel;
885  if ( maSelection.Min() > maText.getLength() )
886  maSelection.Min() = maText.getLength();
887  if ( maSelection.Max() > maText.getLength() )
888  maSelection.Max() = maText.getLength();
889  }
890 
892  mbInternModified = true;
893 }
894 
895 void Edit::ImplSetText( const OUString& rText, const Selection* pNewSelection )
896 {
897  // we delete text by "selecting" the old text completely then calling InsertText; this is flicker free
898  if ( ( rText.getLength() > mnMaxTextLen ) ||
899  ( std::u16string_view(rText) == std::u16string_view(maText.getStr(), maText.getLength())
900  && (!pNewSelection || (*pNewSelection == maSelection)) ) )
901  return;
902 
904  maSelection.Min() = 0;
905  maSelection.Max() = maText.getLength();
906  if ( mnXOffset || HasPaintEvent() )
907  {
908  mnXOffset = 0;
909  maText = ImplGetValidString( rText );
910 
911  // #i54929# recalculate mnXOffset before ImplSetSelection,
912  // else cursor ends up in wrong position
913  ImplAlign();
914 
915  if ( pNewSelection )
916  ImplSetSelection( *pNewSelection, false );
917 
918  if ( mnXOffset && !pNewSelection )
919  maSelection.Max() = 0;
920 
921  Invalidate();
922  }
923  else
924  ImplInsertText( rText, pNewSelection );
925 
927 }
928 
930 {
932  const vcl::Window* pControl = mbIsSubEdit ? GetParent() : this;
933 
934  switch (pControl->GetType())
935  {
936  case WindowType::COMBOBOX:
937  case WindowType::PATTERNBOX:
938  case WindowType::NUMERICBOX:
939  case WindowType::METRICBOX:
940  case WindowType::CURRENCYBOX:
941  case WindowType::DATEBOX:
942  case WindowType::TIMEBOX:
943  case WindowType::LONGCURRENCYBOX:
944  nCtrl = ControlType::Combobox;
945  break;
946 
947  case WindowType::MULTILINEEDIT:
948  if ( GetWindow( GetWindowType::Border ) != this )
950  else
952  break;
953 
954  case WindowType::EDIT:
955  case WindowType::PATTERNFIELD:
956  case WindowType::METRICFIELD:
957  case WindowType::CURRENCYFIELD:
958  case WindowType::DATEFIELD:
959  case WindowType::TIMEFIELD:
960  case WindowType::SPINFIELD:
961  case WindowType::FORMATTEDFIELD:
962  if (pControl->GetStyle() & WB_SPIN)
963  nCtrl = ControlType::Spinbox;
964  else
965  {
966  if (GetWindow(GetWindowType::Border) != this)
967  nCtrl = ControlType::Editbox;
968  else
970  }
971  break;
972 
973  default:
974  nCtrl = ControlType::Editbox;
975  }
976  return nCtrl;
977 }
978 
979 void Edit::ImplClearBackground(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRectangle, long nXStart, long nXEnd )
980 {
981  /*
982  * note: at this point the cursor must be switched off already
983  */
985  aRect.SetLeft( nXStart );
986  aRect.SetRight( nXEnd );
987 
988  if( !(ImplUseNativeBorder(rRenderContext, GetStyle()) || IsPaintTransparent()))
989  rRenderContext.Erase(aRect);
990  else if (SupportsDoubleBuffering() && mbIsSubEdit)
991  {
992  // ImplPaintBorder() is a NOP, we have a native border, and this is a sub-edit of a control.
993  // That means we have to draw the parent native widget to paint the edit area to clear our background.
995  GetParent()->Paint(rRenderContext, rRectangle);
996  }
997 }
998 
999 void Edit::ImplPaintBorder(vcl::RenderContext const & rRenderContext)
1000 {
1001  // this is not needed when double-buffering
1003  return;
1004 
1005  if (!(ImplUseNativeBorder(rRenderContext, GetStyle()) || IsPaintTransparent()))
1006  return;
1007 
1008  // draw the inner part by painting the whole control using its border window
1010  if (pBorder == this)
1011  {
1012  // we have no border, use parent
1013  vcl::Window* pControl = mbIsSubEdit ? GetParent() : this;
1014  pBorder = pControl->GetWindow(GetWindowType::Border);
1015  if (pBorder == this)
1016  pBorder = GetParent();
1017  }
1018 
1019  if (!pBorder)
1020  return;
1021 
1022  // set proper clipping region to not overdraw the whole control
1023  vcl::Region aClipRgn = GetPaintRegion();
1024  if (!aClipRgn.IsNull())
1025  {
1026  // transform clipping region to border window's coordinate system
1027  if (IsRTLEnabled() != pBorder->IsRTLEnabled() && AllSettings::GetLayoutRTL())
1028  {
1029  // need to mirror in case border is not RTL but edit is (or vice versa)
1030 
1031  // mirror
1032  tools::Rectangle aBounds(aClipRgn.GetBoundRect());
1033  int xNew = GetOutputSizePixel().Width() - aBounds.GetWidth() - aBounds.Left();
1034  aClipRgn.Move(xNew - aBounds.Left(), 0);
1035 
1036  // move offset of border window
1037  Point aBorderOffs = pBorder->ScreenToOutputPixel(OutputToScreenPixel(Point()));
1038  aClipRgn.Move(aBorderOffs.X(), aBorderOffs.Y());
1039  }
1040  else
1041  {
1042  // normal case
1043  Point aBorderOffs = pBorder->ScreenToOutputPixel(OutputToScreenPixel(Point()));
1044  aClipRgn.Move(aBorderOffs.X(), aBorderOffs.Y());
1045  }
1046 
1047  vcl::Region oldRgn(pBorder->GetClipRegion());
1048  pBorder->SetClipRegion(aClipRgn);
1049 
1050  pBorder->Paint(*pBorder, tools::Rectangle());
1051 
1052  pBorder->SetClipRegion(oldRgn);
1053  }
1054  else
1055  {
1056  pBorder->Paint(*pBorder, tools::Rectangle());
1057  }
1058 }
1059 
1060 void Edit::ImplShowCursor( bool bOnlyIfVisible )
1061 {
1062  if ( !IsUpdateMode() || ( bOnlyIfVisible && !IsReallyVisible() ) )
1063  return;
1064 
1065  vcl::Cursor* pCursor = GetCursor();
1066  OUString aText = ImplGetText();
1067 
1068  long nTextPos = 0;
1069 
1070  long nDXBuffer[256];
1071  std::unique_ptr<long[]> pDXBuffer;
1072  long* pDX = nDXBuffer;
1073 
1074  if( !aText.isEmpty() )
1075  {
1076  if( o3tl::make_unsigned(2*aText.getLength()) > SAL_N_ELEMENTS(nDXBuffer) )
1077  {
1078  pDXBuffer.reset(new long[2*(aText.getLength()+1)]);
1079  pDX = pDXBuffer.get();
1080  }
1081 
1082  GetCaretPositions( aText, pDX, 0, aText.getLength() );
1083 
1084  if( maSelection.Max() < aText.getLength() )
1085  nTextPos = pDX[ 2*maSelection.Max() ];
1086  else
1087  nTextPos = pDX[ 2*aText.getLength()-1 ];
1088  }
1089 
1090  long nCursorWidth = 0;
1091  if ( !mbInsertMode && !maSelection.Len() && (maSelection.Max() < aText.getLength()) )
1092  nCursorWidth = GetTextWidth(aText, maSelection.Max(), 1);
1093  long nCursorPosX = nTextPos + mnXOffset + ImplGetExtraXOffset();
1094 
1095  // cursor should land in visible area
1096  const Size aOutSize = GetOutputSizePixel();
1097  if ( (nCursorPosX < 0) || (nCursorPosX >= aOutSize.Width()) )
1098  {
1099  long nOldXOffset = mnXOffset;
1100 
1101  if ( nCursorPosX < 0 )
1102  {
1103  mnXOffset = - nTextPos;
1104  long nMaxX = 0;
1105  mnXOffset += aOutSize.Width() / 5;
1106  if ( mnXOffset > nMaxX )
1107  mnXOffset = nMaxX;
1108  }
1109  else
1110  {
1111  mnXOffset = (aOutSize.Width()-ImplGetExtraXOffset()) - nTextPos;
1112  // Something more?
1113  if ( (aOutSize.Width()-ImplGetExtraXOffset()) < nTextPos )
1114  {
1115  long nMaxNegX = (aOutSize.Width()-ImplGetExtraXOffset()) - GetTextWidth( aText );
1116  mnXOffset -= aOutSize.Width() / 5;
1117  if ( mnXOffset < nMaxNegX ) // both negative...
1118  mnXOffset = nMaxNegX;
1119  }
1120  }
1121 
1122  nCursorPosX = nTextPos + mnXOffset + ImplGetExtraXOffset();
1123  if ( nCursorPosX == aOutSize.Width() ) // then invisible...
1124  nCursorPosX--;
1125 
1126  if ( mnXOffset != nOldXOffset )
1128  }
1129 
1130  const long nTextHeight = GetTextHeight();
1131  const long nCursorPosY = ImplGetTextYPosition();
1132  if (pCursor)
1133  {
1134  pCursor->SetPos( Point( nCursorPosX, nCursorPosY ) );
1135  pCursor->SetSize( Size( nCursorWidth, nTextHeight ) );
1136  pCursor->Show();
1137  }
1138 }
1139 
1141 {
1142  if (mnAlign == EDIT_ALIGN_LEFT && !mnXOffset)
1143  {
1144  // short circuit common case and avoid slow GetTextWidth() calc
1145  return;
1146  }
1147 
1148  long nTextWidth = GetTextWidth( ImplGetText() );
1149  long nOutWidth = GetOutputSizePixel().Width();
1150 
1151  if ( mnAlign == EDIT_ALIGN_LEFT )
1152  {
1153  if (nTextWidth < nOutWidth)
1154  mnXOffset = 0;
1155  }
1156  else if ( mnAlign == EDIT_ALIGN_RIGHT )
1157  {
1158  long nMinXOffset = nOutWidth - nTextWidth - 1 - ImplGetExtraXOffset();
1159  bool bRTL = IsRTLEnabled();
1160  if( mbIsSubEdit && GetParent() )
1161  bRTL = GetParent()->IsRTLEnabled();
1162  if( bRTL )
1163  {
1164  if( nTextWidth < nOutWidth )
1165  mnXOffset = nMinXOffset;
1166  }
1167  else
1168  {
1169  if( nTextWidth < nOutWidth )
1170  mnXOffset = nMinXOffset;
1171  else if ( mnXOffset < nMinXOffset )
1172  mnXOffset = nMinXOffset;
1173  }
1174  }
1175  else if( mnAlign == EDIT_ALIGN_CENTER )
1176  {
1177  // would be nicer with check while scrolling but then it's not centred in scrolled state
1178  mnXOffset = (nOutWidth - nTextWidth) / 2;
1179  }
1180 }
1181 
1183 {
1184  ImplAlign();
1186  ImplShowCursor();
1187 }
1188 
1189 sal_Int32 Edit::ImplGetCharPos( const Point& rWindowPos ) const
1190 {
1191  sal_Int32 nIndex = EDIT_NOLIMIT;
1192  OUString aText = ImplGetText();
1193 
1194  long nDXBuffer[256];
1195  std::unique_ptr<long[]> pDXBuffer;
1196  long* pDX = nDXBuffer;
1197  if( o3tl::make_unsigned(2*aText.getLength()) > SAL_N_ELEMENTS(nDXBuffer) )
1198  {
1199  pDXBuffer.reset(new long[2*(aText.getLength()+1)]);
1200  pDX = pDXBuffer.get();
1201  }
1202 
1203  GetCaretPositions( aText, pDX, 0, aText.getLength() );
1204  long nX = rWindowPos.X() - mnXOffset - ImplGetExtraXOffset();
1205  for (sal_Int32 i = 0; i < aText.getLength(); aText.iterateCodePoints(&i))
1206  {
1207  if( (pDX[2*i] >= nX && pDX[2*i+1] <= nX) ||
1208  (pDX[2*i+1] >= nX && pDX[2*i] <= nX))
1209  {
1210  nIndex = i;
1211  if( pDX[2*i] < pDX[2*i+1] )
1212  {
1213  if( nX > (pDX[2*i]+pDX[2*i+1])/2 )
1214  aText.iterateCodePoints(&nIndex);
1215  }
1216  else
1217  {
1218  if( nX < (pDX[2*i]+pDX[2*i+1])/2 )
1219  aText.iterateCodePoints(&nIndex);
1220  }
1221  break;
1222  }
1223  }
1224  if( nIndex == EDIT_NOLIMIT )
1225  {
1226  nIndex = 0;
1227  sal_Int32 nFinalIndex = 0;
1228  long nDiff = std::abs( pDX[0]-nX );
1229  sal_Int32 i = 0;
1230  if (!aText.isEmpty())
1231  {
1232  aText.iterateCodePoints(&i); //skip the first character
1233  }
1234  while (i < aText.getLength())
1235  {
1236  long nNewDiff = std::abs( pDX[2*i]-nX );
1237 
1238  if( nNewDiff < nDiff )
1239  {
1240  nIndex = i;
1241  nDiff = nNewDiff;
1242  }
1243 
1244  nFinalIndex = i;
1245 
1246  aText.iterateCodePoints(&i);
1247  }
1248  if (nIndex == nFinalIndex && std::abs( pDX[2*nIndex+1] - nX ) < nDiff)
1249  nIndex = EDIT_NOLIMIT;
1250  }
1251 
1252  return nIndex;
1253 }
1254 
1255 void Edit::ImplSetCursorPos( sal_Int32 nChar, bool bSelect )
1256 {
1257  Selection aSelection( maSelection );
1258  aSelection.Max() = nChar;
1259  if ( !bSelect )
1260  aSelection.Min() = aSelection.Max();
1261  ImplSetSelection( aSelection );
1262 }
1263 
1265 {
1266  if ( GetSelection().Len() )
1267  {
1268  css::uno::Reference<css::datatransfer::clipboard::XClipboard> aSelection(GetPrimarySelection());
1269  ImplCopy( aSelection );
1270  }
1271 }
1272 
1273 void Edit::ImplCopy( uno::Reference< datatransfer::clipboard::XClipboard > const & rxClipboard )
1274 {
1276 }
1277 
1278 void Edit::ImplPaste( uno::Reference< datatransfer::clipboard::XClipboard > const & rxClipboard )
1279 {
1280  if ( !rxClipboard.is() )
1281  return;
1282 
1283  uno::Reference< datatransfer::XTransferable > xDataObj;
1284 
1285  try
1286  {
1287  SolarMutexReleaser aReleaser;
1288  xDataObj = rxClipboard->getContents();
1289  }
1290  catch( const css::uno::Exception& )
1291  {
1292  }
1293 
1294  if ( !xDataObj.is() )
1295  return;
1296 
1297  datatransfer::DataFlavor aFlavor;
1298  SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor );
1299  try
1300  {
1301  uno::Any aData = xDataObj->getTransferData( aFlavor );
1302  OUString aText;
1303  aData >>= aText;
1304 
1305  Selection aSelection(maSelection);
1306  aSelection.Justify();
1307  if (ImplTruncateToMaxLen(aText, aSelection.Len()))
1309 
1310  ReplaceSelected( aText );
1311  }
1312  catch( const css::uno::Exception& )
1313  {
1314  }
1315 }
1316 
1317 void Edit::MouseButtonDown( const MouseEvent& rMEvt )
1318 {
1319  if ( mpSubEdit )
1320  {
1321  Control::MouseButtonDown( rMEvt );
1322  return;
1323  }
1324 
1325  sal_Int32 nCharPos = ImplGetCharPos( rMEvt.GetPosPixel() );
1326  Selection aSelection( maSelection );
1327  aSelection.Justify();
1328 
1329  if ( rMEvt.GetClicks() < 4 )
1330  {
1331  mbClickedInSelection = false;
1332  if ( rMEvt.GetClicks() == 3 )
1333  {
1336 
1337  }
1338  else if ( rMEvt.GetClicks() == 2 )
1339  {
1340  uno::Reference < i18n::XBreakIterator > xBI = ImplGetBreakIterator();
1341  i18n::Boundary aBoundary = xBI->getWordBoundary( maText.toString(), aSelection.Max(),
1342  GetSettings().GetLanguageTag().getLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, true );
1343  ImplSetSelection( Selection( aBoundary.startPos, aBoundary.endPos ) );
1345  }
1346  else if ( !rMEvt.IsShift() && HasFocus() && aSelection.IsInside( nCharPos ) )
1347  mbClickedInSelection = true;
1348  else if ( rMEvt.IsLeft() )
1349  ImplSetCursorPos( nCharPos, rMEvt.IsShift() );
1350 
1351  if ( !mbClickedInSelection && rMEvt.IsLeft() && ( rMEvt.GetClicks() == 1 ) )
1353  }
1354 
1355  GrabFocus();
1356 }
1357 
1358 void Edit::MouseButtonUp( const MouseEvent& rMEvt )
1359 {
1360  if ( mbClickedInSelection && rMEvt.IsLeft() )
1361  {
1362  sal_Int32 nCharPos = ImplGetCharPos( rMEvt.GetPosPixel() );
1363  ImplSetCursorPos( nCharPos, false );
1364  mbClickedInSelection = false;
1365  }
1366  else if ( rMEvt.IsMiddle() && !mbReadOnly &&
1368  {
1369  css::uno::Reference<css::datatransfer::clipboard::XClipboard> aSelection(Window::GetPrimarySelection());
1370  ImplPaste( aSelection );
1371  Modify();
1372  }
1373 }
1374 
1375 void Edit::Tracking( const TrackingEvent& rTEvt )
1376 {
1377  if ( rTEvt.IsTrackingEnded() )
1378  {
1379  if ( mbClickedInSelection )
1380  {
1381  sal_Int32 nCharPos = ImplGetCharPos( rTEvt.GetMouseEvent().GetPosPixel() );
1382  ImplSetCursorPos( nCharPos, false );
1383  mbClickedInSelection = false;
1384  }
1385  else if ( rTEvt.GetMouseEvent().IsLeft() )
1386  {
1388  }
1389  }
1390  else
1391  {
1392  if( !mbClickedInSelection )
1393  {
1394  sal_Int32 nCharPos = ImplGetCharPos( rTEvt.GetMouseEvent().GetPosPixel() );
1395  ImplSetCursorPos( nCharPos, true );
1396  }
1397  }
1398 }
1399 
1401 {
1402  bool bDone = false;
1403  sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
1404  KeyFuncType eFunc = rKEvt.GetKeyCode().GetFunction();
1405 
1406  mbInternModified = false;
1407 
1408  if ( eFunc != KeyFuncType::DONTKNOW )
1409  {
1410  switch ( eFunc )
1411  {
1412  case KeyFuncType::CUT:
1413  {
1414  if ( !mbReadOnly && maSelection.Len() && !mbPassword )
1415  {
1416  Cut();
1417  Modify();
1418  bDone = true;
1419  }
1420  }
1421  break;
1422 
1423  case KeyFuncType::COPY:
1424  {
1425  if ( !mbPassword )
1426  {
1427  Copy();
1428  bDone = true;
1429  }
1430  }
1431  break;
1432 
1433  case KeyFuncType::PASTE:
1434  {
1435  if ( !mbReadOnly )
1436  {
1437  Paste();
1438  bDone = true;
1439  }
1440  }
1441  break;
1442 
1443  case KeyFuncType::UNDO:
1444  {
1445  if ( !mbReadOnly )
1446  {
1447  Undo();
1448  bDone = true;
1449  }
1450  }
1451  break;
1452 
1453  default:
1454  eFunc = KeyFuncType::DONTKNOW;
1455  }
1456  }
1457 
1458  if ( !bDone && rKEvt.GetKeyCode().IsMod1() && !rKEvt.GetKeyCode().IsMod2() )
1459  {
1460  if ( nCode == KEY_A )
1461  {
1462  ImplSetSelection( Selection( 0, maText.getLength() ) );
1463  bDone = true;
1464  }
1465  else if ( rKEvt.GetKeyCode().IsShift() && (nCode == KEY_S) )
1466  {
1468  {
1469  Selection aSaveSel = GetSelection(); // if someone changes the selection in Get/LoseFocus, e.g. URL bar
1470  OUString aChars = pImplFncGetSpecialChars( GetFrameWeld(), GetFont() );
1471  SetSelection( aSaveSel );
1472  if ( !aChars.isEmpty() )
1473  {
1474  ImplInsertText( aChars );
1475  Modify();
1476  }
1477  bDone = true;
1478  }
1479  }
1480  }
1481 
1482  if ( eFunc == KeyFuncType::DONTKNOW && ! bDone )
1483  {
1484  switch ( nCode )
1485  {
1486  case css::awt::Key::SELECT_ALL:
1487  {
1488  ImplSetSelection( Selection( 0, maText.getLength() ) );
1489  bDone = true;
1490  }
1491  break;
1492 
1493  case KEY_LEFT:
1494  case KEY_RIGHT:
1495  case KEY_HOME:
1496  case KEY_END:
1497  case css::awt::Key::MOVE_WORD_FORWARD:
1498  case css::awt::Key::SELECT_WORD_FORWARD:
1499  case css::awt::Key::MOVE_WORD_BACKWARD:
1500  case css::awt::Key::SELECT_WORD_BACKWARD:
1501  case css::awt::Key::MOVE_TO_BEGIN_OF_LINE:
1502  case css::awt::Key::MOVE_TO_END_OF_LINE:
1503  case css::awt::Key::SELECT_TO_BEGIN_OF_LINE:
1504  case css::awt::Key::SELECT_TO_END_OF_LINE:
1505  case css::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
1506  case css::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
1507  case css::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
1508  case css::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
1509  case css::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
1510  case css::awt::Key::MOVE_TO_END_OF_DOCUMENT:
1511  case css::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
1512  case css::awt::Key::SELECT_TO_END_OF_DOCUMENT:
1513  {
1514  if ( !rKEvt.GetKeyCode().IsMod2() )
1515  {
1517  uno::Reference < i18n::XBreakIterator > xBI = ImplGetBreakIterator();
1518 
1519  Selection aSel( maSelection );
1520  bool bWord = rKEvt.GetKeyCode().IsMod1();
1521  bool bSelect = rKEvt.GetKeyCode().IsShift();
1522  bool bGoLeft = (nCode == KEY_LEFT);
1523  bool bGoRight = (nCode == KEY_RIGHT);
1524  bool bGoHome = (nCode == KEY_HOME);
1525  bool bGoEnd = (nCode == KEY_END);
1526 
1527  switch( nCode )
1528  {
1529  case css::awt::Key::MOVE_WORD_FORWARD:
1530  bGoRight = bWord = true;break;
1531  case css::awt::Key::SELECT_WORD_FORWARD:
1532  bGoRight = bSelect = bWord = true;break;
1533  case css::awt::Key::MOVE_WORD_BACKWARD:
1534  bGoLeft = bWord = true;break;
1535  case css::awt::Key::SELECT_WORD_BACKWARD:
1536  bGoLeft = bSelect = bWord = true;break;
1537  case css::awt::Key::SELECT_TO_BEGIN_OF_LINE:
1538  case css::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
1539  case css::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
1540  bSelect = true;
1541  [[fallthrough]];
1542  case css::awt::Key::MOVE_TO_BEGIN_OF_LINE:
1543  case css::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
1544  case css::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
1545  bGoHome = true;break;
1546  case css::awt::Key::SELECT_TO_END_OF_LINE:
1547  case css::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
1548  case css::awt::Key::SELECT_TO_END_OF_DOCUMENT:
1549  bSelect = true;
1550  [[fallthrough]];
1551  case css::awt::Key::MOVE_TO_END_OF_LINE:
1552  case css::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
1553  case css::awt::Key::MOVE_TO_END_OF_DOCUMENT:
1554  bGoEnd = true;break;
1555  default:
1556  break;
1557  }
1558 
1559  // range is checked in ImplSetSelection ...
1560  if ( bGoLeft && aSel.Max() )
1561  {
1562  if ( bWord )
1563  {
1564  i18n::Boundary aBoundary = xBI->getWordBoundary( maText.toString(), aSel.Max(),
1565  GetSettings().GetLanguageTag().getLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES, true );
1566  if ( aBoundary.startPos == aSel.Max() )
1567  aBoundary = xBI->previousWord( maText.toString(), aSel.Max(),
1568  GetSettings().GetLanguageTag().getLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
1569  aSel.Max() = aBoundary.startPos;
1570  }
1571  else
1572  {
1573  sal_Int32 nCount = 1;
1574  aSel.Max() = xBI->previousCharacters( maText.toString(), aSel.Max(),
1575  GetSettings().GetLanguageTag().getLocale(), i18n::CharacterIteratorMode::SKIPCHARACTER, nCount, nCount );
1576  }
1577  }
1578  else if ( bGoRight && ( aSel.Max() < maText.getLength() ) )
1579  {
1580  if ( bWord )
1581  {
1582  i18n::Boundary aBoundary = xBI->nextWord( maText.toString(), aSel.Max(),
1583  GetSettings().GetLanguageTag().getLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES );
1584  aSel.Max() = aBoundary.startPos;
1585  }
1586  else
1587  {
1588  sal_Int32 nCount = 1;
1589  aSel.Max() = xBI->nextCharacters( maText.toString(), aSel.Max(),
1590  GetSettings().GetLanguageTag().getLocale(), i18n::CharacterIteratorMode::SKIPCHARACTER, nCount, nCount );
1591  }
1592  }
1593  else if ( bGoHome )
1594  {
1595  aSel.Max() = 0;
1596  }
1597  else if ( bGoEnd )
1598  {
1599  aSel.Max() = EDIT_NOLIMIT;
1600  }
1601 
1602  if ( !bSelect )
1603  aSel.Min() = aSel.Max();
1604 
1605  if ( aSel != GetSelection() )
1606  {
1607  ImplSetSelection( aSel );
1609  }
1610 
1611  if (bGoEnd && maAutocompleteHdl.IsSet() && !rKEvt.GetKeyCode().GetModifier())
1612  {
1613  if ( (maSelection.Min() == maSelection.Max()) && (maSelection.Min() == maText.getLength()) )
1614  {
1615  maAutocompleteHdl.Call(*this);
1616  }
1617  }
1618 
1619  bDone = true;
1620  }
1621  }
1622  break;
1623 
1624  case css::awt::Key::DELETE_WORD_BACKWARD:
1625  case css::awt::Key::DELETE_WORD_FORWARD:
1626  case css::awt::Key::DELETE_TO_BEGIN_OF_LINE:
1627  case css::awt::Key::DELETE_TO_END_OF_LINE:
1628  case KEY_BACKSPACE:
1629  case KEY_DELETE:
1630  {
1631  if ( !mbReadOnly && !rKEvt.GetKeyCode().IsMod2() )
1632  {
1633  sal_uInt8 nDel = (nCode == KEY_DELETE) ? EDIT_DEL_RIGHT : EDIT_DEL_LEFT;
1635  if ( (nMode == EDIT_DELMODE_RESTOFWORD) && rKEvt.GetKeyCode().IsShift() )
1637  switch( nCode )
1638  {
1639  case css::awt::Key::DELETE_WORD_BACKWARD:
1640  nDel = EDIT_DEL_LEFT;
1641  nMode = EDIT_DELMODE_RESTOFWORD;
1642  break;
1643  case css::awt::Key::DELETE_WORD_FORWARD:
1644  nDel = EDIT_DEL_RIGHT;
1645  nMode = EDIT_DELMODE_RESTOFWORD;
1646  break;
1647  case css::awt::Key::DELETE_TO_BEGIN_OF_LINE:
1648  nDel = EDIT_DEL_LEFT;
1650  break;
1651  case css::awt::Key::DELETE_TO_END_OF_LINE:
1652  nDel = EDIT_DEL_RIGHT;
1654  break;
1655  default: break;
1656  }
1657  sal_Int32 nOldLen = maText.getLength();
1658  ImplDelete( maSelection, nDel, nMode );
1659  if ( maText.getLength() != nOldLen )
1660  Modify();
1661  bDone = true;
1662  }
1663  }
1664  break;
1665 
1666  case KEY_INSERT:
1667  {
1668  if ( !mpIMEInfos && !mbReadOnly && !rKEvt.GetKeyCode().IsMod2() )
1669  {
1671  bDone = true;
1672  }
1673  }
1674  break;
1675 
1676  case KEY_RETURN:
1677  if (maActivateHdl.IsSet())
1678  {
1679  bDone = maActivateHdl.Call(*this);
1680  }
1681  break;
1682 
1683  default:
1684  {
1685  if ( IsCharInput( rKEvt ) )
1686  {
1687  bDone = true; // read characters also when in ReadOnly
1688  if ( !mbReadOnly )
1689  {
1690  ImplInsertText(OUString(rKEvt.GetCharCode()), nullptr, true);
1691  if (maAutocompleteHdl.IsSet())
1692  {
1693  if ( (maSelection.Min() == maSelection.Max()) && (maSelection.Min() == maText.getLength()) )
1694  {
1695  maAutocompleteHdl.Call(*this);
1696  }
1697  }
1698  }
1699  }
1700  }
1701  }
1702  }
1703 
1704  if ( mbInternModified )
1705  Modify();
1706 
1707  return bDone;
1708 }
1709 
1710 void Edit::KeyInput( const KeyEvent& rKEvt )
1711 {
1712  if ( mpSubEdit || !ImplHandleKeyEvent( rKEvt ) )
1713  Control::KeyInput( rKEvt );
1714 }
1715 
1717 {
1718  mpControlData->mpLayoutData.reset( new vcl::ControlLayoutData );
1719  const_cast<Edit*>(this)->Invalidate();
1720 }
1721 
1722 void Edit::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRectangle)
1723 {
1724  if (!mpSubEdit)
1725  ImplRepaint(rRenderContext, rRectangle);
1726 }
1727 
1729 {
1730  if ( !mpSubEdit && IsReallyVisible() )
1731  {
1732  Control::Resize();
1733  // because of vertical centering...
1734  mnXOffset = 0;
1735  ImplAlign();
1736  Invalidate();
1737  ImplShowCursor();
1738  }
1739 }
1740 
1741 void Edit::Draw( OutputDevice* pDev, const Point& rPos, DrawFlags nFlags )
1742 {
1743  ApplySettings(*pDev);
1744 
1745  Point aPos = pDev->LogicToPixel( rPos );
1746  Size aSize = GetSizePixel();
1747  vcl::Font aFont = GetDrawPixelFont( pDev );
1748 
1749  pDev->Push();
1750  pDev->SetMapMode();
1751  pDev->SetFont( aFont );
1752  pDev->SetTextFillColor();
1753 
1754  // Border/Background
1755  pDev->SetLineColor();
1756  pDev->SetFillColor();
1757  bool bBorder = (GetStyle() & WB_BORDER);
1758  bool bBackground = IsControlBackground();
1759  if ( bBorder || bBackground )
1760  {
1761  tools::Rectangle aRect( aPos, aSize );
1762  if ( bBorder )
1763  {
1764  ImplDrawFrame( pDev, aRect );
1765  }
1766  if ( bBackground )
1767  {
1769  pDev->DrawRect( aRect );
1770  }
1771  }
1772 
1773  // Content
1774  if ( nFlags & DrawFlags::Mono )
1775  pDev->SetTextColor( COL_BLACK );
1776  else
1777  {
1778  if ( !IsEnabled() )
1779  {
1780  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1781  pDev->SetTextColor( rStyleSettings.GetDisableColor() );
1782  }
1783  else
1784  {
1785  pDev->SetTextColor( GetTextColor() );
1786  }
1787  }
1788 
1789  const long nOnePixel = GetDrawPixel( pDev, 1 );
1790  const long nOffX = 3*nOnePixel;
1792  tools::Rectangle aTextRect( aPos, aSize );
1793 
1794  if ( GetStyle() & WB_CENTER )
1795  nTextStyle |= DrawTextFlags::Center;
1796  else if ( GetStyle() & WB_RIGHT )
1797  nTextStyle |= DrawTextFlags::Right;
1798  else
1799  nTextStyle |= DrawTextFlags::Left;
1800 
1801  aTextRect.AdjustLeft(nOffX );
1802  aTextRect.AdjustRight( -nOffX );
1803 
1804  OUString aText = ImplGetText();
1805  long nTextHeight = pDev->GetTextHeight();
1806  long nTextWidth = pDev->GetTextWidth( aText );
1807  long nOffY = (aSize.Height() - nTextHeight) / 2;
1808 
1809  // Clipping?
1810  if ( (nOffY < 0) ||
1811  ((nOffY+nTextHeight) > aSize.Height()) ||
1812  ((nOffX+nTextWidth) > aSize.Width()) )
1813  {
1814  tools::Rectangle aClip( aPos, aSize );
1815  if ( nTextHeight > aSize.Height() )
1816  aClip.AdjustBottom(nTextHeight-aSize.Height()+1 ); // prevent HP printers from 'optimizing'
1817  pDev->IntersectClipRegion( aClip );
1818  }
1819 
1820  pDev->DrawText( aTextRect, aText, nTextStyle );
1821  pDev->Pop();
1822 
1823  if ( GetSubEdit() )
1824  {
1825  Size aOrigSize(GetSubEdit()->GetSizePixel());
1827  GetSubEdit()->Draw(pDev, rPos, nFlags);
1828  GetSubEdit()->SetSizePixel(aOrigSize);
1829  }
1830 }
1831 
1833 {
1834  // allow control to show focused state
1835  vcl::Window *pInvalWin = pWin;
1836  for (;;)
1837  {
1838  vcl::Window* pBorder = pInvalWin->GetWindow( GetWindowType::Border );
1839  if (pBorder == pInvalWin || !pBorder ||
1840  pInvalWin->ImplGetFrame() != pBorder->ImplGetFrame() )
1841  break;
1842  pInvalWin = pBorder;
1843  }
1844 
1846 }
1847 
1849 {
1850  if ( mpSubEdit )
1852  else if ( !mbActivePopup )
1853  {
1854  maUndoText = maText.toString();
1856  if ( !( GetStyle() & (WB_NOHIDESELECTION|WB_READONLY) )
1858  {
1859  if ( nSelOptions & SelectionOptions::ShowFirst )
1860  {
1861  maSelection.Min() = maText.getLength();
1862  maSelection.Max() = 0;
1863  }
1864  else
1865  {
1866  maSelection.Min() = 0;
1867  maSelection.Max() = maText.getLength();
1868  }
1869  if ( mbIsSubEdit )
1871  else
1873  }
1874 
1875  ImplShowCursor();
1876 
1877  // FIXME: this is currently only on macOS
1878  // check for other platforms that need similar handling
1879  if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
1882  {
1884  }
1885  else if ( maSelection.Len() )
1886  {
1887  // paint the selection
1888  if ( !HasPaintEvent() )
1890  else
1891  Invalidate();
1892  }
1893 
1895  }
1896 
1898 }
1899 
1901 {
1902  if ( !mpSubEdit )
1903  {
1904  // FIXME: this is currently only on macOS
1905  // check for other platforms that need similar handling
1906  if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
1909  {
1911  }
1912 
1913  if ( !mbActivePopup && !( GetStyle() & WB_NOHIDESELECTION ) && maSelection.Len() )
1914  ImplInvalidateOrRepaint(); // paint the selection
1915  }
1916 
1918 }
1919 
1920 void Edit::Command( const CommandEvent& rCEvt )
1921 {
1922  if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
1923  {
1925 
1926  bool bEnableCut = true;
1927  bool bEnableCopy = true;
1928  bool bEnableDelete = true;
1929  bool bEnablePaste = true;
1930  bool bEnableSpecialChar = true;
1931 
1932  if ( !maSelection.Len() )
1933  {
1934  bEnableCut = false;
1935  bEnableCopy = false;
1936  bEnableDelete = false;
1937  }
1938 
1939  if ( IsReadOnly() )
1940  {
1941  bEnableCut = false;
1942  bEnablePaste = false;
1943  bEnableDelete = false;
1944  bEnableSpecialChar = false;
1945  }
1946  else
1947  {
1948  // only paste if text available in clipboard
1949  bool bData = false;
1950  uno::Reference< datatransfer::clipboard::XClipboard > xClipboard = GetClipboard();
1951 
1952  if ( xClipboard.is() )
1953  {
1954  uno::Reference< datatransfer::XTransferable > xDataObj;
1955  {
1956  SolarMutexReleaser aReleaser;
1957  xDataObj = xClipboard->getContents();
1958  }
1959  if ( xDataObj.is() )
1960  {
1961  datatransfer::DataFlavor aFlavor;
1962  SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor );
1963  bData = xDataObj->isDataFlavorSupported( aFlavor );
1964  }
1965  }
1966  bEnablePaste = bData;
1967  }
1968 
1969  pPopup->EnableItem(pPopup->GetItemId("cut"), bEnableCut);
1970  pPopup->EnableItem(pPopup->GetItemId("copy"), bEnableCopy);
1971  pPopup->EnableItem(pPopup->GetItemId("delete"), bEnableDelete);
1972  pPopup->EnableItem(pPopup->GetItemId("paste"), bEnablePaste);
1973  pPopup->EnableItem(pPopup->GetItemId("specialchar"), bEnableSpecialChar);
1974  pPopup->EnableItem(
1975  pPopup->GetItemId("undo"),
1976  std::u16string_view(maUndoText)
1977  != std::u16string_view(maText.getStr(), maText.getLength()));
1978  bool bAllSelected = maSelection.Min() == 0 && maSelection.Max() == maText.getLength();
1979  pPopup->EnableItem(pPopup->GetItemId("selectall"), !bAllSelected);
1980  pPopup->ShowItem(pPopup->GetItemId("specialchar"), pImplFncGetSpecialChars != nullptr);
1981 
1982  mbActivePopup = true;
1983  Selection aSaveSel = GetSelection(); // if someone changes selection in Get/LoseFocus, e.g. URL bar
1984  Point aPos = rCEvt.GetMousePosPixel();
1985  if ( !rCEvt.IsMouseEvent() )
1986  {
1987  // Show menu eventually centered in selection
1988  Size aSize = GetOutputSizePixel();
1989  aPos = Point( aSize.Width()/2, aSize.Height()/2 );
1990  }
1991  sal_uInt16 n = pPopup->Execute( this, aPos );
1992  SetSelection( aSaveSel );
1993  OString sCommand = pPopup->GetItemIdent(n);
1994  if (sCommand == "undo")
1995  {
1996  Undo();
1997  Modify();
1998  }
1999  else if (sCommand == "cut")
2000  {
2001  Cut();
2002  Modify();
2003  }
2004  else if (sCommand == "copy")
2005  {
2006  Copy();
2007  }
2008  else if (sCommand == "paste")
2009  {
2010  Paste();
2011  Modify();
2012  }
2013  else if (sCommand == "delete")
2014  {
2015  DeleteSelected();
2016  Modify();
2017  }
2018  else if (sCommand == "selectall")
2019  {
2020  ImplSetSelection( Selection( 0, maText.getLength() ) );
2021  }
2022  else if (sCommand == "specialchar" && pImplFncGetSpecialChars)
2023  {
2024  OUString aChars = pImplFncGetSpecialChars(GetFrameWeld(), GetFont());
2025  if (!IsDisposed()) // destroyed while the insert special character dialog was still open
2026  {
2027  SetSelection( aSaveSel );
2028  if (!aChars.isEmpty())
2029  {
2030  ImplInsertText( aChars );
2031  Modify();
2032  }
2033  }
2034  }
2035  pPopup.clear();
2036  mbActivePopup = false;
2037  }
2038  else if ( rCEvt.GetCommand() == CommandEventId::StartExtTextInput )
2039  {
2040  DeleteSelected();
2041  sal_Int32 nPos = maSelection.Max();
2042  mpIMEInfos.reset(new Impl_IMEInfos( nPos, maText.copy(nPos).makeStringAndClear() ));
2043  mpIMEInfos->bWasCursorOverwrite = !IsInsertMode();
2044  }
2045  else if ( rCEvt.GetCommand() == CommandEventId::EndExtTextInput )
2046  {
2047  bool bInsertMode = !mpIMEInfos->bWasCursorOverwrite;
2048  mpIMEInfos.reset();
2049 
2050  SetInsertMode(bInsertMode);
2051  Modify();
2052 
2053  Invalidate();
2054 
2055  // #i25161# call auto complete handler for ext text commit also
2056  if (maAutocompleteHdl.IsSet())
2057  {
2058  if ( (maSelection.Min() == maSelection.Max()) && (maSelection.Min() == maText.getLength()) )
2059  {
2060  maAutocompleteHdl.Call(*this);
2061  }
2062  }
2063  }
2064  else if ( rCEvt.GetCommand() == CommandEventId::ExtTextInput )
2065  {
2067 
2068  maText.remove( mpIMEInfos->nPos, mpIMEInfos->nLen );
2069  maText.insert( mpIMEInfos->nPos, pData->GetText() );
2070  if ( mpIMEInfos->bWasCursorOverwrite )
2071  {
2072  const sal_Int32 nOldIMETextLen = mpIMEInfos->nLen;
2073  const sal_Int32 nNewIMETextLen = pData->GetText().getLength();
2074  if ( ( nOldIMETextLen > nNewIMETextLen ) &&
2075  ( nNewIMETextLen < mpIMEInfos->aOldTextAfterStartPos.getLength() ) )
2076  {
2077  // restore old characters
2078  const sal_Int32 nRestore = nOldIMETextLen - nNewIMETextLen;
2079  maText.insert( mpIMEInfos->nPos + nNewIMETextLen, mpIMEInfos->aOldTextAfterStartPos.copy( nNewIMETextLen, nRestore ) );
2080  }
2081  else if ( ( nOldIMETextLen < nNewIMETextLen ) &&
2082  ( nOldIMETextLen < mpIMEInfos->aOldTextAfterStartPos.getLength() ) )
2083  {
2084  const sal_Int32 nOverwrite = ( nNewIMETextLen > mpIMEInfos->aOldTextAfterStartPos.getLength()
2085  ? mpIMEInfos->aOldTextAfterStartPos.getLength() : nNewIMETextLen ) - nOldIMETextLen;
2086  maText.remove( mpIMEInfos->nPos + nNewIMETextLen, nOverwrite );
2087  }
2088  }
2089 
2090  if ( pData->GetTextAttr() )
2091  {
2092  mpIMEInfos->CopyAttribs( pData->GetTextAttr(), pData->GetText().getLength() );
2093  mpIMEInfos->bCursor = pData->IsCursorVisible();
2094  }
2095  else
2096  {
2097  mpIMEInfos->DestroyAttribs();
2098  }
2099 
2101  sal_Int32 nCursorPos = mpIMEInfos->nPos + pData->GetCursorPos();
2102  SetSelection( Selection( nCursorPos, nCursorPos ) );
2103  SetInsertMode( !pData->IsCursorOverwrite() );
2104 
2105  if ( pData->IsCursorVisible() )
2106  GetCursor()->Show();
2107  else
2108  GetCursor()->Hide();
2109  }
2110  else if ( rCEvt.GetCommand() == CommandEventId::CursorPos )
2111  {
2112  if ( mpIMEInfos )
2113  {
2114  sal_Int32 nCursorPos = GetSelection().Max();
2115  SetCursorRect( nullptr, GetTextWidth( maText.toString(), nCursorPos, mpIMEInfos->nPos+mpIMEInfos->nLen-nCursorPos ) );
2116  }
2117  else
2118  {
2119  SetCursorRect();
2120  }
2121  }
2122  else if ( rCEvt.GetCommand() == CommandEventId::SelectionChange )
2123  {
2125  Selection aSelection( pData->GetStart(), pData->GetEnd() );
2126  SetSelection(aSelection);
2127  }
2128  else if ( rCEvt.GetCommand() == CommandEventId::QueryCharPosition )
2129  {
2130  if (mpIMEInfos && mpIMEInfos->nLen > 0)
2131  {
2132  OUString aText = ImplGetText();
2133  long nDXBuffer[256];
2134  std::unique_ptr<long[]> pDXBuffer;
2135  long* pDX = nDXBuffer;
2136 
2137  if( !aText.isEmpty() )
2138  {
2139  if( o3tl::make_unsigned(2*aText.getLength()) > SAL_N_ELEMENTS(nDXBuffer) )
2140  {
2141  pDXBuffer.reset(new long[2*(aText.getLength()+1)]);
2142  pDX = pDXBuffer.get();
2143  }
2144 
2145  GetCaretPositions( aText, pDX, 0, aText.getLength() );
2146  }
2147  long nTH = GetTextHeight();
2149 
2150  std::unique_ptr<tools::Rectangle[]> aRects(new tools::Rectangle[ mpIMEInfos->nLen ]);
2151  for ( int nIndex = 0; nIndex < mpIMEInfos->nLen; ++nIndex )
2152  {
2153  tools::Rectangle aRect( aPos, Size( 10, nTH ) );
2154  aRect.SetLeft( pDX[2*(nIndex+mpIMEInfos->nPos)] + mnXOffset + ImplGetExtraXOffset() );
2155  aRects[ nIndex ] = aRect;
2156  }
2157  SetCompositionCharRect( aRects.get(), mpIMEInfos->nLen );
2158  }
2159  }
2160  else
2161  Control::Command( rCEvt );
2162 }
2163 
2165 {
2166  if (nType == StateChangedType::InitShow)
2167  {
2168  if (!mpSubEdit)
2169  {
2170  mnXOffset = 0; // if GrabFocus before while size was still wrong
2171  ImplAlign();
2172  if (!mpSubEdit)
2173  ImplShowCursor(false);
2174  Invalidate();
2175  }
2176  }
2177  else if (nType == StateChangedType::Enable)
2178  {
2179  if (!mpSubEdit)
2180  {
2181  // change text color only
2183  }
2184  }
2185  else if (nType == StateChangedType::Style || nType == StateChangedType::Mirroring)
2186  {
2187  WinBits nStyle = GetStyle();
2188  if (nType == StateChangedType::Style)
2189  {
2190  nStyle = ImplInitStyle(GetStyle());
2191  SetStyle(nStyle);
2192  }
2193 
2194  sal_uInt16 nOldAlign = mnAlign;
2196 
2197  // hack: right align until keyinput and cursor travelling works
2198  // edits are always RTL disabled
2199  // however the parent edits contain the correct setting
2200  if (mbIsSubEdit && GetParent()->IsRTLEnabled())
2201  {
2202  if (GetParent()->GetStyle() & WB_LEFT)
2204  if (nType == StateChangedType::Mirroring)
2206  }
2207  else if (mbIsSubEdit && !GetParent()->IsRTLEnabled())
2208  {
2209  if (nType == StateChangedType::Mirroring)
2211  }
2212 
2213  if (nStyle & WB_RIGHT)
2215  else if (nStyle & WB_CENTER)
2217  if (!maText.isEmpty() && (mnAlign != nOldAlign))
2218  {
2219  ImplAlign();
2220  Invalidate();
2221  }
2222 
2223  }
2224  else if ((nType == StateChangedType::Zoom) || (nType == StateChangedType::ControlFont))
2225  {
2226  if (!mpSubEdit)
2227  {
2228  ApplySettings(*this);
2229  ImplShowCursor();
2230  Invalidate();
2231  }
2232  }
2234  {
2235  if (!mpSubEdit)
2236  {
2237  ApplySettings(*this);
2238  Invalidate();
2239  }
2240  }
2241 
2242  Control::StateChanged(nType);
2243 }
2244 
2246 {
2247  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
2249  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
2250  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
2251  {
2252  if ( !mpSubEdit )
2253  {
2254  ApplySettings(*this);
2255  ImplShowCursor();
2256  Invalidate();
2257  }
2258  }
2259 
2260  Control::DataChanged( rDCEvt );
2261 }
2262 
2264 {
2265  if (!mpDDInfo->bVisCursor)
2266  {
2267  long nTextWidth = GetTextWidth( maText.toString(), 0, mpDDInfo->nDropPos );
2268  long nTextHeight = GetTextHeight();
2269  tools::Rectangle aCursorRect( Point( nTextWidth + mnXOffset, (GetOutputSize().Height()-nTextHeight)/2 ), Size( 2, nTextHeight ) );
2270  mpDDInfo->aCursor.SetWindow( this );
2271  mpDDInfo->aCursor.SetPos( aCursorRect.TopLeft() );
2272  mpDDInfo->aCursor.SetSize( aCursorRect.GetSize() );
2273  mpDDInfo->aCursor.Show();
2274  mpDDInfo->bVisCursor = true;
2275  }
2276 }
2277 
2279 {
2280  if ( mpDDInfo && mpDDInfo->bVisCursor )
2281  {
2282  mpDDInfo->aCursor.Hide();
2283  mpDDInfo->bVisCursor = false;
2284  }
2285 }
2286 
2287 TextFilter::TextFilter(const OUString &rForbiddenChars)
2288  : sForbiddenChars(rForbiddenChars)
2289 {
2290 }
2291 
2293 {
2294 }
2295 
2296 OUString TextFilter::filter(const OUString &rText)
2297 {
2298  OUString sTemp(rText);
2299  for (sal_Int32 i = 0; i < sForbiddenChars.getLength(); ++i)
2300  {
2301  sTemp = sTemp.replaceAll(OUStringChar(sForbiddenChars[i]), "");
2302  }
2303  return sTemp;
2304 }
2305 
2307 {
2308  Selection aSel = GetSelection();
2309  const OUString sOrig = GetText();
2310  const OUString sNew = mpFilterText->filter(GetText());
2311  if (sOrig != sNew)
2312  {
2313  sal_Int32 nDiff = sOrig.getLength() - sNew.getLength();
2314  if (nDiff)
2315  {
2316  aSel.setMin(aSel.getMin() - nDiff);
2317  aSel.setMax(aSel.getMin());
2318  }
2319  SetText(sNew);
2320  SetSelection(aSel);
2321  }
2322 }
2323 
2325 {
2326  if (mpFilterText)
2327  filterText();
2328 
2329  if ( mbIsSubEdit )
2330  {
2331  static_cast<Edit*>(GetParent())->Modify();
2332  }
2333  else
2334  {
2336  // have been destroyed while calling into the handlers
2337  return;
2338 
2339  // #i13677# notify edit listeners about caret position change
2341  // FIXME: this is currently only on macOS
2342  // check for other platforms that need similar handling
2343  if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
2346  {
2348  }
2349  }
2350 }
2351 
2353 {
2354  mcEchoChar = c;
2355  if ( mpSubEdit )
2356  mpSubEdit->SetEchoChar( c );
2357 }
2358 
2359 void Edit::SetReadOnly( bool bReadOnly )
2360 {
2361  if ( mbReadOnly != bReadOnly )
2362  {
2363  mbReadOnly = bReadOnly;
2364  if ( mpSubEdit )
2365  mpSubEdit->SetReadOnly( bReadOnly );
2366 
2368  }
2369 }
2370 
2371 void Edit::SetInsertMode( bool bInsert )
2372 {
2373  if ( bInsert != mbInsertMode )
2374  {
2375  mbInsertMode = bInsert;
2376  if ( mpSubEdit )
2377  mpSubEdit->SetInsertMode( bInsert );
2378  else
2379  ImplShowCursor();
2380  }
2381 }
2382 
2384 {
2385  if ( mpSubEdit )
2386  return mpSubEdit->IsInsertMode();
2387  else
2388  return mbInsertMode;
2389 }
2390 
2391 void Edit::SetMaxTextLen(sal_Int32 nMaxLen)
2392 {
2393  mnMaxTextLen = nMaxLen > 0 ? nMaxLen : EDIT_NOLIMIT;
2394 
2395  if ( mpSubEdit )
2397  else
2398  {
2399  if ( maText.getLength() > mnMaxTextLen )
2401  }
2402 }
2403 
2404 void Edit::SetSelection( const Selection& rSelection )
2405 {
2406  // If the selection was changed from outside, e.g. by MouseButtonDown, don't call Tracking()
2407  // directly afterwards which would change the selection again
2408  if ( IsTracking() )
2409  EndTracking();
2410  else if ( mpSubEdit && mpSubEdit->IsTracking() )
2412 
2413  ImplSetSelection( rSelection );
2414 }
2415 
2416 void Edit::ImplSetSelection( const Selection& rSelection, bool bPaint )
2417 {
2418  if ( mpSubEdit )
2419  mpSubEdit->ImplSetSelection( rSelection );
2420  else
2421  {
2422  if ( rSelection != maSelection )
2423  {
2424  Selection aOld( maSelection );
2425  Selection aNew( rSelection );
2426 
2427  if ( aNew.Min() > maText.getLength() )
2428  aNew.Min() = maText.getLength();
2429  if ( aNew.Max() > maText.getLength() )
2430  aNew.Max() = maText.getLength();
2431  if ( aNew.Min() < 0 )
2432  aNew.Min() = 0;
2433  if ( aNew.Max() < 0 )
2434  aNew.Max() = 0;
2435 
2436  if ( aNew != maSelection )
2437  {
2439  Selection aTemp = maSelection;
2440  maSelection = aNew;
2441 
2442  if ( bPaint && ( aOld.Len() || aNew.Len() || IsPaintTransparent() ) )
2444  ImplShowCursor();
2445 
2446  bool bCaret = false, bSelection = false;
2447  long nB=aNew.Max(), nA=aNew.Min(),oB=aTemp.Max(), oA=aTemp.Min();
2448  long nGap = nB-nA, oGap = oB-oA;
2449  if (nB != oB)
2450  bCaret = true;
2451  if (nGap != 0 || oGap != 0)
2452  bSelection = true;
2453 
2454  if (bSelection)
2455  {
2456  if ( mbIsSubEdit )
2458  else
2460  }
2461 
2462  if (bCaret)
2463  {
2464  if ( mbIsSubEdit )
2466  else
2468  }
2469 
2470  // #103511# notify combobox listeners of deselection
2471  if( !maSelection && GetParent() && GetParent()->GetType() == WindowType::COMBOBOX )
2473  }
2474  }
2475  }
2476 }
2477 
2479 {
2480  if ( mpSubEdit )
2481  return mpSubEdit->GetSelection();
2482  else
2483  return maSelection;
2484 }
2485 
2486 void Edit::ReplaceSelected( const OUString& rStr )
2487 {
2488  if ( mpSubEdit )
2489  mpSubEdit->ReplaceSelected( rStr );
2490  else
2491  ImplInsertText( rStr );
2492 }
2493 
2495 {
2496  if ( mpSubEdit )
2498  else
2499  {
2500  if ( maSelection.Len() )
2502  }
2503 }
2504 
2505 OUString Edit::GetSelected() const
2506 {
2507  if ( mpSubEdit )
2508  return mpSubEdit->GetSelected();
2509  else
2510  {
2511  Selection aSelection( maSelection );
2512  aSelection.Justify();
2513  return OUString( maText.getStr() + aSelection.Min(), aSelection.Len() );
2514  }
2515 }
2516 
2518 {
2519  if ( !mbPassword )
2520  {
2521  Copy();
2522  ReplaceSelected( OUString() );
2523  }
2524 }
2525 
2527 {
2528  if ( !mbPassword )
2529  {
2530  css::uno::Reference<css::datatransfer::clipboard::XClipboard> aClipboard(GetClipboard());
2531  ImplCopy( aClipboard );
2532  }
2533 }
2534 
2536 {
2537  css::uno::Reference<css::datatransfer::clipboard::XClipboard> aClipboard(GetClipboard());
2538  ImplPaste( aClipboard );
2539 }
2540 
2542 {
2543  if ( mpSubEdit )
2544  mpSubEdit->Undo();
2545  else
2546  {
2547  const OUString aText( maText.toString() );
2548  ImplDelete( Selection( 0, aText.getLength() ), EDIT_DEL_RIGHT, EDIT_DELMODE_SIMPLE );
2550  ImplSetSelection( Selection( 0, maUndoText.getLength() ) );
2551  maUndoText = aText;
2552  }
2553 }
2554 
2555 void Edit::SetText( const OUString& rStr )
2556 {
2557  if ( mpSubEdit )
2558  mpSubEdit->SetText( rStr ); // not directly ImplSetText if SetText overridden
2559  else
2560  {
2561  Selection aNewSel( 0, 0 ); // prevent scrolling
2562  ImplSetText( rStr, &aNewSel );
2563  }
2564 }
2565 
2566 void Edit::SetText( const OUString& rStr, const Selection& rSelection )
2567 {
2568  if ( mpSubEdit )
2569  mpSubEdit->SetText( rStr, rSelection );
2570  else
2571  ImplSetText( rStr, &rSelection );
2572 }
2573 
2574 OUString Edit::GetText() const
2575 {
2576  if ( mpSubEdit )
2577  return mpSubEdit->GetText();
2578  else
2579  return maText.toString();
2580 }
2581 
2583  ImplSetCursorPos( GetText().getLength(), false );
2584 }
2585 
2586 void Edit::SetPlaceholderText( const OUString& rStr )
2587 {
2588  if ( mpSubEdit )
2589  mpSubEdit->SetPlaceholderText( rStr );
2590  else if ( maPlaceholderText != rStr )
2591  {
2592  maPlaceholderText = rStr;
2593  if ( GetText().isEmpty() )
2594  Invalidate();
2595  }
2596 }
2597 
2599 {
2600 }
2601 
2603 {
2605  mpSubEdit.set(pEdit);
2606 
2607  if (mpSubEdit)
2608  {
2609  SetPointer(PointerStyle::Arrow); // Only SubEdit has the BEAM...
2610  mpSubEdit->mbIsSubEdit = true;
2611 
2614  }
2615 }
2616 
2617 Size Edit::CalcMinimumSizeForText(const OUString &rString) const
2618 {
2619  ControlType eCtrlType = ImplGetNativeControlType();
2620 
2621  Size aSize;
2622  if (mnWidthInChars != -1)
2623  {
2624  //CalcSize calls CalcWindowSize, but we will call that also in this
2625  //function, so undo the first one with CalcOutputSize
2627  }
2628  else
2629  {
2630  OUString aString;
2631  if (mnMaxWidthChars != -1 && mnMaxWidthChars < rString.getLength())
2632  aString = rString.copy(0, mnMaxWidthChars);
2633  else
2634  aString = rString;
2635 
2636  aSize.setHeight( GetTextHeight() );
2637  aSize.setWidth( GetTextWidth(aString) );
2638  aSize.AdjustWidth(ImplGetExtraXOffset() * 2 );
2639 
2640  // do not create edit fields in which one cannot enter anything
2641  // a default minimum width should exist for at least 3 characters
2642 
2643  //CalcSize calls CalcWindowSize, but we will call that also in this
2644  //function, so undo the first one with CalcOutputSize
2645  Size aMinSize(CalcOutputSize(CalcSize(3)));
2646  if (aSize.Width() < aMinSize.Width())
2647  aSize.setWidth( aMinSize.Width() );
2648  }
2649 
2650  aSize.AdjustHeight(ImplGetExtraYOffset() * 2 );
2651 
2652  aSize = CalcWindowSize( aSize );
2653 
2654  // ask NWF what if it has an opinion, too
2655  ImplControlValue aControlValue;
2656  tools::Rectangle aRect( Point( 0, 0 ), aSize );
2657  tools::Rectangle aContent, aBound;
2659  aControlValue, aBound, aContent))
2660  {
2661  if (aBound.GetHeight() > aSize.Height())
2662  aSize.setHeight( aBound.GetHeight() );
2663  }
2664  return aSize;
2665 }
2666 
2668 {
2669  return CalcMinimumSizeForText(GetText());
2670 }
2671 
2673 {
2674  return CalcMinimumSize();
2675 }
2676 
2677 Size Edit::CalcSize(sal_Int32 nChars) const
2678 {
2679  // width for N characters, independent from content.
2680  // works only correct for fixed fonts, average otherwise
2681  Size aSz( GetTextWidth( "x" ), GetTextHeight() );
2682  aSz.setWidth( aSz.Width() * nChars );
2683  aSz.AdjustWidth(ImplGetExtraXOffset() * 2 );
2684  aSz = CalcWindowSize( aSz );
2685  return aSz;
2686 }
2687 
2688 sal_Int32 Edit::GetMaxVisChars() const
2689 {
2690  const vcl::Window* pW = mpSubEdit ? mpSubEdit : this;
2691  sal_Int32 nOutWidth = pW->GetOutputSizePixel().Width();
2692  sal_Int32 nCharWidth = GetTextWidth( "x" );
2693  return nCharWidth ? nOutWidth/nCharWidth : 0;
2694 }
2695 
2696 namespace vcl
2697 {
2699  {
2701  }
2702 
2704  {
2705  return pImplFncGetSpecialChars;
2706  }
2707 }
2708 
2710 {
2711  if (!mpUIBuilder)
2712  mpUIBuilder.reset(new VclBuilder(nullptr, AllSettings::GetUIRootDir(), "vcl/ui/editmenu.ui", ""));
2713  VclPtr<PopupMenu> pPopup = mpUIBuilder->get_menu("menu");
2714  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
2715  if (rStyleSettings.GetHideDisabledMenuItems())
2717  else
2719  if (rStyleSettings.GetContextMenuShortcuts())
2720  {
2721  pPopup->SetAccelKey(pPopup->GetItemId("undo"), vcl::KeyCode( KeyFuncType::UNDO));
2722  pPopup->SetAccelKey(pPopup->GetItemId("cut"), vcl::KeyCode( KeyFuncType::CUT));
2723  pPopup->SetAccelKey(pPopup->GetItemId("copy"), vcl::KeyCode( KeyFuncType::COPY));
2724  pPopup->SetAccelKey(pPopup->GetItemId("paste"), vcl::KeyCode( KeyFuncType::PASTE));
2725  pPopup->SetAccelKey(pPopup->GetItemId("delete"), vcl::KeyCode( KeyFuncType::DELETE));
2726  pPopup->SetAccelKey(pPopup->GetItemId("selectall"), vcl::KeyCode( KEY_A, false, true, false, false));
2727  pPopup->SetAccelKey(pPopup->GetItemId("specialchar"), vcl::KeyCode( KEY_S, true, true, false, false));
2728  }
2729  return pPopup;
2730 }
2731 
2732 // css::datatransfer::dnd::XDragGestureListener
2733 void Edit::dragGestureRecognized( const css::datatransfer::dnd::DragGestureEvent& rDGE )
2734 {
2735  SolarMutexGuard aVclGuard;
2736 
2737  if ( !(!IsTracking() && maSelection.Len() &&
2738  !mbPassword && (!mpDDInfo || !mpDDInfo->bStarterOfDD)) ) // no repeated D&D
2739  return;
2740 
2741  Selection aSel( maSelection );
2742  aSel.Justify();
2743 
2744  // only if mouse in the selection...
2745  Point aMousePos( rDGE.DragOriginX, rDGE.DragOriginY );
2746  sal_Int32 nCharPos = ImplGetCharPos( aMousePos );
2747  if ( (nCharPos < aSel.Min()) || (nCharPos >= aSel.Max()) )
2748  return;
2749 
2750  if ( !mpDDInfo )
2751  mpDDInfo.reset(new DDInfo);
2752 
2753  mpDDInfo->bStarterOfDD = true;
2754  mpDDInfo->aDndStartSel = aSel;
2755 
2756  if ( IsTracking() )
2757  EndTracking(); // before D&D disable tracking
2758 
2760  sal_Int8 nActions = datatransfer::dnd::DNDConstants::ACTION_COPY;
2761  if ( !IsReadOnly() )
2762  nActions |= datatransfer::dnd::DNDConstants::ACTION_MOVE;
2763  rDGE.DragSource->startDrag( rDGE, nActions, 0 /*cursor*/, 0 /*image*/, pDataObj, mxDnDListener );
2764  if ( GetCursor() )
2765  GetCursor()->Hide();
2766 }
2767 
2768 // css::datatransfer::dnd::XDragSourceListener
2769 void Edit::dragDropEnd( const css::datatransfer::dnd::DragSourceDropEvent& rDSDE )
2770 {
2771  SolarMutexGuard aVclGuard;
2772 
2773  if (rDSDE.DropSuccess && (rDSDE.DropAction & datatransfer::dnd::DNDConstants::ACTION_MOVE) && mpDDInfo)
2774  {
2775  Selection aSel( mpDDInfo->aDndStartSel );
2776  if ( mpDDInfo->bDroppedInMe )
2777  {
2778  if ( aSel.Max() > mpDDInfo->nDropPos )
2779  {
2780  long nLen = aSel.Len();
2781  aSel.Min() += nLen;
2782  aSel.Max() += nLen;
2783  }
2784  }
2786  Modify();
2787  }
2788 
2789  ImplHideDDCursor();
2790  mpDDInfo.reset();
2791 }
2792 
2793 // css::datatransfer::dnd::XDropTargetListener
2794 void Edit::drop( const css::datatransfer::dnd::DropTargetDropEvent& rDTDE )
2795 {
2796  SolarMutexGuard aVclGuard;
2797 
2798  bool bChanges = false;
2799  if ( !mbReadOnly && mpDDInfo )
2800  {
2801  ImplHideDDCursor();
2802 
2803  Selection aSel( maSelection );
2804  aSel.Justify();
2805 
2806  if ( aSel.Len() && !mpDDInfo->bStarterOfDD )
2808 
2809  mpDDInfo->bDroppedInMe = true;
2810 
2811  aSel.Min() = mpDDInfo->nDropPos;
2812  aSel.Max() = mpDDInfo->nDropPos;
2813  ImplSetSelection( aSel );
2814 
2815  uno::Reference< datatransfer::XTransferable > xDataObj = rDTDE.Transferable;
2816  if ( xDataObj.is() )
2817  {
2818  datatransfer::DataFlavor aFlavor;
2819  SotExchange::GetFormatDataFlavor( SotClipboardFormatId::STRING, aFlavor );
2820  if ( xDataObj->isDataFlavorSupported( aFlavor ) )
2821  {
2822  uno::Any aData = xDataObj->getTransferData( aFlavor );
2823  OUString aText;
2824  aData >>= aText;
2825  ImplInsertText( aText );
2826  bChanges = true;
2827  Modify();
2828  }
2829  }
2830 
2831  if ( !mpDDInfo->bStarterOfDD )
2832  {
2833  mpDDInfo.reset();
2834  }
2835  }
2836 
2837  rDTDE.Context->dropComplete( bChanges );
2838 }
2839 
2840 void Edit::dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& rDTDE )
2841 {
2842  if ( !mpDDInfo )
2843  {
2844  mpDDInfo.reset(new DDInfo);
2845  }
2846  // search for string data type
2847  const Sequence< css::datatransfer::DataFlavor >& rFlavors( rDTDE.SupportedDataFlavors );
2848  mpDDInfo->bIsStringSupported = std::any_of(rFlavors.begin(), rFlavors.end(),
2849  [](const css::datatransfer::DataFlavor& rFlavor) {
2850  sal_Int32 nIndex = 0;
2851  const OUString aMimetype = rFlavor.MimeType.getToken( 0, ';', nIndex );
2852  return aMimetype == "text/plain";
2853  });
2854 }
2855 
2856 void Edit::dragExit( const css::datatransfer::dnd::DropTargetEvent& )
2857 {
2858  SolarMutexGuard aVclGuard;
2859 
2860  ImplHideDDCursor();
2861 }
2862 
2863 void Edit::dragOver( const css::datatransfer::dnd::DropTargetDragEvent& rDTDE )
2864 {
2865  SolarMutexGuard aVclGuard;
2866 
2867  Point aMousePos( rDTDE.LocationX, rDTDE.LocationY );
2868 
2869  sal_Int32 nPrevDropPos = mpDDInfo->nDropPos;
2870  mpDDInfo->nDropPos = ImplGetCharPos( aMousePos );
2871 
2872  /*
2873  Size aOutSize = GetOutputSizePixel();
2874  if ( ( aMousePos.X() < 0 ) || ( aMousePos.X() > aOutSize.Width() ) )
2875  {
2876  // Scroll?
2877  // No, I will not receive events in this case...
2878  }
2879  */
2880 
2881  Selection aSel( maSelection );
2882  aSel.Justify();
2883 
2884  // Don't accept drop in selection or read-only field...
2885  if ( IsReadOnly() || aSel.IsInside( mpDDInfo->nDropPos ) || ! mpDDInfo->bIsStringSupported )
2886  {
2887  ImplHideDDCursor();
2888  rDTDE.Context->rejectDrag();
2889  }
2890  else
2891  {
2892  // draw the old cursor away...
2893  if ( !mpDDInfo->bVisCursor || ( nPrevDropPos != mpDDInfo->nDropPos ) )
2894  {
2895  ImplHideDDCursor();
2896  ImplShowDDCursor();
2897  }
2898  rDTDE.Context->acceptDrag( rDTDE.DropAction );
2899  }
2900 }
2901 
2903 {
2904  if (mpSubEdit)
2905  return mpSubEdit->GetSurroundingText();
2906  return maText.toString();
2907 }
2908 
2910 {
2911  return GetSelection();
2912 }
2913 
2915 {
2916  return EditUIObject::create;
2917 }
2918 
2919 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SAL_DLLPRIVATE void ImplPaintBorder(vcl::RenderContext const &rRenderContext)
Definition: edit.cxx:999
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: edit.cxx:1722
Point TopLeft() const
virtual Size CalcMinimumSize() const
Definition: edit.cxx:2667
long Width() const
vcl::Region GetClipRegion() const
const Color & GetTextColor() const
Definition: outdev.hxx:1135
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, MetricVector *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
Definition: text.cxx:795
The child windows are invalidated, too.
bool IsControlBackground() const
Definition: window2.cxx:1087
virtual void EnableRTL(bool bEnable=true) override
Definition: ctrl.cxx:65
GetFocusFlags GetGetFocusFlags() const
Definition: window2.cxx:1188
bool ImplCallEventListenersAndHandler(VclEventId nEvent, std::function< void()> const &callHandler)
this calls both our event listeners, and a specified handler
Definition: ctrl.cxx:305
void SetCompositionCharRect(const tools::Rectangle *pRect, long nCompositionLength, bool bVertical=false)
Definition: window.cxx:2141
sal_Int32 mnMaxWidthChars
Definition: edit.hxx:71
sal_uLong GetEnd() const
SAL_DLLPRIVATE void ImplInsertText(const OUString &rStr, const Selection *pNewSelection=nullptr, bool bIsUserInput=false)
Definition: edit.cxx:786
bool GetContextMenuShortcuts() const
sal_Int32 nIndex
virtual void Cut()
Definition: edit.cxx:2517
Edit(WindowType nType)
Definition: edit.cxx:149
long GetHeight() const
SAL_DLLPRIVATE long ImplGetTextYPosition() const
Definition: edit.cxx:455
bool IsNull() const
Definition: region.hxx:102
virtual void ApplySettings(vcl::RenderContext &rRenderContext) override
Definition: edit.cxx:363
Link< Edit &, void > maModifyHdl
Definition: edit.hxx:81
virtual void dragExit(const css::datatransfer::dnd::DropTargetEvent &dte) override
Definition: edit.cxx:2856
virtual OUString GetSelected() const
Definition: edit.cxx:2505
void SetPos(const Point &rNewPos)
Definition: cursor.cxx:395
long AdjustWidth(long n)
FncGetSpecialChars GetGetSpecialCharsFunction()
Definition: edit.cxx:2703
const char aData[]
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion) const
Query the native control's actual drawing region (including adornment)
virtual void MouseButtonDown(const MouseEvent &rMEvt)
Definition: mouse.cxx:414
const Color & GetHighlightTextColor() const
std::unique_ptr< ContentProperties > pData
Edit * GetSubEdit() const
Definition: edit.hxx:217
#define EDIT_DELMODE_RESTOFWORD
Definition: edit.cxx:87
long Height() const
long mnXOffset
Definition: edit.hxx:66
SAL_DLLPRIVATE void ImplDrawFrame(OutputDevice *pDev, tools::Rectangle &rRect)
draws a frame around the give rectangle, onto the given device
Definition: ctrl.cxx:336
signed char sal_Int8
css::uno::Reference< css::datatransfer::clipboard::XClipboard > GetClipboard()
Definition: window.cxx:3407
bool mbForceControlBackground
Definition: edit.hxx:73
WinBits const WB_NOGROUP
virtual OUString filter(const OUString &rText)
Definition: edit.cxx:2296
virtual FactoryFunction GetUITestFactory() const override
Definition: edit.cxx:2914
constexpr::Color COL_RED(0x80, 0x00, 0x00)
void Union(const tools::Rectangle &rRegion)
Definition: region.cxx:508
SelectionOptions GetSelectionOptions() const
virtual Size CalcMinimumSizeForText(const OUString &rString) const
Definition: edit.cxx:2617
SAL_DLLPRIVATE void ImplClearLayoutData() const
Definition: ctrl.cxx:330
SelectionOptions
Definition: settings.hxx:181
long AdjustLeft(long nHorzMoveDelta)
LINESTYLE_BOLD
static FncGetSpecialChars pImplFncGetSpecialChars
Definition: edit.cxx:77
virtual ~TextFilter()
Definition: edit.cxx:2292
void disposeAndClear()
Definition: vclptr.hxx:200
sal_Int32 nPos
Definition: edit.cxx:116
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:706
constexpr sal_uInt16 KEY_A
Definition: keycodes.hxx:56
virtual void StateChanged(StateChangedType nStateChange) override
Definition: ctrl.cxx:260
SAL_DLLPRIVATE void ImplGrabFocus(GetFocusFlags nFlags)
Definition: mouse.cxx:195
sal_Int64 n
OUString maPlaceholderText
Definition: edit.hxx:63
virtual void Paste()
Definition: edit.cxx:2535
std::function< std::unique_ptr< UIObject >vcl::Window *)> FactoryFunction
virtual Size GetSizePixel() const
Definition: window.cxx:2395
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1262
WinBits const WB_RIGHT
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:563
sal_uInt16 mnAlign
Definition: edit.hxx:68
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: edit.cxx:222
void CompatStateChanged(StateChangedType nStateChange)
Definition: window.cxx:3828
bool IsShift() const
Definition: event.hxx:155
void SetEchoChar(sal_Unicode c)
Definition: edit.cxx:2352
bool mbReadOnly
Definition: edit.hxx:73
SAL_DLLPRIVATE OUString ImplGetText() const
Definition: edit.cxx:425
void SetTextFillColor()
Definition: text.cxx:701
long Len() const
sal_uInt16 GetCode() const
Definition: keycod.hxx:51
void DestroyAttribs()
Definition: edit.cxx:143
css::uno::Reference< css::datatransfer::dnd::XDragSourceListener > mxDnDListener
Definition: edit.hxx:127
vcl::Region GetPaintRegion() const
Definition: paint.cxx:1146
void SetLayoutMode(ComplexTextLayoutFlags nTextLayoutMode)
DataChangedEventType GetType() const
Definition: event.hxx:357
OUString sForbiddenChars
Definition: textfilter.hxx:18
void IntersectClipRegion(const tools::Rectangle &rRect)
sal_uInt16 Execute(vcl::Window *pWindow, const Point &rPopupPos)
Definition: menu.cxx:2794
bool bVisCursor
Definition: edit.cxx:97
The invalidated area is updated immediately.
SAL_DLLPRIVATE void ImplCopy(css::uno::Reference< css::datatransfer::clipboard::XClipboard > const &rxClipboard)
Definition: edit.cxx:1273
void SetPlaceholderText(const OUString &rStr)
Definition: edit.cxx:2586
KeyFuncType
Definition: keycod.hxx:29
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: edit.cxx:180
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
const Color & GetControlBackground() const
Definition: window2.cxx:1082
virtual void drop(const css::datatransfer::dnd::DropTargetDropEvent &dtde) override
Definition: edit.cxx:2794
SAL_DLLPRIVATE void ImplShowCursor(bool bOnlyIfVisible=true)
Definition: edit.cxx:1060
static void ShowTruncationWarning(weld::Widget *pParent)
Definition: edit.cxx:767
virtual ~Edit() override
Definition: edit.cxx:217
tools::Rectangle GetBoundRect() const
Definition: region.cxx:1214
void SetType(WindowType nType)
Definition: window2.cxx:968
virtual void ApplySettings(vcl::RenderContext &rRenderContext) override
Definition: ctrl.cxx:418
bool IsMiddle() const
Definition: event.hxx:148
void PaintImmediately()
Definition: paint.cxx:1286
sal_Int32 nLen
Definition: edit.cxx:117
long AdjustHeight(long n)
void StartTracking(StartTrackingFlags nFlags=StartTrackingFlags::NONE)
Definition: window2.cxx:244
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
void SetMapMode()
Definition: map.cxx:654
const vcl::Font & GetFieldFont() const
#define EDIT_DELMODE_SIMPLE
Definition: edit.cxx:86
const Color & GetFieldTextColor() const
bool IsTracking() const
Definition: window2.cxx:312
bool bStarterOfDD
Definition: edit.cxx:95
bool mbInternModified
Definition: edit.hxx:73
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
#define EDIT_DEL_RIGHT
Definition: edit.cxx:84
const Color & GetHighlightColor() const
bool mbPassword
Definition: edit.hxx:73
long AdjustBottom(long nVertMoveDelta)
bool bWasCursorOverwrite
Definition: edit.cxx:119
constexpr sal_uInt16 KEY_END
Definition: keycodes.hxx:115
StateChangedType
Definition: window.hxx:317
bool IsInsertMode() const
Definition: edit.cxx:2383
weld::Window * GetFrameWeld() const
Definition: window2.cxx:853
LINESTYLE_DASHDOT
sal_uInt16 GetClicks() const
Definition: event.hxx:123
sal_Int64 WinBits
sal_uInt16 sal_Unicode
virtual OUString GetSurroundingText() const override
Definition: edit.cxx:2902
void SetBackground()
Size CalcOutputSize(const Size &rWinSz) const
Definition: window2.cxx:545
virtual void FillLayoutData() const override
Definition: edit.cxx:1716
WinBits const WB_BOTTOM
WinBits const WB_TOP
SAL_DLLPRIVATE long ImplGetExtraYOffset() const
Definition: edit.cxx:413
std::unique_ptr< ExtTextInputAttr[]> pAttribs
Definition: edit.cxx:115
Creates a hierarchy of vcl::Windows (widgets) from a .ui file for dialogs, sidebar, etc.
Definition: builder.hxx:64
const vcl::Font & GetFont() const
Definition: outdev.hxx:649
A helper class that calls Application::ReleaseSolarMutex() in its constructor and restores the mutex ...
Definition: svapp.hxx:1415
sal_Int32 nDropPos
Definition: edit.cxx:94
css::uno::Reference< css::datatransfer::clipboard::XClipboard > GetPrimarySelection()
Definition: window.cxx:3416
void EndTracking(TrackingEventFlags nFlags=TrackingEventFlags::NONE)
Definition: window2.cxx:272
bool IsMouseEvent() const
SAL_DLLPRIVATE void ImplSetSelection(const Selection &rSelection, bool bPaint=true)
Definition: edit.cxx:2416
css::uno::Reference< css::i18n::XBreakIterator > mxBreakIterator
Definition: edit.hxx:86
int nCount
AllSettingsFlags GetFlags() const
Definition: event.hxx:358
void SetMenuFlags(MenuFlags nFlags)
Definition: menu.hxx:252
const CommandExtTextInputData * GetExtTextInputData() const
SAL_DLLPRIVATE css::uno::Reference< css::i18n::XBreakIterator > const & ImplGetBreakIterator()
Definition: edit.cxx:753
virtual void SetModifyFlag()
Definition: edit.cxx:2598
virtual void queue_resize(StateChangedType eReason=StateChangedType::Layout)
Definition: window2.cxx:1314
void Undo()
Definition: edit.cxx:2541
#define CURSOR_SHADOW
Definition: cursor.hxx:36
virtual void Draw(OutputDevice *pDev, const Point &rPos, DrawFlags nFlags) override
Definition: edit.cxx:1741
SAL_DLLPRIVATE bool ImplHandleKeyEvent(const KeyEvent &rKEvt)
Definition: edit.cxx:1400
sal_uLong GetStart() const
virtual void dragDropEnd(const css::datatransfer::dnd::DragSourceDropEvent &dsde) override
Definition: edit.cxx:2769
virtual const Selection & GetSelection() const
Definition: edit.cxx:2478
void SetBorderStyle(WindowBorderStyle nBorderStyle)
Definition: window.cxx:1988
sal_uInt16 GetModifier() const
Definition: keycod.hxx:54
void SetUnderline(FontLineStyle)
Definition: font/font.cxx:245
virtual void MouseButtonUp(const MouseEvent &rMEvt) override
Definition: edit.cxx:1358
void SetStyle(sal_uInt16 nStyle)
Definition: cursor.cxx:359
virtual void dragEnter(const css::datatransfer::dnd::DropTargetDragEnterEvent &dtdee) override
Definition: edit.cxx:2840
sal_Int32 mnMaxTextLen
Definition: edit.hxx:69
Definition: edit.cxx:90
void Move(long nHorzMove, long nVertMove)
Definition: region.cxx:414
Definition: edit.hxx:55
WinBits const WB_NOHIDESELECTION
bool IsCursorOverwrite() const
SAL_DLLPRIVATE void ImplSetCursorPos(sal_Int32 nChar, bool bSelect)
Definition: edit.cxx:1255
css::uno::Reference< css::datatransfer::dnd::XDragGestureRecognizer > GetDragGestureRecognizer()
Definition: mouse.cxx:785
void setMax(long nMax)
void Hide()
Definition: cursor.cxx:377
virtual void DeleteSelected()
Definition: edit.cxx:2494
sal_uInt16 nCode
virtual void SetSelection(const Selection &rSelection)
Definition: edit.cxx:2404
SAL_DLLPRIVATE void ImplHideDDCursor()
Definition: edit.cxx:2278
OUString maUndoText
Definition: edit.hxx:65
void SetTextLineColor()
Definition: textline.cxx:800
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:51
std::unique_ptr< Impl_IMEInfos > mpIMEInfos
Definition: edit.hxx:61
OUStringBuffer maText
Definition: edit.hxx:62
const LanguageTag & GetLanguageTag() const
long GetDrawPixel(::OutputDevice const *pDev, long nPixels) const
Definition: window2.cxx:563
#define SAL_N_ELEMENTS(arr)
virtual void Tracking(const TrackingEvent &rTEvt) override
Definition: edit.cxx:1375
#define EDIT_ALIGN_RIGHT
Definition: edit.cxx:81
SAL_DLLPRIVATE bool ImplUseNativeBorder(vcl::RenderContext const &rRenderContext, WinBits nStyle)
Definition: edit.cxx:288
bool mbInsertMode
Definition: edit.hxx:73
static OUString GetUIRootDir()
Definition: dialog.cxx:546
SAL_DLLPRIVATE void ImplDelete(const Selection &rSelection, sal_uInt8 nDirection, sal_uInt8 nMode)
Definition: edit.cxx:673
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
bool IsEmpty() const
Definition: region.cxx:228
Size CalcWindowSize(const Size &rOutSz) const
Definition: window2.cxx:537
long Min() const
void SetLineColor()
const OUString & GetText() const
void clear()
Definition: vclptr.hxx:190
VclPtr< PopupMenu > CreatePopupMenu()
Definition: edit.cxx:2709
Selection maSelection
Definition: edit.hxx:67
const Color & GetDisableColor() const
void Justify()
#define EDIT_ALIGN_CENTER
Definition: edit.cxx:80
bool IsRTLEnabled() const
Definition: outdev.hxx:1366
SAL_DLLPRIVATE sal_Int32 ImplGetCharPos(const Point &rWindowPos) const
Definition: edit.cxx:1189
void SetInputContext(const InputContext &rInputContext)
Definition: window.cxx:2070
virtual Size GetOptimalSize() const override
Definition: edit.cxx:2672
SAL_DLLPRIVATE void ImplShowDDCursor()
Definition: edit.cxx:2263
int i
static bool IsCharInput(const KeyEvent &rKEvt)
Definition: edit.cxx:353
DrawFlags
Definition: window.hxx:360
MouseMiddleButtonAction GetMiddleButtonAction() const
virtual void GetFocus() override
Definition: edit.cxx:1848
bool IsNativeWidgetEnabled() const
Definition: window.cxx:3679
void SetCursorRect(const tools::Rectangle *pRect=nullptr, long nExtTextInputWidth=0)
Definition: window.cxx:2106
void GetCaretPositions(const OUString &, long *pCaretXArray, sal_Int32 nIndex, sal_Int32 nLen, const SalLayoutGlyphs *pGlyphs=nullptr) const
Definition: text.cxx:1071
virtual void StateChanged(StateChangedType nType) override
Definition: edit.cxx:2164
SAL_DLLPRIVATE void ImplInvalidateOrRepaint()
Definition: edit.cxx:442
constexpr sal_uInt16 KEY_HOME
Definition: keycodes.hxx:114
SAL_DLLPRIVATE void ImplRepaint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRectangle)
Definition: edit.cxx:464
virtual void SetReadOnly(bool bReadOnly=true)
Definition: edit.cxx:2359
LINESTYLE_WAVE
bool mbIsSubEdit
Definition: edit.hxx:73
SAL_DLLPRIVATE void ImplCopyToSelectionClipboard()
Definition: edit.cxx:1264
SAL_DLLPRIVATE long ImplGetExtraXOffset() const
Definition: edit.cxx:401
sal_uInt16 GetItemId(sal_uInt16 nPos) const
Definition: menu.cxx:634
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1162
void SetCursorAtLast()
Definition: edit.cxx:2582
css::uno::Reference< css::datatransfer::dnd::XDropTarget > GetDropTarget()
Definition: mouse.cxx:659
Size GetOutputSize() const
Definition: outdev.hxx:450
std::unique_ptr< VclBuilder > mpUIBuilder
Definition: edit.hxx:84
virtual Selection GetSurroundingTextSelection() const override
Definition: edit.cxx:2909
vcl::Cursor aCursor
Definition: edit.cxx:92
void SetRight(long v)
static SAL_DLLPRIVATE WinBits ImplInitStyle(WinBits nStyle)
Definition: edit.cxx:343
virtual OUString GetText() const override
Definition: edit.cxx:2574
void CallEventListeners(VclEventId nEvent, void *pData=nullptr)
Definition: ctrl.cxx:297
SAL_DLLPRIVATE void ImplPaste(css::uno::Reference< css::datatransfer::clipboard::XClipboard > const &rxClipboard)
Definition: edit.cxx:1278
bool IsUpdateMode() const
Definition: window2.cxx:1173
void SetFillColor()
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:302
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
const Color & GetFieldColor() const
CommandEventId GetCommand() const
bool GetHideDisabledMenuItems() const
virtual void Modify()
Definition: edit.cxx:2324
LINESTYLE_SINGLE
float u
void SetTextColor(const Color &rColor)
Definition: text.cxx:666
bool HasPaintEvent() const
Definition: paint.cxx:1259
virtual void Resize() override
Definition: edit.cxx:1728
static bool GetLayoutRTL()
sal_Unicode mcEchoChar
Definition: edit.hxx:72
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:519
void CopyAttribs(const ExtTextInputAttr *pA, sal_Int32 nL)
Definition: edit.cxx:136
bool IsInside(long nIs) const
void Intersect(const tools::Rectangle &rRegion)
Definition: region.cxx:584
vcl::Cursor * GetCursor() const
Definition: window2.cxx:1203
bool bDroppedInMe
Definition: edit.cxx:96
void Show()
Definition: cursor.cxx:368
SAL_DLLPRIVATE void filterText()
Definition: edit.cxx:2306
void SetSubEdit(Edit *pEdit)
Definition: edit.cxx:2602
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: ctrl.cxx:59
void SetSize(const Size &rNewSize)
Definition: cursor.cxx:404
static bool toBool(const OString &rValue)
Definition: builder.cxx:78
const AllSettings & GetSettings() const
Definition: outdev.hxx:418
Size GetOutputSizePixel() const
Definition: outdev.hxx:441
DrawTextFlags
Definition: outdev.hxx:142
Sets up the buffer to have settings matching the window, and restores the original state in the dtor...
Definition: window.h:402
void ApplyControlForeground(vcl::RenderContext &rRenderContext, const Color &rDefaultColor)
Definition: window2.cxx:489
virtual bool set_property(const OString &rKey, const OUString &rValue)
Definition: window2.cxx:1431
virtual void LoseFocus()
Definition: window.cxx:1849
KeyFuncType GetFunction() const
Definition: keycod.cxx:73
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2810
void GrabFocus()
Definition: window.cxx:2960
long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: text.cxx:903
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: edit.cxx:1710
vcl::Window * GetParent() const
Definition: window2.cxx:1097
WinBits const WB_LEFT
bool IsTrackingEnded() const
Definition: event.hxx:263
void SetStyle(WinBits nStyle)
Definition: window.cxx:1956
static void CopyStringTo(const OUString &rContent, const css::uno::Reference< css::datatransfer::clipboard::XClipboard > &rxClipboard)
copies a given string to a given clipboard
Definition: unohelp2.cxx:42
Size GetSize() const
void EnableItem(sal_uInt16 nItemId, bool bEnable=true)
Definition: menu.cxx:905
constexpr sal_uInt16 KEY_RETURN
Definition: keycodes.hxx:119
WinBits const WB_NOBORDER
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1039
constexpr sal_uInt16 KEY_RIGHT
Definition: keycodes.hxx:113
const Point & GetMousePosPixel() const
Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:941
OUString aOldTextAfterStartPos
Definition: edit.cxx:113
constexpr sal_uInt16 KEY_S
Definition: keycodes.hxx:74
ControlType
These types are all based on the supported variants vcl/salnativewidgets.hxx and must be kept in-sync...
virtual void KeyInput(const KeyEvent &rKEvt)
Definition: window.cxx:1799
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:935
virtual Size CalcSize(sal_Int32 nChars) const
Definition: edit.cxx:2677
void SetPointer(PointerStyle)
Definition: mouse.cxx:474
SalFrame * ImplGetFrame() const
Definition: window2.cxx:848
std::unique_ptr< DDInfo, o3tl::default_delete< DDInfo > > mpDDInfo
Definition: edit.hxx:60
const CommandSelectionChangeData * GetSelectionChangeData() const
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:54
static SAL_DLLPRIVATE void ImplInvalidateOutermostBorder(vcl::Window *pWin)
Definition: edit.cxx:1832
void Erase()
Definition: wallpaper.cxx:103
bool IsShift() const
Definition: keycod.hxx:56
css::uno::Reference< css::i18n::XExtendedInputSequenceChecker > mxISC
Definition: edit.hxx:87
Link< Edit &, void > maAutocompleteHdl
Definition: edit.hxx:82
void SetWidthInChars(sal_Int32 nWidthInChars)
Definition: edit.cxx:162
bool IsCursorVisible() const
virtual void Resize() override
Definition: ctrl.cxx:74
OUString(* FncGetSpecialChars)(weld::Widget *pWin, const vcl::Font &rFont)
long AdjustRight(long nHorzMoveDelta)
WindowType
Definition: ctrl.hxx:33
virtual void GetFocus()
Definition: window.cxx:1835
#define SAL_WARN_IF(condition, area, stream)
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: edit.cxx:2245
WinBits const WB_BORDER
unsigned char sal_uInt8
virtual void dragOver(const css::datatransfer::dnd::DropTargetDragEvent &dtde) override
Definition: edit.cxx:2863
void SetCursor(vcl::Cursor *pCursor)
Definition: window.cxx:2997
LINESTYLE_DOTTED
void SetFont(const vcl::Font &rNewFont)
std::unique_ptr< vcl::ImplControlData > mpControlData
Definition: ctrl.hxx:36
Link< Edit &, bool > maActivateHdl
Definition: edit.hxx:83
void SetInsertMode(bool bInsert)
Definition: edit.cxx:2371
WinBits const WB_READONLY
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: edit.cxx:1317
void ShowItem(sal_uInt16 nItemId, bool bVisible=true)
Definition: menu.cxx:950
Impl_IMEInfos(sal_Int32 nPos, const OUString &rOldTextAfterStartPos)
Definition: edit.cxx:127
SAL_DLLPRIVATE void ImplAlign()
Definition: edit.cxx:1140
Selection aDndStartSel
Definition: edit.cxx:93
vcl::Font GetDrawPixelFont(::OutputDevice const *pDev) const
Definition: window2.cxx:553
bool IsLeft() const
Definition: event.hxx:146
sal_Unicode GetCharCode() const
Definition: event.hxx:53
void setMaxWidthChars(sal_Int32 nWidth)
Definition: edit.cxx:171
sal_Int32 GetCursorPos() const
bool IsMod1() const
Definition: keycod.hxx:58
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
virtual void Copy()
Definition: edit.cxx:2526
Reference< XComponentContext > getProcessComponentContext()
const MouseSettings & GetMouseSettings() const
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
Definition: paint.cxx:1019
void SetAccelKey(sal_uInt16 nItemId, const vcl::KeyCode &rKeyCode)
Definition: menu.cxx:771
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
SAL_DLLPRIVATE void ImplClearBackground(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRectangle, long nXStart, long nXEnd)
Definition: edit.cxx:979
VclPtr< Edit > mpSubEdit
Definition: edit.hxx:58
const Point & GetPosPixel() const
Definition: event.hxx:120
bool bCursor
Definition: edit.cxx:118
double getLength(const B2DPolygon &rCandidate)
void set(reference_type *pBody)
Definition: vclptr.hxx:148
constexpr sal_uInt16 KEY_BACKSPACE
Definition: keycodes.hxx:122
long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
Width of the text.
Definition: text.cxx:892
bool IsDisposed() const
Definition: window.cxx:140
WinBits const WB_TABSTOP
bool IsVisible() const
Definition: cursor.hxx:77
long getMin() const
TextFilter(const OUString &rForbiddenChars=OUString(" "))
Definition: edit.cxx:2287
void SetGetSpecialCharsFunction(FncGetSpecialChars fn)
Definition: edit.cxx:2698
SAL_DLLPRIVATE void ImplInitEditData()
Definition: edit.cxx:259
WindowType GetType() const
Definition: window2.cxx:974
#define EDIT_DELMODE_RESTOFCONTENT
Definition: edit.cxx:88
bool IsPaintTransparent() const
Definition: window2.cxx:1037
SAL_DLLPRIVATE bool ImplTruncateToMaxLen(OUString &, sal_Int32 nSelectionLen) const
Definition: edit.cxx:774
void setMin(long nMin)
WinBits const WB_CENTER
#define EDIT_ALIGN_LEFT
Definition: edit.cxx:79
bool IsEnabled() const
Definition: window2.cxx:1122
void SetLeft(long v)
DDInfo()
Definition: edit.cxx:100
virtual void SetMaxTextLen(sal_Int32 nMaxLen)
Definition: edit.cxx:2391
SAL_DLLPRIVATE void ImplAlignAndPaint()
Definition: edit.cxx:1182
OUString VclResId(const char *pId)
Definition: svdata.cxx:267
ExtTextInputAttr
WinBits GetStyle() const
Definition: window2.cxx:953
void ApplyControlFont(vcl::RenderContext &rRenderContext, const vcl::Font &rDefaultFont)
Definition: window2.cxx:449
constexpr sal_uInt16 KEY_DELETE
Definition: keycodes.hxx:125
virtual void LoseFocus() override
Definition: edit.cxx:1900
constexpr sal_uInt16 KEY_LEFT
Definition: keycodes.hxx:112
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2804
long Max() const
WinBits const WB_GROUP
virtual bool IsReadOnly() const
Definition: edit.hxx:175
virtual void SetText(const OUString &rStr) override
Definition: edit.cxx:2555
#define EDIT_DEL_LEFT
Definition: edit.cxx:83
SAL_DLLPRIVATE css::uno::Reference< css::i18n::XExtendedInputSequenceChecker > const & ImplGetInputSequenceChecker()
Definition: edit.cxx:760
constexpr sal_uInt16 KEY_INSERT
Definition: keycodes.hxx:124
virtual void Command(const CommandEvent &rCEvt)
Definition: window.cxx:1917
const MouseEvent & GetMouseEvent() const
Definition: event.hxx:259
bool IsReallyVisible() const
Definition: window2.cxx:1107
SAL_DLLPRIVATE ControlType ImplGetNativeControlType() const
Definition: edit.cxx:929
bool HasFocus() const
Definition: window.cxx:2965
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:60
bool mbActivePopup
Definition: edit.hxx:73
WinBits const WB_SPIN
OString GetItemIdent(sal_uInt16 nItemId) const
Definition: menu.cxx:676
bool SupportsDoubleBuffering() const
Can the widget derived from this Window do the double-buffering via RenderContext properly...
Definition: window.cxx:3790
sal_Int32 mnWidthInChars
Definition: edit.hxx:70
void setWidth(long nWidth)
WinBits const WB_NOTABSTOP
SAL_DLLPRIVATE void ImplSetText(const OUString &rStr, const Selection *pNewSelection)
Definition: edit.cxx:895
bool bIsStringSupported
Definition: edit.cxx:98
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
Definition: builder.cxx:197
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: edit.cxx:304
bool IsMod3() const
Definition: keycod.hxx:62
sal_Int32 GetMaxVisChars() const
Definition: edit.cxx:2688
sal_uInt16 nPos
static SAL_DLLPRIVATE OUString ImplGetValidString(const OUString &rString)
Definition: edit.cxx:746
bool mbClickedInSelection
Definition: edit.hxx:73
virtual void dragGestureRecognized(const css::datatransfer::dnd::DragGestureEvent &dge) override
Definition: edit.cxx:2733
#define EDIT_NOLIMIT
Definition: edit.hxx:51
TextFilter * mpFilterText
Definition: edit.hxx:59
virtual void DataChanged(const DataChangedEvent &rDCEvt)
Definition: event.cxx:35
virtual void Command(const CommandEvent &rCEvt) override
Definition: edit.cxx:1920
virtual void ReplaceSelected(const OUString &rStr)
Definition: edit.cxx:2486
bool IsMod2() const
Definition: keycod.hxx:60
static bool GetFormatDataFlavor(SotClipboardFormatId nFormat, css::datatransfer::DataFlavor &rFlavor)
void setHeight(long nHeight)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill= '\0')
const ExtTextInputAttr * GetTextAttr() const