1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
44 VclPtr
<VclMultiLineEdit
> pVclMultiLineEdit
;
46 VclPtr
<TextWindow
> mpTextWindow
;
47 VclPtr
<ScrollBar
> mpHScrollBar
;
48 VclPtr
<ScrollBar
> mpVScrollBar
;
49 VclPtr
<ScrollBarBox
> mpScrollBox
;
52 mutable Selection maSelection
;
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 );
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;
88 void SetText( const OUString
& rStr
);
89 OUString
GetText() const;
90 OUString
GetText( LineEnd aSeparator
) const;
91 OUString
GetTextLines( LineEnd aSeparator
) const;
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
))
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() )
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
)
175 void ImpVclMEdit::InitFromStyle( WinBits nWinStyle
)
177 ImpUpdateSrollBarVis( nWinStyle
);
178 SetAlign( nWinStyle
);
180 if ( nWinStyle
& WB_NOHIDESELECTION
)
181 mpTextWindow
->SetAutoFocusHide( false );
183 mpTextWindow
->SetAutoFocusHide( true );
185 if ( nWinStyle
& WB_READONLY
)
186 mpTextWindow
->GetTextView()->SetReadOnly( true );
188 mpTextWindow
->GetTextView()->SetReadOnly( false );
190 if ( nWinStyle
& WB_IGNORETAB
)
192 mpTextWindow
->SetIgnoreTab( true );
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();
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
);
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()
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() );
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
);
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
)
381 // Changing the text window size might effectively have changed the need for
382 // scrollbars, so do another iteration.
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
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
);
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
);
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() );
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();
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();
481 case SfxHintId::TextModified
:
482 ImpUpdateSrollBarVis(pVclMultiLineEdit
->GetStyle());
483 pVclMultiLineEdit
->Modify();
486 case SfxHintId::TextViewSelectionChanged
:
487 pVclMultiLineEdit
->SelectionChanged();
490 case SfxHintId::TextViewCaretChanged
:
491 pVclMultiLineEdit
->CaretChanged();
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;
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' ) )
533 mpTextWindow
->GetTextView()->SetSelection( aTextSel
);
536 const Selection
& ImpVclMEdit::GetSelection() const
538 maSelection
= Selection();
539 TextSelection
aTextSel( mpTextWindow
->GetTextView()->GetSelection() );
541 // flatten selection => every line-break a character
543 ExtTextEngine
* pExtTextEngine
= mpTextWindow
->GetTextEngine();
545 for ( sal_uInt32 n
= 0; n
< aTextSel
.GetStart().GetPara(); ++n
)
547 maSelection
.Min() += pExtTextEngine
->GetTextLen( n
);
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
);
561 maSelection
.Max() += aTextSel
.GetEnd().GetIndex();
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() );
579 Size
ImpVclMEdit::CalcBlockSize( sal_uInt16 nColumns
, sal_uInt16 nLines
) const
581 static const sal_Unicode sampleChar
= 'X';
585 aCharSz
.setWidth( mpTextWindow
->GetTextWidth( OUString(sampleChar
) ) );
586 aCharSz
.setHeight( mpTextWindow
->GetTextHeight() );
589 aSz
.setHeight( nLines
*aCharSz
.Height() );
591 aSz
.setHeight( mpTextWindow
->GetTextEngine()->GetTextHeight() );
594 aSz
.setWidth( nColumns
*aCharSz
.Width() );
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() );
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
)
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
);
641 TextWindow::TextWindow(Edit
* pParent
)
646 mbFocusSelectionHide
= 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()
673 void TextWindow::dispose()
676 mpExtTextView
.reset();
677 mpExtTextEngine
.reset();
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
);
695 void TextWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
697 mpExtTextView
->MouseButtonUp( rMEvt
);
700 void TextWindow::KeyInput( const KeyEvent
& rKEvent
)
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
) ) );
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;
727 else if ( nCode
== KEY_TAB
)
729 if ( !mbIgnoreTab
|| rKEvent
.GetKeyCode().IsMod1() )
730 bDone
= mpExtTextView
->KeyInput( rKEvent
);
734 bDone
= mpExtTextView
->KeyInput( rKEvent
);
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() )
766 bEnableDelete
= false;
768 if ( mpExtTextView
->IsReadOnly() )
771 bEnablePaste
= false;
772 bEnableDelete
= false;
773 bEnableSpecialChar
= false;
775 if ( !mpExtTextView
->GetTextEngine()->HasUndoManager() || !mpExtTextView
->GetTextEngine()->GetUndoManager().GetUndoActionCount() )
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
) );
840 mbActivePopup
= false;
844 mpExtTextView
->Command( rCEvt
);
846 Window::Command( rCEvt
);
849 void TextWindow::GetFocus()
852 if ( !mbActivePopup
)
854 bool bGotoCursor
= !mpExtTextView
->IsReadOnly();
855 if ( mbFocusSelectionHide
&& IsReallyVisible()
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
);
866 mpExtTextView
->SetPaintSelection( true );
867 mpExtTextView
->ShowCursor( bGotoCursor
);
871 void TextWindow::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()
896 void VclMultiLineEdit::dispose()
898 pImpVclMEdit
.reset();
899 pUpdateDataTimer
.reset();
903 WinBits
VclMultiLineEdit::ImplInitStyle( WinBits nStyle
)
905 if ( !(nStyle
& WB_NOTABSTOP
) )
906 nStyle
|= WB_TABSTOP
;
908 if ( !(nStyle
& WB_NOGROUP
) )
911 if ( !(nStyle
& WB_IGNORETAB
))
912 nStyle
|= WB_NODIALOGCONTROL
;
917 void VclMultiLineEdit::ApplySettings(vcl::RenderContext
& rRenderContext
)
919 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
921 // The Font has to be adjusted, as the TextEngine does not take care of
922 // TextColor/Background
924 Color aTextColor
= rStyleSettings
.GetFieldTextColor();
925 if (IsControlForeground())
926 aTextColor
= GetControlForeground();
929 aTextColor
= rStyleSettings
.GetDisableColor();
931 vcl::Font aFont
= rStyleSettings
.GetFieldFont();
932 aFont
.SetTransparent(IsPaintTransparent());
933 ApplyControlFont(rRenderContext
, aFont
);
935 vcl::Font theFont
= rRenderContext
.GetFont();
936 theFont
.SetColor(aTextColor
);
937 if (IsPaintTransparent())
938 theFont
.SetFillColor(COL_TRANSPARENT
);
940 theFont
.SetFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings
.GetFieldColor());
942 pImpVclMEdit
->GetTextWindow()->SetFont(theFont
);
943 // FIXME: next call causes infinite invalidation loop, rethink how to properly fix this situation
944 // pImpVclMEdit->GetTextWindow()->GetTextEngine()->SetFont(theFont);
945 pImpVclMEdit
->GetTextWindow()->SetTextColor(aTextColor
);
947 if (IsPaintTransparent())
949 pImpVclMEdit
->GetTextWindow()->SetPaintTransparent(true);
950 pImpVclMEdit
->GetTextWindow()->SetBackground();
951 pImpVclMEdit
->GetTextWindow()->SetControlBackground();
952 rRenderContext
.SetBackground();
953 SetControlBackground();
957 if (IsControlBackground())
958 pImpVclMEdit
->GetTextWindow()->SetBackground(GetControlBackground());
960 pImpVclMEdit
->GetTextWindow()->SetBackground(rStyleSettings
.GetFieldColor());
961 // also adjust for VclMultiLineEdit as the TextComponent might hide Scrollbars
962 rRenderContext
.SetBackground(pImpVclMEdit
->GetTextWindow()->GetBackground());
966 void VclMultiLineEdit::ImplInitSettings(bool bBackground
)
968 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
970 // The Font has to be adjusted, as the TextEngine does not take care of
971 // TextColor/Background
973 Color aTextColor
= rStyleSettings
.GetFieldTextColor();
974 if (IsControlForeground())
975 aTextColor
= GetControlForeground();
977 aTextColor
= rStyleSettings
.GetDisableColor();
979 vcl::Font aFont
= rStyleSettings
.GetFieldFont();
980 aFont
.SetTransparent(IsPaintTransparent());
981 ApplyControlFont(*this, aFont
);
983 vcl::Font TheFont
= GetFont();
984 TheFont
.SetColor(aTextColor
);
985 if (IsPaintTransparent())
986 TheFont
.SetFillColor(COL_TRANSPARENT
);
988 TheFont
.SetFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings
.GetFieldColor());
989 pImpVclMEdit
->GetTextWindow()->SetFont(TheFont
);
990 pImpVclMEdit
->GetTextWindow()->GetTextEngine()->SetFont(TheFont
);
991 pImpVclMEdit
->GetTextWindow()->SetTextColor(aTextColor
);
995 if (IsPaintTransparent())
997 pImpVclMEdit
->GetTextWindow()->SetPaintTransparent(true);
998 pImpVclMEdit
->GetTextWindow()->SetBackground();
999 pImpVclMEdit
->GetTextWindow()->SetControlBackground();
1001 SetControlBackground();
1005 if (IsControlBackground())
1006 pImpVclMEdit
->GetTextWindow()->SetBackground(GetControlBackground());
1008 pImpVclMEdit
->GetTextWindow()->SetBackground(rStyleSettings
.GetFieldColor());
1009 // also adjust for VclMultiLineEdit as the TextComponent might hide Scrollbars
1010 SetBackground(pImpVclMEdit
->GetTextWindow()->GetBackground());
1015 void VclMultiLineEdit::Modify()
1017 aModifyHdlLink
.Call( *this );
1019 CallEventListeners( VclEventId::EditModify
);
1021 if ( pUpdateDataTimer
)
1022 pUpdateDataTimer
->Start();
1025 void VclMultiLineEdit::SelectionChanged()
1027 CallEventListeners(VclEventId::EditSelectionChanged
);
1030 void VclMultiLineEdit::CaretChanged()
1032 CallEventListeners(VclEventId::EditCaretChanged
);
1035 IMPL_LINK_NOARG(VclMultiLineEdit
, ImpUpdateDataHdl
, Timer
*, void)
1040 void VclMultiLineEdit::UpdateData()
1044 void VclMultiLineEdit::SetModifyFlag()
1046 pImpVclMEdit
->SetModified( true );
1049 void VclMultiLineEdit::ClearModifyFlag()
1051 pImpVclMEdit
->SetModified( false );
1054 bool VclMultiLineEdit::IsModified() const
1056 return pImpVclMEdit
->IsModified();
1059 void VclMultiLineEdit::EnableUpdateData( sal_uLong nTimeout
)
1062 DisableUpdateData();
1065 if ( !pUpdateDataTimer
)
1067 pUpdateDataTimer
.reset(new Timer("MultiLineEditTimer"));
1068 pUpdateDataTimer
->SetInvokeHandler( LINK( this, VclMultiLineEdit
, ImpUpdateDataHdl
) );
1070 pUpdateDataTimer
->SetTimeout( nTimeout
);
1074 void VclMultiLineEdit::SetReadOnly( bool bReadOnly
)
1076 pImpVclMEdit
->SetReadOnly( bReadOnly
);
1077 Edit::SetReadOnly( bReadOnly
);
1079 // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set.
1080 WinBits nStyle
= GetStyle();
1082 nStyle
|= WB_READONLY
;
1084 nStyle
&= ~WB_READONLY
;
1088 bool VclMultiLineEdit::IsReadOnly() const
1090 return pImpVclMEdit
->IsReadOnly();
1093 void VclMultiLineEdit::SetMaxTextLen(sal_Int32 nMaxLen
)
1095 pImpVclMEdit
->SetMaxTextLen(nMaxLen
);
1098 void VclMultiLineEdit::SetMaxTextWidth(long nMaxWidth
)
1100 pImpVclMEdit
->SetMaxTextWidth(nMaxWidth
);
1103 sal_Int32
VclMultiLineEdit::GetMaxTextLen() const
1105 return pImpVclMEdit
->GetMaxTextLen();
1108 void VclMultiLineEdit::ReplaceSelected( const OUString
& rStr
)
1110 pImpVclMEdit
->InsertText( rStr
);
1113 void VclMultiLineEdit::DeleteSelected()
1115 pImpVclMEdit
->InsertText( OUString() );
1118 OUString
VclMultiLineEdit::GetSelected() const
1120 return pImpVclMEdit
->GetSelected();
1123 OUString
VclMultiLineEdit::GetSelected( LineEnd aSeparator
) const
1125 return pImpVclMEdit
->GetSelected( aSeparator
);
1128 void VclMultiLineEdit::Cut()
1130 pImpVclMEdit
->Cut();
1133 void VclMultiLineEdit::Copy()
1135 pImpVclMEdit
->Copy();
1138 void VclMultiLineEdit::Paste()
1140 pImpVclMEdit
->Paste();
1143 void VclMultiLineEdit::SetText( const OUString
& rStr
)
1145 pImpVclMEdit
->SetText( rStr
);
1148 OUString
VclMultiLineEdit::GetText() const
1150 return pImpVclMEdit
? pImpVclMEdit
->GetText() : OUString();
1153 OUString
VclMultiLineEdit::GetText( LineEnd aSeparator
) const
1155 return pImpVclMEdit
? pImpVclMEdit
->GetText( aSeparator
) : OUString();
1158 OUString
VclMultiLineEdit::GetTextLines( LineEnd aSeparator
) const
1160 return pImpVclMEdit
? pImpVclMEdit
->GetTextLines( aSeparator
) : OUString();
1163 void VclMultiLineEdit::Resize()
1165 pImpVclMEdit
->Resize();
1168 void VclMultiLineEdit::GetFocus()
1170 if ( !pImpVclMEdit
) // might be called from within the dtor, when pImpVclMEdit == NULL is a valid state
1173 pImpVclMEdit
->GetFocus();
1176 void VclMultiLineEdit::SetSelection( const Selection
& rSelection
)
1178 pImpVclMEdit
->SetSelection( rSelection
);
1181 const Selection
& VclMultiLineEdit::GetSelection() const
1183 return pImpVclMEdit
->GetSelection();
1186 Size
VclMultiLineEdit::CalcMinimumSize() const
1188 Size aSz
= pImpVclMEdit
->CalcMinimumSize();
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
);
1198 Size
VclMultiLineEdit::CalcAdjustedSize( const Size
& rPrefSize
) const
1200 Size aSz
= rPrefSize
;
1201 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
1202 static_cast<vcl::Window
*>(const_cast<VclMultiLineEdit
*>(this))->GetBorder( nLeft
, nTop
, nRight
, nBottom
);
1204 // center vertically for whole lines
1206 long nHeight
= aSz
.Height() - nTop
- nBottom
;
1207 long nLineHeight
= pImpVclMEdit
->CalcBlockSize( 1, 1 ).Height();
1208 long nLines
= nHeight
/ nLineHeight
;
1212 aSz
.setHeight( nLines
* nLineHeight
);
1213 aSz
.AdjustHeight(nTop
+nBottom
);
1218 Size
VclMultiLineEdit::CalcBlockSize( sal_uInt16 nColumns
, sal_uInt16 nLines
) const
1220 Size aSz
= pImpVclMEdit
->CalcBlockSize( nColumns
, nLines
);
1222 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
1223 static_cast<vcl::Window
*>(const_cast<VclMultiLineEdit
*>(this))->GetBorder( nLeft
, nTop
, nRight
, nBottom
);
1224 aSz
.AdjustWidth(nLeft
+nRight
);
1225 aSz
.AdjustHeight(nTop
+nBottom
);
1229 void VclMultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16
& rnCols
, sal_uInt16
& rnLines
) const
1231 pImpVclMEdit
->GetMaxVisColumnsAndLines( rnCols
, rnLines
);
1234 void VclMultiLineEdit::StateChanged( StateChangedType nType
)
1236 if( nType
== StateChangedType::Enable
)
1238 pImpVclMEdit
->Enable( IsEnabled() );
1239 ImplInitSettings( false );
1241 else if( nType
== StateChangedType::ReadOnly
)
1243 pImpVclMEdit
->SetReadOnly( IsReadOnly() );
1245 else if ( nType
== StateChangedType::Zoom
)
1247 pImpVclMEdit
->GetTextWindow()->SetZoom( GetZoom() );
1248 ImplInitSettings( false );
1251 else if ( nType
== StateChangedType::ControlFont
)
1253 ImplInitSettings( false );
1257 else if ( nType
== StateChangedType::ControlForeground
)
1259 ImplInitSettings( false );
1262 else if ( nType
== StateChangedType::ControlBackground
)
1264 ImplInitSettings( true );
1267 else if ( nType
== StateChangedType::Style
)
1269 pImpVclMEdit
->InitFromStyle( GetStyle() );
1270 SetStyle( ImplInitStyle( GetStyle() ) );
1272 else if ( nType
== StateChangedType::InitShow
)
1274 if( IsPaintTransparent() )
1276 pImpVclMEdit
->GetTextWindow()->SetPaintTransparent( true );
1277 pImpVclMEdit
->GetTextWindow()->SetBackground();
1278 pImpVclMEdit
->GetTextWindow()->SetControlBackground();
1280 SetControlBackground();
1284 Control::StateChanged( nType
);
1287 void VclMultiLineEdit::DataChanged( const DataChangedEvent
& rDCEvt
)
1289 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1290 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
1292 ImplInitSettings( true );
1297 Control::DataChanged( rDCEvt
);
1300 void VclMultiLineEdit::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
, DrawFlags nFlags
)
1302 ImplInitSettings(true);
1304 Point aPos
= pDev
->LogicToPixel( rPos
);
1305 Size aSize
= pDev
->LogicToPixel( rSize
);
1307 vcl::Font aFont
= pImpVclMEdit
->GetTextWindow()->GetDrawPixelFont(pDev
);
1308 aFont
.SetTransparent( true );
1309 OutDevType eOutDevType
= pDev
->GetOutDevType();
1313 pDev
->SetFont( aFont
);
1314 pDev
->SetTextFillColor();
1316 // Border/Background
1317 pDev
->SetLineColor();
1318 pDev
->SetFillColor();
1319 bool bBorder
= (GetStyle() & WB_BORDER
);
1320 bool bBackground
= IsControlBackground();
1321 if ( bBorder
|| bBackground
)
1323 tools::Rectangle
aRect( aPos
, aSize
);
1326 DecorationView
aDecoView( pDev
);
1327 aRect
= aDecoView
.DrawFrame( aRect
, DrawFrameStyle::DoubleIn
);
1331 pDev
->SetFillColor( GetControlBackground() );
1332 pDev
->DrawRect( aRect
);
1337 if ( ( nFlags
& DrawFlags::Mono
) || ( eOutDevType
== OUTDEV_PRINTER
) )
1338 pDev
->SetTextColor( COL_BLACK
);
1343 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1344 pDev
->SetTextColor( rStyleSettings
.GetDisableColor() );
1348 pDev
->SetTextColor( GetTextColor() );
1352 OUString aText
= GetText();
1353 Size
aTextSz( pDev
->GetTextWidth( aText
), pDev
->GetTextHeight() );
1354 sal_uLong nLines
= static_cast<sal_uLong
>(aSize
.Height() / aTextSz
.Height());
1357 aTextSz
.setHeight( nLines
*aTextSz
.Height() );
1358 long nOnePixel
= GetDrawPixel( pDev
, 1 );
1359 long nOffX
= 3*nOnePixel
;
1360 long nOffY
= 2*nOnePixel
;
1363 if ( ( nOffY
< 0 ) || ( (nOffY
+aTextSz
.Height()) > aSize
.Height() ) || ( (nOffX
+aTextSz
.Width()) > aSize
.Width() ) )
1365 tools::Rectangle
aClip( aPos
, aSize
);
1366 if ( aTextSz
.Height() > aSize
.Height() )
1367 aClip
.AdjustBottom(aTextSz
.Height() - aSize
.Height() + 1 ); // so that HP-printer does not 'optimize-away'
1368 pDev
->IntersectClipRegion( aClip
);
1372 aTE
.SetText( GetText() );
1373 aTE
.SetMaxTextWidth( aSize
.Width() );
1374 aTE
.SetFont( aFont
);
1375 aTE
.SetTextAlign( pImpVclMEdit
->GetTextWindow()->GetTextEngine()->GetTextAlign() );
1376 aTE
.Draw( pDev
, Point( aPos
.X() + nOffX
, aPos
.Y() + nOffY
) );
1381 bool VclMultiLineEdit::EventNotify( NotifyEvent
& rNEvt
)
1384 if( rNEvt
.GetType() == MouseNotifyEvent::COMMAND
)
1386 bDone
= pImpVclMEdit
->HandleCommand( *rNEvt
.GetCommandEvent() );
1388 return bDone
|| Edit::EventNotify( rNEvt
);
1391 bool VclMultiLineEdit::PreNotify( NotifyEvent
& rNEvt
)
1395 if( ( rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
) && ( !GetTextView()->IsCursorEnabled() ) )
1397 const KeyEvent
& rKEvent
= *rNEvt
.GetKeyEvent();
1398 if ( !rKEvent
.GetKeyCode().IsShift() && ( rKEvent
.GetKeyCode().GetGroup() == KEYGROUP_CURSOR
) )
1401 TextSelection aSel
= pImpVclMEdit
->GetTextWindow()->GetTextView()->GetSelection();
1402 if ( aSel
.HasRange() )
1404 aSel
.GetStart() = aSel
.GetEnd();
1405 pImpVclMEdit
->GetTextWindow()->GetTextView()->SetSelection( aSel
);
1409 switch ( rKEvent
.GetKeyCode().GetCode() )
1413 if ( pImpVclMEdit
->GetVScrollBar().IsVisible() )
1414 pImpVclMEdit
->GetVScrollBar().DoScrollAction( ScrollType::LineUp
);
1419 if ( pImpVclMEdit
->GetVScrollBar().IsVisible() )
1420 pImpVclMEdit
->GetVScrollBar().DoScrollAction( ScrollType::LineDown
);
1425 if ( pImpVclMEdit
->GetVScrollBar().IsVisible() )
1426 pImpVclMEdit
->GetVScrollBar().DoScrollAction( ScrollType::PageUp
);
1431 if ( pImpVclMEdit
->GetVScrollBar().IsVisible() )
1432 pImpVclMEdit
->GetVScrollBar().DoScrollAction( ScrollType::PageDown
);
1437 if ( pImpVclMEdit
->GetHScrollBar().IsVisible() )
1438 pImpVclMEdit
->GetHScrollBar().DoScrollAction( ScrollType::LineUp
);
1443 if ( pImpVclMEdit
->GetHScrollBar().IsVisible() )
1444 pImpVclMEdit
->GetHScrollBar().DoScrollAction( ScrollType::LineDown
);
1449 if ( rKEvent
.GetKeyCode().IsMod1() )
1450 pImpVclMEdit
->GetTextWindow()->GetTextView()->
1451 SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
1456 if ( rKEvent
.GetKeyCode().IsMod1() )
1457 pImpVclMEdit
->GetTextWindow()->GetTextView()->
1458 SetSelection( TextSelection( TextPaM( TEXT_PARA_ALL
, TEXT_INDEX_ALL
) ) );
1470 return bDone
|| Edit::PreNotify( rNEvt
);
1473 // Internals for derived classes, e.g. TextComponent
1475 ExtTextEngine
* VclMultiLineEdit::GetTextEngine() const
1477 return pImpVclMEdit
->GetTextWindow()->GetTextEngine();
1480 TextView
* VclMultiLineEdit::GetTextView() const
1482 return pImpVclMEdit
->GetTextWindow()->GetTextView();
1485 ScrollBar
& VclMultiLineEdit::GetVScrollBar() const
1487 return pImpVclMEdit
->GetVScrollBar();
1490 void VclMultiLineEdit::EnableFocusSelectionHide( bool bHide
)
1492 pImpVclMEdit
->GetTextWindow()->SetAutoFocusHide( bHide
);
1495 void VclMultiLineEdit::SetRightToLeft( bool bRightToLeft
)
1497 if ( GetTextEngine() )
1499 GetTextEngine()->SetRightToLeft( bRightToLeft
);
1500 GetTextView()->ShowCursor();
1504 void VclMultiLineEdit::DisableSelectionOnFocus()
1506 pImpVclMEdit
->GetTextWindow()->DisableSelectionOnFocus();
1509 void VclMultiLineEdit::EnableCursor( bool bEnable
)
1511 GetTextView()->EnableCursor( bEnable
);
1514 TextWindow
* VclMultiLineEdit::GetTextWindow()
1516 return pImpVclMEdit
->GetTextWindow();
1519 FactoryFunction
VclMultiLineEdit::GetUITestFactory() const
1521 return MultiLineEditUIObject::create
;
1524 bool VclMultiLineEdit::set_property(const OString
&rKey
, const OUString
&rValue
)
1526 if (rKey
== "cursor-visible")
1527 EnableCursor(toBool(rValue
));
1528 else if (rKey
== "accepts-tab")
1529 pImpVclMEdit
->GetTextWindow()->SetIgnoreTab(!toBool(rValue
));
1531 return Edit::set_property(rKey
, rValue
);
1535 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */