blob: fee0459ea53d12721446d12aa3919458ef75a851 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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 <vcl/msgbox.hxx>
#endif
#ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
#include <com/sun/star/sdb/SQLContext.hpp>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _SVTOOLS_IMGDEF_HXX
#include <svtools/imgdef.hxx>
#endif
#ifndef DBACCESS_UI_BROWSER_ID_HXX
#include "browserids.hxx"
#endif
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
#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<XDatabaseMetaData> 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,::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" )))
,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<sal_IntPtr>(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 = GetSettings().GetStyleSettings().GetHighContrastMode();
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<sal_IntPtr>(_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<sal_IntPtr>(_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<sal_IntPtr>(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<sal_IntPtr>(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<sal_IntPtr>(_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<sal_IntPtr>(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<sal_IntPtr>(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<sal_IntPtr>(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<sal_IntPtr>(_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
//......................................................................