blob: e555046a748e8bb1b89f4e24feee885f27a4da53 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include <memory>
#include "unoiface.hxx"
#include <tools/rc.h>
#include <vcl/decoview.hxx>
#include <vcl/svapp.hxx>
#include <svtools/svmedit.hxx>
#include <svtools/xtextedt.hxx>
#include <svl/brdcst.hxx>
#include <svl/undo.hxx>
#include <svtools/textwindowpeer.hxx>
#include <svl/lstner.hxx>
#include <svl/smplhint.hxx>
// IDs erstmal aus VCL geklaut, muss mal richtig delivert werden...
#define SV_MENU_EDIT_UNDO 1
#define SV_MENU_EDIT_CUT 2
#define SV_MENU_EDIT_COPY 3
#define SV_MENU_EDIT_PASTE 4
#define SV_MENU_EDIT_DELETE 5
#define SV_MENU_EDIT_SELECTALL 6
#define SV_MENU_EDIT_INSERTSYMBOL 7
#include <vcl/scrbar.hxx>
namespace css = ::com::sun::star;
class TextWindow : public Window
{
private:
ExtTextEngine* mpExtTextEngine;
ExtTextView* mpExtTextView;
sal_Bool mbInMBDown;
sal_Bool mbFocusSelectionHide;
sal_Bool mbIgnoreTab;
sal_Bool mbActivePopup;
sal_Bool mbSelectOnTab;
public:
TextWindow( Window* pParent );
~TextWindow();
ExtTextEngine* GetTextEngine() const { return mpExtTextEngine; }
ExtTextView* GetTextView() const { return mpExtTextView; }
virtual void MouseMove( const MouseEvent& rMEvt );
virtual void MouseButtonDown( const MouseEvent& rMEvt );
virtual void MouseButtonUp( const MouseEvent& rMEvt );
virtual void KeyInput( const KeyEvent& rKEvent );
virtual void Command( const CommandEvent& rCEvt );
virtual void Paint( const Rectangle& rRect );
virtual void Resize();
virtual void GetFocus();
virtual void LoseFocus();
sal_Bool IsAutoFocusHide() const { return mbFocusSelectionHide; }
void SetAutoFocusHide( sal_Bool bAutoHide ) { mbFocusSelectionHide = bAutoHide; }
sal_Bool IsIgnoreTab() const { return mbIgnoreTab; }
void SetIgnoreTab( sal_Bool bIgnore ) { mbIgnoreTab = bIgnore; }
void DisableSelectionOnFocus() {mbSelectOnTab = sal_False;}
virtual
::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >
GetComponentInterface(sal_Bool bCreate = sal_True);
};
class ImpSvMEdit : public SfxListener
{
private:
MultiLineEdit* pSvMultiLineEdit;
TextWindow* mpTextWindow;
ScrollBar* mpHScrollBar;
ScrollBar* mpVScrollBar;
ScrollBarBox* mpScrollBox;
Point maTextWindowOffset;
xub_StrLen mnTextWidth;
mutable Selection maSelection;
protected:
virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
void ImpUpdateSrollBarVis( WinBits nWinStyle );
void ImpInitScrollBars();
void ImpSetScrollBarRanges();
void ImpSetHScrollBarThumbPos();
DECL_LINK( ScrollHdl, ScrollBar* );
public:
ImpSvMEdit( MultiLineEdit* pSvMultiLineEdit, WinBits nWinStyle );
~ImpSvMEdit();
void SetModified( sal_Bool bMod );
sal_Bool IsModified() const;
void SetReadOnly( sal_Bool bRdOnly );
sal_Bool IsReadOnly() const;
void SetMaxTextLen( xub_StrLen nLen );
xub_StrLen GetMaxTextLen() const;
void SetInsertMode( sal_Bool bInsert );
sal_Bool IsInsertMode() const;
void InsertText( const String& rStr );
String GetSelected() const;
String GetSelected( LineEnd aSeparator ) const;
void SetSelection( const Selection& rSelection );
const Selection& GetSelection() const;
void Cut();
void Copy();
void Paste();
void SetText( const String& rStr );
String GetText() const;
String GetText( LineEnd aSeparator ) const;
String GetTextLines() const;
String GetTextLines( LineEnd aSeparator ) const;
void Resize();
void GetFocus();
sal_Bool HandleCommand( const CommandEvent& rCEvt );
void Enable( sal_Bool bEnable );
Size CalcMinimumSize() const;
Size CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const;
void GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const;
void SetAlign( WinBits nWinStyle );
void InitFromStyle( WinBits nWinStyle );
TextWindow* GetTextWindow() { return mpTextWindow; }
ScrollBar* GetHScrollBar() { return mpHScrollBar; }
ScrollBar* GetVScrollBar() { return mpVScrollBar; }
void SetTextWindowOffset( const Point& rOffset );
};
ImpSvMEdit::ImpSvMEdit( MultiLineEdit* pEdt, WinBits nWinStyle )
:mpHScrollBar(NULL)
,mpVScrollBar(NULL)
,mpScrollBox(NULL)
{
pSvMultiLineEdit = pEdt;
mnTextWidth = 0;
mpTextWindow = new TextWindow( pEdt );
mpTextWindow->Show();
InitFromStyle( nWinStyle );
StartListening( *mpTextWindow->GetTextEngine() );
}
void ImpSvMEdit::ImpUpdateSrollBarVis( WinBits nWinStyle )
{
const sal_Bool bHaveVScroll = (NULL != mpVScrollBar);
const sal_Bool bHaveHScroll = (NULL != mpHScrollBar);
const sal_Bool bHaveScrollBox = (NULL != mpScrollBox);
sal_Bool bNeedVScroll = ( nWinStyle & WB_VSCROLL ) == WB_VSCROLL;
const sal_Bool bNeedHScroll = ( nWinStyle & WB_HSCROLL ) == WB_HSCROLL;
const sal_Bool bAutoVScroll = ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL;
if ( !bNeedVScroll && bAutoVScroll )
{
TextEngine& rEngine( *mpTextWindow->GetTextEngine() );
sal_uLong nOverallTextHeight(0);
for ( sal_uLong i=0; i<rEngine.GetParagraphCount(); ++i )
nOverallTextHeight += rEngine.GetTextHeight( i );
if ( nOverallTextHeight > (sal_uLong)mpTextWindow->GetOutputSizePixel().Height() )
bNeedVScroll = true;
}
const sal_Bool bNeedScrollBox = bNeedVScroll && bNeedHScroll;
sal_Bool bScrollbarsChanged = false;
if ( bHaveVScroll != bNeedVScroll )
{
delete mpVScrollBar;
mpVScrollBar = bNeedVScroll ? new ScrollBar( pSvMultiLineEdit, WB_VSCROLL|WB_DRAG ) : NULL;
if ( bNeedVScroll )
{
mpVScrollBar->Show();
mpVScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) );
}
bScrollbarsChanged = sal_True;
}
if ( bHaveHScroll != bNeedHScroll )
{
delete mpHScrollBar;
mpHScrollBar = bNeedHScroll ? new ScrollBar( pSvMultiLineEdit, WB_HSCROLL|WB_DRAG ) : NULL;
if ( bNeedHScroll )
{
mpHScrollBar->Show();
mpHScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) );
}
bScrollbarsChanged = sal_True;
}
if ( bHaveScrollBox != bNeedScrollBox )
{
delete mpScrollBox;
mpScrollBox = bNeedScrollBox ? new ScrollBarBox( pSvMultiLineEdit, WB_SIZEABLE ) : NULL;
if ( bNeedScrollBox )
mpScrollBox->Show();
}
if ( bScrollbarsChanged )
{
ImpInitScrollBars();
Resize();
}
}
void ImpSvMEdit::InitFromStyle( WinBits nWinStyle )
{
ImpUpdateSrollBarVis( nWinStyle );
SetAlign( nWinStyle );
if ( nWinStyle & WB_NOHIDESELECTION )
mpTextWindow->SetAutoFocusHide( sal_False );
else
mpTextWindow->SetAutoFocusHide( sal_True );
if ( nWinStyle & WB_READONLY )
mpTextWindow->GetTextView()->SetReadOnly( sal_True );
else
mpTextWindow->GetTextView()->SetReadOnly( sal_False );
if ( nWinStyle & WB_IGNORETAB )
{
mpTextWindow->SetIgnoreTab( sal_True );
}
else
{
mpTextWindow->SetIgnoreTab( sal_False );
// #103667# MultiLineEdit has the flag, but focusable window also needs this flag
WinBits nStyle = mpTextWindow->GetStyle();
nStyle |= WINDOW_DLGCTRL_MOD1TAB;
mpTextWindow->SetStyle( nStyle );
}
}
ImpSvMEdit::~ImpSvMEdit()
{
EndListening( *mpTextWindow->GetTextEngine() );
delete mpTextWindow;
delete mpHScrollBar;
delete mpVScrollBar;
delete mpScrollBox;
}
void ImpSvMEdit::ImpSetScrollBarRanges()
{
if ( mpVScrollBar )
{
sal_uLong nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
mpVScrollBar->SetRange( Range( 0, (long)nTextHeight-1 ) );
}
if ( mpHScrollBar )
{
// sal_uLong nTextWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
// Es gibt kein Notify bei Breiten-Aenderung...
// sal_uLong nW = Max( (sal_uLong)mpTextWindow->GetOutputSizePixel().Width()*5, (sal_uLong)nTextWidth );
// mpHScrollBar->SetRange( Range( 0, (long)nW ) );
mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
}
}
void ImpSvMEdit::ImpInitScrollBars()
{
static const sal_Unicode sampleText[] = { 'x', '\0' };
if ( mpHScrollBar || mpVScrollBar )
{
ImpSetScrollBarRanges();
Size aCharBox;
aCharBox.Width() = mpTextWindow->GetTextWidth( sampleText );
aCharBox.Height() = mpTextWindow->GetTextHeight();
Size aOutSz = mpTextWindow->GetOutputSizePixel();
if ( mpHScrollBar )
{
mpHScrollBar->SetVisibleSize( aOutSz.Width() );
mpHScrollBar->SetPageSize( aOutSz.Width() * 8 / 10 );
mpHScrollBar->SetLineSize( aCharBox.Width()*10 );
ImpSetHScrollBarThumbPos();
}
if ( mpVScrollBar )
{
mpVScrollBar->SetVisibleSize( aOutSz.Height() );
mpVScrollBar->SetPageSize( aOutSz.Height() * 8 / 10 );
mpVScrollBar->SetLineSize( aCharBox.Height() );
mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
}
}
}
void ImpSvMEdit::ImpSetHScrollBarThumbPos()
{
long nX = mpTextWindow->GetTextView()->GetStartDocPos().X();
if ( !mpTextWindow->GetTextEngine()->IsRightToLeft() )
mpHScrollBar->SetThumbPos( nX );
else
mpHScrollBar->SetThumbPos( mnTextWidth - mpHScrollBar->GetVisibleSize() - nX );
}
IMPL_LINK( ImpSvMEdit, ScrollHdl, ScrollBar*, pCurScrollBar )
{
long nDiffX = 0, nDiffY = 0;
if ( pCurScrollBar == mpVScrollBar )
nDiffY = mpTextWindow->GetTextView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
else if ( pCurScrollBar == mpHScrollBar )
nDiffX = mpTextWindow->GetTextView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
mpTextWindow->GetTextView()->Scroll( nDiffX, nDiffY );
// mpTextWindow->GetTextView()->ShowCursor( sal_False, sal_True );
return 0;
}
// void ImpSvMEdit::ImpModified()
// {
// // Wann wird das gerufen ?????????????????????
// pSvMultiLineEdit->Modify();
// }
void ImpSvMEdit::SetAlign( WinBits nWinStyle )
{
sal_Bool bRTL = Application::GetSettings().GetLayoutRTL();
mpTextWindow->GetTextEngine()->SetRightToLeft( bRTL );
if ( nWinStyle & WB_CENTER )
mpTextWindow->GetTextEngine()->SetTextAlign( TXTALIGN_CENTER );
else if ( nWinStyle & WB_RIGHT )
mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_RIGHT : TXTALIGN_LEFT );
else if ( nWinStyle & WB_LEFT )
mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_LEFT : TXTALIGN_RIGHT );
}
void ImpSvMEdit::SetTextWindowOffset( const Point& rOffset )
{
maTextWindowOffset = rOffset;
Resize();
}
void ImpSvMEdit::SetModified( sal_Bool bMod )
{
mpTextWindow->GetTextEngine()->SetModified( bMod );
}
sal_Bool ImpSvMEdit::IsModified() const
{
return mpTextWindow->GetTextEngine()->IsModified();
}
void ImpSvMEdit::SetInsertMode( sal_Bool bInsert )
{
mpTextWindow->GetTextView()->SetInsertMode( bInsert );
}
void ImpSvMEdit::SetReadOnly( sal_Bool bRdOnly )
{
mpTextWindow->GetTextView()->SetReadOnly( bRdOnly );
// Farbe anpassen ???????????????????????????
}
sal_Bool ImpSvMEdit::IsReadOnly() const
{
return mpTextWindow->GetTextView()->IsReadOnly();
}
void ImpSvMEdit::SetMaxTextLen( xub_StrLen nLen )
{
mpTextWindow->GetTextEngine()->SetMaxTextLen( nLen );
}
xub_StrLen ImpSvMEdit::GetMaxTextLen() const
{
return sal::static_int_cast< xub_StrLen >(
mpTextWindow->GetTextEngine()->GetMaxTextLen());
}
void ImpSvMEdit::InsertText( const String& rStr )
{
mpTextWindow->GetTextView()->InsertText( rStr );
}
String ImpSvMEdit::GetSelected() const
{
return mpTextWindow->GetTextView()->GetSelected();
}
String ImpSvMEdit::GetSelected( LineEnd aSeparator ) const
{
return mpTextWindow->GetTextView()->GetSelected( aSeparator );
}
void ImpSvMEdit::Resize()
{
size_t nIteration = 1;
do
{
WinBits nWinStyle( pSvMultiLineEdit->GetStyle() );
if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
ImpUpdateSrollBarVis( nWinStyle );
Size aSz = pSvMultiLineEdit->GetOutputSizePixel();
Size aEditSize = aSz;
long nSBWidth = pSvMultiLineEdit->GetSettings().GetStyleSettings().GetScrollBarSize();
nSBWidth = pSvMultiLineEdit->CalcZoom( nSBWidth );
if ( mpHScrollBar )
aSz.Height() -= nSBWidth+1;
if ( mpVScrollBar )
aSz.Width() -= nSBWidth+1;
if ( !mpHScrollBar )
mpTextWindow->GetTextEngine()->SetMaxTextWidth( aSz.Width() );
else
mpHScrollBar->SetPosSizePixel( 0, aEditSize.Height()-nSBWidth, aSz.Width(), nSBWidth );
Point aTextWindowPos( maTextWindowOffset );
if ( mpVScrollBar )
{
if( Application::GetSettings().GetLayoutRTL() )
{
mpVScrollBar->SetPosSizePixel( 0, 0, nSBWidth, aSz.Height() );
aTextWindowPos.X() += nSBWidth;
}
else
mpVScrollBar->SetPosSizePixel( aEditSize.Width()-nSBWidth, 0, nSBWidth, aSz.Height() );
}
if ( mpScrollBox )
mpScrollBox->SetPosSizePixel( aSz.Width(), aSz.Height(), nSBWidth, nSBWidth );
Size aTextWindowSize( aSz );
aTextWindowSize.Width() -= maTextWindowOffset.X();
aTextWindowSize.Height() -= maTextWindowOffset.Y();
if ( aTextWindowSize.Width() < 0 )
aTextWindowSize.Width() = 0;
if ( aTextWindowSize.Height() < 0 )
aTextWindowSize.Height() = 0;
Size aOldTextWindowSize( mpTextWindow->GetSizePixel() );
mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
if ( aOldTextWindowSize == aTextWindowSize )
break;
// Changing the text window size might effectively have changed the need for
// scrollbars, so do another iteration.
++nIteration;
OSL_ENSURE( nIteration < 3, "ImpSvMEdit::Resize: isn't this expected to terminate with the second iteration?" );
} while ( nIteration <= 3 ); // artificial break after four iterations
ImpInitScrollBars();
}
void ImpSvMEdit::GetFocus()
{
mpTextWindow->GrabFocus();
}
void ImpSvMEdit::Cut()
{
if ( !mpTextWindow->GetTextView()->IsReadOnly() )
mpTextWindow->GetTextView()->Cut();
}
void ImpSvMEdit::Copy()
{
mpTextWindow->GetTextView()->Copy();
}
void ImpSvMEdit::Paste()
{
if ( !mpTextWindow->GetTextView()->IsReadOnly() )
mpTextWindow->GetTextView()->Paste();
}
void ImpSvMEdit::SetText( const String& rStr )
{
sal_Bool bWasModified = mpTextWindow->GetTextEngine()->IsModified();
mpTextWindow->GetTextEngine()->SetText( rStr );
if ( !bWasModified )
mpTextWindow->GetTextEngine()->SetModified( sal_False );
mpTextWindow->GetTextView()->SetSelection( TextSelection() );
WinBits nWinStyle( pSvMultiLineEdit->GetStyle() );
if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
ImpUpdateSrollBarVis( nWinStyle );
}
String ImpSvMEdit::GetText() const
{
return mpTextWindow->GetTextEngine()->GetText();
}
String ImpSvMEdit::GetText( LineEnd aSeparator ) const
{
return mpTextWindow->GetTextEngine()->GetText( aSeparator );
}
String ImpSvMEdit::GetTextLines() const
{
return mpTextWindow->GetTextEngine()->GetTextLines();
}
String ImpSvMEdit::GetTextLines( LineEnd aSeparator ) const
{
return mpTextWindow->GetTextEngine()->GetTextLines( aSeparator );
}
void ImpSvMEdit::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
if ( rHint.ISA( TextHint ) )
{
const TextHint& rTextHint = (const TextHint&)rHint;
if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
{
if ( mpHScrollBar )
ImpSetHScrollBarThumbPos();
if ( mpVScrollBar )
mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
}
else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
{
if ( mpTextWindow->GetTextView()->GetStartDocPos().Y() )
{
long nOutHeight = mpTextWindow->GetOutputSizePixel().Height();
long nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
if ( nTextHeight < nOutHeight )
mpTextWindow->GetTextView()->Scroll( 0, mpTextWindow->GetTextView()->GetStartDocPos().Y() );
}
ImpSetScrollBarRanges();
}
else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
{
if ( mpHScrollBar )
{
sal_uLong nWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
if ( nWidth != mnTextWidth )
{
mnTextWidth = sal::static_int_cast< xub_StrLen >(nWidth);
mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
ImpSetHScrollBarThumbPos();
}
}
}
else if( rTextHint.GetId() == TEXT_HINT_MODIFIED )
{
pSvMultiLineEdit->Modify();
}
}
}
void ImpSvMEdit::SetSelection( const Selection& rSelection )
{
String aText = mpTextWindow->GetTextEngine()->GetText();
Selection aNewSelection( rSelection );
if ( aNewSelection.Min() < 0 )
aNewSelection.Min() = 0;
else if ( aNewSelection.Min() > aText.Len() )
aNewSelection.Min() = aText.Len();
if ( aNewSelection.Max() < 0 )
aNewSelection.Max() = 0;
else if ( aNewSelection.Max() > aText.Len() )
aNewSelection.Max() = aText.Len();
long nEnd = Max( aNewSelection.Min(), aNewSelection.Max() );
TextSelection aTextSel;
sal_uLong nPara = 0;
sal_uInt16 nChar = 0;
sal_uInt16 x = 0;
while ( x <= nEnd )
{
if ( x == aNewSelection.Min() )
aTextSel.GetStart() = TextPaM( nPara, nChar );
if ( x == aNewSelection.Max() )
aTextSel.GetEnd() = TextPaM( nPara, nChar );
if ( ( x < aText.Len() ) && ( aText.GetChar( x ) == '\n' ) )
{
nPara++;
nChar = 0;
}
else
nChar++;
x++;
}
mpTextWindow->GetTextView()->SetSelection( aTextSel );
}
const Selection& ImpSvMEdit::GetSelection() const
{
maSelection = Selection();
TextSelection aTextSel( mpTextWindow->GetTextView()->GetSelection() );
aTextSel.Justify();
// Selektion flachklopfen => jeder Umbruch ein Zeichen...
ExtTextEngine* pExtTextEngine = mpTextWindow->GetTextEngine();
// Absaetze davor:
sal_uLong n;
for ( n = 0; n < aTextSel.GetStart().GetPara(); n++ )
{
maSelection.Min() += pExtTextEngine->GetTextLen( n );
maSelection.Min()++;
}
// Erster Absatz mit Selektion:
maSelection.Max() = maSelection.Min();
maSelection.Min() += aTextSel.GetStart().GetIndex();
for ( n = aTextSel.GetStart().GetPara(); n < aTextSel.GetEnd().GetPara(); n++ )
{
maSelection.Max() += pExtTextEngine->GetTextLen( n );
maSelection.Max()++;
}
maSelection.Max() += aTextSel.GetEnd().GetIndex();
return maSelection;
}
Size ImpSvMEdit::CalcMinimumSize() const
{
Size aSz( mpTextWindow->GetTextEngine()->CalcTextWidth(),
mpTextWindow->GetTextEngine()->GetTextHeight() );
if ( mpHScrollBar )
aSz.Height() += mpHScrollBar->GetSizePixel().Height();
if ( mpVScrollBar )
aSz.Width() += mpVScrollBar->GetSizePixel().Width();
return aSz;
}
Size ImpSvMEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
{
static const sal_Unicode sampleText[] = { 'X', '\0' };
Size aSz;
Size aCharSz;
aCharSz.Width() = mpTextWindow->GetTextWidth( sampleText );
aCharSz.Height() = mpTextWindow->GetTextHeight();
if ( nLines )
aSz.Height() = nLines*aCharSz.Height();
else
aSz.Height() = mpTextWindow->GetTextEngine()->GetTextHeight();
if ( nColumns )
aSz.Width() = nColumns*aCharSz.Width();
else
aSz.Width() = mpTextWindow->GetTextEngine()->CalcTextWidth();
if ( mpHScrollBar )
aSz.Height() += mpHScrollBar->GetSizePixel().Height();
if ( mpVScrollBar )
aSz.Width() += mpVScrollBar->GetSizePixel().Width();
return aSz;
}
void ImpSvMEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
{
static const sal_Unicode sampleText[] = { 'x', '\0' };
Size aOutSz = mpTextWindow->GetOutputSizePixel();
Size aCharSz( mpTextWindow->GetTextWidth( sampleText ), mpTextWindow->GetTextHeight() );
rnCols = (sal_uInt16) (aOutSz.Width()/aCharSz.Width());
rnLines = (sal_uInt16) (aOutSz.Height()/aCharSz.Height());
}
void ImpSvMEdit::Enable( sal_Bool bEnable )
{
mpTextWindow->Enable( bEnable );
if ( mpHScrollBar )
mpHScrollBar->Enable( bEnable );
if ( mpVScrollBar )
mpVScrollBar->Enable( bEnable );
}
sal_Bool ImpSvMEdit::HandleCommand( const CommandEvent& rCEvt )
{
sal_Bool bDone = sal_False;
if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
{
mpTextWindow->HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
bDone = sal_True;
}
return bDone;
}
TextWindow::TextWindow( Window* pParent ) : Window( pParent )
{
mbInMBDown = sal_False;
mbSelectOnTab = sal_True;
mbFocusSelectionHide = sal_False;
mbIgnoreTab = sal_False;
mbActivePopup = sal_False;
mbSelectOnTab = sal_True;
SetPointer( Pointer( POINTER_TEXT ) );
mpExtTextEngine = new ExtTextEngine;
mpExtTextEngine->SetMaxTextLen( STRING_MAXLEN );
if( pParent->GetStyle() & WB_BORDER )
mpExtTextEngine->SetLeftMargin( 2 );
mpExtTextEngine->SetLocale( GetSettings().GetLocale() );
mpExtTextView = new ExtTextView( mpExtTextEngine, this );
mpExtTextEngine->InsertView( mpExtTextView );
mpExtTextEngine->EnableUndo( sal_True );
mpExtTextView->ShowCursor();
Color aBackgroundColor = GetSettings().GetStyleSettings().GetWorkspaceColor();
SetBackground( aBackgroundColor );
pParent->SetBackground( aBackgroundColor );
}
TextWindow::~TextWindow()
{
delete mpExtTextView;
delete mpExtTextEngine;
}
void TextWindow::MouseMove( const MouseEvent& rMEvt )
{
mpExtTextView->MouseMove( rMEvt );
Window::MouseMove( rMEvt );
}
void TextWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
mbInMBDown = sal_True; // Dann im GetFocus nicht alles selektieren wird
mpExtTextView->MouseButtonDown( rMEvt );
Window::MouseButtonDown( rMEvt );
GrabFocus();
mbInMBDown = sal_False;
}
void TextWindow::MouseButtonUp( const MouseEvent& rMEvt )
{
mpExtTextView->MouseButtonUp( rMEvt );
Window::MouseButtonUp( rMEvt );
}
void TextWindow::KeyInput( const KeyEvent& rKEvent )
{
sal_Bool bDone = sal_False;
sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
if ( nCode == com::sun::star::awt::Key::SELECT_ALL ||
( (nCode == KEY_A) && rKEvent.GetKeyCode().IsMod1() && !rKEvent.GetKeyCode().IsMod2() )
)
{
mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
bDone = sal_True;
}
else if ( (nCode == KEY_S) && rKEvent.GetKeyCode().IsShift() && rKEvent.GetKeyCode().IsMod1() )
{
if ( Edit::GetGetSpecialCharsFunction() )
{
// Damit die Selektion erhalten bleibt
mbActivePopup = sal_True;
XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
if ( aChars.Len() )
{
mpExtTextView->InsertText( aChars );
mpExtTextView->GetTextEngine()->SetModified( sal_True );
}
mbActivePopup = sal_False;
bDone = sal_True;
}
}
else if ( nCode == KEY_TAB )
{
if ( !mbIgnoreTab || rKEvent.GetKeyCode().IsMod1() )
bDone = mpExtTextView->KeyInput( rKEvent );
}
else
{
bDone = mpExtTextView->KeyInput( rKEvent );
}
if ( !bDone )
Window::KeyInput( rKEvent );
}
void TextWindow::Paint( const Rectangle& rRect )
{
mpExtTextView->Paint( rRect );
}
void TextWindow::Resize()
{
}
void TextWindow::Command( const CommandEvent& rCEvt )
{
if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
{
PopupMenu* pPopup = Edit::CreatePopupMenu();
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
if ( rStyleSettings.GetOptions() & STYLE_OPTION_HIDEDISABLED )
pPopup->SetMenuFlags( MENU_FLAG_HIDEDISABLEDENTRIES );
if ( !mpExtTextView->HasSelection() )
{
pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False );
pPopup->EnableItem( SV_MENU_EDIT_COPY, sal_False );
pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False );
}
if ( mpExtTextView->IsReadOnly() )
{
pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False );
pPopup->EnableItem( SV_MENU_EDIT_PASTE, sal_False );
pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False );
pPopup->EnableItem( SV_MENU_EDIT_INSERTSYMBOL, sal_False );
}
if ( !mpExtTextView->GetTextEngine()->HasUndoManager() || !mpExtTextView->GetTextEngine()->GetUndoManager().GetUndoActionCount() )
{
pPopup->EnableItem( SV_MENU_EDIT_UNDO, sal_False );
}
// if ( ( maSelection.Min() == 0 ) && ( maSelection.Max() == maText.Len() ) )
// {
// pPopup->EnableItem( SV_MENU_EDIT_SELECTALL, sal_False );
// }
if ( !Edit::GetGetSpecialCharsFunction() )
{
sal_uInt16 nPos = pPopup->GetItemPos( SV_MENU_EDIT_INSERTSYMBOL );
pPopup->RemoveItem( nPos );
pPopup->RemoveItem( nPos-1 );
}
mbActivePopup = sal_True;
Point aPos = rCEvt.GetMousePosPixel();
if ( !rCEvt.IsMouseEvent() )
{
// !!! Irgendwann einmal Menu zentriert in der Selektion anzeigen !!!
Size aSize = GetOutputSizePixel();
aPos = Point( aSize.Width()/2, aSize.Height()/2 );
}
// pPopup->RemoveDisabledEntries();
sal_uInt16 n = pPopup->Execute( this, aPos );
Edit::DeletePopupMenu( pPopup );
switch ( n )
{
case SV_MENU_EDIT_UNDO: mpExtTextView->Undo();
mpExtTextEngine->SetModified( sal_True );
mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
break;
case SV_MENU_EDIT_CUT: mpExtTextView->Cut();
mpExtTextEngine->SetModified( sal_True );
mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
break;
case SV_MENU_EDIT_COPY: mpExtTextView->Copy();
break;
case SV_MENU_EDIT_PASTE: mpExtTextView->Paste();
mpExtTextEngine->SetModified( sal_True );
mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
break;
case SV_MENU_EDIT_DELETE: mpExtTextView->DeleteSelected();
mpExtTextEngine->SetModified( sal_True );
mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
break;
case SV_MENU_EDIT_SELECTALL: mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
break;
case SV_MENU_EDIT_INSERTSYMBOL:
{
XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
if ( aChars.Len() )
{
mpExtTextView->InsertText( aChars );
mpExtTextEngine->SetModified( sal_True );
mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
}
}
break;
}
mbActivePopup = sal_False;
}
else
{
mpExtTextView->Command( rCEvt );
}
Window::Command( rCEvt );
}
void TextWindow::GetFocus()
{
Window::GetFocus();
if ( !mbActivePopup )
{
sal_Bool bGotoCursor = !mpExtTextView->IsReadOnly();
if ( mbFocusSelectionHide
&& IsReallyVisible()
&& !mpExtTextView->IsReadOnly()
&& ( mbSelectOnTab
&& ( !mbInMBDown
|| ( GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_FOCUS ) ) ) )
{
// Alles selektieren, aber nicht scrollen
sal_Bool bAutoScroll = mpExtTextView->IsAutoScroll();
mpExtTextView->SetAutoScroll( sal_False );
mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
mpExtTextView->SetAutoScroll( bAutoScroll );
bGotoCursor = sal_False;
}
mpExtTextView->SetPaintSelection( sal_True );
mpExtTextView->ShowCursor( bGotoCursor );
}
}
void TextWindow::LoseFocus()
{
Window::LoseFocus();
if ( mbFocusSelectionHide && !mbActivePopup )
mpExtTextView->SetPaintSelection( sal_False );
}
// virtual
::css::uno::Reference< ::css::awt::XWindowPeer >
TextWindow::GetComponentInterface(sal_Bool bCreate)
{
::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
Window::GetComponentInterface(false));
if (!xPeer.is() && bCreate)
{
xPeer = new ::svt::TextWindowPeer(*GetTextView(), true);
SetComponentInterface(xPeer);
}
return xPeer;
}
MultiLineEdit::MultiLineEdit( Window* pParent, WinBits nWinStyle )
: Edit( pParent, nWinStyle )
{
SetType( WINDOW_MULTILINEEDIT );
pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
ImplInitSettings( sal_True, sal_True, sal_True );
pUpdateDataTimer = 0;
SetCompoundControl( sal_True );
SetStyle( ImplInitStyle( nWinStyle ) );
}
MultiLineEdit::MultiLineEdit( Window* pParent, const ResId& rResId )
: Edit( pParent, rResId.SetRT( RSC_MULTILINEEDIT ) )
{
SetType( WINDOW_MULTILINEEDIT );
WinBits nWinStyle = rResId.GetWinBits();
pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
ImplInitSettings( sal_True, sal_True, sal_True );
pUpdateDataTimer = 0;
sal_uInt16 nMaxLen = Edit::GetMaxTextLen();
if ( nMaxLen )
SetMaxTextLen( nMaxLen );
SetText( Edit::GetText() );
if ( IsVisible() )
pImpSvMEdit->Resize();
SetCompoundControl( sal_True );
SetStyle( ImplInitStyle( nWinStyle ) );
// Base Edit ctor could call Show already, but that would cause problems
// with accessibility, as Show might (indirectly) trigger a call to virtual
// GetComponentInterface, which is the Edit's base version instead of the
// MultiLineEdit's version while in the base Edit ctor:
if ((GetStyle() & WB_HIDE) == 0)
Show();
}
MultiLineEdit::~MultiLineEdit()
{
{
::std::auto_ptr< ImpSvMEdit > pDelete( pImpSvMEdit );
pImpSvMEdit = NULL;
}
delete pUpdateDataTimer;
}
WinBits MultiLineEdit::ImplInitStyle( WinBits nStyle )
{
if ( !(nStyle & WB_NOTABSTOP) )
nStyle |= WB_TABSTOP;
if ( !(nStyle & WB_NOGROUP) )
nStyle |= WB_GROUP;
if ( !(nStyle & WB_IGNORETAB ))
nStyle |= WINDOW_DLGCTRL_MOD1TAB;
return nStyle;
}
void MultiLineEdit::ImplInitSettings( sal_Bool /*bFont*/, sal_Bool /*bForeground*/, sal_Bool bBackground )
{
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
// Der Font muss immer mit manipuliert werden, weil die TextEngine
// sich nicht um TextColor/Background kuemmert
Color aTextColor = rStyleSettings.GetFieldTextColor();
if ( IsControlForeground() )
aTextColor = GetControlForeground();
if ( !IsEnabled() )
aTextColor = rStyleSettings.GetDisableColor();
Font aFont = rStyleSettings.GetFieldFont();
if ( IsControlFont() )
aFont.Merge( GetControlFont() );
aFont.SetTransparent( IsPaintTransparent() );
SetZoomedPointFont( aFont );
Font TheFont = GetFont();
TheFont.SetColor( aTextColor );
if( IsPaintTransparent() )
TheFont.SetFillColor( Color( COL_TRANSPARENT ) );
else
TheFont.SetFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() );
pImpSvMEdit->GetTextWindow()->SetFont( TheFont );
pImpSvMEdit->GetTextWindow()->GetTextEngine()->SetFont( TheFont );
pImpSvMEdit->GetTextWindow()->SetTextColor( aTextColor );
if ( bBackground )
{
if( IsPaintTransparent() )
{
pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
pImpSvMEdit->GetTextWindow()->SetBackground();
pImpSvMEdit->GetTextWindow()->SetControlBackground();
SetBackground();
SetControlBackground();
}
else
{
if( IsControlBackground() )
pImpSvMEdit->GetTextWindow()->SetBackground( GetControlBackground() );
else
pImpSvMEdit->GetTextWindow()->SetBackground( rStyleSettings.GetFieldColor() );
// Auch am MultiLineEdit einstellen, weil die TextComponent
// ggf. die Scrollbars hidet.
SetBackground( pImpSvMEdit->GetTextWindow()->GetBackground() );
}
}
}
void MultiLineEdit::Modify()
{
aModifyHdlLink.Call( this );
CallEventListeners( VCLEVENT_EDIT_MODIFY );
if ( pUpdateDataTimer )
pUpdateDataTimer->Start();
}
IMPL_LINK( MultiLineEdit, ImpUpdateDataHdl, Timer*, EMPTYARG )
{
UpdateData();
return 0;
}
void MultiLineEdit::UpdateData()
{
aUpdateDataHdlLink.Call( this );
}
void MultiLineEdit::SetModifyFlag()
{
pImpSvMEdit->SetModified( sal_True );
}
void MultiLineEdit::ClearModifyFlag()
{
pImpSvMEdit->SetModified( sal_False );
}
sal_Bool MultiLineEdit::IsModified() const
{
return pImpSvMEdit->IsModified();
}
void MultiLineEdit::EnableUpdateData( sal_uLong nTimeout )
{
if ( !nTimeout )
DisableUpdateData();
else
{
if ( !pUpdateDataTimer )
{
pUpdateDataTimer = new Timer;
pUpdateDataTimer->SetTimeoutHdl( LINK( this, MultiLineEdit, ImpUpdateDataHdl ) );
}
pUpdateDataTimer->SetTimeout( nTimeout );
}
}
void MultiLineEdit::SetReadOnly( sal_Bool bReadOnly )
{
pImpSvMEdit->SetReadOnly( bReadOnly );
Edit::SetReadOnly( bReadOnly );
// #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set.
WinBits nStyle = GetStyle();
if ( bReadOnly )
nStyle |= WB_READONLY;
else
nStyle &= ~WB_READONLY;
SetStyle( nStyle );
}
sal_Bool MultiLineEdit::IsReadOnly() const
{
return pImpSvMEdit->IsReadOnly();
}
void MultiLineEdit::SetMaxTextLen( xub_StrLen nMaxLen )
{
pImpSvMEdit->SetMaxTextLen( nMaxLen );
}
xub_StrLen MultiLineEdit::GetMaxTextLen() const
{
return pImpSvMEdit->GetMaxTextLen();
}
void MultiLineEdit::ReplaceSelected( const String& rStr )
{
pImpSvMEdit->InsertText( rStr );
}
void MultiLineEdit::DeleteSelected()
{
pImpSvMEdit->InsertText( String() );
}
String MultiLineEdit::GetSelected() const
{
return pImpSvMEdit->GetSelected();
}
String MultiLineEdit::GetSelected( LineEnd aSeparator ) const
{
return pImpSvMEdit->GetSelected( aSeparator );
}
void MultiLineEdit::Cut()
{
pImpSvMEdit->Cut();
}
void MultiLineEdit::Copy()
{
pImpSvMEdit->Copy();
}
void MultiLineEdit::Paste()
{
pImpSvMEdit->Paste();
}
void MultiLineEdit::SetText( const String& rStr )
{
pImpSvMEdit->SetText( rStr );
}
String MultiLineEdit::GetText() const
{
return pImpSvMEdit->GetText();
}
String MultiLineEdit::GetText( LineEnd aSeparator ) const
{
return pImpSvMEdit->GetText( aSeparator );
}
String MultiLineEdit::GetTextLines() const
{
return pImpSvMEdit->GetTextLines();
}
String MultiLineEdit::GetTextLines( LineEnd aSeparator ) const
{
return pImpSvMEdit->GetTextLines( aSeparator );
}
void MultiLineEdit::Resize()
{
pImpSvMEdit->Resize();
}
void MultiLineEdit::GetFocus()
{
if ( pImpSvMEdit == NULL ) // might be called from within the dtor, when pImpSvMEdit == NULL is a valid state
return;
Edit::GetFocus();
pImpSvMEdit->GetFocus();
}
void MultiLineEdit::SetSelection( const Selection& rSelection )
{
pImpSvMEdit->SetSelection( rSelection );
}
const Selection& MultiLineEdit::GetSelection() const
{
return pImpSvMEdit->GetSelection();
}
Size MultiLineEdit::CalcMinimumSize() const
{
Size aSz = pImpSvMEdit->CalcMinimumSize();
sal_Int32 nLeft, nTop, nRight, nBottom;
((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
aSz.Width() += nLeft+nRight;
aSz.Height() += nTop+nBottom;
return aSz;
}
Size MultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const
{
Size aSz = rPrefSize;
sal_Int32 nLeft, nTop, nRight, nBottom;
((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
// In der Hoehe auf ganze Zeilen justieren
long nHeight = aSz.Height() - nTop - nBottom;
long nLineHeight = pImpSvMEdit->CalcSize( 1, 1 ).Height();
long nLines = nHeight / nLineHeight;
if ( nLines < 1 )
nLines = 1;
aSz.Height() = nLines * nLineHeight;
aSz.Height() += nTop+nBottom;
return aSz;
}
Size MultiLineEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
{
Size aSz = pImpSvMEdit->CalcSize( nColumns, nLines );
sal_Int32 nLeft, nTop, nRight, nBottom;
((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
aSz.Width() += nLeft+nRight;
aSz.Height() += nTop+nBottom;
return aSz;
}
void MultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
{
pImpSvMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines );
}
void MultiLineEdit::StateChanged( StateChangedType nType )
{
if( nType == STATE_CHANGE_ENABLE )
{
pImpSvMEdit->Enable( IsEnabled() );
ImplInitSettings( sal_True, sal_False, sal_False );
}
else if( nType == STATE_CHANGE_READONLY )
{
pImpSvMEdit->SetReadOnly( IsReadOnly() );
}
else if ( nType == STATE_CHANGE_ZOOM )
{
pImpSvMEdit->GetTextWindow()->SetZoom( GetZoom() );
ImplInitSettings( sal_True, sal_False, sal_False );
Resize();
}
else if ( nType == STATE_CHANGE_CONTROLFONT )
{
ImplInitSettings( sal_True, sal_False, sal_False );
Resize();
Invalidate();
}
else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
{
ImplInitSettings( sal_False, sal_True, sal_False );
Invalidate();
}
else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
{
ImplInitSettings( sal_False, sal_False, sal_True );
Invalidate();
}
else if ( nType == STATE_CHANGE_STYLE )
{
pImpSvMEdit->InitFromStyle( GetStyle() );
SetStyle( ImplInitStyle( GetStyle() ) );
}
else if ( nType == STATE_CHANGE_INITSHOW )
{
if( IsPaintTransparent() )
{
pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
pImpSvMEdit->GetTextWindow()->SetBackground();
pImpSvMEdit->GetTextWindow()->SetControlBackground();
SetBackground();
SetControlBackground();
}
}
Control::StateChanged( nType );
}
void MultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt )
{
if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
(rDCEvt.GetFlags() & SETTINGS_STYLE) )
{
ImplInitSettings( sal_True, sal_True, sal_True );
Resize();
Invalidate();
}
else
Control::DataChanged( rDCEvt );
}
void MultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
{
ImplInitSettings( sal_True, sal_True, sal_True );
Point aPos = pDev->LogicToPixel( rPos );
Size aSize = pDev->LogicToPixel( rSize );
Font aFont = pImpSvMEdit->GetTextWindow()->GetDrawPixelFont( pDev );
aFont.SetTransparent( sal_True );
OutDevType eOutDevType = pDev->GetOutDevType();
pDev->Push();
pDev->SetMapMode();
pDev->SetFont( aFont );
pDev->SetTextFillColor();
// Border/Background
pDev->SetLineColor();
pDev->SetFillColor();
sal_Bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
if ( bBorder || bBackground )
{
Rectangle aRect( aPos, aSize );
if ( bBorder )
{
DecorationView aDecoView( pDev );
aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
}
if ( bBackground )
{
pDev->SetFillColor( GetControlBackground() );
pDev->DrawRect( aRect );
}
}
// Inhalt
if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
pDev->SetTextColor( Color( COL_BLACK ) );
else
{
if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
{
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
pDev->SetTextColor( rStyleSettings.GetDisableColor() );
}
else
{
pDev->SetTextColor( GetTextColor() );
}
}
XubString aText = GetText();
Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() );
sal_uLong nLines = (sal_uLong) (aSize.Height() / aTextSz.Height());
if ( !nLines )
nLines = 1;
aTextSz.Height() = nLines*aTextSz.Height();
long nOnePixel = GetDrawPixel( pDev, 1 );
long nOffX = 3*nOnePixel;
long nOffY = 2*nOnePixel;
// Clipping?
if ( ( nOffY < 0 ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) )
{
Rectangle aClip( aPos, aSize );
if ( aTextSz.Height() > aSize.Height() )
aClip.Bottom() += aTextSz.Height() - aSize.Height() + 1; // Damit HP-Drucker nicht 'weg-optimieren'
pDev->IntersectClipRegion( aClip );
}
TextEngine aTE;
aTE.SetText( GetText() );
aTE.SetMaxTextWidth( aSize.Width() );
aTE.SetFont( aFont );
aTE.SetTextAlign( pImpSvMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() );
aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) );
pDev->Pop();
}
long MultiLineEdit::Notify( NotifyEvent& rNEvt )
{
long nDone = 0;
if( rNEvt.GetType() == EVENT_COMMAND )
{
nDone = pImpSvMEdit->HandleCommand( *rNEvt.GetCommandEvent() );
}
return nDone ? nDone : Edit::Notify( rNEvt );
}
long MultiLineEdit::PreNotify( NotifyEvent& rNEvt )
{
long nDone = 0;
#if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL)
if( rNEvt.GetType() == EVENT_KEYINPUT )
{
const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
if ( ( rKEvent.GetKeyCode().GetCode() == KEY_W ) && rKEvent.GetKeyCode().IsMod1() && rKEvent.GetKeyCode().IsMod2() )
{
SetRightToLeft( !IsRightToLeft() );
}
}
#endif
if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) )
{
const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) )
{
nDone = 1;
TextSelection aSel = pImpSvMEdit->GetTextWindow()->GetTextView()->GetSelection();
if ( aSel.HasRange() )
{
aSel.GetStart() = aSel.GetEnd();
pImpSvMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel );
}
else
{
switch ( rKEvent.GetKeyCode().GetCode() )
{
case KEY_UP:
{
if ( pImpSvMEdit->GetVScrollBar() )
pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEUP );
}
break;
case KEY_DOWN:
{
if ( pImpSvMEdit->GetVScrollBar() )
pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
}
break;
case KEY_PAGEUP :
{
if ( pImpSvMEdit->GetVScrollBar() )
pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEUP );
}
break;
case KEY_PAGEDOWN:
{
if ( pImpSvMEdit->GetVScrollBar() )
pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEDOWN );
}
break;
case KEY_LEFT:
{
if ( pImpSvMEdit->GetHScrollBar() )
pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEUP );
}
break;
case KEY_RIGHT:
{
if ( pImpSvMEdit->GetHScrollBar() )
pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
}
break;
case KEY_HOME:
{
if ( rKEvent.GetKeyCode().IsMod1() )
pImpSvMEdit->GetTextWindow()->GetTextView()->
SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
}
break;
case KEY_END:
{
if ( rKEvent.GetKeyCode().IsMod1() )
pImpSvMEdit->GetTextWindow()->GetTextView()->
SetSelection( TextSelection( TextPaM( 0xFFFF, 0xFFFF ) ) );
}
break;
default:
{
nDone = 0;
}
}
}
}
}
return nDone ? nDone : Edit::PreNotify( rNEvt );
}
//
// Internas fuer abgeleitete Klassen, z.B. TextComponent
ExtTextEngine* MultiLineEdit::GetTextEngine() const
{
return pImpSvMEdit->GetTextWindow()->GetTextEngine();
}
ExtTextView* MultiLineEdit::GetTextView() const
{
return pImpSvMEdit->GetTextWindow()->GetTextView();
}
ScrollBar* MultiLineEdit::GetHScrollBar() const
{
return pImpSvMEdit->GetHScrollBar();
}
ScrollBar* MultiLineEdit::GetVScrollBar() const
{
return pImpSvMEdit->GetVScrollBar();
}
void MultiLineEdit::EnableFocusSelectionHide( sal_Bool bHide )
{
pImpSvMEdit->GetTextWindow()->SetAutoFocusHide( bHide );
}
sal_Bool MultiLineEdit::IsFocusSelectionHideEnabled() const
{
return pImpSvMEdit->GetTextWindow()->IsAutoFocusHide();
}
void MultiLineEdit::SetLeftMargin( sal_uInt16 n )
{
if ( GetTextEngine() )
GetTextEngine()->SetLeftMargin( n );
}
sal_uInt16 MultiLineEdit::GetLeftMargin() const
{
if ( GetTextEngine() )
return GetTextEngine()->GetLeftMargin();
else
return 0;
}
void MultiLineEdit::SetRightToLeft( sal_Bool bRightToLeft )
{
if ( GetTextEngine() )
{
GetTextEngine()->SetRightToLeft( bRightToLeft );
GetTextView()->ShowCursor();
}
}
sal_Bool MultiLineEdit::IsRightToLeft() const
{
sal_Bool bRightToLeft = sal_False;
if ( GetTextEngine() )
bRightToLeft = GetTextEngine()->IsRightToLeft();
return bRightToLeft;
}
// virtual
::css::uno::Reference< ::css::awt::XWindowPeer >
MultiLineEdit::GetComponentInterface(sal_Bool bCreate)
{
::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
Edit::GetComponentInterface(false));
if (!xPeer.is() && bCreate)
{
::std::auto_ptr< VCLXMultiLineEdit > xEdit(new VCLXMultiLineEdit());
xEdit->SetWindow(this);
xPeer = xEdit.release();
SetComponentInterface(xPeer);
}
return xPeer;
}
/*-- 11.08.2004 11:29:23---------------------------------------------------
-----------------------------------------------------------------------*/
void MultiLineEdit::DisableSelectionOnFocus()
{
pImpSvMEdit->GetTextWindow()->DisableSelectionOnFocus();
}