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