update dev300-m57
[ooovba.git] / svtools / source / edit / svmedit.cxx
blob6cfc74bdd42009b59775c1aa26303809e75e6499
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svmedit.cxx,v $
10 * $Revision: 1.44.108.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
35 #include <memory>
37 #include "unoiface.hxx"
39 #include <tools/rc.h>
41 #include <vcl/decoview.hxx>
42 #include <vcl/svapp.hxx>
44 #include <svtools/svmedit.hxx>
45 #include <svtools/xtextedt.hxx>
46 #include <svtools/brdcst.hxx>
47 #include <svtools/undo.hxx>
48 #include <svtools/textwindowpeer.hxx>
49 #include <svtools/lstner.hxx>
50 #include <svtools/smplhint.hxx>
53 // IDs erstmal aus VCL geklaut, muss mal richtig delivert werden...
54 #define SV_MENU_EDIT_UNDO 1
55 #define SV_MENU_EDIT_CUT 2
56 #define SV_MENU_EDIT_COPY 3
57 #define SV_MENU_EDIT_PASTE 4
58 #define SV_MENU_EDIT_DELETE 5
59 #define SV_MENU_EDIT_SELECTALL 6
60 #define SV_MENU_EDIT_INSERTSYMBOL 7
61 #include <vcl/scrbar.hxx>
63 namespace css = ::com::sun::star;
65 class TextWindow : public Window
67 private:
68 ExtTextEngine* mpExtTextEngine;
69 ExtTextView* mpExtTextView;
71 BOOL mbInMBDown;
72 BOOL mbFocusSelectionHide;
73 BOOL mbIgnoreTab;
74 BOOL mbActivePopup;
75 BOOL mbSelectOnTab;
77 public:
78 TextWindow( Window* pParent );
79 ~TextWindow();
81 ExtTextEngine* GetTextEngine() const { return mpExtTextEngine; }
82 ExtTextView* GetTextView() const { return mpExtTextView; }
84 virtual void MouseMove( const MouseEvent& rMEvt );
85 virtual void MouseButtonDown( const MouseEvent& rMEvt );
86 virtual void MouseButtonUp( const MouseEvent& rMEvt );
87 virtual void KeyInput( const KeyEvent& rKEvent );
89 virtual void Command( const CommandEvent& rCEvt );
91 virtual void Paint( const Rectangle& rRect );
92 virtual void Resize();
94 virtual void GetFocus();
95 virtual void LoseFocus();
97 BOOL IsAutoFocusHide() const { return mbFocusSelectionHide; }
98 void SetAutoFocusHide( BOOL bAutoHide ) { mbFocusSelectionHide = bAutoHide; }
100 BOOL IsIgnoreTab() const { return mbIgnoreTab; }
101 void SetIgnoreTab( BOOL bIgnore ) { mbIgnoreTab = bIgnore; }
103 void DisableSelectionOnFocus() {mbSelectOnTab = sal_False;}
105 virtual
106 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >
107 GetComponentInterface(BOOL bCreate = TRUE);
111 class ImpSvMEdit : public SfxListener
113 private:
114 MultiLineEdit* pSvMultiLineEdit;
116 TextWindow* mpTextWindow;
117 ScrollBar* mpHScrollBar;
118 ScrollBar* mpVScrollBar;
119 ScrollBarBox* mpScrollBox;
121 Point maTextWindowOffset;
122 xub_StrLen mnTextWidth;
123 mutable Selection maSelection;
125 protected:
126 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
127 void ImpUpdateSrollBarVis( WinBits nWinStyle );
128 void ImpInitScrollBars();
129 void ImpSetScrollBarRanges();
130 void ImpSetHScrollBarThumbPos();
131 DECL_LINK( ScrollHdl, ScrollBar* );
133 public:
134 ImpSvMEdit( MultiLineEdit* pSvMultiLineEdit, WinBits nWinStyle );
135 ~ImpSvMEdit();
137 void SetModified( BOOL bMod );
138 BOOL IsModified() const;
140 void SetReadOnly( BOOL bRdOnly );
141 BOOL IsReadOnly() const;
143 void SetMaxTextLen( xub_StrLen nLen );
144 xub_StrLen GetMaxTextLen() const;
146 void SetInsertMode( BOOL bInsert );
147 BOOL IsInsertMode() const;
149 void InsertText( const String& rStr );
150 String GetSelected() const;
151 String GetSelected( LineEnd aSeparator ) const;
153 void SetSelection( const Selection& rSelection );
154 const Selection& GetSelection() const;
156 void Cut();
157 void Copy();
158 void Paste();
160 void SetText( const String& rStr );
161 String GetText() const;
162 String GetText( LineEnd aSeparator ) const;
163 String GetTextLines() const;
164 String GetTextLines( LineEnd aSeparator ) const;
166 void Resize();
167 void GetFocus();
169 BOOL HandleCommand( const CommandEvent& rCEvt );
171 void Enable( BOOL bEnable );
173 Size CalcMinimumSize() const;
174 Size CalcSize( USHORT nColumns, USHORT nLines ) const;
175 void GetMaxVisColumnsAndLines( USHORT& rnCols, USHORT& rnLines ) const;
177 void SetAlign( WinBits nWinStyle );
179 void InitFromStyle( WinBits nWinStyle );
181 TextWindow* GetTextWindow() { return mpTextWindow; }
182 ScrollBar* GetHScrollBar() { return mpHScrollBar; }
183 ScrollBar* GetVScrollBar() { return mpVScrollBar; }
185 void SetTextWindowOffset( const Point& rOffset );
188 ImpSvMEdit::ImpSvMEdit( MultiLineEdit* pEdt, WinBits nWinStyle )
189 :mpHScrollBar(NULL)
190 ,mpVScrollBar(NULL)
191 ,mpScrollBox(NULL)
193 pSvMultiLineEdit = pEdt;
194 mnTextWidth = 0;
195 mpTextWindow = new TextWindow( pEdt );
196 mpTextWindow->Show();
197 InitFromStyle( nWinStyle );
198 StartListening( *mpTextWindow->GetTextEngine() );
201 void ImpSvMEdit::ImpUpdateSrollBarVis( WinBits nWinStyle )
203 const BOOL bHaveVScroll = (NULL != mpVScrollBar);
204 const BOOL bHaveHScroll = (NULL != mpHScrollBar);
205 const BOOL bHaveScrollBox = (NULL != mpScrollBox);
207 BOOL bNeedVScroll = ( nWinStyle & WB_VSCROLL ) == WB_VSCROLL;
208 const BOOL bNeedHScroll = ( nWinStyle & WB_HSCROLL ) == WB_HSCROLL;
210 const BOOL bAutoVScroll = ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL;
211 if ( !bNeedVScroll && bAutoVScroll )
213 TextEngine& rEngine( *mpTextWindow->GetTextEngine() );
214 ULONG nOverallTextHeight(0);
215 for ( ULONG i=0; i<rEngine.GetParagraphCount(); ++i )
216 nOverallTextHeight += rEngine.GetTextHeight( i );
217 if ( nOverallTextHeight > (ULONG)mpTextWindow->GetOutputSizePixel().Height() )
218 bNeedVScroll = true;
221 const BOOL bNeedScrollBox = bNeedVScroll && bNeedHScroll;
223 BOOL bScrollbarsChanged = false;
224 if ( bHaveVScroll != bNeedVScroll )
226 delete mpVScrollBar;
227 mpVScrollBar = bNeedVScroll ? new ScrollBar( pSvMultiLineEdit, WB_VSCROLL|WB_DRAG ) : NULL;
229 if ( bNeedVScroll )
231 mpVScrollBar->Show();
232 mpVScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) );
235 bScrollbarsChanged = sal_True;
238 if ( bHaveHScroll != bNeedHScroll )
240 delete mpHScrollBar;
241 mpHScrollBar = bNeedHScroll ? new ScrollBar( pSvMultiLineEdit, WB_HSCROLL|WB_DRAG ) : NULL;
243 if ( bNeedHScroll )
245 mpHScrollBar->Show();
246 mpHScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) );
249 bScrollbarsChanged = sal_True;
252 if ( bHaveScrollBox != bNeedScrollBox )
254 delete mpScrollBox;
255 mpScrollBox = bNeedScrollBox ? new ScrollBarBox( pSvMultiLineEdit, WB_SIZEABLE ) : NULL;
257 if ( bNeedScrollBox )
258 mpScrollBox->Show();
261 if ( bScrollbarsChanged )
263 ImpInitScrollBars();
264 Resize();
268 void ImpSvMEdit::InitFromStyle( WinBits nWinStyle )
270 ImpUpdateSrollBarVis( nWinStyle );
271 SetAlign( nWinStyle );
273 if ( nWinStyle & WB_NOHIDESELECTION )
274 mpTextWindow->SetAutoFocusHide( FALSE );
275 else
276 mpTextWindow->SetAutoFocusHide( TRUE );
278 if ( nWinStyle & WB_READONLY )
279 mpTextWindow->GetTextView()->SetReadOnly( TRUE );
280 else
281 mpTextWindow->GetTextView()->SetReadOnly( FALSE );
283 if ( nWinStyle & WB_IGNORETAB )
285 mpTextWindow->SetIgnoreTab( TRUE );
287 else
289 mpTextWindow->SetIgnoreTab( FALSE );
290 // #103667# MultiLineEdit has the flag, but focusable window also needs this flag
291 WinBits nStyle = mpTextWindow->GetStyle();
292 nStyle |= WINDOW_DLGCTRL_MOD1TAB;
293 mpTextWindow->SetStyle( nStyle );
297 ImpSvMEdit::~ImpSvMEdit()
299 EndListening( *mpTextWindow->GetTextEngine() );
300 delete mpTextWindow;
301 delete mpHScrollBar;
302 delete mpVScrollBar;
303 delete mpScrollBox;
306 void ImpSvMEdit::ImpSetScrollBarRanges()
308 if ( mpVScrollBar )
310 ULONG nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
311 mpVScrollBar->SetRange( Range( 0, (long)nTextHeight-1 ) );
313 if ( mpHScrollBar )
315 // ULONG nTextWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
316 // Es gibt kein Notify bei Breiten-Aenderung...
317 // ULONG nW = Max( (ULONG)mpTextWindow->GetOutputSizePixel().Width()*5, (ULONG)nTextWidth );
318 // mpHScrollBar->SetRange( Range( 0, (long)nW ) );
319 mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
323 void ImpSvMEdit::ImpInitScrollBars()
325 static const sal_Unicode sampleText[] = { 'x', '\0' };
326 if ( mpHScrollBar || mpVScrollBar )
328 ImpSetScrollBarRanges();
329 Size aCharBox;
330 aCharBox.Width() = mpTextWindow->GetTextWidth( sampleText );
331 aCharBox.Height() = mpTextWindow->GetTextHeight();
332 Size aOutSz = mpTextWindow->GetOutputSizePixel();
333 if ( mpHScrollBar )
335 mpHScrollBar->SetVisibleSize( aOutSz.Width() );
336 mpHScrollBar->SetPageSize( aOutSz.Width() * 8 / 10 );
337 mpHScrollBar->SetLineSize( aCharBox.Width()*10 );
338 ImpSetHScrollBarThumbPos();
340 if ( mpVScrollBar )
342 mpVScrollBar->SetVisibleSize( aOutSz.Height() );
343 mpVScrollBar->SetPageSize( aOutSz.Height() * 8 / 10 );
344 mpVScrollBar->SetLineSize( aCharBox.Height() );
345 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
350 void ImpSvMEdit::ImpSetHScrollBarThumbPos()
352 long nX = mpTextWindow->GetTextView()->GetStartDocPos().X();
353 if ( !mpTextWindow->GetTextEngine()->IsRightToLeft() )
354 mpHScrollBar->SetThumbPos( nX );
355 else
356 mpHScrollBar->SetThumbPos( mnTextWidth - mpHScrollBar->GetVisibleSize() - nX );
360 IMPL_LINK( ImpSvMEdit, ScrollHdl, ScrollBar*, pCurScrollBar )
362 long nDiffX = 0, nDiffY = 0;
364 if ( pCurScrollBar == mpVScrollBar )
365 nDiffY = mpTextWindow->GetTextView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
366 else if ( pCurScrollBar == mpHScrollBar )
367 nDiffX = mpTextWindow->GetTextView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
369 mpTextWindow->GetTextView()->Scroll( nDiffX, nDiffY );
370 // mpTextWindow->GetTextView()->ShowCursor( FALSE, TRUE );
372 return 0;
376 // void ImpSvMEdit::ImpModified()
377 // {
378 // // Wann wird das gerufen ?????????????????????
379 // pSvMultiLineEdit->Modify();
380 // }
382 void ImpSvMEdit::SetAlign( WinBits nWinStyle )
384 BOOL bRTL = Application::GetSettings().GetLayoutRTL();
385 mpTextWindow->GetTextEngine()->SetRightToLeft( bRTL );
387 if ( nWinStyle & WB_CENTER )
388 mpTextWindow->GetTextEngine()->SetTextAlign( TXTALIGN_CENTER );
389 else if ( nWinStyle & WB_RIGHT )
390 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_RIGHT : TXTALIGN_LEFT );
391 else if ( nWinStyle & WB_LEFT )
392 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_LEFT : TXTALIGN_RIGHT );
395 void ImpSvMEdit::SetTextWindowOffset( const Point& rOffset )
397 maTextWindowOffset = rOffset;
398 Resize();
401 void ImpSvMEdit::SetModified( BOOL bMod )
403 mpTextWindow->GetTextEngine()->SetModified( bMod );
406 BOOL ImpSvMEdit::IsModified() const
408 return mpTextWindow->GetTextEngine()->IsModified();
411 void ImpSvMEdit::SetInsertMode( BOOL bInsert )
413 mpTextWindow->GetTextView()->SetInsertMode( bInsert );
416 void ImpSvMEdit::SetReadOnly( BOOL bRdOnly )
418 mpTextWindow->GetTextView()->SetReadOnly( bRdOnly );
419 // Farbe anpassen ???????????????????????????
422 BOOL ImpSvMEdit::IsReadOnly() const
424 return mpTextWindow->GetTextView()->IsReadOnly();
427 void ImpSvMEdit::SetMaxTextLen( xub_StrLen nLen )
429 mpTextWindow->GetTextEngine()->SetMaxTextLen( nLen );
432 xub_StrLen ImpSvMEdit::GetMaxTextLen() const
434 return sal::static_int_cast< xub_StrLen >(
435 mpTextWindow->GetTextEngine()->GetMaxTextLen());
438 void ImpSvMEdit::InsertText( const String& rStr )
440 mpTextWindow->GetTextView()->InsertText( rStr );
443 String ImpSvMEdit::GetSelected() const
445 return mpTextWindow->GetTextView()->GetSelected();
448 String ImpSvMEdit::GetSelected( LineEnd aSeparator ) const
450 return mpTextWindow->GetTextView()->GetSelected( aSeparator );
453 void ImpSvMEdit::Resize()
455 size_t nIteration = 1;
458 WinBits nWinStyle( pSvMultiLineEdit->GetStyle() );
459 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
460 ImpUpdateSrollBarVis( nWinStyle );
462 Size aSz = pSvMultiLineEdit->GetOutputSizePixel();
463 Size aEditSize = aSz;
464 long nSBWidth = pSvMultiLineEdit->GetSettings().GetStyleSettings().GetScrollBarSize();
465 nSBWidth = pSvMultiLineEdit->CalcZoom( nSBWidth );
467 if ( mpHScrollBar )
468 aSz.Height() -= nSBWidth+1;
469 if ( mpVScrollBar )
470 aSz.Width() -= nSBWidth+1;
472 if ( !mpHScrollBar )
473 mpTextWindow->GetTextEngine()->SetMaxTextWidth( aSz.Width() );
474 else
475 mpHScrollBar->SetPosSizePixel( 0, aEditSize.Height()-nSBWidth, aSz.Width(), nSBWidth );
477 Point aTextWindowPos( maTextWindowOffset );
478 if ( mpVScrollBar )
480 if( Application::GetSettings().GetLayoutRTL() )
482 mpVScrollBar->SetPosSizePixel( 0, 0, nSBWidth, aSz.Height() );
483 aTextWindowPos.X() += nSBWidth;
485 else
486 mpVScrollBar->SetPosSizePixel( aEditSize.Width()-nSBWidth, 0, nSBWidth, aSz.Height() );
489 if ( mpScrollBox )
490 mpScrollBox->SetPosSizePixel( aSz.Width(), aSz.Height(), nSBWidth, nSBWidth );
492 Size aTextWindowSize( aSz );
493 aTextWindowSize.Width() -= maTextWindowOffset.X();
494 aTextWindowSize.Height() -= maTextWindowOffset.Y();
495 if ( aTextWindowSize.Width() < 0 )
496 aTextWindowSize.Width() = 0;
497 if ( aTextWindowSize.Height() < 0 )
498 aTextWindowSize.Height() = 0;
500 Size aOldTextWindowSize( mpTextWindow->GetSizePixel() );
501 mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
502 if ( aOldTextWindowSize == aTextWindowSize )
503 break;
505 // Changing the text window size might effectively have changed the need for
506 // scrollbars, so do another iteration.
507 ++nIteration;
508 OSL_ENSURE( nIteration < 3, "ImpSvMEdit::Resize: isn't this expected to terminate with the second iteration?" );
510 } while ( nIteration <= 3 ); // artificial break after four iterations
512 ImpInitScrollBars();
515 void ImpSvMEdit::GetFocus()
517 mpTextWindow->GrabFocus();
520 void ImpSvMEdit::Cut()
522 if ( !mpTextWindow->GetTextView()->IsReadOnly() )
523 mpTextWindow->GetTextView()->Cut();
526 void ImpSvMEdit::Copy()
528 mpTextWindow->GetTextView()->Copy();
531 void ImpSvMEdit::Paste()
533 if ( !mpTextWindow->GetTextView()->IsReadOnly() )
534 mpTextWindow->GetTextView()->Paste();
537 void ImpSvMEdit::SetText( const String& rStr )
539 BOOL bWasModified = mpTextWindow->GetTextEngine()->IsModified();
540 mpTextWindow->GetTextEngine()->SetText( rStr );
541 if ( !bWasModified )
542 mpTextWindow->GetTextEngine()->SetModified( FALSE );
544 mpTextWindow->GetTextView()->SetSelection( TextSelection() );
546 WinBits nWinStyle( pSvMultiLineEdit->GetStyle() );
547 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
548 ImpUpdateSrollBarVis( nWinStyle );
551 String ImpSvMEdit::GetText() const
553 return mpTextWindow->GetTextEngine()->GetText();
556 String ImpSvMEdit::GetText( LineEnd aSeparator ) const
558 return mpTextWindow->GetTextEngine()->GetText( aSeparator );
561 String ImpSvMEdit::GetTextLines() const
563 return mpTextWindow->GetTextEngine()->GetTextLines();
566 String ImpSvMEdit::GetTextLines( LineEnd aSeparator ) const
568 return mpTextWindow->GetTextEngine()->GetTextLines( aSeparator );
571 void ImpSvMEdit::Notify( SfxBroadcaster&, const SfxHint& rHint )
573 if ( rHint.ISA( TextHint ) )
575 const TextHint& rTextHint = (const TextHint&)rHint;
576 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
578 if ( mpHScrollBar )
579 ImpSetHScrollBarThumbPos();
580 if ( mpVScrollBar )
581 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
583 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
585 if ( mpTextWindow->GetTextView()->GetStartDocPos().Y() )
587 long nOutHeight = mpTextWindow->GetOutputSizePixel().Height();
588 long nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
589 if ( nTextHeight < nOutHeight )
590 mpTextWindow->GetTextView()->Scroll( 0, mpTextWindow->GetTextView()->GetStartDocPos().Y() );
593 ImpSetScrollBarRanges();
595 else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
597 if ( mpHScrollBar )
599 ULONG nWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
600 if ( nWidth != mnTextWidth )
602 mnTextWidth = sal::static_int_cast< xub_StrLen >(nWidth);
603 mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
604 ImpSetHScrollBarThumbPos();
608 else if( rTextHint.GetId() == TEXT_HINT_MODIFIED )
610 pSvMultiLineEdit->Modify();
615 void ImpSvMEdit::SetSelection( const Selection& rSelection )
617 String aText = mpTextWindow->GetTextEngine()->GetText();
619 Selection aNewSelection( rSelection );
620 if ( aNewSelection.Min() < 0 )
621 aNewSelection.Min() = 0;
622 else if ( aNewSelection.Min() > aText.Len() )
623 aNewSelection.Min() = aText.Len();
624 if ( aNewSelection.Max() < 0 )
625 aNewSelection.Max() = 0;
626 else if ( aNewSelection.Max() > aText.Len() )
627 aNewSelection.Max() = aText.Len();
629 long nEnd = Max( aNewSelection.Min(), aNewSelection.Max() );
630 TextSelection aTextSel;
631 ULONG nPara = 0;
632 USHORT nChar = 0;
633 USHORT x = 0;
634 while ( x <= nEnd )
636 if ( x == aNewSelection.Min() )
637 aTextSel.GetStart() = TextPaM( nPara, nChar );
638 if ( x == aNewSelection.Max() )
639 aTextSel.GetEnd() = TextPaM( nPara, nChar );
641 if ( ( x < aText.Len() ) && ( aText.GetChar( x ) == '\n' ) )
643 nPara++;
644 nChar = 0;
646 else
647 nChar++;
648 x++;
650 mpTextWindow->GetTextView()->SetSelection( aTextSel );
653 const Selection& ImpSvMEdit::GetSelection() const
655 maSelection = Selection();
656 TextSelection aTextSel( mpTextWindow->GetTextView()->GetSelection() );
657 aTextSel.Justify();
658 // Selektion flachklopfen => jeder Umbruch ein Zeichen...
660 ExtTextEngine* pExtTextEngine = mpTextWindow->GetTextEngine();
661 // Absaetze davor:
662 ULONG n;
663 for ( n = 0; n < aTextSel.GetStart().GetPara(); n++ )
665 maSelection.Min() += pExtTextEngine->GetTextLen( n );
666 maSelection.Min()++;
669 // Erster Absatz mit Selektion:
670 maSelection.Max() = maSelection.Min();
671 maSelection.Min() += aTextSel.GetStart().GetIndex();
673 for ( n = aTextSel.GetStart().GetPara(); n < aTextSel.GetEnd().GetPara(); n++ )
675 maSelection.Max() += pExtTextEngine->GetTextLen( n );
676 maSelection.Max()++;
679 maSelection.Max() += aTextSel.GetEnd().GetIndex();
681 return maSelection;
684 Size ImpSvMEdit::CalcMinimumSize() const
686 Size aSz( mpTextWindow->GetTextEngine()->CalcTextWidth(),
687 mpTextWindow->GetTextEngine()->GetTextHeight() );
689 if ( mpHScrollBar )
690 aSz.Height() += mpHScrollBar->GetSizePixel().Height();
691 if ( mpVScrollBar )
692 aSz.Width() += mpVScrollBar->GetSizePixel().Width();
694 return aSz;
697 Size ImpSvMEdit::CalcSize( USHORT nColumns, USHORT nLines ) const
699 static const sal_Unicode sampleText[] = { 'X', '\0' };
701 Size aSz;
702 Size aCharSz;
703 aCharSz.Width() = mpTextWindow->GetTextWidth( sampleText );
704 aCharSz.Height() = mpTextWindow->GetTextHeight();
706 if ( nLines )
707 aSz.Height() = nLines*aCharSz.Height();
708 else
709 aSz.Height() = mpTextWindow->GetTextEngine()->GetTextHeight();
711 if ( nColumns )
712 aSz.Width() = nColumns*aCharSz.Width();
713 else
714 aSz.Width() = mpTextWindow->GetTextEngine()->CalcTextWidth();
716 if ( mpHScrollBar )
717 aSz.Height() += mpHScrollBar->GetSizePixel().Height();
718 if ( mpVScrollBar )
719 aSz.Width() += mpVScrollBar->GetSizePixel().Width();
721 return aSz;
724 void ImpSvMEdit::GetMaxVisColumnsAndLines( USHORT& rnCols, USHORT& rnLines ) const
726 static const sal_Unicode sampleText[] = { 'x', '\0' };
727 Size aOutSz = mpTextWindow->GetOutputSizePixel();
728 Size aCharSz( mpTextWindow->GetTextWidth( sampleText ), mpTextWindow->GetTextHeight() );
729 rnCols = (USHORT) (aOutSz.Width()/aCharSz.Width());
730 rnLines = (USHORT) (aOutSz.Height()/aCharSz.Height());
733 void ImpSvMEdit::Enable( BOOL bEnable )
735 mpTextWindow->Enable( bEnable );
736 if ( mpHScrollBar )
737 mpHScrollBar->Enable( bEnable );
738 if ( mpVScrollBar )
739 mpVScrollBar->Enable( bEnable );
742 BOOL ImpSvMEdit::HandleCommand( const CommandEvent& rCEvt )
744 BOOL bDone = FALSE;
745 if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
746 ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
747 ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
749 mpTextWindow->HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
750 bDone = TRUE;
752 return bDone;
756 TextWindow::TextWindow( Window* pParent ) : Window( pParent )
758 mbInMBDown = FALSE;
759 mbSelectOnTab = TRUE;
760 mbFocusSelectionHide = FALSE;
761 mbIgnoreTab = FALSE;
762 mbActivePopup = FALSE;
763 mbSelectOnTab = TRUE;
765 SetPointer( Pointer( POINTER_TEXT ) );
767 mpExtTextEngine = new ExtTextEngine;
768 mpExtTextEngine->SetMaxTextLen( STRING_MAXLEN );
769 if( pParent->GetStyle() & WB_BORDER )
770 mpExtTextEngine->SetLeftMargin( 2 );
771 mpExtTextEngine->SetLocale( GetSettings().GetLocale() );
772 mpExtTextView = new ExtTextView( mpExtTextEngine, this );
773 mpExtTextEngine->InsertView( mpExtTextView );
774 mpExtTextEngine->EnableUndo( TRUE );
775 mpExtTextView->ShowCursor();
777 Color aBackgroundColor = GetSettings().GetStyleSettings().GetWorkspaceColor();
778 SetBackground( aBackgroundColor );
779 pParent->SetBackground( aBackgroundColor );
782 TextWindow::~TextWindow()
784 delete mpExtTextView;
785 delete mpExtTextEngine;
788 void TextWindow::MouseMove( const MouseEvent& rMEvt )
790 mpExtTextView->MouseMove( rMEvt );
791 Window::MouseMove( rMEvt );
794 void TextWindow::MouseButtonDown( const MouseEvent& rMEvt )
796 mbInMBDown = TRUE; // Dann im GetFocus nicht alles selektieren wird
797 mpExtTextView->MouseButtonDown( rMEvt );
798 Window::MouseButtonDown( rMEvt );
799 GrabFocus();
800 mbInMBDown = FALSE;
803 void TextWindow::MouseButtonUp( const MouseEvent& rMEvt )
805 mpExtTextView->MouseButtonUp( rMEvt );
806 Window::MouseButtonUp( rMEvt );
809 void TextWindow::KeyInput( const KeyEvent& rKEvent )
811 BOOL bDone = FALSE;
812 USHORT nCode = rKEvent.GetKeyCode().GetCode();
813 if ( nCode == com::sun::star::awt::Key::SELECT_ALL ||
814 ( (nCode == KEY_A) && rKEvent.GetKeyCode().IsMod1() && !rKEvent.GetKeyCode().IsMod2() )
817 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
818 bDone = TRUE;
820 else if ( (nCode == KEY_S) && rKEvent.GetKeyCode().IsShift() && rKEvent.GetKeyCode().IsMod1() )
822 if ( Edit::GetGetSpecialCharsFunction() )
824 // Damit die Selektion erhalten bleibt
825 mbActivePopup = TRUE;
826 XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
827 if ( aChars.Len() )
829 mpExtTextView->InsertText( aChars );
830 mpExtTextView->GetTextEngine()->SetModified( TRUE );
832 mbActivePopup = FALSE;
833 bDone = TRUE;
836 else if ( nCode == KEY_TAB )
838 if ( !mbIgnoreTab || rKEvent.GetKeyCode().IsMod1() )
839 bDone = mpExtTextView->KeyInput( rKEvent );
841 else
843 bDone = mpExtTextView->KeyInput( rKEvent );
846 if ( !bDone )
847 Window::KeyInput( rKEvent );
850 void TextWindow::Paint( const Rectangle& rRect )
852 mpExtTextView->Paint( rRect );
855 void TextWindow::Resize()
859 void TextWindow::Command( const CommandEvent& rCEvt )
861 if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
863 PopupMenu* pPopup = Edit::CreatePopupMenu();
864 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
865 if ( rStyleSettings.GetOptions() & STYLE_OPTION_HIDEDISABLED )
866 pPopup->SetMenuFlags( MENU_FLAG_HIDEDISABLEDENTRIES );
867 if ( !mpExtTextView->HasSelection() )
869 pPopup->EnableItem( SV_MENU_EDIT_CUT, FALSE );
870 pPopup->EnableItem( SV_MENU_EDIT_COPY, FALSE );
871 pPopup->EnableItem( SV_MENU_EDIT_DELETE, FALSE );
873 if ( mpExtTextView->IsReadOnly() )
875 pPopup->EnableItem( SV_MENU_EDIT_CUT, FALSE );
876 pPopup->EnableItem( SV_MENU_EDIT_PASTE, FALSE );
877 pPopup->EnableItem( SV_MENU_EDIT_DELETE, FALSE );
878 pPopup->EnableItem( SV_MENU_EDIT_INSERTSYMBOL, FALSE );
880 if ( !mpExtTextView->GetTextEngine()->HasUndoManager() || !mpExtTextView->GetTextEngine()->GetUndoManager().GetUndoActionCount() )
882 pPopup->EnableItem( SV_MENU_EDIT_UNDO, FALSE );
884 // if ( ( maSelection.Min() == 0 ) && ( maSelection.Max() == maText.Len() ) )
885 // {
886 // pPopup->EnableItem( SV_MENU_EDIT_SELECTALL, FALSE );
887 // }
888 if ( !Edit::GetGetSpecialCharsFunction() )
890 USHORT nPos = pPopup->GetItemPos( SV_MENU_EDIT_INSERTSYMBOL );
891 pPopup->RemoveItem( nPos );
892 pPopup->RemoveItem( nPos-1 );
895 mbActivePopup = TRUE;
896 Point aPos = rCEvt.GetMousePosPixel();
897 if ( !rCEvt.IsMouseEvent() )
899 // !!! Irgendwann einmal Menu zentriert in der Selektion anzeigen !!!
900 Size aSize = GetOutputSizePixel();
901 aPos = Point( aSize.Width()/2, aSize.Height()/2 );
903 // pPopup->RemoveDisabledEntries();
904 USHORT n = pPopup->Execute( this, aPos );
905 Edit::DeletePopupMenu( pPopup );
906 switch ( n )
908 case SV_MENU_EDIT_UNDO: mpExtTextView->Undo();
909 mpExtTextEngine->SetModified( TRUE );
910 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
911 break;
912 case SV_MENU_EDIT_CUT: mpExtTextView->Cut();
913 mpExtTextEngine->SetModified( TRUE );
914 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
915 break;
916 case SV_MENU_EDIT_COPY: mpExtTextView->Copy();
917 break;
918 case SV_MENU_EDIT_PASTE: mpExtTextView->Paste();
919 mpExtTextEngine->SetModified( TRUE );
920 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
921 break;
922 case SV_MENU_EDIT_DELETE: mpExtTextView->DeleteSelected();
923 mpExtTextEngine->SetModified( TRUE );
924 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
925 break;
926 case SV_MENU_EDIT_SELECTALL: mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
927 break;
928 case SV_MENU_EDIT_INSERTSYMBOL:
930 XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
931 if ( aChars.Len() )
933 mpExtTextView->InsertText( aChars );
934 mpExtTextEngine->SetModified( TRUE );
935 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
938 break;
940 mbActivePopup = FALSE;
942 else
944 mpExtTextView->Command( rCEvt );
946 Window::Command( rCEvt );
949 void TextWindow::GetFocus()
951 Window::GetFocus();
952 if ( !mbActivePopup )
954 BOOL bGotoCursor = !mpExtTextView->IsReadOnly();
955 if ( mbFocusSelectionHide && IsReallyVisible() && !mpExtTextView->IsReadOnly()
956 && ( mbSelectOnTab &&
957 (!mbInMBDown || ( GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_FOCUS ) )) )
959 // Alles selektieren, aber nicht scrollen
960 BOOL bAutoScroll = mpExtTextView->IsAutoScroll();
961 mpExtTextView->SetAutoScroll( FALSE );
962 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
963 mpExtTextView->SetAutoScroll( bAutoScroll );
964 bGotoCursor = FALSE;
966 mpExtTextView->SetPaintSelection( TRUE );
967 mpExtTextView->ShowCursor( bGotoCursor );
971 void TextWindow::LoseFocus()
973 Window::LoseFocus();
975 if ( mbFocusSelectionHide && !mbActivePopup )
976 mpExtTextView->SetPaintSelection( FALSE );
979 // virtual
980 ::css::uno::Reference< ::css::awt::XWindowPeer >
981 TextWindow::GetComponentInterface(BOOL bCreate)
983 ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
984 Window::GetComponentInterface(false));
985 if (!xPeer.is() && bCreate)
987 xPeer = new ::svt::TextWindowPeer(*GetTextView(), true);
988 SetComponentInterface(xPeer);
990 return xPeer;
993 MultiLineEdit::MultiLineEdit( Window* pParent, WinBits nWinStyle )
994 : Edit( pParent, nWinStyle )
996 SetType( WINDOW_MULTILINEEDIT );
997 pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
998 ImplInitSettings( TRUE, TRUE, TRUE );
999 pUpdateDataTimer = 0;
1001 SetCompoundControl( TRUE );
1002 SetStyle( ImplInitStyle( nWinStyle ) );
1005 MultiLineEdit::MultiLineEdit( Window* pParent, const ResId& rResId )
1006 : Edit( pParent, rResId.SetRT( RSC_MULTILINEEDIT ) )
1008 SetType( WINDOW_MULTILINEEDIT );
1009 WinBits nWinStyle = rResId.GetWinBits();
1010 pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
1011 ImplInitSettings( TRUE, TRUE, TRUE );
1012 pUpdateDataTimer = 0;
1014 USHORT nMaxLen = Edit::GetMaxTextLen();
1015 if ( nMaxLen )
1016 SetMaxTextLen( nMaxLen );
1018 SetText( Edit::GetText() );
1020 if ( IsVisible() )
1021 pImpSvMEdit->Resize();
1023 SetCompoundControl( TRUE );
1024 SetStyle( ImplInitStyle( nWinStyle ) );
1026 // Base Edit ctor could call Show already, but that would cause problems
1027 // with accessibility, as Show might (indirectly) trigger a call to virtual
1028 // GetComponentInterface, which is the Edit's base version instead of the
1029 // MultiLineEdit's version while in the base Edit ctor:
1030 if ((GetStyle() & WB_HIDE) == 0)
1031 Show();
1034 MultiLineEdit::~MultiLineEdit()
1037 ::std::auto_ptr< ImpSvMEdit > pDelete( pImpSvMEdit );
1038 pImpSvMEdit = NULL;
1040 delete pUpdateDataTimer;
1043 WinBits MultiLineEdit::ImplInitStyle( WinBits nStyle )
1045 if ( !(nStyle & WB_NOTABSTOP) )
1046 nStyle |= WB_TABSTOP;
1048 if ( !(nStyle & WB_NOGROUP) )
1049 nStyle |= WB_GROUP;
1051 if ( !(nStyle & WB_IGNORETAB ))
1052 nStyle |= WINDOW_DLGCTRL_MOD1TAB;
1054 return nStyle;
1058 void MultiLineEdit::ImplInitSettings( BOOL /*bFont*/, BOOL /*bForeground*/, BOOL bBackground )
1060 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1062 // Der Font muss immer mit manipuliert werden, weil die TextEngine
1063 // sich nicht um TextColor/Background kuemmert
1065 Color aTextColor = rStyleSettings.GetFieldTextColor();
1066 if ( IsControlForeground() )
1067 aTextColor = GetControlForeground();
1068 if ( !IsEnabled() )
1069 aTextColor = rStyleSettings.GetDisableColor();
1071 Font aFont = rStyleSettings.GetFieldFont();
1072 if ( IsControlFont() )
1073 aFont.Merge( GetControlFont() );
1074 aFont.SetTransparent( IsPaintTransparent() );
1075 SetZoomedPointFont( aFont );
1076 Font TheFont = GetFont();
1077 TheFont.SetColor( aTextColor );
1078 if( IsPaintTransparent() )
1079 TheFont.SetFillColor( Color( COL_TRANSPARENT ) );
1080 else
1081 TheFont.SetFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() );
1082 pImpSvMEdit->GetTextWindow()->SetFont( TheFont );
1083 pImpSvMEdit->GetTextWindow()->GetTextEngine()->SetFont( TheFont );
1084 pImpSvMEdit->GetTextWindow()->SetTextColor( aTextColor );
1086 if ( bBackground )
1088 if( IsPaintTransparent() )
1090 pImpSvMEdit->GetTextWindow()->SetPaintTransparent( TRUE );
1091 pImpSvMEdit->GetTextWindow()->SetBackground();
1092 pImpSvMEdit->GetTextWindow()->SetControlBackground();
1093 SetBackground();
1094 SetControlBackground();
1096 else
1098 if( IsControlBackground() )
1099 pImpSvMEdit->GetTextWindow()->SetBackground( GetControlBackground() );
1100 else
1101 pImpSvMEdit->GetTextWindow()->SetBackground( rStyleSettings.GetFieldColor() );
1102 // Auch am MultiLineEdit einstellen, weil die TextComponent
1103 // ggf. die Scrollbars hidet.
1104 SetBackground( pImpSvMEdit->GetTextWindow()->GetBackground() );
1109 void MultiLineEdit::Modify()
1111 aModifyHdlLink.Call( this );
1113 CallEventListeners( VCLEVENT_EDIT_MODIFY );
1115 if ( pUpdateDataTimer )
1116 pUpdateDataTimer->Start();
1119 IMPL_LINK( MultiLineEdit, ImpUpdateDataHdl, Timer*, EMPTYARG )
1121 UpdateData();
1122 return 0;
1125 void MultiLineEdit::UpdateData()
1127 aUpdateDataHdlLink.Call( this );
1130 void MultiLineEdit::SetModifyFlag()
1132 pImpSvMEdit->SetModified( TRUE );
1135 void MultiLineEdit::ClearModifyFlag()
1137 pImpSvMEdit->SetModified( FALSE );
1140 BOOL MultiLineEdit::IsModified() const
1142 return pImpSvMEdit->IsModified();
1145 void MultiLineEdit::EnableUpdateData( ULONG nTimeout )
1147 if ( !nTimeout )
1148 DisableUpdateData();
1149 else
1151 if ( !pUpdateDataTimer )
1153 pUpdateDataTimer = new Timer;
1154 pUpdateDataTimer->SetTimeoutHdl( LINK( this, MultiLineEdit, ImpUpdateDataHdl ) );
1156 pUpdateDataTimer->SetTimeout( nTimeout );
1160 void MultiLineEdit::SetReadOnly( BOOL bReadOnly )
1162 pImpSvMEdit->SetReadOnly( bReadOnly );
1163 Edit::SetReadOnly( bReadOnly );
1165 // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set.
1166 WinBits nStyle = GetStyle();
1167 if ( bReadOnly )
1168 nStyle |= WB_READONLY;
1169 else
1170 nStyle &= ~WB_READONLY;
1171 SetStyle( nStyle );
1174 BOOL MultiLineEdit::IsReadOnly() const
1176 return pImpSvMEdit->IsReadOnly();
1179 void MultiLineEdit::SetMaxTextLen( xub_StrLen nMaxLen )
1181 pImpSvMEdit->SetMaxTextLen( nMaxLen );
1184 xub_StrLen MultiLineEdit::GetMaxTextLen() const
1186 return pImpSvMEdit->GetMaxTextLen();
1189 void MultiLineEdit::ReplaceSelected( const String& rStr )
1191 pImpSvMEdit->InsertText( rStr );
1194 void MultiLineEdit::DeleteSelected()
1196 pImpSvMEdit->InsertText( String() );
1199 String MultiLineEdit::GetSelected() const
1201 return pImpSvMEdit->GetSelected();
1204 String MultiLineEdit::GetSelected( LineEnd aSeparator ) const
1206 return pImpSvMEdit->GetSelected( aSeparator );
1209 void MultiLineEdit::Cut()
1211 pImpSvMEdit->Cut();
1214 void MultiLineEdit::Copy()
1216 pImpSvMEdit->Copy();
1219 void MultiLineEdit::Paste()
1221 pImpSvMEdit->Paste();
1224 void MultiLineEdit::SetText( const String& rStr )
1226 pImpSvMEdit->SetText( rStr );
1229 String MultiLineEdit::GetText() const
1231 return pImpSvMEdit->GetText();
1234 String MultiLineEdit::GetText( LineEnd aSeparator ) const
1236 return pImpSvMEdit->GetText( aSeparator );
1239 String MultiLineEdit::GetTextLines() const
1241 return pImpSvMEdit->GetTextLines();
1244 String MultiLineEdit::GetTextLines( LineEnd aSeparator ) const
1246 return pImpSvMEdit->GetTextLines( aSeparator );
1249 void MultiLineEdit::Resize()
1251 pImpSvMEdit->Resize();
1254 void MultiLineEdit::GetFocus()
1256 if ( !pImpSvMEdit ) // might be called from within the dtor, when pImpSvMEdit == NULL is a valid state
1257 return;
1259 Edit::GetFocus();
1260 pImpSvMEdit->GetFocus();
1263 void MultiLineEdit::SetSelection( const Selection& rSelection )
1265 pImpSvMEdit->SetSelection( rSelection );
1268 const Selection& MultiLineEdit::GetSelection() const
1270 return pImpSvMEdit->GetSelection();
1273 Size MultiLineEdit::CalcMinimumSize() const
1275 Size aSz = pImpSvMEdit->CalcMinimumSize();
1277 sal_Int32 nLeft, nTop, nRight, nBottom;
1278 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1279 aSz.Width() += nLeft+nRight;
1280 aSz.Height() += nTop+nBottom;
1282 return aSz;
1285 Size MultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const
1287 Size aSz = rPrefSize;
1288 sal_Int32 nLeft, nTop, nRight, nBottom;
1289 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1291 // In der Hoehe auf ganze Zeilen justieren
1293 long nHeight = aSz.Height() - nTop - nBottom;
1294 long nLineHeight = pImpSvMEdit->CalcSize( 1, 1 ).Height();
1295 long nLines = nHeight / nLineHeight;
1296 if ( nLines < 1 )
1297 nLines = 1;
1299 aSz.Height() = nLines * nLineHeight;
1300 aSz.Height() += nTop+nBottom;
1302 return aSz;
1305 Size MultiLineEdit::CalcSize( USHORT nColumns, USHORT nLines ) const
1307 Size aSz = pImpSvMEdit->CalcSize( nColumns, nLines );
1309 sal_Int32 nLeft, nTop, nRight, nBottom;
1310 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1311 aSz.Width() += nLeft+nRight;
1312 aSz.Height() += nTop+nBottom;
1313 return aSz;
1316 void MultiLineEdit::GetMaxVisColumnsAndLines( USHORT& rnCols, USHORT& rnLines ) const
1318 pImpSvMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines );
1321 void MultiLineEdit::StateChanged( StateChangedType nType )
1323 if( nType == STATE_CHANGE_ENABLE )
1325 pImpSvMEdit->Enable( IsEnabled() );
1326 ImplInitSettings( TRUE, FALSE, FALSE );
1328 else if( nType == STATE_CHANGE_READONLY )
1330 pImpSvMEdit->SetReadOnly( IsReadOnly() );
1332 else if ( nType == STATE_CHANGE_ZOOM )
1334 pImpSvMEdit->GetTextWindow()->SetZoom( GetZoom() );
1335 ImplInitSettings( TRUE, FALSE, FALSE );
1336 Resize();
1338 else if ( nType == STATE_CHANGE_CONTROLFONT )
1340 ImplInitSettings( TRUE, FALSE, FALSE );
1341 Resize();
1342 Invalidate();
1344 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1346 ImplInitSettings( FALSE, TRUE, FALSE );
1347 Invalidate();
1349 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1351 ImplInitSettings( FALSE, FALSE, TRUE );
1352 Invalidate();
1354 else if ( nType == STATE_CHANGE_STYLE )
1356 pImpSvMEdit->InitFromStyle( GetStyle() );
1357 SetStyle( ImplInitStyle( GetStyle() ) );
1359 else if ( nType == STATE_CHANGE_INITSHOW )
1361 if( IsPaintTransparent() )
1363 pImpSvMEdit->GetTextWindow()->SetPaintTransparent( TRUE );
1364 pImpSvMEdit->GetTextWindow()->SetBackground();
1365 pImpSvMEdit->GetTextWindow()->SetControlBackground();
1366 SetBackground();
1367 SetControlBackground();
1371 Control::StateChanged( nType );
1374 void MultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt )
1376 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1377 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1379 ImplInitSettings( TRUE, TRUE, TRUE );
1380 Resize();
1381 Invalidate();
1383 else
1384 Control::DataChanged( rDCEvt );
1387 void MultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
1389 ImplInitSettings( TRUE, TRUE, TRUE );
1391 Point aPos = pDev->LogicToPixel( rPos );
1392 Size aSize = pDev->LogicToPixel( rSize );
1393 Font aFont = pImpSvMEdit->GetTextWindow()->GetDrawPixelFont( pDev );
1394 aFont.SetTransparent( TRUE );
1395 OutDevType eOutDevType = pDev->GetOutDevType();
1397 pDev->Push();
1398 pDev->SetMapMode();
1399 pDev->SetFont( aFont );
1400 pDev->SetTextFillColor();
1402 // Border/Background
1403 pDev->SetLineColor();
1404 pDev->SetFillColor();
1405 BOOL bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
1406 BOOL bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
1407 if ( bBorder || bBackground )
1409 Rectangle aRect( aPos, aSize );
1410 if ( bBorder )
1412 DecorationView aDecoView( pDev );
1413 aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
1415 if ( bBackground )
1417 pDev->SetFillColor( GetControlBackground() );
1418 pDev->DrawRect( aRect );
1422 // Inhalt
1423 if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
1424 pDev->SetTextColor( Color( COL_BLACK ) );
1425 else
1427 if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
1429 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1430 pDev->SetTextColor( rStyleSettings.GetDisableColor() );
1432 else
1434 pDev->SetTextColor( GetTextColor() );
1438 XubString aText = GetText();
1439 Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() );
1440 ULONG nLines = (ULONG) (aSize.Height() / aTextSz.Height());
1441 if ( !nLines )
1442 nLines = 1;
1443 aTextSz.Height() = nLines*aTextSz.Height();
1444 long nOnePixel = GetDrawPixel( pDev, 1 );
1445 long nOffX = 3*nOnePixel;
1446 long nOffY = 2*nOnePixel;
1448 // Clipping?
1449 if ( ( nOffY < 0 ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) )
1451 Rectangle aClip( aPos, aSize );
1452 if ( aTextSz.Height() > aSize.Height() )
1453 aClip.Bottom() += aTextSz.Height() - aSize.Height() + 1; // Damit HP-Drucker nicht 'weg-optimieren'
1454 pDev->IntersectClipRegion( aClip );
1457 TextEngine aTE;
1458 aTE.SetText( GetText() );
1459 aTE.SetMaxTextWidth( aSize.Width() );
1460 aTE.SetFont( aFont );
1461 aTE.SetTextAlign( pImpSvMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() );
1462 aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) );
1464 pDev->Pop();
1467 long MultiLineEdit::Notify( NotifyEvent& rNEvt )
1469 long nDone = 0;
1470 if( rNEvt.GetType() == EVENT_COMMAND )
1472 nDone = pImpSvMEdit->HandleCommand( *rNEvt.GetCommandEvent() );
1474 return nDone ? nDone : Edit::Notify( rNEvt );
1477 long MultiLineEdit::PreNotify( NotifyEvent& rNEvt )
1479 long nDone = 0;
1481 #if (OSL_DEBUG_LEVEL > 1) && !defined( PRODUCT )
1482 if( rNEvt.GetType() == EVENT_KEYINPUT )
1484 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1485 if ( ( rKEvent.GetKeyCode().GetCode() == KEY_W ) && rKEvent.GetKeyCode().IsMod1() && rKEvent.GetKeyCode().IsMod2() )
1487 SetRightToLeft( !IsRightToLeft() );
1490 #endif
1492 if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) )
1494 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1495 if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) )
1497 nDone = 1;
1498 TextSelection aSel = pImpSvMEdit->GetTextWindow()->GetTextView()->GetSelection();
1499 if ( aSel.HasRange() )
1501 aSel.GetStart() = aSel.GetEnd();
1502 pImpSvMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel );
1504 else
1506 switch ( rKEvent.GetKeyCode().GetCode() )
1508 case KEY_UP:
1510 if ( pImpSvMEdit->GetVScrollBar() )
1511 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEUP );
1513 break;
1514 case KEY_DOWN:
1516 if ( pImpSvMEdit->GetVScrollBar() )
1517 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1519 break;
1520 case KEY_PAGEUP :
1522 if ( pImpSvMEdit->GetVScrollBar() )
1523 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEUP );
1525 break;
1526 case KEY_PAGEDOWN:
1528 if ( pImpSvMEdit->GetVScrollBar() )
1529 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEDOWN );
1531 break;
1532 case KEY_LEFT:
1534 if ( pImpSvMEdit->GetHScrollBar() )
1535 pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEUP );
1537 break;
1538 case KEY_RIGHT:
1540 if ( pImpSvMEdit->GetHScrollBar() )
1541 pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1543 break;
1544 case KEY_HOME:
1546 if ( rKEvent.GetKeyCode().IsMod1() )
1547 pImpSvMEdit->GetTextWindow()->GetTextView()->
1548 SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
1550 break;
1551 case KEY_END:
1553 if ( rKEvent.GetKeyCode().IsMod1() )
1554 pImpSvMEdit->GetTextWindow()->GetTextView()->
1555 SetSelection( TextSelection( TextPaM( 0xFFFF, 0xFFFF ) ) );
1557 break;
1558 default:
1560 nDone = 0;
1567 return nDone ? nDone : Edit::PreNotify( rNEvt );
1571 // Internas fuer abgeleitete Klassen, z.B. TextComponent
1573 ExtTextEngine* MultiLineEdit::GetTextEngine() const
1575 return pImpSvMEdit->GetTextWindow()->GetTextEngine();
1578 ExtTextView* MultiLineEdit::GetTextView() const
1580 return pImpSvMEdit->GetTextWindow()->GetTextView();
1583 ScrollBar* MultiLineEdit::GetHScrollBar() const
1585 return pImpSvMEdit->GetHScrollBar();
1589 ScrollBar* MultiLineEdit::GetVScrollBar() const
1591 return pImpSvMEdit->GetVScrollBar();
1594 void MultiLineEdit::EnableFocusSelectionHide( BOOL bHide )
1596 pImpSvMEdit->GetTextWindow()->SetAutoFocusHide( bHide );
1599 BOOL MultiLineEdit::IsFocusSelectionHideEnabled() const
1601 return pImpSvMEdit->GetTextWindow()->IsAutoFocusHide();
1605 void MultiLineEdit::SetLeftMargin( USHORT n )
1607 if ( GetTextEngine() )
1608 GetTextEngine()->SetLeftMargin( n );
1611 USHORT MultiLineEdit::GetLeftMargin() const
1613 if ( GetTextEngine() )
1614 return GetTextEngine()->GetLeftMargin();
1615 else
1616 return 0;
1619 void MultiLineEdit::SetRightToLeft( BOOL bRightToLeft )
1621 if ( GetTextEngine() )
1623 GetTextEngine()->SetRightToLeft( bRightToLeft );
1624 GetTextView()->ShowCursor();
1628 BOOL MultiLineEdit::IsRightToLeft() const
1630 BOOL bRightToLeft = FALSE;
1632 if ( GetTextEngine() )
1633 bRightToLeft = GetTextEngine()->IsRightToLeft();
1635 return bRightToLeft;
1638 // virtual
1639 ::css::uno::Reference< ::css::awt::XWindowPeer >
1640 MultiLineEdit::GetComponentInterface(BOOL bCreate)
1642 ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
1643 Edit::GetComponentInterface(false));
1644 if (!xPeer.is() && bCreate)
1646 ::std::auto_ptr< VCLXMultiLineEdit > xEdit(new VCLXMultiLineEdit());
1647 xEdit->SetWindow(this);
1648 xPeer = xEdit.release();
1649 SetComponentInterface(xPeer);
1651 return xPeer;
1653 /*-- 11.08.2004 11:29:23---------------------------------------------------
1655 -----------------------------------------------------------------------*/
1656 void MultiLineEdit::DisableSelectionOnFocus()
1658 pImpSvMEdit->GetTextWindow()->DisableSelectionOnFocus();