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