xref: /trunk/main/svtools/source/edit/svmedit.cxx (revision 2463d85f)
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 
GetTextEngine() const74 	ExtTextEngine* 	GetTextEngine() const { return mpExtTextEngine; }
GetTextView() const75 	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 
IsAutoFocusHide() const90 	sal_Bool			IsAutoFocusHide() const { return mbFocusSelectionHide; }
SetAutoFocusHide(sal_Bool bAutoHide)91 	void			SetAutoFocusHide( sal_Bool bAutoHide ) { mbFocusSelectionHide = bAutoHide; }
92 
IsIgnoreTab() const93 	sal_Bool			IsIgnoreTab() const { return mbIgnoreTab; }
SetIgnoreTab(sal_Bool bIgnore)94 	void			SetIgnoreTab( sal_Bool bIgnore ) { mbIgnoreTab = bIgnore; }
95 
DisableSelectionOnFocus()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 
GetTextWindow()174 	TextWindow* GetTextWindow() { return mpTextWindow; }
GetHScrollBar()175 	ScrollBar*  GetHScrollBar() { return mpHScrollBar; }
GetVScrollBar()176 	ScrollBar*  GetVScrollBar() { return mpVScrollBar; }
177 
178 	void 		SetTextWindowOffset( const Point& rOffset );
179 };
180 
ImpSvMEdit(MultiLineEdit * pEdt,WinBits nWinStyle)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 
ImpUpdateSrollBarVis(WinBits nWinStyle)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 
InitFromStyle(WinBits nWinStyle)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 
~ImpSvMEdit()290 ImpSvMEdit::~ImpSvMEdit()
291 {
292 	EndListening( *mpTextWindow->GetTextEngine() );
293 	delete mpTextWindow;
294 	delete mpHScrollBar;
295 	delete mpVScrollBar;
296 	delete mpScrollBox;
297 }
298 
ImpSetScrollBarRanges()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 
ImpInitScrollBars()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 
ImpSetHScrollBarThumbPos()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 
IMPL_LINK(ImpSvMEdit,ScrollHdl,ScrollBar *,pCurScrollBar)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 
SetAlign(WinBits nWinStyle)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 
SetTextWindowOffset(const Point & rOffset)388 void ImpSvMEdit::SetTextWindowOffset( const Point& rOffset )
389 {
390 	maTextWindowOffset = rOffset;
391 	Resize();
392 }
393 
SetModified(sal_Bool bMod)394 void ImpSvMEdit::SetModified( sal_Bool bMod )
395 {
396 	mpTextWindow->GetTextEngine()->SetModified( bMod );
397 }
398 
IsModified() const399 sal_Bool ImpSvMEdit::IsModified() const
400 {
401 	return mpTextWindow->GetTextEngine()->IsModified();
402 }
403 
SetInsertMode(sal_Bool bInsert)404 void ImpSvMEdit::SetInsertMode( sal_Bool bInsert )
405 {
406 	mpTextWindow->GetTextView()->SetInsertMode( bInsert );
407 }
408 
SetReadOnly(sal_Bool bRdOnly)409 void ImpSvMEdit::SetReadOnly( sal_Bool bRdOnly )
410 {
411 	mpTextWindow->GetTextView()->SetReadOnly( bRdOnly );
412 	// Farbe anpassen ???????????????????????????
413 }
414 
IsReadOnly() const415 sal_Bool ImpSvMEdit::IsReadOnly() const
416 {
417 	return mpTextWindow->GetTextView()->IsReadOnly();
418 }
419 
SetMaxTextLen(xub_StrLen nLen)420 void ImpSvMEdit::SetMaxTextLen( xub_StrLen nLen )
421 {
422 	mpTextWindow->GetTextEngine()->SetMaxTextLen( nLen );
423 }
424 
GetMaxTextLen() const425 xub_StrLen ImpSvMEdit::GetMaxTextLen() const
426 {
427 	return sal::static_int_cast< xub_StrLen >(
428         mpTextWindow->GetTextEngine()->GetMaxTextLen());
429 }
430 
InsertText(const String & rStr)431 void ImpSvMEdit::InsertText( const String& rStr )
432 {
433 	mpTextWindow->GetTextView()->InsertText( rStr );
434 }
435 
GetSelected() const436 String ImpSvMEdit::GetSelected() const
437 {
438 	return mpTextWindow->GetTextView()->GetSelected();
439 }
440 
GetSelected(LineEnd aSeparator) const441 String ImpSvMEdit::GetSelected( LineEnd aSeparator ) const
442 {
443 	return mpTextWindow->GetTextView()->GetSelected( aSeparator );
444 }
445 
Resize()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 
GetFocus()508 void ImpSvMEdit::GetFocus()
509 {
510 	mpTextWindow->GrabFocus();
511 }
512 
Cut()513 void ImpSvMEdit::Cut()
514 {
515 	if ( !mpTextWindow->GetTextView()->IsReadOnly() )
516 		mpTextWindow->GetTextView()->Cut();
517 }
518 
Copy()519 void ImpSvMEdit::Copy()
520 {
521 	mpTextWindow->GetTextView()->Copy();
522 }
523 
Paste()524 void ImpSvMEdit::Paste()
525 {
526 	if ( !mpTextWindow->GetTextView()->IsReadOnly() )
527 		mpTextWindow->GetTextView()->Paste();
528 }
529 
SetText(const String & rStr)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 
GetText() const544 String ImpSvMEdit::GetText() const
545 {
546 	return mpTextWindow->GetTextEngine()->GetText();
547 }
548 
GetText(LineEnd aSeparator) const549 String ImpSvMEdit::GetText( LineEnd aSeparator ) const
550 {
551 	return mpTextWindow->GetTextEngine()->GetText( aSeparator );
552 }
553 
GetTextLines() const554 String ImpSvMEdit::GetTextLines() const
555 {
556 	return mpTextWindow->GetTextEngine()->GetTextLines();
557 }
558 
GetTextLines(LineEnd aSeparator) const559 String ImpSvMEdit::GetTextLines( LineEnd aSeparator ) const
560 {
561 	return mpTextWindow->GetTextEngine()->GetTextLines( aSeparator );
562 }
563 
Notify(SfxBroadcaster &,const SfxHint & rHint)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 
SetSelection(const Selection & rSelection)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 
GetSelection() const646 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 
CalcMinimumSize() const677 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 
CalcSize(sal_uInt16 nColumns,sal_uInt16 nLines) const690 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 
GetMaxVisColumnsAndLines(sal_uInt16 & rnCols,sal_uInt16 & rnLines) const717 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 
Enable(sal_Bool bEnable)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 
HandleCommand(const CommandEvent & rCEvt)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 
TextWindow(Window * pParent)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 
~TextWindow()775 TextWindow::~TextWindow()
776 {
777 	delete mpExtTextView;
778 	delete mpExtTextEngine;
779 }
780 
MouseMove(const MouseEvent & rMEvt)781 void TextWindow::MouseMove( const MouseEvent& rMEvt )
782 {
783 	mpExtTextView->MouseMove( rMEvt );
784 	Window::MouseMove( rMEvt );
785 }
786 
MouseButtonDown(const MouseEvent & rMEvt)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 
MouseButtonUp(const MouseEvent & rMEvt)796 void TextWindow::MouseButtonUp( const MouseEvent& rMEvt )
797 {
798 	mpExtTextView->MouseButtonUp( rMEvt );
799 	Window::MouseButtonUp( rMEvt );
800 }
801 
KeyInput(const KeyEvent & rKEvent)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 
Paint(const Rectangle & rRect)843 void TextWindow::Paint( const Rectangle& rRect )
844 {
845 	mpExtTextView->Paint( rRect );
846 }
847 
Resize()848 void TextWindow::Resize()
849 {
850 }
851 
Command(const CommandEvent & rCEvt)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 
GetFocus()942 void TextWindow::GetFocus()
943 {
944     Window::GetFocus();
945 
946     if ( !mbActivePopup )
947     {
948         sal_Bool bGotoCursor = !mpExtTextView->IsReadOnly();
949         if ( mbFocusSelectionHide
950              && IsReallyVisible()
951              && !mpExtTextView->IsReadOnly()
952              && ( mbSelectOnTab
953                   && ( !mbInMBDown
954                        || ( GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_FOCUS ) ) ) )
955         {
956             // Alles selektieren, aber nicht scrollen
957             sal_Bool bAutoScroll = mpExtTextView->IsAutoScroll();
958             mpExtTextView->SetAutoScroll( sal_False );
959             mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
960             mpExtTextView->SetAutoScroll( bAutoScroll );
961             bGotoCursor = sal_False;
962         }
963         mpExtTextView->SetPaintSelection( sal_True );
964         mpExtTextView->ShowCursor( bGotoCursor );
965     }
966 }
967 
968 
LoseFocus()969 void TextWindow::LoseFocus()
970 {
971     Window::LoseFocus();
972 
973     if ( mbFocusSelectionHide && !mbActivePopup )
974         mpExtTextView->SetPaintSelection( sal_False );
975 }
976 
977 
978 // virtual
979 ::css::uno::Reference< ::css::awt::XWindowPeer >
GetComponentInterface(sal_Bool bCreate)980 TextWindow::GetComponentInterface(sal_Bool bCreate)
981 {
982     ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
983         Window::GetComponentInterface(false));
984     if (!xPeer.is() && bCreate)
985     {
986         xPeer = new ::svt::TextWindowPeer(*GetTextView(), true);
987         SetComponentInterface(xPeer);
988     }
989     return xPeer;
990 }
991 
MultiLineEdit(Window * pParent,WinBits nWinStyle)992 MultiLineEdit::MultiLineEdit( Window* pParent, WinBits nWinStyle )
993 	: Edit( pParent, nWinStyle )
994 {
995 	SetType( WINDOW_MULTILINEEDIT );
996 	pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
997 	ImplInitSettings( sal_True, sal_True, sal_True );
998 	pUpdateDataTimer = 0;
999 
1000 	SetCompoundControl( sal_True );
1001 	SetStyle( ImplInitStyle( nWinStyle ) );
1002 }
1003 
MultiLineEdit(Window * pParent,const ResId & rResId)1004 MultiLineEdit::MultiLineEdit( Window* pParent, const ResId& rResId )
1005 	: Edit( pParent, rResId.SetRT( RSC_MULTILINEEDIT ) )
1006 {
1007 	SetType( WINDOW_MULTILINEEDIT );
1008     WinBits nWinStyle = rResId.GetWinBits();
1009 	pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
1010 	ImplInitSettings( sal_True, sal_True, sal_True );
1011 	pUpdateDataTimer = 0;
1012 
1013 	sal_uInt16 nMaxLen = Edit::GetMaxTextLen();
1014 	if ( nMaxLen )
1015 		SetMaxTextLen( nMaxLen );
1016 
1017 	SetText( Edit::GetText() );
1018 
1019 	if ( IsVisible() )
1020 		pImpSvMEdit->Resize();
1021 
1022 	SetCompoundControl( sal_True );
1023 	SetStyle( ImplInitStyle( nWinStyle ) );
1024 
1025     // Base Edit ctor could call Show already, but that would cause problems
1026     // with accessibility, as Show might (indirectly) trigger a call to virtual
1027     // GetComponentInterface, which is the Edit's base version instead of the
1028     // MultiLineEdit's version while in the base Edit ctor:
1029     if ((GetStyle() & WB_HIDE) == 0)
1030         Show();
1031 }
1032 
~MultiLineEdit()1033 MultiLineEdit::~MultiLineEdit()
1034 {
1035     {
1036         ::std::auto_ptr< ImpSvMEdit > pDelete( pImpSvMEdit );
1037         pImpSvMEdit = NULL;
1038     }
1039 	delete pUpdateDataTimer;
1040 }
1041 
ImplInitStyle(WinBits nStyle)1042 WinBits MultiLineEdit::ImplInitStyle( WinBits nStyle )
1043 {
1044 	if ( !(nStyle & WB_NOTABSTOP) )
1045 		nStyle |= WB_TABSTOP;
1046 
1047 	if ( !(nStyle & WB_NOGROUP) )
1048 		nStyle |= WB_GROUP;
1049 
1050 	if ( !(nStyle & WB_IGNORETAB ))
1051 		nStyle |= WINDOW_DLGCTRL_MOD1TAB;
1052 
1053 	return nStyle;
1054 }
1055 
1056 
ImplInitSettings(sal_Bool,sal_Bool,sal_Bool bBackground)1057 void MultiLineEdit::ImplInitSettings( sal_Bool /*bFont*/, sal_Bool /*bForeground*/, sal_Bool bBackground )
1058 {
1059 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1060 
1061 	// Der Font muss immer mit manipuliert werden, weil die TextEngine
1062 	// sich nicht um TextColor/Background kuemmert
1063 
1064 	Color aTextColor = rStyleSettings.GetFieldTextColor();
1065 	if ( IsControlForeground() )
1066 		aTextColor = GetControlForeground();
1067     if ( !IsEnabled() )
1068         aTextColor = rStyleSettings.GetDisableColor();
1069 
1070 	Font aFont = rStyleSettings.GetFieldFont();
1071 	if ( IsControlFont() )
1072 		aFont.Merge( GetControlFont() );
1073 	aFont.SetTransparent( IsPaintTransparent() );
1074 	SetZoomedPointFont( aFont );
1075 	Font TheFont = GetFont();
1076 	TheFont.SetColor( aTextColor );
1077     if( IsPaintTransparent() )
1078         TheFont.SetFillColor( Color( COL_TRANSPARENT ) );
1079     else
1080         TheFont.SetFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() );
1081 	pImpSvMEdit->GetTextWindow()->SetFont( TheFont );
1082 	pImpSvMEdit->GetTextWindow()->GetTextEngine()->SetFont( TheFont );
1083 	pImpSvMEdit->GetTextWindow()->SetTextColor( aTextColor );
1084 
1085 	if ( bBackground )
1086 	{
1087         if( IsPaintTransparent() )
1088         {
1089             pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
1090             pImpSvMEdit->GetTextWindow()->SetBackground();
1091             pImpSvMEdit->GetTextWindow()->SetControlBackground();
1092             SetBackground();
1093             SetControlBackground();
1094         }
1095         else
1096         {
1097             if( IsControlBackground() )
1098                 pImpSvMEdit->GetTextWindow()->SetBackground( GetControlBackground() );
1099             else
1100                 pImpSvMEdit->GetTextWindow()->SetBackground( rStyleSettings.GetFieldColor() );
1101             // Auch am MultiLineEdit einstellen, weil die TextComponent
1102             // ggf. die Scrollbars hidet.
1103             SetBackground( pImpSvMEdit->GetTextWindow()->GetBackground() );
1104         }
1105 	}
1106 }
1107 
Modify()1108 void MultiLineEdit::Modify()
1109 {
1110 	aModifyHdlLink.Call( this );
1111 
1112     CallEventListeners( VCLEVENT_EDIT_MODIFY );
1113 
1114     if ( pUpdateDataTimer )
1115 		pUpdateDataTimer->Start();
1116 }
1117 
IMPL_LINK(MultiLineEdit,ImpUpdateDataHdl,Timer *,EMPTYARG)1118 IMPL_LINK( MultiLineEdit, ImpUpdateDataHdl, Timer*, EMPTYARG )
1119 {
1120 	UpdateData();
1121 	return 0;
1122 }
1123 
UpdateData()1124 void MultiLineEdit::UpdateData()
1125 {
1126 	aUpdateDataHdlLink.Call( this );
1127 }
1128 
SetModifyFlag()1129 void MultiLineEdit::SetModifyFlag()
1130 {
1131 	pImpSvMEdit->SetModified( sal_True );
1132 }
1133 
ClearModifyFlag()1134 void MultiLineEdit::ClearModifyFlag()
1135 {
1136 	pImpSvMEdit->SetModified( sal_False );
1137 }
1138 
IsModified() const1139 sal_Bool MultiLineEdit::IsModified() const
1140 {
1141 	return pImpSvMEdit->IsModified();
1142 }
1143 
EnableUpdateData(sal_uLong nTimeout)1144 void MultiLineEdit::EnableUpdateData( sal_uLong nTimeout )
1145 {
1146 	if ( !nTimeout )
1147 		DisableUpdateData();
1148 	else
1149 	{
1150 		if ( !pUpdateDataTimer )
1151 		{
1152 			pUpdateDataTimer = new Timer;
1153 			pUpdateDataTimer->SetTimeoutHdl( LINK( this, MultiLineEdit, ImpUpdateDataHdl ) );
1154 		}
1155 		pUpdateDataTimer->SetTimeout( nTimeout );
1156 	}
1157 }
1158 
SetReadOnly(sal_Bool bReadOnly)1159 void MultiLineEdit::SetReadOnly( sal_Bool bReadOnly )
1160 {
1161 	pImpSvMEdit->SetReadOnly( bReadOnly );
1162 	Edit::SetReadOnly( bReadOnly );
1163 
1164     // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set.
1165     WinBits nStyle = GetStyle();
1166     if ( bReadOnly )
1167         nStyle |= WB_READONLY;
1168     else
1169         nStyle &= ~WB_READONLY;
1170     SetStyle( nStyle );
1171 }
1172 
IsReadOnly() const1173 sal_Bool MultiLineEdit::IsReadOnly() const
1174 {
1175 	return pImpSvMEdit->IsReadOnly();
1176 }
1177 
SetMaxTextLen(xub_StrLen nMaxLen)1178 void MultiLineEdit::SetMaxTextLen( xub_StrLen nMaxLen )
1179 {
1180 	pImpSvMEdit->SetMaxTextLen( nMaxLen );
1181 }
1182 
GetMaxTextLen() const1183 xub_StrLen MultiLineEdit::GetMaxTextLen() const
1184 {
1185 	return pImpSvMEdit->GetMaxTextLen();
1186 }
1187 
ReplaceSelected(const String & rStr)1188 void MultiLineEdit::ReplaceSelected( const String& rStr )
1189 {
1190 	pImpSvMEdit->InsertText( rStr );
1191 }
1192 
DeleteSelected()1193 void MultiLineEdit::DeleteSelected()
1194 {
1195 	pImpSvMEdit->InsertText( String() );
1196 }
1197 
GetSelected() const1198 String MultiLineEdit::GetSelected() const
1199 {
1200 	return pImpSvMEdit->GetSelected();
1201 }
1202 
GetSelected(LineEnd aSeparator) const1203 String MultiLineEdit::GetSelected( LineEnd aSeparator ) const
1204 {
1205 	return pImpSvMEdit->GetSelected( aSeparator );
1206 }
1207 
Cut()1208 void MultiLineEdit::Cut()
1209 {
1210 	pImpSvMEdit->Cut();
1211 }
1212 
Copy()1213 void MultiLineEdit::Copy()
1214 {
1215 	pImpSvMEdit->Copy();
1216 }
1217 
Paste()1218 void MultiLineEdit::Paste()
1219 {
1220 	pImpSvMEdit->Paste();
1221 }
1222 
SetText(const String & rStr)1223 void MultiLineEdit::SetText( const String& rStr )
1224 {
1225 	pImpSvMEdit->SetText( rStr );
1226 }
1227 
GetText() const1228 String MultiLineEdit::GetText() const
1229 {
1230 	return pImpSvMEdit->GetText();
1231 }
1232 
GetText(LineEnd aSeparator) const1233 String MultiLineEdit::GetText( LineEnd aSeparator ) const
1234 {
1235 	return pImpSvMEdit->GetText( aSeparator );
1236 }
1237 
GetTextLines() const1238 String MultiLineEdit::GetTextLines() const
1239 {
1240 	return pImpSvMEdit->GetTextLines();
1241 }
1242 
GetTextLines(LineEnd aSeparator) const1243 String MultiLineEdit::GetTextLines(  LineEnd aSeparator ) const
1244 {
1245 	return pImpSvMEdit->GetTextLines( aSeparator );
1246 }
1247 
Resize()1248 void MultiLineEdit::Resize()
1249 {
1250 	pImpSvMEdit->Resize();
1251 }
1252 
GetFocus()1253 void MultiLineEdit::GetFocus()
1254 {
1255     if ( pImpSvMEdit == NULL )  // might be called from within the dtor, when pImpSvMEdit == NULL is a valid state
1256         return;
1257 
1258     Edit::GetFocus();
1259 
1260     pImpSvMEdit->GetFocus();
1261 }
1262 
1263 
SetSelection(const Selection & rSelection)1264 void MultiLineEdit::SetSelection( const Selection& rSelection )
1265 {
1266 	pImpSvMEdit->SetSelection( rSelection );
1267 }
1268 
GetSelection() const1269 const Selection& MultiLineEdit::GetSelection() const
1270 {
1271 	return pImpSvMEdit->GetSelection();
1272 }
1273 
CalcMinimumSize() const1274 Size MultiLineEdit::CalcMinimumSize() const
1275 {
1276 	Size aSz = pImpSvMEdit->CalcMinimumSize();
1277 
1278 	sal_Int32 nLeft, nTop, nRight, nBottom;
1279 	((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1280 	aSz.Width() += nLeft+nRight;
1281 	aSz.Height() += nTop+nBottom;
1282 
1283 	return aSz;
1284 }
1285 
CalcAdjustedSize(const Size & rPrefSize) const1286 Size MultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const
1287 {
1288 	Size aSz = rPrefSize;
1289 	sal_Int32 nLeft, nTop, nRight, nBottom;
1290 	((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1291 
1292 	// In der Hoehe auf ganze Zeilen justieren
1293 
1294 	long nHeight = aSz.Height() - nTop - nBottom;
1295 	long nLineHeight = pImpSvMEdit->CalcSize( 1, 1 ).Height();
1296 	long nLines = nHeight / nLineHeight;
1297 	if ( nLines < 1 )
1298 		nLines = 1;
1299 
1300 	aSz.Height() = nLines * nLineHeight;
1301 	aSz.Height() += nTop+nBottom;
1302 
1303 	return aSz;
1304 }
1305 
CalcSize(sal_uInt16 nColumns,sal_uInt16 nLines) const1306 Size MultiLineEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
1307 {
1308 	Size aSz = pImpSvMEdit->CalcSize( nColumns, nLines );
1309 
1310 	sal_Int32 nLeft, nTop, nRight, nBottom;
1311 	((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1312 	aSz.Width() += nLeft+nRight;
1313 	aSz.Height() += nTop+nBottom;
1314 	return aSz;
1315 }
1316 
GetMaxVisColumnsAndLines(sal_uInt16 & rnCols,sal_uInt16 & rnLines) const1317 void MultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
1318 {
1319 	pImpSvMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines );
1320 }
1321 
StateChanged(StateChangedType nType)1322 void MultiLineEdit::StateChanged( StateChangedType nType )
1323 {
1324 	if( nType == STATE_CHANGE_ENABLE )
1325 	{
1326 		pImpSvMEdit->Enable( IsEnabled() );
1327 		ImplInitSettings( sal_True, sal_False, sal_False );
1328 	}
1329 	else if( nType == STATE_CHANGE_READONLY )
1330 	{
1331 		pImpSvMEdit->SetReadOnly( IsReadOnly() );
1332 	}
1333 	else if ( nType == STATE_CHANGE_ZOOM )
1334 	{
1335 		pImpSvMEdit->GetTextWindow()->SetZoom( GetZoom() );
1336 		ImplInitSettings( sal_True, sal_False, sal_False );
1337 		Resize();
1338 	}
1339 	else if ( nType == STATE_CHANGE_CONTROLFONT )
1340 	{
1341 		ImplInitSettings( sal_True, sal_False, sal_False );
1342 		Resize();
1343 		Invalidate();
1344 	}
1345 	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1346 	{
1347 		ImplInitSettings( sal_False, sal_True, sal_False );
1348 		Invalidate();
1349 	}
1350 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1351 	{
1352 		ImplInitSettings( sal_False, sal_False, sal_True );
1353 		Invalidate();
1354 	}
1355 	else if ( nType == STATE_CHANGE_STYLE )
1356 	{
1357 		pImpSvMEdit->InitFromStyle( GetStyle() );
1358 		SetStyle( ImplInitStyle( GetStyle() ) );
1359 	}
1360     else if ( nType == STATE_CHANGE_INITSHOW )
1361     {
1362         if( IsPaintTransparent() )
1363         {
1364             pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
1365             pImpSvMEdit->GetTextWindow()->SetBackground();
1366             pImpSvMEdit->GetTextWindow()->SetControlBackground();
1367             SetBackground();
1368             SetControlBackground();
1369         }
1370     }
1371 
1372 	Control::StateChanged( nType );
1373 }
1374 
DataChanged(const DataChangedEvent & rDCEvt)1375 void MultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt )
1376 {
1377 	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1378 		 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1379 	{
1380 		ImplInitSettings( sal_True, sal_True, sal_True );
1381 		Resize();
1382 		Invalidate();
1383 	}
1384 	else
1385 		Control::DataChanged( rDCEvt );
1386 }
1387 
Draw(OutputDevice * pDev,const Point & rPos,const Size & rSize,sal_uLong nFlags)1388 void MultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
1389 {
1390 	ImplInitSettings( sal_True, sal_True, sal_True );
1391 
1392 	Point aPos = pDev->LogicToPixel( rPos );
1393 	Size aSize = pDev->LogicToPixel( rSize );
1394 	Font aFont = pImpSvMEdit->GetTextWindow()->GetDrawPixelFont( pDev );
1395 	aFont.SetTransparent( sal_True );
1396 	OutDevType eOutDevType = pDev->GetOutDevType();
1397 
1398 	pDev->Push();
1399 	pDev->SetMapMode();
1400 	pDev->SetFont( aFont );
1401 	pDev->SetTextFillColor();
1402 
1403 	// Border/Background
1404 	pDev->SetLineColor();
1405 	pDev->SetFillColor();
1406 	sal_Bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
1407 	sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
1408 	if ( bBorder || bBackground )
1409 	{
1410 		Rectangle aRect( aPos, aSize );
1411 		if ( bBorder )
1412 		{
1413 			DecorationView aDecoView( pDev );
1414 			aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
1415 		}
1416 		if ( bBackground )
1417 		{
1418 			pDev->SetFillColor( GetControlBackground() );
1419 			pDev->DrawRect( aRect );
1420 		}
1421 	}
1422 
1423 	// Inhalt
1424 	if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
1425 		pDev->SetTextColor( Color( COL_BLACK ) );
1426 	else
1427 	{
1428 		if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
1429 		{
1430 			const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1431 			pDev->SetTextColor( rStyleSettings.GetDisableColor() );
1432 		}
1433 		else
1434 		{
1435 			pDev->SetTextColor( GetTextColor() );
1436 		}
1437 	}
1438 
1439 	XubString aText = GetText();
1440 	Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() );
1441 	sal_uLong nLines = (sal_uLong) (aSize.Height() / aTextSz.Height());
1442 	if ( !nLines )
1443 		nLines = 1;
1444 	aTextSz.Height() = nLines*aTextSz.Height();
1445 	long nOnePixel = GetDrawPixel( pDev, 1 );
1446 	long nOffX = 3*nOnePixel;
1447 	long nOffY = 2*nOnePixel;
1448 
1449 	// Clipping?
1450 	if ( ( nOffY < 0  ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) )
1451 	{
1452 		Rectangle aClip( aPos, aSize );
1453 		if ( aTextSz.Height() > aSize.Height() )
1454 			aClip.Bottom() += aTextSz.Height() - aSize.Height() + 1;  // Damit HP-Drucker nicht 'weg-optimieren'
1455 		pDev->IntersectClipRegion( aClip );
1456 	}
1457 
1458 	TextEngine aTE;
1459 	aTE.SetText( GetText() );
1460 	aTE.SetMaxTextWidth( aSize.Width() );
1461 	aTE.SetFont( aFont );
1462 	aTE.SetTextAlign( pImpSvMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() );
1463 	aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) );
1464 
1465 	pDev->Pop();
1466 }
1467 
Notify(NotifyEvent & rNEvt)1468 long MultiLineEdit::Notify( NotifyEvent& rNEvt )
1469 {
1470 	long nDone = 0;
1471 	if( rNEvt.GetType() == EVENT_COMMAND )
1472 	{
1473 		nDone = pImpSvMEdit->HandleCommand( *rNEvt.GetCommandEvent() );
1474 	}
1475 	return nDone ? nDone : Edit::Notify( rNEvt );
1476 }
1477 
PreNotify(NotifyEvent & rNEvt)1478 long MultiLineEdit::PreNotify( NotifyEvent& rNEvt )
1479 {
1480 	long nDone = 0;
1481 
1482 #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL)
1483 	if( rNEvt.GetType() == EVENT_KEYINPUT )
1484 	{
1485 		const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1486         if ( ( rKEvent.GetKeyCode().GetCode() == KEY_W ) && rKEvent.GetKeyCode().IsMod1() && rKEvent.GetKeyCode().IsMod2() )
1487         {
1488             SetRightToLeft( !IsRightToLeft() );
1489         }
1490     }
1491 #endif
1492 
1493 	if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) )
1494 	{
1495 		const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1496 		if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) )
1497 		{
1498 			nDone = 1;
1499 			TextSelection aSel = pImpSvMEdit->GetTextWindow()->GetTextView()->GetSelection();
1500 			if ( aSel.HasRange() )
1501 			{
1502 				aSel.GetStart() = aSel.GetEnd();
1503 				pImpSvMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel );
1504 			}
1505 			else
1506 			{
1507 				switch ( rKEvent.GetKeyCode().GetCode() )
1508 				{
1509 					case KEY_UP:
1510 					{
1511 						if ( pImpSvMEdit->GetVScrollBar() )
1512 							pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEUP );
1513 					}
1514 					break;
1515 					case KEY_DOWN:
1516 					{
1517 						if ( pImpSvMEdit->GetVScrollBar() )
1518 							pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1519 					}
1520 					break;
1521 					case KEY_PAGEUP	:
1522 					{
1523 						if ( pImpSvMEdit->GetVScrollBar() )
1524 							pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEUP );
1525 					}
1526 					break;
1527 					case KEY_PAGEDOWN:
1528 					{
1529 						if ( pImpSvMEdit->GetVScrollBar() )
1530 							pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEDOWN );
1531 					}
1532 					break;
1533 					case KEY_LEFT:
1534 					{
1535 						if ( pImpSvMEdit->GetHScrollBar() )
1536 							pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEUP );
1537 					}
1538 					break;
1539 					case KEY_RIGHT:
1540 					{
1541 						if ( pImpSvMEdit->GetHScrollBar() )
1542 							pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1543 					}
1544 					break;
1545 					case KEY_HOME:
1546 					{
1547 						if ( rKEvent.GetKeyCode().IsMod1() )
1548 							pImpSvMEdit->GetTextWindow()->GetTextView()->
1549 								SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
1550 					}
1551 					break;
1552 					case KEY_END:
1553 					{
1554 						if ( rKEvent.GetKeyCode().IsMod1() )
1555 							pImpSvMEdit->GetTextWindow()->GetTextView()->
1556 								SetSelection( TextSelection( TextPaM( 0xFFFF, 0xFFFF ) ) );
1557 					}
1558 					break;
1559 					default:
1560 					{
1561 						nDone = 0;
1562 					}
1563 				}
1564 			}
1565 		}
1566 	}
1567 
1568 	return nDone ? nDone : Edit::PreNotify( rNEvt );
1569 }
1570 
1571 //
1572 // Internas fuer abgeleitete Klassen, z.B. TextComponent
1573 
GetTextEngine() const1574 ExtTextEngine* MultiLineEdit::GetTextEngine() const
1575 {
1576 	return pImpSvMEdit->GetTextWindow()->GetTextEngine();
1577 }
1578 
GetTextView() const1579 ExtTextView* MultiLineEdit::GetTextView() const
1580 {
1581 	return pImpSvMEdit->GetTextWindow()->GetTextView();
1582 }
1583 
GetHScrollBar() const1584 ScrollBar* MultiLineEdit::GetHScrollBar() const
1585 {
1586 	return pImpSvMEdit->GetHScrollBar();
1587 }
1588 
1589 
GetVScrollBar() const1590 ScrollBar* MultiLineEdit::GetVScrollBar() const
1591 {
1592 	return pImpSvMEdit->GetVScrollBar();
1593 }
1594 
EnableFocusSelectionHide(sal_Bool bHide)1595 void MultiLineEdit::EnableFocusSelectionHide( sal_Bool bHide )
1596 {
1597 	pImpSvMEdit->GetTextWindow()->SetAutoFocusHide( bHide );
1598 }
1599 
IsFocusSelectionHideEnabled() const1600 sal_Bool MultiLineEdit::IsFocusSelectionHideEnabled() const
1601 {
1602 	return pImpSvMEdit->GetTextWindow()->IsAutoFocusHide();
1603 }
1604 
1605 
SetLeftMargin(sal_uInt16 n)1606 void MultiLineEdit::SetLeftMargin( sal_uInt16 n )
1607 {
1608     if ( GetTextEngine() )
1609         GetTextEngine()->SetLeftMargin( n );
1610 }
1611 
GetLeftMargin() const1612 sal_uInt16 MultiLineEdit::GetLeftMargin() const
1613 {
1614     if ( GetTextEngine() )
1615         return GetTextEngine()->GetLeftMargin();
1616     else
1617         return 0;
1618 }
1619 
SetRightToLeft(sal_Bool bRightToLeft)1620 void MultiLineEdit::SetRightToLeft( sal_Bool bRightToLeft )
1621 {
1622     if ( GetTextEngine() )
1623     {
1624         GetTextEngine()->SetRightToLeft( bRightToLeft );
1625         GetTextView()->ShowCursor();
1626     }
1627 }
1628 
IsRightToLeft() const1629 sal_Bool MultiLineEdit::IsRightToLeft() const
1630 {
1631     sal_Bool bRightToLeft = sal_False;
1632 
1633     if ( GetTextEngine() )
1634         bRightToLeft = GetTextEngine()->IsRightToLeft();
1635 
1636     return bRightToLeft;
1637 }
1638 
1639 // virtual
1640 ::css::uno::Reference< ::css::awt::XWindowPeer >
GetComponentInterface(sal_Bool bCreate)1641 MultiLineEdit::GetComponentInterface(sal_Bool bCreate)
1642 {
1643     ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
1644         Edit::GetComponentInterface(false));
1645     if (!xPeer.is() && bCreate)
1646     {
1647         ::std::auto_ptr< VCLXMultiLineEdit > xEdit(new VCLXMultiLineEdit());
1648         xEdit->SetWindow(this);
1649         xPeer = xEdit.release();
1650         SetComponentInterface(xPeer);
1651     }
1652     return xPeer;
1653 }
1654 /*-- 11.08.2004 11:29:23---------------------------------------------------
1655 
1656   -----------------------------------------------------------------------*/
DisableSelectionOnFocus()1657 void MultiLineEdit::DisableSelectionOnFocus()
1658 {
1659     pImpSvMEdit->GetTextWindow()->DisableSelectionOnFocus();
1660 }
1661