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