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