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