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