LibreOffice Module extensions (master) 1
abspilot.cxx
Go to the documentation of this file.
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 <helpids.h>
22#include <strings.hrc>
23#include <componentmodule.hxx>
24#include <tools/debug.hxx>
25#include "typeselectionpage.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"
34
36
37namespace abp
38{
39
40
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
46
47#define PATH_COMPLETE 1
48#define PATH_NO_SETTINGS 2
49#define PATH_NO_FIELDS 3
50#define PATH_NO_SETTINGS_NO_FIELDS 4
51
52 using namespace ::com::sun::star::uno;
53 using namespace ::com::sun::star::lang;
54
55 OAddressBookSourcePilot::OAddressBookSourcePilot(weld::Window* _pParent, const Reference< XComponentContext >& _rxORB)
57 ,m_xORB(_rxORB)
58 ,m_aNewDataSource(_rxORB)
59 ,m_eNewDataSourceType( AST_INVALID )
60 {
67 );
73 );
79 );
84 );
85
87 m_xNextPage->set_help_id(HID_ABSPILOT_NEXT);
88 m_xCancel->set_help_id(HID_ABSPILOT_CANCEL);
89 m_xFinish->set_help_id(HID_ABSPILOT_FINISH);
90 m_xHelp->set_help_id(UID_ABSPILOT_HELP);
91
92 // some initial settings
93#ifdef UNX
94#ifdef MACOSX
96#else
97// FIXME: if KDE use KAB instead
99#endif
100#else
102#endif
103 m_aSettings.sDataSourceName = compmodule::ModuleRes(RID_STR_DEFAULT_NAME);
107
108 defaultButton(WizardButtonFlags::NEXT);
109 enableButtons(WizardButtonFlags::FINISH, false);
110 ActivatePage();
111 m_xAssistant->set_current_page(0);
112
114
115 OUString sDialogTitle = compmodule::ModuleRes(RID_STR_ABSOURCEDIALOGTITLE);
116 setTitleBase(sDialogTitle);
117 m_xAssistant->set_help_id(HID_ABSPILOT);
118 }
119
121 {
122 TranslateId pResId;
123 switch ( _nState )
124 {
125 case STATE_SELECT_ABTYPE: pResId = RID_STR_SELECT_ABTYPE; break;
126 case STATE_INVOKE_ADMIN_DIALOG: pResId = RID_STR_INVOKE_ADMIN_DIALOG; break;
127 case STATE_TABLE_SELECTION: pResId = RID_STR_TABLE_SELECTION; break;
128 case STATE_MANUAL_FIELD_MAPPING: pResId = RID_STR_MANUAL_FIELD_MAPPING; break;
129 case STATE_FINAL_CONFIRM: pResId = RID_STR_FINAL_CONFIRM; break;
130 }
131 DBG_ASSERT( pResId, "OAddressBookSourcePilot::getStateDisplayName: don't know this state!" );
132
133 OUString sDisplayName;
134 if (pResId)
135 {
137 }
138
139 return sDisplayName;
140 }
141
143 {
144 // in real, the data source already exists in the data source context
145 // Thus, if the user changed the name, we have to rename the data source
148
149 // 1. the data source
151
152 // 2. check if we need to register the data source
155
156 // 3. write the data source / table names into the configuration
158
159 // 4. write the field mapping
161 }
162
164 {
167 }
168
170 {
172
173 implCleanup();
174
175 return nRet;
176 }
177
179 {
181 return false;
182
184
186
187 return true;
188 }
189
191 {
192 switch ( _nState )
193 {
195 impl_updateRoadmap( static_cast< TypeSelectionPage* >( GetPage( STATE_SELECT_ABTYPE ) )->getSelectedType() );
196 break;
197
199 if ( !needManualFieldMapping( ) )
201 break;
202
205 break;
206 }
207
209 }
210
211
213 {
215 return false;
216
217 if ( _eReason == vcl::WizardTypes::eTravelBackward )
218 return true;
219
220 bool bAllow = true;
221
222 switch ( getCurrentState() )
223 {
227 break;
228 [[fallthrough]];
229
231 if ( !connectToDataSource( false ) )
232 {
233 // connecting did not succeed -> do not allow proceeding
234 bAllow = false;
235 break;
236 }
237
238
239 // now that we connected to the data source, check whether we need the "table selection" page
240 const StringBag& aTables = m_aNewDataSource.getTableNames();
241
242 if ( aTables.empty() )
243 {
244 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xAssistant.get(),
245 VclMessageType::Question, VclButtonsType::YesNo,
246 compmodule::ModuleRes(getSettings().eType == AST_EVOLUTION_GROUPWISE ? RID_STR_QRY_NO_EVO_GW : RID_STR_QRY_NOTABLES)));
247
248 if (RET_YES != xBox->run())
249 {
250 // cannot ask the user, or the user chose to use this data source, though there are no tables
251 bAllow = false;
252 break;
253 }
254
256 }
257
258 if ( aTables.size() == 1 )
259 // remember the one and only table we have
260 m_aSettings.sSelectedTable = *aTables.begin();
261
262 break;
263 }
264
266 return bAllow;
267 }
268
270 {
271 const StringBag& rTableNames = getDataSource().getTableNames();
272 if ( rTableNames.end() != rTableNames.find( getSettings().sSelectedTable ) )
273 // already a valid table selected
274 return;
275
276 const char* pGuess = nullptr;
277 switch ( getSettings().eType )
278 {
279 case AST_THUNDERBIRD : pGuess = "Personal Address book"; break;
280 case AST_EVOLUTION :
282 case AST_EVOLUTION_LDAP : pGuess = "Personal"; break;
283 default:
284 OSL_FAIL( "OAddressBookSourcePilot::implDefaultTableName: unhandled case!" );
285 return;
286 }
287 const OUString sGuess = OUString::createFromAscii( pGuess );
288 if ( rTableNames.end() != rTableNames.find( sGuess ) )
289 getSettings().sSelectedTable = sGuess;
290 }
291
293 {
294 DBG_ASSERT( !needManualFieldMapping( ), "OAddressBookSourcePilot::implDoAutoFieldMapping: invalid call!" );
295
297 }
298
300 {
302 { // we already have a data source object
304 // and it already has the correct type
305 return;
306
307 // it has a wrong type -> remove it
309 }
310
311 ODataSourceContext aContext( getORB() );
313
314 switch (m_aSettings.eType)
315 {
316 case AST_THUNDERBIRD:
318 break;
319
320 case AST_EVOLUTION:
322 break;
323
326 break;
327
330 break;
331
332 case AST_KAB:
334 break;
335
336 case AST_MACAB:
338 break;
339
340 case AST_OTHER:
342 break;
343
344 case AST_INVALID:
345 OSL_FAIL( "OAddressBookSourcePilot::implCreateDataSource: illegal data source type!" );
346 break;
347 }
349 }
350
352 {
353 DBG_ASSERT( m_aNewDataSource.isValid(), "OAddressBookSourcePilot::implConnect: invalid current data source!" );
354
355 weld::WaitObject aWaitCursor(m_xAssistant.get());
356 if ( _bForceReConnect && m_aNewDataSource.isConnected( ) )
358
360 }
361
362 std::unique_ptr<BuilderPage> OAddressBookSourcePilot::createPage(WizardState _nState)
363 {
364 OUString sIdent(OUString::number(_nState));
365 weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
366
367 std::unique_ptr<vcl::OWizardPage> xRet;
368
369 switch (_nState)
370 {
372 xRet = std::make_unique<TypeSelectionPage>(pPageContainer, this);
373 break;
375 xRet = std::make_unique<AdminDialogInvokationPage>(pPageContainer, this);
376 break;
378 xRet = std::make_unique<TableSelectionPage>(pPageContainer, this);
379 break;
381 xRet = std::make_unique<FieldMappingPage>(pPageContainer, this);
382 break;
384 xRet = std::make_unique<FinalPage>(pPageContainer, this);
385 break;
386 default:
387 assert(false && "OAddressBookSourcePilot::createPage: invalid state!");
388 break;
389 }
390
391 m_xAssistant->set_page_title(sIdent, getStateDisplayName(_nState));
392
393 return xRet;
394 }
395
397 {
398 bool bSettingsPage = needAdminInvokationPage( _eType );
399 bool bTablesPage = needTableSelection( _eType );
400 bool bFieldsPage = needManualFieldMapping( _eType );
401
402 bool bConnected = m_aNewDataSource.isConnected();
403 bool bCanSkipTables =
406 );
407
408 enableState( STATE_INVOKE_ADMIN_DIALOG, bSettingsPage );
409
411 bTablesPage && ( bConnected ? !bCanSkipTables : !bSettingsPage )
412 // if we do not need a settings page, we connect upon "Next" on the first page
413 );
414
416 bFieldsPage && bConnected && m_aNewDataSource.hasTable( m_aSettings.sSelectedTable )
417 );
418
420 bConnected && bCanSkipTables
421 );
422 }
423
425 {
426 PathId nCurrentPathID( PATH_COMPLETE );
427 bool bSettingsPage = needAdminInvokationPage( _eType );
428 bool bFieldsPage = needManualFieldMapping( _eType );
429 if ( !bSettingsPage )
430 if ( !bFieldsPage )
431 nCurrentPathID = PATH_NO_SETTINGS_NO_FIELDS;
432 else
433 nCurrentPathID = PATH_NO_SETTINGS;
434 else
435 if ( !bFieldsPage )
436 nCurrentPathID = PATH_NO_FIELDS;
437 else
438 nCurrentPathID = PATH_COMPLETE;
439 activatePath( nCurrentPathID, true );
440
443 impl_updateRoadmap( _eType );
444 }
445
446} // namespace abp
447
448
449/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define STATE_MANUAL_FIELD_MAPPING
Definition: abspilot.cxx:44
#define STATE_FINAL_CONFIRM
Definition: abspilot.cxx:45
#define PATH_NO_SETTINGS_NO_FIELDS
Definition: abspilot.cxx:50
#define STATE_TABLE_SELECTION
Definition: abspilot.cxx:43
#define STATE_SELECT_ABTYPE
Definition: abspilot.cxx:41
#define PATH_NO_SETTINGS
Definition: abspilot.cxx:48
#define STATE_INVOKE_ADMIN_DIALOG
Definition: abspilot.cxx:42
#define PATH_NO_FIELDS
Definition: abspilot.cxx:49
#define PATH_COMPLETE
Definition: abspilot.cxx:47
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
virtual OUString getStateDisplayName(WizardState _nState) const override
Definition: abspilot.cxx:120
AddressSettings m_aSettings
Definition: abspilot.hxx:36
virtual bool onFinish() override
Definition: abspilot.cxx:178
void implDefaultTableName()
guesses a default for the table name, if no valid table is selected
Definition: abspilot.cxx:269
void implDoAutoFieldMapping()
does an automatic field mapping (possible for all types except AST_OTHER)
Definition: abspilot.cxx:292
bool needManualFieldMapping() const
checks if we need a manual (user-guided) field mapping
Definition: abspilot.hxx:102
static bool needTableSelection(AddressSourceType _eType)
determines whether the given address book type does provide one table only
Definition: abspilot.hxx:108
virtual std::unique_ptr< BuilderPage > createPage(WizardState _nState) override
Definition: abspilot.cxx:362
const css::uno::Reference< css::uno::XComponentContext > & getORB() const
get the service factory which was used to create the dialog
Definition: abspilot.hxx:51
bool needAdminInvokationPage() const
check if with the current settings, we would need to invoke he administration dialog for more details...
Definition: abspilot.hxx:90
OAddressBookSourcePilot(weld::Window *_pParent, const css::uno::Reference< css::uno::XComponentContext > &_rxORB)
ctor
Definition: abspilot.cxx:55
const ODataSource & getDataSource() const
Definition: abspilot.hxx:55
AddressSourceType m_eNewDataSourceType
Definition: abspilot.hxx:39
virtual short run() override
Definition: abspilot.cxx:169
void impl_updateRoadmap(AddressSourceType _eType)
Definition: abspilot.cxx:396
bool connectToDataSource(bool _bForceReConnect)
Definition: abspilot.cxx:351
virtual bool prepareLeaveCurrentState(CommitPageReason _eReason) override
Definition: abspilot.cxx:212
void implCreateDataSource()
creates a new data source of the type indicated by m_aSettings
Definition: abspilot.cxx:299
AddressSettings & getSettings()
Definition: abspilot.hxx:52
virtual void enterState(WizardState _nState) override
Definition: abspilot.cxx:190
void typeSelectionChanged(AddressSourceType _eType)
to be called when the selected type changed
Definition: abspilot.cxx:424
a non-UNO wrapper for the data source context
ODataSource createNewEvolutionGroupwise(const OUString &_rName)
creates a new Evolution GROUPWISE data source
ODataSource createNewEvolutionLdap(const OUString &_rName)
creates a new Evolution LDAP data source
ODataSource createNewKab(const OUString &_rName)
creates a new KDE address book data source
ODataSource createNewMacab(const OUString &_rName)
creates a new macOS address book data source
void disambiguate(OUString &_rDataSourceName)
disambiguates the given name by appending successive numbers
ODataSource createNewOther(const OUString &_rName)
creates a new Other data source; tdf117101: Spreadsheet by default
ODataSource createNewEvolution(const OUString &_rName)
creates a new Evolution local data source
ODataSource createNewThunderbird(const OUString &_rName)
creates a new Thunderbird data source
void store(const AddressSettings &rSettings)
stores the database file
bool connect(weld::Window *_pMessageParent)
connects to the data source represented by this object
void remove()
removes the data source represented by the object from the data source context
bool isValid() const
checks whether or not the object represents a valid data source
void disconnect()
disconnects from the data source (i.e. disposes the UNO connection hold internally)
bool rename(const OUString &_rName)
renames the data source
const StringBag & getTableNames() const
retrieves the tables names from the connection
bool hasTable(const OUString &_rTableName) const
determines whether a given table exists
void registerDataSource(const OUString &_sRegisteredDataSourceName)
register the data source under the given name in the configuration
OUString getName() const
returns the name of the data source
bool isConnected() const
returns <TRUE> if the object has a valid connection, obtained from its data source
void declarePath(RoadmapWizardTypes::PathId _nPathId, const RoadmapWizardTypes::WizardPath &_lWizardStates)
void activatePath(RoadmapWizardTypes::PathId _nPathId, bool _bDecideForIt=false)
virtual void enterState(WizardTypes::WizardState nState) override
void enableState(WizardTypes::WizardState nState, bool _bEnable=true)
std::unique_ptr< weld::Button > m_xNextPage
std::unique_ptr< weld::Button > m_xCancel
virtual bool onFinish()
void defaultButton(WizardButtonFlags _nWizardButtonFlags)
std::unique_ptr< weld::Button > m_xPrevPage
virtual void ActivatePage()
void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
std::unique_ptr< weld::Button > m_xHelp
virtual bool prepareLeaveCurrentState(WizardTypes::CommitPageReason eReason)
std::unique_ptr< weld::Button > m_xFinish
WizardTypes::WizardState getCurrentState() const
void setTitleBase(const OUString &_rTitleBase)
BuilderPage * GetPage(WizardTypes::WizardState eState) const
std::unique_ptr< weld::Assistant > m_xAssistant
virtual short run()
#define DBG_ASSERT(sCon, aError)
DocumentType eType
OUString sDisplayName
constexpr OUStringLiteral HID_ABSPILOT_PREVIOUS
Definition: helpids.h:25
constexpr OUStringLiteral HID_ABSPILOT_NEXT
Definition: helpids.h:26
constexpr OUStringLiteral HID_ABSPILOT_CANCEL
Definition: helpids.h:27
constexpr OUStringLiteral UID_ABSPILOT_HELP
Definition: helpids.h:29
constexpr OUStringLiteral HID_ABSPILOT_FINISH
Definition: helpids.h:28
constexpr OUStringLiteral HID_ABSPILOT
Definition: helpids.h:30
void markPilotSuccess(const Reference< XComponentContext > &_rxContext)
void writeTemplateAddressSource(const Reference< XComponentContext > &_rxContext, const OUString &_rDataSourceName, const OUString &_rTableName)
void defaultMapping(const Reference< XComponentContext > &_rxContext, MapString2String &_rFieldAssignment)
void writeTemplateAddressFieldMapping(const Reference< XComponentContext > &_rxContext, MapString2String &&aFieldAssignment)
std::set< OUString > StringBag
Definition: abptypes.hxx:34
@ AST_EVOLUTION_GROUPWISE
@ AST_EVOLUTION_LDAP
@ AST_THUNDERBIRD
@ AST_EVOLUTION
OUString ModuleRes(TranslateId pId)
sal_Int16 WizardState
CommitPageReason
AddressSourceType eType
MapString2String aFieldMapping
OUString sRegisteredDataSourceName
RET_YES