summaryrefslogtreecommitdiffstats
path: root/dbaccess/source/ui/dlg/indexdialog.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /dbaccess/source/ui/dlg/indexdialog.cxx
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dbaccess/source/ui/dlg/indexdialog.cxx')
-rw-r--r--dbaccess/source/ui/dlg/indexdialog.cxx707
1 files changed, 707 insertions, 0 deletions
diff --git a/dbaccess/source/ui/dlg/indexdialog.cxx b/dbaccess/source/ui/dlg/indexdialog.cxx
new file mode 100644
index 000000000..978fa9f36
--- /dev/null
+++ b/dbaccess/source/ui/dlg/indexdialog.cxx
@@ -0,0 +1,707 @@
+/* -*- 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, "dbaccess/ui/indexdesigndialog.ui", "IndexDesignDialog")
+ , m_xConnection(_rxConnection)
+ , m_bEditingActive(false)
+ , m_bEditAgain(false)
+ , m_bNoHandlerCall(false)
+ , m_xContext(_rxContext)
+ , m_xActions(m_xBuilder->weld_toolbar("ACTIONS"))
+ , m_xIndexList(m_xBuilder->weld_tree_view("INDEX_LIST"))
+ , m_xIndexDetails(m_xBuilder->weld_label("INDEX_DETAILS"))
+ , m_xDescriptionLabel(m_xBuilder->weld_label("DESC_LABEL"))
+ , m_xDescription(m_xBuilder->weld_label("DESCRIPTION"))
+ , m_xUnique(m_xBuilder->weld_check_button("UNIQUE"))
+ , m_xFieldsLabel(m_xBuilder->weld_label("FIELDS_LABEL"))
+ , m_xClose(m_xBuilder->weld_button("close"))
+ , m_xTable(m_xBuilder->weld_container("FIELDS"))
+ , 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_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_clicked(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("ID_INDEX_NEW", !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("ID_INDEX_SAVE", aSelectedPos->isModified() || aSelectedPos->isNew());
+ m_xActions->set_item_sensitive("ID_INDEX_RESET", aSelectedPos->isModified() || aSelectedPos->isNew());
+ bSelectedAnything = !aSelectedPos->bPrimaryKey;
+ }
+ else
+ {
+ m_xActions->set_item_sensitive("ID_INDEX_SAVE", false);
+ m_xActions->set_item_sensitive("ID_INDEX_RESET", false);
+ }
+ m_xActions->set_item_sensitive("ID_INDEX_DROP", bSelectedAnything);
+ m_xActions->set_item_sensitive("ID_INDEX_RENAME", 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, 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 OString&, 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(), "dbaccess/ui/saveindexdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("SaveIndexDialog"));
+ 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)
+ {
+ // 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::Button&, 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(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: */