weld SmEditTextWindow
reuse the WeldEditAccessible a11y impl and remove the then unused
starmath equivalent.
Change-Id: I2dc1e0436ffcd0b295e204c21bfcd365dae08bff
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114044
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/svx/weldeditview.hxx b/include/svx/weldeditview.hxx
index d3697ad..1f388cb 100644
--- a/include/svx/weldeditview.hxx
+++ b/include/svx/weldeditview.hxx
@@ -40,6 +40,7 @@ public:
bool HasSelection() const;
void Delete();
void Cut();
void Copy();
void Paste();
@@ -47,6 +48,7 @@ public:
virtual ~WeldEditView() override;
protected:
bool m_bAcceptsTab;
std::unique_ptr<EditEngine> m_xEditEngine;
std::unique_ptr<EditView> m_xEditView;
rtl::Reference<WeldEditAccessible> m_xAccessible;
@@ -67,6 +69,11 @@ protected:
virtual void LoseFocus() override;
virtual void Resize() override;
// Whether Tab will result in entering a tab or not
bool GetAcceptsTab() const { return m_bAcceptsTab; }
void SetAcceptsTab(bool bAcceptsTab) { m_bAcceptsTab = bAcceptsTab; }
virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
virtual void EditViewInvalidate(const tools::Rectangle& rRect) override { Invalidate(rRect); }
diff --git a/qadevOOo/tests/java/mod/_sm/SmEditAccessible.java b/qadevOOo/tests/java/mod/_sm/SmEditAccessible.java
index 7b7a2c2..b32e7f4 100644
--- a/qadevOOo/tests/java/mod/_sm/SmEditAccessible.java
+++ b/qadevOOo/tests/java/mod/_sm/SmEditAccessible.java
@@ -86,7 +86,7 @@ public class SmEditAccessible extends TestCase {
XAccessible xRoot = AccessibilityTools.getAccessibleObject(xWindow);
oObj = AccessibilityTools.getAccessibleObjectForRole
(xRoot, AccessibleRole.TEXT_FRAME, "", "SmEditAccessible");
(xRoot, AccessibleRole.TEXT_FRAME, "", "WeldEditAccessible");
log.println("ImplementationName " + utils.getImplName(oObj));
AccessibilityTools.printAccessibleTree(log, xRoot, Param.getBool(util.PropertyName.DEBUG_IS_ACTIVE));
diff --git a/starmath/UIConfig_smath.mk b/starmath/UIConfig_smath.mk
index 5aa6e4c..c243742 100644
--- a/starmath/UIConfig_smath.mk
+++ b/starmath/UIConfig_smath.mk
@@ -32,6 +32,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/smath,\
starmath/uiconfig/smath/ui/alignmentdialog \
starmath/uiconfig/smath/ui/catalogdialog \
starmath/uiconfig/smath/ui/dockingelements \
starmath/uiconfig/smath/ui/editwindow \
starmath/uiconfig/smath/ui/fontdialog \
starmath/uiconfig/smath/ui/fontsizedialog \
starmath/uiconfig/smath/ui/fonttypedialog \
diff --git a/starmath/inc/edit.hxx b/starmath/inc/edit.hxx
index 279c068..3a77af0 100644
--- a/starmath/inc/edit.hxx
+++ b/starmath/inc/edit.hxx
@@ -19,7 +19,8 @@
#pragma once
#include <vcl/window.hxx>
#include <svx/weldeditview.hxx>
#include <vcl/InterimItemWindow.hxx>
#include <vcl/idle.hxx>
#include <vcl/transfer.hxx>
@@ -28,11 +29,8 @@ class SmViewShell;
class EditView;
class EditEngine;
class EditStatus;
class ScrollBar;
class ScrollBarBox;
class DataChangedEvent;
class SmCmdBoxWindow;
class SmEditAccessible;
class CommandEvent;
class Timer;
@@ -43,50 +41,64 @@ class ColorConfig;
void SmGetLeftSelectionPart(const ESelection& rSelection, sal_Int32& nPara, sal_uInt16& nPos);
class SmEditWindow final : public vcl::Window, public DropTargetHelper
{
rtl::Reference<SmEditAccessible> mxAccessible;
class SmEditWindow;
SmCmdBoxWindow& rCmdBox;
std::unique_ptr<EditView> pEditView;
VclPtr<ScrollBar> pHScrollBar;
VclPtr<ScrollBar> pVScrollBar;
VclPtr<ScrollBarBox> pScrollBox;
class SmEditTextWindow : public WeldEditView
{
private:
SmEditWindow& mrEditWindow;
Idle aModifyIdle;
Idle aCursorMoveIdle;
ESelection aOldSelection;
virtual void KeyInput(const KeyEvent& rKEvt) override;
virtual void Command(const CommandEvent& rCEvt) override;
ESelection aOldSelection;
DECL_LINK(ModifyTimerHdl, Timer*, void);
DECL_LINK(CursorMoveTimerHdl, Timer*, void);
DECL_LINK(EditStatusHdl, EditStatus&, void);
public:
SmEditTextWindow(SmEditWindow& rEditWindow);
virtual ~SmEditTextWindow() override;
virtual EditEngine* GetEditEngine() const override;
virtual void EditViewScrollStateChange() override;
virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
virtual bool KeyInput(const KeyEvent& rKeyEvt) override;
virtual bool MouseButtonUp(const MouseEvent& rEvt) override;
virtual bool Command(const CommandEvent& rCEvt) override;
virtual void GetFocus() override;
virtual void LoseFocus() override;
void SetText(const OUString& rText);
void InsertText(const OUString& rText);
void SelNextMark();
ESelection GetSelection() const;
void UserPossiblyChangedText();
void Flush();
void UpdateStatus(bool bSetDocModified);
void StartCursorMove();
};
class SmEditWindow final : public InterimItemWindow, public DropTargetHelper
{
SmCmdBoxWindow& rCmdBox;
std::unique_ptr<weld::ScrolledWindow> mxScrolledWindow;
std::unique_ptr<SmEditTextWindow> mxTextControl;
std::unique_ptr<weld::CustomWeld> mxTextControlWin;
virtual void ApplySettings(vcl::RenderContext&) override;
virtual void DataChanged(const DataChangedEvent&) override;
virtual void Resize() override;
virtual void MouseMove(const MouseEvent& rEvt) override;
virtual void MouseButtonUp(const MouseEvent& rEvt) override;
virtual void MouseButtonDown(const MouseEvent& rEvt) override;
virtual OUString GetSurroundingText() const override;
virtual Selection GetSurroundingTextSelection() const override;
virtual bool DeleteSurroundingText(const Selection& rSelection) override;
virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt) override;
virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt) override;
virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
DECL_LINK(EditStatusHdl, EditStatus&, void);
DECL_LINK(ScrollHdl, ScrollBar*, void);
DECL_LINK(ScrollHdl, weld::ScrolledWindow&, void);
void CreateEditView();
tools::Rectangle AdjustScrollBars();
void SetScrollBarRanges();
void InitScrollBars();
void InvalidateSlots();
void UpdateStatus(bool bSetDocModified);
void UserPossiblyChangedText();
public:
explicit SmEditWindow(SmCmdBoxWindow& rMyCmdBoxWin);
@@ -95,14 +107,14 @@ public:
SmDocShell* GetDoc();
SmViewShell* GetView();
EditView* GetEditView();
EditView* GetEditView() const;
EditEngine* GetEditEngine();
// Window
virtual void SetText(const OUString& rText) override;
virtual OUString GetText() const override;
virtual void GetFocus() override;
virtual void LoseFocus() override;
virtual void Resize() override;
virtual void Command(const CommandEvent& rCEvt) override;
ESelection GetSelection() const;
void SetSelection(const ESelection& rSel);
@@ -110,6 +122,9 @@ public:
bool IsEmpty() const;
bool IsSelected() const;
bool IsAllSelected() const;
void SetScrollBarRanges();
tools::Rectangle AdjustScrollBars();
void InvalidateSlots();
void Cut();
void Copy();
void Paste();
@@ -119,19 +134,11 @@ public:
void MarkError(const Point& rPos);
void SelNextMark();
void SelPrevMark();
static bool HasMark(const OUString& rText);
void Flush() override;
void DeleteEditView();
bool HandleWheelCommands(const CommandEvent& rCEvt);
static bool IsInlineEditEnabled();
void StartCursorMove();
// for Accessibility
virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
using Window::GetAccessible;
void HideScrollbars();
void ShowScrollbars();
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/accessibility.cxx b/starmath/source/accessibility.cxx
index d6e5988..bab8d77 100644
--- a/starmath/source/accessibility.cxx
+++ b/starmath/source/accessibility.cxx
@@ -737,1046 +737,4 @@ Sequence< OUString > SAL_CALL SmGraphicAccessible::getSupportedServiceNames()
};
}
SmEditSource::SmEditSource( SmEditAccessible &rAcc ) :
aViewFwd (rAcc),
aTextFwd (rAcc, *this),
aEditViewFwd(rAcc),
rEditAcc (rAcc)
{
}
SmEditSource::SmEditSource( const SmEditSource &rSrc ) :
SvxEditSource(),
aViewFwd (rSrc.rEditAcc),
aTextFwd (rSrc.rEditAcc, *this),
aEditViewFwd(rSrc.rEditAcc),
rEditAcc (rSrc.rEditAcc)
{
}
SmEditSource::~SmEditSource()
{
}
std::unique_ptr<SvxEditSource> SmEditSource::Clone() const
{
return std::unique_ptr<SvxEditSource>(new SmEditSource( *this ));
}
SvxTextForwarder* SmEditSource::GetTextForwarder()
{
return &aTextFwd;
}
SvxViewForwarder* SmEditSource::GetViewForwarder()
{
return &aViewFwd;
}
SvxEditViewForwarder* SmEditSource::GetEditViewForwarder( bool /*bCreate*/ )
{
return &aEditViewFwd;
}
void SmEditSource::UpdateData()
{
// would possibly only by needed if the XText interface is implemented
// and its text needs to be updated.
}
SfxBroadcaster & SmEditSource::GetBroadcaster() const
{
return const_cast<SmEditSource*>(this)->aBroadCaster;
}
SmViewForwarder::SmViewForwarder( SmEditAccessible &rAcc ) :
rEditAcc(rAcc)
{
}
SmViewForwarder::~SmViewForwarder()
{
}
bool SmViewForwarder::IsValid() const
{
return rEditAcc.GetEditView() != nullptr;
}
Point SmViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
{
EditView *pEditView = rEditAcc.GetEditView();
OutputDevice* pOutDev = pEditView ? &pEditView->GetOutputDevice() : nullptr;
if( pOutDev )
{
MapMode aMapMode(pOutDev->GetMapMode());
Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
MapMode(aMapMode.GetMapUnit())) );
aMapMode.SetOrigin(Point());
return pOutDev->LogicToPixel( aPoint, aMapMode );
}
return Point();
}
Point SmViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
{
EditView *pEditView = rEditAcc.GetEditView();
OutputDevice* pOutDev = pEditView ? &pEditView->GetOutputDevice() : nullptr;
if( pOutDev )
{
MapMode aMapMode(pOutDev->GetMapMode());
aMapMode.SetOrigin(Point());
Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
return OutputDevice::LogicToLogic( aPoint,
MapMode(aMapMode.GetMapUnit()),
rMapMode );
}
return Point();
}
SmTextForwarder::SmTextForwarder( SmEditAccessible& rAcc, SmEditSource & rSource) :
rEditAcc ( rAcc ),
rEditSource (rSource)
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->SetNotifyHdl( LINK(this, SmTextForwarder, NotifyHdl) );
}
SmTextForwarder::~SmTextForwarder()
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->SetNotifyHdl( Link<EENotify&,void>() );
}
IMPL_LINK(SmTextForwarder, NotifyHdl, EENotify&, rNotify, void)
{
::std::unique_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( &rNotify );
if (aHint)
rEditSource.GetBroadcaster().Broadcast(*aHint);
}
sal_Int32 SmTextForwarder::GetParagraphCount() const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetParagraphCount() : 0;
}
sal_Int32 SmTextForwarder::GetTextLen( sal_Int32 nParagraph ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetTextLen( nParagraph ) : 0;
}
OUString SmTextForwarder::GetText( const ESelection& rSel ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
OUString aRet;
if (pEditEngine)
aRet = pEditEngine->GetText( rSel );
return convertLineEnd(aRet, GetSystemLineEnd());
}
SfxItemSet SmTextForwarder::GetAttribs( const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
assert(pEditEngine && "EditEngine missing");
if( rSel.nStartPara == rSel.nEndPara )
{
GetAttribsFlags nFlags = GetAttribsFlags::NONE;
switch( nOnlyHardAttrib )
{
case EditEngineAttribs::All:
nFlags = GetAttribsFlags::ALL;
break;
case EditEngineAttribs::OnlyHard:
nFlags = GetAttribsFlags::CHARATTRIBS;
break;
default:
SAL_WARN("starmath", "unknown flags for SmTextForwarder::GetAttribs");
}
return pEditEngine->GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags );
}
else
{
return pEditEngine->GetAttribs( rSel, nOnlyHardAttrib );
}
}
SfxItemSet SmTextForwarder::GetParaAttribs( sal_Int32 nPara ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
assert(pEditEngine && "EditEngine missing");
SfxItemSet aSet( pEditEngine->GetParaAttribs( nPara ) );
sal_uInt16 nWhich = EE_PARA_START;
while( nWhich <= EE_PARA_END )
{
if( aSet.GetItemState( nWhich ) != SfxItemState::SET )
{
if( pEditEngine->HasParaAttrib( nPara, nWhich ) )
aSet.Put( pEditEngine->GetParaAttrib( nPara, nWhich ) );
}
nWhich++;
}
return aSet;
}
void SmTextForwarder::SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet )
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->SetParaAttribs( nPara, rSet );
}
SfxItemPool* SmTextForwarder::GetPool() const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetEmptyItemSet().GetPool() : nullptr;
}
void SmTextForwarder::RemoveAttribs( const ESelection& rSelection )
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->RemoveAttribs( rSelection, false/*bRemoveParaAttribs*/, 0 );
}
void SmTextForwarder::GetPortions( sal_Int32 nPara, std::vector<sal_Int32>& rList ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->GetPortions( nPara, rList );
}
void SmTextForwarder::QuickInsertText( const OUString& rText, const ESelection& rSel )
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->QuickInsertText( rText, rSel );
}
void SmTextForwarder::QuickInsertLineBreak( const ESelection& rSel )
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->QuickInsertLineBreak( rSel );
}
void SmTextForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->QuickInsertField( rFld, rSel );
}
void SmTextForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->QuickSetAttribs( rSet, rSel );
}
bool SmTextForwarder::IsValid() const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
// cannot reliably query EditEngine state
// while in the middle of an update
return pEditEngine && pEditEngine->GetUpdateMode();
}
OUString SmTextForwarder::CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, std::optional<Color>& rpTxtColor, std::optional<Color>& rpFldColor )
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->CalcFieldValue(rField, nPara, nPos, rpTxtColor, rpFldColor) : OUString();
}
void SmTextForwarder::FieldClicked(const SvxFieldItem&)
{
}
static SfxItemState GetSvxEditEngineItemState( EditEngine const & rEditEngine, const ESelection& rSel, sal_uInt16 nWhich )
{
std::vector<EECharAttrib> aAttribs;
const SfxPoolItem* pLastItem = nullptr;
SfxItemState eState = SfxItemState::DEFAULT;
// check all paragraphs inside the selection
for( sal_Int32 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ )
{
SfxItemState eParaState = SfxItemState::DEFAULT;
// calculate start and endpos for this paragraph
sal_Int32 nPos = 0;
if( rSel.nStartPara == nPara )
nPos = rSel.nStartPos;
sal_Int32 nEndPos = rSel.nEndPos;
if( rSel.nEndPara != nPara )
nEndPos = rEditEngine.GetTextLen( nPara );
// get list of char attribs
rEditEngine.GetCharAttribs( nPara, aAttribs );
bool bEmpty = true; // we found no item inside the selection of this paragraph
bool bGaps = false; // we found items but there are gaps between them
sal_Int32 nLastEnd = nPos;
const SfxPoolItem* pParaItem = nullptr;
for(const auto& rAttrib : aAttribs)
{
OSL_ENSURE( rAttrib.pAttr, "GetCharAttribs gives corrupt data" );
const bool bEmptyPortion = (rAttrib.nStart == rAttrib.nEnd);
if( (!bEmptyPortion && (rAttrib.nStart >= nEndPos)) || (bEmptyPortion && (rAttrib.nStart > nEndPos)) )
break; // break if we are already behind our selection
if( (!bEmptyPortion && (rAttrib.nEnd <= nPos)) || (bEmptyPortion && (rAttrib.nEnd < nPos)) )
continue; // or if the attribute ends before our selection
if( rAttrib.pAttr->Which() != nWhich )
continue; // skip if is not the searched item
// if we already found an item
if( pParaItem )
{
// ... and its different to this one than the state is don't care
if( *pParaItem != *(rAttrib.pAttr) )
return SfxItemState::DONTCARE;
}
else
{
pParaItem = rAttrib.pAttr;
}
if( bEmpty )
bEmpty = false;
if( !bGaps && rAttrib.nStart > nLastEnd )
bGaps = true;
nLastEnd = rAttrib.nEnd;
}
if( !bEmpty && !bGaps && nLastEnd < ( nEndPos - 1 ) )
bGaps = true;
if( bEmpty )
eParaState = SfxItemState::DEFAULT;
else if( bGaps )
eParaState = SfxItemState::DONTCARE;
else
eParaState = SfxItemState::SET;
// if we already found an item check if we found the same
if( pLastItem )
{
if( (pParaItem == nullptr) || (*pLastItem != *pParaItem) )
return SfxItemState::DONTCARE;
}
else
{
pLastItem = pParaItem;
eState = eParaState;
}
}
return eState;
}
SfxItemState SmTextForwarder::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const
{
SfxItemState nState = SfxItemState::DISABLED;
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
nState = GetSvxEditEngineItemState( *pEditEngine, rSel, nWhich );
return nState;
}
SfxItemState SmTextForwarder::GetItemState( sal_Int32 nPara, sal_uInt16 nWhich ) const
{
SfxItemState nState = SfxItemState::DISABLED;
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
const SfxItemSet& rSet = pEditEngine->GetParaAttribs( nPara );
nState = rSet.GetItemState( nWhich );
}
return nState;
}
LanguageType SmTextForwarder::GetLanguage( sal_Int32 nPara, sal_Int32 nIndex ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetLanguage(nPara, nIndex) : LANGUAGE_NONE;
}
sal_Int32 SmTextForwarder::GetFieldCount( sal_Int32 nPara ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetFieldCount(nPara) : 0;
}
EFieldInfo SmTextForwarder::GetFieldInfo( sal_Int32 nPara, sal_uInt16 nField ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetFieldInfo( nPara, nField ) : EFieldInfo();
}
EBulletInfo SmTextForwarder::GetBulletInfo( sal_Int32 /*nPara*/ ) const
{
return EBulletInfo();
}
tools::Rectangle SmTextForwarder::GetCharBounds( sal_Int32 nPara, sal_Int32 nIndex ) const
{
tools::Rectangle aRect(0,0,0,0);
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
// Handle virtual position one-past-the end of the string
if( nIndex >= pEditEngine->GetTextLen(nPara) )
{
if( nIndex )
aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex-1) );
aRect.Move( aRect.Right() - aRect.Left(), 0 );
aRect.SetSize( Size(1, pEditEngine->GetTextHeight()) );
}
else
{
aRect = pEditEngine->GetCharacterBounds( EPosition(nPara, nIndex) );
}
}
return aRect;
}
tools::Rectangle SmTextForwarder::GetParaBounds( sal_Int32 nPara ) const
{
tools::Rectangle aRect(0,0,0,0);
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
const Point aPnt = pEditEngine->GetDocPosTopLeft( nPara );
const sal_uLong nWidth = pEditEngine->CalcTextWidth();
const sal_uLong nHeight = pEditEngine->GetTextHeight( nPara );
aRect = tools::Rectangle( aPnt.X(), aPnt.Y(), aPnt.X() + nWidth, aPnt.Y() + nHeight );
}
return aRect;
}
MapMode SmTextForwarder::GetMapMode() const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetRefMapMode() : MapMode( MapUnit::Map100thMM );
}
OutputDevice* SmTextForwarder::GetRefDevice() const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetRefDevice() : nullptr;
}
bool SmTextForwarder::GetIndexAtPoint( const Point& rPos, sal_Int32& nPara, sal_Int32& nIndex ) const
{
bool bRes = false;
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
EPosition aDocPos = pEditEngine->FindDocPosition( rPos );
nPara = aDocPos.nPara;
nIndex = aDocPos.nIndex;
bRes = true;
}
return bRes;
}
bool SmTextForwarder::GetWordIndices( sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart, sal_Int32& nEnd ) const
{
bool bRes = false;
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
ESelection aRes = pEditEngine->GetWord( ESelection(nPara, nIndex, nPara, nIndex), css::i18n::WordType::DICTIONARY_WORD );
if( aRes.nStartPara == nPara &&
aRes.nStartPara == aRes.nEndPara )
{
nStart = aRes.nStartPos;
nEnd = aRes.nEndPos;
bRes = true;
}
}
return bRes;
}
bool SmTextForwarder::GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nPara, sal_Int32 nIndex, bool bInCell ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (!pEditEngine)
return false;
SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, *pEditEngine, nPara, nIndex, bInCell );
return true;
}
sal_Int32 SmTextForwarder::GetLineCount( sal_Int32 nPara ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetLineCount(nPara) : 0;
}
sal_Int32 SmTextForwarder::GetLineLen( sal_Int32 nPara, sal_Int32 nLine ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetLineLen(nPara, nLine) : 0;
}
void SmTextForwarder::GetLineBoundaries( /*out*/sal_Int32 &rStart, /*out*/sal_Int32 &rEnd, sal_Int32 nPara, sal_Int32 nLine ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
pEditEngine->GetLineBoundaries(rStart, rEnd, nPara, nLine);
else
rStart = rEnd = 0;
}
sal_Int32 SmTextForwarder::GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex ) const
{
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
return pEditEngine ? pEditEngine->GetLineNumberAtIndex(nPara, nIndex) : 0;
}
bool SmTextForwarder::QuickFormatDoc( bool /*bFull*/ )
{
bool bRes = false;
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
pEditEngine->QuickFormatDoc();
bRes = true;
}
return bRes;
}
sal_Int16 SmTextForwarder::GetDepth( sal_Int32 /*nPara*/ ) const
{
// math has no outliner...
return -1;
}
bool SmTextForwarder::SetDepth( sal_Int32 /*nPara*/, sal_Int16 nNewDepth )
{
// math has no outliner...
return -1 == nNewDepth; // is it the value from 'GetDepth' ?
}
bool SmTextForwarder::Delete( const ESelection& rSelection )
{
bool bRes = false;
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
pEditEngine->QuickDelete( rSelection );
pEditEngine->QuickFormatDoc();
bRes = true;
}
return bRes;
}
bool SmTextForwarder::InsertText( const OUString& rStr, const ESelection& rSelection )
{
bool bRes = false;
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
pEditEngine->QuickInsertText( rStr, rSelection );
pEditEngine->QuickFormatDoc();
bRes = true;
}
return bRes;
}
const SfxItemSet* SmTextForwarder::GetEmptyItemSetPtr()
{
const SfxItemSet *pItemSet = nullptr;
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
pItemSet = &pEditEngine->GetEmptyItemSet();
}
return pItemSet;
}
void SmTextForwarder::AppendParagraph()
{
// append an empty paragraph
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine)
{
sal_Int32 nParaCount = pEditEngine->GetParagraphCount();
pEditEngine->InsertParagraph( nParaCount, OUString() );
}
}
sal_Int32 SmTextForwarder::AppendTextPortion( sal_Int32 nPara, const OUString &rText, const SfxItemSet &rSet )
{
sal_uInt16 nRes = 0;
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine && nPara < pEditEngine->GetParagraphCount())
{
// append text
ESelection aSel( nPara, pEditEngine->GetTextLen( nPara ) );
pEditEngine->QuickInsertText( rText, aSel );
// set attributes for new appended text
nRes = aSel.nEndPos = pEditEngine->GetTextLen( nPara );
pEditEngine->QuickSetAttribs( rSet, aSel );
}
return nRes;
}
void SmTextForwarder::CopyText(const SvxTextForwarder& rSource)
{
const SmTextForwarder* pSourceForwarder = dynamic_cast< const SmTextForwarder* >( &rSource );
if( !pSourceForwarder )
return;
EditEngine* pSourceEditEngine = pSourceForwarder->rEditAcc.GetEditEngine();
EditEngine *pEditEngine = rEditAcc.GetEditEngine();
if (pEditEngine && pSourceEditEngine )
{
std::unique_ptr<EditTextObject> pNewTextObject = pSourceEditEngine->CreateTextObject();
pEditEngine->SetText( *pNewTextObject );
}
}
SmEditViewForwarder::SmEditViewForwarder( SmEditAccessible& rAcc ) :
rEditAcc( rAcc )
{
}
SmEditViewForwarder::~SmEditViewForwarder()
{
}
bool SmEditViewForwarder::IsValid() const
{
return rEditAcc.GetEditView() != nullptr;
}
Point SmEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
{
EditView *pEditView = rEditAcc.GetEditView();
OutputDevice* pOutDev = pEditView ? &pEditView->GetOutputDevice() : nullptr;
if( pOutDev )
{
MapMode aMapMode(pOutDev->GetMapMode());
Point aPoint( OutputDevice::LogicToLogic( rPoint, rMapMode,
MapMode(aMapMode.GetMapUnit())));
aMapMode.SetOrigin(Point());
return pOutDev->LogicToPixel( aPoint, aMapMode );
}
return Point();
}
Point SmEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
{
EditView *pEditView = rEditAcc.GetEditView();
OutputDevice* pOutDev = pEditView ? &pEditView->GetOutputDevice() : nullptr;
if( pOutDev )
{
MapMode aMapMode(pOutDev->GetMapMode());
aMapMode.SetOrigin(Point());
Point aPoint( pOutDev->PixelToLogic( rPoint, aMapMode ) );
return OutputDevice::LogicToLogic( aPoint,
MapMode(aMapMode.GetMapUnit()),
rMapMode );
}
return Point();
}
bool SmEditViewForwarder::GetSelection( ESelection& rSelection ) const
{
bool bRes = false;
EditView *pEditView = rEditAcc.GetEditView();
if (pEditView)
{
rSelection = pEditView->GetSelection();
bRes = true;
}
return bRes;
}
bool SmEditViewForwarder::SetSelection( const ESelection& rSelection )
{
bool bRes = false;
EditView *pEditView = rEditAcc.GetEditView();
if (pEditView)
{
pEditView->SetSelection( rSelection );
bRes = true;
}
return bRes;
}
bool SmEditViewForwarder::Copy()
{
bool bRes = false;
EditView *pEditView = rEditAcc.GetEditView();
if (pEditView)
{
pEditView->Copy();
bRes = true;
}
return bRes;
}
bool SmEditViewForwarder::Cut()
{
bool bRes = false;
EditView *pEditView = rEditAcc.GetEditView();
if (pEditView)
{
pEditView->Cut();
bRes = true;
}
return bRes;
}
bool SmEditViewForwarder::Paste()
{
bool bRes = false;
EditView *pEditView = rEditAcc.GetEditView();
if (pEditView)
{
pEditView->Paste();
bRes = true;
}
return bRes;
}
SmEditAccessible::SmEditAccessible( SmEditWindow *pEditWin ) :
aAccName (SmResId(STR_CMDBOXWINDOW)),
pTextHelper (),
pWin (pEditWin)
{
OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
}
SmEditAccessible::~SmEditAccessible()
{
}
::accessibility::AccessibleTextHelper *SmEditAccessible::GetTextHelper()
{
return pTextHelper.get();
}
void SmEditAccessible::Init()
{
OSL_ENSURE( pWin, "SmEditAccessible: window missing" );
if (pWin)
{
EditEngine *pEditEngine = pWin->GetEditEngine();
EditView *pEditView = pWin->GetEditView();
if (pEditEngine && pEditView)
{
assert(!pTextHelper);
pTextHelper.reset(new ::accessibility::AccessibleTextHelper( std::make_unique<SmEditSource>( *this ) ));
pTextHelper->SetEventSource( this );
}
}
}
void SmEditAccessible::ClearWin()
{
// remove handler before current object gets destroyed
// (avoid handler being called for already dead object)
EditEngine *pEditEngine = GetEditEngine();
if (pEditEngine)
pEditEngine->SetNotifyHdl( Link<EENotify&,void>() );
pWin = nullptr; // implicitly results in AccessibleStateType::DEFUNC set
//! make TextHelper implicitly release C++ references to some core objects
pTextHelper->SetEditSource( ::std::unique_ptr<SvxEditSource>() );
//! make TextHelper release references
//! (e.g. the one set by the 'SetEventSource' call)
pTextHelper->Dispose();
pTextHelper.reset();
}
// XAccessible
uno::Reference< XAccessibleContext > SAL_CALL SmEditAccessible::getAccessibleContext( )
{
return this;
}
// XAccessibleComponent
sal_Bool SAL_CALL SmEditAccessible::containsPoint( const awt::Point& aPoint )
{
//! the arguments coordinates are relative to the current window !
//! Thus the top left-point is (0, 0)
SolarMutexGuard aGuard;
if (!pWin)
throw RuntimeException();
Size aSz( pWin->GetSizePixel() );
return aPoint.X >= 0 && aPoint.Y >= 0 &&
aPoint.X < aSz.Width() && aPoint.Y < aSz.Height();
}
uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleAtPoint( const awt::Point& aPoint )
{
SolarMutexGuard aGuard;
if (!pTextHelper)
throw RuntimeException();
return pTextHelper->GetAt( aPoint );
}
awt::Rectangle SAL_CALL SmEditAccessible::getBounds( )
{
SolarMutexGuard aGuard;
if (!pWin)
throw RuntimeException();
OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
"mismatch of window parent and accessible parent" );
return lcl_GetBounds( pWin );
}
awt::Point SAL_CALL SmEditAccessible::getLocation( )
{
SolarMutexGuard aGuard;
if (!pWin)
throw RuntimeException();
OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
"mismatch of window parent and accessible parent" );
awt::Rectangle aRect( lcl_GetBounds( pWin ) );
return awt::Point( aRect.X, aRect.Y );
}
awt::Point SAL_CALL SmEditAccessible::getLocationOnScreen( )
{
SolarMutexGuard aGuard;
if (!pWin)
throw RuntimeException();
OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
"mismatch of window parent and accessible parent" );
return lcl_GetLocationOnScreen( pWin );
}
awt::Size SAL_CALL SmEditAccessible::getSize( )
{
SolarMutexGuard aGuard;
if (!pWin)
throw RuntimeException();
OSL_ENSURE(pWin->GetParent()->GetAccessible() == getAccessibleParent(),
"mismatch of window parent and accessible parent" );
Size aSz( pWin->GetSizePixel() );
#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
awt::Rectangle aRect( lcl_GetBounds( pWin ) );
Size aSz2( aRect.Width, aRect.Height );
assert(aSz == aSz2 && "mismatch in width");
#endif
return awt::Size( aSz.Width(), aSz.Height() );
}
void SAL_CALL SmEditAccessible::grabFocus( )
{
SolarMutexGuard aGuard;
if (!pWin)
throw RuntimeException();
pWin->GrabFocus();
}
sal_Int32 SAL_CALL SmEditAccessible::getForeground()
{
SolarMutexGuard aGuard;
if (!pWin)
throw RuntimeException();
return static_cast<sal_Int32>(pWin->GetTextColor());
}
sal_Int32 SAL_CALL SmEditAccessible::getBackground()
{
SolarMutexGuard aGuard;
if (!pWin)
throw RuntimeException();
Wallpaper aWall( pWin->GetDisplayBackground() );
Color nCol;
if (aWall.IsBitmap() || aWall.IsGradient())
nCol = pWin->GetSettings().GetStyleSettings().GetWindowColor();
else
nCol = aWall.GetColor();
return static_cast<sal_Int32>(nCol);
}
// XAccessibleContext
sal_Int32 SAL_CALL SmEditAccessible::getAccessibleChildCount( )
{
SolarMutexGuard aGuard;
if (!pTextHelper)
return 0;
return pTextHelper->GetChildCount();
}
uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleChild( sal_Int32 i )
{
SolarMutexGuard aGuard;
if (!pTextHelper)
throw RuntimeException();
return pTextHelper->GetChild( i );
}
uno::Reference< XAccessible > SAL_CALL SmEditAccessible::getAccessibleParent( )
{
SolarMutexGuard aGuard;
if (!pWin)
throw RuntimeException();
vcl::Window *pAccParent = pWin->GetAccessibleParentWindow();
OSL_ENSURE( pAccParent, "accessible parent missing" );
return pAccParent ? pAccParent->GetAccessible() : Reference< XAccessible >();
}
sal_Int32 SAL_CALL SmEditAccessible::getAccessibleIndexInParent( )
{
SolarMutexGuard aGuard;
sal_Int32 nIdx = -1;
vcl::Window *pAccParent = pWin ? pWin->GetAccessibleParentWindow() : nullptr;
if (pAccParent)
{
sal_uInt16 nCnt = pAccParent->GetAccessibleChildWindowCount();
for (sal_uInt16 i = 0; i < nCnt && nIdx == -1; ++i)
if (pAccParent->GetAccessibleChildWindow( i ) == pWin)
nIdx = i;
}
return nIdx;
}
sal_Int16 SAL_CALL SmEditAccessible::getAccessibleRole( )
{
return AccessibleRole::TEXT_FRAME;
}
OUString SAL_CALL SmEditAccessible::getAccessibleDescription( )
{
return OUString(); // empty as agreed with product-management
}
OUString SAL_CALL SmEditAccessible::getAccessibleName( )
{
SolarMutexGuard aGuard;
// same name as displayed by the window when not docked
return aAccName;
}
uno::Reference< XAccessibleRelationSet > SAL_CALL SmEditAccessible::getAccessibleRelationSet( )
{
Reference< XAccessibleRelationSet > xRelSet = new utl::AccessibleRelationSetHelper();
return xRelSet; // empty relation set
}
uno::Reference< XAccessibleStateSet > SAL_CALL SmEditAccessible::getAccessibleStateSet( )
{
SolarMutexGuard aGuard;
rtl::Reference<::utl::AccessibleStateSetHelper> pStateSet =
new ::utl::AccessibleStateSetHelper;
if (!pWin || !pTextHelper)
pStateSet->AddState( AccessibleStateType::DEFUNC );
else
{
pStateSet->AddState( AccessibleStateType::MULTI_LINE );
pStateSet->AddState( AccessibleStateType::ENABLED );
pStateSet->AddState( AccessibleStateType::EDITABLE );
pStateSet->AddState( AccessibleStateType::FOCUSABLE );
if (pWin->HasFocus())
pStateSet->AddState( AccessibleStateType::FOCUSED );
if (pWin->IsActive())
pStateSet->AddState( AccessibleStateType::ACTIVE );
if (pWin->IsVisible())
pStateSet->AddState( AccessibleStateType::SHOWING );
if (pWin->IsReallyVisible())
pStateSet->AddState( AccessibleStateType::VISIBLE );
if (COL_TRANSPARENT != pWin->GetBackground().GetColor())
pStateSet->AddState( AccessibleStateType::OPAQUE );
}
return pStateSet;
}
Locale SAL_CALL SmEditAccessible::getLocale( )
{
SolarMutexGuard aGuard;
// should be the document language...
// We use the language of the localized symbol names here.
return Application::GetSettings().GetUILanguageTag().getLocale();
}
// XAccessibleEventBroadcaster
void SAL_CALL SmEditAccessible::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
{
if (pTextHelper) // not disposing (about to destroy view shell)
pTextHelper->AddEventListener( xListener );
}
void SAL_CALL SmEditAccessible::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
{
if (pTextHelper) // not disposing (about to destroy view shell)
pTextHelper->RemoveEventListener( xListener );
}
OUString SAL_CALL SmEditAccessible::getImplementationName()
{
return "SmEditAccessible";
}
sal_Bool SAL_CALL SmEditAccessible::supportsService(
const OUString& rServiceName )
{
return cppu::supportsService(this, rServiceName);
}
Sequence< OUString > SAL_CALL SmEditAccessible::getSupportedServiceNames()
{
return {
"css::accessibility::Accessible",
"css::accessibility::AccessibleComponent",
"css::accessibility::AccessibleContext"
};
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/accessibility.hxx b/starmath/source/accessibility.hxx
index d93159b..817c4ca 100644
--- a/starmath/source/accessibility.hxx
+++ b/starmath/source/accessibility.hxx
@@ -135,223 +135,4 @@ public:
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
};
// classes and helper-classes used for accessibility in the command-window
class SmEditAccessible;
class SmEditSource;
class EditView;
class SvxFieldItem;
class SmViewForwarder :
public SvxViewForwarder
{
SmEditAccessible & rEditAcc;
SmViewForwarder( const SmViewForwarder & ) = delete;
SmViewForwarder & operator = ( const SmViewForwarder & ) = delete;
public:
explicit SmViewForwarder( SmEditAccessible &rAcc );
virtual ~SmViewForwarder() override;
virtual bool IsValid() const override;
virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const override;
virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const override;
};
class SmTextForwarder : /* analog to SvxEditEngineForwarder */
public SvxTextForwarder
{
SmEditAccessible & rEditAcc;
SmEditSource & rEditSource;
DECL_LINK( NotifyHdl, EENotify&, void );
SmTextForwarder( const SmTextForwarder & ) = delete;
SmTextForwarder & operator = ( const SmTextForwarder & ) = delete;
public:
SmTextForwarder( SmEditAccessible& rAcc, SmEditSource & rSource );
virtual ~SmTextForwarder() override;
virtual sal_Int32 GetParagraphCount() const override;
virtual sal_Int32 GetTextLen( sal_Int32 nParagraph ) const override;
virtual OUString GetText( const ESelection& rSel ) const override;
virtual SfxItemSet GetAttribs( const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib = EditEngineAttribs::All ) const override;
virtual SfxItemSet GetParaAttribs( sal_Int32 nPara ) const override;
virtual void SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet ) override;
virtual void RemoveAttribs( const ESelection& rSelection ) override;
virtual void GetPortions( sal_Int32 nPara, std::vector<sal_Int32>& rList ) const override;
virtual SfxItemState GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const override;
virtual SfxItemState GetItemState( sal_Int32 nPara, sal_uInt16 nWhich ) const override;
virtual void QuickInsertText( const OUString& rText, const ESelection& rSel ) override;
virtual void QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel ) override;
virtual void QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel ) override;
virtual void QuickInsertLineBreak( const ESelection& rSel ) override;
virtual SfxItemPool* GetPool() const override;
virtual OUString CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, std::optional<Color>& rpTxtColor, std::optional<Color>& rpFldColor ) override;
virtual void FieldClicked(const SvxFieldItem&) override;
virtual bool IsValid() const override;
virtual LanguageType GetLanguage( sal_Int32, sal_Int32 ) const override;
virtual sal_Int32 GetFieldCount( sal_Int32 nPara ) const override;
virtual EFieldInfo GetFieldInfo( sal_Int32 nPara, sal_uInt16 nField ) const override;
virtual EBulletInfo GetBulletInfo( sal_Int32 nPara ) const override;
virtual tools::Rectangle GetCharBounds( sal_Int32 nPara, sal_Int32 nIndex ) const override;
virtual tools::Rectangle GetParaBounds( sal_Int32 nPara ) const override;
virtual MapMode GetMapMode() const override;
virtual OutputDevice* GetRefDevice() const override;
virtual bool GetIndexAtPoint( const Point&, sal_Int32& nPara, sal_Int32& nIndex ) const override;
virtual bool GetWordIndices( sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart, sal_Int32& nEnd ) const override;
virtual bool GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nPara, sal_Int32 nIndex, bool bInCell = false ) const override;
virtual sal_Int32 GetLineCount( sal_Int32 nPara ) const override;
virtual sal_Int32 GetLineLen( sal_Int32 nPara, sal_Int32 nLine ) const override;
virtual void GetLineBoundaries( /*out*/sal_Int32 &rStart, /*out*/sal_Int32 &rEnd, sal_Int32 nParagraph, sal_Int32 nLine ) const override;
virtual sal_Int32 GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nLine ) const override;
virtual bool Delete( const ESelection& ) override;
virtual bool InsertText( const OUString&, const ESelection& ) override;
virtual bool QuickFormatDoc( bool bFull = false ) override;
virtual sal_Int16 GetDepth( sal_Int32 nPara ) const override;
virtual bool SetDepth( sal_Int32 nPara, sal_Int16 nNewDepth ) override;
virtual const SfxItemSet* GetEmptyItemSetPtr() override;
// implementation functions for XParagraphAppend and XTextPortionAppend
virtual void AppendParagraph() override;
virtual sal_Int32 AppendTextPortion( sal_Int32 nPara, const OUString &rText, const SfxItemSet &rSet ) override;
virtual void CopyText(const SvxTextForwarder& rSource) override;
};
class SmEditViewForwarder : /* analog to SvxEditEngineViewForwarder */
public SvxEditViewForwarder
{
SmEditAccessible& rEditAcc;
SmEditViewForwarder( const SmEditViewForwarder & ) = delete;
SmEditViewForwarder & operator = ( const SmEditViewForwarder & ) = delete;
public:
explicit SmEditViewForwarder( SmEditAccessible& rAcc );
virtual ~SmEditViewForwarder() override;
virtual bool IsValid() const override;
virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const override;
virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const override;
virtual bool GetSelection( ESelection& rSelection ) const override;
virtual bool SetSelection( const ESelection& rSelection ) override;
virtual bool Copy() override;
virtual bool Cut() override;
virtual bool Paste() override;
};
class SmEditSource :
public SvxEditSource
{
SfxBroadcaster aBroadCaster;
SmViewForwarder aViewFwd;
SmTextForwarder aTextFwd;
SmEditViewForwarder aEditViewFwd;
SmEditAccessible& rEditAcc;
SmEditSource( const SmEditSource &rSrc );
SmEditSource & operator = ( const SmEditSource & ) = delete;
public:
SmEditSource( SmEditAccessible &rAcc );
virtual ~SmEditSource() override;
virtual std::unique_ptr<SvxEditSource> Clone() const override;
virtual SvxTextForwarder* GetTextForwarder() override;
virtual SvxViewForwarder* GetViewForwarder() override;
virtual SvxEditViewForwarder* GetEditViewForwarder( bool bCreate = false ) override;
virtual void UpdateData() override;
virtual SfxBroadcaster& GetBroadcaster() const override;
};
typedef
cppu::WeakImplHelper
<
css::lang::XServiceInfo,
css::accessibility::XAccessible,
css::accessibility::XAccessibleComponent,
css::accessibility::XAccessibleContext,
css::accessibility::XAccessibleEventBroadcaster
>
SmEditAccessibleBaseClass;
class SmEditAccessible :
public SmEditAccessibleBaseClass
{
OUString aAccName;
std::unique_ptr<::accessibility::AccessibleTextHelper> pTextHelper;
VclPtr<SmEditWindow> pWin;
SmEditAccessible( const SmEditAccessible & ) = delete;
SmEditAccessible & operator = ( const SmEditAccessible & ) = delete;
public:
explicit SmEditAccessible( SmEditWindow *pEditWin );
virtual ~SmEditAccessible() override;
::accessibility::AccessibleTextHelper * GetTextHelper();
void Init();
void ClearWin(); // to be called when view is destroyed
//! access EditEngine and EditView via the functions in the respective window
//! pointers may be 0 (e.g. during reload)
EditEngine * GetEditEngine() { return pWin ? pWin->GetEditEngine() : nullptr; }
EditView * GetEditView() { return pWin ? pWin->GetEditView() : nullptr; }
// XAccessible
virtual css::uno::Reference< css::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) override;
// XAccessibleComponent
virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) override;
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ) override;
virtual css::awt::Rectangle SAL_CALL getBounds( ) override;
virtual css::awt::Point SAL_CALL getLocation( ) override;
virtual css::awt::Point SAL_CALL getLocationOnScreen( ) override;
virtual css::awt::Size SAL_CALL getSize( ) override;
virtual void SAL_CALL grabFocus( ) override;
virtual sal_Int32 SAL_CALL getForeground( ) override;
virtual sal_Int32 SAL_CALL getBackground( ) override;
// XAccessibleContext
virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) override;
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) override;
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) override;
virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) override;
virtual sal_Int16 SAL_CALL getAccessibleRole( ) override;
virtual OUString SAL_CALL getAccessibleDescription( ) override;
virtual OUString SAL_CALL getAccessibleName( ) override;
virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) override;
virtual css::uno::Reference< css::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) override;
virtual css::lang::Locale SAL_CALL getLocale( ) override;
// XAccessibleEventBroadcaster
virtual void SAL_CALL addAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override;
virtual void SAL_CALL removeAccessibleEventListener( const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener ) override;
// XServiceInfo
virtual OUString SAL_CALL getImplementationName( ) override;
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/source/edit.cxx b/starmath/source/edit.cxx
index d06c1db..555e4d8 100644
--- a/starmath/source/edit.cxx
+++ b/starmath/source/edit.cxx
@@ -22,7 +22,7 @@
#include <vcl/commandevent.hxx>
#include <vcl/event.hxx>
#include <vcl/scrbar.hxx>
#include <vcl/ptrstyle.hxx>
#include <vcl/settings.hxx>
#include <editeng/editview.hxx>
@@ -64,18 +64,68 @@ void SmGetLeftSelectionPart(const ESelection &rSel,
}
}
bool SmEditWindow::IsInlineEditEnabled()
SmEditTextWindow::SmEditTextWindow(SmEditWindow& rEditWindow)
: mrEditWindow(rEditWindow)
, aModifyIdle("SmEditWindow ModifyIdle")
, aCursorMoveIdle("SmEditWindow CursorMoveIdle")
{
return SmViewShell::IsInlineEditEnabled();
SetAcceptsTab(true);
aModifyIdle.SetInvokeHandler(LINK(this, SmEditTextWindow, ModifyTimerHdl));
aModifyIdle.SetPriority(TaskPriority::LOWEST);
if (!SmViewShell::IsInlineEditEnabled())
{
aCursorMoveIdle.SetInvokeHandler(LINK(this, SmEditTextWindow, CursorMoveTimerHdl));
aCursorMoveIdle.SetPriority(TaskPriority::LOWEST);
}
}
SmEditTextWindow::~SmEditTextWindow()
{
aModifyIdle.Stop();
StartCursorMove();
}
SmEditWindow::SmEditWindow( SmCmdBoxWindow &rMyCmdBoxWin ) :
Window (&rMyCmdBoxWin, WB_BORDER),
DropTargetHelper ( this ),
rCmdBox (rMyCmdBoxWin),
aModifyIdle ("SmEditWindow ModifyIdle"),
aCursorMoveIdle ("SmEditWindow CursorMoveIdle")
EditEngine* SmEditTextWindow::GetEditEngine() const
{
SmDocShell *pDoc = mrEditWindow.GetDoc();
assert(pDoc);
return &pDoc->GetEditEngine();
}
void SmEditTextWindow::EditViewScrollStateChange()
{
mrEditWindow.SetScrollBarRanges();
}
void SmEditTextWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea)
{
weld::CustomWidgetController::SetDrawingArea(pDrawingArea);
EnableRTL(false);
EditEngine* pEditEngine = GetEditEngine();
m_xEditView.reset(new EditView(pEditEngine, nullptr));
m_xEditView->setEditViewCallbacks(this);
pEditEngine->InsertView(m_xEditView.get());
m_xEditView->SetOutputArea(mrEditWindow.AdjustScrollBars());
pDrawingArea->set_cursor(PointerStyle::Text);
pEditEngine->SetStatusEventHdl(LINK(this, SmEditTextWindow, EditStatusHdl));
InitAccessible();
}
SmEditWindow::SmEditWindow(SmCmdBoxWindow &rMyCmdBoxWin)
: InterimItemWindow(&rMyCmdBoxWin, "modules/smath/ui/editwindow.ui", "EditWindow")
, DropTargetHelper(this)
, rCmdBox(rMyCmdBoxWin)
, mxScrolledWindow(m_xBuilder->weld_scrolled_window("scrolledwindow", true))
{
set_id("math_edit");
SetHelpId(HID_SMA_COMMAND_WIN_EDIT);
@@ -87,21 +137,16 @@ SmEditWindow::SmEditWindow( SmCmdBoxWindow &rMyCmdBoxWin ) :
// compare DataChanged
SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
aModifyIdle.SetInvokeHandler(LINK(this, SmEditWindow, ModifyTimerHdl));
aModifyIdle.SetPriority(TaskPriority::LOWEST);
mxScrolledWindow->connect_hadjustment_changed(LINK(this, SmEditWindow, ScrollHdl));
mxScrolledWindow->connect_vadjustment_changed(LINK(this, SmEditWindow, ScrollHdl));
if (!IsInlineEditEnabled())
{
aCursorMoveIdle.SetInvokeHandler(LINK(this, SmEditWindow, CursorMoveTimerHdl));
aCursorMoveIdle.SetPriority(TaskPriority::LOWEST);
}
CreateEditView();
// if not called explicitly the this edit window within the
// command window will just show an empty gray panel.
Show();
}
SmEditWindow::~SmEditWindow()
{
disposeOnce();
@@ -109,62 +154,17 @@ SmEditWindow::~SmEditWindow()
void SmEditWindow::dispose()
{
aModifyIdle.Stop();
DeleteEditView();
StartCursorMove();
// clean up of classes used for accessibility
// must be done before EditView (and thus EditEngine) is no longer
// available for those classes.
if (mxAccessible.is())
{
mxAccessible->ClearWin(); // make Accessible nonfunctional
mxAccessible.clear();
}
if (pEditView)
{
EditEngine *pEditEngine = pEditView->GetEditEngine();
if (pEditEngine)
{
pEditEngine->SetStatusEventHdl( Link<EditStatus&,void>() );
pEditEngine->RemoveView( pEditView.get() );
}
pEditView.reset();
}
pHScrollBar.disposeAndClear();
pVScrollBar.disposeAndClear();
pScrollBox.disposeAndClear();
mxScrolledWindow.reset();
DropTargetHelper::dispose();
vcl::Window::dispose();
InterimItemWindow::dispose();
}
OUString SmEditWindow::GetSurroundingText() const
void SmEditTextWindow::StartCursorMove()
{
if (pEditView)
return pEditView->GetSurroundingText();
return OUString();
}
Selection SmEditWindow::GetSurroundingTextSelection() const
{
if (pEditView)
return pEditView->GetSurroundingTextSelection();
return Selection(0, 0);
}
bool SmEditWindow::DeleteSurroundingText(const Selection& rSelection)
{
if (pEditView)
return pEditView->DeleteSurroundingText(rSelection);
return false;
}
void SmEditWindow::StartCursorMove()
{
if (!IsInlineEditEnabled())
if (!SmViewShell::IsInlineEditEnabled())
aCursorMoveIdle.Stop();
}
@@ -181,30 +181,22 @@ SmViewShell * SmEditWindow::GetView()
return rCmdBox.GetView();
}
SmDocShell * SmEditWindow::GetDoc()
{
SmViewShell *pView = rCmdBox.GetView();
return pView ? pView->GetDoc() : nullptr;
}
EditView * SmEditWindow::GetEditView()
EditView * SmEditWindow::GetEditView() const
{
return pEditView.get();
return mxTextControl ? mxTextControl->GetEditView() : nullptr;
}
EditEngine * SmEditWindow::GetEditEngine()
{
EditEngine *pEditEng = nullptr;
if (pEditView)
pEditEng = pEditView->GetEditEngine();
else
{
SmDocShell *pDoc = GetDoc();
if (pDoc)
pEditEng = &pDoc->GetEditEngine();
}
return pEditEng;
if (SmDocShell *pDoc = GetDoc())
return &pDoc->GetEditEngine();
return nullptr;
}
void SmEditWindow::ApplySettings(vcl::RenderContext& rRenderContext)
@@ -215,7 +207,7 @@ void SmEditWindow::ApplySettings(vcl::RenderContext& rRenderContext)
void SmEditWindow::DataChanged( const DataChangedEvent& rDCEvt )
{
Window::DataChanged( rDCEvt );
InterimItemWindow::DataChanged( rDCEvt );
if (!((rDCEvt.GetType() == DataChangedEventType::FONTS) ||
(rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
@@ -247,36 +239,33 @@ void SmEditWindow::DataChanged( const DataChangedEvent& rDCEvt )
AdjustScrollBars();
Resize();
}
Invalidate();
}
IMPL_LINK_NOARG( SmEditWindow, ModifyTimerHdl, Timer *, void )
IMPL_LINK_NOARG(SmEditTextWindow, ModifyTimerHdl, Timer *, void)
{
UpdateStatus(false);
aModifyIdle.Stop();
}
IMPL_LINK_NOARG(SmEditWindow, CursorMoveTimerHdl, Timer *, void)
IMPL_LINK_NOARG(SmEditTextWindow, CursorMoveTimerHdl, Timer *, void)
// every once in a while check cursor position (selection) of edit
// window and if it has changed (try to) set the formula-cursor
// according to that.
{
if (IsInlineEditEnabled())
if (SmViewShell::IsInlineEditEnabled())
return;
ESelection aNewSelection(GetSelection());
if (aNewSelection != aOldSelection)
{
SmViewShell *pView = rCmdBox.GetView();
if (pView)
if (SmViewShell *pViewSh = mrEditWindow.GetView())
{
// get row and column to look for
sal_Int32 nRow;
sal_uInt16 nCol;
SmGetLeftSelectionPart(aNewSelection, nRow, nCol);
pView->GetGraphicWindow().SetCursorPos(static_cast<sal_uInt16>(nRow), nCol);
pViewSh->GetGraphicWindow().SetCursorPos(static_cast<sal_uInt16>(nRow), nCol);
aOldSelection = aNewSelection;
}
}
@@ -285,10 +274,9 @@ IMPL_LINK_NOARG(SmEditWindow, CursorMoveTimerHdl, Timer *, void)
void SmEditWindow::Resize()
{
if (!pEditView)
CreateEditView();
InterimItemWindow::Resize();
if (pEditView)
if (EditView* pEditView = GetEditView())
{
// Resizes the edit engine to adjust to the size of the output area
const Size aSize( pEditView->GetOutputArea().GetSize() );
@@ -308,336 +296,271 @@ void SmEditWindow::Resize()
pEditView->SetVisArea(aVisArea);
pEditView->ShowCursor();
}
InitScrollBars();
SetScrollBarRanges();
}
Invalidate();
}
void SmEditWindow::MouseButtonUp(const MouseEvent &rEvt)
bool SmEditTextWindow::MouseButtonUp(const MouseEvent &rEvt)
{
if (pEditView)
pEditView->MouseButtonUp(rEvt);
else
Window::MouseButtonUp (rEvt);
if (!IsInlineEditEnabled())
bool bRet = WeldEditView::MouseButtonUp(rEvt);
if (!SmViewShell::IsInlineEditEnabled())
CursorMoveTimerHdl(&aCursorMoveIdle);
InvalidateSlots();
}
void SmEditWindow::MouseButtonDown(const MouseEvent &rEvt)
{
if (pEditView)
pEditView->MouseButtonDown(rEvt);
else
Window::MouseButtonDown (rEvt);
GrabFocus();
mrEditWindow.InvalidateSlots();
return bRet;
}
void SmEditWindow::Command(const CommandEvent& rCEvt)
{
//pass alt press/release to parent impl
if (rCEvt.GetCommand() == CommandEventId::ModKeyChange)
{
Window::Command(rCEvt);
return;
}
bool bForwardEvt = true;
if (rCEvt.GetCommand() == CommandEventId::ContextMenu)
{
GetParent()->ToTop();
Point aPoint = rCEvt.GetMousePosPixel();
SmViewShell* pViewSh = rCmdBox.GetView();
SmViewShell *pViewSh = GetView();
if (pViewSh)
pViewSh->GetViewFrame()->GetDispatcher()->ExecutePopup("edit", this, &aPoint);
bForwardEvt = false;
return;
}
else if (rCEvt.GetCommand() == CommandEventId::Wheel)
bForwardEvt = !HandleWheelCommands( rCEvt );
if (bForwardEvt)
{
if (pEditView)
{
if (pEditView->Command(rCEvt))
UserPossiblyChangedText();
}
else
Window::Command (rCEvt);
}
InterimItemWindow::Command(rCEvt);
}
bool SmEditWindow::HandleWheelCommands( const CommandEvent &rCEvt )
bool SmEditTextWindow::Command(const CommandEvent& rCEvt)
{
bool bCommandHandled = false; // true if the CommandEvent needs not
// to be passed on (because it has fully
// been taken care of).
// no zooming in Command window
const CommandWheelData* pWData = rCEvt.GetWheelData();
if (pWData)
if (pWData && CommandWheelMode::ZOOM == pWData->GetMode())
return true;
//pass alt press/release to parent impl
if (rCEvt.GetCommand() == CommandEventId::ModKeyChange)
return false;
if (rCEvt.GetCommand() == CommandEventId::ContextMenu)
{
if (CommandWheelMode::ZOOM == pWData->GetMode())
bCommandHandled = true; // no zooming in Command window
else
bCommandHandled = HandleScrollCommand( rCEvt, pHScrollBar.get(), pVScrollBar.get());
// purely for "ExecutePopup" taking a vcl::Window and
// we assume SmEditTextWindow 0,0 is at SmEditWindow 0,0
mrEditWindow.Command(rCEvt);
return false;
}
return bCommandHandled;
bool bConsumed = WeldEditView::Command(rCEvt);
if (bConsumed)
UserPossiblyChangedText();
return bConsumed;
}
void SmEditWindow::KeyInput(const KeyEvent& rKEvt)
bool SmEditTextWindow::KeyInput(const KeyEvent& rKEvt)
{
if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
{
bool bCallBase = true;
SfxViewShell* pViewShell = GetView();
SfxViewShell* pViewShell = mrEditWindow.GetView();
if ( dynamic_cast<const SmViewShell *>(pViewShell) )
{
// Terminate possible InPlace mode
bCallBase = !pViewShell->Escape();
}
if ( bCallBase )
Window::KeyInput( rKEvt );
return !bCallBase;
}
else
StartCursorMove();
bool autoClose = false;
EditView* pEditView = GetEditView();
ESelection aSelection = pEditView->GetSelection();
// as we don't support RTL in Math, we need to swap values from selection when they were done
// in RTL form
aSelection.Adjust();
OUString selected = pEditView->GetEditEngine()->GetText(aSelection);
// Check is auto close brackets/braces is disabled
SmModule *pMod = SM_MOD();
if (pMod && !pMod->GetConfig()->IsAutoCloseBrackets())
autoClose = false;
else if (selected.trim() == "<?>")
autoClose = true;
else if (selected.isEmpty() && !aSelection.HasRange())
{
StartCursorMove();
bool autoClose = false;
if (!pEditView)
CreateEditView();
ESelection aSelection = pEditView->GetSelection();
// as we don't support RTL in Math, we need to swap values from selection when they were done
// in RTL form
aSelection.Adjust();
OUString selected = pEditView->GetEditEngine()->GetText(aSelection);
// Check is auto close brackets/braces is disabled
SmModule *pMod = SM_MOD();
if (pMod && !pMod->GetConfig()->IsAutoCloseBrackets())
autoClose = false;
else if (selected.trim() == "<?>")
autoClose = true;
else if (selected.isEmpty() && !aSelection.HasRange())
selected = pEditView->GetEditEngine()->GetText(aSelection.nEndPara);
if (!selected.isEmpty())
{
selected = pEditView->GetEditEngine()->GetText(aSelection.nEndPara);
if (!selected.isEmpty())
sal_Int32 index = selected.indexOf("\n", aSelection.nEndPos);
if (index != -1)
{
sal_Int32 index = selected.indexOf("\n", aSelection.nEndPos);
if (index != -1)
{
selected = selected.copy(index, sal_Int32(aSelection.nEndPos-index));
if (selected.trim().isEmpty())
autoClose = true;
}
selected = selected.copy(index, sal_Int32(aSelection.nEndPos-index));
if (selected.trim().isEmpty())
autoClose = true;
}
else
{
sal_Int32 length = selected.getLength();
if (aSelection.nEndPos == length)
autoClose = true;
else
{
sal_Int32 length = selected.getLength();
if (aSelection.nEndPos == length)
selected = selected.copy(aSelection.nEndPos);
if (selected.trim().isEmpty())
autoClose = true;
else
{
selected = selected.copy(aSelection.nEndPos);
if (selected.trim().isEmpty())
autoClose = true;
}
}
}
else
autoClose = true;
}
if ( !pEditView->PostKeyEvent(rKEvt) )
{
SmViewShell *pView = GetView();
if ( pView && !pView->KeyInput(rKEvt) )
{
// F1 (help) leads to the destruction of this
Flush();
if ( aModifyIdle.IsActive() )
aModifyIdle.Stop();
Window::KeyInput(rKEvt);
}
else
{
// SFX has maybe called a slot of the view and thus (because of a hack in SFX)
// set the focus to the view
SmViewShell* pVShell = GetView();
if ( pVShell && pVShell->GetGraphicWindow().HasFocus() )
{
GrabFocus();
}
}
}
else
{
UserPossiblyChangedText();
}
// get the current char of the key event
sal_Unicode cCharCode = rKEvt.GetCharCode();
OUString sClose;
if (cCharCode == '{')
sClose = " }";
else if (cCharCode == '[')
sClose = " ]";
else if (cCharCode == '(')
sClose = " )";
// auto close the current character only when needed
if (!sClose.isEmpty() && autoClose)
{
pEditView->InsertText(sClose);
// position it at center of brackets
aSelection.nStartPos += 2;
aSelection.nEndPos = aSelection.nStartPos;
pEditView->SetSelection(aSelection);
}
InvalidateSlots();
autoClose = true;
}
bool bConsumed = WeldEditView::KeyInput(rKEvt);
if (!bConsumed)
{
SmViewShell *pView = mrEditWindow.GetView();
if ( pView && !pView->KeyInput(rKEvt) )
{
// F1 (help) leads to the destruction of this
Flush();
if ( aModifyIdle.IsActive() )
aModifyIdle.Stop();
}
else
{
// SFX has maybe called a slot of the view and thus (because of a hack in SFX)
// set the focus to the view
SmViewShell* pVShell = mrEditWindow.GetView();
if ( pVShell && pVShell->GetGraphicWindow().HasFocus() )
{
GrabFocus();
}
}
}
else
{
UserPossiblyChangedText();
}
// get the current char of the key event
sal_Unicode cCharCode = rKEvt.GetCharCode();
OUString sClose;
if (cCharCode == '{')
sClose = " }";
else if (cCharCode == '[')
sClose = " ]";
else if (cCharCode == '(')
sClose = " )";
// auto close the current character only when needed
if (!sClose.isEmpty() && autoClose)
{
pEditView->InsertText(sClose);
// position it at center of brackets
aSelection.nStartPos += 2;
aSelection.nEndPos = aSelection.nStartPos;
pEditView->SetSelection(aSelection);
}
mrEditWindow.InvalidateSlots();
return bConsumed;
}
void SmEditWindow::UserPossiblyChangedText()
void SmEditTextWindow::UserPossiblyChangedText()
{
// have doc-shell modified only for formula input/change and not
// cursor travelling and such things...
SmDocShell *pDocShell = GetDoc();
SmDocShell *pDocShell = mrEditWindow.GetDoc();
EditEngine *pEditEngine = GetEditEngine();
if (pDocShell && pEditEngine)
pDocShell->SetModified(pEditEngine->IsModified());
aModifyIdle.Start();
}
void SmEditWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
if (!pEditView)
CreateEditView();
pEditView->Paint(rRect, &rRenderContext);
}
void SmEditWindow::CreateEditView()
{
EditEngine *pEditEngine = GetEditEngine();
assert(!mxTextControl);
//! pEditEngine and pEditView may be 0.
EditEngine *pEditEngine = GetEditEngine();
//! pEditEngine may be 0.
//! For example when the program is used by the document-converter
if (pEditView || !pEditEngine)
if (!pEditEngine)
return;
pEditView.reset(new EditView(pEditEngine, this));
pEditEngine->InsertView( pEditView.get() );
if (!pVScrollBar)
pVScrollBar = VclPtr<ScrollBar>::Create(this, WinBits(WB_VSCROLL));
if (!pHScrollBar)
pHScrollBar = VclPtr<ScrollBar>::Create(this, WinBits(WB_HSCROLL));
if (!pScrollBox)
pScrollBox = VclPtr<ScrollBarBox>::Create(this);
pVScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl));
pHScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl));
pVScrollBar->EnableDrag();
pHScrollBar->EnableDrag();
pEditView->SetOutputArea(AdjustScrollBars());
ESelection eSelection;
pEditView->SetSelection(eSelection);
PaintImmediately();
pEditView->ShowCursor();
pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) );
SetPointer(pEditView->GetPointer());
mxTextControl.reset(new SmEditTextWindow(*this));
mxTextControlWin.reset(new weld::CustomWeld(*m_xBuilder, "editview", *mxTextControl));
InitControlBase(mxTextControl->GetDrawingArea());
SetScrollBarRanges();
}
IMPL_LINK_NOARG( SmEditWindow, EditStatusHdl, EditStatus&, void )
IMPL_LINK_NOARG(SmEditTextWindow, EditStatusHdl, EditStatus&, void)
{
if (pEditView)
Resize();
if (GetEditView())
mrEditWindow.Resize();
}
IMPL_LINK( SmEditWindow, ScrollHdl, ScrollBar *, /*pScrollBar*/, void )
IMPL_LINK(SmEditWindow, ScrollHdl, weld::ScrolledWindow&, rScrolledWindow, void)
{
OSL_ENSURE(pEditView, "EditView missing");
if (pEditView)
if (EditView* pEditView = GetEditView())
{
pEditView->SetVisArea(tools::Rectangle(Point(pHScrollBar->GetThumbPos(),
pVScrollBar->GetThumbPos()),
pEditView->GetVisArea().GetSize()));
pEditView->SetVisArea(tools::Rectangle(
Point(rScrolledWindow.hadjustment_get_value(),
rScrolledWindow.vadjustment_get_value()),
pEditView->GetVisArea().GetSize()));
pEditView->Invalidate();
}
}
tools::Rectangle SmEditWindow::AdjustScrollBars()
{
const Size aOut( GetOutputSizePixel() );
tools::Rectangle aRect( Point(), aOut );
tools::Rectangle aRect(Point(), GetOutputSizePixel());
if (pVScrollBar && pHScrollBar && pScrollBox)
if (mxScrolledWindow)
{
const tools::Long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize();
Point aPt( aRect.TopRight() ); aPt.AdjustX( -(nTmp -1) );
pVScrollBar->SetPosSizePixel( aPt, Size(nTmp, aOut.Height() - nTmp));
aPt = aRect.BottomLeft(); aPt.AdjustY( -(nTmp - 1) );
pHScrollBar->SetPosSizePixel( aPt, Size(aOut.Width() - nTmp, nTmp));
aPt.setX( pHScrollBar->GetSizePixel().Width() );
aPt.setY( pVScrollBar->GetSizePixel().Height() );
pScrollBox->SetPosSizePixel(aPt, Size(nTmp, nTmp ));
aRect.SetRight( aPt.X() - 2 );
aRect.SetBottom( aPt.Y() - 2 );
const auto nScrollSize = mxScrolledWindow->get_scroll_thickness();
const auto nMargin = nScrollSize + 2;
aRect.AdjustRight(-nMargin);
aRect.AdjustBottom(-nMargin);
}
return aRect;
}
void SmEditWindow::SetScrollBarRanges()
{
// Extra method, not InitScrollBars, since it's also being used for EditEngine events
EditEngine *pEditEngine = GetEditEngine();
if (pVScrollBar && pHScrollBar && pEditEngine && pEditView)
{
tools::Long nTmp = pEditEngine->GetTextHeight();
pVScrollBar->SetRange(Range(0, nTmp));
pVScrollBar->SetThumbPos(pEditView->GetVisArea().Top());
nTmp = pEditEngine->GetPaperSize().Width();
pHScrollBar->SetRange(Range(0,nTmp));
pHScrollBar->SetThumbPos(pEditView->GetVisArea().Left());
}
}
void SmEditWindow::InitScrollBars()
{
if (!(pVScrollBar && pHScrollBar && pScrollBox && pEditView))
if (!pEditEngine)
return;
if (!mxScrolledWindow)
return;
EditView* pEditView = GetEditView();
if (!pEditView)
return;
const Size aOut( pEditView->GetOutputArea().GetSize() );
pVScrollBar->SetVisibleSize(aOut.Height());
pVScrollBar->SetPageSize(aOut.Height() * 8 / 10);
pVScrollBar->SetLineSize(aOut.Height() * 2 / 10);
int nVUpper = pEditEngine->GetTextHeight();
int nHUpper = pEditEngine->GetPaperSize().Width();
int nVCurrentDocPos = pEditView->GetVisArea().Top();
int nHCurrentDocPos = pEditView->GetVisArea().Left();
const Size aOut(pEditView->GetOutputArea().GetSize());
int nVStepIncrement = aOut.Height() * 2 / 10;
int nHStepIncrement = SCROLL_LINE;
int nVPageIncrement = aOut.Height() * 8 / 10;
int nHPageIncrement = aOut.Width() * 8 / 10;
int nVPageSize = aOut.Height();
int nHPageSize = aOut.Width();
pHScrollBar->SetVisibleSize(aOut.Width());
pHScrollBar->SetPageSize(aOut.Width() * 8 / 10);
pHScrollBar->SetLineSize(SCROLL_LINE );
/* limit the page size to below nUpper because gtk's gtk_scrolled_window_start_deceleration has
effectively...
SetScrollBarRanges();
lower = gtk_adjustment_get_lower
upper = gtk_adjustment_get_upper - gtk_adjustment_get_page_size
pVScrollBar->Show();
pHScrollBar->Show();
pScrollBox->Show();
and requires that upper > lower or the deceleration animation never ends
*/
nVPageSize = std::min(nVPageSize, nVUpper);
nHPageSize = std::min(nHPageSize, nHUpper);
mxScrolledWindow->vadjustment_configure(nVCurrentDocPos, 0, nVUpper,
nVStepIncrement, nVPageIncrement, nVPageSize);
mxScrolledWindow->hadjustment_configure(nHCurrentDocPos, 0, nHUpper,
nHStepIncrement, nHPageIncrement, nHPageSize);
}
OUString SmEditWindow::GetText() const
{
OUString aText;
@@ -648,17 +571,21 @@ OUString SmEditWindow::GetText() const
return aText;
}
void SmEditWindow::SetText(const OUString& rText)
{
if (!mxTextControl)
return;
mxTextControl->SetText(rText);
}
void SmEditTextWindow::SetText(const OUString& rText)
{
EditEngine *pEditEngine = GetEditEngine();
OSL_ENSURE( pEditEngine, "EditEngine missing" );
if (!pEditEngine || pEditEngine->IsModified())
return;
if (!pEditView)
CreateEditView();
EditView* pEditView = GetEditView();
ESelection eSelection = pEditView->GetSelection();
pEditEngine->SetText(rText);
@@ -671,76 +598,54 @@ void SmEditWindow::SetText(const OUString& rText)
pEditView->SetSelection(eSelection);
}
void SmEditWindow::GetFocus()
void SmEditTextWindow::GetFocus()
{
Window::GetFocus();
WeldEditView::GetFocus();
if (mxAccessible.is())
{
// Note: will implicitly send the AccessibleStateType::FOCUSED event
::accessibility::AccessibleTextHelper *pHelper = mxAccessible->GetTextHelper();
if (pHelper)
pHelper->SetFocus();
}
if (!pEditView)
CreateEditView();
EditEngine *pEditEngine = GetEditEngine();
if (pEditEngine)
pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) );
pEditEngine->SetStatusEventHdl(LINK(this, SmEditTextWindow, EditStatusHdl));
//Let SmViewShell know we got focus
if(GetView() && IsInlineEditEnabled())
GetView()->SetInsertIntoEditWindow(true);
if (mrEditWindow.GetView() && SmViewShell::IsInlineEditEnabled())
mrEditWindow.GetView()->SetInsertIntoEditWindow(true);
}
void SmEditWindow::LoseFocus()
void SmEditTextWindow::LoseFocus()
{
EditEngine *pEditEngine = GetEditEngine();
if (pEditEngine)
pEditEngine->SetStatusEventHdl( Link<EditStatus&,void>() );
Window::LoseFocus();
if (mxAccessible.is())
{
// Note: will implicitly send the AccessibleStateType::FOCUSED event
::accessibility::AccessibleTextHelper *pHelper = mxAccessible->GetTextHelper();
if (pHelper)
pHelper->SetFocus(false);
}
WeldEditView::LoseFocus();
}
bool SmEditWindow::IsAllSelected() const
{
bool bRes = false;
EditEngine *pEditEngine = const_cast<SmEditWindow *>(this)->GetEditEngine();
OSL_ENSURE( pEditView, "NULL pointer" );
OSL_ENSURE( pEditEngine, "NULL pointer" );
if (pEditEngine && pEditView)
if (!pEditEngine)
return false;
EditView* pEditView = GetEditView();
if (!pEditView)
return false;
bool bRes = false;
ESelection eSelection( pEditView->GetSelection() );
sal_Int32 nParaCnt = pEditEngine->GetParagraphCount();
if (!(nParaCnt - 1))
{
ESelection eSelection( pEditView->GetSelection() );
sal_Int32 nParaCnt = pEditEngine->GetParagraphCount();
if (!(nParaCnt - 1))
{
sal_Int32 nTextLen = pEditEngine->GetText().getLength();
bRes = !eSelection.nStartPos && (eSelection.nEndPos == nTextLen - 1);
}
else
{
bRes = !eSelection.nStartPara && (eSelection.nEndPara == nParaCnt - 1);
}
sal_Int32 nTextLen = pEditEngine->GetText().getLength();
bRes = !eSelection.nStartPos && (eSelection.nEndPos == nTextLen - 1);
}
else
{
bRes = !eSelection.nStartPara && (eSelection.nEndPara == nParaCnt - 1);
}
return bRes;
}
void SmEditWindow::SelectAll()
{
OSL_ENSURE( pEditView, "NULL pointer" );
if (pEditView)
if (EditView* pEditView = GetEditView())
{
// ALL as last two parameters refers to the end of the text
pEditView->SetSelection( ESelection( 0, 0, EE_PARA_ALL, EE_TEXTPOS_ALL ) );
@@ -749,8 +654,7 @@ void SmEditWindow::SelectAll()
void SmEditWindow::MarkError(const Point &rPos)
{
OSL_ENSURE( pEditView, "EditView missing" );
if (pEditView)
if (EditView* pEditView = GetEditView())
{
const sal_uInt16 nCol = sal::static_int_cast< sal_uInt16 >(rPos.X());
const sal_uInt16 nRow = sal::static_int_cast< sal_uInt16 >(rPos.Y() - 1);
@@ -760,13 +664,21 @@ void SmEditWindow::MarkError(const Point &rPos)
}
}
// Makes selection to next <?> symbol
void SmEditWindow::SelNextMark()
{
if (!mxTextControl)
return;
mxTextControl->SelNextMark();
}
// Makes selection to next <?> symbol
void SmEditTextWindow::SelNextMark()
{
EditEngine *pEditEngine = GetEditEngine();
OSL_ENSURE( pEditView, "NULL pointer" );
OSL_ENSURE( pEditEngine, "NULL pointer" );
if (!pEditEngine || !pEditView)
if (!pEditEngine)
return;
EditView* pEditView = GetEditView();
if (!pEditView)
return;
ESelection eSelection = pEditView->GetSelection();
@@ -792,9 +704,10 @@ void SmEditWindow::SelNextMark()
void SmEditWindow::SelPrevMark()
{
EditEngine *pEditEngine = GetEditEngine();
OSL_ENSURE( pEditEngine, "NULL pointer" );
OSL_ENSURE( pEditView, "NULL pointer" );
if (!(pEditEngine && pEditView))
if (!pEditEngine)
return;
EditView* pEditView = GetEditView();
if (!pEditView)
return;
ESelection eSelection = pEditView->GetSelection();
@@ -814,18 +727,12 @@ void SmEditWindow::SelPrevMark()
pEditView->SetSelection(ESelection(nPara, nPos, nPara, nPos + 3));
}
bool SmEditWindow::HasMark(const OUString& rText)
// returns true iff 'rText' contains a mark
// returns true iff 'rText' contains a mark
static bool HasMark(const OUString& rText)
{
return rText.indexOf("<?>") != -1;
}
void SmEditWindow::MouseMove(const MouseEvent &rEvt)
{
if (pEditView)
pEditView->MouseMove(rEvt);
}
sal_Int8 SmEditWindow::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
{
return DND_ACTION_NONE;
@@ -838,19 +745,23 @@ sal_Int8 SmEditWindow::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ )
ESelection SmEditWindow::GetSelection() const
{
if (mxTextControl)
return mxTextControl->GetSelection();
return ESelection();
}
ESelection SmEditTextWindow::GetSelection() const
{
// pointer may be 0 when reloading a document and the old view
// was already destroyed
//(OSL_ENSURE( pEditView, "NULL pointer" );
ESelection eSel;
if (pEditView)
eSel = pEditView->GetSelection();
return eSel;
if (EditView* pEditView = GetEditView())
return pEditView->GetSelection();
return ESelection();
}
void SmEditWindow::SetSelection(const ESelection &rSel)
{
OSL_ENSURE( pEditView, "NULL pointer" );
if (pEditView)
if (EditView* pEditView = GetEditView())
pEditView->SetSelection(rSel);
InvalidateSlots();
}
@@ -864,59 +775,74 @@ bool SmEditWindow::IsEmpty() const
bool SmEditWindow::IsSelected() const
{
EditView* pEditView = GetEditView();
return pEditView && pEditView->HasSelection();
}
void SmEditWindow::UpdateStatus( bool bSetDocModified )
void SmEditTextWindow::UpdateStatus(bool bSetDocModified)
{
SmModule *pMod = SM_MOD();
if (pMod && pMod->GetConfig()->IsAutoRedraw())
Flush();
if ( bSetDocModified )
GetDoc()->SetModified();
mrEditWindow.GetDoc()->SetModified();
}
void SmEditWindow::Cut()
{
OSL_ENSURE( pEditView, "EditView missing" );
if (pEditView)
if (mxTextControl)
{
pEditView->Cut();
UpdateStatus(true);
mxTextControl->Cut();
mxTextControl->UpdateStatus(true);
}
}
void SmEditWindow::Copy()
{
OSL_ENSURE( pEditView, "EditView missing" );
if (pEditView)
pEditView->Copy();
if (mxTextControl)
mxTextControl->Copy();
}
void SmEditWindow::Paste()
{
OSL_ENSURE( pEditView, "EditView missing" );
if (pEditView)
if (mxTextControl)
{
pEditView->Paste();
UpdateStatus(true);
mxTextControl->Paste();
mxTextControl->UpdateStatus(true);
}
}
void SmEditWindow::Delete()
{
OSL_ENSURE( pEditView, "EditView missing" );
if (pEditView)
if (mxTextControl)
{
pEditView->DeleteSelected();
UpdateStatus(true);
mxTextControl->Delete();
mxTextControl->UpdateStatus(true);
}
}
void SmEditWindow::InsertText(const OUString& rText)
{
OSL_ENSURE( pEditView, "EditView missing" );
if (!mxTextControl)
return;
mxTextControl->InsertText(rText);
}
void SmEditWindow::HideScrollbars()
{
mxScrolledWindow->set_vpolicy(VclPolicyType::NEVER);
mxScrolledWindow->set_hpolicy(VclPolicyType::NEVER);
}
void SmEditWindow::ShowScrollbars()
{
mxScrolledWindow->set_vpolicy(VclPolicyType::ALWAYS);
mxScrolledWindow->set_hpolicy(VclPolicyType::ALWAYS);
}
void SmEditTextWindow::InsertText(const OUString& rText)
{
EditView* pEditView = GetEditView();
if (!pEditView)
return;
@@ -950,12 +876,10 @@ void SmEditWindow::InsertText(const OUString& rText)
This change "solves" the visual problem. But I don't think so
this is the best solution.
*/
pVScrollBar->Hide();
pHScrollBar->Hide();
mrEditWindow.HideScrollbars();
pEditView->InsertText(string);
AdjustScrollBars();
pVScrollBar->Show();
pHScrollBar->Show();
mrEditWindow.AdjustScrollBars();
mrEditWindow.ShowScrollbars();
// Remember start of the selection and move the cursor there afterwards.
aSelection.nEndPara = aSelection.nStartPara;
@@ -974,17 +898,17 @@ void SmEditWindow::InsertText(const OUString& rText)
aModifyIdle.Start();
StartCursorMove();
GrabFocus();
}
void SmEditWindow::Flush()
void SmEditTextWindow::Flush()
{
EditEngine *pEditEngine = GetEditEngine();
if (pEditEngine && pEditEngine->IsModified())
{
pEditEngine->ClearModifyFlag();
SmViewShell *pViewSh = rCmdBox.GetView();
if (pViewSh)
if (SmViewShell *pViewSh = mrEditWindow.GetView())
{
std::unique_ptr<SfxStringItem> pTextToFlush = std::make_unique<SfxStringItem>(SID_TEXT, GetText());
pViewSh->GetViewFrame()->GetDispatcher()->ExecuteList(
@@ -1001,26 +925,17 @@ void SmEditWindow::Flush()
void SmEditWindow::DeleteEditView()
{
if (pEditView)
if (EditView* pEditView = GetEditView())
{
std::unique_ptr<EditEngine> xEditEngine(pEditView->GetEditEngine());
if (xEditEngine)
if (EditEngine* pEditEngine = pEditView->GetEditEngine())
{
xEditEngine->SetStatusEventHdl( Link<EditStatus&,void>() );
xEditEngine->RemoveView( pEditView.get() );
pEditEngine->SetStatusEventHdl( Link<EditStatus&,void>() );
pEditEngine->RemoveView(pEditView);
}
pEditView.reset();
InitControlBase(nullptr);
mxTextControlWin.reset();
mxTextControl.reset();
}
}
uno::Reference< XAccessible > SmEditWindow::CreateAccessible()
{
if (!mxAccessible.is())
{
mxAccessible.set(new SmEditAccessible( this ));
mxAccessible->Init();
}
return mxAccessible;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/starmath/uiconfig/smath/ui/editwindow.ui b/starmath/uiconfig/smath/ui/editwindow.ui
new file mode 100644
index 0000000..ca7794f
--- /dev/null
+++ b/starmath/uiconfig/smath/ui/editwindow.ui
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface domain="sm">
<requires lib="gtk+" version="3.20"/>
<object class="GtkBox" id="EditWindow">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="spacing">6</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="border-width">0</property>
<property name="hscrollbar-policy">always</property>
<property name="vscrollbar-policy">always</property>
<property name="shadow-type">etched-out</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkDrawingArea" id="editview">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK</property>
<child internal-child="accessible">
<object class="AtkObject" id="editview-atkobject">
<property name="AtkObject::accessible-description" translatable="yes" context="headerfootercontent|extended_tip|textviewWND_LEFT">Enter the text to be displayed at the left side of the header or footer.</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</interface>
diff --git a/svx/source/dialog/weldeditview.cxx b/svx/source/dialog/weldeditview.cxx
index f08abb3..b558d9f3 100644
--- a/svx/source/dialog/weldeditview.cxx
+++ b/svx/source/dialog/weldeditview.cxx
@@ -67,6 +67,12 @@ bool WeldEditView::HasSelection() const
return pEditView && pEditView->HasSelection();
}
void WeldEditView::Delete()
{
if (EditView* pEditView = GetEditView())
pEditView->DeleteSelected();
}
void WeldEditView::Cut()
{
if (EditView* pEditView = GetEditView())
@@ -85,7 +91,10 @@ void WeldEditView::Paste()
pEditView->Paste();
}
WeldEditView::WeldEditView() {}
WeldEditView::WeldEditView()
: m_bAcceptsTab(false)
{
}
// tdf#127033 want to use UI font so override makeEditEngine to enable that
void WeldEditView::makeEditEngine()
@@ -203,7 +212,7 @@ bool WeldEditView::KeyInput(const KeyEvent& rKEvt)
sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
if (nKey == KEY_TAB)
if (nKey == KEY_TAB && !GetAcceptsTab())
{
return false;
}