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/menu.hxx>
27 #include <vcl/specialchars.hxx>
28 #include <vcl/timer.hxx>
29 #include <vcl/vclevent.hxx>
30 #include <vcl/xtextedt.hxx>
31 #include <vcl/textview.hxx>
32 #include <vcl/ptrstyle.hxx>
34 #include <svl/undo.hxx>
35 #include <svl/lstner.hxx>
36 #include <vcl/uitest/uiobject.hxx>
38 #include <vcl/settings.hxx>
39 #include <vcl/toolkit/scrbar.hxx>
40 #include <vcl/toolkit/vclmedit.hxx>
41 #include <vcl/weld.hxx>
42 #include <osl/diagnose.h>
43 #include <tools/json_writer.hxx>
45 class ImpVclMEdit
: public SfxListener
48 VclPtr
<VclMultiLineEdit
> pVclMultiLineEdit
;
50 VclPtr
<TextWindow
> mpTextWindow
;
51 VclPtr
<ScrollBar
> mpHScrollBar
;
52 VclPtr
<ScrollBar
> mpVScrollBar
;
53 VclPtr
<ScrollBarBox
> mpScrollBox
;
55 tools::Long mnTextWidth
;
56 mutable Selection maSelection
;
59 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
) override
;
60 void ImpUpdateScrollBarVis( WinBits nWinStyle
);
61 void ImpInitScrollBars();
62 void ImpSetScrollBarRanges();
63 void ImpSetHScrollBarThumbPos();
64 DECL_LINK( ScrollHdl
, ScrollBar
*, void );
67 ImpVclMEdit( VclMultiLineEdit
* pVclMultiLineEdit
, WinBits nWinStyle
);
68 virtual ~ImpVclMEdit() override
;
70 void SetModified( bool bMod
);
72 void SetReadOnly( bool bRdOnly
);
73 bool IsReadOnly() const;
75 void SetMaxTextLen(sal_Int32 nLen
);
76 sal_Int32
GetMaxTextLen() const;
78 void SetMaxTextWidth(tools::Long nMaxWidth
);
80 void InsertText( const OUString
& rStr
);
81 OUString
GetSelected() const;
82 OUString
GetSelected( LineEnd aSeparator
) const;
84 void SetSelection( const Selection
& rSelection
);
85 const Selection
& GetSelection() const;
91 void SetText( const OUString
& rStr
);
92 OUString
GetText() const;
93 OUString
GetText( LineEnd aSeparator
) const;
94 OUString
GetTextLines( LineEnd aSeparator
) const;
99 bool HandleCommand( const CommandEvent
& rCEvt
);
101 void Enable( bool bEnable
);
103 Size
CalcMinimumSize() const;
104 Size
CalcBlockSize( sal_uInt16 nColumns
, sal_uInt16 nLines
) const;
105 void GetMaxVisColumnsAndLines( sal_uInt16
& rnCols
, sal_uInt16
& rnLines
) const;
107 void SetAlign( WinBits nWinStyle
);
109 void InitFromStyle( WinBits nWinStyle
);
111 TextWindow
* GetTextWindow() { return mpTextWindow
; }
112 ScrollBar
& GetHScrollBar() { return *mpHScrollBar
; }
113 ScrollBar
& GetVScrollBar() { return *mpVScrollBar
; }
116 ImpVclMEdit::ImpVclMEdit( VclMultiLineEdit
* pEdt
, WinBits nWinStyle
)
117 : pVclMultiLineEdit(pEdt
)
118 , mpTextWindow(VclPtr
<TextWindow
>::Create(pEdt
))
119 , mpHScrollBar(VclPtr
<ScrollBar
>::Create(pVclMultiLineEdit
, WB_HSCROLL
|WB_DRAG
))
120 , mpVScrollBar(VclPtr
<ScrollBar
>::Create(pVclMultiLineEdit
, WB_VSCROLL
|WB_DRAG
))
121 , mpScrollBox(VclPtr
<ScrollBarBox
>::Create(pVclMultiLineEdit
, WB_SIZEABLE
))
124 mpVScrollBar
->SetScrollHdl( LINK( this, ImpVclMEdit
, ScrollHdl
) );
125 mpHScrollBar
->SetScrollHdl( LINK( this, ImpVclMEdit
, ScrollHdl
) );
126 mpTextWindow
->Show();
127 InitFromStyle( nWinStyle
);
128 StartListening( *mpTextWindow
->GetTextEngine() );
131 void ImpVclMEdit::ImpUpdateScrollBarVis( WinBits nWinStyle
)
133 const bool bHaveVScroll
= mpVScrollBar
->IsVisible();
134 const bool bHaveHScroll
= mpHScrollBar
->IsVisible();
135 const bool bHaveScrollBox
= mpScrollBox
->IsVisible();
137 bool bNeedVScroll
= ( nWinStyle
& WB_VSCROLL
) == WB_VSCROLL
;
138 const bool bNeedHScroll
= ( nWinStyle
& WB_HSCROLL
) == WB_HSCROLL
;
140 const bool bAutoVScroll
= ( nWinStyle
& WB_AUTOVSCROLL
) == WB_AUTOVSCROLL
;
141 if ( !bNeedVScroll
&& bAutoVScroll
)
143 TextEngine
& rEngine( *mpTextWindow
->GetTextEngine() );
144 tools::Long
nOverallTextHeight(0);
145 for ( sal_uInt32 i
=0; i
<rEngine
.GetParagraphCount(); ++i
)
146 nOverallTextHeight
+= rEngine
.GetTextHeight( i
);
147 if ( nOverallTextHeight
> mpTextWindow
->GetOutputSizePixel().Height() )
151 const bool bNeedScrollBox
= bNeedVScroll
&& bNeedHScroll
;
153 bool bScrollbarsChanged
= false;
154 if ( bHaveVScroll
!= bNeedVScroll
)
156 mpVScrollBar
->Show(bNeedVScroll
);
157 bScrollbarsChanged
= true;
160 if ( bHaveHScroll
!= bNeedHScroll
)
162 mpHScrollBar
->Show(bNeedHScroll
);
163 bScrollbarsChanged
= true;
166 if ( bHaveScrollBox
!= bNeedScrollBox
)
168 mpScrollBox
->Show(bNeedScrollBox
);
171 if ( bScrollbarsChanged
)
178 void ImpVclMEdit::InitFromStyle( WinBits nWinStyle
)
180 ImpUpdateScrollBarVis( nWinStyle
);
181 SetAlign( nWinStyle
);
183 if ( nWinStyle
& WB_NOHIDESELECTION
)
184 mpTextWindow
->SetAutoFocusHide( false );
186 mpTextWindow
->SetAutoFocusHide( true );
188 if ( nWinStyle
& WB_READONLY
)
189 mpTextWindow
->GetTextView()->SetReadOnly( true );
191 mpTextWindow
->GetTextView()->SetReadOnly( false );
193 if ( nWinStyle
& WB_IGNORETAB
)
195 mpTextWindow
->SetIgnoreTab( true );
199 mpTextWindow
->SetIgnoreTab( false );
200 // #103667# VclMultiLineEdit has the flag, but focusable window also needs this flag
201 WinBits nStyle
= mpTextWindow
->GetStyle();
202 nStyle
|= WB_NODIALOGCONTROL
;
203 mpTextWindow
->SetStyle( nStyle
);
207 ImpVclMEdit::~ImpVclMEdit()
209 EndListening( *mpTextWindow
->GetTextEngine() );
210 mpTextWindow
.disposeAndClear();
211 mpHScrollBar
.disposeAndClear();
212 mpVScrollBar
.disposeAndClear();
213 mpScrollBox
.disposeAndClear();
214 pVclMultiLineEdit
.disposeAndClear();
217 void ImpVclMEdit::ImpSetScrollBarRanges()
219 const tools::Long nTextHeight
= mpTextWindow
->GetTextEngine()->GetTextHeight();
220 mpVScrollBar
->SetRange( Range( 0, nTextHeight
-1 ) );
222 mpHScrollBar
->SetRange( Range( 0, mnTextWidth
-1 ) );
225 void ImpVclMEdit::ImpInitScrollBars()
227 static const sal_Unicode sampleChar
= { 'x' };
229 ImpSetScrollBarRanges();
232 aCharBox
.setWidth( mpTextWindow
->GetTextWidth( OUString(sampleChar
) ) );
233 aCharBox
.setHeight( mpTextWindow
->GetTextHeight() );
234 Size aOutSz
= mpTextWindow
->GetOutputSizePixel();
236 mpHScrollBar
->SetVisibleSize( aOutSz
.Width() );
237 mpHScrollBar
->SetPageSize( aOutSz
.Width() * 8 / 10 );
238 mpHScrollBar
->SetLineSize( aCharBox
.Width()*10 );
239 ImpSetHScrollBarThumbPos();
241 mpVScrollBar
->SetVisibleSize( aOutSz
.Height() );
242 mpVScrollBar
->SetPageSize( aOutSz
.Height() * 8 / 10 );
243 mpVScrollBar
->SetLineSize( aCharBox
.Height() );
244 mpVScrollBar
->SetThumbPos( mpTextWindow
->GetTextView()->GetStartDocPos().Y() );
247 void ImpVclMEdit::ImpSetHScrollBarThumbPos()
249 tools::Long nX
= mpTextWindow
->GetTextView()->GetStartDocPos().X();
250 if ( !mpTextWindow
->GetTextEngine()->IsRightToLeft() )
251 mpHScrollBar
->SetThumbPos( nX
);
253 mpHScrollBar
->SetThumbPos( mnTextWidth
- mpHScrollBar
->GetVisibleSize() - nX
);
257 IMPL_LINK( ImpVclMEdit
, ScrollHdl
, ScrollBar
*, pCurScrollBar
, void )
259 tools::Long nDiffX
= 0, nDiffY
= 0;
261 if ( pCurScrollBar
== mpVScrollBar
)
262 nDiffY
= mpTextWindow
->GetTextView()->GetStartDocPos().Y() - pCurScrollBar
->GetThumbPos();
263 else if ( pCurScrollBar
== mpHScrollBar
)
264 nDiffX
= mpTextWindow
->GetTextView()->GetStartDocPos().X() - pCurScrollBar
->GetThumbPos();
266 mpTextWindow
->GetTextView()->Scroll( nDiffX
, nDiffY
);
267 // mpTextWindow->GetTextView()->ShowCursor( false, true );
270 void ImpVclMEdit::SetAlign( WinBits nWinStyle
)
272 bool bRTL
= AllSettings::GetLayoutRTL();
273 mpTextWindow
->GetTextEngine()->SetRightToLeft( bRTL
);
275 if ( nWinStyle
& WB_CENTER
)
276 mpTextWindow
->GetTextEngine()->SetTextAlign( TxtAlign::Center
);
277 else if ( nWinStyle
& WB_RIGHT
)
278 mpTextWindow
->GetTextEngine()->SetTextAlign( !bRTL
? TxtAlign::Right
: TxtAlign::Left
);
279 else if ( nWinStyle
& WB_LEFT
)
280 mpTextWindow
->GetTextEngine()->SetTextAlign( !bRTL
? TxtAlign::Left
: TxtAlign::Right
);
283 void ImpVclMEdit::SetModified( bool bMod
)
285 mpTextWindow
->GetTextEngine()->SetModified( bMod
);
288 void ImpVclMEdit::SetReadOnly( bool bRdOnly
)
290 mpTextWindow
->GetTextView()->SetReadOnly( bRdOnly
);
291 // TODO: Adjust color?
294 bool ImpVclMEdit::IsReadOnly() const
296 return mpTextWindow
->GetTextView()->IsReadOnly();
299 void ImpVclMEdit::SetMaxTextLen(sal_Int32 nLen
)
301 mpTextWindow
->GetTextEngine()->SetMaxTextLen(nLen
);
304 sal_Int32
ImpVclMEdit::GetMaxTextLen() const
306 return mpTextWindow
->GetTextEngine()->GetMaxTextLen();
309 void ImpVclMEdit::InsertText( const OUString
& rStr
)
311 mpTextWindow
->GetTextView()->InsertText( rStr
);
314 OUString
ImpVclMEdit::GetSelected() const
316 return mpTextWindow
->GetTextView()->GetSelected();
319 OUString
ImpVclMEdit::GetSelected( LineEnd aSeparator
) const
321 return mpTextWindow
->GetTextView()->GetSelected( aSeparator
);
324 void ImpVclMEdit::SetMaxTextWidth(tools::Long nMaxWidth
)
326 mpTextWindow
->GetTextEngine()->SetMaxTextWidth(nMaxWidth
);
329 void ImpVclMEdit::Resize()
334 WinBits
nWinStyle( pVclMultiLineEdit
->GetStyle() );
335 if ( ( nWinStyle
& WB_AUTOVSCROLL
) == WB_AUTOVSCROLL
)
336 ImpUpdateScrollBarVis( nWinStyle
);
338 Size aSz
= pVclMultiLineEdit
->GetOutputSizePixel();
339 Size aEditSize
= aSz
;
340 tools::Long nSBWidth
= pVclMultiLineEdit
->GetSettings().GetStyleSettings().GetScrollBarSize();
341 nSBWidth
= pVclMultiLineEdit
->CalcZoom( nSBWidth
);
343 if (mpHScrollBar
->IsVisible())
344 aSz
.AdjustHeight( -(nSBWidth
+1) );
345 if (mpVScrollBar
->IsVisible())
346 aSz
.AdjustWidth( -(nSBWidth
+1) );
348 if (!mpHScrollBar
->IsVisible())
349 mpTextWindow
->GetTextEngine()->SetMaxTextWidth( aSz
.Width() );
351 mpHScrollBar
->setPosSizePixel( 0, aEditSize
.Height()-nSBWidth
, aSz
.Width(), nSBWidth
);
353 Point aTextWindowPos
;
354 if (mpVScrollBar
->IsVisible())
356 if( AllSettings::GetLayoutRTL() )
358 mpVScrollBar
->setPosSizePixel( 0, 0, nSBWidth
, aSz
.Height() );
359 aTextWindowPos
.AdjustX(nSBWidth
);
362 mpVScrollBar
->setPosSizePixel( aEditSize
.Width()-nSBWidth
, 0, nSBWidth
, aSz
.Height() );
365 if (mpScrollBox
->IsVisible())
366 mpScrollBox
->setPosSizePixel( aSz
.Width(), aSz
.Height(), nSBWidth
, nSBWidth
);
368 Size
aTextWindowSize( aSz
);
369 if ( aTextWindowSize
.Width() < 0 )
370 aTextWindowSize
.setWidth( 0 );
371 if ( aTextWindowSize
.Height() < 0 )
372 aTextWindowSize
.setHeight( 0 );
374 Size
aOldTextWindowSize( mpTextWindow
->GetSizePixel() );
375 mpTextWindow
->SetPosSizePixel( aTextWindowPos
, aTextWindowSize
);
376 if ( aOldTextWindowSize
== aTextWindowSize
)
379 // Changing the text window size might effectively have changed the need for
380 // scrollbars, so do another iteration.
382 OSL_ENSURE( nIteration
< 3, "ImpVclMEdit::Resize: isn't this expected to terminate with the second iteration?" );
384 } while ( nIteration
<= 3 ); // artificial break after four iterations
389 void ImpVclMEdit::GetFocus()
391 mpTextWindow
->GrabFocus();
394 void ImpVclMEdit::Cut()
396 if ( !mpTextWindow
->GetTextView()->IsReadOnly() )
397 mpTextWindow
->GetTextView()->Cut();
400 void ImpVclMEdit::Copy()
402 mpTextWindow
->GetTextView()->Copy();
405 void ImpVclMEdit::Paste()
407 if ( !mpTextWindow
->GetTextView()->IsReadOnly() )
408 mpTextWindow
->GetTextView()->Paste();
411 void ImpVclMEdit::SetText( const OUString
& rStr
)
413 bool bWasModified
= mpTextWindow
->GetTextEngine()->IsModified();
414 mpTextWindow
->GetTextEngine()->SetText( rStr
);
416 mpTextWindow
->GetTextEngine()->SetModified( false );
418 mpTextWindow
->GetTextView()->SetSelection( TextSelection() );
420 WinBits
nWinStyle( pVclMultiLineEdit
->GetStyle() );
421 if ( ( nWinStyle
& WB_AUTOVSCROLL
) == WB_AUTOVSCROLL
)
422 ImpUpdateScrollBarVis( nWinStyle
);
425 OUString
ImpVclMEdit::GetText() const
427 return mpTextWindow
->GetTextEngine()->GetText();
430 OUString
ImpVclMEdit::GetText( LineEnd aSeparator
) const
432 return mpTextWindow
->GetTextEngine()->GetText( aSeparator
);
435 OUString
ImpVclMEdit::GetTextLines( LineEnd aSeparator
) const
437 return mpTextWindow
->GetTextEngine()->GetTextLines( aSeparator
);
440 void ImpVclMEdit::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
442 const TextHint
* pTextHint
= dynamic_cast<const TextHint
*>(&rHint
);
446 switch (pTextHint
->GetId())
448 case SfxHintId::TextViewScrolled
:
449 if (mpHScrollBar
->IsVisible())
450 ImpSetHScrollBarThumbPos();
451 if (mpVScrollBar
->IsVisible())
452 mpVScrollBar
->SetThumbPos( mpTextWindow
->GetTextView()->GetStartDocPos().Y() );
455 case SfxHintId::TextHeightChanged
:
456 if ( mpTextWindow
->GetTextView()->GetStartDocPos().Y() )
458 tools::Long nOutHeight
= mpTextWindow
->GetOutputSizePixel().Height();
459 tools::Long nTextHeight
= mpTextWindow
->GetTextEngine()->GetTextHeight();
460 if ( nTextHeight
< nOutHeight
)
461 mpTextWindow
->GetTextView()->Scroll( 0, mpTextWindow
->GetTextView()->GetStartDocPos().Y() );
463 ImpSetScrollBarRanges();
466 case SfxHintId::TextFormatted
:
467 if (mpHScrollBar
->IsVisible())
469 const tools::Long nWidth
= mpTextWindow
->GetTextEngine()->CalcTextWidth();
470 if ( nWidth
!= mnTextWidth
)
472 mnTextWidth
= nWidth
;
473 mpHScrollBar
->SetRange( Range( 0, mnTextWidth
-1 ) );
474 ImpSetHScrollBarThumbPos();
479 case SfxHintId::TextModified
:
480 ImpUpdateScrollBarVis(pVclMultiLineEdit
->GetStyle());
481 pVclMultiLineEdit
->Modify();
484 case SfxHintId::TextViewSelectionChanged
:
485 pVclMultiLineEdit
->SelectionChanged();
488 case SfxHintId::TextViewCaretChanged
:
489 pVclMultiLineEdit
->CaretChanged();
496 void ImpVclMEdit::SetSelection( const Selection
& rSelection
)
498 OUString aText
= mpTextWindow
->GetTextEngine()->GetText();
500 Selection
aNewSelection( rSelection
);
501 if ( aNewSelection
.Min() < 0 )
502 aNewSelection
.Min() = 0;
503 else if ( aNewSelection
.Min() > aText
.getLength() )
504 aNewSelection
.Min() = aText
.getLength();
505 if ( aNewSelection
.Max() < 0 )
506 aNewSelection
.Max() = 0;
507 else if ( aNewSelection
.Max() > aText
.getLength() )
508 aNewSelection
.Max() = aText
.getLength();
510 tools::Long nEnd
= std::max( aNewSelection
.Min(), aNewSelection
.Max() );
511 TextSelection aTextSel
;
512 sal_uInt32 nPara
= 0;
517 if ( x
== aNewSelection
.Min() )
518 aTextSel
.GetStart() = TextPaM( nPara
, nChar
);
519 if ( x
== aNewSelection
.Max() )
520 aTextSel
.GetEnd() = TextPaM( nPara
, nChar
);
522 if ( ( x
< aText
.getLength() ) && ( aText
[ x
] == '\n' ) )
531 mpTextWindow
->GetTextView()->SetSelection( aTextSel
);
534 const Selection
& ImpVclMEdit::GetSelection() const
536 maSelection
= Selection();
537 TextSelection
aTextSel( mpTextWindow
->GetTextView()->GetSelection() );
539 // flatten selection => every line-break a character
541 ExtTextEngine
* pExtTextEngine
= mpTextWindow
->GetTextEngine();
543 for ( sal_uInt32 n
= 0; n
< aTextSel
.GetStart().GetPara(); ++n
)
545 maSelection
.Min() += pExtTextEngine
->GetTextLen( n
);
549 // first paragraph with selection
550 maSelection
.Max() = maSelection
.Min();
551 maSelection
.Min() += aTextSel
.GetStart().GetIndex();
553 for ( sal_uInt32 n
= aTextSel
.GetStart().GetPara(); n
< aTextSel
.GetEnd().GetPara(); ++n
)
555 maSelection
.Max() += pExtTextEngine
->GetTextLen( n
);
559 maSelection
.Max() += aTextSel
.GetEnd().GetIndex();
564 Size
ImpVclMEdit::CalcMinimumSize() const
566 Size
aSz( mpTextWindow
->GetTextEngine()->CalcTextWidth(),
567 mpTextWindow
->GetTextEngine()->GetTextHeight() );
569 if (mpHScrollBar
->IsVisible())
570 aSz
.AdjustHeight(mpHScrollBar
->GetSizePixel().Height() );
571 if (mpVScrollBar
->IsVisible())
572 aSz
.AdjustWidth(mpVScrollBar
->GetSizePixel().Width() );
577 Size
ImpVclMEdit::CalcBlockSize( sal_uInt16 nColumns
, sal_uInt16 nLines
) const
579 static const sal_Unicode sampleChar
= 'X';
583 aCharSz
.setWidth( mpTextWindow
->GetTextWidth( OUString(sampleChar
) ) );
584 aCharSz
.setHeight( mpTextWindow
->GetTextHeight() );
587 aSz
.setHeight( nLines
*aCharSz
.Height() );
589 aSz
.setHeight( mpTextWindow
->GetTextEngine()->GetTextHeight() );
592 aSz
.setWidth( nColumns
*aCharSz
.Width() );
594 aSz
.setWidth( mpTextWindow
->GetTextEngine()->CalcTextWidth() );
596 if (mpHScrollBar
->IsVisible())
597 aSz
.AdjustHeight(mpHScrollBar
->GetSizePixel().Height() );
598 if (mpVScrollBar
->IsVisible())
599 aSz
.AdjustWidth(mpVScrollBar
->GetSizePixel().Width() );
604 void ImpVclMEdit::GetMaxVisColumnsAndLines( sal_uInt16
& rnCols
, sal_uInt16
& rnLines
) const
606 static const sal_Unicode sampleChar
= { 'x' };
607 Size aOutSz
= mpTextWindow
->GetOutputSizePixel();
608 Size
aCharSz( mpTextWindow
->GetTextWidth( OUString(sampleChar
) ), mpTextWindow
->GetTextHeight() );
609 rnCols
= static_cast<sal_uInt16
>(aOutSz
.Width()/aCharSz
.Width());
610 rnLines
= static_cast<sal_uInt16
>(aOutSz
.Height()/aCharSz
.Height());
613 void ImpVclMEdit::Enable( bool bEnable
)
615 mpTextWindow
->Enable( bEnable
);
616 if (mpHScrollBar
->IsVisible())
617 mpHScrollBar
->Enable( bEnable
);
618 if (mpVScrollBar
->IsVisible())
619 mpVScrollBar
->Enable( bEnable
);
622 bool ImpVclMEdit::HandleCommand( const CommandEvent
& rCEvt
)
625 CommandEventId nCommand
= rCEvt
.GetCommand();
626 if (nCommand
== CommandEventId::Wheel
||
627 nCommand
== CommandEventId::StartAutoScroll
||
628 nCommand
== CommandEventId::AutoScroll
||
629 nCommand
== CommandEventId::GesturePan
)
631 ScrollBar
* pHScrollBar
= mpHScrollBar
->IsVisible() ? mpHScrollBar
.get() : nullptr;
632 ScrollBar
* pVScrollBar
= mpVScrollBar
->IsVisible() ? mpVScrollBar
.get() : nullptr;
633 mpTextWindow
->HandleScrollCommand(rCEvt
, pHScrollBar
, pVScrollBar
);
639 TextWindow::TextWindow(Edit
* pParent
)
644 mbFocusSelectionHide
= false;
646 mbActivePopup
= false;
647 mbSelectOnTab
= true;
649 SetPointer( PointerStyle::Text
);
651 mpExtTextEngine
.reset(new ExtTextEngine
);
652 mpExtTextEngine
->SetMaxTextLen(EDIT_NOLIMIT
);
653 if( pParent
->GetStyle() & WB_BORDER
)
654 mpExtTextEngine
->SetLeftMargin( 2 );
655 mpExtTextEngine
->SetLocale( GetSettings().GetLanguageTag().getLocale() );
656 mpExtTextView
.reset(new TextView( mpExtTextEngine
.get(), this ));
657 mpExtTextEngine
->InsertView( mpExtTextView
.get() );
658 mpExtTextEngine
->EnableUndo( true );
659 mpExtTextView
->ShowCursor();
661 Color aBackgroundColor
= GetSettings().GetStyleSettings().GetWorkspaceColor();
662 SetBackground( aBackgroundColor
);
663 pParent
->SetBackground( aBackgroundColor
);
666 TextWindow::~TextWindow()
671 void TextWindow::dispose()
674 mpExtTextView
.reset();
675 mpExtTextEngine
.reset();
679 void TextWindow::MouseMove( const MouseEvent
& rMEvt
)
681 mpExtTextView
->MouseMove( rMEvt
);
682 Window::MouseMove( rMEvt
);
685 void TextWindow::MouseButtonDown( const MouseEvent
& rMEvt
)
687 mbInMBDown
= true; // so that GetFocus does not select everything
688 mpExtTextView
->MouseButtonDown( rMEvt
);
693 void TextWindow::MouseButtonUp( const MouseEvent
& rMEvt
)
695 mpExtTextView
->MouseButtonUp( rMEvt
);
698 void TextWindow::KeyInput( const KeyEvent
& rKEvent
)
701 sal_uInt16 nCode
= rKEvent
.GetKeyCode().GetCode();
702 if ( nCode
== css::awt::Key::SELECT_ALL
||
703 ( (nCode
== KEY_A
) && rKEvent
.GetKeyCode().IsMod1() && !rKEvent
.GetKeyCode().IsMod2() )
706 mpExtTextView
->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL
, TEXT_INDEX_ALL
) ) );
709 else if ( (nCode
== KEY_S
) && rKEvent
.GetKeyCode().IsShift() && rKEvent
.GetKeyCode().IsMod1() )
711 if ( vcl::GetGetSpecialCharsFunction() )
713 // to maintain the selection
714 mbActivePopup
= true;
715 OUString aChars
= vcl::GetGetSpecialCharsFunction()(GetFrameWeld(), GetFont());
716 if (!aChars
.isEmpty())
718 mpExtTextView
->InsertText( aChars
);
719 mpExtTextView
->GetTextEngine()->SetModified( true );
721 mbActivePopup
= false;
725 else if ( nCode
== KEY_TAB
)
729 if (!rKEvent
.GetKeyCode().IsMod1())
730 bDone
= mpExtTextView
->KeyInput(rKEvent
);
733 // tdf#107625 make ctrl+tab act like tab when MultiLine Edit normally accepts tab as an input char
734 vcl::KeyCode
aKeyCode(rKEvent
.GetKeyCode().GetCode(), rKEvent
.GetKeyCode().GetModifier() & ~KEY_MOD1
);
735 KeyEvent
aKEventWithoutMod1(rKEvent
.GetCharCode(), aKeyCode
, rKEvent
.GetRepeat());
736 Window::KeyInput(aKEventWithoutMod1
);
743 bDone
= mpExtTextView
->KeyInput( rKEvent
);
747 Window::KeyInput( rKEvent
);
750 void TextWindow::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
)
752 mpExtTextView
->Paint(rRenderContext
, rRect
);
755 void TextWindow::Resize()
759 void TextWindow::Command( const CommandEvent
& rCEvt
)
761 if ( rCEvt
.GetCommand() == CommandEventId::ContextMenu
)
763 VclPtr
<PopupMenu
> pPopup
= mxParent
->CreatePopupMenu();
764 bool bEnableCut
= true;
765 bool bEnableCopy
= true;
766 bool bEnableDelete
= true;
767 bool bEnablePaste
= true;
768 bool bEnableSpecialChar
= true;
769 bool bEnableUndo
= true;
771 if ( !mpExtTextView
->HasSelection() )
775 bEnableDelete
= false;
777 if ( mpExtTextView
->IsReadOnly() )
780 bEnablePaste
= false;
781 bEnableDelete
= false;
782 bEnableSpecialChar
= false;
784 if ( !mpExtTextView
->GetTextEngine()->HasUndoManager() || !mpExtTextView
->GetTextEngine()->GetUndoManager().GetUndoActionCount() )
788 pPopup
->EnableItem(pPopup
->GetItemId(u
"cut"), bEnableCut
);
789 pPopup
->EnableItem(pPopup
->GetItemId(u
"copy"), bEnableCopy
);
790 pPopup
->EnableItem(pPopup
->GetItemId(u
"delete"), bEnableDelete
);
791 pPopup
->EnableItem(pPopup
->GetItemId(u
"paste"), bEnablePaste
);
792 pPopup
->EnableItem(pPopup
->GetItemId(u
"specialchar"), bEnableSpecialChar
);
793 pPopup
->EnableItem(pPopup
->GetItemId(u
"undo"), bEnableUndo
);
794 pPopup
->ShowItem(pPopup
->GetItemId(u
"specialchar"), !vcl::GetGetSpecialCharsFunction());
796 mbActivePopup
= true;
797 Point aPos
= rCEvt
.GetMousePosPixel();
798 if ( !rCEvt
.IsMouseEvent() )
800 // Sometime do show Menu centered in the selection !!!
801 Size aSize
= GetOutputSizePixel();
802 aPos
= Point( aSize
.Width()/2, aSize
.Height()/2 );
804 sal_uInt16 n
= pPopup
->Execute( this, aPos
);
805 OUString sCommand
= pPopup
->GetItemIdent(n
);
806 if (sCommand
== "undo")
808 mpExtTextView
->Undo();
809 mpExtTextEngine
->SetModified( true );
810 mpExtTextEngine
->Broadcast( TextHint( SfxHintId::TextModified
) );
812 else if (sCommand
== "cut")
814 mpExtTextView
->Cut();
815 mpExtTextEngine
->SetModified( true );
816 mpExtTextEngine
->Broadcast( TextHint( SfxHintId::TextModified
) );
818 else if (sCommand
== "copy")
820 mpExtTextView
->Copy();
822 else if (sCommand
== "paste")
824 mpExtTextView
->Paste();
825 mpExtTextEngine
->SetModified( true );
826 mpExtTextEngine
->Broadcast( TextHint( SfxHintId::TextModified
) );
828 else if (sCommand
== "delete")
830 mpExtTextView
->DeleteSelected();
831 mpExtTextEngine
->SetModified( true );
832 mpExtTextEngine
->Broadcast( TextHint( SfxHintId::TextModified
) );
834 else if (sCommand
== "selectall")
836 mpExtTextView
->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL
, TEXT_INDEX_ALL
) ) );
838 else if (sCommand
== "specialchar")
840 OUString aChars
= vcl::GetGetSpecialCharsFunction()(GetFrameWeld(), GetFont());
841 if (!aChars
.isEmpty())
843 mpExtTextView
->InsertText( aChars
);
844 mpExtTextEngine
->SetModified( true );
845 mpExtTextEngine
->Broadcast( TextHint( SfxHintId::TextModified
) );
849 mbActivePopup
= false;
853 mpExtTextView
->Command( rCEvt
);
855 Window::Command( rCEvt
);
858 void TextWindow::GetFocus()
864 bool bGotoCursor
= !mpExtTextView
->IsReadOnly();
865 if ( mbFocusSelectionHide
&& IsReallyVisible() && mbSelectOnTab
&& !mbInMBDown
)
867 // select everything, but do not scroll
868 bool bAutoScroll
= mpExtTextView
->IsAutoScroll();
869 mpExtTextView
->SetAutoScroll( false );
870 mpExtTextView
->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( TEXT_PARA_ALL
, TEXT_INDEX_ALL
) ) );
871 mpExtTextView
->SetAutoScroll( bAutoScroll
);
874 mpExtTextView
->SetPaintSelection( true );
875 mpExtTextView
->ShowCursor( bGotoCursor
);
878 void TextWindow::LoseFocus()
882 if ( mbFocusSelectionHide
&& !mbActivePopup
&& mpExtTextView
)
883 mpExtTextView
->SetPaintSelection( false );
886 VclMultiLineEdit::VclMultiLineEdit( vcl::Window
* pParent
, WinBits nWinStyle
)
887 : Edit( pParent
, nWinStyle
)
889 SetType( WindowType::MULTILINEEDIT
);
890 pImpVclMEdit
.reset(new ImpVclMEdit( this, nWinStyle
));
891 ImplInitSettings( true );
893 SetCompoundControl( true );
894 SetStyle( ImplInitStyle( nWinStyle
) );
897 VclMultiLineEdit::~VclMultiLineEdit()
902 void VclMultiLineEdit::dispose()
904 pImpVclMEdit
.reset();
908 WinBits
VclMultiLineEdit::ImplInitStyle( WinBits nStyle
)
910 if ( !(nStyle
& WB_NOTABSTOP
) )
911 nStyle
|= WB_TABSTOP
;
913 if ( !(nStyle
& WB_NOGROUP
) )
916 if ( !(nStyle
& WB_IGNORETAB
))
917 nStyle
|= WB_NODIALOGCONTROL
;
922 void VclMultiLineEdit::ApplySettings(vcl::RenderContext
& rRenderContext
)
924 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
926 // The Font has to be adjusted, as the TextEngine does not take care of
927 // TextColor/Background
929 Color aTextColor
= rStyleSettings
.GetFieldTextColor();
930 if (IsControlForeground())
931 aTextColor
= GetControlForeground();
934 aTextColor
= rStyleSettings
.GetDisableColor();
936 vcl::Font aFont
= rStyleSettings
.GetFieldFont();
937 aFont
.SetTransparent(IsPaintTransparent());
938 ApplyControlFont(rRenderContext
, aFont
);
940 vcl::Font theFont
= rRenderContext
.GetFont();
941 theFont
.SetColor(aTextColor
);
942 if (IsPaintTransparent())
943 theFont
.SetFillColor(COL_TRANSPARENT
);
945 theFont
.SetFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings
.GetFieldColor());
947 pImpVclMEdit
->GetTextWindow()->SetFont(theFont
);
948 // FIXME: next call causes infinite invalidation loop, rethink how to properly fix this situation
949 // pImpVclMEdit->GetTextWindow()->GetTextEngine()->SetFont(theFont);
950 pImpVclMEdit
->GetTextWindow()->SetTextColor(aTextColor
);
952 if (IsPaintTransparent())
954 pImpVclMEdit
->GetTextWindow()->SetPaintTransparent(true);
955 pImpVclMEdit
->GetTextWindow()->SetBackground();
956 pImpVclMEdit
->GetTextWindow()->SetControlBackground();
957 rRenderContext
.SetBackground();
958 SetControlBackground();
962 if (IsControlBackground())
963 pImpVclMEdit
->GetTextWindow()->SetBackground(GetControlBackground());
965 pImpVclMEdit
->GetTextWindow()->SetBackground(rStyleSettings
.GetFieldColor());
966 // also adjust for VclMultiLineEdit as the TextComponent might hide Scrollbars
967 rRenderContext
.SetBackground(pImpVclMEdit
->GetTextWindow()->GetBackground());
971 void VclMultiLineEdit::ImplInitSettings(bool bBackground
)
973 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
975 // The Font has to be adjusted, as the TextEngine does not take care of
976 // TextColor/Background
978 Color aTextColor
= rStyleSettings
.GetFieldTextColor();
979 if (IsControlForeground())
980 aTextColor
= GetControlForeground();
982 aTextColor
= rStyleSettings
.GetDisableColor();
984 vcl::Font aFont
= rStyleSettings
.GetFieldFont();
985 aFont
.SetTransparent(IsPaintTransparent());
986 ApplyControlFont(*GetOutDev(), aFont
);
988 vcl::Font TheFont
= GetFont();
989 TheFont
.SetColor(aTextColor
);
990 if (IsPaintTransparent())
991 TheFont
.SetFillColor(COL_TRANSPARENT
);
993 TheFont
.SetFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings
.GetFieldColor());
994 pImpVclMEdit
->GetTextWindow()->SetFont(TheFont
);
995 pImpVclMEdit
->GetTextWindow()->GetTextEngine()->SetFont(TheFont
);
996 pImpVclMEdit
->GetTextWindow()->SetTextColor(aTextColor
);
1001 if (IsPaintTransparent())
1003 pImpVclMEdit
->GetTextWindow()->SetPaintTransparent(true);
1004 pImpVclMEdit
->GetTextWindow()->SetBackground();
1005 pImpVclMEdit
->GetTextWindow()->SetControlBackground();
1007 SetControlBackground();
1011 if (IsControlBackground())
1012 pImpVclMEdit
->GetTextWindow()->SetBackground(GetControlBackground());
1014 pImpVclMEdit
->GetTextWindow()->SetBackground(rStyleSettings
.GetFieldColor());
1015 // also adjust for VclMultiLineEdit as the TextComponent might hide Scrollbars
1016 SetBackground(pImpVclMEdit
->GetTextWindow()->GetBackground());
1020 void VclMultiLineEdit::Modify()
1022 aModifyHdlLink
.Call( *this );
1024 CallEventListeners( VclEventId::EditModify
);
1027 void VclMultiLineEdit::SelectionChanged()
1029 CallEventListeners(VclEventId::EditSelectionChanged
);
1032 void VclMultiLineEdit::CaretChanged()
1034 CallEventListeners(VclEventId::EditCaretChanged
);
1037 void VclMultiLineEdit::SetModifyFlag()
1039 pImpVclMEdit
->SetModified( true );
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();
1050 nStyle
|= WB_READONLY
;
1052 nStyle
&= ~WB_READONLY
;
1056 bool VclMultiLineEdit::IsReadOnly() const
1058 if (!pImpVclMEdit
) // might be called from within the dtor, when pImpVclMEdit == NULL is a valid state
1061 return pImpVclMEdit
->IsReadOnly();
1064 void VclMultiLineEdit::SetMaxTextLen(sal_Int32 nMaxLen
)
1066 pImpVclMEdit
->SetMaxTextLen(nMaxLen
);
1069 void VclMultiLineEdit::SetMaxTextWidth(tools::Long nMaxWidth
)
1071 pImpVclMEdit
->SetMaxTextWidth(nMaxWidth
);
1074 sal_Int32
VclMultiLineEdit::GetMaxTextLen() const
1076 return pImpVclMEdit
->GetMaxTextLen();
1079 void VclMultiLineEdit::ReplaceSelected( const OUString
& rStr
)
1081 pImpVclMEdit
->InsertText( rStr
);
1084 void VclMultiLineEdit::DeleteSelected()
1086 pImpVclMEdit
->InsertText( OUString() );
1089 OUString
VclMultiLineEdit::GetSelected() const
1091 return pImpVclMEdit
->GetSelected();
1094 OUString
VclMultiLineEdit::GetSelected( LineEnd aSeparator
) const
1096 return pImpVclMEdit
->GetSelected( aSeparator
);
1099 void VclMultiLineEdit::Cut()
1101 pImpVclMEdit
->Cut();
1104 void VclMultiLineEdit::Copy()
1106 pImpVclMEdit
->Copy();
1109 void VclMultiLineEdit::Paste()
1111 pImpVclMEdit
->Paste();
1114 void VclMultiLineEdit::SetText( const OUString
& rStr
)
1116 pImpVclMEdit
->SetText( rStr
);
1119 OUString
VclMultiLineEdit::GetText() const
1121 return pImpVclMEdit
? pImpVclMEdit
->GetText() : OUString();
1124 OUString
VclMultiLineEdit::GetText( LineEnd aSeparator
) const
1126 return pImpVclMEdit
? pImpVclMEdit
->GetText( aSeparator
) : OUString();
1129 OUString
VclMultiLineEdit::GetTextLines( LineEnd aSeparator
) const
1131 return pImpVclMEdit
? pImpVclMEdit
->GetTextLines( aSeparator
) : OUString();
1134 void VclMultiLineEdit::Resize()
1136 pImpVclMEdit
->Resize();
1139 void VclMultiLineEdit::GetFocus()
1141 if ( !pImpVclMEdit
) // might be called from within the dtor, when pImpVclMEdit == NULL is a valid state
1144 pImpVclMEdit
->GetFocus();
1147 void VclMultiLineEdit::SetSelection( const Selection
& rSelection
)
1149 pImpVclMEdit
->SetSelection( rSelection
);
1152 const Selection
& VclMultiLineEdit::GetSelection() const
1154 return pImpVclMEdit
->GetSelection();
1157 Size
VclMultiLineEdit::CalcMinimumSize() const
1159 Size aSz
= pImpVclMEdit
->CalcMinimumSize();
1161 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
1162 static_cast<vcl::Window
*>(const_cast<VclMultiLineEdit
*>(this))->GetBorder( nLeft
, nTop
, nRight
, nBottom
);
1163 aSz
.AdjustWidth(nLeft
+nRight
);
1164 aSz
.AdjustHeight(nTop
+nBottom
);
1169 Size
VclMultiLineEdit::CalcAdjustedSize( const Size
& rPrefSize
) const
1171 Size aSz
= rPrefSize
;
1172 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
1173 static_cast<vcl::Window
*>(const_cast<VclMultiLineEdit
*>(this))->GetBorder( nLeft
, nTop
, nRight
, nBottom
);
1175 // center vertically for whole lines
1177 tools::Long nHeight
= aSz
.Height() - nTop
- nBottom
;
1178 tools::Long nLineHeight
= pImpVclMEdit
->CalcBlockSize( 1, 1 ).Height();
1179 tools::Long nLines
= nHeight
/ nLineHeight
;
1183 aSz
.setHeight( nLines
* nLineHeight
);
1184 aSz
.AdjustHeight(nTop
+nBottom
);
1189 Size
VclMultiLineEdit::CalcBlockSize( sal_uInt16 nColumns
, sal_uInt16 nLines
) const
1191 Size aSz
= pImpVclMEdit
->CalcBlockSize( nColumns
, nLines
);
1193 sal_Int32 nLeft
, nTop
, nRight
, nBottom
;
1194 static_cast<vcl::Window
*>(const_cast<VclMultiLineEdit
*>(this))->GetBorder( nLeft
, nTop
, nRight
, nBottom
);
1195 aSz
.AdjustWidth(nLeft
+nRight
);
1196 aSz
.AdjustHeight(nTop
+nBottom
);
1200 void VclMultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16
& rnCols
, sal_uInt16
& rnLines
) const
1202 pImpVclMEdit
->GetMaxVisColumnsAndLines( rnCols
, rnLines
);
1205 void VclMultiLineEdit::StateChanged( StateChangedType nType
)
1207 if( nType
== StateChangedType::Enable
)
1209 pImpVclMEdit
->Enable( IsEnabled() );
1210 ImplInitSettings( false );
1212 else if( nType
== StateChangedType::ReadOnly
)
1214 pImpVclMEdit
->SetReadOnly( IsReadOnly() );
1216 else if ( nType
== StateChangedType::Zoom
)
1218 pImpVclMEdit
->GetTextWindow()->SetZoom( GetZoom() );
1219 ImplInitSettings( false );
1222 else if ( nType
== StateChangedType::ControlFont
)
1224 ImplInitSettings( false );
1228 else if ( nType
== StateChangedType::ControlForeground
)
1230 ImplInitSettings( false );
1233 else if ( nType
== StateChangedType::ControlBackground
)
1235 ImplInitSettings( true );
1238 else if ( nType
== StateChangedType::Style
)
1240 pImpVclMEdit
->InitFromStyle( GetStyle() );
1241 SetStyle( ImplInitStyle( GetStyle() ) );
1243 else if ( nType
== StateChangedType::InitShow
)
1245 if( IsPaintTransparent() )
1247 pImpVclMEdit
->GetTextWindow()->SetPaintTransparent( true );
1248 pImpVclMEdit
->GetTextWindow()->SetBackground();
1249 pImpVclMEdit
->GetTextWindow()->SetControlBackground();
1251 SetControlBackground();
1255 Control::StateChanged( nType
);
1258 void VclMultiLineEdit::DataChanged( const DataChangedEvent
& rDCEvt
)
1260 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
1261 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
1263 ImplInitSettings( true );
1268 Control::DataChanged( rDCEvt
);
1271 void VclMultiLineEdit::Draw( OutputDevice
* pDev
, const Point
& rPos
, SystemTextColorFlags nFlags
)
1273 ImplInitSettings(true);
1275 Point aPos
= pDev
->LogicToPixel( rPos
);
1276 Size aSize
= GetSizePixel();
1278 vcl::Font aFont
= pImpVclMEdit
->GetTextWindow()->GetDrawPixelFont(pDev
);
1279 aFont
.SetTransparent( true );
1283 pDev
->SetFont( aFont
);
1284 pDev
->SetTextFillColor();
1286 // Border/Background
1287 pDev
->SetLineColor();
1288 pDev
->SetFillColor();
1289 bool bBorder
= (GetStyle() & WB_BORDER
);
1290 bool bBackground
= IsControlBackground();
1291 if ( bBorder
|| bBackground
)
1293 tools::Rectangle
aRect( aPos
, aSize
);
1296 DecorationView
aDecoView( pDev
);
1297 aRect
= aDecoView
.DrawFrame( aRect
, DrawFrameStyle::DoubleIn
);
1301 pDev
->SetFillColor( GetControlBackground() );
1302 pDev
->DrawRect( aRect
);
1306 pDev
->SetSystemTextColor(nFlags
, IsEnabled());
1308 OUString aText
= GetText();
1309 Size
aTextSz( pDev
->GetTextWidth( aText
), pDev
->GetTextHeight() );
1310 sal_uLong nLines
= static_cast<sal_uLong
>(aSize
.Height() / aTextSz
.Height());
1313 aTextSz
.setHeight( nLines
*aTextSz
.Height() );
1314 tools::Long nOnePixel
= GetDrawPixel( pDev
, 1 );
1315 tools::Long nOffX
= 3*nOnePixel
;
1316 tools::Long nOffY
= 2*nOnePixel
;
1319 if ( ( nOffY
< 0 ) || ( (nOffY
+aTextSz
.Height()) > aSize
.Height() ) || ( (nOffX
+aTextSz
.Width()) > aSize
.Width() ) )
1321 tools::Rectangle
aClip( aPos
, aSize
);
1322 if ( aTextSz
.Height() > aSize
.Height() )
1323 aClip
.AdjustBottom(aTextSz
.Height() - aSize
.Height() + 1 ); // so that HP-printer does not 'optimize-away'
1324 pDev
->IntersectClipRegion( aClip
);
1328 aTE
.SetText( GetText() );
1329 aTE
.SetMaxTextWidth( aSize
.Width() );
1330 aTE
.SetFont( aFont
);
1331 aTE
.SetTextAlign( pImpVclMEdit
->GetTextWindow()->GetTextEngine()->GetTextAlign() );
1332 aTE
.Draw( pDev
, Point( aPos
.X() + nOffX
, aPos
.Y() + nOffY
) );
1337 bool VclMultiLineEdit::EventNotify( NotifyEvent
& rNEvt
)
1340 if( rNEvt
.GetType() == NotifyEventType::COMMAND
)
1342 bDone
= pImpVclMEdit
->HandleCommand( *rNEvt
.GetCommandEvent() );
1344 return bDone
|| Edit::EventNotify( rNEvt
);
1347 bool VclMultiLineEdit::PreNotify( NotifyEvent
& rNEvt
)
1351 if( ( rNEvt
.GetType() == NotifyEventType::KEYINPUT
) && ( !GetTextView()->IsCursorEnabled() ) )
1353 const KeyEvent
& rKEvent
= *rNEvt
.GetKeyEvent();
1354 if ( !rKEvent
.GetKeyCode().IsShift() && ( rKEvent
.GetKeyCode().GetGroup() == KEYGROUP_CURSOR
) )
1357 TextSelection aSel
= pImpVclMEdit
->GetTextWindow()->GetTextView()->GetSelection();
1358 if ( aSel
.HasRange() )
1360 aSel
.GetStart() = aSel
.GetEnd();
1361 pImpVclMEdit
->GetTextWindow()->GetTextView()->SetSelection( aSel
);
1365 switch ( rKEvent
.GetKeyCode().GetCode() )
1369 if ( pImpVclMEdit
->GetVScrollBar().IsVisible() )
1370 pImpVclMEdit
->GetVScrollBar().DoScrollAction( ScrollType::LineUp
);
1375 if ( pImpVclMEdit
->GetVScrollBar().IsVisible() )
1376 pImpVclMEdit
->GetVScrollBar().DoScrollAction( ScrollType::LineDown
);
1381 if ( pImpVclMEdit
->GetVScrollBar().IsVisible() )
1382 pImpVclMEdit
->GetVScrollBar().DoScrollAction( ScrollType::PageUp
);
1387 if ( pImpVclMEdit
->GetVScrollBar().IsVisible() )
1388 pImpVclMEdit
->GetVScrollBar().DoScrollAction( ScrollType::PageDown
);
1393 if ( pImpVclMEdit
->GetHScrollBar().IsVisible() )
1394 pImpVclMEdit
->GetHScrollBar().DoScrollAction( ScrollType::LineUp
);
1399 if ( pImpVclMEdit
->GetHScrollBar().IsVisible() )
1400 pImpVclMEdit
->GetHScrollBar().DoScrollAction( ScrollType::LineDown
);
1405 if ( rKEvent
.GetKeyCode().IsMod1() )
1406 pImpVclMEdit
->GetTextWindow()->GetTextView()->
1407 SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
1412 if ( rKEvent
.GetKeyCode().IsMod1() )
1413 pImpVclMEdit
->GetTextWindow()->GetTextView()->
1414 SetSelection( TextSelection( TextPaM( TEXT_PARA_ALL
, TEXT_INDEX_ALL
) ) );
1426 return bDone
|| Edit::PreNotify( rNEvt
);
1429 // Internals for derived classes, e.g. TextComponent
1431 ExtTextEngine
* VclMultiLineEdit::GetTextEngine() const
1433 return pImpVclMEdit
->GetTextWindow()->GetTextEngine();
1436 TextView
* VclMultiLineEdit::GetTextView() const
1438 return pImpVclMEdit
->GetTextWindow()->GetTextView();
1441 ScrollBar
& VclMultiLineEdit::GetVScrollBar() const
1443 return pImpVclMEdit
->GetVScrollBar();
1446 void VclMultiLineEdit::EnableFocusSelectionHide( bool bHide
)
1448 pImpVclMEdit
->GetTextWindow()->SetAutoFocusHide( bHide
);
1451 void VclMultiLineEdit::DisableSelectionOnFocus()
1453 pImpVclMEdit
->GetTextWindow()->DisableSelectionOnFocus();
1456 void VclMultiLineEdit::EnableCursor( bool bEnable
)
1458 GetTextView()->EnableCursor( bEnable
);
1461 bool VclMultiLineEdit::CanUp() const
1463 TextView
* pTextView
= GetTextView();
1464 const TextSelection
& rTextSelection
= pTextView
->GetSelection();
1465 TextPaM
aPaM(rTextSelection
.GetEnd());
1466 return aPaM
!= pTextView
->CursorUp(aPaM
);
1469 bool VclMultiLineEdit::CanDown() const
1471 TextView
* pTextView
= GetTextView();
1472 const TextSelection
& rTextSelection
= pTextView
->GetSelection();
1473 TextPaM
aPaM(rTextSelection
.GetEnd());
1474 return aPaM
!= pTextView
->CursorDown(aPaM
);
1477 TextWindow
* VclMultiLineEdit::GetTextWindow()
1479 return pImpVclMEdit
->GetTextWindow();
1482 FactoryFunction
VclMultiLineEdit::GetUITestFactory() const
1484 return MultiLineEditUIObject::create
;
1487 bool VclMultiLineEdit::set_property(const OUString
&rKey
, const OUString
&rValue
)
1489 if (rKey
== "cursor-visible")
1490 EnableCursor(toBool(rValue
));
1491 else if (rKey
== "accepts-tab")
1492 pImpVclMEdit
->GetTextWindow()->SetIgnoreTab(!toBool(rValue
));
1494 return Edit::set_property(rKey
, rValue
);
1498 void VclMultiLineEdit::DumpAsPropertyTree(tools::JsonWriter
& rJsonWriter
)
1500 Edit::DumpAsPropertyTree(rJsonWriter
);
1502 rJsonWriter
.put("cursor", pImpVclMEdit
->GetTextWindow()->GetTextView()->IsCursorEnabled());
1505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */