bump product version to 4.1.6.2
[LibreOffice.git] / dbaccess / source / ui / dlg / indexdialog.cxx
blob0530b1f9cb1e0764a6ff2a646c5bce1e74e3b6f5
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 "indexdialog.hxx"
25 #include "dbu_dlg.hrc"
26 #include "dbaccess_helpid.hrc"
27 #include "indexdialog.hrc"
28 #include "indexfieldscontrol.hxx"
29 #include "indexcollection.hxx"
30 #include <vcl/msgbox.hxx>
31 #include <com/sun/star/sdb/SQLContext.hpp>
32 #include "UITools.hxx"
33 #include <svtools/imgdef.hxx>
34 #include "svtools/treelistentry.hxx"
35 #include "browserids.hxx"
36 #include <connectivity/dbtools.hxx>
37 #include <osl/diagnose.h>
38 //......................................................................
39 namespace dbaui
41 //......................................................................
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::container;
45 using namespace ::com::sun::star::sdbc;
46 using namespace ::com::sun::star::sdb;
47 using namespace ::com::sun::star::lang;
48 using namespace ::dbtools;
50 //==================================================================
51 //= helper
52 //==================================================================
53 //------------------------------------------------------------------
54 sal_Bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS)
56 return (_rLHS.sFieldName == _rRHS.sFieldName)
57 && (_rLHS.bSortAscending == _rRHS.bSortAscending);
60 //------------------------------------------------------------------
61 sal_Bool operator !=(const OIndexField& _rLHS, const OIndexField& _rRHS)
63 return !(_rLHS == _rRHS);
66 //------------------------------------------------------------------
67 sal_Bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS)
69 if (_rLHS.size() != _rRHS.size())
70 return sal_False;
72 ConstIndexFieldsIterator aLeft = _rLHS.begin();
73 ConstIndexFieldsIterator aLeftEnd = _rLHS.end();
74 ConstIndexFieldsIterator aRight = _rRHS.begin();
75 for (; aLeft != aLeftEnd; ++aLeft, ++aRight)
77 if (*aLeft != *aRight)
78 return sal_False;
81 return sal_True;
84 //------------------------------------------------------------------
85 sal_Bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
87 return !(_rLHS == _rRHS);
90 //==================================================================
91 //= DbaIndexList
92 //==================================================================
93 //------------------------------------------------------------------
94 DbaIndexList::DbaIndexList(Window* _pParent, const ResId& _rId)
95 :SvTreeListBox(_pParent, _rId)
96 ,m_bSuspendSelectHdl(sal_False)
100 extern sal_Bool isCharOk(sal_Unicode _cChar,sal_Bool _bFirstChar,sal_Bool _bUpperCase,const OUString& _sAllowedChars);
101 //------------------------------------------------------------------
102 sal_Bool DbaIndexList::EditedEntry( SvTreeListEntry* _pEntry, const OUString& _rNewText )
104 // first check if this is valid SQL92 name
105 if ( isSQL92CheckEnabled(m_xConnection) )
107 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
108 if ( xMeta.is() )
110 OUString sAlias = ::dbtools::convertName2SQLName(_rNewText, xMeta->getExtraNameCharacters());
111 if ( ( xMeta->supportsMixedCaseQuotedIdentifiers() )
113 sAlias != _rNewText
115 !_rNewText.equalsIgnoreAsciiCase(sAlias))
116 return sal_False;
120 if (!SvTreeListBox::EditedEntry(_pEntry, _rNewText))
121 return sal_False;
123 String sOldText = GetEntryText(_pEntry);
124 SvTreeListBox::SetEntryText(_pEntry, _rNewText);
126 sal_Bool bValid = sal_True;
127 if (m_aEndEditHdl.IsSet())
128 bValid = (0 != m_aEndEditHdl.Call(_pEntry));
130 if (bValid)
131 return sal_True;
133 SvTreeListBox::SetEntryText(_pEntry, sOldText);
135 return sal_False;
138 //------------------------------------------------------------------
139 void DbaIndexList::enableSelectHandler()
141 OSL_ENSURE(m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
142 m_bSuspendSelectHdl = sal_False;
145 //------------------------------------------------------------------
146 void DbaIndexList::disableSelectHandler()
148 OSL_ENSURE(!m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
149 m_bSuspendSelectHdl = sal_True;
152 //------------------------------------------------------------------
153 void DbaIndexList::SelectNoHandlerCall( SvTreeListEntry* _pEntry )
155 disableSelectHandler();
156 Select(_pEntry, sal_True);
157 enableSelectHandler();
160 //------------------------------------------------------------------
161 sal_Bool DbaIndexList::Select( SvTreeListEntry* pEntry, sal_Bool _bSelect )
163 sal_Bool bReturn = SvTreeListBox::Select(pEntry, _bSelect);
165 if (m_aSelectHdl.IsSet() && !m_bSuspendSelectHdl && _bSelect)
166 m_aSelectHdl.Call(this);
168 return bReturn;
171 //==================================================================
172 //= DbaIndexDialog
173 //==================================================================
174 DBG_NAME(DbaIndexDialog)
175 //------------------------------------------------------------------
176 DbaIndexDialog::DbaIndexDialog( Window* _pParent, const Sequence< OUString >& _rFieldNames,
177 const Reference< XNameAccess >& _rxIndexes,
178 const Reference< XConnection >& _rxConnection,
179 const Reference< XComponentContext >& _rxContext,sal_Int32 _nMaxColumnsInIndex)
180 :ModalDialog( _pParent, ModuleRes(DLG_INDEXDESIGN))
181 ,m_xConnection(_rxConnection)
182 ,m_aGeometrySettings(E_DIALOG, OUString("dbaccess.tabledesign.indexdialog"))
183 ,m_aActions (this, ModuleRes(TLB_ACTIONS))
184 ,m_aIndexes (this, ModuleRes(CTR_INDEXLIST))
185 ,m_aIndexDetails (this, ModuleRes(FL_INDEXDETAILS))
186 ,m_aDescriptionLabel (this, ModuleRes(FT_DESC_LABEL))
187 ,m_aDescription (this, ModuleRes(FT_DESCRIPTION))
188 ,m_aUnique (this, ModuleRes(CB_UNIQUE))
189 ,m_aFieldsLabel (this, ModuleRes(FT_FIELDS))
190 ,m_pFields(new IndexFieldsControl (this, ModuleRes(CTR_FIELDS),_nMaxColumnsInIndex,::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" )))
191 ,m_aClose (this, ModuleRes(PB_CLOSE))
192 ,m_aHelp (this, ModuleRes(HB_HELP))
193 ,m_pIndexes(NULL)
194 ,m_pPreviousSelection(NULL)
195 ,m_bEditAgain(sal_False)
196 ,m_xContext(_rxContext)
198 DBG_CTOR(DbaIndexDialog,NULL);
200 FreeResource();
202 m_aActions.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexAction));
204 m_aIndexes.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexSelected));
205 m_aIndexes.SetEndEditHdl(LINK(this, DbaIndexDialog, OnEntryEdited));
206 m_aIndexes.SetSelectionMode(SINGLE_SELECTION);
207 m_aIndexes.SetHighlightRange();
208 m_aIndexes.setConnection(m_xConnection);
210 m_pFields->Init(_rFieldNames);
212 setToolBox(&m_aActions);
214 m_pIndexes = new OIndexCollection();
217 m_pIndexes->attach(_rxIndexes);
219 catch(SQLException& e)
221 ::dbaui::showError(SQLExceptionInfo(e),_pParent,_rxContext);
223 catch(Exception&)
225 OSL_FAIL("DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
228 fillIndexList();
230 m_aUnique.SetClickHdl(LINK(this, DbaIndexDialog, OnModified));
231 m_pFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified));
233 m_aClose.SetClickHdl(LINK(this, DbaIndexDialog, OnCloseDialog));
235 // if all of the indexes have an empty description, we're not interested in displaying it
236 Indexes::const_iterator aCheck;
238 for ( aCheck = m_pIndexes->begin();
239 aCheck != m_pIndexes->end();
240 ++aCheck
243 if (!aCheck->sDescription.isEmpty())
244 break;
247 if (aCheck == m_pIndexes->end())
249 sal_Int32 nMoveUp = m_aUnique.GetPosPixel().Y() - m_aDescriptionLabel.GetPosPixel().Y();
251 // hide the controls which are necessary for the description
252 m_aDescription.Hide();
253 m_aDescriptionLabel.Hide();
255 // move other controls up
256 Point aPos = m_aUnique.GetPosPixel();
257 aPos.Y() -= nMoveUp;
258 m_aUnique.SetPosPixel(aPos);
260 aPos = m_aFieldsLabel.GetPosPixel();
261 aPos.Y() -= nMoveUp;
262 m_aFieldsLabel.SetPosPixel(aPos);
264 aPos = m_pFields->GetPosPixel();
265 aPos.Y() -= nMoveUp;
266 m_pFields->SetPosPixel(aPos);
268 // and enlarge the fields list
269 Size aSize = m_pFields->GetSizePixel();
270 aSize.Height() += nMoveUp;
271 m_pFields->SetSizePixel(aSize);
275 //------------------------------------------------------------------
276 void DbaIndexDialog::updateToolbox()
278 m_aActions.EnableItem(ID_INDEX_NEW, !m_aIndexes.IsEditingActive());
280 SvTreeListEntry* pSelected = m_aIndexes.FirstSelected();
281 sal_Bool bSelectedAnything = NULL != pSelected;
284 if (pSelected)
286 // is the current entry modified?
287 Indexes::const_iterator aSelectedPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
288 m_aActions.EnableItem(ID_INDEX_SAVE, aSelectedPos->isModified() || aSelectedPos->isNew());
289 m_aActions.EnableItem(ID_INDEX_RESET, aSelectedPos->isModified() || aSelectedPos->isNew());
290 bSelectedAnything = bSelectedAnything && !aSelectedPos->bPrimaryKey;
292 else
294 m_aActions.EnableItem(ID_INDEX_SAVE, sal_False);
295 m_aActions.EnableItem(ID_INDEX_RESET, sal_False);
297 m_aActions.EnableItem(ID_INDEX_DROP, bSelectedAnything);
298 m_aActions.EnableItem(ID_INDEX_RENAME, bSelectedAnything);
301 //------------------------------------------------------------------
302 void DbaIndexDialog::fillIndexList()
304 Image aPKeyIcon(ModuleRes( IMG_PKEYICON ));
305 // fill the list with the index names
306 m_aIndexes.Clear();
307 Indexes::iterator aIndexLoop = m_pIndexes->begin();
308 Indexes::iterator aEnd = m_pIndexes->end();
309 for (; aIndexLoop != aEnd; ++aIndexLoop)
311 SvTreeListEntry* pNewEntry = NULL;
312 if (aIndexLoop->bPrimaryKey)
313 pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName, aPKeyIcon, aPKeyIcon);
314 else
315 pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName);
317 pNewEntry->SetUserData(reinterpret_cast< void* >(sal_Int32(aIndexLoop - m_pIndexes->begin())));
320 OnIndexSelected(&m_aIndexes);
323 //------------------------------------------------------------------
324 DbaIndexDialog::~DbaIndexDialog( )
326 setToolBox(NULL);
327 delete m_pIndexes;
328 delete m_pFields;
330 DBG_DTOR(DbaIndexDialog,NULL);
333 //------------------------------------------------------------------
334 sal_Bool DbaIndexDialog::implCommit(SvTreeListEntry* _pEntry)
336 OSL_ENSURE(_pEntry, "DbaIndexDialog::implCommit: invalid entry!");
338 Indexes::iterator aCommitPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
340 // if it's not a new index, remove it
341 // (we can't modify indexes, only drop'n'insert)
342 if (!aCommitPos->isNew())
343 if (!implDropIndex(_pEntry, sal_False))
344 return sal_False;
346 // create the new index
347 SQLExceptionInfo aExceptionInfo;
350 m_pIndexes->commitNewIndex(aCommitPos);
352 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
353 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
354 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
356 // reflect the new selection in the toolbox
357 updateToolbox();
359 if (aExceptionInfo.isValid())
360 showError(aExceptionInfo, this, m_xContext);
361 else
363 m_aUnique.SaveValue();
364 m_pFields->SaveValue();
367 return !aExceptionInfo.isValid();
370 //------------------------------------------------------------------
371 void DbaIndexDialog::OnNewIndex()
373 // commit the current entry, if necessary
374 if (!implCommitPreviouslySelected())
375 return;
377 // get a new unique name for the new index
378 String sNewIndexName;
379 const String sNewIndexNameBase(ModuleRes(STR_LOGICAL_INDEX_NAME));
380 sal_Int32 i;
382 for ( i = 1; i < 0x7FFFFFFF; ++i )
384 sNewIndexName = sNewIndexNameBase;
385 sNewIndexName += OUString::number(i);
386 if (m_pIndexes->end() == m_pIndexes->find(sNewIndexName))
387 break;
389 if (i == 0x7FFFFFFF)
391 OSL_FAIL("DbaIndexDialog::OnNewIndex: no free index name found!");
392 // can't do anything ... of course we try another base, but this could end with the same result ...
393 return;
396 SvTreeListEntry* pNewEntry = m_aIndexes.InsertEntry(sNewIndexName);
397 m_pIndexes->insert(sNewIndexName);
399 // update the user data on the entries in the list box:
400 // they're iterators of the index collection, and thus they have changed when removing the index
401 for (SvTreeListEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust))
403 Indexes::iterator aAfterInsertPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust));
404 OSL_ENSURE(aAfterInsertPos != m_pIndexes->end(), "DbaIndexDialog::OnNewIndex: problems with on of the entries!");
405 pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterInsertPos - m_pIndexes->begin())));
408 // select the entry and start in-place editing
409 m_aIndexes.SelectNoHandlerCall(pNewEntry);
410 OnIndexSelected(&m_aIndexes);
411 m_aIndexes.EditEntry(pNewEntry);
412 updateToolbox();
415 //------------------------------------------------------------------
416 void DbaIndexDialog::OnDropIndex(sal_Bool _bConfirm)
418 // the selected index
419 SvTreeListEntry* pSelected = m_aIndexes.FirstSelected();
420 OSL_ENSURE(pSelected, "DbaIndexDialog::OnDropIndex: invalid call!");
421 if (pSelected)
423 // let the user confirm the drop
424 if (_bConfirm)
426 String sConfirm(ModuleRes(STR_CONFIRM_DROP_INDEX));
427 sConfirm.SearchAndReplaceAscii("$name$", m_aIndexes.GetEntryText(pSelected));
428 QueryBox aConfirm(this, WB_YES_NO, sConfirm);
429 if (RET_YES != aConfirm.Execute())
430 return;
433 // do the drop
434 implDropIndex(pSelected, sal_True);
436 // reflect the new selection in the toolbox
437 updateToolbox();
441 //------------------------------------------------------------------
442 sal_Bool DbaIndexDialog::implDropIndex(SvTreeListEntry* _pEntry, sal_Bool _bRemoveFromCollection)
444 // do the drop
445 Indexes::iterator aDropPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
446 OSL_ENSURE(aDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!");
448 SQLExceptionInfo aExceptionInfo;
449 sal_Bool bSuccess = sal_False;
452 if (_bRemoveFromCollection)
453 bSuccess = m_pIndexes->drop(aDropPos);
454 else
455 bSuccess = m_pIndexes->dropNoRemove(aDropPos);
457 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
458 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
459 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
461 if (aExceptionInfo.isValid())
462 showError(aExceptionInfo, this, m_xContext);
463 else if (bSuccess && _bRemoveFromCollection)
465 SvTreeList* pModel = m_aIndexes.GetModel();
467 m_aIndexes.disableSelectHandler();
468 pModel->Remove(_pEntry);
469 m_aIndexes.enableSelectHandler();
471 // update the user data on the entries in the list box:
472 // they're iterators of the index collection, and thus they have changed when removing the index
473 for (SvTreeListEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust))
475 Indexes::iterator aAfterDropPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust));
476 OSL_ENSURE(aAfterDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: problems with on of the remaining entries!");
477 pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterDropPos - m_pIndexes->begin())));
480 // if the remvoved entry was the selected on ...
481 if (m_pPreviousSelection == _pEntry)
482 m_pPreviousSelection = NULL;
484 // the Remove automatically selected another entry (if possible), but we disabled the calling of the handler
485 // to prevent that we missed something ... call the handler directly
486 OnIndexSelected(&m_aIndexes);
489 return !aExceptionInfo.isValid();
492 //------------------------------------------------------------------
493 void DbaIndexDialog::OnRenameIndex()
495 // the selected index
496 SvTreeListEntry* pSelected = m_aIndexes.FirstSelected();
497 OSL_ENSURE(pSelected, "DbaIndexDialog::OnRenameIndex: invalid call!");
499 // save the changes made 'til here
500 // Upon leaving the edit mode, the control will be re-initialized with the
501 // settings from the current entry
502 implSaveModified(sal_False);
504 m_aIndexes.EditEntry(pSelected);
505 updateToolbox();
508 //------------------------------------------------------------------
509 void DbaIndexDialog::OnSaveIndex()
511 // the selected index
512 #if OSL_DEBUG_LEVEL > 0
513 SvTreeListEntry* pSelected = m_aIndexes.FirstSelected();
514 OSL_ENSURE( pSelected, "DbaIndexDialog::OnSaveIndex: invalid call!" );
515 #endif
517 implCommitPreviouslySelected();
518 updateToolbox();
521 //------------------------------------------------------------------
522 void DbaIndexDialog::OnResetIndex()
524 // the selected index
525 SvTreeListEntry* pSelected = m_aIndexes.FirstSelected();
526 OSL_ENSURE(pSelected, "DbaIndexDialog::OnResetIndex: invalid call!");
528 Indexes::iterator aResetPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
530 if (aResetPos->isNew())
532 OnDropIndex(sal_False);
533 return;
536 SQLExceptionInfo aExceptionInfo;
539 m_pIndexes->resetIndex(aResetPos);
541 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
542 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
543 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
545 if (aExceptionInfo.isValid())
546 showError(aExceptionInfo, this, m_xContext);
547 else
548 m_aIndexes.SetEntryText(pSelected, aResetPos->sName);
550 updateControls(pSelected);
551 updateToolbox();
554 //------------------------------------------------------------------
555 IMPL_LINK( DbaIndexDialog, OnIndexAction, ToolBox*, /*NOTINTERESTEDIN*/ )
557 sal_uInt16 nClicked = m_aActions.GetCurItemId();
558 switch (nClicked)
560 case ID_INDEX_NEW:
561 OnNewIndex();
562 break;
563 case ID_INDEX_DROP:
564 OnDropIndex();
565 break;
566 case ID_INDEX_RENAME:
567 OnRenameIndex();
568 break;
569 case ID_INDEX_SAVE:
570 OnSaveIndex();
571 break;
572 case ID_INDEX_RESET:
573 OnResetIndex();
574 break;
576 return 0L;
579 //------------------------------------------------------------------
580 IMPL_LINK( DbaIndexDialog, OnCloseDialog, void*, /*NOTINTERESTEDIN*/ )
582 if (m_aIndexes.IsEditingActive())
584 OSL_ENSURE(!m_bEditAgain, "DbaIndexDialog::OnCloseDialog: somebody was faster than hell!");
585 // this means somebody entered a new name, which was invalid, which cause us to posted us an event,
586 // and before the event arrived the user clicked onto "close". VERY fast, this user ....
587 m_aIndexes.EndEditing(sal_False);
588 if (m_bEditAgain)
589 // could not commit the new name (started a new - asynchronous - edit trial)
590 return 1L;
593 // the currently selected entry
594 const SvTreeListEntry* pSelected = m_aIndexes.FirstSelected();
595 OSL_ENSURE(pSelected == m_pPreviousSelection, "DbaIndexDialog::OnCloseDialog: inconsistence!");
597 sal_Int32 nResponse = RET_NO;
598 if (pSelected)
600 // the descriptor
601 Indexes::const_iterator aSelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
603 if (aSelected->isModified() || aSelected->isNew())
605 QueryBox aQuestion(this, ModuleRes(QUERY_SAVE_CURRENT_INDEX));
606 nResponse = aQuestion.Execute();
610 switch (nResponse)
612 case RET_YES:
613 if (!implCommitPreviouslySelected())
614 return 1L;
615 break;
616 case RET_NO:
617 break;
618 default:
619 return 1L;
622 EndDialog(RET_OK);
624 return 0L;
627 //------------------------------------------------------------------
628 IMPL_LINK( DbaIndexDialog, OnEditIndexAgain, SvTreeListEntry*, _pEntry )
630 m_bEditAgain = sal_False;
631 m_aIndexes.EditEntry(_pEntry);
632 return 0L;
635 //------------------------------------------------------------------
636 IMPL_LINK( DbaIndexDialog, OnEntryEdited, SvTreeListEntry*, _pEntry )
638 Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
640 OSL_ENSURE(aPosition >= m_pIndexes->begin() && aPosition < m_pIndexes->end(),
641 "DbaIndexDialog::OnEntryEdited: invalid entry!");
643 String sNewName = m_aIndexes.GetEntryText(_pEntry);
645 Indexes::const_iterator aSameName = m_pIndexes->find(sNewName);
646 if ((aSameName != aPosition) && (m_pIndexes->end() != aSameName))
648 String sError(ModuleRes(STR_INDEX_NAME_ALREADY_USED));
649 sError.SearchAndReplaceAscii("$name$", sNewName);
650 ErrorBox aError(this, WB_OK, sError);
651 aError.Execute();
653 updateToolbox();
654 m_bEditAgain = sal_True;
655 PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), _pEntry);
656 return 0L;
659 aPosition->sName = sNewName;
661 // rename can be done by a drop/insert combination only
662 if (aPosition->isNew())
664 updateToolbox();
665 // no commitment needed here ....
666 return 1L;
669 if (aPosition->sName != aPosition->getOriginalName())
671 aPosition->setModified(sal_True);
672 updateToolbox();
675 return 1L;
678 //------------------------------------------------------------------
679 sal_Bool DbaIndexDialog::implSaveModified(sal_Bool _bPlausibility)
681 if (m_pPreviousSelection)
683 // try to commit the previously selected index
684 if (m_pFields->IsModified() && !m_pFields->SaveModified())
685 return sal_False;
687 Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
689 // the unique flag
690 aPreviouslySelected->bUnique = m_aUnique.IsChecked();
691 if (m_aUnique.GetSavedValue() != m_aUnique.GetState())
692 aPreviouslySelected->setModified(sal_True);
694 // the fields
695 m_pFields->commitTo(aPreviouslySelected->aFields);
696 if (m_pFields->GetSavedValue() != aPreviouslySelected->aFields)
697 aPreviouslySelected->setModified(sal_True);
699 // plausibility checks
700 if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected))
701 return sal_False;
704 return sal_True;
707 //------------------------------------------------------------------
708 sal_Bool DbaIndexDialog::implCheckPlausibility(const ConstIndexesIterator& _rPos)
710 // need at least one field
711 if (0 == _rPos->aFields.size())
713 ErrorBox aError(this, ModuleRes(ERR_NEED_INDEX_FIELDS));
714 aError.Execute();
715 m_pFields->GrabFocus();
716 return sal_False;
719 // no double fields
720 std::set< String > aExistentFields;
721 for ( ConstIndexFieldsIterator aFieldCheck = _rPos->aFields.begin();
722 aFieldCheck != _rPos->aFields.end();
723 ++aFieldCheck
726 if (aExistentFields.end() != aExistentFields.find(aFieldCheck->sFieldName))
728 // a column is specified twice ... won't work anyway, so prevent this here and now
729 String sMessage(ModuleRes(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME));
730 sMessage.SearchAndReplaceAscii("$name$", aFieldCheck->sFieldName);
731 ErrorBox aError(this, WB_OK, sMessage);
732 aError.Execute();
733 m_pFields->GrabFocus();
734 return sal_False;
736 aExistentFields.insert(aFieldCheck->sFieldName);
739 return sal_True;
742 //------------------------------------------------------------------
743 sal_Bool DbaIndexDialog::implCommitPreviouslySelected()
745 if (m_pPreviousSelection)
747 Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
749 if (!implSaveModified())
750 return sal_False;
752 // commit the index (if necessary)
753 if (aPreviouslySelected->isModified() && !implCommit(m_pPreviousSelection))
754 return sal_False;
757 return sal_True;
760 //------------------------------------------------------------------
761 IMPL_LINK( DbaIndexDialog, OnModified, void*, /*NOTINTERESTEDIN*/ )
763 OSL_ENSURE(m_pPreviousSelection, "DbaIndexDialog, OnModified: invalid call!");
764 Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
766 aPosition->setModified(sal_True);
767 updateToolbox();
769 return 1L;
772 //------------------------------------------------------------------
773 void DbaIndexDialog::updateControls(const SvTreeListEntry* _pEntry)
775 if (_pEntry)
777 // the descriptor of the selected index
778 Indexes::const_iterator aSelectedIndex = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
780 // fill the controls
781 m_aUnique.Check(aSelectedIndex->bUnique);
782 m_aUnique.Enable(!aSelectedIndex->bPrimaryKey);
783 m_aUnique.SaveValue();
785 m_pFields->initializeFrom(aSelectedIndex->aFields);
786 m_pFields->Enable(!aSelectedIndex->bPrimaryKey);
787 m_pFields->SaveValue();
789 m_aDescription.SetText(aSelectedIndex->sDescription);
790 m_aDescription.Enable(!aSelectedIndex->bPrimaryKey);
792 m_aDescriptionLabel.Enable(!aSelectedIndex->bPrimaryKey);
794 else
796 m_aUnique.Check(sal_False);
797 m_pFields->initializeFrom(IndexFields());
798 m_aDescription.SetText(String());
802 //------------------------------------------------------------------
803 IMPL_LINK( DbaIndexDialog, OnIndexSelected, DbaIndexList*, /*NOTINTERESTEDIN*/ )
805 m_aIndexes.EndSelection();
807 if (m_aIndexes.IsEditingActive())
808 m_aIndexes.EndEditing(sal_False);
810 // commit the old data
811 if (m_aIndexes.FirstSelected() != m_pPreviousSelection)
812 { // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing)
813 if (!implCommitPreviouslySelected())
815 m_aIndexes.SelectNoHandlerCall(m_pPreviousSelection);
816 return 1L;
820 sal_Bool bHaveSelection = (NULL != m_aIndexes.FirstSelected());
822 // disable/enable the detail controls
823 m_aIndexDetails.Enable(bHaveSelection);
824 m_aUnique.Enable(bHaveSelection);
825 m_aDescriptionLabel.Enable(bHaveSelection);
826 m_aFieldsLabel.Enable(bHaveSelection);
827 m_pFields->Enable(bHaveSelection);
829 SvTreeListEntry* pNewSelection = m_aIndexes.FirstSelected();
830 updateControls(pNewSelection);
831 if (bHaveSelection)
832 m_aIndexes.GrabFocus();
834 m_pPreviousSelection = pNewSelection;
836 updateToolbox();
837 return 0L;
839 // -----------------------------------------------------------------------------
840 void DbaIndexDialog::StateChanged( StateChangedType nType )
842 ModalDialog::StateChanged( nType );
844 if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
846 // Check if we need to get new images for normal/high contrast mode
847 checkImageList();
849 else if ( nType == STATE_CHANGE_TEXT )
851 // The physical toolbar changed its outlook and shows another logical toolbar!
852 // We have to set the correct high contrast mode on the new tbx manager.
853 // pMgr->SetHiContrast( IsHiContrastMode() );
854 checkImageList();
857 // -----------------------------------------------------------------------------
858 void DbaIndexDialog::DataChanged( const DataChangedEvent& rDCEvt )
860 ModalDialog::DataChanged( rDCEvt );
862 if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
863 ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) &&
864 ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
866 // Check if we need to get new images for normal/high contrast mode
867 checkImageList();
870 //------------------------------------------------------------------
871 ImageList DbaIndexDialog::getImageList(sal_Int16 _eBitmapSet) const
873 sal_Int16 nN = IMG_INDEX_DLG_SC;
874 if ( _eBitmapSet == SFX_SYMBOLS_SIZE_LARGE )
876 nN = IMG_INDEX_DLG_LC;
878 return ImageList(ModuleRes(nN));
880 //------------------------------------------------------------------
881 void DbaIndexDialog::resizeControls(const Size& _rDiff)
883 // we use large images so we must change them
884 if ( _rDiff.Width() || _rDiff.Height() )
886 Size aDlgSize = GetSizePixel();
887 // adjust size of dlg
888 SetSizePixel(Size(aDlgSize.Width() + _rDiff.Width(),
889 aDlgSize.Height() + _rDiff.Height())
891 Size aIndexSize = m_aIndexes.GetSizePixel();
892 m_aIndexes.SetPosSizePixel(m_aIndexes.GetPosPixel() + Point(0,_rDiff.Height()),
893 Size(aIndexSize.Width() + _rDiff.Width(),
894 aIndexSize.Height()));
896 //now move the rest to the left side
897 Point aMove(_rDiff.Width(),_rDiff.Height());
898 m_aIndexDetails.SetPosPixel(m_aIndexDetails.GetPosPixel() + aMove);
899 m_aDescriptionLabel.SetPosPixel(m_aDescriptionLabel.GetPosPixel() + aMove);
900 m_aDescription.SetPosPixel(m_aDescription.GetPosPixel() + aMove);
901 m_aUnique.SetPosPixel(m_aUnique.GetPosPixel() + aMove);
902 m_aFieldsLabel.SetPosPixel(m_aFieldsLabel.GetPosPixel() + aMove);
903 OSL_ENSURE(m_pFields,"NO valid fields!");
904 m_pFields->SetPosPixel(m_pFields->GetPosPixel() + aMove);
905 m_aClose.SetPosPixel(m_aClose.GetPosPixel() + aMove);
906 m_aHelp.SetPosPixel(m_aHelp.GetPosPixel() + aMove);
908 Invalidate();
912 //......................................................................
913 } // namespace dbaui
914 //......................................................................
916 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */