1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
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 //......................................................................
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 //==================================================================
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())
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
)
84 //------------------------------------------------------------------
85 sal_Bool
operator !=(const IndexFields
& _rLHS
, const IndexFields
& _rRHS
)
87 return !(_rLHS
== _rRHS
);
90 //==================================================================
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();
110 OUString sAlias
= ::dbtools::convertName2SQLName(_rNewText
, xMeta
->getExtraNameCharacters());
111 if ( ( xMeta
->supportsMixedCaseQuotedIdentifiers() )
115 !_rNewText
.equalsIgnoreAsciiCase(sAlias
))
120 if (!SvTreeListBox::EditedEntry(_pEntry
, _rNewText
))
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
));
133 SvTreeListBox::SetEntryText(_pEntry
, sOldText
);
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);
171 //==================================================================
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
))
194 ,m_pPreviousSelection(NULL
)
195 ,m_bEditAgain(sal_False
)
196 ,m_xContext(_rxContext
)
198 DBG_CTOR(DbaIndexDialog
,NULL
);
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
);
225 OSL_FAIL("DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
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();
243 if (!aCheck
->sDescription
.isEmpty())
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();
258 m_aUnique
.SetPosPixel(aPos
);
260 aPos
= m_aFieldsLabel
.GetPosPixel();
262 m_aFieldsLabel
.SetPosPixel(aPos
);
264 aPos
= m_pFields
->GetPosPixel();
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
;
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
;
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
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
);
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( )
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
))
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
359 if (aExceptionInfo
.isValid())
360 showError(aExceptionInfo
, this, m_xContext
);
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())
377 // get a new unique name for the new index
378 String sNewIndexName
;
379 const String
sNewIndexNameBase(ModuleRes(STR_LOGICAL_INDEX_NAME
));
382 for ( i
= 1; i
< 0x7FFFFFFF; ++i
)
384 sNewIndexName
= sNewIndexNameBase
;
385 sNewIndexName
+= OUString::number(i
);
386 if (m_pIndexes
->end() == m_pIndexes
->find(sNewIndexName
))
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 ...
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
);
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!");
423 // let the user confirm the drop
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())
434 implDropIndex(pSelected
, sal_True
);
436 // reflect the new selection in the toolbox
441 //------------------------------------------------------------------
442 sal_Bool
DbaIndexDialog::implDropIndex(SvTreeListEntry
* _pEntry
, sal_Bool _bRemoveFromCollection
)
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
);
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
);
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!" );
517 implCommitPreviouslySelected();
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
);
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
);
548 m_aIndexes
.SetEntryText(pSelected
, aResetPos
->sName
);
550 updateControls(pSelected
);
554 //------------------------------------------------------------------
555 IMPL_LINK( DbaIndexDialog
, OnIndexAction
, ToolBox
*, /*NOTINTERESTEDIN*/ )
557 sal_uInt16 nClicked
= m_aActions
.GetCurItemId();
566 case ID_INDEX_RENAME
:
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
);
589 // could not commit the new name (started a new - asynchronous - edit trial)
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
;
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();
613 if (!implCommitPreviouslySelected())
627 //------------------------------------------------------------------
628 IMPL_LINK( DbaIndexDialog
, OnEditIndexAgain
, SvTreeListEntry
*, _pEntry
)
630 m_bEditAgain
= sal_False
;
631 m_aIndexes
.EditEntry(_pEntry
);
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
);
654 m_bEditAgain
= sal_True
;
655 PostUserEvent(LINK(this, DbaIndexDialog
, OnEditIndexAgain
), _pEntry
);
659 aPosition
->sName
= sNewName
;
661 // rename can be done by a drop/insert combination only
662 if (aPosition
->isNew())
665 // no commitment needed here ....
669 if (aPosition
->sName
!= aPosition
->getOriginalName())
671 aPosition
->setModified(sal_True
);
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())
687 Indexes::iterator aPreviouslySelected
= m_pIndexes
->begin() + reinterpret_cast<sal_IntPtr
>(m_pPreviousSelection
->GetUserData());
690 aPreviouslySelected
->bUnique
= m_aUnique
.IsChecked();
691 if (m_aUnique
.GetSavedValue() != m_aUnique
.GetState())
692 aPreviouslySelected
->setModified(sal_True
);
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
))
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
));
715 m_pFields
->GrabFocus();
720 std::set
< String
> aExistentFields
;
721 for ( ConstIndexFieldsIterator aFieldCheck
= _rPos
->aFields
.begin();
722 aFieldCheck
!= _rPos
->aFields
.end();
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
);
733 m_pFields
->GrabFocus();
736 aExistentFields
.insert(aFieldCheck
->sFieldName
);
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())
752 // commit the index (if necessary)
753 if (aPreviouslySelected
->isModified() && !implCommit(m_pPreviousSelection
))
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
);
772 //------------------------------------------------------------------
773 void DbaIndexDialog::updateControls(const SvTreeListEntry
* _pEntry
)
777 // the descriptor of the selected index
778 Indexes::const_iterator aSelectedIndex
= m_pIndexes
->begin() + reinterpret_cast<sal_IntPtr
>(_pEntry
->GetUserData());
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
);
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
);
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
);
832 m_aIndexes
.GrabFocus();
834 m_pPreviousSelection
= pNewSelection
;
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
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() );
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
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
);
912 //......................................................................
914 //......................................................................
916 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */