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