1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
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
61 bool invokeDialog( const Reference
< XComponentContext
>& _rxORB
, class vcl::Window
* _pParent
,
62 const Reference
< XPropertySet
>& _rxDataSource
, AddressSettings
& _rSettings
)
64 _rSettings
.aFieldMapping
.clear();
66 DBG_ASSERT( _rxORB
.is(), "fieldmapping::invokeDialog: invalid service factory!" );
67 DBG_ASSERT( _rxDataSource
.is(), "fieldmapping::invokeDialog: invalid data source!" );
68 if ( !_rxORB
.is() || !_rxDataSource
.is() )
74 // create an instance of the dialog service
75 Reference
< XWindow
> xDialogParent
= VCLUnoHelper::GetInterface( _pParent
);
76 OUString
sTitle(ModuleRes(RID_STR_FIELDDIALOGTITLE
));
77 Reference
< XExecutableDialog
> xDialog
= AddressBookSourceDialog::createWithDataSource(_rxORB
,
81 _rSettings
.bRegisterDataSource
? _rSettings
.sRegisteredDataSourceName
: _rSettings
.sDataSourceName
,
83 _rSettings
.sSelectedTable
,
87 if ( xDialog
->execute() )
89 // retrieve the field mapping as set by he user
90 Reference
< XPropertySet
> xDialogProps( xDialog
, UNO_QUERY
);
92 Sequence
< AliasProgrammaticPair
> aMapping
;
94 xDialogProps
->getPropertyValue("FieldMapping") >>= aMapping
;
95 DBG_ASSERT( bSuccess
, "fieldmapping::invokeDialog: invalid property type for FieldMapping!" );
97 // and copy it into the map
98 const AliasProgrammaticPair
* pMapping
= aMapping
.getConstArray();
99 const AliasProgrammaticPair
* pMappingEnd
= pMapping
+ aMapping
.getLength();
100 for (;pMapping
!= pMappingEnd
; ++pMapping
)
101 _rSettings
.aFieldMapping
[ pMapping
->ProgrammaticName
] = pMapping
->Alias
;
107 catch(const Exception
&)
109 OSL_FAIL("fieldmapping::invokeDialog: caught an exception while executing the dialog!");
115 void defaultMapping( const Reference
< XComponentContext
>& _rxContext
, MapString2String
& _rFieldAssignment
)
117 _rFieldAssignment
.clear();
122 // a) For the address data source, we need a mapping from programmatic names (1) to real column names
123 // b) The SDBC driver has a fixed set of columns, which, when returned, are named according to
124 // some configuration entries. E.g., the driver displays the field which it knows contains
125 // the first name as "First Name" - the latter string is stored in the config.
126 // For this, the driver uses programmatic names, too, but they differ from the programmatic names the
127 // template documents have.
128 // So what we need first is a mapping from programmatic names (1) to programmatic names (2)
129 const sal_Char
* pMappingProgrammatics
[] =
131 "FirstName", "FirstName",
132 "LastName", "LastName",
133 "Street", "HomeAddress",
134 "Zip", "HomeZipCode",
136 "State", "HomeState",
137 "Country", "HomeCountry",
138 "PhonePriv", "HomePhone",
139 "PhoneComp", "WorkPhone",
140 "PhoneCell", "CellularNumber",
141 "Pager", "PagerNumber",
143 "EMail", "PrimaryEmail",
146 "Altfield1", "Custom1",
147 "Altfield2", "Custom2",
148 "Altfield3", "Custom3",
149 "Altfield4", "Custom4",
151 "Company", "Company",
152 "Department", "Department"
154 // (this list is not complete: both lists of programmatic names are larger in real,
155 // but this list above is the intersection)
158 // access the configuration information which the driver uses for determining its column names
159 OUString
sDriverAliasesNodeName(
160 OUStringLiteral(sDriverSettingsNodeName
)
163 // create a config node for this
164 OConfigurationTreeRoot aDriverFieldAliasing
= OConfigurationTreeRoot::createWithComponentContext(
165 _rxContext
, sDriverAliasesNodeName
, -1, OConfigurationTreeRoot::CM_READONLY
);
167 // loop through all programmatic pairs
168 DBG_ASSERT( 0 == SAL_N_ELEMENTS( pMappingProgrammatics
) % 2,
169 "fieldmapping::defaultMapping: invalid programmatic map!" );
171 sal_Int32 nIntersectedProgrammatics
= SAL_N_ELEMENTS( pMappingProgrammatics
) / 2;
173 const sal_Char
** pProgrammatic
= pMappingProgrammatics
;
174 OUString sAddressProgrammatic
;
175 OUString sDriverProgrammatic
;
178 i
< nIntersectedProgrammatics
;
182 sAddressProgrammatic
= OUString::createFromAscii( *pProgrammatic
++ );
183 sDriverProgrammatic
= OUString::createFromAscii( *pProgrammatic
++ );
185 if ( aDriverFieldAliasing
.hasByName( sDriverProgrammatic
) )
187 aDriverFieldAliasing
.getNodeValue( sDriverProgrammatic
) >>= sDriverUI
;
188 if ( 0 == sDriverUI
.getLength() )
190 OSL_FAIL( "fieldmapping::defaultMapping: invalid driver UI column name!");
193 _rFieldAssignment
[ sAddressProgrammatic
] = sDriverUI
;
197 OSL_FAIL( "fieldmapping::defaultMapping: invalid driver programmatic name!" );
201 catch( const Exception
& )
203 OSL_FAIL("fieldmapping::defaultMapping: code is assumed to throw no exceptions!");
204 // the config nodes we're using herein should not do this ....
209 void writeTemplateAddressFieldMapping( const Reference
< XComponentContext
>& _rxContext
, const MapString2String
& _rFieldAssignment
)
211 // want to have a non-const map for easier handling
212 MapString2String
aFieldAssignment( _rFieldAssignment
);
214 // access the configuration information which the driver uses for determining its column names
216 // create a config node for this
217 OConfigurationTreeRoot aAddressBookSettings
= OConfigurationTreeRoot::createWithComponentContext(
218 _rxContext
, sAddressBookNodeName
);
220 OConfigurationNode aFields
= aAddressBookSettings
.openNode( OUString( "Fields" ) );
222 // loop through all existent fields
223 Sequence
< OUString
> aExistentFields
= aFields
.getNodeNames();
224 const OUString
* pExistentFields
= aExistentFields
.getConstArray();
225 const OUString
* pExistentFieldsEnd
= pExistentFields
+ aExistentFields
.getLength();
227 const OUString
sProgrammaticNodeName( "ProgrammaticFieldName" );
228 const OUString
sAssignedNodeName( "AssignedFieldName" );
230 for ( ; pExistentFields
!= pExistentFieldsEnd
; ++pExistentFields
)
233 ((aFields
.openNode(*pExistentFields
)
234 .getNodeValue(sProgrammaticNodeName
).get
<OUString
>())
235 != *pExistentFields
),
236 "extensions.abpilot",
237 "fieldmapping::writeTemplateAddressFieldMapping: inconsistent config data!");
238 // there should be a redundancy in the config data .... if this asserts, there isn't anymore!
240 // do we have a new alias for the programmatic?
241 MapString2String::iterator aPos
= aFieldAssignment
.find( *pExistentFields
);
242 if ( aFieldAssignment
.end() != aPos
)
244 // -> set a new value
245 OConfigurationNode aExistentField
= aFields
.openNode( *pExistentFields
);
246 aExistentField
.setNodeValue( sAssignedNodeName
, makeAny( aPos
->second
) );
247 // and remove the mapping entry
248 aFieldAssignment
.erase( *pExistentFields
);
253 aFields
.removeNode( *pExistentFields
);
257 // now everything remaining in aFieldAssignment marks a mapping entry which was not present
258 // in the config before
259 for ( MapString2String::const_iterator aNewMapping
= aFieldAssignment
.begin();
260 aNewMapping
!= aFieldAssignment
.end();
264 DBG_ASSERT( !aFields
.hasByName( aNewMapping
->first
),
265 "fieldmapping::writeTemplateAddressFieldMapping: inconsistence!" );
266 // in case the config node for the fields already has the node named <aNewMapping->first>,
267 // the entry should have been removed from aNewMapping (in the above loop)
268 OConfigurationNode aNewField
= aFields
.createNode( aNewMapping
->first
);
269 aNewField
.setNodeValue( sProgrammaticNodeName
, makeAny( aNewMapping
->first
) );
270 aNewField
.setNodeValue( sAssignedNodeName
, makeAny( aNewMapping
->second
) );
273 // commit the changes done
274 aAddressBookSettings
.commit();
278 } // namespace fieldmapping
281 namespace addressconfig
285 void writeTemplateAddressSource( const Reference
< XComponentContext
>& _rxContext
,
286 const OUString
& _rDataSourceName
, const OUString
& _rTableName
)
288 // access the configuration information which the driver uses for determining its column names
290 // create a config node for this
291 OConfigurationTreeRoot aAddressBookSettings
= OConfigurationTreeRoot::createWithComponentContext(
292 _rxContext
, sAddressBookNodeName
);
294 aAddressBookSettings
.setNodeValue( OUString( "DataSourceName" ), makeAny( _rDataSourceName
) );
295 aAddressBookSettings
.setNodeValue( OUString( "Command" ), makeAny( _rTableName
) );
296 aAddressBookSettings
.setNodeValue( OUString( "CommandType" ), makeAny( (sal_Int16
)CommandType::TABLE
) );
298 // commit the changes done
299 aAddressBookSettings
.commit();
303 void markPilotSuccess( const Reference
< XComponentContext
>& _rxContext
)
305 // access the configuration information which the driver uses for determining its column names
307 // create a config node for this
308 OConfigurationTreeRoot aAddressBookSettings
= OConfigurationTreeRoot::createWithComponentContext(
309 _rxContext
, sAddressBookNodeName
);
312 aAddressBookSettings
.setNodeValue( OUString( "AutoPilotCompleted" ), makeAny( true ) );
314 // commit the changes done
315 aAddressBookSettings
.commit();
319 } // namespace addressconfig
325 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */