1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "abspilot.hxx"
22 #include <strings.hrc>
23 #include <componentmodule.hxx>
24 #include <tools/debug.hxx>
25 #include "typeselectionpage.hxx"
26 #include "admininvokationpage.hxx"
27 #include "tableselectionpage.hxx"
28 #include <vcl/svapp.hxx>
29 #include <vcl/weld.hxx>
30 #include <osl/diagnose.h>
31 #include "abpfinalpage.hxx"
32 #include "fieldmappingpage.hxx"
33 #include "fieldmappingimpl.hxx"
35 using vcl::RoadmapWizardTypes::PathId
;
41 #define STATE_SELECT_ABTYPE 0
42 #define STATE_INVOKE_ADMIN_DIALOG 1
43 #define STATE_TABLE_SELECTION 2
44 #define STATE_MANUAL_FIELD_MAPPING 3
45 #define STATE_FINAL_CONFIRM 4
49 using namespace ::com::sun::star::uno
;
51 OAddressBookSourcePilot::OAddressBookSourcePilot(weld::Window
* _pParent
, const Reference
< XComponentContext
>& _rxORB
)
52 :OAddressBookSourcePilot_Base( _pParent
)
54 ,m_aNewDataSource(_rxORB
)
55 ,m_eNewDataSourceType( AST_INVALID
)
57 declarePath(PathId::COMPLETE
,
59 STATE_INVOKE_ADMIN_DIALOG
,
60 STATE_TABLE_SELECTION
,
61 STATE_MANUAL_FIELD_MAPPING
,
64 declarePath(PathId::NO_SETTINGS
,
66 STATE_TABLE_SELECTION
,
67 STATE_MANUAL_FIELD_MAPPING
,
70 declarePath(PathId::NO_FIELDS
,
72 STATE_INVOKE_ADMIN_DIALOG
,
73 STATE_TABLE_SELECTION
,
76 declarePath(PathId::NO_SETTINGS_NO_FIELDS
,
78 STATE_TABLE_SELECTION
,
82 m_xPrevPage
->set_help_id(HID_ABSPILOT_PREVIOUS
);
83 m_xNextPage
->set_help_id(HID_ABSPILOT_NEXT
);
84 m_xCancel
->set_help_id(HID_ABSPILOT_CANCEL
);
85 m_xFinish
->set_help_id(HID_ABSPILOT_FINISH
);
86 m_xHelp
->set_help_id(UID_ABSPILOT_HELP
);
88 // some initial settings
91 m_aSettings
.eType
= AST_MACAB
;
93 // FIXME: if KDE use KAB instead
94 m_aSettings
.eType
= AST_EVOLUTION
;
97 m_aSettings
.eType
= AST_OTHER
;
99 m_aSettings
.sDataSourceName
= compmodule::ModuleRes(RID_STR_DEFAULT_NAME
);
100 m_aSettings
.bRegisterDataSource
= false;
101 m_aSettings
.bEmbedDataSource
= false;
102 m_aSettings
.bIgnoreNoTable
= false;
104 defaultButton(WizardButtonFlags::NEXT
);
105 enableButtons(WizardButtonFlags::FINISH
, false);
107 m_xAssistant
->set_current_page(0);
109 typeSelectionChanged( m_aSettings
.eType
);
111 OUString sDialogTitle
= compmodule::ModuleRes(RID_STR_ABSOURCEDIALOGTITLE
);
112 setTitleBase(sDialogTitle
);
113 m_xAssistant
->set_help_id(HID_ABSPILOT
);
116 OUString
OAddressBookSourcePilot::getStateDisplayName( WizardState _nState
) const
121 case STATE_SELECT_ABTYPE
: pResId
= RID_STR_SELECT_ABTYPE
; break;
122 case STATE_INVOKE_ADMIN_DIALOG
: pResId
= RID_STR_INVOKE_ADMIN_DIALOG
; break;
123 case STATE_TABLE_SELECTION
: pResId
= RID_STR_TABLE_SELECTION
; break;
124 case STATE_MANUAL_FIELD_MAPPING
: pResId
= RID_STR_MANUAL_FIELD_MAPPING
; break;
125 case STATE_FINAL_CONFIRM
: pResId
= RID_STR_FINAL_CONFIRM
; break;
127 DBG_ASSERT( pResId
, "OAddressBookSourcePilot::getStateDisplayName: don't know this state!" );
129 OUString sDisplayName
;
132 sDisplayName
= compmodule::ModuleRes(pResId
);
138 void OAddressBookSourcePilot::implCommitAll()
140 // in real, the data source already exists in the data source context
141 // Thus, if the user changed the name, we have to rename the data source
142 if ( m_aSettings
.sDataSourceName
!= m_aNewDataSource
.getName() )
143 m_aNewDataSource
.rename( m_aSettings
.sDataSourceName
);
145 // 1. the data source
146 m_aNewDataSource
.store(m_aSettings
);
148 // 2. check if we need to register the data source
149 if ( m_aSettings
.bRegisterDataSource
)
150 m_aNewDataSource
.registerDataSource(m_aSettings
.sRegisteredDataSourceName
);
152 // 3. write the data source / table names into the configuration
153 addressconfig::writeTemplateAddressSource( getORB(), m_aSettings
.bRegisterDataSource
? m_aSettings
.sRegisteredDataSourceName
: m_aSettings
.sDataSourceName
, m_aSettings
.sSelectedTable
);
155 // 4. write the field mapping
156 fieldmapping::writeTemplateAddressFieldMapping( getORB(), std::map(m_aSettings
.aFieldMapping
) );
159 void OAddressBookSourcePilot::implCleanup()
161 if ( m_aNewDataSource
.isValid() )
162 m_aNewDataSource
.remove();
165 short OAddressBookSourcePilot::run()
167 short nRet
= OAddressBookSourcePilot_Base::run();
174 bool OAddressBookSourcePilot::onFinish()
176 if ( !OAddressBookSourcePilot_Base::onFinish() )
181 addressconfig::markPilotSuccess( getORB() );
186 void OAddressBookSourcePilot::enterState( WizardState _nState
)
190 case STATE_SELECT_ABTYPE
:
191 impl_updateRoadmap( static_cast< TypeSelectionPage
* >( GetPage( STATE_SELECT_ABTYPE
) )->getSelectedType() );
194 case STATE_FINAL_CONFIRM
:
195 if ( !needManualFieldMapping( ) )
196 implDoAutoFieldMapping();
199 case STATE_TABLE_SELECTION
:
200 implDefaultTableName();
204 OAddressBookSourcePilot_Base::enterState(_nState
);
208 bool OAddressBookSourcePilot::prepareLeaveCurrentState( CommitPageReason _eReason
)
210 if ( !OAddressBookSourcePilot_Base::prepareLeaveCurrentState( _eReason
) )
213 if ( _eReason
== vcl::WizardTypes::eTravelBackward
)
218 switch ( getCurrentState() )
220 case STATE_SELECT_ABTYPE
:
221 implCreateDataSource();
222 if ( needAdminInvokationPage() )
226 case STATE_INVOKE_ADMIN_DIALOG
:
227 if ( !connectToDataSource( false ) )
229 // connecting did not succeed -> do not allow proceeding
235 // now that we connected to the data source, check whether we need the "table selection" page
236 const StringBag
& aTables
= m_aNewDataSource
.getTableNames();
238 if ( aTables
.empty() )
240 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xAssistant
.get(),
241 VclMessageType::Question
, VclButtonsType::YesNo
,
242 compmodule::ModuleRes(getSettings().eType
== AST_EVOLUTION_GROUPWISE
? RID_STR_QRY_NO_EVO_GW
: RID_STR_QRY_NOTABLES
)));
244 if (RET_YES
!= xBox
->run())
246 // cannot ask the user, or the user chose to use this data source, though there are no tables
251 m_aSettings
.bIgnoreNoTable
= true;
254 if ( aTables
.size() == 1 )
255 // remember the one and only table we have
256 m_aSettings
.sSelectedTable
= *aTables
.begin();
261 impl_updateRoadmap( m_aSettings
.eType
);
265 void OAddressBookSourcePilot::implDefaultTableName()
267 const StringBag
& rTableNames
= getDataSource().getTableNames();
268 if ( rTableNames
.end() != rTableNames
.find( getSettings().sSelectedTable
) )
269 // already a valid table selected
272 const char* pGuess
= nullptr;
273 switch ( getSettings().eType
)
275 case AST_THUNDERBIRD
: pGuess
= "Personal Address book"; break;
277 case AST_EVOLUTION_GROUPWISE
:
278 case AST_EVOLUTION_LDAP
: pGuess
= "Personal"; break;
280 OSL_FAIL( "OAddressBookSourcePilot::implDefaultTableName: unhandled case!" );
283 const OUString sGuess
= OUString::createFromAscii( pGuess
);
284 if ( rTableNames
.end() != rTableNames
.find( sGuess
) )
285 getSettings().sSelectedTable
= sGuess
;
288 void OAddressBookSourcePilot::implDoAutoFieldMapping()
290 DBG_ASSERT( !needManualFieldMapping( ), "OAddressBookSourcePilot::implDoAutoFieldMapping: invalid call!" );
292 fieldmapping::defaultMapping( getORB(), m_aSettings
.aFieldMapping
);
295 void OAddressBookSourcePilot::implCreateDataSource()
297 if (m_aNewDataSource
.isValid())
298 { // we already have a data source object
299 if ( m_aSettings
.eType
== m_eNewDataSourceType
)
300 // and it already has the correct type
303 // it has a wrong type -> remove it
304 m_aNewDataSource
.remove();
307 ODataSourceContext
aContext( getORB() );
308 aContext
.disambiguate( m_aSettings
.sDataSourceName
);
310 switch (m_aSettings
.eType
)
312 case AST_THUNDERBIRD
:
313 m_aNewDataSource
= aContext
.createNewThunderbird( m_aSettings
.sDataSourceName
);
317 m_aNewDataSource
= aContext
.createNewEvolution( m_aSettings
.sDataSourceName
);
320 case AST_EVOLUTION_GROUPWISE
:
321 m_aNewDataSource
= aContext
.createNewEvolutionGroupwise( m_aSettings
.sDataSourceName
);
324 case AST_EVOLUTION_LDAP
:
325 m_aNewDataSource
= aContext
.createNewEvolutionLdap( m_aSettings
.sDataSourceName
);
329 m_aNewDataSource
= aContext
.createNewKab( m_aSettings
.sDataSourceName
);
333 m_aNewDataSource
= aContext
.createNewMacab( m_aSettings
.sDataSourceName
);
337 m_aNewDataSource
= aContext
.createNewOther( m_aSettings
.sDataSourceName
);
341 OSL_FAIL( "OAddressBookSourcePilot::implCreateDataSource: illegal data source type!" );
344 m_eNewDataSourceType
= m_aSettings
.eType
;
347 bool OAddressBookSourcePilot::connectToDataSource( bool _bForceReConnect
)
349 DBG_ASSERT( m_aNewDataSource
.isValid(), "OAddressBookSourcePilot::implConnect: invalid current data source!" );
351 weld::WaitObject
aWaitCursor(m_xAssistant
.get());
352 if ( _bForceReConnect
&& m_aNewDataSource
.isConnected( ) )
353 m_aNewDataSource
.disconnect( );
355 return m_aNewDataSource
.connect(m_xAssistant
.get());
358 std::unique_ptr
<BuilderPage
> OAddressBookSourcePilot::createPage(WizardState _nState
)
360 OUString
sIdent(OUString::number(_nState
));
361 weld::Container
* pPageContainer
= m_xAssistant
->append_page(sIdent
);
363 std::unique_ptr
<vcl::OWizardPage
> xRet
;
367 case STATE_SELECT_ABTYPE
:
368 xRet
= std::make_unique
<TypeSelectionPage
>(pPageContainer
, this);
370 case STATE_INVOKE_ADMIN_DIALOG
:
371 xRet
= std::make_unique
<AdminDialogInvokationPage
>(pPageContainer
, this);
373 case STATE_TABLE_SELECTION
:
374 xRet
= std::make_unique
<TableSelectionPage
>(pPageContainer
, this);
376 case STATE_MANUAL_FIELD_MAPPING
:
377 xRet
= std::make_unique
<FieldMappingPage
>(pPageContainer
, this);
379 case STATE_FINAL_CONFIRM
:
380 xRet
= std::make_unique
<FinalPage
>(pPageContainer
, this);
383 assert(false && "OAddressBookSourcePilot::createPage: invalid state!");
387 m_xAssistant
->set_page_title(sIdent
, getStateDisplayName(_nState
));
392 void OAddressBookSourcePilot::impl_updateRoadmap( AddressSourceType _eType
)
394 bool bSettingsPage
= needAdminInvokationPage( _eType
);
395 bool bTablesPage
= needTableSelection( _eType
);
396 bool bFieldsPage
= needManualFieldMapping( _eType
);
398 bool bConnected
= m_aNewDataSource
.isConnected();
399 bool bCanSkipTables
=
400 ( m_aNewDataSource
.hasTable( m_aSettings
.sSelectedTable
)
401 || m_aSettings
.bIgnoreNoTable
404 enableState( STATE_INVOKE_ADMIN_DIALOG
, bSettingsPage
);
406 enableState( STATE_TABLE_SELECTION
,
407 bTablesPage
&& ( bConnected
? !bCanSkipTables
: !bSettingsPage
)
408 // if we do not need a settings page, we connect upon "Next" on the first page
411 enableState( STATE_MANUAL_FIELD_MAPPING
,
412 bFieldsPage
&& bConnected
&& m_aNewDataSource
.hasTable( m_aSettings
.sSelectedTable
)
415 enableState( STATE_FINAL_CONFIRM
,
416 bConnected
&& bCanSkipTables
420 void OAddressBookSourcePilot::typeSelectionChanged( AddressSourceType _eType
)
422 PathId
nCurrentPathID( PathId::COMPLETE
);
423 bool bSettingsPage
= needAdminInvokationPage( _eType
);
424 bool bFieldsPage
= needManualFieldMapping( _eType
);
425 if ( !bSettingsPage
)
427 nCurrentPathID
= PathId::NO_SETTINGS_NO_FIELDS
;
429 nCurrentPathID
= PathId::NO_SETTINGS
;
432 nCurrentPathID
= PathId::NO_FIELDS
;
434 nCurrentPathID
= PathId::COMPLETE
;
435 activatePath( nCurrentPathID
, true );
437 m_aNewDataSource
.disconnect();
438 m_aSettings
.bIgnoreNoTable
= false;
439 impl_updateRoadmap( _eType
);
445 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */