LCOV - code coverage report
Current view: top level - vcl/source/control - edit.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 642 1650 38.9 %
Date: 2015-06-13 12:38:46 Functions: 57 120 47.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11