Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / dbaccess / source / ui / dlg / indexdialog.cxx
bloba4080cde40d1f3883a5a170c4f3a46f795ea16ae
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "indexdialog.hxx"
31 #include "dbu_dlg.hrc"
32 #include "dbaccess_helpid.hrc"
33 #include "indexdialog.hrc"
34 #include "indexfieldscontrol.hxx"
35 #include "indexcollection.hxx"
36 #include <vcl/msgbox.hxx>
37 #include <com/sun/star/sdb/SQLContext.hpp>
38 #include "UITools.hxx"
39 #include <svtools/imgdef.hxx>
40 #include "browserids.hxx"
41 #include <connectivity/dbtools.hxx>
42 #include <osl/diagnose.h>
43 //......................................................................
44 namespace dbaui
46 //......................................................................
48 using namespace ::com::sun::star::uno;
49 using namespace ::com::sun::star::container;
50 using namespace ::com::sun::star::sdbc;
51 using namespace ::com::sun::star::sdb;
52 using namespace ::com::sun::star::lang;
53 using namespace ::dbtools;
55 //==================================================================
56 //= helper
57 //==================================================================
58 //------------------------------------------------------------------
59 sal_Bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS)
61 return (_rLHS.sFieldName == _rRHS.sFieldName)
62 && (_rLHS.bSortAscending == _rRHS.bSortAscending);
65 //------------------------------------------------------------------
66 sal_Bool operator !=(const OIndexField& _rLHS, const OIndexField& _rRHS)
68 return !(_rLHS == _rRHS);
71 //------------------------------------------------------------------
72 sal_Bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS)
74 if (_rLHS.size() != _rRHS.size())
75 return sal_False;
77 ConstIndexFieldsIterator aLeft = _rLHS.begin();
78 ConstIndexFieldsIterator aLeftEnd = _rLHS.end();
79 ConstIndexFieldsIterator aRight = _rRHS.begin();
80 for (; aLeft != aLeftEnd; ++aLeft, ++aRight)
82 if (*aLeft != *aRight)
83 return sal_False;
86 return sal_True;
89 //------------------------------------------------------------------
90 sal_Bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
92 return !(_rLHS == _rRHS);
95 //==================================================================
96 //= DbaIndexList
97 //==================================================================
98 //------------------------------------------------------------------
99 DbaIndexList::DbaIndexList(Window* _pParent, const ResId& _rId)
100 :SvTreeListBox(_pParent, _rId)
101 ,m_bSuspendSelectHdl(sal_False)
105 extern sal_Bool isCharOk(sal_Unicode _cChar,sal_Bool _bFirstChar,sal_Bool _bUpperCase,const ::rtl::OUString& _sAllowedChars);
106 //------------------------------------------------------------------
107 sal_Bool DbaIndexList::EditedEntry( SvLBoxEntry* _pEntry, const rtl::OUString& _rNewText )
109 // first check if this is valid SQL92 name
110 if ( isSQL92CheckEnabled(m_xConnection) )
112 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
113 if ( xMeta.is() )
115 ::rtl::OUString sAlias = ::dbtools::convertName2SQLName(_rNewText, xMeta->getExtraNameCharacters());
116 if ( ( xMeta->supportsMixedCaseQuotedIdentifiers() )
118 sAlias != _rNewText
120 !_rNewText.equalsIgnoreAsciiCase(sAlias))
121 return sal_False;
125 if (!SvTreeListBox::EditedEntry(_pEntry, _rNewText))
126 return sal_False;
128 String sOldText = GetEntryText(_pEntry);
129 SvTreeListBox::SetEntryText(_pEntry, _rNewText);
131 sal_Bool bValid = sal_True;
132 if (m_aEndEditHdl.IsSet())
133 bValid = (0 != m_aEndEditHdl.Call(_pEntry));
135 if (bValid)
136 return sal_True;
138 SvTreeListBox::SetEntryText(_pEntry, sOldText);
140 return sal_False;
143 //------------------------------------------------------------------
144 void DbaIndexList::enableSelectHandler()
146 OSL_ENSURE(m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
147 m_bSuspendSelectHdl = sal_False;
150 //------------------------------------------------------------------
151 void DbaIndexList::disableSelectHandler()
153 OSL_ENSURE(!m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
154 m_bSuspendSelectHdl = sal_True;
157 //------------------------------------------------------------------
158 void DbaIndexList::SelectNoHandlerCall( SvLBoxEntry* _pEntry )
160 disableSelectHandler();
161 Select(_pEntry, sal_True);
162 enableSelectHandler();
165 //------------------------------------------------------------------
166 sal_Bool DbaIndexList::Select( SvLBoxEntry* pEntry, sal_Bool _bSelect )
168 sal_Bool bReturn = SvTreeListBox::Select(pEntry, _bSelect);
170 if (m_aSelectHdl.IsSet() && !m_bSuspendSelectHdl && _bSelect)
171 m_aSelectHdl.Call(this);
173 return bReturn;
176 //==================================================================
177 //= DbaIndexDialog
178 //==================================================================
179 DBG_NAME(DbaIndexDialog)
180 //------------------------------------------------------------------
181 DbaIndexDialog::DbaIndexDialog( Window* _pParent, const Sequence< ::rtl::OUString >& _rFieldNames,
182 const Reference< XNameAccess >& _rxIndexes,
183 const Reference< XConnection >& _rxConnection,
184 const Reference< XMultiServiceFactory >& _rxORB,sal_Int32 _nMaxColumnsInIndex)
185 :ModalDialog( _pParent, ModuleRes(DLG_INDEXDESIGN))
186 ,m_xConnection(_rxConnection)
187 ,m_aGeometrySettings(E_DIALOG, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("dbaccess.tabledesign.indexdialog")))
188 ,m_aActions (this, ModuleRes(TLB_ACTIONS))
189 ,m_aIndexes (this, ModuleRes(CTR_INDEXLIST))
190 ,m_aIndexDetails (this, ModuleRes(FL_INDEXDETAILS))
191 ,m_aDescriptionLabel (this, ModuleRes(FT_DESC_LABEL))
192 ,m_aDescription (this, ModuleRes(FT_DESCRIPTION))
193 ,m_aUnique (this, ModuleRes(CB_UNIQUE))
194 ,m_aFieldsLabel (this, ModuleRes(FT_FIELDS))
195 ,m_pFields(new IndexFieldsControl (this, ModuleRes(CTR_FIELDS),_nMaxColumnsInIndex,::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" )))
196 ,m_aClose (this, ModuleRes(PB_CLOSE))
197 ,m_aHelp (this, ModuleRes(HB_HELP))
198 ,m_pIndexes(NULL)
199 ,m_pPreviousSelection(NULL)
200 ,m_bEditAgain(sal_False)
201 ,m_xORB(_rxORB)
203 DBG_CTOR(DbaIndexDialog,NULL);
205 FreeResource();
207 m_aActions.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexAction));
209 m_aIndexes.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexSelected));
210 m_aIndexes.SetEndEditHdl(LINK(this, DbaIndexDialog, OnEntryEdited));
211 m_aIndexes.SetSelectionMode(SINGLE_SELECTION);
212 m_aIndexes.SetHighlightRange();
213 m_aIndexes.setConnection(m_xConnection);
215 m_pFields->Init(_rFieldNames);
217 setToolBox(&m_aActions);
219 m_pIndexes = new OIndexCollection();
222 m_pIndexes->attach(_rxIndexes);
224 catch(SQLException& e)
226 ::dbaui::showError(SQLExceptionInfo(e),_pParent,_rxORB);
228 catch(Exception&)
230 OSL_FAIL("DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
233 fillIndexList();
235 m_aUnique.SetClickHdl(LINK(this, DbaIndexDialog, OnModified));
236 m_pFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified));
238 m_aClose.SetClickHdl(LINK(this, DbaIndexDialog, OnCloseDialog));
240 // if all of the indexes have an empty description, we're not interested in displaying it
241 Indexes::const_iterator aCheck;
243 for ( aCheck = m_pIndexes->begin();
244 aCheck != m_pIndexes->end();
245 ++aCheck
248 if (!aCheck->sDescription.isEmpty())
249 break;
252 if (aCheck == m_pIndexes->end())
254 sal_Int32 nMoveUp = m_aUnique.GetPosPixel().Y() - m_aDescriptionLabel.GetPosPixel().Y();
256 // hide the controls which are necessary for the description
257 m_aDescription.Hide();
258 m_aDescriptionLabel.Hide();
260 // move other controls up
261 Point aPos = m_aUnique.GetPosPixel();
262 aPos.Y() -= nMoveUp;
263 m_aUnique.SetPosPixel(aPos);
265 aPos = m_aFieldsLabel.GetPosPixel();
266 aPos.Y() -= nMoveUp;
267 m_aFieldsLabel.SetPosPixel(aPos);
269 aPos = m_pFields->GetPosPixel();
270 aPos.Y() -= nMoveUp;
271 m_pFields->SetPosPixel(aPos);
273 // and enlarge the fields list
274 Size aSize = m_pFields->GetSizePixel();
275 aSize.Height() += nMoveUp;
276 m_pFields->SetSizePixel(aSize);
280 //------------------------------------------------------------------
281 void DbaIndexDialog::updateToolbox()
283 m_aActions.EnableItem(ID_INDEX_NEW, !m_aIndexes.IsEditingActive());
285 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
286 sal_Bool bSelectedAnything = NULL != pSelected;
289 if (pSelected)
291 // is the current entry modified?
292 Indexes::const_iterator aSelectedPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
293 m_aActions.EnableItem(ID_INDEX_SAVE, aSelectedPos->isModified() || aSelectedPos->isNew());
294 m_aActions.EnableItem(ID_INDEX_RESET, aSelectedPos->isModified() || aSelectedPos->isNew());
295 bSelectedAnything = bSelectedAnything && !aSelectedPos->bPrimaryKey;
297 else
299 m_aActions.EnableItem(ID_INDEX_SAVE, sal_False);
300 m_aActions.EnableItem(ID_INDEX_RESET, sal_False);
302 m_aActions.EnableItem(ID_INDEX_DROP, bSelectedAnything);
303 m_aActions.EnableItem(ID_INDEX_RENAME, bSelectedAnything);
306 //------------------------------------------------------------------
307 void DbaIndexDialog::fillIndexList()
309 Image aPKeyIcon(ModuleRes( IMG_PKEYICON ));
310 // fill the list with the index names
311 m_aIndexes.Clear();
312 Indexes::iterator aIndexLoop = m_pIndexes->begin();
313 Indexes::iterator aEnd = m_pIndexes->end();
314 for (; aIndexLoop != aEnd; ++aIndexLoop)
316 SvLBoxEntry* pNewEntry = NULL;
317 if (aIndexLoop->bPrimaryKey)
318 pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName, aPKeyIcon, aPKeyIcon);
319 else
320 pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName);
322 pNewEntry->SetUserData(reinterpret_cast< void* >(sal_Int32(aIndexLoop - m_pIndexes->begin())));
325 OnIndexSelected(&m_aIndexes);
328 //------------------------------------------------------------------
329 DbaIndexDialog::~DbaIndexDialog( )
331 setToolBox(NULL);
332 delete m_pIndexes;
333 delete m_pFields;
335 DBG_DTOR(DbaIndexDialog,NULL);
338 //------------------------------------------------------------------
339 sal_Bool DbaIndexDialog::implCommit(SvLBoxEntry* _pEntry)
341 OSL_ENSURE(_pEntry, "DbaIndexDialog::implCommit: invalid entry!");
343 Indexes::iterator aCommitPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
345 // if it's not a new index, remove it
346 // (we can't modify indexes, only drop'n'insert)
347 if (!aCommitPos->isNew())
348 if (!implDropIndex(_pEntry, sal_False))
349 return sal_False;
351 // create the new index
352 SQLExceptionInfo aExceptionInfo;
355 m_pIndexes->commitNewIndex(aCommitPos);
357 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
358 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
359 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
361 // reflect the new selection in the toolbox
362 updateToolbox();
364 if (aExceptionInfo.isValid())
365 showError(aExceptionInfo, this, m_xORB);
366 else
368 m_aUnique.SaveValue();
369 m_pFields->SaveValue();
372 return !aExceptionInfo.isValid();
375 //------------------------------------------------------------------
376 void DbaIndexDialog::OnNewIndex()
378 // commit the current entry, if necessary
379 if (!implCommitPreviouslySelected())
380 return;
382 // get a new unique name for the new index
383 String sNewIndexName;
384 const String sNewIndexNameBase(ModuleRes(STR_LOGICAL_INDEX_NAME));
385 sal_Int32 i;
387 for ( i = 1; i < 0x7FFFFFFF; ++i )
389 sNewIndexName = sNewIndexNameBase;
390 sNewIndexName += String::CreateFromInt32(i);
391 if (m_pIndexes->end() == m_pIndexes->find(sNewIndexName))
392 break;
394 if ((i>0x7FFFFFFF) || (i<0))
396 OSL_FAIL("DbaIndexDialog::OnNewIndex: no free index name found!");
397 // can't do anything ... of course we try another base, but this could end with the same result ...
398 return;
401 SvLBoxEntry* pNewEntry = m_aIndexes.InsertEntry(sNewIndexName);
402 m_pIndexes->insert(sNewIndexName);
404 // update the user data on the entries in the list box:
405 // they're iterators of the index collection, and thus they have changed when removing the index
406 for (SvLBoxEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust))
408 Indexes::iterator aAfterInsertPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust));
409 OSL_ENSURE(aAfterInsertPos != m_pIndexes->end(), "DbaIndexDialog::OnNewIndex: problems with on of the entries!");
410 pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterInsertPos - m_pIndexes->begin())));
413 // select the entry and start in-place editing
414 m_aIndexes.SelectNoHandlerCall(pNewEntry);
415 OnIndexSelected(&m_aIndexes);
416 m_aIndexes.EditEntry(pNewEntry);
417 updateToolbox();
420 //------------------------------------------------------------------
421 void DbaIndexDialog::OnDropIndex(sal_Bool _bConfirm)
423 // the selected index
424 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
425 OSL_ENSURE(pSelected, "DbaIndexDialog::OnDropIndex: invalid call!");
426 if (pSelected)
428 // let the user confirm the drop
429 if (_bConfirm)
431 String sConfirm(ModuleRes(STR_CONFIRM_DROP_INDEX));
432 sConfirm.SearchAndReplaceAscii("$name$", m_aIndexes.GetEntryText(pSelected));
433 QueryBox aConfirm(this, WB_YES_NO, sConfirm);
434 if (RET_YES != aConfirm.Execute())
435 return;
438 // do the drop
439 implDropIndex(pSelected, sal_True);
441 // reflect the new selection in the toolbox
442 updateToolbox();
446 //------------------------------------------------------------------
447 sal_Bool DbaIndexDialog::implDropIndex(SvLBoxEntry* _pEntry, sal_Bool _bRemoveFromCollection)
449 // do the drop
450 Indexes::iterator aDropPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
451 OSL_ENSURE(aDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!");
453 SQLExceptionInfo aExceptionInfo;
454 sal_Bool bSuccess = sal_False;
457 if (_bRemoveFromCollection)
458 bSuccess = m_pIndexes->drop(aDropPos);
459 else
460 bSuccess = m_pIndexes->dropNoRemove(aDropPos);
462 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
463 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
464 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
466 if (aExceptionInfo.isValid())
467 showError(aExceptionInfo, this, m_xORB);
468 else if (bSuccess && _bRemoveFromCollection)
470 SvLBoxTreeList* pModel = m_aIndexes.GetModel();
472 m_aIndexes.disableSelectHandler();
473 pModel->Remove(_pEntry);
474 m_aIndexes.enableSelectHandler();
476 // update the user data on the entries in the list box:
477 // they're iterators of the index collection, and thus they have changed when removing the index
478 for (SvLBoxEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust))
480 Indexes::iterator aAfterDropPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust));
481 OSL_ENSURE(aAfterDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: problems with on of the remaining entries!");
482 pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterDropPos - m_pIndexes->begin())));
485 // if the remvoved entry was the selected on ...
486 if (m_pPreviousSelection == _pEntry)
487 m_pPreviousSelection = NULL;
489 // the Remove automatically selected another entry (if possible), but we disabled the calling of the handler
490 // to prevent that we missed something ... call the handler directly
491 OnIndexSelected(&m_aIndexes);
494 return !aExceptionInfo.isValid();
497 //------------------------------------------------------------------
498 void DbaIndexDialog::OnRenameIndex()
500 // the selected index
501 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
502 OSL_ENSURE(pSelected, "DbaIndexDialog::OnRenameIndex: invalid call!");
504 // save the changes made 'til here
505 // Upon leaving the edit mode, the control will be re-initialized with the
506 // settings from the current entry
507 implSaveModified(sal_False);
509 m_aIndexes.EditEntry(pSelected);
510 updateToolbox();
513 //------------------------------------------------------------------
514 void DbaIndexDialog::OnSaveIndex()
516 // the selected index
517 #if OSL_DEBUG_LEVEL > 0
518 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
519 OSL_ENSURE( pSelected, "DbaIndexDialog::OnSaveIndex: invalid call!" );
520 #endif
522 implCommitPreviouslySelected();
523 updateToolbox();
526 //------------------------------------------------------------------
527 void DbaIndexDialog::OnResetIndex()
529 // the selected index
530 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
531 OSL_ENSURE(pSelected, "DbaIndexDialog::OnResetIndex: invalid call!");
533 Indexes::iterator aResetPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
535 if (aResetPos->isNew())
537 OnDropIndex(sal_False);
538 return;
541 SQLExceptionInfo aExceptionInfo;
544 m_pIndexes->resetIndex(aResetPos);
546 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
547 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
548 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
550 if (aExceptionInfo.isValid())
551 showError(aExceptionInfo, this, m_xORB);
552 else
553 m_aIndexes.SetEntryText(pSelected, aResetPos->sName);
555 updateControls(pSelected);
556 updateToolbox();
559 //------------------------------------------------------------------
560 IMPL_LINK( DbaIndexDialog, OnIndexAction, ToolBox*, /*NOTINTERESTEDIN*/ )
562 sal_uInt16 nClicked = m_aActions.GetCurItemId();
563 switch (nClicked)
565 case ID_INDEX_NEW:
566 OnNewIndex();
567 break;
568 case ID_INDEX_DROP:
569 OnDropIndex();
570 break;
571 case ID_INDEX_RENAME:
572 OnRenameIndex();
573 break;
574 case ID_INDEX_SAVE:
575 OnSaveIndex();
576 break;
577 case ID_INDEX_RESET:
578 OnResetIndex();
579 break;
581 return 0L;
584 //------------------------------------------------------------------
585 IMPL_LINK( DbaIndexDialog, OnCloseDialog, void*, /*NOTINTERESTEDIN*/ )
587 if (m_aIndexes.IsEditingActive())
589 OSL_ENSURE(!m_bEditAgain, "DbaIndexDialog::OnCloseDialog: somebody was faster than hell!");
590 // this means somebody entered a new name, which was invalid, which cause us to posted us an event,
591 // and before the event arrived the user clicked onto "close". VERY fast, this user ....
592 m_aIndexes.EndEditing(sal_False);
593 if (m_bEditAgain)
594 // could not commit the new name (started a new - asynchronous - edit trial)
595 return 1L;
598 // the currently selected entry
599 const SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
600 OSL_ENSURE(pSelected == m_pPreviousSelection, "DbaIndexDialog::OnCloseDialog: inconsistence!");
602 sal_Int32 nResponse = RET_NO;
603 if (pSelected)
605 // the descriptor
606 Indexes::const_iterator aSelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
608 if (aSelected->isModified() || aSelected->isNew())
610 QueryBox aQuestion(this, ModuleRes(QUERY_SAVE_CURRENT_INDEX));
611 nResponse = aQuestion.Execute();
615 switch (nResponse)
617 case RET_YES:
618 if (!implCommitPreviouslySelected())
619 return 1L;
620 break;
621 case RET_NO:
622 break;
623 default:
624 return 1L;
627 EndDialog(RET_OK);
629 return 0L;
632 //------------------------------------------------------------------
633 IMPL_LINK( DbaIndexDialog, OnEditIndexAgain, SvLBoxEntry*, _pEntry )
635 m_bEditAgain = sal_False;
636 m_aIndexes.EditEntry(_pEntry);
637 return 0L;
640 //------------------------------------------------------------------
641 IMPL_LINK( DbaIndexDialog, OnEntryEdited, SvLBoxEntry*, _pEntry )
643 Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
645 OSL_ENSURE(aPosition >= m_pIndexes->begin() && aPosition < m_pIndexes->end(),
646 "DbaIndexDialog::OnEntryEdited: invalid entry!");
648 String sNewName = m_aIndexes.GetEntryText(_pEntry);
650 Indexes::const_iterator aSameName = m_pIndexes->find(sNewName);
651 if ((aSameName != aPosition) && (m_pIndexes->end() != aSameName))
653 String sError(ModuleRes(STR_INDEX_NAME_ALREADY_USED));
654 sError.SearchAndReplaceAscii("$name$", sNewName);
655 ErrorBox aError(this, WB_OK, sError);
656 aError.Execute();
658 updateToolbox();
659 m_bEditAgain = sal_True;
660 PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), _pEntry);
661 return 0L;
664 aPosition->sName = sNewName;
666 // rename can be done by a drop/insert combination only
667 if (aPosition->isNew())
669 updateToolbox();
670 // no commitment needed here ....
671 return 1L;
674 if (aPosition->sName != aPosition->getOriginalName())
676 aPosition->setModified(sal_True);
677 updateToolbox();
680 return 1L;
683 //------------------------------------------------------------------
684 sal_Bool DbaIndexDialog::implSaveModified(sal_Bool _bPlausibility)
686 if (m_pPreviousSelection)
688 // try to commit the previously selected index
689 if (m_pFields->IsModified() && !m_pFields->SaveModified())
690 return sal_False;
692 Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
694 // the unique flag
695 aPreviouslySelected->bUnique = m_aUnique.IsChecked();
696 if (m_aUnique.GetSavedValue() != m_aUnique.GetState())
697 aPreviouslySelected->setModified(sal_True);
699 // the fields
700 m_pFields->commitTo(aPreviouslySelected->aFields);
701 if (m_pFields->GetSavedValue() != aPreviouslySelected->aFields)
702 aPreviouslySelected->setModified(sal_True);
704 // plausibility checks
705 if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected))
706 return sal_False;
709 return sal_True;
712 //------------------------------------------------------------------
713 sal_Bool DbaIndexDialog::implCheckPlausibility(const ConstIndexesIterator& _rPos)
715 // need at least one field
716 if (0 == _rPos->aFields.size())
718 ErrorBox aError(this, ModuleRes(ERR_NEED_INDEX_FIELDS));
719 aError.Execute();
720 m_pFields->GrabFocus();
721 return sal_False;
724 // no double fields
725 DECLARE_STL_STDKEY_SET( String, StringBag );
726 StringBag aExistentFields;
727 for ( ConstIndexFieldsIterator aFieldCheck = _rPos->aFields.begin();
728 aFieldCheck != _rPos->aFields.end();
729 ++aFieldCheck
732 if (aExistentFields.end() != aExistentFields.find(aFieldCheck->sFieldName))
734 // a column is specified twice ... won't work anyway, so prevent this here and now
735 String sMessage(ModuleRes(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME));
736 sMessage.SearchAndReplaceAscii("$name$", aFieldCheck->sFieldName);
737 ErrorBox aError(this, WB_OK, sMessage);
738 aError.Execute();
739 m_pFields->GrabFocus();
740 return sal_False;
742 aExistentFields.insert(aFieldCheck->sFieldName);
745 return sal_True;
748 //------------------------------------------------------------------
749 sal_Bool DbaIndexDialog::implCommitPreviouslySelected()
751 if (m_pPreviousSelection)
753 Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
755 if (!implSaveModified())
756 return sal_False;
758 // commit the index (if necessary)
759 if (aPreviouslySelected->isModified() && !implCommit(m_pPreviousSelection))
760 return sal_False;
763 return sal_True;
766 //------------------------------------------------------------------
767 IMPL_LINK( DbaIndexDialog, OnModified, void*, /*NOTINTERESTEDIN*/ )
769 OSL_ENSURE(m_pPreviousSelection, "DbaIndexDialog, OnModified: invalid call!");
770 Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
772 aPosition->setModified(sal_True);
773 updateToolbox();
775 return 1L;
778 //------------------------------------------------------------------
779 void DbaIndexDialog::updateControls(const SvLBoxEntry* _pEntry)
781 if (_pEntry)
783 // the descriptor of the selected index
784 Indexes::const_iterator aSelectedIndex = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
786 // fill the controls
787 m_aUnique.Check(aSelectedIndex->bUnique);
788 m_aUnique.Enable(!aSelectedIndex->bPrimaryKey);
789 m_aUnique.SaveValue();
791 m_pFields->initializeFrom(aSelectedIndex->aFields);
792 m_pFields->Enable(!aSelectedIndex->bPrimaryKey);
793 m_pFields->SaveValue();
795 m_aDescription.SetText(aSelectedIndex->sDescription);
796 m_aDescription.Enable(!aSelectedIndex->bPrimaryKey);
798 m_aDescriptionLabel.Enable(!aSelectedIndex->bPrimaryKey);
800 else
802 m_aUnique.Check(sal_False);
803 m_pFields->initializeFrom(IndexFields());
804 m_aDescription.SetText(String());
808 //------------------------------------------------------------------
809 IMPL_LINK( DbaIndexDialog, OnIndexSelected, DbaIndexList*, /*NOTINTERESTEDIN*/ )
811 m_aIndexes.EndSelection();
813 if (m_aIndexes.IsEditingActive())
814 m_aIndexes.EndEditing(sal_False);
816 // commit the old data
817 if (m_aIndexes.FirstSelected() != m_pPreviousSelection)
818 { // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing)
819 if (!implCommitPreviouslySelected())
821 m_aIndexes.SelectNoHandlerCall(m_pPreviousSelection);
822 return 1L;
826 sal_Bool bHaveSelection = (NULL != m_aIndexes.FirstSelected());
828 // disable/enable the detail controls
829 m_aIndexDetails.Enable(bHaveSelection);
830 m_aUnique.Enable(bHaveSelection);
831 m_aDescriptionLabel.Enable(bHaveSelection);
832 m_aFieldsLabel.Enable(bHaveSelection);
833 m_pFields->Enable(bHaveSelection);
835 SvLBoxEntry* pNewSelection = m_aIndexes.FirstSelected();
836 updateControls(pNewSelection);
837 if (bHaveSelection)
838 m_aIndexes.GrabFocus();
840 m_pPreviousSelection = pNewSelection;
842 updateToolbox();
843 return 0L;
845 // -----------------------------------------------------------------------------
846 void DbaIndexDialog::StateChanged( StateChangedType nType )
848 ModalDialog::StateChanged( nType );
850 if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
852 // Check if we need to get new images for normal/high contrast mode
853 checkImageList();
855 else if ( nType == STATE_CHANGE_TEXT )
857 // The physical toolbar changed its outlook and shows another logical toolbar!
858 // We have to set the correct high contrast mode on the new tbx manager.
859 // pMgr->SetHiContrast( IsHiContrastMode() );
860 checkImageList();
863 // -----------------------------------------------------------------------------
864 void DbaIndexDialog::DataChanged( const DataChangedEvent& rDCEvt )
866 ModalDialog::DataChanged( rDCEvt );
868 if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
869 ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) &&
870 ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
872 // Check if we need to get new images for normal/high contrast mode
873 checkImageList();
876 //------------------------------------------------------------------
877 ImageList DbaIndexDialog::getImageList(sal_Int16 _eBitmapSet) const
879 sal_Int16 nN = IMG_INDEX_DLG_SC;
880 if ( _eBitmapSet == SFX_SYMBOLS_SIZE_LARGE )
882 nN = IMG_INDEX_DLG_LC;
884 return ImageList(ModuleRes(nN));
886 //------------------------------------------------------------------
887 void DbaIndexDialog::resizeControls(const Size& _rDiff)
889 // we use large images so we must change them
890 if ( _rDiff.Width() || _rDiff.Height() )
892 Size aDlgSize = GetSizePixel();
893 // adjust size of dlg
894 SetSizePixel(Size(aDlgSize.Width() + _rDiff.Width(),
895 aDlgSize.Height() + _rDiff.Height())
897 Size aIndexSize = m_aIndexes.GetSizePixel();
898 m_aIndexes.SetPosSizePixel(m_aIndexes.GetPosPixel() + Point(0,_rDiff.Height()),
899 Size(aIndexSize.Width() + _rDiff.Width(),
900 aIndexSize.Height()));
902 //now move the rest to the left side
903 Point aMove(_rDiff.Width(),_rDiff.Height());
904 m_aIndexDetails.SetPosPixel(m_aIndexDetails.GetPosPixel() + aMove);
905 m_aDescriptionLabel.SetPosPixel(m_aDescriptionLabel.GetPosPixel() + aMove);
906 m_aDescription.SetPosPixel(m_aDescription.GetPosPixel() + aMove);
907 m_aUnique.SetPosPixel(m_aUnique.GetPosPixel() + aMove);
908 m_aFieldsLabel.SetPosPixel(m_aFieldsLabel.GetPosPixel() + aMove);
909 OSL_ENSURE(m_pFields,"NO valid fields!");
910 m_pFields->SetPosPixel(m_pFields->GetPosPixel() + aMove);
911 m_aClose.SetPosPixel(m_aClose.GetPosPixel() + aMove);
912 m_aHelp.SetPosPixel(m_aHelp.GetPosPixel() + aMove);
914 Invalidate();
918 //......................................................................
919 } // namespace dbaui
920 //......................................................................
922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */