Gtk-WARNING gtktreestore.c:1047: Invalid column number 1 added to iter
[LibreOffice.git] / dbaccess / source / ui / dlg / indexdialog.cxx
blob160eafa192ec4f0596d8c86b69d9b6411a2be92c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <set>
24 #include <core_resource.hxx>
25 #include <indexdialog.hxx>
26 #include <strings.hrc>
27 #include <bitmaps.hlst>
28 #include <indexfieldscontrol.hxx>
29 #include <indexcollection.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/weld.hxx>
32 #include <com/sun/star/sdb/SQLContext.hpp>
33 #include <connectivity/dbtools.hxx>
34 #include <osl/diagnose.h>
36 namespace dbaui
39 using namespace ::com::sun::star::uno;
40 using namespace ::com::sun::star::container;
41 using namespace ::com::sun::star::sdbc;
42 using namespace ::com::sun::star::sdb;
43 using namespace ::com::sun::star::lang;
44 using namespace ::dbtools;
46 // helper
47 static bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS)
49 return (_rLHS.sFieldName == _rRHS.sFieldName)
50 && (_rLHS.bSortAscending == _rRHS.bSortAscending);
53 static bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS)
55 return std::equal(_rLHS.begin(), _rLHS.end(), _rRHS.begin(), _rRHS.end());
58 static bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
60 return !(_rLHS == _rRHS);
63 // DbaIndexDialog
64 DbaIndexDialog::DbaIndexDialog(weld::Window* pParent, const Sequence< OUString >& _rFieldNames,
65 const Reference< XNameAccess >& _rxIndexes,
66 const Reference< XConnection >& _rxConnection,
67 const Reference< XComponentContext >& _rxContext)
68 : GenericDialogController(pParent, u"dbaccess/ui/indexdesigndialog.ui"_ustr, u"IndexDesignDialog"_ustr)
69 , m_xConnection(_rxConnection)
70 , m_bEditingActive(false)
71 , m_bEditAgain(false)
72 , m_bNoHandlerCall(false)
73 , m_xContext(_rxContext)
74 , m_xActions(m_xBuilder->weld_toolbar(u"ACTIONS"_ustr))
75 , m_xIndexList(m_xBuilder->weld_tree_view(u"INDEX_LIST"_ustr))
76 , m_xIndexDetails(m_xBuilder->weld_label(u"INDEX_DETAILS"_ustr))
77 , m_xDescriptionLabel(m_xBuilder->weld_label(u"DESC_LABEL"_ustr))
78 , m_xDescription(m_xBuilder->weld_label(u"DESCRIPTION"_ustr))
79 , m_xUnique(m_xBuilder->weld_check_button(u"UNIQUE"_ustr))
80 , m_xFieldsLabel(m_xBuilder->weld_label(u"FIELDS_LABEL"_ustr))
81 , m_xClose(m_xBuilder->weld_button(u"close"_ustr))
82 , m_xTable(m_xBuilder->weld_container(u"FIELDS"_ustr))
83 , m_xTableCtrlParent(m_xTable->CreateChildFrame())
84 , m_xFields(VclPtr<IndexFieldsControl>::Create(m_xTableCtrlParent))
86 m_xIndexList->set_size_request(m_xIndexList->get_approximate_digit_width() * 17,
87 m_xIndexList->get_height_rows(12));
89 int nWidth = m_xIndexList->get_approximate_digit_width() * 60;
90 int nHeight = m_xIndexList->get_height_rows(8);
91 m_xTable->set_size_request(nWidth, nHeight);
93 m_xActions->connect_clicked(LINK(this, DbaIndexDialog, OnIndexAction));
95 m_xIndexList->connect_selection_changed(LINK(this, DbaIndexDialog, OnIndexSelected));
96 m_xIndexList->connect_editing(LINK(this, DbaIndexDialog, OnEntryEditing),
97 LINK(this, DbaIndexDialog, OnEntryEdited));
99 m_xFields->SetSizePixel(Size(nWidth, 100));
100 m_xFields->Init(_rFieldNames, ::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" ));
101 m_xFields->Show();
103 m_xIndexes.reset(new OIndexCollection());
106 m_xIndexes->attach(_rxIndexes);
108 catch(SQLException& e)
110 ::dbtools::showError(SQLExceptionInfo(e), pParent->GetXWindow(), _rxContext);
112 catch(Exception&)
114 OSL_FAIL("DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
117 fillIndexList();
119 m_xUnique->connect_toggled(LINK(this, DbaIndexDialog, OnModifiedClick));
120 m_xFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified));
122 m_xClose->connect_clicked(LINK(this, DbaIndexDialog, OnCloseDialog));
124 // if all of the indexes have an empty description, we're not interested in displaying it
125 bool bFound = false;
126 for (auto const& check : *m_xIndexes)
128 if (!check.sDescription.isEmpty())
130 bFound = true;
131 break;
134 if (!bFound)
136 // hide the controls which are necessary for the description
137 m_xDescription->hide();
138 m_xDescriptionLabel->hide();
142 void DbaIndexDialog::updateToolbox()
144 m_xActions->set_item_sensitive(u"ID_INDEX_NEW"_ustr, !m_bEditingActive);
146 int nSelected = m_xIndexList->get_selected_index();
147 bool bSelectedAnything = nSelected != -1;
148 if (bSelectedAnything)
150 // is the current entry modified?
151 Indexes::const_iterator aSelectedPos = m_xIndexes->begin() + m_xIndexList->get_id(nSelected).toUInt32();
152 m_xActions->set_item_sensitive(u"ID_INDEX_SAVE"_ustr, aSelectedPos->isModified() || aSelectedPos->isNew());
153 m_xActions->set_item_sensitive(u"ID_INDEX_RESET"_ustr, aSelectedPos->isModified() || aSelectedPos->isNew());
154 bSelectedAnything = !aSelectedPos->bPrimaryKey;
156 else
158 m_xActions->set_item_sensitive(u"ID_INDEX_SAVE"_ustr, false);
159 m_xActions->set_item_sensitive(u"ID_INDEX_RESET"_ustr, false);
161 m_xActions->set_item_sensitive(u"ID_INDEX_DROP"_ustr, bSelectedAnything);
162 m_xActions->set_item_sensitive(u"ID_INDEX_RENAME"_ustr, bSelectedAnything);
165 void DbaIndexDialog::fillIndexList()
167 OUString aPKeyIcon(BMP_PKEYICON);
168 // fill the list with the index names
169 m_xIndexList->clear();
170 sal_uInt32 nPos = 0;
171 for (auto const& indexLoop : *m_xIndexes)
173 m_xIndexList->append(OUString::number(nPos), indexLoop.sName);
174 if (indexLoop.bPrimaryKey)
175 m_xIndexList->set_image(nPos, aPKeyIcon);
176 ++nPos;
179 if (nPos)
180 m_xIndexList->select(0);
182 IndexSelected();
185 DbaIndexDialog::~DbaIndexDialog( )
187 m_xIndexes.reset();
188 m_xFields.disposeAndClear();
189 m_xTableCtrlParent->dispose();
190 m_xTableCtrlParent.clear();
193 bool DbaIndexDialog::implCommit(const weld::TreeIter* pEntry)
195 assert(pEntry && "DbaIndexDialog::implCommit: invalid entry!");
197 Indexes::iterator aCommitPos = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();
199 // if it's not a new index, remove it
200 // (we can't modify indexes, only drop'n'insert)
201 if (!aCommitPos->isNew())
202 if (!implDropIndex(pEntry, false))
203 return false;
205 // create the new index
206 SQLExceptionInfo aExceptionInfo;
209 m_xIndexes->commitNewIndex(aCommitPos);
211 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
212 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
213 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
215 // reflect the new selection in the toolbox
216 updateToolbox();
218 if (aExceptionInfo.isValid())
219 showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
220 else
222 m_xUnique->save_state();
223 m_xFields->SaveValue();
226 return !aExceptionInfo.isValid();
229 void DbaIndexDialog::OnNewIndex()
231 // commit the current entry, if necessary
232 if (!implCommitPreviouslySelected())
233 return;
235 // get a new unique name for the new index
236 OUString sNewIndexName;
237 const OUString sNewIndexNameBase(DBA_RES(STR_LOGICAL_INDEX_NAME));
238 sal_Int32 i;
240 for ( i = 1; i < 0x7FFFFFFF; ++i )
242 sNewIndexName = sNewIndexNameBase + OUString::number(i);
243 if (m_xIndexes->end() == m_xIndexes->find(sNewIndexName))
244 break;
246 if (i == 0x7FFFFFFF)
248 OSL_FAIL("DbaIndexDialog::OnNewIndex: no free index name found!");
249 // can't do anything ... of course we try another base, but this could end with the same result ...
250 return;
253 std::unique_ptr<weld::TreeIter> xNewEntry(m_xIndexList->make_iterator());
254 m_xIndexList->insert(nullptr, -1, &sNewIndexName, nullptr, nullptr, nullptr, false, xNewEntry.get());
255 m_xIndexes->insert(sNewIndexName);
257 // update the user data on the entries in the list box:
258 // they're iterators of the index collection, and thus they have changed when removing the index
259 m_xIndexList->all_foreach([this](weld::TreeIter& rEntry){
260 Indexes::const_iterator aAfterInsertPos = m_xIndexes->find(m_xIndexList->get_text(rEntry));
261 OSL_ENSURE(aAfterInsertPos != m_xIndexes->end(), "DbaIndexDialog::OnNewIndex: problems with one of the entries!");
262 m_xIndexList->set_id(rEntry, OUString::number(aAfterInsertPos - m_xIndexes->begin()));
263 return false;
266 // select the entry and start in-place editing
267 m_bNoHandlerCall = true;
268 m_xIndexList->select(*xNewEntry);
269 m_bNoHandlerCall = false;
270 IndexSelected();
271 m_xIndexList->grab_focus();
272 m_xIndexList->start_editing(*xNewEntry);
273 updateToolbox();
276 void DbaIndexDialog::OnDropIndex(bool _bConfirm)
278 std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
279 // the selected index
280 if (!m_xIndexList->get_selected(xSelected.get()))
281 return;
283 // let the user confirm the drop
284 if (_bConfirm)
286 OUString sConfirm(DBA_RES(STR_CONFIRM_DROP_INDEX));
287 sConfirm = sConfirm.replaceFirst("$name$", m_xIndexList->get_text(*xSelected));
288 std::unique_ptr<weld::MessageDialog> xConfirm(Application::CreateMessageDialog(m_xDialog.get(),
289 VclMessageType::Question, VclButtonsType::YesNo,
290 sConfirm));
291 if (RET_YES != xConfirm->run())
292 return;
295 // do the drop
296 implDropIndex(xSelected.get(), true);
298 // reflect the new selection in the toolbox
299 updateToolbox();
302 bool DbaIndexDialog::implDropIndex(const weld::TreeIter* pEntry, bool _bRemoveFromCollection)
304 // do the drop
305 Indexes::iterator aDropPos = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();
306 OSL_ENSURE(aDropPos != m_xIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!");
308 SQLExceptionInfo aExceptionInfo;
309 bool bSuccess = false;
312 if (_bRemoveFromCollection)
313 bSuccess = m_xIndexes->drop(aDropPos);
314 else
315 bSuccess = m_xIndexes->dropNoRemove(aDropPos);
317 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
318 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
319 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
321 if (aExceptionInfo.isValid())
322 showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
323 else if (bSuccess && _bRemoveFromCollection)
325 m_bNoHandlerCall = true;
327 // if the entry to remove is the selected on...
328 if (m_xPreviousSelection && m_xPreviousSelection->equal(*pEntry))
329 m_xPreviousSelection.reset();
330 m_xIndexList->remove(*pEntry);
332 m_bNoHandlerCall = false;
334 // update the user data on the entries in the list box:
335 // they're iterators of the index collection, and thus they have changed when removing the index
336 m_xIndexList->all_foreach([this](weld::TreeIter& rEntry){
337 Indexes::const_iterator aAfterDropPos = m_xIndexes->find(m_xIndexList->get_text(rEntry));
338 OSL_ENSURE(aAfterDropPos != m_xIndexes->end(), "DbaIndexDialog::OnDropIndex: problems with one of the remaining entries!");
339 m_xIndexList->set_id(rEntry, OUString::number(aAfterDropPos - m_xIndexes->begin()));
340 return false;
343 // the Remove automatically selected another entry (if possible), but we disabled the calling of the handler
344 // to prevent that we missed something... call the handler directly
345 IndexSelected();
348 return !aExceptionInfo.isValid();
351 void DbaIndexDialog::OnRenameIndex()
353 // the selected iterator
354 std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
355 if (!m_xIndexList->get_selected(xSelected.get()))
356 return;
358 // save the changes made 'til here
359 // Upon leaving the edit mode, the control will be re-initialized with the
360 // settings from the current entry
361 implSaveModified(false);
363 m_xIndexList->grab_focus();
364 m_xIndexList->start_editing(*xSelected);
365 updateToolbox();
368 void DbaIndexDialog::OnSaveIndex()
370 // the selected index
371 implCommitPreviouslySelected();
372 updateToolbox();
375 void DbaIndexDialog::OnResetIndex()
377 // the selected index
378 std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
379 // the selected index
380 if (!m_xIndexList->get_selected(xSelected.get()))
381 xSelected.reset();
382 OSL_ENSURE(xSelected, "DbaIndexDialog::OnResetIndex: invalid call!");
383 if (!xSelected)
384 return;
386 Indexes::iterator aResetPos = m_xIndexes->begin() + m_xIndexList->get_id(*xSelected).toUInt32();
388 if (aResetPos->isNew())
390 OnDropIndex(false);
391 return;
394 SQLExceptionInfo aExceptionInfo;
397 m_xIndexes->resetIndex(aResetPos);
399 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
400 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
401 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
403 if (aExceptionInfo.isValid())
404 showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
405 else
406 m_xIndexList->set_text(*xSelected, aResetPos->sName);
408 updateControls(xSelected.get());
409 updateToolbox();
412 IMPL_LINK(DbaIndexDialog, OnIndexAction, const OUString&, rClicked, void)
414 if (rClicked == "ID_INDEX_NEW")
415 OnNewIndex();
416 else if (rClicked == "ID_INDEX_DROP")
417 OnDropIndex();
418 else if (rClicked == "ID_INDEX_RENAME")
419 OnRenameIndex();
420 else if (rClicked == "ID_INDEX_SAVE")
421 OnSaveIndex();
422 else if (rClicked == "ID_INDEX_RESET")
423 OnResetIndex();
426 IMPL_LINK_NOARG(DbaIndexDialog, OnCloseDialog, weld::Button&, void)
428 if (m_bEditingActive)
430 OSL_ENSURE(!m_bEditAgain, "DbaIndexDialog::OnCloseDialog: somebody was faster than hell!");
431 // this means somebody entered a new name, which was invalid, which cause us to posted us an event,
432 // and before the event arrived the user clicked onto "close". VERY fast, this user...
433 m_xIndexList->end_editing();
434 if (m_bEditAgain)
435 // could not commit the new name (started a new - asynchronous - edit trial)
436 return;
439 // the currently selected entry
440 std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
441 // the selected index
442 if (!m_xIndexList->get_selected(xSelected.get()))
443 xSelected.reset();
445 OSL_ENSURE(xSelected && m_xPreviousSelection && xSelected->equal(*m_xPreviousSelection), "DbaIndexDialog::OnCloseDialog: inconsistence!");
447 sal_Int32 nResponse = RET_NO;
448 if (xSelected)
450 // the descriptor
451 Indexes::const_iterator aSelected = m_xIndexes->begin() + m_xIndexList->get_id(*xSelected).toUInt32();
452 if (aSelected->isModified() || aSelected->isNew())
454 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), u"dbaccess/ui/saveindexdialog.ui"_ustr));
455 std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog(u"SaveIndexDialog"_ustr));
456 nResponse = xQuery->run();
460 switch (nResponse)
462 case RET_YES:
463 if (!implCommitPreviouslySelected())
464 return;
465 break;
466 case RET_NO:
467 break;
468 default:
469 return;
472 m_xDialog->response(RET_OK);
475 IMPL_LINK(DbaIndexDialog, OnEditIndexAgain, void*, p, void)
477 weld::TreeIter* pEntry = static_cast<weld::TreeIter*>(p);
478 m_bEditAgain = false;
479 m_xIndexList->grab_focus();
480 m_xIndexList->start_editing(*pEntry);
481 delete pEntry;
484 IMPL_LINK_NOARG(DbaIndexDialog, OnEntryEditing, const weld::TreeIter&, bool)
486 m_bEditingActive = true;
487 return true;
490 IMPL_LINK(DbaIndexDialog, OnEntryEdited, const IterString&, rIterString, bool)
492 m_bEditingActive = false;
494 const weld::TreeIter& rEntry = rIterString.first;
495 OUString sNewName = rIterString.second;
497 Indexes::iterator aPosition = m_xIndexes->begin() + m_xIndexList->get_id(rEntry).toUInt32();
499 OSL_ENSURE(aPosition >= m_xIndexes->begin() && aPosition < m_xIndexes->end(),
500 "DbaIndexDialog::OnEntryEdited: invalid entry!");
502 Indexes::const_iterator aSameName = m_xIndexes->find(sNewName);
503 if (aSameName != aPosition && m_xIndexes->end() != aSameName)
505 OUString sError(DBA_RES(STR_INDEX_NAME_ALREADY_USED));
506 sError = sError.replaceFirst("$name$", sNewName);
507 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
508 VclMessageType::Warning, VclButtonsType::Ok,
509 sError));
510 xError->run();
512 updateToolbox();
513 m_bEditAgain = true;
514 std::unique_ptr<weld::TreeIter> xEntry(m_xIndexList->make_iterator(&rEntry));
515 Application::PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), xEntry.release());
516 return false;
519 aPosition->sName = sNewName;
521 // rename can be done by a drop/insert combination only
522 if (aPosition->isNew())
524 updateToolbox();
525 // no commitment needed here...
526 return true;
529 if (aPosition->sName != aPosition->getOriginalName())
531 aPosition->setModified(true);
532 updateToolbox();
535 return true;
538 bool DbaIndexDialog::implSaveModified(bool _bPlausibility)
540 if (!m_xPreviousSelection)
541 return true;
543 // try to commit the previously selected index
544 if (m_xFields->IsModified() && !m_xFields->SaveModified())
545 return false;
547 Indexes::iterator aPreviouslySelected = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();
549 // the unique flag
550 aPreviouslySelected->bUnique = m_xUnique->get_active();
551 if (m_xUnique->get_state_changed_from_saved())
552 aPreviouslySelected->setModified(true);
554 // the fields
555 m_xFields->commitTo(aPreviouslySelected->aFields);
556 if (m_xFields->GetSavedValue() != aPreviouslySelected->aFields)
557 aPreviouslySelected->setModified(true);
559 // plausibility checks
560 if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected))
561 return false;
563 return true;
566 bool DbaIndexDialog::implCheckPlausibility(const Indexes::const_iterator& _rPos)
568 // need at least one field
569 if (_rPos->aFields.empty())
571 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
572 VclMessageType::Warning, VclButtonsType::Ok,
573 DBA_RES(STR_NEED_INDEX_FIELDS)));
574 xError->run();
575 m_xFields->GrabFocus();
576 return false;
579 // no double fields
580 std::set< OUString > aExistentFields;
581 for (auto const& fieldCheck : _rPos->aFields)
583 if (aExistentFields.end() != aExistentFields.find(fieldCheck.sFieldName))
585 // a column is specified twice ... won't work anyway, so prevent this here and now
586 OUString sMessage(DBA_RES(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME));
587 sMessage = sMessage.replaceFirst("$name$", fieldCheck.sFieldName);
588 std::unique_ptr<weld::MessageDialog> xError(Application::CreateMessageDialog(m_xDialog.get(),
589 VclMessageType::Warning, VclButtonsType::Ok,
590 sMessage));
591 xError->run();
592 m_xFields->GrabFocus();
593 return false;
595 aExistentFields.insert(fieldCheck.sFieldName);
598 return true;
601 bool DbaIndexDialog::implCommitPreviouslySelected()
603 if (m_xPreviousSelection)
605 Indexes::const_iterator aPreviouslySelected = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();
607 if (!implSaveModified())
608 return false;
610 // commit the index (if necessary)
611 if (aPreviouslySelected->isModified() && !implCommit(m_xPreviousSelection.get()))
612 return false;
615 return true;
618 IMPL_LINK_NOARG(DbaIndexDialog, OnModifiedClick, weld::Toggleable&, void)
620 OnModified(*m_xFields);
623 IMPL_LINK_NOARG( DbaIndexDialog, OnModified, IndexFieldsControl&, void )
625 assert(m_xPreviousSelection && "DbaIndexDialog, OnModified: invalid call!");
626 Indexes::iterator aPosition = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();
628 aPosition->setModified(true);
629 updateToolbox();
632 void DbaIndexDialog::updateControls(const weld::TreeIter* pEntry)
634 if (pEntry)
636 // the descriptor of the selected index
637 Indexes::const_iterator aSelectedIndex = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();
639 // fill the controls
640 m_xUnique->set_active(aSelectedIndex->bUnique);
641 m_xUnique->set_sensitive(!aSelectedIndex->bPrimaryKey);
642 m_xUnique->save_state();
644 m_xFields->initializeFrom(std::vector(aSelectedIndex->aFields));
645 m_xFields->Enable(!aSelectedIndex->bPrimaryKey);
646 m_xFields->SaveValue();
648 m_xDescription->set_label(aSelectedIndex->sDescription);
649 m_xDescription->set_sensitive(!aSelectedIndex->bPrimaryKey);
651 m_xDescriptionLabel->set_sensitive(!aSelectedIndex->bPrimaryKey);
653 else
655 m_xUnique->set_active(false);
656 m_xFields->initializeFrom(IndexFields());
657 m_xDescription->set_label(OUString());
661 void DbaIndexDialog::IndexSelected()
663 if (m_bEditingActive)
664 m_xIndexList->end_editing();
666 std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
667 if (!m_xIndexList->get_selected(xSelected.get()))
668 xSelected.reset();
670 // commit the old data
671 if (m_xPreviousSelection && (!xSelected || !m_xPreviousSelection->equal(*xSelected)))
673 // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing)
674 if (!implCommitPreviouslySelected())
676 m_bNoHandlerCall = true;
677 m_xIndexList->select(*m_xPreviousSelection);
678 m_bNoHandlerCall = false;
679 return;
683 // disable/enable the detail controls
684 m_xIndexDetails->set_sensitive(xSelected != nullptr);
685 m_xUnique->set_sensitive(xSelected != nullptr);
686 m_xDescriptionLabel->set_sensitive(xSelected != nullptr);
687 m_xFieldsLabel->set_sensitive(xSelected != nullptr);
688 m_xFields->Enable(xSelected != nullptr);
690 updateControls(xSelected.get());
691 if (xSelected)
692 m_xIndexList->grab_focus();
694 m_xPreviousSelection = std::move(xSelected);
696 updateToolbox();
699 IMPL_LINK_NOARG(DbaIndexDialog, OnIndexSelected, weld::TreeView&, void)
701 if (m_bNoHandlerCall)
702 return;
703 IndexSelected();
705 } // namespace dbaui
707 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */