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 <swuiidxmrk.hxx>
21 #include <hintids.hxx>
22 #include <helpids.h>
23 #include <comphelper/processfactory.hxx>
24 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <com/sun/star/frame/Bibliography.hpp>
28 #include <com/sun/star/i18n/IndexEntrySupplier.hpp>
29 #include <com/sun/star/util/SearchAlgorithms2.hpp>
30 #include <com/sun/star/util/SearchFlags.hpp>
31 #include <i18nutil/searchopt.hxx>
32 #include <svl/stritem.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/weld.hxx>
35 #include <sfx2/dispatch.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <svl/eitem.hxx>
38 #include <unotools/textsearch.hxx>
39 #include <editeng/scripttypeitem.hxx>
40 #include <svl/itemset.hxx>
41 #include <editeng/langitem.hxx>
42 #include <editeng/unolingu.hxx>
43 #include <swtypes.hxx>
44 #include <idxmrk.hxx>
45 #include <toxmgr.hxx>
46 #include <txttxmrk.hxx>
47 #include <wrtsh.hxx>
48 #include <view.hxx>
49 #include <multmrk.hxx>
50 #include <swundo.hxx>
51 #include <cmdid.h>
52 #include <app.hrc>
53 #include <swmodule.hxx>
54 #include <fldmgr.hxx>
55 #include <fldbas.hxx>
56 #include <strings.hrc>
57 #include <swcont.hxx>
58 #include <svl/cjkoptions.hxx>
59 #include <ndtxt.hxx>
60 #include <breakit.hxx>
61 #include <SwRewriter.hxx>
62 
63 #include <unomid.h>
64 
65 #define POS_CONTENT 0
66 #define POS_INDEX   1
67 
68 static sal_Int32  nTypePos = 1; // TOX_INDEX as standard
69 static sal_uInt16 nKey1Pos = USHRT_MAX;
70 
71 static sal_uInt16 nKey2Pos = USHRT_MAX;
72 
73 using namespace com::sun::star;
74 using namespace com::sun::star::i18n;
75 using namespace com::sun::star::lang;
76 using namespace com::sun::star::util;
77 using namespace ::comphelper;
78 
79 // dialog to insert a directory selection
SwIndexMarkPane(const std::shared_ptr<weld::Dialog> & rDialog,weld::Builder & rBuilder,bool bNewDlg,SwWrtShell & rWrtShell)80 SwIndexMarkPane::SwIndexMarkPane(const std::shared_ptr<weld::Dialog>& rDialog, weld::Builder& rBuilder, bool bNewDlg,
81     SwWrtShell& rWrtShell)
82     : m_xDialog(rDialog)
83     , m_bDel(false)
84     , m_bNewMark(bNewDlg)
85     , m_bSelected(false)
86     , m_bPhoneticED0_ChangedByUser(false)
87     , m_bPhoneticED1_ChangedByUser(false)
88     , m_bPhoneticED2_ChangedByUser(false)
89     , m_nLangForPhoneticReading(LANGUAGE_CHINESE_SIMPLIFIED)
90     , m_bIsPhoneticReadingEnabled(false)
91     , m_pSh(&rWrtShell)
92     , m_xTypeFT(rBuilder.weld_label("typeft"))
93     , m_xTypeDCB(rBuilder.weld_combo_box("typecb"))
94     , m_xNewBT(rBuilder.weld_button("new"))
95     , m_xEntryED(rBuilder.weld_entry("entryed"))
96     , m_xSyncED(rBuilder.weld_button("sync"))
97     , m_xPhoneticFT0(rBuilder.weld_label("phonetic0ft"))
98     , m_xPhoneticED0(rBuilder.weld_entry("phonetic0ed"))
99     , m_xKey1FT(rBuilder.weld_label("key1ft"))
100     , m_xKey1DCB(rBuilder.weld_combo_box("key1cb"))
101     , m_xPhoneticFT1(rBuilder.weld_label("phonetic1ft"))
102     , m_xPhoneticED1(rBuilder.weld_entry("phonetic1ed"))
103     , m_xKey2FT(rBuilder.weld_label("key2ft"))
104     , m_xKey2DCB(rBuilder.weld_combo_box("key2cb"))
105     , m_xPhoneticFT2(rBuilder.weld_label("phonetic2ft"))
106     , m_xPhoneticED2(rBuilder.weld_entry("phonetic2ed"))
107     , m_xLevelFT(rBuilder.weld_label("levelft"))
108     , m_xLevelNF(rBuilder.weld_spin_button("levelnf"))
109     , m_xMainEntryCB(rBuilder.weld_check_button("mainentrycb"))
110     , m_xApplyToAllCB(rBuilder.weld_check_button("applytoallcb"))
111     , m_xSearchCaseSensitiveCB(rBuilder.weld_check_button("searchcasesensitivecb"))
112     , m_xSearchCaseWordOnlyCB(rBuilder.weld_check_button("searchcasewordonlycb"))
113     , m_xOKBT(bNewDlg ? rBuilder.weld_button("insert") : rBuilder.weld_button("ok"))
114     , m_xCloseBT(rBuilder.weld_button("close"))
115     , m_xDelBT(rBuilder.weld_button("delete"))
116     , m_xPrevSameBT(rBuilder.weld_button("first"))
117     , m_xNextSameBT(rBuilder.weld_button("last"))
118     , m_xPrevBT(rBuilder.weld_button("previous"))
119     , m_xNextBT(rBuilder.weld_button("next"))
120 {
121     m_xSyncED->show();
122 
123     if (SvtCJKOptions().IsCJKFontEnabled())
124     {
125         uno::Reference< uno::XComponentContext > xContext = getProcessComponentContext();
126 
127         m_xExtendedIndexEntrySupplier = i18n::IndexEntrySupplier::create(xContext);
128 
129         m_xPhoneticFT0->show();
130         m_xPhoneticED0->show();
131         m_xPhoneticFT1->show();
132         m_xPhoneticED1->show();
133         m_xPhoneticFT2->show();
134         m_xPhoneticED2->show();
135     }
136 
137     m_xDialog->set_title(SwResId(m_bNewMark ? STR_IDXMRK_INSERT : STR_IDXMRK_EDIT));
138 
139     m_xDelBT->connect_clicked(LINK(this,SwIndexMarkPane,        DelHdl));
140     m_xPrevBT->connect_clicked(LINK(this,SwIndexMarkPane,       PrevHdl));
141     m_xPrevSameBT->connect_clicked(LINK(this,SwIndexMarkPane,   PrevSameHdl));
142     m_xNextBT->connect_clicked(LINK(this,SwIndexMarkPane,       NextHdl));
143     m_xNextSameBT->connect_clicked(LINK(this,SwIndexMarkPane,   NextSameHdl));
144     m_xTypeDCB->connect_changed(LINK(this,SwIndexMarkPane,     ModifyListBoxHdl));
145     m_xKey1DCB->connect_changed(LINK(this,SwIndexMarkPane,      KeyDCBModifyHdl));
146     m_xKey2DCB->connect_changed(LINK(this,SwIndexMarkPane,     KeyDCBModifyHdl));
147     m_xCloseBT->connect_clicked(LINK(this,SwIndexMarkPane,      CloseHdl));
148     m_xEntryED->connect_changed(LINK(this,SwIndexMarkPane,     ModifyEditHdl));
149     m_xNewBT->connect_clicked(LINK(this, SwIndexMarkPane,       NewUserIdxHdl));
150     m_xApplyToAllCB->connect_toggled(LINK(this, SwIndexMarkPane, SearchTypeHdl));
151     m_xPhoneticED0->connect_changed(LINK(this,SwIndexMarkPane, PhoneticEDModifyHdl));
152     m_xPhoneticED1->connect_changed(LINK(this,SwIndexMarkPane, PhoneticEDModifyHdl));
153     m_xPhoneticED2->connect_changed(LINK(this,SwIndexMarkPane, PhoneticEDModifyHdl));
154     m_xSyncED->connect_clicked(LINK(this, SwIndexMarkPane, SyncSelectionHdl));
155 
156     if (m_bNewMark)
157         m_xDelBT->hide();
158     else
159         m_xNewBT->hide();
160     m_xOKBT->show();
161     m_xOKBT->connect_clicked(LINK(this, SwIndexMarkPane, InsertHdl));
162 
163     m_xEntryED->grab_focus();
164 }
165 
166 // Newly initialise controls with the new selection
InitControls()167 void SwIndexMarkPane::InitControls()
168 {
169     assert(m_pSh && m_pTOXMgr && "no shell?");
170     // contents index
171     const SwTOXType* pType = m_pTOXMgr->GetTOXType(TOX_CONTENT);
172     assert(pType && "No directory type !!");
173     OUString sTmpTypeSelection;
174     if (m_xTypeDCB->get_active() != -1)
175         sTmpTypeSelection = m_xTypeDCB->get_active_text();
176     m_xTypeDCB->clear();
177     m_xTypeDCB->append_text(pType->GetTypeName());
178 
179     // keyword index
180     pType = m_pTOXMgr->GetTOXType(TOX_INDEX);
181     assert(pType && "No directory type !!");
182     m_xTypeDCB->append_text(pType->GetTypeName());
183 
184     // user index
185     sal_uInt16 nCount = m_pSh->GetTOXTypeCount(TOX_USER);
186     for (sal_uInt16 i = 0; i < nCount; ++i)
187         m_xTypeDCB->append_text(m_pSh->GetTOXType(TOX_USER, i)->GetTypeName());
188 
189     // read keywords primary
190     {
191         std::vector<OUString> aArr;
192         m_pSh->GetTOIKeys(TOI_PRIMARY, aArr);
193         std::sort(aArr.begin(), aArr.end());
194         auto last = std::unique(aArr.begin(), aArr.end());
195         for (auto it = aArr.begin(); it != last; ++it)
196             m_xKey1DCB->append_text(*it);
197     }
198 
199     // read keywords secondary
200     {
201         std::vector<OUString> aArr;
202         m_pSh->GetTOIKeys( TOI_SECONDARY, aArr );
203         std::sort(aArr.begin(), aArr.end());
204         auto last = std::unique(aArr.begin(), aArr.end());
205         for (auto it = aArr.begin(); it != last; ++it)
206             m_xKey2DCB->append_text(*it);
207     }
208 
209     UpdateLanguageDependenciesForPhoneticReading();
210 
211     // current entry
212     const SwTOXMark* pMark = m_pTOXMgr->GetCurTOXMark();
213     if( pMark && !m_bNewMark)
214     {
215         // Controls-Handling
216 
217         // only if there are more than one
218         // if equal it lands at the same entry
219         m_pSh->SttCursorMove();
220 
221         const SwTOXMark* pMoveMark;
222         bool bShow = false;
223 
224         pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_PRV );
225         if( pMoveMark != pMark )
226         {
227             m_pSh->GotoTOXMark( *pMoveMark, TOX_NXT );
228             bShow = true;
229         }
230         m_xPrevBT->set_sensitive(pMoveMark != pMark);
231         pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_NXT );
232         if( pMoveMark != pMark )
233         {
234             m_pSh->GotoTOXMark( *pMoveMark, TOX_PRV );
235             bShow = true;
236         }
237         m_xNextBT->set_sensitive(pMoveMark != pMark);
238         if( bShow )
239         {
240             m_xPrevBT->show();
241             m_xNextBT->show();
242             bShow = false;
243         }
244 
245         pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_PRV );
246         if( pMoveMark != pMark )
247         {
248             m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_NXT );
249             bShow = true;
250         }
251         m_xPrevSameBT->set_sensitive(pMoveMark != pMark);
252         pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_NXT );
253         if( pMoveMark != pMark )
254         {
255             m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_PRV );
256             bShow = true;
257         }
258         m_xNextSameBT->set_sensitive(pMoveMark != pMark);
259         if( bShow )
260         {
261             m_xNextSameBT->show();
262             m_xPrevSameBT->show();
263         }
264         m_pSh->EndCursorMove();
265 
266         m_xTypeFT->show();
267 
268         m_xTypeDCB->set_sensitive(false);
269         m_xTypeFT->set_sensitive(false);
270 
271         UpdateDialog();
272     }
273     else
274     {   // display current selection (first element) ????
275         if (m_pSh->GetCursorCnt() < 2)
276         {
277             m_bSelected = !m_pSh->HasSelection();
278             m_aOrgStr = m_pSh->GetView().GetSelectionTextParam(true, false);
279             m_xEntryED->set_text(m_aOrgStr);
280 
281             //to include all equal entries may only be allowed in the body and even there
282             //only when a simple selection exists
283             const FrameTypeFlags nFrameType = m_pSh->GetFrameType(nullptr,true);
284             m_xApplyToAllCB->show();
285             m_xSearchCaseSensitiveCB->show();
286             m_xSearchCaseWordOnlyCB->show();
287             m_xApplyToAllCB->set_sensitive(!m_aOrgStr.isEmpty() &&
288                 !(nFrameType & ( FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FLY_ANY )));
289             SearchTypeHdl(*m_xApplyToAllCB);
290         }
291 
292         // index type is default
293         if (!sTmpTypeSelection.isEmpty() && m_xTypeDCB->find_text(sTmpTypeSelection) != -1)
294             m_xTypeDCB->set_active_text(sTmpTypeSelection);
295         else
296             m_xTypeDCB->set_active_text(m_xTypeDCB->get_text(nTypePos));
297         ModifyHdl(*m_xTypeDCB);
298     }
299 }
300 
UpdateLanguageDependenciesForPhoneticReading()301 void    SwIndexMarkPane::UpdateLanguageDependenciesForPhoneticReading()
302 {
303     //no phonetic reading if no global cjk support
304     if( !m_xExtendedIndexEntrySupplier.is() )
305     {
306         m_bIsPhoneticReadingEnabled = false;
307         return;
308     }
309     m_bIsPhoneticReadingEnabled = true;
310 
311     //get the current language
312     if(!m_bNewMark) //if dialog is opened to iterate existing marks
313     {
314         OSL_ENSURE(m_pTOXMgr, "need TOXMgr");
315         if(!m_pTOXMgr)
316             return;
317         SwTOXMark* pMark = m_pTOXMgr->GetCurTOXMark();
318         OSL_ENSURE(pMark, "need current SwTOXMark");
319         if(!pMark)
320             return;
321         SwTextTOXMark* pTextTOXMark = pMark->GetTextTOXMark();
322         OSL_ENSURE(pTextTOXMark, "need current SwTextTOXMark");
323         if(!pTextTOXMark)
324             return;
325         const SwTextNode* pTextNode = pTextTOXMark->GetpTextNd();
326         OSL_ENSURE(pTextNode, "need current SwTextNode");
327         if(!pTextNode)
328             return;
329         sal_Int32 nTextIndex = pTextTOXMark->GetStart();
330         m_nLangForPhoneticReading = pTextNode->GetLang( nTextIndex );
331     }
332     else //if dialog is opened to create a new mark
333     {
334         sal_uInt16 nWhich;
335         switch(m_pSh->GetScriptType())
336         {
337             case SvtScriptType::ASIAN: nWhich = RES_CHRATR_CJK_LANGUAGE; break;
338             case SvtScriptType::COMPLEX:nWhich = RES_CHRATR_CTL_LANGUAGE; break;
339             default:nWhich = RES_CHRATR_LANGUAGE; break;
340         }
341         SfxItemSet aLangSet(m_pSh->GetAttrPool(), {{nWhich, nWhich}});
342         m_pSh->GetCurAttr(aLangSet);
343         m_nLangForPhoneticReading = static_cast<const SvxLanguageItem&>(aLangSet.Get(nWhich)).GetLanguage();
344     }
345 
346 }
347 
GetDefaultPhoneticReading(const OUString & rText)348 OUString SwIndexMarkPane::GetDefaultPhoneticReading( const OUString& rText )
349 {
350     if( !m_bIsPhoneticReadingEnabled )
351         return OUString();
352 
353     return m_xExtendedIndexEntrySupplier->getPhoneticCandidate(rText, LanguageTag::convertToLocale( m_nLangForPhoneticReading ));
354 }
355 
Activate()356 void    SwIndexMarkPane::Activate()
357 {
358     // display current selection (first element) ????
359     if (m_bNewMark)
360     {
361         m_xSyncED->set_sensitive(m_pSh->GetCursorCnt() < 2);
362     }
363 }
364 
IMPL_LINK_NOARG(SwIndexMarkPane,SyncSelectionHdl,weld::Button &,void)365 IMPL_LINK_NOARG(SwIndexMarkPane, SyncSelectionHdl, weld::Button&, void)
366 {
367     m_bSelected = !m_pSh->HasSelection();
368     m_aOrgStr = m_pSh->GetView().GetSelectionTextParam(true, false);
369     m_xEntryED->set_text(m_aOrgStr);
370 
371     //to include all equal entries may only be allowed in the body and even there
372     //only when a simple selection exists
373     const FrameTypeFlags nFrameType = m_pSh->GetFrameType(nullptr,true);
374     m_xApplyToAllCB->show();
375     m_xSearchCaseSensitiveCB->show();
376     m_xSearchCaseWordOnlyCB->show();
377     m_xApplyToAllCB->set_sensitive(!m_aOrgStr.isEmpty() &&
378         !(nFrameType & ( FrameTypeFlags::HEADER | FrameTypeFlags::FOOTER | FrameTypeFlags::FLY_ANY )));
379     SearchTypeHdl(*m_xApplyToAllCB);
380     ModifyHdl(*m_xEntryED);
381 }
382 
383 // evaluate Ok-Button
Apply()384 void SwIndexMarkPane::Apply()
385 {
386     InsertUpdate();
387     if(m_bSelected)
388         m_pSh->ResetSelect(nullptr, false);
389 }
390 
391 // apply changes
InsertUpdate()392 void SwIndexMarkPane::InsertUpdate()
393 {
394     m_pSh->StartUndo(m_bDel ? SwUndoId::INDEX_ENTRY_DELETE : SwUndoId::INDEX_ENTRY_INSERT);
395     m_pSh->StartAllAction();
396     SwRewriter aRewriter;
397 
398     if( m_bNewMark )
399     {
400         InsertMark();
401 
402         if ( m_pTOXMgr->GetCurTOXMark())
403             aRewriter.AddRule(UndoArg1,
404                     m_pTOXMgr->GetCurTOXMark()->GetText(m_pSh->GetLayout()));
405     }
406     else if( !m_pSh->HasReadonlySel() )
407     {
408         if ( m_pTOXMgr->GetCurTOXMark())
409             aRewriter.AddRule(UndoArg1,
410                     m_pTOXMgr->GetCurTOXMark()->GetText(m_pSh->GetLayout()));
411 
412         if( m_bDel )
413             m_pTOXMgr->DeleteTOXMark();
414         else if( m_pTOXMgr->GetCurTOXMark() )
415             UpdateMark();
416     }
417 
418     m_pSh->EndAllAction();
419     m_pSh->EndUndo(m_bDel ? SwUndoId::INDEX_ENTRY_DELETE : SwUndoId::INDEX_ENTRY_INSERT);
420 
421     if((nTypePos = m_xTypeDCB->find_text(m_xTypeDCB->get_active_text())) == -1)
422         nTypePos = 0;
423 
424     nKey1Pos = m_xKey1DCB->find_text(m_xKey1DCB->get_active_text());
425     nKey2Pos = m_xKey2DCB->find_text(m_xKey2DCB->get_active_text());
426 }
427 
428 // insert mark
lcl_SelectSameStrings(SwWrtShell & rSh,bool bWordOnly,bool bCaseSensitive)429 static void lcl_SelectSameStrings(SwWrtShell& rSh, bool bWordOnly, bool bCaseSensitive)
430 {
431     rSh.Push();
432 
433     i18nutil::SearchOptions2 aSearchOpt(
434                         SearchAlgorithms_ABSOLUTE,
435                         ( bWordOnly ? SearchFlags::NORM_WORD_ONLY : 0 ),
436                         rSh.GetSelText(), OUString(),
437                         GetAppLanguageTag().getLocale(),
438                         0, 0, 0,
439                         (bCaseSensitive
440                             ? TransliterationFlags::NONE
441                             : TransliterationFlags::IGNORE_CASE),
442                         SearchAlgorithms2::ABSOLUTE,
443                         '\\' );
444 
445     rSh.ClearMark();
446     bool bCancel;
447 
448     //todo/mba: assuming that notes should not be searched
449     rSh.Find_Text(aSearchOpt, false/*bSearchInNotes*/, SwDocPositions::Start, SwDocPositions::End, bCancel,
450               FindRanges::InSelAll | FindRanges::InBodyOnly );
451 }
452 
InsertMark()453 void SwIndexMarkPane::InsertMark()
454 {
455     auto nPos = m_xTypeDCB->find_text(m_xTypeDCB->get_active_text());
456     TOXTypes eType = nPos == POS_CONTENT ? TOX_CONTENT :
457                         nPos == POS_INDEX ? TOX_INDEX : TOX_USER;
458 
459     SwTOXMarkDescription aDesc(eType);
460 
461     const int nLevel = m_xLevelNF->denormalize(m_xLevelNF->get_value());
462     switch( nPos)
463     {
464         case POS_CONTENT : break;
465         case POS_INDEX:     // keyword index mark
466         {
467             UpdateKeyBoxes();
468             aDesc.SetPrimKey(m_xKey1DCB->get_active_text());
469             aDesc.SetSecKey(m_xKey2DCB->get_active_text());
470             aDesc.SetMainEntry(m_xMainEntryCB->get_active());
471             aDesc.SetPhoneticReadingOfAltStr(m_xPhoneticED0->get_text());
472             aDesc.SetPhoneticReadingOfPrimKey(m_xPhoneticED1->get_text());
473             aDesc.SetPhoneticReadingOfSecKey(m_xPhoneticED2->get_text());
474         }
475         break;
476         default:            // Userdefined index mark
477         {
478             aDesc.SetTOUName(m_xTypeDCB->get_active_text());
479         }
480     }
481     if (m_aOrgStr != m_xEntryED->get_text())
482         aDesc.SetAltStr(m_xEntryED->get_text());
483     bool bApplyAll = m_xApplyToAllCB->get_active();
484     bool bWordOnly = m_xSearchCaseWordOnlyCB->get_active();
485     bool bCaseSensitive = m_xSearchCaseSensitiveCB->get_active();
486 
487     m_pSh->StartAllAction();
488     // all equal strings have to be selected here so that the
489     // entry is applied to all equal strings
490     if(bApplyAll)
491     {
492         lcl_SelectSameStrings(*m_pSh, bWordOnly, bCaseSensitive);
493     }
494     aDesc.SetLevel(nLevel);
495     SwTOXMgr aMgr(m_pSh);
496     aMgr.InsertTOXMark(aDesc);
497     if(bApplyAll)
498         m_pSh->Pop(SwCursorShell::PopMode::DeleteCurrent);
499 
500     m_pSh->EndAllAction();
501 }
502 
503 // update mark
UpdateMark()504 void SwIndexMarkPane::UpdateMark()
505 {
506     OUString  aAltText(m_xEntryED->get_text());
507     OUString* pAltText = m_aOrgStr != m_xEntryED->get_text() ? &aAltText : nullptr;
508     //empty alternative texts are not allowed
509     if(pAltText && pAltText->isEmpty())
510         return;
511 
512     UpdateKeyBoxes();
513 
514     auto nPos = m_xTypeDCB->find_text(m_xTypeDCB->get_active_text());
515     TOXTypes eType = TOX_USER;
516     if(POS_CONTENT == nPos)
517         eType = TOX_CONTENT;
518     else if(POS_INDEX == nPos)
519         eType = TOX_INDEX;
520 
521     SwTOXMarkDescription aDesc(eType);
522     aDesc.SetLevel(m_xLevelNF->get_value());
523     if(pAltText)
524         aDesc.SetAltStr(*pAltText);
525 
526     OUString  aPrim(m_xKey1DCB->get_active_text());
527     if(!aPrim.isEmpty())
528         aDesc.SetPrimKey(aPrim);
529     OUString  aSec(m_xKey2DCB->get_active_text());
530     if(!aSec.isEmpty())
531         aDesc.SetSecKey(aSec);
532 
533     if(eType == TOX_INDEX)
534     {
535         aDesc.SetPhoneticReadingOfAltStr(m_xPhoneticED0->get_text());
536         aDesc.SetPhoneticReadingOfPrimKey(m_xPhoneticED1->get_text());
537         aDesc.SetPhoneticReadingOfSecKey(m_xPhoneticED2->get_text());
538     }
539     aDesc.SetMainEntry(m_xMainEntryCB->get_visible() && m_xMainEntryCB->get_active());
540     m_pTOXMgr->UpdateTOXMark(aDesc);
541 }
542 
543 // insert new keys
UpdateKeyBoxes()544 void SwIndexMarkPane::UpdateKeyBoxes()
545 {
546     OUString aKey(m_xKey1DCB->get_active_text());
547     auto nPos = m_xKey1DCB->find_text(aKey);
548     if(nPos == -1 && !aKey.isEmpty())
549     {   // create new key
550         m_xKey1DCB->append_text(aKey);
551     }
552 
553     aKey = m_xKey2DCB->get_active_text();
554     nPos = m_xKey2DCB->find_text(aKey);
555 
556     if(nPos == -1 && !aKey.isEmpty())
557     {   // create new key
558         m_xKey2DCB->append_text(aKey);
559     }
560 }
561 
562 class SwNewUserIdxDlg : public weld::GenericDialogController
563 {
564     SwIndexMarkPane* m_pDlg;
565 
566     std::unique_ptr<weld::Button> m_xOKPB;
567     std::unique_ptr<weld::Entry> m_xNameED;
568 
569     DECL_LINK(ModifyHdl, weld::Entry&, void);
570 
571 public:
SwNewUserIdxDlg(SwIndexMarkPane * pPane,weld::Window * pParent)572     explicit SwNewUserIdxDlg(SwIndexMarkPane* pPane, weld::Window* pParent)
573         : GenericDialogController(pParent, "modules/swriter/ui/newuserindexdialog.ui", "NewUserIndexDialog")
574         , m_pDlg(pPane)
575         , m_xOKPB(m_xBuilder->weld_button("ok"))
576         , m_xNameED(m_xBuilder->weld_entry("entry"))
577     {
578         m_xNameED->connect_changed(LINK(this, SwNewUserIdxDlg, ModifyHdl));
579         m_xOKPB->set_sensitive(false);
580         m_xNameED->grab_focus();
581     }
GetName() const582     OUString GetName() const { return m_xNameED->get_text(); }
583 };
584 
IMPL_LINK(SwNewUserIdxDlg,ModifyHdl,weld::Entry &,rEdit,void)585 IMPL_LINK( SwNewUserIdxDlg, ModifyHdl, weld::Entry&, rEdit, void)
586 {
587     m_xOKPB->set_sensitive(!rEdit.get_text().isEmpty() && !m_pDlg->IsTOXType(rEdit.get_text()));
588 }
589 
IMPL_LINK_NOARG(SwIndexMarkPane,NewUserIdxHdl,weld::Button &,void)590 IMPL_LINK_NOARG(SwIndexMarkPane, NewUserIdxHdl, weld::Button&, void)
591 {
592     SwNewUserIdxDlg aDlg(this, m_xDialog.get());
593     if (aDlg.run() == RET_OK)
594     {
595         OUString sNewName(aDlg.GetName());
596         m_xTypeDCB->append_text(sNewName);
597         m_xTypeDCB->set_active_text(sNewName);
598     }
599 }
600 
IMPL_LINK(SwIndexMarkPane,SearchTypeHdl,weld::ToggleButton &,rBox,void)601 IMPL_LINK( SwIndexMarkPane, SearchTypeHdl, weld::ToggleButton&, rBox, void)
602 {
603     const bool bEnable = rBox.get_active() && rBox.get_sensitive();
604     m_xSearchCaseWordOnlyCB->set_sensitive(bEnable);
605     m_xSearchCaseSensitiveCB->set_sensitive(bEnable);
606 }
607 
IMPL_LINK(SwIndexMarkPane,InsertHdl,weld::Button &,rButton,void)608 IMPL_LINK(SwIndexMarkPane, InsertHdl, weld::Button&, rButton, void)
609 {
610     Apply();
611     //close the dialog if only one entry is available
612     if(!m_bNewMark && !m_xPrevBT->get_visible() && !m_xNextBT->get_visible())
613         CloseHdl(rButton);
614 }
615 
IMPL_LINK_NOARG(SwIndexMarkPane,CloseHdl,weld::Button &,void)616 IMPL_LINK_NOARG(SwIndexMarkPane, CloseHdl, weld::Button&, void)
617 {
618     if (m_bNewMark)
619     {
620         SfxViewFrame::Current()->GetDispatcher()->Execute(FN_INSERT_IDX_ENTRY_DLG,
621                     SfxCallMode::ASYNCHRON|SfxCallMode::RECORD);
622     }
623     else
624     {
625         m_xDialog->response(RET_CLOSE);
626     }
627 }
628 
629 // select index type only when inserting
IMPL_LINK(SwIndexMarkPane,ModifyListBoxHdl,weld::ComboBox &,rBox,void)630 IMPL_LINK(SwIndexMarkPane, ModifyListBoxHdl, weld::ComboBox&, rBox, void)
631 {
632     ModifyHdl(rBox);
633 }
634 
IMPL_LINK(SwIndexMarkPane,ModifyEditHdl,weld::Entry &,rEdit,void)635 IMPL_LINK(SwIndexMarkPane, ModifyEditHdl, weld::Entry&, rEdit, void)
636 {
637     ModifyHdl(rEdit);
638 }
639 
ModifyHdl(const weld::Widget & rBox)640 void SwIndexMarkPane::ModifyHdl(const weld::Widget& rBox)
641 {
642     if (m_xTypeDCB.get() == &rBox)
643     {
644         // set index type
645         auto nPos = m_xTypeDCB->find_text(m_xTypeDCB->get_active_text());
646         bool bLevelEnable = false,
647              bKeyEnable   = false,
648              bSetKey2     = false,
649              bKey2Enable  = false,
650              bEntryHasText   = false,
651              bKey1HasText    = false,
652              bKey2HasText    = false;
653         if(nPos == POS_INDEX)
654         {
655             if (!m_xEntryED->get_text().isEmpty())
656                 bEntryHasText = true;
657             m_xPhoneticED0->set_text(GetDefaultPhoneticReading(m_xEntryED->get_text()));
658 
659             bKeyEnable = true;
660             m_xKey1DCB->set_active_text(m_xKey1DCB->get_text(nKey1Pos));
661             m_xPhoneticED1->set_text(GetDefaultPhoneticReading(m_xKey1DCB->get_active_text()));
662             if (!m_xKey1DCB->get_active_text().isEmpty())
663             {
664                 bKey1HasText = bSetKey2 = bKey2Enable = true;
665                 m_xKey2DCB->set_active_text(m_xKey2DCB->get_text(nKey2Pos));
666                 m_xPhoneticED2->set_text(GetDefaultPhoneticReading(m_xKey2DCB->get_active_text()));
667                 if(!m_xKey2DCB->get_active_text().isEmpty())
668                     bKey2HasText = true;
669             }
670         }
671         else
672         {
673             bLevelEnable = true;
674             m_xLevelNF->set_max(MAXLEVEL);
675             m_xLevelNF->set_value(m_xLevelNF->normalize(0));
676             bSetKey2 = true;
677         }
678         m_xLevelFT->set_visible(bLevelEnable);
679         m_xLevelNF->set_visible(bLevelEnable);
680         m_xMainEntryCB->set_visible(nPos == POS_INDEX);
681 
682         m_xKey1FT->set_sensitive(bKeyEnable);
683         m_xKey1DCB->set_sensitive(bKeyEnable);
684         if ( bSetKey2 )
685         {
686             m_xKey2DCB->set_sensitive(bKey2Enable);
687             m_xKey2FT->set_sensitive(bKey2Enable);
688         }
689         m_xPhoneticFT0->set_sensitive(bKeyEnable&&bEntryHasText&&m_bIsPhoneticReadingEnabled);
690         m_xPhoneticED0->set_sensitive(bKeyEnable&&bEntryHasText&&m_bIsPhoneticReadingEnabled);
691         m_xPhoneticFT1->set_sensitive(bKeyEnable&&bKey1HasText&&m_bIsPhoneticReadingEnabled);
692         m_xPhoneticED1->set_sensitive(bKeyEnable&&bKey1HasText&&m_bIsPhoneticReadingEnabled);
693         m_xPhoneticFT2->set_sensitive(bKeyEnable&&bKey2HasText&&m_bIsPhoneticReadingEnabled);
694         m_xPhoneticED2->set_sensitive(bKeyEnable&&bKey2HasText&&m_bIsPhoneticReadingEnabled);
695     }
696     else //m_xEntryED  !!m_xEntryED is not a ListBox but an Edit
697     {
698         bool bHasText = !m_xEntryED->get_text().isEmpty();
699         if(!bHasText)
700         {
701             m_xPhoneticED0->set_text(OUString());
702             m_bPhoneticED0_ChangedByUser = false;
703         }
704         else if(!m_bPhoneticED0_ChangedByUser)
705             m_xPhoneticED0->set_text(GetDefaultPhoneticReading(m_xEntryED->get_text()));
706 
707         m_xPhoneticFT0->set_sensitive(bHasText&&m_bIsPhoneticReadingEnabled);
708         m_xPhoneticED0->set_sensitive(bHasText&&m_bIsPhoneticReadingEnabled);
709     }
710     m_xOKBT->set_sensitive(!m_pSh->HasReadonlySel() &&
711         (!m_xEntryED->get_text().isEmpty() || m_pSh->GetCursorCnt(false)));
712 }
713 
IMPL_LINK_NOARG(SwIndexMarkPane,NextHdl,weld::Button &,void)714 IMPL_LINK_NOARG(SwIndexMarkPane, NextHdl, weld::Button&, void)
715 {
716     InsertUpdate();
717     m_pTOXMgr->NextTOXMark();
718     UpdateDialog();
719 }
720 
IMPL_LINK_NOARG(SwIndexMarkPane,NextSameHdl,weld::Button &,void)721 IMPL_LINK_NOARG(SwIndexMarkPane, NextSameHdl, weld::Button&, void)
722 {
723     InsertUpdate();
724     m_pTOXMgr->NextTOXMark(true);
725     UpdateDialog();
726 }
727 
IMPL_LINK_NOARG(SwIndexMarkPane,PrevHdl,weld::Button &,void)728 IMPL_LINK_NOARG(SwIndexMarkPane, PrevHdl, weld::Button&, void)
729 {
730     InsertUpdate();
731     m_pTOXMgr->PrevTOXMark();
732     UpdateDialog();
733 }
734 
IMPL_LINK_NOARG(SwIndexMarkPane,PrevSameHdl,weld::Button &,void)735 IMPL_LINK_NOARG(SwIndexMarkPane, PrevSameHdl, weld::Button&, void)
736 {
737     InsertUpdate();
738     m_pTOXMgr->PrevTOXMark(true);
739     UpdateDialog();
740 }
741 
IMPL_LINK_NOARG(SwIndexMarkPane,DelHdl,weld::Button &,void)742 IMPL_LINK_NOARG(SwIndexMarkPane, DelHdl, weld::Button&, void)
743 {
744     m_bDel = true;
745     InsertUpdate();
746     m_bDel = false;
747 
748     if(m_pTOXMgr->GetCurTOXMark())
749         UpdateDialog();
750     else
751     {
752         CloseHdl(*m_xCloseBT);
753         SfxViewFrame::Current()->GetBindings().Invalidate(FN_EDIT_IDX_ENTRY_DLG);
754     }
755 }
756 
757 // renew dialog view
UpdateDialog()758 void SwIndexMarkPane::UpdateDialog()
759 {
760     OSL_ENSURE(m_pSh && m_pTOXMgr, "no shell?");
761     SwTOXMark* pMark = m_pTOXMgr->GetCurTOXMark();
762     OSL_ENSURE(pMark, "no current marker");
763     if(!pMark)
764         return;
765 
766     SwViewShell::SetCareDialog(m_xDialog);
767 
768     m_aOrgStr = pMark->GetText(m_pSh->GetLayout());
769     m_xEntryED->set_text(m_aOrgStr);
770 
771     // set index type
772     bool bLevelEnable = true,
773          bKeyEnable   = false,
774          bKey2Enable  = false,
775          bEntryHasText  = false,
776          bKey1HasText   = false,
777          bKey2HasText   = false;
778 
779     TOXTypes eCurType = pMark->GetTOXType()->GetType();
780     if(TOX_INDEX == eCurType)
781     {
782         bLevelEnable = false;
783         bKeyEnable = true;
784         bKey1HasText = bKey2Enable = !pMark->GetPrimaryKey().isEmpty();
785         bKey2HasText = !pMark->GetSecondaryKey().isEmpty();
786         bEntryHasText = !pMark->GetText(m_pSh->GetLayout()).isEmpty();
787         m_xKey1DCB->set_entry_text( pMark->GetPrimaryKey() );
788         m_xKey2DCB->set_entry_text( pMark->GetSecondaryKey() );
789         m_xPhoneticED0->set_text( pMark->GetTextReading() );
790         m_xPhoneticED1->set_text( pMark->GetPrimaryKeyReading() );
791         m_xPhoneticED2->set_text( pMark->GetSecondaryKeyReading() );
792         m_xMainEntryCB->set_active(pMark->IsMainEntry());
793     }
794     else if(TOX_CONTENT == eCurType || TOX_USER == eCurType)
795     {
796         m_xLevelNF->set_value(m_xLevelNF->normalize(pMark->GetLevel()));
797     }
798     m_xKey1FT->set_sensitive(bKeyEnable);
799     m_xKey1DCB->set_sensitive(bKeyEnable);
800     m_xLevelNF->set_max(MAXLEVEL);
801     m_xLevelFT->set_visible(bLevelEnable);
802     m_xLevelNF->set_visible(bLevelEnable);
803     m_xMainEntryCB->set_visible(!bLevelEnable);
804     m_xKey2FT->set_sensitive(bKey2Enable);
805     m_xKey2DCB->set_sensitive(bKey2Enable);
806 
807     UpdateLanguageDependenciesForPhoneticReading();
808     m_xPhoneticFT0->set_sensitive(bKeyEnable&&bEntryHasText&&m_bIsPhoneticReadingEnabled);
809     m_xPhoneticED0->set_sensitive(bKeyEnable&&bEntryHasText&&m_bIsPhoneticReadingEnabled);
810     m_xPhoneticFT1->set_sensitive(bKeyEnable&&bKey1HasText&&m_bIsPhoneticReadingEnabled);
811     m_xPhoneticED1->set_sensitive(bKeyEnable&&bKey1HasText&&m_bIsPhoneticReadingEnabled);
812     m_xPhoneticFT2->set_sensitive(bKeyEnable&&bKey2HasText&&m_bIsPhoneticReadingEnabled);
813     m_xPhoneticED2->set_sensitive(bKeyEnable&&bKey2HasText&&m_bIsPhoneticReadingEnabled);
814 
815     // set index type
816     m_xTypeDCB->set_active_text(pMark->GetTOXType()->GetTypeName());
817 
818     // set Next - Prev - Buttons
819     m_pSh->SttCursorMove();
820     if( m_xPrevBT->get_visible() )
821     {
822         const SwTOXMark* pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_PRV );
823         if( pMoveMark != pMark )
824             m_pSh->GotoTOXMark( *pMoveMark, TOX_NXT );
825         m_xPrevBT->set_sensitive( pMoveMark != pMark );
826         pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_NXT );
827         if( pMoveMark != pMark )
828             m_pSh->GotoTOXMark( *pMoveMark, TOX_PRV );
829         m_xNextBT->set_sensitive( pMoveMark != pMark );
830     }
831 
832     if (m_xPrevSameBT->get_visible())
833     {
834         const SwTOXMark* pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_PRV );
835         if( pMoveMark != pMark )
836             m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_NXT );
837         m_xPrevSameBT->set_sensitive( pMoveMark != pMark );
838         pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_NXT );
839         if( pMoveMark != pMark )
840             m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_PRV );
841         m_xNextSameBT->set_sensitive( pMoveMark != pMark );
842     }
843 
844     const bool bEnable = !m_pSh->HasReadonlySel();
845     m_xOKBT->set_sensitive(bEnable);
846     m_xDelBT->set_sensitive(bEnable);
847     m_xEntryED->set_sensitive(bEnable);
848     m_xLevelNF->set_sensitive(bEnable);
849     m_xKey1DCB->set_sensitive(bEnable);
850     m_xKey2DCB->set_sensitive(bEnable);
851 
852     m_pSh->SelectTextAttr( RES_TXTATR_TOXMARK, pMark->GetTextTOXMark() );
853     // we need the point at the start of the attribute
854     m_pSh->SwapPam();
855 
856     m_pSh->EndCursorMove();
857 }
858 
859 // Remind whether the edit boxes for Phonetic reading are changed manually
IMPL_LINK(SwIndexMarkPane,PhoneticEDModifyHdl,weld::Entry &,rEdit,void)860 IMPL_LINK(SwIndexMarkPane, PhoneticEDModifyHdl, weld::Entry&, rEdit, void)
861 {
862     if (m_xPhoneticED0.get() == &rEdit)
863     {
864         m_bPhoneticED0_ChangedByUser = !rEdit.get_text().isEmpty();
865     }
866     else if (m_xPhoneticED1.get() == &rEdit)
867     {
868         m_bPhoneticED1_ChangedByUser = !rEdit.get_text().isEmpty();
869     }
870     else if (m_xPhoneticED2.get() == &rEdit)
871     {
872         m_bPhoneticED2_ChangedByUser = !rEdit.get_text().isEmpty();
873     }
874 }
875 
876 // Enable Disable of the 2nd key
IMPL_LINK(SwIndexMarkPane,KeyDCBModifyHdl,weld::ComboBox &,rBox,void)877 IMPL_LINK( SwIndexMarkPane, KeyDCBModifyHdl, weld::ComboBox&, rBox, void )
878 {
879     if (m_xKey1DCB.get() == &rBox)
880     {
881         bool bEnable = !rBox.get_active_text().isEmpty();
882         if(!bEnable)
883         {
884             m_xKey2DCB->set_entry_text(OUString());
885             m_xPhoneticED1->set_text(OUString());
886             m_xPhoneticED2->set_text(OUString());
887             m_bPhoneticED1_ChangedByUser = false;
888             m_bPhoneticED2_ChangedByUser = false;
889         }
890         else
891         {
892             if (rBox.get_popup_shown())
893             {
894                 //reset bPhoneticED1_ChangedByUser if a completely new string is selected
895                 m_bPhoneticED1_ChangedByUser = false;
896             }
897             if (!m_bPhoneticED1_ChangedByUser)
898                 m_xPhoneticED1->set_text(GetDefaultPhoneticReading(rBox.get_active_text()));
899         }
900         m_xKey2DCB->set_sensitive(bEnable);
901         m_xKey2FT->set_sensitive(bEnable);
902     }
903     else if (m_xKey2DCB.get() == &rBox)
904     {
905         if (rBox.get_active_text().isEmpty())
906         {
907             m_xPhoneticED2->set_text(OUString());
908             m_bPhoneticED2_ChangedByUser = false;
909         }
910         else
911         {
912             if (rBox.get_popup_shown())
913             {
914                 //reset bPhoneticED1_ChangedByUser if a completely new string is selected
915                 m_bPhoneticED2_ChangedByUser = false;
916             }
917             if(!m_bPhoneticED2_ChangedByUser)
918                 m_xPhoneticED2->set_text(GetDefaultPhoneticReading(rBox.get_active_text()));
919         }
920     }
921 
922     bool bKey1HasText = !m_xKey1DCB->get_active_text().isEmpty();
923     bool bKey2HasText = !m_xKey2DCB->get_active_text().isEmpty();
924 
925     m_xPhoneticFT1->set_sensitive(bKey1HasText && m_bIsPhoneticReadingEnabled);
926     m_xPhoneticED1->set_sensitive(bKey1HasText && m_bIsPhoneticReadingEnabled);
927     m_xPhoneticFT2->set_sensitive(bKey2HasText && m_bIsPhoneticReadingEnabled);
928     m_xPhoneticED2->set_sensitive(bKey2HasText && m_bIsPhoneticReadingEnabled);
929 }
930 
~SwIndexMarkPane()931 SwIndexMarkPane::~SwIndexMarkPane()
932 {
933 }
934 
ReInitDlg(SwWrtShell & rWrtShell,SwTOXMark const * pCurTOXMark)935 void    SwIndexMarkPane::ReInitDlg(SwWrtShell& rWrtShell, SwTOXMark const * pCurTOXMark)
936 {
937     m_pSh = &rWrtShell;
938     m_pTOXMgr.reset( new SwTOXMgr(m_pSh) );
939     if(pCurTOXMark)
940     {
941         for(sal_uInt16 i = 0; i < m_pTOXMgr->GetTOXMarkCount(); i++)
942             if(m_pTOXMgr->GetTOXMark(i) == pCurTOXMark)
943             {
944                 m_pTOXMgr->SetCurTOXMark(i);
945                 break;
946             }
947     }
948     InitControls();
949 }
950 
SwIndexMarkFloatDlg(SfxBindings * _pBindings,SfxChildWindow * pChild,weld::Window * pParent,SfxChildWinInfo const * pInfo,bool bNew)951 SwIndexMarkFloatDlg::SwIndexMarkFloatDlg(SfxBindings* _pBindings,
952     SfxChildWindow* pChild, weld::Window *pParent,
953     SfxChildWinInfo const * pInfo, bool bNew)
954     : SfxModelessDialogController(_pBindings, pChild, pParent,
955         "modules/swriter/ui/indexentry.ui", "IndexEntryDialog")
956     , m_aContent(m_xDialog, *m_xBuilder, bNew, *::GetActiveWrtShell())
957 {
958     m_aContent.ReInitDlg(*::GetActiveWrtShell());
959     Initialize(pInfo);
960 }
961 
Activate()962 void SwIndexMarkFloatDlg::Activate()
963 {
964     SfxModelessDialogController::Activate();
965     m_aContent.Activate();
966 }
967 
ReInitDlg(SwWrtShell & rWrtShell)968 void SwIndexMarkFloatDlg::ReInitDlg(SwWrtShell& rWrtShell)
969 {
970     m_aContent.ReInitDlg( rWrtShell );
971 }
972 
SwIndexMarkModalDlg(weld::Window * pParent,SwWrtShell & rSh,SwTOXMark const * pCurTOXMark)973 SwIndexMarkModalDlg::SwIndexMarkModalDlg(weld::Window *pParent, SwWrtShell& rSh, SwTOXMark const * pCurTOXMark)
974     : SfxDialogController(pParent, "modules/swriter/ui/indexentry.ui",
975                           "IndexEntryDialog")
976     , m_aContent(m_xDialog, *m_xBuilder, false, rSh)
977 {
978     m_aContent.ReInitDlg(rSh, pCurTOXMark);
979 }
980 
~SwIndexMarkModalDlg()981 SwIndexMarkModalDlg::~SwIndexMarkModalDlg()
982 {
983     SwViewShell::SetCareDialog(nullptr);
984 }
985 
run()986 short SwIndexMarkModalDlg::run()
987 {
988     short nRet = SfxDialogController::run();
989     if (RET_OK == nRet)
990         m_aContent.Apply();
991     return nRet;
992 }
993 
994 class SwCreateAuthEntryDlg_Impl : public weld::GenericDialogController
995 {
996     std::vector<std::unique_ptr<weld::Builder>> m_aBuilders;
997 
998     Link<weld::Entry&,bool>       aShortNameCheckLink;
999 
1000     SwWrtShell&     rWrtSh;
1001 
1002     bool            m_bNewEntryMode;
1003     bool            m_bNameAllowed;
1004 
1005     std::vector<std::unique_ptr<weld::Container>> m_aOrigContainers;
1006     std::vector<std::unique_ptr<weld::Label>> m_aFixedTexts;
1007     std::unique_ptr<weld::Entry> pEdits[AUTH_FIELD_END];
1008     std::unique_ptr<weld::Button> m_xOKBT;
1009     std::unique_ptr<weld::Container> m_xBox;
1010     std::unique_ptr<weld::Container> m_xLeft;
1011     std::unique_ptr<weld::Container> m_xRight;
1012     std::unique_ptr<weld::ComboBox> m_xTypeListBox;
1013     std::unique_ptr<weld::ComboBox> m_xIdentifierBox;
1014 
1015     DECL_LINK(IdentifierHdl, weld::ComboBox&, void);
1016     DECL_LINK(ShortNameHdl, weld::Entry&, void);
1017     DECL_LINK(EnableHdl, weld::ComboBox&, void);
1018 
1019 public:
1020     SwCreateAuthEntryDlg_Impl(weld::Window* pParent,
1021                               const OUString pFields[],
1022                               SwWrtShell& rSh,
1023                               bool bNewEntry,
1024                               bool bCreate);
1025 
1026     OUString        GetEntryText(ToxAuthorityField eField) const;
1027 
SetCheckNameHdl(const Link<weld::Entry &,bool> & rLink)1028     void            SetCheckNameHdl(const Link<weld::Entry&,bool>& rLink) {aShortNameCheckLink = rLink;}
1029 
1030 };
1031 
1032 struct TextInfo
1033 {
1034     ToxAuthorityField nToxField;
1035     const char* pHelpId;
1036 };
1037 
1038 static const TextInfo aTextInfoArr[] =
1039 {
1040     {AUTH_FIELD_IDENTIFIER,      HID_AUTH_FIELD_IDENTIFIER      },
1041     {AUTH_FIELD_AUTHORITY_TYPE,  HID_AUTH_FIELD_AUTHORITY_TYPE  },
1042     {AUTH_FIELD_AUTHOR,          HID_AUTH_FIELD_AUTHOR          },
1043     {AUTH_FIELD_TITLE,           HID_AUTH_FIELD_TITLE           },
1044     {AUTH_FIELD_YEAR,            HID_AUTH_FIELD_YEAR            },
1045     {AUTH_FIELD_PUBLISHER,       HID_AUTH_FIELD_PUBLISHER       },
1046     {AUTH_FIELD_ADDRESS,         HID_AUTH_FIELD_ADDRESS         },
1047     {AUTH_FIELD_ISBN,            HID_AUTH_FIELD_ISBN            },
1048     {AUTH_FIELD_CHAPTER,         HID_AUTH_FIELD_CHAPTER         },
1049     {AUTH_FIELD_PAGES,           HID_AUTH_FIELD_PAGES           },
1050     {AUTH_FIELD_EDITOR,          HID_AUTH_FIELD_EDITOR          },
1051     {AUTH_FIELD_EDITION,         HID_AUTH_FIELD_EDITION         },
1052     {AUTH_FIELD_BOOKTITLE,       HID_AUTH_FIELD_BOOKTITLE       },
1053     {AUTH_FIELD_VOLUME,          HID_AUTH_FIELD_VOLUME          },
1054     {AUTH_FIELD_HOWPUBLISHED,    HID_AUTH_FIELD_HOWPUBLISHED    },
1055     {AUTH_FIELD_ORGANIZATIONS,   HID_AUTH_FIELD_ORGANIZATIONS   },
1056     {AUTH_FIELD_INSTITUTION,     HID_AUTH_FIELD_INSTITUTION     },
1057     {AUTH_FIELD_SCHOOL,          HID_AUTH_FIELD_SCHOOL          },
1058     {AUTH_FIELD_REPORT_TYPE,     HID_AUTH_FIELD_REPORT_TYPE     },
1059     {AUTH_FIELD_MONTH,           HID_AUTH_FIELD_MONTH           },
1060     {AUTH_FIELD_JOURNAL,         HID_AUTH_FIELD_JOURNAL         },
1061     {AUTH_FIELD_NUMBER,          HID_AUTH_FIELD_NUMBER          },
1062     {AUTH_FIELD_SERIES,          HID_AUTH_FIELD_SERIES          },
1063     {AUTH_FIELD_ANNOTE,          HID_AUTH_FIELD_ANNOTE          },
1064     {AUTH_FIELD_NOTE,            HID_AUTH_FIELD_NOTE            },
1065     {AUTH_FIELD_URL,             HID_AUTH_FIELD_URL             },
1066     {AUTH_FIELD_CUSTOM1,         HID_AUTH_FIELD_CUSTOM1         },
1067     {AUTH_FIELD_CUSTOM2,         HID_AUTH_FIELD_CUSTOM2         },
1068     {AUTH_FIELD_CUSTOM3,         HID_AUTH_FIELD_CUSTOM3         },
1069     {AUTH_FIELD_CUSTOM4,         HID_AUTH_FIELD_CUSTOM4         },
1070     {AUTH_FIELD_CUSTOM5,         HID_AUTH_FIELD_CUSTOM5         }
1071 };
1072 
lcl_FindColumnEntry(const uno::Sequence<beans::PropertyValue> & rFields,const OUString & rColumnTitle)1073 static OUString lcl_FindColumnEntry(const uno::Sequence<beans::PropertyValue>& rFields, const OUString& rColumnTitle)
1074 {
1075     for(const auto& rField : rFields)
1076     {
1077         OUString sRet;
1078         if(rField.Name == rColumnTitle &&
1079             (rField.Value >>= sRet))
1080         {
1081             return sRet;
1082         }
1083     }
1084     return OUString();
1085 }
1086 
1087 bool SwAuthorMarkPane::bIsFromComponent = true;
1088 
SwAuthorMarkPane(weld::DialogController & rDialog,weld::Builder & rBuilder,bool bNewDlg)1089 SwAuthorMarkPane::SwAuthorMarkPane(weld::DialogController &rDialog, weld::Builder& rBuilder, bool bNewDlg)
1090     : m_rDialog(rDialog)
1091     , bNewEntry(bNewDlg)
1092     , bBibAccessInitialized(false)
1093     , pSh(nullptr)
1094     , m_xFromComponentRB(rBuilder.weld_radio_button("frombibliography"))
1095     , m_xFromDocContentRB(rBuilder.weld_radio_button("fromdocument"))
1096     , m_xAuthorFI(rBuilder.weld_label("author"))
1097     , m_xTitleFI(rBuilder.weld_label("title"))
1098     , m_xEntryED(rBuilder.weld_entry("entryed"))
1099     , m_xEntryLB(rBuilder.weld_combo_box("entrylb"))
1100     , m_xActionBT(rBuilder.weld_button(bNewEntry ? OString("insert") : OString("modify")))
1101     , m_xCloseBT(rBuilder.weld_button("close"))
1102     , m_xCreateEntryPB(rBuilder.weld_button("new"))
1103     , m_xEditEntryPB(rBuilder.weld_button("edit"))
1104 {
1105     m_xActionBT->show();
1106     m_xFromComponentRB->set_visible(bNewEntry);
1107     m_xFromDocContentRB->set_visible(bNewEntry);
1108     m_xFromComponentRB->set_active(bIsFromComponent);
1109     m_xFromDocContentRB->set_active(!bIsFromComponent);
1110 
1111     m_xActionBT->connect_clicked(LINK(this,SwAuthorMarkPane, InsertHdl));
1112     m_xCloseBT->connect_clicked(LINK(this,SwAuthorMarkPane, CloseHdl));
1113     m_xCreateEntryPB->connect_clicked(LINK(this,SwAuthorMarkPane, CreateEntryHdl));
1114     m_xEditEntryPB->connect_clicked(LINK(this,SwAuthorMarkPane, CreateEntryHdl));
1115     m_xFromComponentRB->connect_toggled(LINK(this,SwAuthorMarkPane, ChangeSourceHdl));
1116     m_xFromDocContentRB->connect_toggled(LINK(this,SwAuthorMarkPane, ChangeSourceHdl));
1117     m_xEntryED->connect_changed(LINK(this,SwAuthorMarkPane, EditModifyHdl));
1118 
1119     m_rDialog.set_title(SwResId(
1120                     bNewEntry ? STR_AUTHMRK_INSERT : STR_AUTHMRK_EDIT));
1121 
1122     m_xEntryED->set_visible(!bNewEntry);
1123     m_xEntryLB->set_visible(bNewEntry);
1124     if (bNewEntry)
1125     {
1126         m_xEntryLB->connect_changed(LINK(this, SwAuthorMarkPane, CompEntryHdl));
1127     }
1128 }
1129 
ReInitDlg(SwWrtShell & rWrtShell)1130 void SwAuthorMarkPane::ReInitDlg(SwWrtShell& rWrtShell)
1131 {
1132     pSh = &rWrtShell;
1133     InitControls();
1134 }
1135 
IMPL_LINK_NOARG(SwAuthorMarkPane,CloseHdl,weld::Button &,void)1136 IMPL_LINK_NOARG(SwAuthorMarkPane, CloseHdl, weld::Button&, void)
1137 {
1138     if(bNewEntry)
1139     {
1140         SfxViewFrame::Current()->GetDispatcher()->Execute(FN_INSERT_AUTH_ENTRY_DLG,
1141                     SfxCallMode::ASYNCHRON|SfxCallMode::RECORD);
1142     }
1143     else
1144     {
1145         m_rDialog.response(RET_CANCEL);
1146     }
1147 }
1148 
IMPL_LINK(SwAuthorMarkPane,CompEntryHdl,weld::ComboBox &,rBox,void)1149 IMPL_LINK( SwAuthorMarkPane, CompEntryHdl, weld::ComboBox&, rBox, void)
1150 {
1151     const OUString sEntry(rBox.get_active_text());
1152     if(bIsFromComponent)
1153     {
1154         if(xBibAccess.is() && !sEntry.isEmpty())
1155         {
1156             if(xBibAccess->hasByName(sEntry))
1157             {
1158                 uno::Any aEntry(xBibAccess->getByName(sEntry));
1159                 uno::Sequence<beans::PropertyValue> aFieldProps;
1160                 if(aEntry >>= aFieldProps)
1161                 {
1162                     auto nSize = std::min(static_cast<sal_Int32>(AUTH_FIELD_END), aFieldProps.getLength());
1163                     for(sal_Int32 i = 0; i < nSize; i++)
1164                     {
1165                         m_sFields[i] = lcl_FindColumnEntry(aFieldProps, m_sColumnTitles[i]);
1166                     }
1167                 }
1168             }
1169         }
1170     }
1171     else
1172     {
1173         if(!sEntry.isEmpty())
1174         {
1175             const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
1176                                         pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
1177             const SwAuthEntry*  pEntry = pFType ? pFType->GetEntryByIdentifier(sEntry) : nullptr;
1178             for(int i = 0; i < AUTH_FIELD_END; i++)
1179                 m_sFields[i] = pEntry ?
1180                             pEntry->GetAuthorField(static_cast<ToxAuthorityField>(i)) : OUString();
1181         }
1182     }
1183     if (rBox.get_active_text().isEmpty())
1184     {
1185         for(OUString & s : m_sFields)
1186             s.clear();
1187     }
1188     m_xAuthorFI->set_label(m_sFields[AUTH_FIELD_AUTHOR]);
1189     m_xTitleFI->set_label(m_sFields[AUTH_FIELD_TITLE]);
1190 }
1191 
IMPL_LINK_NOARG(SwAuthorMarkPane,InsertHdl,weld::Button &,void)1192 IMPL_LINK_NOARG(SwAuthorMarkPane, InsertHdl, weld::Button&, void)
1193 {
1194     //insert or update the SwAuthorityField...
1195     if(pSh)
1196     {
1197         bool bDifferent = false;
1198         OSL_ENSURE(!m_sFields[AUTH_FIELD_IDENTIFIER].isEmpty() , "No Id is set!");
1199         OSL_ENSURE(!m_sFields[AUTH_FIELD_AUTHORITY_TYPE].isEmpty() , "No authority type is set!");
1200         //check if the entry already exists with different content
1201         const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
1202                                         pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
1203         const SwAuthEntry*  pEntry = pFType ?
1204                 pFType->GetEntryByIdentifier( m_sFields[AUTH_FIELD_IDENTIFIER])
1205                 : nullptr;
1206         if(pEntry)
1207         {
1208             for(int i = 0; i < AUTH_FIELD_END && !bDifferent; i++)
1209                 bDifferent |= m_sFields[i] != pEntry->GetAuthorField(static_cast<ToxAuthorityField>(i));
1210             if(bDifferent)
1211             {
1212                 std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(m_rDialog.getDialog(),
1213                                                             VclMessageType::Question, VclButtonsType::YesNo,
1214                                                             SwResId(STR_QUERY_CHANGE_AUTH_ENTRY)));
1215                 if (RET_YES != xQuery->run())
1216                     return;
1217             }
1218         }
1219 
1220         SwFieldMgr aMgr(pSh);
1221         OUStringBuffer sFields;
1222         for(OUString & s : m_sFields)
1223         {
1224             sFields.append(s).append(TOX_STYLE_DELIMITER);
1225         }
1226         if(bNewEntry)
1227         {
1228             if(bDifferent)
1229             {
1230                 rtl::Reference<SwAuthEntry> xNewData(new SwAuthEntry);
1231                 for(int i = 0; i < AUTH_FIELD_END; i++)
1232                     xNewData->SetAuthorField(static_cast<ToxAuthorityField>(i), m_sFields[i]);
1233                 pSh->ChangeAuthorityData(xNewData.get());
1234             }
1235             SwInsertField_Data aData(SwFieldTypesEnum::Authority, 0, sFields.makeStringAndClear(), OUString(), 0 );
1236             aMgr.InsertField( aData );
1237         }
1238         else if(aMgr.GetCurField())
1239         {
1240             aMgr.UpdateCurField(0, sFields.makeStringAndClear(), OUString());
1241         }
1242     }
1243     if(!bNewEntry)
1244         CloseHdl(*m_xCloseBT);
1245 }
1246 
IMPL_LINK(SwAuthorMarkPane,CreateEntryHdl,weld::Button &,rButton,void)1247 IMPL_LINK(SwAuthorMarkPane, CreateEntryHdl, weld::Button&, rButton, void)
1248 {
1249     bool bCreate = &rButton == m_xCreateEntryPB.get();
1250     OUString sOldId = m_sCreatedEntry[0];
1251     for(int i = 0; i < AUTH_FIELD_END; i++)
1252         m_sCreatedEntry[i] = bCreate ? OUString() : m_sFields[i];
1253     SwCreateAuthEntryDlg_Impl aDlg(m_rDialog.getDialog(),
1254                 bCreate ? m_sCreatedEntry : m_sFields,
1255                 *pSh, bNewEntry, bCreate);
1256     if(bNewEntry)
1257     {
1258         aDlg.SetCheckNameHdl(LINK(this, SwAuthorMarkPane, IsEntryAllowedHdl));
1259     }
1260     if(RET_OK == aDlg.run())
1261     {
1262         if(bCreate && !sOldId.isEmpty())
1263         {
1264             m_xEntryLB->remove_text(sOldId);
1265         }
1266         for(int i = 0; i < AUTH_FIELD_END; i++)
1267         {
1268             m_sFields[i] = aDlg.GetEntryText(static_cast<ToxAuthorityField>(i));
1269             m_sCreatedEntry[i] = m_sFields[i];
1270         }
1271         if(bNewEntry && !m_xFromDocContentRB->get_active())
1272         {
1273             m_xFromDocContentRB->set_active(true);
1274             ChangeSourceHdl(*m_xFromDocContentRB);
1275         }
1276         if(bCreate)
1277         {
1278             OSL_ENSURE(m_xEntryLB->find_text(m_sFields[AUTH_FIELD_IDENTIFIER]) == -1,
1279                         "entry exists!");
1280             m_xEntryLB->append_text(m_sFields[AUTH_FIELD_IDENTIFIER]);
1281             m_xEntryLB->set_active_text(m_sFields[AUTH_FIELD_IDENTIFIER]);
1282         }
1283         m_xEntryED->set_text(m_sFields[AUTH_FIELD_IDENTIFIER]);
1284         m_xAuthorFI->set_label(m_sFields[AUTH_FIELD_AUTHOR]);
1285         m_xTitleFI->set_label(m_sFields[AUTH_FIELD_TITLE]);
1286         m_xActionBT->set_sensitive(true);
1287     }
1288 }
1289 
IMPL_LINK_NOARG(SwAuthorMarkPane,ChangeSourceHdl,weld::ToggleButton &,void)1290 IMPL_LINK_NOARG(SwAuthorMarkPane, ChangeSourceHdl, weld::ToggleButton&, void)
1291 {
1292     bool bFromComp = m_xFromComponentRB->get_active();
1293     bIsFromComponent = bFromComp;
1294     m_xCreateEntryPB->set_sensitive(!bIsFromComponent);
1295     m_xEntryLB->clear();
1296     if(bIsFromComponent)
1297     {
1298         if(!bBibAccessInitialized)
1299         {
1300             uno::Reference< uno::XComponentContext > xContext = getProcessComponentContext();
1301             xBibAccess = frame::Bibliography::create( xContext );
1302             uno::Reference< beans::XPropertySet >  xPropSet(xBibAccess, uno::UNO_QUERY);
1303             OUString uPropName("BibliographyDataFieldNames");
1304             if(xPropSet.is() && xPropSet->getPropertySetInfo()->hasPropertyByName(uPropName))
1305             {
1306                 uno::Any aNames = xPropSet->getPropertyValue(uPropName);
1307                 uno::Sequence<beans::PropertyValue> aSeq;
1308                 if( aNames >>= aSeq)
1309                 {
1310                     for(const beans::PropertyValue& rProp : std::as_const(aSeq))
1311                     {
1312                         sal_Int16 nField = 0;
1313                         rProp.Value >>= nField;
1314                         if(nField >= 0 && nField < AUTH_FIELD_END)
1315                             m_sColumnTitles[nField] = rProp.Name;
1316                     }
1317                 }
1318             }
1319             bBibAccessInitialized = true;
1320         }
1321         if(xBibAccess.is())
1322         {
1323             const uno::Sequence<OUString> aIdentifiers = xBibAccess->getElementNames();
1324             for(const OUString& rName : aIdentifiers)
1325                 m_xEntryLB->append_text(rName);
1326         }
1327     }
1328     else
1329     {
1330         const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
1331                                     pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
1332         if(pFType)
1333         {
1334             std::vector<OUString> aIds;
1335             pFType->GetAllEntryIdentifiers( aIds );
1336             for(const OUString & i : aIds)
1337                 m_xEntryLB->append_text(i);
1338         }
1339         if(!m_sCreatedEntry[AUTH_FIELD_IDENTIFIER].isEmpty())
1340             m_xEntryLB->append_text(m_sCreatedEntry[AUTH_FIELD_IDENTIFIER]);
1341     }
1342     m_xEntryLB->set_active(0);
1343     CompEntryHdl(*m_xEntryLB);
1344 }
1345 
IMPL_LINK(SwAuthorMarkPane,EditModifyHdl,weld::Entry &,rEdit,void)1346 IMPL_LINK(SwAuthorMarkPane, EditModifyHdl, weld::Entry&, rEdit, void)
1347 {
1348     Link<weld::Entry&,bool> aAllowed = LINK(this, SwAuthorMarkPane, IsEditAllowedHdl);
1349     bool bResult = aAllowed.Call(rEdit);
1350     m_xActionBT->set_sensitive(bResult);
1351     if(bResult)
1352     {
1353         OUString sEntry(rEdit.get_text());
1354         m_sFields[AUTH_FIELD_IDENTIFIER] = sEntry;
1355         m_sCreatedEntry[AUTH_FIELD_IDENTIFIER] = sEntry;
1356     }
1357 };
1358 
IMPL_LINK(SwAuthorMarkPane,IsEntryAllowedHdl,weld::Entry &,rEdit,bool)1359 IMPL_LINK(SwAuthorMarkPane, IsEntryAllowedHdl, weld::Entry&, rEdit, bool)
1360 {
1361     OUString sEntry = rEdit.get_text();
1362     bool bAllowed = false;
1363     if(!sEntry.isEmpty())
1364     {
1365         if (m_xEntryLB->find_text(sEntry) != -1)
1366             return false;
1367         else if(bIsFromComponent)
1368         {
1369             const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
1370                                         pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
1371             bAllowed = !pFType || !pFType->GetEntryByIdentifier(sEntry);
1372         }
1373         else
1374         {
1375             bAllowed = !xBibAccess.is() || !xBibAccess->hasByName(sEntry);
1376         }
1377     }
1378     return bAllowed;
1379 }
1380 
IMPL_LINK(SwAuthorMarkPane,IsEditAllowedHdl,weld::Entry &,rEdit,bool)1381 IMPL_LINK(SwAuthorMarkPane, IsEditAllowedHdl, weld::Entry&, rEdit, bool)
1382 {
1383     OUString sEntry = rEdit.get_text();
1384     bool bAllowed = false;
1385     if(!sEntry.isEmpty())
1386     {
1387         if (m_xEntryLB->find_text(sEntry) != -1)
1388             return false;
1389         else if(bIsFromComponent)
1390         {
1391             const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
1392                                         pSh->GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
1393             bAllowed = !pFType || !pFType->GetEntryByIdentifier(sEntry);
1394         }
1395         else
1396         {
1397             bAllowed = !xBibAccess.is() || !xBibAccess->hasByName(sEntry);
1398         }
1399     }
1400     return bAllowed;
1401 }
1402 
InitControls()1403 void SwAuthorMarkPane::InitControls()
1404 {
1405     OSL_ENSURE(pSh, "no shell?");
1406     SwField* pField = pSh->GetCurField();
1407     OSL_ENSURE(bNewEntry || pField, "no current marker");
1408     if(bNewEntry)
1409     {
1410         ChangeSourceHdl(m_xFromComponentRB->get_active() ? *m_xFromComponentRB : *m_xFromDocContentRB);
1411         m_xCreateEntryPB->set_sensitive(!m_xFromComponentRB->get_active());
1412         if(!m_xFromComponentRB->get_active() && !m_sCreatedEntry[0].isEmpty())
1413             for(int i = 0; i < AUTH_FIELD_END; i++)
1414                 m_sFields[i] = m_sCreatedEntry[i];
1415     }
1416     if(bNewEntry || !pField || pField->GetTyp()->Which() != SwFieldIds::TableOfAuthorities)
1417         return;
1418 
1419     const SwAuthEntry* pEntry = static_cast<SwAuthorityField*>(pField)->GetAuthEntry();
1420 
1421     OSL_ENSURE(pEntry, "No authority entry found");
1422     if(!pEntry)
1423         return;
1424     for(int i = 0; i < AUTH_FIELD_END; i++)
1425         m_sFields[i] = pEntry->GetAuthorField(static_cast<ToxAuthorityField>(i));
1426 
1427     m_xEntryED->set_text(pEntry->GetAuthorField(AUTH_FIELD_IDENTIFIER));
1428     m_xAuthorFI->set_label(pEntry->GetAuthorField(AUTH_FIELD_AUTHOR));
1429     m_xTitleFI->set_label(pEntry->GetAuthorField(AUTH_FIELD_TITLE));
1430 }
1431 
Activate()1432 void SwAuthorMarkPane::Activate()
1433 {
1434     m_xActionBT->set_sensitive(!pSh->HasReadonlySel());
1435 }
1436 
1437 namespace
1438 {
1439     const char* STR_AUTH_FIELD_ARY[] =
1440     {
1441         STR_AUTH_FIELD_IDENTIFIER,
1442         STR_AUTH_FIELD_AUTHORITY_TYPE,
1443         STR_AUTH_FIELD_ADDRESS,
1444         STR_AUTH_FIELD_ANNOTE,
1445         STR_AUTH_FIELD_AUTHOR,
1446         STR_AUTH_FIELD_BOOKTITLE,
1447         STR_AUTH_FIELD_CHAPTER,
1448         STR_AUTH_FIELD_EDITION,
1449         STR_AUTH_FIELD_EDITOR,
1450         STR_AUTH_FIELD_HOWPUBLISHED,
1451         STR_AUTH_FIELD_INSTITUTION,
1452         STR_AUTH_FIELD_JOURNAL,
1453         STR_AUTH_FIELD_MONTH,
1454         STR_AUTH_FIELD_NOTE,
1455         STR_AUTH_FIELD_NUMBER,
1456         STR_AUTH_FIELD_ORGANIZATIONS,
1457         STR_AUTH_FIELD_PAGES,
1458         STR_AUTH_FIELD_PUBLISHER,
1459         STR_AUTH_FIELD_SCHOOL,
1460         STR_AUTH_FIELD_SERIES,
1461         STR_AUTH_FIELD_TITLE,
1462         STR_AUTH_FIELD_TYPE,
1463         STR_AUTH_FIELD_VOLUME,
1464         STR_AUTH_FIELD_YEAR,
1465         STR_AUTH_FIELD_URL,
1466         STR_AUTH_FIELD_CUSTOM1,
1467         STR_AUTH_FIELD_CUSTOM2,
1468         STR_AUTH_FIELD_CUSTOM3,
1469         STR_AUTH_FIELD_CUSTOM4,
1470         STR_AUTH_FIELD_CUSTOM5,
1471         STR_AUTH_FIELD_ISBN
1472     };
1473 }
1474 
SwCreateAuthEntryDlg_Impl(weld::Window * pParent,const OUString pFields[],SwWrtShell & rSh,bool bNewEntry,bool bCreate)1475 SwCreateAuthEntryDlg_Impl::SwCreateAuthEntryDlg_Impl(weld::Window* pParent,
1476         const OUString pFields[],
1477         SwWrtShell& rSh,
1478         bool bNewEntry,
1479         bool bCreate)
1480     : GenericDialogController(pParent, "modules/swriter/ui/createauthorentry.ui", "CreateAuthorEntryDialog")
1481     , rWrtSh(rSh)
1482     , m_bNewEntryMode(bNewEntry)
1483     , m_bNameAllowed(true)
1484     , m_xOKBT(m_xBuilder->weld_button("ok"))
1485     , m_xBox(m_xBuilder->weld_container("box"))
1486     , m_xLeft(m_xBuilder->weld_container("leftgrid"))
1487     , m_xRight(m_xBuilder->weld_container("rightgrid"))
1488 {
1489     bool bLeft = true;
1490     sal_Int32 nLeftRow(0), nRightRow(0);
1491     for(int nIndex = 0; nIndex < AUTH_FIELD_END; nIndex++)
1492     {
1493         //m_xBox parent just to have some parent during setup, added contents are not directly visible under m_xBox
1494         m_aBuilders.emplace_back(Application::CreateBuilder(m_xBox.get(), "modules/swriter/ui/bibliofragment.ui"));
1495         const TextInfo aCurInfo = aTextInfoArr[nIndex];
1496 
1497         m_aOrigContainers.emplace_back(m_aBuilders.back()->weld_container("biblioentry"));
1498         m_aFixedTexts.emplace_back(m_aBuilders.back()->weld_label("label"));
1499         if (bLeft)
1500             m_aOrigContainers.back()->move(m_aFixedTexts.back().get(), m_xLeft.get());
1501         else
1502             m_aOrigContainers.back()->move(m_aFixedTexts.back().get(), m_xRight.get());
1503         m_aFixedTexts.back()->set_grid_left_attach(0);
1504         m_aFixedTexts.back()->set_grid_top_attach(bLeft ? nLeftRow : nRightRow);
1505         m_aFixedTexts.back()->set_label(SwResId(STR_AUTH_FIELD_ARY[aCurInfo.nToxField]));
1506         m_aFixedTexts.back()->show();
1507         if( AUTH_FIELD_AUTHORITY_TYPE == aCurInfo.nToxField )
1508         {
1509             m_xTypeListBox = m_aBuilders.back()->weld_combo_box("listbox");
1510             if (bLeft)
1511                 m_aOrigContainers.back()->move(m_xTypeListBox.get(), m_xLeft.get());
1512             else
1513                 m_aOrigContainers.back()->move(m_xTypeListBox.get(), m_xRight.get());
1514 
1515             for (int j = 0; j < AUTH_TYPE_END; j++)
1516                 m_xTypeListBox->append_text(SwAuthorityFieldType::GetAuthTypeName(static_cast<ToxAuthorityType>(j)));
1517             if(!pFields[aCurInfo.nToxField].isEmpty())
1518             {
1519                 m_xTypeListBox->set_active(pFields[aCurInfo.nToxField].toInt32());
1520             }
1521             m_xTypeListBox->set_grid_left_attach(1);
1522             m_xTypeListBox->set_grid_top_attach(bLeft ? nLeftRow : nRightRow);
1523             m_xTypeListBox->set_hexpand(true);
1524             m_xTypeListBox->show();
1525             m_xTypeListBox->connect_changed(LINK(this, SwCreateAuthEntryDlg_Impl, EnableHdl));
1526             m_xTypeListBox->set_help_id(aCurInfo.pHelpId);
1527             m_aFixedTexts.back()->set_mnemonic_widget(m_xTypeListBox.get());
1528         }
1529         else if(AUTH_FIELD_IDENTIFIER == aCurInfo.nToxField && !m_bNewEntryMode)
1530         {
1531             m_xIdentifierBox = m_aBuilders.back()->weld_combo_box("combobox");
1532             if (bLeft)
1533                 m_aOrigContainers.back()->move(m_xIdentifierBox.get(), m_xLeft.get());
1534             else
1535                 m_aOrigContainers.back()->move(m_xIdentifierBox.get(), m_xRight.get());
1536 
1537             m_xIdentifierBox->connect_changed(LINK(this,
1538                                     SwCreateAuthEntryDlg_Impl, IdentifierHdl));
1539 
1540             const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
1541                                         rSh.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
1542             if(pFType)
1543             {
1544                 std::vector<OUString> aIds;
1545                 pFType->GetAllEntryIdentifiers( aIds );
1546                 for (const OUString& a : aIds)
1547                     m_xIdentifierBox->append_text(a);
1548             }
1549             m_xIdentifierBox->set_entry_text(pFields[aCurInfo.nToxField]);
1550             m_xIdentifierBox->set_grid_left_attach(1);
1551             m_xIdentifierBox->set_grid_top_attach(bLeft ? nLeftRow : nRightRow);
1552             m_xIdentifierBox->set_hexpand(true);
1553             m_xIdentifierBox->show();
1554             m_xIdentifierBox->set_help_id(aCurInfo.pHelpId);
1555             m_aFixedTexts.back()->set_mnemonic_widget(m_xIdentifierBox.get());
1556         }
1557         else
1558         {
1559             pEdits[nIndex] = m_aBuilders.back()->weld_entry("entry");
1560             if (bLeft)
1561                 m_aOrigContainers.back()->move(pEdits[nIndex].get(), m_xLeft.get());
1562             else
1563                 m_aOrigContainers.back()->move(pEdits[nIndex].get(), m_xRight.get());
1564 
1565             pEdits[nIndex]->set_grid_left_attach(1);
1566             pEdits[nIndex]->set_grid_top_attach(bLeft ? nLeftRow : nRightRow);
1567             pEdits[nIndex]->set_hexpand(true);
1568             pEdits[nIndex]->set_text(pFields[aCurInfo.nToxField]);
1569             pEdits[nIndex]->show();
1570             pEdits[nIndex]->set_help_id(aCurInfo.pHelpId);
1571             if(AUTH_FIELD_IDENTIFIER == aCurInfo.nToxField)
1572             {
1573                 pEdits[nIndex]->connect_changed(LINK(this, SwCreateAuthEntryDlg_Impl, ShortNameHdl));
1574                 m_bNameAllowed = !pFields[nIndex].isEmpty();
1575                 if(!bCreate)
1576                 {
1577                     m_aFixedTexts.back()->set_sensitive(false);
1578                     pEdits[nIndex]->set_sensitive(false);
1579                 }
1580             }
1581             m_aFixedTexts.back()->set_mnemonic_widget(pEdits[nIndex].get());
1582         }
1583         if(bLeft)
1584             ++nLeftRow;
1585         else
1586             ++nRightRow;
1587         bLeft = !bLeft;
1588     }
1589     EnableHdl(*m_xTypeListBox);
1590 }
1591 
GetEntryText(ToxAuthorityField eField) const1592 OUString  SwCreateAuthEntryDlg_Impl::GetEntryText(ToxAuthorityField eField) const
1593 {
1594     if( AUTH_FIELD_AUTHORITY_TYPE == eField )
1595     {
1596         OSL_ENSURE(m_xTypeListBox, "No ListBox");
1597         return OUString::number(m_xTypeListBox->get_active());
1598     }
1599 
1600     if( AUTH_FIELD_IDENTIFIER == eField && !m_bNewEntryMode)
1601     {
1602         OSL_ENSURE(m_xIdentifierBox, "No ComboBox");
1603         return m_xIdentifierBox->get_active_text();
1604     }
1605 
1606     for(int nIndex = 0; nIndex < AUTH_FIELD_END; nIndex++)
1607     {
1608         const TextInfo aCurInfo = aTextInfoArr[nIndex];
1609         if(aCurInfo.nToxField == eField)
1610         {
1611             return pEdits[nIndex]->get_text();
1612         }
1613     }
1614 
1615     return OUString();
1616 }
1617 
IMPL_LINK(SwCreateAuthEntryDlg_Impl,IdentifierHdl,weld::ComboBox &,rBox,void)1618 IMPL_LINK(SwCreateAuthEntryDlg_Impl, IdentifierHdl, weld::ComboBox&, rBox, void)
1619 {
1620     const SwAuthorityFieldType* pFType = static_cast<const SwAuthorityFieldType*>(
1621                                 rWrtSh.GetFieldType(SwFieldIds::TableOfAuthorities, OUString()));
1622     if(pFType)
1623     {
1624         const SwAuthEntry* pEntry = pFType->GetEntryByIdentifier(
1625                                                         rBox.get_active_text());
1626         if(pEntry)
1627         {
1628             for(int i = 0; i < AUTH_FIELD_END; i++)
1629             {
1630                 const TextInfo aCurInfo = aTextInfoArr[i];
1631                 if(AUTH_FIELD_IDENTIFIER == aCurInfo.nToxField)
1632                     continue;
1633                 if(AUTH_FIELD_AUTHORITY_TYPE == aCurInfo.nToxField)
1634                     m_xTypeListBox->set_active_text(
1635                                 pEntry->GetAuthorField(aCurInfo.nToxField));
1636                 else
1637                     pEdits[i]->set_text(
1638                                 pEntry->GetAuthorField(aCurInfo.nToxField));
1639             }
1640         }
1641     }
1642 }
1643 
IMPL_LINK(SwCreateAuthEntryDlg_Impl,ShortNameHdl,weld::Entry &,rEdit,void)1644 IMPL_LINK(SwCreateAuthEntryDlg_Impl, ShortNameHdl, weld::Entry&, rEdit, void)
1645 {
1646     if (aShortNameCheckLink.IsSet())
1647     {
1648         bool bEnable = aShortNameCheckLink.Call(rEdit);
1649         m_bNameAllowed |= bEnable;
1650         m_xOKBT->set_sensitive(m_xTypeListBox->get_active() != -1 && bEnable);
1651     }
1652 }
1653 
IMPL_LINK(SwCreateAuthEntryDlg_Impl,EnableHdl,weld::ComboBox &,rBox,void)1654 IMPL_LINK(SwCreateAuthEntryDlg_Impl, EnableHdl, weld::ComboBox&, rBox, void)
1655 {
1656     m_xOKBT->set_sensitive(m_bNameAllowed && rBox.get_active() != -1);
1657 };
1658 
SwAuthMarkFloatDlg(SfxBindings * _pBindings,SfxChildWindow * pChild,weld::Window * pParent,SfxChildWinInfo const * pInfo,bool bNew)1659 SwAuthMarkFloatDlg::SwAuthMarkFloatDlg(SfxBindings* _pBindings,
1660                                        SfxChildWindow* pChild,
1661                                        weld::Window *pParent,
1662                                        SfxChildWinInfo const * pInfo,
1663                                        bool bNew)
1664     : SfxModelessDialogController(_pBindings, pChild, pParent,
1665         "modules/swriter/ui/bibliographyentry.ui", "BibliographyEntryDialog")
1666     , m_aContent(*this, *m_xBuilder, bNew)
1667 {
1668     Initialize(pInfo);
1669     SwWrtShell* pWrtShell = ::GetActiveWrtShell();
1670     if (pWrtShell)
1671         m_aContent.ReInitDlg(*pWrtShell);
1672 }
1673 
Activate()1674 void SwAuthMarkFloatDlg::Activate()
1675 {
1676     SfxModelessDialogController::Activate();
1677     m_aContent.Activate();
1678 }
1679 
ReInitDlg(SwWrtShell & rWrtShell)1680 void SwAuthMarkFloatDlg::ReInitDlg(SwWrtShell& rWrtShell)
1681 {
1682     m_aContent.ReInitDlg( rWrtShell );
1683 }
1684 
SwAuthMarkModalDlg(weld::Window * pParent,SwWrtShell & rSh)1685 SwAuthMarkModalDlg::SwAuthMarkModalDlg(weld::Window *pParent, SwWrtShell& rSh)
1686     : SfxDialogController(pParent, "modules/swriter/ui/bibliographyentry.ui",
1687                           "BibliographyEntryDialog")
1688     , m_aContent(*this, *m_xBuilder, false)
1689 {
1690     m_aContent.ReInitDlg(rSh);
1691 }
1692 
run()1693 short SwAuthMarkModalDlg::run()
1694 {
1695     short ret = SfxDialogController::run();
1696     if (ret == RET_OK)
1697         Apply();
1698     return ret;
1699 }
1700 
Apply()1701 void SwAuthMarkModalDlg::Apply()
1702 {
1703     m_aContent.InsertHdl(*m_aContent.m_xActionBT);
1704 }
1705 
1706 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1707