/* -*- 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 .
*/
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!");
}
// if all of the indexes have an empty description, we're not interested in displaying it bool bFound = false; for (autoconst& 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();
}
}
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 (autoconst& indexLoop : *m_xIndexes)
{
m_xIndexList->append(OUString::number(nPos), indexLoop.sName); if (indexLoop.bPrimaryKey)
m_xIndexList->set_image(nPos, aPKeyIcon);
++nPos;
}
// 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)) returnfalse;
// 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;
}
// 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())); returnfalse;
});
// 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!");
// 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())); returnfalse;
});
// 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);
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;
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();
// 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)) returnfalse;
returntrue;
}
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(); returnfalse;
}
// no double fields
std::set< OUString > aExistentFields; for (autoconst& 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(); returnfalse;
}
aExistentFields.insert(fieldCheck.sFieldName);
}
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();
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;
}
}
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.