Line data Source code
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 "indexdialog.hxx"
25 : #include "dbu_dlg.hrc"
26 : #include "dbaccess_helpid.hrc"
27 : #include "indexfieldscontrol.hxx"
28 : #include "indexcollection.hxx"
29 : #include <vcl/layout.hxx>
30 : #include <vcl/settings.hxx>
31 : #include <vcl/builderfactory.hxx>
32 : #include <com/sun/star/sdb/SQLContext.hpp>
33 : #include "UITools.hxx"
34 : #include <svtools/imgdef.hxx>
35 : #include "svtools/treelistentry.hxx"
36 : #include "browserids.hxx"
37 : #include <connectivity/dbtools.hxx>
38 : #include <osl/diagnose.h>
39 :
40 : const char INDEX_NEW_CMD[] = ".index:createNew";
41 : const char INDEX_DROP_CMD[] = ".index:dropCurrent";
42 : const char INDEX_RENAME_CMD[] = ".index:renameCurrent";
43 : const char INDEX_SAVE_CMD[] = ".index:saveCurrent";
44 : const char INDEX_RESET_CMD[] = ".index:resetCurrent";
45 :
46 : namespace dbaui
47 : {
48 :
49 : using namespace ::com::sun::star::uno;
50 : using namespace ::com::sun::star::container;
51 : using namespace ::com::sun::star::sdbc;
52 : using namespace ::com::sun::star::sdb;
53 : using namespace ::com::sun::star::lang;
54 : using namespace ::dbtools;
55 :
56 : // helper
57 0 : bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS)
58 : {
59 0 : return (_rLHS.sFieldName == _rRHS.sFieldName)
60 0 : && (_rLHS.bSortAscending == _rRHS.bSortAscending);
61 : }
62 :
63 0 : bool operator !=(const OIndexField& _rLHS, const OIndexField& _rRHS)
64 : {
65 0 : return !(_rLHS == _rRHS);
66 : }
67 :
68 0 : bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS)
69 : {
70 0 : if (_rLHS.size() != _rRHS.size())
71 0 : return false;
72 :
73 0 : IndexFields::const_iterator aLeft = _rLHS.begin();
74 0 : IndexFields::const_iterator aLeftEnd = _rLHS.end();
75 0 : IndexFields::const_iterator aRight = _rRHS.begin();
76 0 : for (; aLeft != aLeftEnd; ++aLeft, ++aRight)
77 : {
78 0 : if (*aLeft != *aRight)
79 0 : return false;
80 : }
81 :
82 0 : return true;
83 : }
84 :
85 0 : bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
86 : {
87 0 : return !(_rLHS == _rRHS);
88 : }
89 :
90 : // DbaIndexList
91 0 : DbaIndexList::DbaIndexList(vcl::Window* _pParent, WinBits nWinBits)
92 : :SvTreeListBox(_pParent, nWinBits)
93 0 : ,m_bSuspendSelectHdl(false)
94 : {
95 0 : }
96 :
97 0 : bool DbaIndexList::EditedEntry( SvTreeListEntry* _pEntry, const OUString& _rNewText )
98 : {
99 : // first check if this is valid SQL92 name
100 0 : if ( isSQL92CheckEnabled(m_xConnection) )
101 : {
102 0 : Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
103 0 : if ( xMeta.is() )
104 : {
105 0 : OUString sAlias = ::dbtools::convertName2SQLName(_rNewText, xMeta->getExtraNameCharacters());
106 0 : if ( ( xMeta->supportsMixedCaseQuotedIdentifiers() )
107 : ?
108 : sAlias != _rNewText
109 : :
110 0 : !_rNewText.equalsIgnoreAsciiCase(sAlias))
111 0 : return false;
112 0 : }
113 : }
114 :
115 0 : if (!SvTreeListBox::EditedEntry(_pEntry, _rNewText))
116 0 : return false;
117 :
118 0 : OUString sOldText = GetEntryText(_pEntry);
119 0 : SvTreeListBox::SetEntryText(_pEntry, _rNewText);
120 :
121 0 : bool bValid = true;
122 0 : if (m_aEndEditHdl.IsSet())
123 0 : bValid = (0 != m_aEndEditHdl.Call(_pEntry));
124 :
125 0 : if (bValid)
126 0 : return true;
127 :
128 0 : SvTreeListBox::SetEntryText(_pEntry, sOldText);
129 :
130 0 : return false;
131 : }
132 :
133 0 : void DbaIndexList::enableSelectHandler()
134 : {
135 : OSL_ENSURE(m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
136 0 : m_bSuspendSelectHdl = false;
137 0 : }
138 :
139 0 : void DbaIndexList::disableSelectHandler()
140 : {
141 : OSL_ENSURE(!m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
142 0 : m_bSuspendSelectHdl = true;
143 0 : }
144 :
145 0 : void DbaIndexList::SelectNoHandlerCall( SvTreeListEntry* _pEntry )
146 : {
147 0 : disableSelectHandler();
148 0 : Select(_pEntry, true);
149 0 : enableSelectHandler();
150 0 : }
151 :
152 0 : bool DbaIndexList::Select(SvTreeListEntry* pEntry, bool _bSelect)
153 : {
154 0 : bool bReturn = SvTreeListBox::Select(pEntry, _bSelect);
155 :
156 0 : if (m_aSelectHdl.IsSet() && !m_bSuspendSelectHdl && _bSelect)
157 0 : m_aSelectHdl.Call(this);
158 :
159 0 : return bReturn;
160 : }
161 :
162 0 : VCL_BUILDER_FACTORY_ARGS(DbaIndexList, WB_BORDER)
163 :
164 : // DbaIndexDialog
165 0 : DbaIndexDialog::DbaIndexDialog( vcl::Window* _pParent, const Sequence< OUString >& _rFieldNames,
166 : const Reference< XNameAccess >& _rxIndexes,
167 : const Reference< XConnection >& _rxConnection,
168 : const Reference< XComponentContext >& _rxContext,sal_Int32 _nMaxColumnsInIndex)
169 : :ModalDialog( _pParent, "IndexDesignDialog", "dbaccess/ui/indexdesigndialog.ui")
170 : ,m_xConnection(_rxConnection)
171 : ,m_aGeometrySettings(E_DIALOG, OUString("dbaccess.tabledesign.indexdialog"))
172 : ,m_pIndexes(NULL)
173 : ,m_pPreviousSelection(NULL)
174 : ,m_bEditAgain(false)
175 0 : ,m_xContext(_rxContext)
176 : {
177 0 : get(m_pActions, "ACTIONS");
178 :
179 0 : mnNewCmdId = m_pActions->GetItemId(INDEX_NEW_CMD);
180 0 : mnDropCmdId = m_pActions->GetItemId(INDEX_DROP_CMD);
181 0 : mnRenameCmdId = m_pActions->GetItemId(INDEX_RENAME_CMD);
182 0 : mnSaveCmdId = m_pActions->GetItemId(INDEX_SAVE_CMD);
183 0 : mnResetCmdId = m_pActions->GetItemId(INDEX_RESET_CMD);
184 :
185 0 : maScNewCmdImg = m_pActions->GetItemImage(mnNewCmdId);
186 0 : maScDropCmdImg = m_pActions->GetItemImage(mnDropCmdId);
187 0 : maScRenameCmdImg = m_pActions->GetItemImage(mnRenameCmdId);
188 0 : maScSaveCmdImg = m_pActions->GetItemImage(mnSaveCmdId);
189 0 : maScResetCmdImg = m_pActions->GetItemImage(mnResetCmdId);
190 0 : maLcNewCmdImg = get<FixedImage>("image1")->GetImage();
191 0 : maLcDropCmdImg = get<FixedImage>("image2")->GetImage();
192 0 : maLcRenameCmdImg = get<FixedImage>("image3")->GetImage();
193 0 : maLcSaveCmdImg = get<FixedImage>("image4")->GetImage();
194 0 : maLcResetCmdImg = get<FixedImage>("image5")->GetImage();
195 :
196 0 : get(m_pIndexList, "INDEX_LIST");
197 0 : Size aSize(LogicToPixel(Size(70, 97), MAP_APPFONT));
198 0 : m_pIndexList->set_width_request(aSize.Width());
199 0 : m_pIndexList->set_height_request(aSize.Height());
200 0 : get(m_pIndexDetails, "INDEX_DETAILS");
201 0 : get(m_pDescriptionLabel, "DESC_LABEL");
202 0 : get(m_pDescription, "DESCRIPTION");
203 0 : get(m_pUnique, "UNIQUE");
204 0 : get(m_pFieldsLabel, "FIELDS_LABEL");
205 0 : get(m_pFields, "FIELDS");
206 0 : aSize = LogicToPixel(Size(128, 61), MAP_APPFONT);
207 0 : m_pFields->set_width_request(aSize.Width());
208 0 : m_pFields->set_height_request(aSize.Height());
209 0 : get(m_pClose, "close");
210 :
211 0 : m_pActions->SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexAction));
212 :
213 0 : m_pIndexList->SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexSelected));
214 0 : m_pIndexList->SetEndEditHdl(LINK(this, DbaIndexDialog, OnEntryEdited));
215 0 : m_pIndexList->SetSelectionMode(SINGLE_SELECTION);
216 0 : m_pIndexList->SetHighlightRange();
217 0 : m_pIndexList->setConnection(m_xConnection);
218 :
219 0 : m_pFields->SetSizePixel(Size(300, 100));
220 0 : m_pFields->Init(_rFieldNames, _nMaxColumnsInIndex, ::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" ));
221 :
222 0 : setToolBox(m_pActions);
223 :
224 0 : m_pIndexes = new OIndexCollection();
225 : try
226 : {
227 0 : m_pIndexes->attach(_rxIndexes);
228 : }
229 0 : catch(SQLException& e)
230 : {
231 0 : ::dbaui::showError(SQLExceptionInfo(e),_pParent,_rxContext);
232 : }
233 0 : catch(Exception&)
234 : {
235 : OSL_FAIL("DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
236 : }
237 :
238 0 : fillIndexList();
239 :
240 0 : m_pUnique->SetClickHdl(LINK(this, DbaIndexDialog, OnModified));
241 0 : m_pFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified));
242 :
243 0 : m_pClose->SetClickHdl(LINK(this, DbaIndexDialog, OnCloseDialog));
244 :
245 : // if all of the indexes have an empty description, we're not interested in displaying it
246 0 : Indexes::const_iterator aCheck;
247 :
248 0 : for ( aCheck = m_pIndexes->begin();
249 0 : aCheck != m_pIndexes->end();
250 : ++aCheck
251 : )
252 : {
253 0 : if (!aCheck->sDescription.isEmpty())
254 0 : break;
255 : }
256 :
257 0 : if (aCheck == m_pIndexes->end())
258 : {
259 : // hide the controls which are necessary for the description
260 0 : m_pDescription->Hide();
261 0 : m_pDescriptionLabel->Hide();
262 : }
263 0 : }
264 :
265 0 : void DbaIndexDialog::updateToolbox()
266 : {
267 0 : m_pActions->EnableItem(mnNewCmdId, !m_pIndexList->IsEditingActive());
268 :
269 0 : SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
270 0 : bool bSelectedAnything = NULL != pSelected;
271 :
272 0 : if (pSelected)
273 : {
274 : // is the current entry modified?
275 0 : Indexes::const_iterator aSelectedPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
276 0 : m_pActions->EnableItem(mnSaveCmdId, aSelectedPos->isModified() || aSelectedPos->isNew());
277 0 : m_pActions->EnableItem(mnResetCmdId, aSelectedPos->isModified() || aSelectedPos->isNew());
278 0 : bSelectedAnything = bSelectedAnything && !aSelectedPos->bPrimaryKey;
279 : }
280 : else
281 : {
282 0 : m_pActions->EnableItem(mnSaveCmdId, false);
283 0 : m_pActions->EnableItem(mnResetCmdId, false);
284 : }
285 0 : m_pActions->EnableItem(mnDropCmdId, bSelectedAnything);
286 0 : m_pActions->EnableItem(mnRenameCmdId, bSelectedAnything);
287 0 : }
288 :
289 0 : void DbaIndexDialog::fillIndexList()
290 : {
291 0 : Image aPKeyIcon(ModuleRes( IMG_PKEYICON ));
292 : // fill the list with the index names
293 0 : m_pIndexList->Clear();
294 0 : Indexes::iterator aIndexLoop = m_pIndexes->begin();
295 0 : Indexes::iterator aEnd = m_pIndexes->end();
296 0 : for (; aIndexLoop != aEnd; ++aIndexLoop)
297 : {
298 0 : SvTreeListEntry* pNewEntry = NULL;
299 0 : if (aIndexLoop->bPrimaryKey)
300 0 : pNewEntry = m_pIndexList->InsertEntry(aIndexLoop->sName, aPKeyIcon, aPKeyIcon);
301 : else
302 0 : pNewEntry = m_pIndexList->InsertEntry(aIndexLoop->sName);
303 :
304 0 : pNewEntry->SetUserData(reinterpret_cast< void* >(sal_Int32(aIndexLoop - m_pIndexes->begin())));
305 : }
306 :
307 0 : OnIndexSelected(m_pIndexList);
308 0 : }
309 :
310 0 : DbaIndexDialog::~DbaIndexDialog( )
311 : {
312 0 : disposeOnce();
313 0 : }
314 :
315 0 : void DbaIndexDialog::dispose()
316 : {
317 0 : setToolBox(NULL);
318 0 : delete m_pIndexes;
319 0 : m_pActions.clear();
320 0 : m_pIndexList.clear();
321 0 : m_pIndexDetails.clear();
322 0 : m_pDescriptionLabel.clear();
323 0 : m_pDescription.clear();
324 0 : m_pUnique.clear();
325 0 : m_pFieldsLabel.clear();
326 0 : m_pFields.clear();
327 0 : m_pClose.clear();
328 0 : ModalDialog::dispose();
329 0 : }
330 :
331 0 : bool DbaIndexDialog::implCommit(SvTreeListEntry* _pEntry)
332 : {
333 : OSL_ENSURE(_pEntry, "DbaIndexDialog::implCommit: invalid entry!");
334 :
335 0 : Indexes::iterator aCommitPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
336 :
337 : // if it's not a new index, remove it
338 : // (we can't modify indexes, only drop'n'insert)
339 0 : if (!aCommitPos->isNew())
340 0 : if (!implDropIndex(_pEntry, false))
341 0 : return false;
342 :
343 : // create the new index
344 0 : SQLExceptionInfo aExceptionInfo;
345 : try
346 : {
347 0 : m_pIndexes->commitNewIndex(aCommitPos);
348 : }
349 0 : catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
350 0 : catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
351 0 : catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
352 :
353 : // reflect the new selection in the toolbox
354 0 : updateToolbox();
355 :
356 0 : if (aExceptionInfo.isValid())
357 0 : showError(aExceptionInfo, this, m_xContext);
358 : else
359 : {
360 0 : m_pUnique->SaveValue();
361 0 : m_pFields->SaveValue();
362 : }
363 :
364 0 : return !aExceptionInfo.isValid();
365 : }
366 :
367 0 : void DbaIndexDialog::OnNewIndex()
368 : {
369 : // commit the current entry, if necessary
370 0 : if (!implCommitPreviouslySelected())
371 0 : return;
372 :
373 : // get a new unique name for the new index
374 0 : OUString sNewIndexName;
375 0 : const OUString sNewIndexNameBase(ModuleRes(STR_LOGICAL_INDEX_NAME));
376 : sal_Int32 i;
377 :
378 0 : for ( i = 1; i < 0x7FFFFFFF; ++i )
379 : {
380 0 : sNewIndexName = sNewIndexNameBase;
381 0 : sNewIndexName += OUString::number(i);
382 0 : if (m_pIndexes->end() == m_pIndexes->find(sNewIndexName))
383 0 : break;
384 : }
385 0 : if (i == 0x7FFFFFFF)
386 : {
387 : OSL_FAIL("DbaIndexDialog::OnNewIndex: no free index name found!");
388 : // can't do anything ... of course we try another base, but this could end with the same result ...
389 0 : return;
390 : }
391 :
392 0 : SvTreeListEntry* pNewEntry = m_pIndexList->InsertEntry(sNewIndexName);
393 0 : m_pIndexes->insert(sNewIndexName);
394 :
395 : // update the user data on the entries in the list box:
396 : // they're iterators of the index collection, and thus they have changed when removing the index
397 0 : for (SvTreeListEntry* pAdjust = m_pIndexList->First(); pAdjust; pAdjust = m_pIndexList->Next(pAdjust))
398 : {
399 0 : Indexes::iterator aAfterInsertPos = m_pIndexes->find(m_pIndexList->GetEntryText(pAdjust));
400 : OSL_ENSURE(aAfterInsertPos != m_pIndexes->end(), "DbaIndexDialog::OnNewIndex: problems with on of the entries!");
401 0 : pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterInsertPos - m_pIndexes->begin())));
402 : }
403 :
404 : // select the entry and start in-place editing
405 0 : m_pIndexList->SelectNoHandlerCall(pNewEntry);
406 0 : OnIndexSelected(m_pIndexList);
407 0 : m_pIndexList->EditEntry(pNewEntry);
408 0 : updateToolbox();
409 : }
410 :
411 0 : void DbaIndexDialog::OnDropIndex(bool _bConfirm)
412 : {
413 : // the selected index
414 0 : SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
415 : OSL_ENSURE(pSelected, "DbaIndexDialog::OnDropIndex: invalid call!");
416 0 : if (pSelected)
417 : {
418 : // let the user confirm the drop
419 0 : if (_bConfirm)
420 : {
421 0 : OUString sConfirm(ModuleRes(STR_CONFIRM_DROP_INDEX));
422 0 : sConfirm = sConfirm.replaceFirst("$name$", m_pIndexList->GetEntryText(pSelected));
423 0 : ScopedVclPtrInstance< MessageDialog > aConfirm(this, sConfirm, VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
424 0 : if (RET_YES != aConfirm->Execute())
425 0 : return;
426 : }
427 :
428 : // do the drop
429 0 : implDropIndex(pSelected, true);
430 :
431 : // reflect the new selection in the toolbox
432 0 : updateToolbox();
433 : }
434 : }
435 :
436 0 : bool DbaIndexDialog::implDropIndex(SvTreeListEntry* _pEntry, bool _bRemoveFromCollection)
437 : {
438 : // do the drop
439 0 : Indexes::iterator aDropPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
440 : OSL_ENSURE(aDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!");
441 :
442 0 : SQLExceptionInfo aExceptionInfo;
443 0 : bool bSuccess = false;
444 : try
445 : {
446 0 : if (_bRemoveFromCollection)
447 0 : bSuccess = m_pIndexes->drop(aDropPos);
448 : else
449 0 : bSuccess = m_pIndexes->dropNoRemove(aDropPos);
450 : }
451 0 : catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
452 0 : catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
453 0 : catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
454 :
455 0 : if (aExceptionInfo.isValid())
456 0 : showError(aExceptionInfo, this, m_xContext);
457 0 : else if (bSuccess && _bRemoveFromCollection)
458 : {
459 0 : SvTreeList* pModel = m_pIndexList->GetModel();
460 :
461 0 : m_pIndexList->disableSelectHandler();
462 0 : pModel->Remove(_pEntry);
463 0 : m_pIndexList->enableSelectHandler();
464 :
465 : // update the user data on the entries in the list box:
466 : // they're iterators of the index collection, and thus they have changed when removing the index
467 0 : for (SvTreeListEntry* pAdjust = m_pIndexList->First(); pAdjust; pAdjust = m_pIndexList->Next(pAdjust))
468 : {
469 0 : Indexes::iterator aAfterDropPos = m_pIndexes->find(m_pIndexList->GetEntryText(pAdjust));
470 : OSL_ENSURE(aAfterDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: problems with on of the remaining entries!");
471 0 : pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterDropPos - m_pIndexes->begin())));
472 : }
473 :
474 : // if the remvoved entry was the selected on ...
475 0 : if (m_pPreviousSelection == _pEntry)
476 0 : m_pPreviousSelection = NULL;
477 :
478 : // the Remove automatically selected another entry (if possible), but we disabled the calling of the handler
479 : // to prevent that we missed something ... call the handler directly
480 0 : OnIndexSelected(m_pIndexList);
481 : }
482 :
483 0 : return !aExceptionInfo.isValid();
484 : }
485 :
486 0 : void DbaIndexDialog::OnRenameIndex()
487 : {
488 : // the selected index
489 0 : SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
490 : OSL_ENSURE(pSelected, "DbaIndexDialog::OnRenameIndex: invalid call!");
491 :
492 : // save the changes made 'til here
493 : // Upon leaving the edit mode, the control will be re-initialized with the
494 : // settings from the current entry
495 0 : implSaveModified(false);
496 :
497 0 : m_pIndexList->EditEntry(pSelected);
498 0 : updateToolbox();
499 0 : }
500 :
501 0 : void DbaIndexDialog::OnSaveIndex()
502 : {
503 : // the selected index
504 : #if OSL_DEBUG_LEVEL > 0
505 : SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
506 : OSL_ENSURE( pSelected, "DbaIndexDialog::OnSaveIndex: invalid call!" );
507 : #endif
508 :
509 0 : implCommitPreviouslySelected();
510 0 : updateToolbox();
511 0 : }
512 :
513 0 : void DbaIndexDialog::OnResetIndex()
514 : {
515 : // the selected index
516 0 : SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
517 : OSL_ENSURE(pSelected, "DbaIndexDialog::OnResetIndex: invalid call!");
518 :
519 0 : Indexes::iterator aResetPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
520 :
521 0 : if (aResetPos->isNew())
522 : {
523 0 : OnDropIndex(false);
524 0 : return;
525 : }
526 :
527 0 : SQLExceptionInfo aExceptionInfo;
528 : try
529 : {
530 0 : m_pIndexes->resetIndex(aResetPos);
531 : }
532 0 : catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
533 0 : catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
534 0 : catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
535 :
536 0 : if (aExceptionInfo.isValid())
537 0 : showError(aExceptionInfo, this, m_xContext);
538 : else
539 0 : m_pIndexList->SetEntryText(pSelected, aResetPos->sName);
540 :
541 0 : updateControls(pSelected);
542 0 : updateToolbox();
543 : }
544 :
545 0 : IMPL_LINK_NOARG_TYPED( DbaIndexDialog, OnIndexAction, ToolBox*, void )
546 : {
547 0 : sal_uInt16 nClicked = m_pActions->GetCurItemId();
548 0 : if (nClicked == mnNewCmdId)
549 0 : OnNewIndex();
550 0 : else if (nClicked == mnDropCmdId)
551 0 : OnDropIndex();
552 0 : else if (nClicked == mnRenameCmdId)
553 0 : OnRenameIndex();
554 0 : else if (nClicked == mnSaveCmdId)
555 0 : OnSaveIndex();
556 0 : else if (nClicked == mnResetCmdId)
557 0 : OnResetIndex();
558 0 : }
559 :
560 0 : IMPL_LINK_NOARG( DbaIndexDialog, OnCloseDialog )
561 : {
562 0 : if (m_pIndexList->IsEditingActive())
563 : {
564 : OSL_ENSURE(!m_bEditAgain, "DbaIndexDialog::OnCloseDialog: somebody was faster than hell!");
565 : // this means somebody entered a new name, which was invalid, which cause us to posted us an event,
566 : // and before the event arrived the user clicked onto "close". VERY fast, this user ....
567 0 : m_pIndexList->EndEditing(false);
568 0 : if (m_bEditAgain)
569 : // could not commit the new name (started a new - asynchronous - edit trial)
570 0 : return 1L;
571 : }
572 :
573 : // the currently selected entry
574 0 : const SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
575 : OSL_ENSURE(pSelected == m_pPreviousSelection, "DbaIndexDialog::OnCloseDialog: inconsistence!");
576 :
577 0 : sal_Int32 nResponse = RET_NO;
578 0 : if (pSelected)
579 : {
580 : // the descriptor
581 0 : Indexes::const_iterator aSelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
582 :
583 0 : if (aSelected->isModified() || aSelected->isNew())
584 : {
585 : ScopedVclPtrInstance<MessageDialog> aQuestion(this, "SaveIndexDialog",
586 0 : "dbaccess/ui/saveindexdialog.ui" );
587 0 : nResponse = aQuestion->Execute();
588 : }
589 : }
590 :
591 0 : switch (nResponse)
592 : {
593 : case RET_YES:
594 0 : if (!implCommitPreviouslySelected())
595 0 : return 1L;
596 0 : break;
597 : case RET_NO:
598 0 : break;
599 : default:
600 0 : return 1L;
601 : }
602 :
603 0 : EndDialog(RET_OK);
604 :
605 0 : return 0L;
606 : }
607 :
608 0 : IMPL_LINK( DbaIndexDialog, OnEditIndexAgain, SvTreeListEntry*, _pEntry )
609 : {
610 0 : m_bEditAgain = false;
611 0 : m_pIndexList->EditEntry(_pEntry);
612 0 : return 0L;
613 : }
614 :
615 0 : IMPL_LINK( DbaIndexDialog, OnEntryEdited, SvTreeListEntry*, _pEntry )
616 : {
617 0 : Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
618 :
619 : OSL_ENSURE(aPosition >= m_pIndexes->begin() && aPosition < m_pIndexes->end(),
620 : "DbaIndexDialog::OnEntryEdited: invalid entry!");
621 :
622 0 : OUString sNewName = m_pIndexList->GetEntryText(_pEntry);
623 :
624 0 : Indexes::const_iterator aSameName = m_pIndexes->find(sNewName);
625 0 : if ((aSameName != aPosition) && (m_pIndexes->end() != aSameName))
626 : {
627 0 : OUString sError(ModuleRes(STR_INDEX_NAME_ALREADY_USED));
628 0 : sError = sError.replaceFirst("$name$", sNewName);
629 0 : ScopedVclPtrInstance< MessageDialog > aError(this, sError);
630 0 : aError->Execute();
631 :
632 0 : updateToolbox();
633 0 : m_bEditAgain = true;
634 0 : PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), _pEntry, true);
635 0 : return 0L;
636 : }
637 :
638 0 : aPosition->sName = sNewName;
639 :
640 : // rename can be done by a drop/insert combination only
641 0 : if (aPosition->isNew())
642 : {
643 0 : updateToolbox();
644 : // no commitment needed here ....
645 0 : return 1L;
646 : }
647 :
648 0 : if (aPosition->sName != aPosition->getOriginalName())
649 : {
650 0 : aPosition->setModified(true);
651 0 : updateToolbox();
652 : }
653 :
654 0 : return 1L;
655 : }
656 :
657 0 : bool DbaIndexDialog::implSaveModified(bool _bPlausibility)
658 : {
659 0 : if (m_pPreviousSelection)
660 : {
661 : // try to commit the previously selected index
662 0 : if (m_pFields->IsModified() && !m_pFields->SaveModified())
663 0 : return false;
664 :
665 0 : Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
666 :
667 : // the unique flag
668 0 : aPreviouslySelected->bUnique = m_pUnique->IsChecked();
669 0 : if (m_pUnique->GetSavedValue() != m_pUnique->GetState())
670 0 : aPreviouslySelected->setModified(true);
671 :
672 : // the fields
673 0 : m_pFields->commitTo(aPreviouslySelected->aFields);
674 0 : if (m_pFields->GetSavedValue() != aPreviouslySelected->aFields)
675 0 : aPreviouslySelected->setModified(true);
676 :
677 : // plausibility checks
678 0 : if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected))
679 0 : return false;
680 : }
681 :
682 0 : return true;
683 : }
684 :
685 0 : bool DbaIndexDialog::implCheckPlausibility(const Indexes::const_iterator& _rPos)
686 : {
687 : // need at least one field
688 0 : if (0 == _rPos->aFields.size())
689 : {
690 0 : ScopedVclPtrInstance< MessageDialog > aError(this, ModuleRes(STR_NEED_INDEX_FIELDS));
691 0 : aError->Execute();
692 0 : m_pFields->GrabFocus();
693 0 : return false;
694 : }
695 :
696 : // no double fields
697 0 : std::set< OUString > aExistentFields;
698 0 : for ( IndexFields::const_iterator aFieldCheck = _rPos->aFields.begin();
699 0 : aFieldCheck != _rPos->aFields.end();
700 : ++aFieldCheck
701 : )
702 : {
703 0 : if (aExistentFields.end() != aExistentFields.find(aFieldCheck->sFieldName))
704 : {
705 : // a column is specified twice ... won't work anyway, so prevent this here and now
706 0 : OUString sMessage(ModuleRes(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME));
707 0 : sMessage = sMessage.replaceFirst("$name$", aFieldCheck->sFieldName);
708 0 : ScopedVclPtrInstance< MessageDialog > aError(this, sMessage);
709 0 : aError->Execute();
710 0 : m_pFields->GrabFocus();
711 0 : return false;
712 : }
713 0 : aExistentFields.insert(aFieldCheck->sFieldName);
714 : }
715 :
716 0 : return true;
717 : }
718 :
719 0 : bool DbaIndexDialog::implCommitPreviouslySelected()
720 : {
721 0 : if (m_pPreviousSelection)
722 : {
723 0 : Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
724 :
725 0 : if (!implSaveModified())
726 0 : return false;
727 :
728 : // commit the index (if necessary)
729 0 : if (aPreviouslySelected->isModified() && !implCommit(m_pPreviousSelection))
730 0 : return false;
731 : }
732 :
733 0 : return true;
734 : }
735 :
736 0 : IMPL_LINK_NOARG( DbaIndexDialog, OnModified )
737 : {
738 : OSL_ENSURE(m_pPreviousSelection, "DbaIndexDialog, OnModified: invalid call!");
739 0 : Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
740 :
741 0 : aPosition->setModified(true);
742 0 : updateToolbox();
743 :
744 0 : return 1L;
745 : }
746 :
747 0 : void DbaIndexDialog::updateControls(const SvTreeListEntry* _pEntry)
748 : {
749 0 : if (_pEntry)
750 : {
751 : // the descriptor of the selected index
752 0 : Indexes::const_iterator aSelectedIndex = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
753 :
754 : // fill the controls
755 0 : m_pUnique->Check(aSelectedIndex->bUnique);
756 0 : m_pUnique->Enable(!aSelectedIndex->bPrimaryKey);
757 0 : m_pUnique->SaveValue();
758 :
759 0 : m_pFields->initializeFrom(aSelectedIndex->aFields);
760 0 : m_pFields->Enable(!aSelectedIndex->bPrimaryKey);
761 0 : m_pFields->SaveValue();
762 :
763 0 : m_pDescription->SetText(aSelectedIndex->sDescription);
764 0 : m_pDescription->Enable(!aSelectedIndex->bPrimaryKey);
765 :
766 0 : m_pDescriptionLabel->Enable(!aSelectedIndex->bPrimaryKey);
767 : }
768 : else
769 : {
770 0 : m_pUnique->Check(false);
771 0 : m_pFields->initializeFrom(IndexFields());
772 0 : m_pDescription->SetText(OUString());
773 : }
774 0 : }
775 :
776 0 : IMPL_LINK( DbaIndexDialog, OnIndexSelected, DbaIndexList*, /*NOTINTERESTEDIN*/ )
777 : {
778 0 : m_pIndexList->EndSelection();
779 :
780 0 : if (m_pIndexList->IsEditingActive())
781 0 : m_pIndexList->EndEditing(false);
782 :
783 : // commit the old data
784 0 : if (m_pIndexList->FirstSelected() != m_pPreviousSelection)
785 : { // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing)
786 0 : if (!implCommitPreviouslySelected())
787 : {
788 0 : m_pIndexList->SelectNoHandlerCall(m_pPreviousSelection);
789 0 : return 1L;
790 : }
791 : }
792 :
793 0 : bool bHaveSelection = (NULL != m_pIndexList->FirstSelected());
794 :
795 : // disable/enable the detail controls
796 0 : m_pIndexDetails->Enable(bHaveSelection);
797 0 : m_pUnique->Enable(bHaveSelection);
798 0 : m_pDescriptionLabel->Enable(bHaveSelection);
799 0 : m_pFieldsLabel->Enable(bHaveSelection);
800 0 : m_pFields->Enable(bHaveSelection);
801 :
802 0 : SvTreeListEntry* pNewSelection = m_pIndexList->FirstSelected();
803 0 : updateControls(pNewSelection);
804 0 : if (bHaveSelection)
805 0 : m_pIndexList->GrabFocus();
806 :
807 0 : m_pPreviousSelection = pNewSelection;
808 :
809 0 : updateToolbox();
810 0 : return 0L;
811 : }
812 0 : void DbaIndexDialog::StateChanged( StateChangedType nType )
813 : {
814 0 : ModalDialog::StateChanged( nType );
815 :
816 0 : if ( nType == StateChangedType::ControlBackground )
817 : {
818 : // Check if we need to get new images for normal/high contrast mode
819 0 : checkImageList();
820 : }
821 0 : else if ( nType == StateChangedType::Text )
822 : {
823 : // The physical toolbar changed its outlook and shows another logical toolbar!
824 : // We have to set the correct high contrast mode on the new tbx manager.
825 : // pMgr->SetHiContrast( IsHiContrastMode() );
826 0 : checkImageList();
827 : }
828 0 : }
829 0 : void DbaIndexDialog::DataChanged( const DataChangedEvent& rDCEvt )
830 : {
831 0 : ModalDialog::DataChanged( rDCEvt );
832 :
833 0 : if ((( rDCEvt.GetType() == DataChangedEventType::SETTINGS ) ||
834 0 : ( rDCEvt.GetType() == DataChangedEventType::DISPLAY )) &&
835 0 : ( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ))
836 : {
837 : // Check if we need to get new images for normal/high contrast mode
838 0 : checkImageList();
839 : }
840 0 : }
841 :
842 0 : void DbaIndexDialog::setImageList(sal_Int16 _eBitmapSet)
843 : {
844 0 : if ( _eBitmapSet == SFX_SYMBOLS_SIZE_LARGE )
845 : {
846 0 : m_pActions->SetItemImage(mnNewCmdId, maLcNewCmdImg);
847 0 : m_pActions->SetItemImage(mnDropCmdId, maLcDropCmdImg);
848 0 : m_pActions->SetItemImage(mnRenameCmdId, maLcRenameCmdImg);
849 0 : m_pActions->SetItemImage(mnSaveCmdId, maLcSaveCmdImg);
850 0 : m_pActions->SetItemImage(mnResetCmdId, maLcResetCmdImg);
851 : }
852 : else
853 : {
854 0 : m_pActions->SetItemImage(mnNewCmdId, maScNewCmdImg);
855 0 : m_pActions->SetItemImage(mnDropCmdId, maScDropCmdImg);
856 0 : m_pActions->SetItemImage(mnRenameCmdId, maScRenameCmdImg);
857 0 : m_pActions->SetItemImage(mnSaveCmdId, maScSaveCmdImg);
858 0 : m_pActions->SetItemImage(mnResetCmdId, maScResetCmdImg);
859 : }
860 0 : }
861 :
862 0 : void DbaIndexDialog::resizeControls(const Size&)
863 : {
864 0 : }
865 :
866 36 : } // namespace dbaui
867 :
868 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|