merge the formfield patch from ooo-build
[ooovba.git] / dbaccess / source / ui / dlg / indexdialog.cxx
blob08d0ab1445df7572427bd05f75d7a34ac702a7e3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: indexdialog.cxx,v $
10 * $Revision: 1.30 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #ifndef _DBAUI_INDEXDIALOG_HXX_
35 #include "indexdialog.hxx"
36 #endif
37 #ifndef _DBU_DLG_HRC_
38 #include "dbu_dlg.hrc"
39 #endif
40 #ifndef _DBA_DBACCESS_HELPID_HRC_
41 #include "dbaccess_helpid.hrc"
42 #endif
43 #ifndef _DBAUI_INDEXDIALOG_HRC_
44 #include "indexdialog.hrc"
45 #endif
46 #ifndef _DBAUI_INDEXFIELDSCONTROL_HXX_
47 #include "indexfieldscontrol.hxx"
48 #endif
49 #ifndef _DBAUI_INDEXCOLLECTION_HXX_
50 #include "indexcollection.hxx"
51 #endif
52 #ifndef _SV_MSGBOX_HXX
53 #include <vcl/msgbox.hxx>
54 #endif
55 #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
56 #include <com/sun/star/sdb/SQLContext.hpp>
57 #endif
58 #ifndef DBAUI_TOOLS_HXX
59 #include "UITools.hxx"
60 #endif
61 #ifndef _SVTOOLS_IMGDEF_HXX
62 #include <svtools/imgdef.hxx>
63 #endif
64 #ifndef DBACCESS_UI_BROWSER_ID_HXX
65 #include "browserids.hxx"
66 #endif
67 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
68 #include <connectivity/dbtools.hxx>
69 #endif
70 //......................................................................
71 namespace dbaui
73 //......................................................................
75 using namespace ::com::sun::star::uno;
76 using namespace ::com::sun::star::container;
77 using namespace ::com::sun::star::sdbc;
78 using namespace ::com::sun::star::sdb;
79 using namespace ::com::sun::star::lang;
80 using namespace ::dbtools;
82 //==================================================================
83 //= helper
84 //==================================================================
85 //------------------------------------------------------------------
86 sal_Bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS)
88 return (_rLHS.sFieldName == _rRHS.sFieldName)
89 && (_rLHS.bSortAscending == _rRHS.bSortAscending);
92 //------------------------------------------------------------------
93 sal_Bool operator !=(const OIndexField& _rLHS, const OIndexField& _rRHS)
95 return !(_rLHS == _rRHS);
98 //------------------------------------------------------------------
99 sal_Bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS)
101 if (_rLHS.size() != _rRHS.size())
102 return sal_False;
104 ConstIndexFieldsIterator aLeft = _rLHS.begin();
105 ConstIndexFieldsIterator aLeftEnd = _rLHS.end();
106 ConstIndexFieldsIterator aRight = _rRHS.begin();
107 for (; aLeft != aLeftEnd; ++aLeft, ++aRight)
109 if (*aLeft != *aRight)
110 return sal_False;
113 return sal_True;
116 //------------------------------------------------------------------
117 sal_Bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
119 return !(_rLHS == _rRHS);
122 //==================================================================
123 //= DbaIndexList
124 //==================================================================
125 //------------------------------------------------------------------
126 DbaIndexList::DbaIndexList(Window* _pParent, const ResId& _rId)
127 :SvTreeListBox(_pParent, _rId)
128 ,m_bSuspendSelectHdl(sal_False)
132 extern sal_Bool isCharOk(sal_Unicode _cChar,sal_Bool _bFirstChar,sal_Bool _bUpperCase,const ::rtl::OUString& _sAllowedChars);
133 //------------------------------------------------------------------
134 sal_Bool DbaIndexList::EditedEntry( SvLBoxEntry* _pEntry, const String& _rNewText )
136 // first check if this is valid SQL92 name
137 if ( isSQL92CheckEnabled(m_xConnection) )
139 Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
140 if ( xMeta.is() )
142 ::rtl::OUString sNewName(_rNewText);
143 ::rtl::OUString sAlias = ::dbtools::convertName2SQLName(sNewName,xMeta->getExtraNameCharacters());
144 if ( ( xMeta->supportsMixedCaseQuotedIdentifiers() )
146 sAlias != sNewName
148 !sNewName.equalsIgnoreAsciiCase(sAlias))
149 return sal_False;
153 if (!SvTreeListBox::EditedEntry(_pEntry, _rNewText))
154 return sal_False;
156 String sOldText = GetEntryText(_pEntry);
157 SvTreeListBox::SetEntryText(_pEntry, _rNewText);
159 sal_Bool bValid = sal_True;
160 if (m_aEndEditHdl.IsSet())
161 bValid = (0 != m_aEndEditHdl.Call(_pEntry));
163 if (bValid)
164 return sal_True;
166 SvTreeListBox::SetEntryText(_pEntry, sOldText);
168 return sal_False;
171 //------------------------------------------------------------------
172 void DbaIndexList::enableSelectHandler()
174 DBG_ASSERT(m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
175 m_bSuspendSelectHdl = sal_False;
178 //------------------------------------------------------------------
179 void DbaIndexList::disableSelectHandler()
181 DBG_ASSERT(!m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
182 m_bSuspendSelectHdl = sal_True;
185 //------------------------------------------------------------------
186 void DbaIndexList::SelectNoHandlerCall( SvLBoxEntry* _pEntry )
188 disableSelectHandler();
189 Select(_pEntry, sal_True);
190 enableSelectHandler();
193 //------------------------------------------------------------------
194 sal_Bool DbaIndexList::Select( SvLBoxEntry* pEntry, sal_Bool _bSelect )
196 sal_Bool bReturn = SvTreeListBox::Select(pEntry, _bSelect);
198 if (m_aSelectHdl.IsSet() && !m_bSuspendSelectHdl && _bSelect)
199 m_aSelectHdl.Call(this);
201 return bReturn;
204 //==================================================================
205 //= DbaIndexDialog
206 //==================================================================
207 DBG_NAME(DbaIndexDialog)
208 //------------------------------------------------------------------
209 DbaIndexDialog::DbaIndexDialog( Window* _pParent, const Sequence< ::rtl::OUString >& _rFieldNames,
210 const Reference< XNameAccess >& _rxIndexes,
211 const Reference< XConnection >& _rxConnection,
212 const Reference< XMultiServiceFactory >& _rxORB,sal_Int32 _nMaxColumnsInIndex)
213 :ModalDialog( _pParent, ModuleRes(DLG_INDEXDESIGN))
214 ,m_xConnection(_rxConnection)
215 ,m_aGeometrySettings(E_DIALOG, ::rtl::OUString::createFromAscii("dbaccess.tabledesign.indexdialog"))
216 ,m_aActions (this, ModuleRes(TLB_ACTIONS))
217 ,m_aIndexes (this, ModuleRes(CTR_INDEXLIST))
218 ,m_aIndexDetails (this, ModuleRes(FL_INDEXDETAILS))
219 ,m_aDescriptionLabel (this, ModuleRes(FT_DESC_LABEL))
220 ,m_aDescription (this, ModuleRes(FT_DESCRIPTION))
221 ,m_aUnique (this, ModuleRes(CB_UNIQUE))
222 ,m_aFieldsLabel (this, ModuleRes(FT_FIELDS))
223 ,m_pFields(new IndexFieldsControl (this, ModuleRes(CTR_FIELDS),_nMaxColumnsInIndex))
224 ,m_aClose (this, ModuleRes(PB_CLOSE))
225 ,m_aHelp (this, ModuleRes(HB_HELP))
226 ,m_pIndexes(NULL)
227 ,m_pPreviousSelection(NULL)
228 ,m_bEditAgain(sal_False)
229 ,m_xORB(_rxORB)
231 DBG_CTOR(DbaIndexDialog,NULL);
233 FreeResource();
235 m_aActions.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexAction));
237 m_aIndexes.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexSelected));
238 m_aIndexes.SetEndEditHdl(LINK(this, DbaIndexDialog, OnEntryEdited));
239 m_aIndexes.SetSelectionMode(SINGLE_SELECTION);
240 m_aIndexes.SetHighlightRange();
241 m_aIndexes.setConnection(m_xConnection);
243 m_pFields->Init(_rFieldNames);
245 setToolBox(&m_aActions);
247 m_pIndexes = new OIndexCollection();
250 m_pIndexes->attach(_rxIndexes);
252 catch(SQLException& e)
254 ::dbaui::showError(SQLExceptionInfo(e),_pParent,_rxORB);
256 catch(Exception&)
258 OSL_ENSURE(sal_False, "DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
261 fillIndexList();
263 m_aUnique.SetClickHdl(LINK(this, DbaIndexDialog, OnModified));
264 m_pFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified));
266 m_aClose.SetClickHdl(LINK(this, DbaIndexDialog, OnCloseDialog));
268 // get our most recent geometry settings
269 // if (m_aGeometrySettings.Exists())
270 // {
271 // Point aPos;
272 // m_aGeometrySettings.GetPosition(aPos.X(), aPos.Y());
273 // SetPosPixel(aPos);
274 // }
276 // if all of the indexes have an empty description, we're not interested in displaying it
277 Indexes::const_iterator aCheck;
279 for ( aCheck = m_pIndexes->begin();
280 aCheck != m_pIndexes->end();
281 ++aCheck
284 if (aCheck->sDescription.getLength())
285 break;
288 if (aCheck == m_pIndexes->end())
290 sal_Int32 nMoveUp = m_aUnique.GetPosPixel().Y() - m_aDescriptionLabel.GetPosPixel().Y();
292 // hide the controls which are necessary for the description
293 m_aDescription.Hide();
294 m_aDescriptionLabel.Hide();
296 // move other controls up
297 Point aPos = m_aUnique.GetPosPixel();
298 aPos.Y() -= nMoveUp;
299 m_aUnique.SetPosPixel(aPos);
301 aPos = m_aFieldsLabel.GetPosPixel();
302 aPos.Y() -= nMoveUp;
303 m_aFieldsLabel.SetPosPixel(aPos);
305 aPos = m_pFields->GetPosPixel();
306 aPos.Y() -= nMoveUp;
307 m_pFields->SetPosPixel(aPos);
309 // and enlarge the fields list
310 Size aSize = m_pFields->GetSizePixel();
311 aSize.Height() += nMoveUp;
312 m_pFields->SetSizePixel(aSize);
316 //------------------------------------------------------------------
317 void DbaIndexDialog::updateToolbox()
319 m_aActions.EnableItem(ID_INDEX_NEW, !m_aIndexes.IsEditingActive());
321 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
322 sal_Bool bSelectedAnything = NULL != pSelected;
325 if (pSelected)
327 // is the current entry modified?
328 Indexes::const_iterator aSelectedPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
329 m_aActions.EnableItem(ID_INDEX_SAVE, aSelectedPos->isModified() || aSelectedPos->isNew());
330 m_aActions.EnableItem(ID_INDEX_RESET, aSelectedPos->isModified() || aSelectedPos->isNew());
331 bSelectedAnything = bSelectedAnything && !aSelectedPos->bPrimaryKey;
333 else
335 m_aActions.EnableItem(ID_INDEX_SAVE, sal_False);
336 m_aActions.EnableItem(ID_INDEX_RESET, sal_False);
338 m_aActions.EnableItem(ID_INDEX_DROP, bSelectedAnything);
339 m_aActions.EnableItem(ID_INDEX_RENAME, bSelectedAnything);
342 //------------------------------------------------------------------
343 void DbaIndexDialog::fillIndexList()
345 sal_Bool bHiContrast = GetBackground().GetColor().IsDark();
346 Image aPKeyIcon(ModuleRes( bHiContrast ? IMG_PKEYICON_SCH : IMG_PKEYICON));
347 // fill the list with the index names
348 m_aIndexes.Clear();
349 Indexes::iterator aIndexLoop = m_pIndexes->begin();
350 Indexes::iterator aEnd = m_pIndexes->end();
351 for (; aIndexLoop != aEnd; ++aIndexLoop)
353 SvLBoxEntry* pNewEntry = NULL;
354 if (aIndexLoop->bPrimaryKey)
355 pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName, aPKeyIcon, aPKeyIcon);
356 else
357 pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName);
359 pNewEntry->SetUserData(reinterpret_cast< void* >(sal_Int32(aIndexLoop - m_pIndexes->begin())));
362 OnIndexSelected(&m_aIndexes);
365 //------------------------------------------------------------------
366 DbaIndexDialog::~DbaIndexDialog( )
368 setToolBox(NULL);
369 delete m_pIndexes;
370 delete m_pFields;
372 // save our geometry settings
373 // Point aPos = GetPosPixel();
374 // m_aGeometrySettings.SetPosition(aPos.X(), aPos.Y());
376 DBG_DTOR(DbaIndexDialog,NULL);
379 //------------------------------------------------------------------
380 sal_Bool DbaIndexDialog::implCommit(SvLBoxEntry* _pEntry)
382 DBG_ASSERT(_pEntry, "DbaIndexDialog::implCommit: invalid entry!");
384 Indexes::iterator aCommitPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
386 // if it's not a new index, remove it
387 // (we can't modify indexes, only drop'n'insert)
388 if (!aCommitPos->isNew())
389 if (!implDropIndex(_pEntry, sal_False))
390 return sal_False;
392 // create the new index
393 SQLExceptionInfo aExceptionInfo;
396 m_pIndexes->commitNewIndex(aCommitPos);
398 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
399 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
400 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
402 // reflect the new selection in the toolbox
403 updateToolbox();
405 if (aExceptionInfo.isValid())
406 showError(aExceptionInfo, this, m_xORB);
407 else
409 m_aUnique.SaveValue();
410 m_pFields->SaveValue();
413 return !aExceptionInfo.isValid();
416 //------------------------------------------------------------------
417 void DbaIndexDialog::OnNewIndex()
419 // commit the current entry, if necessary
420 if (!implCommitPreviouslySelected())
421 return;
423 // get a new unique name for the new index
424 String sNewIndexName;
425 const String sNewIndexNameBase(ModuleRes(STR_LOGICAL_INDEX_NAME));
426 sal_Int32 i;
428 for ( i = 1; i < 0x7FFFFFFF; ++i )
430 sNewIndexName = sNewIndexNameBase;
431 sNewIndexName += String::CreateFromInt32(i);
432 if (m_pIndexes->end() == m_pIndexes->find(sNewIndexName))
433 break;
435 if ((i>0x7FFFFFFF) || (i<0))
437 DBG_ERROR("DbaIndexDialog::OnNewIndex: no free index name found!");
438 // can't do anything ... of course we try another base, but this could end with the same result ...
439 return;
442 SvLBoxEntry* pNewEntry = m_aIndexes.InsertEntry(sNewIndexName);
443 m_pIndexes->insert(sNewIndexName);
445 // update the user data on the entries in the list box:
446 // they're iterators of the index collection, and thus they have changed when removing the index
447 for (SvLBoxEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust))
449 Indexes::iterator aAfterInsertPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust));
450 DBG_ASSERT(aAfterInsertPos != m_pIndexes->end(), "DbaIndexDialog::OnNewIndex: problems with on of the entries!");
451 pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterInsertPos - m_pIndexes->begin())));
454 // select the entry and start in-place editing
455 m_aIndexes.SelectNoHandlerCall(pNewEntry);
456 OnIndexSelected(&m_aIndexes);
457 m_aIndexes.EditEntry(pNewEntry);
458 updateToolbox();
461 //------------------------------------------------------------------
462 void DbaIndexDialog::OnDropIndex(sal_Bool _bConfirm)
464 // the selected index
465 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
466 DBG_ASSERT(pSelected, "DbaIndexDialog::OnDropIndex: invalid call!");
467 if (pSelected)
469 // let the user confirm the drop
470 if (_bConfirm)
472 String sConfirm(ModuleRes(STR_CONFIRM_DROP_INDEX));
473 sConfirm.SearchAndReplaceAscii("$name$", m_aIndexes.GetEntryText(pSelected));
474 QueryBox aConfirm(this, WB_YES_NO, sConfirm);
475 if (RET_YES != aConfirm.Execute())
476 return;
479 // do the drop
480 implDropIndex(pSelected, sal_True);
482 // reflect the new selection in the toolbox
483 updateToolbox();
487 //------------------------------------------------------------------
488 sal_Bool DbaIndexDialog::implDropIndex(SvLBoxEntry* _pEntry, sal_Bool _bRemoveFromCollection)
490 // do the drop
491 Indexes::iterator aDropPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
492 DBG_ASSERT(aDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!");
494 SQLExceptionInfo aExceptionInfo;
495 sal_Bool bSuccess = sal_False;
498 if (_bRemoveFromCollection)
499 bSuccess = m_pIndexes->drop(aDropPos);
500 else
501 bSuccess = m_pIndexes->dropNoRemove(aDropPos);
503 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
504 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
505 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
507 if (aExceptionInfo.isValid())
508 showError(aExceptionInfo, this, m_xORB);
509 else if (bSuccess && _bRemoveFromCollection)
511 SvLBoxTreeList* pModel = m_aIndexes.GetModel();
513 m_aIndexes.disableSelectHandler();
514 pModel->Remove(_pEntry);
515 m_aIndexes.enableSelectHandler();
517 // update the user data on the entries in the list box:
518 // they're iterators of the index collection, and thus they have changed when removing the index
519 for (SvLBoxEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust))
521 Indexes::iterator aAfterDropPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust));
522 DBG_ASSERT(aAfterDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: problems with on of the remaining entries!");
523 pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterDropPos - m_pIndexes->begin())));
526 // if the remvoved entry was the selected on ...
527 if (m_pPreviousSelection == _pEntry)
528 m_pPreviousSelection = NULL;
530 // the Remove automatically selected another entry (if possible), but we disabled the calling of the handler
531 // to prevent that we missed something ... call the handler directly
532 OnIndexSelected(&m_aIndexes);
535 return !aExceptionInfo.isValid();
538 //------------------------------------------------------------------
539 void DbaIndexDialog::OnRenameIndex()
541 // the selected index
542 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
543 DBG_ASSERT(pSelected, "DbaIndexDialog::OnRenameIndex: invalid call!");
545 // save the changes made 'til here
546 // Upon leaving the edit mode, the control will be re-initialized with the
547 // settings from the current entry
548 implSaveModified(sal_False);
550 m_aIndexes.EditEntry(pSelected);
551 updateToolbox();
554 //------------------------------------------------------------------
555 void DbaIndexDialog::OnSaveIndex()
557 // the selected index
558 #if OSL_DEBUG_LEVEL > 0
559 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
560 OSL_ENSURE( pSelected, "DbaIndexDialog::OnSaveIndex: invalid call!" );
561 #endif
563 implCommitPreviouslySelected();
564 updateToolbox();
567 //------------------------------------------------------------------
568 void DbaIndexDialog::OnResetIndex()
570 // the selected index
571 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
572 DBG_ASSERT(pSelected, "DbaIndexDialog::OnResetIndex: invalid call!");
574 Indexes::iterator aResetPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
576 if (aResetPos->isNew())
578 OnDropIndex(sal_False);
579 return;
582 SQLExceptionInfo aExceptionInfo;
585 m_pIndexes->resetIndex(aResetPos);
587 catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); }
588 catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); }
589 catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); }
591 if (aExceptionInfo.isValid())
592 showError(aExceptionInfo, this, m_xORB);
593 else
594 m_aIndexes.SetEntryText(pSelected, aResetPos->sName);
596 updateControls(pSelected);
597 updateToolbox();
600 //------------------------------------------------------------------
601 IMPL_LINK( DbaIndexDialog, OnIndexAction, ToolBox*, /*NOTINTERESTEDIN*/ )
603 sal_uInt16 nClicked = m_aActions.GetCurItemId();
604 switch (nClicked)
606 case ID_INDEX_NEW:
607 OnNewIndex();
608 break;
609 case ID_INDEX_DROP:
610 OnDropIndex();
611 break;
612 case ID_INDEX_RENAME:
613 OnRenameIndex();
614 break;
615 case ID_INDEX_SAVE:
616 OnSaveIndex();
617 break;
618 case ID_INDEX_RESET:
619 OnResetIndex();
620 break;
622 return 0L;
625 //------------------------------------------------------------------
626 IMPL_LINK( DbaIndexDialog, OnCloseDialog, void*, /*NOTINTERESTEDIN*/ )
628 if (m_aIndexes.IsEditingActive())
630 DBG_ASSERT(!m_bEditAgain, "DbaIndexDialog::OnCloseDialog: somebody was faster than hell!");
631 // this means somebody entered a new name, which was invalid, which cause us to posted us an event,
632 // and before the event arrived the user clicked onto "close". VERY fast, this user ....
633 m_aIndexes.EndEditing(sal_False);
634 if (m_bEditAgain)
635 // could not commit the new name (started a new - asynchronous - edit trial)
636 return 1L;
639 // the currently selected entry
640 const SvLBoxEntry* pSelected = m_aIndexes.FirstSelected();
641 DBG_ASSERT(pSelected == m_pPreviousSelection, "DbaIndexDialog::OnCloseDialog: inconsistence!");
643 sal_Int32 nResponse = RET_NO;
644 if (pSelected)
646 // the descriptor
647 Indexes::const_iterator aSelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
649 if (aSelected->isModified() || aSelected->isNew())
651 QueryBox aQuestion(this, ModuleRes(QUERY_SAVE_CURRENT_INDEX));
652 nResponse = aQuestion.Execute();
656 switch (nResponse)
658 case RET_YES:
659 if (!implCommitPreviouslySelected())
660 return 1L;
661 break;
662 case RET_NO:
663 break;
664 default:
665 return 1L;
668 EndDialog(RET_OK);
670 return 0L;
673 //------------------------------------------------------------------
674 IMPL_LINK( DbaIndexDialog, OnEditIndexAgain, SvLBoxEntry*, _pEntry )
676 m_bEditAgain = sal_False;
677 m_aIndexes.EditEntry(_pEntry);
678 return 0L;
681 //------------------------------------------------------------------
682 IMPL_LINK( DbaIndexDialog, OnEntryEdited, SvLBoxEntry*, _pEntry )
684 Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
686 DBG_ASSERT(aPosition >= m_pIndexes->begin() && aPosition < m_pIndexes->end(),
687 "DbaIndexDialog::OnEntryEdited: invalid entry!");
689 String sNewName = m_aIndexes.GetEntryText(_pEntry);
691 Indexes::const_iterator aSameName = m_pIndexes->find(sNewName);
692 if ((aSameName != aPosition) && (m_pIndexes->end() != aSameName))
694 String sError(ModuleRes(STR_INDEX_NAME_ALREADY_USED));
695 sError.SearchAndReplaceAscii("$name$", sNewName);
696 ErrorBox aError(this, WB_OK, sError);
697 aError.Execute();
699 updateToolbox();
700 m_bEditAgain = sal_True;
701 PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), _pEntry);
702 return 0L;
705 aPosition->sName = sNewName;
707 // rename can be done by a drop/insert combination only
708 if (aPosition->isNew())
710 updateToolbox();
711 // no commitment needed here ....
712 return 1L;
715 if (aPosition->sName != aPosition->getOriginalName())
717 aPosition->setModified(sal_True);
718 updateToolbox();
721 return 1L;
724 //------------------------------------------------------------------
725 sal_Bool DbaIndexDialog::implSaveModified(sal_Bool _bPlausibility)
727 if (m_pPreviousSelection)
729 // try to commit the previously selected index
730 if (m_pFields->IsModified() && !m_pFields->SaveModified())
731 return sal_False;
733 Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
735 // the unique flag
736 aPreviouslySelected->bUnique = m_aUnique.IsChecked();
737 if (m_aUnique.GetSavedValue() != m_aUnique.GetState())
738 aPreviouslySelected->setModified(sal_True);
740 // the fields
741 m_pFields->commitTo(aPreviouslySelected->aFields);
742 if (m_pFields->GetSavedValue() != aPreviouslySelected->aFields)
743 aPreviouslySelected->setModified(sal_True);
745 // plausibility checks
746 if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected))
747 return sal_False;
750 return sal_True;
753 //------------------------------------------------------------------
754 sal_Bool DbaIndexDialog::implCheckPlausibility(const ConstIndexesIterator& _rPos)
756 // need at least one field
757 if (0 == _rPos->aFields.size())
759 ErrorBox aError(this, ModuleRes(ERR_NEED_INDEX_FIELDS));
760 aError.Execute();
761 m_pFields->GrabFocus();
762 return sal_False;
765 // no double fields
766 DECLARE_STL_STDKEY_SET( String, StringBag );
767 StringBag aExistentFields;
768 for ( ConstIndexFieldsIterator aFieldCheck = _rPos->aFields.begin();
769 aFieldCheck != _rPos->aFields.end();
770 ++aFieldCheck
773 if (aExistentFields.end() != aExistentFields.find(aFieldCheck->sFieldName))
775 // a column is specified twice ... won't work anyway, so prevent this here and now
776 String sMessage(ModuleRes(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME));
777 sMessage.SearchAndReplaceAscii("$name$", aFieldCheck->sFieldName);
778 ErrorBox aError(this, WB_OK, sMessage);
779 aError.Execute();
780 m_pFields->GrabFocus();
781 return sal_False;
783 aExistentFields.insert(aFieldCheck->sFieldName);
786 return sal_True;
789 //------------------------------------------------------------------
790 sal_Bool DbaIndexDialog::implCommitPreviouslySelected()
792 if (m_pPreviousSelection)
794 Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
796 if (!implSaveModified())
797 return sal_False;
799 // commit the index (if necessary)
800 if (aPreviouslySelected->isModified() && !implCommit(m_pPreviousSelection))
801 return sal_False;
804 return sal_True;
807 //------------------------------------------------------------------
808 IMPL_LINK( DbaIndexDialog, OnModified, void*, /*NOTINTERESTEDIN*/ )
810 DBG_ASSERT(m_pPreviousSelection, "DbaIndexDialog, OnModified: invalid call!");
811 Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
813 aPosition->setModified(sal_True);
814 updateToolbox();
816 return 1L;
819 //------------------------------------------------------------------
820 void DbaIndexDialog::updateControls(const SvLBoxEntry* _pEntry)
822 if (_pEntry)
824 // the descriptor of the selected index
825 Indexes::const_iterator aSelectedIndex = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
827 // fill the controls
828 m_aUnique.Check(aSelectedIndex->bUnique);
829 m_aUnique.Enable(!aSelectedIndex->bPrimaryKey);
830 m_aUnique.SaveValue();
832 m_pFields->initializeFrom(aSelectedIndex->aFields);
833 m_pFields->Enable(!aSelectedIndex->bPrimaryKey);
834 m_pFields->SaveValue();
836 m_aDescription.SetText(aSelectedIndex->sDescription);
837 m_aDescription.Enable(!aSelectedIndex->bPrimaryKey);
839 m_aDescriptionLabel.Enable(!aSelectedIndex->bPrimaryKey);
841 else
843 m_aUnique.Check(sal_False);
844 m_pFields->initializeFrom(IndexFields());
845 m_aDescription.SetText(String());
849 //------------------------------------------------------------------
850 IMPL_LINK( DbaIndexDialog, OnIndexSelected, DbaIndexList*, /*NOTINTERESTEDIN*/ )
852 m_aIndexes.EndSelection();
854 if (m_aIndexes.IsEditingActive())
855 m_aIndexes.EndEditing(sal_False);
857 // commit the old data
858 if (m_aIndexes.FirstSelected() != m_pPreviousSelection)
859 { // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing)
860 if (!implCommitPreviouslySelected())
862 m_aIndexes.SelectNoHandlerCall(m_pPreviousSelection);
863 return 1L;
867 sal_Bool bHaveSelection = (NULL != m_aIndexes.FirstSelected());
869 // disable/enable the detail controls
870 m_aIndexDetails.Enable(bHaveSelection);
871 m_aUnique.Enable(bHaveSelection);
872 m_aDescriptionLabel.Enable(bHaveSelection);
873 m_aFieldsLabel.Enable(bHaveSelection);
874 m_pFields->Enable(bHaveSelection);
876 SvLBoxEntry* pNewSelection = m_aIndexes.FirstSelected();
877 updateControls(pNewSelection);
878 if (bHaveSelection)
879 m_aIndexes.GrabFocus();
881 m_pPreviousSelection = pNewSelection;
883 updateToolbox();
884 return 0L;
886 // -----------------------------------------------------------------------------
887 void DbaIndexDialog::StateChanged( StateChangedType nType )
889 ModalDialog::StateChanged( nType );
891 if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
893 // Check if we need to get new images for normal/high contrast mode
894 checkImageList();
896 else if ( nType == STATE_CHANGE_TEXT )
898 // The physical toolbar changed its outlook and shows another logical toolbar!
899 // We have to set the correct high contrast mode on the new tbx manager.
900 // pMgr->SetHiContrast( IsHiContrastMode() );
901 checkImageList();
904 // -----------------------------------------------------------------------------
905 void DbaIndexDialog::DataChanged( const DataChangedEvent& rDCEvt )
907 ModalDialog::DataChanged( rDCEvt );
909 if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) ||
910 ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) &&
911 ( rDCEvt.GetFlags() & SETTINGS_STYLE ))
913 // Check if we need to get new images for normal/high contrast mode
914 checkImageList();
917 //------------------------------------------------------------------
918 ImageList DbaIndexDialog::getImageList(sal_Int16 _eBitmapSet,sal_Bool _bHiContast) const
920 sal_Int16 nN = IMG_INDEX_DLG_SC;
921 sal_Int16 nH = IMG_INDEX_DLG_SCH;
922 if ( _eBitmapSet == SFX_SYMBOLS_SIZE_LARGE )
924 nN = IMG_INDEX_DLG_LC;
925 nH = IMG_INDEX_DLG_LCH;
926 } // if ( _eBitmapSet == SFX_SYMBOLS_LARGE )
927 return ImageList(ModuleRes( _bHiContast ? nH : nN ));
929 //------------------------------------------------------------------
930 void DbaIndexDialog::resizeControls(const Size& _rDiff)
932 // we use large images so we must change them
933 Size aTbNewSize = m_aActions.GetSizePixel();
934 if ( _rDiff.Width() || _rDiff.Height() )
936 Size aDlgSize = GetSizePixel();
937 // adjust size of dlg
938 SetSizePixel(Size(aDlgSize.Width() + _rDiff.Width(),
939 aDlgSize.Height() + _rDiff.Height())
941 Size aIndexSize = m_aIndexes.GetSizePixel();
942 m_aIndexes.SetPosSizePixel(m_aIndexes.GetPosPixel() + Point(0,_rDiff.Height()),
943 Size(aIndexSize.Width() + _rDiff.Width(),
944 aIndexSize.Height()));
946 //now move the rest to the left side
947 Point aMove(_rDiff.Width(),_rDiff.Height());
948 m_aIndexDetails.SetPosPixel(m_aIndexDetails.GetPosPixel() + aMove);
949 m_aDescriptionLabel.SetPosPixel(m_aDescriptionLabel.GetPosPixel() + aMove);
950 m_aDescription.SetPosPixel(m_aDescription.GetPosPixel() + aMove);
951 m_aUnique.SetPosPixel(m_aUnique.GetPosPixel() + aMove);
952 m_aFieldsLabel.SetPosPixel(m_aFieldsLabel.GetPosPixel() + aMove);
953 OSL_ENSURE(m_pFields,"NO valid fields!");
954 m_pFields->SetPosPixel(m_pFields->GetPosPixel() + aMove);
955 m_aClose.SetPosPixel(m_aClose.GetPosPixel() + aMove);
956 m_aHelp.SetPosPixel(m_aHelp.GetPosPixel() + aMove);
958 Invalidate();
962 //......................................................................
963 } // namespace dbaui
964 //......................................................................