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 .
22 #include <svtools/addresstemplate.hxx>
23 #include "addresstemplate.hrc"
24 #include <svtools/svtools.hrc>
25 #include <svtools/helpid.hrc>
26 #include <svtools/svtresid.hxx>
27 #include <tools/debug.hxx>
28 #include <comphelper/extract.hxx>
29 #include <comphelper/interaction.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <comphelper/stl_types.hxx>
32 #include <comphelper/string.hxx>
33 #include <vcl/stdtext.hxx>
34 #include <vcl/waitobj.hxx>
35 #include <vcl/msgbox.hxx>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <com/sun/star/ui/dialogs/AddressBookSourcePilot.hpp>
38 #include <com/sun/star/awt/XWindow.hpp>
39 #include <com/sun/star/beans/PropertyValue.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/sdb/DatabaseContext.hpp>
42 #include <com/sun/star/sdb/XCompletedConnection.hpp>
43 #include <com/sun/star/sdb/SQLContext.hpp>
44 #include <com/sun/star/sdbc/SQLWarning.hpp>
45 #include <com/sun/star/sdbc/XConnection.hpp>
46 #include <com/sun/star/task/InteractionHandler.hpp>
47 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
48 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
49 #include <com/sun/star/sdb/CommandType.hpp>
50 #include <svtools/localresaccess.hxx>
51 #include "svl/filenotation.hxx"
52 #include <tools/urlobj.hxx>
55 // .......................................................................
58 // .......................................................................
60 using namespace ::com::sun::star::uno
;
61 using namespace ::com::sun::star::lang
;
62 using namespace ::com::sun::star::container
;
63 using namespace ::com::sun::star::ui::dialogs
;
64 using namespace ::com::sun::star::util
;
65 using namespace ::com::sun::star::beans
;
66 using namespace ::com::sun::star::sdb
;
67 using namespace ::com::sun::star::sdbc
;
68 using namespace ::com::sun::star::sdbcx
;
69 using namespace ::com::sun::star::task
;
70 using namespace ::comphelper
;
71 using namespace ::utl
;
73 typedef std::vector
<OUString
> StringArray
;
74 typedef std::set
<OUString
> StringBag
;
75 DECLARE_STL_USTRINGACCESS_MAP( OUString
, MapString2String
);
79 OUString
lcl_getSelectedDataSource( const ComboBox
& _dataSourceCombo
)
81 OUString selectedDataSource
= _dataSourceCombo
.GetText();
82 if ( _dataSourceCombo
.GetEntryPos( selectedDataSource
) == LISTBOX_ENTRY_NOTFOUND
)
84 // none of the pre-selected entries -> assume a path to a database document
85 OFileNotation
aFileNotation( selectedDataSource
, OFileNotation::N_SYSTEM
);
86 selectedDataSource
= aFileNotation
.get( OFileNotation::N_URL
);
88 return selectedDataSource
;
92 // ===================================================================
94 // ===================================================================
98 virtual ~IAssigmentData();
100 /// the data source to use for the address book
101 virtual OUString
getDatasourceName() const = 0;
103 /// the command to use for the address book
104 virtual OUString
getCommand() const = 0;
106 /** the command type to use for the address book
108 a <type scope="com.sun.star.sdb">CommandType</type> value
110 virtual sal_Int32
getCommandType() const = 0;
112 /// checks whether or not there is an assignment for a given logical field
113 virtual sal_Bool
hasFieldAssignment(const OUString
& _rLogicalName
) = 0;
114 /// retrieves the assignment for a given logical field
115 virtual OUString
getFieldAssignment(const OUString
& _rLogicalName
) = 0;
117 /// set the assignment for a given logical field
118 virtual void setFieldAssignment(const OUString
& _rLogicalName
, const OUString
& _rAssignment
) = 0;
119 /// clear the assignment for a given logical field
120 virtual void clearFieldAssignment(const OUString
& _rLogicalName
) = 0;
122 virtual void setDatasourceName(const OUString
& _rName
) = 0;
123 virtual void setCommand(const OUString
& _rCommand
) = 0;
126 // -------------------------------------------------------------------
127 IAssigmentData::~IAssigmentData()
131 // ===================================================================
132 // = AssigmentTransientData
133 // ===================================================================
134 class AssigmentTransientData
: public IAssigmentData
137 Reference
< XDataSource
> m_xDataSource
;
139 OUString m_sTableName
;
140 MapString2String m_aAliases
;
143 AssigmentTransientData(
144 const Reference
< XDataSource
>& _rxDataSource
,
145 const OUString
& _rDataSourceName
,
146 const OUString
& _rTableName
,
147 const Sequence
< AliasProgrammaticPair
>& _rFields
150 // IAssigmentData overridables
151 virtual OUString
getDatasourceName() const;
152 virtual OUString
getCommand() const;
153 virtual sal_Int32
getCommandType() const;
155 virtual sal_Bool
hasFieldAssignment(const OUString
& _rLogicalName
);
156 virtual OUString
getFieldAssignment(const OUString
& _rLogicalName
);
157 virtual void setFieldAssignment(const OUString
& _rLogicalName
, const OUString
& _rAssignment
);
158 virtual void clearFieldAssignment(const OUString
& _rLogicalName
);
160 virtual void setDatasourceName(const OUString
& _rName
);
161 virtual void setCommand(const OUString
& _rCommand
);
164 // -------------------------------------------------------------------
165 AssigmentTransientData::AssigmentTransientData( const Reference
< XDataSource
>& _rxDataSource
,
166 const OUString
& _rDataSourceName
, const OUString
& _rTableName
,
167 const Sequence
< AliasProgrammaticPair
>& _rFields
)
168 :m_xDataSource( _rxDataSource
)
169 ,m_sDSName( _rDataSourceName
)
170 ,m_sTableName( _rTableName
)
172 // fill our aliaes structure
173 // first collect all known programmatic names
174 StringBag aKnownNames
;
176 OUString
sLogicalFieldNames(SVT_RESSTR(STR_LOGICAL_FIELD_NAMES
));
177 sal_Int32 nIndex
= 0;
180 OUString aToken
= sLogicalFieldNames
.getToken(0, ';', nIndex
);
181 aKnownNames
.insert(aToken
);
183 while ( nIndex
>= 0);
185 // loop throuzh the given names
186 const AliasProgrammaticPair
* pFields
= _rFields
.getConstArray();
187 const AliasProgrammaticPair
* pFieldsEnd
= pFields
+ _rFields
.getLength();
188 for (;pFields
!= pFieldsEnd
; ++pFields
)
190 StringBag::const_iterator aKnownPos
= aKnownNames
.find( pFields
->ProgrammaticName
);
191 if ( aKnownNames
.end() != aKnownPos
)
193 m_aAliases
[ pFields
->ProgrammaticName
] = pFields
->Alias
;
197 OSL_FAIL( ( OString("AssigmentTransientData::AssigmentTransientData: unknown programmatic name (")
198 += OString(pFields
->ProgrammaticName
.getStr(), pFields
->ProgrammaticName
.getLength(), RTL_TEXTENCODING_ASCII_US
)
206 // -------------------------------------------------------------------
207 OUString
AssigmentTransientData::getDatasourceName() const
212 // -------------------------------------------------------------------
213 OUString
AssigmentTransientData::getCommand() const
218 // -------------------------------------------------------------------
219 sal_Int32
AssigmentTransientData::getCommandType() const
221 return CommandType::TABLE
;
224 // -------------------------------------------------------------------
225 sal_Bool
AssigmentTransientData::hasFieldAssignment(const OUString
& _rLogicalName
)
227 ConstMapString2StringIterator aPos
= m_aAliases
.find( _rLogicalName
);
228 return ( m_aAliases
.end() != aPos
)
229 && ( !aPos
->second
.isEmpty() );
232 // -------------------------------------------------------------------
233 OUString
AssigmentTransientData::getFieldAssignment(const OUString
& _rLogicalName
)
236 ConstMapString2StringIterator aPos
= m_aAliases
.find( _rLogicalName
);
237 if ( m_aAliases
.end() != aPos
)
238 sReturn
= aPos
->second
;
243 // -------------------------------------------------------------------
244 void AssigmentTransientData::setFieldAssignment(const OUString
& _rLogicalName
, const OUString
& _rAssignment
)
246 m_aAliases
[ _rLogicalName
] = _rAssignment
;
249 // -------------------------------------------------------------------
250 void AssigmentTransientData::clearFieldAssignment(const OUString
& _rLogicalName
)
252 MapString2StringIterator aPos
= m_aAliases
.find( _rLogicalName
);
253 if ( m_aAliases
.end() != aPos
)
254 m_aAliases
.erase( aPos
);
257 // -------------------------------------------------------------------
258 void AssigmentTransientData::setDatasourceName(const OUString
&)
260 OSL_FAIL( "AssigmentTransientData::setDatasourceName: cannot be implemented for transient data!" );
263 // -------------------------------------------------------------------
264 void AssigmentTransientData::setCommand(const OUString
&)
266 OSL_FAIL( "AssigmentTransientData::setCommand: cannot be implemented for transient data!" );
269 // ===================================================================
270 // = AssignmentPersistentData
271 // ===================================================================
272 class AssignmentPersistentData
273 :public ::utl::ConfigItem
274 ,public IAssigmentData
277 StringBag m_aStoredFields
;
280 ::com::sun::star::uno::Any
281 getProperty(const OUString
& _rLocalName
) const;
282 ::com::sun::star::uno::Any
283 getProperty(const sal_Char
* _pLocalName
) const;
285 OUString
getStringProperty(const sal_Char
* _pLocalName
) const;
286 sal_Int32
getInt32Property(const sal_Char
* _pLocalName
) const;
288 OUString
getStringProperty(const OUString
& _rLocalName
) const;
290 void setStringProperty(const sal_Char
* _pLocalName
, const OUString
& _rValue
);
293 AssignmentPersistentData();
294 ~AssignmentPersistentData();
296 // IAssigmentData overridables
297 virtual OUString
getDatasourceName() const;
298 virtual OUString
getCommand() const;
299 virtual sal_Int32
getCommandType() const;
301 virtual sal_Bool
hasFieldAssignment(const OUString
& _rLogicalName
);
302 virtual OUString
getFieldAssignment(const OUString
& _rLogicalName
);
303 virtual void setFieldAssignment(const OUString
& _rLogicalName
, const OUString
& _rAssignment
);
304 virtual void clearFieldAssignment(const OUString
& _rLogicalName
);
306 virtual void setDatasourceName(const OUString
& _rName
);
307 virtual void setCommand(const OUString
& _rCommand
);
309 virtual void Notify( const com::sun::star::uno::Sequence
<OUString
>& aPropertyNames
);
310 virtual void Commit();
314 void AssignmentPersistentData::Notify( const com::sun::star::uno::Sequence
<OUString
>& )
318 void AssignmentPersistentData::Commit()
322 // -------------------------------------------------------------------
323 AssignmentPersistentData::AssignmentPersistentData()
324 :ConfigItem( OUString( "Office.DataAccess/AddressBook" ))
326 Sequence
< OUString
> aStoredNames
= GetNodeNames(OUString("Fields"));
327 const OUString
* pStoredNames
= aStoredNames
.getConstArray();
328 for (sal_Int32 i
=0; i
<aStoredNames
.getLength(); ++i
, ++pStoredNames
)
329 m_aStoredFields
.insert(*pStoredNames
);
332 // -------------------------------------------------------------------
333 AssignmentPersistentData::~AssignmentPersistentData()
337 // -------------------------------------------------------------------
338 sal_Bool
AssignmentPersistentData::hasFieldAssignment(const OUString
& _rLogicalName
)
340 return (m_aStoredFields
.end() != m_aStoredFields
.find(_rLogicalName
));
343 // -------------------------------------------------------------------
344 OUString
AssignmentPersistentData::getFieldAssignment(const OUString
& _rLogicalName
)
346 OUString sAssignment
;
347 if (hasFieldAssignment(_rLogicalName
))
349 OUString
sFieldPath("Fields/");
350 sFieldPath
+= _rLogicalName
;
351 sFieldPath
+= "/AssignedFieldName";
352 sAssignment
= getStringProperty(sFieldPath
);
357 // -------------------------------------------------------------------
358 Any
AssignmentPersistentData::getProperty(const sal_Char
* _pLocalName
) const
360 return getProperty(OUString::createFromAscii(_pLocalName
));
363 // -------------------------------------------------------------------
364 Any
AssignmentPersistentData::getProperty(const OUString
& _rLocalName
) const
366 Sequence
< OUString
> aProperties(&_rLocalName
, 1);
367 Sequence
< Any
> aValues
= const_cast<AssignmentPersistentData
*>(this)->GetProperties(aProperties
);
368 DBG_ASSERT(aValues
.getLength() == 1, "AssignmentPersistentData::getProperty: invalid sequence length!");
372 // -------------------------------------------------------------------
373 OUString
AssignmentPersistentData::getStringProperty(const OUString
& _rLocalName
) const
376 getProperty( _rLocalName
) >>= sReturn
;
380 // -------------------------------------------------------------------
381 OUString
AssignmentPersistentData::getStringProperty(const sal_Char
* _pLocalName
) const
384 getProperty( _pLocalName
) >>= sReturn
;
388 // -------------------------------------------------------------------
389 sal_Int32
AssignmentPersistentData::getInt32Property(const sal_Char
* _pLocalName
) const
391 sal_Int32 nReturn
= 0;
392 getProperty( _pLocalName
) >>= nReturn
;
396 // -------------------------------------------------------------------
397 void AssignmentPersistentData::setStringProperty(const sal_Char
* _pLocalName
, const OUString
& _rValue
)
399 Sequence
< OUString
> aNames(1);
400 Sequence
< Any
> aValues(1);
401 aNames
[0] = OUString::createFromAscii(_pLocalName
);
402 aValues
[0] <<= _rValue
;
403 PutProperties(aNames
, aValues
);
406 // -------------------------------------------------------------------
407 void AssignmentPersistentData::setFieldAssignment(const OUString
& _rLogicalName
, const OUString
& _rAssignment
)
409 if (_rAssignment
.isEmpty())
411 if (hasFieldAssignment(_rLogicalName
))
413 // the assignment exists but it should be reset
414 clearFieldAssignment(_rLogicalName
);
420 OUString
sDescriptionNodePath("Fields");
423 OUString
sFieldElementNodePath(sDescriptionNodePath
);
424 sFieldElementNodePath
+= "/";
425 sFieldElementNodePath
+= _rLogicalName
;
427 Sequence
< PropertyValue
> aNewFieldDescription(2);
428 // Fields/<field>/ProgrammaticFieldName
429 aNewFieldDescription
[0].Name
= sFieldElementNodePath
+ "/ProgrammaticFieldName";
430 aNewFieldDescription
[0].Value
<<= _rLogicalName
;
431 // Fields/<field>/AssignedFieldName
432 aNewFieldDescription
[1].Name
= sFieldElementNodePath
+ "/AssignedFieldName";
433 aNewFieldDescription
[1].Value
<<= _rAssignment
;
435 // just set the new value
439 SetSetProperties(sDescriptionNodePath
, aNewFieldDescription
);
440 DBG_ASSERT(bSuccess
, "AssignmentPersistentData::setFieldAssignment: could not commit the changes a field!");
443 // -------------------------------------------------------------------
444 void AssignmentPersistentData::clearFieldAssignment(const OUString
& _rLogicalName
)
446 if (!hasFieldAssignment(_rLogicalName
))
450 OUString
sDescriptionNodePath("Fields");
451 Sequence
< OUString
> aNames(&_rLogicalName
, 1);
452 ClearNodeElements(sDescriptionNodePath
, aNames
);
455 // -------------------------------------------------------------------
456 OUString
AssignmentPersistentData::getDatasourceName() const
458 return getStringProperty( "DataSourceName" );
461 // -------------------------------------------------------------------
462 OUString
AssignmentPersistentData::getCommand() const
464 return getStringProperty( "Command" );
467 // -------------------------------------------------------------------
468 void AssignmentPersistentData::setDatasourceName(const OUString
& _rName
)
470 setStringProperty( "DataSourceName", _rName
);
473 // -------------------------------------------------------------------
474 void AssignmentPersistentData::setCommand(const OUString
& _rCommand
)
476 setStringProperty( "Command", _rCommand
);
479 // -------------------------------------------------------------------
480 sal_Int32
AssignmentPersistentData::getCommandType() const
482 return getInt32Property( "CommandType" );
485 // ===================================================================
486 // = AddressBookSourceDialogData
487 // ===================================================================
488 struct AddressBookSourceDialogData
490 FixedText
* pFieldLabels
[FIELD_PAIRS_VISIBLE
* 2];
491 ListBox
* pFields
[FIELD_PAIRS_VISIBLE
* 2];
493 /// when working transient, we need the data source
494 Reference
< XDataSource
>
495 m_xTransientDataSource
;
496 /// current scroll pos in the field list
497 sal_Int32 nFieldScrollPos
;
498 /// the index within m_pFields of the last visible list box. This is redundant, it could be extracted from other members
499 sal_Int32 nLastVisibleListIndex
;
500 /// indicates that we've an odd field number. This member is for efficiency only, it's redundant.
501 sal_Bool bOddFieldNumber
: 1;
502 /// indicates that we're working with the real persistent configuration
503 sal_Bool bWorkingPersistent
: 1;
505 /// the strings to use as labels for the field selection listboxes
506 StringArray aFieldLabels
;
507 // the current field assignment
508 StringArray aFieldAssignments
;
509 /// the logical field names
510 StringArray aLogicalFieldNames
;
512 IAssigmentData
* pConfigData
;
514 // ................................................................
515 AddressBookSourceDialogData( )
517 ,nLastVisibleListIndex(0)
518 ,bOddFieldNumber(sal_False
)
519 ,bWorkingPersistent( sal_True
)
520 ,pConfigData( new AssignmentPersistentData
)
524 // ................................................................
525 AddressBookSourceDialogData( const Reference
< XDataSource
>& _rxTransientDS
, const OUString
& _rDataSourceName
,
526 const OUString
& _rTableName
, const Sequence
< AliasProgrammaticPair
>& _rFields
)
527 :m_xTransientDataSource( _rxTransientDS
)
529 ,nLastVisibleListIndex(0)
530 ,bOddFieldNumber(sal_False
)
531 ,bWorkingPersistent( sal_False
)
532 ,pConfigData( new AssigmentTransientData( m_xTransientDataSource
, _rDataSourceName
, _rTableName
, _rFields
) )
536 ~AddressBookSourceDialogData()
543 // ===================================================================
544 // = AddressBookSourceDialog
545 // ===================================================================
547 // -------------------------------------------------------------------
548 AddressBookSourceDialog::AddressBookSourceDialog(Window
* _pParent
,
549 const Reference
< XComponentContext
>& _rxORB
)
550 : ModalDialog(_pParent
, "AddressTemplateDialog", "svt/ui/addresstemplatedialog.ui")
551 , m_sNoFieldSelection(SVT_RESSTR(STR_NO_FIELD_SELECTION
))
553 , m_pImpl( new AddressBookSourceDialogData
)
558 // -------------------------------------------------------------------
559 AddressBookSourceDialog::AddressBookSourceDialog( Window
* _pParent
, const Reference
< XComponentContext
>& _rxORB
,
560 const Reference
< XDataSource
>& _rxTransientDS
, const OUString
& _rDataSourceName
,
561 const OUString
& _rTable
, const Sequence
< AliasProgrammaticPair
>& _rMapping
)
562 : ModalDialog(_pParent
, "AddressTemplateDialog", "svt/ui/addresstemplatedialog.ui")
563 , m_sNoFieldSelection(SVT_RESSTR(STR_NO_FIELD_SELECTION
))
565 , m_pImpl( new AddressBookSourceDialogData( _rxTransientDS
, _rDataSourceName
, _rTable
, _rMapping
) )
570 // -------------------------------------------------------------------
571 void AddressBookSourceDialog::implConstruct()
573 get(m_pDatasource
, "datasource");
574 get(m_pAdministrateDatasources
, "admin");
575 get(m_pTable
, "datatable");
576 VclScrolledWindow
*pScrollWindow
= get
<VclScrolledWindow
>("scrollwindow");
577 pScrollWindow
->setUserManagedScrolling(true);
578 m_pFieldScroller
= &pScrollWindow
->getVertScrollBar();
580 for (sal_Int32 row
=0; row
<FIELD_PAIRS_VISIBLE
; ++row
)
582 for (sal_Int32 column
=0; column
<2; ++column
)
585 m_pImpl
->pFieldLabels
[row
* 2 + column
] = get
<FixedText
>(OString("label") + OString::number(row
* 2 + column
));
587 m_pImpl
->pFields
[row
* 2 + column
] = get
<ListBox
>(OString("box") + OString::number(row
* 2 + column
));
588 m_pImpl
->pFields
[row
* 2 + column
]->SetSelectHdl(LINK(this, AddressBookSourceDialog
, OnFieldSelect
));
590 m_pImpl
->pFields
[row
* 2 + column
]->SetHelpId("svt/ui/addresstemplatedialog/assign");
594 initializeDatasources();
596 // for the moment, we have a hard coded list of all known fields.
597 // A better solution would be to store all known field translations in the configuration, which could be
598 // extensible by the user in an arbitrary way.
599 // But for the moment we need a quick solution ...
600 // (the main thing would be to store the translations to use here in the user interface, besides that, the code
601 // should be adjustable with a rather small effort.)
603 // initialize the strings for the field labels
604 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_FIRSTNAME
));
605 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_LASTNAME
));
606 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_COMPANY
));
607 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_DEPARTMENT
));
608 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_STREET
));
609 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_ZIPCODE
));
610 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_CITY
));
611 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_STATE
));
612 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_COUNTRY
));
613 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_HOMETEL
));
614 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_WORKTEL
));
615 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_OFFICETEL
));
616 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_MOBILE
));
617 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_TELOTHER
));
618 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_PAGER
));
619 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_FAX
));
620 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_EMAIL
));
621 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_URL
));
622 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_TITLE
));
623 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_POSITION
));
624 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_INITIALS
));
625 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_ADDRFORM
));
626 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_SALUTATION
));
627 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_ID
));
628 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_CALENDAR
));
629 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_INVITE
));
630 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_NOTE
));
631 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_USER1
));
632 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_USER2
));
633 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_USER3
));
634 m_pImpl
->aFieldLabels
.push_back( SVT_RESSTR( STR_FIELD_USER4
));
636 long nLabelWidth
= 0;
637 long nListBoxWidth
= m_pImpl
->pFields
[0]->approximate_char_width() * 20;
638 for (StringArray::const_iterator aI
= m_pImpl
->aFieldLabels
.begin(), aEnd
= m_pImpl
->aFieldLabels
.end(); aI
!= aEnd
; ++aI
)
640 nLabelWidth
= std::max(nLabelWidth
, FixedText::getTextDimensions(m_pImpl
->pFieldLabels
[0], *aI
, 0x7FFFFFFF).Width());
642 for (sal_Int32 row
=0; row
<FIELD_PAIRS_VISIBLE
; ++row
)
644 for (sal_Int32 column
=0; column
<2; ++column
)
646 m_pImpl
->pFieldLabels
[row
* 2 + column
]->set_width_request(nLabelWidth
);
647 m_pImpl
->pFields
[row
* 2 + column
]->set_width_request(nListBoxWidth
);
652 // force a even number of known fields
653 m_pImpl
->bOddFieldNumber
= (m_pImpl
->aFieldLabels
.size() % 2) != 0;
654 if (m_pImpl
->bOddFieldNumber
)
655 m_pImpl
->aFieldLabels
.push_back( OUString() );
657 // limit the scrollbar range accordingly
658 sal_Int32 nOverallFieldPairs
= m_pImpl
->aFieldLabels
.size() / 2;
659 m_pFieldScroller
->SetRange( Range(0, nOverallFieldPairs
- FIELD_PAIRS_VISIBLE
) );
660 m_pFieldScroller
->SetLineSize(1);
661 m_pFieldScroller
->SetPageSize(FIELD_PAIRS_VISIBLE
);
663 // reset the current field assignments
664 m_pImpl
->aFieldAssignments
.resize(m_pImpl
->aFieldLabels
.size());
665 // (empty strings mean "no assignment")
668 m_pFieldScroller
->SetScrollHdl(LINK(this, AddressBookSourceDialog
, OnFieldScroll
));
669 m_pAdministrateDatasources
->SetClickHdl(LINK(this, AddressBookSourceDialog
, OnAdministrateDatasources
));
670 m_pDatasource
->EnableAutocomplete(sal_True
);
671 m_pTable
->EnableAutocomplete(sal_True
);
672 m_pTable
->SetGetFocusHdl(LINK(this, AddressBookSourceDialog
, OnComboGetFocus
));
673 m_pDatasource
->SetGetFocusHdl(LINK(this, AddressBookSourceDialog
, OnComboGetFocus
));
674 m_pTable
->SetLoseFocusHdl(LINK(this, AddressBookSourceDialog
, OnComboLoseFocus
));
675 m_pDatasource
->SetLoseFocusHdl(LINK(this, AddressBookSourceDialog
, OnComboLoseFocus
));
676 m_pTable
->SetSelectHdl(LINK(this, AddressBookSourceDialog
, OnComboSelect
));
677 m_pDatasource
->SetSelectHdl(LINK(this, AddressBookSourceDialog
, OnComboSelect
));
678 get
<OKButton
>("ok")->SetClickHdl(LINK(this, AddressBookSourceDialog
, OnOkClicked
));
680 // initialize the field controls
682 m_pFieldScroller
->SetThumbPos(0);
683 m_pImpl
->nFieldScrollPos
= -1;
684 implScrollFields(0, sal_False
, sal_False
);
687 OUString
sLogicalFieldNames(SVT_RESSTR(STR_LOGICAL_FIELD_NAMES
));
688 sal_Int32 nAdjustedTokenCount
= comphelper::string::getTokenCount(sLogicalFieldNames
, ';') + (m_pImpl
->bOddFieldNumber
? 1 : 0);
689 DBG_ASSERT(nAdjustedTokenCount
== (sal_Int32
)m_pImpl
->aFieldLabels
.size(),
690 "AddressBookSourceDialog::AddressBookSourceDialog: inconsistence between logical and UI field names!");
691 m_pImpl
->aLogicalFieldNames
.reserve(nAdjustedTokenCount
);
692 for (sal_Int32 i
= 0; i
<nAdjustedTokenCount
; ++i
)
693 m_pImpl
->aLogicalFieldNames
.push_back(comphelper::string::getToken(sLogicalFieldNames
, i
, ';'));
695 PostUserEvent(LINK(this, AddressBookSourceDialog
, OnDelayedInitialize
));
696 // so the dialog will at least show up before we do the loading of the
697 // configuration data and the (maybe time consuming) analysis of the data source/table to select
699 if ( !m_pImpl
->bWorkingPersistent
)
701 StyleSettings aSystemStyle
= GetSettings().GetStyleSettings();
702 const ::Color
& rNewColor
= aSystemStyle
.GetDialogColor();
704 m_pDatasource
->SetReadOnly( sal_True
);
705 m_pDatasource
->SetBackground( Wallpaper( rNewColor
) );
706 m_pDatasource
->SetControlBackground( rNewColor
);
708 m_pTable
->SetReadOnly( sal_True
);
709 m_pTable
->SetBackground( Wallpaper( rNewColor
) );
710 m_pTable
->SetControlBackground( rNewColor
);
712 m_pAdministrateDatasources
->Hide( );
716 // -------------------------------------------------------------------
717 void AddressBookSourceDialog::getFieldMapping(Sequence
< AliasProgrammaticPair
>& _rMapping
) const
719 _rMapping
.realloc( m_pImpl
->aLogicalFieldNames
.size() );
720 AliasProgrammaticPair
* pPair
= _rMapping
.getArray();
723 for ( StringArray::const_iterator aProgrammatic
= m_pImpl
->aLogicalFieldNames
.begin();
724 aProgrammatic
!= m_pImpl
->aLogicalFieldNames
.end();
728 sCurrent
= *aProgrammatic
;
729 if ( m_pImpl
->pConfigData
->hasFieldAssignment( sCurrent
) )
731 // the user gave us an assignment for this field
732 pPair
->ProgrammaticName
= *aProgrammatic
;
733 pPair
->Alias
= m_pImpl
->pConfigData
->getFieldAssignment( *aProgrammatic
);
738 _rMapping
.realloc( pPair
- _rMapping
.getArray() );
741 // -------------------------------------------------------------------
742 void AddressBookSourceDialog::loadConfiguration()
744 OUString sName
= m_pImpl
->pConfigData
->getDatasourceName();
745 INetURLObject
aURL( sName
);
746 if( aURL
.GetProtocol() != INET_PROT_NOT_VALID
)
748 OFileNotation
aFileNotation( aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
749 sName
= aFileNotation
.get(OFileNotation::N_SYSTEM
);
752 m_pDatasource
->SetText(sName
);
753 m_pTable
->SetText(m_pImpl
->pConfigData
->getCommand());
754 // we ignore the CommandType: only tables are supported
756 // the logical names for the fields
757 // AddressBookSourceDialog::loadConfiguration: inconsistence between field names and field assignments!
758 assert(m_pImpl
->aLogicalFieldNames
.size() == m_pImpl
->aFieldAssignments
.size());
760 StringArray::const_iterator aLogical
= m_pImpl
->aLogicalFieldNames
.begin();
761 StringArray::iterator aAssignment
= m_pImpl
->aFieldAssignments
.begin();
763 aLogical
!= m_pImpl
->aLogicalFieldNames
.end();
764 ++aLogical
, ++aAssignment
766 *aAssignment
= m_pImpl
->pConfigData
->getFieldAssignment(*aLogical
);
769 // -------------------------------------------------------------------
770 AddressBookSourceDialog::~AddressBookSourceDialog()
775 // -------------------------------------------------------------------
776 void AddressBookSourceDialog::initializeDatasources()
778 if (!m_xDatabaseContext
.is())
780 DBG_ASSERT(m_xORB
.is(), "AddressBookSourceDialog::initializeDatasources: no service factory!");
786 m_xDatabaseContext
= DatabaseContext::create(m_xORB
);
788 catch(const Exception
&) { }
789 if (!m_xDatabaseContext
.is())
791 const OUString
sContextServiceName("com.sun.star.sdb.DatabaseContext");
792 ShowServiceNotAvailableError( this, sContextServiceName
, sal_False
);
796 m_pDatasource
->Clear();
798 // fill the datasources listbox
799 Sequence
< OUString
> aDatasourceNames
;
802 aDatasourceNames
= m_xDatabaseContext
->getElementNames();
806 OSL_FAIL("AddressBookSourceDialog::initializeDatasources: caught an exception while asking for the data source names!");
808 const OUString
* pDatasourceNames
= aDatasourceNames
.getConstArray();
809 const OUString
* pEnd
= pDatasourceNames
+ aDatasourceNames
.getLength();
810 for (; pDatasourceNames
< pEnd
; ++pDatasourceNames
)
811 m_pDatasource
->InsertEntry(*pDatasourceNames
);
814 // -------------------------------------------------------------------
815 IMPL_LINK(AddressBookSourceDialog
, OnFieldScroll
, ScrollBar
*, _pScrollBar
)
817 implScrollFields( _pScrollBar
->GetThumbPos(), sal_True
, sal_True
);
821 // -------------------------------------------------------------------
822 void AddressBookSourceDialog::resetTables()
824 if (!m_xDatabaseContext
.is())
827 WaitObject
aWaitCursor(this);
829 // no matter what we do here, we handled the currently selected data source (no matter if successful or not)
830 m_pDatasource
->SaveValue();
832 // create an interaction handler (may be needed for connecting)
833 Reference
< XInteractionHandler
> xHandler
;
837 InteractionHandler::createWithParent(m_xORB
, 0),
840 catch(const Exception
&) { }
843 const OUString
sInteractionHandlerServiceName("com.sun.star.task.InteractionHandler");
844 ShowServiceNotAvailableError(this, sInteractionHandlerServiceName
, sal_True
);
848 // the currently selected table
849 OUString sOldTable
= m_pTable
->GetText();
853 m_xCurrentDatasourceTables
= NULL
;
855 // get the tables of the connection
856 Sequence
< OUString
> aTableNames
;
860 Reference
< XCompletedConnection
> xDS
;
861 if ( m_pImpl
->bWorkingPersistent
)
863 OUString sSelectedDS
= lcl_getSelectedDataSource(*m_pDatasource
);
865 // get the data source the user has chosen and let it build a connection
866 INetURLObject
aURL( sSelectedDS
);
867 if ( aURL
.GetProtocol() != INET_PROT_NOT_VALID
|| m_xDatabaseContext
->hasByName(sSelectedDS
) )
868 m_xDatabaseContext
->getByName( sSelectedDS
) >>= xDS
;
872 xDS
= xDS
.query( m_pImpl
->m_xTransientDataSource
);
875 // build the connection
876 Reference
< XConnection
> xConn
;
878 xConn
= xDS
->connectWithCompletion(xHandler
);
880 // get the table names
881 Reference
< XTablesSupplier
> xSupplTables(xConn
, UNO_QUERY
);
882 if (xSupplTables
.is())
884 m_xCurrentDatasourceTables
= Reference
< XNameAccess
>(xSupplTables
->getTables(), UNO_QUERY
);
885 if (m_xCurrentDatasourceTables
.is())
886 aTableNames
= m_xCurrentDatasourceTables
->getElementNames();
889 catch(const SQLContext
& e
) { aException
<<= e
; }
890 catch(const SQLWarning
& e
) { aException
<<= e
; }
891 catch(const SQLException
& e
) { aException
<<= e
; }
894 OSL_FAIL("AddressBookSourceDialog::resetTables: could not retrieve the table!");
897 if (aException
.hasValue())
899 Reference
< XInteractionRequest
> xRequest
= new OInteractionRequest(aException
);
902 xHandler
->handle(xRequest
);
904 catch(Exception
&) { }
908 sal_Bool bKnowOldTable
= sal_False
;
909 // fill the table list
910 const OUString
* pTableNames
= aTableNames
.getConstArray();
911 const OUString
* pEnd
= pTableNames
+ aTableNames
.getLength();
912 for (;pTableNames
!= pEnd
; ++pTableNames
)
914 m_pTable
->InsertEntry(*pTableNames
);
915 if (0 == pTableNames
->compareTo(sOldTable
))
916 bKnowOldTable
= sal_True
;
919 // set the old table, if the new data source knows a table with this name, too. Else reset the tables edit field.
921 sOldTable
= OUString();
922 m_pTable
->SetText(sOldTable
);
927 // -------------------------------------------------------------------
928 void AddressBookSourceDialog::resetFields()
930 WaitObject
aWaitCursor(this);
932 // no matter what we do here, we handled the currently selected table (no matter if successful or not)
933 m_pDatasource
->SaveValue();
935 OUString sSelectedTable
= m_pTable
->GetText();
936 Sequence
< OUString
> aColumnNames
;
939 if (m_xCurrentDatasourceTables
.is())
941 // get the table and the columns
942 Reference
< XColumnsSupplier
> xSuppTableCols
;
943 if (m_xCurrentDatasourceTables
->hasByName(sSelectedTable
))
944 ::cppu::extractInterface(xSuppTableCols
, m_xCurrentDatasourceTables
->getByName(sSelectedTable
));
945 Reference
< XNameAccess
> xColumns
;
946 if (xSuppTableCols
.is())
947 xColumns
= xSuppTableCols
->getColumns();
949 aColumnNames
= xColumns
->getElementNames();
952 catch (const Exception
&)
954 OSL_FAIL("AddressBookSourceDialog::resetFields: could not retrieve the table columns!");
958 const OUString
* pColumnNames
= aColumnNames
.getConstArray();
959 const OUString
* pEnd
= pColumnNames
+ aColumnNames
.getLength();
961 // for quicker access
962 ::std::set
< OUString
> aColumnNameSet
;
963 for (pColumnNames
= aColumnNames
.getConstArray(); pColumnNames
!= pEnd
; ++pColumnNames
)
964 aColumnNameSet
.insert(*pColumnNames
);
966 std::vector
<OUString
>::iterator aInitialSelection
= m_pImpl
->aFieldAssignments
.begin() + m_pImpl
->nFieldScrollPos
;
968 ListBox
** pListbox
= m_pImpl
->pFields
;
969 OUString sSaveSelection
;
970 for (sal_Int32 i
=0; i
<FIELD_CONTROLS_VISIBLE
; ++i
, ++pListbox
, ++aInitialSelection
)
972 sSaveSelection
= (*pListbox
)->GetSelectEntry();
974 (*pListbox
)->Clear();
976 // the one entry for "no selection"
977 (*pListbox
)->InsertEntry(m_sNoFieldSelection
, 0);
978 // as it's entry data, set the index of the list box in our array
979 (*pListbox
)->SetEntryData(0, reinterpret_cast<void*>(i
));
982 for (pColumnNames
= aColumnNames
.getConstArray(); pColumnNames
!= pEnd
; ++pColumnNames
)
983 (*pListbox
)->InsertEntry(*pColumnNames
);
985 if (!aInitialSelection
->isEmpty() && (aColumnNameSet
.end() != aColumnNameSet
.find(*aInitialSelection
)))
986 // we can select the entry as specified in our field assignment array
987 (*pListbox
)->SelectEntry(*aInitialSelection
);
989 // try to restore the selection
990 if (aColumnNameSet
.end() != aColumnNameSet
.find(sSaveSelection
))
991 // the old selection is a valid column name
992 (*pListbox
)->SelectEntry(sSaveSelection
);
994 // select the <none> entry
995 (*pListbox
)->SelectEntryPos(0);
998 // adjust m_pImpl->aFieldAssignments
999 for ( StringArray::iterator aAdjust
= m_pImpl
->aFieldAssignments
.begin();
1000 aAdjust
!= m_pImpl
->aFieldAssignments
.end();
1003 if (!aAdjust
->isEmpty())
1004 if (aColumnNameSet
.end() == aColumnNameSet
.find(*aAdjust
))
1008 // -------------------------------------------------------------------
1009 IMPL_LINK(AddressBookSourceDialog
, OnFieldSelect
, ListBox
*, _pListbox
)
1011 // the index of the affected list box in our array
1012 sal_IntPtr nListBoxIndex
= reinterpret_cast<sal_IntPtr
>(_pListbox
->GetEntryData(0));
1013 DBG_ASSERT(nListBoxIndex
>= 0 && nListBoxIndex
< FIELD_CONTROLS_VISIBLE
,
1014 "AddressBookSourceDialog::OnFieldScroll: invalid list box entry!");
1016 // update the array where we remember the field selections
1017 if (0 == _pListbox
->GetSelectEntryPos())
1018 // it's the "no field selection" entry
1019 m_pImpl
->aFieldAssignments
[m_pImpl
->nFieldScrollPos
* 2 + nListBoxIndex
] = "";
1021 // it's a regular field entry
1022 m_pImpl
->aFieldAssignments
[m_pImpl
->nFieldScrollPos
* 2 + nListBoxIndex
] = _pListbox
->GetSelectEntry();
1027 // -------------------------------------------------------------------
1028 void AddressBookSourceDialog::implScrollFields(sal_Int32 _nPos
, sal_Bool _bAdjustFocus
, sal_Bool _bAdjustScrollbar
)
1030 if (_nPos
== m_pImpl
->nFieldScrollPos
)
1034 // loop through our field control rows and do some adjustments
1035 // for the new texts
1036 FixedText
** pLeftLabelControl
= m_pImpl
->pFieldLabels
;
1037 FixedText
** pRightLabelControl
= pLeftLabelControl
+ 1;
1038 StringArray::const_iterator pLeftColumnLabel
= m_pImpl
->aFieldLabels
.begin() + 2 * _nPos
;
1039 StringArray::const_iterator pRightColumnLabel
= pLeftColumnLabel
+ 1;
1041 // for the focus movement and the selection scroll
1042 ListBox
** pLeftListControl
= m_pImpl
->pFields
;
1043 ListBox
** pRightListControl
= pLeftListControl
+ 1;
1045 // for the focus movement
1046 sal_Int32 nOldFocusRow
= -1;
1047 sal_Int32 nOldFocusColumn
= 0;
1049 // for the selection scroll
1050 StringArray::const_iterator pLeftAssignment
= m_pImpl
->aFieldAssignments
.begin() + 2 * _nPos
;
1051 StringArray::const_iterator pRightAssignment
= pLeftAssignment
+ 1;
1053 m_pImpl
->nLastVisibleListIndex
= -1;
1055 for (sal_Int32 i
=0; i
<FIELD_PAIRS_VISIBLE
; ++i
)
1057 if ((*pLeftListControl
)->HasChildPathFocus())
1060 nOldFocusColumn
= 0;
1062 else if ((*pRightListControl
)->HasChildPathFocus())
1065 nOldFocusColumn
= 1;
1068 // the new texts of the label controls
1069 (*pLeftLabelControl
)->SetText(*pLeftColumnLabel
);
1070 (*pRightLabelControl
)->SetText(*pRightColumnLabel
);
1072 // we may have to hide the controls in the right column, if we have no label text for it
1073 // (which means we have an odd number of fields, though we forced our internal arrays to
1074 // be even-sized for easier handling)
1075 // (If sometimes we support an arbitrary number of field assignments, we would have to care for
1076 // an invisible left hand side column, too. But right now, the left hand side controls are always
1078 sal_Bool bHideRightColumn
= pRightColumnLabel
->isEmpty();
1079 (*pRightLabelControl
)->Show(!bHideRightColumn
);
1080 (*pRightListControl
)->Show(!bHideRightColumn
);
1081 // the new selections of the listboxes
1082 implSelectField(*pLeftListControl
, *pLeftAssignment
);
1083 implSelectField(*pRightListControl
, *pRightAssignment
);
1085 // the index of the last visible list box
1086 ++m_pImpl
->nLastVisibleListIndex
; // the left hand side box is always visible
1087 if (!bHideRightColumn
)
1088 ++m_pImpl
->nLastVisibleListIndex
;
1091 if ( i
< FIELD_PAIRS_VISIBLE
- 1 )
1092 { // (not in the very last round, here the +=2 could result in an invalid
1093 // iterator position, which causes an abort in a non-product version
1094 pLeftLabelControl
+= 2;
1095 pRightLabelControl
+= 2;
1096 pLeftColumnLabel
+= 2;
1097 pRightColumnLabel
+= 2;
1099 pLeftListControl
+= 2;
1100 pRightListControl
+= 2;
1101 pLeftAssignment
+= 2;
1102 pRightAssignment
+= 2;
1106 if (_bAdjustFocus
&& (nOldFocusRow
>= 0))
1107 { // we have to adjust the focus and one of the list boxes has the focus
1108 sal_Int32 nDelta
= m_pImpl
->nFieldScrollPos
- _nPos
;
1109 // the new row for the focus
1110 sal_Int32 nNewFocusRow
= nOldFocusRow
+ nDelta
;
1112 nNewFocusRow
= std::min(nNewFocusRow
, (sal_Int32
)(FIELD_PAIRS_VISIBLE
- 1), ::std::less
< sal_Int32
>());
1113 nNewFocusRow
= std::max(nNewFocusRow
, (sal_Int32
)0, ::std::less
< sal_Int32
>());
1114 // set the new focus (in the same column)
1115 m_pImpl
->pFields
[nNewFocusRow
* 2 + nOldFocusColumn
]->GrabFocus();
1118 m_pImpl
->nFieldScrollPos
= _nPos
;
1120 if (_bAdjustScrollbar
)
1121 m_pFieldScroller
->SetThumbPos(m_pImpl
->nFieldScrollPos
);
1124 // -------------------------------------------------------------------
1125 void AddressBookSourceDialog::implSelectField(ListBox
* _pBox
, const OUString
& _rText
)
1127 if (!_rText
.isEmpty())
1128 // a valid field name
1129 _pBox
->SelectEntry(_rText
);
1131 // no selection for this item
1132 _pBox
->SelectEntryPos(0);
1135 // -------------------------------------------------------------------
1136 IMPL_LINK_NOARG(AddressBookSourceDialog
, OnDelayedInitialize
)
1138 // load the initial data from the configuration
1139 loadConfiguration();
1141 // will reset the tables/fields implicitly
1143 if ( !m_pImpl
->bWorkingPersistent
)
1144 if ( m_pImpl
->pFields
[0] )
1145 m_pImpl
->pFields
[0]->GrabFocus();
1150 // -------------------------------------------------------------------
1151 IMPL_LINK(AddressBookSourceDialog
, OnComboSelect
, ComboBox
*, _pBox
)
1153 if (_pBox
== m_pDatasource
)
1160 // -------------------------------------------------------------------
1161 IMPL_LINK(AddressBookSourceDialog
, OnComboGetFocus
, ComboBox
*, _pBox
)
1167 // -------------------------------------------------------------------
1168 IMPL_LINK(AddressBookSourceDialog
, OnComboLoseFocus
, ComboBox
*, _pBox
)
1170 if (_pBox
->GetSavedValue() != _pBox
->GetText())
1172 if (_pBox
== m_pDatasource
)
1180 // -------------------------------------------------------------------
1181 IMPL_LINK_NOARG(AddressBookSourceDialog
, OnOkClicked
)
1183 OUString sSelectedDS
= lcl_getSelectedDataSource(*m_pDatasource
);
1184 if ( m_pImpl
->bWorkingPersistent
)
1186 m_pImpl
->pConfigData
->setDatasourceName(sSelectedDS
);
1187 m_pImpl
->pConfigData
->setCommand(m_pTable
->GetText());
1190 // AddressBookSourceDialog::loadConfiguration: inconsistence between field names and field assignments!
1191 assert(m_pImpl
->aLogicalFieldNames
.size() == m_pImpl
->aFieldAssignments
.size());
1193 // set the field assignments
1194 StringArray::const_iterator aLogical
= m_pImpl
->aLogicalFieldNames
.begin();
1195 StringArray::const_iterator aAssignment
= m_pImpl
->aFieldAssignments
.begin();
1197 aLogical
!= m_pImpl
->aLogicalFieldNames
.end();
1198 ++aLogical
, ++aAssignment
1200 m_pImpl
->pConfigData
->setFieldAssignment(*aLogical
, *aAssignment
);
1207 // -------------------------------------------------------------------
1208 IMPL_LINK_NOARG(AddressBookSourceDialog
, OnAdministrateDatasources
)
1210 // create the dialog object
1211 Reference
< XExecutableDialog
> xAdminDialog
;
1214 xAdminDialog
= AddressBookSourcePilot::createWithParent( m_xORB
, VCLUnoHelper::GetInterface(this) );
1216 catch(const Exception
&) { }
1217 if (!xAdminDialog
.is())
1219 ShowServiceNotAvailableError(this, OUString("com.sun.star.ui.dialogs.AddressBookSourcePilot"), sal_True
);
1223 // excute the dialog
1226 if ( xAdminDialog
->execute() == RET_OK
)
1228 Reference
<XPropertySet
> xProp(xAdminDialog
,UNO_QUERY
);
1232 xProp
->getPropertyValue("DataSourceName") >>= sName
;
1234 INetURLObject
aURL( sName
);
1235 if( aURL
.GetProtocol() != INET_PROT_NOT_VALID
)
1237 OFileNotation
aFileNotation( aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
1238 sName
= aFileNotation
.get(OFileNotation::N_SYSTEM
);
1240 m_pDatasource
->InsertEntry(sName
);
1241 delete m_pImpl
->pConfigData
;
1242 m_pImpl
->pConfigData
= new AssignmentPersistentData();
1243 loadConfiguration();
1245 // will reset the fields implicitly
1249 catch(const Exception
&)
1251 OSL_FAIL("AddressBookSourceDialog::OnAdministrateDatasources: an error occurred while executing the administration dialog!");
1254 // re-fill the data source list
1255 // try to preserve the current selection
1257 // initializeDatasources();
1262 // -------------------------------------------------------------------
1263 long AddressBookSourceDialog::PreNotify( NotifyEvent
& _rNEvt
)
1265 switch (_rNEvt
.GetType())
1267 case EVENT_KEYINPUT
:
1269 const KeyEvent
* pKeyEvent
= _rNEvt
.GetKeyEvent();
1270 sal_uInt16 nCode
= pKeyEvent
->GetKeyCode().GetCode();
1271 sal_Bool bShift
= pKeyEvent
->GetKeyCode().IsShift();
1272 sal_Bool bCtrl
= pKeyEvent
->GetKeyCode().IsMod1();
1273 sal_Bool bAlt
= pKeyEvent
->GetKeyCode().IsMod2();
1275 if (KEY_TAB
== nCode
)
1276 { // somebody pressed the tab key
1277 if (!bAlt
&& !bCtrl
&& !bShift
)
1278 { // it's really the only the key (no modifiers)
1279 if (m_pImpl
->pFields
[m_pImpl
->nLastVisibleListIndex
]->HasChildPathFocus())
1280 // the last of our visible list boxes has the focus
1281 if (m_pImpl
->nFieldScrollPos
< m_pFieldScroller
->GetRangeMax())
1282 { // we can still scroll down
1283 sal_Int32 nNextFocusList
= m_pImpl
->nLastVisibleListIndex
+ 1 - 2;
1285 implScrollFields(m_pImpl
->nFieldScrollPos
+ 1, sal_False
, sal_True
);
1286 // give the left control in the "next" line the focus
1287 m_pImpl
->pFields
[nNextFocusList
]->GrabFocus();
1288 // return saying "have handled this"
1292 else if (!bAlt
&& !bCtrl
&& bShift
)
1294 if (m_pImpl
->pFields
[0]->HasChildPathFocus())
1295 // our first list box has the focus
1296 if (m_pImpl
->nFieldScrollPos
> 0)
1297 { // we can still scroll up
1299 implScrollFields(m_pImpl
->nFieldScrollPos
- 1, sal_False
, sal_True
);
1300 // give the right control in the "prebious" line the focus
1301 m_pImpl
->pFields
[0 - 1 + 2]->GrabFocus();
1302 // return saying "have handled this"
1310 return ModalDialog::PreNotify(_rNEvt
);
1313 // .......................................................................
1315 // .......................................................................
1317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */