Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/starmath/source/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 23 kB image not shown  

Quelle  edit.cxx   Sprache: C

 
/* -*- 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 .
 */


#include <config_wasm_strip.h>

#include <starmath.hrc>
#include <helpids.h>

#include <vcl/commandevent.hxx>
#include <vcl/event.hxx>
#include <vcl/ptrstyle.hxx>
#include <vcl/settings.hxx>

#include <editeng/editview.hxx>
#include <editeng/editeng.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/sfxsids.hrc>
#include <svl/stritem.hxx>
#include <svl/itemset.hxx>
#include <sfx2/viewfrm.hxx>
#include <osl/diagnose.h>
#include <o3tl/string_view.hxx>

#include <edit.hxx>
#include <smmod.hxx>
#include <view.hxx>
#include <document.hxx>
#include <cfgitem.hxx>
#include <smediteng.hxx>

using namespace com::sun::star;


void SmGetLeftSelectionPart(const ESelection &rSel,
                            sal_Int32 &nPara, sal_uInt16 &nPos)
    // returns paragraph number and position of the selections left part
{
    // compare start and end of selection and use the one that comes first
    if (rSel.start < rSel.end)
    {   nPara = rSel.start.nPara;
        nPos  = rSel.start.nIndex;
    }
    else
    {   nPara = rSel.end.nPara;
        nPos  = rSel.end.nIndex;
    }
}

SmEditTextWindow::SmEditTextWindow(SmEditWindow& rEditWindow)
    : mrEditWindow(rEditWindow)
    , aModifyIdle("SmEditWindow ModifyIdle")
    , aCursorMoveIdle("SmEditWindow CursorMoveIdle")
{
    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();
}

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);

    Color aBgColor = Application::GetSettings().GetStyleSettings().GetFieldColor();

    OutputDevice& rDevice = pDrawingArea->get_ref_device();
    rDevice.SetBackground(aBgColor);

    SetHelpId(HID_SMA_COMMAND_WIN_EDIT);

    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());

    m_xEditView->SetBackgroundColor(aBgColor);

    pDrawingArea->set_cursor(PointerStyle::Text);

    pEditEngine->SetStatusEventHdl(LINK(this, SmEditTextWindow, EditStatusHdl));

#if !ENABLE_WASM_STRIP_ACCESSIBILITY
    InitAccessible();
#endif

    //Apply zoom to smeditwindow text
    if(GetEditView())
        static_cast<SmEditEngine*>(GetEditEngine())->executeZoom(GetEditView());
}

SmEditWindow::SmEditWindow(SmCmdBoxWindow &rMyCmdBoxWin, weld::Builder& rBuilder)
    : rCmdBox(rMyCmdBoxWin)
    , mxScrolledWindow(rBuilder.weld_scrolled_window(u"scrolledwindow"_ustr, true))
{
    mxScrolledWindow->connect_vadjustment_changed(LINK(this, SmEditWindow, ScrollHdl));

    CreateEditView(rBuilder);
}

SmEditWindow::~SmEditWindow() COVERITY_NOEXCEPT_FALSE
{
    DeleteEditView();
    mxScrolledWindow.reset();
}

weld::Window* SmEditWindow::GetFrameWeld() const
{
    return rCmdBox.GetFrameWeld();
}

void SmEditTextWindow::StartCursorMove()
{
    if (!SmViewShell::IsInlineEditEnabled())
        aCursorMoveIdle.Stop();
}

void SmEditWindow::InvalidateSlots()
{
    GetView()->InvalidateSlots();
}

SmViewShell * SmEditWindow::GetView()
{
    return rCmdBox.GetView();
}

SmDocShell * SmEditWindow::GetDoc()
{
    SmViewShell *pView = rCmdBox.GetView();
    return pView ? pView->GetDoc() : nullptr;
}

EditView * SmEditWindow::GetEditView() const
{
    return mxTextControl ? mxTextControl->GetEditView() : nullptr;
}

EditEngine * SmEditWindow::GetEditEngine()
{
    if (SmDocShell *pDoc = GetDoc())
        return &pDoc->GetEditEngine();
    return nullptr;
}

void SmEditTextWindow::StyleUpdated()
{
    WeldEditView::StyleUpdated();
    EditEngine *pEditEngine = GetEditEngine();
    SmDocShell *pDoc = mrEditWindow.GetDoc();

    if (pEditEngine && pDoc)
    {
        //!
        //! see also SmDocShell::GetEditEngine() !
        //!
        const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();

        pDoc->UpdateEditEngineDefaultFonts();
        pEditEngine->SetBackgroundColor(rStyleSettings.GetFieldColor());
        pEditEngine->SetDefTab(sal_uInt16(GetTextWidth(u"XXXX"_ustr)));

        // forces new settings to be used
        // unfortunately this resets the whole edit engine
        // thus we need to save at least the text
        OUString aTxt( pEditEngine->GetText() );
        pEditEngine->Clear();   //incorrect font size
        pEditEngine->SetText( aTxt );

        Resize();
    }

    // Apply zoom to smeditwindow text
    static_cast<SmEditEngine*>(GetEditEngine())->executeZoom(GetEditView());
}

IMPL_LINK_NOARG(SmEditTextWindow, ModifyTimerHdl, Timer *, void)
{
    UpdateStatus(false);
    aModifyIdle.Stop();
}

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 (SmViewShell::IsInlineEditEnabled())
        return;

    ESelection aNewSelection(GetSelection());

    if (aNewSelection != aOldSelection)
    {
        if (SmViewShell *pViewSh = mrEditWindow.GetView())
        {
            // get row and column to look for
            sal_Int32  nRow;
            sal_uInt16 nCol;
            SmGetLeftSelectionPart(aNewSelection, nRow, nCol);
            pViewSh->GetGraphicWidget().SetCursorPos(static_cast<sal_uInt16>(nRow), nCol);
            aOldSelection = aNewSelection;
        }
    }
    aCursorMoveIdle.Stop();
}

bool SmEditTextWindow::MouseButtonUp(const MouseEvent &rEvt)
{
    bool bRet = WeldEditView::MouseButtonUp(rEvt);
    if (!SmViewShell::IsInlineEditEnabled())
        CursorMoveTimerHdl(&aCursorMoveIdle);
    mrEditWindow.InvalidateSlots();
    return bRet;
}

bool SmEditTextWindow::Command(const CommandEvent& rCEvt)
{
    // no zooming in Command window
    const CommandWheelData* pWData = rCEvt.GetWheelData();
    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)
    {
        ReleaseMouse();
        SmCmdBoxWindow& rCmdBox = mrEditWindow.GetCmdBox();
        rCmdBox.ShowContextMenu(rCmdBox.WidgetToWindowPos(*GetDrawingArea(), rCEvt.GetMousePosPixel()));
        GrabFocus();
        return true;
    }

    bool bConsumed = WeldEditView::Command(rCEvt);
    if (bConsumed)
        UserPossiblyChangedText();
    return bConsumed;
}

bool SmEditTextWindow::KeyInput(const KeyEvent& rKEvt)
{
    if (rKEvt.GetKeyCode().GetCode() == KEY_F1)
    {
        mrEditWindow.GetView()->StartMainHelp();
        return true;
    }

    if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
    {
        bool bCallBase = true;
        SfxViewShell* pViewShell = mrEditWindow.GetView();
        if ( dynamic_cast<const SmViewShell *>(pViewShell) )
        {
            // Terminate possible InPlace mode
            bCallBase = !pViewShell->Escape();
        }
        return !bCallBase;
    }

    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 = SmModule::get();
    if (pMod && !pMod->GetConfig()->IsAutoCloseBrackets())
        autoClose = false;
    else if (o3tl::trim(selected) == u"")
        autoClose = true;
    else if (selected.isEmpty() && !aSelection.HasRange())
    {
        selected = pEditView->getEditEngine().GetText(aSelection.end.nPara);
        if (!selected.isEmpty())
        {
            sal_Int32 index = selected.indexOf("\n", aSelection.end.nIndex);
            if (index != -1)
            {
                selected = selected.copy(index, sal_Int32(aSelection.end.nIndex-index));
                if (o3tl::trim(selected).empty())
                    autoClose = true;
            }
            else
            {
                sal_Int32 length = selected.getLength();
                if (aSelection.end.nIndex == length)
                    autoClose = true;
                else
                {
                    selected = selected.copy(aSelection.end.nIndex);
                    if (o3tl::trim(selected).empty())
                        autoClose = true;
                }
            }
        }
        else
            autoClose = true;
    }

    bool bConsumed = WeldEditView::KeyInput(rKEvt);
    if (!bConsumed)
    {
        SmViewShell *pView = mrEditWindow.GetView();
        if (pView)
            bConsumed = pView->KeyInput(rKEvt);
        if (pView && !bConsumed)
        {
            // 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->GetGraphicWidget().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.start.nIndex += 2;
        aSelection.end.nIndex = aSelection.start.nIndex;
        pEditView->SetSelection(aSelection);
    }

    mrEditWindow.InvalidateSlots();
    return bConsumed;
}

void SmEditTextWindow::UserPossiblyChangedText()
{
    // have doc-shell modified only for formula input/change and not
    // cursor travelling and such things...
    SmDocShell *pDocShell = mrEditWindow.GetDoc();
    EditEngine *pEditEngine = GetEditEngine();
    if (pDocShell && pEditEngine && pEditEngine->IsModified())
        pDocShell->SetModified(true);
    aModifyIdle.Start();
}

void SmEditWindow::CreateEditView(weld::Builder& rBuilder)
{
    assert(!mxTextControl);

    EditEngine *pEditEngine = GetEditEngine();
    //! pEditEngine may be 0.
    //! For example when the program is used by the document-converter
    if (!pEditEngine)
        return;

    mxTextControl.reset(new SmEditTextWindow(*this));
    mxTextControlWin.reset(new weld::CustomWeld(rBuilder, u"editview"_ustr, *mxTextControl));

    SetScrollBarRanges();
}

IMPL_LINK_NOARG(SmEditTextWindow, EditStatusHdl, EditStatus&, void)
{
    Resize();
}

IMPL_LINK(SmEditWindow, ScrollHdl, weld::ScrolledWindow&, rScrolledWindow, void)
{
    if (EditView* pEditView = GetEditView())
    {
        pEditView->SetVisArea(tools::Rectangle(
                    Point(0,
                          rScrolledWindow.vadjustment_get_value()),
                    pEditView->GetVisArea().GetSize()));
        pEditView->Invalidate();
    }
}

tools::Rectangle SmEditWindow::AdjustScrollBars()
{
    tools::Rectangle aRect(Point(), rCmdBox.GetOutputSizePixel());

    if (mxScrolledWindow)
    {
        const auto nScrollSize = mxScrolledWindow->get_scroll_thickness();
        const auto nMargin = nScrollSize + 2;
        aRect.AdjustRight(-nMargin);
        aRect.AdjustBottom(-nMargin);
    }

    return aRect;
}

void SmEditWindow::SetScrollBarRanges()
{
    EditEngine *pEditEngine = GetEditEngine();
    if (!pEditEngine)
        return;
    if (!mxScrolledWindow)
        return;
    EditView* pEditView = GetEditView();
    if (!pEditView)
        return;

    int nVUpper = pEditEngine->GetTextHeight();
    int nVCurrentDocPos = pEditView->GetVisArea().Top();
    const Size aOut(pEditView->GetOutputArea().GetSize());
    int nVStepIncrement = aOut.Height() * 2 / 10;
    int nVPageIncrement = aOut.Height() * 8 / 10;
    int nVPageSize = aOut.Height();

    /* limit the page size to below nUpper because gtk's gtk_scrolled_window_start_deceleration has
       effectively...

       lower = gtk_adjustment_get_lower
       upper = gtk_adjustment_get_upper - gtk_adjustment_get_page_size

       and requires that upper > lower or the deceleration animation never ends
    */

    nVPageSize = std::min(nVPageSize, nVUpper);

    mxScrolledWindow->vadjustment_configure(nVCurrentDocPos, 0, nVUpper,
                                            nVStepIncrement, nVPageIncrement, nVPageSize);
}

OUString SmEditWindow::GetText() const
{
    OUString aText;
    EditEngine *pEditEngine = const_cast< SmEditWindow* >(this)->GetEditEngine();
    OSL_ENSURE( pEditEngine, "EditEngine missing" );
    if (pEditEngine)
        aText = pEditEngine->GetText();
    return aText;
}

void SmEditWindow::SetText(const OUString& rText)
{
    if (!mxTextControl)
        return;
    mxTextControl->SetText(rText);
}

void SmEditWindow::Flush()
{
    if (!mxTextControl)
        return;
    mxTextControl->Flush();
}

void SmEditWindow::GrabFocus()
{
    if (!mxTextControl)
        return;
    mxTextControl->GrabFocus();
}

void SmEditTextWindow::SetText(const OUString& rText)
{
    EditEngine *pEditEngine = GetEditEngine();
    OSL_ENSURE( pEditEngine, "EditEngine missing" );
    if (!pEditEngine || pEditEngine->IsModified())
        return;

    EditView* pEditView = GetEditView();
    ESelection eSelection = pEditView->GetSelection();

    pEditEngine->SetText(rText);
    pEditEngine->ClearModifyFlag();

    // Restarting the timer here, prevents calling the handlers for other (currently inactive)
    // math tasks
    aModifyIdle.Start();

    // Apply zoom to smeditwindow text
    static_cast<SmEditEngine&>(pEditView->getEditEngine()).executeZoom(pEditView);
    pEditView->SetSelection(eSelection);
}

void SmEditTextWindow::GetFocus()
{
    WeldEditView::GetFocus();

    EditEngine *pEditEngine = GetEditEngine();
    if (pEditEngine)
        pEditEngine->SetStatusEventHdl(LINK(this, SmEditTextWindow, EditStatusHdl));
}

void SmEditTextWindow::LoseFocus()
{
    EditEngine *pEditEngine = GetEditEngine();
    if (pEditEngine)
        pEditEngine->SetStatusEventHdl( Link<EditStatus&,void>() );

    WeldEditView::LoseFocus();
}

bool SmEditWindow::IsAllSelected() const
{
    EditEngine *pEditEngine = const_cast<SmEditWindow *>(this)->GetEditEngine();
    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))
    {
        sal_Int32 nTextLen = pEditEngine->GetText().getLength();
        bRes = !eSelection.start.nIndex && (eSelection.end.nIndex == nTextLen - 1);
    }
    else
    {
        bRes = !eSelection.start.nPara && (eSelection.end.nPara == nParaCnt - 1);
    }
    return bRes;
}

void SmEditWindow::SelectAll()
{
    if (EditView* pEditView = GetEditView())
    {
        pEditView->SetSelection(ESelection::All());
    }
}

void SmEditWindow::MarkError(const Point &rPos)
{
    if (EditView* pEditView = GetEditView())
    {
        const sal_Int32 nCol = rPos.X();
        const sal_Int32 nRow = rPos.Y() - 1;

        pEditView->SetSelection(ESelection(nRow, nCol - 1, nRow, nCol));
        GrabFocus();
    }
}

void SmEditWindow::SelNextMark()
{
    if (!mxTextControl)
        return;
    mxTextControl->SelNextMark();
}

// Makes selection to next <?> symbol
void SmEditTextWindow::SelNextMark()
{
    EditEngine *pEditEngine = GetEditEngine();
    if (!pEditEngine)
        return;
    EditView* pEditView = GetEditView();
    if (!pEditView)
        return;

    ESelection eSelection = pEditView->GetSelection();
    sal_Int32 nPos = eSelection.end.nIndex;
    sal_Int32 nCounts = pEditEngine->GetParagraphCount();

    while (eSelection.end.nPara < nCounts)
    {
        OUString aText = pEditEngine->GetText(eSelection.end.nPara);
        nPos = aText.indexOf("", nPos);
        if (nPos != -1)
        {
            pEditView->SetSelection(ESelection(
                eSelection.end.nPara, nPos, eSelection.end.nPara, nPos + 3));
            break;
        }

        nPos = 0;
        eSelection.end.nPara++;
    }
}

void SmEditWindow::SelPrevMark()
{
    EditEngine *pEditEngine = GetEditEngine();
    if (!pEditEngine)
        return;
    EditView* pEditView = GetEditView();
    if (!pEditView)
        return;

    ESelection eSelection = pEditView->GetSelection();
    sal_Int32 nPara = eSelection.start.nPara;
    sal_Int32 nMax = eSelection.start.nIndex;
    OUString aText(pEditEngine->GetText(nPara));
    static constexpr OUStringLiteral aMark(u"");
    sal_Int32 nPos;

    while ( (nPos = aText.lastIndexOf(aMark, nMax)) < 0 )
    {
        if (--nPara < 0)
            return;
        aText = pEditEngine->GetText(nPara);
        nMax = aText.getLength();
    }
    pEditView->SetSelection(ESelection(nPara, nPos, nPara, nPos + 3));
}

// returns true iff 'rText' contains a mark
static bool HasMark(std::u16string_view rText)
{
    return rText.find(u"") != std::u16string_view::npos;
}

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
    if (EditView* pEditView = GetEditView())
        return pEditView->GetSelection();
    return ESelection();
}

void SmEditWindow::SetSelection(const ESelection &rSel)
{
    if (EditView* pEditView = GetEditView())
        pEditView->SetSelection(rSel);
    InvalidateSlots();
}

bool SmEditWindow::IsEmpty() const
{
    EditEngine *pEditEngine = const_cast<SmEditWindow *>(this)->GetEditEngine();
    bool bEmpty = ( pEditEngine && pEditEngine->GetTextLen() == 0 );
    return bEmpty;
}

bool SmEditWindow::IsSelected() const
{
    EditView* pEditView = GetEditView();
    return pEditView && pEditView->HasSelection();
}

void SmEditTextWindow::UpdateStatus(bool bSetDocModified)
{
    if (SmModule* pMod = SmModule::get())
        if (pMod->GetConfig()->IsAutoRedraw())
            Flush();

    if (bSetDocModified)
        if (SmDocShell* pModifyDoc = mrEditWindow.GetDoc())
            pModifyDoc->SetModified();

    static_cast<SmEditEngine*>(GetEditEngine())->executeZoom(GetEditView());
}

void SmEditWindow::UpdateStatus()
{
    mxTextControl->UpdateStatus(/*bSetDocModified*/false);
}

void SmEditWindow::Cut()
{
    if (mxTextControl)
    {
        mxTextControl->Cut();
        mxTextControl->UpdateStatus(true);
    }
}

void SmEditWindow::Copy()
{
    if (mxTextControl)
        mxTextControl->Copy();
}

void SmEditWindow::Paste()
{
    if (mxTextControl)
    {
        mxTextControl->Paste();
        mxTextControl->UpdateStatus(true);
    }
}

void SmEditWindow::Delete()
{
    if (mxTextControl)
    {
        mxTextControl->Delete();
        mxTextControl->UpdateStatus(true);
    }
}

void SmEditWindow::InsertText(const OUString& rText)
{
    if (!mxTextControl)
        return;
    mxTextControl->InsertText(rText);
}

void SmEditTextWindow::InsertText(const OUString& rText)
{
    EditView* pEditView = GetEditView();
    if (!pEditView)
        return;

    // Note: Insertion of a space in front of commands is done here and
    // in SmEditWindow::InsertCommand.
    ESelection aSelection = pEditView->GetSelection();
    OUString aCurrentFormula = pEditView->getEditEngine().GetText();
    sal_Int32 nStartIndex = 0;

    // get the start position (when we get a multi line formula)
    for (sal_Int32 nParaPos = 0; nParaPos < aSelection.start.nPara; nParaPos++)
         nStartIndex = aCurrentFormula.indexOf("\n", nStartIndex) + 1;

    nStartIndex += aSelection.start.nIndex;

    // TODO: unify this function with the InsertCommand: The do the same thing for different
    // callers
    OUString string(rText);

    OUString selected(pEditView->GetSelected());
    // if we have text selected, use it in the first placeholder
    if (!selected.isEmpty())
        string = string.replaceFirst("", selected);

    // put a space before a new command if not in the beginning of a line
    if (aSelection.start.nIndex > 0 && aCurrentFormula[nStartIndex - 1] != ' ')
        string = " " + string;

    pEditView->InsertText(string);

    // Remember start of the selection and move the cursor there afterwards.
    aSelection.end.nPara = aSelection.start.nPara;
    if (HasMark(string))
    {
        aSelection.end.nIndex = aSelection.start.nIndex;
        pEditView->SetSelection(aSelection);
        SelNextMark();
    }
    else
    {   // set selection after inserted text
        aSelection.end.nIndex = aSelection.start.nIndex + string.getLength();
        aSelection.start.nIndex = aSelection.end.nIndex;
        pEditView->SetSelection(aSelection);
    }

    aModifyIdle.Start();
    StartCursorMove();

    GrabFocus();
}

void SmEditTextWindow::Flush()
{
    EditEngine *pEditEngine = GetEditEngine();
    if (pEditEngine  &&  pEditEngine->IsModified())
    {
        pEditEngine->ClearModifyFlag();
        if (SmViewShell *pViewSh = mrEditWindow.GetView())
        {
            SfxStringItem aTextToFlush(SID_TEXT, GetText());
            pViewSh->GetViewFrame().GetDispatcher()->ExecuteList(
                    SID_TEXT, SfxCallMode::RECORD,
                    { &aTextToFlush });
        }
    }
    if (aCursorMoveIdle.IsActive())
    {
        aCursorMoveIdle.Stop();
        CursorMoveTimerHdl(&aCursorMoveIdle);
    }
}

void SmEditWindow::DeleteEditView()
{
    if (EditView* pEditView = GetEditView())
    {
        EditEngine& rEditEngine = pEditView->getEditEngine();
        rEditEngine.SetStatusEventHdl( Link<EditStatus&,void>() );
        rEditEngine.RemoveView(pEditView);
        mxTextControlWin.reset();
        mxTextControl.reset();
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

99%


¤ Dauer der Verarbeitung: 0.15 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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 ist noch experimentell.