1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svtools.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <stdio.h>
32*cdf0e10cSrcweir #include <svtools/addresstemplate.hxx>
33*cdf0e10cSrcweir #include "addresstemplate.hrc"
34*cdf0e10cSrcweir #include <svtools/svtools.hrc>
35*cdf0e10cSrcweir #include <svtools/helpid.hrc>
36*cdf0e10cSrcweir #include <svtools/svtdata.hxx>
37*cdf0e10cSrcweir #include <tools/debug.hxx>
38*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
39*cdf0e10cSrcweir #include <comphelper/stl_types.hxx>
40*cdf0e10cSrcweir #include <vcl/stdtext.hxx>
41*cdf0e10cSrcweir #include <vcl/waitobj.hxx>
42*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
43*cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx>
44*cdf0e10cSrcweir #include <comphelper/extract.hxx>
45*cdf0e10cSrcweir #include <comphelper/interaction.hxx>
46*cdf0e10cSrcweir #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/awt/XWindow.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/sdb/XCompletedConnection.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/sdb/SQLContext.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/sdbc/SQLWarning.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/sdbc/XConnection.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/task/XInteractionHandler.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
56*cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
57*cdf0e10cSrcweir #include <com/sun/star/sdb/CommandType.hpp>
58*cdf0e10cSrcweir #include <svtools/localresaccess.hxx>
59*cdf0e10cSrcweir #include "svl/filenotation.hxx"
60*cdf0e10cSrcweir #include <tools/urlobj.hxx>
61*cdf0e10cSrcweir #include <algorithm>
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir // .......................................................................
64*cdf0e10cSrcweir namespace svt
65*cdf0e10cSrcweir {
66*cdf0e10cSrcweir // .......................................................................
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir 	using namespace ::com::sun::star::uno;
69*cdf0e10cSrcweir 	using namespace ::com::sun::star::lang;
70*cdf0e10cSrcweir 	using namespace ::com::sun::star::container;
71*cdf0e10cSrcweir 	using namespace ::com::sun::star::ui::dialogs;
72*cdf0e10cSrcweir 	using namespace ::com::sun::star::util;
73*cdf0e10cSrcweir 	using namespace ::com::sun::star::beans;
74*cdf0e10cSrcweir 	using namespace ::com::sun::star::sdb;
75*cdf0e10cSrcweir 	using namespace ::com::sun::star::sdbc;
76*cdf0e10cSrcweir 	using namespace ::com::sun::star::sdbcx;
77*cdf0e10cSrcweir 	using namespace ::com::sun::star::task;
78*cdf0e10cSrcweir 	using namespace ::comphelper;
79*cdf0e10cSrcweir 	using namespace ::utl;
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir 	DECLARE_STL_VECTOR( String, StringArray );
82*cdf0e10cSrcweir 	DECLARE_STL_STDKEY_SET( ::rtl::OUString, StringBag );
83*cdf0e10cSrcweir 	DECLARE_STL_USTRINGACCESS_MAP( ::rtl::OUString, MapString2String );
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir     namespace
86*cdf0e10cSrcweir     {
87*cdf0e10cSrcweir         String lcl_getSelectedDataSource( const ComboBox& _dataSourceCombo )
88*cdf0e10cSrcweir         {
89*cdf0e10cSrcweir             String selectedDataSource = _dataSourceCombo.GetText();
90*cdf0e10cSrcweir             if ( _dataSourceCombo.GetEntryPos( selectedDataSource ) == LISTBOX_ENTRY_NOTFOUND )
91*cdf0e10cSrcweir             {
92*cdf0e10cSrcweir                 // none of the pre-selected entries -> assume a path to a database document
93*cdf0e10cSrcweir 	            OFileNotation aFileNotation( selectedDataSource, OFileNotation::N_SYSTEM );
94*cdf0e10cSrcweir 	            selectedDataSource = aFileNotation.get( OFileNotation::N_URL );
95*cdf0e10cSrcweir             }
96*cdf0e10cSrcweir             return selectedDataSource;
97*cdf0e10cSrcweir         }
98*cdf0e10cSrcweir     }
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir     // ===================================================================
101*cdf0e10cSrcweir 	// = IAssigmentData
102*cdf0e10cSrcweir 	// ===================================================================
103*cdf0e10cSrcweir 	class IAssigmentData
104*cdf0e10cSrcweir 	{
105*cdf0e10cSrcweir 	public:
106*cdf0e10cSrcweir 		virtual ~IAssigmentData();
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir 		/// the data source to use for the address book
109*cdf0e10cSrcweir 		virtual ::rtl::OUString getDatasourceName() const = 0;
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir 		/// the command to use for the address book
112*cdf0e10cSrcweir 		virtual ::rtl::OUString getCommand() const = 0;
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir 		/** the command type to use for the address book
115*cdf0e10cSrcweir 			@return
116*cdf0e10cSrcweir 				a <type scope="com.sun.star.sdb">CommandType</type> value
117*cdf0e10cSrcweir 		*/
118*cdf0e10cSrcweir 		virtual sal_Int32		getCommandType() const = 0;
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir 		/// checks whether or not there is an assignment for a given logical field
121*cdf0e10cSrcweir 		virtual sal_Bool		hasFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
122*cdf0e10cSrcweir 		/// retrieves the assignment for a given logical field
123*cdf0e10cSrcweir 		virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir 		/// set the assignment for a given logical field
126*cdf0e10cSrcweir 		virtual void			setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment) = 0;
127*cdf0e10cSrcweir 		/// clear the assignment for a given logical field
128*cdf0e10cSrcweir 		virtual void			clearFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir 		virtual void	setDatasourceName(const ::rtl::OUString& _rName) = 0;
131*cdf0e10cSrcweir 		virtual void	setCommand(const ::rtl::OUString& _rCommand) = 0;
132*cdf0e10cSrcweir 	};
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir 	// -------------------------------------------------------------------
135*cdf0e10cSrcweir 	IAssigmentData::~IAssigmentData()
136*cdf0e10cSrcweir 	{
137*cdf0e10cSrcweir 	}
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 	// ===================================================================
140*cdf0e10cSrcweir 	// = AssigmentTransientData
141*cdf0e10cSrcweir 	// ===================================================================
142*cdf0e10cSrcweir 	class AssigmentTransientData : public IAssigmentData
143*cdf0e10cSrcweir 	{
144*cdf0e10cSrcweir 	protected:
145*cdf0e10cSrcweir         Reference< XDataSource >    m_xDataSource;
146*cdf0e10cSrcweir 		::rtl::OUString			    m_sDSName;
147*cdf0e10cSrcweir 		::rtl::OUString			    m_sTableName;
148*cdf0e10cSrcweir 		MapString2String		    m_aAliases;
149*cdf0e10cSrcweir 
150*cdf0e10cSrcweir public:
151*cdf0e10cSrcweir 		AssigmentTransientData(
152*cdf0e10cSrcweir 			const Reference< XDataSource >& _rxDataSource,
153*cdf0e10cSrcweir 			const ::rtl::OUString& _rDataSourceName,
154*cdf0e10cSrcweir 			const ::rtl::OUString& _rTableName,
155*cdf0e10cSrcweir 			const Sequence< AliasProgrammaticPair >& _rFields
156*cdf0e10cSrcweir 		);
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir 		// IAssigmentData overridables
159*cdf0e10cSrcweir 		virtual ::rtl::OUString getDatasourceName() const;
160*cdf0e10cSrcweir 		virtual ::rtl::OUString getCommand() const;
161*cdf0e10cSrcweir 		virtual sal_Int32		getCommandType() const;
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir 		virtual sal_Bool		hasFieldAssignment(const ::rtl::OUString& _rLogicalName);
164*cdf0e10cSrcweir 		virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName);
165*cdf0e10cSrcweir 		virtual void			setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment);
166*cdf0e10cSrcweir 		virtual void			clearFieldAssignment(const ::rtl::OUString& _rLogicalName);
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir 		virtual void	setDatasourceName(const ::rtl::OUString& _rName);
169*cdf0e10cSrcweir 		virtual void	setCommand(const ::rtl::OUString& _rCommand);
170*cdf0e10cSrcweir 	};
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 	// -------------------------------------------------------------------
173*cdf0e10cSrcweir 	AssigmentTransientData::AssigmentTransientData( const Reference< XDataSource >& _rxDataSource,
174*cdf0e10cSrcweir 			const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rTableName,
175*cdf0e10cSrcweir             const Sequence< AliasProgrammaticPair >& _rFields )
176*cdf0e10cSrcweir 		:m_xDataSource( _rxDataSource )
177*cdf0e10cSrcweir         ,m_sDSName( _rDataSourceName )
178*cdf0e10cSrcweir         ,m_sTableName( _rTableName )
179*cdf0e10cSrcweir 	{
180*cdf0e10cSrcweir         // fill our aliaes structure
181*cdf0e10cSrcweir 		// first collect all known programmatic names
182*cdf0e10cSrcweir 		StringBag aKnownNames;
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir 		String sLogicalFieldNames( SvtResId( STR_LOCAGICAL_FIELD_NAMES ) );
185*cdf0e10cSrcweir 		sal_Int32 nTokenCount = sLogicalFieldNames.GetTokenCount(';');
186*cdf0e10cSrcweir 		for (sal_Int32 i = 0; i<nTokenCount; ++i)
187*cdf0e10cSrcweir 			aKnownNames.insert(sLogicalFieldNames.GetToken((sal_uInt16)i, ';'));
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir 		// loop throuzh the given names
190*cdf0e10cSrcweir 		const AliasProgrammaticPair* pFields = _rFields.getConstArray();
191*cdf0e10cSrcweir 		for (;pFields != pFields; ++pFields)
192*cdf0e10cSrcweir 		{
193*cdf0e10cSrcweir 			StringBagIterator aKnownPos = aKnownNames.find( pFields->ProgrammaticName );
194*cdf0e10cSrcweir 			if ( aKnownNames.end() != aKnownPos )
195*cdf0e10cSrcweir 			{
196*cdf0e10cSrcweir 				m_aAliases[ pFields->ProgrammaticName ] = pFields->Alias;
197*cdf0e10cSrcweir 			}
198*cdf0e10cSrcweir 			else
199*cdf0e10cSrcweir 			{
200*cdf0e10cSrcweir 				DBG_ERROR	(	(	::rtl::OString("AssigmentTransientData::AssigmentTransientData: unknown programmatic name (")
201*cdf0e10cSrcweir 								+=	::rtl::OString(pFields->ProgrammaticName.getStr(), pFields->ProgrammaticName.getLength(), RTL_TEXTENCODING_ASCII_US)
202*cdf0e10cSrcweir 								+=	::rtl::OString(")!")
203*cdf0e10cSrcweir 								).getStr()
204*cdf0e10cSrcweir 							);
205*cdf0e10cSrcweir 			}
206*cdf0e10cSrcweir 		}
207*cdf0e10cSrcweir 	}
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir 	// -------------------------------------------------------------------
210*cdf0e10cSrcweir 	::rtl::OUString AssigmentTransientData::getDatasourceName() const
211*cdf0e10cSrcweir 	{
212*cdf0e10cSrcweir 		return m_sDSName;
213*cdf0e10cSrcweir 	}
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir 	// -------------------------------------------------------------------
216*cdf0e10cSrcweir 	::rtl::OUString AssigmentTransientData::getCommand() const
217*cdf0e10cSrcweir 	{
218*cdf0e10cSrcweir 		return m_sTableName;
219*cdf0e10cSrcweir 	}
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir 	// -------------------------------------------------------------------
222*cdf0e10cSrcweir 	sal_Int32 AssigmentTransientData::getCommandType() const
223*cdf0e10cSrcweir 	{
224*cdf0e10cSrcweir 		return CommandType::TABLE;
225*cdf0e10cSrcweir 	}
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir 	// -------------------------------------------------------------------
228*cdf0e10cSrcweir 	sal_Bool AssigmentTransientData::hasFieldAssignment(const ::rtl::OUString& _rLogicalName)
229*cdf0e10cSrcweir 	{
230*cdf0e10cSrcweir 		ConstMapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
231*cdf0e10cSrcweir 		return	( m_aAliases.end() != aPos )
232*cdf0e10cSrcweir 			&&	( aPos->second.getLength() );
233*cdf0e10cSrcweir 	}
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir 	// -------------------------------------------------------------------
236*cdf0e10cSrcweir 	::rtl::OUString AssigmentTransientData::getFieldAssignment(const ::rtl::OUString& _rLogicalName)
237*cdf0e10cSrcweir 	{
238*cdf0e10cSrcweir 		::rtl::OUString sReturn;
239*cdf0e10cSrcweir 		ConstMapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
240*cdf0e10cSrcweir 		if ( m_aAliases.end() != aPos )
241*cdf0e10cSrcweir 			sReturn = aPos->second;
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir 		return sReturn;
244*cdf0e10cSrcweir 	}
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir 	// -------------------------------------------------------------------
247*cdf0e10cSrcweir 	void AssigmentTransientData::setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment)
248*cdf0e10cSrcweir 	{
249*cdf0e10cSrcweir 		m_aAliases[ _rLogicalName ] = _rAssignment;
250*cdf0e10cSrcweir 	}
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir 	// -------------------------------------------------------------------
253*cdf0e10cSrcweir 	void AssigmentTransientData::clearFieldAssignment(const ::rtl::OUString& _rLogicalName)
254*cdf0e10cSrcweir 	{
255*cdf0e10cSrcweir 		MapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
256*cdf0e10cSrcweir 		if ( m_aAliases.end() != aPos )
257*cdf0e10cSrcweir 			m_aAliases.erase( aPos );
258*cdf0e10cSrcweir 	}
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir 	// -------------------------------------------------------------------
261*cdf0e10cSrcweir 	void AssigmentTransientData::setDatasourceName(const ::rtl::OUString&)
262*cdf0e10cSrcweir 	{
263*cdf0e10cSrcweir         DBG_ERROR( "AssigmentTransientData::setDatasourceName: cannot be implemented for transient data!" );
264*cdf0e10cSrcweir 	}
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir 	// -------------------------------------------------------------------
267*cdf0e10cSrcweir 	void AssigmentTransientData::setCommand(const ::rtl::OUString&)
268*cdf0e10cSrcweir 	{
269*cdf0e10cSrcweir         DBG_ERROR( "AssigmentTransientData::setCommand: cannot be implemented for transient data!" );
270*cdf0e10cSrcweir 	}
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir 	// ===================================================================
273*cdf0e10cSrcweir 	// = AssignmentPersistentData
274*cdf0e10cSrcweir 	// ===================================================================
275*cdf0e10cSrcweir 	class AssignmentPersistentData
276*cdf0e10cSrcweir 			:public ::utl::ConfigItem
277*cdf0e10cSrcweir 			,public IAssigmentData
278*cdf0e10cSrcweir 	{
279*cdf0e10cSrcweir 	protected:
280*cdf0e10cSrcweir 		StringBag		m_aStoredFields;
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir 	protected:
283*cdf0e10cSrcweir 		::com::sun::star::uno::Any
284*cdf0e10cSrcweir 						getProperty(const ::rtl::OUString& _rLocalName) const;
285*cdf0e10cSrcweir 		::com::sun::star::uno::Any
286*cdf0e10cSrcweir 						getProperty(const sal_Char* _pLocalName) const;
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir 		::rtl::OUString	getStringProperty(const sal_Char* _pLocalName) const;
289*cdf0e10cSrcweir 		sal_Int32		getInt32Property(const sal_Char* _pLocalName) const;
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir 		::rtl::OUString	getStringProperty(const ::rtl::OUString& _rLocalName) const;
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 		void			setStringProperty(const sal_Char* _pLocalName, const ::rtl::OUString& _rValue);
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir 	public:
296*cdf0e10cSrcweir 		AssignmentPersistentData();
297*cdf0e10cSrcweir 		~AssignmentPersistentData();
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir 		// IAssigmentData overridables
300*cdf0e10cSrcweir 		virtual ::rtl::OUString getDatasourceName() const;
301*cdf0e10cSrcweir 		virtual ::rtl::OUString getCommand() const;
302*cdf0e10cSrcweir 		virtual sal_Int32		getCommandType() const;
303*cdf0e10cSrcweir 
304*cdf0e10cSrcweir 		virtual sal_Bool		hasFieldAssignment(const ::rtl::OUString& _rLogicalName);
305*cdf0e10cSrcweir 		virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName);
306*cdf0e10cSrcweir 		virtual void			setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment);
307*cdf0e10cSrcweir 		virtual void			clearFieldAssignment(const ::rtl::OUString& _rLogicalName);
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir 		virtual void	setDatasourceName(const ::rtl::OUString& _rName);
310*cdf0e10cSrcweir 		virtual void	setCommand(const ::rtl::OUString& _rCommand);
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir         virtual void    Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames);
313*cdf0e10cSrcweir 		virtual void	Commit();
314*cdf0e10cSrcweir 	};
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir void AssignmentPersistentData::Notify( const com::sun::star::uno::Sequence<rtl::OUString>& )
318*cdf0e10cSrcweir {
319*cdf0e10cSrcweir }
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir void AssignmentPersistentData::Commit()
322*cdf0e10cSrcweir {
323*cdf0e10cSrcweir }
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir 	// -------------------------------------------------------------------
326*cdf0e10cSrcweir 	AssignmentPersistentData::AssignmentPersistentData()
327*cdf0e10cSrcweir 		:ConfigItem( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.DataAccess/AddressBook" )))
328*cdf0e10cSrcweir 	{
329*cdf0e10cSrcweir 		Sequence< ::rtl::OUString > aStoredNames = GetNodeNames(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Fields")));
330*cdf0e10cSrcweir 		const ::rtl::OUString* pStoredNames = aStoredNames.getConstArray();
331*cdf0e10cSrcweir 		for (sal_Int32 i=0; i<aStoredNames.getLength(); ++i, ++pStoredNames)
332*cdf0e10cSrcweir 			m_aStoredFields.insert(*pStoredNames);
333*cdf0e10cSrcweir 	}
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir 	// -------------------------------------------------------------------
336*cdf0e10cSrcweir 	AssignmentPersistentData::~AssignmentPersistentData()
337*cdf0e10cSrcweir 	{
338*cdf0e10cSrcweir 	}
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir 	// -------------------------------------------------------------------
341*cdf0e10cSrcweir 	sal_Bool AssignmentPersistentData::hasFieldAssignment(const ::rtl::OUString& _rLogicalName)
342*cdf0e10cSrcweir 	{
343*cdf0e10cSrcweir 		return (m_aStoredFields.end() != m_aStoredFields.find(_rLogicalName));
344*cdf0e10cSrcweir 	}
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir 	// -------------------------------------------------------------------
347*cdf0e10cSrcweir 	::rtl::OUString AssignmentPersistentData::getFieldAssignment(const ::rtl::OUString& _rLogicalName)
348*cdf0e10cSrcweir 	{
349*cdf0e10cSrcweir 		::rtl::OUString sAssignment;
350*cdf0e10cSrcweir 		if (hasFieldAssignment(_rLogicalName))
351*cdf0e10cSrcweir 		{
352*cdf0e10cSrcweir 			::rtl::OUString sFieldPath(RTL_CONSTASCII_USTRINGPARAM("Fields/"));
353*cdf0e10cSrcweir 			sFieldPath += _rLogicalName;
354*cdf0e10cSrcweir 			sFieldPath += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
355*cdf0e10cSrcweir 			sAssignment = getStringProperty(sFieldPath);
356*cdf0e10cSrcweir 		}
357*cdf0e10cSrcweir 		return sAssignment;
358*cdf0e10cSrcweir 	}
359*cdf0e10cSrcweir 
360*cdf0e10cSrcweir 	// -------------------------------------------------------------------
361*cdf0e10cSrcweir 	Any AssignmentPersistentData::getProperty(const sal_Char* _pLocalName) const
362*cdf0e10cSrcweir 	{
363*cdf0e10cSrcweir 		return getProperty(::rtl::OUString::createFromAscii(_pLocalName));
364*cdf0e10cSrcweir 	}
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir 	// -------------------------------------------------------------------
367*cdf0e10cSrcweir 	Any AssignmentPersistentData::getProperty(const ::rtl::OUString& _rLocalName) const
368*cdf0e10cSrcweir 	{
369*cdf0e10cSrcweir 		Sequence< ::rtl::OUString > aProperties(&_rLocalName, 1);
370*cdf0e10cSrcweir 		Sequence< Any > aValues = const_cast<AssignmentPersistentData*>(this)->GetProperties(aProperties);
371*cdf0e10cSrcweir 		DBG_ASSERT(aValues.getLength() == 1, "AssignmentPersistentData::getProperty: invalid sequence length!");
372*cdf0e10cSrcweir 		return aValues[0];
373*cdf0e10cSrcweir 	}
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir 	// -------------------------------------------------------------------
376*cdf0e10cSrcweir 	::rtl::OUString	AssignmentPersistentData::getStringProperty(const ::rtl::OUString& _rLocalName) const
377*cdf0e10cSrcweir 	{
378*cdf0e10cSrcweir 		::rtl::OUString sReturn;
379*cdf0e10cSrcweir 		getProperty( _rLocalName ) >>= sReturn;
380*cdf0e10cSrcweir 		return sReturn;
381*cdf0e10cSrcweir 	}
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir 	// -------------------------------------------------------------------
384*cdf0e10cSrcweir 	::rtl::OUString	AssignmentPersistentData::getStringProperty(const sal_Char* _pLocalName) const
385*cdf0e10cSrcweir 	{
386*cdf0e10cSrcweir 		::rtl::OUString sReturn;
387*cdf0e10cSrcweir 		getProperty( _pLocalName ) >>= sReturn;
388*cdf0e10cSrcweir 		return sReturn;
389*cdf0e10cSrcweir 	}
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir 	// -------------------------------------------------------------------
392*cdf0e10cSrcweir 	sal_Int32 AssignmentPersistentData::getInt32Property(const sal_Char* _pLocalName) const
393*cdf0e10cSrcweir 	{
394*cdf0e10cSrcweir 		sal_Int32 nReturn = 0;
395*cdf0e10cSrcweir 		getProperty( _pLocalName ) >>= nReturn;
396*cdf0e10cSrcweir 		return nReturn;
397*cdf0e10cSrcweir 	}
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir 	// -------------------------------------------------------------------
400*cdf0e10cSrcweir 	void AssignmentPersistentData::setStringProperty(const sal_Char* _pLocalName, const ::rtl::OUString& _rValue)
401*cdf0e10cSrcweir 	{
402*cdf0e10cSrcweir 		Sequence< ::rtl::OUString > aNames(1);
403*cdf0e10cSrcweir 		Sequence< Any > aValues(1);
404*cdf0e10cSrcweir 		aNames[0] = ::rtl::OUString::createFromAscii(_pLocalName);
405*cdf0e10cSrcweir 		aValues[0] <<= _rValue;
406*cdf0e10cSrcweir 		PutProperties(aNames, aValues);
407*cdf0e10cSrcweir 	}
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir 	// -------------------------------------------------------------------
410*cdf0e10cSrcweir 	void AssignmentPersistentData::setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment)
411*cdf0e10cSrcweir 	{
412*cdf0e10cSrcweir 		if (!_rAssignment.getLength())
413*cdf0e10cSrcweir 		{
414*cdf0e10cSrcweir 			if (hasFieldAssignment(_rLogicalName))
415*cdf0e10cSrcweir 				// the assignment exists but it should be reset
416*cdf0e10cSrcweir 				clearFieldAssignment(_rLogicalName);
417*cdf0e10cSrcweir 				return;
418*cdf0e10cSrcweir 		}
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir 		// Fields
421*cdf0e10cSrcweir 		::rtl::OUString sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir 		// Fields/<field>
424*cdf0e10cSrcweir 		::rtl::OUString sFieldElementNodePath(sDescriptionNodePath);
425*cdf0e10cSrcweir 		sFieldElementNodePath += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
426*cdf0e10cSrcweir 		sFieldElementNodePath += _rLogicalName;
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir 		Sequence< PropertyValue > aNewFieldDescription(2);
429*cdf0e10cSrcweir 		// Fields/<field>/ProgrammaticFieldName
430*cdf0e10cSrcweir 		aNewFieldDescription[0].Name = sFieldElementNodePath;
431*cdf0e10cSrcweir 		aNewFieldDescription[0].Name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/ProgrammaticFieldName"));
432*cdf0e10cSrcweir 		aNewFieldDescription[0].Value <<= _rLogicalName;
433*cdf0e10cSrcweir 		// Fields/<field>/AssignedFieldName
434*cdf0e10cSrcweir 		aNewFieldDescription[1].Name = sFieldElementNodePath;
435*cdf0e10cSrcweir 		aNewFieldDescription[1].Name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
436*cdf0e10cSrcweir 		aNewFieldDescription[1].Value <<= _rAssignment;
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir 		// just set the new value
439*cdf0e10cSrcweir #ifdef DBG_UTIL
440*cdf0e10cSrcweir 		sal_Bool bSuccess =
441*cdf0e10cSrcweir #endif
442*cdf0e10cSrcweir 		SetSetProperties(sDescriptionNodePath, aNewFieldDescription);
443*cdf0e10cSrcweir 		DBG_ASSERT(bSuccess, "AssignmentPersistentData::setFieldAssignment: could not commit the changes a field!");
444*cdf0e10cSrcweir 	}
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir 	// -------------------------------------------------------------------
447*cdf0e10cSrcweir 	void AssignmentPersistentData::clearFieldAssignment(const ::rtl::OUString& _rLogicalName)
448*cdf0e10cSrcweir 	{
449*cdf0e10cSrcweir 		if (!hasFieldAssignment(_rLogicalName))
450*cdf0e10cSrcweir 			// nothing to do
451*cdf0e10cSrcweir 			return;
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir 		::rtl::OUString sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));
454*cdf0e10cSrcweir 		Sequence< ::rtl::OUString > aNames(&_rLogicalName, 1);
455*cdf0e10cSrcweir 		ClearNodeElements(sDescriptionNodePath, aNames);
456*cdf0e10cSrcweir 	}
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir 	// -------------------------------------------------------------------
459*cdf0e10cSrcweir 	::rtl::OUString AssignmentPersistentData::getDatasourceName() const
460*cdf0e10cSrcweir 	{
461*cdf0e10cSrcweir 		return getStringProperty( "DataSourceName" );
462*cdf0e10cSrcweir 	}
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir 	// -------------------------------------------------------------------
465*cdf0e10cSrcweir 	::rtl::OUString AssignmentPersistentData::getCommand() const
466*cdf0e10cSrcweir 	{
467*cdf0e10cSrcweir 		return getStringProperty( "Command" );
468*cdf0e10cSrcweir 	}
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir 	// -------------------------------------------------------------------
471*cdf0e10cSrcweir 	void AssignmentPersistentData::setDatasourceName(const ::rtl::OUString& _rName)
472*cdf0e10cSrcweir 	{
473*cdf0e10cSrcweir 		setStringProperty( "DataSourceName", _rName );
474*cdf0e10cSrcweir 	}
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir 	// -------------------------------------------------------------------
477*cdf0e10cSrcweir 	void AssignmentPersistentData::setCommand(const ::rtl::OUString& _rCommand)
478*cdf0e10cSrcweir 	{
479*cdf0e10cSrcweir 		setStringProperty( "Command", _rCommand );
480*cdf0e10cSrcweir 	}
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir 	// -------------------------------------------------------------------
483*cdf0e10cSrcweir 	sal_Int32 AssignmentPersistentData::getCommandType() const
484*cdf0e10cSrcweir 	{
485*cdf0e10cSrcweir 		return getInt32Property( "CommandType" );
486*cdf0e10cSrcweir 	}
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir 	// ===================================================================
489*cdf0e10cSrcweir 	// = AddressBookSourceDialogData
490*cdf0e10cSrcweir 	// ===================================================================
491*cdf0e10cSrcweir 	struct AddressBookSourceDialogData
492*cdf0e10cSrcweir 	{
493*cdf0e10cSrcweir 		FixedText*		pFieldLabels[FIELD_PAIRS_VISIBLE * 2];
494*cdf0e10cSrcweir 		ListBox*		pFields[FIELD_PAIRS_VISIBLE * 2];
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir         /// when working transient, we need the data source
497*cdf0e10cSrcweir         Reference< XDataSource >
498*cdf0e10cSrcweir                         m_xTransientDataSource;
499*cdf0e10cSrcweir 		/// current scroll pos in the field list
500*cdf0e10cSrcweir 		sal_Int32		nFieldScrollPos;
501*cdf0e10cSrcweir 		/// the index within m_pFields of the last visible list box. This is redundant, it could be extracted from other members
502*cdf0e10cSrcweir 		sal_Int32		nLastVisibleListIndex;
503*cdf0e10cSrcweir 		/// indicates that we've an odd field number. This member is for efficiency only, it's redundant.
504*cdf0e10cSrcweir 		sal_Bool		bOddFieldNumber : 1;
505*cdf0e10cSrcweir 		/// indicates that we're working with the real persistent configuration
506*cdf0e10cSrcweir 		sal_Bool		bWorkingPersistent : 1;
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir 		/// the strings to use as labels for the field selection listboxes
509*cdf0e10cSrcweir 		StringArray		aFieldLabels;
510*cdf0e10cSrcweir 		// the current field assignment
511*cdf0e10cSrcweir 		StringArray		aFieldAssignments;
512*cdf0e10cSrcweir 		/// the logical field names
513*cdf0e10cSrcweir 		StringArray		aLogicalFieldNames;
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir 		IAssigmentData*	pConfigData;
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir 		// ................................................................
518*cdf0e10cSrcweir 		AddressBookSourceDialogData( )
519*cdf0e10cSrcweir 			:nFieldScrollPos(0)
520*cdf0e10cSrcweir 			,nLastVisibleListIndex(0)
521*cdf0e10cSrcweir 			,bOddFieldNumber(sal_False)
522*cdf0e10cSrcweir 			,bWorkingPersistent( sal_True )
523*cdf0e10cSrcweir 			,pConfigData( new AssignmentPersistentData )
524*cdf0e10cSrcweir 		{
525*cdf0e10cSrcweir 		}
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir 		// ................................................................
528*cdf0e10cSrcweir 		AddressBookSourceDialogData( const Reference< XDataSource >& _rxTransientDS, const ::rtl::OUString& _rDataSourceName,
529*cdf0e10cSrcweir             const ::rtl::OUString& _rTableName, const Sequence< AliasProgrammaticPair >& _rFields )
530*cdf0e10cSrcweir 			:m_xTransientDataSource( _rxTransientDS )
531*cdf0e10cSrcweir             ,nFieldScrollPos(0)
532*cdf0e10cSrcweir 			,nLastVisibleListIndex(0)
533*cdf0e10cSrcweir 			,bOddFieldNumber(sal_False)
534*cdf0e10cSrcweir 			,bWorkingPersistent( sal_False )
535*cdf0e10cSrcweir 			,pConfigData( new AssigmentTransientData( m_xTransientDataSource, _rDataSourceName, _rTableName, _rFields ) )
536*cdf0e10cSrcweir 		{
537*cdf0e10cSrcweir 		}
538*cdf0e10cSrcweir 
539*cdf0e10cSrcweir 		~AddressBookSourceDialogData()
540*cdf0e10cSrcweir 		{
541*cdf0e10cSrcweir 			delete pConfigData;
542*cdf0e10cSrcweir 		}
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir 	};
545*cdf0e10cSrcweir 
546*cdf0e10cSrcweir 	// ===================================================================
547*cdf0e10cSrcweir 	// = AddressBookSourceDialog
548*cdf0e10cSrcweir 	// ===================================================================
549*cdf0e10cSrcweir #define INIT_FIELDS()	\
550*cdf0e10cSrcweir 		 ModalDialog(_pParent, SvtResId( DLG_ADDRESSBOOKSOURCE ))\
551*cdf0e10cSrcweir 		,m_aDatasourceFrame			(this, SvtResId(FL_DATASOURCEFRAME))\
552*cdf0e10cSrcweir 		,m_aDatasourceLabel			(this, SvtResId(FT_DATASOURCE))\
553*cdf0e10cSrcweir 		,m_aDatasource				(this, SvtResId(CB_DATASOURCE))\
554*cdf0e10cSrcweir 		,m_aAdministrateDatasources	(this, SvtResId(PB_ADMINISTATE_DATASOURCES))\
555*cdf0e10cSrcweir 		,m_aTableLabel				(this, SvtResId(FT_TABLE))\
556*cdf0e10cSrcweir 		,m_aTable					(this, SvtResId(CB_TABLE))\
557*cdf0e10cSrcweir 		,m_aFieldsTitle				(this, SvtResId(FT_FIELDS))\
558*cdf0e10cSrcweir 		,m_aFieldsFrame				(this, SvtResId(CT_BORDER))\
559*cdf0e10cSrcweir 		,m_aFieldScroller			(&m_aFieldsFrame, SvtResId(SB_FIELDSCROLLER))\
560*cdf0e10cSrcweir 		,m_aOK						(this, SvtResId(PB_OK))\
561*cdf0e10cSrcweir 		,m_aCancel					(this, SvtResId(PB_CANCEL))\
562*cdf0e10cSrcweir 		,m_aHelp					(this, SvtResId(PB_HELP))\
563*cdf0e10cSrcweir 		,m_sNoFieldSelection(SvtResId(STR_NO_FIELD_SELECTION))\
564*cdf0e10cSrcweir 		,m_xORB(_rxORB)
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir 	// -------------------------------------------------------------------
567*cdf0e10cSrcweir 	AddressBookSourceDialog::AddressBookSourceDialog(Window* _pParent,
568*cdf0e10cSrcweir 			const Reference< XMultiServiceFactory >& _rxORB )
569*cdf0e10cSrcweir 		:INIT_FIELDS()
570*cdf0e10cSrcweir 		,m_pImpl( new AddressBookSourceDialogData )
571*cdf0e10cSrcweir 	{
572*cdf0e10cSrcweir 		implConstruct();
573*cdf0e10cSrcweir 	}
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir 	// -------------------------------------------------------------------
576*cdf0e10cSrcweir 	AddressBookSourceDialog::AddressBookSourceDialog( Window* _pParent, const Reference< XMultiServiceFactory >& _rxORB,
577*cdf0e10cSrcweir 		const Reference< XDataSource >& _rxTransientDS, const ::rtl::OUString& _rDataSourceName,
578*cdf0e10cSrcweir         const ::rtl::OUString& _rTable, const Sequence< AliasProgrammaticPair >& _rMapping )
579*cdf0e10cSrcweir 		:INIT_FIELDS()
580*cdf0e10cSrcweir 		,m_pImpl( new AddressBookSourceDialogData( _rxTransientDS, _rDataSourceName, _rTable, _rMapping ) )
581*cdf0e10cSrcweir 	{
582*cdf0e10cSrcweir 		implConstruct();
583*cdf0e10cSrcweir 	}
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir 	// -------------------------------------------------------------------
586*cdf0e10cSrcweir 	void AddressBookSourceDialog::implConstruct()
587*cdf0e10cSrcweir 	{
588*cdf0e10cSrcweir 		for (sal_Int32 row=0; row<FIELD_PAIRS_VISIBLE; ++row)
589*cdf0e10cSrcweir 		{
590*cdf0e10cSrcweir 			for (sal_Int32 column=0; column<2; ++column)
591*cdf0e10cSrcweir 			{
592*cdf0e10cSrcweir 				// the label
593*cdf0e10cSrcweir 				m_pImpl->pFieldLabels[row * 2 + column] = new FixedText(&m_aFieldsFrame, SvtResId((sal_uInt16)(FT_FIELD_BASE + row * 2 + column)));
594*cdf0e10cSrcweir 				// the listbox
595*cdf0e10cSrcweir 				m_pImpl->pFields[row * 2 + column] = new ListBox(&m_aFieldsFrame, SvtResId((sal_uInt16)(LB_FIELD_BASE + row * 2 + column)));
596*cdf0e10cSrcweir 				m_pImpl->pFields[row * 2 + column]->SetDropDownLineCount(15);
597*cdf0e10cSrcweir 				m_pImpl->pFields[row * 2 + column]->SetSelectHdl(LINK(this, AddressBookSourceDialog, OnFieldSelect));
598*cdf0e10cSrcweir 
599*cdf0e10cSrcweir 				m_pImpl->pFields[row * 2 + column]->SetHelpId(HID_ADDRTEMPL_FIELD_ASSIGNMENT);
600*cdf0e10cSrcweir 			}
601*cdf0e10cSrcweir 		}
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir 		m_aFieldsFrame.SetStyle((m_aFieldsFrame.GetStyle() | WB_TABSTOP | WB_DIALOGCONTROL) & ~WB_NODIALOGCONTROL);
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir 		// correct the z-order
606*cdf0e10cSrcweir 		m_aFieldScroller.SetZOrder(m_pImpl->pFields[FIELD_CONTROLS_VISIBLE - 1], WINDOW_ZORDER_BEHIND);
607*cdf0e10cSrcweir 		m_aOK.SetZOrder(&m_aFieldsFrame, WINDOW_ZORDER_BEHIND);
608*cdf0e10cSrcweir 		m_aCancel.SetZOrder(&m_aOK, WINDOW_ZORDER_BEHIND);
609*cdf0e10cSrcweir 
610*cdf0e10cSrcweir 		initializeDatasources();
611*cdf0e10cSrcweir 
612*cdf0e10cSrcweir 		// for the moment, we have a hard coded list of all known fields.
613*cdf0e10cSrcweir 		// A better solution would be to store all known field translations in the configuration, which could be
614*cdf0e10cSrcweir 		// extensible by the user in an arbitrary way.
615*cdf0e10cSrcweir 		// But for the moment we need a quick solution ...
616*cdf0e10cSrcweir 		// (the main thing would be to store the translations to use here in the user interface, besides that, the code
617*cdf0e10cSrcweir 		// should be adjustable with a rather small effort.)
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir 		// initialize the strings for the field labels
620*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_FIRSTNAME )) );
621*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_LASTNAME )) );
622*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_COMPANY)) );
623*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_DEPARTMENT )) );
624*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_STREET )) );
625*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_ZIPCODE )) );
626*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_CITY )) );
627*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_STATE)) );
628*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_COUNTRY )) );
629*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_HOMETEL )) );
630*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_WORKTEL )) );
631*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_OFFICETEL)) );
632*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_MOBILE)) );
633*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_TELOTHER)) );
634*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_PAGER)) );
635*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_FAX )) );
636*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_EMAIL )) );
637*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_URL )) );
638*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_TITLE )) );
639*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_POSITION )) );
640*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_INITIALS )) );
641*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_ADDRFORM )) );
642*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_SALUTATION )) );
643*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_ID)) );
644*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_CALENDAR)) );
645*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_INVITE)) );
646*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_NOTE)) );
647*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER1)) );
648*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER2)) );
649*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER3)) );
650*cdf0e10cSrcweir 		m_pImpl->aFieldLabels.push_back( String(SvtResId( STR_FIELD_USER4)) );
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir 		// force a even number of known fields
653*cdf0e10cSrcweir 		m_pImpl->bOddFieldNumber = (m_pImpl->aFieldLabels.size() % 2) != 0;
654*cdf0e10cSrcweir 		if (m_pImpl->bOddFieldNumber)
655*cdf0e10cSrcweir 			m_pImpl->aFieldLabels.push_back( String() );
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir 		// limit the scrollbar range accordingly
658*cdf0e10cSrcweir 		sal_Int32 nOverallFieldPairs = m_pImpl->aFieldLabels.size() / 2;
659*cdf0e10cSrcweir 		m_aFieldScroller.SetRange( Range(0, nOverallFieldPairs - FIELD_PAIRS_VISIBLE) );
660*cdf0e10cSrcweir 		m_aFieldScroller.SetLineSize(1);
661*cdf0e10cSrcweir 		m_aFieldScroller.SetPageSize(FIELD_PAIRS_VISIBLE);
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir 		// reset the current field assignments
664*cdf0e10cSrcweir 		m_pImpl->aFieldAssignments.resize(m_pImpl->aFieldLabels.size());
665*cdf0e10cSrcweir 			// (empty strings mean "no assignment")
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir 		// some knittings
668*cdf0e10cSrcweir 		m_aFieldScroller.SetScrollHdl(LINK(this, AddressBookSourceDialog, OnFieldScroll));
669*cdf0e10cSrcweir 		m_aAdministrateDatasources.SetClickHdl(LINK(this, AddressBookSourceDialog, OnAdministrateDatasources));
670*cdf0e10cSrcweir 		m_aDatasource.EnableAutocomplete(sal_True);
671*cdf0e10cSrcweir 		m_aTable.EnableAutocomplete(sal_True);
672*cdf0e10cSrcweir 		m_aTable.SetGetFocusHdl(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
673*cdf0e10cSrcweir 		m_aDatasource.SetGetFocusHdl(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
674*cdf0e10cSrcweir 		m_aTable.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
675*cdf0e10cSrcweir 		m_aDatasource.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
676*cdf0e10cSrcweir 		m_aTable.SetSelectHdl(LINK(this, AddressBookSourceDialog, OnComboSelect));
677*cdf0e10cSrcweir 		m_aDatasource.SetSelectHdl(LINK(this, AddressBookSourceDialog, OnComboSelect));
678*cdf0e10cSrcweir 		m_aOK.SetClickHdl(LINK(this, AddressBookSourceDialog, OnOkClicked));
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir 		m_aDatasource.SetDropDownLineCount(15);
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir 		// initialize the field controls
683*cdf0e10cSrcweir 		resetFields();
684*cdf0e10cSrcweir 		m_aFieldScroller.SetThumbPos(0);
685*cdf0e10cSrcweir 		m_pImpl->nFieldScrollPos = -1;
686*cdf0e10cSrcweir 		implScrollFields(0, sal_False, sal_False);
687*cdf0e10cSrcweir 
688*cdf0e10cSrcweir 		// the logical names
689*cdf0e10cSrcweir 		String sLogicalFieldNames(SvtResId(STR_LOCAGICAL_FIELD_NAMES));
690*cdf0e10cSrcweir 		sal_Int32 nAdjustedTokenCount = sLogicalFieldNames.GetTokenCount(';') + (m_pImpl->bOddFieldNumber ? 1 : 0);
691*cdf0e10cSrcweir 		DBG_ASSERT(nAdjustedTokenCount == (sal_Int32)m_pImpl->aFieldLabels.size(),
692*cdf0e10cSrcweir 			"AddressBookSourceDialog::AddressBookSourceDialog: inconsistence between logical and UI field names!");
693*cdf0e10cSrcweir 		m_pImpl->aLogicalFieldNames.reserve(nAdjustedTokenCount);
694*cdf0e10cSrcweir 		for (sal_Int32 i = 0; i<nAdjustedTokenCount; ++i)
695*cdf0e10cSrcweir 			m_pImpl->aLogicalFieldNames.push_back(sLogicalFieldNames.GetToken((sal_uInt16)i, ';'));
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir 		PostUserEvent(LINK(this, AddressBookSourceDialog, OnDelayedInitialize));
698*cdf0e10cSrcweir 			// so the dialog will at least show up before we do the loading of the
699*cdf0e10cSrcweir 			// configuration data and the (maybe time consuming) analysis of the data source/table to select
700*cdf0e10cSrcweir 
701*cdf0e10cSrcweir 		FreeResource();
702*cdf0e10cSrcweir 
703*cdf0e10cSrcweir 		if ( !m_pImpl->bWorkingPersistent )
704*cdf0e10cSrcweir 		{
705*cdf0e10cSrcweir 			StyleSettings aSystemStyle = GetSettings().GetStyleSettings();
706*cdf0e10cSrcweir 			const Color& rNewColor = aSystemStyle.GetDialogColor();
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir 			m_aDatasource.SetReadOnly( sal_True );
709*cdf0e10cSrcweir 			m_aDatasource.SetBackground( Wallpaper( rNewColor ) );
710*cdf0e10cSrcweir 			m_aDatasource.SetControlBackground( rNewColor );
711*cdf0e10cSrcweir 
712*cdf0e10cSrcweir 			m_aTable.SetReadOnly( sal_True );
713*cdf0e10cSrcweir 			m_aTable.SetBackground( Wallpaper( rNewColor ) );
714*cdf0e10cSrcweir 			m_aTable.SetControlBackground( rNewColor );
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir 			m_aAdministrateDatasources.Hide( );
717*cdf0e10cSrcweir 		}
718*cdf0e10cSrcweir 	}
719*cdf0e10cSrcweir 
720*cdf0e10cSrcweir 	// -------------------------------------------------------------------
721*cdf0e10cSrcweir 	void AddressBookSourceDialog::getFieldMapping(Sequence< AliasProgrammaticPair >& _rMapping) const
722*cdf0e10cSrcweir 	{
723*cdf0e10cSrcweir 		_rMapping.realloc( m_pImpl->aLogicalFieldNames.size() );
724*cdf0e10cSrcweir 		AliasProgrammaticPair* pPair = _rMapping.getArray();
725*cdf0e10cSrcweir 
726*cdf0e10cSrcweir 		::rtl::OUString sCurrent;
727*cdf0e10cSrcweir 		for	(	ConstStringArrayIterator aProgrammatic = m_pImpl->aLogicalFieldNames.begin();
728*cdf0e10cSrcweir 				aProgrammatic != m_pImpl->aLogicalFieldNames.end();
729*cdf0e10cSrcweir 				++aProgrammatic
730*cdf0e10cSrcweir 			)
731*cdf0e10cSrcweir 		{
732*cdf0e10cSrcweir 			sCurrent = *aProgrammatic;
733*cdf0e10cSrcweir 			if ( m_pImpl->pConfigData->hasFieldAssignment( sCurrent ) )
734*cdf0e10cSrcweir 			{
735*cdf0e10cSrcweir 				// the user gave us an assignment for this field
736*cdf0e10cSrcweir 				pPair->ProgrammaticName = *aProgrammatic;
737*cdf0e10cSrcweir 				pPair->Alias = m_pImpl->pConfigData->getFieldAssignment( *aProgrammatic );
738*cdf0e10cSrcweir 				++pPair;
739*cdf0e10cSrcweir 			}
740*cdf0e10cSrcweir 		}
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir 		_rMapping.realloc( pPair - _rMapping.getArray() );
743*cdf0e10cSrcweir 	}
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir 	// -------------------------------------------------------------------
746*cdf0e10cSrcweir 	void AddressBookSourceDialog::loadConfiguration()
747*cdf0e10cSrcweir 	{
748*cdf0e10cSrcweir         ::rtl::OUString sName = m_pImpl->pConfigData->getDatasourceName();
749*cdf0e10cSrcweir         INetURLObject aURL( sName );
750*cdf0e10cSrcweir         if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
751*cdf0e10cSrcweir 		{
752*cdf0e10cSrcweir 			OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
753*cdf0e10cSrcweir 			sName = aFileNotation.get(OFileNotation::N_SYSTEM);
754*cdf0e10cSrcweir         }
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir 		m_aDatasource.SetText(sName);
757*cdf0e10cSrcweir 		m_aTable.SetText(m_pImpl->pConfigData->getCommand());
758*cdf0e10cSrcweir 		// we ignore the CommandType: only tables are supported
759*cdf0e10cSrcweir 
760*cdf0e10cSrcweir 		// the logical names for the fields
761*cdf0e10cSrcweir 		DBG_ASSERT(m_pImpl->aLogicalFieldNames.size() == m_pImpl->aFieldAssignments.size(),
762*cdf0e10cSrcweir 			"AddressBookSourceDialog::loadConfiguration: inconsistence between field names and field assignments!");
763*cdf0e10cSrcweir 
764*cdf0e10cSrcweir 		ConstStringArrayIterator aLogical = m_pImpl->aLogicalFieldNames.begin();
765*cdf0e10cSrcweir 		StringArrayIterator aAssignment = m_pImpl->aFieldAssignments.begin();
766*cdf0e10cSrcweir 		for	(	;
767*cdf0e10cSrcweir 				aLogical < m_pImpl->aLogicalFieldNames.end();
768*cdf0e10cSrcweir 				++aLogical, ++aAssignment
769*cdf0e10cSrcweir 			)
770*cdf0e10cSrcweir 			*aAssignment = m_pImpl->pConfigData->getFieldAssignment(*aLogical);
771*cdf0e10cSrcweir 	}
772*cdf0e10cSrcweir 
773*cdf0e10cSrcweir 	// -------------------------------------------------------------------
774*cdf0e10cSrcweir 	AddressBookSourceDialog::~AddressBookSourceDialog()
775*cdf0e10cSrcweir 	{
776*cdf0e10cSrcweir 		sal_Int32 i;
777*cdf0e10cSrcweir 		for (i=0; i<FIELD_CONTROLS_VISIBLE; ++i)
778*cdf0e10cSrcweir 		{
779*cdf0e10cSrcweir 			delete m_pImpl->pFieldLabels[i];
780*cdf0e10cSrcweir 			delete m_pImpl->pFields[i];
781*cdf0e10cSrcweir 		}
782*cdf0e10cSrcweir 
783*cdf0e10cSrcweir 		delete m_pImpl;
784*cdf0e10cSrcweir 	}
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir 	// -------------------------------------------------------------------
787*cdf0e10cSrcweir 	void AddressBookSourceDialog::initializeDatasources()
788*cdf0e10cSrcweir 	{
789*cdf0e10cSrcweir 		if (!m_xDatabaseContext.is())
790*cdf0e10cSrcweir 		{
791*cdf0e10cSrcweir 			DBG_ASSERT(m_xORB.is(), "AddressBookSourceDialog::initializeDatasources: no service factory!");
792*cdf0e10cSrcweir 			if (!m_xORB.is())
793*cdf0e10cSrcweir 				return;
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir 			const String sContextServiceName = String::CreateFromAscii("com.sun.star.sdb.DatabaseContext");
796*cdf0e10cSrcweir 			try
797*cdf0e10cSrcweir 			{
798*cdf0e10cSrcweir 				m_xDatabaseContext = Reference< XNameAccess >(m_xORB->createInstance(sContextServiceName), UNO_QUERY);
799*cdf0e10cSrcweir 			}
800*cdf0e10cSrcweir 			catch(Exception&) { }
801*cdf0e10cSrcweir 			if (!m_xDatabaseContext.is())
802*cdf0e10cSrcweir 			{
803*cdf0e10cSrcweir 				ShowServiceNotAvailableError( this, sContextServiceName, sal_False);
804*cdf0e10cSrcweir 				return;
805*cdf0e10cSrcweir 			}
806*cdf0e10cSrcweir 		}
807*cdf0e10cSrcweir 		m_aDatasource.Clear();
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir 		// fill the datasources listbox
810*cdf0e10cSrcweir 		Sequence< ::rtl::OUString > aDatasourceNames;
811*cdf0e10cSrcweir 		try
812*cdf0e10cSrcweir 		{
813*cdf0e10cSrcweir 			aDatasourceNames = m_xDatabaseContext->getElementNames();
814*cdf0e10cSrcweir 		}
815*cdf0e10cSrcweir 		catch(Exception&)
816*cdf0e10cSrcweir 		{
817*cdf0e10cSrcweir 			DBG_ERROR("AddressBookSourceDialog::initializeDatasources: caught an exception while asking for the data source names!");
818*cdf0e10cSrcweir 		}
819*cdf0e10cSrcweir 		const ::rtl::OUString* pDatasourceNames = aDatasourceNames.getConstArray();
820*cdf0e10cSrcweir 		const ::rtl::OUString* pEnd = pDatasourceNames + aDatasourceNames.getLength();
821*cdf0e10cSrcweir 		for (; pDatasourceNames < pEnd; ++pDatasourceNames)
822*cdf0e10cSrcweir 			m_aDatasource.InsertEntry(*pDatasourceNames);
823*cdf0e10cSrcweir 	}
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir 	// -------------------------------------------------------------------
826*cdf0e10cSrcweir 	IMPL_LINK(AddressBookSourceDialog, OnFieldScroll, ScrollBar*, _pScrollBar)
827*cdf0e10cSrcweir 	{
828*cdf0e10cSrcweir 		implScrollFields( _pScrollBar->GetThumbPos(), sal_True, sal_True );
829*cdf0e10cSrcweir 		return 0L;
830*cdf0e10cSrcweir 	}
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir 	// -------------------------------------------------------------------
833*cdf0e10cSrcweir 	void AddressBookSourceDialog::resetTables()
834*cdf0e10cSrcweir 	{
835*cdf0e10cSrcweir 		if (!m_xDatabaseContext.is())
836*cdf0e10cSrcweir 			return;
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir 		WaitObject aWaitCursor(this);
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir 		// no matter what we do here, we handled the currently selected data source (no matter if successfull or not)
841*cdf0e10cSrcweir 		m_aDatasource.SaveValue();
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir 		// create an interaction handler (may be needed for connecting)
844*cdf0e10cSrcweir 		const String sInteractionHandlerServiceName = String::CreateFromAscii("com.sun.star.task.InteractionHandler");
845*cdf0e10cSrcweir 		Reference< XInteractionHandler > xHandler;
846*cdf0e10cSrcweir 		try
847*cdf0e10cSrcweir 		{
848*cdf0e10cSrcweir 			xHandler = Reference< XInteractionHandler >(m_xORB->createInstance(sInteractionHandlerServiceName), UNO_QUERY);
849*cdf0e10cSrcweir 		}
850*cdf0e10cSrcweir 		catch(Exception&) { }
851*cdf0e10cSrcweir 		if (!xHandler.is())
852*cdf0e10cSrcweir 		{
853*cdf0e10cSrcweir 			ShowServiceNotAvailableError(this, sInteractionHandlerServiceName, sal_True);
854*cdf0e10cSrcweir 			return;
855*cdf0e10cSrcweir 		}
856*cdf0e10cSrcweir 
857*cdf0e10cSrcweir 		// the currently selected table
858*cdf0e10cSrcweir 		::rtl::OUString sOldTable = m_aTable.GetText();
859*cdf0e10cSrcweir 
860*cdf0e10cSrcweir 		m_aTable.Clear();
861*cdf0e10cSrcweir 
862*cdf0e10cSrcweir 		m_xCurrentDatasourceTables= NULL;
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir 		// get the tables of the connection
865*cdf0e10cSrcweir 		Sequence< ::rtl::OUString > aTableNames;
866*cdf0e10cSrcweir 		Any aException;
867*cdf0e10cSrcweir 		try
868*cdf0e10cSrcweir 		{
869*cdf0e10cSrcweir 			Reference< XCompletedConnection > xDS;
870*cdf0e10cSrcweir             if ( m_pImpl->bWorkingPersistent )
871*cdf0e10cSrcweir             {
872*cdf0e10cSrcweir                 String sSelectedDS = lcl_getSelectedDataSource(  m_aDatasource );
873*cdf0e10cSrcweir 
874*cdf0e10cSrcweir 			    // get the data source the user has chosen and let it build a connection
875*cdf0e10cSrcweir                 INetURLObject aURL( sSelectedDS );
876*cdf0e10cSrcweir                 if ( aURL.GetProtocol() != INET_PROT_NOT_VALID || m_xDatabaseContext->hasByName(sSelectedDS) )
877*cdf0e10cSrcweir 				    m_xDatabaseContext->getByName( sSelectedDS ) >>= xDS;
878*cdf0e10cSrcweir             }
879*cdf0e10cSrcweir             else
880*cdf0e10cSrcweir             {
881*cdf0e10cSrcweir                 xDS = xDS.query( m_pImpl->m_xTransientDataSource );
882*cdf0e10cSrcweir             }
883*cdf0e10cSrcweir 
884*cdf0e10cSrcweir 			// build the connection
885*cdf0e10cSrcweir 			Reference< XConnection > xConn;
886*cdf0e10cSrcweir             if (xDS.is())
887*cdf0e10cSrcweir 				xConn = xDS->connectWithCompletion(xHandler);
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir 			// get the table names
890*cdf0e10cSrcweir 			Reference< XTablesSupplier > xSupplTables(xConn, UNO_QUERY);
891*cdf0e10cSrcweir 			if (xSupplTables.is())
892*cdf0e10cSrcweir 			{
893*cdf0e10cSrcweir 				m_xCurrentDatasourceTables = Reference< XNameAccess >(xSupplTables->getTables(), UNO_QUERY);
894*cdf0e10cSrcweir 				if (m_xCurrentDatasourceTables.is())
895*cdf0e10cSrcweir 					aTableNames = m_xCurrentDatasourceTables->getElementNames();
896*cdf0e10cSrcweir 			}
897*cdf0e10cSrcweir 		}
898*cdf0e10cSrcweir 		catch(SQLContext& e) { aException <<= e; }
899*cdf0e10cSrcweir 		catch(SQLWarning& e) { aException <<= e; }
900*cdf0e10cSrcweir 		catch(SQLException& e) { aException <<= e; }
901*cdf0e10cSrcweir 		catch(Exception&)
902*cdf0e10cSrcweir 		{
903*cdf0e10cSrcweir 			DBG_ERROR("AddressBookSourceDialog::resetTables: could not retrieve the table!");
904*cdf0e10cSrcweir 		}
905*cdf0e10cSrcweir 
906*cdf0e10cSrcweir 		if (aException.hasValue())
907*cdf0e10cSrcweir 		{
908*cdf0e10cSrcweir 			Reference< XInteractionRequest > xRequest = new OInteractionRequest(aException);
909*cdf0e10cSrcweir 			try
910*cdf0e10cSrcweir 			{
911*cdf0e10cSrcweir 				xHandler->handle(xRequest);
912*cdf0e10cSrcweir 			}
913*cdf0e10cSrcweir 			catch(Exception&) { }
914*cdf0e10cSrcweir 			return;
915*cdf0e10cSrcweir 		}
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir 		sal_Bool bKnowOldTable = sal_False;
918*cdf0e10cSrcweir 		// fill the table list
919*cdf0e10cSrcweir 		const ::rtl::OUString* pTableNames = aTableNames.getConstArray();
920*cdf0e10cSrcweir 		const ::rtl::OUString* pEnd = pTableNames + aTableNames.getLength();
921*cdf0e10cSrcweir 		for (;pTableNames != pEnd; ++pTableNames)
922*cdf0e10cSrcweir 		{
923*cdf0e10cSrcweir 			m_aTable.InsertEntry(*pTableNames);
924*cdf0e10cSrcweir 			if (0 == pTableNames->compareTo(sOldTable))
925*cdf0e10cSrcweir 				bKnowOldTable = sal_True;
926*cdf0e10cSrcweir 		}
927*cdf0e10cSrcweir 
928*cdf0e10cSrcweir 		// set the old table, if the new data source knows a table with this name, too. Else reset the tables edit field.
929*cdf0e10cSrcweir 		if (!bKnowOldTable)
930*cdf0e10cSrcweir 			sOldTable = ::rtl::OUString();
931*cdf0e10cSrcweir 		m_aTable.SetText(sOldTable);
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir 		resetFields();
934*cdf0e10cSrcweir 	}
935*cdf0e10cSrcweir 
936*cdf0e10cSrcweir 	// -------------------------------------------------------------------
937*cdf0e10cSrcweir 	void AddressBookSourceDialog::resetFields()
938*cdf0e10cSrcweir 	{
939*cdf0e10cSrcweir 		WaitObject aWaitCursor(this);
940*cdf0e10cSrcweir 
941*cdf0e10cSrcweir 		// no matter what we do here, we handled the currently selected table (no matter if successfull or not)
942*cdf0e10cSrcweir 		m_aDatasource.SaveValue();
943*cdf0e10cSrcweir 
944*cdf0e10cSrcweir 		String sSelectedTable = m_aTable.GetText();
945*cdf0e10cSrcweir 		Sequence< ::rtl::OUString > aColumnNames;
946*cdf0e10cSrcweir 		try
947*cdf0e10cSrcweir 		{
948*cdf0e10cSrcweir 			if (m_xCurrentDatasourceTables.is())
949*cdf0e10cSrcweir 			{
950*cdf0e10cSrcweir 				// get the table and the columns
951*cdf0e10cSrcweir 				Reference< XColumnsSupplier > xSuppTableCols;
952*cdf0e10cSrcweir 				if (m_xCurrentDatasourceTables->hasByName(sSelectedTable))
953*cdf0e10cSrcweir 					::cppu::extractInterface(xSuppTableCols, m_xCurrentDatasourceTables->getByName(sSelectedTable));
954*cdf0e10cSrcweir 				Reference< XNameAccess > xColumns;
955*cdf0e10cSrcweir 				if (xSuppTableCols.is())
956*cdf0e10cSrcweir 					xColumns = xSuppTableCols->getColumns();
957*cdf0e10cSrcweir 				if (xColumns.is())
958*cdf0e10cSrcweir 					aColumnNames = xColumns->getElementNames();
959*cdf0e10cSrcweir 			}
960*cdf0e10cSrcweir 		}
961*cdf0e10cSrcweir 		catch(Exception&)
962*cdf0e10cSrcweir 		{
963*cdf0e10cSrcweir 			DBG_ERROR("AddressBookSourceDialog::resetFields: could not retrieve the table columns!");
964*cdf0e10cSrcweir 		}
965*cdf0e10cSrcweir 
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir 		const ::rtl::OUString* pColumnNames = aColumnNames.getConstArray();
968*cdf0e10cSrcweir 		const ::rtl::OUString* pEnd = pColumnNames + aColumnNames.getLength();
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir 		// for quicker access
971*cdf0e10cSrcweir 		::std::set< String > aColumnNameSet;
972*cdf0e10cSrcweir 		for (pColumnNames = aColumnNames.getConstArray(); pColumnNames != pEnd; ++pColumnNames)
973*cdf0e10cSrcweir 			aColumnNameSet.insert(*pColumnNames);
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir 		std::vector<String>::iterator aInitialSelection = m_pImpl->aFieldAssignments.begin() + m_pImpl->nFieldScrollPos;
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir 		ListBox** pListbox = m_pImpl->pFields;
978*cdf0e10cSrcweir 		String sSaveSelection;
979*cdf0e10cSrcweir 		for (sal_Int32 i=0; i<FIELD_CONTROLS_VISIBLE; ++i, ++pListbox, ++aInitialSelection)
980*cdf0e10cSrcweir 		{
981*cdf0e10cSrcweir 			sSaveSelection = (*pListbox)->GetSelectEntry();
982*cdf0e10cSrcweir 
983*cdf0e10cSrcweir 			(*pListbox)->Clear();
984*cdf0e10cSrcweir 
985*cdf0e10cSrcweir 			// the one entry for "no selection"
986*cdf0e10cSrcweir 			(*pListbox)->InsertEntry(m_sNoFieldSelection, 0);
987*cdf0e10cSrcweir 			// as it's entry data, set the index of the list box in our array
988*cdf0e10cSrcweir 			(*pListbox)->SetEntryData(0, reinterpret_cast<void*>(i));
989*cdf0e10cSrcweir 
990*cdf0e10cSrcweir 			// the field names
991*cdf0e10cSrcweir 			for (pColumnNames = aColumnNames.getConstArray(); pColumnNames != pEnd; ++pColumnNames)
992*cdf0e10cSrcweir 				(*pListbox)->InsertEntry(*pColumnNames);
993*cdf0e10cSrcweir 
994*cdf0e10cSrcweir 			if (aInitialSelection->Len() && (aColumnNameSet.end() != aColumnNameSet.find(*aInitialSelection)))
995*cdf0e10cSrcweir 				// we can select the entry as specified in our field assignment array
996*cdf0e10cSrcweir 				(*pListbox)->SelectEntry(*aInitialSelection);
997*cdf0e10cSrcweir 			else
998*cdf0e10cSrcweir 				// try to restore the selection
999*cdf0e10cSrcweir 				if (aColumnNameSet.end() != aColumnNameSet.find(sSaveSelection))
1000*cdf0e10cSrcweir 					// the old selection is a valid column name
1001*cdf0e10cSrcweir 					(*pListbox)->SelectEntry(sSaveSelection);
1002*cdf0e10cSrcweir 				else
1003*cdf0e10cSrcweir 					// select the <none> entry
1004*cdf0e10cSrcweir 					(*pListbox)->SelectEntryPos(0);
1005*cdf0e10cSrcweir 		}
1006*cdf0e10cSrcweir 
1007*cdf0e10cSrcweir 		// adjust m_pImpl->aFieldAssignments
1008*cdf0e10cSrcweir 		for (	StringArrayIterator aAdjust = m_pImpl->aFieldAssignments.begin();
1009*cdf0e10cSrcweir 				aAdjust != m_pImpl->aFieldAssignments.end();
1010*cdf0e10cSrcweir 				++aAdjust
1011*cdf0e10cSrcweir 			)
1012*cdf0e10cSrcweir 			if (aAdjust->Len())
1013*cdf0e10cSrcweir 				if (aColumnNameSet.end() == aColumnNameSet.find(*aAdjust))
1014*cdf0e10cSrcweir 					aAdjust->Erase();
1015*cdf0e10cSrcweir 	}
1016*cdf0e10cSrcweir 
1017*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1018*cdf0e10cSrcweir 	IMPL_LINK(AddressBookSourceDialog, OnFieldSelect, ListBox*, _pListbox)
1019*cdf0e10cSrcweir 	{
1020*cdf0e10cSrcweir 		// the index of the affected list box in our array
1021*cdf0e10cSrcweir 		sal_IntPtr nListBoxIndex = reinterpret_cast<sal_IntPtr>(_pListbox->GetEntryData(0));
1022*cdf0e10cSrcweir 		DBG_ASSERT(nListBoxIndex >= 0 && nListBoxIndex < FIELD_CONTROLS_VISIBLE,
1023*cdf0e10cSrcweir 			"AddressBookSourceDialog::OnFieldScroll: invalid list box entry!");
1024*cdf0e10cSrcweir 
1025*cdf0e10cSrcweir 		// update the array where we remember the field selections
1026*cdf0e10cSrcweir 		if (0 == _pListbox->GetSelectEntryPos())
1027*cdf0e10cSrcweir 			// it's the "no field selection" entry
1028*cdf0e10cSrcweir 			m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = String();
1029*cdf0e10cSrcweir 		else
1030*cdf0e10cSrcweir 			// it's a regular field entry
1031*cdf0e10cSrcweir 			m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = _pListbox->GetSelectEntry();
1032*cdf0e10cSrcweir 
1033*cdf0e10cSrcweir 		return 0L;
1034*cdf0e10cSrcweir 	}
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1037*cdf0e10cSrcweir 	void AddressBookSourceDialog::implScrollFields(sal_Int32 _nPos, sal_Bool _bAdjustFocus, sal_Bool _bAdjustScrollbar)
1038*cdf0e10cSrcweir 	{
1039*cdf0e10cSrcweir 		if (_nPos == m_pImpl->nFieldScrollPos)
1040*cdf0e10cSrcweir 			// nothing to do
1041*cdf0e10cSrcweir 			return;
1042*cdf0e10cSrcweir 
1043*cdf0e10cSrcweir 		// loop through our field control rows and do some adjustments
1044*cdf0e10cSrcweir 		// for the new texts
1045*cdf0e10cSrcweir 		FixedText** pLeftLabelControl = m_pImpl->pFieldLabels;
1046*cdf0e10cSrcweir 		FixedText** pRightLabelControl = pLeftLabelControl + 1;
1047*cdf0e10cSrcweir 		ConstStringArrayIterator pLeftColumnLabel = m_pImpl->aFieldLabels.begin() + 2 * _nPos;
1048*cdf0e10cSrcweir 		ConstStringArrayIterator pRightColumnLabel = pLeftColumnLabel + 1;
1049*cdf0e10cSrcweir 
1050*cdf0e10cSrcweir 		// for the focus movement and the selection scroll
1051*cdf0e10cSrcweir 		ListBox** pLeftListControl = m_pImpl->pFields;
1052*cdf0e10cSrcweir 		ListBox** pRightListControl = pLeftListControl + 1;
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir 		// for the focus movement
1055*cdf0e10cSrcweir 		sal_Int32 nOldFocusRow = -1;
1056*cdf0e10cSrcweir 		sal_Int32 nOldFocusColumn = 0;
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir 		// for the selection scroll
1059*cdf0e10cSrcweir 		ConstStringArrayIterator pLeftAssignment = m_pImpl->aFieldAssignments.begin() + 2 * _nPos;
1060*cdf0e10cSrcweir 		ConstStringArrayIterator pRightAssignment = pLeftAssignment + 1;
1061*cdf0e10cSrcweir 
1062*cdf0e10cSrcweir 		m_pImpl->nLastVisibleListIndex = -1;
1063*cdf0e10cSrcweir 		// loop
1064*cdf0e10cSrcweir 		for (sal_Int32 i=0; i<FIELD_PAIRS_VISIBLE; ++i)
1065*cdf0e10cSrcweir 		{
1066*cdf0e10cSrcweir 			if ((*pLeftListControl)->HasChildPathFocus())
1067*cdf0e10cSrcweir 			{
1068*cdf0e10cSrcweir 				nOldFocusRow = i;
1069*cdf0e10cSrcweir 				nOldFocusColumn = 0;
1070*cdf0e10cSrcweir 			}
1071*cdf0e10cSrcweir 			else if ((*pRightListControl)->HasChildPathFocus())
1072*cdf0e10cSrcweir 			{
1073*cdf0e10cSrcweir 				nOldFocusRow = i;
1074*cdf0e10cSrcweir 				nOldFocusColumn = 1;
1075*cdf0e10cSrcweir 			}
1076*cdf0e10cSrcweir 
1077*cdf0e10cSrcweir 			// the new texts of the label controls
1078*cdf0e10cSrcweir 			(*pLeftLabelControl)->SetText(*pLeftColumnLabel);
1079*cdf0e10cSrcweir 			(*pRightLabelControl)->SetText(*pRightColumnLabel);
1080*cdf0e10cSrcweir 
1081*cdf0e10cSrcweir 			// we may have to hide the controls in the right column, if we have no label text for it
1082*cdf0e10cSrcweir 			// (which means we have an odd number of fields, though we forced our internal arrays to
1083*cdf0e10cSrcweir 			// be even-sized for easier handling)
1084*cdf0e10cSrcweir 			// (If sometimes we support an arbitrary number of field assignments, we would have to care for
1085*cdf0e10cSrcweir 			// an invisible left hand side column, too. But right now, the left hand side controls are always
1086*cdf0e10cSrcweir 			// visible)
1087*cdf0e10cSrcweir 			sal_Bool bHideRightColumn = (0 == pRightColumnLabel->Len());
1088*cdf0e10cSrcweir 			(*pRightLabelControl)->Show(!bHideRightColumn);
1089*cdf0e10cSrcweir 			(*pRightListControl)->Show(!bHideRightColumn);
1090*cdf0e10cSrcweir 			// the new selections of the listboxes
1091*cdf0e10cSrcweir 			implSelectField(*pLeftListControl, *pLeftAssignment);
1092*cdf0e10cSrcweir 			implSelectField(*pRightListControl, *pRightAssignment);
1093*cdf0e10cSrcweir 
1094*cdf0e10cSrcweir 			// the index of the last visible list box
1095*cdf0e10cSrcweir 			++m_pImpl->nLastVisibleListIndex;	// the left hand side box is always visible
1096*cdf0e10cSrcweir 			if (!bHideRightColumn)
1097*cdf0e10cSrcweir 				++m_pImpl->nLastVisibleListIndex;
1098*cdf0e10cSrcweir 
1099*cdf0e10cSrcweir 		    // increment ...
1100*cdf0e10cSrcweir             if ( i < FIELD_PAIRS_VISIBLE - 1 )
1101*cdf0e10cSrcweir             {   // (not in the very last round, here the +=2 could result in an invalid
1102*cdf0e10cSrcweir                 // iterator position, which causes an abort in a non-product version
1103*cdf0e10cSrcweir 			    pLeftLabelControl += 2;
1104*cdf0e10cSrcweir 			    pRightLabelControl += 2;
1105*cdf0e10cSrcweir 			    pLeftColumnLabel += 2;
1106*cdf0e10cSrcweir 			    pRightColumnLabel += 2;
1107*cdf0e10cSrcweir 
1108*cdf0e10cSrcweir 			    pLeftListControl += 2;
1109*cdf0e10cSrcweir 			    pRightListControl += 2;
1110*cdf0e10cSrcweir 			    pLeftAssignment += 2;
1111*cdf0e10cSrcweir 			    pRightAssignment += 2;
1112*cdf0e10cSrcweir             }
1113*cdf0e10cSrcweir 		}
1114*cdf0e10cSrcweir 
1115*cdf0e10cSrcweir 		if (_bAdjustFocus && (nOldFocusRow >= 0))
1116*cdf0e10cSrcweir 		{	// we have to adjust the focus and one of the list boxes has the focus
1117*cdf0e10cSrcweir 			sal_Int32 nDelta = m_pImpl->nFieldScrollPos - _nPos;
1118*cdf0e10cSrcweir 			// the new row for the focus
1119*cdf0e10cSrcweir 			sal_Int32 nNewFocusRow = nOldFocusRow + nDelta;
1120*cdf0e10cSrcweir 			// normalize
1121*cdf0e10cSrcweir 			nNewFocusRow = std::min(nNewFocusRow, (sal_Int32)(FIELD_PAIRS_VISIBLE - 1), ::std::less< sal_Int32 >());
1122*cdf0e10cSrcweir 			nNewFocusRow = std::max(nNewFocusRow, (sal_Int32)0, ::std::less< sal_Int32 >());
1123*cdf0e10cSrcweir 			// set the new focus (in the same column)
1124*cdf0e10cSrcweir 			m_pImpl->pFields[nNewFocusRow * 2 + nOldFocusColumn]->GrabFocus();
1125*cdf0e10cSrcweir 		}
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir 		m_pImpl->nFieldScrollPos = _nPos;
1128*cdf0e10cSrcweir 
1129*cdf0e10cSrcweir 		if (_bAdjustScrollbar)
1130*cdf0e10cSrcweir 			m_aFieldScroller.SetThumbPos(m_pImpl->nFieldScrollPos);
1131*cdf0e10cSrcweir 	}
1132*cdf0e10cSrcweir 
1133*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1134*cdf0e10cSrcweir 	void AddressBookSourceDialog::implSelectField(ListBox* _pBox, const String& _rText)
1135*cdf0e10cSrcweir 	{
1136*cdf0e10cSrcweir 		if (_rText.Len())
1137*cdf0e10cSrcweir 			// a valid field name
1138*cdf0e10cSrcweir 			_pBox->SelectEntry(_rText);
1139*cdf0e10cSrcweir 		else
1140*cdf0e10cSrcweir 			// no selection for this item
1141*cdf0e10cSrcweir 			_pBox->SelectEntryPos(0);
1142*cdf0e10cSrcweir 	}
1143*cdf0e10cSrcweir 
1144*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1145*cdf0e10cSrcweir 	IMPL_LINK(AddressBookSourceDialog, OnDelayedInitialize, void*, EMPTYARG)
1146*cdf0e10cSrcweir 	{
1147*cdf0e10cSrcweir 		// load the initial data from the configuration
1148*cdf0e10cSrcweir 		loadConfiguration();
1149*cdf0e10cSrcweir 		resetTables();
1150*cdf0e10cSrcweir 			// will reset the tables/fields implicitly
1151*cdf0e10cSrcweir 
1152*cdf0e10cSrcweir 		if ( !m_pImpl->bWorkingPersistent )
1153*cdf0e10cSrcweir 			if ( m_pImpl->pFields[0] )
1154*cdf0e10cSrcweir 				m_pImpl->pFields[0]->GrabFocus();
1155*cdf0e10cSrcweir 
1156*cdf0e10cSrcweir 		return 0L;
1157*cdf0e10cSrcweir 	}
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1160*cdf0e10cSrcweir 	IMPL_LINK(AddressBookSourceDialog, OnComboSelect, ComboBox*, _pBox)
1161*cdf0e10cSrcweir 	{
1162*cdf0e10cSrcweir 		if (_pBox == &m_aDatasource)
1163*cdf0e10cSrcweir 			resetTables();
1164*cdf0e10cSrcweir 		else
1165*cdf0e10cSrcweir 			resetFields();
1166*cdf0e10cSrcweir 		return 0;
1167*cdf0e10cSrcweir 	}
1168*cdf0e10cSrcweir 
1169*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1170*cdf0e10cSrcweir 	IMPL_LINK(AddressBookSourceDialog, OnComboGetFocus, ComboBox*, _pBox)
1171*cdf0e10cSrcweir 	{
1172*cdf0e10cSrcweir 		_pBox->SaveValue();
1173*cdf0e10cSrcweir 		return 0L;
1174*cdf0e10cSrcweir 	}
1175*cdf0e10cSrcweir 
1176*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1177*cdf0e10cSrcweir 	IMPL_LINK(AddressBookSourceDialog, OnComboLoseFocus, ComboBox*, _pBox)
1178*cdf0e10cSrcweir 	{
1179*cdf0e10cSrcweir 		if (_pBox->GetSavedValue() != _pBox->GetText())
1180*cdf0e10cSrcweir 		{
1181*cdf0e10cSrcweir 			if (_pBox == &m_aDatasource)
1182*cdf0e10cSrcweir 				resetTables();
1183*cdf0e10cSrcweir 			else
1184*cdf0e10cSrcweir 				resetFields();
1185*cdf0e10cSrcweir 		}
1186*cdf0e10cSrcweir 		return 0L;
1187*cdf0e10cSrcweir 	}
1188*cdf0e10cSrcweir 
1189*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1190*cdf0e10cSrcweir 	IMPL_LINK(AddressBookSourceDialog, OnOkClicked, Button*, EMPTYARG)
1191*cdf0e10cSrcweir 	{
1192*cdf0e10cSrcweir         String sSelectedDS = lcl_getSelectedDataSource(  m_aDatasource );
1193*cdf0e10cSrcweir         if ( m_pImpl->bWorkingPersistent )
1194*cdf0e10cSrcweir         {
1195*cdf0e10cSrcweir 		    m_pImpl->pConfigData->setDatasourceName(sSelectedDS);
1196*cdf0e10cSrcweir 		    m_pImpl->pConfigData->setCommand(m_aTable.GetText());
1197*cdf0e10cSrcweir         }
1198*cdf0e10cSrcweir 
1199*cdf0e10cSrcweir 		// set the field assignments
1200*cdf0e10cSrcweir 		ConstStringArrayIterator aLogical = m_pImpl->aLogicalFieldNames.begin();
1201*cdf0e10cSrcweir 		ConstStringArrayIterator aAssignment = m_pImpl->aFieldAssignments.begin();
1202*cdf0e10cSrcweir 		for	(	;
1203*cdf0e10cSrcweir 				aLogical < m_pImpl->aLogicalFieldNames.end();
1204*cdf0e10cSrcweir 				++aLogical, ++aAssignment
1205*cdf0e10cSrcweir 			)
1206*cdf0e10cSrcweir 			m_pImpl->pConfigData->setFieldAssignment(*aLogical, *aAssignment);
1207*cdf0e10cSrcweir 
1208*cdf0e10cSrcweir 
1209*cdf0e10cSrcweir 		EndDialog(RET_OK);
1210*cdf0e10cSrcweir 		return 0L;
1211*cdf0e10cSrcweir 	}
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1214*cdf0e10cSrcweir 	IMPL_LINK(AddressBookSourceDialog, OnAdministrateDatasources, void*, EMPTYARG)
1215*cdf0e10cSrcweir 	{
1216*cdf0e10cSrcweir 		// collect some initial arguments for the dialog
1217*cdf0e10cSrcweir 		Sequence< Any > aArgs(1);
1218*cdf0e10cSrcweir         aArgs[0] <<= PropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow")), 0, makeAny(VCLUnoHelper::GetInterface(this)), PropertyState_DIRECT_VALUE);
1219*cdf0e10cSrcweir 
1220*cdf0e10cSrcweir 		// create the dialog object
1221*cdf0e10cSrcweir 		const String sDialogServiceName = String::CreateFromAscii("com.sun.star.ui.dialogs.AddressBookSourcePilot");
1222*cdf0e10cSrcweir 		Reference< XExecutableDialog > xAdminDialog;
1223*cdf0e10cSrcweir 		try
1224*cdf0e10cSrcweir 		{
1225*cdf0e10cSrcweir 			xAdminDialog = Reference< XExecutableDialog >(m_xORB->createInstanceWithArguments(sDialogServiceName, aArgs), UNO_QUERY);
1226*cdf0e10cSrcweir 		}
1227*cdf0e10cSrcweir 		catch(Exception&) { }
1228*cdf0e10cSrcweir 		if (!xAdminDialog.is())
1229*cdf0e10cSrcweir 		{
1230*cdf0e10cSrcweir 			ShowServiceNotAvailableError(this, sDialogServiceName, sal_True);
1231*cdf0e10cSrcweir 			return 1L;
1232*cdf0e10cSrcweir 		}
1233*cdf0e10cSrcweir 
1234*cdf0e10cSrcweir 		// excute the dialog
1235*cdf0e10cSrcweir 		try
1236*cdf0e10cSrcweir 		{
1237*cdf0e10cSrcweir             if ( xAdminDialog->execute() == RET_OK )
1238*cdf0e10cSrcweir             {
1239*cdf0e10cSrcweir                 Reference<XPropertySet> xProp(xAdminDialog,UNO_QUERY);
1240*cdf0e10cSrcweir 				if ( xProp.is() )
1241*cdf0e10cSrcweir 				{
1242*cdf0e10cSrcweir                     ::rtl::OUString sName;
1243*cdf0e10cSrcweir                     xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSourceName"))) >>= sName;
1244*cdf0e10cSrcweir 
1245*cdf0e10cSrcweir                     INetURLObject aURL( sName );
1246*cdf0e10cSrcweir                     if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
1247*cdf0e10cSrcweir 			        {
1248*cdf0e10cSrcweir 				        OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
1249*cdf0e10cSrcweir 				        sName = aFileNotation.get(OFileNotation::N_SYSTEM);
1250*cdf0e10cSrcweir                     }
1251*cdf0e10cSrcweir                     m_aDatasource.InsertEntry(sName);
1252*cdf0e10cSrcweir 					delete m_pImpl->pConfigData;
1253*cdf0e10cSrcweir 					m_pImpl->pConfigData = new AssignmentPersistentData();
1254*cdf0e10cSrcweir 					loadConfiguration();
1255*cdf0e10cSrcweir                     resetTables();
1256*cdf0e10cSrcweir 			        // will reset the fields implicitly
1257*cdf0e10cSrcweir                 }
1258*cdf0e10cSrcweir             }
1259*cdf0e10cSrcweir 		}
1260*cdf0e10cSrcweir 		catch(Exception&)
1261*cdf0e10cSrcweir 		{
1262*cdf0e10cSrcweir 			DBG_ERROR("AddressBookSourceDialog::OnAdministrateDatasources: an error occured while executing the administration dialog!");
1263*cdf0e10cSrcweir 		}
1264*cdf0e10cSrcweir 
1265*cdf0e10cSrcweir 		// re-fill the data source list
1266*cdf0e10cSrcweir 		// try to preserve the current selection
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir //		initializeDatasources();
1269*cdf0e10cSrcweir 
1270*cdf0e10cSrcweir 		return 0L;
1271*cdf0e10cSrcweir 	}
1272*cdf0e10cSrcweir 
1273*cdf0e10cSrcweir 	// -------------------------------------------------------------------
1274*cdf0e10cSrcweir 	long AddressBookSourceDialog::PreNotify( NotifyEvent& _rNEvt )
1275*cdf0e10cSrcweir 	{
1276*cdf0e10cSrcweir 		switch (_rNEvt.GetType())
1277*cdf0e10cSrcweir 		{
1278*cdf0e10cSrcweir 			case EVENT_KEYINPUT:
1279*cdf0e10cSrcweir 			{
1280*cdf0e10cSrcweir 				const KeyEvent* pKeyEvent =	_rNEvt.GetKeyEvent();
1281*cdf0e10cSrcweir 				sal_uInt16 nCode  = pKeyEvent->GetKeyCode().GetCode();
1282*cdf0e10cSrcweir 				sal_Bool   bShift = pKeyEvent->GetKeyCode().IsShift();
1283*cdf0e10cSrcweir 				sal_Bool   bCtrl  = pKeyEvent->GetKeyCode().IsMod1();
1284*cdf0e10cSrcweir 				sal_Bool   bAlt =	pKeyEvent->GetKeyCode().IsMod2();
1285*cdf0e10cSrcweir 
1286*cdf0e10cSrcweir 				if (KEY_TAB == nCode)
1287*cdf0e10cSrcweir 				{	// somebody pressed the tab key
1288*cdf0e10cSrcweir 					if (!bAlt && !bCtrl && !bShift)
1289*cdf0e10cSrcweir 					{	// it's really the only the key (no modifiers)
1290*cdf0e10cSrcweir 						if (m_pImpl->pFields[m_pImpl->nLastVisibleListIndex]->HasChildPathFocus())
1291*cdf0e10cSrcweir 							// the last of our visible list boxes has the focus
1292*cdf0e10cSrcweir 							if (m_pImpl->nFieldScrollPos < m_aFieldScroller.GetRangeMax())
1293*cdf0e10cSrcweir 							{	// we can still scroll down
1294*cdf0e10cSrcweir 								sal_Int32 nNextFocusList = m_pImpl->nLastVisibleListIndex + 1 - 2;
1295*cdf0e10cSrcweir 								// -> scroll down
1296*cdf0e10cSrcweir 								implScrollFields(m_pImpl->nFieldScrollPos + 1, sal_False, sal_True);
1297*cdf0e10cSrcweir 								// give the left control in the "next" line the focus
1298*cdf0e10cSrcweir 								m_pImpl->pFields[nNextFocusList]->GrabFocus();
1299*cdf0e10cSrcweir 								// return saying "have handled this"
1300*cdf0e10cSrcweir 								return 1;
1301*cdf0e10cSrcweir 							}
1302*cdf0e10cSrcweir 					}
1303*cdf0e10cSrcweir 					else if (!bAlt && !bCtrl && bShift)
1304*cdf0e10cSrcweir 					{	// it's shift-tab
1305*cdf0e10cSrcweir 						if (m_pImpl->pFields[0]->HasChildPathFocus())
1306*cdf0e10cSrcweir 							// our first list box has the focus
1307*cdf0e10cSrcweir 							if (m_pImpl->nFieldScrollPos > 0)
1308*cdf0e10cSrcweir 							{	// we can still scroll up
1309*cdf0e10cSrcweir 								// -> scroll up
1310*cdf0e10cSrcweir 								implScrollFields(m_pImpl->nFieldScrollPos - 1, sal_False, sal_True);
1311*cdf0e10cSrcweir 								// give the right control in the "prebious" line the focus
1312*cdf0e10cSrcweir 								m_pImpl->pFields[0 - 1 + 2]->GrabFocus();
1313*cdf0e10cSrcweir 								// return saying "have handled this"
1314*cdf0e10cSrcweir 								return 1;
1315*cdf0e10cSrcweir 							}
1316*cdf0e10cSrcweir 					}
1317*cdf0e10cSrcweir 				}
1318*cdf0e10cSrcweir 			}
1319*cdf0e10cSrcweir 			break;
1320*cdf0e10cSrcweir 		}
1321*cdf0e10cSrcweir 		return ModalDialog::PreNotify(_rNEvt);
1322*cdf0e10cSrcweir 	}
1323*cdf0e10cSrcweir 
1324*cdf0e10cSrcweir // .......................................................................
1325*cdf0e10cSrcweir }	// namespace svt
1326*cdf0e10cSrcweir // .......................................................................
1327*cdf0e10cSrcweir 
1328