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 <hintids.hxx>
21 #include <svl/eitem.hxx>
22 #include <svl/stritem.hxx>
23 #include <editeng/fontitem.hxx>
24 #include <fmtftn.hxx>
25 #include <swundo.hxx>
26 #include <cmdid.h>
27 #include <wrtsh.hxx>
28 #include <insfnote.hxx>
29 #include <svx/svxdlg.hxx>
30 
31 #include <memory>
32 
33 static bool bFootnote = true;
34 
35 // inserting a footnote with OK
Apply()36 void SwInsFootNoteDlg::Apply()
37 {
38     OUString aStr;
39     if ( m_xNumberCharBtn->get_active() )
40         aStr = m_xNumberCharEdit->get_text();
41 
42     if (m_bEdit)
43     {
44         m_rSh.StartAction();
45         m_rSh.Left(CRSR_SKIP_CHARS, false, 1, false );
46         m_rSh.StartUndo( SwUndoId::START );
47         SwFormatFootnote aNote( m_xEndNoteBtn->get_active() );
48         aNote.SetNumStr( aStr );
49 
50         if (m_rSh.SetCurFootnote( aNote ) && m_bExtCharAvailable)
51         {
52             m_rSh.Right(CRSR_SKIP_CHARS, true, 1, false );
53             SfxItemSet aSet(m_rSh.GetAttrPool(), svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONT>{});
54             m_rSh.GetCurAttr(aSet);
55             const SvxFontItem &rFont = aSet.Get( RES_CHRATR_FONT );
56             SvxFontItem aFont( rFont.GetFamily(), m_aFontName,
57                                rFont.GetStyleName(), rFont.GetPitch(),
58                                m_eCharSet, RES_CHRATR_FONT );
59             aSet.Put( aFont );
60             m_rSh.SetAttrSet( aSet, SetAttrMode::DONTEXPAND );
61             m_rSh.ResetSelect(nullptr, false);
62             m_rSh.Left(CRSR_SKIP_CHARS, false, 1, false );
63         }
64         m_rSh.EndUndo( SwUndoId::END );
65         m_rSh.EndAction();
66     }
67 
68     bFootnote = m_xFootnoteBtn->get_active();
69 }
70 
IMPL_LINK_NOARG(SwInsFootNoteDlg,NumberEditHdl,weld::Entry &,void)71 IMPL_LINK_NOARG(SwInsFootNoteDlg, NumberEditHdl, weld::Entry&, void)
72 {
73     m_xNumberCharBtn->set_active(true);
74     m_xOkBtn->set_sensitive( !m_xNumberCharEdit->get_text().isEmpty() );
75 }
76 
IMPL_LINK(SwInsFootNoteDlg,NumberToggleHdl,weld::Toggleable &,rButton,void)77 IMPL_LINK(SwInsFootNoteDlg, NumberToggleHdl, weld::Toggleable&, rButton, void)
78 {
79     if (!rButton.get_active())
80         return;
81 
82     if (m_xNumberAutoBtn->get_active())
83         m_xOkBtn->set_sensitive(true);
84     else if (m_xNumberCharBtn->get_active())
85     {
86         m_xNumberCharEdit->grab_focus();
87         m_xOkBtn->set_sensitive( !m_xNumberCharEdit->get_text().isEmpty() || m_bExtCharAvailable );
88     }
89 }
90 
IMPL_LINK_NOARG(SwInsFootNoteDlg,NumberExtCharHdl,weld::Button &,void)91 IMPL_LINK_NOARG(SwInsFootNoteDlg, NumberExtCharHdl, weld::Button&, void)
92 {
93     m_xNumberCharBtn->set_active(true);
94 
95     SfxItemSet aSet(m_rSh.GetAttrPool(), svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONT>{});
96     m_rSh.GetCurAttr( aSet );
97     const SvxFontItem &rFont = aSet.Get( RES_CHRATR_FONT );
98 
99     SfxAllItemSet aAllSet(m_rSh.GetAttrPool());
100     aAllSet.Put( SfxBoolItem( FN_PARAM_1, false ) );
101     aAllSet.Put( rFont );
102 
103     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
104     ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(m_xDialog.get(), aAllSet, nullptr));
105     if (RET_OK != pDlg->Execute())
106         return;
107 
108     const SfxStringItem* pItem = SfxItemSet::GetItem<SfxStringItem>(pDlg->GetOutputItemSet(), SID_CHARMAP, false);
109     const SvxFontItem* pFontItem = SfxItemSet::GetItem<SvxFontItem>(pDlg->GetOutputItemSet(), SID_ATTR_CHAR_FONT, false);
110     if ( !pItem )
111         return;
112 
113     m_xNumberCharEdit->set_text(pItem->GetValue());
114 
115     if ( pFontItem )
116     {
117         m_aFontName = pFontItem->GetFamilyName();
118         m_eCharSet  = pFontItem->GetCharSet();
119         vcl::Font aFont(m_aFontName, pFontItem->GetStyleName(), m_xNumberCharEdit->get_font().GetFontSize());
120         aFont.SetCharSet( pFontItem->GetCharSet() );
121         aFont.SetPitch( pFontItem->GetPitch() );
122         m_xNumberCharEdit->set_font(aFont);
123     }
124 
125     m_bExtCharAvailable = true;
126     m_xOkBtn->set_sensitive(!m_xNumberCharEdit->get_text().isEmpty());
127 }
128 
IMPL_LINK(SwInsFootNoteDlg,NextPrevHdl,weld::Button &,rBtn,void)129 IMPL_LINK( SwInsFootNoteDlg, NextPrevHdl, weld::Button&, rBtn, void )
130 {
131     Apply();
132 
133     // go to the next foot/endnote here
134     m_rSh.ResetSelect(nullptr, false);
135     if (&rBtn == m_xNextBT.get())
136         m_rSh.GotoNextFootnoteAnchor();
137     else
138         m_rSh.GotoPrevFootnoteAnchor();
139 
140     Init();
141 }
142 
SwInsFootNoteDlg(weld::Window * pParent,SwWrtShell & rShell,bool bEd)143 SwInsFootNoteDlg::SwInsFootNoteDlg(weld::Window *pParent, SwWrtShell &rShell, bool bEd)
144     : GenericDialogController(pParent, "modules/swriter/ui/insertfootnote.ui", "InsertFootnoteDialog")
145     , m_rSh(rShell)
146     , m_eCharSet(RTL_TEXTENCODING_DONTKNOW)
147     , m_bExtCharAvailable(false)
148     , m_bEdit(bEd)
149     , m_xNumberFrame(m_xBuilder->weld_widget("numberingframe"))
150     , m_xNumberAutoBtn(m_xBuilder->weld_radio_button("automatic"))
151     , m_xNumberCharBtn(m_xBuilder->weld_radio_button("character"))
152     , m_xNumberCharEdit(m_xBuilder->weld_entry("characterentry"))
153     , m_xNumberExtChar(m_xBuilder->weld_button("choosecharacter"))
154     , m_xFootnoteBtn(m_xBuilder->weld_radio_button("footnote"))
155     , m_xEndNoteBtn(m_xBuilder->weld_radio_button("endnote"))
156     , m_xOkBtn(m_xBuilder->weld_button("ok"))
157     , m_xPrevBT(m_xBuilder->weld_button("prev"))
158     , m_xNextBT(m_xBuilder->weld_button("next"))
159 {
160     m_xNumberAutoBtn->connect_toggled(LINK(this,SwInsFootNoteDlg,NumberToggleHdl));
161     m_xNumberCharBtn->connect_toggled(LINK(this,SwInsFootNoteDlg,NumberToggleHdl));
162     m_xNumberExtChar->connect_clicked(LINK(this,SwInsFootNoteDlg,NumberExtCharHdl));
163     m_xNumberCharEdit->connect_changed(LINK(this,SwInsFootNoteDlg,NumberEditHdl));
164 
165     m_xPrevBT->connect_clicked(LINK(this, SwInsFootNoteDlg, NextPrevHdl));
166     m_xNextBT->connect_clicked(LINK(this, SwInsFootNoteDlg, NextPrevHdl));
167 
168     SwViewShell::SetCareDialog(m_xDialog);
169 
170     if (m_bEdit)
171     {
172         Init();
173 
174         m_xPrevBT->show();
175         m_xNextBT->show();
176     }
177 }
178 
~SwInsFootNoteDlg()179 SwInsFootNoteDlg::~SwInsFootNoteDlg() COVERITY_NOEXCEPT_FALSE
180 {
181     SwViewShell::SetCareDialog(nullptr);
182 
183     if (m_bEdit)
184         m_rSh.ResetSelect(nullptr, false);
185 }
186 
Init()187 void SwInsFootNoteDlg::Init()
188 {
189     SwFormatFootnote aFootnoteNote;
190     OUString sNumStr;
191     vcl::Font aFont;
192     m_bExtCharAvailable = false;
193 
194     m_rSh.StartAction();
195 
196     if (m_rSh.GetCurFootnote(&aFootnoteNote))
197     {
198         if (!aFootnoteNote.GetNumStr().isEmpty())
199         {
200             sNumStr = aFootnoteNote.GetNumStr();
201 
202             m_rSh.Right(CRSR_SKIP_CHARS, true, 1, false );
203             SfxItemSet aSet(m_rSh.GetAttrPool(), svl::Items<RES_CHRATR_FONT, RES_CHRATR_FONT>{});
204             m_rSh.GetCurAttr(aSet);
205             const SvxFontItem &rFont = aSet.Get( RES_CHRATR_FONT );
206             aFont = m_xNumberCharEdit->get_font();
207             m_aFontName = rFont.GetFamilyName();
208             m_eCharSet = rFont.GetCharSet();
209             aFont.SetFamilyName(m_aFontName);
210             aFont.SetCharSet(m_eCharSet);
211             m_bExtCharAvailable = true;
212             m_rSh.Left( CRSR_SKIP_CHARS, false, 1, false );
213         }
214         bFootnote = !aFootnoteNote.IsEndNote();
215     }
216     m_xNumberCharEdit->set_font(aFont);
217 
218     const bool bNumChar = !sNumStr.isEmpty();
219 
220     m_xNumberCharEdit->set_text(sNumStr);
221     m_xNumberCharBtn->set_active(bNumChar);
222     m_xNumberAutoBtn->set_active(!bNumChar);
223     if (bNumChar)
224         m_xNumberCharEdit->grab_focus();
225 
226     if (bFootnote)
227         m_xFootnoteBtn->set_active(true);
228     else
229         m_xEndNoteBtn->set_active(true);
230 
231     bool bNext = m_rSh.GotoNextFootnoteAnchor();
232 
233     if (bNext)
234         m_rSh.GotoPrevFootnoteAnchor();
235 
236     bool bPrev = m_rSh.GotoPrevFootnoteAnchor();
237 
238     if (bPrev)
239         m_rSh.GotoNextFootnoteAnchor();
240 
241     m_xPrevBT->set_sensitive(bPrev);
242     m_xNextBT->set_sensitive(bNext);
243 
244     m_rSh.Right(CRSR_SKIP_CHARS, true, 1, false );
245 
246     m_rSh.EndAction();
247 }
248 
249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
250