1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: edit.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
37 #include <vcl/svdata.hxx>
38 #include <vcl/decoview.hxx>
39 #include <vcl/event.hxx>
40 #include <vcl/cursor.hxx>
41 #include <vcl/virdev.hxx>
43 #include <vcl/svids.hrc>
45 #include <vcl/menu.hxx>
46 #include <vcl/cmdevt.h>
47 #include <vcl/subedit.hxx>
48 #include <vcl/edit.hxx>
49 #include <vcl/svapp.hxx>
50 #include <vcl/controllayout.hxx>
51 #include <vcl/msgbox.hxx>
52 #include <vcl/window.h>
54 #include <vos/mutex.hxx>
57 #include <com/sun/star/i18n/XBreakIterator.hpp>
58 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
59 #include <com/sun/star/i18n/WordType.hpp>
60 #include <cppuhelper/weak.hxx>
61 #include <com/sun/star/datatransfer/XTransferable.hpp>
62 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
63 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
65 #ifndef _COM_SUN_STAR_DATATRANSFER_DND_DNDCONSTANS_HPP_
66 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
68 #include <com/sun/star/datatransfer/dnd/XDragGestureRecognizer.hpp>
69 #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
71 #ifndef _COM_SUN_STAR_I18N_XEXTENDEDINPUTSEQUENCECHECKER_HDL_
72 #include <com/sun/star/i18n/XExtendedInputSequenceChecker.hpp>
74 #include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
75 #include <com/sun/star/i18n/ScriptType.hpp>
76 #include <com/sun/star/container/XNameAccess.hpp>
78 #include <com/sun/star/uno/Any.hxx>
80 #include <comphelper/processfactory.hxx>
81 #include <comphelper/configurationhelper.hxx>
83 #include <sot/exchange.hxx>
84 #include <sot/formats.hxx>
85 #include <rtl/memory.h>
87 #include <vcl/unohelp.hxx>
88 #include <vcl/unohelp2.hxx>
93 using namespace ::com::sun::star
;
94 using namespace ::com::sun::star::uno
;
95 using namespace ::com::sun::star::lang
;
96 using namespace ::rtl
;
99 // - Bei Tracking-Cancel DefaultSelection wieder herstellen
101 // =======================================================================
103 static FncGetSpecialChars pImplFncGetSpecialChars
= NULL
;
105 // =======================================================================
107 #define EDIT_ALIGN_LEFT 1
108 #define EDIT_ALIGN_CENTER 2
109 #define EDIT_ALIGN_RIGHT 3
111 #define EDIT_DEL_LEFT 1
112 #define EDIT_DEL_RIGHT 2
114 #define EDIT_DELMODE_SIMPLE 11
115 #define EDIT_DELMODE_RESTOFWORD 12
116 #define EDIT_DELMODE_RESTOFCONTENT 13
118 // =======================================================================
123 Selection aDndStartSel
;
131 aCursor
.SetStyle( CURSOR_SHADOW
);
133 bStarterOfDD
= FALSE
;
134 bDroppedInMe
= FALSE
;
139 // =======================================================================
143 String aOldTextAfterStartPos
;
148 BOOL bWasCursorOverwrite
;
150 Impl_IMEInfos( xub_StrLen nPos
, const String
& rOldTextAfterStartPos
);
153 void CopyAttribs( const xub_StrLen
* pA
, xub_StrLen nL
);
154 void DestroyAttribs();
157 // -----------------------------------------------------------------------
159 Impl_IMEInfos::Impl_IMEInfos( xub_StrLen nP
, const String
& rOldTextAfterStartPos
)
160 : aOldTextAfterStartPos( rOldTextAfterStartPos
)
166 bWasCursorOverwrite
= FALSE
;
169 // -----------------------------------------------------------------------
171 Impl_IMEInfos::~Impl_IMEInfos()
176 // -----------------------------------------------------------------------
178 void Impl_IMEInfos::CopyAttribs( const xub_StrLen
* pA
, xub_StrLen nL
)
182 pAttribs
= new USHORT
[ nL
];
183 rtl_copyMemory( pAttribs
, pA
, nL
*sizeof(USHORT
) );
186 // -----------------------------------------------------------------------
188 void Impl_IMEInfos::DestroyAttribs()
195 // =======================================================================
197 Edit::Edit( WindowType nType
) :
203 // -----------------------------------------------------------------------
205 Edit::Edit( Window
* pParent
, WinBits nStyle
) :
206 Control( WINDOW_EDIT
)
209 ImplInit( pParent
, nStyle
);
212 // -----------------------------------------------------------------------
214 Edit::Edit( Window
* pParent
, const ResId
& rResId
) :
215 Control( WINDOW_EDIT
)
218 rResId
.SetRT( RSC_EDIT
);
219 WinBits nStyle
= ImplInitRes( rResId
);
220 ImplInit( pParent
, nStyle
);
221 ImplLoadRes( rResId
);
223 // Derived MultiLineEdit takes care to call Show only after MultiLineEdit
224 // ctor has already started:
225 if ( !(nStyle
& WB_HIDE
) && rResId
.GetRT() != RSC_MULTILINEEDIT
)
229 // -----------------------------------------------------------------------
231 Edit::Edit( Window
* pParent
, const ResId
& rResId
, bool bDisableAccessibleLabeledByRelation
) :
232 Control( WINDOW_EDIT
)
235 rResId
.SetRT( RSC_EDIT
);
236 WinBits nStyle
= ImplInitRes( rResId
);
237 ImplInit( pParent
, nStyle
);
238 ImplLoadRes( rResId
);
239 if ( bDisableAccessibleLabeledByRelation
)
240 ImplGetWindowImpl()->mbDisableAccessibleLabeledByRelation
= TRUE
;
242 // Derived MultiLineEdit takes care to call Show only after MultiLineEdit
243 // ctor has already started:
244 if ( !(nStyle
& WB_HIDE
) && rResId
.GetRT() != RSC_MULTILINEEDIT
)
248 // -----------------------------------------------------------------------
253 Cursor
* pCursor
= GetCursor();
262 if ( mpUpdateDataTimer
)
263 delete mpUpdateDataTimer
;
265 if ( mxDnDListener
.is() )
267 if ( GetDragGestureRecognizer().is() )
269 uno::Reference
< datatransfer::dnd::XDragGestureListener
> xDGL( mxDnDListener
, uno::UNO_QUERY
);
270 GetDragGestureRecognizer()->removeDragGestureListener( xDGL
);
272 if ( GetDropTarget().is() )
274 uno::Reference
< datatransfer::dnd::XDropTargetListener
> xDTL( mxDnDListener
, uno::UNO_QUERY
);
275 GetDropTarget()->removeDropTargetListener( xDTL
);
278 uno::Reference
< lang::XEventListener
> xEL( mxDnDListener
, uno::UNO_QUERY
);
279 xEL
->disposing( lang::EventObject() ); // #95154# #96585# Empty Source means it's the Client
283 // -----------------------------------------------------------------------
285 void Edit::ImplInitEditData()
288 mpUpdateDataTimer
= NULL
;
290 mnAlign
= EDIT_ALIGN_LEFT
;
291 mnMaxTextLen
= EDIT_NOLIMIT
;
292 meAutocompleteAction
= AUTOCOMPLETE_KEYINPUT
;
294 mbInternModified
= FALSE
;
297 mbClickedInSelection
= FALSE
;
298 mbActivePopup
= FALSE
;
305 // --- RTL --- no default mirroring for Edit controls
306 // note: controls that use a subedit will revert this (SpinField, ComboBox)
309 vcl::unohelper::DragAndDropWrapper
* pDnDWrapper
= new vcl::unohelper::DragAndDropWrapper( this );
310 mxDnDListener
= pDnDWrapper
;
313 // -----------------------------------------------------------------------
315 bool Edit::ImplUseNativeBorder( WinBits nStyle
)
318 IsNativeControlSupported(ImplGetNativeControlType(), HAS_BACKGROUND_TEXTURE
)
319 && ((nStyle
&WB_BORDER
) && !(nStyle
&WB_NOBORDER
));
320 if( ! bRet
&& mbIsSubEdit
)
322 Window
* pWindow
= GetParent();
323 nStyle
= pWindow
->GetStyle();
324 bRet
= pWindow
->IsNativeControlSupported(ImplGetNativeControlType(), HAS_BACKGROUND_TEXTURE
)
325 && ((nStyle
&WB_BORDER
) && !(nStyle
&WB_NOBORDER
));
330 void Edit::ImplInit( Window
* pParent
, WinBits nStyle
)
332 nStyle
= ImplInitStyle( nStyle
);
333 if ( !(nStyle
& (WB_CENTER
| WB_RIGHT
)) )
336 Control::ImplInit( pParent
, nStyle
, NULL
);
338 mbReadOnly
= (nStyle
& WB_READONLY
) != 0;
340 mnAlign
= EDIT_ALIGN_LEFT
;
342 // --- RTL --- hack: right align until keyinput and cursor travelling works
344 mnAlign
= EDIT_ALIGN_RIGHT
;
346 if ( nStyle
& WB_RIGHT
)
347 mnAlign
= EDIT_ALIGN_RIGHT
;
348 else if ( nStyle
& WB_CENTER
)
349 mnAlign
= EDIT_ALIGN_CENTER
;
351 SetCursor( new Cursor
);
353 SetPointer( Pointer( POINTER_TEXT
) );
354 ImplInitSettings( TRUE
, TRUE
, TRUE
);
356 uno::Reference
< datatransfer::dnd::XDragGestureListener
> xDGL( mxDnDListener
, uno::UNO_QUERY
);
357 uno::Reference
< datatransfer::dnd::XDragGestureRecognizer
> xDGR
= GetDragGestureRecognizer();
360 xDGR
->addDragGestureListener( xDGL
);
361 uno::Reference
< datatransfer::dnd::XDropTargetListener
> xDTL( mxDnDListener
, uno::UNO_QUERY
);
362 GetDropTarget()->addDropTargetListener( xDTL
);
363 GetDropTarget()->setActive( sal_True
);
364 GetDropTarget()->setDefaultActions( datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE
);
368 // -----------------------------------------------------------------------
370 WinBits
Edit::ImplInitStyle( WinBits nStyle
)
372 if ( !(nStyle
& WB_NOTABSTOP
) )
373 nStyle
|= WB_TABSTOP
;
374 if ( !(nStyle
& WB_NOGROUP
) )
380 // -----------------------------------------------------------------------
382 BOOL
Edit::IsCharInput( const KeyEvent
& rKeyEvent
)
384 // In the future we must use new Unicode functions for this
385 xub_Unicode cCharCode
= rKeyEvent
.GetCharCode();
386 return ((cCharCode
>= 32) && (cCharCode
!= 127) &&
387 !rKeyEvent
.GetKeyCode().IsMod3() &&
388 !rKeyEvent
.GetKeyCode().IsMod2() &&
389 !rKeyEvent
.GetKeyCode().IsMod1() );
392 // -----------------------------------------------------------------------
394 void Edit::ImplModified()
400 // -----------------------------------------------------------------------
402 void Edit::ImplInitSettings( BOOL bFont
, BOOL bForeground
, BOOL bBackground
)
404 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
408 Font aFont
= rStyleSettings
.GetFieldFont();
409 if ( IsControlFont() )
410 aFont
.Merge( GetControlFont() );
411 SetZoomedPointFont( aFont
);
412 delete mpLayoutData
, mpLayoutData
= NULL
;
415 if ( bFont
|| bForeground
)
417 Color aTextColor
= rStyleSettings
.GetFieldTextColor();
418 if ( IsControlForeground() )
419 aTextColor
= GetControlForeground();
420 SetTextColor( aTextColor
);
425 if ( ImplUseNativeBorder( GetStyle() ) || IsPaintTransparent() )
427 // Transparent background
431 else if ( IsControlBackground() )
433 SetBackground( GetControlBackground() );
434 SetFillColor( GetControlBackground() );
438 SetBackground( rStyleSettings
.GetFieldColor() );
439 SetFillColor( rStyleSettings
.GetFieldColor() );
444 // -----------------------------------------------------------------------
446 long Edit::ImplGetExtraOffset() const
448 // MT 09/2002: nExtraOffsetX should become a member, instead of checking every time,
449 // but I need an incompatible update for this...
450 // #94095# Use extra offset only when edit has a border
451 long nExtraOffset
= 0;
452 if( ( GetStyle() & WB_BORDER
) || ( mbIsSubEdit
&& ( GetParent()->GetStyle() & WB_BORDER
) ) )
459 // -----------------------------------------------------------------------
461 XubString
Edit::ImplGetText() const
463 if ( mcEchoChar
|| (GetStyle() & WB_PASSWORD
) )
466 xub_Unicode cEchoChar
;
468 cEchoChar
= mcEchoChar
;
471 aText
.Fill( maText
.Len(), cEchoChar
);
478 // -----------------------------------------------------------------------
480 void Edit::ImplInvalidateOrRepaint( xub_StrLen nStart
, xub_StrLen nEnd
)
482 if( IsPaintTransparent() )
485 // FIXME: this is currently only on aqua
486 if( ImplGetSVData()->maNWFData
.mbNoFocusRects
)
490 ImplRepaint( nStart
, nEnd
);
493 // -----------------------------------------------------------------------
495 void Edit::ImplRepaint( xub_StrLen nStart
, xub_StrLen nEnd
, bool bLayout
)
497 if ( !IsReallyVisible() )
500 XubString aText
= ImplGetText();
504 sal_Int32 nDXBuffer
[256];
505 sal_Int32
* pDXBuffer
= NULL
;
506 sal_Int32
* pDX
= nDXBuffer
;
510 if( 2*aText
.Len() > xub_StrLen(sizeof(nDXBuffer
)/sizeof(nDXBuffer
[0])) )
512 pDXBuffer
= new sal_Int32
[2*(aText
.Len()+1)];
516 GetCaretPositions( aText
, pDX
, nStart
, nEnd
);
520 long nH
= GetOutputSize().Height();
521 long nTH
= GetTextHeight();
522 Point
aPos( mnXOffset
, (nH
-nTH
)/2 );
526 long nPos
= nStart
? pDX
[2*nStart
] : 0;
527 aPos
.X() = nPos
+ mnXOffset
+ ImplGetExtraOffset();
529 MetricVector
* pVector
= &mpLayoutData
->m_aUnicodeBoundRects
;
530 String
* pDisplayText
= &mpLayoutData
->m_aDisplayText
;
532 DrawText( aPos
, aText
, nStart
, nEnd
- nStart
, pVector
, pDisplayText
);
539 Cursor
* pCursor
= GetCursor();
540 BOOL bVisCursor
= pCursor
? pCursor
->IsVisible() : FALSE
;
544 ImplClearBackground( 0, GetOutputSizePixel().Width() );
546 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
548 ImplInitSettings( FALSE
, TRUE
, FALSE
);
550 SetTextColor( rStyleSettings
.GetDisableColor() );
552 // Set background color of the normal text
553 if( (GetStyle() & WB_FORCECTRLBACKGROUND
) != 0 && IsControlBackground() )
555 // check if we need to set ControlBackground even in NWF case
556 Push( PUSH_FILLCOLOR
| PUSH_LINECOLOR
);
558 SetFillColor( GetControlBackground() );
559 DrawRect( Rectangle( aPos
, Size( GetOutputSizePixel().Width() - 2*mnXOffset
, nTH
) ) );
562 SetTextFillColor( GetControlBackground() );
564 else if( IsPaintTransparent() || ImplUseNativeBorder( GetStyle() ) )
567 SetTextFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings
.GetFieldColor() );
569 BOOL bDrawSelection
= maSelection
.Len() && ( HasFocus() || ( GetStyle() & WB_NOHIDESELECTION
) || mbActivePopup
);
571 long nPos
= nStart
? pDX
[2*nStart
] : 0;
572 aPos
.X() = nPos
+ mnXOffset
+ ImplGetExtraOffset();
573 if ( !bDrawSelection
&& !mpIMEInfos
)
575 DrawText( aPos
, aText
, nStart
, nEnd
- nStart
);
579 // save graphics state
581 // first calculate higlighted and non highlighted clip regions
582 Region aHiglightClipRegion
;
583 Region aNormalClipRegion
;
584 Selection
aTmpSel( maSelection
);
586 // selection is highlighted
588 for( i
= 0; i
< aText
.Len(); i
++ )
590 Rectangle
aRect( aPos
, Size( 10, nTH
) );
591 aRect
.Left() = pDX
[2*i
] + mnXOffset
+ ImplGetExtraOffset();
592 aRect
.Right() = pDX
[2*i
+1] + mnXOffset
+ ImplGetExtraOffset();
594 bool bHighlight
= false;
595 if( i
>= aTmpSel
.Min() && i
< aTmpSel
.Max() )
598 if( mpIMEInfos
&& mpIMEInfos
->pAttribs
&&
599 i
>= mpIMEInfos
->nPos
&& i
< (mpIMEInfos
->nPos
+mpIMEInfos
->nLen
) &&
600 ( mpIMEInfos
->pAttribs
[i
-mpIMEInfos
->nPos
] & EXTTEXTINPUT_ATTR_HIGHLIGHT
) )
604 aHiglightClipRegion
.Union( aRect
);
606 aNormalClipRegion
.Union( aRect
);
609 Color aNormalTextColor
= GetTextColor();
610 SetClipRegion( aNormalClipRegion
);
612 if( IsPaintTransparent() )
616 // Set background color when part of the text is selected
617 if ( ImplUseNativeBorder( GetStyle() ) )
619 if( (GetStyle() & WB_FORCECTRLBACKGROUND
) != 0 && IsControlBackground() )
620 SetTextFillColor( GetControlBackground() );
625 SetTextFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings
.GetFieldColor() );
627 DrawText( aPos
, aText
, nStart
, nEnd
- nStart
);
629 // draw highlighted text
630 SetClipRegion( aHiglightClipRegion
);
631 SetTextColor( rStyleSettings
.GetHighlightTextColor() );
632 SetTextFillColor( rStyleSettings
.GetHighlightColor() );
633 DrawText( aPos
, aText
, nStart
, nEnd
- nStart
);
635 // if IME info exists loop over portions and output different font attributes
636 if( mpIMEInfos
&& mpIMEInfos
->pAttribs
)
638 for( int n
= 0; n
< 2; n
++ )
643 SetTextColor( aNormalTextColor
);
644 if( IsPaintTransparent() )
647 SetTextFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings
.GetFieldColor() );
648 aRegion
= aNormalClipRegion
;
652 SetTextColor( rStyleSettings
.GetHighlightTextColor() );
653 SetTextFillColor( rStyleSettings
.GetHighlightColor() );
654 aRegion
= aHiglightClipRegion
;
657 for( i
= 0; i
< mpIMEInfos
->nLen
; )
659 USHORT nAttr
= mpIMEInfos
->pAttribs
[i
];
662 while( nIndex
< mpIMEInfos
->nLen
&& mpIMEInfos
->pAttribs
[nIndex
] == nAttr
) // #112631# check nIndex before using it
664 Rectangle
aRect( aPos
, Size( 10, nTH
) );
665 aRect
.Left() = pDX
[2*(nIndex
+mpIMEInfos
->nPos
)] + mnXOffset
+ ImplGetExtraOffset();
666 aRect
.Right() = pDX
[2*(nIndex
+mpIMEInfos
->nPos
)+1] + mnXOffset
+ ImplGetExtraOffset();
668 aClip
.Union( aRect
);
672 if( aClip
.Intersect( aRegion
) && nAttr
)
674 Font aFont
= GetFont();
675 if ( nAttr
& EXTTEXTINPUT_ATTR_UNDERLINE
)
676 aFont
.SetUnderline( UNDERLINE_SINGLE
);
677 else if ( nAttr
& EXTTEXTINPUT_ATTR_BOLDUNDERLINE
)
678 aFont
.SetUnderline( UNDERLINE_BOLD
);
679 else if ( nAttr
& EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE
)
680 aFont
.SetUnderline( UNDERLINE_DOTTED
);
681 else if ( nAttr
& EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE
)
682 aFont
.SetUnderline( UNDERLINE_DOTTED
);
683 else if ( nAttr
& EXTTEXTINPUT_ATTR_GRAYWAVELINE
)
685 aFont
.SetUnderline( UNDERLINE_WAVE
);
686 SetTextLineColor( Color( COL_LIGHTGRAY
) );
690 if ( nAttr
& EXTTEXTINPUT_ATTR_REDTEXT
)
691 SetTextColor( Color( COL_RED
) );
692 else if ( nAttr
& EXTTEXTINPUT_ATTR_HALFTONETEXT
)
693 SetTextColor( Color( COL_LIGHTGRAY
) );
695 SetClipRegion( aClip
);
696 DrawText( aPos
, aText
, nStart
, nEnd
- nStart
);
702 // restore graphics state
706 if ( bVisCursor
&& ( !mpIMEInfos
|| mpIMEInfos
->bCursor
) )
713 // -----------------------------------------------------------------------
715 void Edit::ImplDelete( const Selection
& rSelection
, BYTE nDirection
, BYTE nMode
)
717 XubString aText
= ImplGetText();
719 // loeschen moeglich?
720 if ( !rSelection
.Len() &&
721 (((rSelection
.Min() == 0) && (nDirection
== EDIT_DEL_LEFT
)) ||
722 ((rSelection
.Max() == aText
.Len()) && (nDirection
== EDIT_DEL_RIGHT
))) )
725 delete mpLayoutData
, mpLayoutData
= NULL
;
727 Selection
aSelection( rSelection
);
728 aSelection
.Justify();
730 if ( !aSelection
.Len() )
732 uno::Reference
< i18n::XBreakIterator
> xBI
= ImplGetBreakIterator();
733 if ( nDirection
== EDIT_DEL_LEFT
)
735 if ( nMode
== EDIT_DELMODE_RESTOFWORD
)
737 i18n::Boundary aBoundary
= xBI
->getWordBoundary( maText
, aSelection
.Min(), GetSettings().GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES
, sal_True
);
738 if ( aBoundary
.startPos
== aSelection
.Min() )
739 aBoundary
= xBI
->previousWord( maText
, aSelection
.Min(), GetSettings().GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES
);
740 aSelection
.Min() = aBoundary
.startPos
;
742 else if ( nMode
== EDIT_DELMODE_RESTOFCONTENT
)
744 aSelection
.Min() = 0;
748 sal_Int32 nCount
= 1;
749 aSelection
.Min() = xBI
->previousCharacters( maText
, aSelection
.Min(), GetSettings().GetLocale(), i18n::CharacterIteratorMode::SKIPCHARACTER
, nCount
, nCount
);
754 if ( nMode
== EDIT_DELMODE_RESTOFWORD
)
756 i18n::Boundary aBoundary
= xBI
->nextWord( maText
, aSelection
.Max(), GetSettings().GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES
);
757 aSelection
.Max() = aBoundary
.startPos
;
759 else if ( nMode
== EDIT_DELMODE_RESTOFCONTENT
)
761 aSelection
.Max() = aText
.Len();
765 sal_Int32 nCount
= 1;
766 aSelection
.Max() = xBI
->nextCharacters( maText
, aSelection
.Max(), GetSettings().GetLocale(), i18n::CharacterIteratorMode::SKIPCHARACTER
, nCount
, nCount
);;
771 maText
.Erase( (xub_StrLen
)aSelection
.Min(), (xub_StrLen
)aSelection
.Len() );
772 maSelection
.Min() = aSelection
.Min();
773 maSelection
.Max() = aSelection
.Min();
775 mbInternModified
= TRUE
;
778 // -----------------------------------------------------------------------
780 String
Edit::ImplGetValidString( const String
& rString
) const
782 String
aValidString( rString
);
783 aValidString
.EraseAllChars( _LF
);
784 aValidString
.EraseAllChars( _CR
);
785 aValidString
.SearchAndReplaceAll( '\t', ' ' );
789 // -----------------------------------------------------------------------
790 Reference
< i18n::XBreakIterator
> Edit::ImplGetBreakIterator() const
792 //!! since we don't want to become incompatible in the next minor update
793 //!! where this code will get integrated into, xISC will be a local
794 //!! variable instead of a class member!
795 Reference
< i18n::XBreakIterator
> xBI
;
798 Reference
< lang::XMultiServiceFactory
> xMSF
= ::comphelper::getProcessServiceFactory();
799 Reference
< XInterface
> xI
= xMSF
->createInstance( OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) );
802 Any x
= xI
->queryInterface( ::getCppuType((const Reference
< i18n::XBreakIterator
>*)0) );
808 // -----------------------------------------------------------------------
810 Reference
< i18n::XExtendedInputSequenceChecker
> Edit::ImplGetInputSequenceChecker() const
812 //!! since we don't want to become incompatible in the next minor update
813 //!! where this code will get integrated into, xISC will be a local
814 //!! variable instead of a class member!
815 Reference
< i18n::XExtendedInputSequenceChecker
> xISC
;
818 Reference
< lang::XMultiServiceFactory
> xMSF
= ::comphelper::getProcessServiceFactory();
819 Reference
< XInterface
> xI
= xMSF
->createInstance( OUString::createFromAscii( "com.sun.star.i18n.InputSequenceChecker" ) );
822 Any x
= xI
->queryInterface( ::getCppuType((const Reference
< i18n::XExtendedInputSequenceChecker
>*)0) );
829 // -----------------------------------------------------------------------
831 void Edit::ShowTruncationWarning( Window
* pParent
)
833 ResMgr
* pResMgr
= ImplGetResMgr();
836 WarningBox
aBox( pParent
, ResId( SV_EDIT_WARNING_BOX
, *pResMgr
) );
841 // -----------------------------------------------------------------------
843 bool Edit::ImplTruncateToMaxLen( rtl::OUString
& rStr
, sal_uInt32 nSelectionLen
) const
845 bool bWasTruncated
= false;
846 const sal_uInt32 nMaxLen
= mnMaxTextLen
< 65534 ? mnMaxTextLen
: 65534;
847 sal_uInt32 nLenAfter
= static_cast<sal_uInt32
>(maText
.Len()) + rStr
.getLength() - nSelectionLen
;
848 if ( nLenAfter
> nMaxLen
)
850 sal_uInt32 nErasePos
= nMaxLen
- static_cast<sal_uInt32
>(maText
.Len()) + nSelectionLen
;
851 rStr
= rStr
.copy( 0, nErasePos
);
852 bWasTruncated
= true;
854 return bWasTruncated
;
857 // -----------------------------------------------------------------------
859 void Edit::ImplInsertText( const XubString
& rStr
, const Selection
* pNewSel
, sal_Bool bIsUserInput
)
861 Selection
aSelection( maSelection
);
862 aSelection
.Justify();
864 rtl::OUString
aNewText( ImplGetValidString( rStr
) );
865 ImplTruncateToMaxLen( aNewText
, aSelection
.Len() );
867 delete mpLayoutData
, mpLayoutData
= NULL
;
869 if ( aSelection
.Len() )
870 maText
.Erase( (xub_StrLen
)aSelection
.Min(), (xub_StrLen
)aSelection
.Len() );
871 else if ( !mbInsertMode
&& (aSelection
.Max() < maText
.Len()) )
872 maText
.Erase( (xub_StrLen
)aSelection
.Max(), 1 );
874 // take care of input-sequence-checking now
875 if (bIsUserInput
&& rStr
.Len())
877 DBG_ASSERT( rStr
.Len() == 1, "unexpected string length. User input is expected to providse 1 char only!" );
879 // determine if input-sequence-checking should be applied or not
881 static OUString
sModule( OUString::createFromAscii( "/org.openoffice.Office.Common/I18N" ) );
882 static OUString
sRelNode( OUString::createFromAscii( "CTL" ) );
883 static OUString
sCTLSequenceChecking( OUString::createFromAscii( "CTLSequenceChecking" ) );
884 static OUString
sCTLSequenceCheckingRestricted( OUString::createFromAscii( "CTLSequenceCheckingRestricted" ) );
885 static OUString
sCTLSequenceCheckingTypeAndReplace( OUString::createFromAscii( "CTLSequenceCheckingTypeAndReplace" ) );
886 static OUString
sCTLFont( OUString::createFromAscii( "CTLFont" ) );
888 sal_Bool bCTLSequenceChecking
= sal_False
;
889 sal_Bool bCTLSequenceCheckingRestricted
= sal_False
;
890 sal_Bool bCTLSequenceCheckingTypeAndReplace
= sal_False
;
891 sal_Bool bCTLFontEnabled
= sal_False
;
892 sal_Bool bIsInputSequenceChecking
= sal_False
;
894 // get access to the configuration of this office module
897 Reference
< lang::XMultiServiceFactory
> xMSF
= ::comphelper::getProcessServiceFactory();
898 Reference
< container::XNameAccess
> xModuleCfg( ::comphelper::ConfigurationHelper::openConfig(
901 ::comphelper::ConfigurationHelper::E_READONLY
),
904 //!! get values from configuration.
905 //!! we can't use SvtCTLOptions here since vcl must not be linked
906 //!! against svtools. (It is already the other way around.)
907 Any aCTLSequenceChecking
= ::comphelper::ConfigurationHelper::readRelativeKey( xModuleCfg
, sRelNode
, sCTLSequenceChecking
);
908 Any aCTLSequenceCheckingRestricted
= ::comphelper::ConfigurationHelper::readRelativeKey( xModuleCfg
, sRelNode
, sCTLSequenceCheckingRestricted
);
909 Any aCTLSequenceCheckingTypeAndReplace
= ::comphelper::ConfigurationHelper::readRelativeKey( xModuleCfg
, sRelNode
, sCTLSequenceCheckingTypeAndReplace
);
910 Any aCTLFontEnabled
= ::comphelper::ConfigurationHelper::readRelativeKey( xModuleCfg
, sRelNode
, sCTLFont
);
911 aCTLSequenceChecking
>>= bCTLSequenceChecking
;
912 aCTLSequenceCheckingRestricted
>>= bCTLSequenceCheckingRestricted
;
913 aCTLSequenceCheckingTypeAndReplace
>>= bCTLSequenceCheckingTypeAndReplace
;
914 aCTLFontEnabled
>>= bCTLFontEnabled
;
918 bIsInputSequenceChecking
= sal_False
; // continue with inserting the new text
921 uno::Reference
< i18n::XBreakIterator
> xBI( ImplGetBreakIterator(), UNO_QUERY
);
922 bIsInputSequenceChecking
= rStr
.Len() == 1 &&
924 bCTLSequenceChecking
&&
925 aSelection
.Min() > 0 && /* first char needs not to be checked */
926 xBI
.is() && i18n::ScriptType::COMPLEX
== xBI
->getScriptType( rStr
, 0 );
929 uno::Reference
< i18n::XExtendedInputSequenceChecker
> xISC
;
930 if (bIsInputSequenceChecking
&& (xISC
= ImplGetInputSequenceChecker()).is())
932 sal_Unicode cChar
= rStr
.GetChar(0);
933 xub_StrLen nTmpPos
= static_cast< xub_StrLen
>( aSelection
.Min() );
934 sal_Int16 nCheckMode
= bCTLSequenceCheckingRestricted
?
935 i18n::InputSequenceCheckMode::STRICT
: i18n::InputSequenceCheckMode::BASIC
;
937 // the text that needs to be checked is only the one
938 // before the current cursor position
939 rtl::OUString
aOldText( maText
.Copy(0, nTmpPos
) );
940 rtl::OUString
aTmpText( aOldText
);
941 if (bCTLSequenceCheckingTypeAndReplace
)
943 xISC
->correctInputSequence( aTmpText
, nTmpPos
- 1, cChar
, nCheckMode
);
945 // find position of first character that has changed
946 sal_Int32 nOldLen
= aOldText
.getLength();
947 sal_Int32 nTmpLen
= aTmpText
.getLength();
948 const sal_Unicode
*pOldTxt
= aOldText
.getStr();
949 const sal_Unicode
*pTmpTxt
= aTmpText
.getStr();
950 sal_Int32 nChgPos
= 0;
951 while ( nChgPos
< nOldLen
&& nChgPos
< nTmpLen
&&
952 pOldTxt
[nChgPos
] == pTmpTxt
[nChgPos
] )
955 xub_StrLen nChgLen
= static_cast< xub_StrLen
>( nTmpLen
- nChgPos
);
956 String
aChgText( aTmpText
.copy( nChgPos
), nChgLen
);
958 // remove text from first pos to be changed to current pos
959 maText
.Erase( static_cast< xub_StrLen
>( nChgPos
), static_cast< xub_StrLen
>( nTmpPos
- nChgPos
) );
964 aSelection
.Min() = nChgPos
; // position for new text to be inserted
967 aNewText
= String::EmptyString();
971 // should the character be ignored (i.e. not get inserted) ?
972 if (!xISC
->checkInputSequence( aOldText
, nTmpPos
- 1, cChar
, nCheckMode
))
973 aNewText
= String::EmptyString();
977 // at this point now we will insert the non-empty text 'normally' some lines below...
980 if ( aNewText
.getLength() )
981 maText
.Insert( String( aNewText
), (xub_StrLen
)aSelection
.Min() );
985 maSelection
.Min() = aSelection
.Min() + aNewText
.getLength();
986 maSelection
.Max() = maSelection
.Min();
990 maSelection
= *pNewSel
;
991 if ( maSelection
.Min() > maText
.Len() )
992 maSelection
.Min() = maText
.Len();
993 if ( maSelection
.Max() > maText
.Len() )
994 maSelection
.Max() = maText
.Len();
998 mbInternModified
= TRUE
;
1001 // -----------------------------------------------------------------------
1003 void Edit::ImplSetText( const XubString
& rText
, const Selection
* pNewSelection
)
1005 // Der Text wird dadurch geloescht das der alte Text komplett 'selektiert'
1006 // wird, dann InsertText, damit flackerfrei.
1007 if ( ( rText
.Len() <= mnMaxTextLen
) && ( (rText
!= maText
) || (pNewSelection
&& (*pNewSelection
!= maSelection
)) ) )
1009 delete mpLayoutData
, mpLayoutData
= NULL
;
1010 maSelection
.Min() = 0;
1011 maSelection
.Max() = maText
.Len();
1012 if ( mnXOffset
|| HasPaintEvent() )
1015 maText
= ImplGetValidString( rText
);
1017 // #i54929# recalculate mnXOffset before ImplSetSelection,
1018 // else cursor ends up in wrong position
1021 if ( pNewSelection
)
1022 ImplSetSelection( *pNewSelection
, FALSE
);
1024 if ( mnXOffset
&& !pNewSelection
)
1025 maSelection
.Max() = 0;
1030 ImplInsertText( rText
, pNewSelection
);
1032 ImplCallEventListeners( VCLEVENT_EDIT_MODIFY
);
1036 // -----------------------------------------------------------------------
1038 int Edit::ImplGetNativeControlType()
1041 Window
*pControl
= mbIsSubEdit
? GetParent() : this;
1043 switch( pControl
->GetType() )
1045 case WINDOW_COMBOBOX
:
1046 case WINDOW_PATTERNBOX
:
1047 case WINDOW_NUMERICBOX
:
1048 case WINDOW_METRICBOX
:
1049 case WINDOW_CURRENCYBOX
:
1050 case WINDOW_DATEBOX
:
1051 case WINDOW_TIMEBOX
:
1052 case WINDOW_LONGCURRENCYBOX
:
1053 nCtrl
= CTRL_COMBOBOX
;
1056 case WINDOW_MULTILINEEDIT
:
1057 if ( GetWindow( WINDOW_BORDER
) != this )
1058 nCtrl
= CTRL_MULTILINE_EDITBOX
;
1060 nCtrl
= CTRL_EDITBOX_NOBORDER
;
1064 case WINDOW_PATTERNFIELD
:
1065 case WINDOW_METRICFIELD
:
1066 case WINDOW_CURRENCYFIELD
:
1067 case WINDOW_DATEFIELD
:
1068 case WINDOW_TIMEFIELD
:
1069 case WINDOW_LONGCURRENCYFIELD
:
1070 case WINDOW_NUMERICFIELD
:
1071 case WINDOW_SPINFIELD
:
1072 if( pControl
->GetStyle() & WB_SPIN
)
1073 nCtrl
= CTRL_SPINBOX
;
1076 if ( GetWindow( WINDOW_BORDER
) != this )
1077 nCtrl
= CTRL_EDITBOX
;
1079 nCtrl
= CTRL_EDITBOX_NOBORDER
;
1084 nCtrl
= CTRL_EDITBOX
;
1089 void Edit::ImplClearBackground( long nXStart
, long nXEnd
)
1092 * note: at this point the cursor must be switched off already
1095 Rectangle
aRect( aTmpPoint
, GetOutputSizePixel() );
1096 aRect
.Left() = nXStart
;
1097 aRect
.Right() = nXEnd
;
1099 if( ImplUseNativeBorder( GetStyle() ) || IsPaintTransparent() )
1101 // draw the inner part by painting the whole control using its border window
1102 Window
*pControl
= this;
1103 Window
*pBorder
= GetWindow( WINDOW_BORDER
);
1104 if( pBorder
== this )
1106 // we have no border, use parent
1107 pControl
= mbIsSubEdit
? GetParent() : this;
1108 pBorder
= pControl
->GetWindow( WINDOW_BORDER
);
1109 if( pBorder
== this )
1110 pBorder
= GetParent();
1115 // set proper clipping region to not overdraw the whole control
1116 Region aClipRgn
= GetPaintRegion();
1117 if( !aClipRgn
.IsNull() )
1119 // transform clipping region to border window's coordinate system
1120 if( IsRTLEnabled() != pBorder
->IsRTLEnabled() && Application::GetSettings().GetLayoutRTL() )
1122 // need to mirror in case border is not RTL but edit is (or vice versa)
1125 Rectangle
aBounds( aClipRgn
.GetBoundRect() );
1126 int xNew
= GetOutputSizePixel().Width() - aBounds
.GetWidth() - aBounds
.Left();
1127 aClipRgn
.Move( xNew
- aBounds
.Left(), 0 );
1129 // move offset of border window
1131 aBorderOffs
= pBorder
->ScreenToOutputPixel( OutputToScreenPixel( aBorderOffs
) );
1132 aClipRgn
.Move( aBorderOffs
.X(), aBorderOffs
.Y() );
1138 aBorderOffs
= pBorder
->ScreenToOutputPixel( OutputToScreenPixel( aBorderOffs
) );
1139 aClipRgn
.Move( aBorderOffs
.X(), aBorderOffs
.Y() );
1142 Region
oldRgn( pBorder
->GetClipRegion() );
1143 pBorder
->SetClipRegion( aClipRgn
);
1145 pBorder
->Paint( Rectangle() );
1147 pBorder
->SetClipRegion( oldRgn
);
1150 pBorder
->Paint( Rectangle() );
1158 // -----------------------------------------------------------------------
1160 void Edit::ImplShowCursor( BOOL bOnlyIfVisible
)
1162 if ( !IsUpdateMode() || ( bOnlyIfVisible
&& !IsReallyVisible() ) )
1165 Cursor
* pCursor
= GetCursor();
1166 XubString aText
= ImplGetText();
1170 sal_Int32 nDXBuffer
[256];
1171 sal_Int32
* pDXBuffer
= NULL
;
1172 sal_Int32
* pDX
= nDXBuffer
;
1176 if( 2*aText
.Len() > xub_StrLen(sizeof(nDXBuffer
)/sizeof(nDXBuffer
[0])) )
1178 pDXBuffer
= new sal_Int32
[2*(aText
.Len()+1)];
1182 GetCaretPositions( aText
, pDX
, 0, aText
.Len() );
1184 if( maSelection
.Max() < aText
.Len() )
1185 nTextPos
= pDX
[ 2*maSelection
.Max() ];
1187 nTextPos
= pDX
[ 2*aText
.Len()-1 ];
1190 long nCursorWidth
= 0;
1191 if ( !mbInsertMode
&& !maSelection
.Len() && (maSelection
.Max() < aText
.Len()) )
1192 nCursorWidth
= GetTextWidth( aText
, (xub_StrLen
)maSelection
.Max(), 1 );
1193 long nCursorPosX
= nTextPos
+ mnXOffset
+ ImplGetExtraOffset();
1195 // Cursor muss im sichtbaren Bereich landen:
1196 Size aOutSize
= GetOutputSizePixel();
1197 if ( (nCursorPosX
< 0) || (nCursorPosX
>= aOutSize
.Width()) )
1199 long nOldXOffset
= mnXOffset
;
1201 if ( nCursorPosX
< 0 )
1203 mnXOffset
= - nTextPos
;
1205 mnXOffset
+= aOutSize
.Width() / 5;
1206 if ( mnXOffset
> nMaxX
)
1211 mnXOffset
= (aOutSize
.Width()-ImplGetExtraOffset()) - nTextPos
;
1213 if ( (aOutSize
.Width()-ImplGetExtraOffset()) < nTextPos
)
1215 long nMaxNegX
= (aOutSize
.Width()-ImplGetExtraOffset()) - GetTextWidth( aText
);
1216 mnXOffset
-= aOutSize
.Width() / 5;
1217 if ( mnXOffset
< nMaxNegX
) // beides negativ...
1218 mnXOffset
= nMaxNegX
;
1222 nCursorPosX
= nTextPos
+ mnXOffset
+ ImplGetExtraOffset();
1223 if ( nCursorPosX
== aOutSize
.Width() ) // dann nicht sichtbar...
1226 if ( mnXOffset
!= nOldXOffset
)
1227 ImplInvalidateOrRepaint();
1230 long nTextHeight
= GetTextHeight();
1231 long nCursorPosY
= (aOutSize
.Height()-nTextHeight
) / 2;
1232 pCursor
->SetPos( Point( nCursorPosX
, nCursorPosY
) );
1233 pCursor
->SetSize( Size( nCursorWidth
, nTextHeight
) );
1237 delete [] pDXBuffer
;
1240 // -----------------------------------------------------------------------
1242 void Edit::ImplAlign()
1244 long nTextWidth
= GetTextWidth( ImplGetText() );
1245 long nOutWidth
= GetOutputSizePixel().Width();
1247 if ( mnAlign
== EDIT_ALIGN_LEFT
)
1249 if( mnXOffset
&& ( nTextWidth
< nOutWidth
) )
1253 else if ( mnAlign
== EDIT_ALIGN_RIGHT
)
1255 long nMinXOffset
= nOutWidth
- nTextWidth
- 1 - ImplGetExtraOffset();
1256 bool bRTL
= IsRTLEnabled();
1257 if( mbIsSubEdit
&& GetParent() )
1258 bRTL
= GetParent()->IsRTLEnabled();
1261 if( nTextWidth
< nOutWidth
)
1262 mnXOffset
= nMinXOffset
;
1266 if( nTextWidth
< nOutWidth
)
1267 mnXOffset
= nMinXOffset
;
1268 else if ( mnXOffset
< nMinXOffset
)
1269 mnXOffset
= nMinXOffset
;
1272 else if( mnAlign
== EDIT_ALIGN_CENTER
)
1274 // Mit Abfrage schoener, wenn gescrollt, dann aber nicht zentriert im gescrollten Zustand...
1275 // if ( nTextWidth < nOutWidth )
1276 mnXOffset
= (nOutWidth
- nTextWidth
) / 2;
1281 // -----------------------------------------------------------------------
1283 void Edit::ImplAlignAndPaint()
1286 ImplInvalidateOrRepaint( 0, STRING_LEN
);
1290 // -----------------------------------------------------------------------
1292 xub_StrLen
Edit::ImplGetCharPos( const Point
& rWindowPos
) const
1294 xub_StrLen nIndex
= STRING_LEN
;
1295 String aText
= ImplGetText();
1297 sal_Int32 nDXBuffer
[256];
1298 sal_Int32
* pDXBuffer
= NULL
;
1299 sal_Int32
* pDX
= nDXBuffer
;
1300 if( 2*aText
.Len() > xub_StrLen(sizeof(nDXBuffer
)/sizeof(nDXBuffer
[0])) )
1302 pDXBuffer
= new sal_Int32
[2*(aText
.Len()+1)];
1306 GetCaretPositions( aText
, pDX
, 0, aText
.Len() );
1307 long nX
= rWindowPos
.X() - mnXOffset
- ImplGetExtraOffset();
1308 for( int i
= 0; i
< aText
.Len(); i
++ )
1310 if( (pDX
[2*i
] >= nX
&& pDX
[2*i
+1] <= nX
) ||
1311 (pDX
[2*i
+1] >= nX
&& pDX
[2*i
] <= nX
))
1313 nIndex
= sal::static_int_cast
<xub_StrLen
>(i
);
1314 if( pDX
[2*i
] < pDX
[2*i
+1] )
1316 if( nX
> (pDX
[2*i
]+pDX
[2*i
+1])/2 )
1321 if( nX
< (pDX
[2*i
]+pDX
[2*i
+1])/2 )
1327 if( nIndex
== STRING_LEN
)
1330 long nDiff
= Abs( pDX
[0]-nX
);
1331 for( int i
= 1; i
< aText
.Len(); i
++ )
1333 long nNewDiff
= Abs( pDX
[2*i
]-nX
);
1335 if( nNewDiff
< nDiff
)
1337 nIndex
= sal::static_int_cast
<xub_StrLen
>(i
);
1341 if( nIndex
== aText
.Len()-1 && Abs( pDX
[2*nIndex
+1] - nX
) < nDiff
)
1342 nIndex
= STRING_LEN
;
1346 delete [] pDXBuffer
;
1351 // -----------------------------------------------------------------------
1353 void Edit::ImplSetCursorPos( xub_StrLen nChar
, BOOL bSelect
)
1355 Selection
aSelection( maSelection
);
1356 aSelection
.Max() = nChar
;
1358 aSelection
.Min() = aSelection
.Max();
1359 ImplSetSelection( aSelection
);
1362 // -----------------------------------------------------------------------
1364 void Edit::ImplLoadRes( const ResId
& rResId
)
1366 Control::ImplLoadRes( rResId
);
1368 xub_StrLen nTextLength
= ReadShortRes();
1370 SetMaxTextLen( nTextLength
);
1373 // -----------------------------------------------------------------------
1375 void Edit::ImplCopyToSelectionClipboard()
1377 if ( GetSelection().Len() )
1379 ::com::sun::star::uno::Reference
<com::sun::star::datatransfer::clipboard::XClipboard
> aSelection(GetPrimarySelection());
1380 ImplCopy( aSelection
);
1384 void Edit::ImplCopy( uno::Reference
< datatransfer::clipboard::XClipboard
>& rxClipboard
)
1386 ::vcl::unohelper::TextDataObject::CopyStringTo( GetSelected(), rxClipboard
);
1389 // -----------------------------------------------------------------------
1391 void Edit::ImplPaste( uno::Reference
< datatransfer::clipboard::XClipboard
>& rxClipboard
)
1393 if ( rxClipboard
.is() )
1395 uno::Reference
< datatransfer::XTransferable
> xDataObj
;
1397 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
1401 xDataObj
= rxClipboard
->getContents();
1403 catch( const ::com::sun::star::uno::Exception
& )
1407 Application::AcquireSolarMutex( nRef
);
1409 if ( xDataObj
.is() )
1411 datatransfer::DataFlavor aFlavor
;
1412 SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING
, aFlavor
);
1415 uno::Any aData
= xDataObj
->getTransferData( aFlavor
);
1416 ::rtl::OUString aText
;
1418 if( ImplTruncateToMaxLen( aText
, maSelection
.Len() ) )
1419 ShowTruncationWarning( const_cast<Edit
*>(this) );
1420 ReplaceSelected( aText
);
1422 catch( const ::com::sun::star::uno::Exception
& )
1429 // -----------------------------------------------------------------------
1431 void Edit::MouseButtonDown( const MouseEvent
& rMEvt
)
1435 Control::MouseButtonDown( rMEvt
);
1439 xub_StrLen nChar
= ImplGetCharPos( rMEvt
.GetPosPixel() );
1440 Selection
aSelection( maSelection
);
1441 aSelection
.Justify();
1443 if ( rMEvt
.GetClicks() < 4 )
1445 mbClickedInSelection
= FALSE
;
1446 if ( rMEvt
.GetClicks() == 3 )
1448 ImplSetSelection( Selection( 0, 0xFFFF ) );
1449 ImplCopyToSelectionClipboard();
1452 else if ( rMEvt
.GetClicks() == 2 )
1454 uno::Reference
< i18n::XBreakIterator
> xBI
= ImplGetBreakIterator();
1455 i18n::Boundary aBoundary
= xBI
->getWordBoundary( maText
, aSelection
.Max(), GetSettings().GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES
, sal_True
);
1456 ImplSetSelection( Selection( aBoundary
.startPos
, aBoundary
.endPos
) );
1457 ImplCopyToSelectionClipboard();
1459 else if ( !rMEvt
.IsShift() && HasFocus() && aSelection
.IsInside( nChar
) )
1460 mbClickedInSelection
= TRUE
;
1461 else if ( rMEvt
.IsLeft() )
1462 ImplSetCursorPos( nChar
, rMEvt
.IsShift() );
1464 if ( !mbClickedInSelection
&& rMEvt
.IsLeft() && ( rMEvt
.GetClicks() == 1 ) )
1465 StartTracking( STARTTRACK_SCROLLREPEAT
);
1468 mbInMBDown
= TRUE
; // Dann im GetFocus nicht alles selektieren
1473 // -----------------------------------------------------------------------
1475 void Edit::MouseButtonUp( const MouseEvent
& rMEvt
)
1477 if ( mbClickedInSelection
&& rMEvt
.IsLeft() )
1479 xub_StrLen nChar
= ImplGetCharPos( rMEvt
.GetPosPixel() );
1480 ImplSetCursorPos( nChar
, FALSE
);
1481 mbClickedInSelection
= FALSE
;
1483 else if ( rMEvt
.IsMiddle() && !mbReadOnly
&&
1484 ( GetSettings().GetMouseSettings().GetMiddleButtonAction() == MOUSE_MIDDLE_PASTESELECTION
) )
1486 ::com::sun::star::uno::Reference
<com::sun::star::datatransfer::clipboard::XClipboard
> aSelection(Window::GetPrimarySelection());
1487 ImplPaste( aSelection
);
1492 // -----------------------------------------------------------------------
1494 void Edit::Tracking( const TrackingEvent
& rTEvt
)
1496 if ( rTEvt
.IsTrackingEnded() )
1498 if ( mbClickedInSelection
)
1500 xub_StrLen nChar
= ImplGetCharPos( rTEvt
.GetMouseEvent().GetPosPixel() );
1501 ImplSetCursorPos( nChar
, FALSE
);
1502 mbClickedInSelection
= FALSE
;
1504 else if ( rTEvt
.GetMouseEvent().IsLeft() )
1506 ImplCopyToSelectionClipboard();
1511 if( !mbClickedInSelection
)
1513 xub_StrLen nChar
= ImplGetCharPos( rTEvt
.GetMouseEvent().GetPosPixel() );
1514 ImplSetCursorPos( nChar
, TRUE
);
1518 if ( mpUpdateDataTimer
&& !mbIsSubEdit
&& mpUpdateDataTimer
->IsActive() )
1519 mpUpdateDataTimer
->Start();//do not update while the user is still travelling in the control
1522 // -----------------------------------------------------------------------
1524 BOOL
Edit::ImplHandleKeyEvent( const KeyEvent
& rKEvt
)
1527 USHORT nCode
= rKEvt
.GetKeyCode().GetCode();
1528 KeyFuncType eFunc
= rKEvt
.GetKeyCode().GetFunction();
1530 mbInternModified
= FALSE
;
1532 if ( eFunc
!= KEYFUNC_DONTKNOW
)
1538 if ( !mbReadOnly
&& maSelection
.Len() && !(GetStyle() & WB_PASSWORD
) )
1549 if ( !(GetStyle() & WB_PASSWORD
) )
1577 default: // wird dann evtl. unten bearbeitet.
1578 eFunc
= KEYFUNC_DONTKNOW
;
1582 if ( !bDone
&& rKEvt
.GetKeyCode().IsMod1() && !rKEvt
.GetKeyCode().IsMod2() )
1584 if ( nCode
== KEY_A
)
1586 ImplSetSelection( Selection( 0, maText
.Len() ) );
1589 else if ( rKEvt
.GetKeyCode().IsShift() && (nCode
== KEY_S
) )
1591 if ( pImplFncGetSpecialChars
)
1593 Selection aSaveSel
= GetSelection(); // Falls jemand in Get/LoseFocus die Selektion verbiegt, z.B. URL-Zeile...
1594 XubString aChars
= pImplFncGetSpecialChars( this, GetFont() );
1595 SetSelection( aSaveSel
);
1598 ImplInsertText( aChars
);
1606 if ( eFunc
== KEYFUNC_DONTKNOW
&& ! bDone
)
1610 case com::sun::star::awt::Key::SELECT_ALL
:
1612 ImplSetSelection( Selection( 0, maText
.Len() ) );
1621 case com::sun::star::awt::Key::MOVE_WORD_FORWARD
:
1622 case com::sun::star::awt::Key::SELECT_WORD_FORWARD
:
1623 case com::sun::star::awt::Key::MOVE_WORD_BACKWARD
:
1624 case com::sun::star::awt::Key::SELECT_WORD_BACKWARD
:
1625 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE
:
1626 case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE
:
1627 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE
:
1628 case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE
:
1629 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH
:
1630 case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH
:
1631 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH
:
1632 case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH
:
1633 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT
:
1634 case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT
:
1635 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT
:
1636 case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT
:
1638 if ( !rKEvt
.GetKeyCode().IsMod2() )
1640 delete mpLayoutData
, mpLayoutData
= NULL
;
1641 uno::Reference
< i18n::XBreakIterator
> xBI
= ImplGetBreakIterator();
1643 Selection
aSel( maSelection
);
1644 bool bWord
= rKEvt
.GetKeyCode().IsMod1();
1645 bool bSelect
= rKEvt
.GetKeyCode().IsShift();
1646 bool bGoLeft
= (nCode
== KEY_LEFT
);
1647 bool bGoRight
= (nCode
== KEY_RIGHT
);
1648 bool bGoHome
= (nCode
== KEY_HOME
);
1649 bool bGoEnd
= (nCode
== KEY_END
);
1653 case com::sun::star::awt::Key::MOVE_WORD_FORWARD
:
1654 bGoRight
= bWord
= true;break;
1655 case com::sun::star::awt::Key::SELECT_WORD_FORWARD
:
1656 bGoRight
= bSelect
= bWord
= true;break;
1657 case com::sun::star::awt::Key::MOVE_WORD_BACKWARD
:
1658 bGoLeft
= bWord
= true;break;
1659 case com::sun::star::awt::Key::SELECT_WORD_BACKWARD
:
1660 bGoLeft
= bSelect
= bWord
= true;break;
1661 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE
:
1662 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH
:
1663 case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT
:
1665 // fallthrough intended
1666 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE
:
1667 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH
:
1668 case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT
:
1669 bGoHome
= true;break;
1670 case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE
:
1671 case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH
:
1672 case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT
:
1674 // fallthrough intended
1675 case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE
:
1676 case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH
:
1677 case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT
:
1678 bGoEnd
= true;break;
1683 // Range wird in ImplSetSelection geprueft...
1684 if ( bGoLeft
&& aSel
.Max() )
1688 i18n::Boundary aBoundary
= xBI
->getWordBoundary( maText
, aSel
.Max(), GetSettings().GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES
, sal_True
);
1689 if ( aBoundary
.startPos
== aSel
.Max() )
1690 aBoundary
= xBI
->previousWord( maText
, aSel
.Max(), GetSettings().GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES
);
1691 aSel
.Max() = aBoundary
.startPos
;
1695 sal_Int32 nCount
= 1;
1696 aSel
.Max() = xBI
->previousCharacters( maText
, aSel
.Max(), GetSettings().GetLocale(), i18n::CharacterIteratorMode::SKIPCHARACTER
, nCount
, nCount
);
1699 else if ( bGoRight
&& ( aSel
.Max() < maText
.Len() ) )
1703 i18n::Boundary aBoundary
= xBI
->nextWord( maText
, aSel
.Max(), GetSettings().GetLocale(), i18n::WordType::ANYWORD_IGNOREWHITESPACES
);
1704 aSel
.Max() = aBoundary
.startPos
;
1708 sal_Int32 nCount
= 1;
1709 aSel
.Max() = xBI
->nextCharacters( maText
, aSel
.Max(), GetSettings().GetLocale(), i18n::CharacterIteratorMode::SKIPCHARACTER
, nCount
, nCount
);
1718 aSel
.Max() = 0xFFFF;
1722 aSel
.Min() = aSel
.Max();
1724 if ( aSel
!= GetSelection() )
1726 ImplSetSelection( aSel
);
1727 ImplCopyToSelectionClipboard();
1730 if ( bGoEnd
&& maAutocompleteHdl
.IsSet() && !rKEvt
.GetKeyCode().GetModifier() )
1732 if ( (maSelection
.Min() == maSelection
.Max()) && (maSelection
.Min() == maText
.Len()) )
1734 meAutocompleteAction
= AUTOCOMPLETE_KEYINPUT
;
1735 maAutocompleteHdl
.Call( this );
1744 case com::sun::star::awt::Key::DELETE_WORD_BACKWARD
:
1745 case com::sun::star::awt::Key::DELETE_WORD_FORWARD
:
1746 case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE
:
1747 case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE
:
1751 if ( !mbReadOnly
&& !rKEvt
.GetKeyCode().IsMod2() )
1753 BYTE nDel
= (nCode
== KEY_DELETE
) ? EDIT_DEL_RIGHT
: EDIT_DEL_LEFT
;
1754 BYTE nMode
= rKEvt
.GetKeyCode().IsMod1() ? EDIT_DELMODE_RESTOFWORD
: EDIT_DELMODE_SIMPLE
;
1755 if ( (nMode
== EDIT_DELMODE_RESTOFWORD
) && rKEvt
.GetKeyCode().IsShift() )
1756 nMode
= EDIT_DELMODE_RESTOFCONTENT
;
1759 case com::sun::star::awt::Key::DELETE_WORD_BACKWARD
:
1760 nDel
= EDIT_DEL_LEFT
;
1761 nMode
= EDIT_DELMODE_RESTOFWORD
;
1763 case com::sun::star::awt::Key::DELETE_WORD_FORWARD
:
1764 nDel
= EDIT_DEL_RIGHT
;
1765 nMode
= EDIT_DELMODE_RESTOFWORD
;
1767 case com::sun::star::awt::Key::DELETE_TO_BEGIN_OF_LINE
:
1768 nDel
= EDIT_DEL_LEFT
;
1769 nMode
= EDIT_DELMODE_RESTOFCONTENT
;
1771 case com::sun::star::awt::Key::DELETE_TO_END_OF_LINE
:
1772 nDel
= EDIT_DEL_RIGHT
;
1773 nMode
= EDIT_DELMODE_RESTOFCONTENT
;
1777 xub_StrLen nOldLen
= maText
.Len();
1778 ImplDelete( maSelection
, nDel
, nMode
);
1779 if ( maText
.Len() != nOldLen
)
1788 if ( !mpIMEInfos
&& !mbReadOnly
&& !rKEvt
.GetKeyCode().IsMod2() )
1790 SetInsertMode( !mbInsertMode
);
1798 if ( !mbReadOnly
&& maAutocompleteHdl
.IsSet() &&
1799 maSelection
.Min() && (maSelection
.Min() == maText
.Len()) &&
1800 !rKEvt
.GetKeyCode().IsMod1() && !rKEvt
.GetKeyCode().IsMod2() )
1802 // Kein Autocomplete wenn alles Selektiert oder Edit leer, weil dann
1803 // keine vernuenftige Tab-Steuerung!
1804 if ( rKEvt
.GetKeyCode().IsShift() )
1805 meAutocompleteAction
= AUTOCOMPLETE_TABBACKWARD
;
1807 meAutocompleteAction
= AUTOCOMPLETE_TABFORWARD
;
1809 maAutocompleteHdl
.Call( this );
1811 // Wurde nichts veraendert, dann TAB fuer DialogControl
1812 if ( GetSelection().Len() )
1820 if ( IsCharInput( rKEvt
) )
1822 bDone
= TRUE
; // Auch bei ReadOnly die Zeichen schlucken.
1825 ImplInsertText( rKEvt
.GetCharCode(), 0, sal_True
);
1826 if ( maAutocompleteHdl
.IsSet() )
1828 if ( (maSelection
.Min() == maSelection
.Max()) && (maSelection
.Min() == maText
.Len()) )
1830 meAutocompleteAction
= AUTOCOMPLETE_KEYINPUT
;
1831 maAutocompleteHdl
.Call( this );
1840 if ( mbInternModified
)
1846 // -----------------------------------------------------------------------
1848 void Edit::KeyInput( const KeyEvent
& rKEvt
)
1850 if ( mpUpdateDataTimer
&& !mbIsSubEdit
&& mpUpdateDataTimer
->IsActive() )
1851 mpUpdateDataTimer
->Start();//do not update while the user is still travelling in the control
1853 if ( mpSubEdit
|| !ImplHandleKeyEvent( rKEvt
) )
1854 Control::KeyInput( rKEvt
);
1857 // -----------------------------------------------------------------------
1859 void Edit::FillLayoutData() const
1861 mpLayoutData
= new vcl::ControlLayoutData();
1862 const_cast<Edit
*>(this)->ImplRepaint( 0, STRING_LEN
, true );
1865 // -----------------------------------------------------------------------
1867 void Edit::Paint( const Rectangle
& )
1873 // -----------------------------------------------------------------------
1877 if ( !mpSubEdit
&& IsReallyVisible() )
1880 // Wegen vertikaler Zentrierung...
1888 // -----------------------------------------------------------------------
1890 void Edit::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
, ULONG nFlags
)
1892 ImplInitSettings( TRUE
, TRUE
, TRUE
);
1894 Point aPos
= pDev
->LogicToPixel( rPos
);
1895 Size aSize
= pDev
->LogicToPixel( rSize
);
1896 Font aFont
= GetDrawPixelFont( pDev
);
1897 OutDevType eOutDevType
= pDev
->GetOutDevType();
1901 pDev
->SetFont( aFont
);
1902 pDev
->SetTextFillColor();
1904 // Border/Background
1905 pDev
->SetLineColor();
1906 pDev
->SetFillColor();
1907 BOOL bBorder
= !(nFlags
& WINDOW_DRAW_NOBORDER
) && (GetStyle() & WB_BORDER
);
1908 BOOL bBackground
= !(nFlags
& WINDOW_DRAW_NOBACKGROUND
) && IsControlBackground();
1909 if ( bBorder
|| bBackground
)
1911 Rectangle
aRect( aPos
, aSize
);
1914 ImplDrawFrame( pDev
, aRect
);
1918 pDev
->SetFillColor( GetControlBackground() );
1919 pDev
->DrawRect( aRect
);
1924 if ( ( nFlags
& WINDOW_DRAW_MONO
) || ( eOutDevType
== OUTDEV_PRINTER
) )
1925 pDev
->SetTextColor( Color( COL_BLACK
) );
1928 if ( !(nFlags
& WINDOW_DRAW_NODISABLE
) && !IsEnabled() )
1930 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1931 pDev
->SetTextColor( rStyleSettings
.GetDisableColor() );
1935 pDev
->SetTextColor( GetTextColor() );
1939 XubString aText
= ImplGetText();
1940 long nTextHeight
= pDev
->GetTextHeight();
1941 long nTextWidth
= pDev
->GetTextWidth( aText
);
1942 long nOnePixel
= GetDrawPixel( pDev
, 1 );
1943 long nOffX
= 3*nOnePixel
;
1944 long nOffY
= (aSize
.Height() - nTextHeight
) / 2;
1948 ((nOffY
+nTextHeight
) > aSize
.Height()) ||
1949 ((nOffX
+nTextWidth
) > aSize
.Width()) )
1951 Rectangle
aClip( aPos
, aSize
);
1952 if ( nTextHeight
> aSize
.Height() )
1953 aClip
.Bottom() += nTextHeight
-aSize
.Height()+1; // Damit HP-Drucker nicht 'weg-optimieren'
1954 pDev
->IntersectClipRegion( aClip
);
1957 if ( GetStyle() & WB_CENTER
)
1959 aPos
.X() += (aSize
.Width() - nTextWidth
) / 2;
1962 else if ( GetStyle() & WB_RIGHT
)
1964 aPos
.X() += aSize
.Width() - nTextWidth
;
1968 pDev
->DrawText( Point( aPos
.X() + nOffX
, aPos
.Y() + nOffY
), aText
);
1973 GetSubEdit()->Draw( pDev
, rPos
, rSize
, nFlags
);
1977 // -----------------------------------------------------------------------
1979 void Edit::ImplInvalidateOutermostBorder( Window
* pWin
)
1981 // allow control to show focused state
1982 Window
*pInvalWin
= pWin
, *pBorder
= pWin
;
1983 while( ( pBorder
= pInvalWin
->GetWindow( WINDOW_BORDER
) ) != pInvalWin
&& pBorder
&&
1984 pInvalWin
->ImplGetFrame() == pBorder
->ImplGetFrame() )
1986 pInvalWin
= pBorder
;
1989 pInvalWin
->Invalidate( INVALIDATE_CHILDREN
| INVALIDATE_UPDATE
);
1992 void Edit::GetFocus()
1995 mpSubEdit
->ImplGrabFocus( GetGetFocusFlags() );
1996 else if ( !mbActivePopup
)
1998 maUndoText
= maText
;
2000 ULONG nSelOptions
= GetSettings().GetStyleSettings().GetSelectionOptions();
2001 if ( !( GetStyle() & (WB_NOHIDESELECTION
|WB_READONLY
) )
2002 && ( GetGetFocusFlags() & (GETFOCUS_INIT
|GETFOCUS_TAB
|GETFOCUS_CURSOR
|GETFOCUS_MNEMONIC
) ) )
2004 if ( nSelOptions
& SELECTION_OPTION_SHOWFIRST
)
2006 maSelection
.Min() = maText
.Len();
2007 maSelection
.Max() = 0;
2011 maSelection
.Min() = 0;
2012 maSelection
.Max() = maText
.Len();
2015 ((Edit
*)GetParent())->ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED
);
2017 ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED
);
2022 // FIXME: this is currently only on aqua
2023 // check for other platforms that need similar handling
2024 if( ImplGetSVData()->maNWFData
.mbNoFocusRects
&&
2025 IsNativeWidgetEnabled() &&
2026 IsNativeControlSupported( CTRL_EDITBOX
, PART_ENTIRE_CONTROL
) )
2028 ImplInvalidateOutermostBorder( mbIsSubEdit
? GetParent() : this );
2030 else if ( maSelection
.Len() )
2033 if ( !HasPaintEvent() )
2034 ImplInvalidateOrRepaint();
2039 SetInputContext( InputContext( GetFont(), !IsReadOnly() ? INPUTCONTEXT_TEXT
|INPUTCONTEXT_EXTTEXTINPUT
: 0 ) );
2042 Control::GetFocus();
2045 // -----------------------------------------------------------------------
2047 Window
* Edit::GetPreferredKeyInputWindow()
2050 return mpSubEdit
->GetPreferredKeyInputWindow();
2055 // -----------------------------------------------------------------------
2057 void Edit::LoseFocus()
2059 if ( mpUpdateDataTimer
&& !mbIsSubEdit
&& mpUpdateDataTimer
->IsActive() )
2061 //notify an update latest when the focus is lost
2062 mpUpdateDataTimer
->Stop();
2063 mpUpdateDataTimer
->Timeout();
2068 // FIXME: this is currently only on aqua
2069 // check for other platforms that need similar handling
2070 if( ImplGetSVData()->maNWFData
.mbNoFocusRects
&&
2071 IsNativeWidgetEnabled() &&
2072 IsNativeControlSupported( CTRL_EDITBOX
, PART_ENTIRE_CONTROL
) )
2074 ImplInvalidateOutermostBorder( mbIsSubEdit
? GetParent() : this );
2077 if ( !mbActivePopup
&& !( GetStyle() & WB_NOHIDESELECTION
) && maSelection
.Len() )
2078 ImplInvalidateOrRepaint(); // Selektion malen
2081 Control::LoseFocus();
2084 // -----------------------------------------------------------------------
2086 void Edit::Command( const CommandEvent
& rCEvt
)
2088 if ( rCEvt
.GetCommand() == COMMAND_CONTEXTMENU
)
2090 PopupMenu
* pPopup
= Edit::CreatePopupMenu();
2091 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
2092 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_HIDEDISABLED
)
2093 pPopup
->SetMenuFlags( MENU_FLAG_HIDEDISABLEDENTRIES
);
2095 if ( !maSelection
.Len() )
2097 pPopup
->EnableItem( SV_MENU_EDIT_CUT
, FALSE
);
2098 pPopup
->EnableItem( SV_MENU_EDIT_COPY
, FALSE
);
2099 pPopup
->EnableItem( SV_MENU_EDIT_DELETE
, FALSE
);
2104 pPopup
->EnableItem( SV_MENU_EDIT_CUT
, FALSE
);
2105 pPopup
->EnableItem( SV_MENU_EDIT_PASTE
, FALSE
);
2106 pPopup
->EnableItem( SV_MENU_EDIT_DELETE
, FALSE
);
2107 pPopup
->EnableItem( SV_MENU_EDIT_INSERTSYMBOL
, FALSE
);
2111 // Paste nur, wenn Text im Clipboard
2113 uno::Reference
< datatransfer::clipboard::XClipboard
> xClipboard
= GetClipboard();
2114 if ( xClipboard
.is() )
2116 const sal_uInt32 nRef
= Application::ReleaseSolarMutex();
2117 uno::Reference
< datatransfer::XTransferable
> xDataObj
= xClipboard
->getContents();
2118 Application::AcquireSolarMutex( nRef
);
2119 if ( xDataObj
.is() )
2121 datatransfer::DataFlavor aFlavor
;
2122 SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING
, aFlavor
);
2123 bData
= xDataObj
->isDataFlavorSupported( aFlavor
);
2126 pPopup
->EnableItem( SV_MENU_EDIT_PASTE
, bData
);
2129 if ( maUndoText
== maText
)
2130 pPopup
->EnableItem( SV_MENU_EDIT_UNDO
, FALSE
);
2131 if ( ( maSelection
.Min() == 0 ) && ( maSelection
.Max() == maText
.Len() ) )
2132 pPopup
->EnableItem( SV_MENU_EDIT_SELECTALL
, FALSE
);
2133 if ( !pImplFncGetSpecialChars
)
2135 USHORT nPos
= pPopup
->GetItemPos( SV_MENU_EDIT_INSERTSYMBOL
);
2136 pPopup
->RemoveItem( nPos
);
2137 pPopup
->RemoveItem( nPos
-1 );
2140 mbActivePopup
= TRUE
;
2141 Selection aSaveSel
= GetSelection(); // Falls jemand in Get/LoseFocus die Selektion verbiegt, z.B. URL-Zeile...
2142 Point aPos
= rCEvt
.GetMousePosPixel();
2143 if ( !rCEvt
.IsMouseEvent() )
2145 // !!! Irgendwann einmal Menu zentriert in der Selektion anzeigen !!!
2146 Size aSize
= GetOutputSizePixel();
2147 aPos
= Point( aSize
.Width()/2, aSize
.Height()/2 );
2149 USHORT n
= pPopup
->Execute( this, aPos
);
2150 Edit::DeletePopupMenu( pPopup
);
2151 SetSelection( aSaveSel
);
2154 case SV_MENU_EDIT_UNDO
:
2158 case SV_MENU_EDIT_CUT
:
2162 case SV_MENU_EDIT_COPY
:
2165 case SV_MENU_EDIT_PASTE
:
2169 case SV_MENU_EDIT_DELETE
:
2173 case SV_MENU_EDIT_SELECTALL
:
2174 ImplSetSelection( Selection( 0, maText
.Len() ) );
2176 case SV_MENU_EDIT_INSERTSYMBOL
:
2178 XubString aChars
= pImplFncGetSpecialChars( this, GetFont() );
2179 SetSelection( aSaveSel
);
2182 ImplInsertText( aChars
);
2188 mbActivePopup
= FALSE
;
2190 else if ( rCEvt
.GetCommand() == COMMAND_VOICE
)
2192 const CommandVoiceData
* pData
= rCEvt
.GetVoiceData();
2193 if ( pData
->GetType() == VOICECOMMANDTYPE_DICTATION
)
2195 switch ( pData
->GetCommand() )
2197 case DICTATIONCOMMAND_UNKNOWN
:
2199 ReplaceSelected( pData
->GetText() );
2202 case DICTATIONCOMMAND_LEFT
:
2204 ImplHandleKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT
, KEY_MOD1
) ) );
2207 case DICTATIONCOMMAND_RIGHT
:
2209 ImplHandleKeyEvent( KeyEvent( 0, KeyCode( KEY_RIGHT
, KEY_MOD1
) ) );
2212 case DICTATIONCOMMAND_UNDO
:
2217 case DICTATIONCOMMAND_DEL
:
2219 ImplHandleKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT
, KEY_MOD1
|KEY_SHIFT
) ) );
2226 else if ( rCEvt
.GetCommand() == COMMAND_STARTEXTTEXTINPUT
)
2230 xub_StrLen nPos
= (xub_StrLen
)maSelection
.Max();
2231 mpIMEInfos
= new Impl_IMEInfos( nPos
, maText
.Copy( nPos
) );
2232 mpIMEInfos
->bWasCursorOverwrite
= !IsInsertMode();
2234 else if ( rCEvt
.GetCommand() == COMMAND_ENDEXTTEXTINPUT
)
2236 BOOL bInsertMode
= !mpIMEInfos
->bWasCursorOverwrite
;
2239 // Font wieder ohne Attribute einstellen, wird jetzt im Repaint nicht
2240 // mehr neu initialisiert
2241 ImplInitSettings( TRUE
, FALSE
, FALSE
);
2243 SetInsertMode( bInsertMode
);
2247 // #i25161# call auto complete handler for ext text commit also
2248 if ( maAutocompleteHdl
.IsSet() )
2250 if ( (maSelection
.Min() == maSelection
.Max()) && (maSelection
.Min() == maText
.Len()) )
2252 meAutocompleteAction
= AUTOCOMPLETE_KEYINPUT
;
2253 maAutocompleteHdl
.Call( this );
2257 else if ( rCEvt
.GetCommand() == COMMAND_EXTTEXTINPUT
)
2259 const CommandExtTextInputData
* pData
= rCEvt
.GetExtTextInputData();
2261 maText
.Erase( mpIMEInfos
->nPos
, mpIMEInfos
->nLen
);
2262 maText
.Insert( pData
->GetText(), mpIMEInfos
->nPos
);
2263 if ( mpIMEInfos
->bWasCursorOverwrite
)
2265 USHORT nOldIMETextLen
= mpIMEInfos
->nLen
;
2266 USHORT nNewIMETextLen
= pData
->GetText().Len();
2267 if ( ( nOldIMETextLen
> nNewIMETextLen
) &&
2268 ( nNewIMETextLen
< mpIMEInfos
->aOldTextAfterStartPos
.Len() ) )
2270 // restore old characters
2271 USHORT nRestore
= nOldIMETextLen
- nNewIMETextLen
;
2272 maText
.Insert( mpIMEInfos
->aOldTextAfterStartPos
.Copy( nNewIMETextLen
, nRestore
), mpIMEInfos
->nPos
+ nNewIMETextLen
);
2274 else if ( ( nOldIMETextLen
< nNewIMETextLen
) &&
2275 ( nOldIMETextLen
< mpIMEInfos
->aOldTextAfterStartPos
.Len() ) )
2278 USHORT nOverwrite
= nNewIMETextLen
- nOldIMETextLen
;
2279 if ( ( nOldIMETextLen
+ nOverwrite
) > mpIMEInfos
->aOldTextAfterStartPos
.Len() )
2280 nOverwrite
= mpIMEInfos
->aOldTextAfterStartPos
.Len() - nOldIMETextLen
;
2281 maText
.Erase( mpIMEInfos
->nPos
+ nNewIMETextLen
, nOverwrite
);
2286 if ( pData
->GetTextAttr() )
2288 mpIMEInfos
->CopyAttribs( pData
->GetTextAttr(), pData
->GetText().Len() );
2289 mpIMEInfos
->bCursor
= pData
->IsCursorVisible();
2293 mpIMEInfos
->DestroyAttribs();
2296 ImplAlignAndPaint();
2297 xub_StrLen nCursorPos
= mpIMEInfos
->nPos
+ pData
->GetCursorPos();
2298 SetSelection( Selection( nCursorPos
, nCursorPos
) );
2299 SetInsertMode( !pData
->IsCursorOverwrite() );
2301 if ( pData
->IsCursorVisible() )
2302 GetCursor()->Show();
2304 GetCursor()->Hide();
2306 else if ( rCEvt
.GetCommand() == COMMAND_CURSORPOS
)
2310 xub_StrLen nCursorPos
= (USHORT
)GetSelection().Max();
2311 SetCursorRect( NULL
, GetTextWidth(
2312 maText
, nCursorPos
, mpIMEInfos
->nPos
+mpIMEInfos
->nLen
-nCursorPos
) );
2319 else if ( rCEvt
.GetCommand() == COMMAND_SELECTIONCHANGE
)
2321 const CommandSelectionChangeData
*pData
= rCEvt
.GetSelectionChangeData();
2322 Selection
aSelection( pData
->GetStart(), pData
->GetEnd() );
2323 SetSelection(aSelection
);
2326 Control::Command( rCEvt
);
2329 // -----------------------------------------------------------------------
2331 void Edit::StateChanged( StateChangedType nType
)
2333 if ( nType
== STATE_CHANGE_INITSHOW
)
2337 mnXOffset
= 0; // Falls vorher GrabFocus, als Groesse noch falsch.
2340 ImplShowCursor( FALSE
);
2342 // update background (eventual SetPaintTransparent)
2343 ImplInitSettings( FALSE
, FALSE
, TRUE
);
2345 else if ( nType
== STATE_CHANGE_ENABLE
)
2349 // Es aendert sich nur die Textfarbe...
2350 ImplInvalidateOrRepaint( 0, 0xFFFF );
2353 else if ( nType
== STATE_CHANGE_STYLE
|| nType
== STATE_CHANGE_MIRRORING
)
2355 WinBits nStyle
= GetStyle();
2356 if( nType
== STATE_CHANGE_STYLE
)
2358 nStyle
= ImplInitStyle( GetStyle() );
2362 USHORT nOldAlign
= mnAlign
;
2363 mnAlign
= EDIT_ALIGN_LEFT
;
2365 // --- RTL --- hack: right align until keyinput and cursor travelling works
2366 // edits are always RTL disabled
2367 // however the parent edits contain the correct setting
2368 if( mbIsSubEdit
&& GetParent()->IsRTLEnabled() )
2370 if( GetParent()->GetStyle() & WB_LEFT
)
2371 mnAlign
= EDIT_ALIGN_RIGHT
;
2372 if ( nType
== STATE_CHANGE_MIRRORING
)
2373 SetLayoutMode( TEXT_LAYOUT_BIDI_RTL
| TEXT_LAYOUT_TEXTORIGIN_LEFT
);
2375 else if( mbIsSubEdit
&& !GetParent()->IsRTLEnabled() )
2377 if ( nType
== STATE_CHANGE_MIRRORING
)
2378 SetLayoutMode( TEXT_LAYOUT_BIDI_LTR
| TEXT_LAYOUT_TEXTORIGIN_LEFT
);
2381 if ( nStyle
& WB_RIGHT
)
2382 mnAlign
= EDIT_ALIGN_RIGHT
;
2383 else if ( nStyle
& WB_CENTER
)
2384 mnAlign
= EDIT_ALIGN_CENTER
;
2385 if ( maText
.Len() && ( mnAlign
!= nOldAlign
) )
2392 else if ( nType
== STATE_CHANGE_ZOOM
)
2396 ImplInitSettings( TRUE
, FALSE
, FALSE
);
2397 ImplShowCursor( TRUE
);
2401 else if ( nType
== STATE_CHANGE_CONTROLFONT
)
2405 ImplInitSettings( TRUE
, FALSE
, FALSE
);
2410 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
2414 ImplInitSettings( FALSE
, TRUE
, FALSE
);
2418 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
2422 ImplInitSettings( FALSE
, FALSE
, TRUE
);
2427 Control::StateChanged( nType
);
2430 // -----------------------------------------------------------------------
2432 void Edit::DataChanged( const DataChangedEvent
& rDCEvt
)
2434 if ( (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
2435 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
2436 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
2437 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
2441 ImplInitSettings( TRUE
, TRUE
, TRUE
);
2442 ImplShowCursor( TRUE
);
2447 Control::DataChanged( rDCEvt
);
2450 // -----------------------------------------------------------------------
2452 void Edit::ImplShowDDCursor()
2454 if ( !mpDDInfo
->bVisCursor
)
2456 long nTextWidth
= GetTextWidth( maText
, 0, mpDDInfo
->nDropPos
);
2457 long nTextHeight
= GetTextHeight();
2458 Rectangle
aCursorRect( Point( nTextWidth
+ mnXOffset
, (GetOutputSize().Height()-nTextHeight
)/2 ), Size( 2, nTextHeight
) );
2459 mpDDInfo
->aCursor
.SetWindow( this );
2460 mpDDInfo
->aCursor
.SetPos( aCursorRect
.TopLeft() );
2461 mpDDInfo
->aCursor
.SetSize( aCursorRect
.GetSize() );
2462 mpDDInfo
->aCursor
.Show();
2463 mpDDInfo
->bVisCursor
= TRUE
;
2467 // -----------------------------------------------------------------------
2469 void Edit::ImplHideDDCursor()
2471 if ( mpDDInfo
&& mpDDInfo
->bVisCursor
)
2473 mpDDInfo
->aCursor
.Hide();
2474 mpDDInfo
->bVisCursor
= FALSE
;
2478 // -----------------------------------------------------------------------
2484 ((Edit
*)GetParent())->Modify();
2488 if ( mpUpdateDataTimer
)
2489 mpUpdateDataTimer
->Start();
2491 if ( ImplCallEventListenersAndHandler( VCLEVENT_EDIT_MODIFY
, maModifyHdl
, this ) )
2492 // have been destroyed while calling into the handlers
2495 // #i13677# notify edit listeners about caret position change
2496 ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED
);
2498 // FIXME: this is currently only on aqua
2499 // check for other platforms that need similar handling
2500 if( ImplGetSVData()->maNWFData
.mbNoFocusRects
&&
2501 IsNativeWidgetEnabled() &&
2502 IsNativeControlSupported( CTRL_EDITBOX
, PART_ENTIRE_CONTROL
) )
2504 ImplInvalidateOutermostBorder( this );
2509 // -----------------------------------------------------------------------
2511 void Edit::UpdateData()
2513 maUpdateDataHdl
.Call( this );
2516 // -----------------------------------------------------------------------
2518 IMPL_LINK( Edit
, ImplUpdateDataHdl
, Timer
*, EMPTYARG
)
2524 // -----------------------------------------------------------------------
2526 void Edit::EnableUpdateData( ULONG nTimeout
)
2529 DisableUpdateData();
2532 if ( !mpUpdateDataTimer
)
2534 mpUpdateDataTimer
= new Timer
;
2535 mpUpdateDataTimer
->SetTimeoutHdl( LINK( this, Edit
, ImplUpdateDataHdl
) );
2538 mpUpdateDataTimer
->SetTimeout( nTimeout
);
2542 // -----------------------------------------------------------------------
2544 void Edit::SetEchoChar( xub_Unicode c
)
2548 mpSubEdit
->SetEchoChar( c
);
2551 // -----------------------------------------------------------------------
2553 void Edit::SetReadOnly( BOOL bReadOnly
)
2555 if ( mbReadOnly
!= bReadOnly
)
2557 mbReadOnly
= bReadOnly
;
2559 mpSubEdit
->SetReadOnly( bReadOnly
);
2561 StateChanged( STATE_CHANGE_READONLY
);
2565 // -----------------------------------------------------------------------
2567 void Edit::SetAutocompleteHdl( const Link
& rHdl
)
2569 maAutocompleteHdl
= rHdl
;
2571 mpSubEdit
->SetAutocompleteHdl( rHdl
);
2574 // -----------------------------------------------------------------------
2576 void Edit::SetInsertMode( BOOL bInsert
)
2578 if ( bInsert
!= mbInsertMode
)
2580 mbInsertMode
= bInsert
;
2582 mpSubEdit
->SetInsertMode( bInsert
);
2588 // -----------------------------------------------------------------------
2590 BOOL
Edit::IsInsertMode() const
2593 return mpSubEdit
->IsInsertMode();
2595 return mbInsertMode
;
2598 // -----------------------------------------------------------------------
2600 void Edit::SetMaxTextLen( xub_StrLen nMaxLen
)
2602 mnMaxTextLen
= nMaxLen
? nMaxLen
: EDIT_NOLIMIT
;
2605 mpSubEdit
->SetMaxTextLen( mnMaxTextLen
);
2608 if ( maText
.Len() > mnMaxTextLen
)
2609 ImplDelete( Selection( mnMaxTextLen
, maText
.Len() ), EDIT_DEL_RIGHT
, EDIT_DELMODE_SIMPLE
);
2613 // -----------------------------------------------------------------------
2615 void Edit::SetSelection( const Selection
& rSelection
)
2617 // Wenn von aussen z.B. im MouseButtonDown die Selektion geaendert wird,
2618 // soll nicht gleich ein Tracking() zuschlagen und die Selektion aendern.
2621 else if ( mpSubEdit
&& mpSubEdit
->IsTracking() )
2622 mpSubEdit
->EndTracking();
2624 ImplSetSelection( rSelection
);
2627 // -----------------------------------------------------------------------
2629 void Edit::ImplSetSelection( const Selection
& rSelection
, BOOL bPaint
)
2632 mpSubEdit
->ImplSetSelection( rSelection
);
2635 if ( rSelection
!= maSelection
)
2637 Selection
aOld( maSelection
);
2638 Selection
aNew( rSelection
);
2640 if ( aNew
.Min() > maText
.Len() )
2641 aNew
.Min() = maText
.Len();
2642 if ( aNew
.Max() > maText
.Len() )
2643 aNew
.Max() = maText
.Len();
2644 if ( aNew
.Min() < 0 )
2646 if ( aNew
.Max() < 0 )
2649 if ( aNew
!= maSelection
)
2651 delete mpLayoutData
, mpLayoutData
= NULL
;
2654 if ( bPaint
&& ( aOld
.Len() || aNew
.Len() || IsPaintTransparent() ) )
2655 ImplInvalidateOrRepaint( 0, maText
.Len() );
2658 ((Edit
*)GetParent())->ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED
);
2660 ImplCallEventListeners( VCLEVENT_EDIT_SELECTIONCHANGED
);
2661 // #103511# notify combobox listeners of deselection
2662 if( !maSelection
&& GetParent() && GetParent()->GetType() == WINDOW_COMBOBOX
)
2663 ((Edit
*)GetParent())->ImplCallEventListeners( VCLEVENT_COMBOBOX_DESELECT
);
2669 // -----------------------------------------------------------------------
2671 const Selection
& Edit::GetSelection() const
2674 return mpSubEdit
->GetSelection();
2679 // -----------------------------------------------------------------------
2681 void Edit::ReplaceSelected( const XubString
& rStr
)
2684 mpSubEdit
->ReplaceSelected( rStr
);
2686 ImplInsertText( rStr
);
2689 // -----------------------------------------------------------------------
2691 void Edit::DeleteSelected()
2694 mpSubEdit
->DeleteSelected();
2697 if ( maSelection
.Len() )
2698 ImplDelete( maSelection
, EDIT_DEL_RIGHT
, EDIT_DELMODE_SIMPLE
);
2702 // -----------------------------------------------------------------------
2704 XubString
Edit::GetSelected() const
2707 return mpSubEdit
->GetSelected();
2710 Selection
aSelection( maSelection
);
2711 aSelection
.Justify();
2712 return maText
.Copy( (xub_StrLen
)aSelection
.Min(), (xub_StrLen
)aSelection
.Len() );
2716 // -----------------------------------------------------------------------
2720 if ( !(GetStyle() & WB_PASSWORD
) )
2723 ReplaceSelected( ImplGetSVEmptyStr() );
2727 // -----------------------------------------------------------------------
2731 if ( !(GetStyle() & WB_PASSWORD
) )
2733 ::com::sun::star::uno::Reference
<com::sun::star::datatransfer::clipboard::XClipboard
> aClipboard(GetClipboard());
2734 ImplCopy( aClipboard
);
2738 // -----------------------------------------------------------------------
2742 ::com::sun::star::uno::Reference
<com::sun::star::datatransfer::clipboard::XClipboard
> aClipboard(GetClipboard());
2743 ImplPaste( aClipboard
);
2746 // -----------------------------------------------------------------------
2754 XubString
aText( maText
);
2755 ImplDelete( Selection( 0, aText
.Len() ), EDIT_DEL_RIGHT
, EDIT_DELMODE_SIMPLE
);
2756 ImplInsertText( maUndoText
);
2757 ImplSetSelection( Selection( 0, maUndoText
.Len() ) );
2762 // -----------------------------------------------------------------------
2764 void Edit::SetText( const XubString
& rStr
)
2767 mpSubEdit
->SetText( rStr
); // Nicht direkt ImplSetText, falls SetText ueberladen
2770 Selection
aNewSel( 0, 0 ); // Damit nicht gescrollt wird
2771 ImplSetText( rStr
, &aNewSel
);
2775 // -----------------------------------------------------------------------
2777 void Edit::SetText( const XubString
& rStr
, const Selection
& rSelection
)
2780 mpSubEdit
->SetText( rStr
, rSelection
);
2782 ImplSetText( rStr
, &rSelection
);
2785 // -----------------------------------------------------------------------
2787 XubString
Edit::GetText() const
2790 return mpSubEdit
->GetText();
2795 // -----------------------------------------------------------------------
2797 void Edit::SetModifyFlag()
2800 mpSubEdit
->mbModified
= TRUE
;
2805 // -----------------------------------------------------------------------
2807 void Edit::ClearModifyFlag()
2810 mpSubEdit
->mbModified
= FALSE
;
2815 // -----------------------------------------------------------------------
2817 void Edit::SetSubEdit( Edit
* pEdit
)
2822 SetPointer( POINTER_ARROW
); // Nur das SubEdit hat den BEAM...
2823 mpSubEdit
->mbIsSubEdit
= TRUE
;
2825 mpSubEdit
->SetReadOnly( mbReadOnly
);
2829 // -----------------------------------------------------------------------
2831 Size
Edit::CalcMinimumSize() const
2833 Size
aSize ( GetTextWidth( GetText() ), GetTextHeight() );
2834 return CalcWindowSize( aSize
);
2837 // -----------------------------------------------------------------------
2839 Size
Edit::GetOptimalSize(WindowSizeType eType
) const
2842 case WINDOWSIZE_MINIMUM
:
2843 return CalcMinimumSize();
2845 return Control::GetOptimalSize( eType
);
2849 // -----------------------------------------------------------------------
2851 Size
Edit::CalcSize( xub_StrLen nChars
) const
2853 // Breite fuer n Zeichen, unabhaengig vom Inhalt.
2854 // Funktioniert nur bei FixedFont richtig, sonst Mittelwert.
2855 Size
aSz( GetTextWidth( XubString( 'x' ) ), GetTextHeight() );
2856 aSz
.Width() *= nChars
;
2857 aSz
= CalcWindowSize( aSz
);
2861 // -----------------------------------------------------------------------
2863 xub_StrLen
Edit::GetMaxVisChars() const
2865 const Window
* pW
= mpSubEdit
? mpSubEdit
: this;
2866 long nOutWidth
= pW
->GetOutputSizePixel().Width();
2867 long nCharWidth
= GetTextWidth( XubString( 'x' ) );
2868 return nCharWidth
? (xub_StrLen
)(nOutWidth
/nCharWidth
) : 0;
2871 // -----------------------------------------------------------------------
2873 xub_StrLen
Edit::GetCharPos( const Point
& rWindowPos
) const
2875 return ImplGetCharPos( rWindowPos
);
2878 // -----------------------------------------------------------------------
2880 void Edit::SetGetSpecialCharsFunction( FncGetSpecialChars fn
)
2882 pImplFncGetSpecialChars
= fn
;
2885 // -----------------------------------------------------------------------
2887 FncGetSpecialChars
Edit::GetGetSpecialCharsFunction()
2889 return pImplFncGetSpecialChars
;
2892 // -----------------------------------------------------------------------
2894 PopupMenu
* Edit::CreatePopupMenu()
2896 ResMgr
* pResMgr
= ImplGetResMgr();
2898 return new PopupMenu();
2900 PopupMenu
* pPopup
= new PopupMenu( ResId( SV_RESID_MENU_EDIT
, *pResMgr
) );
2901 pPopup
->SetAccelKey( SV_MENU_EDIT_UNDO
, KeyCode( KEYFUNC_UNDO
) );
2902 pPopup
->SetAccelKey( SV_MENU_EDIT_CUT
, KeyCode( KEYFUNC_CUT
) );
2903 pPopup
->SetAccelKey( SV_MENU_EDIT_COPY
, KeyCode( KEYFUNC_COPY
) );
2904 pPopup
->SetAccelKey( SV_MENU_EDIT_PASTE
, KeyCode( KEYFUNC_PASTE
) );
2905 pPopup
->SetAccelKey( SV_MENU_EDIT_DELETE
, KeyCode( KEYFUNC_DELETE
) );
2906 pPopup
->SetAccelKey( SV_MENU_EDIT_SELECTALL
, KeyCode( KEY_A
, FALSE
, TRUE
, FALSE
, FALSE
) );
2907 pPopup
->SetAccelKey( SV_MENU_EDIT_INSERTSYMBOL
, KeyCode( KEY_S
, TRUE
, TRUE
, FALSE
, FALSE
) );
2911 // -----------------------------------------------------------------------
2913 void Edit::DeletePopupMenu( PopupMenu
* pMenu
)
2918 // ::com::sun::star::datatransfer::dnd::XDragGestureListener
2919 void Edit::dragGestureRecognized( const ::com::sun::star::datatransfer::dnd::DragGestureEvent
& rDGE
) throw (::com::sun::star::uno::RuntimeException
)
2921 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
2923 if ( !IsTracking() && maSelection
.Len() &&
2924 !(GetStyle() & WB_PASSWORD
) && (!mpDDInfo
|| mpDDInfo
->bStarterOfDD
== FALSE
) ) // Kein Mehrfach D&D
2926 Selection
aSel( maSelection
);
2929 // Nur wenn Maus in der Selektion...
2930 Point
aMousePos( rDGE
.DragOriginX
, rDGE
.DragOriginY
);
2931 xub_StrLen nChar
= ImplGetCharPos( aMousePos
);
2932 if ( (nChar
>= aSel
.Min()) && (nChar
< aSel
.Max()) )
2935 mpDDInfo
= new DDInfo
;
2937 mpDDInfo
->bStarterOfDD
= TRUE
;
2938 mpDDInfo
->aDndStartSel
= aSel
;
2942 EndTracking(); // Vor D&D Tracking ausschalten
2944 ::vcl::unohelper::TextDataObject
* pDataObj
= new ::vcl::unohelper::TextDataObject( GetSelected() );
2945 sal_Int8 nActions
= datatransfer::dnd::DNDConstants::ACTION_COPY
;
2946 if ( !IsReadOnly() )
2947 nActions
|= datatransfer::dnd::DNDConstants::ACTION_MOVE
;
2948 rDGE
.DragSource
->startDrag( rDGE
, nActions
, 0 /*cursor*/, 0 /*image*/, pDataObj
, mxDnDListener
);
2950 GetCursor()->Hide();
2956 // ::com::sun::star::datatransfer::dnd::XDragSourceListener
2957 void Edit::dragDropEnd( const ::com::sun::star::datatransfer::dnd::DragSourceDropEvent
& rDSDE
) throw (::com::sun::star::uno::RuntimeException
)
2959 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
2961 if ( rDSDE
.DropSuccess
&& ( rDSDE
.DropAction
& datatransfer::dnd::DNDConstants::ACTION_MOVE
) )
2963 Selection
aSel( mpDDInfo
->aDndStartSel
);
2964 if ( mpDDInfo
->bDroppedInMe
)
2966 if ( aSel
.Max() > mpDDInfo
->nDropPos
)
2968 long nLen
= aSel
.Len();
2973 ImplDelete( aSel
, EDIT_DEL_RIGHT
, EDIT_DELMODE_SIMPLE
);
2982 // ::com::sun::star::datatransfer::dnd::XDropTargetListener
2983 void Edit::drop( const ::com::sun::star::datatransfer::dnd::DropTargetDropEvent
& rDTDE
) throw (::com::sun::star::uno::RuntimeException
)
2985 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
2987 BOOL bChanges
= FALSE
;
2988 if ( !mbReadOnly
&& mpDDInfo
)
2992 Selection
aSel( maSelection
);
2995 if ( aSel
.Len() && !mpDDInfo
->bStarterOfDD
)
2996 ImplDelete( aSel
, EDIT_DEL_RIGHT
, EDIT_DELMODE_SIMPLE
);
2998 mpDDInfo
->bDroppedInMe
= TRUE
;
3000 aSel
.Min() = mpDDInfo
->nDropPos
;
3001 aSel
.Max() = mpDDInfo
->nDropPos
;
3002 ImplSetSelection( aSel
);
3004 uno::Reference
< datatransfer::XTransferable
> xDataObj
= rDTDE
.Transferable
;
3005 if ( xDataObj
.is() )
3007 datatransfer::DataFlavor aFlavor
;
3008 SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING
, aFlavor
);
3009 if ( xDataObj
->isDataFlavorSupported( aFlavor
) )
3011 uno::Any aData
= xDataObj
->getTransferData( aFlavor
);
3012 ::rtl::OUString aText
;
3014 ImplInsertText( aText
);
3020 if ( !mpDDInfo
->bStarterOfDD
)
3027 rDTDE
.Context
->dropComplete( bChanges
);
3030 void Edit::dragEnter( const ::com::sun::star::datatransfer::dnd::DropTargetDragEnterEvent
& ) throw (::com::sun::star::uno::RuntimeException
)
3034 mpDDInfo
= new DDInfo
;
3036 // sal_Bool bTextContent = mbReadOnly ? sal_False : sal_True; // quiery from rDTDEE.SupportedDataFlavors()
3037 // if ( bTextContent )
3038 // rDTDEE.Context->acceptDrop(datatransfer::dnd::DNDConstants::ACTION_COPY_OR_MOVE);
3040 // rDTDEE.Context->rejectDrop();
3043 void Edit::dragExit( const ::com::sun::star::datatransfer::dnd::DropTargetEvent
& ) throw (::com::sun::star::uno::RuntimeException
)
3045 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
3050 void Edit::dragOver( const ::com::sun::star::datatransfer::dnd::DropTargetDragEvent
& rDTDE
) throw (::com::sun::star::uno::RuntimeException
)
3052 vos::OGuard
aVclGuard( Application::GetSolarMutex() );
3054 Point
aMousePos( rDTDE
.LocationX
, rDTDE
.LocationY
);
3056 xub_StrLen nPrevDropPos
= mpDDInfo
->nDropPos
;
3057 mpDDInfo
->nDropPos
= ImplGetCharPos( aMousePos
);
3060 Size aOutSize = GetOutputSizePixel();
3061 if ( ( aMousePos.X() < 0 ) || ( aMousePos.X() > aOutSize.Width() ) )
3064 // No, I will not receive events in this case....
3068 Selection
aSel( maSelection
);
3071 // Don't accept drop in selection or read-only field...
3072 if ( IsReadOnly() || aSel
.IsInside( mpDDInfo
->nDropPos
) )
3075 rDTDE
.Context
->rejectDrag();
3079 // Alten Cursor wegzeichnen...
3080 if ( !mpDDInfo
->bVisCursor
|| ( nPrevDropPos
!= mpDDInfo
->nDropPos
) )
3085 rDTDE
.Context
->acceptDrag( rDTDE
.DropAction
);
3089 ImplSubEdit::ImplSubEdit( Edit
* pParent
, WinBits nStyle
) :
3090 Edit( pParent
, nStyle
)
3092 pParent
->SetSubEdit( this );
3095 // -----------------------------------------------------------------------
3097 void ImplSubEdit::Modify()
3099 GetParent()->Modify();
3102 XubString
Edit::GetSurroundingText() const
3105 return mpSubEdit
->GetSurroundingText();
3110 Selection
Edit::GetSurroundingTextSelection() const
3112 return GetSelection();