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 <osl/diagnose.h>
21
22 #include <mailmergewizard.hxx>
23 #include "mmdocselectpage.hxx"
24 #include "mmoutputtypepage.hxx"
25 #include "mmaddressblockpage.hxx"
26 #include "mmgreetingspage.hxx"
27 #include "mmlayoutpage.hxx"
28 #include <mmconfigitem.hxx>
29 #include <swabstdlg.hxx>
30 #include <strings.hrc>
31 #include <utility>
32 #include <view.hxx>
33
34 #include <helpids.h>
35
36 using namespace ::com::sun::star;
37 using vcl::RoadmapWizardTypes::PathId;
38
SwMailMergeWizard(SwView & rView,std::shared_ptr<SwMailMergeConfigItem> xItem)39 SwMailMergeWizard::SwMailMergeWizard(SwView& rView, std::shared_ptr<SwMailMergeConfigItem> xItem)
40 : RoadmapWizardMachine(rView.GetFrameWeld())
41 , m_rSwView(rView)
42 , m_bDocumentLoad(false)
43 , m_xConfigItem(std::move(xItem))
44 , m_sStarting(SwResId(ST_STARTING))
45 , m_sDocumentType(SwResId(ST_DOCUMENTTYPE))
46 , m_sAddressBlock(SwResId(ST_ADDRESSBLOCK))
47 , m_sAddressList(SwResId(ST_ADDRESSLIST))
48 , m_sGreetingsLine(SwResId(ST_GREETINGSLINE))
49 , m_sLayout(SwResId(ST_LAYOUT))
50 , m_nRestartPage(MM_DOCUMENTSELECTPAGE)
51 {
52 defaultButton(WizardButtonFlags::NEXT);
53 enableButtons(WizardButtonFlags::FINISH, false);
54
55 setTitleBase(SwResId(ST_MMWTITLE));
56
57 m_xFinish->set_label(SwResId( ST_FINISH ));
58 m_xNextPage->set_help_id(HID_MM_NEXT_PAGE);
59 m_xPrevPage->set_help_id(HID_MM_PREV_PAGE);
60
61 //#i51949# no output type page visible if e-Mail is not supported
62 if (m_xConfigItem->IsMailAvailable())
63 declarePath(
64 PathId::COMMON_FIRST_STATE,
65 {MM_DOCUMENTSELECTPAGE,
66 MM_OUTPUTTYPETPAGE,
67 MM_ADDRESSBLOCKPAGE,
68 MM_GREETINGSPAGE,
69 MM_LAYOUTPAGE}
70 );
71 else
72 declarePath(
73 PathId::COMMON_FIRST_STATE,
74 {MM_DOCUMENTSELECTPAGE,
75 MM_ADDRESSBLOCKPAGE,
76 MM_GREETINGSPAGE,
77 MM_LAYOUTPAGE}
78 );
79
80 ActivatePage();
81 m_xAssistant->set_current_page(0);
82 UpdateRoadmap();
83 }
84
~SwMailMergeWizard()85 SwMailMergeWizard::~SwMailMergeWizard()
86 {
87 }
88
createPage(WizardState _nState)89 std::unique_ptr<BuilderPage> SwMailMergeWizard::createPage(WizardState _nState)
90 {
91 OUString sIdent(OUString::number(_nState));
92 weld::Container* pPageContainer = m_xAssistant->append_page(sIdent);
93
94 std::unique_ptr<vcl::OWizardPage> xRet;
95 switch(_nState)
96 {
97 case MM_DOCUMENTSELECTPAGE :
98 xRet = std::make_unique<SwMailMergeDocSelectPage>(pPageContainer, this);
99
100 /* tdf#52986 Set help ID using SetRoadmapHelpId for all pages
101 so that when by default the focus is on the left side pane of
102 the wizard the relevant help page is displayed when hitting
103 the Help / F1 button */
104 SetRoadmapHelpId(u"modules/swriter/ui/mmselectpage/MMSelectPage"_ustr);
105 break;
106 case MM_OUTPUTTYPETPAGE :
107 xRet = std::make_unique<SwMailMergeOutputTypePage>(pPageContainer, this);
108 SetRoadmapHelpId(u"modules/swriter/ui/mmoutputtypepage/MMOutputTypePage"_ustr);
109 break;
110 case MM_ADDRESSBLOCKPAGE :
111 xRet = std::make_unique<SwMailMergeAddressBlockPage>(pPageContainer, this);
112 SetRoadmapHelpId(u"modules/swriter/ui/mmaddressblockpage/MMAddressBlockPage"_ustr);
113 break;
114 case MM_GREETINGSPAGE :
115 xRet = std::make_unique<SwMailMergeGreetingsPage>(pPageContainer, this);
116 SetRoadmapHelpId(u"modules/swriter/ui/mmsalutationpage/MMSalutationPage"_ustr);
117 break;
118 case MM_LAYOUTPAGE :
119 xRet = std::make_unique<SwMailMergeLayoutPage>(pPageContainer, this);
120 SetRoadmapHelpId(u"modules/swriter/ui/mmlayoutpage/MMLayoutPage"_ustr);
121 break;
122 }
123
124 m_xAssistant->set_page_title(sIdent, getStateDisplayName(_nState));
125
126 OSL_ENSURE(xRet, "no page created in ::createPage");
127 return xRet;
128 }
129
enterState(WizardState _nState)130 void SwMailMergeWizard::enterState( WizardState _nState )
131 {
132 ::vcl::RoadmapWizardMachine::enterState( _nState );
133
134 if (m_xConfigItem->GetTargetView())
135 {
136 //close the dialog, remove the target view, show the source view
137 m_nRestartPage = _nState;
138 //set ResultSet back to start
139 m_xConfigItem->MoveResultSet(1);
140 m_xAssistant->response(RET_REMOVE_TARGET);
141 return;
142 }
143 bool bEnablePrev = true;
144 bool bEnableNext = true;
145 switch(_nState)
146 {
147 case MM_DOCUMENTSELECTPAGE:
148 {
149 bEnablePrev = false; // the first page
150
151 OUString sDataSourceName = GetSwView().GetDataSourceName();
152 if(!sDataSourceName.isEmpty() &&
153 !SwView::IsDataSourceAvailable(sDataSourceName))
154 {
155 bEnableNext = false;
156 }
157 }
158 break;
159 case MM_ADDRESSBLOCKPAGE :
160 bEnableNext = m_xConfigItem->GetResultSet().is();
161 break;
162 case MM_LAYOUTPAGE:
163 bEnableNext = false; // the last page
164 break;
165 }
166 enableButtons( WizardButtonFlags::PREVIOUS, bEnablePrev);
167 enableButtons( WizardButtonFlags::NEXT, bEnableNext);
168
169 UpdateRoadmap();
170 }
171
getStateDisplayName(WizardState _nState) const172 OUString SwMailMergeWizard::getStateDisplayName( WizardState _nState ) const
173 {
174 switch(_nState)
175 {
176 case MM_DOCUMENTSELECTPAGE:
177 return m_sStarting;
178 case MM_OUTPUTTYPETPAGE:
179 return m_sDocumentType;
180 case MM_ADDRESSBLOCKPAGE:
181 return m_xConfigItem->IsOutputToLetter() ?
182 m_sAddressBlock : m_sAddressList;
183 case MM_GREETINGSPAGE:
184 return m_sGreetingsLine;
185 case MM_LAYOUTPAGE:
186 return m_sLayout;
187 }
188 return OUString();
189 }
190
191 // enables/disables pages in the roadmap depending on the current page and state
UpdateRoadmap()192 void SwMailMergeWizard::UpdateRoadmap()
193 {
194 /*
195 MM_DOCUMENTSELECTPAGE > inactive after the layoutpage
196 MM_OUTPUTTYPETPAGE : > inactive after the layoutpage
197 MM_ADDRESSBLOCKPAGE > inactive after the layoutpage
198 MM_GREETINGSPAGE > inactive after the layoutpage
199 MM_LAYOUTPAGE > inactive after the layoutpage
200 inactive if address block and greeting are switched off
201 or are already inserted into the source document
202 */
203
204 // enableState( <page id>, false );
205 const sal_uInt16 nCurPage = m_xAssistant->get_current_page();
206 BuilderPage* pCurPage = GetPage( nCurPage );
207 if(!pCurPage)
208 return;
209 bool bAddressFieldsConfigured = !m_xConfigItem->IsOutputToLetter() ||
210 !m_xConfigItem->IsAddressBlock() ||
211 m_xConfigItem->IsAddressFieldsAssigned();
212 bool bGreetingFieldsConfigured = !m_xConfigItem->IsGreetingLine(false) ||
213 !m_xConfigItem->IsIndividualGreeting(false) ||
214 m_xConfigItem->IsGreetingFieldsAssigned();
215
216 //#i97436# if a document has to be loaded then enable output type page only
217 m_bDocumentLoad = false;
218 bool bEnableOutputTypePage = (nCurPage != MM_DOCUMENTSELECTPAGE) ||
219 static_cast<vcl::OWizardPage*>(pCurPage)->commitPage( ::vcl::WizardTypes::eValidate );
220
221 // handle the Finish button
222 bool bCanFinish = !m_bDocumentLoad && bEnableOutputTypePage &&
223 m_xConfigItem->GetResultSet().is() &&
224 bAddressFieldsConfigured &&
225 bGreetingFieldsConfigured;
226 enableButtons(WizardButtonFlags::FINISH, (nCurPage != MM_DOCUMENTSELECTPAGE) && bCanFinish);
227
228 for(sal_uInt16 nPage = MM_DOCUMENTSELECTPAGE; nPage <= MM_LAYOUTPAGE; ++nPage)
229 {
230 bool bEnable = true;
231 switch(nPage)
232 {
233 case MM_DOCUMENTSELECTPAGE:
234 bEnable = true;
235 break;
236 case MM_OUTPUTTYPETPAGE:
237 bEnable = bEnableOutputTypePage;
238 break;
239 case MM_ADDRESSBLOCKPAGE:
240 bEnable = !m_bDocumentLoad && bEnableOutputTypePage;
241 // update page title for email vs letter
242 m_xAssistant->set_page_title(OUString::number(MM_ADDRESSBLOCKPAGE), getStateDisplayName(MM_ADDRESSBLOCKPAGE));
243 break;
244 case MM_GREETINGSPAGE:
245 bEnable = !m_bDocumentLoad && bEnableOutputTypePage &&
246 m_xConfigItem->GetResultSet().is() &&
247 bAddressFieldsConfigured;
248 break;
249 case MM_LAYOUTPAGE:
250 bEnable = bCanFinish &&
251 ((m_xConfigItem->IsAddressBlock() && !m_xConfigItem->IsAddressInserted()) ||
252 (m_xConfigItem->IsGreetingLine(false) && !m_xConfigItem->IsGreetingInserted() ));
253 break;
254 }
255 enableState( nPage, bEnable );
256 }
257 }
258
run()259 short SwMailMergeWizard::run()
260 {
261 OSL_FAIL("SwMailMergeWizard cannot be executed via Dialog::Execute!\n"
262 "It creates a thread (MailDispatcher instance) that will call"
263 "back to VCL apartment => deadlock!\n"
264 "Use Dialog::StartExecuteAsync to execute the dialog!" );
265 return RET_CANCEL;
266 }
267
268 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
269