Files
libreoffice/dbaccess/source/ui/dlg/dbadmin.cxx
2001-07-17 06:35:00 +00:00

1978 lines
78 KiB
C++

/*************************************************************************
*
* $RCSfile: dbadmin.cxx,v $
*
* $Revision: 1.65 $
*
* last change: $Author: oj $ $Date: 2001-07-17 07:30:50 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (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.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc..
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#ifndef _DBAUI_DBADMIN_HXX_
#include "dbadmin.hxx"
#endif
#ifndef _DBAUI_DBADMIN_HRC_
#include "dbadmin.hrc"
#endif
#ifndef _DBU_RESOURCE_HRC_
#include "dbu_resource.hrc"
#endif
#ifndef _DBAUI_MODULE_DBU_HXX_
#include "moduledbu.hxx"
#endif
#ifndef _DBAUI_DATASOURCEITEMS_HXX_
#include "dsitems.hxx"
#endif
#ifndef _SFXSTRITEM_HXX
#include <svtools/stritem.hxx>
#endif
#ifndef _SFXENUMITEM_HXX
#include <svtools/eitem.hxx>
#endif
#ifndef _SFXINTITEM_HXX
#include <svtools/intitem.hxx>
#endif
#ifndef _VCL_STDTEXT_HXX
#include <vcl/stdtext.hxx>
#endif
#ifndef _SV_MSGBOX_HXX
#include <vcl/msgbox.hxx>
#endif
#ifndef _SVTOOLS_LOGINDLG_HXX_
#include <svtools/logindlg.hxx>
#endif
#ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
#include <com/sun/star/sdb/SQLContext.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XNAMINGSERVICE_HPP_
#include <com/sun/star/uno/XNamingService.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XFLUSHABLE_HPP_
#include <com/sun/star/util/XFlushable.hpp>
#endif
#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
#include "dbustrings.hrc"
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _DBAUI_ADMINPAGES_HXX_
#include "adminpages.hxx"
#endif
#ifndef _DBAUI_DETAILPAGES_HXX_
#include "detailpages.hxx"
#endif
#ifndef _DBAUI_COMMONPAGES_HXX_
#include "commonpages.hxx"
#endif
#ifndef _DBAUI_TABLESPAGE_HXX_
#include "tablespage.hxx"
#endif
#ifndef _DBAUI_GENERALPAGE_HXX_
#include "generalpage.hxx"
#endif
#ifndef _DBAUI_LOCALRESACCESS_HXX_
#include "localresaccess.hxx"
#endif
#ifndef _DBAUI_STRINGLISTITEM_HXX_
#include "stringlistitem.hxx"
#endif
#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_
#include <typelib/typedescription.hxx>
#endif
#ifndef _COMPHELPER_PROPERTY_HXX_
#include <comphelper/property.hxx>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _DBAUI_PROPERTYSETITEM_HXX_
#include "propertysetitem.hxx"
#endif
#ifndef DBAUI_ADABASPAGE_HXX
#include "AdabasPage.hxx"
#endif
#ifndef _DBHELPER_DBEXCEPTION_HXX_
#include <connectivity/dbexception.hxx>
#endif
#ifndef DBAUI_TOOLS_HXX
#include "UITools.hxx"
#endif
#ifndef _SV_WAITOBJ_HXX
#include <vcl/waitobj.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDRIVERACCESS_HPP_
#include <com/sun/star/sdbc/XDriverAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDRIVER_HPP_
#include <com/sun/star/sdbc/XDriver.hpp>
#endif
#ifndef DBAUI_USERADMIN_HXX
#include "UserAdmin.hxx"
#endif
//.........................................................................
namespace dbaui
{
//.........................................................................
using namespace dbtools;
using namespace com::sun::star::uno;
using namespace com::sun::star::sdbc;
using namespace com::sun::star::sdb;
using namespace com::sun::star::lang;
using namespace com::sun::star::util;
using namespace com::sun::star::beans;
using namespace com::sun::star::container;
//=========================================================================
//= ODbAdminDialog
//=========================================================================
//-------------------------------------------------------------------------
ODbAdminDialog::ODbAdminDialog(Window* _pParent, SfxItemSet* _pItems, const Reference< XMultiServiceFactory >& _rxORB)
:SfxTabDialog(_pParent, ModuleRes(DLG_DATABASE_ADMINISTRATION), _pItems)
,m_aSelector(this, ResId(WND_DATASOURCESELECTOR))
,m_bResetting(sal_False)
,m_aDatasources(_rxORB)
,m_xORB(_rxORB)
,m_nPostApplyPage(0)
,m_pPostApplyPageSettings(NULL)
{
// add the initial tab pages
AddTabPage(PAGE_GENERAL, String(ResId(STR_PAGETITLE_GENERAL)), OGeneralPage::Create, NULL);
AddTabPage(PAGE_TABLESUBSCRIPTION, String(ResId(STR_PAGETITLE_TABLESUBSCRIPTION)), OTableSubscriptionPage::Create, NULL);
AddTabPage(PAGE_QUERYADMINISTRATION, String(ResId(STR_PAGETITLE_QUERIES)), OQueryAdministrationPage::Create, NULL);
AddTabPage(PAGE_DOCUMENTLINKS, String(ResId(STR_PAGETITLE_DOCUMENTS)), ODocumentLinksPage::Create, NULL);
// no local resources needed anymore
FreeResource();
/// initialize the property translation map
// direct properties of a data source
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_CONNECTURL, PROPERTY_URL));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_NAME, PROPERTY_NAME));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_USER, PROPERTY_USER));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_PASSWORD, PROPERTY_PASSWORD));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_PASSWORDREQUIRED, PROPERTY_ISPASSWORDREQUIRED));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_TABLEFILTER, PROPERTY_TABLEFILTER));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_READONLY, PROPERTY_ISREADONLY));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_SUPPRESSVERSIONCL, PROPERTY_SUPPRESSVERSIONCL));
// implicit properties, to be found in the direct property "Info"
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_JDBCDRIVERCLASS, ::rtl::OUString::createFromAscii("JavaDriverClass")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_TEXTFILEEXTENSION, ::rtl::OUString::createFromAscii("Extension")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CHARSET, ::rtl::OUString::createFromAscii("CharSet")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_TEXTFILEHEADER, ::rtl::OUString::createFromAscii("HeaderLine")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_FIELDDELIMITER, ::rtl::OUString::createFromAscii("FieldDelimiter")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_TEXTDELIMITER, ::rtl::OUString::createFromAscii("StringDelimiter")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_DECIMALDELIMITER, ::rtl::OUString::createFromAscii("DecimalDelimiter")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_THOUSANDSDELIMITER, ::rtl::OUString::createFromAscii("ThousandDelimiter")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_SHOWDELETEDROWS, ::rtl::OUString::createFromAscii("ShowDeleted")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ALLOWLONGTABLENAMES, ::rtl::OUString::createFromAscii("NoNameLengthLimit")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ADDITIONALOPTIONS, ::rtl::OUString::createFromAscii("SystemDriverSettings")));
// special settings for adabas
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_SHUTSERVICE, ::rtl::OUString::createFromAscii("ShutdownDatabase")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_DATAINC, ::rtl::OUString::createFromAscii("DataCacheSizeIncrement")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_CACHESIZE, ::rtl::OUString::createFromAscii("DataCacheSize")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_CTRLUSER, ::rtl::OUString::createFromAscii("ControlUser")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_CTRLPWD, ::rtl::OUString::createFromAscii("ControlPassword")));
// extra settings for odbc
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_USECATALOG, ::rtl::OUString::createFromAscii("UseCatalog")));
// extra settings for a ldap address book
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_HOSTNAME, ::rtl::OUString::createFromAscii("HostName")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_BASEDN, ::rtl::OUString::createFromAscii("BaseDN")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_PORTNUMBER, ::rtl::OUString::createFromAscii("PortNumber")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_ROWCOUNT, ::rtl::OUString::createFromAscii("MaxRowCount")));
// remove the reset button - it's meaning is much too ambiguous in this dialog
RemoveResetButton();
// enable an apply button
EnableApplyButton(sal_True);
SetApplyHandler(LINK(this, ODbAdminDialog, OnApplyChanges));
// disable the apply button
GetApplyButton()->Enable(sal_False);
// register the view window
SetViewWindow(&m_aSelector);
SetViewAlign(WINDOWALIGN_LEFT);
AdjustLayout();
// do some knittings
m_aSelector.setSelectHandler(LINK(this, ODbAdminDialog, OnDatasourceSelected));
m_aSelector.setNewHandler(LINK(this, ODbAdminDialog, OnNewDatasource));
m_aSelector.setDeleteHandler(LINK(this, ODbAdminDialog, OnDeleteDatasource));
m_aSelector.setRestoreHandler(LINK(this, ODbAdminDialog, OnRestoreDatasource));
::rtl::OUString sInitialSelection; // will be the initial selection
if (!m_aDatasources.isValid())
{
ShowServiceNotAvailableError(_pParent, String(SERVICE_SDB_DATABASECONTEXT), sal_True);
m_aSelector.Disable();
}
else
{
m_xDatabaseContext = m_aDatasources.getContext();
m_xDynamicContext = Reference< XNamingService >(m_xDatabaseContext, UNO_QUERY);
DBG_ASSERT(m_xDynamicContext.is(), "ODbAdminDialog::ODbAdminDialog : no XNamingService interface !");
// fill the listbox with the names of the registered datasources
ODatasourceMap::Iterator aDatasourceLoop = m_aDatasources.begin();
while (aDatasourceLoop != m_aDatasources.end())
{
m_aSelector.insert(*aDatasourceLoop);
m_aValidDatasources.insert(*aDatasourceLoop);
++aDatasourceLoop;
}
if (!m_aDatasources.size())
{
WarningBox(_pParent, ModuleRes(ERR_NOREGISTEREDDATASOURCES)).Execute();
}
else
sInitialSelection = *m_aDatasources.begin();
}
implSelectDatasource(sInitialSelection);
GetApplyButton()->Enable(sal_False);
// nothing modified 'til now -> now apply
}
//-------------------------------------------------------------------------
ODbAdminDialog::~ODbAdminDialog()
{
SetInputSet(NULL);
DELETEZ(pExampleSet);
}
// -----------------------------------------------------------------------------
String ODbAdminDialog::getConnectionURL() const
{
SFX_ITEMSET_GET(*GetExampleSet(), pUrlItem, SfxStringItem, DSID_CONNECTURL, sal_True);
return pUrlItem->GetValue();
}
// -----------------------------------------------------------------------------
Reference< XDriver > ODbAdminDialog::getDriver()
{
// get the global DriverManager
Reference< XDriverAccess > xDriverManager;
String sCurrentActionError = String(ModuleRes(STR_COULDNOTCREATE_DRIVERMANAGER));
// in case an error occures
sCurrentActionError.SearchAndReplaceAscii("#servicename#", (::rtl::OUString)SERVICE_SDBC_CONNECTIONPOOL);
try
{
xDriverManager = Reference< XDriverAccess >(getORB()->createInstance(SERVICE_SDBC_CONNECTIONPOOL), UNO_QUERY);
DBG_ASSERT(xDriverManager.is(), "ODbAdminDialog::getDriver: could not instantiate the driver manager, or it does not provide the necessary interface!");
}
catch (Exception& e)
{
// wrap the exception into an SQLException
SQLException aSQLWrapper(e.Message, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, Any());
throw SQLException(sCurrentActionError, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, makeAny(aSQLWrapper));
}
if (!xDriverManager.is())
throw SQLException(sCurrentActionError, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, Any());
sCurrentActionError = String(ModuleRes(STR_NOREGISTEREDDRIVER));
Reference< XDriver > xDriver = xDriverManager->getDriverByURL(getConnectionURL());
if (!xDriver.is())
// will be caught and translated into an SQLContext exception
throw SQLException(sCurrentActionError, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, Any());
return xDriver;
}
// -----------------------------------------------------------------------------
Reference<XConnection> ODbAdminDialog::createConnection()
{
Reference<XConnection> xConnection;
// // if (bValid)
{ // get the current table list from the connection for the current settings
// the PropertyValues for the current dialog settings
Sequence< PropertyValue > aConnectionParams;
if (getCurrentSettings(aConnectionParams))
{
// the current DSN
// fill the table list with this connection information
SQLExceptionInfo aErrorInfo;
try
{
WaitObject aWaitCursor(this);
xConnection = getDriver()->connect(getConnectionURL(), aConnectionParams);
}
catch (::com::sun::star::sdb::SQLContext& e) { aErrorInfo = SQLExceptionInfo(e); }
catch (::com::sun::star::sdbc::SQLWarning& e) { aErrorInfo = SQLExceptionInfo(e); }
catch (::com::sun::star::sdbc::SQLException& e) { aErrorInfo = SQLExceptionInfo(e); }
showError(aErrorInfo,this,getORB());
}
}
if(xConnection.is())
successfullyConnected();// notify the admindlg to save the password
return xConnection;
}
//-------------------------------------------------------------------------
short ODbAdminDialog::Execute()
{
short nResult = SfxTabDialog::Execute();
// within it's dtor, the SfxTabDialog saves (amongst others) the currently selected tab page and
// reads it upon the next Execute (dependent on the resource id, which thus has to be globally unique,
// though our's isn't)
// As this is not wanted if e.g. the table subscription page is selected, we show the GeneralPage here
ShowPage(PAGE_GENERAL);
// clear the temporary SfxItemSets we created
m_aDatasources.clear();
return nResult;
}
//-------------------------------------------------------------------------
void ODbAdminDialog::selectDataSource(const ::rtl::OUString& _rName)
{
if (m_aDatasources.exists(_rName))
implSelectDatasource(_rName);
}
//-------------------------------------------------------------------------
void ODbAdminDialog::clearPassword()
{
if (pExampleSet)
pExampleSet->ClearItem(DSID_PASSWORD);
}
//-------------------------------------------------------------------------
void ODbAdminDialog::successfullyConnected()
{
DBG_ASSERT(GetExampleSet(), "ODbAdminDialog::successfullyConnected: not to be called without an example set!");
if (!GetExampleSet())
return;
if (hasAuthentication(*GetExampleSet()))
{
SFX_ITEMSET_GET(*GetExampleSet(), pPassword, SfxStringItem, DSID_PASSWORD, sal_True);
if (pPassword && (0 != pPassword->GetValue().Len()))
{
::rtl::OUString sPassword = pPassword->GetValue();
ODatasourceMap::ODatasourceInfo aDatasourceInfo = m_aDatasources[m_sCurrentDatasource];
Reference< XPropertySet > xCurrentDatasource = aDatasourceInfo.getDatasource();
DBG_ASSERT(xCurrentDatasource.is(), "ODbAdminDialog::successfullyConnected: no data source!");
if (xCurrentDatasource.is())
{
try
{
xCurrentDatasource->setPropertyValue(m_aDirectPropTranslator[DSID_PASSWORD], makeAny(sPassword));
}
catch(const Exception&)
{
DBG_ERROR("ODbAdminDialog::successfullyConnected: caught an exception!");
}
}
}
}
}
//-------------------------------------------------------------------------
sal_Bool ODbAdminDialog::getCurrentSettings(Sequence< PropertyValue >& _rDriverParam)
{
DBG_ASSERT(GetExampleSet(), "ODbAdminDialog::getCurrentSettings : not to be called without an example set!");
if (!GetExampleSet())
return sal_False;
::std::vector< PropertyValue > aReturn;
// collecting this in a vector because it has a push_back, in opposite to sequences
// user: DSID_USER -> "user"
SFX_ITEMSET_GET(*GetExampleSet(), pUser, SfxStringItem, DSID_USER, sal_True);
if (pUser && pUser->GetValue().Len())
aReturn.push_back(
PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user")), 0,
makeAny(::rtl::OUString(pUser->GetValue())), PropertyState_DIRECT_VALUE));
// check if the connection type requires a password
if (hasAuthentication(*GetExampleSet()))
{
// password: DSID_PASSWORD -> "password"
SFX_ITEMSET_GET(*GetExampleSet(), pPassword, SfxStringItem, DSID_PASSWORD, sal_True);
String sPassword = pPassword ? pPassword->GetValue() : String();
SFX_ITEMSET_GET(*GetExampleSet(), pPasswordRequired, SfxBoolItem, DSID_PASSWORDREQUIRED, sal_True);
// if the set does not contain a password, but the item set says it requires one, ask the user
if ((!pPassword || !pPassword->GetValue().Len()) && (pPasswordRequired && pPasswordRequired->GetValue()))
{
SFX_ITEMSET_GET(*GetExampleSet(), pName, SfxStringItem, DSID_NAME, sal_True);
::svt::LoginDialog aDlg(this,
LF_NO_PATH | LF_NO_ACCOUNT | LF_NO_ERRORTEXT | LF_USERNAME_READONLY,
String(), NULL);
aDlg.SetName(pUser ? pUser->GetValue() : String());
aDlg.ClearPassword(); // this will give the password field the focus
String sLoginRequest(ModuleRes(STR_ENTER_CONNECTION_PASSWORD));
sLoginRequest.SearchAndReplaceAscii("$name$", pName ? pName->GetValue() : String()),
aDlg.SetLoginRequestText(sLoginRequest);
aDlg.SetSavePasswordText(ModuleRes(STR_REMEMBERPASSWORD_SESSION));
aDlg.SetSavePassword(sal_True);
sal_Int32 nResult = aDlg.Execute();
if (nResult != RET_OK)
return sal_False;
sPassword = aDlg.GetPassword();
if (aDlg.IsSavePassword())
pExampleSet->Put(SfxStringItem(DSID_PASSWORD, sPassword));
}
if (sPassword.Len())
aReturn.push_back(
PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("password")), 0,
makeAny(::rtl::OUString(sPassword)), PropertyState_DIRECT_VALUE));
}
_rDriverParam = Sequence< PropertyValue >(aReturn.begin(), aReturn.size());
// append all the other stuff (charset etc.)
fillDatasourceInfo(*GetExampleSet(), _rDriverParam);
return sal_True;
}
//-------------------------------------------------------------------------
sal_Bool ODbAdminDialog::isCurrentModified() const
{
if (0 == m_aSelector.count())
return sal_False;
String sCurrentlySelected = m_aSelector.getSelected();
return const_cast<ODbAdminDialog*>(this)->m_aDatasources[sCurrentlySelected].isModified();
}
//-------------------------------------------------------------------------
sal_Bool ODbAdminDialog::isApplyable() const
{
return GetApplyButton()->IsEnabled();
}
//-------------------------------------------------------------------------
void ODbAdminDialog::applyChangesAsync(const OPageSettings* _pUseTheseSettings)
{
DBG_ASSERT(isApplyable(), "ODbAdminDialog::applyChangesAsync: invalid call!");
DBG_ASSERT((0 == m_nPostApplyPage) && !m_pPostApplyPageSettings, "ODbAdminDialog::applyChangesAsync: already doing this!");
sal_uInt16 nCurrentPageId = GetCurPageId();
// get the view settings
if (!_pUseTheseSettings)
{
OGenericAdministrationPage* pCurrentPage = static_cast<OGenericAdministrationPage*>(GetTabPage(nCurrentPageId));
OPageSettings* pViewSettings = NULL;
if (pCurrentPage)
{ // get the pages current view settings
pViewSettings = pCurrentPage->createViewSettings();
pCurrentPage->fillViewSettings(pViewSettings);
}
m_pPostApplyPageSettings = pViewSettings;
}
else
m_pPostApplyPageSettings = _pUseTheseSettings;
// remember the page id
m_nPostApplyPage = nCurrentPageId;
PostUserEvent(LINK(this, ODbAdminDialog, OnAsyncApplyChanges));
}
//-------------------------------------------------------------------------
short ODbAdminDialog::Ok()
{
short nResult = SfxTabDialog::Ok();
return (AR_LEAVE_MODIFIED == implApplyChanges(sal_False)) ? RET_OK : RET_CANCEL;
// TODO : AR_ERROR is not handled correctly, we always close the dialog here
}
//-------------------------------------------------------------------------
void ODbAdminDialog::PageCreated(USHORT _nId, SfxTabPage& _rPage)
{
// register ourself as modified listener
static_cast<OGenericAdministrationPage&>(_rPage).SetModifiedHandler(LINK(this, ODbAdminDialog, OnDatasourceModifed));
// some registrations which depend on the type of the page
switch (_nId)
{
case PAGE_GENERAL:
static_cast<OGeneralPage&>(_rPage).SetTypeSelectHandler(LINK(this, ODbAdminDialog, OnTypeSelected));
static_cast<OGeneralPage&>(_rPage).SetNameModifyHandler(LINK(this, ODbAdminDialog, OnNameModified));
static_cast<OGeneralPage&>(_rPage).setServiceFactory(m_xORB);
static_cast<OGeneralPage&>(_rPage).SetAdminDialog(this);
break;
case PAGE_TABLESUBSCRIPTION:
static_cast<OTableSubscriptionPage&>(_rPage).setServiceFactory(m_xORB);
static_cast<OTableSubscriptionPage&>(_rPage).SetAdminDialog(this);
break;
case PAGE_DOCUMENTLINKS:
case PAGE_QUERYADMINISTRATION:
static_cast<OCollectionPage&>(_rPage).setServiceFactory(m_xORB);
static_cast<OCollectionPage&>(_rPage).SetAdminDialog(this);
break;
case TAB_PAG_ADABAS_SETTINGS:
static_cast<OAdabasAdminSettings&>(_rPage).SetAdminDialog(this);
break;
case TAB_PAGE_USERADMIN:
static_cast<OUserAdmin&>(_rPage).setServiceFactory(m_xORB);
static_cast<OUserAdmin&>(_rPage).SetAdminDialog(this);
break;
}
AdjustLayout();
Window *pWin = GetViewWindow();
if(pWin)
pWin->Invalidate();
SfxTabDialog::PageCreated(_nId, _rPage);
}
//-------------------------------------------------------------------------
SfxItemSet* ODbAdminDialog::createItemSet(SfxItemSet*& _rpSet, SfxItemPool*& _rpPool, SfxPoolItem**& _rppDefaults, ODsnTypeCollection* _pTypeCollection)
{
// just to be sure ....
_rpSet = NULL;
_rpPool = NULL;
_rppDefaults = NULL;
// create and initialize the defaults
_rppDefaults = new SfxPoolItem*[DSID_LAST_ITEM_ID - DSID_FIRST_ITEM_ID + 1];
SfxPoolItem** pCounter = _rppDefaults; // want to modify this without affecting the out param _rppDefaults
*pCounter++ = new SfxStringItem(DSID_NAME, String());
*pCounter++ = new SfxStringItem(DSID_ORIGINALNAME, String());
*pCounter++ = new SfxStringItem(DSID_CONNECTURL, _pTypeCollection ? _pTypeCollection->getDatasourcePrefix(DST_JDBC) : String());
*pCounter++ = new OStringListItem(DSID_TABLEFILTER, Sequence< ::rtl::OUString >(&::rtl::OUString("%", 1, RTL_TEXTENCODING_ASCII_US), 1));
*pCounter++ = new DbuTypeCollectionItem(DSID_TYPECOLLECTION, _pTypeCollection);
*pCounter++ = new SfxBoolItem(DSID_INVALID_SELECTION, sal_False);
*pCounter++ = new SfxBoolItem(DSID_READONLY, sal_False);
*pCounter++ = new SfxStringItem(DSID_USER, String());
*pCounter++ = new SfxStringItem(DSID_PASSWORD, String());
*pCounter++ = new SfxStringItem(DSID_ADDITIONALOPTIONS, String());
*pCounter++ = new SfxStringItem(DSID_CHARSET, String());
*pCounter++ = new SfxBoolItem(DSID_PASSWORDREQUIRED, sal_False);
*pCounter++ = new SfxBoolItem(DSID_SHOWDELETEDROWS, sal_False);
*pCounter++ = new SfxBoolItem(DSID_ALLOWLONGTABLENAMES, sal_False);
*pCounter++ = new SfxStringItem(DSID_JDBCDRIVERCLASS, String());
*pCounter++ = new SfxStringItem(DSID_FIELDDELIMITER, ';');
*pCounter++ = new SfxStringItem(DSID_TEXTDELIMITER, '"');
*pCounter++ = new SfxStringItem(DSID_DECIMALDELIMITER, '.');
*pCounter++ = new SfxStringItem(DSID_THOUSANDSDELIMITER, ',');
*pCounter++ = new SfxStringItem(DSID_TEXTFILEEXTENSION, String::CreateFromAscii("txt"));
*pCounter++ = new SfxBoolItem(DSID_TEXTFILEHEADER, sal_True);
*pCounter++ = new SfxBoolItem(DSID_NEWDATASOURCE, sal_False);
*pCounter++ = new SfxBoolItem(DSID_DELETEDDATASOURCE, sal_False);
*pCounter++ = new SfxBoolItem(DSID_SUPPRESSVERSIONCL, sal_True);
*pCounter++ = new OPropertySetItem(DSID_DATASOURCE_UNO);
*pCounter++ = new SfxBoolItem(DSID_CONN_SHUTSERVICE, sal_False);
*pCounter++ = new SfxInt32Item(DSID_CONN_DATAINC, 20);
*pCounter++ = new SfxInt32Item(DSID_CONN_CACHESIZE, 20);
*pCounter++ = new SfxStringItem(DSID_CONN_CTRLUSER, String());
*pCounter++ = new SfxStringItem(DSID_CONN_CTRLPWD, String());
*pCounter++ = new SfxBoolItem(DSID_USECATALOG, sal_False);
*pCounter++ = new SfxStringItem(DSID_CONN_LDAP_HOSTNAME, String());
*pCounter++ = new SfxStringItem(DSID_CONN_LDAP_BASEDN, String());
*pCounter++ = new SfxInt32Item(DSID_CONN_LDAP_PORTNUMBER, 389);
*pCounter++ = new SfxInt32Item(DSID_CONN_LDAP_ROWCOUNT, 100);
// create the pool
static SfxItemInfo __READONLY_DATA aItemInfos[DSID_LAST_ITEM_ID - DSID_FIRST_ITEM_ID + 1] =
{
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
{0,0},
};
_rpPool = new SfxItemPool(String::CreateFromAscii("DSAItemPool"), DSID_FIRST_ITEM_ID, DSID_LAST_ITEM_ID,
aItemInfos, _rppDefaults);
_rpPool->FreezeIdRanges();
// and, finally, the set
_rpSet = new SfxItemSet(*_rpPool, sal_True);
return _rpSet;
}
//-------------------------------------------------------------------------
void ODbAdminDialog::destroyItemSet(SfxItemSet*& _rpSet, SfxItemPool*& _rpPool, SfxPoolItem**& _rppDefaults)
{
// _first_ delete the set (refering the pool)
if (_rpSet)
{
delete _rpSet;
_rpSet = NULL;
}
// delete the pool
if (_rpPool)
{
_rpPool->ReleaseDefaults(sal_True);
// the "true" means delete the items, too
delete _rpPool;
_rpPool = NULL;
}
// reset the defaults ptr
_rppDefaults = NULL;
// no need to explicitly delete the defaults, this has been done by the ReleaseDefaults
}
//-------------------------------------------------------------------------
IMPL_LINK(ODbAdminDialog, OnDatasourceSelected, ListBox*, _pBox)
{
if (!prepareSwitchDatasource())
{ // restore the old selection
if (m_sCurrentDatasource.getLength())
m_aSelector.select(m_sCurrentDatasource);
else
m_aSelector.select(m_nCurrentDeletedDataSource);
}
// switch the content of the pages
if (DELETED == m_aSelector.getSelectedState())
implSelectDeleted(m_aSelector.getSelectedAccessKey());
else
implSelectDatasource(m_aSelector.getSelected());
return 0L;
}
//-------------------------------------------------------------------------
IMPL_LINK(ODbAdminDialog, OnDatasourceModifed, SfxTabPage*, _pTabPage)
{
// check if the currently selected entry is already marked as modified
String sCurrentlySelected = m_aSelector.getSelected();
if (m_aDatasources[sCurrentlySelected].isModified())
// yes -> nothing to do
return 0L;
// no -> mark the item as modified
m_aSelector.modified(sCurrentlySelected);
m_aDatasources.update(sCurrentlySelected, *pExampleSet);
// enable the apply button
GetApplyButton()->Enable(sal_True);
return 0L;
}
//-------------------------------------------------------------------------
IMPL_LINK(ODbAdminDialog, OnNameModified, OGeneralPage*, _pTabPage)
{
if (!m_bResetting)
{
::rtl::OUString sNewStringSuggestion = _pTabPage->GetCurrentName();
// check if there's already a data source with the suggested name
ConstStringSetIterator aExistentPos = m_aValidDatasources.find(sNewStringSuggestion);
// !! m_aValidDatasources contains _all_ data source names _except_ the currently selected one !!
sal_Bool bValid = m_aValidDatasources.end() == aExistentPos;
// the user is not allowed to leave the current data source (or to commit the dialog) as long
// as the name is invalid
m_aSelector.Enable(bValid && m_aDatasources.isValid());
GetOKButton().Enable(bValid);
GetApplyButton()->Enable(bValid);
// if this is the first modification for this data source, we have to adjust the DS list accordingly
String sSelected = m_aSelector.getSelected();
if (!m_aDatasources[sSelected].isModified())
{ // (we could do it all the time here, but as this link is called every time a single character
// of the name changes, this maybe would be too expensive.)
m_aSelector.modified(sSelected);
m_aDatasources.update(sSelected, *pExampleSet);
}
// enable the apply button
GetApplyButton()->Enable(sal_True && bValid);
return bValid ? 1L : 0L;
}
return 1L;
}
// -----------------------------------------------------------------------------
void ODbAdminDialog::removeDetailPages()
{
// remove all current detail pages
while (m_aCurrentDetailPages.size())
{
RemoveTabPage((USHORT)m_aCurrentDetailPages.top());
m_aCurrentDetailPages.pop();
}
}
// -----------------------------------------------------------------------------
void ODbAdminDialog::addDetailPage(USHORT _nPageId, USHORT _nTextId, CreateTabPage _pCreateFunc)
{
// open our own resource block, as the page titles are strings local to this block
OLocalResourceAccess aDummy(DLG_DATABASE_ADMINISTRATION, RSC_TABDIALOG);
AddTabPage(_nPageId, String(ResId(_nTextId)), _pCreateFunc, 0, sal_False, 1);
m_aCurrentDetailPages.push(_nPageId);
}
//-------------------------------------------------------------------------
IMPL_LINK(ODbAdminDialog, OnTypeSelected, OGeneralPage*, _pTabPage)
{
// doe have to reset the "password required" flag to false? (in case the datasource does not support passwords)
sal_Bool bResetPasswordRequired = sal_False;
_pTabPage->enableConnectionURL();
// remove all current detail pages
removeDetailPages();
// and insert the new ones
switch (_pTabPage->GetSelectedType())
{
case DST_DBASE:
addDetailPage(PAGE_DBASE, STR_PAGETITLE_DBASE, ODbaseDetailsPage::Create);
bResetPasswordRequired = sal_True;
break;
case DST_JDBC:
addDetailPage(PAGE_JDBC, STR_PAGETITLE_JDBC, OJdbcDetailsPage::Create);
break;
case DST_ADO:
addDetailPage(PAGE_ADO, STR_PAGETITLE_ADO, OAdoDetailsPage::Create);
break;
case DST_TEXT:
addDetailPage(PAGE_TEXT, STR_PAGETITLE_TEXT, OTextDetailsPage::Create);
bResetPasswordRequired = sal_True;
break;
case DST_ODBC:
addDetailPage(PAGE_ODBC, STR_PAGETITLE_ODBC, OOdbcDetailsPage::Create);
break;
case DST_ADABAS:
// for adabas we have more than one page
// CAUTION: the order of inserting pages matters.
// the major detail page should be inserted last always (thus, it becomes the first page after
// the general page)
addDetailPage(TAB_PAGE_USERADMIN, STR_PAGETITLE_USERADMIN, OUserAdmin::Create);
addDetailPage(TAB_PAG_ADABAS_SETTINGS, STR_PAGETITLE_ADABAS_STATISTIC, OAdabasAdminSettings::Create);
addDetailPage(PAGE_ADABAS, STR_PAGETITLE_ADABAS, OAdabasDetailsPage::Create);
{
// Size aOldSize = pTabControl->GetSizePixel();
// pTabControl->SetTabPageSizePixel( ... );
// Size aNewSize = pTabControl->GetSizePixel();
// if ( aOldSize != aNewSize )
// pTabDialog->AdjustLayout();
}
break;
case DST_ADDRESSBOOK:
if(getDatasourceType(*GetExampleSet()) == DST_ADDRESSBOOK)
{
String sConnectionURL;
SFX_ITEMSET_GET(*GetExampleSet(), pUrlItem, SfxStringItem, DSID_CONNECTURL, sal_True);
sConnectionURL = pUrlItem->GetValue();
if (0 == sConnectionURL.CompareToAscii("sdbc:address:ldap:"))
addDetailPage(PAGE_LDAP,STR_PAGETITLE_LDAP,OLDAPDetailsPage::Create);
}
_pTabPage->disableConnectionURL();
break;
}
if (bResetPasswordRequired)
{
GetInputSetImpl()->Put(SfxBoolItem(DSID_PASSWORDREQUIRED, sal_False));
if (pExampleSet)
pExampleSet->Put(SfxBoolItem(DSID_PASSWORDREQUIRED, sal_False));
}
return 0L;
}
//-------------------------------------------------------------------------
Reference< XPropertySet > ODbAdminDialog::getDatasource(const ::rtl::OUString& _rName)
{
DBG_ASSERT(m_aDatasources.isValid(), "ODbAdminDialog::getDatasource : have no database context!");
if (!m_aDatasources.exists(_rName))
return Reference< XPropertySet >();
return m_aDatasources[_rName]->getDatasource();
}
//-------------------------------------------------------------------------
void ODbAdminDialog::implSelectDeleted(sal_Int32 _nKey)
{
m_aSelector.select(_nKey);
// insert the previously selected data source into our "all valid datasources" set
if (m_sCurrentDatasource.getLength()) // previous selection was not on a deleted data source
m_aValidDatasources.insert(m_sCurrentDatasource);
m_sCurrentDatasource = ::rtl::OUString();
m_nCurrentDeletedDataSource = _nKey;
// reset the tag pages
resetPages(Reference< XPropertySet >(), sal_True);
// disallow reset for deleted pages
// GetResetButton().Enable(sal_False);
}
//-------------------------------------------------------------------------
void ODbAdminDialog::implSelectDatasource(const ::rtl::OUString& _rRegisteredName)
{
m_aSelector.select(_rRegisteredName);
// insert the previously selected data source into our set
if (m_sCurrentDatasource.getLength()) // previous selection was not on a deleted data source
m_aValidDatasources.insert(m_sCurrentDatasource);
m_sCurrentDatasource = _rRegisteredName;
m_nCurrentDeletedDataSource = -1;
// remove the now selected data source from our set
m_aValidDatasources.erase(m_sCurrentDatasource);
// reset the tag pages
Reference< XPropertySet > xDatasource = getDatasource(_rRegisteredName);
resetPages(xDatasource, sal_False);
// allow reset for non-deleted pages
// GetResetButton().Enable(sal_True);
}
//-------------------------------------------------------------------------
void ODbAdminDialog::resetPages(const Reference< XPropertySet >& _rxDatasource, sal_Bool _bDeleted)
{
// the selection is valid if and only if we have a datasource now
GetInputSetImpl()->Put(SfxBoolItem(DSID_INVALID_SELECTION, !_rxDatasource.is()));
// (sal_False tells the tab pages to disable and reset all their controls, which is different
// from "just set them to readonly")
// reset the pages
// prevent flicker
SetUpdateMode(sal_False);
m_bResetting = sal_True;
ShowPage(PAGE_GENERAL);
m_bResetting = sal_False;
// remove all tab pages (except the general one)
// remove all current detail pages
while (m_aCurrentDetailPages.size())
{
RemoveTabPage((USHORT)m_aCurrentDetailPages.top());
m_aCurrentDetailPages.pop();
}
// remove the table/query tab pages
RemoveTabPage(PAGE_TABLESUBSCRIPTION);
RemoveTabPage(PAGE_QUERYADMINISTRATION);
RemoveTabPage(PAGE_DOCUMENTLINKS);
// extract all relevant data from the property set of the data source
translateProperties(_rxDatasource, *GetInputSetImpl());
// reset some meta data items in the input set which are for tracking the state of the current ds
GetInputSetImpl()->Put(SfxBoolItem(DSID_NEWDATASOURCE, sal_False));
GetInputSetImpl()->Put(SfxBoolItem(DSID_DELETEDDATASOURCE, _bDeleted));
GetInputSetImpl()->Put(OPropertySetItem(DSID_DATASOURCE_UNO, _rxDatasource));
// fill in the remembered settings for the data source
if (m_sCurrentDatasource.getLength()) // the current datasource is not deleted
if (m_aDatasources[m_sCurrentDatasource]->isModified()) // the current data source was modified before
GetInputSetImpl()->Put(*m_aDatasources[m_sCurrentDatasource]->getModifications());
// propagate this set as our new input set and reset the example set
SetInputSet(GetInputSetImpl());
delete pExampleSet;
pExampleSet = new SfxItemSet(*GetInputSetImpl());
// and again, add the non-details tab pages
if (!_bDeleted)
{
OLocalResourceAccess aDummy(DLG_DATABASE_ADMINISTRATION, RSC_TABDIALOG);
AddTabPage(PAGE_TABLESUBSCRIPTION, String(ResId(STR_PAGETITLE_TABLESUBSCRIPTION)), OTableSubscriptionPage::Create, NULL);
AddTabPage(PAGE_QUERYADMINISTRATION, String(ResId(STR_PAGETITLE_QUERIES)), OQueryAdministrationPage::Create, NULL);
AddTabPage(PAGE_DOCUMENTLINKS, String(ResId(STR_PAGETITLE_DOCUMENTS)), ODocumentLinksPage::Create, NULL);
}
m_bResetting = sal_True;
ShowPage(PAGE_GENERAL);
SetUpdateMode(sal_True);
// propagate the new data to the general tab page the general tab page
SfxTabPage* pGeneralPage = GetTabPage(PAGE_GENERAL);
if (pGeneralPage)
pGeneralPage->Reset(*GetInputSetImpl());
// if this is NULL, the page has not been created yet, which means we're called before the
// dialog was displayed (probably from inside the ctor)
m_bResetting = sal_False;
}
//-------------------------------------------------------------------------
Any ODbAdminDialog::implTranslateProperty(const SfxPoolItem* _pItem)
{
// translate the SfxPoolItem
Any aValue;
if (_pItem->ISA(SfxStringItem))
aValue <<= ::rtl::OUString(PTR_CAST(SfxStringItem, _pItem)->GetValue().GetBuffer());
else if (_pItem->ISA(SfxBoolItem))
aValue = ::cppu::bool2any(PTR_CAST(SfxBoolItem, _pItem)->GetValue());
else if (_pItem->ISA(SfxInt32Item))
aValue <<= PTR_CAST(SfxInt32Item, _pItem)->GetValue();
else if (_pItem->ISA(OStringListItem))
aValue <<= PTR_CAST(OStringListItem, _pItem)->getList();
else
{
DBG_ERROR("ODbAdminDialog::implTranslateProperty: unsupported item type!");
return aValue;
}
return aValue;
}
//-------------------------------------------------------------------------
void ODbAdminDialog::implTranslateProperty(const Reference< XPropertySet >& _rxSet, const ::rtl::OUString& _rName, const SfxPoolItem* _pItem)
{
Any aValue = implTranslateProperty(_pItem);
try
{
_rxSet->setPropertyValue(_rName, aValue);
}
catch(Exception&)
{
#ifdef DBG_UTIL
::rtl::OString sMessage("ODbAdminDialog::implTranslateProperty: could not set the property ");
sMessage += ::rtl::OString(_rName.getStr(), _rName.getLength(), RTL_TEXTENCODING_ASCII_US);
sMessage += ::rtl::OString("!");
DBG_ERROR(sMessage.getStr());
#endif
}
}
//-------------------------------------------------------------------------
void ODbAdminDialog::implTranslateProperty(SfxItemSet& _rSet, sal_Int32 _nId, const Any& _rValue)
{
switch (_rValue.getValueType().getTypeClass())
{
case TypeClass_STRING:
{
::rtl::OUString sValue;
_rValue >>= sValue;
_rSet.Put(SfxStringItem((USHORT)_nId, sValue.getStr()));
}
break;
case TypeClass_BOOLEAN:
_rSet.Put(SfxBoolItem((USHORT)_nId, ::cppu::any2bool(_rValue)));
break;
case TypeClass_LONG:
{
sal_Int32 nValue = 0;
_rValue >>= nValue;
_rSet.Put(SfxInt32Item((USHORT)_nId, nValue));
}
break;
case TypeClass_SEQUENCE:
{
// determine the element type
TypeDescription aTD(_rValue.getValueType());
typelib_IndirectTypeDescription* pSequenceTD =
reinterpret_cast< typelib_IndirectTypeDescription* >(aTD.get());
DBG_ASSERT(pSequenceTD && pSequenceTD->pType, "ODbAdminDialog::implTranslateProperty: invalid sequence type!");
Type aElementType(pSequenceTD->pType);
switch (aElementType.getTypeClass())
{
case TypeClass_STRING:
{
Sequence< ::rtl::OUString > aStringList;
_rValue >>= aStringList;
_rSet.Put(OStringListItem((USHORT)_nId, aStringList));
}
break;
default:
DBG_ERROR("ODbAdminDialog::implTranslateProperty: unsupported property value type!");
}
}
break;
case TypeClass_VOID:
_rSet.ClearItem((USHORT)_nId);
break;
default:
DBG_ERROR("ODbAdminDialog::implTranslateProperty: unsupported property value type!");
}
}
//-------------------------------------------------------------------------
struct PropertyValueLess
{
bool operator() (const PropertyValue& x, const PropertyValue& y) const
{ return x.Name < y.Name ? true : false; } // construct prevents a MSVC6 warning
};
DECLARE_STL_SET( PropertyValue, PropertyValueLess, PropertyValueSet);
//........................................................................
void ODbAdminDialog::translateProperties(const Reference< XPropertySet >& _rxSource, SfxItemSet& _rDest)
{
::rtl::OUString sNewConnectURL, sName, sUid, sPwd;
Sequence< ::rtl::OUString > aTableFitler;
sal_Bool bPasswordRequired = sal_False;
sal_Bool bReadOnly = sal_True;
if (_rxSource.is())
{
for ( ConstMapInt2StringIterator aDirect = m_aDirectPropTranslator.begin();
aDirect != m_aDirectPropTranslator.end();
++aDirect
)
{
// get the property value
Any aValue;
try
{
aValue = _rxSource->getPropertyValue(aDirect->second);
}
catch(Exception&)
{
#if DBG_UTIL
::rtl::OString aMessage("ODbAdminDialog::translateProperties: could not extract the property ");
aMessage += ::rtl::OString(aDirect->second.getStr(), aDirect->second.getLength(), RTL_TEXTENCODING_ASCII_US);
aMessage += ::rtl::OString("!");
DBG_ERROR(aMessage.getStr());
#endif
}
// transfer it into an item
implTranslateProperty(_rDest, aDirect->first, aValue);
}
// get the additional informations
Sequence< PropertyValue > aAdditionalInfo;
try
{
_rxSource->getPropertyValue(PROPERTY_INFO) >>= aAdditionalInfo;
}
catch(Exception&) { }
// collect the names of the additional settings
const PropertyValue* pAdditionalInfo = aAdditionalInfo.getConstArray();
PropertyValueSet aInfos;
for (sal_Int32 i=0; i<aAdditionalInfo.getLength(); ++i, ++pAdditionalInfo)
{
if (0 == pAdditionalInfo->Name.compareToAscii("JDBCDRV"))
{ // compatibility
PropertyValue aCompatibility(*pAdditionalInfo);
aCompatibility.Name = ::rtl::OUString::createFromAscii("JavaDriverClass");
aInfos.insert(aCompatibility);
}
else
aInfos.insert(*pAdditionalInfo);
}
// go through all known translations and check if we have such a setting
PropertyValue aSearchFor;
for ( ConstMapInt2StringIterator aIndirect = m_aIndirectPropTranslator.begin();
aIndirect != m_aIndirectPropTranslator.end();
++aIndirect
)
{
aSearchFor.Name = aIndirect->second;
ConstPropertyValueSetIterator aInfoPos = aInfos.find(aSearchFor);
if (aInfos.end() != aInfoPos)
// the property is contained in the info sequence
// -> transfer it into an item
implTranslateProperty(_rDest, aIndirect->first, aInfoPos->Value);
}
}
}
//-------------------------------------------------------------------------
void ODbAdminDialog::translateProperties(const SfxItemSet& _rSource, const Reference< XPropertySet >& _rxDest)
{
DBG_ASSERT(_rxDest.is(), "ODbAdminDialog::translateProperties: invalid property set!");
if (!_rxDest.is())
return;
// the property set info
Reference< XPropertySetInfo > xInfo;
try { xInfo = _rxDest->getPropertySetInfo(); }
catch(Exception&) { }
// -----------------------------
// transfer the direct propertis
for ( ConstMapInt2StringIterator aDirect = m_aDirectPropTranslator.begin();
aDirect != m_aDirectPropTranslator.end();
++aDirect
)
{
const SfxPoolItem* pCurrentItem = _rSource.GetItem((USHORT)aDirect->first);
if (pCurrentItem)
{
sal_Int16 nAttributes = PropertyAttribute::READONLY;
if (xInfo.is())
{
try { nAttributes = xInfo->getPropertyByName(aDirect->second).Attributes; }
catch(Exception&) { }
}
if ((nAttributes & PropertyAttribute::READONLY) == 0)
implTranslateProperty(_rxDest, aDirect->second, pCurrentItem);
}
}
// -------------------------------
// now for the indirect properties
Sequence< PropertyValue > aInfo;
// the original properties
try
{
_rxDest->getPropertyValue(PROPERTY_INFO) >>= aInfo;
}
catch(Exception&) { }
// overwrite and extend them
fillDatasourceInfo(_rSource, aInfo);
// and propagate the (newly composed) sequence to the set
try
{
_rxDest->setPropertyValue(PROPERTY_INFO, makeAny(aInfo));
}
catch(Exception&)
{
DBG_ERROR("ODbAdminDialog::translateProperties: could not propagate the composed info sequence to the property set!");
}
}
//-------------------------------------------------------------------------
DATASOURCE_TYPE ODbAdminDialog::getDatasourceType(const SfxItemSet& _rSet) const
{
SFX_ITEMSET_GET(_rSet, pConnectURL, SfxStringItem, DSID_CONNECTURL, sal_True);
SFX_ITEMSET_GET(_rSet, pTypeCollection, DbuTypeCollectionItem, DSID_TYPECOLLECTION, sal_True);
DBG_ASSERT(pConnectURL && pTypeCollection, "ODbAdminDialog::getDatasourceType: invalid items in the source set!");
String sConnectURL = pConnectURL->GetValue();
ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
DBG_ASSERT(pCollection, "ODbAdminDialog::getDatasourceType: invalid type collection!");
return pCollection->getType(sConnectURL);
}
//-------------------------------------------------------------------------
sal_Bool ODbAdminDialog::hasAuthentication(const SfxItemSet& _rSet) const
{
DATASOURCE_TYPE eType = getDatasourceType(_rSet);
SFX_ITEMSET_GET(_rSet, pTypeCollection, DbuTypeCollectionItem, DSID_TYPECOLLECTION, sal_True);
return pTypeCollection->getCollection()->hasAuthentication(eType);
}
//-------------------------------------------------------------------------
const sal_Int32* ODbAdminDialog::getRelevantItems(const SfxItemSet& _rSet) const
{
DATASOURCE_TYPE eType = getDatasourceType(_rSet);
const sal_Int32* pRelevantItems = NULL;
switch (eType)
{
case DST_ADABAS:
{
static sal_Int32* pAdabasItems = NULL;
if(!pAdabasItems)
{
const sal_Int32* pFirstRelevantItems = OAdabasDetailsPage::getDetailIds();
const sal_Int32* pSecondRelevantItems = OAdabasAdminSettings::getDetailIds();
sal_Int32 nFLen = 0;
sal_Int32 nSLen = 0;
for(pRelevantItems = pFirstRelevantItems;pRelevantItems && *pRelevantItems;++pRelevantItems)
++nFLen;
for(pRelevantItems = pSecondRelevantItems;pRelevantItems && *pRelevantItems;++pRelevantItems)
++nSLen;
pAdabasItems = new sal_Int32[nFLen + nSLen + 1];
nFLen = 0;
for(pRelevantItems = pFirstRelevantItems;pRelevantItems && *pRelevantItems;++pRelevantItems)
pAdabasItems[nFLen++] = *pRelevantItems;
for(pRelevantItems = pSecondRelevantItems;pRelevantItems && *pRelevantItems;++pRelevantItems)
pAdabasItems[nFLen++] = *pRelevantItems;
pAdabasItems[nFLen] = 0;
}
pRelevantItems = pAdabasItems;
}
break;
case DST_JDBC: pRelevantItems = OJdbcDetailsPage::getDetailIds(); break;
case DST_ADO: pRelevantItems = OAdoDetailsPage::getDetailIds(); break;
case DST_ODBC: pRelevantItems = OOdbcDetailsPage::getDetailIds(); break;
case DST_ADDRESSBOOK:
{
String sConnectionURL;
SFX_ITEMSET_GET(*GetExampleSet(), pUrlItem, SfxStringItem, DSID_CONNECTURL, sal_True);
sConnectionURL = pUrlItem->GetValue();
if(String::CreateFromAscii("sdbc:address:ldap:") == sConnectionURL)
pRelevantItems = OLDAPDetailsPage::getDetailIds();
else
{
static sal_Int32 nRelevantIds[] = { 0 };
pRelevantItems = nRelevantIds;
}
break;
}
case DST_DBASE: pRelevantItems = ODbaseDetailsPage::getDetailIds(); break;
case DST_TEXT: pRelevantItems = OTextDetailsPage::getDetailIds(); break;
case DST_CALC:
{
// spreadsheet currently has no options page
static sal_Int32 nRelevantIds[] = { 0 };
pRelevantItems = nRelevantIds;
}
break;
}
return pRelevantItems;
}
//-------------------------------------------------------------------------
void ODbAdminDialog::fillDatasourceInfo(const SfxItemSet& _rSource, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rInfo)
{
// within the current "Info" sequence, replace the ones we can examine from the item set
// (we don't just fill a completely new sequence with our own items, but we preserve any properties unknown to
// us)
// first determine which of all the items are relevant for the data source (depends on the connection url)
const sal_Int32* pRelevantItems = getRelevantItems(_rSource);
DBG_ASSERT(pRelevantItems, "ODbAdminDialog::translateProperties: invalid item ids got from the page!");
// collect the translated property values for the relevant items
PropertyValueSet aRelevantSettings;
ConstMapInt2StringIterator aTranslation;
while (pRelevantItems && *pRelevantItems)
{
const SfxPoolItem* pCurrent = _rSource.GetItem((USHORT)*pRelevantItems);
aTranslation = m_aIndirectPropTranslator.find(*pRelevantItems);
if (pCurrent && (m_aIndirectPropTranslator.end() != aTranslation))
aRelevantSettings.insert(PropertyValue(aTranslation->second, 0, implTranslateProperty(pCurrent), PropertyState_DIRECT_VALUE));
++pRelevantItems;
}
// settings to preserve
MapInt2String aPreservedSettings;
// now aRelevantSettings contains all the property values relevant for the current data source type,
// check the original sequence if it already contains any of these values (which have to be overwritten, then)
PropertyValue* pInfo = _rInfo.getArray();
PropertyValue aSearchFor;
sal_Int32 nObsoleteSetting = -1;
for (sal_Int32 i=0; i<_rInfo.getLength(); ++i, ++pInfo)
{
aSearchFor.Name = pInfo->Name;
PropertyValueSetIterator aOverwrittenSetting = aRelevantSettings.find(aSearchFor);
if (aRelevantSettings.end() != aOverwrittenSetting)
{ // the setting was present in the original sequence, and it is to be overwritten -> replace it
*pInfo = *aOverwrittenSetting;
aRelevantSettings.erase(aOverwrittenSetting);
}
else if (0 == pInfo->Name.compareToAscii("JDBCDRV"))
{ // this is a compatibility setting, remove it from the sequence (it's replaced by JavaDriverClass)
nObsoleteSetting = i;
}
else
aPreservedSettings[i] = pInfo->Name;
}
if (-1 != nObsoleteSetting)
::comphelper::removeElementAt(_rInfo, nObsoleteSetting);
if (aPreservedSettings.size())
{ // check if there are settings which
// * are known as indirect properties
// * but not relevant for the current data source type
// These settings have to be removed: If they're not relevant, we have no UI for changing them.
// 25.06.2001 - 88004/87182 - frank.schoenheit@sun.com
// for this, we need a string-controlled quick access to m_aIndirectPropTranslator
StringSet aIndirectProps;
for ( ConstMapInt2StringIterator aIPLoop = m_aIndirectPropTranslator.begin();
aIPLoop != m_aIndirectPropTranslator.end();
++aIPLoop
)
{
aIndirectProps.insert(aIPLoop->second);
}
// now check the to-be-preserved props
::std::vector< sal_Int32 > aRemoveIndexes;
sal_Int32 nPositionCorrector = 0;
for ( ConstMapInt2StringIterator aPreserved = aPreservedSettings.begin();
aPreserved != aPreservedSettings.end();
++aPreserved
)
{
if (aIndirectProps.end() != aIndirectProps.find(aPreserved->second))
{
#ifdef DBG_UTIL
const ::rtl::OUString sName = aPreserved->second;
#endif
aRemoveIndexes.push_back(aPreserved->first - nPositionCorrector);
++nPositionCorrector;
}
}
// now finally remove all such props
for ( ::std::vector< sal_Int32 >::const_iterator aRemoveIndex = aRemoveIndexes.begin();
aRemoveIndex != aRemoveIndexes.end();
++aRemoveIndex
)
::comphelper::removeElementAt(_rInfo, *aRemoveIndex);
#ifdef DBG_UTIL
const PropertyValue* pWhatsLeft = _rInfo.getConstArray();
const PropertyValue* pWhatsLeftEnd = pWhatsLeft + _rInfo.getLength();
for (; pWhatsLeft != pWhatsLeftEnd; ++pWhatsLeft)
{
::rtl::OUString sLookAtIt = pWhatsLeft->Name;
}
#endif
}
// check which values are still left ('cause they were not present in the original sequence, but are to be set)
sal_Int32 nOldLength = _rInfo.getLength();
_rInfo.realloc(nOldLength + aRelevantSettings.size());
PropertyValue* pAppendValues = _rInfo.getArray() + nOldLength;
for ( ConstPropertyValueSetIterator aLoop = aRelevantSettings.begin();
aLoop != aRelevantSettings.end();
++aLoop, ++pAppendValues
)
{
*pAppendValues = *aLoop;
}
}
//-------------------------------------------------------------------------
::rtl::OUString ODbAdminDialog::getUniqueName() const
{
::rtl::OUString sBase = String(ModuleRes(STR_DATASOURCE_DEFAULTNAME)).GetBuffer();
sBase += ::rtl::OUString(" ", 1, RTL_TEXTENCODING_ASCII_US);
for (sal_Int32 i=1; i<65635; ++i)
{
::rtl::OUString sCheck(sBase);
sCheck += ::rtl::OUString::valueOf(i);
// check if "all but the current" datasources aleady contain the to-be-checked name
if (m_aValidDatasources.end() != m_aValidDatasources.find(sCheck))
continue;
// check if the currently selected data source allows the new name
if (m_sCurrentDatasource.equals(sCheck))
continue;
// have a valid new name
return sCheck;
}
DBG_ERROR("ODbAdminDialog::getUniqueName: no free names!");
return ::rtl::OUString();
}
//-------------------------------------------------------------------------
sal_Bool ODbAdminDialog::prepareSwitchDatasource()
{
// first ask the current page if it is allowed to leave
if (!PrepareLeaveCurrentPage())
// the page did not allow us to leave -> outta here
return sal_False;
// if the old data source is not a to-be-deleted one, save the modifications made in the tabpages
if (m_sCurrentDatasource.getLength())
{
// remember the settings for this data source
ODatasourceMap::ODatasourceInfo aPreviouslySelected = m_aDatasources[m_sCurrentDatasource];
if (aPreviouslySelected.isModified())
m_aDatasources.update(m_sCurrentDatasource, *pExampleSet);
// (The modified flag is set as soon as any UI element has any change (e.g. a single new character in a edit line).
// But when this flag is set, and other changes occur, no items are transfered.
// That's why the above statement "if (isModified()) update()" makes sense, though it may not seem so :)
// need a special handling for the name property
if (aPreviouslySelected.isModified())
{
String sName = aPreviouslySelected.getName().getStr();
DBG_ASSERT(m_sCurrentDatasource.equals(sName.GetBuffer()), "ODbAdminDialog::prepareSwitchDatasource: inconsistent names!");
// first adjust the name which the datasource is stored under in our map.
String sNewName = m_aDatasources.adjustRealName(sName);
// if this was a real change ('cause the ds was stored under name "A", but the modifications set already contained
// an DSID_NAME item "B", which has been corrected by the previous call), tell the selector window that
// something changed
if (!sNewName.Equals(sName))
{
// tell our selector window that the name has changed
m_aSelector.renamed(sName, sNewName);
// update our "current database"
m_sCurrentDatasource = sNewName;
}
}
}
return sal_True;
}
//-------------------------------------------------------------------------
IMPL_LINK(ODbAdminDialog, OnNewDatasource, Window*, _pWindow)
{
if (!prepareSwitchDatasource())
return 1L;
::rtl::OUString sNewName = getUniqueName();
if (0 == sNewName.getLength())
return 1L; // no free names
// create a new datasource (not belonging to a context, yet)
Reference< XPropertySet > xFloatingDatasource = m_aDatasources.createNew(sNewName, GetInputSetImpl()->GetPool(), GetInputSetImpl()->GetRanges());
if (!xFloatingDatasource.is())
{
ShowServiceNotAvailableError(this, String(SERVICE_SDB_DATASOURCE), sal_True);
return 1L;
}
GetInputSetImpl()->ClearItem();
// insert a new entry for the new DS
m_aSelector.insertNew(sNewName);
// update our "all-but the selected ds" structure
m_aValidDatasources.insert(sNewName);
// and select this new entry
m_aSelector.select(sNewName);
implSelectDatasource(sNewName);
// enable the apply button
GetApplyButton()->Enable(sal_True);
SfxTabPage* pGeneralPage = GetTabPage(PAGE_GENERAL);
if (pGeneralPage)
pGeneralPage->GrabFocus();
return 0L;
}
//-------------------------------------------------------------------------
IMPL_LINK(ODbAdminDialog, OnDeleteDatasource, Window*, _pWindow)
{
::rtl::OUString sDeleteWhich = m_aSelector.getSelected();
if (NEW == m_aSelector.getSelectedState())
{
// insert the previously selected data source into our "all valid datasources" set
if (m_sCurrentDatasource.getLength()) // previous selection was not on a deleted data source
m_aValidDatasources.insert(m_sCurrentDatasource);
m_sCurrentDatasource = ::rtl::OUString();
m_aDatasources.deleted(sDeleteWhich);
m_aSelector.deleted(sDeleteWhich);
}
else
{
sal_Int32 nAccessKey = m_aDatasources.markDeleted(sDeleteWhich);
if (-1 == nAccessKey)
return 0L;
// mark it as deleted
m_aSelector.markDeleted(sDeleteWhich, nAccessKey);
// re-select it (to reset the pages so they reflect the new state)
implSelectDeleted(nAccessKey);
}
// mark the name as "available"
m_aValidDatasources.erase(sDeleteWhich);
// enable the apply button
GetApplyButton()->Enable(sal_True);
return 1L;
}
//-------------------------------------------------------------------------
IMPL_LINK(ODbAdminDialog, OnRestoreDatasource, Window*, _pWindow)
{
sal_Int32 nAccessKey = m_aSelector.getSelectedAccessKey();
::rtl::OUString sName;
if (m_aDatasources.restoreDeleted(nAccessKey, sName))
{ // successfully restore the item in the map
// -> restore it in the view, too
ODatasourceMap::ODatasourceInfo aInfo(m_aDatasources[sName]);
m_aSelector.restoreDeleted(nAccessKey, aInfo.isModified() ? MODIFIED : aInfo.isNew() ? NEW : CLEAN);
implSelectDatasource(sName);
}
else
{
ErrorBox aError(this, ModuleRes(ERR_COULDNOTRESTOREDS));
aError.Execute();
}
// enable the apply button
GetApplyButton()->Enable(sal_True);
return 0L;
}
//-------------------------------------------------------------------------
ODbAdminDialog::ApplyResult ODbAdminDialog::implApplyChanges(const sal_Bool _bActivateOnSuccess)
{
if (!PrepareLeaveCurrentPage())
{ // the page did not allow us to leave
return AR_KEEP;
}
ApplyResult eResult = AR_LEAVE_UNCHANGED;
// save the settings for the currently selected data source
if (m_aSelector.count() && (DELETED != m_aSelector.getSelectedState()))
{
::rtl::OUString sCurrentlySelected = m_aSelector.getSelected();
if (m_aDatasources[sCurrentlySelected]->isModified())
{
m_aDatasources.update(sCurrentlySelected, *pExampleSet);
String sNewName = m_aDatasources.adjustRealName(sCurrentlySelected);
String sOldName = sCurrentlySelected;
// the data source has not only been modified, but renamed, too
// -> adjust the selector and m_sCurrentDatasource
// (we are allowed to do this here, this is no part of the committment of the changes, it just
// leaves our structures in a consistent state for the real commitment)
if (!sNewName.Equals(sOldName))
{
// tell our selector window that the name has changed
m_aSelector.renamed(sOldName, sNewName);
// update our "current database"
m_sCurrentDatasource = sNewName;
// adjust the selection
implSelectDatasource(m_sCurrentDatasource);
}
}
}
// We allowed the user to freely rename/create/delete datasources, without committing anything ('til now).
// This could lead to conflicts: if datasource "A" was renamed to "B", and a new ds "A" created, then we
// would have to do the renaming before the creation. This would require us to analyze the changes in
// m_aDatasources for any such dependencies, which could be difficult (okay, I'm not willing to do it :)
// Instead we use another approach: If we encounter a conflict (a DS which can't be renamed or inserted),
// we save this entry and continue with the next one. This way, the ds causing the conflict should be handled
// first. After that, we do a new round, assuming that now the conflict is resolved.
// A disadvantage is that this may require O(n^2) rounds, but this is not really expensive ....
// first delete all datasources which were scheduled for deletion
for ( ODatasourceMap::Iterator aLoopDeleted = m_aDatasources.beginDeleted();
aLoopDeleted != m_aDatasources.endDeleted();
++aLoopDeleted
)
{
::rtl::OUString sDeleteWhich = aLoopDeleted->getOriginalName();
sal_Bool bOperationSuccess = sal_False;
try
{
m_xDynamicContext->revokeObject(sDeleteWhich);
bOperationSuccess = sal_True;
}
catch(Exception&) { }
if (bOperationSuccess)
{
eResult = AR_LEAVE_MODIFIED;
m_aSelector.deleted(aLoopDeleted->getAccessKey());
}
else
{
DBG_ERROR("ODbAdminDialog::implApplyChanges: could not delete a data source!");
// TODO: an error message
}
}
m_aDatasources.clearDeleted();
sal_Int32 nDelayed = 0;
sal_Int32 nLastRoundDelayed = -1;
// to ensure that we're not looping 'til death: If this doesn't change within one round, the DatabaseContext
// is not in the state as this dialog started anymore. This means somebody else did some renamings
// or insertings, causing us conflicts now.
do
{
if (nLastRoundDelayed == nDelayed)
{
DBG_ERROR("ODbAdminDialog::implApplyChanges: somebody tampered with the context!");
// TODO: error handling
break;
}
// reset the counter
nLastRoundDelayed = nDelayed;
nDelayed = 0;
// propagate all the settings made to the appropriate data source, and add/drop/rename data sources
for ( ODatasourceMap::Iterator aLoop = m_aDatasources.begin();
aLoop != m_aDatasources.end();
++aLoop
)
{
// nothing to do if no modifications were done
if (aLoop->isModified())
{
Reference< XPropertySet > xDatasource = aLoop->getDatasource();
if (xDatasource.is())
{
eResult = AR_LEAVE_MODIFIED;
// we changes something
// put the remembered settings into the property set
translateProperties(*aLoop->getModifications(), xDatasource);
::rtl::OUString sName = aLoop->getName();
DBG_ASSERT(sName.equals(aLoop->getRealName()), "ODbAdminDialog::implApplyChanges: invalid name/realname combination!");
// these both names shouldn't be diefferent here anymore
::rtl::OUString sOriginalName = aLoop->getOriginalName();
// if we need a new name, check for conflicts
if (aLoop->isRenamed() || aLoop->isNew())
{
sal_Bool bAlreadyHaveNewName = sal_True;
try
{
bAlreadyHaveNewName = m_xDatabaseContext->hasByName(sName);
}
catch(RuntimeException&) { }
if (bAlreadyHaveNewName)
{
++nDelayed;
continue;
// | <---------------- continue with the next data source
}
if (aLoop->isRenamed())
{
// remove the object
sal_Bool bOperationSuccess = sal_False;
try
{
m_xDynamicContext->revokeObject(sOriginalName);
bOperationSuccess = sal_True;
}
catch(Exception&) { }
if (!bOperationSuccess)
{
DBG_ERROR("ODbAdminDialog::implApplyChanges: data source was renamed, but could not remove it (to insert it under a new name)!");
// TODO: an error message
}
}
// (re)insert the object under the new name
sal_Bool bOperationSuccess = sal_False;
try
{
m_xDynamicContext->registerObject(sName, xDatasource.get());
bOperationSuccess = sal_True;
}
catch(Exception&) { }
if (bOperationSuccess)
{
// everything's ok ...
// no need to flush the object anymore, this is done automatically upon insertion
}
else if (aLoop->isRenamed())
{
// oops ... we removed the ds, but could not re-insert it
// try to prevent data loss
DBG_ERROR("ODbAdminDialog::implApplyChanges: removed the entry, but could not re-insert it!");
// we're going to re-insert the object under it's old name
bOperationSuccess = sal_False;
try
{
m_xDynamicContext->registerObject(sOriginalName, xDatasource.get());
bOperationSuccess = sal_True;
}
catch(Exception&) { }
DBG_ASSERT(bOperationSuccess, "ODbAdminDialog::implApplyChanges: could not insert it under the old name, too ... no we have a data loss!");
}
// reset the item, so in case we need an extra round (because of delayed items) it
// won't be included anymore
m_aDatasources.clearModifiedFlag(sName);
// and tell the selector the new state
m_aSelector.flushed(sName);
continue;
// | <------------ continue with the next data source
}
// We're here if the data source was not renamed, not deleted and is not new. Just flush it.
Reference< XFlushable > xFlushDatasource(xDatasource, UNO_QUERY);
if (!xFlushDatasource.is())
{
DBG_ERROR("ODbAdminDialog::implApplyChanges: the datasource should be flushable!");
continue;
}
try
{
xFlushDatasource->flush();
}
catch(RuntimeException&)
{
DBG_ERROR("ODbAdminDialog::implApplyChanges: caught an exception whild flushing the data source's data!");
}
// reset the item, so in case we need an extra round (because of delayed items) it
// won't be included anymore
m_aDatasources.clearModifiedFlag(sName);
// and tell the selector the new state
m_aSelector.flushed(sName);
}
}
}
}
while (nDelayed);
// reset some meta-data-items in the the example set
// 00/11/10 - 80185 - FS
pExampleSet->Put(SfxBoolItem(DSID_NEWDATASOURCE, sal_False));
pExampleSet->Put(SfxBoolItem(DSID_DELETEDDATASOURCE, sal_False));
// disable the apply button
GetApplyButton()->Enable(sal_False);
if (_bActivateOnSuccess)
ShowPage(GetCurPageId());
// This does the usual ActivatePage, so the pages can save their current status.
// This way, next time they're asked what has changed since now and here, they really
// can compare with the status they have _now_ (not the one they had before this apply call).
return eResult;
}
//-------------------------------------------------------------------------
IMPL_LINK(ODbAdminDialog, OnAsyncApplyChanges, void*, _OnErrorResId)
{
SfxTabDialog::Ok();
if (AR_KEEP != implApplyChanges())
{
// show the page
if (GetCurPageId() != m_nPostApplyPage)
ShowPage(m_nPostApplyPage);
// restore the view settings
if (m_pPostApplyPageSettings)
{
SfxTabPage* pPage = GetTabPage(m_nPostApplyPage);
if (pPage)
static_cast<OGenericAdministrationPage*>(pPage)->restoreViewSettings(m_pPostApplyPageSettings);
delete m_pPostApplyPageSettings;
m_pPostApplyPageSettings = NULL;
}
m_nPostApplyPage = 0;
return 1L;
}
return 0L;
}
//-------------------------------------------------------------------------
IMPL_LINK(ODbAdminDialog, OnApplyChanges, PushButton*, EMPTYARG)
{
const sal_uInt16 nOldPageId = GetCurPageId();
// get the view settings of the current page
SfxTabPage* pCurrentPage = GetTabPage(nOldPageId);
OPageSettings* pViewSettings = NULL;
if (pCurrentPage)
{
pViewSettings = static_cast<OGenericAdministrationPage *>(pCurrentPage)->createViewSettings();
static_cast<OGenericAdministrationPage *>(pCurrentPage)->fillViewSettings(pViewSettings);
}
// really apply the changes
implApplyChanges();
// select the old page, again (if possible)
const sal_uInt16 nNewPageId = GetCurPageId();
pCurrentPage = GetTabPage(nOldPageId);
if (pCurrentPage)
{
if (nNewPageId != nOldPageId)
ShowPage(nOldPageId);
static_cast<OGenericAdministrationPage *>(pCurrentPage)->restoreViewSettings(pViewSettings);
}
delete pViewSettings;
return 0L;
}
//.........................................................................
} // namespace dbaui
//.........................................................................
/*************************************************************************
* history:
* $Log: not supported by cvs2svn $
* Revision 1.64 2001/07/11 10:10:30 oj
* #87257# change GetUILanguage
*
* Revision 1.63 2001/07/06 11:33:29 oj
* #89359# now dialog saves password temp
*
* Revision 1.62 2001/06/25 16:04:40 fs
* #88004# outsourced ODataSourceMap and ODataSourceSelector / adjusted fillDatasourceInfo so that settings without and UI are do not survive the method
*
* Revision 1.61 2001/06/25 08:27:18 oj
* #88699# new control for ldap rowcount
*
* Revision 1.60 2001/06/20 13:43:42 fs
* #88447# corrected order of detail pages
*
* Revision 1.59 2001/06/20 07:08:33 oj
* #88434# new page for user admin
*
* Revision 1.58 2001/06/14 14:18:10 fs
* #88242# corrected adding/removing detail pages
*
* Revision 1.57 2001/06/07 15:12:36 fs
* #87934# removed a wrong assertion
*
* Revision 1.56 2001/06/01 08:41:31 oj
* #87149# changed order for tabpages
*
* Revision 1.55 2001/05/31 11:37:57 oj
* #87149# correct ldap protocol
*
* Revision 1.54 2001/05/31 11:09:07 oj
* #87149# change subprotocol and Propertynames
*
* Revision 1.53 2001/05/29 13:33:12 oj
* #87149# addressbook ui impl
*
* Revision 1.52 2001/05/29 10:18:26 fs
* #86082# set the service factory on the general page
*
* Revision 1.51 2001/05/23 14:16:42 oj
* #87149# new helpids
*
* Revision 1.50 2001/05/15 15:07:06 fs
* #86991# save the current (modified) settings when inserting a new data source
*
* Revision 1.49 2001/05/15 11:25:35 fs
* #86996# use the connection pool instead of the driver manager
*
* Revision 1.48 2001/05/10 13:37:04 fs
* #86223# restore view settings after applying (no matter if syncronously or asynchronously / +successfullyConnected to make the password persistent
*
* Revision 1.47 2001/04/27 15:47:03 fs
* resetPages: do a ShowPage(GENERAL) before removing pages
*
* Revision 1.46 2001/04/26 11:40:21 fs
* file is alive, again - added support for data source associated bookmarks
*
* Revision 1.45 2001/04/20 13:38:06 oj
* #85736# new checkbox for odbc
*
* Revision 1.44 2001/04/04 10:38:43 oj
* reading uninitialized memory
*
* Revision 1.43 2001/03/30 11:54:34 fs
* #65293# missing include
*
* Revision 1.42 2001/03/29 07:44:43 fs
* #84826# +clearPassword
*
* Revision 1.41 2001/03/29 07:34:00 oj
* dispose connection in dtor and type casts
*
* Revision 1.0 20.09.00 10:55:58 fs
************************************************************************/