xref: /core/sw/source/ui/dbui/mailmergewizard.cxx (revision 59953740b20ceb2bbc682625739f9bb6278ca7cb)
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