/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
bool Edit::IsCharInput( const KeyEvent& rKeyEvent )
{ // In the future we must use new Unicode functions for this
sal_Unicode cCharCode = rKeyEvent.GetCharCode(); return ((cCharCode >= 32) && (cCharCode != 127) &&
!rKeyEvent.GetKeyCode().IsMod3() &&
!rKeyEvent.GetKeyCode().IsMod2() &&
!rKeyEvent.GetKeyCode().IsMod1() );
}
Color aTextColor = rStyleSettings.GetFieldTextColor();
ApplyControlForeground(rRenderContext, aTextColor);
if (IsControlBackground())
{
rRenderContext.SetBackground(GetControlBackground());
rRenderContext.SetFillColor(GetControlBackground());
if (ImplUseNativeBorder(rRenderContext, GetStyle()))
{ // indicates that no non-native drawing of background should take place
mpWindowImpl->mnNativeBackground = ControlPart::Entire;
}
} elseif (ImplUseNativeBorder(rRenderContext, GetStyle()))
{ // Transparent background
rRenderContext.SetBackground();
rRenderContext.SetFillColor();
} else
{
rRenderContext.SetBackground(rStyleSettings.GetFieldColor());
rRenderContext.SetFillColor(rStyleSettings.GetFieldColor());
}
}
tools::Long Edit::ImplGetExtraXOffset() const
{ // MT 09/2002: nExtraOffsetX should become a member, instead of checking every time, // but I need an incompatible update for this... // #94095# Use extra offset only when edit has a border
tools::Long nExtraOffset = 0; if( ( GetStyle() & WB_BORDER ) || ( mbIsSubEdit && ( GetParent()->GetStyle() & WB_BORDER ) ) )
nExtraOffset = 2;
return nExtraOffset;
}
tools::Long Edit::ImplGetExtraYOffset() const
{
tools::Long nExtraOffset = 0;
ControlType eCtrlType = ImplGetNativeControlType(); if (eCtrlType != ControlType::EditboxNoBorder)
{ // add some space between text entry and border
nExtraOffset = 2;
} return nExtraOffset;
}
void Edit::ImplInvalidateOrRepaint()
{ if( IsPaintTransparent() )
{
Invalidate(); // FIXME: this is currently only on macOS if( ImplGetSVData()->maNWFData.mbNoFocusRects )
PaintImmediately();
} else
Invalidate();
}
if (!IsEnabled() || bPaintPlaceholderText)
rRenderContext.SetTextColor(rStyleSettings.GetDisableColor());
// Set background color of the normal text if (mbForceControlBackground && IsControlBackground())
{ // check if we need to set ControlBackground even in NWF case
rRenderContext.Push(vcl::PushFlags::FILLCOLOR | vcl::PushFlags::LINECOLOR);
rRenderContext.SetLineColor();
rRenderContext.SetFillColor(GetControlBackground());
rRenderContext.DrawRect(tools::Rectangle(aPos, Size(GetOutputSizePixel().Width() - 2 * mnXOffset, GetOutputSizePixel().Height())));
rRenderContext.Pop();
aPos.setX( mnXOffset + ImplGetExtraXOffset() ); if (bPaintPlaceholderText)
{
rRenderContext.DrawText(aPos, maPlaceholderText);
} elseif (!bDrawSelection && !mpIMEInfos)
{
rRenderContext.DrawText(aPos, aText, 0, nLen);
} else
{ // save graphics state
rRenderContext.Push(); // first calculate highlighted and non highlighted clip regions
vcl::Region aHighlightClipRegion;
vcl::Region aNormalClipRegion;
Selection aTmpSel(maSelection);
aTmpSel.Normalize(); // selection is highlighted for(sal_Int32 i = 0; i < nLen; ++i)
{
tools::Rectangle aRect(aPos, Size(10, nTH));
aRect.SetLeft( aDX[2 * i] + mnXOffset + ImplGetExtraXOffset() );
aRect.SetRight( aDX[2 * i + 1] + mnXOffset + ImplGetExtraXOffset() );
aRect.Normalize(); bool bHighlight = false; if (i >= aTmpSel.Min() && i < aTmpSel.Max())
bHighlight = true;
if (mpIMEInfos && mpIMEInfos->pAttribs &&
i >= mpIMEInfos->nPos && i < (mpIMEInfos->nPos+mpIMEInfos->nLen) &&
(mpIMEInfos->pAttribs[i - mpIMEInfos->nPos] & ExtTextInputAttr::Highlight))
{
bHighlight = true;
}
if (bHighlight)
aHighlightClipRegion.Union(aRect); else
aNormalClipRegion.Union(aRect);
} // draw normal text
Color aNormalTextColor = rRenderContext.GetTextColor();
rRenderContext.SetClipRegion(aNormalClipRegion);
if (IsPaintTransparent())
rRenderContext.SetTextFillColor(); else
{ // Set background color when part of the text is selected if (ImplUseNativeBorder(rRenderContext, GetStyle()))
{ if( mbForceControlBackground && IsControlBackground() )
rRenderContext.SetTextFillColor(GetControlBackground()); else
rRenderContext.SetTextFillColor();
} else
{
rRenderContext.SetTextFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor());
}
}
rRenderContext.DrawText(aPos, aText, 0, nLen);
// if IME info exists loop over portions and output different font attributes if (mpIMEInfos && mpIMEInfos->pAttribs)
{ for(int n = 0; n < 2; n++)
{
vcl::Region aRegion; if (n == 0)
{
rRenderContext.SetTextColor(aNormalTextColor); if (IsPaintTransparent())
rRenderContext.SetTextFillColor(); else
rRenderContext.SetTextFillColor(IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor());
aRegion = aNormalClipRegion;
} else
{
rRenderContext.SetTextColor(rStyleSettings.GetHighlightTextColor());
rRenderContext.SetTextFillColor(rStyleSettings.GetHighlightColor());
aRegion = aHighlightClipRegion;
}
// as below, if there's no selection, but we're in overwrite mode and not beyond // the end of the existing text then that's like a selection of 1 auto nSelectionLen = aSelection.Len(); if (!nSelectionLen && !mbInsertMode && aSelection.Max() < maText.getLength())
nSelectionLen = 1;
ImplTruncateToMaxLen( aNewText, nSelectionLen );
// take care of input-sequence-checking now if (bIsUserInput && !rStr.isEmpty())
{
SAL_WARN_IF( rStr.getLength() != 1, "vcl", "unexpected string length. User input is expected to provide 1 char only!" );
// determine if input-sequence-checking should be applied or not
css::uno::Reference<css::i18n::XBreakIterator> xBI = ImplGetBreakIterator(); bool bIsInputSequenceChecking = rStr.getLength() == 1 &&
officecfg::Office::Common::I18N::CTL::CTLFont::get() &&
officecfg::Office::Common::I18N::CTL::CTLSequenceChecking::get() &&
aSelection.Min() > 0 && /* first char needs not to be checked */
xBI.is() && css::i18n::ScriptType::COMPLEX == xBI->getScriptType( rStr, 0 );
// the text that needs to be checked is only the one // before the current cursor position const OUString aOldText( maText.subView(0, nTmpPos) );
OUString aTmpText( aOldText ); if (officecfg::Office::Common::I18N::CTL::CTLSequenceCheckingTypeAndReplace::get())
{
xISC->correctInputSequence( aTmpText, nTmpPos - 1, cChar, nCheckMode );
// find position of first character that has changed
sal_Int32 nOldLen = aOldText.getLength();
sal_Int32 nTmpLen = aTmpText.getLength(); const sal_Unicode *pOldTxt = aOldText.getStr(); const sal_Unicode *pTmpTxt = aTmpText.getStr();
sal_Int32 nChgPos = 0; while ( nChgPos < nOldLen && nChgPos < nTmpLen &&
pOldTxt[nChgPos] == pTmpTxt[nChgPos] )
++nChgPos;
// remove text from first pos to be changed to current pos
maText.remove( nChgPos, nTmpPos - nChgPos );
if (!aChgText.isEmpty())
{
aNewText = aChgText;
aSelection.Min() = nChgPos; // position for new text to be inserted
} else
aNewText.clear();
} else
{ // should the character be ignored (i.e. not get inserted) ? if (!xISC->checkInputSequence( aOldText, nTmpPos - 1, cChar, nCheckMode ))
aNewText.clear();
}
}
}
// at this point now we will insert the non-empty text 'normally' some lines below...
}
if ( !aNewText.isEmpty() )
maText.insert( aSelection.Min(), aNewText );
void Edit::ImplSetText( const OUString& rText, const Selection* pNewSelection )
{ // we delete text by "selecting" the old text completely then calling InsertText; this is flicker free if ( ( rText.getLength() > mnMaxTextLen ) ||
( std::u16string_view(rText) == std::u16string_view(maText)
&& (!pNewSelection || (*pNewSelection == maSelection)) ) ) return;
switch (pControl->GetType())
{ case WindowType::COMBOBOX: case WindowType::PATTERNBOX: case WindowType::NUMERICBOX: case WindowType::METRICBOX: case WindowType::CURRENCYBOX: case WindowType::DATEBOX: case WindowType::TIMEBOX: case WindowType::LONGCURRENCYBOX:
nCtrl = ControlType::Combobox; break;
case WindowType::MULTILINEEDIT: if ( GetWindow( GetWindowType::Border ) != this )
nCtrl = ControlType::MultilineEditbox; else
nCtrl = ControlType::EditboxNoBorder; break;
case WindowType::EDIT: case WindowType::PATTERNFIELD: case WindowType::METRICFIELD: case WindowType::CURRENCYFIELD: case WindowType::DATEFIELD: case WindowType::TIMEFIELD: case WindowType::SPINFIELD: case WindowType::FORMATTEDFIELD: if (pControl->GetStyle() & WB_SPIN)
nCtrl = ControlType::Spinbox; else
{ if (GetWindow(GetWindowType::Border) != this)
nCtrl = ControlType::Editbox; else
nCtrl = ControlType::EditboxNoBorder;
} break;
void Edit::ImplClearBackground(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRectangle, tools::Long nXStart, tools::Long nXEnd )
{ /* * note: at this point the cursor must be switched off already
*/
tools::Rectangle aRect(Point(), GetOutputSizePixel());
aRect.SetLeft( nXStart );
aRect.SetRight( nXEnd );
if( !(ImplUseNativeBorder(rRenderContext, GetStyle()) || IsPaintTransparent()))
rRenderContext.Erase(aRect); elseif (SupportsDoubleBuffering() && mbIsSubEdit)
{ // ImplPaintBorder() is a NOP, we have a native border, and this is a sub-edit of a control. // That means we have to draw the parent native widget to paint the edit area to clear our background.
vcl::PaintBufferGuard g(ImplGetWindowImpl()->mpFrameData, GetParent());
GetParent()->Paint(rRenderContext, rRectangle);
}
}
void Edit::ImplPaintBorder(vcl::RenderContext const & rRenderContext)
{ // this is not needed when double-buffering if (SupportsDoubleBuffering()) return;
if (!(ImplUseNativeBorder(rRenderContext, GetStyle()) || IsPaintTransparent())) return;
// draw the inner part by painting the whole control using its border window
vcl::Window* pBorder = GetWindow(GetWindowType::Border); if (pBorder == this)
{ // we have no border, use parent
vcl::Window* pControl = mbIsSubEdit ? GetParent() : this;
pBorder = pControl->GetWindow(GetWindowType::Border); if (pBorder == this)
pBorder = GetParent();
}
if (!pBorder) return;
// set proper clipping region to not overdraw the whole control
vcl::Region aClipRgn = GetPaintRegion(); if (!aClipRgn.IsNull())
{ // transform clipping region to border window's coordinate system if (IsRTLEnabled() != pBorder->IsRTLEnabled() && AllSettings::GetLayoutRTL())
{ // need to mirror in case border is not RTL but edit is (or vice versa)
// move offset of border window
Point aBorderOffs = pBorder->ScreenToOutputPixel(OutputToScreenPixel(Point()));
aClipRgn.Move(aBorderOffs.X(), aBorderOffs.Y());
} else
{ // normal case
Point aBorderOffs = pBorder->ScreenToOutputPixel(OutputToScreenPixel(Point()));
aClipRgn.Move(aBorderOffs.X(), aBorderOffs.Y());
}
// tdf#127588 - extend selection to the entire field or paste the text // from the clipboard to the current position if there is no selection if (mnMaxTextLen < EDIT_NOLIMIT && maSelection.Len() == 0)
{ const sal_Int32 aTextLen = aText.getLength(); if (aTextLen == mnMaxTextLen)
{
maSelection.Min() = 0;
maSelection.Max() = mnMaxTextLen;
} else
maSelection.Max() = std::min<sal_Int32>(maSelection.Min() + aTextLen, mnMaxTextLen);
}
Selection aSelection(maSelection);
aSelection.Normalize(); if (ImplTruncateToMaxLen(aText, aSelection.Len()))
ShowTruncationWarning(GetFrameWeld());
case KEY_LEFT: case KEY_RIGHT: case KEY_HOME: case KEY_END: case css::awt::Key::MOVE_WORD_FORWARD: case css::awt::Key::SELECT_WORD_FORWARD: case css::awt::Key::MOVE_WORD_BACKWARD: case css::awt::Key::SELECT_WORD_BACKWARD: case css::awt::Key::MOVE_TO_BEGIN_OF_LINE: case css::awt::Key::MOVE_TO_END_OF_LINE: case css::awt::Key::SELECT_TO_BEGIN_OF_LINE: case css::awt::Key::SELECT_TO_END_OF_LINE: case css::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH: case css::awt::Key::MOVE_TO_END_OF_PARAGRAPH: case css::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH: case css::awt::Key::SELECT_TO_END_OF_PARAGRAPH: case css::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT: case css::awt::Key::MOVE_TO_END_OF_DOCUMENT: case css::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT: case css::awt::Key::SELECT_TO_END_OF_DOCUMENT:
{ if ( !rKEvt.GetKeyCode().IsMod2() )
{
ImplClearLayoutData();
css::uno::Reference<css::i18n::XBreakIterator> xBI = ImplGetBreakIterator();
switch( nCode )
{ case css::awt::Key::MOVE_WORD_FORWARD:
bGoRight = bWord = true;break; case css::awt::Key::SELECT_WORD_FORWARD:
bGoRight = bSelect = bWord = true;break; case css::awt::Key::MOVE_WORD_BACKWARD:
bGoLeft = bWord = true;break; case css::awt::Key::SELECT_WORD_BACKWARD:
bGoLeft = bSelect = bWord = true;break; case css::awt::Key::SELECT_TO_BEGIN_OF_LINE: case css::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH: case css::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
bSelect = true;
[[fallthrough]]; case css::awt::Key::MOVE_TO_BEGIN_OF_LINE: case css::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH: case css::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
bGoHome = true;break; case css::awt::Key::SELECT_TO_END_OF_LINE: case css::awt::Key::SELECT_TO_END_OF_PARAGRAPH: case css::awt::Key::SELECT_TO_END_OF_DOCUMENT:
bSelect = true;
[[fallthrough]]; case css::awt::Key::MOVE_TO_END_OF_LINE: case css::awt::Key::MOVE_TO_END_OF_PARAGRAPH: case css::awt::Key::MOVE_TO_END_OF_DOCUMENT:
bGoEnd = true;break; default: break;
}
// tdf#164127 for an Edit in the UNO control property browser, above call to Control::GetFocus // can result in it getting disposed - return early in that case if (isDisposed()) return;
if ( IsReadOnly() )
{
bEnableCut = false;
bEnablePaste = false;
bEnableDelete = false;
bEnableSpecialChar = false;
} else
{ // only paste if text available in clipboard
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.