Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / source / edit / vclmedit.cxx
blobcc2b52e658b7929f9815c3b63aac66f8bfe7a4a0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <memory>
21 #include <i18nlangtag/languagetag.hxx>
22 #include <vcl/commandevent.hxx>
23 #include <vcl/builder.hxx>
24 #include <vcl/decoview.hxx>
25 #include <vcl/event.hxx>
26 #include <vcl/timer.hxx>
27 #include <vcl/vclmedit.hxx>
28 #include <vcl/xtextedt.hxx>
29 #include <vcl/textview.hxx>
30 #include <vcl/ptrstyle.hxx>
32 #include <svl/undo.hxx>
33 #include <svl/lstner.hxx>
34 #include <vcl/uitest/uiobject.hxx>
36 #include <vcl/scrbar.hxx>
37 #include <vcl/settings.hxx>
38 #include <vcl/weld.hxx>
39 #include <osl/diagnose.h>
41 class ImpVclMEdit : public SfxListener
43 private:
44 VclPtr<VclMultiLineEdit> pVclMultiLineEdit;
46 VclPtr<TextWindow> mpTextWindow;
47 VclPtr<ScrollBar> mpHScrollBar;
48 VclPtr<ScrollBar> mpVScrollBar;
49 VclPtr<ScrollBarBox> mpScrollBox;
51 long mnTextWidth;
52 mutable Selection maSelection;
54 protected:
55 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
56 void ImpUpdateSrollBarVis( WinBits nWinStyle );
57 void ImpInitScrollBars();
58 void ImpSetScrollBarRanges();
59 void ImpSetHScrollBarThumbPos();
60 DECL_LINK( ScrollHdl, ScrollBar*, void );
62 public:
63 ImpVclMEdit( VclMultiLineEdit* pVclMultiLineEdit, WinBits nWinStyle );
64 virtual ~ImpVclMEdit() override;
66 void SetModified( bool bMod );
67 bool IsModified() const;
69 void SetReadOnly( bool bRdOnly );
70 bool IsReadOnly() const;
72 void SetMaxTextLen(sal_Int32 nLen);
73 sal_Int32 GetMaxTextLen() const;
75 void SetMaxTextWidth(long nMaxWidth);
77 void InsertText( const OUString& rStr );
78 OUString GetSelected() const;
79 OUString GetSelected( LineEnd aSeparator ) const;
81 void SetSelection( const Selection& rSelection );
82 const Selection& GetSelection() const;
84 void Cut();
85 void Copy();
86 void Paste();
88 void SetText( const OUString& rStr );
89 OUString GetText() const;
90 OUString GetText( LineEnd aSeparator ) const;
91 OUString GetTextLines( LineEnd aSeparator ) const;
93 void Resize();
94 void GetFocus();
96 bool HandleCommand( const CommandEvent& rCEvt );
98 void Enable( bool bEnable );
100 Size CalcMinimumSize() const;
101 Size CalcBlockSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const;
102 void GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const;
104 void SetAlign( WinBits nWinStyle );
106 void InitFromStyle( WinBits nWinStyle );
108 TextWindow* GetTextWindow() { return mpTextWindow; }
109 ScrollBar& GetHScrollBar() { return *mpHScrollBar; }
110 ScrollBar& GetVScrollBar() { return *mpVScrollBar; }
113 ImpVclMEdit::ImpVclMEdit( VclMultiLineEdit* pEdt, WinBits nWinStyle )
114 : pVclMultiLineEdit(pEdt)
115 , mpTextWindow(VclPtr<TextWindow>::Create(pEdt))
116 , mpHScrollBar(VclPtr<ScrollBar>::Create(pVclMultiLineEdit, WB_HSCROLL|WB_DRAG))
117 , mpVScrollBar(VclPtr<ScrollBar>::Create(pVclMultiLineEdit, WB_VSCROLL|WB_DRAG))
118 , mpScrollBox(VclPtr<ScrollBarBox>::Create(pVclMultiLineEdit, WB_SIZEABLE))
119 , mnTextWidth(0)
121 mpVScrollBar->SetScrollHdl( LINK( this, ImpVclMEdit, ScrollHdl ) );
122 mpHScrollBar->SetScrollHdl( LINK( this, ImpVclMEdit, ScrollHdl ) );
123 mpTextWindow->Show();
124 InitFromStyle( nWinStyle );
125 StartListening( *mpTextWindow->GetTextEngine() );
128 void ImpVclMEdit::ImpUpdateSrollBarVis( WinBits nWinStyle )
130 const bool bHaveVScroll = mpVScrollBar->IsVisible();
131 const bool bHaveHScroll = mpHScrollBar->IsVisible();
132 const bool bHaveScrollBox = mpScrollBox->IsVisible();
134 bool bNeedVScroll = ( nWinStyle & WB_VSCROLL ) == WB_VSCROLL;
135 const bool bNeedHScroll = ( nWinStyle & WB_HSCROLL ) == WB_HSCROLL;
137 const bool bAutoVScroll = ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL;
138 if ( !bNeedVScroll && bAutoVScroll )
140 TextEngine& rEngine( *mpTextWindow->GetTextEngine() );
141 long nOverallTextHeight(0);
142 for ( sal_uInt32 i=0; i<rEngine.GetParagraphCount(); ++i )
143 nOverallTextHeight += rEngine.GetTextHeight( i );
144 if ( nOverallTextHeight > mpTextWindow->GetOutputSizePixel().Height() )
145 bNeedVScroll = true;
148 const bool bNeedScrollBox = bNeedVScroll && bNeedHScroll;
150 bool bScrollbarsChanged = false;
151 if ( bHaveVScroll != bNeedVScroll )
153 mpVScrollBar->Show(bNeedVScroll);
154 bScrollbarsChanged = true;
157 if ( bHaveHScroll != bNeedHScroll )
159 mpHScrollBar->Show(bNeedHScroll);
160 bScrollbarsChanged = true;
163 if ( bHaveScrollBox != bNeedScrollBox )
165 mpScrollBox->Show(bNeedScrollBox);
168 if ( bScrollbarsChanged )
170 ImpInitScrollBars();
171 Resize();
175 void ImpVclMEdit::InitFromStyle( WinBits nWinStyle )
177 ImpUpdateSrollBarVis( nWinStyle );
178 SetAlign( nWinStyle );
180 if ( nWinStyle & WB_NOHIDESELECTION )
181 mpTextWindow->SetAutoFocusHide( false );
182 else
183 mpTextWindow->SetAutoFocusHide( true );
185 if ( nWinStyle & WB_READONLY )
186 mpTextWindow->GetTextView()->SetReadOnly( true );
187 else
188 mpTextWindow->GetTextView()->SetReadOnly( false );
190 if ( nWinStyle & WB_IGNORETAB )
192 mpTextWindow->SetIgnoreTab( true );
194 else
196 mpTextWindow->SetIgnoreTab( false );
197 // #103667# VclMultiLineEdit has the flag, but focusable window also needs this flag
198 WinBits nStyle = mpTextWindow->GetStyle();
199 nStyle |= WB_NODIALOGCONTROL;
200 mpTextWindow->SetStyle( nStyle );
204 ImpVclMEdit::~ImpVclMEdit()
206 EndListening( *mpTextWindow->GetTextEngine() );
207 mpTextWindow.disposeAndClear();
208 mpHScrollBar.disposeAndClear();
209 mpVScrollBar.disposeAndClear();
210 mpScrollBox.disposeAndClear();
211 pVclMultiLineEdit.disposeAndClear();
214 void ImpVclMEdit::ImpSetScrollBarRanges()
216 const long nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
217 mpVScrollBar->SetRange( Range( 0, nTextHeight-1 ) );
219 mpHScrollBar->SetRange( Range( 0, mnTextWidth-1 ) );
222 void ImpVclMEdit::ImpInitScrollBars()
224 static const sal_Unicode sampleChar = { 'x' };
226 ImpSetScrollBarRanges();
228 Size aCharBox;
229 aCharBox.setWidth( mpTextWindow->GetTextWidth( OUString(sampleChar) ) );
230 aCharBox.setHeight( mpTextWindow->GetTextHeight() );
231 Size aOutSz = mpTextWindow->GetOutputSizePixel();
233 mpHScrollBar->SetVisibleSize( aOutSz.Width() );
234 mpHScrollBar->SetPageSize( aOutSz.Width() * 8 / 10 );
235 mpHScrollBar->SetLineSize( aCharBox.Width()*10 );
236 ImpSetHScrollBarThumbPos();
238 mpVScrollBar->SetVisibleSize( aOutSz.Height() );
239 mpVScrollBar->SetPageSize( aOutSz.Height() * 8 / 10 );
240 mpVScrollBar->SetLineSize( aCharBox.Height() );
241 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
244 void ImpVclMEdit::ImpSetHScrollBarThumbPos()
246 long nX = mpTextWindow->GetTextView()->GetStartDocPos().X();
247 if ( !mpTextWindow->GetTextEngine()->IsRightToLeft() )
248 mpHScrollBar->SetThumbPos( nX );
249 else
250 mpHScrollBar->SetThumbPos( mnTextWidth - mpHScrollBar->GetVisibleSize() - nX );
254 IMPL_LINK( ImpVclMEdit, ScrollHdl, ScrollBar*, pCurScrollBar, void )
256 long nDiffX = 0, nDiffY = 0;
258 if ( pCurScrollBar == mpVScrollBar )
259 nDiffY = mpTextWindow->GetTextView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
260 else if ( pCurScrollBar == mpHScrollBar )
261 nDiffX = mpTextWindow->GetTextView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
263 mpTextWindow->GetTextView()->Scroll( nDiffX, nDiffY );
264 // mpTextWindow->GetTextView()->ShowCursor( false, true );
267 void ImpVclMEdit::SetAlign( WinBits nWinStyle )
269 bool bRTL = AllSettings::GetLayoutRTL();
270 mpTextWindow->GetTextEngine()->SetRightToLeft( bRTL );
272 if ( nWinStyle & WB_CENTER )
273 mpTextWindow->GetTextEngine()->SetTextAlign( TxtAlign::Center );
274 else if ( nWinStyle & WB_RIGHT )
275 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TxtAlign::Right : TxtAlign::Left );
276 else if ( nWinStyle & WB_LEFT )
277 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TxtAlign::Left : TxtAlign::Right );
280 void ImpVclMEdit::SetModified( bool bMod )
282 mpTextWindow->GetTextEngine()->SetModified( bMod );
285 bool ImpVclMEdit::IsModified() const
287 return mpTextWindow->GetTextEngine()->IsModified();
290 void ImpVclMEdit::SetReadOnly( bool bRdOnly )
292 mpTextWindow->GetTextView()->SetReadOnly( bRdOnly );
293 // TODO: Adjust color?
296 bool ImpVclMEdit::IsReadOnly() const
298 return mpTextWindow->GetTextView()->IsReadOnly();
301 void ImpVclMEdit::SetMaxTextLen(sal_Int32 nLen)
303 mpTextWindow->GetTextEngine()->SetMaxTextLen(nLen);
306 sal_Int32 ImpVclMEdit::GetMaxTextLen() const
308 return mpTextWindow->GetTextEngine()->GetMaxTextLen();
311 void ImpVclMEdit::InsertText( const OUString& rStr )
313 mpTextWindow->GetTextView()->InsertText( rStr );
316 OUString ImpVclMEdit::GetSelected() const
318 return mpTextWindow->GetTextView()->GetSelected();
321 OUString ImpVclMEdit::GetSelected( LineEnd aSeparator ) const
323 return mpTextWindow->GetTextView()->GetSelected( aSeparator );
326 void ImpVclMEdit::SetMaxTextWidth(long nMaxWidth)
328 mpTextWindow->GetTextEngine()->SetMaxTextWidth(nMaxWidth);
331 void ImpVclMEdit::Resize()
333 int nIteration = 1;
336 WinBits nWinStyle( pVclMultiLineEdit->GetStyle() );
337 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
338 ImpUpdateSrollBarVis( nWinStyle );
340 Size aSz = pVclMultiLineEdit->GetOutputSizePixel();
341 Size aEditSize = aSz;
342 long nSBWidth = pVclMultiLineEdit->GetSettings().GetStyleSettings().GetScrollBarSize();
343 nSBWidth = pVclMultiLineEdit->CalcZoom( nSBWidth );
345 if (mpHScrollBar->IsVisible())
346 aSz.AdjustHeight( -(nSBWidth+1) );
347 if (mpVScrollBar->IsVisible())
348 aSz.AdjustWidth( -(nSBWidth+1) );
350 if (!mpHScrollBar->IsVisible())
351 mpTextWindow->GetTextEngine()->SetMaxTextWidth( aSz.Width() );
352 else
353 mpHScrollBar->setPosSizePixel( 0, aEditSize.Height()-nSBWidth, aSz.Width(), nSBWidth );
355 Point aTextWindowPos;
356 if (mpVScrollBar->IsVisible())
358 if( AllSettings::GetLayoutRTL() )
360 mpVScrollBar->setPosSizePixel( 0, 0, nSBWidth, aSz.Height() );
361 aTextWindowPos.AdjustX(nSBWidth );
363 else
364 mpVScrollBar->setPosSizePixel( aEditSize.Width()-nSBWidth, 0, nSBWidth, aSz.Height() );
367 if (mpScrollBox->IsVisible())
368 mpScrollBox->setPosSizePixel( aSz.Width(), aSz.Height(), nSBWidth, nSBWidth );
370 Size aTextWindowSize( aSz );
371 if ( aTextWindowSize.Width() < 0 )
372 aTextWindowSize.setWidth( 0 );
373 if ( aTextWindowSize.Height() < 0 )
374 aTextWindowSize.setHeight( 0 );
376 Size aOldTextWindowSize( mpTextWindow->GetSizePixel() );
377 mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
378 if ( aOldTextWindowSize == aTextWindowSize )
379 break;
381 // Changing the text window size might effectively have changed the need for
382 // scrollbars, so do another iteration.
383 ++nIteration;
384 OSL_ENSURE( nIteration < 3, "ImpVclMEdit::Resize: isn't this expected to terminate with the second iteration?" );
386 } while ( nIteration <= 3 ); // artificial break after four iterations
388 ImpInitScrollBars();
391 void ImpVclMEdit::GetFocus()
393 mpTextWindow->GrabFocus();
396 void ImpVclMEdit::Cut()
398 if ( !mpTextWindow->GetTextView()->IsReadOnly() )
399 mpTextWindow->GetTextView()->Cut();
402 void ImpVclMEdit::Copy()
404 mpTextWindow->GetTextView()->Copy();
407 void ImpVclMEdit::Paste()
409 if ( !mpTextWindow->GetTextView()->IsReadOnly() )
410 mpTextWindow->GetTextView()->Paste();
413 void ImpVclMEdit::SetText( const OUString& rStr )
415 bool bWasModified = mpTextWindow->GetTextEngine()->IsModified();
416 mpTextWindow->GetTextEngine()->SetText( rStr );
417 if ( !bWasModified )
418 mpTextWindow->GetTextEngine()->SetModified( false );
420 mpTextWindow->GetTextView()->SetSelection( TextSelection() );
422 WinBits nWinStyle( pVclMultiLineEdit->GetStyle() );
423 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
424 ImpUpdateSrollBarVis( nWinStyle );
427 OUString ImpVclMEdit::GetText() const
429 return mpTextWindow->GetTextEngine()->GetText();
432 OUString ImpVclMEdit::GetText( LineEnd aSeparator ) const
434 return mpTextWindow->GetTextEngine()->GetText( aSeparator );
437 OUString ImpVclMEdit::GetTextLines( LineEnd aSeparator ) const
439 return mpTextWindow->GetTextEngine()->GetTextLines( aSeparator );
442 void ImpVclMEdit::Notify( SfxBroadcaster&, const SfxHint& rHint )
444 const TextHint* pTextHint = dynamic_cast<const TextHint*>(&rHint);
445 if ( !pTextHint )
446 return;
448 switch (pTextHint->GetId())
450 case SfxHintId::TextViewScrolled:
451 if (mpHScrollBar->IsVisible())
452 ImpSetHScrollBarThumbPos();
453 if (mpVScrollBar->IsVisible())
454 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
455 break;
457 case SfxHintId::TextHeightChanged:
458 if ( mpTextWindow->GetTextView()->GetStartDocPos().Y() )
460 long nOutHeight = mpTextWindow->GetOutputSizePixel().Height();
461 long nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
462 if ( nTextHeight < nOutHeight )
463 mpTextWindow->GetTextView()->Scroll( 0, mpTextWindow->GetTextView()->GetStartDocPos().Y() );
465 ImpSetScrollBarRanges();
466 break;
468 case SfxHintId::TextFormatted:
469 if (mpHScrollBar->IsVisible())
471 const long nWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
472 if ( nWidth != mnTextWidth )
474 mnTextWidth = nWidth;
475 mpHScrollBar->SetRange( Range( 0, mnTextWidth-1 ) );
476 ImpSetHScrollBarThumbPos();
479 break;
481 case SfxHintId::TextModified:
482 ImpUpdateSrollBarVis(pVclMultiLineEdit->GetStyle());
483 pVclMultiLineEdit->Modify();
484 break;
486 case SfxHintId::TextViewSelectionChanged:
487 pVclMultiLineEdit->SelectionChanged();
488 break;
490 case SfxHintId::TextViewCaretChanged:
491 pVclMultiLineEdit->CaretChanged();
492 break;
494 default: break;
498 void ImpVclMEdit::SetSelection( const Selection& rSelection )
500 OUString aText = mpTextWindow->GetTextEngine()->GetText();
502 Selection aNewSelection( rSelection );
503 if ( aNewSelection.Min() < 0 )
504 aNewSelection.Min() = 0;
505 else if ( aNewSelection.Min() > aText.getLength() )
506 aNewSelection.Min() = aText.getLength();
507 if ( aNewSelection.Max() < 0 )
508 aNewSelection.Max() = 0;
509 else if ( aNewSelection.Max() > aText.getLength() )
510 aNewSelection.Max() = aText.getLength();
512 long nEnd = std::max( aNewSelection.Min(), aNewSelection.Max() );
513 TextSelection aTextSel;
514 sal_uInt32 nPara = 0;
515 sal_Int32 nChar = 0;
516 long x = 0;
517 while ( x <= nEnd )
519 if ( x == aNewSelection.Min() )
520 aTextSel.GetStart() = TextPaM( nPara, nChar );
521 if ( x == aNewSelection.Max() )
522 aTextSel.GetEnd() = TextPaM( nPara, nChar );
524 if ( ( x < aText.getLength() ) && ( aText[ x ] == '\n' ) )
526 nPara++;
527 nChar = 0;
529 else
530 nChar++;
531 x++;
533 mpTextWindow->GetTextView()->SetSelection( aTextSel );
536 const Selection& ImpVclMEdit::GetSelection() const
538 maSelection = Selection();
539 TextSelection aTextSel( mpTextWindow->GetTextView()->GetSelection() );
540 aTextSel.Justify();
541 // flatten selection => every line-break a character
543 ExtTextEngine* pExtTextEngine = mpTextWindow->GetTextEngine();
544 // paragraphs before
545 for ( sal_uInt32 n = 0; n < aTextSel.GetStart().GetPara(); ++n )
547 maSelection.Min() += pExtTextEngine->GetTextLen( n );
548 maSelection.Min()++;
551 // first paragraph with selection
552 maSelection.Max() = maSelection.Min();
553 maSelection.Min() += aTextSel.GetStart().GetIndex();
555 for ( sal_uInt32 n = aTextSel.GetStart().GetPara(); n < aTextSel.GetEnd().GetPara(); ++n )
557 maSelection.Max() += pExtTextEngine->GetTextLen( n );
558 maSelection.Max()++;
561 maSelection.Max() += aTextSel.GetEnd().GetIndex();
563 return maSelection;
566 Size ImpVclMEdit::CalcMinimumSize() const
568 Size aSz( mpTextWindow->GetTextEngine()->CalcTextWidth(),
569 mpTextWindow->GetTextEngine()->GetTextHeight() );
571 if (mpHScrollBar->IsVisible())
572 aSz.AdjustHeight(mpHScrollBar->GetSizePixel().Height() );
573 if (mpVScrollBar->IsVisible())
574 aSz.AdjustWidth(mpVScrollBar->GetSizePixel().Width() );
576 return aSz;
579 Size ImpVclMEdit::CalcBlockSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
581 static const sal_Unicode sampleChar = 'X';
583 Size aSz;
584 Size aCharSz;
585 aCharSz.setWidth( mpTextWindow->GetTextWidth( OUString(sampleChar) ) );
586 aCharSz.setHeight( mpTextWindow->GetTextHeight() );
588 if ( nLines )
589 aSz.setHeight( nLines*aCharSz.Height() );
590 else
591 aSz.setHeight( mpTextWindow->GetTextEngine()->GetTextHeight() );
593 if ( nColumns )
594 aSz.setWidth( nColumns*aCharSz.Width() );
595 else
596 aSz.setWidth( mpTextWindow->GetTextEngine()->CalcTextWidth() );
598 if (mpHScrollBar->IsVisible())
599 aSz.AdjustHeight(mpHScrollBar->GetSizePixel().Height() );
600 if (mpVScrollBar->IsVisible())
601 aSz.AdjustWidth(mpVScrollBar->GetSizePixel().Width() );
603 return aSz;
606 void ImpVclMEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
608 static const sal_Unicode sampleChar = { 'x' };
609 Size aOutSz = mpTextWindow->GetOutputSizePixel();
610 Size aCharSz( mpTextWindow->GetTextWidth( OUString(sampleChar) ), mpTextWindow->GetTextHeight() );
611 rnCols = static_cast<sal_uInt16>(aOutSz.Width()/aCharSz.Width());
612 rnLines = static_cast<sal_uInt16>(aOutSz.Height()/aCharSz.Height());
615 void ImpVclMEdit::Enable( bool bEnable )
617 mpTextWindow->Enable( bEnable );
618 if (mpHScrollBar->IsVisible())
619 mpHScrollBar->Enable( bEnable );
620 if (mpVScrollBar->IsVisible())
621 mpVScrollBar->Enable( bEnable );
624 bool ImpVclMEdit::HandleCommand( const CommandEvent& rCEvt )
626 bool bDone = false;
627 CommandEventId nCommand = rCEvt.GetCommand();
628 if (nCommand == CommandEventId::Wheel ||
629 nCommand == CommandEventId::StartAutoScroll ||
630 nCommand == CommandEventId::AutoScroll ||
631 nCommand == CommandEventId::Gesture)
633 ScrollBar* pHScrollBar = mpHScrollBar->IsVisible() ? mpHScrollBar.get() : nullptr;
634 ScrollBar* pVScrollBar = mpVScrollBar->IsVisible() ? mpVScrollBar.get() : nullptr;
635 mpTextWindow->HandleScrollCommand(rCEvt, pHScrollBar, pVScrollBar);
636 bDone = true;
638 return bDone;
641 TextWindow::TextWindow(Edit* pParent)
642 : Window(pParent)
643 , mxParent(pParent)
645 mbInMBDown = false;
646 mbFocusSelectionHide = false;
647 mbIgnoreTab = false;
648 mbActivePopup = false;
649 mbSelectOnTab = true;
651 SetPointer( PointerStyle::Text );
653 mpExtTextEngine.reset(new ExtTextEngine);
654 mpExtTextEngine->SetMaxTextLen(EDIT_NOLIMIT);
655 if( pParent->GetStyle() & WB_BORDER )
656 mpExtTextEngine->SetLeftMargin( 2 );
657 mpExtTextEngine->SetLocale( GetSettings().GetLanguageTag().getLocale() );
658 mpExtTextView.reset(new TextView( mpExtTextEngine.get(), this ));
659 mpExtTextEngine->InsertView( mpExtTextView.get() );
660 mpExtTextEngine->EnableUndo( true );
661 mpExtTextView->ShowCursor();
663 Color aBackgroundColor = GetSettings().GetStyleSettings().GetWorkspaceColor();
664 SetBackground( aBackgroundColor );
665 pParent->SetBackground( aBackgroundColor );
668 TextWindow::~TextWindow()
670 disposeOnce();
673 void TextWindow::dispose()
675 mxParent.clear();
676 mpExtTextView.reset();
677 mpExtTextEngine.reset();
678 Window::dispose();
681 void TextWindow::MouseMove( const MouseEvent& rMEvt )
683 mpExtTextView->MouseMove( rMEvt );
684 Window::MouseMove( rMEvt );
687 void TextWindow::MouseButtonDown( const MouseEvent& rMEvt )
689 mbInMBDown = true; // so that GetFocus does not select everything
690 mpExtTextView->MouseButtonDown( rMEvt );
691 GrabFocus();
692 mbInMBDown = false;
695 void TextWindow::MouseButtonUp( const MouseEvent& rMEvt )
697 mpExtTextView->MouseButtonUp( rMEvt );
700 void TextWindow::KeyInput( const KeyEvent& rKEvent )
702 bool bDone = false;
703 sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
704 if ( nCode == css::awt::Key::SELECT_ALL ||
705 ( (nCode == KEY_A) && rKEvent.GetKeyCode().IsMod1() && !rKEvent.GetKeyCode().IsMod2() )
708 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) ) );
709 bDone = true;
711 else if ( (nCode == KEY_S) && rKEvent.GetKeyCode().IsShift() && rKEvent.GetKeyCode().IsMod1() )
713 if ( Edit::GetGetSpecialCharsFunction() )
715 // to maintain the selection
716 mbActivePopup = true;
717 OUString aChars = Edit::GetGetSpecialCharsFunction()(GetFrameWeld(), GetFont());
718 if (!aChars.isEmpty())
720 mpExtTextView->InsertText( aChars );
721 mpExtTextView->GetTextEngine()->SetModified( true );
723 mbActivePopup = false;
724 bDone = true;
727 else if ( nCode == KEY_TAB )
729 if ( !mbIgnoreTab || rKEvent.GetKeyCode().IsMod1() )
730 bDone = mpExtTextView->KeyInput( rKEvent );
732 else
734 bDone = mpExtTextView->KeyInput( rKEvent );
737 if ( !bDone )
738 Window::KeyInput( rKEvent );
741 void TextWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
743 mpExtTextView->Paint(rRenderContext, rRect);
746 void TextWindow::Resize()
750 void TextWindow::Command( const CommandEvent& rCEvt )
752 if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
754 VclPtr<PopupMenu> pPopup = mxParent->CreatePopupMenu();
755 bool bEnableCut = true;
756 bool bEnableCopy = true;
757 bool bEnableDelete = true;
758 bool bEnablePaste = true;
759 bool bEnableSpecialChar = true;
760 bool bEnableUndo = true;
762 if ( !mpExtTextView->HasSelection() )
764 bEnableCut = false;
765 bEnableCopy = false;
766 bEnableDelete = false;
768 if ( mpExtTextView->IsReadOnly() )
770 bEnableCut = false;
771 bEnablePaste = false;
772 bEnableDelete = false;
773 bEnableSpecialChar = false;
775 if ( !mpExtTextView->GetTextEngine()->HasUndoManager() || !mpExtTextView->GetTextEngine()->GetUndoManager().GetUndoActionCount() )
777 bEnableUndo = false;
779 pPopup->EnableItem(pPopup->GetItemId("cut"), bEnableCut);
780 pPopup->EnableItem(pPopup->GetItemId("copy"), bEnableCopy);
781 pPopup->EnableItem(pPopup->GetItemId("delete"), bEnableDelete);
782 pPopup->EnableItem(pPopup->GetItemId("paste"), bEnablePaste);
783 pPopup->EnableItem(pPopup->GetItemId("specialchar"), bEnableSpecialChar);
784 pPopup->EnableItem(pPopup->GetItemId("undo"), bEnableUndo);
785 pPopup->ShowItem(pPopup->GetItemId("specialchar"), !Edit::GetGetSpecialCharsFunction());
787 mbActivePopup = true;
788 Point aPos = rCEvt.GetMousePosPixel();
789 if ( !rCEvt.IsMouseEvent() )
791 // Sometime do show Menu centered in the selection !!!
792 Size aSize = GetOutputSizePixel();
793 aPos = Point( aSize.Width()/2, aSize.Height()/2 );
795 sal_uInt16 n = pPopup->Execute( this, aPos );
796 OString sCommand = pPopup->GetItemIdent(n);
797 if (sCommand == "undo")
799 mpExtTextView->Undo();
800 mpExtTextEngine->SetModified( true );
801 mpExtTextEngine->Broadcast( TextHint( SfxHintId::TextModified ) );
803 else if (sCommand == "cut")
805 mpExtTextView->Cut();
806 mpExtTextEngine->SetModified( true );
807 mpExtTextEngine->Broadcast( TextHint( SfxHintId::TextModified ) );
809 else if (sCommand == "copy")
811 mpExtTextView->Copy();
813 else if (sCommand == "paste")
815 mpExtTextView->Paste();
816 mpExtTextEngine->SetModified( true );
817 mpExtTextEngine->Broadcast( TextHint( SfxHintId::TextModified ) );
819 else if (sCommand == "delete")
821 mpExtTextView->DeleteSelected();
822 mpExtTextEngine->SetModified( true );
823 mpExtTextEngine->Broadcast( TextHint( SfxHintId::TextModified ) );
825 else if (sCommand == "selectall")
827 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) ) );
829 else if (sCommand == "specialchar")
831 OUString aChars = Edit::GetGetSpecialCharsFunction()(GetFrameWeld(), GetFont());
832 if (!aChars.isEmpty())
834 mpExtTextView->InsertText( aChars );
835 mpExtTextEngine->SetModified( true );
836 mpExtTextEngine->Broadcast( TextHint( SfxHintId::TextModified ) );
839 pPopup.clear();
840 mbActivePopup = false;
842 else
844 mpExtTextView->Command( rCEvt );
846 Window::Command( rCEvt );
849 void TextWindow::GetFocus()
851 Window::GetFocus();
852 if ( !mbActivePopup )
854 bool bGotoCursor = !mpExtTextView->IsReadOnly();
855 if ( mbFocusSelectionHide && IsReallyVisible() && !mpExtTextView->IsReadOnly()
856 && ( mbSelectOnTab &&
857 (!mbInMBDown || ( GetSettings().GetStyleSettings().GetSelectionOptions() & SelectionOptions::Focus ) )) )
859 // select everything, but do not scroll
860 bool bAutoScroll = mpExtTextView->IsAutoScroll();
861 mpExtTextView->SetAutoScroll( false );
862 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) ) );
863 mpExtTextView->SetAutoScroll( bAutoScroll );
864 bGotoCursor = false;
866 mpExtTextView->SetPaintSelection( true );
867 mpExtTextView->ShowCursor( bGotoCursor );
871 void TextWindow::LoseFocus()
873 Window::LoseFocus();
875 if ( mbFocusSelectionHide && !mbActivePopup && mpExtTextView )
876 mpExtTextView->SetPaintSelection( false );
879 VclMultiLineEdit::VclMultiLineEdit( vcl::Window* pParent, WinBits nWinStyle )
880 : Edit( pParent, nWinStyle )
882 SetType( WindowType::MULTILINEEDIT );
883 pImpVclMEdit.reset(new ImpVclMEdit( this, nWinStyle ));
884 ImplInitSettings( true );
885 pUpdateDataTimer = nullptr;
887 SetCompoundControl( true );
888 SetStyle( ImplInitStyle( nWinStyle ) );
891 VclMultiLineEdit::~VclMultiLineEdit()
893 disposeOnce();
896 void VclMultiLineEdit::dispose()
898 pImpVclMEdit.reset();
899 pUpdateDataTimer.reset();
900 Edit::dispose();
903 WinBits VclMultiLineEdit::ImplInitStyle( WinBits nStyle )
905 if ( !(nStyle & WB_NOTABSTOP) )
906 nStyle |= WB_TABSTOP;
908 if ( !(nStyle & WB_NOGROUP) )
909 nStyle |= WB_GROUP;
911 if ( !(nStyle & WB_IGNORETAB ))
912 nStyle |= WB_NODIALOGCONTROL;
914 return nStyle;
917 void VclMultiLineEdit::ApplyBackgroundSettings(vcl::RenderContext& rRenderContext, const StyleSettings& rStyleSettings)
919 if (IsPaintTransparent())
921 pImpVclMEdit->GetTextWindow()->SetPaintTransparent(true);
922 pImpVclMEdit->GetTextWindow()->SetBackground();
923 pImpVclMEdit->GetTextWindow()->SetControlBackground();
924 rRenderContext.SetBackground();
925 SetControlBackground();
927 else
929 if (IsControlBackground())
930 pImpVclMEdit->GetTextWindow()->SetBackground(GetControlBackground());
931 else
932 pImpVclMEdit->GetTextWindow()->SetBackground(rStyleSettings.GetFieldColor());
933 // also adjust for VclMultiLineEdit as the TextComponent might hide Scrollbars
934 rRenderContext.SetBackground(pImpVclMEdit->GetTextWindow()->GetBackground());
938 void VclMultiLineEdit::ApplyFontSettings(vcl::RenderContext& rRenderContext, const StyleSettings& rStyleSettings)
940 // The Font has to be adjusted, as the TextEngine does not take care of
941 // TextColor/Background
943 Color aTextColor = rStyleSettings.GetFieldTextColor();
944 if (IsControlForeground())
945 aTextColor = GetControlForeground();
946 if (!IsEnabled())
947 aTextColor = rStyleSettings.GetDisableColor();
949 vcl::Font aFont = rStyleSettings.GetFieldFont();
950 aFont.SetTransparent(IsPaintTransparent());
951 ApplyControlFont(rRenderContext, aFont);
953 vcl::Font TheFont = rRenderContext.GetFont();
954 TheFont.SetColor(aTextColor);
955 if (IsPaintTransparent())
956 TheFont.SetFillColor(COL_TRANSPARENT);
957 else
958 TheFont.SetFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor());
960 pImpVclMEdit->GetTextWindow()->SetFont(TheFont);
961 pImpVclMEdit->GetTextWindow()->GetTextEngine()->SetFont(TheFont);
962 pImpVclMEdit->GetTextWindow()->SetTextColor(aTextColor);
965 void VclMultiLineEdit::ApplySettings(vcl::RenderContext& rRenderContext)
967 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
969 ApplyFontSettings(rRenderContext, rStyleSettings);
970 ApplyBackgroundSettings(rRenderContext, rStyleSettings);
973 void VclMultiLineEdit::ImplInitSettings(bool bBackground)
975 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
977 ApplyFontSettings(*this, rStyleSettings);
979 if (bBackground)
980 ApplyBackgroundSettings(*this, rStyleSettings);
983 void VclMultiLineEdit::Modify()
985 aModifyHdlLink.Call( *this );
987 CallEventListeners( VclEventId::EditModify );
989 if ( pUpdateDataTimer )
990 pUpdateDataTimer->Start();
993 void VclMultiLineEdit::SelectionChanged()
995 CallEventListeners(VclEventId::EditSelectionChanged);
998 void VclMultiLineEdit::CaretChanged()
1000 CallEventListeners(VclEventId::EditCaretChanged);
1003 IMPL_LINK_NOARG(VclMultiLineEdit, ImpUpdateDataHdl, Timer *, void)
1005 UpdateData();
1008 void VclMultiLineEdit::UpdateData()
1012 void VclMultiLineEdit::SetModifyFlag()
1014 pImpVclMEdit->SetModified( true );
1017 void VclMultiLineEdit::ClearModifyFlag()
1019 pImpVclMEdit->SetModified( false );
1022 bool VclMultiLineEdit::IsModified() const
1024 return pImpVclMEdit->IsModified();
1027 void VclMultiLineEdit::EnableUpdateData( sal_uLong nTimeout )
1029 if ( !nTimeout )
1030 DisableUpdateData();
1031 else
1033 if ( !pUpdateDataTimer )
1035 pUpdateDataTimer.reset(new Timer("MultiLineEditTimer"));
1036 pUpdateDataTimer->SetInvokeHandler( LINK( this, VclMultiLineEdit, ImpUpdateDataHdl ) );
1038 pUpdateDataTimer->SetTimeout( nTimeout );
1042 void VclMultiLineEdit::SetReadOnly( bool bReadOnly )
1044 pImpVclMEdit->SetReadOnly( bReadOnly );
1045 Edit::SetReadOnly( bReadOnly );
1047 // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set.
1048 WinBits nStyle = GetStyle();
1049 if ( bReadOnly )
1050 nStyle |= WB_READONLY;
1051 else
1052 nStyle &= ~WB_READONLY;
1053 SetStyle( nStyle );
1056 bool VclMultiLineEdit::IsReadOnly() const
1058 return pImpVclMEdit->IsReadOnly();
1061 void VclMultiLineEdit::SetMaxTextLen(sal_Int32 nMaxLen)
1063 pImpVclMEdit->SetMaxTextLen(nMaxLen);
1066 void VclMultiLineEdit::SetMaxTextWidth(long nMaxWidth)
1068 pImpVclMEdit->SetMaxTextWidth(nMaxWidth );
1071 sal_Int32 VclMultiLineEdit::GetMaxTextLen() const
1073 return pImpVclMEdit->GetMaxTextLen();
1076 void VclMultiLineEdit::ReplaceSelected( const OUString& rStr )
1078 pImpVclMEdit->InsertText( rStr );
1081 void VclMultiLineEdit::DeleteSelected()
1083 pImpVclMEdit->InsertText( OUString() );
1086 OUString VclMultiLineEdit::GetSelected() const
1088 return pImpVclMEdit->GetSelected();
1091 OUString VclMultiLineEdit::GetSelected( LineEnd aSeparator ) const
1093 return pImpVclMEdit->GetSelected( aSeparator );
1096 void VclMultiLineEdit::Cut()
1098 pImpVclMEdit->Cut();
1101 void VclMultiLineEdit::Copy()
1103 pImpVclMEdit->Copy();
1106 void VclMultiLineEdit::Paste()
1108 pImpVclMEdit->Paste();
1111 void VclMultiLineEdit::SetText( const OUString& rStr )
1113 pImpVclMEdit->SetText( rStr );
1116 OUString VclMultiLineEdit::GetText() const
1118 return pImpVclMEdit ? pImpVclMEdit->GetText() : OUString();
1121 OUString VclMultiLineEdit::GetText( LineEnd aSeparator ) const
1123 return pImpVclMEdit ? pImpVclMEdit->GetText( aSeparator ) : OUString();
1126 OUString VclMultiLineEdit::GetTextLines( LineEnd aSeparator ) const
1128 return pImpVclMEdit ? pImpVclMEdit->GetTextLines( aSeparator ) : OUString();
1131 void VclMultiLineEdit::Resize()
1133 pImpVclMEdit->Resize();
1136 void VclMultiLineEdit::GetFocus()
1138 if ( !pImpVclMEdit ) // might be called from within the dtor, when pImpVclMEdit == NULL is a valid state
1139 return;
1141 pImpVclMEdit->GetFocus();
1144 void VclMultiLineEdit::SetSelection( const Selection& rSelection )
1146 pImpVclMEdit->SetSelection( rSelection );
1149 const Selection& VclMultiLineEdit::GetSelection() const
1151 return pImpVclMEdit->GetSelection();
1154 Size VclMultiLineEdit::CalcMinimumSize() const
1156 Size aSz = pImpVclMEdit->CalcMinimumSize();
1158 sal_Int32 nLeft, nTop, nRight, nBottom;
1159 static_cast<vcl::Window*>(const_cast<VclMultiLineEdit *>(this))->GetBorder( nLeft, nTop, nRight, nBottom );
1160 aSz.AdjustWidth(nLeft+nRight );
1161 aSz.AdjustHeight(nTop+nBottom );
1163 return aSz;
1166 Size VclMultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const
1168 Size aSz = rPrefSize;
1169 sal_Int32 nLeft, nTop, nRight, nBottom;
1170 static_cast<vcl::Window*>(const_cast<VclMultiLineEdit *>(this))->GetBorder( nLeft, nTop, nRight, nBottom );
1172 // center vertically for whole lines
1174 long nHeight = aSz.Height() - nTop - nBottom;
1175 long nLineHeight = pImpVclMEdit->CalcBlockSize( 1, 1 ).Height();
1176 long nLines = nHeight / nLineHeight;
1177 if ( nLines < 1 )
1178 nLines = 1;
1180 aSz.setHeight( nLines * nLineHeight );
1181 aSz.AdjustHeight(nTop+nBottom );
1183 return aSz;
1186 Size VclMultiLineEdit::CalcBlockSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
1188 Size aSz = pImpVclMEdit->CalcBlockSize( nColumns, nLines );
1190 sal_Int32 nLeft, nTop, nRight, nBottom;
1191 static_cast<vcl::Window*>(const_cast<VclMultiLineEdit *>(this))->GetBorder( nLeft, nTop, nRight, nBottom );
1192 aSz.AdjustWidth(nLeft+nRight );
1193 aSz.AdjustHeight(nTop+nBottom );
1194 return aSz;
1197 void VclMultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
1199 pImpVclMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines );
1202 void VclMultiLineEdit::StateChanged( StateChangedType nType )
1204 if( nType == StateChangedType::Enable )
1206 pImpVclMEdit->Enable( IsEnabled() );
1207 ImplInitSettings( false );
1209 else if( nType == StateChangedType::ReadOnly )
1211 pImpVclMEdit->SetReadOnly( IsReadOnly() );
1213 else if ( nType == StateChangedType::Zoom )
1215 pImpVclMEdit->GetTextWindow()->SetZoom( GetZoom() );
1216 ImplInitSettings( false );
1217 Resize();
1219 else if ( nType == StateChangedType::ControlFont )
1221 ImplInitSettings( false );
1222 Resize();
1223 Invalidate();
1225 else if ( nType == StateChangedType::ControlForeground )
1227 ImplInitSettings( false );
1228 Invalidate();
1230 else if ( nType == StateChangedType::ControlBackground )
1232 ImplInitSettings( true );
1233 Invalidate();
1235 else if ( nType == StateChangedType::Style )
1237 pImpVclMEdit->InitFromStyle( GetStyle() );
1238 SetStyle( ImplInitStyle( GetStyle() ) );
1240 else if ( nType == StateChangedType::InitShow )
1242 if( IsPaintTransparent() )
1244 pImpVclMEdit->GetTextWindow()->SetPaintTransparent( true );
1245 pImpVclMEdit->GetTextWindow()->SetBackground();
1246 pImpVclMEdit->GetTextWindow()->SetControlBackground();
1247 SetBackground();
1248 SetControlBackground();
1252 Control::StateChanged( nType );
1255 void VclMultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt )
1257 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1258 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
1260 ImplInitSettings( true );
1261 Resize();
1262 Invalidate();
1264 else
1265 Control::DataChanged( rDCEvt );
1268 void VclMultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, DrawFlags nFlags )
1270 ImplInitSettings(true);
1272 Point aPos = pDev->LogicToPixel( rPos );
1273 Size aSize = pDev->LogicToPixel( rSize );
1275 vcl::Font aFont = pImpVclMEdit->GetTextWindow()->GetDrawPixelFont(pDev);
1276 aFont.SetTransparent( true );
1277 OutDevType eOutDevType = pDev->GetOutDevType();
1279 pDev->Push();
1280 pDev->SetMapMode();
1281 pDev->SetFont( aFont );
1282 pDev->SetTextFillColor();
1284 // Border/Background
1285 pDev->SetLineColor();
1286 pDev->SetFillColor();
1287 bool bBorder = (GetStyle() & WB_BORDER);
1288 bool bBackground = IsControlBackground();
1289 if ( bBorder || bBackground )
1291 tools::Rectangle aRect( aPos, aSize );
1292 if ( bBorder )
1294 DecorationView aDecoView( pDev );
1295 aRect = aDecoView.DrawFrame( aRect, DrawFrameStyle::DoubleIn );
1297 if ( bBackground )
1299 pDev->SetFillColor( GetControlBackground() );
1300 pDev->DrawRect( aRect );
1304 // contents
1305 if ( ( nFlags & DrawFlags::Mono ) || ( eOutDevType == OUTDEV_PRINTER ) )
1306 pDev->SetTextColor( COL_BLACK );
1307 else
1309 if ( !IsEnabled() )
1311 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1312 pDev->SetTextColor( rStyleSettings.GetDisableColor() );
1314 else
1316 pDev->SetTextColor( GetTextColor() );
1320 OUString aText = GetText();
1321 Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() );
1322 sal_uLong nLines = static_cast<sal_uLong>(aSize.Height() / aTextSz.Height());
1323 if ( !nLines )
1324 nLines = 1;
1325 aTextSz.setHeight( nLines*aTextSz.Height() );
1326 long nOnePixel = GetDrawPixel( pDev, 1 );
1327 long nOffX = 3*nOnePixel;
1328 long nOffY = 2*nOnePixel;
1330 // Clipping?
1331 if ( ( nOffY < 0 ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) )
1333 tools::Rectangle aClip( aPos, aSize );
1334 if ( aTextSz.Height() > aSize.Height() )
1335 aClip.AdjustBottom(aTextSz.Height() - aSize.Height() + 1 ); // so that HP-printer does not 'optimize-away'
1336 pDev->IntersectClipRegion( aClip );
1339 ExtTextEngine aTE;
1340 aTE.SetText( GetText() );
1341 aTE.SetMaxTextWidth( aSize.Width() );
1342 aTE.SetFont( aFont );
1343 aTE.SetTextAlign( pImpVclMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() );
1344 aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) );
1346 pDev->Pop();
1349 bool VclMultiLineEdit::EventNotify( NotifyEvent& rNEvt )
1351 bool bDone = false;
1352 if( rNEvt.GetType() == MouseNotifyEvent::COMMAND )
1354 bDone = pImpVclMEdit->HandleCommand( *rNEvt.GetCommandEvent() );
1356 return bDone || Edit::EventNotify( rNEvt );
1359 bool VclMultiLineEdit::PreNotify( NotifyEvent& rNEvt )
1361 bool bDone = false;
1363 if( ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) )
1365 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1366 if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) )
1368 bDone = true;
1369 TextSelection aSel = pImpVclMEdit->GetTextWindow()->GetTextView()->GetSelection();
1370 if ( aSel.HasRange() )
1372 aSel.GetStart() = aSel.GetEnd();
1373 pImpVclMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel );
1375 else
1377 switch ( rKEvent.GetKeyCode().GetCode() )
1379 case KEY_UP:
1381 if ( pImpVclMEdit->GetVScrollBar().IsVisible() )
1382 pImpVclMEdit->GetVScrollBar().DoScrollAction( ScrollType::LineUp );
1384 break;
1385 case KEY_DOWN:
1387 if ( pImpVclMEdit->GetVScrollBar().IsVisible() )
1388 pImpVclMEdit->GetVScrollBar().DoScrollAction( ScrollType::LineDown );
1390 break;
1391 case KEY_PAGEUP :
1393 if ( pImpVclMEdit->GetVScrollBar().IsVisible() )
1394 pImpVclMEdit->GetVScrollBar().DoScrollAction( ScrollType::PageUp );
1396 break;
1397 case KEY_PAGEDOWN:
1399 if ( pImpVclMEdit->GetVScrollBar().IsVisible() )
1400 pImpVclMEdit->GetVScrollBar().DoScrollAction( ScrollType::PageDown );
1402 break;
1403 case KEY_LEFT:
1405 if ( pImpVclMEdit->GetHScrollBar().IsVisible() )
1406 pImpVclMEdit->GetHScrollBar().DoScrollAction( ScrollType::LineUp );
1408 break;
1409 case KEY_RIGHT:
1411 if ( pImpVclMEdit->GetHScrollBar().IsVisible() )
1412 pImpVclMEdit->GetHScrollBar().DoScrollAction( ScrollType::LineDown );
1414 break;
1415 case KEY_HOME:
1417 if ( rKEvent.GetKeyCode().IsMod1() )
1418 pImpVclMEdit->GetTextWindow()->GetTextView()->
1419 SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
1421 break;
1422 case KEY_END:
1424 if ( rKEvent.GetKeyCode().IsMod1() )
1425 pImpVclMEdit->GetTextWindow()->GetTextView()->
1426 SetSelection( TextSelection( TextPaM( TEXT_PARA_ALL, TEXT_INDEX_ALL ) ) );
1428 break;
1429 default:
1431 bDone = false;
1438 return bDone || Edit::PreNotify( rNEvt );
1441 // Internals for derived classes, e.g. TextComponent
1443 ExtTextEngine* VclMultiLineEdit::GetTextEngine() const
1445 return pImpVclMEdit->GetTextWindow()->GetTextEngine();
1448 TextView* VclMultiLineEdit::GetTextView() const
1450 return pImpVclMEdit->GetTextWindow()->GetTextView();
1453 ScrollBar& VclMultiLineEdit::GetVScrollBar() const
1455 return pImpVclMEdit->GetVScrollBar();
1458 void VclMultiLineEdit::EnableFocusSelectionHide( bool bHide )
1460 pImpVclMEdit->GetTextWindow()->SetAutoFocusHide( bHide );
1463 void VclMultiLineEdit::SetRightToLeft( bool bRightToLeft )
1465 if ( GetTextEngine() )
1467 GetTextEngine()->SetRightToLeft( bRightToLeft );
1468 GetTextView()->ShowCursor();
1472 void VclMultiLineEdit::DisableSelectionOnFocus()
1474 pImpVclMEdit->GetTextWindow()->DisableSelectionOnFocus();
1477 void VclMultiLineEdit::EnableCursor( bool bEnable )
1479 GetTextView()->EnableCursor( bEnable );
1482 TextWindow* VclMultiLineEdit::GetTextWindow()
1484 return pImpVclMEdit->GetTextWindow();
1487 FactoryFunction VclMultiLineEdit::GetUITestFactory() const
1489 return MultiLineEditUIObject::create;
1492 bool VclMultiLineEdit::set_property(const OString &rKey, const OUString &rValue)
1494 if (rKey == "cursor-visible")
1495 EnableCursor(toBool(rValue));
1496 else if (rKey == "accepts-tab")
1497 pImpVclMEdit->GetTextWindow()->SetIgnoreTab(!toBool(rValue));
1498 else
1499 return Edit::set_property(rKey, rValue);
1500 return true;
1503 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */