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 <svl/style.hxx>
21 #include <osl/diagnose.h>
22 #include <wrtsh.hxx>
23 #include <view.hxx>
24 #include <docsh.hxx>
25 #include <docfnote.hxx>
26 #include "impfnote.hxx"
27 #include <ftninfo.hxx>
28 #include <fmtcol.hxx>
29 #include <pagedesc.hxx>
30 #include <charfmt.hxx>
31 #include <docstyle.hxx>
32 #include <wdocsh.hxx>
33 #include <uitool.hxx>
34 #include <poolfmt.hxx>
35 #include <SwStyleNameMapper.hxx>
36 #include <memory>
37 
SwFootNoteOptionDlg(weld::Window * pParent,SwWrtShell & rS)38 SwFootNoteOptionDlg::SwFootNoteOptionDlg(weld::Window *pParent, SwWrtShell &rS)
39     : SfxTabDialogController(pParent, "modules/swriter/ui/footendnotedialog.ui", "FootEndnoteDialog")
40     , rSh( rS )
41 {
42     RemoveResetButton();
43 
44     GetOKButton().connect_clicked(LINK(this, SwFootNoteOptionDlg, OkHdl));
45 
46     AddTabPage("footnotes", SwFootNoteOptionPage::Create, nullptr);
47     AddTabPage("endnotes",  SwEndNoteOptionPage::Create, nullptr);
48 }
49 
PageCreated(const OString &,SfxTabPage & rPage)50 void SwFootNoteOptionDlg::PageCreated(const OString& /*rId*/, SfxTabPage &rPage)
51 {
52     static_cast<SwEndNoteOptionPage&>(rPage).SetShell(rSh);
53 }
54 
IMPL_LINK(SwFootNoteOptionDlg,OkHdl,weld::Button &,rBtn,void)55 IMPL_LINK(SwFootNoteOptionDlg, OkHdl, weld::Button&, rBtn, void)
56 {
57     SfxItemSet aDummySet(rSh.GetAttrPool(), svl::Items<1, 1>{} );
58     SfxTabPage *pPage = GetTabPage("footnotes");
59     if ( pPage )
60         pPage->FillItemSet( &aDummySet );
61     pPage = GetTabPage("endnotes");
62     if ( pPage )
63         pPage->FillItemSet( &aDummySet );
64     SfxTabDialogController::OkHdl(rBtn);
65 }
66 
SwEndNoteOptionPage(weld::Container * pPage,weld::DialogController * pController,bool bEN,const SfxItemSet & rSet)67 SwEndNoteOptionPage::SwEndNoteOptionPage(weld::Container* pPage, weld::DialogController* pController, bool bEN,
68     const SfxItemSet &rSet)
69     : SfxTabPage(pPage, pController,
70         bEN ? OUString("modules/swriter/ui/endnotepage.ui") : OUString("modules/swriter/ui/footnotepage.ui"),
71         bEN ? OString("EndnotePage") : OString("FootnotePage"),
72         &rSet)
73     , pSh(nullptr)
74     , bPosDoc(false)
75     , bEndNote(bEN)
76     , m_xNumViewBox(new SwNumberingTypeListBox(m_xBuilder->weld_combo_box("numberinglb")))
77     , m_xOffsetLbl(m_xBuilder->weld_label("offset"))
78     , m_xOffsetField(m_xBuilder->weld_spin_button("offsetnf"))
79     , m_xNumCountBox(m_xBuilder->weld_combo_box("countinglb"))
80     , m_xPrefixED(m_xBuilder->weld_entry("prefix"))
81     , m_xSuffixED(m_xBuilder->weld_entry("suffix"))
82     , m_xPosFT(m_xBuilder->weld_label("pos"))
83     , m_xPosPageBox(m_xBuilder->weld_radio_button("pospagecb"))
84     , m_xPosChapterBox(m_xBuilder->weld_radio_button("posdoccb"))
85     , m_xStylesContainer(m_xBuilder->weld_widget("allstyles"))
86     , m_xParaTemplBox(m_xBuilder->weld_combo_box("parastylelb"))
87     , m_xPageTemplLbl(m_xBuilder->weld_label("pagestyleft"))
88     , m_xPageTemplBox(m_xBuilder->weld_combo_box("pagestylelb"))
89     , m_xFootnoteCharAnchorTemplBox(m_xBuilder->weld_combo_box("charanchorstylelb"))
90     , m_xFootnoteCharTextTemplBox(m_xBuilder->weld_combo_box("charstylelb"))
91     , m_xContEdit(m_xBuilder->weld_entry("conted"))
92     , m_xContFromEdit(m_xBuilder->weld_entry("contfromed"))
93 {
94     m_xNumViewBox->Reload(SwInsertNumTypes::Extended);
95     if (!bEndNote)
96     {
97         m_xNumCountBox->connect_changed(LINK(this, SwEndNoteOptionPage, NumCountHdl));
98         aNumDoc = m_xNumCountBox->get_text(FTNNUM_DOC);
99         aNumPage = m_xNumCountBox->get_text(FTNNUM_PAGE);
100         aNumChapter = m_xNumCountBox->get_text(FTNNUM_CHAPTER);
101         m_xPosPageBox->connect_toggled(LINK(this, SwEndNoteOptionPage, ToggleHdl));
102         m_xPosChapterBox->connect_toggled(LINK(this, SwEndNoteOptionPage, ToggleHdl));
103     }
104     m_xParaTemplBox->make_sorted();
105 }
106 
~SwEndNoteOptionPage()107 SwEndNoteOptionPage::~SwEndNoteOptionPage()
108 {
109 }
110 
Reset(const SfxItemSet *)111 void SwEndNoteOptionPage::Reset( const SfxItemSet* )
112 {
113     std::unique_ptr<SwEndNoteInfo> pInf(bEndNote ? new SwEndNoteInfo( pSh->GetEndNoteInfo() )
114                                           : new SwFootnoteInfo( pSh->GetFootnoteInfo() ));
115     SfxObjectShell * pDocSh = SfxObjectShell::Current();
116 
117     if (dynamic_cast<SwWebDocShell*>( pDocSh) )
118         m_xStylesContainer->hide();
119 
120     if ( bEndNote )
121     {
122         bPosDoc = true;
123     }
124     else
125     {
126         const SwFootnoteInfo &rInf = pSh->GetFootnoteInfo();
127         // set position (page, chapter)
128         if ( rInf.m_ePos == FTNPOS_PAGE )
129         {
130             m_xPosPageBox->set_active(true);
131             m_xPageTemplLbl->set_sensitive(false);
132             m_xPageTemplBox->set_sensitive(false);
133         }
134         else
135         {
136             m_xPosChapterBox->set_active(true);
137             m_xNumCountBox->remove_text(aNumPage);
138             m_xNumCountBox->remove_text(aNumChapter);
139             bPosDoc = true;
140         }
141             // reference tests
142         m_xContEdit->set_text(rInf.m_aQuoVadis);
143         m_xContFromEdit->set_text(rInf.m_aErgoSum);
144 
145             // collected
146         SelectNumbering(rInf.m_eNum);
147     }
148 
149         // numbering
150         // art
151     m_xNumViewBox->SelectNumberingType( pInf->m_aFormat.GetNumberingType());
152     m_xOffsetField->set_value(pInf->m_nFootnoteOffset + 1);
153     m_xPrefixED->set_text(pInf->GetPrefix().replaceAll("\t", "\\t")); // fdo#65666
154     m_xSuffixED->set_text(pInf->GetSuffix().replaceAll("\t", "\\t"));
155 
156     const SwCharFormat* pCharFormat = pInf->GetCharFormat(
157                         *pSh->GetView().GetDocShell()->GetDoc());
158     m_xFootnoteCharTextTemplBox->set_active_text(pCharFormat->GetName());
159     m_xFootnoteCharTextTemplBox->save_value();
160 
161     pCharFormat = pInf->GetAnchorCharFormat( *pSh->GetDoc() );
162     m_xFootnoteCharAnchorTemplBox->set_active_text( pCharFormat->GetName() );
163     m_xFootnoteCharAnchorTemplBox->save_value();
164 
165         // styles   special regions
166         // paragraph
167     SfxStyleSheetBasePool* pStyleSheetPool = pSh->GetView().GetDocShell()->GetStyleSheetPool();
168     SfxStyleSheetBase *pStyle = pStyleSheetPool->First(SfxStyleFamily::Para, SfxStyleSearchBits::SwExtra);
169     while(pStyle)
170     {
171         m_xParaTemplBox->append_text(pStyle->GetName());
172         pStyle = pStyleSheetPool->Next();
173     }
174 
175     OUString sStr;
176     SwStyleNameMapper::FillUIName( static_cast< sal_uInt16 >(bEndNote ? RES_POOLCOLL_ENDNOTE
177                            : RES_POOLCOLL_FOOTNOTE), sStr );
178     if (m_xParaTemplBox->find_text(sStr) == -1)
179         m_xParaTemplBox->append_text(sStr);
180 
181     SwTextFormatColl* pColl = pInf->GetFootnoteTextColl();
182     if( !pColl )
183         m_xParaTemplBox->set_active_text(sStr);      // Default
184     else
185     {
186         OSL_ENSURE(!pColl->IsDefault(), "default style for footnotes is wrong");
187         const int nPos = m_xParaTemplBox->find_text(pColl->GetName());
188         if (nPos != -1)
189             m_xParaTemplBox->set_active( nPos );
190         else
191         {
192             m_xParaTemplBox->append_text(pColl->GetName());
193             m_xParaTemplBox->set_active_text(pColl->GetName());
194         }
195     }
196 
197     // page
198     for (sal_uInt16 i = RES_POOLPAGE_BEGIN; i < RES_POOLPAGE_END; ++i)
199         m_xPageTemplBox->append_text(SwStyleNameMapper::GetUIName(i, OUString()));
200 
201     const size_t nCount = pSh->GetPageDescCnt();
202     for(size_t i = 0; i < nCount; ++i)
203     {
204         const SwPageDesc &rPageDesc = pSh->GetPageDesc(i);
205         if (m_xPageTemplBox->find_text(rPageDesc.GetName()) == -1)
206             m_xPageTemplBox->append_text(rPageDesc.GetName());
207     }
208     m_xPageTemplBox->make_sorted();
209 
210     m_xPageTemplBox->set_active_text(pInf->GetPageDesc(*pSh->GetDoc())->GetName());
211 }
212 
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)213 std::unique_ptr<SfxTabPage> SwEndNoteOptionPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet )
214 {
215     return std::make_unique<SwEndNoteOptionPage>(pPage, pController, true, *rSet);
216 }
217 
218 // Different kinds of numbering; because the Listbox has varying numbers of
219 // entries, here are functions to set and query the intended kind of numbering.
SelectNumbering(SwFootnoteNum const eNum)220 void SwEndNoteOptionPage::SelectNumbering(SwFootnoteNum const eNum)
221 {
222     OUString sSelect;
223     switch(eNum)
224     {
225         case FTNNUM_DOC:
226             sSelect = aNumDoc;
227         break;
228         case FTNNUM_PAGE:
229             sSelect = aNumPage;
230         break;
231         case FTNNUM_CHAPTER:
232             sSelect = aNumChapter;
233         break;
234         default:
235             assert(false);
236     }
237     m_xNumCountBox->set_active_text(sSelect);
238     NumCountHdl(*m_xNumCountBox);
239 }
240 
GetNumbering() const241 SwFootnoteNum SwEndNoteOptionPage::GetNumbering() const
242 {
243     const int nPos = m_xNumCountBox->get_active();
244     return static_cast<SwFootnoteNum>(bPosDoc ? nPos + 2 : nPos);
245 }
246 
SetShell(SwWrtShell & rShell)247 void SwEndNoteOptionPage::SetShell( SwWrtShell &rShell )
248 {
249     pSh = &rShell;
250     // collect character templates
251     m_xFootnoteCharTextTemplBox->clear();
252     m_xFootnoteCharAnchorTemplBox->clear();
253     ::FillCharStyleListBox(*m_xFootnoteCharTextTemplBox,
254                         pSh->GetView().GetDocShell(), true);
255 
256     ::FillCharStyleListBox(*m_xFootnoteCharAnchorTemplBox,
257                         pSh->GetView().GetDocShell(), true);
258 }
259 
IMPL_LINK(SwEndNoteOptionPage,ToggleHdl,weld::Toggleable &,rButton,void)260 IMPL_LINK(SwEndNoteOptionPage, ToggleHdl, weld::Toggleable&, rButton, void)
261 {
262     if (!rButton.get_active())
263         return;
264 
265     if (m_xPosPageBox->get_active())
266     {
267         // Handler behind the button to collect the footnote at the page. In this case
268         // all kinds of numbering can be used.
269 
270         const SwFootnoteNum eNum = GetNumbering();
271         bPosDoc = false;
272         if (m_xNumCountBox->find_text(aNumPage) == -1)
273         {
274             m_xNumCountBox->insert_text(FTNNUM_PAGE, aNumPage);
275             m_xNumCountBox->insert_text(FTNNUM_CHAPTER, aNumChapter);
276             SelectNumbering(eNum);
277         }
278         m_xPageTemplLbl->set_sensitive(false);
279         m_xPageTemplBox->set_sensitive(false);
280     }
281     else if (m_xPosChapterBox->get_active())
282     {
283         // Handler behind the button to collect the footnote at the chapter or end of
284         // the document. In this case no pagewise numbering can be used.
285 
286         if ( !bPosDoc )
287             SelectNumbering(FTNNUM_DOC);
288 
289         bPosDoc = true;
290         m_xNumCountBox->remove_text(aNumPage);
291         m_xNumCountBox->remove_text(aNumChapter);
292         m_xPageTemplLbl->set_sensitive(true);
293         m_xPageTemplBox->set_sensitive(true);
294     }
295 }
296 
IMPL_LINK_NOARG(SwEndNoteOptionPage,NumCountHdl,weld::ComboBox &,void)297 IMPL_LINK_NOARG(SwEndNoteOptionPage, NumCountHdl, weld::ComboBox&, void)
298 {
299     bool bEnable = true;
300     if (m_xNumCountBox->get_count() - 1 != m_xNumCountBox->get_active())
301     {
302         bEnable = false;
303         m_xOffsetField->set_value(1);
304     }
305     m_xOffsetLbl->set_sensitive(bEnable);
306     m_xOffsetField->set_sensitive(bEnable);
307 }
308 
lcl_GetCharFormat(SwWrtShell * pSh,const OUString & rCharFormatName)309 static SwCharFormat* lcl_GetCharFormat( SwWrtShell* pSh, const OUString& rCharFormatName )
310 {
311     SwCharFormat* pFormat = nullptr;
312     const sal_uInt16 nChCount = pSh->GetCharFormatCount();
313     for(sal_uInt16 i = 0; i< nChCount; i++)
314     {
315         SwCharFormat& rChFormat = pSh->GetCharFormat(i);
316         if(rChFormat.GetName() == rCharFormatName )
317         {
318             pFormat = &rChFormat;
319             break;
320         }
321     }
322     if(!pFormat)
323     {
324         SfxStyleSheetBasePool* pPool = pSh->GetView().GetDocShell()->GetStyleSheetPool();
325         SfxStyleSheetBase* pBase;
326         pBase = pPool->Find(rCharFormatName, SfxStyleFamily::Char);
327         if(!pBase)
328             pBase = &pPool->Make(rCharFormatName, SfxStyleFamily::Char);
329         pFormat = static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat();
330     }
331     return pFormat;
332 }
333 
FillItemSet(SfxItemSet *)334 bool SwEndNoteOptionPage::FillItemSet( SfxItemSet * )
335 {
336     std::unique_ptr<SwEndNoteInfo> pInf(bEndNote ? new SwEndNoteInfo() : new SwFootnoteInfo());
337 
338     pInf->m_nFootnoteOffset = m_xOffsetField->get_value() - 1;
339     pInf->m_aFormat.SetNumberingType(m_xNumViewBox->GetSelectedNumberingType() );
340     pInf->SetPrefix(m_xPrefixED->get_text().replaceAll("\\t", "\t"));
341     pInf->SetSuffix(m_xSuffixED->get_text().replaceAll("\\t", "\t"));
342 
343     pInf->SetCharFormat( lcl_GetCharFormat( pSh,
344                         m_xFootnoteCharTextTemplBox->get_active_text() ) );
345     pInf->SetAnchorCharFormat( lcl_GetCharFormat( pSh,
346                         m_xFootnoteCharAnchorTemplBox->get_active_text() ) );
347 
348     // paragraph template
349     int nPos = m_xParaTemplBox->get_active();
350     if (nPos != -1)
351     {
352         const OUString aFormatName( m_xParaTemplBox->get_active_text() );
353         SwTextFormatColl *pColl = pSh->GetParaStyle(aFormatName, SwWrtShell::GETSTYLE_CREATEANY);
354         OSL_ENSURE(pColl, "paragraph style not found");
355         pInf->SetFootnoteTextColl(*pColl);
356     }
357 
358     // page template
359     pInf->ChgPageDesc( pSh->FindPageDescByName(
360                                 m_xPageTemplBox->get_active_text(), true ) );
361 
362     if ( bEndNote )
363     {
364         if ( !(*pInf == pSh->GetEndNoteInfo()) )
365             pSh->SetEndNoteInfo( *pInf );
366     }
367     else
368     {
369         SwFootnoteInfo *pI = static_cast<SwFootnoteInfo*>(pInf.get());
370         pI->m_ePos = m_xPosPageBox->get_active() ? FTNPOS_PAGE : FTNPOS_CHAPTER;
371         pI->m_eNum = GetNumbering();
372         pI->m_aQuoVadis = m_xContEdit->get_text();
373         pI->m_aErgoSum = m_xContFromEdit->get_text();
374         if ( !(*pI == pSh->GetFootnoteInfo()) )
375             pSh->SetFootnoteInfo( *pI );
376     }
377     return true;
378 }
379 
SwFootNoteOptionPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)380 SwFootNoteOptionPage::SwFootNoteOptionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
381     : SwEndNoteOptionPage(pPage, pController, false, rSet)
382 {
383 }
384 
~SwFootNoteOptionPage()385 SwFootNoteOptionPage::~SwFootNoteOptionPage()
386 {
387 }
388 
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)389 std::unique_ptr<SfxTabPage> SwFootNoteOptionPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet )
390 {
391     return std::make_unique<SwFootNoteOptionPage>(pPage, pController, *rSet);
392 }
393 
394 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
395