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


Quelle  indexdialog.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 <sal/config.h>

#include <set>

#include <core_resource.hxx>
#include <indexdialog.hxx>
#include <strings.hrc>
#include <bitmaps.hlst>
#include <indexfieldscontrol.hxx>
#include <indexcollection.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <com/sun/star/sdb/SQLContext.hpp>
#include <connectivity/dbtools.hxx>
#include <osl/diagnose.h>

namespace dbaui
{

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::container;
    using namespace ::com::sun::star::sdbc;
    using namespace ::com::sun::star::sdb;
    using namespace ::com::sun::star::lang;
    using namespace ::dbtools;

    // helper
    static bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS)
    {
        return  (_rLHS.sFieldName == _rRHS.sFieldName)
            &&  (_rLHS.bSortAscending == _rRHS.bSortAscending);
    }

    static bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS)
    {
        return std::equal(_rLHS.begin(), _rLHS.end(), _rRHS.begin(), _rRHS.end());
    }

    static bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
    {
        return !(_rLHS == _rRHS);
    }

    // DbaIndexDialog
    DbaIndexDialog::DbaIndexDialog(weld::Window* pParent, const Sequence< OUString >& _rFieldNames,
                                   const Reference< XNameAccess >& _rxIndexes,
                                   const Reference< XConnection >& _rxConnection,
                                   const Reference< XComponentContext >& _rxContext)
        : GenericDialogController(pParent, u"dbaccess/ui/indexdesigndialog.ui"_ustr, u"IndexDesignDialog"_ustr)
        , m_xConnection(_rxConnection)
        , m_bEditingActive(false)
        , m_bEditAgain(false)
        , m_bNoHandlerCall(false)
        , m_xContext(_rxContext)
        , m_xActions(m_xBuilder->weld_toolbar(u"ACTIONS"_ustr))
        , m_xIndexList(m_xBuilder->weld_tree_view(u"INDEX_LIST"_ustr))
        , m_xIndexDetails(m_xBuilder->weld_label(u"INDEX_DETAILS"_ustr))
        , m_xDescriptionLabel(m_xBuilder->weld_label(u"DESC_LABEL"_ustr))
        , m_xDescription(m_xBuilder->weld_label(u"DESCRIPTION"_ustr))
        , m_xUnique(m_xBuilder->weld_check_button(u"UNIQUE"_ustr))
        , m_xFieldsLabel(m_xBuilder->weld_label(u"FIELDS_LABEL"_ustr))
        , m_xClose(m_xBuilder->weld_button(u"close"_ustr))
        , m_xTable(m_xBuilder->weld_container(u"FIELDS"_ustr))
        , m_xTableCtrlParent(m_xTable->CreateChildFrame())
        , m_xFields(VclPtr<IndexFieldsControl>::Create(m_xTableCtrlParent))
    {
        m_xIndexList->set_size_request(m_xIndexList->get_approximate_digit_width() * 17,
                                       m_xIndexList->get_height_rows(12));

        int nWidth = m_xIndexList->get_approximate_digit_width() * 60;
        int nHeight = m_xIndexList->get_height_rows(8);
        m_xTable->set_size_request(nWidth, nHeight);

        m_xActions->connect_clicked(LINK(this, DbaIndexDialog, OnIndexAction));

        m_xIndexList->connect_selection_changed(LINK(this, DbaIndexDialog, OnIndexSelected));
        m_xIndexList->connect_editing(LINK(this, DbaIndexDialog, OnEntryEditing),
                                      LINK(this, DbaIndexDialog, OnEntryEdited));

        m_xFields->SetSizePixel(Size(nWidth, 100));
        m_xFields->Init(_rFieldNames, ::dbtools::getBooleanDataSourceSetting( m_xConnection"AddIndexAppendix" ));
        m_xFields->Show();

        m_xIndexes.reset(new OIndexCollection());
        try
        {
            m_xIndexes->attach(_rxIndexes);
        }
        catch(SQLException& e)
        {
            ::dbtools::showError(SQLExceptionInfo(e), pParent->GetXWindow(), _rxContext);
        }
        catch(Exception&)
        {
            OSL_FAIL("DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
        }

        fillIndexList();

        m_xUnique->connect_toggled(LINK(this, DbaIndexDialog, OnModifiedClick));
        m_xFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified));

        m_xClose->connect_clicked(LINK(this, DbaIndexDialog, OnCloseDialog));

        // if all of the indexes have an empty description, we're not interested in displaying it
        bool bFound = false;
        for (auto const& check : *m_xIndexes)
        {
            if (!check.sDescription.isEmpty())
            {
                bFound = true;
                break;
            }
        }
        if (!bFound)
        {
            // hide the controls which are necessary for the description
            m_xDescription->hide();
            m_xDescriptionLabel->hide();
        }
    }

    void DbaIndexDialog::updateToolbox()
    {
        m_xActions->set_item_sensitive(u"ID_INDEX_NEW"_ustr, !m_bEditingActive);

        int nSelected = m_xIndexList->get_selected_index();
        bool bSelectedAnything = nSelected != -1;
        if (bSelectedAnything)
        {
            // is the current entry modified?
            Indexes::const_iterator aSelectedPos = m_xIndexes->begin() + m_xIndexList->get_id(nSelected).toUInt32();
            m_xActions->set_item_sensitive(u"ID_INDEX_SAVE"_ustr, aSelectedPos->isModified() || aSelectedPos->isNew());
            m_xActions->set_item_sensitive(u"ID_INDEX_RESET"_ustr, aSelectedPos->isModified() || aSelectedPos->isNew());
            bSelectedAnything = !aSelectedPos->bPrimaryKey;
        }
        else
        {
            m_xActions->set_item_sensitive(u"ID_INDEX_SAVE"_ustr, false);
            m_xActions->set_item_sensitive(u"ID_INDEX_RESET"_ustr, false);
        }
        m_xActions->set_item_sensitive(u"ID_INDEX_DROP"_ustr, bSelectedAnything);
        m_xActions->set_item_sensitive(u"ID_INDEX_RENAME"_ustr, bSelectedAnything);
    }

    void DbaIndexDialog::fillIndexList()
    {
        OUString aPKeyIcon(BMP_PKEYICON);
        // fill the list with the index names
        m_xIndexList->clear();
        sal_uInt32 nPos = 0;
        for (auto const& indexLoop : *m_xIndexes)
        {
            m_xIndexList->append(OUString::number(nPos), indexLoop.sName);
            if (indexLoop.bPrimaryKey)
                m_xIndexList->set_image(nPos, aPKeyIcon);
            ++nPos;
        }

        if (nPos)
            m_xIndexList->select(0);

        IndexSelected();
    }

    DbaIndexDialog::~DbaIndexDialog( )
    {
        m_xIndexes.reset();
        m_xFields.disposeAndClear();
        m_xTableCtrlParent->dispose();
        m_xTableCtrlParent.clear();
    }

    bool DbaIndexDialog::implCommit(const weld::TreeIter* pEntry)
    {
        assert(pEntry && "DbaIndexDialog::implCommit: invalid entry!");

        Indexes::iterator aCommitPos = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();

        // if it's not a new index, remove it
        // (we can't modify indexes, only drop'n'insert)
        if (!aCommitPos->isNew())
            if (!implDropIndex(pEntry, false))
                return false;

        // create the new index
        SQLExceptionInfo aExceptionInfo;
        try
        {
            m_xIndexes->commitNewIndex(aCommitPos);
        }
        catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
        catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
        catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }

        // reflect the new selection in the toolbox
        updateToolbox();

        if (aExceptionInfo.isValid())
            showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
        else
        {
            m_xUnique->save_state();
            m_xFields->SaveValue();
        }

        return !aExceptionInfo.isValid();
    }

    void DbaIndexDialog::OnNewIndex()
    {
        // commit the current entry, if necessary
        if (!implCommitPreviouslySelected())
            return;

        // get a new unique name for the new index
        OUString sNewIndexName;
        const OUString sNewIndexNameBase(DBA_RES(STR_LOGICAL_INDEX_NAME));
        sal_Int32 i;

        for ( i = 1; i < 0x7FFFFFFF; ++i )
        {
            sNewIndexName = sNewIndexNameBase + OUString::number(i);
            if (m_xIndexes->end() == m_xIndexes->find(sNewIndexName))
                break;
        }
        if (i == 0x7FFFFFFF)
        {
            OSL_FAIL("DbaIndexDialog::OnNewIndex: no free index name found!");
            // can't do anything ... of course we try another base, but this could end with the same result ...
            return;
        }

        std::unique_ptr<weld::TreeIter> xNewEntry(m_xIndexList->make_iterator());
        m_xIndexList->insert(nullptr, -1, &sNewIndexName, nullptr, nullptr, nullptr, false, xNewEntry.get());
        m_xIndexes->insert(sNewIndexName);

        // update the user data on the entries in the list box:
        // they're iterators of the index collection, and thus they have changed when removing the index
        m_xIndexList->all_foreach([this](weld::TreeIter& rEntry){
            Indexes::const_iterator aAfterInsertPos = m_xIndexes->find(m_xIndexList->get_text(rEntry));
            OSL_ENSURE(aAfterInsertPos != m_xIndexes->end(), "DbaIndexDialog::OnNewIndex: problems with one of the entries!");
            m_xIndexList->set_id(rEntry, OUString::number(aAfterInsertPos - m_xIndexes->begin()));
            return false;
        });

        // select the entry and start in-place editing
        m_bNoHandlerCall = true;
        m_xIndexList->select(*xNewEntry);
        m_bNoHandlerCall = false;
        IndexSelected();
        m_xIndexList->grab_focus();
        m_xIndexList->start_editing(*xNewEntry);
        updateToolbox();
    }

    void DbaIndexDialog::OnDropIndex(bool _bConfirm)
    {
        std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
        // the selected index
        if (!m_xIndexList->get_selected(xSelected.get()))
            return;

        // let the user confirm the drop
        if (_bConfirm)
        {
            OUString sConfirm(DBA_RES(STR_CONFIRM_DROP_INDEX));
            sConfirm = sConfirm.replaceFirst("$name$", m_xIndexList->get_text(*xSelected));
            std::unique_ptr<weld::MessageDialog> xConfirm(Application::CreateMessageDialog(m_xDialog.get(),
                                                          VclMessageType::Question, VclButtonsType::YesNo,
                                                          sConfirm));
            if (RET_YES != xConfirm->run())
                return;
        }

        // do the drop
        implDropIndex(xSelected.get(), true);

        // reflect the new selection in the toolbox
        updateToolbox();
    }

    bool DbaIndexDialog::implDropIndex(const weld::TreeIter* pEntry, bool _bRemoveFromCollection)
    {
        // do the drop
        Indexes::iterator aDropPos = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();
        OSL_ENSURE(aDropPos != m_xIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!");

        SQLExceptionInfo aExceptionInfo;
        bool bSuccess = false;
        try
        {
            if (_bRemoveFromCollection)
                bSuccess = m_xIndexes->drop(aDropPos);
            else
                bSuccess = m_xIndexes->dropNoRemove(aDropPos);
        }
        catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
        catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
        catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }

        if (aExceptionInfo.isValid())
            showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
        else if (bSuccess && _bRemoveFromCollection)
        {
            m_bNoHandlerCall = true;

            // if the entry to remove is the selected on...
            if (m_xPreviousSelection && m_xPreviousSelection->equal(*pEntry))
                m_xPreviousSelection.reset();
            m_xIndexList->remove(*pEntry);

            m_bNoHandlerCall = false;

            // update the user data on the entries in the list box:
            // they're iterators of the index collection, and thus they have changed when removing the index
            m_xIndexList->all_foreach([this](weld::TreeIter& rEntry){
                Indexes::const_iterator aAfterDropPos = m_xIndexes->find(m_xIndexList->get_text(rEntry));
                OSL_ENSURE(aAfterDropPos != m_xIndexes->end(), "DbaIndexDialog::OnDropIndex: problems with one of the remaining entries!");
                m_xIndexList->set_id(rEntry, OUString::number(aAfterDropPos - m_xIndexes->begin()));
                return false;
            });

            // the Remove automatically selected another entry (if possible), but we disabled the calling of the handler
            // to prevent that we missed something... call the handler directly
            IndexSelected();
        }

        return !aExceptionInfo.isValid();
    }

    void DbaIndexDialog::OnRenameIndex()
    {
        // the selected iterator
        std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
        if (!m_xIndexList->get_selected(xSelected.get()))
            return;

        // save the changes made 'til here
        // Upon leaving the edit mode, the control will be re-initialized with the
        // settings from the current entry
        implSaveModified(false);

        m_xIndexList->grab_focus();
        m_xIndexList->start_editing(*xSelected);
        updateToolbox();
    }

    void DbaIndexDialog::OnSaveIndex()
    {
        // the selected index
        implCommitPreviouslySelected();
        updateToolbox();
    }

    void DbaIndexDialog::OnResetIndex()
    {
        // the selected index
        std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
        // the selected index
        if (!m_xIndexList->get_selected(xSelected.get()))
            xSelected.reset();
        OSL_ENSURE(xSelected, "DbaIndexDialog::OnResetIndex: invalid call!");
        if (!xSelected)
            return;

        Indexes::iterator aResetPos = m_xIndexes->begin() + m_xIndexList->get_id(*xSelected).toUInt32();

        if (aResetPos->isNew())
        {
            OnDropIndex(false);
            return;
        }

        SQLExceptionInfo aExceptionInfo;
        try
        {
            m_xIndexes->resetIndex(aResetPos);
        }
        catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
        catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
        catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }

        if (aExceptionInfo.isValid())
            showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
        else
            m_xIndexList->set_text(*xSelected, aResetPos->sName);

        updateControls(xSelected.get());
        updateToolbox();
    }

    IMPL_LINK(DbaIndexDialog, OnIndexAction, const OUString&, rClicked, void)
    {
        if (rClicked == "ID_INDEX_NEW")
            OnNewIndex();
        else if (rClicked == "ID_INDEX_DROP")
            OnDropIndex();
        else if (rClicked == "ID_INDEX_RENAME")
            OnRenameIndex();
        else if (rClicked == "ID_INDEX_SAVE")
            OnSaveIndex();
        else if (rClicked == "ID_INDEX_RESET")
            OnResetIndex();
    }

    IMPL_LINK_NOARG(DbaIndexDialog, OnCloseDialog, weld::Button&, void)
    {
        if (m_bEditingActive)
        {
            OSL_ENSURE(!m_bEditAgain, "DbaIndexDialog::OnCloseDialog: somebody was faster than hell!");
                // this means somebody entered a new name, which was invalid, which cause us to posted us an event,
                // and before the event arrived the user clicked onto "close". VERY fast, this user...
            m_xIndexList->end_editing();
            if (m_bEditAgain)
                // could not commit the new name (started a new - asynchronous - edit trial)
                return;
        }

        // the currently selected entry
        std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
        // the selected index
        if (!m_xIndexList->get_selected(xSelected.get()))
            xSelected.reset();

        OSL_ENSURE(xSelected && m_xPreviousSelection && xSelected->equal(*m_xPreviousSelection), "DbaIndexDialog::OnCloseDialog: inconsistence!");

        sal_Int32 nResponse = RET_NO;
        if (xSelected)
        {
            // the descriptor
            Indexes::const_iterator aSelected = m_xIndexes->begin() + m_xIndexList->get_id(*xSelected).toUInt32();
            if (aSelected->isModified() || aSelected->isNew())
            {
                std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), u"dbaccess/ui/saveindexdialog.ui"_ustr));
                std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog(u"SaveIndexDialog"_ustr));
                nResponse = xQuery->run();
            }
        }

        switch (nResponse)
        {
            case RET_YES:
                if (!implCommitPreviouslySelected())
                    return;
                break;
            case RET_NO:
                break;
            default:
                return;
        }

        m_xDialog->response(RET_OK);
    }

    IMPL_LINK(DbaIndexDialog, OnEditIndexAgain, void*, p, void)
    {
        weld::TreeIter* pEntry = static_cast<weld::TreeIter*>(p);
        m_bEditAgain = false;
        m_xIndexList->grab_focus();
        m_xIndexList->start_editing(*pEntry);
        delete pEntry;
    }

    IMPL_LINK_NOARG(DbaIndexDialog, OnEntryEditing, const weld::TreeIter&, bool)
    {
        m_bEditingActive = true;
        return true;
    }

    IMPL_LINK(DbaIndexDialog, OnEntryEdited, const IterString&, rIterString, bool)
    {
        m_bEditingActive = false;

        const weld::TreeIter& rEntry = rIterString.first;
        OUString sNewName = rIterString.second;

        Indexes::iterator aPosition = m_xIndexes->begin() + m_xIndexList->get_id(rEntry).toUInt32();

        OSL_ENSURE(aPosition >= m_xIndexes->begin() && aPosition < m_xIndexes->end(),
            "DbaIndexDialog::OnEntryEdited: invalid entry!");

        Indexes::const_iterator aSameName = m_xIndexes->find(sNewName);
        if (aSameName != aPosition && m_xIndexes->end() != aSameName)
        {
            OUString sError(DBA_RES(STR_INDEX_NAME_ALREADY_USED));
            sError = sError.replaceFirst("$name$", sNewName);
            std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
                                                        VclMessageType::Warning, VclButtonsType::Ok,
                                                        sError));
            xError->run();

            updateToolbox();
            m_bEditAgain = true;
            std::unique_ptr<weld::TreeIter> xEntry(m_xIndexList->make_iterator(&rEntry));
            Application::PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), xEntry.release());
            return false;
        }

        aPosition->sName = sNewName;

        // rename can be done by a drop/insert combination only
        if (aPosition->isNew())
        {
            updateToolbox();
            // no commitment needed here...
            return true;
        }

        if (aPosition->sName != aPosition->getOriginalName())
        {
            aPosition->setModified(true);
            updateToolbox();
        }

        return true;
    }

    bool DbaIndexDialog::implSaveModified(bool _bPlausibility)
    {
        if (!m_xPreviousSelection)
            return true;

        // try to commit the previously selected index
        if (m_xFields->IsModified() && !m_xFields->SaveModified())
            return false;

        Indexes::iterator aPreviouslySelected = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();

        // the unique flag
        aPreviouslySelected->bUnique = m_xUnique->get_active();
        if (m_xUnique->get_state_changed_from_saved())
            aPreviouslySelected->setModified(true);

        // the fields
        m_xFields->commitTo(aPreviouslySelected->aFields);
        if (m_xFields->GetSavedValue() != aPreviouslySelected->aFields)
            aPreviouslySelected->setModified(true);

        // plausibility checks
        if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected))
            return false;

        return true;
    }

    bool DbaIndexDialog::implCheckPlausibility(const Indexes::const_iterator& _rPos)
    {
        // need at least one field
        if (_rPos->aFields.empty())
        {
            std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
                                                        VclMessageType::Warning, VclButtonsType::Ok,
                                                        DBA_RES(STR_NEED_INDEX_FIELDS)));
            xError->run();
            m_xFields->GrabFocus();
            return false;
        }

        // no double fields
        std::set< OUString > aExistentFields;
        for (auto const& fieldCheck : _rPos->aFields)
        {
            if (aExistentFields.end() != aExistentFields.find(fieldCheck.sFieldName))
            {
                // a column is specified twice ... won't work anyway, so prevent this here and now
                OUString sMessage(DBA_RES(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME));
                sMessage = sMessage.replaceFirst("$name$", fieldCheck.sFieldName);
                std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
                                                            VclMessageType::Warning, VclButtonsType::Ok,
                                                            sMessage));
                xError->run();
                m_xFields->GrabFocus();
                return false;
            }
            aExistentFields.insert(fieldCheck.sFieldName);
        }

        return true;
    }

    bool DbaIndexDialog::implCommitPreviouslySelected()
    {
        if (m_xPreviousSelection)
        {
            Indexes::const_iterator aPreviouslySelected = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();

            if (!implSaveModified())
                return false;

            // commit the index (if necessary)
            if (aPreviouslySelected->isModified() && !implCommit(m_xPreviousSelection.get()))
                return false;
        }

        return true;
    }

    IMPL_LINK_NOARG(DbaIndexDialog, OnModifiedClick, weld::Toggleable&, void)
    {
        OnModified(*m_xFields);
    }

    IMPL_LINK_NOARG( DbaIndexDialog, OnModified, IndexFieldsControl&, void )
    {
        assert(m_xPreviousSelection && "DbaIndexDialog, OnModified: invalid call!");
        Indexes::iterator aPosition = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();

        aPosition->setModified(true);
        updateToolbox();
    }

    void DbaIndexDialog::updateControls(const weld::TreeIter* pEntry)
    {
        if (pEntry)
        {
            // the descriptor of the selected index
            Indexes::const_iterator aSelectedIndex = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();

            // fill the controls
            m_xUnique->set_active(aSelectedIndex->bUnique);
            m_xUnique->set_sensitive(!aSelectedIndex->bPrimaryKey);
            m_xUnique->save_state();

            m_xFields->initializeFrom(std::vector(aSelectedIndex->aFields));
            m_xFields->Enable(!aSelectedIndex->bPrimaryKey);
            m_xFields->SaveValue();

            m_xDescription->set_label(aSelectedIndex->sDescription);
            m_xDescription->set_sensitive(!aSelectedIndex->bPrimaryKey);

            m_xDescriptionLabel->set_sensitive(!aSelectedIndex->bPrimaryKey);
        }
        else
        {
            m_xUnique->set_active(false);
            m_xFields->initializeFrom(IndexFields());
            m_xDescription->set_label(OUString());
        }
    }

    void DbaIndexDialog::IndexSelected()
    {
        if (m_bEditingActive)
            m_xIndexList->end_editing();

        std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
        if (!m_xIndexList->get_selected(xSelected.get()))
            xSelected.reset();

        // commit the old data
        if (m_xPreviousSelection && (!xSelected || !m_xPreviousSelection->equal(*xSelected)))
        {
            // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing)
            if (!implCommitPreviouslySelected())
            {
                m_bNoHandlerCall = true;
                m_xIndexList->select(*m_xPreviousSelection);
                m_bNoHandlerCall = false;
                return;
            }
        }

        // disable/enable the detail controls
        m_xIndexDetails->set_sensitive(xSelected != nullptr);
        m_xUnique->set_sensitive(xSelected != nullptr);
        m_xDescriptionLabel->set_sensitive(xSelected != nullptr);
        m_xFieldsLabel->set_sensitive(xSelected != nullptr);
        m_xFields->Enable(xSelected != nullptr);

        updateControls(xSelected.get());
        if (xSelected)
            m_xIndexList->grab_focus();

        m_xPreviousSelection = std::move(xSelected);

        updateToolbox();
    }

    IMPL_LINK_NOARG(DbaIndexDialog, OnIndexSelected, weld::TreeView&, void)
    {
        if (m_bNoHandlerCall)
            return;
        IndexSelected();
    }
}   // namespace dbaui

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

Messung V0.5
C=94 H=95 G=94

¤ Dauer der Verarbeitung: 0.2 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