1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: addresstemplate.cxx,v $
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_svtools.hxx"
37 #include "addresstemplate.hxx"
38 #ifndef _SVT_ADDRESSTEMPLATE_HRC_
39 #include "addresstemplate.hrc"
42 #include <svtools/svtools.hrc>
44 #ifndef _SVT_HELPID_HRC
45 #include <svtools/helpid.hrc>
47 #include <svtools/svtdata.hxx>
48 #include <tools/debug.hxx>
49 #include <comphelper/processfactory.hxx>
50 #include <comphelper/stl_types.hxx>
51 #include <vcl/stdtext.hxx>
52 #include <vcl/waitobj.hxx>
53 #include <vcl/msgbox.hxx>
54 #include <toolkit/helper/vclunohelper.hxx>
55 #ifndef _CPPUHELPER_EXTRACT_HXX_
56 #include <cppuhelper/extract.hxx>
58 #include <comphelper/interaction.hxx>
59 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
60 #include <com/sun/star/awt/XWindow.hpp>
61 #include <com/sun/star/beans/PropertyValue.hpp>
62 #include <com/sun/star/beans/XPropertySet.hpp>
63 #include <com/sun/star/sdb/XCompletedConnection.hpp>
64 #include <com/sun/star/sdb/SQLContext.hpp>
65 #include <com/sun/star/sdbc/SQLWarning.hpp>
66 #include <com/sun/star/sdbc/XConnection.hpp>
67 #include <com/sun/star/task/XInteractionHandler.hpp>
68 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
69 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
70 #include <com/sun/star/sdb/CommandType.hpp>
71 #include "localresaccess.hxx"
72 #ifndef SVTOOLS_FILENOTATION_HXX_
73 #include "filenotation.hxx"
75 #include <tools/urlobj.hxx>
79 // .......................................................................
82 // .......................................................................
84 using namespace ::com::sun::star::uno
;
85 using namespace ::com::sun::star::lang
;
86 using namespace ::com::sun::star::container
;
87 using namespace ::com::sun::star::ui::dialogs
;
88 using namespace ::com::sun::star::util
;
89 using namespace ::com::sun::star::beans
;
90 using namespace ::com::sun::star::sdb
;
91 using namespace ::com::sun::star::sdbc
;
92 using namespace ::com::sun::star::sdbcx
;
93 using namespace ::com::sun::star::task
;
94 using namespace ::comphelper
;
95 using namespace ::utl
;
97 DECLARE_STL_VECTOR( String
, StringArray
);
98 DECLARE_STL_STDKEY_SET( ::rtl::OUString
, StringBag
);
99 DECLARE_STL_USTRINGACCESS_MAP( ::rtl::OUString
, MapString2String
);
103 String
lcl_getSelectedDataSource( const ComboBox
& _dataSourceCombo
)
105 String selectedDataSource
= _dataSourceCombo
.GetText();
106 if ( _dataSourceCombo
.GetEntryPos( selectedDataSource
) == LISTBOX_ENTRY_NOTFOUND
)
108 // none of the pre-selected entries -> assume a path to a database document
109 OFileNotation
aFileNotation( selectedDataSource
, OFileNotation::N_SYSTEM
);
110 selectedDataSource
= aFileNotation
.get( OFileNotation::N_URL
);
112 return selectedDataSource
;
116 // ===================================================================
118 // ===================================================================
122 virtual ~IAssigmentData();
124 /// the data source to use for the address book
125 virtual ::rtl::OUString
getDatasourceName() const = 0;
127 /// the command to use for the address book
128 virtual ::rtl::OUString
getCommand() const = 0;
130 /** the command type to use for the address book
132 a <type scope="com.sun.star.sdb">CommandType</type> value
134 virtual sal_Int32
getCommandType() const = 0;
136 /// checks whether or not there is an assignment for a given logical field
137 virtual sal_Bool
hasFieldAssignment(const ::rtl::OUString
& _rLogicalName
) = 0;
138 /// retrieves the assignment for a given logical field
139 virtual ::rtl::OUString
getFieldAssignment(const ::rtl::OUString
& _rLogicalName
) = 0;
141 /// set the assignment for a given logical field
142 virtual void setFieldAssignment(const ::rtl::OUString
& _rLogicalName
, const ::rtl::OUString
& _rAssignment
) = 0;
143 /// clear the assignment for a given logical field
144 virtual void clearFieldAssignment(const ::rtl::OUString
& _rLogicalName
) = 0;
146 virtual void setDatasourceName(const ::rtl::OUString
& _rName
) = 0;
147 virtual void setCommand(const ::rtl::OUString
& _rCommand
) = 0;
150 // -------------------------------------------------------------------
151 IAssigmentData::~IAssigmentData()
155 // ===================================================================
156 // = AssigmentTransientData
157 // ===================================================================
158 class AssigmentTransientData
: public IAssigmentData
161 Reference
< XDataSource
> m_xDataSource
;
162 ::rtl::OUString m_sDSName
;
163 ::rtl::OUString m_sTableName
;
164 MapString2String m_aAliases
;
167 AssigmentTransientData(
168 const Reference
< XDataSource
>& _rxDataSource
,
169 const ::rtl::OUString
& _rDataSourceName
,
170 const ::rtl::OUString
& _rTableName
,
171 const Sequence
< AliasProgrammaticPair
>& _rFields
174 // IAssigmentData overridables
175 virtual ::rtl::OUString
getDatasourceName() const;
176 virtual ::rtl::OUString
getCommand() const;
177 virtual sal_Int32
getCommandType() const;
179 virtual sal_Bool
hasFieldAssignment(const ::rtl::OUString
& _rLogicalName
);
180 virtual ::rtl::OUString
getFieldAssignment(const ::rtl::OUString
& _rLogicalName
);
181 virtual void setFieldAssignment(const ::rtl::OUString
& _rLogicalName
, const ::rtl::OUString
& _rAssignment
);
182 virtual void clearFieldAssignment(const ::rtl::OUString
& _rLogicalName
);
184 virtual void setDatasourceName(const ::rtl::OUString
& _rName
);
185 virtual void setCommand(const ::rtl::OUString
& _rCommand
);
188 // -------------------------------------------------------------------
189 AssigmentTransientData::AssigmentTransientData( const Reference
< XDataSource
>& _rxDataSource
,
190 const ::rtl::OUString
& _rDataSourceName
, const ::rtl::OUString
& _rTableName
,
191 const Sequence
< AliasProgrammaticPair
>& _rFields
)
192 :m_xDataSource( _rxDataSource
)
193 ,m_sDSName( _rDataSourceName
)
194 ,m_sTableName( _rTableName
)
196 // fill our aliaes structure
197 // first collect all known programmatic names
198 StringBag aKnownNames
;
200 String
sLogicalFieldNames( SvtResId( STR_LOCAGICAL_FIELD_NAMES
) );
201 sal_Int32 nTokenCount
= sLogicalFieldNames
.GetTokenCount(';');
202 for (sal_Int32 i
= 0; i
<nTokenCount
; ++i
)
203 aKnownNames
.insert(sLogicalFieldNames
.GetToken((sal_uInt16
)i
, ';'));
205 // loop throuzh the given names
206 const AliasProgrammaticPair
* pFields
= _rFields
.getConstArray();
207 for (;pFields
!= pFields
; ++pFields
)
209 StringBagIterator aKnownPos
= aKnownNames
.find( pFields
->ProgrammaticName
);
210 if ( aKnownNames
.end() != aKnownPos
)
212 m_aAliases
[ pFields
->ProgrammaticName
] = pFields
->Alias
;
216 DBG_ERROR ( ( ::rtl::OString("AssigmentTransientData::AssigmentTransientData: unknown programmatic name (")
217 += ::rtl::OString(pFields
->ProgrammaticName
.getStr(), pFields
->ProgrammaticName
.getLength(), RTL_TEXTENCODING_ASCII_US
)
218 += ::rtl::OString(")!")
225 // -------------------------------------------------------------------
226 ::rtl::OUString
AssigmentTransientData::getDatasourceName() const
231 // -------------------------------------------------------------------
232 ::rtl::OUString
AssigmentTransientData::getCommand() const
237 // -------------------------------------------------------------------
238 sal_Int32
AssigmentTransientData::getCommandType() const
240 return CommandType::TABLE
;
243 // -------------------------------------------------------------------
244 sal_Bool
AssigmentTransientData::hasFieldAssignment(const ::rtl::OUString
& _rLogicalName
)
246 ConstMapString2StringIterator aPos
= m_aAliases
.find( _rLogicalName
);
247 return ( m_aAliases
.end() != aPos
)
248 && ( aPos
->second
.getLength() );
251 // -------------------------------------------------------------------
252 ::rtl::OUString
AssigmentTransientData::getFieldAssignment(const ::rtl::OUString
& _rLogicalName
)
254 ::rtl::OUString sReturn
;
255 ConstMapString2StringIterator aPos
= m_aAliases
.find( _rLogicalName
);
256 if ( m_aAliases
.end() != aPos
)
257 sReturn
= aPos
->second
;
262 // -------------------------------------------------------------------
263 void AssigmentTransientData::setFieldAssignment(const ::rtl::OUString
& _rLogicalName
, const ::rtl::OUString
& _rAssignment
)
265 m_aAliases
[ _rLogicalName
] = _rAssignment
;
268 // -------------------------------------------------------------------
269 void AssigmentTransientData::clearFieldAssignment(const ::rtl::OUString
& _rLogicalName
)
271 MapString2StringIterator aPos
= m_aAliases
.find( _rLogicalName
);
272 if ( m_aAliases
.end() != aPos
)
273 m_aAliases
.erase( aPos
);
276 // -------------------------------------------------------------------
277 void AssigmentTransientData::setDatasourceName(const ::rtl::OUString
&)
279 DBG_ERROR( "AssigmentTransientData::setDatasourceName: cannot be implemented for transient data!" );
282 // -------------------------------------------------------------------
283 void AssigmentTransientData::setCommand(const ::rtl::OUString
&)
285 DBG_ERROR( "AssigmentTransientData::setCommand: cannot be implemented for transient data!" );
288 // ===================================================================
289 // = AssignmentPersistentData
290 // ===================================================================
291 class AssignmentPersistentData
292 :public ::utl::ConfigItem
293 ,public IAssigmentData
296 StringBag m_aStoredFields
;
299 ::com::sun::star::uno::Any
300 getProperty(const ::rtl::OUString
& _rLocalName
) const;
301 ::com::sun::star::uno::Any
302 getProperty(const sal_Char
* _pLocalName
) const;
304 ::rtl::OUString
getStringProperty(const sal_Char
* _pLocalName
) const;
305 sal_Int32
getInt32Property(const sal_Char
* _pLocalName
) const;
307 ::rtl::OUString
getStringProperty(const ::rtl::OUString
& _rLocalName
) const;
309 void setStringProperty(const sal_Char
* _pLocalName
, const ::rtl::OUString
& _rValue
);
312 AssignmentPersistentData();
313 ~AssignmentPersistentData();
315 // IAssigmentData overridables
316 virtual ::rtl::OUString
getDatasourceName() const;
317 virtual ::rtl::OUString
getCommand() const;
318 virtual sal_Int32
getCommandType() const;
320 virtual sal_Bool
hasFieldAssignment(const ::rtl::OUString
& _rLogicalName
);
321 virtual ::rtl::OUString
getFieldAssignment(const ::rtl::OUString
& _rLogicalName
);
322 virtual void setFieldAssignment(const ::rtl::OUString
& _rLogicalName
, const ::rtl::OUString
& _rAssignment
);
323 virtual void clearFieldAssignment(const ::rtl::OUString
& _rLogicalName
);
325 virtual void setDatasourceName(const ::rtl::OUString
& _rName
);
326 virtual void setCommand(const ::rtl::OUString
& _rCommand
);
329 // -------------------------------------------------------------------
330 AssignmentPersistentData::AssignmentPersistentData()
331 :ConfigItem( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.DataAccess/AddressBook" )))
333 Sequence
< ::rtl::OUString
> aStoredNames
= GetNodeNames(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Fields")));
334 const ::rtl::OUString
* pStoredNames
= aStoredNames
.getConstArray();
335 for (sal_Int32 i
=0; i
<aStoredNames
.getLength(); ++i
, ++pStoredNames
)
336 m_aStoredFields
.insert(*pStoredNames
);
339 // -------------------------------------------------------------------
340 AssignmentPersistentData::~AssignmentPersistentData()
344 // -------------------------------------------------------------------
345 sal_Bool
AssignmentPersistentData::hasFieldAssignment(const ::rtl::OUString
& _rLogicalName
)
347 return (m_aStoredFields
.end() != m_aStoredFields
.find(_rLogicalName
));
350 // -------------------------------------------------------------------
351 ::rtl::OUString
AssignmentPersistentData::getFieldAssignment(const ::rtl::OUString
& _rLogicalName
)
353 ::rtl::OUString sAssignment
;
354 if (hasFieldAssignment(_rLogicalName
))
356 ::rtl::OUString
sFieldPath(RTL_CONSTASCII_USTRINGPARAM("Fields/"));
357 sFieldPath
+= _rLogicalName
;
358 sFieldPath
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
359 sAssignment
= getStringProperty(sFieldPath
);
364 // -------------------------------------------------------------------
365 Any
AssignmentPersistentData::getProperty(const sal_Char
* _pLocalName
) const
367 return getProperty(::rtl::OUString::createFromAscii(_pLocalName
));
370 // -------------------------------------------------------------------
371 Any
AssignmentPersistentData::getProperty(const ::rtl::OUString
& _rLocalName
) const
373 Sequence
< ::rtl::OUString
> aProperties(&_rLocalName
, 1);
374 Sequence
< Any
> aValues
= const_cast<AssignmentPersistentData
*>(this)->GetProperties(aProperties
);
375 DBG_ASSERT(aValues
.getLength() == 1, "AssignmentPersistentData::getProperty: invalid sequence length!");
379 // -------------------------------------------------------------------
380 ::rtl::OUString
AssignmentPersistentData::getStringProperty(const ::rtl::OUString
& _rLocalName
) const
382 ::rtl::OUString sReturn
;
383 getProperty( _rLocalName
) >>= sReturn
;
387 // -------------------------------------------------------------------
388 ::rtl::OUString
AssignmentPersistentData::getStringProperty(const sal_Char
* _pLocalName
) const
390 ::rtl::OUString sReturn
;
391 getProperty( _pLocalName
) >>= sReturn
;
395 // -------------------------------------------------------------------
396 sal_Int32
AssignmentPersistentData::getInt32Property(const sal_Char
* _pLocalName
) const
398 sal_Int32 nReturn
= 0;
399 getProperty( _pLocalName
) >>= nReturn
;
403 // -------------------------------------------------------------------
404 void AssignmentPersistentData::setStringProperty(const sal_Char
* _pLocalName
, const ::rtl::OUString
& _rValue
)
406 Sequence
< ::rtl::OUString
> aNames(1);
407 Sequence
< Any
> aValues(1);
408 aNames
[0] = ::rtl::OUString::createFromAscii(_pLocalName
);
409 aValues
[0] <<= _rValue
;
410 PutProperties(aNames
, aValues
);
413 // -------------------------------------------------------------------
414 void AssignmentPersistentData::setFieldAssignment(const ::rtl::OUString
& _rLogicalName
, const ::rtl::OUString
& _rAssignment
)
416 if (!_rAssignment
.getLength())
418 if (hasFieldAssignment(_rLogicalName
))
419 // the assignment exists but it should be reset
420 clearFieldAssignment(_rLogicalName
);
425 ::rtl::OUString
sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));
428 ::rtl::OUString
sFieldElementNodePath(sDescriptionNodePath
);
429 sFieldElementNodePath
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
430 sFieldElementNodePath
+= _rLogicalName
;
432 Sequence
< PropertyValue
> aNewFieldDescription(2);
433 // Fields/<field>/ProgrammaticFieldName
434 aNewFieldDescription
[0].Name
= sFieldElementNodePath
;
435 aNewFieldDescription
[0].Name
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/ProgrammaticFieldName"));
436 aNewFieldDescription
[0].Value
<<= _rLogicalName
;
437 // Fields/<field>/AssignedFieldName
438 aNewFieldDescription
[1].Name
= sFieldElementNodePath
;
439 aNewFieldDescription
[1].Name
+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
440 aNewFieldDescription
[1].Value
<<= _rAssignment
;
442 // just set the new value
446 SetSetProperties(sDescriptionNodePath
, aNewFieldDescription
);
447 DBG_ASSERT(bSuccess
, "AssignmentPersistentData::setFieldAssignment: could not commit the changes a field!");
450 // -------------------------------------------------------------------
451 void AssignmentPersistentData::clearFieldAssignment(const ::rtl::OUString
& _rLogicalName
)
453 if (!hasFieldAssignment(_rLogicalName
))
457 ::rtl::OUString
sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));
458 Sequence
< ::rtl::OUString
> aNames(&_rLogicalName
, 1);
459 ClearNodeElements(sDescriptionNodePath
, aNames
);
462 // -------------------------------------------------------------------
463 ::rtl::OUString
AssignmentPersistentData::getDatasourceName() const
465 return getStringProperty( "DataSourceName" );
468 // -------------------------------------------------------------------
469 ::rtl::OUString
AssignmentPersistentData::getCommand() const
471 return getStringProperty( "Command" );
474 // -------------------------------------------------------------------
475 void AssignmentPersistentData::setDatasourceName(const ::rtl::OUString
& _rName
)
477 setStringProperty( "DataSourceName", _rName
);
480 // -------------------------------------------------------------------
481 void AssignmentPersistentData::setCommand(const ::rtl::OUString
& _rCommand
)
483 setStringProperty( "Command", _rCommand
);
486 // -------------------------------------------------------------------
487 sal_Int32
AssignmentPersistentData::getCommandType() const
489 return getInt32Property( "CommandType" );
492 // ===================================================================
493 // = AddressBookSourceDialogData
494 // ===================================================================
495 struct AddressBookSourceDialogData
497 FixedText
* pFieldLabels
[FIELD_PAIRS_VISIBLE
* 2];
498 ListBox
* pFields
[FIELD_PAIRS_VISIBLE
* 2];
500 /// when working transient, we need the data source
501 Reference
< XDataSource
>
502 m_xTransientDataSource
;
503 /// current scroll pos in the field list
504 sal_Int32 nFieldScrollPos
;
505 /// the index within m_pFields of the last visible list box. This is redundant, it could be extracted from other members
506 sal_Int32 nLastVisibleListIndex
;
507 /// indicates that we've an odd field number. This member is for efficiency only, it's redundant.
508 sal_Bool bOddFieldNumber
: 1;
509 /// indicates that we're working with the real persistent configuration
510 sal_Bool bWorkingPersistent
: 1;
512 /// the strings to use as labels for the field selection listboxes
513 StringArray aFieldLabels
;
514 // the current field assignment
515 StringArray aFieldAssignments
;
516 /// the logical field names
517 StringArray aLogicalFieldNames
;
519 IAssigmentData
* pConfigData
;
521 // ................................................................
522 AddressBookSourceDialogData( )
524 ,nLastVisibleListIndex(0)
525 ,bOddFieldNumber(sal_False
)
526 ,bWorkingPersistent( sal_True
)
527 ,pConfigData( new AssignmentPersistentData
)
531 // ................................................................
532 AddressBookSourceDialogData( const Reference
< XDataSource
>& _rxTransientDS
, const ::rtl::OUString
& _rDataSourceName
,
533 const ::rtl::OUString
& _rTableName
, const Sequence
< AliasProgrammaticPair
>& _rFields
)
534 :m_xTransientDataSource( _rxTransientDS
)
536 ,nLastVisibleListIndex(0)
537 ,bOddFieldNumber(sal_False
)
538 ,bWorkingPersistent( sal_False
)
539 ,pConfigData( new AssigmentTransientData( m_xTransientDataSource
, _rDataSourceName
, _rTableName
, _rFields
) )
543 ~AddressBookSourceDialogData()
550 // ===================================================================
551 // = AddressBookSourceDialog
552 // ===================================================================
553 #define INIT_FIELDS() \
554 ModalDialog(_pParent, SvtResId( DLG_ADDRESSBOOKSOURCE ))\
555 ,m_aDatasourceFrame (this, SvtResId(FL_DATASOURCEFRAME))\
556 ,m_aDatasourceLabel (this, SvtResId(FT_DATASOURCE))\
557 ,m_aDatasource (this, SvtResId(CB_DATASOURCE))\
558 ,m_aAdministrateDatasources (this, SvtResId(PB_ADMINISTATE_DATASOURCES))\
559 ,m_aTableLabel (this, SvtResId(FT_TABLE))\
560 ,m_aTable (this, SvtResId(CB_TABLE))\
561 ,m_aFieldsTitle (this, SvtResId(FT_FIELDS))\
562 ,m_aFieldsFrame (this, SvtResId(CT_BORDER))\
563 ,m_aFieldScroller (&m_aFieldsFrame, SvtResId(SB_FIELDSCROLLER))\
564 ,m_aOK (this, SvtResId(PB_OK))\
565 ,m_aCancel (this, SvtResId(PB_CANCEL))\
566 ,m_aHelp (this, SvtResId(PB_HELP))\
567 ,m_sNoFieldSelection(SvtResId(STR_NO_FIELD_SELECTION))\
570 // -------------------------------------------------------------------
571 AddressBookSourceDialog::AddressBookSourceDialog(Window
* _pParent
,
572 const Reference
< XMultiServiceFactory
>& _rxORB
)
574 ,m_pImpl( new AddressBookSourceDialogData
)
579 // -------------------------------------------------------------------
580 AddressBookSourceDialog::AddressBookSourceDialog( Window
* _pParent
, const Reference
< XMultiServiceFactory
>& _rxORB
,
581 const Reference
< XDataSource
>& _rxTransientDS
, const ::rtl::OUString
& _rDataSourceName
,
582 const ::rtl::OUString
& _rTable
, const Sequence
< AliasProgrammaticPair
>& _rMapping
)
584 ,m_pImpl( new AddressBookSourceDialogData( _rxTransientDS
, _rDataSourceName
, _rTable
, _rMapping
) )
589 // -------------------------------------------------------------------
590 void AddressBookSourceDialog::implConstruct()
592 for (sal_Int32 row
=0; row
<FIELD_PAIRS_VISIBLE
; ++row
)
594 for (sal_Int32 column
=0; column
<2; ++column
)
597 m_pImpl
->pFieldLabels
[row
* 2 + column
] = new FixedText(&m_aFieldsFrame
, SvtResId((USHORT
)(FT_FIELD_BASE
+ row
* 2 + column
)));
599 m_pImpl
->pFields
[row
* 2 + column
] = new ListBox(&m_aFieldsFrame
, SvtResId((USHORT
)(LB_FIELD_BASE
+ row
* 2 + column
)));
600 m_pImpl
->pFields
[row
* 2 + column
]->SetDropDownLineCount(15);
601 m_pImpl
->pFields
[row
* 2 + column
]->SetSelectHdl(LINK(this, AddressBookSourceDialog
, OnFieldSelect
));
603 m_pImpl
->pFields
[row
* 2 + column
]->SetHelpId(HID_ADDRTEMPL_FIELD_ASSIGNMENT
);
607 m_aFieldsFrame
.SetStyle((m_aFieldsFrame
.GetStyle() | WB_TABSTOP
| WB_DIALOGCONTROL
) & ~WB_NODIALOGCONTROL
);
609 // correct the z-order
610 m_aFieldScroller
.SetZOrder(m_pImpl
->pFields
[FIELD_CONTROLS_VISIBLE
- 1], WINDOW_ZORDER_BEHIND
);
611 m_aOK
.SetZOrder(&m_aFieldsFrame
, WINDOW_ZORDER_BEHIND
);
612 m_aCancel
.SetZOrder(&m_aOK
, WINDOW_ZORDER_BEHIND
);
614 initializeDatasources();
616 // for the moment, we have a hard coded list of all known fields.
617 // A better solution would be to store all known field translations in the configuration, which could be
618 // extensible by the user in an arbitrary way.
619 // But for the moment we need a quick solution ...
620 // (the main thing would be to store the translations to use here in the user interface, besides that, the code
621 // should be adjustable with a rather small effort.)
623 // initialize the strings for the field labels
624 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_FIRSTNAME
)) );
625 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_LASTNAME
)) );
626 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_COMPANY
)) );
627 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_DEPARTMENT
)) );
628 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_STREET
)) );
629 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_ZIPCODE
)) );
630 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_CITY
)) );
631 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_STATE
)) );
632 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_COUNTRY
)) );
633 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_HOMETEL
)) );
634 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_WORKTEL
)) );
635 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_OFFICETEL
)) );
636 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_MOBILE
)) );
637 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_TELOTHER
)) );
638 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_PAGER
)) );
639 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_FAX
)) );
640 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_EMAIL
)) );
641 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_URL
)) );
642 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_TITLE
)) );
643 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_POSITION
)) );
644 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_INITIALS
)) );
645 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_ADDRFORM
)) );
646 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_SALUTATION
)) );
647 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_ID
)) );
648 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_CALENDAR
)) );
649 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_INVITE
)) );
650 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_NOTE
)) );
651 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_USER1
)) );
652 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_USER2
)) );
653 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_USER3
)) );
654 m_pImpl
->aFieldLabels
.push_back( String(SvtResId( STR_FIELD_USER4
)) );
656 // force a even number of known fields
657 m_pImpl
->bOddFieldNumber
= (m_pImpl
->aFieldLabels
.size() % 2) != 0;
658 if (m_pImpl
->bOddFieldNumber
)
659 m_pImpl
->aFieldLabels
.push_back( String() );
661 // limit the scrollbar range accordingly
662 sal_Int32 nOverallFieldPairs
= m_pImpl
->aFieldLabels
.size() / 2;
663 m_aFieldScroller
.SetRange( Range(0, nOverallFieldPairs
- FIELD_PAIRS_VISIBLE
) );
664 m_aFieldScroller
.SetLineSize(1);
665 m_aFieldScroller
.SetPageSize(FIELD_PAIRS_VISIBLE
);
667 // reset the current field assignments
668 m_pImpl
->aFieldAssignments
.resize(m_pImpl
->aFieldLabels
.size());
669 // (empty strings mean "no assignment")
672 m_aFieldScroller
.SetScrollHdl(LINK(this, AddressBookSourceDialog
, OnFieldScroll
));
673 m_aAdministrateDatasources
.SetClickHdl(LINK(this, AddressBookSourceDialog
, OnAdministrateDatasources
));
674 m_aDatasource
.EnableAutocomplete(sal_True
);
675 m_aTable
.EnableAutocomplete(sal_True
);
676 m_aTable
.SetGetFocusHdl(LINK(this, AddressBookSourceDialog
, OnComboGetFocus
));
677 m_aDatasource
.SetGetFocusHdl(LINK(this, AddressBookSourceDialog
, OnComboGetFocus
));
678 m_aTable
.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog
, OnComboLoseFocus
));
679 m_aDatasource
.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog
, OnComboLoseFocus
));
680 m_aTable
.SetSelectHdl(LINK(this, AddressBookSourceDialog
, OnComboSelect
));
681 m_aDatasource
.SetSelectHdl(LINK(this, AddressBookSourceDialog
, OnComboSelect
));
682 m_aOK
.SetClickHdl(LINK(this, AddressBookSourceDialog
, OnOkClicked
));
684 m_aDatasource
.SetDropDownLineCount(15);
686 // initialize the field controls
688 m_aFieldScroller
.SetThumbPos(0);
689 m_pImpl
->nFieldScrollPos
= -1;
690 implScrollFields(0, sal_False
, sal_False
);
693 String
sLogicalFieldNames(SvtResId(STR_LOCAGICAL_FIELD_NAMES
));
694 sal_Int32 nAdjustedTokenCount
= sLogicalFieldNames
.GetTokenCount(';') + (m_pImpl
->bOddFieldNumber
? 1 : 0);
695 DBG_ASSERT(nAdjustedTokenCount
== (sal_Int32
)m_pImpl
->aFieldLabels
.size(),
696 "AddressBookSourceDialog::AddressBookSourceDialog: inconsistence between logical and UI field names!");
697 m_pImpl
->aLogicalFieldNames
.reserve(nAdjustedTokenCount
);
698 for (sal_Int32 i
= 0; i
<nAdjustedTokenCount
; ++i
)
699 m_pImpl
->aLogicalFieldNames
.push_back(sLogicalFieldNames
.GetToken((sal_uInt16
)i
, ';'));
701 PostUserEvent(LINK(this, AddressBookSourceDialog
, OnDelayedInitialize
));
702 // so the dialog will at least show up before we do the loading of the
703 // configuration data and the (maybe time consuming) analysis of the data source/table to select
707 if ( !m_pImpl
->bWorkingPersistent
)
709 StyleSettings aSystemStyle
= GetSettings().GetStyleSettings();
710 const Color
& rNewColor
= aSystemStyle
.GetDialogColor();
712 m_aDatasource
.SetReadOnly( sal_True
);
713 m_aDatasource
.SetBackground( Wallpaper( rNewColor
) );
714 m_aDatasource
.SetControlBackground( rNewColor
);
716 m_aTable
.SetReadOnly( sal_True
);
717 m_aTable
.SetBackground( Wallpaper( rNewColor
) );
718 m_aTable
.SetControlBackground( rNewColor
);
720 m_aAdministrateDatasources
.Hide( );
724 // -------------------------------------------------------------------
725 void AddressBookSourceDialog::getFieldMapping(Sequence
< AliasProgrammaticPair
>& _rMapping
) const
727 _rMapping
.realloc( m_pImpl
->aLogicalFieldNames
.size() );
728 AliasProgrammaticPair
* pPair
= _rMapping
.getArray();
730 ::rtl::OUString sCurrent
;
731 for ( ConstStringArrayIterator aProgrammatic
= m_pImpl
->aLogicalFieldNames
.begin();
732 aProgrammatic
!= m_pImpl
->aLogicalFieldNames
.end();
736 sCurrent
= *aProgrammatic
;
737 if ( m_pImpl
->pConfigData
->hasFieldAssignment( sCurrent
) )
739 // the user gave us an assignment for this field
740 pPair
->ProgrammaticName
= *aProgrammatic
;
741 pPair
->Alias
= m_pImpl
->pConfigData
->getFieldAssignment( *aProgrammatic
);
746 _rMapping
.realloc( pPair
- _rMapping
.getArray() );
749 // -------------------------------------------------------------------
750 void AddressBookSourceDialog::loadConfiguration()
752 ::rtl::OUString sName
= m_pImpl
->pConfigData
->getDatasourceName();
753 INetURLObject
aURL( sName
);
754 if( aURL
.GetProtocol() != INET_PROT_NOT_VALID
)
756 OFileNotation
aFileNotation( aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
757 sName
= aFileNotation
.get(OFileNotation::N_SYSTEM
);
760 m_aDatasource
.SetText(sName
);
761 m_aTable
.SetText(m_pImpl
->pConfigData
->getCommand());
762 // we ignore the CommandType: only tables are supported
764 // the logical names for the fields
765 DBG_ASSERT(m_pImpl
->aLogicalFieldNames
.size() == m_pImpl
->aFieldAssignments
.size(),
766 "AddressBookSourceDialog::loadConfiguration: inconsistence between field names and field assignments!");
768 ConstStringArrayIterator aLogical
= m_pImpl
->aLogicalFieldNames
.begin();
769 StringArrayIterator aAssignment
= m_pImpl
->aFieldAssignments
.begin();
771 aLogical
< m_pImpl
->aLogicalFieldNames
.end();
772 ++aLogical
, ++aAssignment
774 *aAssignment
= m_pImpl
->pConfigData
->getFieldAssignment(*aLogical
);
777 // -------------------------------------------------------------------
778 AddressBookSourceDialog::~AddressBookSourceDialog()
781 for (i
=0; i
<FIELD_CONTROLS_VISIBLE
; ++i
)
783 delete m_pImpl
->pFieldLabels
[i
];
784 delete m_pImpl
->pFields
[i
];
790 // -------------------------------------------------------------------
791 void AddressBookSourceDialog::initializeDatasources()
793 if (!m_xDatabaseContext
.is())
795 DBG_ASSERT(m_xORB
.is(), "AddressBookSourceDialog::initializeDatasources: no service factory!");
799 const String sContextServiceName
= String::CreateFromAscii("com.sun.star.sdb.DatabaseContext");
802 m_xDatabaseContext
= Reference
< XNameAccess
>(m_xORB
->createInstance(sContextServiceName
), UNO_QUERY
);
804 catch(Exception
&) { }
805 if (!m_xDatabaseContext
.is())
807 ShowServiceNotAvailableError( this, sContextServiceName
, sal_False
);
811 m_aDatasource
.Clear();
813 // fill the datasources listbox
814 Sequence
< ::rtl::OUString
> aDatasourceNames
;
817 aDatasourceNames
= m_xDatabaseContext
->getElementNames();
821 DBG_ERROR("AddressBookSourceDialog::initializeDatasources: caught an exception while asking for the data source names!");
823 const ::rtl::OUString
* pDatasourceNames
= aDatasourceNames
.getConstArray();
824 const ::rtl::OUString
* pEnd
= pDatasourceNames
+ aDatasourceNames
.getLength();
825 for (; pDatasourceNames
< pEnd
; ++pDatasourceNames
)
826 m_aDatasource
.InsertEntry(*pDatasourceNames
);
829 // -------------------------------------------------------------------
830 IMPL_LINK(AddressBookSourceDialog
, OnFieldScroll
, ScrollBar
*, _pScrollBar
)
832 implScrollFields( _pScrollBar
->GetThumbPos(), sal_True
, sal_True
);
836 // -------------------------------------------------------------------
837 void AddressBookSourceDialog::resetTables()
839 if (!m_xDatabaseContext
.is())
842 WaitObject
aWaitCursor(this);
844 // no matter what we do here, we handled the currently selected data source (no matter if successfull or not)
845 m_aDatasource
.SaveValue();
847 // create an interaction handler (may be needed for connecting)
848 const String sInteractionHandlerServiceName
= String::CreateFromAscii("com.sun.star.sdb.InteractionHandler");
849 Reference
< XInteractionHandler
> xHandler
;
852 xHandler
= Reference
< XInteractionHandler
>(m_xORB
->createInstance(sInteractionHandlerServiceName
), UNO_QUERY
);
854 catch(Exception
&) { }
857 ShowServiceNotAvailableError(this, sInteractionHandlerServiceName
, sal_True
);
861 // the currently selected table
862 ::rtl::OUString sOldTable
= m_aTable
.GetText();
866 m_xCurrentDatasourceTables
= NULL
;
868 // get the tables of the connection
869 Sequence
< ::rtl::OUString
> aTableNames
;
873 Reference
< XCompletedConnection
> xDS
;
874 if ( m_pImpl
->bWorkingPersistent
)
876 String sSelectedDS
= lcl_getSelectedDataSource( m_aDatasource
);
878 // get the data source the user has chosen and let it build a connection
879 INetURLObject
aURL( sSelectedDS
);
880 if ( aURL
.GetProtocol() != INET_PROT_NOT_VALID
|| m_xDatabaseContext
->hasByName(sSelectedDS
) )
881 m_xDatabaseContext
->getByName( sSelectedDS
) >>= xDS
;
885 xDS
= xDS
.query( m_pImpl
->m_xTransientDataSource
);
888 // build the connection
889 Reference
< XConnection
> xConn
;
891 xConn
= xDS
->connectWithCompletion(xHandler
);
893 // get the table names
894 Reference
< XTablesSupplier
> xSupplTables(xConn
, UNO_QUERY
);
895 if (xSupplTables
.is())
897 m_xCurrentDatasourceTables
= Reference
< XNameAccess
>(xSupplTables
->getTables(), UNO_QUERY
);
898 if (m_xCurrentDatasourceTables
.is())
899 aTableNames
= m_xCurrentDatasourceTables
->getElementNames();
902 catch(SQLContext
& e
) { aException
<<= e
; }
903 catch(SQLWarning
& e
) { aException
<<= e
; }
904 catch(SQLException
& e
) { aException
<<= e
; }
907 DBG_ERROR("AddressBookSourceDialog::resetTables: could not retrieve the table!");
910 if (aException
.hasValue())
912 Reference
< XInteractionRequest
> xRequest
= new OInteractionRequest(aException
);
915 xHandler
->handle(xRequest
);
917 catch(Exception
&) { }
921 sal_Bool bKnowOldTable
= sal_False
;
922 // fill the table list
923 const ::rtl::OUString
* pTableNames
= aTableNames
.getConstArray();
924 const ::rtl::OUString
* pEnd
= pTableNames
+ aTableNames
.getLength();
925 for (;pTableNames
!= pEnd
; ++pTableNames
)
927 m_aTable
.InsertEntry(*pTableNames
);
928 if (0 == pTableNames
->compareTo(sOldTable
))
929 bKnowOldTable
= sal_True
;
932 // set the old table, if the new data source knows a table with this name, too. Else reset the tables edit field.
934 sOldTable
= ::rtl::OUString();
935 m_aTable
.SetText(sOldTable
);
940 // -------------------------------------------------------------------
941 void AddressBookSourceDialog::resetFields()
943 WaitObject
aWaitCursor(this);
945 // no matter what we do here, we handled the currently selected table (no matter if successfull or not)
946 m_aDatasource
.SaveValue();
948 String sSelectedTable
= m_aTable
.GetText();
949 Sequence
< ::rtl::OUString
> aColumnNames
;
952 if (m_xCurrentDatasourceTables
.is())
954 // get the table and the columns
955 Reference
< XColumnsSupplier
> xSuppTableCols
;
956 if (m_xCurrentDatasourceTables
->hasByName(sSelectedTable
))
957 ::cppu::extractInterface(xSuppTableCols
, m_xCurrentDatasourceTables
->getByName(sSelectedTable
));
958 Reference
< XNameAccess
> xColumns
;
959 if (xSuppTableCols
.is())
960 xColumns
= xSuppTableCols
->getColumns();
962 aColumnNames
= xColumns
->getElementNames();
967 DBG_ERROR("AddressBookSourceDialog::resetFields: could not retrieve the table columns!");
971 const ::rtl::OUString
* pColumnNames
= aColumnNames
.getConstArray();
972 const ::rtl::OUString
* pEnd
= pColumnNames
+ aColumnNames
.getLength();
974 // for quicker access
975 ::std::set
< String
> aColumnNameSet
;
976 for (pColumnNames
= aColumnNames
.getConstArray(); pColumnNames
!= pEnd
; ++pColumnNames
)
977 aColumnNameSet
.insert(*pColumnNames
);
979 std::vector
<String
>::iterator aInitialSelection
= m_pImpl
->aFieldAssignments
.begin() + m_pImpl
->nFieldScrollPos
;
981 ListBox
** pListbox
= m_pImpl
->pFields
;
982 String sSaveSelection
;
983 for (sal_Int32 i
=0; i
<FIELD_CONTROLS_VISIBLE
; ++i
, ++pListbox
, ++aInitialSelection
)
985 sSaveSelection
= (*pListbox
)->GetSelectEntry();
987 (*pListbox
)->Clear();
989 // the one entry for "no selection"
990 (*pListbox
)->InsertEntry(m_sNoFieldSelection
, 0);
991 // as it's entry data, set the index of the list box in our array
992 (*pListbox
)->SetEntryData(0, reinterpret_cast<void*>(i
));
995 for (pColumnNames
= aColumnNames
.getConstArray(); pColumnNames
!= pEnd
; ++pColumnNames
)
996 (*pListbox
)->InsertEntry(*pColumnNames
);
998 if (aInitialSelection
->Len() && (aColumnNameSet
.end() != aColumnNameSet
.find(*aInitialSelection
)))
999 // we can select the entry as specified in our field assignment array
1000 (*pListbox
)->SelectEntry(*aInitialSelection
);
1002 // try to restore the selection
1003 if (aColumnNameSet
.end() != aColumnNameSet
.find(sSaveSelection
))
1004 // the old selection is a valid column name
1005 (*pListbox
)->SelectEntry(sSaveSelection
);
1007 // select the <none> entry
1008 (*pListbox
)->SelectEntryPos(0);
1011 // adjust m_pImpl->aFieldAssignments
1012 for ( StringArrayIterator aAdjust
= m_pImpl
->aFieldAssignments
.begin();
1013 aAdjust
!= m_pImpl
->aFieldAssignments
.end();
1017 if (aColumnNameSet
.end() == aColumnNameSet
.find(*aAdjust
))
1021 // -------------------------------------------------------------------
1022 IMPL_LINK(AddressBookSourceDialog
, OnFieldSelect
, ListBox
*, _pListbox
)
1024 // the index of the affected list box in our array
1025 sal_IntPtr nListBoxIndex
= reinterpret_cast<sal_IntPtr
>(_pListbox
->GetEntryData(0));
1026 DBG_ASSERT(nListBoxIndex
>= 0 && nListBoxIndex
< FIELD_CONTROLS_VISIBLE
,
1027 "AddressBookSourceDialog::OnFieldScroll: invalid list box entry!");
1029 // update the array where we remember the field selections
1030 if (0 == _pListbox
->GetSelectEntryPos())
1031 // it's the "no field selection" entry
1032 m_pImpl
->aFieldAssignments
[m_pImpl
->nFieldScrollPos
* 2 + nListBoxIndex
] = String();
1034 // it's a regular field entry
1035 m_pImpl
->aFieldAssignments
[m_pImpl
->nFieldScrollPos
* 2 + nListBoxIndex
] = _pListbox
->GetSelectEntry();
1040 // -------------------------------------------------------------------
1041 void AddressBookSourceDialog::implScrollFields(sal_Int32 _nPos
, sal_Bool _bAdjustFocus
, sal_Bool _bAdjustScrollbar
)
1043 if (_nPos
== m_pImpl
->nFieldScrollPos
)
1047 // loop through our field control rows and do some adjustments
1048 // for the new texts
1049 FixedText
** pLeftLabelControl
= m_pImpl
->pFieldLabels
;
1050 FixedText
** pRightLabelControl
= pLeftLabelControl
+ 1;
1051 ConstStringArrayIterator pLeftColumnLabel
= m_pImpl
->aFieldLabels
.begin() + 2 * _nPos
;
1052 ConstStringArrayIterator pRightColumnLabel
= pLeftColumnLabel
+ 1;
1054 // for the focus movement and the selection scroll
1055 ListBox
** pLeftListControl
= m_pImpl
->pFields
;
1056 ListBox
** pRightListControl
= pLeftListControl
+ 1;
1058 // for the focus movement
1059 sal_Int32 nOldFocusRow
= -1;
1060 sal_Int32 nOldFocusColumn
= 0;
1062 // for the selection scroll
1063 ConstStringArrayIterator pLeftAssignment
= m_pImpl
->aFieldAssignments
.begin() + 2 * _nPos
;
1064 ConstStringArrayIterator pRightAssignment
= pLeftAssignment
+ 1;
1066 m_pImpl
->nLastVisibleListIndex
= -1;
1068 for (sal_Int32 i
=0; i
<FIELD_PAIRS_VISIBLE
; ++i
)
1070 if ((*pLeftListControl
)->HasChildPathFocus())
1073 nOldFocusColumn
= 0;
1075 else if ((*pRightListControl
)->HasChildPathFocus())
1078 nOldFocusColumn
= 1;
1081 // the new texts of the label controls
1082 (*pLeftLabelControl
)->SetText(*pLeftColumnLabel
);
1083 (*pRightLabelControl
)->SetText(*pRightColumnLabel
);
1085 // we may have to hide the controls in the right column, if we have no label text for it
1086 // (which means we have an odd number of fields, though we forced our internal arrays to
1087 // be even-sized for easier handling)
1088 // (If sometimes we support an arbitrary number of field assignments, we would have to care for
1089 // an invisible left hand side column, too. But right now, the left hand side controls are always
1091 sal_Bool bHideRightColumn
= (0 == pRightColumnLabel
->Len());
1092 (*pRightLabelControl
)->Show(!bHideRightColumn
);
1093 (*pRightListControl
)->Show(!bHideRightColumn
);
1094 // the new selections of the listboxes
1095 implSelectField(*pLeftListControl
, *pLeftAssignment
);
1096 implSelectField(*pRightListControl
, *pRightAssignment
);
1098 // the index of the last visible list box
1099 ++m_pImpl
->nLastVisibleListIndex
; // the left hand side box is always visible
1100 if (!bHideRightColumn
)
1101 ++m_pImpl
->nLastVisibleListIndex
;
1104 if ( i
< FIELD_PAIRS_VISIBLE
- 1 )
1105 { // (not in the very last round, here the +=2 could result in an invalid
1106 // iterator position, which causes an abort in a non-product version
1107 pLeftLabelControl
+= 2;
1108 pRightLabelControl
+= 2;
1109 pLeftColumnLabel
+= 2;
1110 pRightColumnLabel
+= 2;
1112 pLeftListControl
+= 2;
1113 pRightListControl
+= 2;
1114 pLeftAssignment
+= 2;
1115 pRightAssignment
+= 2;
1119 if (_bAdjustFocus
&& (nOldFocusRow
>= 0))
1120 { // we have to adjust the focus and one of the list boxes has the focus
1121 sal_Int32 nDelta
= m_pImpl
->nFieldScrollPos
- _nPos
;
1122 // the new row for the focus
1123 sal_Int32 nNewFocusRow
= nOldFocusRow
+ nDelta
;
1125 nNewFocusRow
= std::min(nNewFocusRow
, (sal_Int32
)(FIELD_PAIRS_VISIBLE
- 1), ::std::less
< sal_Int32
>());
1126 nNewFocusRow
= std::max(nNewFocusRow
, (sal_Int32
)0, ::std::less
< sal_Int32
>());
1127 // set the new focus (in the same column)
1128 m_pImpl
->pFields
[nNewFocusRow
* 2 + nOldFocusColumn
]->GrabFocus();
1131 m_pImpl
->nFieldScrollPos
= _nPos
;
1133 if (_bAdjustScrollbar
)
1134 m_aFieldScroller
.SetThumbPos(m_pImpl
->nFieldScrollPos
);
1137 // -------------------------------------------------------------------
1138 void AddressBookSourceDialog::implSelectField(ListBox
* _pBox
, const String
& _rText
)
1141 // a valid field name
1142 _pBox
->SelectEntry(_rText
);
1144 // no selection for this item
1145 _pBox
->SelectEntryPos(0);
1148 // -------------------------------------------------------------------
1149 IMPL_LINK(AddressBookSourceDialog
, OnDelayedInitialize
, void*, EMPTYARG
)
1151 // load the initial data from the configuration
1152 loadConfiguration();
1154 // will reset the tables/fields implicitly
1156 if ( !m_pImpl
->bWorkingPersistent
)
1157 if ( m_pImpl
->pFields
[0] )
1158 m_pImpl
->pFields
[0]->GrabFocus();
1163 // -------------------------------------------------------------------
1164 IMPL_LINK(AddressBookSourceDialog
, OnComboSelect
, ComboBox
*, _pBox
)
1166 if (_pBox
== &m_aDatasource
)
1173 // -------------------------------------------------------------------
1174 IMPL_LINK(AddressBookSourceDialog
, OnComboGetFocus
, ComboBox
*, _pBox
)
1180 // -------------------------------------------------------------------
1181 IMPL_LINK(AddressBookSourceDialog
, OnComboLoseFocus
, ComboBox
*, _pBox
)
1183 if (_pBox
->GetSavedValue() != _pBox
->GetText())
1185 if (_pBox
== &m_aDatasource
)
1193 // -------------------------------------------------------------------
1194 IMPL_LINK(AddressBookSourceDialog
, OnOkClicked
, Button
*, EMPTYARG
)
1196 String sSelectedDS
= lcl_getSelectedDataSource( m_aDatasource
);
1197 if ( m_pImpl
->bWorkingPersistent
)
1199 m_pImpl
->pConfigData
->setDatasourceName(sSelectedDS
);
1200 m_pImpl
->pConfigData
->setCommand(m_aTable
.GetText());
1203 // set the field assignments
1204 ConstStringArrayIterator aLogical
= m_pImpl
->aLogicalFieldNames
.begin();
1205 ConstStringArrayIterator aAssignment
= m_pImpl
->aFieldAssignments
.begin();
1207 aLogical
< m_pImpl
->aLogicalFieldNames
.end();
1208 ++aLogical
, ++aAssignment
1210 m_pImpl
->pConfigData
->setFieldAssignment(*aLogical
, *aAssignment
);
1217 // -------------------------------------------------------------------
1218 IMPL_LINK(AddressBookSourceDialog
, OnAdministrateDatasources
, void*, EMPTYARG
)
1220 // collect some initial arguments for the dialog
1221 Sequence
< Any
> aArgs(1);
1222 aArgs
[0] <<= PropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow")), 0, makeAny(VCLUnoHelper::GetInterface(this)), PropertyState_DIRECT_VALUE
);
1224 // create the dialog object
1225 const String sDialogServiceName
= String::CreateFromAscii("com.sun.star.ui.dialogs.AddressBookSourcePilot");
1226 Reference
< XExecutableDialog
> xAdminDialog
;
1229 xAdminDialog
= Reference
< XExecutableDialog
>(m_xORB
->createInstanceWithArguments(sDialogServiceName
, aArgs
), UNO_QUERY
);
1231 catch(Exception
&) { }
1232 if (!xAdminDialog
.is())
1234 ShowServiceNotAvailableError(this, sDialogServiceName
, sal_True
);
1238 // excute the dialog
1241 if ( xAdminDialog
->execute() == RET_OK
)
1243 Reference
<XPropertySet
> xProp(xAdminDialog
,UNO_QUERY
);
1246 ::rtl::OUString sName
;
1247 xProp
->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSourceName"))) >>= sName
;
1249 INetURLObject
aURL( sName
);
1250 if( aURL
.GetProtocol() != INET_PROT_NOT_VALID
)
1252 OFileNotation
aFileNotation( aURL
.GetMainURL( INetURLObject::NO_DECODE
) );
1253 sName
= aFileNotation
.get(OFileNotation::N_SYSTEM
);
1255 m_aDatasource
.InsertEntry(sName
);
1256 delete m_pImpl
->pConfigData
;
1257 m_pImpl
->pConfigData
= new AssignmentPersistentData();
1258 loadConfiguration();
1260 // will reset the fields implicitly
1266 DBG_ERROR("AddressBookSourceDialog::OnAdministrateDatasources: an error occured while executing the administration dialog!");
1269 // re-fill the data source list
1270 // try to preserve the current selection
1272 // initializeDatasources();
1277 // -------------------------------------------------------------------
1278 long AddressBookSourceDialog::PreNotify( NotifyEvent
& _rNEvt
)
1280 switch (_rNEvt
.GetType())
1282 case EVENT_KEYINPUT
:
1284 const KeyEvent
* pKeyEvent
= _rNEvt
.GetKeyEvent();
1285 sal_uInt16 nCode
= pKeyEvent
->GetKeyCode().GetCode();
1286 sal_Bool bShift
= pKeyEvent
->GetKeyCode().IsShift();
1287 sal_Bool bCtrl
= pKeyEvent
->GetKeyCode().IsMod1();
1288 sal_Bool bAlt
= pKeyEvent
->GetKeyCode().IsMod2();
1290 if (KEY_TAB
== nCode
)
1291 { // somebody pressed the tab key
1292 if (!bAlt
&& !bCtrl
&& !bShift
)
1293 { // it's really the only the key (no modifiers)
1294 if (m_pImpl
->pFields
[m_pImpl
->nLastVisibleListIndex
]->HasChildPathFocus())
1295 // the last of our visible list boxes has the focus
1296 if (m_pImpl
->nFieldScrollPos
< m_aFieldScroller
.GetRangeMax())
1297 { // we can still scroll down
1298 sal_Int32 nNextFocusList
= m_pImpl
->nLastVisibleListIndex
+ 1 - 2;
1300 implScrollFields(m_pImpl
->nFieldScrollPos
+ 1, sal_False
, sal_True
);
1301 // give the left control in the "next" line the focus
1302 m_pImpl
->pFields
[nNextFocusList
]->GrabFocus();
1303 // return saying "have handled this"
1307 else if (!bAlt
&& !bCtrl
&& bShift
)
1309 if (m_pImpl
->pFields
[0]->HasChildPathFocus())
1310 // our first list box has the focus
1311 if (m_pImpl
->nFieldScrollPos
> 0)
1312 { // we can still scroll up
1314 implScrollFields(m_pImpl
->nFieldScrollPos
- 1, sal_False
, sal_True
);
1315 // give the right control in the "prebious" line the focus
1316 m_pImpl
->pFields
[0 - 1 + 2]->GrabFocus();
1317 // return saying "have handled this"
1325 return ModalDialog::PreNotify(_rNEvt
);
1328 // .......................................................................
1330 // .......................................................................