LibreOffice Module dbaccess (master) 1
indexdialog.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <set>
23
24#include <core_resource.hxx>
25#include <indexdialog.hxx>
26#include <strings.hrc>
27#include <bitmaps.hlst>
29#include <indexcollection.hxx>
30#include <vcl/svapp.hxx>
31#include <vcl/weld.hxx>
32#include <com/sun/star/sdb/SQLContext.hpp>
34#include <osl/diagnose.h>
35
36namespace dbaui
37{
38
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;
45
46 // helper
47 static bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS)
48 {
49 return (_rLHS.sFieldName == _rRHS.sFieldName)
50 && (_rLHS.bSortAscending == _rRHS.bSortAscending);
51 }
52
53 static bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS)
54 {
55 return std::equal(_rLHS.begin(), _rLHS.end(), _rRHS.begin(), _rRHS.end());
56 }
57
58 static bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
59 {
60 return !(_rLHS == _rRHS);
61 }
62
63 // DbaIndexDialog
65 const Reference< XNameAccess >& _rxIndexes,
66 const Reference< XConnection >& _rxConnection,
67 const Reference< XComponentContext >& _rxContext)
68 : GenericDialogController(pParent, "dbaccess/ui/indexdesigndialog.ui", "IndexDesignDialog")
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("ACTIONS"))
75 , m_xIndexList(m_xBuilder->weld_tree_view("INDEX_LIST"))
76 , m_xIndexDetails(m_xBuilder->weld_label("INDEX_DETAILS"))
77 , m_xDescriptionLabel(m_xBuilder->weld_label("DESC_LABEL"))
78 , m_xDescription(m_xBuilder->weld_label("DESCRIPTION"))
79 , m_xUnique(m_xBuilder->weld_check_button("UNIQUE"))
80 , m_xFieldsLabel(m_xBuilder->weld_label("FIELDS_LABEL"))
81 , m_xClose(m_xBuilder->weld_button("close"))
82 , m_xTable(m_xBuilder->weld_container("FIELDS"))
83 , m_xTableCtrlParent(m_xTable->CreateChildFrame())
84 , m_xFields(VclPtr<IndexFieldsControl>::Create(m_xTableCtrlParent))
85 {
86 m_xIndexList->set_size_request(m_xIndexList->get_approximate_digit_width() * 17,
87 m_xIndexList->get_height_rows(12));
88
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);
92
93 m_xActions->connect_clicked(LINK(this, DbaIndexDialog, OnIndexAction));
94
95 m_xIndexList->connect_changed(LINK(this, DbaIndexDialog, OnIndexSelected));
96 m_xIndexList->connect_editing(LINK(this, DbaIndexDialog, OnEntryEditing),
97 LINK(this, DbaIndexDialog, OnEntryEdited));
98
99 m_xFields->SetSizePixel(Size(nWidth, 100));
100 m_xFields->Init(_rFieldNames, ::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" ));
101 m_xFields->Show();
102
103 m_xIndexes.reset(new OIndexCollection());
104 try
105 {
106 m_xIndexes->attach(_rxIndexes);
107 }
108 catch(SQLException& e)
109 {
110 ::dbtools::showError(SQLExceptionInfo(e), pParent->GetXWindow(), _rxContext);
111 }
112 catch(Exception&)
113 {
114 OSL_FAIL("DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
115 }
116
118
119 m_xUnique->connect_toggled(LINK(this, DbaIndexDialog, OnModifiedClick));
120 m_xFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified));
121
122 m_xClose->connect_clicked(LINK(this, DbaIndexDialog, OnCloseDialog));
123
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)
127 {
128 if (!check.sDescription.isEmpty())
129 {
130 bFound = true;
131 break;
132 }
133 }
134 if (!bFound)
135 {
136 // hide the controls which are necessary for the description
137 m_xDescription->hide();
138 m_xDescriptionLabel->hide();
139 }
140 }
141
143 {
144 m_xActions->set_item_sensitive("ID_INDEX_NEW", !m_bEditingActive);
145
146 int nSelected = m_xIndexList->get_selected_index();
147 bool bSelectedAnything = nSelected != -1;
148 if (bSelectedAnything)
149 {
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("ID_INDEX_SAVE", aSelectedPos->isModified() || aSelectedPos->isNew());
153 m_xActions->set_item_sensitive("ID_INDEX_RESET", aSelectedPos->isModified() || aSelectedPos->isNew());
154 bSelectedAnything = !aSelectedPos->bPrimaryKey;
155 }
156 else
157 {
158 m_xActions->set_item_sensitive("ID_INDEX_SAVE", false);
159 m_xActions->set_item_sensitive("ID_INDEX_RESET", false);
160 }
161 m_xActions->set_item_sensitive("ID_INDEX_DROP", bSelectedAnything);
162 m_xActions->set_item_sensitive("ID_INDEX_RENAME", bSelectedAnything);
163 }
164
166 {
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)
172 {
173 m_xIndexList->append(OUString::number(nPos), indexLoop.sName);
174 if (indexLoop.bPrimaryKey)
175 m_xIndexList->set_image(nPos, aPKeyIcon);
176 ++nPos;
177 }
178
179 if (nPos)
180 m_xIndexList->select(0);
181
183 }
184
186 {
187 m_xIndexes.reset();
188 m_xFields.disposeAndClear();
189 m_xTableCtrlParent->dispose();
190 m_xTableCtrlParent.clear();
191 }
192
194 {
195 assert(pEntry && "DbaIndexDialog::implCommit: invalid entry!");
196
197 Indexes::iterator aCommitPos = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();
198
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;
204
205 // create the new index
206 SQLExceptionInfo aExceptionInfo;
207 try
208 {
209 m_xIndexes->commitNewIndex(aCommitPos);
210 }
211 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
212 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
213 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
214
215 // reflect the new selection in the toolbox
217
218 if (aExceptionInfo.isValid())
219 showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
220 else
221 {
222 m_xUnique->save_state();
223 m_xFields->SaveValue();
224 }
225
226 return !aExceptionInfo.isValid();
227 }
228
230 {
231 // commit the current entry, if necessary
233 return;
234
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;
239
240 for ( i = 1; i < 0x7FFFFFFF; ++i )
241 {
242 sNewIndexName = sNewIndexNameBase + OUString::number(i);
243 if (m_xIndexes->end() == m_xIndexes->find(sNewIndexName))
244 break;
245 }
246 if (i == 0x7FFFFFFF)
247 {
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;
251 }
252
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);
256
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;
264 });
265
266 // select the entry and start in-place editing
267 m_bNoHandlerCall = true;
268 m_xIndexList->select(*xNewEntry);
269 m_bNoHandlerCall = false;
271 m_xIndexList->grab_focus();
272 m_xIndexList->start_editing(*xNewEntry);
274 }
275
276 void DbaIndexDialog::OnDropIndex(bool _bConfirm)
277 {
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;
282
283 // let the user confirm the drop
284 if (_bConfirm)
285 {
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;
293 }
294
295 // do the drop
296 implDropIndex(xSelected.get(), true);
297
298 // reflect the new selection in the toolbox
300 }
301
302 bool DbaIndexDialog::implDropIndex(const weld::TreeIter* pEntry, bool _bRemoveFromCollection)
303 {
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!");
307
308 SQLExceptionInfo aExceptionInfo;
309 bool bSuccess = false;
310 try
311 {
312 if (_bRemoveFromCollection)
313 bSuccess = m_xIndexes->drop(aDropPos);
314 else
315 bSuccess = m_xIndexes->dropNoRemove(aDropPos);
316 }
317 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
318 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
319 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
320
321 if (aExceptionInfo.isValid())
322 showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
323 else if (bSuccess && _bRemoveFromCollection)
324 {
325 m_bNoHandlerCall = true;
326
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);
331
332 m_bNoHandlerCall = false;
333
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;
341 });
342
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
346 }
347
348 return !aExceptionInfo.isValid();
349 }
350
352 {
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;
357
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);
362
363 m_xIndexList->grab_focus();
364 m_xIndexList->start_editing(*xSelected);
366 }
367
369 {
370 // the selected index
373 }
374
376 {
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;
385
386 Indexes::iterator aResetPos = m_xIndexes->begin() + m_xIndexList->get_id(*xSelected).toUInt32();
387
388 if (aResetPos->isNew())
389 {
390 OnDropIndex(false);
391 return;
392 }
393
394 SQLExceptionInfo aExceptionInfo;
395 try
396 {
397 m_xIndexes->resetIndex(aResetPos);
398 }
399 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
400 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
401 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
402
403 if (aExceptionInfo.isValid())
404 showError(aExceptionInfo, m_xDialog->GetXWindow(), m_xContext);
405 else
406 m_xIndexList->set_text(*xSelected, aResetPos->sName);
407
408 updateControls(xSelected.get());
410 }
411
412 IMPL_LINK(DbaIndexDialog, OnIndexAction, const OUString&, rClicked, void)
413 {
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();
424 }
425
427 {
428 if (m_bEditingActive)
429 {
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;
437 }
438
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();
444
445 OSL_ENSURE(xSelected && m_xPreviousSelection && xSelected->equal(*m_xPreviousSelection), "DbaIndexDialog::OnCloseDialog: inconsistence!");
446
447 sal_Int32 nResponse = RET_NO;
448 if (xSelected)
449 {
450 // the descriptor
451 Indexes::const_iterator aSelected = m_xIndexes->begin() + m_xIndexList->get_id(*xSelected).toUInt32();
452 if (aSelected->isModified() || aSelected->isNew())
453 {
454 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), "dbaccess/ui/saveindexdialog.ui"));
455 std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("SaveIndexDialog"));
456 nResponse = xQuery->run();
457 }
458 }
459
460 switch (nResponse)
461 {
462 case RET_YES:
463 if (!implCommitPreviouslySelected())
464 return;
465 break;
466 case RET_NO:
467 break;
468 default:
469 return;
470 }
471
472 m_xDialog->response(RET_OK);
473 }
474
475 IMPL_LINK(DbaIndexDialog, OnEditIndexAgain, void*, p, void)
476 {
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;
482 }
483
484 IMPL_LINK_NOARG(DbaIndexDialog, OnEntryEditing, const weld::TreeIter&, bool)
485 {
486 m_bEditingActive = true;
487 return true;
488 }
489
490 IMPL_LINK(DbaIndexDialog, OnEntryEdited, const IterString&, rIterString, bool)
491 {
492 m_bEditingActive = false;
493
494 const weld::TreeIter& rEntry = rIterString.first;
495 OUString sNewName = rIterString.second;
496
497 Indexes::iterator aPosition = m_xIndexes->begin() + m_xIndexList->get_id(rEntry).toUInt32();
498
499 OSL_ENSURE(aPosition >= m_xIndexes->begin() && aPosition < m_xIndexes->end(),
500 "DbaIndexDialog::OnEntryEdited: invalid entry!");
501
502 Indexes::const_iterator aSameName = m_xIndexes->find(sNewName);
503 if (aSameName != aPosition && m_xIndexes->end() != aSameName)
504 {
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();
511
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;
517 }
518
519 aPosition->sName = sNewName;
520
521 // rename can be done by a drop/insert combination only
522 if (aPosition->isNew())
523 {
524 updateToolbox();
525 // no commitment needed here...
526 return true;
527 }
528
529 if (aPosition->sName != aPosition->getOriginalName())
530 {
531 aPosition->setModified(true);
532 updateToolbox();
533 }
534
535 return true;
536 }
537
538 bool DbaIndexDialog::implSaveModified(bool _bPlausibility)
539 {
541 return true;
542
543 // try to commit the previously selected index
544 if (m_xFields->IsModified() && !m_xFields->SaveModified())
545 return false;
546
547 Indexes::iterator aPreviouslySelected = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();
548
549 // the unique flag
550 aPreviouslySelected->bUnique = m_xUnique->get_active();
551 if (m_xUnique->get_state_changed_from_saved())
552 aPreviouslySelected->setModified(true);
553
554 // the fields
555 m_xFields->commitTo(aPreviouslySelected->aFields);
556 if (m_xFields->GetSavedValue() != aPreviouslySelected->aFields)
557 aPreviouslySelected->setModified(true);
558
559 // plausibility checks
560 if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected))
561 return false;
562
563 return true;
564 }
565
566 bool DbaIndexDialog::implCheckPlausibility(const Indexes::const_iterator& _rPos)
567 {
568 // need at least one field
569 if (_rPos->aFields.empty())
570 {
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;
577 }
578
579 // no double fields
580 std::set< OUString > aExistentFields;
581 for (auto const& fieldCheck : _rPos->aFields)
582 {
583 if (aExistentFields.end() != aExistentFields.find(fieldCheck.sFieldName))
584 {
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;
594 }
595 aExistentFields.insert(fieldCheck.sFieldName);
596 }
597
598 return true;
599 }
600
602 {
604 {
605 Indexes::const_iterator aPreviouslySelected = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();
606
607 if (!implSaveModified())
608 return false;
609
610 // commit the index (if necessary)
611 if (aPreviouslySelected->isModified() && !implCommit(m_xPreviousSelection.get()))
612 return false;
613 }
614
615 return true;
616 }
617
619 {
620 OnModified(*m_xFields);
621 }
622
624 {
625 assert(m_xPreviousSelection && "DbaIndexDialog, OnModified: invalid call!");
626 Indexes::iterator aPosition = m_xIndexes->begin() + m_xIndexList->get_id(*m_xPreviousSelection).toUInt32();
627
628 aPosition->setModified(true);
629 updateToolbox();
630 }
631
633 {
634 if (pEntry)
635 {
636 // the descriptor of the selected index
637 Indexes::const_iterator aSelectedIndex = m_xIndexes->begin() + m_xIndexList->get_id(*pEntry).toUInt32();
638
639 // fill the controls
640 m_xUnique->set_active(aSelectedIndex->bUnique);
641 m_xUnique->set_sensitive(!aSelectedIndex->bPrimaryKey);
642 m_xUnique->save_state();
643
644 m_xFields->initializeFrom(std::vector(aSelectedIndex->aFields));
645 m_xFields->Enable(!aSelectedIndex->bPrimaryKey);
646 m_xFields->SaveValue();
647
648 m_xDescription->set_label(aSelectedIndex->sDescription);
649 m_xDescription->set_sensitive(!aSelectedIndex->bPrimaryKey);
650
651 m_xDescriptionLabel->set_sensitive(!aSelectedIndex->bPrimaryKey);
652 }
653 else
654 {
655 m_xUnique->set_active(false);
656 m_xFields->initializeFrom(IndexFields());
657 m_xDescription->set_label(OUString());
658 }
659 }
660
662 {
664 m_xIndexList->end_editing();
665
666 std::unique_ptr<weld::TreeIter> xSelected(m_xIndexList->make_iterator());
667 if (!m_xIndexList->get_selected(xSelected.get()))
668 xSelected.reset();
669
670 // commit the old data
671 if (m_xPreviousSelection && (!xSelected || !m_xPreviousSelection->equal(*xSelected)))
672 {
673 // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing)
675 {
676 m_bNoHandlerCall = true;
678 m_bNoHandlerCall = false;
679 return;
680 }
681 }
682
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);
689
690 updateControls(xSelected.get());
691 if (xSelected)
692 m_xIndexList->grab_focus();
693
694 m_xPreviousSelection = std::move(xSelected);
695
697 }
698
700 {
701 if (m_bNoHandlerCall)
702 return;
703 IndexSelected();
704 }
705} // namespace dbaui
706
707/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XExecutableDialog > m_xDialog
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
std::unique_ptr< weld::Container > m_xTable
Definition: indexdialog.hxx:55
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: indexdialog.hxx:45
css::uno::Reference< css::awt::XWindow > m_xTableCtrlParent
Definition: indexdialog.hxx:56
std::unique_ptr< OIndexCollection > m_xIndexes
Definition: indexdialog.hxx:38
virtual ~DbaIndexDialog() override
bool implCommitPreviouslySelected()
std::unique_ptr< weld::Label > m_xDescription
Definition: indexdialog.hxx:51
css::uno::Reference< css::sdbc::XConnection > m_xConnection
Definition: indexdialog.hxx:36
std::unique_ptr< weld::Label > m_xDescriptionLabel
Definition: indexdialog.hxx:50
std::unique_ptr< weld::Toolbar > m_xActions
Definition: indexdialog.hxx:47
std::unique_ptr< weld::Button > m_xClose
Definition: indexdialog.hxx:54
void updateControls(const weld::TreeIter *pEntry)
DbaIndexDialog(weld::Window *_pParent, const css::uno::Sequence< OUString > &_rFieldNames, const css::uno::Reference< css::container::XNameAccess > &_rxIndexes, const css::uno::Reference< css::sdbc::XConnection > &_rxConnection, const css::uno::Reference< css::uno::XComponentContext > &_rxContext)
Definition: indexdialog.cxx:64
std::unique_ptr< weld::Label > m_xIndexDetails
Definition: indexdialog.hxx:49
bool implDropIndex(const weld::TreeIter *pEntry, bool _bRemoveFromCollection)
std::unique_ptr< weld::TreeIter > m_xPreviousSelection
Definition: indexdialog.hxx:39
std::unique_ptr< weld::TreeView > m_xIndexList
Definition: indexdialog.hxx:48
void OnDropIndex(bool _bConfirm=true)
bool implSaveModified(bool _bPlausibility=true)
VclPtr< IndexFieldsControl > m_xFields
Definition: indexdialog.hxx:57
std::unique_ptr< weld::CheckButton > m_xUnique
Definition: indexdialog.hxx:52
bool implCheckPlausibility(const Indexes::const_iterator &_rPos)
bool implCommit(const weld::TreeIter *pEntry)
std::unique_ptr< weld::Label > m_xFieldsLabel
Definition: indexdialog.hxx:53
std::shared_ptr< weld::Dialog > m_xDialog
virtual css::uno::Reference< css::awt::XWindow > GetXWindow()=0
Reference< XComponentContext > m_xContext
#define DBA_RES(id)
void * p
sal_uInt16 nPos
@ Exception
IMPL_LINK_NOARG(OApplicationController, OnClipboardChanged, TransferableDataHelper *, void)
IMPL_LINK(OApplicationController, OnSelectContainer, void *, _pType, void)
static bool operator==(const OIndexField &_rLHS, const OIndexField &_rRHS)
Definition: indexdialog.cxx:47
std::vector< OIndexField > IndexFields
Definition: indexes.hxx:39
static bool operator!=(const IndexFields &_rLHS, const IndexFields &_rRHS)
Definition: indexdialog.cxx:58
void showError(const SQLExceptionInfo &_rInfo, const Reference< XWindow > &_xParent, const Reference< XComponentContext > &_rxContext)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > > check(dp_misc::DescriptionInfoset const &infoset)
int i
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
end
Reference< XConnection > m_xConnection
Definition: objectnames.cxx:79
OUString sMessage
Definition: sqlmessage.cxx:159
OUString sFieldName
Definition: indexes.hxx:33
RET_OK
RET_NO
RET_YES