GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / svtools / source / dialogs / addresstemplate.cxx
blobfc4a4810f4636e31741a7c4929c5c834dfc55a03
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <stdio.h>
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>
53 #include <algorithm>
55 // .......................................................................
56 namespace svt
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 );
77 namespace
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 // ===================================================================
93 // = IAssigmentData
94 // ===================================================================
95 class IAssigmentData
97 public:
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
107 @return
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
136 protected:
137 Reference< XDataSource > m_xDataSource;
138 OUString m_sDSName;
139 OUString m_sTableName;
140 MapString2String m_aAliases;
142 public:
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;
195 else
197 OSL_FAIL( ( OString("AssigmentTransientData::AssigmentTransientData: unknown programmatic name (")
198 += OString(pFields->ProgrammaticName.getStr(), pFields->ProgrammaticName.getLength(), RTL_TEXTENCODING_ASCII_US)
199 += OString(")!")
200 ).getStr()
206 // -------------------------------------------------------------------
207 OUString AssigmentTransientData::getDatasourceName() const
209 return m_sDSName;
212 // -------------------------------------------------------------------
213 OUString AssigmentTransientData::getCommand() const
215 return m_sTableName;
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)
235 OUString sReturn;
236 ConstMapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
237 if ( m_aAliases.end() != aPos )
238 sReturn = aPos->second;
240 return sReturn;
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
276 protected:
277 StringBag m_aStoredFields;
279 protected:
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);
292 public:
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);
354 return sAssignment;
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!");
369 return aValues[0];
372 // -------------------------------------------------------------------
373 OUString AssignmentPersistentData::getStringProperty(const OUString& _rLocalName) const
375 OUString sReturn;
376 getProperty( _rLocalName ) >>= sReturn;
377 return sReturn;
380 // -------------------------------------------------------------------
381 OUString AssignmentPersistentData::getStringProperty(const sal_Char* _pLocalName) const
383 OUString sReturn;
384 getProperty( _pLocalName ) >>= sReturn;
385 return sReturn;
388 // -------------------------------------------------------------------
389 sal_Int32 AssignmentPersistentData::getInt32Property(const sal_Char* _pLocalName) const
391 sal_Int32 nReturn = 0;
392 getProperty( _pLocalName ) >>= nReturn;
393 return 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);
416 return;
419 // Fields
420 OUString sDescriptionNodePath("Fields");
422 // Fields/<field>
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
436 #ifdef DBG_UTIL
437 sal_Bool bSuccess =
438 #endif
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))
447 // nothing to do
448 return;
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( )
516 :nFieldScrollPos(0)
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 )
528 ,nFieldScrollPos(0)
529 ,nLastVisibleListIndex(0)
530 ,bOddFieldNumber(sal_False)
531 ,bWorkingPersistent( sal_False )
532 ,pConfigData( new AssigmentTransientData( m_xTransientDataSource, _rDataSourceName, _rTableName, _rFields ) )
536 ~AddressBookSourceDialogData()
538 delete pConfigData;
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))
552 , m_xORB(_rxORB)
553 , m_pImpl( new AddressBookSourceDialogData )
555 implConstruct();
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))
564 , m_xORB(_rxORB)
565 , m_pImpl( new AddressBookSourceDialogData( _rxTransientDS, _rDataSourceName, _rTable, _rMapping ) )
567 implConstruct();
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)
584 // the label
585 m_pImpl->pFieldLabels[row * 2 + column] = get<FixedText>(OString("label") + OString::number(row * 2 + column));
586 // the listbox
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")
667 // some knittings
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
681 resetFields();
682 m_pFieldScroller->SetThumbPos(0);
683 m_pImpl->nFieldScrollPos = -1;
684 implScrollFields(0, sal_False, sal_False);
686 // the logical names
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();
722 OUString sCurrent;
723 for ( StringArray::const_iterator aProgrammatic = m_pImpl->aLogicalFieldNames.begin();
724 aProgrammatic != m_pImpl->aLogicalFieldNames.end();
725 ++aProgrammatic
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 );
734 ++pPair;
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();
762 for ( ;
763 aLogical != m_pImpl->aLogicalFieldNames.end();
764 ++aLogical, ++aAssignment
766 *aAssignment = m_pImpl->pConfigData->getFieldAssignment(*aLogical);
769 // -------------------------------------------------------------------
770 AddressBookSourceDialog::~AddressBookSourceDialog()
772 delete m_pImpl;
775 // -------------------------------------------------------------------
776 void AddressBookSourceDialog::initializeDatasources()
778 if (!m_xDatabaseContext.is())
780 DBG_ASSERT(m_xORB.is(), "AddressBookSourceDialog::initializeDatasources: no service factory!");
781 if (!m_xORB.is())
782 return;
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);
793 return;
796 m_pDatasource->Clear();
798 // fill the datasources listbox
799 Sequence< OUString > aDatasourceNames;
802 aDatasourceNames = m_xDatabaseContext->getElementNames();
804 catch(Exception&)
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 );
818 return 0L;
821 // -------------------------------------------------------------------
822 void AddressBookSourceDialog::resetTables()
824 if (!m_xDatabaseContext.is())
825 return;
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;
836 xHandler.set(
837 InteractionHandler::createWithParent(m_xORB, 0),
838 UNO_QUERY_THROW );
840 catch(const Exception&) { }
841 if (!xHandler.is())
843 const OUString sInteractionHandlerServiceName("com.sun.star.task.InteractionHandler");
844 ShowServiceNotAvailableError(this, sInteractionHandlerServiceName, sal_True);
845 return;
848 // the currently selected table
849 OUString sOldTable = m_pTable->GetText();
851 m_pTable->Clear();
853 m_xCurrentDatasourceTables= NULL;
855 // get the tables of the connection
856 Sequence< OUString > aTableNames;
857 Any aException;
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;
870 else
872 xDS = xDS.query( m_pImpl->m_xTransientDataSource );
875 // build the connection
876 Reference< XConnection > xConn;
877 if (xDS.is())
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; }
892 catch(Exception&)
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&) { }
905 return;
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.
920 if (!bKnowOldTable)
921 sOldTable = OUString();
922 m_pTable->SetText(sOldTable);
924 resetFields();
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();
948 if (xColumns.is())
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));
981 // the field names
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);
988 else
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);
993 else
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();
1001 ++aAdjust
1003 if (!aAdjust->isEmpty())
1004 if (aColumnNameSet.end() == aColumnNameSet.find(*aAdjust))
1005 (*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] = "";
1020 else
1021 // it's a regular field entry
1022 m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = _pListbox->GetSelectEntry();
1024 return 0L;
1027 // -------------------------------------------------------------------
1028 void AddressBookSourceDialog::implScrollFields(sal_Int32 _nPos, sal_Bool _bAdjustFocus, sal_Bool _bAdjustScrollbar)
1030 if (_nPos == m_pImpl->nFieldScrollPos)
1031 // nothing to do
1032 return;
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;
1054 // loop
1055 for (sal_Int32 i=0; i<FIELD_PAIRS_VISIBLE; ++i)
1057 if ((*pLeftListControl)->HasChildPathFocus())
1059 nOldFocusRow = i;
1060 nOldFocusColumn = 0;
1062 else if ((*pRightListControl)->HasChildPathFocus())
1064 nOldFocusRow = i;
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
1077 // visible)
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;
1090 // increment ...
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;
1111 // normalize
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);
1130 else
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();
1140 resetTables();
1141 // will reset the tables/fields implicitly
1143 if ( !m_pImpl->bWorkingPersistent )
1144 if ( m_pImpl->pFields[0] )
1145 m_pImpl->pFields[0]->GrabFocus();
1147 return 0L;
1150 // -------------------------------------------------------------------
1151 IMPL_LINK(AddressBookSourceDialog, OnComboSelect, ComboBox*, _pBox)
1153 if (_pBox == m_pDatasource)
1154 resetTables();
1155 else
1156 resetFields();
1157 return 0;
1160 // -------------------------------------------------------------------
1161 IMPL_LINK(AddressBookSourceDialog, OnComboGetFocus, ComboBox*, _pBox)
1163 _pBox->SaveValue();
1164 return 0L;
1167 // -------------------------------------------------------------------
1168 IMPL_LINK(AddressBookSourceDialog, OnComboLoseFocus, ComboBox*, _pBox)
1170 if (_pBox->GetSavedValue() != _pBox->GetText())
1172 if (_pBox == m_pDatasource)
1173 resetTables();
1174 else
1175 resetFields();
1177 return 0L;
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();
1196 for ( ;
1197 aLogical != m_pImpl->aLogicalFieldNames.end();
1198 ++aLogical, ++aAssignment
1200 m_pImpl->pConfigData->setFieldAssignment(*aLogical, *aAssignment);
1203 EndDialog(RET_OK);
1204 return 0L;
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);
1220 return 1L;
1223 // excute the dialog
1226 if ( xAdminDialog->execute() == RET_OK )
1228 Reference<XPropertySet> xProp(xAdminDialog,UNO_QUERY);
1229 if ( xProp.is() )
1231 OUString sName;
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();
1244 resetTables();
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();
1259 return 0L;
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;
1284 // -> scroll down
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"
1289 return 1;
1292 else if (!bAlt && !bCtrl && bShift)
1293 { // it's shift-tab
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
1298 // -> 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"
1303 return 1;
1308 break;
1310 return ModalDialog::PreNotify(_rNEvt);
1313 // .......................................................................
1314 } // namespace svt
1315 // .......................................................................
1317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */