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

Quelle  dbfindex.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 "dbfindex.hxx"
#include <comphelper/processfactory.hxx>
#include <osl/file.hxx>
#include <osl/thread.hxx>
#include <tools/config.hxx>
#include <osl/diagnose.h>
#include <unotools/localfilehelper.hxx>
#include <tools/urlobj.hxx>
#include <unotools/pathoptions.hxx>
#include <ucbhelper/content.hxx>
#include <svl/filenotation.hxx>
#include <rtl/strbuf.hxx>
#include <utility>

namespace dbaui
{
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::svt;

constexpr OString aGroupIdent("dBase III"_ostr);


ODbaseIndexDialog::ODbaseIndexDialog(weld::Window * pParent, OUString aDataSrcName)
    : GenericDialogController(pParent, u"dbaccess/ui/dbaseindexdialog.ui"_ustr, u"DBaseIndexDialog"_ustr)
    , m_aDSN(std::move(aDataSrcName))
    , m_xPB_OK(m_xBuilder->weld_button(u"ok"_ustr))
    , m_xCB_Tables(m_xBuilder->weld_combo_box(u"table"_ustr))
    , m_xIndexes(m_xBuilder->weld_widget(u"frame"_ustr))
    , m_xLB_TableIndexes(m_xBuilder->weld_tree_view(u"tableindex"_ustr))
    , m_xLB_FreeIndexes(m_xBuilder->weld_tree_view(u"freeindex"_ustr))
    , m_xAdd(m_xBuilder->weld_button(u"add"_ustr))
    , m_xRemove(m_xBuilder->weld_button(u"remove"_ustr))
    , m_xAddAll(m_xBuilder->weld_button(u"addall"_ustr))
    , m_xRemoveAll(m_xBuilder->weld_button(u"removeall"_ustr))
{
    int nWidth = m_xLB_TableIndexes->get_approximate_digit_width() * 18;
    int nHeight = m_xLB_TableIndexes->get_height_rows(10);
    m_xLB_TableIndexes->set_size_request(nWidth, nHeight);
    m_xLB_FreeIndexes->set_size_request(nWidth, nHeight);

    m_xCB_Tables->connect_changed( LINK(this, ODbaseIndexDialog, TableSelectHdl) );
    m_xAdd->connect_clicked( LINK(this, ODbaseIndexDialog, AddClickHdl) );
    m_xRemove->connect_clicked( LINK(this, ODbaseIndexDialog, RemoveClickHdl) );
    m_xAddAll->connect_clicked( LINK(this, ODbaseIndexDialog, AddAllClickHdl) );
    m_xRemoveAll->connect_clicked( LINK(this, ODbaseIndexDialog, RemoveAllClickHdl) );
    m_xPB_OK->connect_clicked( LINK(this, ODbaseIndexDialog, OKClickHdl) );

    m_xLB_FreeIndexes->connect_selection_changed(
        LINK(this, ODbaseIndexDialog, OnListEntrySelected));
    m_xLB_TableIndexes->connect_selection_changed(
        LINK(this, ODbaseIndexDialog, OnListEntrySelected));

    Init();
    SetCtrls();
}

ODbaseIndexDialog::~ODbaseIndexDialog()
{
}

void ODbaseIndexDialog::checkButtons()
{
    m_xAdd->set_sensitive(0 != m_xLB_FreeIndexes->count_selected_rows());
    m_xAddAll->set_sensitive(0 != m_xLB_FreeIndexes->n_children());

    m_xRemove->set_sensitive(0 != m_xLB_TableIndexes->count_selected_rows());
    m_xRemoveAll->set_sensitive(0 != m_xLB_TableIndexes->n_children());
}

OTableIndex ODbaseIndexDialog::implRemoveIndex(const OUString& _rName, TableIndexList& _rList, weld::TreeView& _rDisplay, bool _bMustExist)
{
    OTableIndex aReturn;

    TableIndexList::iterator aSearch = std::find_if(_rList.begin(), _rList.end(),
        [&_rName](const OTableIndex& rIndex) { return rIndex.GetIndexFileName() == _rName; });
    if (aSearch != _rList.end())
    {
        sal_Int32 nPos = static_cast<sal_Int32>(std::distance(_rList.begin(), aSearch));

        aReturn = *aSearch;

        _rList.erase(aSearch);
        _rDisplay.remove_text(_rName);

        // adjust selection if necessary
        if (static_cast<sal_uInt32>(nPos) == _rList.size())
            _rDisplay.select(static_cast<sal_uInt16>(nPos)-1);
        else
            _rDisplay.select(static_cast<sal_uInt16>(nPos));
    }
    OSL_ENSURE(!_bMustExist || !aReturn.GetIndexFileName().isEmpty(), "ODbaseIndexDialog::implRemoveIndex : did not find the index!");
    return aReturn;
}

void ODbaseIndexDialog::implInsertIndex(const OTableIndex& _rIndex, TableIndexList& _rList, weld::TreeView& _rDisplay)
{
    _rList.push_front(_rIndex);
    _rDisplay.append_text(_rIndex.GetIndexFileName());
    _rDisplay.select(0);
}

OTableIndex ODbaseIndexDialog::RemoveTableIndex( std::u16string_view _rTableName, const OUString& _rIndexName )
{
    OTableIndex aReturn;

    // does the table exist ?
    TableInfoList::iterator aTablePos = std::find_if(m_aTableInfoList.begin(), m_aTableInfoList.end(),
                                           [&] (const OTableInfo& arg) { return arg.aTableName == _rTableName; });

    if (aTablePos == m_aTableInfoList.end())
        return aReturn;

    return implRemoveIndex(_rIndexName, aTablePos->aIndexList, *m_xLB_TableIndexes, true/*_bMustExist*/);
}

void ODbaseIndexDialog::InsertTableIndex( std::u16string_view _rTableName, const OTableIndex& _rIndex)
{
    TableInfoList::iterator aTablePos = std::find_if(m_aTableInfoList.begin(), m_aTableInfoList.end(),
                                           [&] (const OTableInfo& arg) { return arg.aTableName == _rTableName; });

    if (aTablePos == m_aTableInfoList.end())
        return;

    implInsertIndex(_rIndex, aTablePos->aIndexList, *m_xLB_TableIndexes);
}

IMPL_LINK_NOARG(ODbaseIndexDialog, OKClickHdl, weld::Button&, void)
{
    // let all tables write their INF file

    for (auto const& tableInfo : m_aTableInfoList)
        tableInfo.WriteInfFile(m_aDSN);

    m_xDialog->response(RET_OK);
}

IMPL_LINK_NOARG(ODbaseIndexDialog, AddClickHdl, weld::Button&, void)
{
    OUString aSelection = m_xLB_FreeIndexes->get_selected_text();
    OUString aTableName = m_xCB_Tables->get_active_text();
    OTableIndex aIndex = RemoveFreeIndex( aSelection, true );
    InsertTableIndex( aTableName, aIndex );

    checkButtons();
}

IMPL_LINK_NOARG(ODbaseIndexDialog, RemoveClickHdl, weld::Button&, void)
{
    OUString aSelection = m_xLB_TableIndexes->get_selected_text();
    OUString aTableName = m_xCB_Tables->get_active_text();
    OTableIndex aIndex = RemoveTableIndex( aTableName, aSelection );
    InsertFreeIndex( aIndex );

    checkButtons();
}

IMPL_LINK_NOARG(ODbaseIndexDialog, AddAllClickHdl, weld::Button&, void)
{
    const sal_Int32 nCnt = m_xLB_FreeIndexes->n_children();
    OUString aTableName = m_xCB_Tables->get_active_text();

    for (sal_Int32 nPos = 0; nPos < nCnt; ++nPos)
        InsertTableIndex(aTableName, RemoveFreeIndex(m_xLB_FreeIndexes->get_text(0), true));

    checkButtons();
}

IMPL_LINK_NOARG(ODbaseIndexDialog, RemoveAllClickHdl, weld::Button&, void)
{
    const sal_Int32 nCnt = m_xLB_TableIndexes->n_children();
    OUString aTableName = m_xCB_Tables->get_active_text();

    for (sal_Int32 nPos = 0; nPos < nCnt; ++nPos)
        InsertFreeIndex(RemoveTableIndex(aTableName, m_xLB_TableIndexes->get_text(0)));

    checkButtons();
}

IMPL_LINK_NOARG(ODbaseIndexDialog, OnListEntrySelected, weld::TreeView&, void)
{
    checkButtons();
}

IMPL_LINK(ODbaseIndexDialog, TableSelectHdl, weld::ComboBox&, rComboBox, void)
{
    // search the table
    TableInfoList::iterator aTablePos = std::find_if(m_aTableInfoList.begin(), m_aTableInfoList.end(),
                                           [&] (const OTableInfo& arg) { return arg.aTableName == rComboBox.get_active_text() ; });

    if (aTablePos == m_aTableInfoList.end())
        return;

    // fill the listbox for the indexes
    m_xLB_TableIndexes->clear();
    for (auto const& index : aTablePos->aIndexList)
        m_xLB_TableIndexes->append_text(index.GetIndexFileName());

    if (!aTablePos->aIndexList.empty())
        m_xLB_TableIndexes->select(0);

    checkButtons();
}

void ODbaseIndexDialog::Init()
{
    m_xPB_OK->set_sensitive(false);
    m_xIndexes->set_sensitive(false);

    // All indices are first added to a list of free indices.
    // Afterwards, check the index of each table in the Inf-file.
    // These indices are removed from the list of free indices and
    // entered in the indexlist of the table.

    // if the string does not contain a path, cut the string
    INetURLObject aURL;
    aURL.SetSmartProtocol(INetProtocol::File);
    {
        SvtPathOptions aPathOptions;
        m_aDSN = aPathOptions.SubstituteVariable(m_aDSN);
    }
    aURL.SetSmartURL(m_aDSN);

    //  String aFileName = aURL.PathToFileName();
    m_aDSN = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
    ::ucbhelper::Content aFile;
    bool bFolder=true;
    try
    {
        aFile = ::ucbhelper::Content(m_aDSN,Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext());
        bFolder = aFile.isFolder();
    }
    catch(Exception&)
    {
        return;
    }

    // first assume for all indexes they're free

    std::vector< OUString > aUsedIndexes;

    aURL.SetSmartProtocol(INetProtocol::File);
    const Sequence<OUString> aFolderUrls = ::utl::LocalFileHelper::GetFolderContents(m_aDSN, bFolder);
    for(const OUString& rURL : aFolderUrls)
    {
        OUString aName;
        osl::FileBase::getSystemPathFromFileURL(rURL,aName);
        aURL.SetSmartURL(aName);
        OUString aExt = aURL.getExtension();
        if (aExt == "ndx")
        {
            m_aFreeIndexList.emplace_back(aURL.getName() );
        }
        else if (aExt == "dbf")
        {
            m_aTableInfoList.emplace_back(aURL.getName() );
            OTableInfo& rTabInfo = m_aTableInfoList.back();

            // open the INF file
            aURL.setExtension(u"inf");
            OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
            Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
            aInfFile.SetGroup( aGroupIdent );

            // fill the indexes list
            OString aNDX;
            sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
            OString aKeyName;
            OUString aEntry;

            for( sal_uInt16 nKey = 0; nKey < nKeyCnt; nKey++ )
            {
                // does the key point to an index file ?
                aKeyName = aInfFile.GetKeyName( nKey );
                aNDX = aKeyName.copy(0,3);

                // yes -> add to the tables index list
                if (aNDX == "NDX")
                {
                    aEntry = OStringToOUString(aInfFile.ReadKey(aKeyName), osl_getThreadTextEncoding());
                    rTabInfo.aIndexList.emplace_back( aEntry );

                    // and remove it from the free index list
                    aUsedIndexes.push_back(aEntry);
                        // do this later below. We may not have encountered the index file, yet, thus we may not
                        // know the index as being free, yet
                }
            }
        }
    }

    for (auto const& usedIndex : aUsedIndexes)
        RemoveFreeIndex( usedIndex, false );

    if (!m_aTableInfoList.empty())
    {
        m_xPB_OK->set_sensitive(true);
        m_xIndexes->set_sensitive(true);
    }

    checkButtons();
}

void ODbaseIndexDialog::SetCtrls()
{
    // ComboBox tables
    for (auto const& tableInfo : m_aTableInfoList)
        m_xCB_Tables->append_text(tableInfo.aTableName);

    // put the first dataset into Edit
    if (!m_aTableInfoList.empty())
    {
        const OTableInfo& rTabInfo = m_aTableInfoList.front();
        m_xCB_Tables->set_entry_text(rTabInfo.aTableName);

        // build ListBox of the table indices
        for (auto const& index : rTabInfo.aIndexList)
            m_xLB_TableIndexes->append_text(index.GetIndexFileName());

        if (!rTabInfo.aIndexList.empty())
            m_xLB_TableIndexes->select(0);
    }

    // ListBox of the free indices
    for (auto const& freeIndex : m_aFreeIndexList)
        m_xLB_FreeIndexes->append_text(freeIndex.GetIndexFileName());

    if (!m_aFreeIndexList.empty())
        m_xLB_FreeIndexes->select(0);

    TableSelectHdl(*m_xCB_Tables);
    checkButtons();
}

void OTableInfo::WriteInfFile( const OUString& rDSN ) const
{
    // open INF file
    INetURLObject aURL;
    aURL.SetSmartProtocol(INetProtocol::File);
    OUString aDsn = rDSN;
    {
        SvtPathOptions aPathOptions;
        aDsn = aPathOptions.SubstituteVariable(aDsn);
    }
    aURL.SetSmartURL(aDsn);
    aURL.Append(aTableName);
    aURL.setExtension(u"inf");

    OFileNotation aTransformer(aURL.GetURLNoPass(), OFileNotation::N_URL);
    Config aInfFile( aTransformer.get(OFileNotation::N_SYSTEM) );
    aInfFile.SetGroup( aGroupIdent );

    // first, delete all table indices
    sal_uInt16 nKeyCnt = aInfFile.GetKeyCount();
    sal_uInt16 nKey = 0;

    while( nKey < nKeyCnt )
    {
        // Does the key point to an index file?...
        OString aKeyName = aInfFile.GetKeyName( nKey );
        OString aNDX = aKeyName.copy(0,3);

        //...if yes, delete index file, nKey is at subsequent key
        if (aNDX == "NDX")
        {
            aInfFile.DeleteKey(aKeyName);
            nKeyCnt--;
        }
        else
            nKey++;

    }

    // now add all saved indices
    sal_uInt16 nPos = 0;
    for (auto const& index : aIndexList)
    {
        OStringBuffer aKeyName("NDX");
        if( nPos > 0 )  // first index contains no number
            aKeyName.append(static_cast<sal_Int32>(nPos));
        aInfFile.WriteKey(
            aKeyName.makeStringAndClear(),
            OUStringToOString(index.GetIndexFileName(),
                osl_getThreadTextEncoding()));
        ++nPos;
    }

    aInfFile.Flush();

    // if only [dbase] is left in INF-file, delete file
    if(nPos)
        return;

    try
    {
        ::ucbhelper::Content aContent(aURL.GetURLNoPass(),Reference<XCommandEnvironment>(), comphelper::getProcessComponentContext());
        aContent.executeCommand( u"delete"_ustr, Any( true ) );
    }
    catch (const Exception& )
    {
        // simply silent this. The strange algorithm here does a lot of
        // things even if no files at all were created or accessed, so it's
        // possible that the file we're trying to delete does not even
        // exist, and this is a valid condition.
    }
}

// namespace

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

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

¤ Dauer der Verarbeitung: 0.24 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 und die Messung sind noch experimentell.