Files
libreoffice/dbaccess/source/ui/dlg/indexdialog.cxx
Michael Meeks e4097762dd Audit all PostUserEvent calls and instrument for VclPtr.
Hold a reference on the VclPtr while we're waiting for the UserEvent.

Change-Id: I55c2671ca12eb14761c6a7dffd551af71547ecbd
2015-05-25 21:38:08 +01:00

869 lines
31 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#include "sal/config.h"
#include <set>
#include "indexdialog.hxx"
#include "dbu_dlg.hrc"
#include "dbaccess_helpid.hrc"
#include "indexfieldscontrol.hxx"
#include "indexcollection.hxx"
#include <vcl/layout.hxx>
#include <vcl/settings.hxx>
#include <vcl/builderfactory.hxx>
#include <com/sun/star/sdb/SQLContext.hpp>
#include "UITools.hxx"
#include <svtools/imgdef.hxx>
#include "svtools/treelistentry.hxx"
#include "browserids.hxx"
#include <connectivity/dbtools.hxx>
#include <osl/diagnose.h>
const char INDEX_NEW_CMD[] = ".index:createNew";
const char INDEX_DROP_CMD[] = ".index:dropCurrent";
const char INDEX_RENAME_CMD[] = ".index:renameCurrent";
const char INDEX_SAVE_CMD[] = ".index:saveCurrent";
const char INDEX_RESET_CMD[] = ".index:resetCurrent";
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
bool operator ==(const OIndexField& _rLHS, const OIndexField& _rRHS)
{
return (_rLHS.sFieldName == _rRHS.sFieldName)
&& (_rLHS.bSortAscending == _rRHS.bSortAscending);
}
bool operator !=(const OIndexField& _rLHS, const OIndexField& _rRHS)
{
return !(_rLHS == _rRHS);
}
bool operator ==(const IndexFields& _rLHS, const IndexFields& _rRHS)
{
if (_rLHS.size() != _rRHS.size())
return false;
IndexFields::const_iterator aLeft = _rLHS.begin();
IndexFields::const_iterator aLeftEnd = _rLHS.end();
IndexFields::const_iterator aRight = _rRHS.begin();
for (; aLeft != aLeftEnd; ++aLeft, ++aRight)
{
if (*aLeft != *aRight)
return false;
}
return true;
}
bool operator !=(const IndexFields& _rLHS, const IndexFields& _rRHS)
{
return !(_rLHS == _rRHS);
}
// DbaIndexList
DbaIndexList::DbaIndexList(vcl::Window* _pParent, WinBits nWinBits)
:SvTreeListBox(_pParent, nWinBits)
,m_bSuspendSelectHdl(false)
{
}
bool DbaIndexList::EditedEntry( SvTreeListEntry* _pEntry, const OUString& _rNewText )
{
// first check if this is valid SQL92 name
if ( isSQL92CheckEnabled(m_xConnection) )
{
Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
if ( xMeta.is() )
{
OUString sAlias = ::dbtools::convertName2SQLName(_rNewText, xMeta->getExtraNameCharacters());
if ( ( xMeta->supportsMixedCaseQuotedIdentifiers() )
?
sAlias != _rNewText
:
!_rNewText.equalsIgnoreAsciiCase(sAlias))
return false;
}
}
if (!SvTreeListBox::EditedEntry(_pEntry, _rNewText))
return false;
OUString sOldText = GetEntryText(_pEntry);
SvTreeListBox::SetEntryText(_pEntry, _rNewText);
bool bValid = true;
if (m_aEndEditHdl.IsSet())
bValid = (0 != m_aEndEditHdl.Call(_pEntry));
if (bValid)
return true;
SvTreeListBox::SetEntryText(_pEntry, sOldText);
return false;
}
void DbaIndexList::enableSelectHandler()
{
OSL_ENSURE(m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
m_bSuspendSelectHdl = false;
}
void DbaIndexList::disableSelectHandler()
{
OSL_ENSURE(!m_bSuspendSelectHdl, "DbaIndexList::enableSelectHandler: invalid call (this is not cumulative)!");
m_bSuspendSelectHdl = true;
}
void DbaIndexList::SelectNoHandlerCall( SvTreeListEntry* _pEntry )
{
disableSelectHandler();
Select(_pEntry, true);
enableSelectHandler();
}
bool DbaIndexList::Select(SvTreeListEntry* pEntry, bool _bSelect)
{
bool bReturn = SvTreeListBox::Select(pEntry, _bSelect);
if (m_aSelectHdl.IsSet() && !m_bSuspendSelectHdl && _bSelect)
m_aSelectHdl.Call(this);
return bReturn;
}
VCL_BUILDER_FACTORY_ARGS(DbaIndexList, WB_BORDER)
// DbaIndexDialog
DbaIndexDialog::DbaIndexDialog( vcl::Window* _pParent, const Sequence< OUString >& _rFieldNames,
const Reference< XNameAccess >& _rxIndexes,
const Reference< XConnection >& _rxConnection,
const Reference< XComponentContext >& _rxContext,sal_Int32 _nMaxColumnsInIndex)
:ModalDialog( _pParent, "IndexDesignDialog", "dbaccess/ui/indexdesigndialog.ui")
,m_xConnection(_rxConnection)
,m_aGeometrySettings(E_DIALOG, OUString("dbaccess.tabledesign.indexdialog"))
,m_pIndexes(NULL)
,m_pPreviousSelection(NULL)
,m_bEditAgain(false)
,m_xContext(_rxContext)
{
get(m_pActions, "ACTIONS");
mnNewCmdId = m_pActions->GetItemId(INDEX_NEW_CMD);
mnDropCmdId = m_pActions->GetItemId(INDEX_DROP_CMD);
mnRenameCmdId = m_pActions->GetItemId(INDEX_RENAME_CMD);
mnSaveCmdId = m_pActions->GetItemId(INDEX_SAVE_CMD);
mnResetCmdId = m_pActions->GetItemId(INDEX_RESET_CMD);
maScNewCmdImg = m_pActions->GetItemImage(mnNewCmdId);
maScDropCmdImg = m_pActions->GetItemImage(mnDropCmdId);
maScRenameCmdImg = m_pActions->GetItemImage(mnRenameCmdId);
maScSaveCmdImg = m_pActions->GetItemImage(mnSaveCmdId);
maScResetCmdImg = m_pActions->GetItemImage(mnResetCmdId);
maLcNewCmdImg = get<FixedImage>("image1")->GetImage();
maLcDropCmdImg = get<FixedImage>("image2")->GetImage();
maLcRenameCmdImg = get<FixedImage>("image3")->GetImage();
maLcSaveCmdImg = get<FixedImage>("image4")->GetImage();
maLcResetCmdImg = get<FixedImage>("image5")->GetImage();
get(m_pIndexList, "INDEX_LIST");
Size aSize(LogicToPixel(Size(70, 97), MAP_APPFONT));
m_pIndexList->set_width_request(aSize.Width());
m_pIndexList->set_height_request(aSize.Height());
get(m_pIndexDetails, "INDEX_DETAILS");
get(m_pDescriptionLabel, "DESC_LABEL");
get(m_pDescription, "DESCRIPTION");
get(m_pUnique, "UNIQUE");
get(m_pFieldsLabel, "FIELDS_LABEL");
get(m_pFields, "FIELDS");
aSize = LogicToPixel(Size(128, 61), MAP_APPFONT);
m_pFields->set_width_request(aSize.Width());
m_pFields->set_height_request(aSize.Height());
get(m_pClose, "close");
m_pActions->SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexAction));
m_pIndexList->SetSelectHdl(LINK(this, DbaIndexDialog, OnIndexSelected));
m_pIndexList->SetEndEditHdl(LINK(this, DbaIndexDialog, OnEntryEdited));
m_pIndexList->SetSelectionMode(SINGLE_SELECTION);
m_pIndexList->SetHighlightRange();
m_pIndexList->setConnection(m_xConnection);
m_pFields->SetSizePixel(Size(300, 100));
m_pFields->Init(_rFieldNames, _nMaxColumnsInIndex, ::dbtools::getBooleanDataSourceSetting( m_xConnection, "AddIndexAppendix" ));
setToolBox(m_pActions);
m_pIndexes = new OIndexCollection();
try
{
m_pIndexes->attach(_rxIndexes);
}
catch(SQLException& e)
{
::dbaui::showError(SQLExceptionInfo(e),_pParent,_rxContext);
}
catch(Exception&)
{
OSL_FAIL("DbaIndexDialog::DbaIndexDialog: could not retrieve basic information from the UNO collection!");
}
fillIndexList();
m_pUnique->SetClickHdl(LINK(this, DbaIndexDialog, OnModified));
m_pFields->SetModifyHdl(LINK(this, DbaIndexDialog, OnModified));
m_pClose->SetClickHdl(LINK(this, DbaIndexDialog, OnCloseDialog));
// 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.isEmpty())
break;
}
if (aCheck == m_pIndexes->end())
{
// hide the controls which are necessary for the description
m_pDescription->Hide();
m_pDescriptionLabel->Hide();
}
}
void DbaIndexDialog::updateToolbox()
{
m_pActions->EnableItem(mnNewCmdId, !m_pIndexList->IsEditingActive());
SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
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_pActions->EnableItem(mnSaveCmdId, aSelectedPos->isModified() || aSelectedPos->isNew());
m_pActions->EnableItem(mnResetCmdId, aSelectedPos->isModified() || aSelectedPos->isNew());
bSelectedAnything = bSelectedAnything && !aSelectedPos->bPrimaryKey;
}
else
{
m_pActions->EnableItem(mnSaveCmdId, false);
m_pActions->EnableItem(mnResetCmdId, false);
}
m_pActions->EnableItem(mnDropCmdId, bSelectedAnything);
m_pActions->EnableItem(mnRenameCmdId, bSelectedAnything);
}
void DbaIndexDialog::fillIndexList()
{
Image aPKeyIcon(ModuleRes( IMG_PKEYICON ));
// fill the list with the index names
m_pIndexList->Clear();
Indexes::iterator aIndexLoop = m_pIndexes->begin();
Indexes::iterator aEnd = m_pIndexes->end();
for (; aIndexLoop != aEnd; ++aIndexLoop)
{
SvTreeListEntry* pNewEntry = NULL;
if (aIndexLoop->bPrimaryKey)
pNewEntry = m_pIndexList->InsertEntry(aIndexLoop->sName, aPKeyIcon, aPKeyIcon);
else
pNewEntry = m_pIndexList->InsertEntry(aIndexLoop->sName);
pNewEntry->SetUserData(reinterpret_cast< void* >(sal_Int32(aIndexLoop - m_pIndexes->begin())));
}
OnIndexSelected(m_pIndexList);
}
DbaIndexDialog::~DbaIndexDialog( )
{
disposeOnce();
}
void DbaIndexDialog::dispose()
{
setToolBox(NULL);
delete m_pIndexes;
m_pActions.clear();
m_pIndexList.clear();
m_pIndexDetails.clear();
m_pDescriptionLabel.clear();
m_pDescription.clear();
m_pUnique.clear();
m_pFieldsLabel.clear();
m_pFields.clear();
m_pClose.clear();
ModalDialog::dispose();
}
bool DbaIndexDialog::implCommit(SvTreeListEntry* _pEntry)
{
OSL_ENSURE(_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, false))
return 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_xContext);
else
{
m_pUnique->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
OUString sNewIndexName;
const OUString sNewIndexNameBase(ModuleRes(STR_LOGICAL_INDEX_NAME));
sal_Int32 i;
for ( i = 1; i < 0x7FFFFFFF; ++i )
{
sNewIndexName = sNewIndexNameBase;
sNewIndexName += OUString::number(i);
if (m_pIndexes->end() == m_pIndexes->find(sNewIndexName))
break;
}
if (i == 0x7FFFFFFF)
{
OSL_FAIL("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;
}
SvTreeListEntry* pNewEntry = m_pIndexList->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 (SvTreeListEntry* pAdjust = m_pIndexList->First(); pAdjust; pAdjust = m_pIndexList->Next(pAdjust))
{
Indexes::iterator aAfterInsertPos = m_pIndexes->find(m_pIndexList->GetEntryText(pAdjust));
OSL_ENSURE(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_pIndexList->SelectNoHandlerCall(pNewEntry);
OnIndexSelected(m_pIndexList);
m_pIndexList->EditEntry(pNewEntry);
updateToolbox();
}
void DbaIndexDialog::OnDropIndex(bool _bConfirm)
{
// the selected index
SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
OSL_ENSURE(pSelected, "DbaIndexDialog::OnDropIndex: invalid call!");
if (pSelected)
{
// let the user confirm the drop
if (_bConfirm)
{
OUString sConfirm(ModuleRes(STR_CONFIRM_DROP_INDEX));
sConfirm = sConfirm.replaceFirst("$name$", m_pIndexList->GetEntryText(pSelected));
ScopedVclPtrInstance< MessageDialog > aConfirm(this, sConfirm, VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
if (RET_YES != aConfirm->Execute())
return;
}
// do the drop
implDropIndex(pSelected, true);
// reflect the new selection in the toolbox
updateToolbox();
}
}
bool DbaIndexDialog::implDropIndex(SvTreeListEntry* _pEntry, bool _bRemoveFromCollection)
{
// do the drop
Indexes::iterator aDropPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
OSL_ENSURE(aDropPos != m_pIndexes->end(), "DbaIndexDialog::OnDropIndex: did not find the index in my collection!");
SQLExceptionInfo aExceptionInfo;
bool bSuccess = 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_xContext);
else if (bSuccess && _bRemoveFromCollection)
{
SvTreeList* pModel = m_pIndexList->GetModel();
m_pIndexList->disableSelectHandler();
pModel->Remove(_pEntry);
m_pIndexList->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 (SvTreeListEntry* pAdjust = m_pIndexList->First(); pAdjust; pAdjust = m_pIndexList->Next(pAdjust))
{
Indexes::iterator aAfterDropPos = m_pIndexes->find(m_pIndexList->GetEntryText(pAdjust));
OSL_ENSURE(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_pIndexList);
}
return !aExceptionInfo.isValid();
}
void DbaIndexDialog::OnRenameIndex()
{
// the selected index
SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
OSL_ENSURE(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(false);
m_pIndexList->EditEntry(pSelected);
updateToolbox();
}
void DbaIndexDialog::OnSaveIndex()
{
// the selected index
#if OSL_DEBUG_LEVEL > 0
SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
OSL_ENSURE( pSelected, "DbaIndexDialog::OnSaveIndex: invalid call!" );
#endif
implCommitPreviouslySelected();
updateToolbox();
}
void DbaIndexDialog::OnResetIndex()
{
// the selected index
SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
OSL_ENSURE(pSelected, "DbaIndexDialog::OnResetIndex: invalid call!");
Indexes::iterator aResetPos = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(pSelected->GetUserData());
if (aResetPos->isNew())
{
OnDropIndex(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_xContext);
else
m_pIndexList->SetEntryText(pSelected, aResetPos->sName);
updateControls(pSelected);
updateToolbox();
}
IMPL_LINK_NOARG_TYPED( DbaIndexDialog, OnIndexAction, ToolBox*, void )
{
sal_uInt16 nClicked = m_pActions->GetCurItemId();
if (nClicked == mnNewCmdId)
OnNewIndex();
else if (nClicked == mnDropCmdId)
OnDropIndex();
else if (nClicked == mnRenameCmdId)
OnRenameIndex();
else if (nClicked == mnSaveCmdId)
OnSaveIndex();
else if (nClicked == mnResetCmdId)
OnResetIndex();
}
IMPL_LINK_NOARG( DbaIndexDialog, OnCloseDialog )
{
if (m_pIndexList->IsEditingActive())
{
OSL_ENSURE(!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_pIndexList->EndEditing(false);
if (m_bEditAgain)
// could not commit the new name (started a new - asynchronous - edit trial)
return 1L;
}
// the currently selected entry
const SvTreeListEntry* pSelected = m_pIndexList->FirstSelected();
OSL_ENSURE(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())
{
ScopedVclPtrInstance<MessageDialog> aQuestion(this, "SaveIndexDialog",
"dbaccess/ui/saveindexdialog.ui" );
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, SvTreeListEntry*, _pEntry )
{
m_bEditAgain = false;
m_pIndexList->EditEntry(_pEntry);
return 0L;
}
IMPL_LINK( DbaIndexDialog, OnEntryEdited, SvTreeListEntry*, _pEntry )
{
Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(_pEntry->GetUserData());
OSL_ENSURE(aPosition >= m_pIndexes->begin() && aPosition < m_pIndexes->end(),
"DbaIndexDialog::OnEntryEdited: invalid entry!");
OUString sNewName = m_pIndexList->GetEntryText(_pEntry);
Indexes::const_iterator aSameName = m_pIndexes->find(sNewName);
if ((aSameName != aPosition) && (m_pIndexes->end() != aSameName))
{
OUString sError(ModuleRes(STR_INDEX_NAME_ALREADY_USED));
sError = sError.replaceFirst("$name$", sNewName);
ScopedVclPtrInstance< MessageDialog > aError(this, sError);
aError->Execute();
updateToolbox();
m_bEditAgain = true;
PostUserEvent(LINK(this, DbaIndexDialog, OnEditIndexAgain), _pEntry, true);
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(true);
updateToolbox();
}
return 1L;
}
bool DbaIndexDialog::implSaveModified(bool _bPlausibility)
{
if (m_pPreviousSelection)
{
// try to commit the previously selected index
if (m_pFields->IsModified() && !m_pFields->SaveModified())
return false;
Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
// the unique flag
aPreviouslySelected->bUnique = m_pUnique->IsChecked();
if (m_pUnique->GetSavedValue() != m_pUnique->GetState())
aPreviouslySelected->setModified(true);
// the fields
m_pFields->commitTo(aPreviouslySelected->aFields);
if (m_pFields->GetSavedValue() != aPreviouslySelected->aFields)
aPreviouslySelected->setModified(true);
// plausibility checks
if (_bPlausibility && !implCheckPlausibility(aPreviouslySelected))
return false;
}
return true;
}
bool DbaIndexDialog::implCheckPlausibility(const Indexes::const_iterator& _rPos)
{
// need at least one field
if (0 == _rPos->aFields.size())
{
ScopedVclPtrInstance< MessageDialog > aError(this, ModuleRes(STR_NEED_INDEX_FIELDS));
aError->Execute();
m_pFields->GrabFocus();
return false;
}
// no double fields
std::set< OUString > aExistentFields;
for ( IndexFields::const_iterator 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
OUString sMessage(ModuleRes(STR_INDEXDESIGN_DOUBLE_COLUMN_NAME));
sMessage = sMessage.replaceFirst("$name$", aFieldCheck->sFieldName);
ScopedVclPtrInstance< MessageDialog > aError(this, sMessage);
aError->Execute();
m_pFields->GrabFocus();
return false;
}
aExistentFields.insert(aFieldCheck->sFieldName);
}
return true;
}
bool DbaIndexDialog::implCommitPreviouslySelected()
{
if (m_pPreviousSelection)
{
Indexes::iterator aPreviouslySelected = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
if (!implSaveModified())
return false;
// commit the index (if necessary)
if (aPreviouslySelected->isModified() && !implCommit(m_pPreviousSelection))
return false;
}
return true;
}
IMPL_LINK_NOARG( DbaIndexDialog, OnModified )
{
OSL_ENSURE(m_pPreviousSelection, "DbaIndexDialog, OnModified: invalid call!");
Indexes::iterator aPosition = m_pIndexes->begin() + reinterpret_cast<sal_IntPtr>(m_pPreviousSelection->GetUserData());
aPosition->setModified(true);
updateToolbox();
return 1L;
}
void DbaIndexDialog::updateControls(const SvTreeListEntry* _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_pUnique->Check(aSelectedIndex->bUnique);
m_pUnique->Enable(!aSelectedIndex->bPrimaryKey);
m_pUnique->SaveValue();
m_pFields->initializeFrom(aSelectedIndex->aFields);
m_pFields->Enable(!aSelectedIndex->bPrimaryKey);
m_pFields->SaveValue();
m_pDescription->SetText(aSelectedIndex->sDescription);
m_pDescription->Enable(!aSelectedIndex->bPrimaryKey);
m_pDescriptionLabel->Enable(!aSelectedIndex->bPrimaryKey);
}
else
{
m_pUnique->Check(false);
m_pFields->initializeFrom(IndexFields());
m_pDescription->SetText(OUString());
}
}
IMPL_LINK( DbaIndexDialog, OnIndexSelected, DbaIndexList*, /*NOTINTERESTEDIN*/ )
{
m_pIndexList->EndSelection();
if (m_pIndexList->IsEditingActive())
m_pIndexList->EndEditing(false);
// commit the old data
if (m_pIndexList->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_pIndexList->SelectNoHandlerCall(m_pPreviousSelection);
return 1L;
}
}
bool bHaveSelection = (NULL != m_pIndexList->FirstSelected());
// disable/enable the detail controls
m_pIndexDetails->Enable(bHaveSelection);
m_pUnique->Enable(bHaveSelection);
m_pDescriptionLabel->Enable(bHaveSelection);
m_pFieldsLabel->Enable(bHaveSelection);
m_pFields->Enable(bHaveSelection);
SvTreeListEntry* pNewSelection = m_pIndexList->FirstSelected();
updateControls(pNewSelection);
if (bHaveSelection)
m_pIndexList->GrabFocus();
m_pPreviousSelection = pNewSelection;
updateToolbox();
return 0L;
}
void DbaIndexDialog::StateChanged( StateChangedType nType )
{
ModalDialog::StateChanged( nType );
if ( nType == StateChangedType::ControlBackground )
{
// Check if we need to get new images for normal/high contrast mode
checkImageList();
}
else if ( nType == StateChangedType::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() == DataChangedEventType::SETTINGS ) ||
( rDCEvt.GetType() == DataChangedEventType::DISPLAY )) &&
( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ))
{
// Check if we need to get new images for normal/high contrast mode
checkImageList();
}
}
void DbaIndexDialog::setImageList(sal_Int16 _eBitmapSet)
{
if ( _eBitmapSet == SFX_SYMBOLS_SIZE_LARGE )
{
m_pActions->SetItemImage(mnNewCmdId, maLcNewCmdImg);
m_pActions->SetItemImage(mnDropCmdId, maLcDropCmdImg);
m_pActions->SetItemImage(mnRenameCmdId, maLcRenameCmdImg);
m_pActions->SetItemImage(mnSaveCmdId, maLcSaveCmdImg);
m_pActions->SetItemImage(mnResetCmdId, maLcResetCmdImg);
}
else
{
m_pActions->SetItemImage(mnNewCmdId, maScNewCmdImg);
m_pActions->SetItemImage(mnDropCmdId, maScDropCmdImg);
m_pActions->SetItemImage(mnRenameCmdId, maScRenameCmdImg);
m_pActions->SetItemImage(mnSaveCmdId, maScSaveCmdImg);
m_pActions->SetItemImage(mnResetCmdId, maScResetCmdImg);
}
}
void DbaIndexDialog::resizeControls(const Size&)
{
}
} // namespace dbaui
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */