Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <memory>
21 :
22 : #include <tools/rc.h>
23 : #include <vcl/builder.hxx>
24 : #include <vcl/decoview.hxx>
25 : #include <vcl/svapp.hxx>
26 :
27 : #include <vcl/vclmedit.hxx>
28 : #include <vcl/xtextedt.hxx>
29 : #include <svl/brdcst.hxx>
30 : #include <svl/undo.hxx>
31 : #include <svl/lstner.hxx>
32 : #include <svl/smplhint.hxx>
33 :
34 : #include <svids.hrc>
35 : #include <vcl/scrbar.hxx>
36 :
37 :
38 : class TextWindow : public Window
39 : {
40 : private:
41 : ExtTextEngine* mpExtTextEngine;
42 : ExtTextView* mpExtTextView;
43 :
44 : bool mbInMBDown;
45 : bool mbFocusSelectionHide;
46 : bool mbIgnoreTab;
47 : bool mbActivePopup;
48 : bool mbSelectOnTab;
49 : bool mbTextSelectable;
50 :
51 : public:
52 : TextWindow( Window* pParent );
53 : ~TextWindow();
54 :
55 1053 : ExtTextEngine* GetTextEngine() const { return mpExtTextEngine; }
56 493 : ExtTextView* GetTextView() const { return mpExtTextView; }
57 :
58 : virtual void MouseMove( const MouseEvent& rMEvt );
59 : virtual void MouseButtonDown( const MouseEvent& rMEvt );
60 : virtual void MouseButtonUp( const MouseEvent& rMEvt );
61 : virtual void KeyInput( const KeyEvent& rKEvent );
62 :
63 : virtual void Command( const CommandEvent& rCEvt );
64 :
65 : virtual void Paint( const Rectangle& rRect );
66 : virtual void Resize();
67 :
68 : virtual void GetFocus();
69 : virtual void LoseFocus();
70 :
71 : bool IsAutoFocusHide() const { return mbFocusSelectionHide; }
72 149 : void SetAutoFocusHide( bool bAutoHide ) { mbFocusSelectionHide = bAutoHide; }
73 :
74 : bool IsIgnoreTab() const { return mbIgnoreTab; }
75 136 : void SetIgnoreTab( bool bIgnore ) { mbIgnoreTab = bIgnore; }
76 :
77 11 : void DisableSelectionOnFocus() { mbSelectOnTab = false; }
78 :
79 0 : void SetTextSelectable( bool bTextSelectable ) { mbTextSelectable = bTextSelectable; }
80 : };
81 :
82 :
83 : class ImpVclMEdit : public SfxListener
84 : {
85 : private:
86 : VclMultiLineEdit* pVclMultiLineEdit;
87 :
88 : TextWindow* mpTextWindow;
89 : ScrollBar* mpHScrollBar;
90 : ScrollBar* mpVScrollBar;
91 : ScrollBarBox* mpScrollBox;
92 :
93 : Point maTextWindowOffset;
94 : xub_StrLen mnTextWidth;
95 : mutable Selection maSelection;
96 :
97 : protected:
98 : virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
99 : void ImpUpdateSrollBarVis( WinBits nWinStyle );
100 : void ImpInitScrollBars();
101 : void ImpSetScrollBarRanges();
102 : void ImpSetHScrollBarThumbPos();
103 : DECL_LINK( ScrollHdl, ScrollBar* );
104 :
105 : public:
106 : ImpVclMEdit( VclMultiLineEdit* pVclMultiLineEdit, WinBits nWinStyle );
107 : ~ImpVclMEdit();
108 :
109 : void SetModified( sal_Bool bMod );
110 : sal_Bool IsModified() const;
111 :
112 : void SetReadOnly( sal_Bool bRdOnly );
113 : sal_Bool IsReadOnly() const;
114 :
115 : void SetMaxTextLen( xub_StrLen nLen );
116 : xub_StrLen GetMaxTextLen() const;
117 :
118 : void SetMaxTextWidth( sal_uLong nMaxWidth );
119 :
120 : sal_Bool IsInsertMode() const;
121 :
122 : void InsertText( const String& rStr );
123 : String GetSelected() const;
124 : String GetSelected( LineEnd aSeparator ) const;
125 :
126 : void SetSelection( const Selection& rSelection );
127 : const Selection& GetSelection() const;
128 :
129 : void Cut();
130 : void Copy();
131 : void Paste();
132 :
133 : void SetText( const OUString& rStr );
134 : OUString GetText() const;
135 : String GetText( LineEnd aSeparator ) const;
136 : String GetTextLines( LineEnd aSeparator ) const;
137 :
138 : void Resize();
139 : void GetFocus();
140 :
141 : sal_Bool HandleCommand( const CommandEvent& rCEvt );
142 :
143 : void Enable( sal_Bool bEnable );
144 :
145 : Size CalcMinimumSize() const;
146 : Size CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const;
147 : void GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const;
148 :
149 : void SetAlign( WinBits nWinStyle );
150 :
151 : void InitFromStyle( WinBits nWinStyle );
152 :
153 905 : TextWindow* GetTextWindow() { return mpTextWindow; }
154 0 : ScrollBar* GetHScrollBar() { return mpHScrollBar; }
155 0 : ScrollBar* GetVScrollBar() { return mpVScrollBar; }
156 : };
157 :
158 45 : ImpVclMEdit::ImpVclMEdit( VclMultiLineEdit* pEdt, WinBits nWinStyle )
159 : :mpHScrollBar(NULL)
160 : ,mpVScrollBar(NULL)
161 45 : ,mpScrollBox(NULL)
162 : {
163 45 : pVclMultiLineEdit = pEdt;
164 45 : mnTextWidth = 0;
165 45 : mpTextWindow = new TextWindow( pEdt );
166 45 : mpTextWindow->Show();
167 45 : InitFromStyle( nWinStyle );
168 45 : StartListening( *mpTextWindow->GetTextEngine() );
169 45 : }
170 :
171 136 : void ImpVclMEdit::ImpUpdateSrollBarVis( WinBits nWinStyle )
172 : {
173 136 : const bool bHaveVScroll = (NULL != mpVScrollBar);
174 136 : const bool bHaveHScroll = (NULL != mpHScrollBar);
175 136 : const bool bHaveScrollBox = (NULL != mpScrollBox);
176 :
177 136 : bool bNeedVScroll = ( nWinStyle & WB_VSCROLL ) == WB_VSCROLL;
178 136 : const bool bNeedHScroll = ( nWinStyle & WB_HSCROLL ) == WB_HSCROLL;
179 :
180 136 : const bool bAutoVScroll = ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL;
181 136 : if ( !bNeedVScroll && bAutoVScroll )
182 : {
183 0 : TextEngine& rEngine( *mpTextWindow->GetTextEngine() );
184 0 : sal_uLong nOverallTextHeight(0);
185 0 : for ( sal_uLong i=0; i<rEngine.GetParagraphCount(); ++i )
186 0 : nOverallTextHeight += rEngine.GetTextHeight( i );
187 0 : if ( nOverallTextHeight > (sal_uLong)mpTextWindow->GetOutputSizePixel().Height() )
188 0 : bNeedVScroll = true;
189 : }
190 :
191 136 : const bool bNeedScrollBox = bNeedVScroll && bNeedHScroll;
192 :
193 136 : bool bScrollbarsChanged = false;
194 136 : if ( bHaveVScroll != bNeedVScroll )
195 : {
196 7 : delete mpVScrollBar;
197 7 : mpVScrollBar = bNeedVScroll ? new ScrollBar( pVclMultiLineEdit, WB_VSCROLL|WB_DRAG ) : NULL;
198 :
199 7 : if ( bNeedVScroll )
200 : {
201 7 : mpVScrollBar->Show();
202 7 : mpVScrollBar->SetScrollHdl( LINK( this, ImpVclMEdit, ScrollHdl ) );
203 : }
204 :
205 7 : bScrollbarsChanged = true;
206 : }
207 :
208 136 : if ( bHaveHScroll != bNeedHScroll )
209 : {
210 9 : delete mpHScrollBar;
211 9 : mpHScrollBar = bNeedHScroll ? new ScrollBar( pVclMultiLineEdit, WB_HSCROLL|WB_DRAG ) : NULL;
212 :
213 9 : if ( bNeedHScroll )
214 : {
215 9 : mpHScrollBar->Show();
216 9 : mpHScrollBar->SetScrollHdl( LINK( this, ImpVclMEdit, ScrollHdl ) );
217 : }
218 :
219 9 : bScrollbarsChanged = true;
220 : }
221 :
222 136 : if ( bHaveScrollBox != bNeedScrollBox )
223 : {
224 5 : delete mpScrollBox;
225 5 : mpScrollBox = bNeedScrollBox ? new ScrollBarBox( pVclMultiLineEdit, WB_SIZEABLE ) : NULL;
226 :
227 5 : if ( bNeedScrollBox )
228 5 : mpScrollBox->Show();
229 : }
230 :
231 136 : if ( bScrollbarsChanged )
232 : {
233 11 : ImpInitScrollBars();
234 11 : Resize();
235 : }
236 136 : }
237 :
238 136 : void ImpVclMEdit::InitFromStyle( WinBits nWinStyle )
239 : {
240 136 : ImpUpdateSrollBarVis( nWinStyle );
241 136 : SetAlign( nWinStyle );
242 :
243 136 : if ( nWinStyle & WB_NOHIDESELECTION )
244 44 : mpTextWindow->SetAutoFocusHide( sal_False );
245 : else
246 92 : mpTextWindow->SetAutoFocusHide( sal_True );
247 :
248 136 : if ( nWinStyle & WB_READONLY )
249 31 : mpTextWindow->GetTextView()->SetReadOnly( sal_True );
250 : else
251 105 : mpTextWindow->GetTextView()->SetReadOnly( sal_False );
252 :
253 136 : if ( nWinStyle & WB_IGNORETAB )
254 : {
255 68 : mpTextWindow->SetIgnoreTab( true );
256 : }
257 : else
258 : {
259 68 : mpTextWindow->SetIgnoreTab( false );
260 : // #103667# VclMultiLineEdit has the flag, but focusable window also needs this flag
261 68 : WinBits nStyle = mpTextWindow->GetStyle();
262 68 : nStyle |= WINDOW_DLGCTRL_MOD1TAB;
263 68 : mpTextWindow->SetStyle( nStyle );
264 : }
265 136 : }
266 :
267 135 : ImpVclMEdit::~ImpVclMEdit()
268 : {
269 45 : EndListening( *mpTextWindow->GetTextEngine() );
270 45 : delete mpTextWindow;
271 45 : delete mpHScrollBar;
272 45 : delete mpVScrollBar;
273 45 : delete mpScrollBox;
274 90 : }
275 :
276 185 : void ImpVclMEdit::ImpSetScrollBarRanges()
277 : {
278 185 : if ( mpVScrollBar )
279 : {
280 72 : sal_uLong nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
281 72 : mpVScrollBar->SetRange( Range( 0, (long)nTextHeight-1 ) );
282 : }
283 185 : if ( mpHScrollBar )
284 : {
285 : // sal_uLong nTextWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
286 : // Es gibt kein Notify bei Breiten-Aenderung...
287 : // sal_uLong nW = Max( (sal_uLong)mpTextWindow->GetOutputSizePixel().Width()*5, (sal_uLong)nTextWidth );
288 : // mpHScrollBar->SetRange( Range( 0, (long)nW ) );
289 95 : mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
290 : }
291 185 : }
292 :
293 100 : void ImpVclMEdit::ImpInitScrollBars()
294 : {
295 : static const sal_Unicode sampleChar = { 'x' };
296 100 : if ( mpHScrollBar || mpVScrollBar )
297 : {
298 80 : ImpSetScrollBarRanges();
299 80 : Size aCharBox;
300 80 : aCharBox.Width() = mpTextWindow->GetTextWidth( OUString(sampleChar) );
301 80 : aCharBox.Height() = mpTextWindow->GetTextHeight();
302 80 : Size aOutSz = mpTextWindow->GetOutputSizePixel();
303 80 : if ( mpHScrollBar )
304 : {
305 66 : mpHScrollBar->SetVisibleSize( aOutSz.Width() );
306 66 : mpHScrollBar->SetPageSize( aOutSz.Width() * 8 / 10 );
307 66 : mpHScrollBar->SetLineSize( aCharBox.Width()*10 );
308 66 : ImpSetHScrollBarThumbPos();
309 : }
310 80 : if ( mpVScrollBar )
311 : {
312 49 : mpVScrollBar->SetVisibleSize( aOutSz.Height() );
313 49 : mpVScrollBar->SetPageSize( aOutSz.Height() * 8 / 10 );
314 49 : mpVScrollBar->SetLineSize( aCharBox.Height() );
315 49 : mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
316 : }
317 : }
318 100 : }
319 :
320 87 : void ImpVclMEdit::ImpSetHScrollBarThumbPos()
321 : {
322 87 : long nX = mpTextWindow->GetTextView()->GetStartDocPos().X();
323 87 : if ( !mpTextWindow->GetTextEngine()->IsRightToLeft() )
324 87 : mpHScrollBar->SetThumbPos( nX );
325 : else
326 0 : mpHScrollBar->SetThumbPos( mnTextWidth - mpHScrollBar->GetVisibleSize() - nX );
327 :
328 87 : }
329 :
330 0 : IMPL_LINK( ImpVclMEdit, ScrollHdl, ScrollBar*, pCurScrollBar )
331 : {
332 0 : long nDiffX = 0, nDiffY = 0;
333 :
334 0 : if ( pCurScrollBar == mpVScrollBar )
335 0 : nDiffY = mpTextWindow->GetTextView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
336 0 : else if ( pCurScrollBar == mpHScrollBar )
337 0 : nDiffX = mpTextWindow->GetTextView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
338 :
339 0 : mpTextWindow->GetTextView()->Scroll( nDiffX, nDiffY );
340 : // mpTextWindow->GetTextView()->ShowCursor( sal_False, sal_True );
341 :
342 0 : return 0;
343 : }
344 :
345 136 : void ImpVclMEdit::SetAlign( WinBits nWinStyle )
346 : {
347 136 : sal_Bool bRTL = Application::GetSettings().GetLayoutRTL();
348 136 : mpTextWindow->GetTextEngine()->SetRightToLeft( bRTL );
349 :
350 136 : if ( nWinStyle & WB_CENTER )
351 62 : mpTextWindow->GetTextEngine()->SetTextAlign( TXTALIGN_CENTER );
352 74 : else if ( nWinStyle & WB_RIGHT )
353 0 : mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_RIGHT : TXTALIGN_LEFT );
354 74 : else if ( nWinStyle & WB_LEFT )
355 74 : mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_LEFT : TXTALIGN_RIGHT );
356 136 : }
357 :
358 16 : void ImpVclMEdit::SetModified( sal_Bool bMod )
359 : {
360 16 : mpTextWindow->GetTextEngine()->SetModified( bMod );
361 16 : }
362 :
363 0 : sal_Bool ImpVclMEdit::IsModified() const
364 : {
365 0 : return mpTextWindow->GetTextEngine()->IsModified();
366 : }
367 :
368 41 : void ImpVclMEdit::SetReadOnly( sal_Bool bRdOnly )
369 : {
370 41 : mpTextWindow->GetTextView()->SetReadOnly( bRdOnly );
371 : // TODO: Adjust color?
372 41 : }
373 :
374 11 : sal_Bool ImpVclMEdit::IsReadOnly() const
375 : {
376 11 : return mpTextWindow->GetTextView()->IsReadOnly();
377 : }
378 :
379 47 : void ImpVclMEdit::SetMaxTextLen( xub_StrLen nLen )
380 : {
381 47 : mpTextWindow->GetTextEngine()->SetMaxTextLen( nLen );
382 47 : }
383 :
384 0 : xub_StrLen ImpVclMEdit::GetMaxTextLen() const
385 : {
386 : return sal::static_int_cast< xub_StrLen >(
387 0 : mpTextWindow->GetTextEngine()->GetMaxTextLen());
388 : }
389 :
390 0 : void ImpVclMEdit::InsertText( const String& rStr )
391 : {
392 0 : mpTextWindow->GetTextView()->InsertText( rStr );
393 0 : }
394 :
395 0 : String ImpVclMEdit::GetSelected() const
396 : {
397 0 : return mpTextWindow->GetTextView()->GetSelected();
398 : }
399 :
400 0 : String ImpVclMEdit::GetSelected( LineEnd aSeparator ) const
401 : {
402 0 : return mpTextWindow->GetTextView()->GetSelected( aSeparator );
403 : }
404 :
405 0 : void ImpVclMEdit::SetMaxTextWidth( sal_uLong nMaxWidth )
406 : {
407 0 : mpTextWindow->GetTextEngine()->SetMaxTextWidth( nMaxWidth );
408 0 : }
409 :
410 89 : void ImpVclMEdit::Resize()
411 : {
412 89 : size_t nIteration = 1;
413 21 : do
414 : {
415 110 : WinBits nWinStyle( pVclMultiLineEdit->GetStyle() );
416 110 : if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
417 0 : ImpUpdateSrollBarVis( nWinStyle );
418 :
419 110 : Size aSz = pVclMultiLineEdit->GetOutputSizePixel();
420 110 : Size aEditSize = aSz;
421 110 : long nSBWidth = pVclMultiLineEdit->GetSettings().GetStyleSettings().GetScrollBarSize();
422 110 : nSBWidth = pVclMultiLineEdit->CalcZoom( nSBWidth );
423 :
424 110 : if ( mpHScrollBar )
425 72 : aSz.Height() -= nSBWidth+1;
426 110 : if ( mpVScrollBar )
427 53 : aSz.Width() -= nSBWidth+1;
428 :
429 110 : if ( !mpHScrollBar )
430 38 : mpTextWindow->GetTextEngine()->SetMaxTextWidth( aSz.Width() );
431 : else
432 72 : mpHScrollBar->setPosSizePixel( 0, aEditSize.Height()-nSBWidth, aSz.Width(), nSBWidth );
433 :
434 110 : Point aTextWindowPos( maTextWindowOffset );
435 110 : if ( mpVScrollBar )
436 : {
437 53 : if( Application::GetSettings().GetLayoutRTL() )
438 : {
439 0 : mpVScrollBar->setPosSizePixel( 0, 0, nSBWidth, aSz.Height() );
440 0 : aTextWindowPos.X() += nSBWidth;
441 : }
442 : else
443 53 : mpVScrollBar->setPosSizePixel( aEditSize.Width()-nSBWidth, 0, nSBWidth, aSz.Height() );
444 : }
445 :
446 110 : if ( mpScrollBox )
447 38 : mpScrollBox->setPosSizePixel( aSz.Width(), aSz.Height(), nSBWidth, nSBWidth );
448 :
449 110 : Size aTextWindowSize( aSz );
450 110 : aTextWindowSize.Width() -= maTextWindowOffset.X();
451 110 : aTextWindowSize.Height() -= maTextWindowOffset.Y();
452 110 : if ( aTextWindowSize.Width() < 0 )
453 7 : aTextWindowSize.Width() = 0;
454 110 : if ( aTextWindowSize.Height() < 0 )
455 9 : aTextWindowSize.Height() = 0;
456 :
457 110 : Size aOldTextWindowSize( mpTextWindow->GetSizePixel() );
458 110 : mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
459 110 : if ( aOldTextWindowSize == aTextWindowSize )
460 89 : break;
461 :
462 : // Changing the text window size might effectively have changed the need for
463 : // scrollbars, so do another iteration.
464 21 : ++nIteration;
465 : OSL_ENSURE( nIteration < 3, "ImpVclMEdit::Resize: isn't this expected to terminate with the second iteration?" );
466 :
467 : } while ( nIteration <= 3 ); // artificial break after four iterations
468 :
469 89 : ImpInitScrollBars();
470 89 : }
471 :
472 0 : void ImpVclMEdit::GetFocus()
473 : {
474 0 : mpTextWindow->GrabFocus();
475 0 : }
476 :
477 0 : void ImpVclMEdit::Cut()
478 : {
479 0 : if ( !mpTextWindow->GetTextView()->IsReadOnly() )
480 0 : mpTextWindow->GetTextView()->Cut();
481 0 : }
482 :
483 0 : void ImpVclMEdit::Copy()
484 : {
485 0 : mpTextWindow->GetTextView()->Copy();
486 0 : }
487 :
488 0 : void ImpVclMEdit::Paste()
489 : {
490 0 : if ( !mpTextWindow->GetTextView()->IsReadOnly() )
491 0 : mpTextWindow->GetTextView()->Paste();
492 0 : }
493 :
494 64 : void ImpVclMEdit::SetText( const OUString& rStr )
495 : {
496 64 : sal_Bool bWasModified = mpTextWindow->GetTextEngine()->IsModified();
497 64 : mpTextWindow->GetTextEngine()->SetText( rStr );
498 64 : if ( !bWasModified )
499 59 : mpTextWindow->GetTextEngine()->SetModified( sal_False );
500 :
501 64 : mpTextWindow->GetTextView()->SetSelection( TextSelection() );
502 :
503 64 : WinBits nWinStyle( pVclMultiLineEdit->GetStyle() );
504 64 : if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
505 0 : ImpUpdateSrollBarVis( nWinStyle );
506 64 : }
507 :
508 0 : OUString ImpVclMEdit::GetText() const
509 : {
510 0 : return mpTextWindow->GetTextEngine()->GetText();
511 : }
512 :
513 0 : String ImpVclMEdit::GetText( LineEnd aSeparator ) const
514 : {
515 0 : return mpTextWindow->GetTextEngine()->GetText( aSeparator );
516 : }
517 :
518 0 : String ImpVclMEdit::GetTextLines( LineEnd aSeparator ) const
519 : {
520 0 : return mpTextWindow->GetTextEngine()->GetTextLines( aSeparator );
521 : }
522 :
523 741 : void ImpVclMEdit::Notify( SfxBroadcaster&, const SfxHint& rHint )
524 : {
525 741 : if ( rHint.ISA( TextHint ) )
526 : {
527 741 : const TextHint& rTextHint = (const TextHint&)rHint;
528 741 : if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
529 : {
530 0 : if ( mpHScrollBar )
531 0 : ImpSetHScrollBarThumbPos();
532 0 : if ( mpVScrollBar )
533 0 : mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
534 : }
535 741 : else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
536 : {
537 105 : if ( mpTextWindow->GetTextView()->GetStartDocPos().Y() )
538 : {
539 0 : long nOutHeight = mpTextWindow->GetOutputSizePixel().Height();
540 0 : long nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
541 0 : if ( nTextHeight < nOutHeight )
542 0 : mpTextWindow->GetTextView()->Scroll( 0, mpTextWindow->GetTextView()->GetStartDocPos().Y() );
543 : }
544 :
545 105 : ImpSetScrollBarRanges();
546 : }
547 636 : else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
548 : {
549 241 : if ( mpHScrollBar )
550 : {
551 73 : sal_uLong nWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
552 73 : if ( nWidth != mnTextWidth )
553 : {
554 21 : mnTextWidth = sal::static_int_cast< xub_StrLen >(nWidth);
555 21 : mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
556 21 : ImpSetHScrollBarThumbPos();
557 : }
558 : }
559 : }
560 395 : else if( rTextHint.GetId() == TEXT_HINT_MODIFIED )
561 : {
562 0 : ImpUpdateSrollBarVis(pVclMultiLineEdit->GetStyle());
563 0 : pVclMultiLineEdit->Modify();
564 : }
565 : }
566 741 : }
567 :
568 0 : void ImpVclMEdit::SetSelection( const Selection& rSelection )
569 : {
570 0 : String aText = mpTextWindow->GetTextEngine()->GetText();
571 :
572 0 : Selection aNewSelection( rSelection );
573 0 : if ( aNewSelection.Min() < 0 )
574 0 : aNewSelection.Min() = 0;
575 0 : else if ( aNewSelection.Min() > aText.Len() )
576 0 : aNewSelection.Min() = aText.Len();
577 0 : if ( aNewSelection.Max() < 0 )
578 0 : aNewSelection.Max() = 0;
579 0 : else if ( aNewSelection.Max() > aText.Len() )
580 0 : aNewSelection.Max() = aText.Len();
581 :
582 0 : long nEnd = std::max( aNewSelection.Min(), aNewSelection.Max() );
583 0 : TextSelection aTextSel;
584 0 : sal_uLong nPara = 0;
585 0 : sal_uInt16 nChar = 0;
586 0 : sal_uInt16 x = 0;
587 0 : while ( x <= nEnd )
588 : {
589 0 : if ( x == aNewSelection.Min() )
590 0 : aTextSel.GetStart() = TextPaM( nPara, nChar );
591 0 : if ( x == aNewSelection.Max() )
592 0 : aTextSel.GetEnd() = TextPaM( nPara, nChar );
593 :
594 0 : if ( ( x < aText.Len() ) && ( aText.GetChar( x ) == '\n' ) )
595 : {
596 0 : nPara++;
597 0 : nChar = 0;
598 : }
599 : else
600 0 : nChar++;
601 0 : x++;
602 : }
603 0 : mpTextWindow->GetTextView()->SetSelection( aTextSel );
604 0 : }
605 :
606 0 : const Selection& ImpVclMEdit::GetSelection() const
607 : {
608 0 : maSelection = Selection();
609 0 : TextSelection aTextSel( mpTextWindow->GetTextView()->GetSelection() );
610 0 : aTextSel.Justify();
611 : // flatten selection => every line-break a character
612 :
613 0 : ExtTextEngine* pExtTextEngine = mpTextWindow->GetTextEngine();
614 : // paragraphs before
615 : sal_uLong n;
616 0 : for ( n = 0; n < aTextSel.GetStart().GetPara(); n++ )
617 : {
618 0 : maSelection.Min() += pExtTextEngine->GetTextLen( n );
619 0 : maSelection.Min()++;
620 : }
621 :
622 : // first paragraph with selection
623 0 : maSelection.Max() = maSelection.Min();
624 0 : maSelection.Min() += aTextSel.GetStart().GetIndex();
625 :
626 0 : for ( n = aTextSel.GetStart().GetPara(); n < aTextSel.GetEnd().GetPara(); n++ )
627 : {
628 0 : maSelection.Max() += pExtTextEngine->GetTextLen( n );
629 0 : maSelection.Max()++;
630 : }
631 :
632 0 : maSelection.Max() += aTextSel.GetEnd().GetIndex();
633 :
634 0 : return maSelection;
635 : }
636 :
637 0 : Size ImpVclMEdit::CalcMinimumSize() const
638 : {
639 0 : Size aSz( mpTextWindow->GetTextEngine()->CalcTextWidth(),
640 0 : mpTextWindow->GetTextEngine()->GetTextHeight() );
641 :
642 0 : if ( mpHScrollBar )
643 0 : aSz.Height() += mpHScrollBar->GetSizePixel().Height();
644 0 : if ( mpVScrollBar )
645 0 : aSz.Width() += mpVScrollBar->GetSizePixel().Width();
646 :
647 0 : return aSz;
648 : }
649 :
650 0 : Size ImpVclMEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
651 : {
652 : static const sal_Unicode sampleChar = 'X';
653 :
654 0 : Size aSz;
655 0 : Size aCharSz;
656 0 : aCharSz.Width() = mpTextWindow->GetTextWidth( OUString(sampleChar) );
657 0 : aCharSz.Height() = mpTextWindow->GetTextHeight();
658 :
659 0 : if ( nLines )
660 0 : aSz.Height() = nLines*aCharSz.Height();
661 : else
662 0 : aSz.Height() = mpTextWindow->GetTextEngine()->GetTextHeight();
663 :
664 0 : if ( nColumns )
665 0 : aSz.Width() = nColumns*aCharSz.Width();
666 : else
667 0 : aSz.Width() = mpTextWindow->GetTextEngine()->CalcTextWidth();
668 :
669 0 : if ( mpHScrollBar )
670 0 : aSz.Height() += mpHScrollBar->GetSizePixel().Height();
671 0 : if ( mpVScrollBar )
672 0 : aSz.Width() += mpVScrollBar->GetSizePixel().Width();
673 :
674 0 : return aSz;
675 : }
676 :
677 0 : void ImpVclMEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
678 : {
679 : static const sal_Unicode sampleChar = { 'x' };
680 0 : Size aOutSz = mpTextWindow->GetOutputSizePixel();
681 0 : Size aCharSz( mpTextWindow->GetTextWidth( OUString(sampleChar) ), mpTextWindow->GetTextHeight() );
682 0 : rnCols = (sal_uInt16) (aOutSz.Width()/aCharSz.Width());
683 0 : rnLines = (sal_uInt16) (aOutSz.Height()/aCharSz.Height());
684 0 : }
685 :
686 11 : void ImpVclMEdit::Enable( sal_Bool bEnable )
687 : {
688 11 : mpTextWindow->Enable( bEnable );
689 11 : if ( mpHScrollBar )
690 11 : mpHScrollBar->Enable( bEnable );
691 11 : if ( mpVScrollBar )
692 7 : mpVScrollBar->Enable( bEnable );
693 11 : }
694 :
695 0 : sal_Bool ImpVclMEdit::HandleCommand( const CommandEvent& rCEvt )
696 : {
697 0 : sal_Bool bDone = sal_False;
698 0 : if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
699 0 : ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
700 0 : ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
701 : {
702 0 : mpTextWindow->HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
703 0 : bDone = sal_True;
704 : }
705 0 : return bDone;
706 : }
707 :
708 :
709 45 : TextWindow::TextWindow( Window* pParent ) : Window( pParent )
710 : {
711 45 : mbInMBDown = false;
712 45 : mbFocusSelectionHide = false;
713 45 : mbIgnoreTab = false;
714 45 : mbActivePopup = false;
715 45 : mbSelectOnTab = true;
716 45 : mbTextSelectable = true;
717 :
718 45 : SetPointer( Pointer( POINTER_TEXT ) );
719 :
720 45 : mpExtTextEngine = new ExtTextEngine;
721 45 : mpExtTextEngine->SetMaxTextLen( STRING_MAXLEN );
722 45 : if( pParent->GetStyle() & WB_BORDER )
723 11 : mpExtTextEngine->SetLeftMargin( 2 );
724 45 : mpExtTextEngine->SetLocale( GetSettings().GetLanguageTag().getLocale() );
725 45 : mpExtTextView = new ExtTextView( mpExtTextEngine, this );
726 45 : mpExtTextEngine->InsertView( mpExtTextView );
727 45 : mpExtTextEngine->EnableUndo( sal_True );
728 45 : mpExtTextView->ShowCursor();
729 :
730 45 : Color aBackgroundColor = GetSettings().GetStyleSettings().GetWorkspaceColor();
731 45 : SetBackground( aBackgroundColor );
732 45 : pParent->SetBackground( aBackgroundColor );
733 45 : }
734 :
735 135 : TextWindow::~TextWindow()
736 : {
737 45 : delete mpExtTextView;
738 45 : delete mpExtTextEngine;
739 90 : }
740 :
741 0 : void TextWindow::MouseMove( const MouseEvent& rMEvt )
742 : {
743 0 : mpExtTextView->MouseMove( rMEvt );
744 0 : Window::MouseMove( rMEvt );
745 0 : }
746 :
747 0 : void TextWindow::MouseButtonDown( const MouseEvent& rMEvt )
748 : {
749 0 : if ( !mbTextSelectable )
750 0 : return;
751 :
752 0 : mbInMBDown = true; // so that GetFocus does not select everything
753 0 : mpExtTextView->MouseButtonDown( rMEvt );
754 0 : Window::MouseButtonDown( rMEvt );
755 0 : GrabFocus();
756 0 : mbInMBDown = false;
757 : }
758 :
759 0 : void TextWindow::MouseButtonUp( const MouseEvent& rMEvt )
760 : {
761 0 : mpExtTextView->MouseButtonUp( rMEvt );
762 0 : Window::MouseButtonUp( rMEvt );
763 0 : }
764 :
765 0 : void TextWindow::KeyInput( const KeyEvent& rKEvent )
766 : {
767 0 : sal_Bool bDone = sal_False;
768 0 : sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
769 0 : if ( nCode == com::sun::star::awt::Key::SELECT_ALL ||
770 0 : ( (nCode == KEY_A) && rKEvent.GetKeyCode().IsMod1() && !rKEvent.GetKeyCode().IsMod2() )
771 : )
772 : {
773 0 : mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
774 0 : bDone = sal_True;
775 : }
776 0 : else if ( (nCode == KEY_S) && rKEvent.GetKeyCode().IsShift() && rKEvent.GetKeyCode().IsMod1() )
777 : {
778 0 : if ( Edit::GetGetSpecialCharsFunction() )
779 : {
780 : // to maintain the selection
781 0 : mbActivePopup = true;
782 0 : OUString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
783 0 : if (!aChars.isEmpty())
784 : {
785 0 : mpExtTextView->InsertText( aChars );
786 0 : mpExtTextView->GetTextEngine()->SetModified( sal_True );
787 : }
788 0 : mbActivePopup = false;
789 0 : bDone = sal_True;
790 : }
791 : }
792 0 : else if ( nCode == KEY_TAB )
793 : {
794 0 : if ( !mbIgnoreTab || rKEvent.GetKeyCode().IsMod1() )
795 0 : bDone = mpExtTextView->KeyInput( rKEvent );
796 : }
797 : else
798 : {
799 0 : bDone = mpExtTextView->KeyInput( rKEvent );
800 : }
801 :
802 0 : if ( !bDone )
803 0 : Window::KeyInput( rKEvent );
804 0 : }
805 :
806 45 : void TextWindow::Paint( const Rectangle& rRect )
807 : {
808 45 : mpExtTextView->Paint( rRect );
809 45 : }
810 :
811 66 : void TextWindow::Resize()
812 : {
813 66 : }
814 :
815 0 : void TextWindow::Command( const CommandEvent& rCEvt )
816 : {
817 0 : if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
818 : {
819 0 : PopupMenu* pPopup = Edit::CreatePopupMenu();
820 0 : if ( !mpExtTextView->HasSelection() )
821 : {
822 0 : pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False );
823 0 : pPopup->EnableItem( SV_MENU_EDIT_COPY, sal_False );
824 0 : pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False );
825 : }
826 0 : if ( mpExtTextView->IsReadOnly() )
827 : {
828 0 : pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False );
829 0 : pPopup->EnableItem( SV_MENU_EDIT_PASTE, sal_False );
830 0 : pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False );
831 0 : pPopup->EnableItem( SV_MENU_EDIT_INSERTSYMBOL, sal_False );
832 : }
833 0 : if ( !mpExtTextView->GetTextEngine()->HasUndoManager() || !mpExtTextView->GetTextEngine()->GetUndoManager().GetUndoActionCount() )
834 : {
835 0 : pPopup->EnableItem( SV_MENU_EDIT_UNDO, sal_False );
836 : }
837 : // if ( ( maSelection.Min() == 0 ) && ( maSelection.Max() == maText.Len() ) )
838 : // {
839 : // pPopup->EnableItem( SV_MENU_EDIT_SELECTALL, sal_False );
840 : // }
841 0 : if ( !Edit::GetGetSpecialCharsFunction() )
842 : {
843 0 : sal_uInt16 nPos = pPopup->GetItemPos( SV_MENU_EDIT_INSERTSYMBOL );
844 0 : pPopup->RemoveItem( nPos );
845 0 : pPopup->RemoveItem( nPos-1 );
846 : }
847 :
848 0 : mbActivePopup = true;
849 0 : Point aPos = rCEvt.GetMousePosPixel();
850 0 : if ( !rCEvt.IsMouseEvent() )
851 : {
852 : // Sometime do show Menu centered in the selection !!!
853 0 : Size aSize = GetOutputSizePixel();
854 0 : aPos = Point( aSize.Width()/2, aSize.Height()/2 );
855 : }
856 : // pPopup->RemoveDisabledEntries();
857 0 : sal_uInt16 n = pPopup->Execute( this, aPos );
858 0 : Edit::DeletePopupMenu( pPopup );
859 0 : switch ( n )
860 : {
861 0 : case SV_MENU_EDIT_UNDO: mpExtTextView->Undo();
862 0 : mpExtTextEngine->SetModified( sal_True );
863 0 : mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
864 0 : break;
865 0 : case SV_MENU_EDIT_CUT: mpExtTextView->Cut();
866 0 : mpExtTextEngine->SetModified( sal_True );
867 0 : mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
868 0 : break;
869 0 : case SV_MENU_EDIT_COPY: mpExtTextView->Copy();
870 0 : break;
871 0 : case SV_MENU_EDIT_PASTE: mpExtTextView->Paste();
872 0 : mpExtTextEngine->SetModified( sal_True );
873 0 : mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
874 0 : break;
875 0 : case SV_MENU_EDIT_DELETE: mpExtTextView->DeleteSelected();
876 0 : mpExtTextEngine->SetModified( sal_True );
877 0 : mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
878 0 : break;
879 0 : case SV_MENU_EDIT_SELECTALL: mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
880 0 : break;
881 : case SV_MENU_EDIT_INSERTSYMBOL:
882 : {
883 0 : OUString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
884 0 : if (!aChars.isEmpty())
885 : {
886 0 : mpExtTextView->InsertText( aChars );
887 0 : mpExtTextEngine->SetModified( sal_True );
888 0 : mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
889 0 : }
890 : }
891 0 : break;
892 : }
893 0 : mbActivePopup = false;
894 : }
895 : else
896 : {
897 0 : mpExtTextView->Command( rCEvt );
898 : }
899 0 : Window::Command( rCEvt );
900 0 : }
901 :
902 0 : void TextWindow::GetFocus()
903 : {
904 0 : Window::GetFocus();
905 0 : if ( !mbActivePopup )
906 : {
907 0 : sal_Bool bGotoCursor = !mpExtTextView->IsReadOnly();
908 0 : if ( mbFocusSelectionHide && IsReallyVisible() && !mpExtTextView->IsReadOnly()
909 0 : && ( mbSelectOnTab &&
910 0 : (!mbInMBDown || ( GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_FOCUS ) )) )
911 : {
912 : // select everything, but do not scroll
913 0 : sal_Bool bAutoScroll = mpExtTextView->IsAutoScroll();
914 0 : mpExtTextView->SetAutoScroll( sal_False );
915 0 : mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
916 0 : mpExtTextView->SetAutoScroll( bAutoScroll );
917 0 : bGotoCursor = sal_False;
918 : }
919 0 : mpExtTextView->SetPaintSelection( sal_True );
920 0 : mpExtTextView->ShowCursor( bGotoCursor );
921 : }
922 0 : }
923 :
924 0 : void TextWindow::LoseFocus()
925 : {
926 0 : Window::LoseFocus();
927 :
928 0 : if ( mbFocusSelectionHide && !mbActivePopup )
929 0 : mpExtTextView->SetPaintSelection( sal_False );
930 0 : }
931 :
932 45 : VclMultiLineEdit::VclMultiLineEdit( Window* pParent, WinBits nWinStyle )
933 45 : : Edit( pParent, nWinStyle )
934 : {
935 45 : SetType( WINDOW_MULTILINEEDIT );
936 45 : pImpVclMEdit = new ImpVclMEdit( this, nWinStyle );
937 45 : ImplInitSettings( sal_True, sal_True, sal_True );
938 45 : pUpdateDataTimer = 0;
939 :
940 45 : SetCompoundControl( sal_True );
941 45 : SetStyle( ImplInitStyle( nWinStyle ) );
942 45 : }
943 :
944 0 : VclMultiLineEdit::VclMultiLineEdit( Window* pParent, const ResId& rResId )
945 0 : : Edit( pParent, rResId.SetRT( RSC_MULTILINEEDIT ) )
946 : {
947 0 : SetType( WINDOW_MULTILINEEDIT );
948 0 : WinBits nWinStyle = rResId.GetWinBits();
949 0 : pImpVclMEdit = new ImpVclMEdit( this, nWinStyle );
950 0 : ImplInitSettings( sal_True, sal_True, sal_True );
951 0 : pUpdateDataTimer = 0;
952 :
953 0 : sal_uInt16 nMaxLen = Edit::GetMaxTextLen();
954 0 : if ( nMaxLen )
955 0 : SetMaxTextLen( nMaxLen );
956 :
957 0 : SetText( Edit::GetText() );
958 :
959 0 : if ( IsVisible() )
960 0 : pImpVclMEdit->Resize();
961 :
962 0 : SetCompoundControl( sal_True );
963 0 : SetStyle( ImplInitStyle( nWinStyle ) );
964 :
965 : // Base Edit ctor could call Show already, but that would cause problems
966 : // with accessibility, as Show might (indirectly) trigger a call to virtual
967 : // GetComponentInterface, which is the Edit's base version instead of the
968 : // VclMultiLineEdit's version while in the base Edit ctor:
969 0 : if ((GetStyle() & WB_HIDE) == 0)
970 0 : Show();
971 :
972 0 : }
973 :
974 90 : VclMultiLineEdit::~VclMultiLineEdit()
975 : {
976 : {
977 45 : ::std::auto_ptr< ImpVclMEdit > pDelete( pImpVclMEdit );
978 45 : pImpVclMEdit = NULL;
979 : }
980 45 : delete pUpdateDataTimer;
981 45 : }
982 :
983 136 : WinBits VclMultiLineEdit::ImplInitStyle( WinBits nStyle )
984 : {
985 136 : if ( !(nStyle & WB_NOTABSTOP) )
986 136 : nStyle |= WB_TABSTOP;
987 :
988 136 : if ( !(nStyle & WB_NOGROUP) )
989 136 : nStyle |= WB_GROUP;
990 :
991 136 : if ( !(nStyle & WB_IGNORETAB ))
992 68 : nStyle |= WINDOW_DLGCTRL_MOD1TAB;
993 :
994 136 : return nStyle;
995 : }
996 :
997 :
998 171 : void VclMultiLineEdit::ImplInitSettings( sal_Bool /*bFont*/, sal_Bool /*bForeground*/, sal_Bool bBackground )
999 : {
1000 171 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1001 :
1002 : // The Font has to be adjusted, as the TextEngine does not take care of
1003 : // TextColor/Background
1004 :
1005 171 : Color aTextColor = rStyleSettings.GetFieldTextColor();
1006 171 : if ( IsControlForeground() )
1007 45 : aTextColor = GetControlForeground();
1008 171 : if ( !IsEnabled() )
1009 39 : aTextColor = rStyleSettings.GetDisableColor();
1010 :
1011 171 : Font aFont = rStyleSettings.GetFieldFont();
1012 171 : if ( IsControlFont() )
1013 38 : aFont.Merge( GetControlFont() );
1014 171 : aFont.SetTransparent( IsPaintTransparent() );
1015 171 : SetZoomedPointFont( aFont );
1016 342 : Font TheFont = GetFont();
1017 171 : TheFont.SetColor( aTextColor );
1018 171 : if( IsPaintTransparent() )
1019 51 : TheFont.SetFillColor( Color( COL_TRANSPARENT ) );
1020 : else
1021 120 : TheFont.SetFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() );
1022 171 : pImpVclMEdit->GetTextWindow()->SetFont( TheFont );
1023 171 : pImpVclMEdit->GetTextWindow()->GetTextEngine()->SetFont( TheFont );
1024 171 : pImpVclMEdit->GetTextWindow()->SetTextColor( aTextColor );
1025 :
1026 171 : if ( bBackground )
1027 : {
1028 124 : if( IsPaintTransparent() )
1029 : {
1030 48 : pImpVclMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
1031 48 : pImpVclMEdit->GetTextWindow()->SetBackground();
1032 48 : pImpVclMEdit->GetTextWindow()->SetControlBackground();
1033 48 : SetBackground();
1034 48 : SetControlBackground();
1035 : }
1036 : else
1037 : {
1038 76 : if( IsControlBackground() )
1039 0 : pImpVclMEdit->GetTextWindow()->SetBackground( GetControlBackground() );
1040 : else
1041 76 : pImpVclMEdit->GetTextWindow()->SetBackground( rStyleSettings.GetFieldColor() );
1042 : // also adjust for VclMultiLineEdit as the TextComponent might hide Scrollbars
1043 76 : SetBackground( pImpVclMEdit->GetTextWindow()->GetBackground() );
1044 : }
1045 171 : }
1046 171 : }
1047 :
1048 16 : void VclMultiLineEdit::Modify()
1049 : {
1050 16 : aModifyHdlLink.Call( this );
1051 :
1052 16 : CallEventListeners( VCLEVENT_EDIT_MODIFY );
1053 :
1054 16 : if ( pUpdateDataTimer )
1055 0 : pUpdateDataTimer->Start();
1056 16 : }
1057 :
1058 0 : IMPL_LINK_NOARG(VclMultiLineEdit, ImpUpdateDataHdl)
1059 : {
1060 0 : UpdateData();
1061 0 : return 0;
1062 : }
1063 :
1064 0 : void VclMultiLineEdit::UpdateData()
1065 : {
1066 0 : aUpdateDataHdlLink.Call( this );
1067 0 : }
1068 :
1069 16 : void VclMultiLineEdit::SetModifyFlag()
1070 : {
1071 16 : pImpVclMEdit->SetModified( sal_True );
1072 16 : }
1073 :
1074 0 : void VclMultiLineEdit::ClearModifyFlag()
1075 : {
1076 0 : pImpVclMEdit->SetModified( sal_False );
1077 0 : }
1078 :
1079 0 : sal_Bool VclMultiLineEdit::IsModified() const
1080 : {
1081 0 : return pImpVclMEdit->IsModified();
1082 : }
1083 :
1084 0 : void VclMultiLineEdit::EnableUpdateData( sal_uLong nTimeout )
1085 : {
1086 0 : if ( !nTimeout )
1087 0 : DisableUpdateData();
1088 : else
1089 : {
1090 0 : if ( !pUpdateDataTimer )
1091 : {
1092 0 : pUpdateDataTimer = new Timer;
1093 0 : pUpdateDataTimer->SetTimeoutHdl( LINK( this, VclMultiLineEdit, ImpUpdateDataHdl ) );
1094 : }
1095 0 : pUpdateDataTimer->SetTimeout( nTimeout );
1096 : }
1097 0 : }
1098 :
1099 30 : void VclMultiLineEdit::SetReadOnly( sal_Bool bReadOnly )
1100 : {
1101 30 : pImpVclMEdit->SetReadOnly( bReadOnly );
1102 30 : Edit::SetReadOnly( bReadOnly );
1103 :
1104 : // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set.
1105 30 : WinBits nStyle = GetStyle();
1106 30 : if ( bReadOnly )
1107 11 : nStyle |= WB_READONLY;
1108 : else
1109 19 : nStyle &= ~WB_READONLY;
1110 30 : SetStyle( nStyle );
1111 30 : }
1112 :
1113 11 : sal_Bool VclMultiLineEdit::IsReadOnly() const
1114 : {
1115 11 : return pImpVclMEdit->IsReadOnly();
1116 : }
1117 :
1118 47 : void VclMultiLineEdit::SetMaxTextLen( xub_StrLen nMaxLen )
1119 : {
1120 47 : pImpVclMEdit->SetMaxTextLen( nMaxLen );
1121 47 : }
1122 :
1123 0 : void VclMultiLineEdit::SetMaxTextWidth( sal_uLong nMaxWidth )
1124 : {
1125 0 : pImpVclMEdit->SetMaxTextWidth(nMaxWidth );
1126 0 : }
1127 :
1128 0 : xub_StrLen VclMultiLineEdit::GetMaxTextLen() const
1129 : {
1130 0 : return pImpVclMEdit->GetMaxTextLen();
1131 : }
1132 :
1133 0 : void VclMultiLineEdit::ReplaceSelected( const OUString& rStr )
1134 : {
1135 0 : pImpVclMEdit->InsertText( rStr );
1136 0 : }
1137 :
1138 0 : void VclMultiLineEdit::DeleteSelected()
1139 : {
1140 0 : pImpVclMEdit->InsertText( String() );
1141 0 : }
1142 :
1143 0 : OUString VclMultiLineEdit::GetSelected() const
1144 : {
1145 0 : return pImpVclMEdit->GetSelected();
1146 : }
1147 :
1148 0 : OUString VclMultiLineEdit::GetSelected( LineEnd aSeparator ) const
1149 : {
1150 0 : return pImpVclMEdit->GetSelected( aSeparator );
1151 : }
1152 :
1153 0 : void VclMultiLineEdit::Cut()
1154 : {
1155 0 : pImpVclMEdit->Cut();
1156 0 : }
1157 :
1158 0 : void VclMultiLineEdit::Copy()
1159 : {
1160 0 : pImpVclMEdit->Copy();
1161 0 : }
1162 :
1163 0 : void VclMultiLineEdit::Paste()
1164 : {
1165 0 : pImpVclMEdit->Paste();
1166 0 : }
1167 :
1168 64 : void VclMultiLineEdit::SetText( const OUString& rStr )
1169 : {
1170 64 : pImpVclMEdit->SetText( rStr );
1171 64 : }
1172 :
1173 0 : OUString VclMultiLineEdit::GetText() const
1174 : {
1175 0 : return pImpVclMEdit->GetText();
1176 : }
1177 :
1178 0 : OUString VclMultiLineEdit::GetText( LineEnd aSeparator ) const
1179 : {
1180 0 : return pImpVclMEdit->GetText( aSeparator );
1181 : }
1182 :
1183 0 : String VclMultiLineEdit::GetTextLines( LineEnd aSeparator ) const
1184 : {
1185 0 : return pImpVclMEdit->GetTextLines( aSeparator );
1186 : }
1187 :
1188 78 : void VclMultiLineEdit::Resize()
1189 : {
1190 78 : pImpVclMEdit->Resize();
1191 78 : }
1192 :
1193 0 : void VclMultiLineEdit::GetFocus()
1194 : {
1195 0 : if ( !pImpVclMEdit ) // might be called from within the dtor, when pImpVclMEdit == NULL is a valid state
1196 0 : return;
1197 :
1198 0 : Edit::GetFocus();
1199 0 : pImpVclMEdit->GetFocus();
1200 : }
1201 :
1202 0 : void VclMultiLineEdit::SetSelection( const Selection& rSelection )
1203 : {
1204 0 : pImpVclMEdit->SetSelection( rSelection );
1205 0 : }
1206 :
1207 0 : const Selection& VclMultiLineEdit::GetSelection() const
1208 : {
1209 0 : return pImpVclMEdit->GetSelection();
1210 : }
1211 :
1212 0 : Size VclMultiLineEdit::CalcMinimumSize() const
1213 : {
1214 0 : Size aSz = pImpVclMEdit->CalcMinimumSize();
1215 :
1216 : sal_Int32 nLeft, nTop, nRight, nBottom;
1217 0 : ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1218 0 : aSz.Width() += nLeft+nRight;
1219 0 : aSz.Height() += nTop+nBottom;
1220 :
1221 0 : return aSz;
1222 : }
1223 :
1224 0 : Size VclMultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const
1225 : {
1226 0 : Size aSz = rPrefSize;
1227 : sal_Int32 nLeft, nTop, nRight, nBottom;
1228 0 : ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1229 :
1230 : // center vertically for whole lines
1231 :
1232 0 : long nHeight = aSz.Height() - nTop - nBottom;
1233 0 : long nLineHeight = pImpVclMEdit->CalcSize( 1, 1 ).Height();
1234 0 : long nLines = nHeight / nLineHeight;
1235 0 : if ( nLines < 1 )
1236 0 : nLines = 1;
1237 :
1238 0 : aSz.Height() = nLines * nLineHeight;
1239 0 : aSz.Height() += nTop+nBottom;
1240 :
1241 0 : return aSz;
1242 : }
1243 :
1244 0 : Size VclMultiLineEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
1245 : {
1246 0 : Size aSz = pImpVclMEdit->CalcSize( nColumns, nLines );
1247 :
1248 : sal_Int32 nLeft, nTop, nRight, nBottom;
1249 0 : ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1250 0 : aSz.Width() += nLeft+nRight;
1251 0 : aSz.Height() += nTop+nBottom;
1252 0 : return aSz;
1253 : }
1254 :
1255 0 : void VclMultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
1256 : {
1257 0 : pImpVclMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines );
1258 0 : }
1259 :
1260 370 : void VclMultiLineEdit::StateChanged( StateChangedType nType )
1261 : {
1262 370 : if( nType == STATE_CHANGE_ENABLE )
1263 : {
1264 11 : pImpVclMEdit->Enable( IsEnabled() );
1265 11 : ImplInitSettings( sal_True, sal_False, sal_False );
1266 : }
1267 359 : else if( nType == STATE_CHANGE_READONLY )
1268 : {
1269 11 : pImpVclMEdit->SetReadOnly( IsReadOnly() );
1270 : }
1271 348 : else if ( nType == STATE_CHANGE_ZOOM )
1272 : {
1273 0 : pImpVclMEdit->GetTextWindow()->SetZoom( GetZoom() );
1274 0 : ImplInitSettings( sal_True, sal_False, sal_False );
1275 0 : Resize();
1276 : }
1277 348 : else if ( nType == STATE_CHANGE_CONTROLFONT )
1278 : {
1279 33 : ImplInitSettings( sal_True, sal_False, sal_False );
1280 33 : Resize();
1281 33 : Invalidate();
1282 : }
1283 315 : else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1284 : {
1285 3 : ImplInitSettings( sal_False, sal_True, sal_False );
1286 3 : Invalidate();
1287 : }
1288 312 : else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1289 : {
1290 48 : ImplInitSettings( sal_False, sal_False, sal_True );
1291 48 : Invalidate();
1292 : }
1293 264 : else if ( nType == STATE_CHANGE_STYLE )
1294 : {
1295 91 : pImpVclMEdit->InitFromStyle( GetStyle() );
1296 91 : SetStyle( ImplInitStyle( GetStyle() ) );
1297 : }
1298 173 : else if ( nType == STATE_CHANGE_INITSHOW )
1299 : {
1300 24 : if( IsPaintTransparent() )
1301 : {
1302 24 : pImpVclMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
1303 24 : pImpVclMEdit->GetTextWindow()->SetBackground();
1304 24 : pImpVclMEdit->GetTextWindow()->SetControlBackground();
1305 24 : SetBackground();
1306 24 : SetControlBackground();
1307 : }
1308 : }
1309 :
1310 370 : Control::StateChanged( nType );
1311 370 : }
1312 :
1313 31 : void VclMultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt )
1314 : {
1315 62 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1316 31 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1317 : {
1318 31 : ImplInitSettings( sal_True, sal_True, sal_True );
1319 31 : Resize();
1320 31 : Invalidate();
1321 : }
1322 : else
1323 0 : Control::DataChanged( rDCEvt );
1324 31 : }
1325 :
1326 0 : void VclMultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
1327 : {
1328 0 : ImplInitSettings( sal_True, sal_True, sal_True );
1329 :
1330 0 : Point aPos = pDev->LogicToPixel( rPos );
1331 0 : Size aSize = pDev->LogicToPixel( rSize );
1332 0 : Font aFont = pImpVclMEdit->GetTextWindow()->GetDrawPixelFont( pDev );
1333 0 : aFont.SetTransparent( sal_True );
1334 0 : OutDevType eOutDevType = pDev->GetOutDevType();
1335 :
1336 0 : pDev->Push();
1337 0 : pDev->SetMapMode();
1338 0 : pDev->SetFont( aFont );
1339 0 : pDev->SetTextFillColor();
1340 :
1341 : // Border/Background
1342 0 : pDev->SetLineColor();
1343 0 : pDev->SetFillColor();
1344 0 : bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
1345 0 : bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
1346 0 : if ( bBorder || bBackground )
1347 : {
1348 0 : Rectangle aRect( aPos, aSize );
1349 0 : if ( bBorder )
1350 : {
1351 0 : DecorationView aDecoView( pDev );
1352 0 : aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
1353 : }
1354 0 : if ( bBackground )
1355 : {
1356 0 : pDev->SetFillColor( GetControlBackground() );
1357 0 : pDev->DrawRect( aRect );
1358 : }
1359 : }
1360 :
1361 : // contents
1362 0 : if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
1363 0 : pDev->SetTextColor( Color( COL_BLACK ) );
1364 : else
1365 : {
1366 0 : if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
1367 : {
1368 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1369 0 : pDev->SetTextColor( rStyleSettings.GetDisableColor() );
1370 : }
1371 : else
1372 : {
1373 0 : pDev->SetTextColor( GetTextColor() );
1374 : }
1375 : }
1376 :
1377 0 : OUString aText = GetText();
1378 0 : Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() );
1379 0 : sal_uLong nLines = (sal_uLong) (aSize.Height() / aTextSz.Height());
1380 0 : if ( !nLines )
1381 0 : nLines = 1;
1382 0 : aTextSz.Height() = nLines*aTextSz.Height();
1383 0 : long nOnePixel = GetDrawPixel( pDev, 1 );
1384 0 : long nOffX = 3*nOnePixel;
1385 0 : long nOffY = 2*nOnePixel;
1386 :
1387 : // Clipping?
1388 0 : if ( ( nOffY < 0 ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) )
1389 : {
1390 0 : Rectangle aClip( aPos, aSize );
1391 0 : if ( aTextSz.Height() > aSize.Height() )
1392 0 : aClip.Bottom() += aTextSz.Height() - aSize.Height() + 1; // so that HP-printer does not 'optimize-away'
1393 0 : pDev->IntersectClipRegion( aClip );
1394 : }
1395 :
1396 0 : ExtTextEngine aTE;
1397 0 : aTE.SetText( GetText() );
1398 0 : aTE.SetMaxTextWidth( aSize.Width() );
1399 0 : aTE.SetFont( aFont );
1400 0 : aTE.SetTextAlign( pImpVclMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() );
1401 0 : aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) );
1402 :
1403 0 : pDev->Pop();
1404 0 : }
1405 :
1406 72 : long VclMultiLineEdit::Notify( NotifyEvent& rNEvt )
1407 : {
1408 72 : long nDone = 0;
1409 72 : if( rNEvt.GetType() == EVENT_COMMAND )
1410 : {
1411 0 : nDone = pImpVclMEdit->HandleCommand( *rNEvt.GetCommandEvent() );
1412 : }
1413 72 : return nDone ? nDone : Edit::Notify( rNEvt );
1414 : }
1415 :
1416 0 : long VclMultiLineEdit::PreNotify( NotifyEvent& rNEvt )
1417 : {
1418 0 : long nDone = 0;
1419 :
1420 : #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL)
1421 : if( rNEvt.GetType() == EVENT_KEYINPUT )
1422 : {
1423 : const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1424 : if ( ( rKEvent.GetKeyCode().GetCode() == KEY_W ) && rKEvent.GetKeyCode().IsMod1() && rKEvent.GetKeyCode().IsMod2() )
1425 : {
1426 : SetRightToLeft( !IsRightToLeft() );
1427 : }
1428 : }
1429 : #endif
1430 :
1431 0 : if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) )
1432 : {
1433 0 : const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1434 0 : if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) )
1435 : {
1436 0 : nDone = 1;
1437 0 : TextSelection aSel = pImpVclMEdit->GetTextWindow()->GetTextView()->GetSelection();
1438 0 : if ( aSel.HasRange() )
1439 : {
1440 0 : aSel.GetStart() = aSel.GetEnd();
1441 0 : pImpVclMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel );
1442 : }
1443 : else
1444 : {
1445 0 : switch ( rKEvent.GetKeyCode().GetCode() )
1446 : {
1447 : case KEY_UP:
1448 : {
1449 0 : if ( pImpVclMEdit->GetVScrollBar() )
1450 0 : pImpVclMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEUP );
1451 : }
1452 0 : break;
1453 : case KEY_DOWN:
1454 : {
1455 0 : if ( pImpVclMEdit->GetVScrollBar() )
1456 0 : pImpVclMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1457 : }
1458 0 : break;
1459 : case KEY_PAGEUP :
1460 : {
1461 0 : if ( pImpVclMEdit->GetVScrollBar() )
1462 0 : pImpVclMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEUP );
1463 : }
1464 0 : break;
1465 : case KEY_PAGEDOWN:
1466 : {
1467 0 : if ( pImpVclMEdit->GetVScrollBar() )
1468 0 : pImpVclMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEDOWN );
1469 : }
1470 0 : break;
1471 : case KEY_LEFT:
1472 : {
1473 0 : if ( pImpVclMEdit->GetHScrollBar() )
1474 0 : pImpVclMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEUP );
1475 : }
1476 0 : break;
1477 : case KEY_RIGHT:
1478 : {
1479 0 : if ( pImpVclMEdit->GetHScrollBar() )
1480 0 : pImpVclMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1481 : }
1482 0 : break;
1483 : case KEY_HOME:
1484 : {
1485 0 : if ( rKEvent.GetKeyCode().IsMod1() )
1486 0 : pImpVclMEdit->GetTextWindow()->GetTextView()->
1487 0 : SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
1488 : }
1489 0 : break;
1490 : case KEY_END:
1491 : {
1492 0 : if ( rKEvent.GetKeyCode().IsMod1() )
1493 0 : pImpVclMEdit->GetTextWindow()->GetTextView()->
1494 0 : SetSelection( TextSelection( TextPaM( 0xFFFF, 0xFFFF ) ) );
1495 : }
1496 0 : break;
1497 : default:
1498 : {
1499 0 : nDone = 0;
1500 : }
1501 : }
1502 : }
1503 : }
1504 : }
1505 :
1506 0 : return nDone ? nDone : Edit::PreNotify( rNEvt );
1507 : }
1508 :
1509 : //
1510 : // Internals for derived classes, e.g. TextComponent
1511 :
1512 0 : ExtTextEngine* VclMultiLineEdit::GetTextEngine() const
1513 : {
1514 0 : return pImpVclMEdit->GetTextWindow()->GetTextEngine();
1515 : }
1516 :
1517 0 : ExtTextView* VclMultiLineEdit::GetTextView() const
1518 : {
1519 0 : return pImpVclMEdit->GetTextWindow()->GetTextView();
1520 : }
1521 :
1522 0 : ScrollBar* VclMultiLineEdit::GetVScrollBar() const
1523 : {
1524 0 : return pImpVclMEdit->GetVScrollBar();
1525 : }
1526 :
1527 13 : void VclMultiLineEdit::EnableFocusSelectionHide( sal_Bool bHide )
1528 : {
1529 13 : pImpVclMEdit->GetTextWindow()->SetAutoFocusHide( bHide );
1530 13 : }
1531 :
1532 0 : void VclMultiLineEdit::SetLeftMargin( sal_uInt16 n )
1533 : {
1534 0 : if ( GetTextEngine() )
1535 0 : GetTextEngine()->SetLeftMargin( n );
1536 0 : }
1537 :
1538 0 : void VclMultiLineEdit::SetRightToLeft( sal_Bool bRightToLeft )
1539 : {
1540 0 : if ( GetTextEngine() )
1541 : {
1542 0 : GetTextEngine()->SetRightToLeft( bRightToLeft );
1543 0 : GetTextView()->ShowCursor();
1544 : }
1545 0 : }
1546 :
1547 0 : sal_Bool VclMultiLineEdit::IsRightToLeft() const
1548 : {
1549 0 : sal_Bool bRightToLeft = sal_False;
1550 :
1551 0 : if ( GetTextEngine() )
1552 0 : bRightToLeft = GetTextEngine()->IsRightToLeft();
1553 :
1554 0 : return bRightToLeft;
1555 : }
1556 :
1557 11 : void VclMultiLineEdit::DisableSelectionOnFocus()
1558 : {
1559 11 : pImpVclMEdit->GetTextWindow()->DisableSelectionOnFocus();
1560 11 : }
1561 :
1562 0 : void VclMultiLineEdit::SetTextSelectable( bool bTextSelectable )
1563 : {
1564 0 : pImpVclMEdit->GetTextWindow()->SetTextSelectable( bTextSelectable );
1565 0 : }
1566 :
1567 0 : void VclMultiLineEdit::EnableCursor( sal_Bool bEnable )
1568 : {
1569 0 : GetTextView()->EnableCursor( bEnable );
1570 0 : }
1571 :
1572 0 : bool VclMultiLineEdit::set_property(const OString &rKey, const OString &rValue)
1573 : {
1574 0 : if (rKey == "cursor-visible")
1575 0 : EnableCursor(toBool(rValue));
1576 : else
1577 0 : return Edit::set_property(rKey, rValue);
1578 0 : return true;
1579 465 : }
1580 :
1581 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|