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