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