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