Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


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


#include <namedefdlg.hxx>

#include <formula/errorcodes.hxx>
#include <sfx2/app.hxx>
#include <unotools/charclass.hxx>

#include <compiler.hxx>
#include <document.hxx>
#include <globstr.hrc>
#include <scresid.hxx>
#include <globalnames.hxx>
#include <rangenam.hxx>
#include <reffact.hxx>
#include <undorangename.hxx>
#include <tabvwsh.hxx>
#include <tokenarray.hxx>

ScNameDefDlg::ScNameDefDlg( SfxBindings* pB, SfxChildWindow* pCW, weld::Window* pParent,
        const ScViewData& rViewData, std::map<OUString, ScRangeName*>&& aRangeMap,
        const ScAddress& aCursorPos, const bool bUndo )
    : ScAnyRefDlgController( pB, pCW, pParent, u"modules/scalc/ui/definename.ui"_ustr, u"DefineNameDialog"_ustr)
    , mbUndo( bUndo )
    , mrDoc(rViewData.GetDocument())
    , mrDocShell ( rViewData.GetDocShell() )
    , maCursorPos( aCursorPos )
    , maGlobalNameStr  ( ScResId(STR_GLOBAL_SCOPE) )
    , maErrInvalidNameStr( ScResId(STR_ERR_NAME_INVALID))
    , maErrInvalidNameCellRefStr( ScResId(STR_ERR_NAME_INVALID_CELL_REF))
    , maErrInvalidSheetReference(ScResId(STR_INVALID_TABREF_PRINT_AREA))
    , maErrNameInUse   ( ScResId(STR_ERR_NAME_EXISTS))
    , maRangeMap( std::move(aRangeMap) )
    , m_xEdName(m_xBuilder->weld_entry(u"edit"_ustr))
    , m_xEdRange(new formula::RefEdit(m_xBuilder->weld_entry(u"range"_ustr)))
    , m_xRbRange(new formula::RefButton(m_xBuilder->weld_button(u"refbutton"_ustr)))
    , m_xLbScope(m_xBuilder->weld_combo_box(u"scope"_ustr))
    , m_xBtnRowHeader(m_xBuilder->weld_check_button(u"rowheader"_ustr))
    , m_xBtnColHeader(m_xBuilder->weld_check_button(u"colheader"_ustr))
    , m_xBtnPrintArea(m_xBuilder->weld_check_button(u"printarea"_ustr))
    , m_xBtnCriteria(m_xBuilder->weld_check_button(u"filter"_ustr))
    , m_xBtnAdd(m_xBuilder->weld_button(u"add"_ustr))
    , m_xBtnCancel(m_xBuilder->weld_button(u"cancel"_ustr))
    , m_xFtInfo(m_xBuilder->weld_label(u"label"_ustr))
    , m_xExpander(m_xBuilder->weld_expander(u"more"_ustr))
    , m_xFtRange(m_xBuilder->weld_label(u"label3"_ustr))
{
    m_xEdRange->SetReferences(this, m_xFtRange.get());
    m_xRbRange->SetReferences(this, m_xEdRange.get());
    maStrInfoDefault = m_xFtInfo->get_label();

    // Initialize scope list.
    m_xLbScope->append_text(maGlobalNameStr);
    m_xLbScope->set_active(0);
    SCTAB n = mrDoc.GetTableCount();
    for (SCTAB i = 0; i < n; ++i)
    {
        OUString aTabName;
        mrDoc.GetName(i, aTabName);
        m_xLbScope->append_text(aTabName);
    }

    m_xBtnCancel->connect_clicked( LINK( this, ScNameDefDlg, CancelBtnHdl));
    m_xBtnAdd->connect_clicked( LINK( this, ScNameDefDlg, AddBtnHdl ));
    m_xEdName->connect_changed( LINK( this, ScNameDefDlg, NameModifyHdl ));
    m_xEdRange->SetGetFocusHdl( LINK( this, ScNameDefDlg, AssignGetFocusHdl ) );
    m_xEdRange->SetModifyHdl( LINK( this, ScNameDefDlg, RefEdModifyHdl ) );
    m_xBtnPrintArea->connect_toggled(LINK(this, ScNameDefDlg, EdModifyCheckBoxHdl));

    m_xBtnAdd->set_sensitive(false); // empty name is invalid

    ScRange aRange;

    rViewData.GetSimpleArea( aRange );
    OUString aAreaStr(aRange.Format(mrDoc, ScRefFlags::RANGE_ABS_3D,
            ScAddress::Details(mrDoc.GetAddressConvention(), 0, 0)));

    m_xEdRange->SetText( aAreaStr );

    m_xEdName->grab_focus();
    m_xEdName->select_region(0, -1);
}

ScNameDefDlg::~ScNameDefDlg()
{
}

void ScNameDefDlg::CancelPushed()
{
    if (mbUndo)
        response(RET_CANCEL);
    else
    {
        if (ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell())
            pViewSh->SwitchBetweenRefDialogs(this);
    }
}

bool ScNameDefDlg::IsFormulaValid()
{
    const OUString aRangeOrFormulaExp = m_xEdRange->GetText();
    // tdf#140394 - check if formula is a valid print range
    if (m_xBtnPrintArea->get_active())
    {
        const ScRefFlags nValidAddr  = ScRefFlags::VALID | ScRefFlags::ROW_VALID | ScRefFlags::COL_VALID;
        const ScRefFlags nValidRange = nValidAddr | ScRefFlags::ROW2_VALID | ScRefFlags::COL2_VALID;
        const formula::FormulaGrammar::AddressConvention eConv = mrDoc.GetAddressConvention();
        const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep);

        ScAddress aAddr;
        ScRange aRange;
        for (sal_Int32 nIdx = 0; nIdx >= 0;)
        {
            const OUString aOne = aRangeOrFormulaExp.getToken(0, sep, nIdx);
            ScRefFlags nResult = aRange.Parse(aOne, mrDoc, eConv);
            if ((nResult & nValidRange) != nValidRange)
            {
                ScRefFlags nAddrResult = aAddr.Parse(aOne, mrDoc, eConv);
                if ((nAddrResult & nValidAddr) != nValidAddr)
                    return false;
            }
        }
    }
    else
    {
        ScCompiler aComp(mrDoc, maCursorPos, mrDoc.GetGrammar());
        std::unique_ptr<ScTokenArray> pCode = aComp.CompileString(m_xEdRange->GetText());
        if (pCode->GetCodeError() != FormulaError::NONE)
            return false;
    }

    return true;
}

bool ScNameDefDlg::IsNameValid()
{
    OUString aScope = m_xLbScope->get_active_text();
    OUString aName = m_xEdName->get_text();

    bool bIsNameValid = true;
    OUString aHelpText = maStrInfoDefault;

    ScRangeName* pRangeName = nullptr;
    if(aScope == maGlobalNameStr)
    {
        const auto iter = maRangeMap.find(STR_GLOBAL_RANGE_NAME);
        assert(iter != maRangeMap.end());
        pRangeName = iter->second;
    }
    else
    {
        const auto iter = maRangeMap.find(aScope);
        assert(iter != maRangeMap.end());
        pRangeName = iter->second;
    }

    ScRangeData::IsNameValidType eType;
    if ( aName.isEmpty() )
    {
        bIsNameValid = false;
    }
    else if ((eType = ScRangeData::IsNameValid(aName, mrDoc))
             != ScRangeData::IsNameValidType::NAME_VALID)
    {
        if (eType == ScRangeData::IsNameValidType::NAME_INVALID_BAD_STRING)
        {
            aHelpText = maErrInvalidNameStr;
        }
        else if (eType == ScRangeData::IsNameValidType::NAME_INVALID_CELL_REF)
        {
            aHelpText = maErrInvalidNameCellRefStr;
        }
        bIsNameValid = false;
    }
    else if (pRangeName->findByUpperName(ScGlobal::getCharClass().uppercase(aName)))
    {
        aHelpText = maErrNameInUse;
        bIsNameValid = false;
    }

    if (!IsFormulaValid())
    {
        bIsNameValid = false;
        if (m_xBtnPrintArea->get_active())
            aHelpText = maErrInvalidSheetReference;
        //TODO: info message for a non valid formula (print range not checked)
    }

    m_xEdName->set_tooltip_text(aHelpText);
    m_xEdName->set_message_type(bIsNameValid || aName.isEmpty() ? weld::EntryMessageType::Normal
                                                                : weld::EntryMessageType::Error);
    m_xBtnAdd->set_sensitive(bIsNameValid);
    return bIsNameValid;
}

void ScNameDefDlg::AddPushed()
{
    OUString aScope = m_xLbScope->get_active_text();
    OUString aName = m_xEdName->get_text();
    OUString aExpression = m_xEdRange->GetText();

    if (aName.isEmpty())
    {
        return;
    }
    if (aScope.isEmpty())
    {
        return;
    }

    ScRangeName* pRangeName = nullptr;
    if(aScope == maGlobalNameStr)
    {
        const auto iter = maRangeMap.find(STR_GLOBAL_RANGE_NAME);
        assert(iter != maRangeMap.end());
        pRangeName = iter->second;
    }
    else
    {
        const auto iter = maRangeMap.find(aScope);
        assert(iter != maRangeMap.end());
        pRangeName = iter->second;
    }
    if (!pRangeName)
        return;

    if (!IsNameValid()) //should not happen, but make sure we don't break anything
        return;
    else
    {
        ScRangeData::Type nType = ScRangeData::Type::Name;

        ScRangeData* pNewEntry = new ScRangeData( mrDoc,
                aName,
                aExpression,
                maCursorPos,
                nType );

        if ( m_xBtnRowHeader->get_active() ) nType |= ScRangeData::Type::RowHeader;
        if ( m_xBtnColHeader->get_active() ) nType |= ScRangeData::Type::ColHeader;
        if ( m_xBtnPrintArea->get_active() ) nType |= ScRangeData::Type::PrintArea;
        if ( m_xBtnCriteria->get_active()  ) nType |= ScRangeData::Type::Criteria;

        pNewEntry->AddType(nType);

        // aExpression valid?
        if ( FormulaError::NONE == pNewEntry->GetErrCode() )
        {
            if ( !pRangeName->insert( pNewEntry, false /*bReuseFreeIndex*/ ) )
                pNewEntry = nullptr;

            if (mbUndo)
            {
                // this means we called directly through the menu

                SCTAB nTab;
                // if no table with that name is found, assume global range name
                if (!mrDoc.GetTable(aScope, nTab))
                    nTab = -1;

                assert( pNewEntry);     // undo of no insertion smells fishy
                if (pNewEntry)
                    mrDocShell.GetUndoManager()->AddUndoAction(
                            std::make_unique<ScUndoAddRangeData>( mrDocShell, pNewEntry, nTab) );

                // set table stream invalid, otherwise RangeName won't be saved if no other
                // call invalidates the stream
                if (nTab != -1)
                    mrDoc.SetStreamValid(nTab, false);
                SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
                mrDocShell.SetDocumentModified();
                Close();
            }
            else
            {
                maName = aName;
                maScope = aScope;
                if (ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell())
                    pViewSh->SwitchBetweenRefDialogs(this);
            }
        }
        else
        {
            delete pNewEntry;
            m_xEdRange->GrabFocus();
            m_xEdRange->SelectAll();
        }
    }
}

void ScNameDefDlg::GetNewData(OUString& rName, OUString& rScope)
{
    rName = maName;
    rScope = maScope;
}

bool ScNameDefDlg::IsRefInputMode() const
{
    return m_xEdRange->GetWidget()->get_sensitive();
}

void ScNameDefDlg::RefInputDone( bool bForced)
{
    ScAnyRefDlgController::RefInputDone(bForced);
    IsNameValid();
}

void ScNameDefDlg::SetReference( const ScRange& rRef, ScDocument& rDocP )
{
    if (m_xEdRange->GetWidget()->get_sensitive())
    {
        if ( rRef.aStart != rRef.aEnd )
            RefInputStart(m_xEdRange.get());
        OUString aRefStr(rRef.Format(rDocP, ScRefFlags::RANGE_ABS_3D,
                ScAddress::Details(rDocP.GetAddressConvention(), 0, 0)));
        m_xEdRange->SetRefString( aRefStr );
    }
}

void ScNameDefDlg::Close()
{
    DoClose( ScNameDefDlgWrapper::GetChildWindowId() );
}

void ScNameDefDlg::SetActive()
{
    m_xEdRange->GrabFocus();
    RefInputDone();
}

IMPL_LINK_NOARG(ScNameDefDlg, CancelBtnHdl, weld::Button&, void)
{
    CancelPushed();
}

IMPL_LINK_NOARG(ScNameDefDlg, AddBtnHdl, weld::Button&, void)
{
    AddPushed();
};

IMPL_LINK_NOARG(ScNameDefDlg, NameModifyHdl, weld::Entry&, void)
{
    IsNameValid();
}

IMPL_LINK_NOARG(ScNameDefDlg, AssignGetFocusHdl, formula::RefEdit&, void)
{
    IsNameValid();
}

IMPL_LINK_NOARG(ScNameDefDlg, EdModifyCheckBoxHdl, weld::Toggleable&, void)
{
    IsNameValid();
}

IMPL_LINK_NOARG(ScNameDefDlg, RefEdModifyHdl, formula::RefEdit&, void)
{
    IsNameValid();
}

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

Messung V0.5
C=93 H=96 G=94

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet)  ¤

*© 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 und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge