LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/dialogs - addresstemplate.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 533 0.0 %
Date: 2012-12-27 Functions: 0 68 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : 
      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/XExecutableDialog.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>
      54             : 
      55             : // .......................................................................
      56             : namespace svt
      57             : {
      58             : // .......................................................................
      59             : 
      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;
      72             : 
      73             :     DECLARE_STL_VECTOR( String, StringArray );
      74             :     DECLARE_STL_STDKEY_SET( ::rtl::OUString, StringBag );
      75             :     DECLARE_STL_USTRINGACCESS_MAP( ::rtl::OUString, MapString2String );
      76             : 
      77             :     namespace
      78             :     {
      79           0 :         String lcl_getSelectedDataSource( const ComboBox& _dataSourceCombo )
      80             :         {
      81           0 :             String selectedDataSource = _dataSourceCombo.GetText();
      82           0 :             if ( _dataSourceCombo.GetEntryPos( selectedDataSource ) == LISTBOX_ENTRY_NOTFOUND )
      83             :             {
      84             :                 // none of the pre-selected entries -> assume a path to a database document
      85           0 :                 OFileNotation aFileNotation( selectedDataSource, OFileNotation::N_SYSTEM );
      86           0 :                 selectedDataSource = aFileNotation.get( OFileNotation::N_URL );
      87             :             }
      88           0 :             return selectedDataSource;
      89             :         }
      90             :     }
      91             : 
      92             :     // ===================================================================
      93             :     // = IAssigmentData
      94             :     // ===================================================================
      95           0 :     class IAssigmentData
      96             :     {
      97             :     public:
      98             :         virtual ~IAssigmentData();
      99             : 
     100             :         /// the data source to use for the address book
     101             :         virtual ::rtl::OUString getDatasourceName() const = 0;
     102             : 
     103             :         /// the command to use for the address book
     104             :         virtual ::rtl::OUString getCommand() const = 0;
     105             : 
     106             :         /** the command type to use for the address book
     107             :             @return
     108             :                 a <type scope="com.sun.star.sdb">CommandType</type> value
     109             :         */
     110             :         virtual sal_Int32       getCommandType() const = 0;
     111             : 
     112             :         /// checks whether or not there is an assignment for a given logical field
     113             :         virtual sal_Bool        hasFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
     114             :         /// retrieves the assignment for a given logical field
     115             :         virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
     116             : 
     117             :         /// set the assignment for a given logical field
     118             :         virtual void            setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment) = 0;
     119             :         /// clear the assignment for a given logical field
     120             :         virtual void            clearFieldAssignment(const ::rtl::OUString& _rLogicalName) = 0;
     121             : 
     122             :         virtual void    setDatasourceName(const ::rtl::OUString& _rName) = 0;
     123             :         virtual void    setCommand(const ::rtl::OUString& _rCommand) = 0;
     124             :     };
     125             : 
     126             :     // -------------------------------------------------------------------
     127           0 :     IAssigmentData::~IAssigmentData()
     128             :     {
     129           0 :     }
     130             : 
     131             :     // ===================================================================
     132             :     // = AssigmentTransientData
     133             :     // ===================================================================
     134           0 :     class AssigmentTransientData : public IAssigmentData
     135             :     {
     136             :     protected:
     137             :         Reference< XDataSource >    m_xDataSource;
     138             :         ::rtl::OUString             m_sDSName;
     139             :         ::rtl::OUString             m_sTableName;
     140             :         MapString2String            m_aAliases;
     141             : 
     142             : public:
     143             :         AssigmentTransientData(
     144             :             const Reference< XDataSource >& _rxDataSource,
     145             :             const ::rtl::OUString& _rDataSourceName,
     146             :             const ::rtl::OUString& _rTableName,
     147             :             const Sequence< AliasProgrammaticPair >& _rFields
     148             :         );
     149             : 
     150             :         // IAssigmentData overridables
     151             :         virtual ::rtl::OUString getDatasourceName() const;
     152             :         virtual ::rtl::OUString getCommand() const;
     153             :         virtual sal_Int32       getCommandType() const;
     154             : 
     155             :         virtual sal_Bool        hasFieldAssignment(const ::rtl::OUString& _rLogicalName);
     156             :         virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName);
     157             :         virtual void            setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment);
     158             :         virtual void            clearFieldAssignment(const ::rtl::OUString& _rLogicalName);
     159             : 
     160             :         virtual void    setDatasourceName(const ::rtl::OUString& _rName);
     161             :         virtual void    setCommand(const ::rtl::OUString& _rCommand);
     162             :     };
     163             : 
     164             :     // -------------------------------------------------------------------
     165           0 :     AssigmentTransientData::AssigmentTransientData( const Reference< XDataSource >& _rxDataSource,
     166             :             const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rTableName,
     167             :             const Sequence< AliasProgrammaticPair >& _rFields )
     168             :         :m_xDataSource( _rxDataSource )
     169             :         ,m_sDSName( _rDataSourceName )
     170           0 :         ,m_sTableName( _rTableName )
     171             :     {
     172             :         // fill our aliaes structure
     173             :         // first collect all known programmatic names
     174           0 :         StringBag aKnownNames;
     175             : 
     176           0 :         rtl::OUString sLogicalFieldNames(SVT_RESSTR(STR_LOGICAL_FIELD_NAMES));
     177           0 :         sal_Int32 nIndex = 0;
     178           0 :         do
     179             :         {
     180           0 :             rtl::OUString aToken = sLogicalFieldNames.getToken(0, ';', nIndex);
     181           0 :             aKnownNames.insert(aToken);
     182             :         }
     183             :         while ( nIndex >= 0);
     184             : 
     185             :         // loop throuzh the given names
     186           0 :         const AliasProgrammaticPair* pFields = _rFields.getConstArray();
     187           0 :         const AliasProgrammaticPair* pFieldsEnd = pFields + _rFields.getLength();
     188           0 :         for (;pFields != pFieldsEnd; ++pFields)
     189             :         {
     190           0 :             StringBagIterator aKnownPos = aKnownNames.find( pFields->ProgrammaticName );
     191           0 :             if ( aKnownNames.end() != aKnownPos )
     192             :             {
     193           0 :                 m_aAliases[ pFields->ProgrammaticName ] = pFields->Alias;
     194             :             }
     195             :             else
     196             :             {
     197             :                 OSL_FAIL(   (   ::rtl::OString("AssigmentTransientData::AssigmentTransientData: unknown programmatic name (")
     198             :                                 +=  ::rtl::OString(pFields->ProgrammaticName.getStr(), pFields->ProgrammaticName.getLength(), RTL_TEXTENCODING_ASCII_US)
     199             :                                 +=  ::rtl::OString(")!")
     200             :                                 ).getStr()
     201             :                             );
     202             :             }
     203           0 :         }
     204           0 :     }
     205             : 
     206             :     // -------------------------------------------------------------------
     207           0 :     ::rtl::OUString AssigmentTransientData::getDatasourceName() const
     208             :     {
     209           0 :         return m_sDSName;
     210             :     }
     211             : 
     212             :     // -------------------------------------------------------------------
     213           0 :     ::rtl::OUString AssigmentTransientData::getCommand() const
     214             :     {
     215           0 :         return m_sTableName;
     216             :     }
     217             : 
     218             :     // -------------------------------------------------------------------
     219           0 :     sal_Int32 AssigmentTransientData::getCommandType() const
     220             :     {
     221           0 :         return CommandType::TABLE;
     222             :     }
     223             : 
     224             :     // -------------------------------------------------------------------
     225           0 :     sal_Bool AssigmentTransientData::hasFieldAssignment(const ::rtl::OUString& _rLogicalName)
     226             :     {
     227           0 :         ConstMapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
     228           0 :         return  ( m_aAliases.end() != aPos )
     229           0 :             &&  ( !aPos->second.isEmpty() );
     230             :     }
     231             : 
     232             :     // -------------------------------------------------------------------
     233           0 :     ::rtl::OUString AssigmentTransientData::getFieldAssignment(const ::rtl::OUString& _rLogicalName)
     234             :     {
     235           0 :         ::rtl::OUString sReturn;
     236           0 :         ConstMapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
     237           0 :         if ( m_aAliases.end() != aPos )
     238           0 :             sReturn = aPos->second;
     239             : 
     240           0 :         return sReturn;
     241             :     }
     242             : 
     243             :     // -------------------------------------------------------------------
     244           0 :     void AssigmentTransientData::setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment)
     245             :     {
     246           0 :         m_aAliases[ _rLogicalName ] = _rAssignment;
     247           0 :     }
     248             : 
     249             :     // -------------------------------------------------------------------
     250           0 :     void AssigmentTransientData::clearFieldAssignment(const ::rtl::OUString& _rLogicalName)
     251             :     {
     252           0 :         MapString2StringIterator aPos = m_aAliases.find( _rLogicalName );
     253           0 :         if ( m_aAliases.end() != aPos )
     254           0 :             m_aAliases.erase( aPos );
     255           0 :     }
     256             : 
     257             :     // -------------------------------------------------------------------
     258           0 :     void AssigmentTransientData::setDatasourceName(const ::rtl::OUString&)
     259             :     {
     260             :         OSL_FAIL( "AssigmentTransientData::setDatasourceName: cannot be implemented for transient data!" );
     261           0 :     }
     262             : 
     263             :     // -------------------------------------------------------------------
     264           0 :     void AssigmentTransientData::setCommand(const ::rtl::OUString&)
     265             :     {
     266             :         OSL_FAIL( "AssigmentTransientData::setCommand: cannot be implemented for transient data!" );
     267           0 :     }
     268             : 
     269             :     // ===================================================================
     270             :     // = AssignmentPersistentData
     271             :     // ===================================================================
     272             :     class AssignmentPersistentData
     273             :             :public ::utl::ConfigItem
     274             :             ,public IAssigmentData
     275             :     {
     276             :     protected:
     277             :         StringBag       m_aStoredFields;
     278             : 
     279             :     protected:
     280             :         ::com::sun::star::uno::Any
     281             :                         getProperty(const ::rtl::OUString& _rLocalName) const;
     282             :         ::com::sun::star::uno::Any
     283             :                         getProperty(const sal_Char* _pLocalName) const;
     284             : 
     285             :         ::rtl::OUString getStringProperty(const sal_Char* _pLocalName) const;
     286             :         sal_Int32       getInt32Property(const sal_Char* _pLocalName) const;
     287             : 
     288             :         ::rtl::OUString getStringProperty(const ::rtl::OUString& _rLocalName) const;
     289             : 
     290             :         void            setStringProperty(const sal_Char* _pLocalName, const ::rtl::OUString& _rValue);
     291             : 
     292             :     public:
     293             :         AssignmentPersistentData();
     294             :         ~AssignmentPersistentData();
     295             : 
     296             :         // IAssigmentData overridables
     297             :         virtual ::rtl::OUString getDatasourceName() const;
     298             :         virtual ::rtl::OUString getCommand() const;
     299             :         virtual sal_Int32       getCommandType() const;
     300             : 
     301             :         virtual sal_Bool        hasFieldAssignment(const ::rtl::OUString& _rLogicalName);
     302             :         virtual ::rtl::OUString getFieldAssignment(const ::rtl::OUString& _rLogicalName);
     303             :         virtual void            setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment);
     304             :         virtual void            clearFieldAssignment(const ::rtl::OUString& _rLogicalName);
     305             : 
     306             :         virtual void    setDatasourceName(const ::rtl::OUString& _rName);
     307             :         virtual void    setCommand(const ::rtl::OUString& _rCommand);
     308             : 
     309             :         virtual void    Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames);
     310             :         virtual void    Commit();
     311             :     };
     312             : 
     313             : 
     314           0 : void AssignmentPersistentData::Notify( const com::sun::star::uno::Sequence<rtl::OUString>& )
     315             : {
     316           0 : }
     317             : 
     318           0 : void AssignmentPersistentData::Commit()
     319             : {
     320           0 : }
     321             : 
     322             :     // -------------------------------------------------------------------
     323           0 :     AssignmentPersistentData::AssignmentPersistentData()
     324           0 :         :ConfigItem( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Office.DataAccess/AddressBook" )))
     325             :     {
     326           0 :         Sequence< ::rtl::OUString > aStoredNames = GetNodeNames(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Fields")));
     327           0 :         const ::rtl::OUString* pStoredNames = aStoredNames.getConstArray();
     328           0 :         for (sal_Int32 i=0; i<aStoredNames.getLength(); ++i, ++pStoredNames)
     329           0 :             m_aStoredFields.insert(*pStoredNames);
     330           0 :     }
     331             : 
     332             :     // -------------------------------------------------------------------
     333           0 :     AssignmentPersistentData::~AssignmentPersistentData()
     334             :     {
     335           0 :     }
     336             : 
     337             :     // -------------------------------------------------------------------
     338           0 :     sal_Bool AssignmentPersistentData::hasFieldAssignment(const ::rtl::OUString& _rLogicalName)
     339             :     {
     340           0 :         return (m_aStoredFields.end() != m_aStoredFields.find(_rLogicalName));
     341             :     }
     342             : 
     343             :     // -------------------------------------------------------------------
     344           0 :     ::rtl::OUString AssignmentPersistentData::getFieldAssignment(const ::rtl::OUString& _rLogicalName)
     345             :     {
     346           0 :         ::rtl::OUString sAssignment;
     347           0 :         if (hasFieldAssignment(_rLogicalName))
     348             :         {
     349           0 :             ::rtl::OUString sFieldPath(RTL_CONSTASCII_USTRINGPARAM("Fields/"));
     350           0 :             sFieldPath += _rLogicalName;
     351           0 :             sFieldPath += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
     352           0 :             sAssignment = getStringProperty(sFieldPath);
     353             :         }
     354           0 :         return sAssignment;
     355             :     }
     356             : 
     357             :     // -------------------------------------------------------------------
     358           0 :     Any AssignmentPersistentData::getProperty(const sal_Char* _pLocalName) const
     359             :     {
     360           0 :         return getProperty(::rtl::OUString::createFromAscii(_pLocalName));
     361             :     }
     362             : 
     363             :     // -------------------------------------------------------------------
     364           0 :     Any AssignmentPersistentData::getProperty(const ::rtl::OUString& _rLocalName) const
     365             :     {
     366           0 :         Sequence< ::rtl::OUString > aProperties(&_rLocalName, 1);
     367           0 :         Sequence< Any > aValues = const_cast<AssignmentPersistentData*>(this)->GetProperties(aProperties);
     368             :         DBG_ASSERT(aValues.getLength() == 1, "AssignmentPersistentData::getProperty: invalid sequence length!");
     369           0 :         return aValues[0];
     370             :     }
     371             : 
     372             :     // -------------------------------------------------------------------
     373           0 :     ::rtl::OUString AssignmentPersistentData::getStringProperty(const ::rtl::OUString& _rLocalName) const
     374             :     {
     375           0 :         ::rtl::OUString sReturn;
     376           0 :         getProperty( _rLocalName ) >>= sReturn;
     377           0 :         return sReturn;
     378             :     }
     379             : 
     380             :     // -------------------------------------------------------------------
     381           0 :     ::rtl::OUString AssignmentPersistentData::getStringProperty(const sal_Char* _pLocalName) const
     382             :     {
     383           0 :         ::rtl::OUString sReturn;
     384           0 :         getProperty( _pLocalName ) >>= sReturn;
     385           0 :         return sReturn;
     386             :     }
     387             : 
     388             :     // -------------------------------------------------------------------
     389           0 :     sal_Int32 AssignmentPersistentData::getInt32Property(const sal_Char* _pLocalName) const
     390             :     {
     391           0 :         sal_Int32 nReturn = 0;
     392           0 :         getProperty( _pLocalName ) >>= nReturn;
     393           0 :         return nReturn;
     394             :     }
     395             : 
     396             :     // -------------------------------------------------------------------
     397           0 :     void AssignmentPersistentData::setStringProperty(const sal_Char* _pLocalName, const ::rtl::OUString& _rValue)
     398             :     {
     399           0 :         Sequence< ::rtl::OUString > aNames(1);
     400           0 :         Sequence< Any > aValues(1);
     401           0 :         aNames[0] = ::rtl::OUString::createFromAscii(_pLocalName);
     402           0 :         aValues[0] <<= _rValue;
     403           0 :         PutProperties(aNames, aValues);
     404           0 :     }
     405             : 
     406             :     // -------------------------------------------------------------------
     407           0 :     void AssignmentPersistentData::setFieldAssignment(const ::rtl::OUString& _rLogicalName, const ::rtl::OUString& _rAssignment)
     408             :     {
     409           0 :         if (_rAssignment.isEmpty())
     410             :         {
     411           0 :             if (hasFieldAssignment(_rLogicalName))
     412             :                 // the assignment exists but it should be reset
     413           0 :                 clearFieldAssignment(_rLogicalName);
     414           0 :                 return;
     415             :         }
     416             : 
     417             :         // Fields
     418           0 :         ::rtl::OUString sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));
     419             : 
     420             :         // Fields/<field>
     421           0 :         ::rtl::OUString sFieldElementNodePath(sDescriptionNodePath);
     422           0 :         sFieldElementNodePath += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
     423           0 :         sFieldElementNodePath += _rLogicalName;
     424             : 
     425           0 :         Sequence< PropertyValue > aNewFieldDescription(2);
     426             :         // Fields/<field>/ProgrammaticFieldName
     427           0 :         aNewFieldDescription[0].Name = sFieldElementNodePath;
     428           0 :         aNewFieldDescription[0].Name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/ProgrammaticFieldName"));
     429           0 :         aNewFieldDescription[0].Value <<= _rLogicalName;
     430             :         // Fields/<field>/AssignedFieldName
     431           0 :         aNewFieldDescription[1].Name = sFieldElementNodePath;
     432           0 :         aNewFieldDescription[1].Name += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/AssignedFieldName"));
     433           0 :         aNewFieldDescription[1].Value <<= _rAssignment;
     434             : 
     435             :         // just set the new value
     436             : #ifdef DBG_UTIL
     437             :         sal_Bool bSuccess =
     438             : #endif
     439           0 :         SetSetProperties(sDescriptionNodePath, aNewFieldDescription);
     440           0 :         DBG_ASSERT(bSuccess, "AssignmentPersistentData::setFieldAssignment: could not commit the changes a field!");
     441             :     }
     442             : 
     443             :     // -------------------------------------------------------------------
     444           0 :     void AssignmentPersistentData::clearFieldAssignment(const ::rtl::OUString& _rLogicalName)
     445             :     {
     446           0 :         if (!hasFieldAssignment(_rLogicalName))
     447             :             // nothing to do
     448           0 :             return;
     449             : 
     450           0 :         ::rtl::OUString sDescriptionNodePath(RTL_CONSTASCII_USTRINGPARAM("Fields"));
     451           0 :         Sequence< ::rtl::OUString > aNames(&_rLogicalName, 1);
     452           0 :         ClearNodeElements(sDescriptionNodePath, aNames);
     453             :     }
     454             : 
     455             :     // -------------------------------------------------------------------
     456           0 :     ::rtl::OUString AssignmentPersistentData::getDatasourceName() const
     457             :     {
     458           0 :         return getStringProperty( "DataSourceName" );
     459             :     }
     460             : 
     461             :     // -------------------------------------------------------------------
     462           0 :     ::rtl::OUString AssignmentPersistentData::getCommand() const
     463             :     {
     464           0 :         return getStringProperty( "Command" );
     465             :     }
     466             : 
     467             :     // -------------------------------------------------------------------
     468           0 :     void AssignmentPersistentData::setDatasourceName(const ::rtl::OUString& _rName)
     469             :     {
     470           0 :         setStringProperty( "DataSourceName", _rName );
     471           0 :     }
     472             : 
     473             :     // -------------------------------------------------------------------
     474           0 :     void AssignmentPersistentData::setCommand(const ::rtl::OUString& _rCommand)
     475             :     {
     476           0 :         setStringProperty( "Command", _rCommand );
     477           0 :     }
     478             : 
     479             :     // -------------------------------------------------------------------
     480           0 :     sal_Int32 AssignmentPersistentData::getCommandType() const
     481             :     {
     482           0 :         return getInt32Property( "CommandType" );
     483             :     }
     484             : 
     485             :     // ===================================================================
     486             :     // = AddressBookSourceDialogData
     487             :     // ===================================================================
     488             :     struct AddressBookSourceDialogData
     489             :     {
     490             :         FixedText*      pFieldLabels[FIELD_PAIRS_VISIBLE * 2];
     491             :         ListBox*        pFields[FIELD_PAIRS_VISIBLE * 2];
     492             : 
     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;
     504             : 
     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;
     511             : 
     512             :         IAssigmentData* pConfigData;
     513             : 
     514             :         // ................................................................
     515           0 :         AddressBookSourceDialogData( )
     516             :             :nFieldScrollPos(0)
     517             :             ,nLastVisibleListIndex(0)
     518             :             ,bOddFieldNumber(sal_False)
     519             :             ,bWorkingPersistent( sal_True )
     520           0 :             ,pConfigData( new AssignmentPersistentData )
     521             :         {
     522           0 :         }
     523             : 
     524             :         // ................................................................
     525           0 :         AddressBookSourceDialogData( const Reference< XDataSource >& _rxTransientDS, const ::rtl::OUString& _rDataSourceName,
     526             :             const ::rtl::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           0 :             ,pConfigData( new AssigmentTransientData( m_xTransientDataSource, _rDataSourceName, _rTableName, _rFields ) )
     533             :         {
     534           0 :         }
     535             : 
     536           0 :         ~AddressBookSourceDialogData()
     537           0 :         {
     538           0 :             delete pConfigData;
     539           0 :         }
     540             : 
     541             :     };
     542             : 
     543             :     // ===================================================================
     544             :     // = AddressBookSourceDialog
     545             :     // ===================================================================
     546             : #define INIT_FIELDS()   \
     547             :          ModalDialog(_pParent, SvtResId( DLG_ADDRESSBOOKSOURCE ))\
     548             :         ,m_aDatasourceFrame         (this, SvtResId(FL_DATASOURCEFRAME))\
     549             :         ,m_aDatasourceLabel         (this, SvtResId(FT_DATASOURCE))\
     550             :         ,m_aDatasource              (this, SvtResId(CB_DATASOURCE))\
     551             :         ,m_aAdministrateDatasources (this, SvtResId(PB_ADMINISTATE_DATASOURCES))\
     552             :         ,m_aTableLabel              (this, SvtResId(FT_TABLE))\
     553             :         ,m_aTable                   (this, SvtResId(CB_TABLE))\
     554             :         ,m_aFieldsTitle             (this, SvtResId(FT_FIELDS))\
     555             :         ,m_aFieldsFrame             (this, SvtResId(CT_BORDER))\
     556             :         ,m_aFieldScroller           (&m_aFieldsFrame, SvtResId(SB_FIELDSCROLLER))\
     557             :         ,m_aOK                      (this, SvtResId(PB_OK))\
     558             :         ,m_aCancel                  (this, SvtResId(PB_CANCEL))\
     559             :         ,m_aHelp                    (this, SvtResId(PB_HELP))\
     560             :         ,m_sNoFieldSelection(SVT_RESSTR(STR_NO_FIELD_SELECTION))\
     561             :         ,m_xORB(_rxORB)
     562             : 
     563             :     // -------------------------------------------------------------------
     564           0 :     AddressBookSourceDialog::AddressBookSourceDialog(Window* _pParent,
     565             :             const Reference< XMultiServiceFactory >& _rxORB )
     566             :         :INIT_FIELDS()
     567           0 :         ,m_pImpl( new AddressBookSourceDialogData )
     568             :     {
     569           0 :         implConstruct();
     570           0 :     }
     571             : 
     572             :     // -------------------------------------------------------------------
     573           0 :     AddressBookSourceDialog::AddressBookSourceDialog( Window* _pParent, const Reference< XMultiServiceFactory >& _rxORB,
     574             :         const Reference< XDataSource >& _rxTransientDS, const ::rtl::OUString& _rDataSourceName,
     575             :         const ::rtl::OUString& _rTable, const Sequence< AliasProgrammaticPair >& _rMapping )
     576             :         :INIT_FIELDS()
     577           0 :         ,m_pImpl( new AddressBookSourceDialogData( _rxTransientDS, _rDataSourceName, _rTable, _rMapping ) )
     578             :     {
     579           0 :         implConstruct();
     580           0 :     }
     581             : 
     582             :     // -------------------------------------------------------------------
     583           0 :     void AddressBookSourceDialog::implConstruct()
     584             :     {
     585           0 :         for (sal_Int32 row=0; row<FIELD_PAIRS_VISIBLE; ++row)
     586             :         {
     587           0 :             for (sal_Int32 column=0; column<2; ++column)
     588             :             {
     589             :                 // the label
     590           0 :                 m_pImpl->pFieldLabels[row * 2 + column] = new FixedText(&m_aFieldsFrame, SvtResId((sal_uInt16)(FT_FIELD_BASE + row * 2 + column)));
     591             :                 // the listbox
     592           0 :                 m_pImpl->pFields[row * 2 + column] = new ListBox(&m_aFieldsFrame, SvtResId((sal_uInt16)(LB_FIELD_BASE + row * 2 + column)));
     593           0 :                 m_pImpl->pFields[row * 2 + column]->SetDropDownLineCount(15);
     594           0 :                 m_pImpl->pFields[row * 2 + column]->SetSelectHdl(LINK(this, AddressBookSourceDialog, OnFieldSelect));
     595             : 
     596           0 :                 m_pImpl->pFields[row * 2 + column]->SetHelpId(HID_ADDRTEMPL_FIELD_ASSIGNMENT);
     597             :             }
     598             :         }
     599             : 
     600           0 :         m_aFieldsFrame.SetStyle((m_aFieldsFrame.GetStyle() | WB_TABSTOP | WB_DIALOGCONTROL) & ~WB_NODIALOGCONTROL);
     601             : 
     602             :         // correct the z-order
     603           0 :         m_aFieldScroller.SetZOrder(m_pImpl->pFields[FIELD_CONTROLS_VISIBLE - 1], WINDOW_ZORDER_BEHIND);
     604           0 :         m_aOK.SetZOrder(&m_aFieldsFrame, WINDOW_ZORDER_BEHIND);
     605           0 :         m_aCancel.SetZOrder(&m_aOK, WINDOW_ZORDER_BEHIND);
     606             : 
     607           0 :         initializeDatasources();
     608             : 
     609             :         // for the moment, we have a hard coded list of all known fields.
     610             :         // A better solution would be to store all known field translations in the configuration, which could be
     611             :         // extensible by the user in an arbitrary way.
     612             :         // But for the moment we need a quick solution ...
     613             :         // (the main thing would be to store the translations to use here in the user interface, besides that, the code
     614             :         // should be adjustable with a rather small effort.)
     615             : 
     616             :         // initialize the strings for the field labels
     617           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_FIRSTNAME ));
     618           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_LASTNAME ));
     619           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_COMPANY));
     620           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_DEPARTMENT ));
     621           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_STREET ));
     622           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_ZIPCODE ));
     623           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_CITY ));
     624           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_STATE));
     625           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_COUNTRY ));
     626           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_HOMETEL ));
     627           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_WORKTEL ));
     628           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_OFFICETEL));
     629           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_MOBILE));
     630           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_TELOTHER));
     631           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_PAGER));
     632           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_FAX ));
     633           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_EMAIL ));
     634           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_URL ));
     635           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_TITLE ));
     636           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_POSITION ));
     637           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_INITIALS ));
     638           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_ADDRFORM ));
     639           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_SALUTATION ));
     640           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_ID));
     641           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_CALENDAR));
     642           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_INVITE));
     643           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_NOTE));
     644           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_USER1));
     645           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_USER2));
     646           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_USER3));
     647           0 :         m_pImpl->aFieldLabels.push_back( SVT_RESSTR( STR_FIELD_USER4));
     648             : 
     649             :         // force a even number of known fields
     650           0 :         m_pImpl->bOddFieldNumber = (m_pImpl->aFieldLabels.size() % 2) != 0;
     651           0 :         if (m_pImpl->bOddFieldNumber)
     652           0 :             m_pImpl->aFieldLabels.push_back( String() );
     653             : 
     654             :         // limit the scrollbar range accordingly
     655           0 :         sal_Int32 nOverallFieldPairs = m_pImpl->aFieldLabels.size() / 2;
     656           0 :         m_aFieldScroller.SetRange( Range(0, nOverallFieldPairs - FIELD_PAIRS_VISIBLE) );
     657           0 :         m_aFieldScroller.SetLineSize(1);
     658           0 :         m_aFieldScroller.SetPageSize(FIELD_PAIRS_VISIBLE);
     659             : 
     660             :         // reset the current field assignments
     661           0 :         m_pImpl->aFieldAssignments.resize(m_pImpl->aFieldLabels.size());
     662             :             // (empty strings mean "no assignment")
     663             : 
     664             :         // some knittings
     665           0 :         m_aFieldScroller.SetScrollHdl(LINK(this, AddressBookSourceDialog, OnFieldScroll));
     666           0 :         m_aAdministrateDatasources.SetClickHdl(LINK(this, AddressBookSourceDialog, OnAdministrateDatasources));
     667           0 :         m_aDatasource.EnableAutocomplete(sal_True);
     668           0 :         m_aTable.EnableAutocomplete(sal_True);
     669           0 :         m_aTable.SetGetFocusHdl(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
     670           0 :         m_aDatasource.SetGetFocusHdl(LINK(this, AddressBookSourceDialog, OnComboGetFocus));
     671           0 :         m_aTable.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
     672           0 :         m_aDatasource.SetLoseFocusHdl(LINK(this, AddressBookSourceDialog, OnComboLoseFocus));
     673           0 :         m_aTable.SetSelectHdl(LINK(this, AddressBookSourceDialog, OnComboSelect));
     674           0 :         m_aDatasource.SetSelectHdl(LINK(this, AddressBookSourceDialog, OnComboSelect));
     675           0 :         m_aOK.SetClickHdl(LINK(this, AddressBookSourceDialog, OnOkClicked));
     676             : 
     677           0 :         m_aDatasource.SetDropDownLineCount(15);
     678             : 
     679             :         // initialize the field controls
     680           0 :         resetFields();
     681           0 :         m_aFieldScroller.SetThumbPos(0);
     682           0 :         m_pImpl->nFieldScrollPos = -1;
     683           0 :         implScrollFields(0, sal_False, sal_False);
     684             : 
     685             :         // the logical names
     686           0 :         rtl::OUString sLogicalFieldNames(SVT_RESSTR(STR_LOGICAL_FIELD_NAMES));
     687           0 :         sal_Int32 nAdjustedTokenCount = comphelper::string::getTokenCount(sLogicalFieldNames, ';') + (m_pImpl->bOddFieldNumber ? 1 : 0);
     688             :         DBG_ASSERT(nAdjustedTokenCount == (sal_Int32)m_pImpl->aFieldLabels.size(),
     689             :             "AddressBookSourceDialog::AddressBookSourceDialog: inconsistence between logical and UI field names!");
     690           0 :         m_pImpl->aLogicalFieldNames.reserve(nAdjustedTokenCount);
     691           0 :         for (sal_Int32 i = 0; i<nAdjustedTokenCount; ++i)
     692           0 :             m_pImpl->aLogicalFieldNames.push_back(comphelper::string::getToken(sLogicalFieldNames, i, ';'));
     693             : 
     694           0 :         PostUserEvent(LINK(this, AddressBookSourceDialog, OnDelayedInitialize));
     695             :             // so the dialog will at least show up before we do the loading of the
     696             :             // configuration data and the (maybe time consuming) analysis of the data source/table to select
     697             : 
     698           0 :         FreeResource();
     699             : 
     700           0 :         if ( !m_pImpl->bWorkingPersistent )
     701             :         {
     702           0 :             StyleSettings aSystemStyle = GetSettings().GetStyleSettings();
     703           0 :             const Color& rNewColor = aSystemStyle.GetDialogColor();
     704             : 
     705           0 :             m_aDatasource.SetReadOnly( sal_True );
     706           0 :             m_aDatasource.SetBackground( Wallpaper( rNewColor ) );
     707           0 :             m_aDatasource.SetControlBackground( rNewColor );
     708             : 
     709           0 :             m_aTable.SetReadOnly( sal_True );
     710           0 :             m_aTable.SetBackground( Wallpaper( rNewColor ) );
     711           0 :             m_aTable.SetControlBackground( rNewColor );
     712             : 
     713           0 :             m_aAdministrateDatasources.Hide( );
     714           0 :         }
     715           0 :     }
     716             : 
     717             :     // -------------------------------------------------------------------
     718           0 :     void AddressBookSourceDialog::getFieldMapping(Sequence< AliasProgrammaticPair >& _rMapping) const
     719             :     {
     720           0 :         _rMapping.realloc( m_pImpl->aLogicalFieldNames.size() );
     721           0 :         AliasProgrammaticPair* pPair = _rMapping.getArray();
     722             : 
     723           0 :         ::rtl::OUString sCurrent;
     724           0 :         for (   ConstStringArrayIterator aProgrammatic = m_pImpl->aLogicalFieldNames.begin();
     725           0 :                 aProgrammatic != m_pImpl->aLogicalFieldNames.end();
     726             :                 ++aProgrammatic
     727             :             )
     728             :         {
     729           0 :             sCurrent = *aProgrammatic;
     730           0 :             if ( m_pImpl->pConfigData->hasFieldAssignment( sCurrent ) )
     731             :             {
     732             :                 // the user gave us an assignment for this field
     733           0 :                 pPair->ProgrammaticName = *aProgrammatic;
     734           0 :                 pPair->Alias = m_pImpl->pConfigData->getFieldAssignment( *aProgrammatic );
     735           0 :                 ++pPair;
     736             :             }
     737             :         }
     738             : 
     739           0 :         _rMapping.realloc( pPair - _rMapping.getArray() );
     740           0 :     }
     741             : 
     742             :     // -------------------------------------------------------------------
     743           0 :     void AddressBookSourceDialog::loadConfiguration()
     744             :     {
     745           0 :         ::rtl::OUString sName = m_pImpl->pConfigData->getDatasourceName();
     746           0 :         INetURLObject aURL( sName );
     747           0 :         if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
     748             :         {
     749           0 :             OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
     750           0 :             sName = aFileNotation.get(OFileNotation::N_SYSTEM);
     751             :         }
     752             : 
     753           0 :         m_aDatasource.SetText(sName);
     754           0 :         m_aTable.SetText(m_pImpl->pConfigData->getCommand());
     755             :         // we ignore the CommandType: only tables are supported
     756             : 
     757             :         // the logical names for the fields
     758             :         DBG_ASSERT(m_pImpl->aLogicalFieldNames.size() == m_pImpl->aFieldAssignments.size(),
     759             :             "AddressBookSourceDialog::loadConfiguration: inconsistence between field names and field assignments!");
     760             : 
     761           0 :         ConstStringArrayIterator aLogical = m_pImpl->aLogicalFieldNames.begin();
     762           0 :         StringArrayIterator aAssignment = m_pImpl->aFieldAssignments.begin();
     763           0 :         for (   ;
     764           0 :                 aLogical < m_pImpl->aLogicalFieldNames.end();
     765             :                 ++aLogical, ++aAssignment
     766             :             )
     767           0 :             *aAssignment = m_pImpl->pConfigData->getFieldAssignment(*aLogical);
     768           0 :     }
     769             : 
     770             :     // -------------------------------------------------------------------
     771           0 :     AddressBookSourceDialog::~AddressBookSourceDialog()
     772             :     {
     773             :         sal_Int32 i;
     774           0 :         for (i=0; i<FIELD_CONTROLS_VISIBLE; ++i)
     775             :         {
     776           0 :             delete m_pImpl->pFieldLabels[i];
     777           0 :             delete m_pImpl->pFields[i];
     778             :         }
     779             : 
     780           0 :         delete m_pImpl;
     781           0 :     }
     782             : 
     783             :     // -------------------------------------------------------------------
     784           0 :     void AddressBookSourceDialog::initializeDatasources()
     785             :     {
     786           0 :         if (!m_xDatabaseContext.is())
     787             :         {
     788             :             DBG_ASSERT(m_xORB.is(), "AddressBookSourceDialog::initializeDatasources: no service factory!");
     789           0 :             if (!m_xORB.is())
     790             :                 return;
     791             : 
     792             :             try
     793             :             {
     794           0 :                 m_xDatabaseContext = DatabaseContext::create(comphelper::getComponentContext(m_xORB));
     795             :             }
     796           0 :             catch(Exception&) { }
     797           0 :             if (!m_xDatabaseContext.is())
     798             :             {
     799           0 :                 const rtl::OUString sContextServiceName("com.sun.star.sdb.DatabaseContext");
     800           0 :                 ShowServiceNotAvailableError( this, sContextServiceName, sal_False);
     801           0 :                 return;
     802             :             }
     803             :         }
     804           0 :         m_aDatasource.Clear();
     805             : 
     806             :         // fill the datasources listbox
     807           0 :         Sequence< ::rtl::OUString > aDatasourceNames;
     808             :         try
     809             :         {
     810           0 :             aDatasourceNames = m_xDatabaseContext->getElementNames();
     811             :         }
     812           0 :         catch(Exception&)
     813             :         {
     814             :             OSL_FAIL("AddressBookSourceDialog::initializeDatasources: caught an exception while asking for the data source names!");
     815             :         }
     816           0 :         const ::rtl::OUString* pDatasourceNames = aDatasourceNames.getConstArray();
     817           0 :         const ::rtl::OUString* pEnd = pDatasourceNames + aDatasourceNames.getLength();
     818           0 :         for (; pDatasourceNames < pEnd; ++pDatasourceNames)
     819           0 :             m_aDatasource.InsertEntry(*pDatasourceNames);
     820             :     }
     821             : 
     822             :     // -------------------------------------------------------------------
     823           0 :     IMPL_LINK(AddressBookSourceDialog, OnFieldScroll, ScrollBar*, _pScrollBar)
     824             :     {
     825           0 :         implScrollFields( _pScrollBar->GetThumbPos(), sal_True, sal_True );
     826           0 :         return 0L;
     827             :     }
     828             : 
     829             :     // -------------------------------------------------------------------
     830           0 :     void AddressBookSourceDialog::resetTables()
     831             :     {
     832           0 :         if (!m_xDatabaseContext.is())
     833             :             return;
     834             : 
     835           0 :         WaitObject aWaitCursor(this);
     836             : 
     837             :         // no matter what we do here, we handled the currently selected data source (no matter if successfull or not)
     838           0 :         m_aDatasource.SaveValue();
     839             : 
     840             :         // create an interaction handler (may be needed for connecting)
     841           0 :         Reference< XInteractionHandler > xHandler;
     842             :         try
     843             :         {
     844             :             xHandler.set(
     845             :                 InteractionHandler::createWithParent(comphelper::getComponentContext(m_xORB), 0),
     846           0 :                 UNO_QUERY_THROW );
     847             :         }
     848           0 :         catch(Exception&) { }
     849           0 :         if (!xHandler.is())
     850             :         {
     851           0 :             const rtl::OUString sInteractionHandlerServiceName("com.sun.star.task.InteractionHandler");
     852           0 :             ShowServiceNotAvailableError(this, sInteractionHandlerServiceName, sal_True);
     853           0 :             return;
     854             :         }
     855             : 
     856             :         // the currently selected table
     857           0 :         ::rtl::OUString sOldTable = m_aTable.GetText();
     858             : 
     859           0 :         m_aTable.Clear();
     860             : 
     861           0 :         m_xCurrentDatasourceTables= NULL;
     862             : 
     863             :         // get the tables of the connection
     864           0 :         Sequence< ::rtl::OUString > aTableNames;
     865           0 :         Any aException;
     866             :         try
     867             :         {
     868           0 :             Reference< XCompletedConnection > xDS;
     869           0 :             if ( m_pImpl->bWorkingPersistent )
     870             :             {
     871           0 :                 String sSelectedDS = lcl_getSelectedDataSource(  m_aDatasource );
     872             : 
     873             :                 // get the data source the user has chosen and let it build a connection
     874           0 :                 INetURLObject aURL( sSelectedDS );
     875           0 :                 if ( aURL.GetProtocol() != INET_PROT_NOT_VALID || m_xDatabaseContext->hasByName(sSelectedDS) )
     876           0 :                     m_xDatabaseContext->getByName( sSelectedDS ) >>= xDS;
     877             :             }
     878             :             else
     879             :             {
     880           0 :                 xDS = xDS.query( m_pImpl->m_xTransientDataSource );
     881             :             }
     882             : 
     883             :             // build the connection
     884           0 :             Reference< XConnection > xConn;
     885           0 :             if (xDS.is())
     886           0 :                 xConn = xDS->connectWithCompletion(xHandler);
     887             : 
     888             :             // get the table names
     889           0 :             Reference< XTablesSupplier > xSupplTables(xConn, UNO_QUERY);
     890           0 :             if (xSupplTables.is())
     891             :             {
     892           0 :                 m_xCurrentDatasourceTables = Reference< XNameAccess >(xSupplTables->getTables(), UNO_QUERY);
     893           0 :                 if (m_xCurrentDatasourceTables.is())
     894           0 :                     aTableNames = m_xCurrentDatasourceTables->getElementNames();
     895           0 :             }
     896             :         }
     897           0 :         catch(const SQLContext& e) { aException <<= e; }
     898           0 :         catch(const SQLWarning& e) { aException <<= e; }
     899           0 :         catch(const SQLException& e) { aException <<= e; }
     900           0 :         catch(Exception&)
     901             :         {
     902             :             OSL_FAIL("AddressBookSourceDialog::resetTables: could not retrieve the table!");
     903             :         }
     904             : 
     905           0 :         if (aException.hasValue())
     906             :         {
     907           0 :             Reference< XInteractionRequest > xRequest = new OInteractionRequest(aException);
     908             :             try
     909             :             {
     910           0 :                 xHandler->handle(xRequest);
     911             :             }
     912           0 :             catch(Exception&) { }
     913           0 :             return;
     914             :         }
     915             : 
     916           0 :         sal_Bool bKnowOldTable = sal_False;
     917             :         // fill the table list
     918           0 :         const ::rtl::OUString* pTableNames = aTableNames.getConstArray();
     919           0 :         const ::rtl::OUString* pEnd = pTableNames + aTableNames.getLength();
     920           0 :         for (;pTableNames != pEnd; ++pTableNames)
     921             :         {
     922           0 :             m_aTable.InsertEntry(*pTableNames);
     923           0 :             if (0 == pTableNames->compareTo(sOldTable))
     924           0 :                 bKnowOldTable = sal_True;
     925             :         }
     926             : 
     927             :         // set the old table, if the new data source knows a table with this name, too. Else reset the tables edit field.
     928           0 :         if (!bKnowOldTable)
     929           0 :             sOldTable = ::rtl::OUString();
     930           0 :         m_aTable.SetText(sOldTable);
     931             : 
     932           0 :         resetFields();
     933             :     }
     934             : 
     935             :     // -------------------------------------------------------------------
     936           0 :     void AddressBookSourceDialog::resetFields()
     937             :     {
     938           0 :         WaitObject aWaitCursor(this);
     939             : 
     940             :         // no matter what we do here, we handled the currently selected table (no matter if successfull or not)
     941           0 :         m_aDatasource.SaveValue();
     942             : 
     943           0 :         String sSelectedTable = m_aTable.GetText();
     944           0 :         Sequence< ::rtl::OUString > aColumnNames;
     945             :         try
     946             :         {
     947           0 :             if (m_xCurrentDatasourceTables.is())
     948             :             {
     949             :                 // get the table and the columns
     950           0 :                 Reference< XColumnsSupplier > xSuppTableCols;
     951           0 :                 if (m_xCurrentDatasourceTables->hasByName(sSelectedTable))
     952           0 :                     ::cppu::extractInterface(xSuppTableCols, m_xCurrentDatasourceTables->getByName(sSelectedTable));
     953           0 :                 Reference< XNameAccess > xColumns;
     954           0 :                 if (xSuppTableCols.is())
     955           0 :                     xColumns = xSuppTableCols->getColumns();
     956           0 :                 if (xColumns.is())
     957           0 :                     aColumnNames = xColumns->getElementNames();
     958             :             }
     959             :         }
     960           0 :         catch(Exception&)
     961             :         {
     962             :             OSL_FAIL("AddressBookSourceDialog::resetFields: could not retrieve the table columns!");
     963             :         }
     964             : 
     965             : 
     966           0 :         const ::rtl::OUString* pColumnNames = aColumnNames.getConstArray();
     967           0 :         const ::rtl::OUString* pEnd = pColumnNames + aColumnNames.getLength();
     968             : 
     969             :         // for quicker access
     970           0 :         ::std::set< String > aColumnNameSet;
     971           0 :         for (pColumnNames = aColumnNames.getConstArray(); pColumnNames != pEnd; ++pColumnNames)
     972           0 :             aColumnNameSet.insert(*pColumnNames);
     973             : 
     974           0 :         std::vector<String>::iterator aInitialSelection = m_pImpl->aFieldAssignments.begin() + m_pImpl->nFieldScrollPos;
     975             : 
     976           0 :         ListBox** pListbox = m_pImpl->pFields;
     977           0 :         String sSaveSelection;
     978           0 :         for (sal_Int32 i=0; i<FIELD_CONTROLS_VISIBLE; ++i, ++pListbox, ++aInitialSelection)
     979             :         {
     980           0 :             sSaveSelection = (*pListbox)->GetSelectEntry();
     981             : 
     982           0 :             (*pListbox)->Clear();
     983             : 
     984             :             // the one entry for "no selection"
     985           0 :             (*pListbox)->InsertEntry(m_sNoFieldSelection, 0);
     986             :             // as it's entry data, set the index of the list box in our array
     987           0 :             (*pListbox)->SetEntryData(0, reinterpret_cast<void*>(i));
     988             : 
     989             :             // the field names
     990           0 :             for (pColumnNames = aColumnNames.getConstArray(); pColumnNames != pEnd; ++pColumnNames)
     991           0 :                 (*pListbox)->InsertEntry(*pColumnNames);
     992             : 
     993           0 :             if (aInitialSelection->Len() && (aColumnNameSet.end() != aColumnNameSet.find(*aInitialSelection)))
     994             :                 // we can select the entry as specified in our field assignment array
     995           0 :                 (*pListbox)->SelectEntry(*aInitialSelection);
     996             :             else
     997             :                 // try to restore the selection
     998           0 :                 if (aColumnNameSet.end() != aColumnNameSet.find(sSaveSelection))
     999             :                     // the old selection is a valid column name
    1000           0 :                     (*pListbox)->SelectEntry(sSaveSelection);
    1001             :                 else
    1002             :                     // select the <none> entry
    1003           0 :                     (*pListbox)->SelectEntryPos(0);
    1004             :         }
    1005             : 
    1006             :         // adjust m_pImpl->aFieldAssignments
    1007           0 :         for (   StringArrayIterator aAdjust = m_pImpl->aFieldAssignments.begin();
    1008           0 :                 aAdjust != m_pImpl->aFieldAssignments.end();
    1009             :                 ++aAdjust
    1010             :             )
    1011           0 :             if (aAdjust->Len())
    1012           0 :                 if (aColumnNameSet.end() == aColumnNameSet.find(*aAdjust))
    1013           0 :                     aAdjust->Erase();
    1014           0 :     }
    1015             : 
    1016             :     // -------------------------------------------------------------------
    1017           0 :     IMPL_LINK(AddressBookSourceDialog, OnFieldSelect, ListBox*, _pListbox)
    1018             :     {
    1019             :         // the index of the affected list box in our array
    1020           0 :         sal_IntPtr nListBoxIndex = reinterpret_cast<sal_IntPtr>(_pListbox->GetEntryData(0));
    1021             :         DBG_ASSERT(nListBoxIndex >= 0 && nListBoxIndex < FIELD_CONTROLS_VISIBLE,
    1022             :             "AddressBookSourceDialog::OnFieldScroll: invalid list box entry!");
    1023             : 
    1024             :         // update the array where we remember the field selections
    1025           0 :         if (0 == _pListbox->GetSelectEntryPos())
    1026             :             // it's the "no field selection" entry
    1027           0 :             m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = String();
    1028             :         else
    1029             :             // it's a regular field entry
    1030           0 :             m_pImpl->aFieldAssignments[m_pImpl->nFieldScrollPos * 2 + nListBoxIndex] = _pListbox->GetSelectEntry();
    1031             : 
    1032           0 :         return 0L;
    1033             :     }
    1034             : 
    1035             :     // -------------------------------------------------------------------
    1036           0 :     void AddressBookSourceDialog::implScrollFields(sal_Int32 _nPos, sal_Bool _bAdjustFocus, sal_Bool _bAdjustScrollbar)
    1037             :     {
    1038           0 :         if (_nPos == m_pImpl->nFieldScrollPos)
    1039             :             // nothing to do
    1040           0 :             return;
    1041             : 
    1042             :         // loop through our field control rows and do some adjustments
    1043             :         // for the new texts
    1044           0 :         FixedText** pLeftLabelControl = m_pImpl->pFieldLabels;
    1045           0 :         FixedText** pRightLabelControl = pLeftLabelControl + 1;
    1046           0 :         ConstStringArrayIterator pLeftColumnLabel = m_pImpl->aFieldLabels.begin() + 2 * _nPos;
    1047           0 :         ConstStringArrayIterator pRightColumnLabel = pLeftColumnLabel + 1;
    1048             : 
    1049             :         // for the focus movement and the selection scroll
    1050           0 :         ListBox** pLeftListControl = m_pImpl->pFields;
    1051           0 :         ListBox** pRightListControl = pLeftListControl + 1;
    1052             : 
    1053             :         // for the focus movement
    1054           0 :         sal_Int32 nOldFocusRow = -1;
    1055           0 :         sal_Int32 nOldFocusColumn = 0;
    1056             : 
    1057             :         // for the selection scroll
    1058           0 :         ConstStringArrayIterator pLeftAssignment = m_pImpl->aFieldAssignments.begin() + 2 * _nPos;
    1059           0 :         ConstStringArrayIterator pRightAssignment = pLeftAssignment + 1;
    1060             : 
    1061           0 :         m_pImpl->nLastVisibleListIndex = -1;
    1062             :         // loop
    1063           0 :         for (sal_Int32 i=0; i<FIELD_PAIRS_VISIBLE; ++i)
    1064             :         {
    1065           0 :             if ((*pLeftListControl)->HasChildPathFocus())
    1066             :             {
    1067           0 :                 nOldFocusRow = i;
    1068           0 :                 nOldFocusColumn = 0;
    1069             :             }
    1070           0 :             else if ((*pRightListControl)->HasChildPathFocus())
    1071             :             {
    1072           0 :                 nOldFocusRow = i;
    1073           0 :                 nOldFocusColumn = 1;
    1074             :             }
    1075             : 
    1076             :             // the new texts of the label controls
    1077           0 :             (*pLeftLabelControl)->SetText(*pLeftColumnLabel);
    1078           0 :             (*pRightLabelControl)->SetText(*pRightColumnLabel);
    1079             : 
    1080             :             // we may have to hide the controls in the right column, if we have no label text for it
    1081             :             // (which means we have an odd number of fields, though we forced our internal arrays to
    1082             :             // be even-sized for easier handling)
    1083             :             // (If sometimes we support an arbitrary number of field assignments, we would have to care for
    1084             :             // an invisible left hand side column, too. But right now, the left hand side controls are always
    1085             :             // visible)
    1086           0 :             sal_Bool bHideRightColumn = (0 == pRightColumnLabel->Len());
    1087           0 :             (*pRightLabelControl)->Show(!bHideRightColumn);
    1088           0 :             (*pRightListControl)->Show(!bHideRightColumn);
    1089             :             // the new selections of the listboxes
    1090           0 :             implSelectField(*pLeftListControl, *pLeftAssignment);
    1091           0 :             implSelectField(*pRightListControl, *pRightAssignment);
    1092             : 
    1093             :             // the index of the last visible list box
    1094           0 :             ++m_pImpl->nLastVisibleListIndex;   // the left hand side box is always visible
    1095           0 :             if (!bHideRightColumn)
    1096           0 :                 ++m_pImpl->nLastVisibleListIndex;
    1097             : 
    1098             :             // increment ...
    1099           0 :             if ( i < FIELD_PAIRS_VISIBLE - 1 )
    1100             :             {   // (not in the very last round, here the +=2 could result in an invalid
    1101             :                 // iterator position, which causes an abort in a non-product version
    1102           0 :                 pLeftLabelControl += 2;
    1103           0 :                 pRightLabelControl += 2;
    1104           0 :                 pLeftColumnLabel += 2;
    1105           0 :                 pRightColumnLabel += 2;
    1106             : 
    1107           0 :                 pLeftListControl += 2;
    1108           0 :                 pRightListControl += 2;
    1109           0 :                 pLeftAssignment += 2;
    1110           0 :                 pRightAssignment += 2;
    1111             :             }
    1112             :         }
    1113             : 
    1114           0 :         if (_bAdjustFocus && (nOldFocusRow >= 0))
    1115             :         {   // we have to adjust the focus and one of the list boxes has the focus
    1116           0 :             sal_Int32 nDelta = m_pImpl->nFieldScrollPos - _nPos;
    1117             :             // the new row for the focus
    1118           0 :             sal_Int32 nNewFocusRow = nOldFocusRow + nDelta;
    1119             :             // normalize
    1120           0 :             nNewFocusRow = std::min(nNewFocusRow, (sal_Int32)(FIELD_PAIRS_VISIBLE - 1), ::std::less< sal_Int32 >());
    1121           0 :             nNewFocusRow = std::max(nNewFocusRow, (sal_Int32)0, ::std::less< sal_Int32 >());
    1122             :             // set the new focus (in the same column)
    1123           0 :             m_pImpl->pFields[nNewFocusRow * 2 + nOldFocusColumn]->GrabFocus();
    1124             :         }
    1125             : 
    1126           0 :         m_pImpl->nFieldScrollPos = _nPos;
    1127             : 
    1128           0 :         if (_bAdjustScrollbar)
    1129           0 :             m_aFieldScroller.SetThumbPos(m_pImpl->nFieldScrollPos);
    1130             :     }
    1131             : 
    1132             :     // -------------------------------------------------------------------
    1133           0 :     void AddressBookSourceDialog::implSelectField(ListBox* _pBox, const String& _rText)
    1134             :     {
    1135           0 :         if (_rText.Len())
    1136             :             // a valid field name
    1137           0 :             _pBox->SelectEntry(_rText);
    1138             :         else
    1139             :             // no selection for this item
    1140           0 :             _pBox->SelectEntryPos(0);
    1141           0 :     }
    1142             : 
    1143             :     // -------------------------------------------------------------------
    1144           0 :     IMPL_LINK_NOARG(AddressBookSourceDialog, OnDelayedInitialize)
    1145             :     {
    1146             :         // load the initial data from the configuration
    1147           0 :         loadConfiguration();
    1148           0 :         resetTables();
    1149             :             // will reset the tables/fields implicitly
    1150             : 
    1151           0 :         if ( !m_pImpl->bWorkingPersistent )
    1152           0 :             if ( m_pImpl->pFields[0] )
    1153           0 :                 m_pImpl->pFields[0]->GrabFocus();
    1154             : 
    1155           0 :         return 0L;
    1156             :     }
    1157             : 
    1158             :     // -------------------------------------------------------------------
    1159           0 :     IMPL_LINK(AddressBookSourceDialog, OnComboSelect, ComboBox*, _pBox)
    1160             :     {
    1161           0 :         if (_pBox == &m_aDatasource)
    1162           0 :             resetTables();
    1163             :         else
    1164           0 :             resetFields();
    1165           0 :         return 0;
    1166             :     }
    1167             : 
    1168             :     // -------------------------------------------------------------------
    1169           0 :     IMPL_LINK(AddressBookSourceDialog, OnComboGetFocus, ComboBox*, _pBox)
    1170             :     {
    1171           0 :         _pBox->SaveValue();
    1172           0 :         return 0L;
    1173             :     }
    1174             : 
    1175             :     // -------------------------------------------------------------------
    1176           0 :     IMPL_LINK(AddressBookSourceDialog, OnComboLoseFocus, ComboBox*, _pBox)
    1177             :     {
    1178           0 :         if (_pBox->GetSavedValue() != _pBox->GetText())
    1179             :         {
    1180           0 :             if (_pBox == &m_aDatasource)
    1181           0 :                 resetTables();
    1182             :             else
    1183           0 :                 resetFields();
    1184             :         }
    1185           0 :         return 0L;
    1186             :     }
    1187             : 
    1188             :     // -------------------------------------------------------------------
    1189           0 :     IMPL_LINK_NOARG(AddressBookSourceDialog, OnOkClicked)
    1190             :     {
    1191           0 :         String sSelectedDS = lcl_getSelectedDataSource(  m_aDatasource );
    1192           0 :         if ( m_pImpl->bWorkingPersistent )
    1193             :         {
    1194           0 :             m_pImpl->pConfigData->setDatasourceName(sSelectedDS);
    1195           0 :             m_pImpl->pConfigData->setCommand(m_aTable.GetText());
    1196             :         }
    1197             : 
    1198             :         // set the field assignments
    1199           0 :         ConstStringArrayIterator aLogical = m_pImpl->aLogicalFieldNames.begin();
    1200           0 :         ConstStringArrayIterator aAssignment = m_pImpl->aFieldAssignments.begin();
    1201           0 :         for (   ;
    1202           0 :                 aLogical < m_pImpl->aLogicalFieldNames.end();
    1203             :                 ++aLogical, ++aAssignment
    1204             :             )
    1205           0 :             m_pImpl->pConfigData->setFieldAssignment(*aLogical, *aAssignment);
    1206             : 
    1207             : 
    1208           0 :         EndDialog(RET_OK);
    1209           0 :         return 0L;
    1210             :     }
    1211             : 
    1212             :     // -------------------------------------------------------------------
    1213           0 :     IMPL_LINK_NOARG(AddressBookSourceDialog, OnAdministrateDatasources)
    1214             :     {
    1215             :         // collect some initial arguments for the dialog
    1216           0 :         Sequence< Any > aArgs(1);
    1217           0 :         aArgs[0] <<= PropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow")), 0, makeAny(VCLUnoHelper::GetInterface(this)), PropertyState_DIRECT_VALUE);
    1218             : 
    1219             :         // create the dialog object
    1220           0 :         const rtl::OUString sDialogServiceName("com.sun.star.ui.dialogs.AddressBookSourcePilot");
    1221           0 :         Reference< XExecutableDialog > xAdminDialog;
    1222             :         try
    1223             :         {
    1224           0 :             xAdminDialog = Reference< XExecutableDialog >(m_xORB->createInstanceWithArguments(sDialogServiceName, aArgs), UNO_QUERY);
    1225             :         }
    1226           0 :         catch(Exception&) { }
    1227           0 :         if (!xAdminDialog.is())
    1228             :         {
    1229           0 :             ShowServiceNotAvailableError(this, sDialogServiceName, sal_True);
    1230           0 :             return 1L;
    1231             :         }
    1232             : 
    1233             :         // excute the dialog
    1234             :         try
    1235             :         {
    1236           0 :             if ( xAdminDialog->execute() == RET_OK )
    1237             :             {
    1238           0 :                 Reference<XPropertySet> xProp(xAdminDialog,UNO_QUERY);
    1239           0 :                 if ( xProp.is() )
    1240             :                 {
    1241           0 :                     ::rtl::OUString sName;
    1242           0 :                     xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("DataSourceName"))) >>= sName;
    1243             : 
    1244           0 :                     INetURLObject aURL( sName );
    1245           0 :                     if( aURL.GetProtocol() != INET_PROT_NOT_VALID )
    1246             :                     {
    1247           0 :                         OFileNotation aFileNotation( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
    1248           0 :                         sName = aFileNotation.get(OFileNotation::N_SYSTEM);
    1249             :                     }
    1250           0 :                     m_aDatasource.InsertEntry(sName);
    1251           0 :                     delete m_pImpl->pConfigData;
    1252           0 :                     m_pImpl->pConfigData = new AssignmentPersistentData();
    1253           0 :                     loadConfiguration();
    1254           0 :                     resetTables();
    1255             :                     // will reset the fields implicitly
    1256           0 :                 }
    1257             :             }
    1258             :         }
    1259           0 :         catch(Exception&)
    1260             :         {
    1261             :             OSL_FAIL("AddressBookSourceDialog::OnAdministrateDatasources: an error occurred while executing the administration dialog!");
    1262             :         }
    1263             : 
    1264             :         // re-fill the data source list
    1265             :         // try to preserve the current selection
    1266             : 
    1267             : //      initializeDatasources();
    1268             : 
    1269           0 :         return 0L;
    1270             :     }
    1271             : 
    1272             :     // -------------------------------------------------------------------
    1273           0 :     long AddressBookSourceDialog::PreNotify( NotifyEvent& _rNEvt )
    1274             :     {
    1275           0 :         switch (_rNEvt.GetType())
    1276             :         {
    1277             :             case EVENT_KEYINPUT:
    1278             :             {
    1279           0 :                 const KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent();
    1280           0 :                 sal_uInt16 nCode  = pKeyEvent->GetKeyCode().GetCode();
    1281           0 :                 sal_Bool   bShift = pKeyEvent->GetKeyCode().IsShift();
    1282           0 :                 sal_Bool   bCtrl  = pKeyEvent->GetKeyCode().IsMod1();
    1283           0 :                 sal_Bool   bAlt =   pKeyEvent->GetKeyCode().IsMod2();
    1284             : 
    1285           0 :                 if (KEY_TAB == nCode)
    1286             :                 {   // somebody pressed the tab key
    1287           0 :                     if (!bAlt && !bCtrl && !bShift)
    1288             :                     {   // it's really the only the key (no modifiers)
    1289           0 :                         if (m_pImpl->pFields[m_pImpl->nLastVisibleListIndex]->HasChildPathFocus())
    1290             :                             // the last of our visible list boxes has the focus
    1291           0 :                             if (m_pImpl->nFieldScrollPos < m_aFieldScroller.GetRangeMax())
    1292             :                             {   // we can still scroll down
    1293           0 :                                 sal_Int32 nNextFocusList = m_pImpl->nLastVisibleListIndex + 1 - 2;
    1294             :                                 // -> scroll down
    1295           0 :                                 implScrollFields(m_pImpl->nFieldScrollPos + 1, sal_False, sal_True);
    1296             :                                 // give the left control in the "next" line the focus
    1297           0 :                                 m_pImpl->pFields[nNextFocusList]->GrabFocus();
    1298             :                                 // return saying "have handled this"
    1299           0 :                                 return 1;
    1300           0 :                             }
    1301             :                     }
    1302           0 :                     else if (!bAlt && !bCtrl && bShift)
    1303             :                     {   // it's shift-tab
    1304           0 :                         if (m_pImpl->pFields[0]->HasChildPathFocus())
    1305             :                             // our first list box has the focus
    1306           0 :                             if (m_pImpl->nFieldScrollPos > 0)
    1307             :                             {   // we can still scroll up
    1308             :                                 // -> scroll up
    1309           0 :                                 implScrollFields(m_pImpl->nFieldScrollPos - 1, sal_False, sal_True);
    1310             :                                 // give the right control in the "prebious" line the focus
    1311           0 :                                 m_pImpl->pFields[0 - 1 + 2]->GrabFocus();
    1312             :                                 // return saying "have handled this"
    1313           0 :                                 return 1;
    1314             :                             }
    1315             :                     }
    1316             :                 }
    1317             :             }
    1318           0 :             break;
    1319             :         }
    1320           0 :         return ModalDialog::PreNotify(_rNEvt);
    1321             :     }
    1322             : 
    1323             : // .......................................................................
    1324             : }   // namespace svt
    1325             : // .......................................................................
    1326             : 
    1327             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10