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