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