update dev300-m58
[ooovba.git] / extensions / source / abpilot / fieldmappingimpl.cxx
blob6a6da80e51d4707b73e39cba2a706a3aca80dd3a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fieldmappingimpl.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
33 #include "fieldmappingimpl.hxx"
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
38 #include <com/sun/star/awt/XWindow.hpp>
39 #include <com/sun/star/sdb/CommandType.hpp>
40 #include <tools/debug.hxx>
41 #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
42 #include <toolkit/unohlp.hxx>
43 #endif
44 #include <vcl/stdtext.hxx>
45 #include <com/sun/star/util/AliasProgrammaticPair.hpp>
46 #ifndef EXTENSIONS_ABPRESID_HRC
47 #include "abpresid.hrc"
48 #endif
49 #include "componentmodule.hxx"
50 #include <unotools/confignode.hxx>
52 //.........................................................................
53 namespace abp
55 //.........................................................................
57 using namespace ::utl;
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::awt;
60 using namespace ::com::sun::star::util;
61 using namespace ::com::sun::star::lang;
62 using namespace ::com::sun::star::beans;
63 using namespace ::com::sun::star::sdb;
64 using namespace ::com::sun::star::ui::dialogs;
66 //---------------------------------------------------------------------
67 static const ::rtl::OUString& lcl_getDriverSettingsNodeName()
69 static const ::rtl::OUString s_sDriverSettingsNodeName =
70 ::rtl::OUString::createFromAscii( "/org.openoffice.Office.DataAccess/DriverSettings/com.sun.star.comp.sdbc.MozabDriver" );
71 return s_sDriverSettingsNodeName;
74 //---------------------------------------------------------------------
75 static const ::rtl::OUString& lcl_getAddressBookNodeName()
77 static const ::rtl::OUString s_sAddressBookNodeName =
78 ::rtl::OUString::createFromAscii( "/org.openoffice.Office.DataAccess/AddressBook" );
79 return s_sAddressBookNodeName;
82 //.....................................................................
83 namespace fieldmapping
85 //.....................................................................
87 //-----------------------------------------------------------------
88 sal_Bool invokeDialog( const Reference< XMultiServiceFactory >& _rxORB, class Window* _pParent,
89 const Reference< XPropertySet >& _rxDataSource, AddressSettings& _rSettings ) SAL_THROW ( ( ) )
91 _rSettings.aFieldMapping.clear();
93 DBG_ASSERT( _rxORB.is(), "fieldmapping::invokeDialog: invalid service factory!" );
94 DBG_ASSERT( _rxDataSource.is(), "fieldmapping::invokeDialog: invalid data source!" );
95 if ( !_rxORB.is() || !_rxDataSource.is() )
96 return sal_False;
98 try
100 // ........................................................
101 // the parameters for creating the dialog
102 Sequence< Any > aArguments(5);
103 Any* pArguments = aArguments.getArray();
105 // the parent window
106 Reference< XWindow > xDialogParent = VCLUnoHelper::GetInterface( _pParent );
107 *pArguments++ <<= PropertyValue(::rtl::OUString::createFromAscii( "ParentWindow" ), -1, makeAny( xDialogParent ), PropertyState_DIRECT_VALUE);
109 // the data source to use
110 *pArguments++ <<= PropertyValue(::rtl::OUString::createFromAscii( "DataSource" ), -1, makeAny( _rxDataSource ), PropertyState_DIRECT_VALUE);
111 *pArguments++ <<= PropertyValue(::rtl::OUString::createFromAscii( "DataSourceName" ), -1, makeAny( (sal_Bool)_rSettings.bRegisterDataSource ? _rSettings.sRegisteredDataSourceName : _rSettings.sDataSourceName ), PropertyState_DIRECT_VALUE);
113 // the table to use
114 *pArguments++ <<= PropertyValue(::rtl::OUString::createFromAscii( "Command" ), -1, makeAny( _rSettings.sSelectedTable ), PropertyState_DIRECT_VALUE);
116 // the title
117 ::rtl::OUString sTitle = String( ModuleRes( RID_STR_FIELDDIALOGTITLE ) );
118 *pArguments++ <<= PropertyValue(::rtl::OUString::createFromAscii( "Title" ), -1, makeAny( sTitle ), PropertyState_DIRECT_VALUE);
120 // ........................................................
121 // create an instance of the dialog service
122 static ::rtl::OUString s_sAdressBookFieldAssignmentServiceName = ::rtl::OUString::createFromAscii( "com.sun.star.ui.AddressBookSourceDialog" );
123 Reference< XExecutableDialog > xDialog(
124 _rxORB->createInstanceWithArguments( s_sAdressBookFieldAssignmentServiceName, aArguments ),
125 UNO_QUERY
127 if ( !xDialog.is( ) )
129 ShowServiceNotAvailableError( _pParent, s_sAdressBookFieldAssignmentServiceName, sal_True );
130 return sal_False;
133 // execute the dialog
134 if ( xDialog->execute() )
136 // retrieve the field mapping as set by he user
137 Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY );
139 Sequence< AliasProgrammaticPair > aMapping;
140 #ifdef DBG_UTIL
141 sal_Bool bSuccess =
142 #endif
143 xDialogProps->getPropertyValue( ::rtl::OUString::createFromAscii( "FieldMapping" ) ) >>= aMapping;
144 DBG_ASSERT( bSuccess, "fieldmapping::invokeDialog: invalid property type for FieldMapping!" );
146 // and copy it into the map
147 const AliasProgrammaticPair* pMapping = aMapping.getConstArray();
148 const AliasProgrammaticPair* pMappingEnd = pMapping + aMapping.getLength();
149 for (;pMapping != pMappingEnd; ++pMapping)
150 _rSettings.aFieldMapping[ pMapping->ProgrammaticName ] = pMapping->Alias;
152 return sal_True;
156 catch(const Exception&)
158 DBG_ERROR("fieldmapping::invokeDialog: caught an exception while executing the dialog!");
160 return sal_False;
163 //-----------------------------------------------------------------
164 void defaultMapping( const Reference< XMultiServiceFactory >& _rxORB, MapString2String& _rFieldAssignment ) SAL_THROW ( ( ) )
166 _rFieldAssignment.clear();
170 // what we have:
171 // a) For the address data source, we need a mapping from programmatic names (1) to real column names
172 // b) The SDBC driver has a fixed set of columns, which, when returned, are named according to
173 // some configuration entries. E.g., the driver displays the field which it knows contains
174 // the first name as "First Name" - the latter string is stored in the config.
175 // For this, the driver uses programmatic names, too, but they differ from the programmatic names the
176 // template documents have.
177 // So what we need first is a mapping from programmatic names (1) to programmatic names (2)
178 const sal_Char* pMappingProgrammatics[] =
180 "FirstName", "FirstName",
181 "LastName", "LastName",
182 "Street", "HomeAddress",
183 "Zip", "HomeZipCode",
184 "City", "HomeCity",
185 "State", "HomeState",
186 "Country", "HomeCountry",
187 "PhonePriv", "HomePhone",
188 "PhoneComp", "WorkPhone",
189 "PhoneCell", "CellularNumber",
190 "Pager", "PagerNumber",
191 "Fax", "FaxNumber",
192 "EMail", "PrimaryEmail",
193 "URL", "WebPage1",
194 "Note", "Notes",
195 "Altfield1", "Custom1",
196 "Altfield2", "Custom2",
197 "Altfield3", "Custom3",
198 "Altfield4", "Custom4",
199 "Title", "JobTitle",
200 "Company", "Company",
201 "Department", "Department"
203 // (this list is not complete: both lists of programmatic names are larger in real,
204 // but this list above is the intersection)
207 // access the configuration information which the driver uses for determining it's column names
208 ::rtl::OUString sDriverAliasesNodeName = lcl_getDriverSettingsNodeName();
209 sDriverAliasesNodeName += ::rtl::OUString::createFromAscii( "/ColumnAliases" );
211 // create a config node for this
212 OConfigurationTreeRoot aDriverFieldAliasing = OConfigurationTreeRoot::createWithServiceFactory(
213 _rxORB, sDriverAliasesNodeName, -1, OConfigurationTreeRoot::CM_READONLY);
215 // loop through all programmatic pairs
216 DBG_ASSERT( 0 == ( sizeof( pMappingProgrammatics ) / sizeof( pMappingProgrammatics[ 0 ] ) ) % 2,
217 "fieldmapping::defaultMapping: invalid programmatic map!" );
218 // number of pairs
219 sal_Int32 nIntersectedProgrammatics = sizeof( pMappingProgrammatics ) / sizeof( pMappingProgrammatics[ 0 ] ) / 2;
221 const sal_Char** pProgrammatic = pMappingProgrammatics;
222 ::rtl::OUString sAddressProgrammatic;
223 ::rtl::OUString sDriverProgrammatic;
224 ::rtl::OUString sDriverUI;
225 for ( sal_Int32 i=0;
226 i < nIntersectedProgrammatics;
230 sAddressProgrammatic = ::rtl::OUString::createFromAscii( *pProgrammatic++ );
231 sDriverProgrammatic = ::rtl::OUString::createFromAscii( *pProgrammatic++ );
233 if ( aDriverFieldAliasing.hasByName( sDriverProgrammatic ) )
235 aDriverFieldAliasing.getNodeValue( sDriverProgrammatic ) >>= sDriverUI;
236 if ( 0 == sDriverUI.getLength() )
238 DBG_ERROR( "fieldmapping::defaultMapping: invalid driver UI column name!");
240 else
241 _rFieldAssignment[ sAddressProgrammatic ] = sDriverUI;
243 else
245 DBG_ERROR( "fieldmapping::defaultMapping: invalid driver programmatic name!" );
249 catch( const Exception& )
251 DBG_ERROR("fieldmapping::defaultMapping: code is assumed to throw no exceptions!");
252 // the config nodes we're using herein should not do this ....
256 //-----------------------------------------------------------------
257 void writeTemplateAddressFieldMapping( const Reference< XMultiServiceFactory >& _rxORB, const MapString2String& _rFieldAssignment ) SAL_THROW ( ( ) )
259 // want to have a non-const map for easier handling
260 MapString2String aFieldAssignment( _rFieldAssignment );
262 // access the configuration information which the driver uses for determining it's column names
263 const ::rtl::OUString& sAddressBookNodeName = lcl_getAddressBookNodeName();
265 // create a config node for this
266 OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithServiceFactory(
267 _rxORB, sAddressBookNodeName, -1, OConfigurationTreeRoot::CM_UPDATABLE);
269 OConfigurationNode aFields = aAddressBookSettings.openNode( ::rtl::OUString::createFromAscii( "Fields" ) );
271 // loop through all existent fields
272 Sequence< ::rtl::OUString > aExistentFields = aFields.getNodeNames();
273 const ::rtl::OUString* pExistentFields = aExistentFields.getConstArray();
274 const ::rtl::OUString* pExistentFieldsEnd = pExistentFields + aExistentFields.getLength();
276 const ::rtl::OUString sProgrammaticNodeName = ::rtl::OUString::createFromAscii( "ProgrammaticFieldName" );
277 const ::rtl::OUString sAssignedNodeName = ::rtl::OUString::createFromAscii( "AssignedFieldName" );
279 for ( ; pExistentFields != pExistentFieldsEnd; ++pExistentFields )
281 #ifdef DBG_UTIL
282 ::rtl::OUString sRedundantProgrammaticName;
283 aFields.openNode( *pExistentFields ).getNodeValue( sProgrammaticNodeName ) >>= sRedundantProgrammaticName;
284 #endif
285 DBG_ASSERT( sRedundantProgrammaticName == *pExistentFields,
286 "fieldmapping::writeTemplateAddressFieldMapping: inconsistent config data!" );
287 // there should be a redundancy in the config data .... if this asserts, there isn't anymore!
289 // do we have a new alias for the programmatic?
290 MapString2StringIterator aPos = aFieldAssignment.find( *pExistentFields );
291 if ( aFieldAssignment.end() != aPos )
292 { // yes
293 // -> set a new value
294 OConfigurationNode aExistentField = aFields.openNode( *pExistentFields );
295 aExistentField.setNodeValue( sAssignedNodeName, makeAny( aPos->second ) );
296 // and remove the mapping entry
297 aFieldAssignment.erase( *pExistentFields );
299 else
300 { // no
301 // -> remove it
302 aFields.removeNode( *pExistentFields );
306 // now everything remaining in aFieldAssignment marks a mapping entry which was not present
307 // in the config before
308 for ( ConstMapString2StringIterator aNewMapping = aFieldAssignment.begin();
309 aNewMapping != aFieldAssignment.end();
310 ++aNewMapping
313 DBG_ASSERT( !aFields.hasByName( aNewMapping->first ),
314 "fieldmapping::writeTemplateAddressFieldMapping: inconsistence!" );
315 // in case the config node for the fields already has the node named <aNewMapping->first>,
316 // the entry should have been removed from aNewMapping (in the above loop)
317 OConfigurationNode aNewField = aFields.createNode( aNewMapping->first );
318 aNewField.setNodeValue( sProgrammaticNodeName, makeAny( aNewMapping->first ) );
319 aNewField.setNodeValue( sAssignedNodeName, makeAny( aNewMapping->second ) );
322 // commit the changes done
323 aAddressBookSettings.commit();
326 //.....................................................................
327 } // namespace fieldmapping
328 //.....................................................................
330 //.....................................................................
331 namespace addressconfig
333 //.....................................................................
335 //-----------------------------------------------------------------
336 void writeTemplateAddressSource( const Reference< XMultiServiceFactory >& _rxORB,
337 const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rTableName ) SAL_THROW ( ( ) )
339 // access the configuration information which the driver uses for determining it's column names
340 const ::rtl::OUString& sAddressBookNodeName = lcl_getAddressBookNodeName();
342 // create a config node for this
343 OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithServiceFactory(
344 _rxORB, sAddressBookNodeName, -1, OConfigurationTreeRoot::CM_UPDATABLE);
346 aAddressBookSettings.setNodeValue( ::rtl::OUString::createFromAscii( "DataSourceName" ), makeAny( _rDataSourceName ) );
347 aAddressBookSettings.setNodeValue( ::rtl::OUString::createFromAscii( "Command" ), makeAny( _rTableName ) );
348 aAddressBookSettings.setNodeValue( ::rtl::OUString::createFromAscii( "CommandType" ), makeAny( (sal_Int32)CommandType::TABLE ) );
350 // commit the changes done
351 aAddressBookSettings.commit();
354 //-----------------------------------------------------------------
355 void markPilotSuccess( const Reference< XMultiServiceFactory >& _rxORB ) SAL_THROW ( ( ) )
357 // access the configuration information which the driver uses for determining it's column names
358 const ::rtl::OUString& sAddressBookNodeName = lcl_getAddressBookNodeName();
360 // create a config node for this
361 OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithServiceFactory(
362 _rxORB, sAddressBookNodeName, -1, OConfigurationTreeRoot::CM_UPDATABLE);
364 // set the flag
365 aAddressBookSettings.setNodeValue( ::rtl::OUString::createFromAscii( "AutoPilotCompleted" ), makeAny( (sal_Bool)sal_True ) );
367 // commit the changes done
368 aAddressBookSettings.commit();
371 //.....................................................................
372 } // namespace addressconfig
373 //.....................................................................
375 //.........................................................................
376 } // namespace abp
377 //.........................................................................