/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: indexdialog.cxx,v $ * $Revision: 1.30 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_dbaccess.hxx" #ifndef _DBAUI_INDEXDIALOG_HXX_ #include "indexdialog.hxx" #endif #ifndef _DBU_DLG_HRC_ #include "dbu_dlg.hrc" #endif #ifndef _DBA_DBACCESS_HELPID_HRC_ #include "dbaccess_helpid.hrc" #endif #ifndef _DBAUI_INDEXDIALOG_HRC_ #include "indexdialog.hrc" #endif #ifndef _DBAUI_INDEXFIELDSCONTROL_HXX_ #include "indexfieldscontrol.hxx" #endif #ifndef _DBAUI_INDEXCOLLECTION_HXX_ #include "indexcollection.hxx" #endif #ifndef _SV_MSGBOX_HXX #include #endif #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_ #include #endif #ifndef DBAUI_TOOLS_HXX #include "UITools.hxx" #endif #ifndef _SVTOOLS_IMGDEF_HXX #include #endif #ifndef DBACCESS_UI_BROWSER_ID_HXX #include "browserids.hxx" #endif #ifndef _CONNECTIVITY_DBTOOLS_HXX_ #include #endif //...................................................................... namespace dbaui { //...................................................................... using namespace ::com::sun::star::uno; using namespace ::com::sun::star::container; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::lang; using namespace ::dbtools; //================================================================== //= helper //================================================================== //------------------------------------------------------------------ sal_Bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS) { return (_rLHS.sFieldName == _rRHS.sFieldName) && (_rLHS.bSortAscending == _rRHS.bSortAscending); } //------------------------------------------------------------------ sal_Bool operator !=(const OIndexField& _rLHS, const OIndexField& _rRHS) { return !(_rLHS == _rRHS); } //------------------------------------------------------------------ sal_Bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS) { if (_rLHS.size() != _rRHS.size()) return sal_False; ConstIndexFieldsIterator aLeft = _rLHS.begin(); ConstIndexFieldsIterator aLeftEnd = _rLHS.end(); ConstIndexFieldsIterator aRight = _rRHS.begin(); for (; aLeft != aLeftEnd; ++aLeft, ++aRight) { if (*aLeft != *aRight) return sal_False; } return sal_True; } //------------------------------------------------------------------ sal_Bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS) { return !(_rLHS == _rRHS); } //================================================================== //= DbaIndexList //================================================================== //------------------------------------------------------------------ DbaIndexList::DbaIndexList(Window* _pParent, const ResId& _rId) :SvTreeListBox(_pParent, _rId) ,m_bSuspendSelectHdl(sal_False) { } extern sal_Bool isCharOk(sal_Unicode _cChar,sal_Bool _bFirstChar,sal_Bool _bUpperCase,const ::rtl::OUString& _sAllowedChars); //------------------------------------------------------------------ sal_Bool DbaIndexList::EditedEntry( SvLBoxEntry* _pEntry, const String& _rNewText ) { // first check if this is valid SQL92 name if ( isSQL92CheckEnabled(m_xConnection) ) { Reference xMeta = m_xConnection->getMetaData(); if ( xMeta.is() ) { ::rtl::OUString sNewName(_rNewText); ::rtl::OUString sAlias = ::dbtools::convertName2SQLName(sNewName,xMeta->getExtraNameCharacters()); if ( ( xMeta->supportsMixedCaseQuotedIdentifiers() ) ? sAlias != sNewName : !sNewName.equalsIgnoreAsciiCase(sAlias)) return sal_False; } } if (!SvTreeListBox::EditedEntry(_pEntry, _rNewText)) return sal_False; String sOldText = GetEntryText(_pEntry); SvTreeListBox::SetEntryText(_pEntry, _rNewText); sal_Bool bValid = sal_True; if (m_aEndEditHdl.IsSet()) bValid = (0 != m_aEndEditHdl.Call(_pEntry)); if (bValid) return sal_True; SvTreeListBox::SetEntryText(_pEntry, sOldText); return sal_False; } //------------------------------------------------------------------ void DbaIndexList::enableSelectHandler() { DBG_ASSERT(m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!"); m_bSuspendSelectHdl = sal_False; } //------------------------------------------------------------------ void DbaIndexList::disableSelectHandler() { DBG_ASSERT(!m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!"); m_bSuspendSelectHdl = sal_True; } //------------------------------------------------------------------ void DbaIndexList::SelectNoHandlerCall( SvLBoxEntry* _pEntry ) { disableSelectHandler(); Select(_pEntry, sal_True); enableSelectHandler(); } //------------------------------------------------------------------ sal_Bool DbaIndexList::Select( SvLBoxEntry* pEntry, sal_Bool _bSelect ) { sal_Bool bReturn = SvTreeListBox::Select(pEntry, _bSelect); if (m_aSelectHdl.IsSet() && !m_bSuspendSelectHdl && _bSelect) m_aSelectHdl.Call(this); return bReturn; } //================================================================== //= DbaIndexDialog //================================================================== DBG_NAME(DbaIndexDialog) //------------------------------------------------------------------ DbaIndexDialog::DbaIndexDialog( Window* _pParent, const Sequence< ::rtl::OUString >& _rFieldNames, const Reference< XNameAccess >& _rxIndexes, const Reference< XConnection >& _rxConnection, const Reference< XMultiServiceFactory >& _rxORB,sal_Int32 _nMaxColumnsInIndex) :ModalDialog( _pParent, ModuleRes(DLG_INDEXDESIGN)) ,m_xConnection(_rxConnection) ,m_aGeometrySettings(E_DIALOG, ::rtl::OUString::createFromAscii("dbaccess.tabledesign.indexdialog")) ,m_aActions (this, ModuleRes(TLB_ACTIONS)) ,m_aIndexes (this, ModuleRes(CTR_INDEXLIST)) ,m_aIndexDetails (this, ModuleRes(FL_INDEXDETAILS)) ,m_aDescriptionLabel (this, ModuleRes(FT_DESC_LABEL)) ,m_aDescription (this, ModuleRes(FT_DESCRIPTION)) ,m_aUnique (this, ModuleRes(CB_UNIQUE)) ,m_aFieldsLabel (this, ModuleRes(FT_FIELDS)) ,m_pFields(new IndexFieldsControl (this, ModuleRes(CTR_FIELDS),_nMaxColumnsInIndex)) ,m_aClose (this, ModuleRes(PB_CLOSE)) ,m_aHelp (this, ModuleRes(HB_HELP)) ,m_pIndexes(NULL) ,m_pPreviousSelection(NULL) ,m_bEditAgain(sal_False) ,m_xORB(_rxORB) { DBG_CTOR(DbaIndexDialog,NULL); FreeResource(); m_aActions.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexAction)); m_aIndexes.SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexSelected)); m_aIndexes.SetEndEditHdl(LINK(this, DbaIndexDialog, OnEntryEdited)); m_aIndexes.SetSelectionMode(SINGLE_SELECTION); m_aIndexes.SetHighlightRange(); m_aIndexes.setConnection(m_xConnection); m_pFields->Init(_rFieldNames); setToolBox(&m_aActions); m_pIndexes = new OIndexCollection(); try { m_pIndexes->attach(_rxIndexes); } catch(SQLException& e) { ::dbaui::showError(SQLExceptionInfo(e),_pParent,_rxORB); } catch(Exception&) { OSL_ENSURE(sal_False, "DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!"); } fillIndexList(); m_aUnique.SetClickHdl(LINK(this, DbaIndexDialog, OnModified)); m_pFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified)); m_aClose.SetClickHdl(LINK(this, DbaIndexDialog, OnCloseDialog)); // get our most recent geometry settings // if (m_aGeometrySettings.Exists()) // { // Point aPos; // m_aGeometrySettings.GetPosition(aPos.X(), aPos.Y()); // SetPosPixel(aPos); // } // if all of the indexes have an empty description, we're not interested in displaying it Indexes::const_iterator aCheck; for ( aCheck = m_pIndexes->begin(); aCheck != m_pIndexes->end(); ++aCheck ) { if (aCheck->sDescription.getLength()) break; } if (aCheck == m_pIndexes->end()) { sal_Int32 nMoveUp = m_aUnique.GetPosPixel().Y() - m_aDescriptionLabel.GetPosPixel().Y(); // hide the controls which are necessary for the description m_aDescription.Hide(); m_aDescriptionLabel.Hide(); // move other controls up Point aPos = m_aUnique.GetPosPixel(); aPos.Y() -= nMoveUp; m_aUnique.SetPosPixel(aPos); aPos = m_aFieldsLabel.GetPosPixel(); aPos.Y() -= nMoveUp; m_aFieldsLabel.SetPosPixel(aPos); aPos = m_pFields->GetPosPixel(); aPos.Y() -= nMoveUp; m_pFields->SetPosPixel(aPos); // and enlarge the fields list Size aSize = m_pFields->GetSizePixel(); aSize.Height() += nMoveUp; m_pFields->SetSizePixel(aSize); } } //------------------------------------------------------------------ void DbaIndexDialog::updateToolbox() { m_aActions.EnableItem(ID_INDEX_NEW, !m_aIndexes.IsEditingActive()); SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); sal_Bool bSelectedAnything = NULL != pSelected; if (pSelected) { // is the current entry modified? Indexes::const_iterator aSelectedPos = m_pIndexes->begin() + reinterpret_cast(pSelected->GetUserData()); m_aActions.EnableItem(ID_INDEX_SAVE, aSelectedPos->isModified() || aSelectedPos->isNew()); m_aActions.EnableItem(ID_INDEX_RESET, aSelectedPos->isModified() || aSelectedPos->isNew()); bSelectedAnything = bSelectedAnything && !aSelectedPos->bPrimaryKey; } else { m_aActions.EnableItem(ID_INDEX_SAVE, sal_False); m_aActions.EnableItem(ID_INDEX_RESET, sal_False); } m_aActions.EnableItem(ID_INDEX_DROP, bSelectedAnything); m_aActions.EnableItem(ID_INDEX_RENAME, bSelectedAnything); } //------------------------------------------------------------------ void DbaIndexDialog::fillIndexList() { sal_Bool bHiContrast = GetBackground().GetColor().IsDark(); Image aPKeyIcon(ModuleRes( bHiContrast ? IMG_PKEYICON_SCH : IMG_PKEYICON)); // fill the list with the index names m_aIndexes.Clear(); Indexes::iterator aIndexLoop = m_pIndexes->begin(); Indexes::iterator aEnd = m_pIndexes->end(); for (; aIndexLoop != aEnd; ++aIndexLoop) { SvLBoxEntry* pNewEntry = NULL; if (aIndexLoop->bPrimaryKey) pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName, aPKeyIcon, aPKeyIcon); else pNewEntry = m_aIndexes.InsertEntry(aIndexLoop->sName); pNewEntry->SetUserData(reinterpret_cast< void* >(sal_Int32(aIndexLoop - m_pIndexes->begin()))); } OnIndexSelected(&m_aIndexes); } //------------------------------------------------------------------ DbaIndexDialog::~DbaIndexDialog( ) { setToolBox(NULL); delete m_pIndexes; delete m_pFields; // save our geometry settings // Point aPos = GetPosPixel(); // m_aGeometrySettings.SetPosition(aPos.X(), aPos.Y()); DBG_DTOR(DbaIndexDialog,NULL); } //------------------------------------------------------------------ sal_Bool DbaIndexDialog::implCommit(SvLBoxEntry* _pEntry) { DBG_ASSERT(_pEntry, "DbaIndexDialog::implCommit: invalid entry!"); Indexes::iterator aCommitPos = m_pIndexes->begin() + reinterpret_cast(_pEntry->GetUserData()); // if it's not a new index, remove it // (we can't modify indexes, only drop'n'insert) if (!aCommitPos->isNew()) if (!implDropIndex(_pEntry, sal_False)) return sal_False; // create the new index SQLExceptionInfo aExceptionInfo; try { m_pIndexes->commitNewIndex(aCommitPos); } catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); } catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); } catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); } // reflect the new selection in the toolbox updateToolbox(); if (aExceptionInfo.isValid()) showError(aExceptionInfo, this, m_xORB); else { m_aUnique.SaveValue(); m_pFields->SaveValue(); } return !aExceptionInfo.isValid(); } //------------------------------------------------------------------ void DbaIndexDialog::OnNewIndex() { // commit the current entry, if necessary if (!implCommitPreviouslySelected()) return; // get a new unique name for the new index String sNewIndexName; const String sNewIndexNameBase(ModuleRes(STR_LOGICAL_INDEX_NAME)); sal_Int32 i; for ( i = 1; i < 0x7FFFFFFF; ++i ) { sNewIndexName = sNewIndexNameBase; sNewIndexName += String::CreateFromInt32(i); if (m_pIndexes->end() == m_pIndexes->find(sNewIndexName)) break; } if ((i>0x7FFFFFFF) || (i<0)) { DBG_ERROR("DbaIndexDialog::OnNewIndex: no free index name found!"); // can't do anything ... of course we try another base, but this could end with the same result ... return; } SvLBoxEntry* pNewEntry = m_aIndexes.InsertEntry(sNewIndexName); m_pIndexes->insert(sNewIndexName); // update the user data on the entries in the list box: // they're iterators of the index collection, and thus they have changed when removing the index for (SvLBoxEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust)) { Indexes::iterator aAfterInsertPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust)); DBG_ASSERT(aAfterInsertPos != m_pIndexes->end(), "DbaIndexDialog::OnNewIndex: problems with on of the entries!"); pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterInsertPos - m_pIndexes->begin()))); } // select the entry and start in-place editing m_aIndexes.SelectNoHandlerCall(pNewEntry); OnIndexSelected(&m_aIndexes); m_aIndexes.EditEntry(pNewEntry); updateToolbox(); } //------------------------------------------------------------------ void DbaIndexDialog::OnDropIndex(sal_Bool _bConfirm) { // the selected index SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); DBG_ASSERT(pSelected, "DbaIndexDialog::OnDropIndex: invalid call!"); if (pSelected) { // let the user confirm the drop if (_bConfirm) { String sConfirm(ModuleRes(STR_CONFIRM_DROP_INDEX)); sConfirm.SearchAndReplaceAscii("$name$", m_aIndexes.GetEntryText(pSelected)); QueryBox aConfirm(this, WB_YES_NO, sConfirm); if (RET_YES != aConfirm.Execute()) return; } // do the drop implDropIndex(pSelected, sal_True); // reflect the new selection in the toolbox updateToolbox(); } } //------------------------------------------------------------------ sal_Bool DbaIndexDialog::implDropIndex(SvLBoxEntry* _pEntry, sal_Bool _bRemoveFromCollection) { // do the drop Indexes::iterator aDropPos = m_pIndexes->begin() + reinterpret_cast(_pEntry->GetUserData()); DBG_ASSERT(aDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!"); SQLExceptionInfo aExceptionInfo; sal_Bool bSuccess = sal_False; try { if (_bRemoveFromCollection) bSuccess = m_pIndexes->drop(aDropPos); else bSuccess = m_pIndexes->dropNoRemove(aDropPos); } catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); } catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); } catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); } if (aExceptionInfo.isValid()) showError(aExceptionInfo, this, m_xORB); else if (bSuccess && _bRemoveFromCollection) { SvLBoxTreeList* pModel = m_aIndexes.GetModel(); m_aIndexes.disableSelectHandler(); pModel->Remove(_pEntry); m_aIndexes.enableSelectHandler(); // update the user data on the entries in the list box: // they're iterators of the index collection, and thus they have changed when removing the index for (SvLBoxEntry* pAdjust = m_aIndexes.First(); pAdjust; pAdjust = m_aIndexes.Next(pAdjust)) { Indexes::iterator aAfterDropPos = m_pIndexes->find(m_aIndexes.GetEntryText(pAdjust)); DBG_ASSERT(aAfterDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: problems with on of the remaining entries!"); pAdjust->SetUserData(reinterpret_cast< void* >(sal_Int32(aAfterDropPos - m_pIndexes->begin()))); } // if the remvoved entry was the selected on ... if (m_pPreviousSelection == _pEntry) m_pPreviousSelection = NULL; // the Remove automatically selected another entry (if possible), but we disabled the calling of the handler // to prevent that we missed something ... call the handler directly OnIndexSelected(&m_aIndexes); } return !aExceptionInfo.isValid(); } //------------------------------------------------------------------ void DbaIndexDialog::OnRenameIndex() { // the selected index SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); DBG_ASSERT(pSelected, "DbaIndexDialog::OnRenameIndex: invalid call!"); // save the changes made 'til here // Upon leaving the edit mode, the control will be re-initialized with the // settings from the current entry implSaveModified(sal_False); m_aIndexes.EditEntry(pSelected); updateToolbox(); } //------------------------------------------------------------------ void DbaIndexDialog::OnSaveIndex() { // the selected index #if OSL_DEBUG_LEVEL > 0 SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); OSL_ENSURE( pSelected, "DbaIndexDialog::OnSaveIndex: invalid call!" ); #endif implCommitPreviouslySelected(); updateToolbox(); } //------------------------------------------------------------------ void DbaIndexDialog::OnResetIndex() { // the selected index SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); DBG_ASSERT(pSelected, "DbaIndexDialog::OnResetIndex: invalid call!"); Indexes::iterator aResetPos = m_pIndexes->begin() + reinterpret_cast(pSelected->GetUserData()); if (aResetPos->isNew()) { OnDropIndex(sal_False); return; } SQLExceptionInfo aExceptionInfo; try { m_pIndexes->resetIndex(aResetPos); } catch(SQLContext& e) { aExceptionInfo = SQLExceptionInfo(e); } catch(SQLWarning& e) { aExceptionInfo = SQLExceptionInfo(e); } catch(SQLException& e) { aExceptionInfo = SQLExceptionInfo(e); } if (aExceptionInfo.isValid()) showError(aExceptionInfo, this, m_xORB); else m_aIndexes.SetEntryText(pSelected, aResetPos->sName); updateControls(pSelected); updateToolbox(); } //------------------------------------------------------------------ IMPL_LINK( DbaIndexDialog, OnIndexAction, ToolBox*, /*NOTINTERESTEDIN*/ ) { sal_uInt16 nClicked = m_aActions.GetCurItemId(); switch (nClicked) { case ID_INDEX_NEW: OnNewIndex(); break; case ID_INDEX_DROP: OnDropIndex(); break; case ID_INDEX_RENAME: OnRenameIndex(); break; case ID_INDEX_SAVE: OnSaveIndex(); break; case ID_INDEX_RESET: OnResetIndex(); break; } return 0L; } //------------------------------------------------------------------ IMPL_LINK( DbaIndexDialog, OnCloseDialog, void*, /*NOTINTERESTEDIN*/ ) { if (m_aIndexes.IsEditingActive()) { DBG_ASSERT(!m_bEditAgain, "DbaIndexDialog::OnCloseDialog: somebody was faster than hell!"); // this means somebody entered a new name, which was invalid, which cause us to posted us an event, // and before the event arrived the user clicked onto "close". VERY fast, this user .... m_aIndexes.EndEditing(sal_False); if (m_bEditAgain) // could not commit the new name (started a new - asynchronous - edit trial) return 1L; } // the currently selected entry const SvLBoxEntry* pSelected = m_aIndexes.FirstSelected(); DBG_ASSERT(pSelected == m_pPreviousSelection, "DbaIndexDialog::OnCloseDialog: inconsistence!"); sal_Int32 nResponse = RET_NO; if (pSelected) { // the descriptor Indexes::const_iterator aSelected = m_pIndexes->begin() + reinterpret_cast(pSelected->GetUserData()); if (aSelected->isModified() || aSelected->isNew()) { QueryBox aQuestion(this, ModuleRes(QUERY_SAVE_CURRENT_INDEX)); nResponse = aQuestion.Execute(); } } switch (nResponse) { case RET_YES: if (!implCommitPreviouslySelected()) return 1L; break; case RET_NO: break; default: return 1L; } EndDialog(RET_OK); return 0L; } //------------------------------------------------------------------ IMPL_LINK( DbaIndexDialog, OnEditIndexAgain, SvLBoxEntry*, _pEntry ) { m_bEditAgain = sal_False; m_aIndexes.EditEntry(_pEntry); return 0L; } //------------------------------------------------------------------ IMPL_LINK( DbaIndexDialog, OnEntryEdited, SvLBoxEntry*, _pEntry ) { Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast(_pEntry->GetUserData()); DBG_ASSERT(aPosition >= m_pIndexes->begin() && aPosition < m_pIndexes->end(), "DbaIndexDialog::OnEntryEdited: invalid entry!"); String sNewName = m_aIndexes.GetEntryText(_pEntry); Indexes::const_iterator aSameName = m_pIndexes->find(sNewName); if ((aSameName != aPosition) && (m_pIndexes->end() != aSameName)) { String sError(ModuleRes(STR_INDEX_NAME_ALREADY_USED)); sError.SearchAndReplaceAscii("$name$", sNewName); ErrorBox aError(this, WB_OK, sError); aError.Execute(); updateToolbox(); m_bEditAgain = sal_True; PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), _pEntry); return 0L; } aPosition->sName = sNewName; // rename can be done by a drop/insert combination only if (aPosition->isNew()) { updateToolbox(); // no commitment needed here .... return 1L; } if (aPosition->sName != aPosition->getOriginalName()) { aPosition->setModified(sal_True); updateToolbox(); } return 1L; } //------------------------------------------------------------------ sal_Bool DbaIndexDialog::implSaveModified(sal_Bool _bPlausibility) { if (m_pPreviousSelection) { // try to commit the previously selected index if (m_pFields->IsModified() && !m_pFields->SaveModified()) return sal_False; Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast(m_pPreviousSelection->GetUserData()); // the unique flag aPreviouslySelected->bUnique = m_aUnique.IsChecked(); if (m_aUnique.GetSavedValue() != m_aUnique.GetState()) aPreviouslySelected->setModified(sal_True); // the fields m_pFields->commitTo(aPreviouslySelected->aFields); if (m_pFields->GetSavedValue() != aPreviouslySelected->aFields) aPreviouslySelected->setModified(sal_True); // plausibility checks if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected)) return sal_False; } return sal_True; } //------------------------------------------------------------------ sal_Bool DbaIndexDialog::implCheckPlausibility(const ConstIndexesIterator& _rPos) { // need at least one field if (0 == _rPos->aFields.size()) { ErrorBox aError(this, ModuleRes(ERR_NEED_INDEX_FIELDS)); aError.Execute(); m_pFields->GrabFocus(); return sal_False; } // no double fields DECLARE_STL_STDKEY_SET( String, StringBag ); StringBag aExistentFields; for ( ConstIndexFieldsIterator aFieldCheck = _rPos->aFields.begin(); aFieldCheck != _rPos->aFields.end(); ++aFieldCheck ) { if (aExistentFields.end() != aExistentFields.find(aFieldCheck->sFieldName)) { // a column is specified twice ... won't work anyway, so prevent this here and now String sMessage(ModuleRes(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME)); sMessage.SearchAndReplaceAscii("$name$", aFieldCheck->sFieldName); ErrorBox aError(this, WB_OK, sMessage); aError.Execute(); m_pFields->GrabFocus(); return sal_False; } aExistentFields.insert(aFieldCheck->sFieldName); } return sal_True; } //------------------------------------------------------------------ sal_Bool DbaIndexDialog::implCommitPreviouslySelected() { if (m_pPreviousSelection) { Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast(m_pPreviousSelection->GetUserData()); if (!implSaveModified()) return sal_False; // commit the index (if necessary) if (aPreviouslySelected->isModified() && !implCommit(m_pPreviousSelection)) return sal_False; } return sal_True; } //------------------------------------------------------------------ IMPL_LINK( DbaIndexDialog, OnModified, void*, /*NOTINTERESTEDIN*/ ) { DBG_ASSERT(m_pPreviousSelection, "DbaIndexDialog, OnModified: invalid call!"); Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast(m_pPreviousSelection->GetUserData()); aPosition->setModified(sal_True); updateToolbox(); return 1L; } //------------------------------------------------------------------ void DbaIndexDialog::updateControls(const SvLBoxEntry* _pEntry) { if (_pEntry) { // the descriptor of the selected index Indexes::const_iterator aSelectedIndex = m_pIndexes->begin() + reinterpret_cast(_pEntry->GetUserData()); // fill the controls m_aUnique.Check(aSelectedIndex->bUnique); m_aUnique.Enable(!aSelectedIndex->bPrimaryKey); m_aUnique.SaveValue(); m_pFields->initializeFrom(aSelectedIndex->aFields); m_pFields->Enable(!aSelectedIndex->bPrimaryKey); m_pFields->SaveValue(); m_aDescription.SetText(aSelectedIndex->sDescription); m_aDescription.Enable(!aSelectedIndex->bPrimaryKey); m_aDescriptionLabel.Enable(!aSelectedIndex->bPrimaryKey); } else { m_aUnique.Check(sal_False); m_pFields->initializeFrom(IndexFields()); m_aDescription.SetText(String()); } } //------------------------------------------------------------------ IMPL_LINK( DbaIndexDialog, OnIndexSelected, DbaIndexList*, /*NOTINTERESTEDIN*/ ) { m_aIndexes.EndSelection(); if (m_aIndexes.IsEditingActive()) m_aIndexes.EndEditing(sal_False); // commit the old data if (m_aIndexes.FirstSelected() != m_pPreviousSelection) { // (this call may happen in case somebody ended an in-place edit with 'return', so we need to check this before committing) if (!implCommitPreviouslySelected()) { m_aIndexes.SelectNoHandlerCall(m_pPreviousSelection); return 1L; } } sal_Bool bHaveSelection = (NULL != m_aIndexes.FirstSelected()); // disable/enable the detail controls m_aIndexDetails.Enable(bHaveSelection); m_aUnique.Enable(bHaveSelection); m_aDescriptionLabel.Enable(bHaveSelection); m_aFieldsLabel.Enable(bHaveSelection); m_pFields->Enable(bHaveSelection); SvLBoxEntry* pNewSelection = m_aIndexes.FirstSelected(); updateControls(pNewSelection); if (bHaveSelection) m_aIndexes.GrabFocus(); m_pPreviousSelection = pNewSelection; updateToolbox(); return 0L; } // ----------------------------------------------------------------------------- void DbaIndexDialog::StateChanged( StateChangedType nType ) { ModalDialog::StateChanged( nType ); if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) { // Check if we need to get new images for normal/high contrast mode checkImageList(); } else if ( nType == STATE_CHANGE_TEXT ) { // The physical toolbar changed its outlook and shows another logical toolbar! // We have to set the correct high contrast mode on the new tbx manager. // pMgr->SetHiContrast( IsHiContrastMode() ); checkImageList(); } } // ----------------------------------------------------------------------------- void DbaIndexDialog::DataChanged( const DataChangedEvent& rDCEvt ) { ModalDialog::DataChanged( rDCEvt ); if ((( rDCEvt.GetType() == DATACHANGED_SETTINGS ) || ( rDCEvt.GetType() == DATACHANGED_DISPLAY )) && ( rDCEvt.GetFlags() & SETTINGS_STYLE )) { // Check if we need to get new images for normal/high contrast mode checkImageList(); } } //------------------------------------------------------------------ ImageList DbaIndexDialog::getImageList(sal_Int16 _eBitmapSet,sal_Bool _bHiContast) const { sal_Int16 nN = IMG_INDEX_DLG_SC; sal_Int16 nH = IMG_INDEX_DLG_SCH; if ( _eBitmapSet == SFX_SYMBOLS_SIZE_LARGE ) { nN = IMG_INDEX_DLG_LC; nH = IMG_INDEX_DLG_LCH; } // if ( _eBitmapSet == SFX_SYMBOLS_LARGE ) return ImageList(ModuleRes( _bHiContast ? nH : nN )); } //------------------------------------------------------------------ void DbaIndexDialog::resizeControls(const Size& _rDiff) { // we use large images so we must change them Size aTbNewSize = m_aActions.GetSizePixel(); if ( _rDiff.Width() || _rDiff.Height() ) { Size aDlgSize = GetSizePixel(); // adjust size of dlg SetSizePixel(Size(aDlgSize.Width() + _rDiff.Width(), aDlgSize.Height() + _rDiff.Height()) ); Size aIndexSize = m_aIndexes.GetSizePixel(); m_aIndexes.SetPosSizePixel(m_aIndexes.GetPosPixel() + Point(0,_rDiff.Height()), Size(aIndexSize.Width() + _rDiff.Width(), aIndexSize.Height())); //now move the rest to the left side Point aMove(_rDiff.Width(),_rDiff.Height()); m_aIndexDetails.SetPosPixel(m_aIndexDetails.GetPosPixel() + aMove); m_aDescriptionLabel.SetPosPixel(m_aDescriptionLabel.GetPosPixel() + aMove); m_aDescription.SetPosPixel(m_aDescription.GetPosPixel() + aMove); m_aUnique.SetPosPixel(m_aUnique.GetPosPixel() + aMove); m_aFieldsLabel.SetPosPixel(m_aFieldsLabel.GetPosPixel() + aMove); OSL_ENSURE(m_pFields,"NO valid fields!"); m_pFields->SetPosPixel(m_pFields->GetPosPixel() + aMove); m_aClose.SetPosPixel(m_aClose.GetPosPixel() + aMove); m_aHelp.SetPosPixel(m_aHelp.GetPosPixel() + aMove); Invalidate(); } } //...................................................................... } // namespace dbaui //......................................................................