xref: /trunk/main/extensions/source/abpilot/abspilot.cxx (revision 7dbe28d420f41caf4208fa0a77115d7601de2198)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_extensions.hxx"
24 #include "abspilot.hxx"
25 #include "abpilot.hrc"
26 #include "abpresid.hrc"
27 #include "componentmodule.hxx"
28 #include <tools/debug.hxx>
29 #include <svtools/localresaccess.hxx>
30 #include "typeselectionpage.hxx"
31 #include "admininvokationpage.hxx"
32 #include "tableselectionpage.hxx"
33 #include <vcl/waitobj.hxx>
34 #include <vcl/msgbox.hxx>
35 #include "abpfinalpage.hxx"
36 #include "fieldmappingpage.hxx"
37 #include "fieldmappingimpl.hxx"
38 
39 namespace abp
40 {
41 //.........................................................................
42 
43 #define STATE_SELECT_ABTYPE         0
44 #define STATE_INVOKE_ADMIN_DIALOG   1
45 #define STATE_TABLE_SELECTION       2
46 #define STATE_MANUAL_FIELD_MAPPING  3
47 #define STATE_FINAL_CONFIRM         4
48 
49 #define PATH_COMPLETE               1
50 #define PATH_NO_SETTINGS            2
51 #define PATH_NO_FIELDS              3
52 #define PATH_NO_SETTINGS_NO_FIELDS  4
53 
54     using namespace ::svt;
55     using namespace ::com::sun::star::uno;
56     using namespace ::com::sun::star::lang;
57 
58     //=====================================================================
59     //= OAddessBookSourcePilot
60     //=====================================================================
61     //---------------------------------------------------------------------
OAddessBookSourcePilot(Window * _pParent,const Reference<XMultiServiceFactory> & _rxORB)62     OAddessBookSourcePilot::OAddessBookSourcePilot(Window* _pParent, const Reference< XMultiServiceFactory >& _rxORB)
63         :OAddessBookSourcePilot_Base( _pParent, ModuleRes( RID_DLG_ADDRESSBOOKSOURCEPILOT ),
64             WZB_HELP | WZB_FINISH | WZB_CANCEL | WZB_NEXT | WZB_PREVIOUS )
65         ,m_xORB(_rxORB)
66         ,m_aNewDataSource(_rxORB)
67         ,m_eNewDataSourceType( AST_INVALID )
68     {
69         SetPageSizePixel(LogicToPixel(Size(WINDOW_SIZE_X, WINDOW_SIZE_Y), MAP_APPFONT));
70 
71         ShowButtonFixedLine(sal_True);
72 
73         declarePath( PATH_COMPLETE,
74             STATE_SELECT_ABTYPE,
75             STATE_INVOKE_ADMIN_DIALOG,
76             STATE_TABLE_SELECTION,
77             STATE_MANUAL_FIELD_MAPPING,
78             STATE_FINAL_CONFIRM,
79             WZS_INVALID_STATE
80         );
81         declarePath( PATH_NO_SETTINGS,
82             STATE_SELECT_ABTYPE,
83             STATE_TABLE_SELECTION,
84             STATE_MANUAL_FIELD_MAPPING,
85             STATE_FINAL_CONFIRM,
86             WZS_INVALID_STATE
87         );
88         declarePath( PATH_NO_FIELDS,
89             STATE_SELECT_ABTYPE,
90             STATE_INVOKE_ADMIN_DIALOG,
91             STATE_TABLE_SELECTION,
92             STATE_FINAL_CONFIRM,
93             WZS_INVALID_STATE
94         );
95         declarePath( PATH_NO_SETTINGS_NO_FIELDS,
96             STATE_SELECT_ABTYPE,
97             STATE_TABLE_SELECTION,
98             STATE_FINAL_CONFIRM,
99             WZS_INVALID_STATE
100         );
101 
102         m_pPrevPage->SetHelpId(HID_ABSPILOT_PREVIOUS);
103         m_pNextPage->SetHelpId(HID_ABSPILOT_NEXT);
104         m_pCancel->SetHelpId(HID_ABSPILOT_CANCEL);
105         m_pFinish->SetHelpId(HID_ABSPILOT_FINISH);
106         m_pHelp->SetUniqueId(UID_ABSPILOT_HELP);
107 
108         m_pCancel->SetClickHdl( LINK( this, OAddessBookSourcePilot, OnCancelClicked) );
109 
110         // some initial settings
111 #ifdef MACOSX
112         m_aSettings.eType = AST_MACAB;
113 #elif WITH_MOZILLA
114 #ifdef UNX
115         m_aSettings.eType = AST_THUNDERBIRD;
116 #else
117         m_aSettings.eType = AST_OE;
118 #endif
119 #else
120         m_aSettings.eType = AST_OTHER;
121 #endif
122         m_aSettings.sDataSourceName = String(ModuleRes(RID_STR_DEFAULT_NAME));
123         m_aSettings.bRegisterDataSource = false;
124         m_aSettings.bIgnoreNoTable = false;
125 
126         defaultButton(WZB_NEXT);
127         enableButtons(WZB_FINISH, sal_False);
128         ActivatePage();
129 
130         typeSelectionChanged( m_aSettings.eType );
131     }
132 
133     //---------------------------------------------------------------------
getStateDisplayName(WizardState _nState) const134     String OAddessBookSourcePilot::getStateDisplayName( WizardState _nState ) const
135     {
136         sal_uInt16 nResId = 0;
137         switch ( _nState )
138         {
139             case STATE_SELECT_ABTYPE:        nResId = STR_SELECT_ABTYPE; break;
140             case STATE_INVOKE_ADMIN_DIALOG:  nResId = STR_INVOKE_ADMIN_DIALOG; break;
141             case STATE_TABLE_SELECTION:      nResId = STR_TABLE_SELECTION; break;
142             case STATE_MANUAL_FIELD_MAPPING: nResId = STR_MANUAL_FIELD_MAPPING; break;
143             case STATE_FINAL_CONFIRM:        nResId = STR_FINAL_CONFIRM; break;
144         }
145         DBG_ASSERT( nResId, "OAddessBookSourcePilot::getStateDisplayName: don't know this state!" );
146 
147         String sDisplayName;
148         if ( nResId )
149         {
150             svt::OLocalResourceAccess aAccess( ModuleRes( RID_DLG_ADDRESSBOOKSOURCEPILOT ), RSC_MODALDIALOG );
151             sDisplayName = String( ModuleRes( nResId ) );
152         }
153 
154         return sDisplayName;
155     }
156 
157     //---------------------------------------------------------------------
implCommitAll()158     void OAddessBookSourcePilot::implCommitAll()
159     {
160         // in real, the data source already exists in the data source context
161         // Thus, if the user changed the name, we have to rename the data source
162         if ( m_aSettings.sDataSourceName != m_aNewDataSource.getName() )
163             m_aNewDataSource.rename( m_aSettings.sDataSourceName );
164 
165         // 1. the data source
166         m_aNewDataSource.store();
167 
168         // 2. check if we need to register the data source
169         if ( m_aSettings.bRegisterDataSource )
170             m_aNewDataSource.registerDataSource(m_aSettings.sRegisteredDataSourceName);
171 
172         // 3. write the data source / table names into the configuration
173         addressconfig::writeTemplateAddressSource( getORB(), m_aSettings.bRegisterDataSource ? m_aSettings.sRegisteredDataSourceName : m_aSettings.sDataSourceName, m_aSettings.sSelectedTable );
174 
175         // 4. write the field mapping
176         fieldmapping::writeTemplateAddressFieldMapping( getORB(), m_aSettings.aFieldMapping );
177     }
178 
179     //---------------------------------------------------------------------
implCleanup()180     void OAddessBookSourcePilot::implCleanup()
181     {
182         if ( m_aNewDataSource.isValid() )
183             m_aNewDataSource.remove();
184     }
185 
186     //---------------------------------------------------------------------
187     IMPL_LINK( OAddessBookSourcePilot, OnCancelClicked, void*, /*NOTINTERESTEDIN*/ )
188     {
189         // do cleanups
190         implCleanup();
191 
192         // reset the click hdl
193         m_pCancel->SetClickHdl( Link() );
194         // simulate the click again - this time, the default handling of the button will strike...
195         m_pCancel->Click();
196 
197         return 0L;
198     }
199 
200     //---------------------------------------------------------------------
Close()201     sal_Bool OAddessBookSourcePilot::Close()
202     {
203         implCleanup();
204 
205         return OAddessBookSourcePilot_Base::Close();
206     }
207 
208     //---------------------------------------------------------------------
onFinish()209     sal_Bool OAddessBookSourcePilot::onFinish()
210     {
211         if ( !OAddessBookSourcePilot_Base::onFinish() )
212             return sal_False;
213 
214         implCommitAll();
215 
216         addressconfig::markPilotSuccess( getORB() );
217 
218         return sal_True;
219     }
220 
221     //---------------------------------------------------------------------
enterState(WizardState _nState)222     void OAddessBookSourcePilot::enterState( WizardState _nState )
223     {
224         switch ( _nState )
225         {
226             case STATE_SELECT_ABTYPE:
227                 impl_updateRoadmap( static_cast< TypeSelectionPage* >( GetPage( STATE_SELECT_ABTYPE ) )->getSelectedType() );
228                 break;
229 
230             case STATE_FINAL_CONFIRM:
231                 if ( !needManualFieldMapping( ) )
232                     implDoAutoFieldMapping();
233                 break;
234 
235             case STATE_TABLE_SELECTION:
236                 implDefaultTableName();
237                 break;
238         }
239 
240         OAddessBookSourcePilot_Base::enterState(_nState);
241     }
242 
243     //---------------------------------------------------------------------
prepareLeaveCurrentState(CommitPageReason _eReason)244     sal_Bool OAddessBookSourcePilot::prepareLeaveCurrentState( CommitPageReason _eReason )
245     {
246         if ( !OAddessBookSourcePilot_Base::prepareLeaveCurrentState( _eReason ) )
247             return sal_False;
248 
249         if ( _eReason == eTravelBackward )
250             return sal_True;
251 
252         sal_Bool bAllow = sal_True;
253 
254         switch ( getCurrentState() )
255         {
256         case STATE_SELECT_ABTYPE:
257             implCreateDataSource();
258             if ( needAdminInvokationPage() )
259                 break;
260             // no break here
261 
262         case STATE_INVOKE_ADMIN_DIALOG:
263             if ( !connectToDataSource( sal_False ) )
264             {
265                 // connecting did not succeed -> do not allow proceeding
266                 bAllow = sal_False;
267                 break;
268             }
269 
270             // ........................................................
271             // now that we connected to the data source, check whether we need the "table selection" page
272             const StringBag& aTables = m_aNewDataSource.getTableNames();
273 
274             if ( aTables.empty() )
275             {
276                 if ( RET_YES != QueryBox( this, ModuleRes( RID_QRY_NOTABLES ) ).Execute() )
277                 {
278                     // cannot ask the user, or the user chose to use this data source, though there are no tables
279                     bAllow = sal_False;
280                     break;
281                 }
282 
283                 m_aSettings.bIgnoreNoTable = true;
284             }
285 
286             if ( aTables.size() == 1 )
287                 // remember the one and only table we have
288                 m_aSettings.sSelectedTable = *aTables.begin();
289 
290             break;
291         }
292 
293         impl_updateRoadmap( m_aSettings.eType );
294         return bAllow;
295     }
296 
297     //---------------------------------------------------------------------
implDefaultTableName()298     void OAddessBookSourcePilot::implDefaultTableName()
299     {
300         const StringBag& rTableNames = getDataSource().getTableNames();
301         if ( rTableNames.end() != rTableNames.find( getSettings().sSelectedTable ) )
302             // already a valid table selected
303             return;
304 
305         const sal_Char* pGuess = NULL;
306         switch ( getSettings().eType )
307         {
308             case AST_THUNDERBIRD        : pGuess = "Personal Address book"; break;
309             case AST_LDAP               : pGuess = "LDAP Directory"; break;
310             case AST_EVOLUTION          :
311             case AST_EVOLUTION_GROUPWISE:
312             case AST_EVOLUTION_LDAP     : pGuess = "Personal"; break;
313             default:
314                 DBG_ERROR( "OAddessBookSourcePilot::implDefaultTableName: unhandled case!" );
315                 return;
316         }
317         const ::rtl::OUString sGuess = ::rtl::OUString::createFromAscii( pGuess );
318         if ( rTableNames.end() != rTableNames.find( sGuess ) )
319             getSettings().sSelectedTable = sGuess;
320     }
321 
322     //---------------------------------------------------------------------
implDoAutoFieldMapping()323     void OAddessBookSourcePilot::implDoAutoFieldMapping()
324     {
325         DBG_ASSERT( !needManualFieldMapping( ), "OAddessBookSourcePilot::implDoAutoFieldMapping: invalid call!" );
326 
327         fieldmapping::defaultMapping( getORB(), m_aSettings.aFieldMapping );
328     }
329 
330     //---------------------------------------------------------------------
implCreateDataSource()331     void OAddessBookSourcePilot::implCreateDataSource()
332     {
333         if (m_aNewDataSource.isValid())
334         {   // we already have a data source object
335             if ( m_aSettings.eType == m_eNewDataSourceType )
336                 // and it already has the correct type
337                 return;
338 
339             // it has a wrong type -> remove it
340             m_aNewDataSource.remove();
341         }
342 
343         ODataSourceContext aContext( getORB() );
344         aContext.disambiguate( m_aSettings.sDataSourceName );
345 
346         switch (m_aSettings.eType)
347         {
348             case AST_THUNDERBIRD:
349                 m_aNewDataSource = aContext.createNewThunderbird( m_aSettings.sDataSourceName );
350                 break;
351 
352             case AST_EVOLUTION:
353                 m_aNewDataSource = aContext.createNewEvolution( m_aSettings.sDataSourceName );
354                 break;
355 
356             case AST_EVOLUTION_GROUPWISE:
357                 m_aNewDataSource = aContext.createNewEvolutionGroupwise( m_aSettings.sDataSourceName );
358                 break;
359 
360             case AST_EVOLUTION_LDAP:
361                 m_aNewDataSource = aContext.createNewEvolutionLdap( m_aSettings.sDataSourceName );
362                 break;
363 
364             case AST_KAB:
365                 m_aNewDataSource = aContext.createNewKab( m_aSettings.sDataSourceName );
366                 break;
367 
368             case AST_MACAB:
369                 m_aNewDataSource = aContext.createNewMacab( m_aSettings.sDataSourceName );
370                 break;
371 
372             case AST_LDAP:
373                 m_aNewDataSource = aContext.createNewLDAP( m_aSettings.sDataSourceName );
374                 break;
375 
376             case AST_OUTLOOK:
377                 m_aNewDataSource = aContext.createNewOutlook( m_aSettings.sDataSourceName );
378                 break;
379 
380             case AST_OE:
381                 m_aNewDataSource = aContext.createNewOE( m_aSettings.sDataSourceName );
382                 break;
383 
384             case AST_OTHER:
385                 m_aNewDataSource = aContext.createNewDBase( m_aSettings.sDataSourceName );
386                 break;
387 
388             case AST_INVALID:
389                 DBG_ERROR( "OAddessBookSourcePilot::implCreateDataSource: illegal data source type!" );
390                 break;
391         }
392         m_eNewDataSourceType = m_aSettings.eType;
393     }
394 
395     //---------------------------------------------------------------------
connectToDataSource(sal_Bool _bForceReConnect)396     sal_Bool OAddessBookSourcePilot::connectToDataSource( sal_Bool _bForceReConnect )
397     {
398         DBG_ASSERT( m_aNewDataSource.isValid(), "OAddessBookSourcePilot::implConnect: invalid current data source!" );
399 
400         WaitObject aWaitCursor( this );
401         if ( _bForceReConnect && m_aNewDataSource.isConnected( ) )
402             m_aNewDataSource.disconnect( );
403 
404         return m_aNewDataSource.connect( this );
405     }
406 
407     //---------------------------------------------------------------------
createPage(WizardState _nState)408     OWizardPage* OAddessBookSourcePilot::createPage(WizardState _nState)
409     {
410         switch (_nState)
411         {
412             case STATE_SELECT_ABTYPE:
413                 return new TypeSelectionPage( this );
414 
415             case STATE_INVOKE_ADMIN_DIALOG:
416                 return new AdminDialogInvokationPage( this );
417 
418             case STATE_TABLE_SELECTION:
419                 return new TableSelectionPage( this );
420 
421             case STATE_MANUAL_FIELD_MAPPING:
422                 return new FieldMappingPage( this );
423 
424             case STATE_FINAL_CONFIRM:
425                 return new FinalPage( this );
426 
427             default:
428                 DBG_ERROR("OAddessBookSourcePilot::createPage: invalid state!");
429                 return NULL;
430         }
431     }
432 
433     //---------------------------------------------------------------------
impl_updateRoadmap(AddressSourceType _eType)434     void OAddessBookSourcePilot::impl_updateRoadmap( AddressSourceType _eType )
435     {
436         bool bSettingsPage = needAdminInvokationPage( _eType );
437         bool bTablesPage   = needTableSelection( _eType );
438         bool bFieldsPage   = needManualFieldMapping( _eType );
439 
440         bool bConnected = m_aNewDataSource.isConnected();
441         bool bCanSkipTables =
442                 (  m_aNewDataSource.hasTable( m_aSettings.sSelectedTable )
443                 || m_aSettings.bIgnoreNoTable
444                 );
445 
446         enableState( STATE_INVOKE_ADMIN_DIALOG, bSettingsPage );
447 
448         enableState( STATE_TABLE_SELECTION,
449             bTablesPage && ( bConnected ? !bCanSkipTables : !bSettingsPage )
450             // if we do not need a settings page, we connect upon "Next" on the first page
451         );
452 
453         enableState( STATE_MANUAL_FIELD_MAPPING,
454                 bFieldsPage && bConnected && m_aNewDataSource.hasTable( m_aSettings.sSelectedTable )
455         );
456 
457         enableState( STATE_FINAL_CONFIRM,
458             bConnected && bCanSkipTables
459         );
460     }
461 
462     //---------------------------------------------------------------------
typeSelectionChanged(AddressSourceType _eType)463     void OAddessBookSourcePilot::typeSelectionChanged( AddressSourceType _eType )
464     {
465         PathId nCurrentPathID( PATH_COMPLETE );
466         bool bSettingsPage = needAdminInvokationPage( _eType );
467         bool bFieldsPage = needManualFieldMapping( _eType );
468         if ( !bSettingsPage )
469             if ( !bFieldsPage )
470                 nCurrentPathID = PATH_NO_SETTINGS_NO_FIELDS;
471             else
472                 nCurrentPathID = PATH_NO_SETTINGS;
473         else
474             if ( !bFieldsPage )
475                 nCurrentPathID = PATH_NO_FIELDS;
476             else
477                 nCurrentPathID = PATH_COMPLETE;
478         activatePath( nCurrentPathID, true );
479 
480         m_aNewDataSource.disconnect();
481         m_aSettings.bIgnoreNoTable = false;
482         impl_updateRoadmap( _eType );
483     }
484 
485 //.........................................................................
486 }   // namespace abp
487 
488 /* vim: set noet sw=4 ts=4: */
489