bump product version to 4.1.6.2
[LibreOffice.git] / vcl / source / edit / vclmedit.cxx
blob79d8399332675a50b56c1e793aec734022584cb5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <memory>
22 #include <tools/rc.h>
23 #include <vcl/builder.hxx>
24 #include <vcl/decoview.hxx>
25 #include <vcl/svapp.hxx>
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>
34 #include <svids.hrc>
35 #include <vcl/scrbar.hxx>
38 class TextWindow : public Window
40 private:
41 ExtTextEngine* mpExtTextEngine;
42 ExtTextView* mpExtTextView;
44 bool mbInMBDown;
45 sal_Bool mbFocusSelectionHide;
46 sal_Bool mbIgnoreTab;
47 sal_Bool mbActivePopup;
48 sal_Bool mbSelectOnTab;
49 sal_Bool mbTextSelectable;
51 public:
52 TextWindow( Window* pParent );
53 ~TextWindow();
55 ExtTextEngine* GetTextEngine() const { return mpExtTextEngine; }
56 ExtTextView* GetTextView() const { return mpExtTextView; }
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 );
63 virtual void Command( const CommandEvent& rCEvt );
65 virtual void Paint( const Rectangle& rRect );
66 virtual void Resize();
68 virtual void GetFocus();
69 virtual void LoseFocus();
71 sal_Bool IsAutoFocusHide() const { return mbFocusSelectionHide; }
72 void SetAutoFocusHide( sal_Bool bAutoHide ) { mbFocusSelectionHide = bAutoHide; }
74 sal_Bool IsIgnoreTab() const { return mbIgnoreTab; }
75 void SetIgnoreTab( sal_Bool bIgnore ) { mbIgnoreTab = bIgnore; }
77 void DisableSelectionOnFocus() { mbSelectOnTab = sal_False; }
79 void SetTextSelectable( sal_Bool bTextSelectable ) { mbTextSelectable = bTextSelectable; }
83 class ImpVclMEdit : public SfxListener
85 private:
86 VclMultiLineEdit* pVclMultiLineEdit;
88 TextWindow* mpTextWindow;
89 ScrollBar* mpHScrollBar;
90 ScrollBar* mpVScrollBar;
91 ScrollBarBox* mpScrollBox;
93 Point maTextWindowOffset;
94 xub_StrLen mnTextWidth;
95 mutable Selection maSelection;
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* );
105 public:
106 ImpVclMEdit( VclMultiLineEdit* pVclMultiLineEdit, WinBits nWinStyle );
107 ~ImpVclMEdit();
109 void SetModified( sal_Bool bMod );
110 sal_Bool IsModified() const;
112 void SetReadOnly( sal_Bool bRdOnly );
113 sal_Bool IsReadOnly() const;
115 void SetMaxTextLen( xub_StrLen nLen );
116 xub_StrLen GetMaxTextLen() const;
118 void SetMaxTextWidth( sal_uLong nMaxWidth );
120 sal_Bool IsInsertMode() const;
122 void InsertText( const String& rStr );
123 String GetSelected() const;
124 String GetSelected( LineEnd aSeparator ) const;
126 void SetSelection( const Selection& rSelection );
127 const Selection& GetSelection() const;
129 void Cut();
130 void Copy();
131 void Paste();
133 void SetText( const OUString& rStr );
134 OUString GetText() const;
135 String GetText( LineEnd aSeparator ) const;
136 String GetTextLines( LineEnd aSeparator ) const;
138 void Resize();
139 void GetFocus();
141 sal_Bool HandleCommand( const CommandEvent& rCEvt );
143 void Enable( sal_Bool bEnable );
145 Size CalcMinimumSize() const;
146 Size CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const;
147 void GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const;
149 void SetAlign( WinBits nWinStyle );
151 void InitFromStyle( WinBits nWinStyle );
153 TextWindow* GetTextWindow() { return mpTextWindow; }
154 ScrollBar* GetHScrollBar() { return mpHScrollBar; }
155 ScrollBar* GetVScrollBar() { return mpVScrollBar; }
158 ImpVclMEdit::ImpVclMEdit( VclMultiLineEdit* pEdt, WinBits nWinStyle )
159 :mpHScrollBar(NULL)
160 ,mpVScrollBar(NULL)
161 ,mpScrollBox(NULL)
163 pVclMultiLineEdit = pEdt;
164 mnTextWidth = 0;
165 mpTextWindow = new TextWindow( pEdt );
166 mpTextWindow->Show();
167 InitFromStyle( nWinStyle );
168 StartListening( *mpTextWindow->GetTextEngine() );
171 void ImpVclMEdit::ImpUpdateSrollBarVis( WinBits nWinStyle )
173 const bool bHaveVScroll = (NULL != mpVScrollBar);
174 const bool bHaveHScroll = (NULL != mpHScrollBar);
175 const bool bHaveScrollBox = (NULL != mpScrollBox);
177 bool bNeedVScroll = ( nWinStyle & WB_VSCROLL ) == WB_VSCROLL;
178 const bool bNeedHScroll = ( nWinStyle & WB_HSCROLL ) == WB_HSCROLL;
180 const bool bAutoVScroll = ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL;
181 if ( !bNeedVScroll && bAutoVScroll )
183 TextEngine& rEngine( *mpTextWindow->GetTextEngine() );
184 sal_uLong nOverallTextHeight(0);
185 for ( sal_uLong i=0; i<rEngine.GetParagraphCount(); ++i )
186 nOverallTextHeight += rEngine.GetTextHeight( i );
187 if ( nOverallTextHeight > (sal_uLong)mpTextWindow->GetOutputSizePixel().Height() )
188 bNeedVScroll = true;
191 const bool bNeedScrollBox = bNeedVScroll && bNeedHScroll;
193 bool bScrollbarsChanged = false;
194 if ( bHaveVScroll != bNeedVScroll )
196 delete mpVScrollBar;
197 mpVScrollBar = bNeedVScroll ? new ScrollBar( pVclMultiLineEdit, WB_VSCROLL|WB_DRAG ) : NULL;
199 if ( bNeedVScroll )
201 mpVScrollBar->Show();
202 mpVScrollBar->SetScrollHdl( LINK( this, ImpVclMEdit, ScrollHdl ) );
205 bScrollbarsChanged = true;
208 if ( bHaveHScroll != bNeedHScroll )
210 delete mpHScrollBar;
211 mpHScrollBar = bNeedHScroll ? new ScrollBar( pVclMultiLineEdit, WB_HSCROLL|WB_DRAG ) : NULL;
213 if ( bNeedHScroll )
215 mpHScrollBar->Show();
216 mpHScrollBar->SetScrollHdl( LINK( this, ImpVclMEdit, ScrollHdl ) );
219 bScrollbarsChanged = true;
222 if ( bHaveScrollBox != bNeedScrollBox )
224 delete mpScrollBox;
225 mpScrollBox = bNeedScrollBox ? new ScrollBarBox( pVclMultiLineEdit, WB_SIZEABLE ) : NULL;
227 if ( bNeedScrollBox )
228 mpScrollBox->Show();
231 if ( bScrollbarsChanged )
233 ImpInitScrollBars();
234 Resize();
238 void ImpVclMEdit::InitFromStyle( WinBits nWinStyle )
240 ImpUpdateSrollBarVis( nWinStyle );
241 SetAlign( nWinStyle );
243 if ( nWinStyle & WB_NOHIDESELECTION )
244 mpTextWindow->SetAutoFocusHide( sal_False );
245 else
246 mpTextWindow->SetAutoFocusHide( sal_True );
248 if ( nWinStyle & WB_READONLY )
249 mpTextWindow->GetTextView()->SetReadOnly( sal_True );
250 else
251 mpTextWindow->GetTextView()->SetReadOnly( sal_False );
253 if ( nWinStyle & WB_IGNORETAB )
255 mpTextWindow->SetIgnoreTab( sal_True );
257 else
259 mpTextWindow->SetIgnoreTab( sal_False );
260 // #103667# VclMultiLineEdit has the flag, but focusable window also needs this flag
261 WinBits nStyle = mpTextWindow->GetStyle();
262 nStyle |= WINDOW_DLGCTRL_MOD1TAB;
263 mpTextWindow->SetStyle( nStyle );
267 ImpVclMEdit::~ImpVclMEdit()
269 EndListening( *mpTextWindow->GetTextEngine() );
270 delete mpTextWindow;
271 delete mpHScrollBar;
272 delete mpVScrollBar;
273 delete mpScrollBox;
276 void ImpVclMEdit::ImpSetScrollBarRanges()
278 if ( mpVScrollBar )
280 sal_uLong nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
281 mpVScrollBar->SetRange( Range( 0, (long)nTextHeight-1 ) );
283 if ( mpHScrollBar )
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 mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
293 void ImpVclMEdit::ImpInitScrollBars()
295 static const sal_Unicode sampleChar = { 'x' };
296 if ( mpHScrollBar || mpVScrollBar )
298 ImpSetScrollBarRanges();
299 Size aCharBox;
300 aCharBox.Width() = mpTextWindow->GetTextWidth( OUString(sampleChar) );
301 aCharBox.Height() = mpTextWindow->GetTextHeight();
302 Size aOutSz = mpTextWindow->GetOutputSizePixel();
303 if ( mpHScrollBar )
305 mpHScrollBar->SetVisibleSize( aOutSz.Width() );
306 mpHScrollBar->SetPageSize( aOutSz.Width() * 8 / 10 );
307 mpHScrollBar->SetLineSize( aCharBox.Width()*10 );
308 ImpSetHScrollBarThumbPos();
310 if ( mpVScrollBar )
312 mpVScrollBar->SetVisibleSize( aOutSz.Height() );
313 mpVScrollBar->SetPageSize( aOutSz.Height() * 8 / 10 );
314 mpVScrollBar->SetLineSize( aCharBox.Height() );
315 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
320 void ImpVclMEdit::ImpSetHScrollBarThumbPos()
322 long nX = mpTextWindow->GetTextView()->GetStartDocPos().X();
323 if ( !mpTextWindow->GetTextEngine()->IsRightToLeft() )
324 mpHScrollBar->SetThumbPos( nX );
325 else
326 mpHScrollBar->SetThumbPos( mnTextWidth - mpHScrollBar->GetVisibleSize() - nX );
330 IMPL_LINK( ImpVclMEdit, ScrollHdl, ScrollBar*, pCurScrollBar )
332 long nDiffX = 0, nDiffY = 0;
334 if ( pCurScrollBar == mpVScrollBar )
335 nDiffY = mpTextWindow->GetTextView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
336 else if ( pCurScrollBar == mpHScrollBar )
337 nDiffX = mpTextWindow->GetTextView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
339 mpTextWindow->GetTextView()->Scroll( nDiffX, nDiffY );
340 // mpTextWindow->GetTextView()->ShowCursor( sal_False, sal_True );
342 return 0;
345 void ImpVclMEdit::SetAlign( WinBits nWinStyle )
347 sal_Bool bRTL = Application::GetSettings().GetLayoutRTL();
348 mpTextWindow->GetTextEngine()->SetRightToLeft( bRTL );
350 if ( nWinStyle & WB_CENTER )
351 mpTextWindow->GetTextEngine()->SetTextAlign( TXTALIGN_CENTER );
352 else if ( nWinStyle & WB_RIGHT )
353 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_RIGHT : TXTALIGN_LEFT );
354 else if ( nWinStyle & WB_LEFT )
355 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_LEFT : TXTALIGN_RIGHT );
358 void ImpVclMEdit::SetModified( sal_Bool bMod )
360 mpTextWindow->GetTextEngine()->SetModified( bMod );
363 sal_Bool ImpVclMEdit::IsModified() const
365 return mpTextWindow->GetTextEngine()->IsModified();
368 void ImpVclMEdit::SetReadOnly( sal_Bool bRdOnly )
370 mpTextWindow->GetTextView()->SetReadOnly( bRdOnly );
371 // TODO: Adjust color?
374 sal_Bool ImpVclMEdit::IsReadOnly() const
376 return mpTextWindow->GetTextView()->IsReadOnly();
379 void ImpVclMEdit::SetMaxTextLen( xub_StrLen nLen )
381 mpTextWindow->GetTextEngine()->SetMaxTextLen( nLen );
384 xub_StrLen ImpVclMEdit::GetMaxTextLen() const
386 return sal::static_int_cast< xub_StrLen >(
387 mpTextWindow->GetTextEngine()->GetMaxTextLen());
390 void ImpVclMEdit::InsertText( const String& rStr )
392 mpTextWindow->GetTextView()->InsertText( rStr );
395 String ImpVclMEdit::GetSelected() const
397 return mpTextWindow->GetTextView()->GetSelected();
400 String ImpVclMEdit::GetSelected( LineEnd aSeparator ) const
402 return mpTextWindow->GetTextView()->GetSelected( aSeparator );
405 void ImpVclMEdit::SetMaxTextWidth( sal_uLong nMaxWidth )
407 mpTextWindow->GetTextEngine()->SetMaxTextWidth( nMaxWidth );
410 void ImpVclMEdit::Resize()
412 size_t nIteration = 1;
415 WinBits nWinStyle( pVclMultiLineEdit->GetStyle() );
416 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
417 ImpUpdateSrollBarVis( nWinStyle );
419 Size aSz = pVclMultiLineEdit->GetOutputSizePixel();
420 Size aEditSize = aSz;
421 long nSBWidth = pVclMultiLineEdit->GetSettings().GetStyleSettings().GetScrollBarSize();
422 nSBWidth = pVclMultiLineEdit->CalcZoom( nSBWidth );
424 if ( mpHScrollBar )
425 aSz.Height() -= nSBWidth+1;
426 if ( mpVScrollBar )
427 aSz.Width() -= nSBWidth+1;
429 if ( !mpHScrollBar )
430 mpTextWindow->GetTextEngine()->SetMaxTextWidth( aSz.Width() );
431 else
432 mpHScrollBar->setPosSizePixel( 0, aEditSize.Height()-nSBWidth, aSz.Width(), nSBWidth );
434 Point aTextWindowPos( maTextWindowOffset );
435 if ( mpVScrollBar )
437 if( Application::GetSettings().GetLayoutRTL() )
439 mpVScrollBar->setPosSizePixel( 0, 0, nSBWidth, aSz.Height() );
440 aTextWindowPos.X() += nSBWidth;
442 else
443 mpVScrollBar->setPosSizePixel( aEditSize.Width()-nSBWidth, 0, nSBWidth, aSz.Height() );
446 if ( mpScrollBox )
447 mpScrollBox->setPosSizePixel( aSz.Width(), aSz.Height(), nSBWidth, nSBWidth );
449 Size aTextWindowSize( aSz );
450 aTextWindowSize.Width() -= maTextWindowOffset.X();
451 aTextWindowSize.Height() -= maTextWindowOffset.Y();
452 if ( aTextWindowSize.Width() < 0 )
453 aTextWindowSize.Width() = 0;
454 if ( aTextWindowSize.Height() < 0 )
455 aTextWindowSize.Height() = 0;
457 Size aOldTextWindowSize( mpTextWindow->GetSizePixel() );
458 mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
459 if ( aOldTextWindowSize == aTextWindowSize )
460 break;
462 // Changing the text window size might effectively have changed the need for
463 // scrollbars, so do another iteration.
464 ++nIteration;
465 OSL_ENSURE( nIteration < 3, "ImpVclMEdit::Resize: isn't this expected to terminate with the second iteration?" );
467 } while ( nIteration <= 3 ); // artificial break after four iterations
469 ImpInitScrollBars();
472 void ImpVclMEdit::GetFocus()
474 mpTextWindow->GrabFocus();
477 void ImpVclMEdit::Cut()
479 if ( !mpTextWindow->GetTextView()->IsReadOnly() )
480 mpTextWindow->GetTextView()->Cut();
483 void ImpVclMEdit::Copy()
485 mpTextWindow->GetTextView()->Copy();
488 void ImpVclMEdit::Paste()
490 if ( !mpTextWindow->GetTextView()->IsReadOnly() )
491 mpTextWindow->GetTextView()->Paste();
494 void ImpVclMEdit::SetText( const OUString& rStr )
496 sal_Bool bWasModified = mpTextWindow->GetTextEngine()->IsModified();
497 mpTextWindow->GetTextEngine()->SetText( rStr );
498 if ( !bWasModified )
499 mpTextWindow->GetTextEngine()->SetModified( sal_False );
501 mpTextWindow->GetTextView()->SetSelection( TextSelection() );
503 WinBits nWinStyle( pVclMultiLineEdit->GetStyle() );
504 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
505 ImpUpdateSrollBarVis( nWinStyle );
508 OUString ImpVclMEdit::GetText() const
510 return mpTextWindow->GetTextEngine()->GetText();
513 String ImpVclMEdit::GetText( LineEnd aSeparator ) const
515 return mpTextWindow->GetTextEngine()->GetText( aSeparator );
518 String ImpVclMEdit::GetTextLines( LineEnd aSeparator ) const
520 return mpTextWindow->GetTextEngine()->GetTextLines( aSeparator );
523 void ImpVclMEdit::Notify( SfxBroadcaster&, const SfxHint& rHint )
525 if ( rHint.ISA( TextHint ) )
527 const TextHint& rTextHint = (const TextHint&)rHint;
528 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
530 if ( mpHScrollBar )
531 ImpSetHScrollBarThumbPos();
532 if ( mpVScrollBar )
533 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
535 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
537 if ( mpTextWindow->GetTextView()->GetStartDocPos().Y() )
539 long nOutHeight = mpTextWindow->GetOutputSizePixel().Height();
540 long nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
541 if ( nTextHeight < nOutHeight )
542 mpTextWindow->GetTextView()->Scroll( 0, mpTextWindow->GetTextView()->GetStartDocPos().Y() );
545 ImpSetScrollBarRanges();
547 else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
549 if ( mpHScrollBar )
551 sal_uLong nWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
552 if ( nWidth != mnTextWidth )
554 mnTextWidth = sal::static_int_cast< xub_StrLen >(nWidth);
555 mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
556 ImpSetHScrollBarThumbPos();
560 else if( rTextHint.GetId() == TEXT_HINT_MODIFIED )
562 ImpUpdateSrollBarVis(pVclMultiLineEdit->GetStyle());
563 pVclMultiLineEdit->Modify();
568 void ImpVclMEdit::SetSelection( const Selection& rSelection )
570 String aText = mpTextWindow->GetTextEngine()->GetText();
572 Selection aNewSelection( rSelection );
573 if ( aNewSelection.Min() < 0 )
574 aNewSelection.Min() = 0;
575 else if ( aNewSelection.Min() > aText.Len() )
576 aNewSelection.Min() = aText.Len();
577 if ( aNewSelection.Max() < 0 )
578 aNewSelection.Max() = 0;
579 else if ( aNewSelection.Max() > aText.Len() )
580 aNewSelection.Max() = aText.Len();
582 long nEnd = std::max( aNewSelection.Min(), aNewSelection.Max() );
583 TextSelection aTextSel;
584 sal_uLong nPara = 0;
585 sal_uInt16 nChar = 0;
586 sal_uInt16 x = 0;
587 while ( x <= nEnd )
589 if ( x == aNewSelection.Min() )
590 aTextSel.GetStart() = TextPaM( nPara, nChar );
591 if ( x == aNewSelection.Max() )
592 aTextSel.GetEnd() = TextPaM( nPara, nChar );
594 if ( ( x < aText.Len() ) && ( aText.GetChar( x ) == '\n' ) )
596 nPara++;
597 nChar = 0;
599 else
600 nChar++;
601 x++;
603 mpTextWindow->GetTextView()->SetSelection( aTextSel );
606 const Selection& ImpVclMEdit::GetSelection() const
608 maSelection = Selection();
609 TextSelection aTextSel( mpTextWindow->GetTextView()->GetSelection() );
610 aTextSel.Justify();
611 // flatten selection => every line-break a character
613 ExtTextEngine* pExtTextEngine = mpTextWindow->GetTextEngine();
614 // paragraphs before
615 sal_uLong n;
616 for ( n = 0; n < aTextSel.GetStart().GetPara(); n++ )
618 maSelection.Min() += pExtTextEngine->GetTextLen( n );
619 maSelection.Min()++;
622 // first paragraph with selection
623 maSelection.Max() = maSelection.Min();
624 maSelection.Min() += aTextSel.GetStart().GetIndex();
626 for ( n = aTextSel.GetStart().GetPara(); n < aTextSel.GetEnd().GetPara(); n++ )
628 maSelection.Max() += pExtTextEngine->GetTextLen( n );
629 maSelection.Max()++;
632 maSelection.Max() += aTextSel.GetEnd().GetIndex();
634 return maSelection;
637 Size ImpVclMEdit::CalcMinimumSize() const
639 Size aSz( mpTextWindow->GetTextEngine()->CalcTextWidth(),
640 mpTextWindow->GetTextEngine()->GetTextHeight() );
642 if ( mpHScrollBar )
643 aSz.Height() += mpHScrollBar->GetSizePixel().Height();
644 if ( mpVScrollBar )
645 aSz.Width() += mpVScrollBar->GetSizePixel().Width();
647 return aSz;
650 Size ImpVclMEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
652 static const sal_Unicode sampleChar = 'X';
654 Size aSz;
655 Size aCharSz;
656 aCharSz.Width() = mpTextWindow->GetTextWidth( OUString(sampleChar) );
657 aCharSz.Height() = mpTextWindow->GetTextHeight();
659 if ( nLines )
660 aSz.Height() = nLines*aCharSz.Height();
661 else
662 aSz.Height() = mpTextWindow->GetTextEngine()->GetTextHeight();
664 if ( nColumns )
665 aSz.Width() = nColumns*aCharSz.Width();
666 else
667 aSz.Width() = mpTextWindow->GetTextEngine()->CalcTextWidth();
669 if ( mpHScrollBar )
670 aSz.Height() += mpHScrollBar->GetSizePixel().Height();
671 if ( mpVScrollBar )
672 aSz.Width() += mpVScrollBar->GetSizePixel().Width();
674 return aSz;
677 void ImpVclMEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
679 static const sal_Unicode sampleChar = { 'x' };
680 Size aOutSz = mpTextWindow->GetOutputSizePixel();
681 Size aCharSz( mpTextWindow->GetTextWidth( OUString(sampleChar) ), mpTextWindow->GetTextHeight() );
682 rnCols = (sal_uInt16) (aOutSz.Width()/aCharSz.Width());
683 rnLines = (sal_uInt16) (aOutSz.Height()/aCharSz.Height());
686 void ImpVclMEdit::Enable( sal_Bool bEnable )
688 mpTextWindow->Enable( bEnable );
689 if ( mpHScrollBar )
690 mpHScrollBar->Enable( bEnable );
691 if ( mpVScrollBar )
692 mpVScrollBar->Enable( bEnable );
695 sal_Bool ImpVclMEdit::HandleCommand( const CommandEvent& rCEvt )
697 sal_Bool bDone = sal_False;
698 if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
699 ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
700 ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
702 mpTextWindow->HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
703 bDone = sal_True;
705 return bDone;
709 TextWindow::TextWindow( Window* pParent ) : Window( pParent )
711 mbInMBDown = false;
712 mbFocusSelectionHide = sal_False;
713 mbIgnoreTab = sal_False;
714 mbActivePopup = sal_False;
715 mbSelectOnTab = sal_True;
716 mbTextSelectable = sal_True;
718 SetPointer( Pointer( POINTER_TEXT ) );
720 mpExtTextEngine = new ExtTextEngine;
721 mpExtTextEngine->SetMaxTextLen( STRING_MAXLEN );
722 if( pParent->GetStyle() & WB_BORDER )
723 mpExtTextEngine->SetLeftMargin( 2 );
724 mpExtTextEngine->SetLocale( GetSettings().GetLanguageTag().getLocale() );
725 mpExtTextView = new ExtTextView( mpExtTextEngine, this );
726 mpExtTextEngine->InsertView( mpExtTextView );
727 mpExtTextEngine->EnableUndo( sal_True );
728 mpExtTextView->ShowCursor();
730 Color aBackgroundColor = GetSettings().GetStyleSettings().GetWorkspaceColor();
731 SetBackground( aBackgroundColor );
732 pParent->SetBackground( aBackgroundColor );
735 TextWindow::~TextWindow()
737 delete mpExtTextView;
738 delete mpExtTextEngine;
741 void TextWindow::MouseMove( const MouseEvent& rMEvt )
743 mpExtTextView->MouseMove( rMEvt );
744 Window::MouseMove( rMEvt );
747 void TextWindow::MouseButtonDown( const MouseEvent& rMEvt )
749 if ( !mbTextSelectable )
750 return;
752 mbInMBDown = true; // so that GetFocus does not select everything
753 mpExtTextView->MouseButtonDown( rMEvt );
754 Window::MouseButtonDown( rMEvt );
755 GrabFocus();
756 mbInMBDown = false;
759 void TextWindow::MouseButtonUp( const MouseEvent& rMEvt )
761 mpExtTextView->MouseButtonUp( rMEvt );
762 Window::MouseButtonUp( rMEvt );
765 void TextWindow::KeyInput( const KeyEvent& rKEvent )
767 sal_Bool bDone = sal_False;
768 sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
769 if ( nCode == com::sun::star::awt::Key::SELECT_ALL ||
770 ( (nCode == KEY_A) && rKEvent.GetKeyCode().IsMod1() && !rKEvent.GetKeyCode().IsMod2() )
773 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
774 bDone = sal_True;
776 else if ( (nCode == KEY_S) && rKEvent.GetKeyCode().IsShift() && rKEvent.GetKeyCode().IsMod1() )
778 if ( Edit::GetGetSpecialCharsFunction() )
780 // to maintain the selection
781 mbActivePopup = sal_True;
782 OUString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
783 if (!aChars.isEmpty())
785 mpExtTextView->InsertText( aChars );
786 mpExtTextView->GetTextEngine()->SetModified( sal_True );
788 mbActivePopup = sal_False;
789 bDone = sal_True;
792 else if ( nCode == KEY_TAB )
794 if ( !mbIgnoreTab || rKEvent.GetKeyCode().IsMod1() )
795 bDone = mpExtTextView->KeyInput( rKEvent );
797 else
799 bDone = mpExtTextView->KeyInput( rKEvent );
802 if ( !bDone )
803 Window::KeyInput( rKEvent );
806 void TextWindow::Paint( const Rectangle& rRect )
808 mpExtTextView->Paint( rRect );
811 void TextWindow::Resize()
815 void TextWindow::Command( const CommandEvent& rCEvt )
817 if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
819 PopupMenu* pPopup = Edit::CreatePopupMenu();
820 if ( !mpExtTextView->HasSelection() )
822 pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False );
823 pPopup->EnableItem( SV_MENU_EDIT_COPY, sal_False );
824 pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False );
826 if ( mpExtTextView->IsReadOnly() )
828 pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False );
829 pPopup->EnableItem( SV_MENU_EDIT_PASTE, sal_False );
830 pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False );
831 pPopup->EnableItem( SV_MENU_EDIT_INSERTSYMBOL, sal_False );
833 if ( !mpExtTextView->GetTextEngine()->HasUndoManager() || !mpExtTextView->GetTextEngine()->GetUndoManager().GetUndoActionCount() )
835 pPopup->EnableItem( SV_MENU_EDIT_UNDO, sal_False );
837 // if ( ( maSelection.Min() == 0 ) && ( maSelection.Max() == maText.Len() ) )
838 // {
839 // pPopup->EnableItem( SV_MENU_EDIT_SELECTALL, sal_False );
840 // }
841 if ( !Edit::GetGetSpecialCharsFunction() )
843 sal_uInt16 nPos = pPopup->GetItemPos( SV_MENU_EDIT_INSERTSYMBOL );
844 pPopup->RemoveItem( nPos );
845 pPopup->RemoveItem( nPos-1 );
848 mbActivePopup = sal_True;
849 Point aPos = rCEvt.GetMousePosPixel();
850 if ( !rCEvt.IsMouseEvent() )
852 // Sometime do show Menu centered in the selection !!!
853 Size aSize = GetOutputSizePixel();
854 aPos = Point( aSize.Width()/2, aSize.Height()/2 );
856 // pPopup->RemoveDisabledEntries();
857 sal_uInt16 n = pPopup->Execute( this, aPos );
858 Edit::DeletePopupMenu( pPopup );
859 switch ( n )
861 case SV_MENU_EDIT_UNDO: mpExtTextView->Undo();
862 mpExtTextEngine->SetModified( sal_True );
863 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
864 break;
865 case SV_MENU_EDIT_CUT: mpExtTextView->Cut();
866 mpExtTextEngine->SetModified( sal_True );
867 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
868 break;
869 case SV_MENU_EDIT_COPY: mpExtTextView->Copy();
870 break;
871 case SV_MENU_EDIT_PASTE: mpExtTextView->Paste();
872 mpExtTextEngine->SetModified( sal_True );
873 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
874 break;
875 case SV_MENU_EDIT_DELETE: mpExtTextView->DeleteSelected();
876 mpExtTextEngine->SetModified( sal_True );
877 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
878 break;
879 case SV_MENU_EDIT_SELECTALL: mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
880 break;
881 case SV_MENU_EDIT_INSERTSYMBOL:
883 OUString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
884 if (!aChars.isEmpty())
886 mpExtTextView->InsertText( aChars );
887 mpExtTextEngine->SetModified( sal_True );
888 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
891 break;
893 mbActivePopup = sal_False;
895 else
897 mpExtTextView->Command( rCEvt );
899 Window::Command( rCEvt );
902 void TextWindow::GetFocus()
904 Window::GetFocus();
905 if ( !mbActivePopup )
907 sal_Bool bGotoCursor = !mpExtTextView->IsReadOnly();
908 if ( mbFocusSelectionHide && IsReallyVisible() && !mpExtTextView->IsReadOnly()
909 && ( mbSelectOnTab &&
910 (!mbInMBDown || ( GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_FOCUS ) )) )
912 // select everything, but do not scroll
913 sal_Bool bAutoScroll = mpExtTextView->IsAutoScroll();
914 mpExtTextView->SetAutoScroll( sal_False );
915 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
916 mpExtTextView->SetAutoScroll( bAutoScroll );
917 bGotoCursor = sal_False;
919 mpExtTextView->SetPaintSelection( sal_True );
920 mpExtTextView->ShowCursor( bGotoCursor );
924 void TextWindow::LoseFocus()
926 Window::LoseFocus();
928 if ( mbFocusSelectionHide && !mbActivePopup )
929 mpExtTextView->SetPaintSelection( sal_False );
932 VclMultiLineEdit::VclMultiLineEdit( Window* pParent, WinBits nWinStyle )
933 : Edit( pParent, nWinStyle )
935 SetType( WINDOW_MULTILINEEDIT );
936 pImpVclMEdit = new ImpVclMEdit( this, nWinStyle );
937 ImplInitSettings( sal_True, sal_True, sal_True );
938 pUpdateDataTimer = 0;
940 SetCompoundControl( sal_True );
941 SetStyle( ImplInitStyle( nWinStyle ) );
944 VclMultiLineEdit::VclMultiLineEdit( Window* pParent, const ResId& rResId )
945 : Edit( pParent, rResId.SetRT( RSC_MULTILINEEDIT ) )
947 SetType( WINDOW_MULTILINEEDIT );
948 WinBits nWinStyle = rResId.GetWinBits();
949 pImpVclMEdit = new ImpVclMEdit( this, nWinStyle );
950 ImplInitSettings( sal_True, sal_True, sal_True );
951 pUpdateDataTimer = 0;
953 sal_uInt16 nMaxLen = Edit::GetMaxTextLen();
954 if ( nMaxLen )
955 SetMaxTextLen( nMaxLen );
957 SetText( Edit::GetText() );
959 if ( IsVisible() )
960 pImpVclMEdit->Resize();
962 SetCompoundControl( sal_True );
963 SetStyle( ImplInitStyle( nWinStyle ) );
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 if ((GetStyle() & WB_HIDE) == 0)
970 Show();
974 VclMultiLineEdit::~VclMultiLineEdit()
977 ::std::auto_ptr< ImpVclMEdit > pDelete( pImpVclMEdit );
978 pImpVclMEdit = NULL;
980 delete pUpdateDataTimer;
983 WinBits VclMultiLineEdit::ImplInitStyle( WinBits nStyle )
985 if ( !(nStyle & WB_NOTABSTOP) )
986 nStyle |= WB_TABSTOP;
988 if ( !(nStyle & WB_NOGROUP) )
989 nStyle |= WB_GROUP;
991 if ( !(nStyle & WB_IGNORETAB ))
992 nStyle |= WINDOW_DLGCTRL_MOD1TAB;
994 return nStyle;
998 void VclMultiLineEdit::ImplInitSettings( sal_Bool /*bFont*/, sal_Bool /*bForeground*/, sal_Bool bBackground )
1000 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1002 // The Font has to be adjusted, as the TextEngine does not take care of
1003 // TextColor/Background
1005 Color aTextColor = rStyleSettings.GetFieldTextColor();
1006 if ( IsControlForeground() )
1007 aTextColor = GetControlForeground();
1008 if ( !IsEnabled() )
1009 aTextColor = rStyleSettings.GetDisableColor();
1011 Font aFont = rStyleSettings.GetFieldFont();
1012 if ( IsControlFont() )
1013 aFont.Merge( GetControlFont() );
1014 aFont.SetTransparent( IsPaintTransparent() );
1015 SetZoomedPointFont( aFont );
1016 Font TheFont = GetFont();
1017 TheFont.SetColor( aTextColor );
1018 if( IsPaintTransparent() )
1019 TheFont.SetFillColor( Color( COL_TRANSPARENT ) );
1020 else
1021 TheFont.SetFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() );
1022 pImpVclMEdit->GetTextWindow()->SetFont( TheFont );
1023 pImpVclMEdit->GetTextWindow()->GetTextEngine()->SetFont( TheFont );
1024 pImpVclMEdit->GetTextWindow()->SetTextColor( aTextColor );
1026 if ( bBackground )
1028 if( IsPaintTransparent() )
1030 pImpVclMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
1031 pImpVclMEdit->GetTextWindow()->SetBackground();
1032 pImpVclMEdit->GetTextWindow()->SetControlBackground();
1033 SetBackground();
1034 SetControlBackground();
1036 else
1038 if( IsControlBackground() )
1039 pImpVclMEdit->GetTextWindow()->SetBackground( GetControlBackground() );
1040 else
1041 pImpVclMEdit->GetTextWindow()->SetBackground( rStyleSettings.GetFieldColor() );
1042 // also adjust for VclMultiLineEdit as the TextComponent might hide Scrollbars
1043 SetBackground( pImpVclMEdit->GetTextWindow()->GetBackground() );
1048 void VclMultiLineEdit::Modify()
1050 aModifyHdlLink.Call( this );
1052 CallEventListeners( VCLEVENT_EDIT_MODIFY );
1054 if ( pUpdateDataTimer )
1055 pUpdateDataTimer->Start();
1058 IMPL_LINK_NOARG(VclMultiLineEdit, ImpUpdateDataHdl)
1060 UpdateData();
1061 return 0;
1064 void VclMultiLineEdit::UpdateData()
1066 aUpdateDataHdlLink.Call( this );
1069 void VclMultiLineEdit::SetModifyFlag()
1071 pImpVclMEdit->SetModified( sal_True );
1074 void VclMultiLineEdit::ClearModifyFlag()
1076 pImpVclMEdit->SetModified( sal_False );
1079 sal_Bool VclMultiLineEdit::IsModified() const
1081 return pImpVclMEdit->IsModified();
1084 void VclMultiLineEdit::EnableUpdateData( sal_uLong nTimeout )
1086 if ( !nTimeout )
1087 DisableUpdateData();
1088 else
1090 if ( !pUpdateDataTimer )
1092 pUpdateDataTimer = new Timer;
1093 pUpdateDataTimer->SetTimeoutHdl( LINK( this, VclMultiLineEdit, ImpUpdateDataHdl ) );
1095 pUpdateDataTimer->SetTimeout( nTimeout );
1099 void VclMultiLineEdit::SetReadOnly( sal_Bool bReadOnly )
1101 pImpVclMEdit->SetReadOnly( bReadOnly );
1102 Edit::SetReadOnly( bReadOnly );
1104 // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set.
1105 WinBits nStyle = GetStyle();
1106 if ( bReadOnly )
1107 nStyle |= WB_READONLY;
1108 else
1109 nStyle &= ~WB_READONLY;
1110 SetStyle( nStyle );
1113 sal_Bool VclMultiLineEdit::IsReadOnly() const
1115 return pImpVclMEdit->IsReadOnly();
1118 void VclMultiLineEdit::SetMaxTextLen( xub_StrLen nMaxLen )
1120 pImpVclMEdit->SetMaxTextLen( nMaxLen );
1123 void VclMultiLineEdit::SetMaxTextWidth( sal_uLong nMaxWidth )
1125 pImpVclMEdit->SetMaxTextWidth(nMaxWidth );
1128 xub_StrLen VclMultiLineEdit::GetMaxTextLen() const
1130 return pImpVclMEdit->GetMaxTextLen();
1133 void VclMultiLineEdit::ReplaceSelected( const OUString& rStr )
1135 pImpVclMEdit->InsertText( rStr );
1138 void VclMultiLineEdit::DeleteSelected()
1140 pImpVclMEdit->InsertText( String() );
1143 OUString VclMultiLineEdit::GetSelected() const
1145 return pImpVclMEdit->GetSelected();
1148 OUString VclMultiLineEdit::GetSelected( LineEnd aSeparator ) const
1150 return pImpVclMEdit->GetSelected( aSeparator );
1153 void VclMultiLineEdit::Cut()
1155 pImpVclMEdit->Cut();
1158 void VclMultiLineEdit::Copy()
1160 pImpVclMEdit->Copy();
1163 void VclMultiLineEdit::Paste()
1165 pImpVclMEdit->Paste();
1168 void VclMultiLineEdit::SetText( const OUString& rStr )
1170 pImpVclMEdit->SetText( rStr );
1173 OUString VclMultiLineEdit::GetText() const
1175 return pImpVclMEdit->GetText();
1178 OUString VclMultiLineEdit::GetText( LineEnd aSeparator ) const
1180 return pImpVclMEdit->GetText( aSeparator );
1183 String VclMultiLineEdit::GetTextLines( LineEnd aSeparator ) const
1185 return pImpVclMEdit->GetTextLines( aSeparator );
1188 void VclMultiLineEdit::Resize()
1190 pImpVclMEdit->Resize();
1193 void VclMultiLineEdit::GetFocus()
1195 if ( !pImpVclMEdit ) // might be called from within the dtor, when pImpVclMEdit == NULL is a valid state
1196 return;
1198 Edit::GetFocus();
1199 pImpVclMEdit->GetFocus();
1202 void VclMultiLineEdit::SetSelection( const Selection& rSelection )
1204 pImpVclMEdit->SetSelection( rSelection );
1207 const Selection& VclMultiLineEdit::GetSelection() const
1209 return pImpVclMEdit->GetSelection();
1212 Size VclMultiLineEdit::CalcMinimumSize() const
1214 Size aSz = pImpVclMEdit->CalcMinimumSize();
1216 sal_Int32 nLeft, nTop, nRight, nBottom;
1217 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1218 aSz.Width() += nLeft+nRight;
1219 aSz.Height() += nTop+nBottom;
1221 return aSz;
1224 Size VclMultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const
1226 Size aSz = rPrefSize;
1227 sal_Int32 nLeft, nTop, nRight, nBottom;
1228 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1230 // center vertically for whole lines
1232 long nHeight = aSz.Height() - nTop - nBottom;
1233 long nLineHeight = pImpVclMEdit->CalcSize( 1, 1 ).Height();
1234 long nLines = nHeight / nLineHeight;
1235 if ( nLines < 1 )
1236 nLines = 1;
1238 aSz.Height() = nLines * nLineHeight;
1239 aSz.Height() += nTop+nBottom;
1241 return aSz;
1244 Size VclMultiLineEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
1246 Size aSz = pImpVclMEdit->CalcSize( nColumns, nLines );
1248 sal_Int32 nLeft, nTop, nRight, nBottom;
1249 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1250 aSz.Width() += nLeft+nRight;
1251 aSz.Height() += nTop+nBottom;
1252 return aSz;
1255 void VclMultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
1257 pImpVclMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines );
1260 void VclMultiLineEdit::StateChanged( StateChangedType nType )
1262 if( nType == STATE_CHANGE_ENABLE )
1264 pImpVclMEdit->Enable( IsEnabled() );
1265 ImplInitSettings( sal_True, sal_False, sal_False );
1267 else if( nType == STATE_CHANGE_READONLY )
1269 pImpVclMEdit->SetReadOnly( IsReadOnly() );
1271 else if ( nType == STATE_CHANGE_ZOOM )
1273 pImpVclMEdit->GetTextWindow()->SetZoom( GetZoom() );
1274 ImplInitSettings( sal_True, sal_False, sal_False );
1275 Resize();
1277 else if ( nType == STATE_CHANGE_CONTROLFONT )
1279 ImplInitSettings( sal_True, sal_False, sal_False );
1280 Resize();
1281 Invalidate();
1283 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1285 ImplInitSettings( sal_False, sal_True, sal_False );
1286 Invalidate();
1288 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1290 ImplInitSettings( sal_False, sal_False, sal_True );
1291 Invalidate();
1293 else if ( nType == STATE_CHANGE_STYLE )
1295 pImpVclMEdit->InitFromStyle( GetStyle() );
1296 SetStyle( ImplInitStyle( GetStyle() ) );
1298 else if ( nType == STATE_CHANGE_INITSHOW )
1300 if( IsPaintTransparent() )
1302 pImpVclMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
1303 pImpVclMEdit->GetTextWindow()->SetBackground();
1304 pImpVclMEdit->GetTextWindow()->SetControlBackground();
1305 SetBackground();
1306 SetControlBackground();
1310 Control::StateChanged( nType );
1313 void VclMultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt )
1315 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1316 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1318 ImplInitSettings( sal_True, sal_True, sal_True );
1319 Resize();
1320 Invalidate();
1322 else
1323 Control::DataChanged( rDCEvt );
1326 void VclMultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
1328 ImplInitSettings( sal_True, sal_True, sal_True );
1330 Point aPos = pDev->LogicToPixel( rPos );
1331 Size aSize = pDev->LogicToPixel( rSize );
1332 Font aFont = pImpVclMEdit->GetTextWindow()->GetDrawPixelFont( pDev );
1333 aFont.SetTransparent( sal_True );
1334 OutDevType eOutDevType = pDev->GetOutDevType();
1336 pDev->Push();
1337 pDev->SetMapMode();
1338 pDev->SetFont( aFont );
1339 pDev->SetTextFillColor();
1341 // Border/Background
1342 pDev->SetLineColor();
1343 pDev->SetFillColor();
1344 bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
1345 bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
1346 if ( bBorder || bBackground )
1348 Rectangle aRect( aPos, aSize );
1349 if ( bBorder )
1351 DecorationView aDecoView( pDev );
1352 aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
1354 if ( bBackground )
1356 pDev->SetFillColor( GetControlBackground() );
1357 pDev->DrawRect( aRect );
1361 // contents
1362 if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
1363 pDev->SetTextColor( Color( COL_BLACK ) );
1364 else
1366 if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
1368 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1369 pDev->SetTextColor( rStyleSettings.GetDisableColor() );
1371 else
1373 pDev->SetTextColor( GetTextColor() );
1377 OUString aText = GetText();
1378 Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() );
1379 sal_uLong nLines = (sal_uLong) (aSize.Height() / aTextSz.Height());
1380 if ( !nLines )
1381 nLines = 1;
1382 aTextSz.Height() = nLines*aTextSz.Height();
1383 long nOnePixel = GetDrawPixel( pDev, 1 );
1384 long nOffX = 3*nOnePixel;
1385 long nOffY = 2*nOnePixel;
1387 // Clipping?
1388 if ( ( nOffY < 0 ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) )
1390 Rectangle aClip( aPos, aSize );
1391 if ( aTextSz.Height() > aSize.Height() )
1392 aClip.Bottom() += aTextSz.Height() - aSize.Height() + 1; // so that HP-printer does not 'optimize-away'
1393 pDev->IntersectClipRegion( aClip );
1396 ExtTextEngine aTE;
1397 aTE.SetText( GetText() );
1398 aTE.SetMaxTextWidth( aSize.Width() );
1399 aTE.SetFont( aFont );
1400 aTE.SetTextAlign( pImpVclMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() );
1401 aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) );
1403 pDev->Pop();
1406 long VclMultiLineEdit::Notify( NotifyEvent& rNEvt )
1408 long nDone = 0;
1409 if( rNEvt.GetType() == EVENT_COMMAND )
1411 nDone = pImpVclMEdit->HandleCommand( *rNEvt.GetCommandEvent() );
1413 return nDone ? nDone : Edit::Notify( rNEvt );
1416 long VclMultiLineEdit::PreNotify( NotifyEvent& rNEvt )
1418 long nDone = 0;
1420 #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL)
1421 if( rNEvt.GetType() == EVENT_KEYINPUT )
1423 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1424 if ( ( rKEvent.GetKeyCode().GetCode() == KEY_W ) && rKEvent.GetKeyCode().IsMod1() && rKEvent.GetKeyCode().IsMod2() )
1426 SetRightToLeft( !IsRightToLeft() );
1429 #endif
1431 if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) )
1433 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1434 if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) )
1436 nDone = 1;
1437 TextSelection aSel = pImpVclMEdit->GetTextWindow()->GetTextView()->GetSelection();
1438 if ( aSel.HasRange() )
1440 aSel.GetStart() = aSel.GetEnd();
1441 pImpVclMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel );
1443 else
1445 switch ( rKEvent.GetKeyCode().GetCode() )
1447 case KEY_UP:
1449 if ( pImpVclMEdit->GetVScrollBar() )
1450 pImpVclMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEUP );
1452 break;
1453 case KEY_DOWN:
1455 if ( pImpVclMEdit->GetVScrollBar() )
1456 pImpVclMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1458 break;
1459 case KEY_PAGEUP :
1461 if ( pImpVclMEdit->GetVScrollBar() )
1462 pImpVclMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEUP );
1464 break;
1465 case KEY_PAGEDOWN:
1467 if ( pImpVclMEdit->GetVScrollBar() )
1468 pImpVclMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEDOWN );
1470 break;
1471 case KEY_LEFT:
1473 if ( pImpVclMEdit->GetHScrollBar() )
1474 pImpVclMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEUP );
1476 break;
1477 case KEY_RIGHT:
1479 if ( pImpVclMEdit->GetHScrollBar() )
1480 pImpVclMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1482 break;
1483 case KEY_HOME:
1485 if ( rKEvent.GetKeyCode().IsMod1() )
1486 pImpVclMEdit->GetTextWindow()->GetTextView()->
1487 SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
1489 break;
1490 case KEY_END:
1492 if ( rKEvent.GetKeyCode().IsMod1() )
1493 pImpVclMEdit->GetTextWindow()->GetTextView()->
1494 SetSelection( TextSelection( TextPaM( 0xFFFF, 0xFFFF ) ) );
1496 break;
1497 default:
1499 nDone = 0;
1506 return nDone ? nDone : Edit::PreNotify( rNEvt );
1510 // Internals for derived classes, e.g. TextComponent
1512 ExtTextEngine* VclMultiLineEdit::GetTextEngine() const
1514 return pImpVclMEdit->GetTextWindow()->GetTextEngine();
1517 ExtTextView* VclMultiLineEdit::GetTextView() const
1519 return pImpVclMEdit->GetTextWindow()->GetTextView();
1522 ScrollBar* VclMultiLineEdit::GetVScrollBar() const
1524 return pImpVclMEdit->GetVScrollBar();
1527 void VclMultiLineEdit::EnableFocusSelectionHide( sal_Bool bHide )
1529 pImpVclMEdit->GetTextWindow()->SetAutoFocusHide( bHide );
1532 void VclMultiLineEdit::SetLeftMargin( sal_uInt16 n )
1534 if ( GetTextEngine() )
1535 GetTextEngine()->SetLeftMargin( n );
1538 void VclMultiLineEdit::SetRightToLeft( sal_Bool bRightToLeft )
1540 if ( GetTextEngine() )
1542 GetTextEngine()->SetRightToLeft( bRightToLeft );
1543 GetTextView()->ShowCursor();
1547 sal_Bool VclMultiLineEdit::IsRightToLeft() const
1549 sal_Bool bRightToLeft = sal_False;
1551 if ( GetTextEngine() )
1552 bRightToLeft = GetTextEngine()->IsRightToLeft();
1554 return bRightToLeft;
1557 void VclMultiLineEdit::DisableSelectionOnFocus()
1559 pImpVclMEdit->GetTextWindow()->DisableSelectionOnFocus();
1562 void VclMultiLineEdit::SetTextSelectable( sal_Bool bTextSelectable )
1564 pImpVclMEdit->GetTextWindow()->SetTextSelectable( bTextSelectable );
1567 void VclMultiLineEdit::EnableCursor( sal_Bool bEnable )
1569 GetTextView()->EnableCursor( bEnable );
1572 bool VclMultiLineEdit::set_property(const OString &rKey, const OString &rValue)
1574 if (rKey == "cursor-visible")
1575 EnableCursor(toBool(rValue));
1576 else
1577 return Edit::set_property(rKey, rValue);
1578 return true;
1581 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */