bump product version to 5.0.4.1
[LibreOffice.git] / extensions / source / abpilot / fieldmappingimpl.cxx
blob7103319d8b6d59d30aa366e3782f55eeaefedfd4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "fieldmappingimpl.hxx"
21 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
22 #include <com/sun/star/beans/PropertyValue.hpp>
23 #include <com/sun/star/beans/XPropertySet.hpp>
24 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
25 #include <com/sun/star/ui/AddressBookSourceDialog.hpp>
26 #include <com/sun/star/awt/XWindow.hpp>
27 #include <com/sun/star/sdb/CommandType.hpp>
28 #include <tools/debug.hxx>
29 #include <toolkit/helper/vclunohelper.hxx>
30 #include <vcl/stdtext.hxx>
31 #include <com/sun/star/util/AliasProgrammaticPair.hpp>
32 #include "abpresid.hrc"
33 #include "componentmodule.hxx"
34 #include <unotools/confignode.hxx>
35 #include "sal/macros.h"
38 namespace abp
42 using namespace ::utl;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::awt;
45 using namespace ::com::sun::star::util;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::beans;
48 using namespace ::com::sun::star::sdb;
49 using namespace ::com::sun::star::ui;
50 using namespace ::com::sun::star::ui::dialogs;
53 static const char sDriverSettingsNodeName[] = "/org.openoffice.Office.DataAccess/DriverSettings/com.sun.star.comp.sdbc.MozabDriver";
54 static const char sAddressBookNodeName[] = "/org.openoffice.Office.DataAccess/AddressBook";
57 namespace fieldmapping
62 bool invokeDialog( const Reference< XComponentContext >& _rxORB, class vcl::Window* _pParent,
63 const Reference< XPropertySet >& _rxDataSource, AddressSettings& _rSettings )
65 _rSettings.aFieldMapping.clear();
67 DBG_ASSERT( _rxORB.is(), "fieldmapping::invokeDialog: invalid service factory!" );
68 DBG_ASSERT( _rxDataSource.is(), "fieldmapping::invokeDialog: invalid data source!" );
69 if ( !_rxORB.is() || !_rxDataSource.is() )
70 return false;
72 try
75 // create an instance of the dialog service
76 Reference< XWindow > xDialogParent = VCLUnoHelper::GetInterface( _pParent );
77 OUString sTitle(ModuleRes(RID_STR_FIELDDIALOGTITLE).toString());
78 Reference< XExecutableDialog > xDialog = AddressBookSourceDialog::createWithDataSource(_rxORB,
79 // the parent window
80 xDialogParent,
81 _rxDataSource,
82 _rSettings.bRegisterDataSource ? _rSettings.sRegisteredDataSourceName : _rSettings.sDataSourceName,
83 // the table to use
84 _rSettings.sSelectedTable,
85 sTitle);
87 // execute the dialog
88 if ( xDialog->execute() )
90 // retrieve the field mapping as set by he user
91 Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY );
93 Sequence< AliasProgrammaticPair > aMapping;
94 #ifdef DBG_UTIL
95 bool bSuccess =
96 #endif
97 xDialogProps->getPropertyValue("FieldMapping") >>= aMapping;
98 DBG_ASSERT( bSuccess, "fieldmapping::invokeDialog: invalid property type for FieldMapping!" );
100 // and copy it into the map
101 const AliasProgrammaticPair* pMapping = aMapping.getConstArray();
102 const AliasProgrammaticPair* pMappingEnd = pMapping + aMapping.getLength();
103 for (;pMapping != pMappingEnd; ++pMapping)
104 _rSettings.aFieldMapping[ pMapping->ProgrammaticName ] = pMapping->Alias;
106 return true;
110 catch(const Exception&)
112 OSL_FAIL("fieldmapping::invokeDialog: caught an exception while executing the dialog!");
114 return false;
118 void defaultMapping( const Reference< XComponentContext >& _rxContext, MapString2String& _rFieldAssignment )
120 _rFieldAssignment.clear();
124 // what we have:
125 // a) For the address data source, we need a mapping from programmatic names (1) to real column names
126 // b) The SDBC driver has a fixed set of columns, which, when returned, are named according to
127 // some configuration entries. E.g., the driver displays the field which it knows contains
128 // the first name as "First Name" - the latter string is stored in the config.
129 // For this, the driver uses programmatic names, too, but they differ from the programmatic names the
130 // template documents have.
131 // So what we need first is a mapping from programmatic names (1) to programmatic names (2)
132 const sal_Char* pMappingProgrammatics[] =
134 "FirstName", "FirstName",
135 "LastName", "LastName",
136 "Street", "HomeAddress",
137 "Zip", "HomeZipCode",
138 "City", "HomeCity",
139 "State", "HomeState",
140 "Country", "HomeCountry",
141 "PhonePriv", "HomePhone",
142 "PhoneComp", "WorkPhone",
143 "PhoneCell", "CellularNumber",
144 "Pager", "PagerNumber",
145 "Fax", "FaxNumber",
146 "EMail", "PrimaryEmail",
147 "URL", "WebPage1",
148 "Note", "Notes",
149 "Altfield1", "Custom1",
150 "Altfield2", "Custom2",
151 "Altfield3", "Custom3",
152 "Altfield4", "Custom4",
153 "Title", "JobTitle",
154 "Company", "Company",
155 "Department", "Department"
157 // (this list is not complete: both lists of programmatic names are larger in real,
158 // but this list above is the intersection)
161 // access the configuration information which the driver uses for determining it's column names
162 OUString sDriverAliasesNodeName = sDriverSettingsNodeName;
163 sDriverAliasesNodeName += OUString( "/ColumnAliases" );
165 // create a config node for this
166 OConfigurationTreeRoot aDriverFieldAliasing = OConfigurationTreeRoot::createWithComponentContext(
167 _rxContext, sDriverAliasesNodeName, -1, OConfigurationTreeRoot::CM_READONLY);
169 // loop through all programmatic pairs
170 DBG_ASSERT( 0 == SAL_N_ELEMENTS( pMappingProgrammatics ) % 2,
171 "fieldmapping::defaultMapping: invalid programmatic map!" );
172 // number of pairs
173 sal_Int32 nIntersectedProgrammatics = SAL_N_ELEMENTS( pMappingProgrammatics ) / 2;
175 const sal_Char** pProgrammatic = pMappingProgrammatics;
176 OUString sAddressProgrammatic;
177 OUString sDriverProgrammatic;
178 OUString sDriverUI;
179 for ( sal_Int32 i=0;
180 i < nIntersectedProgrammatics;
184 sAddressProgrammatic = OUString::createFromAscii( *pProgrammatic++ );
185 sDriverProgrammatic = OUString::createFromAscii( *pProgrammatic++ );
187 if ( aDriverFieldAliasing.hasByName( sDriverProgrammatic ) )
189 aDriverFieldAliasing.getNodeValue( sDriverProgrammatic ) >>= sDriverUI;
190 if ( 0 == sDriverUI.getLength() )
192 OSL_FAIL( "fieldmapping::defaultMapping: invalid driver UI column name!");
194 else
195 _rFieldAssignment[ sAddressProgrammatic ] = sDriverUI;
197 else
199 OSL_FAIL( "fieldmapping::defaultMapping: invalid driver programmatic name!" );
203 catch( const Exception& )
205 OSL_FAIL("fieldmapping::defaultMapping: code is assumed to throw no exceptions!");
206 // the config nodes we're using herein should not do this ....
211 void writeTemplateAddressFieldMapping( const Reference< XComponentContext >& _rxContext, const MapString2String& _rFieldAssignment )
213 // want to have a non-const map for easier handling
214 MapString2String aFieldAssignment( _rFieldAssignment );
216 // access the configuration information which the driver uses for determining it's column names
218 // create a config node for this
219 OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithComponentContext(
220 _rxContext, sAddressBookNodeName, -1, OConfigurationTreeRoot::CM_UPDATABLE);
222 OConfigurationNode aFields = aAddressBookSettings.openNode( OUString( "Fields" ) );
224 // loop through all existent fields
225 Sequence< OUString > aExistentFields = aFields.getNodeNames();
226 const OUString* pExistentFields = aExistentFields.getConstArray();
227 const OUString* pExistentFieldsEnd = pExistentFields + aExistentFields.getLength();
229 const OUString sProgrammaticNodeName( "ProgrammaticFieldName" );
230 const OUString sAssignedNodeName( "AssignedFieldName" );
232 for ( ; pExistentFields != pExistentFieldsEnd; ++pExistentFields )
234 #ifdef DBG_UTIL
235 OUString sRedundantProgrammaticName;
236 aFields.openNode( *pExistentFields ).getNodeValue( sProgrammaticNodeName ) >>= sRedundantProgrammaticName;
237 #endif
238 DBG_ASSERT( sRedundantProgrammaticName == *pExistentFields,
239 "fieldmapping::writeTemplateAddressFieldMapping: inconsistent config data!" );
240 // there should be a redundancy in the config data .... if this asserts, there isn't anymore!
242 // do we have a new alias for the programmatic?
243 MapString2String::iterator aPos = aFieldAssignment.find( *pExistentFields );
244 if ( aFieldAssignment.end() != aPos )
245 { // yes
246 // -> set a new value
247 OConfigurationNode aExistentField = aFields.openNode( *pExistentFields );
248 aExistentField.setNodeValue( sAssignedNodeName, makeAny( aPos->second ) );
249 // and remove the mapping entry
250 aFieldAssignment.erase( *pExistentFields );
252 else
253 { // no
254 // -> remove it
255 aFields.removeNode( *pExistentFields );
259 // now everything remaining in aFieldAssignment marks a mapping entry which was not present
260 // in the config before
261 for ( MapString2String::const_iterator aNewMapping = aFieldAssignment.begin();
262 aNewMapping != aFieldAssignment.end();
263 ++aNewMapping
266 DBG_ASSERT( !aFields.hasByName( aNewMapping->first ),
267 "fieldmapping::writeTemplateAddressFieldMapping: inconsistence!" );
268 // in case the config node for the fields already has the node named <aNewMapping->first>,
269 // the entry should have been removed from aNewMapping (in the above loop)
270 OConfigurationNode aNewField = aFields.createNode( aNewMapping->first );
271 aNewField.setNodeValue( sProgrammaticNodeName, makeAny( aNewMapping->first ) );
272 aNewField.setNodeValue( sAssignedNodeName, makeAny( aNewMapping->second ) );
275 // commit the changes done
276 aAddressBookSettings.commit();
280 } // namespace fieldmapping
284 namespace addressconfig
289 void writeTemplateAddressSource( const Reference< XComponentContext >& _rxContext,
290 const OUString& _rDataSourceName, const OUString& _rTableName )
292 // access the configuration information which the driver uses for determining it's column names
294 // create a config node for this
295 OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithComponentContext(
296 _rxContext, sAddressBookNodeName, -1, OConfigurationTreeRoot::CM_UPDATABLE);
298 aAddressBookSettings.setNodeValue( OUString( "DataSourceName" ), makeAny( _rDataSourceName ) );
299 aAddressBookSettings.setNodeValue( OUString( "Command" ), makeAny( _rTableName ) );
300 aAddressBookSettings.setNodeValue( OUString( "CommandType" ), makeAny( (sal_Int32)CommandType::TABLE ) );
302 // commit the changes done
303 aAddressBookSettings.commit();
307 void markPilotSuccess( const Reference< XComponentContext >& _rxContext )
309 // access the configuration information which the driver uses for determining it's column names
311 // create a config node for this
312 OConfigurationTreeRoot aAddressBookSettings = OConfigurationTreeRoot::createWithComponentContext(
313 _rxContext, sAddressBookNodeName, -1, OConfigurationTreeRoot::CM_UPDATABLE);
315 // set the flag
316 aAddressBookSettings.setNodeValue( OUString( "AutoPilotCompleted" ), makeAny( true ) );
318 // commit the changes done
319 aAddressBookSettings.commit();
323 } // namespace addressconfig
327 } // namespace abp
330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */