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

Generated by: LCOV version 1.10