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