lok: Hide file linking in section
[LibreOffice.git] / sw / source / ui / misc / glossary.cxx
blob3fd85a31895ab63a5590954f3175b33d30a38027
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <hintids.hxx>
22 #include <o3tl/any.hxx>
23 #include <vcl/event.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/weld.hxx>
26 #include <vcl/help.hxx>
27 #include <svl/stritem.hxx>
28 #include <svl/macitem.hxx>
29 #include <unotools/pathoptions.hxx>
30 #include <unotools/lingucfg.hxx>
31 #include <sfx2/request.hxx>
32 #include <sfx2/fcontnr.hxx>
33 #include <sfx2/docfilt.hxx>
35 #include <svx/svxdlg.hxx>
36 #include <svx/dialogs.hrc>
37 #include <editeng/acorrcfg.hxx>
38 #include <sfx2/viewfrm.hxx>
39 #include <unocrsr.hxx>
40 #include <unotools.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <ucbhelper/content.hxx>
43 #include <com/sun/star/text/AutoTextContainer.hpp>
44 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
45 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
46 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
47 #include <svl/urihelper.hxx>
48 #include <unotools/charclass.hxx>
49 #include <swwait.hxx>
50 #include <swtypes.hxx>
51 #include <wrtsh.hxx>
52 #include <view.hxx>
53 #include <basesh.hxx>
54 #include <glossary.hxx>
55 #include <gloshdl.hxx>
56 #include <glosbib.hxx>
57 #include <initui.hxx>
58 #include <glosdoc.hxx>
59 #include <macassgn.hxx>
60 #include <swevent.hxx>
61 #include <docsh.hxx>
62 #include <shellio.hxx>
64 #include <cmdid.h>
65 #include <swerror.h>
66 #include <globals.hrc>
67 #include <swmodule.hxx>
68 #include <sfx2/filedlghelper.hxx>
70 #include <memory>
72 #include <strings.hrc>
73 #include <iodetect.hxx>
75 #include <officecfg/Office/Writer.hxx>
77 using namespace ::com::sun::star;
78 using namespace ::com::sun::star::lang;
79 using namespace ::com::sun::star::uno;
80 using namespace ::com::sun::star::text;
81 using namespace ::com::sun::star::ucb;
82 using namespace ::com::sun::star::ui::dialogs;
83 using namespace ::ucbhelper;
84 using namespace ::sfx2;
86 static OUString lcl_GetValidShortCut( const OUString& rName )
88 const sal_Int32 nSz = rName.getLength();
90 if ( 0 == nSz )
91 return rName;
93 sal_Int32 nStart = 1;
94 while( rName[nStart-1]==' ' && nStart < nSz )
95 nStart++;
97 OUStringBuffer aBuf;
98 aBuf.append(rName[nStart-1]);
100 for( ; nStart < nSz; ++nStart )
102 if( rName[nStart-1]==' ' && rName[nStart]!=' ')
103 aBuf.append(rName[nStart]);
105 return aBuf.makeStringAndClear();
108 struct GroupUserData
110 OUString sGroupName;
111 sal_uInt16 nPathIdx;
112 bool bReadonly;
114 GroupUserData()
115 : nPathIdx(0),
116 bReadonly(false) {}
119 // dialog for new block name
120 class SwNewGlosNameDlg : public weld::GenericDialogController
122 TextFilter m_aNoSpaceFilter;
123 SwGlossaryDlg* m_pParent;
125 std::unique_ptr<weld::Entry> m_xNewName;
126 std::unique_ptr<weld::Entry> m_xNewShort;
127 std::unique_ptr<weld::Button> m_xOk;
128 std::unique_ptr<weld::Entry> m_xOldName;
129 std::unique_ptr<weld::Entry> m_xOldShort;
131 protected:
132 DECL_LINK(Modify, weld::Entry&, void);
133 DECL_LINK(Rename, weld::Button&, void);
134 DECL_LINK(TextFilterHdl, OUString&, bool);
136 public:
137 SwNewGlosNameDlg(SwGlossaryDlg* pParent,
138 const OUString& rOldName,
139 const OUString& rOldShort);
141 OUString GetNewName() const { return m_xNewName->get_text(); }
142 OUString GetNewShort() const { return m_xNewShort->get_text(); }
145 IMPL_LINK(SwNewGlosNameDlg, TextFilterHdl, OUString&, rTest, bool)
147 rTest = m_aNoSpaceFilter.filter(rTest);
148 return true;
151 SwNewGlosNameDlg::SwNewGlosNameDlg(SwGlossaryDlg* pParent, const OUString& rOldName, const OUString& rOldShort)
152 : GenericDialogController(pParent->getDialog(), "modules/swriter/ui/renameautotextdialog.ui", "RenameAutoTextDialog")
153 , m_pParent(pParent)
154 , m_xNewName(m_xBuilder->weld_entry("newname"))
155 , m_xNewShort(m_xBuilder->weld_entry("newsc"))
156 , m_xOk(m_xBuilder->weld_button("ok"))
157 , m_xOldName(m_xBuilder->weld_entry("oldname"))
158 , m_xOldShort(m_xBuilder->weld_entry("oldsc"))
160 m_xNewShort->connect_insert_text(LINK(this, SwNewGlosNameDlg, TextFilterHdl));
162 m_xOldName->set_text(rOldName);
163 m_xOldShort->set_text(rOldShort);
164 m_xNewName->connect_changed(LINK(this, SwNewGlosNameDlg, Modify ));
165 m_xNewShort->connect_changed(LINK(this, SwNewGlosNameDlg, Modify ));
166 m_xOk->connect_clicked(LINK(this, SwNewGlosNameDlg, Rename ));
167 m_xNewName->grab_focus();
170 // query / set currently set group
171 OUString SwGlossaryDlg::GetCurrGroup()
173 if( !::GetCurrGlosGroup().isEmpty() )
174 return ::GetCurrGlosGroup();
175 return SwGlossaries::GetDefName();
178 void SwGlossaryDlg::SetActGroup(const OUString &rGrp)
180 ::SetCurrGlosGroup(rGrp);
183 IMPL_LINK(SwGlossaryDlg, TextFilterHdl, OUString&, rTest, bool)
185 rTest = m_aNoSpaceFilter.filter(rTest);
186 return true;
189 SwGlossaryDlg::SwGlossaryDlg(SfxViewFrame const * pViewFrame,
190 SwGlossaryHdl * pGlosHdl, SwWrtShell *pWrtShell)
191 : SfxDialogController(pViewFrame->GetWindow().GetFrameWeld(), "modules/swriter/ui/autotext.ui", "AutoTextDialog")
192 , m_sReadonlyPath(SwResId(STR_READONLY_PATH))
193 , m_pGlossaryHdl(pGlosHdl)
194 , m_bResume(false)
195 , m_bSelection(pWrtShell->IsSelection())
196 , m_bReadOnly(false)
197 , m_bIsOld(false)
198 , m_bIsDocReadOnly(false)
199 , m_pShell(pWrtShell)
200 , m_xInsertTipCB(m_xBuilder->weld_check_button("inserttip"))
201 , m_xNameED(m_xBuilder->weld_entry("name"))
202 , m_xShortNameLbl(m_xBuilder->weld_label("shortnameft"))
203 , m_xShortNameEdit(m_xBuilder->weld_entry("shortname"))
204 , m_xCategoryBox(m_xBuilder->weld_tree_view("category"))
205 , m_xFileRelCB(m_xBuilder->weld_check_button("relfile"))
206 , m_xNetRelCB(m_xBuilder->weld_check_button("relnet"))
207 , m_xInsertBtn(m_xBuilder->weld_button("ok"))
208 , m_xEditBtn(m_xBuilder->weld_menu_button("autotext"))
209 , m_xBibBtn(m_xBuilder->weld_button("categories"))
210 , m_xPathBtn(m_xBuilder->weld_button("path"))
212 m_xCategoryBox->set_size_request(m_xCategoryBox->get_approximate_digit_width() * 52,
213 m_xCategoryBox->get_height_rows(12));
215 Link<SwOneExampleFrame&,void> aLink(LINK(this, SwGlossaryDlg, PreviewLoadedHdl));
216 m_xExampleFrame.reset(new SwOneExampleFrame(EX_SHOW_ONLINE_LAYOUT, &aLink));
217 m_xExampleFrameWin.reset(new weld::CustomWeld(*m_xBuilder, "example", *m_xExampleFrame));
218 Size aSize = m_xExampleFrame->GetDrawingArea()->get_ref_device().LogicToPixel(
219 Size(82, 124), MapMode(MapUnit::MapAppFont));
220 m_xExampleFrame->set_size_request(aSize.Width(), aSize.Height());
222 m_xShortNameEdit->connect_insert_text(LINK(this, SwGlossaryDlg, TextFilterHdl));
224 SvtLinguConfig aLocalLinguConfig;
226 m_xEditBtn->connect_toggled(LINK(this, SwGlossaryDlg, EnableHdl));
227 m_xEditBtn->connect_selected(LINK(this, SwGlossaryDlg, MenuHdl));
228 m_xPathBtn->connect_clicked(LINK(this, SwGlossaryDlg, PathHdl));
230 m_xNameED->connect_changed(LINK(this,SwGlossaryDlg,NameModify));
231 m_xShortNameEdit->connect_changed(LINK(this,SwGlossaryDlg,NameModify));
233 m_xCategoryBox->connect_row_activated(LINK(this, SwGlossaryDlg, NameDoubleClick));
234 m_xCategoryBox->connect_changed(LINK(this, SwGlossaryDlg, GrpSelect));
235 m_xCategoryBox->connect_key_press(LINK(this, SwGlossaryDlg, KeyInputHdl));
236 m_xBibBtn->connect_clicked(LINK(this,SwGlossaryDlg,BibHdl));
238 m_xInsertBtn->connect_clicked(LINK(this,SwGlossaryDlg,InsertHdl));
240 ShowPreview();
242 m_bIsDocReadOnly = m_pShell->GetView().GetDocShell()->IsReadOnly() ||
243 m_pShell->HasReadonlySel();
244 if( m_bIsDocReadOnly )
245 m_xInsertBtn->set_sensitive(false);
246 m_xNameED->grab_focus();
247 m_xCategoryBox->make_sorted();
248 m_xCategoryBox->set_sort_order(true);
250 Init();
253 SwGlossaryDlg::~SwGlossaryDlg()
257 namespace
260 OUString getCurrentGlossary()
262 const OUString sTemp{ ::GetCurrGlosGroup() };
264 // the zeroth path is not being recorded!
265 if (sTemp.getToken(1, GLOS_DELIM).startsWith("0"))
266 return sTemp.getToken(0, GLOS_DELIM);
268 return sTemp;
273 // select new group
274 IMPL_LINK(SwGlossaryDlg, GrpSelect, weld::TreeView&, rBox, void)
276 std::unique_ptr<weld::TreeIter> xEntry = rBox.make_iterator();
277 if (!rBox.get_selected(xEntry.get()))
278 return;
280 std::unique_ptr<weld::TreeIter> xParent = rBox.make_iterator(xEntry.get());
281 weld::TreeIter* pParent;
282 if (rBox.get_iter_depth(*xParent))
284 rBox.iter_parent(*xParent);
285 pParent = xParent.get();
287 else
288 pParent = xEntry.get();
289 GroupUserData* pGroupData = reinterpret_cast<GroupUserData*>(rBox.get_id(*pParent).toInt64());
290 ::SetCurrGlosGroup(pGroupData->sGroupName
291 + OUStringChar(GLOS_DELIM)
292 + OUString::number(pGroupData->nPathIdx));
293 m_pGlossaryHdl->SetCurGroup(::GetCurrGlosGroup());
294 // set current text block
295 m_bReadOnly = m_pGlossaryHdl->IsReadOnly();
296 EnableShortName( !m_bReadOnly );
297 m_xEditBtn->set_sensitive(!m_bReadOnly);
298 m_bIsOld = m_pGlossaryHdl->IsOld();
299 if( pParent != xEntry.get())
301 OUString aName(rBox.get_text(*xEntry));
302 m_xNameED->set_text(aName);
303 m_xShortNameEdit->set_text(rBox.get_id(*xEntry));
304 m_xInsertBtn->set_sensitive( !m_bIsDocReadOnly);
305 ShowAutoText(::GetCurrGlosGroup(), m_xShortNameEdit->get_text());
307 else
309 m_xNameED->set_text("");
310 m_xShortNameEdit->set_text("");
311 m_xShortNameEdit->set_sensitive(false);
312 ShowAutoText("", "");
314 // update controls
315 NameModify(*m_xShortNameEdit);
316 if( SfxRequest::HasMacroRecorder( m_pShell->GetView().GetViewFrame() ) )
318 SfxRequest aReq( m_pShell->GetView().GetViewFrame(), FN_SET_ACT_GLOSSARY );
319 aReq.AppendItem(SfxStringItem(FN_SET_ACT_GLOSSARY, getCurrentGlossary()));
320 aReq.Done();
324 short SwGlossaryDlg::run()
326 short nRet = SfxDialogController::run();
327 if (nRet == RET_OK)
328 Apply();
329 return nRet;
332 void SwGlossaryDlg::Apply()
334 const OUString aGlosName(m_xShortNameEdit->get_text());
335 if (!aGlosName.isEmpty())
337 m_pGlossaryHdl->InsertGlossary(aGlosName);
339 if( SfxRequest::HasMacroRecorder( m_pShell->GetView().GetViewFrame() ) )
341 SfxRequest aReq( m_pShell->GetView().GetViewFrame(), FN_INSERT_GLOSSARY );
342 aReq.AppendItem(SfxStringItem(FN_INSERT_GLOSSARY, getCurrentGlossary()));
343 aReq.AppendItem(SfxStringItem(FN_PARAM_1, aGlosName));
344 aReq.Done();
348 void SwGlossaryDlg::EnableShortName(bool bOn)
350 m_xShortNameLbl->set_sensitive(bOn);
351 m_xShortNameEdit->set_sensitive(bOn);
354 // does the title exist in the selected group?
355 std::unique_ptr<weld::TreeIter> SwGlossaryDlg::DoesBlockExist(const OUString& rBlock,
356 const OUString& rShort)
358 // look for possible entry in TreeListBox
359 std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
360 if (m_xCategoryBox->get_selected(xEntry.get()))
362 if (m_xCategoryBox->get_iter_depth(*xEntry))
363 m_xCategoryBox->iter_parent(*xEntry);
364 if (!m_xCategoryBox->iter_children(*xEntry))
365 return nullptr;
368 if (rBlock == m_xCategoryBox->get_text(*xEntry) &&
369 (rShort.isEmpty() ||
370 rShort == m_xCategoryBox->get_id(*xEntry))
373 return xEntry;
376 while (m_xCategoryBox->iter_next_sibling(*xEntry));
378 return nullptr;
381 IMPL_LINK(SwGlossaryDlg, NameModify, weld::Entry&, rEdit, void)
383 const OUString aName(m_xNameED->get_text());
384 bool bNameED = &rEdit == m_xNameED.get();
385 if( aName.isEmpty() )
387 if(bNameED)
388 m_xShortNameEdit->set_text(aName);
389 m_xInsertBtn->set_sensitive(false);
390 return;
392 const bool bNotFound = !DoesBlockExist(aName, bNameED ? OUString() : rEdit.get_text());
393 if(bNameED)
395 // did the text get in to the Listbox in the Edit with a click?
396 if(bNotFound)
398 m_xShortNameEdit->set_text( lcl_GetValidShortCut( aName ) );
399 EnableShortName();
401 else
403 m_xShortNameEdit->set_text(m_pGlossaryHdl->GetGlossaryShortName(aName));
404 EnableShortName(!m_bReadOnly);
406 m_xInsertBtn->set_sensitive(!bNotFound && !m_bIsDocReadOnly);
408 else
410 //ShortNameEdit
411 if(!bNotFound)
413 m_xInsertBtn->set_sensitive(!m_bIsDocReadOnly);
418 IMPL_LINK( SwGlossaryDlg, NameDoubleClick, weld::TreeView&, rBox, bool )
420 std::unique_ptr<weld::TreeIter> xEntry = rBox.make_iterator();
421 if (rBox.get_selected(xEntry.get()) && rBox.get_iter_depth(*xEntry) && !m_bIsDocReadOnly)
422 m_xDialog->response(RET_OK);
423 return true;
426 IMPL_LINK_NOARG( SwGlossaryDlg, EnableHdl, weld::ToggleButton&, void )
428 std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
429 bool bEntry = m_xCategoryBox->get_selected(xEntry.get());
431 const OUString aEditText(m_xNameED->get_text());
432 const bool bHasEntry = !aEditText.isEmpty() && !m_xShortNameEdit->get_text().isEmpty();
433 const bool bExists = nullptr != DoesBlockExist(aEditText, m_xShortNameEdit->get_text());
434 const bool bIsGroup = bEntry && !m_xCategoryBox->get_iter_depth(*xEntry);
435 m_xEditBtn->set_item_visible("new", m_bSelection && bHasEntry && !bExists);
436 m_xEditBtn->set_item_visible("newtext", m_bSelection && bHasEntry && !bExists);
437 m_xEditBtn->set_item_visible("copy", bExists && !bIsGroup);
438 m_xEditBtn->set_item_visible("replace", m_bSelection && bExists && !bIsGroup && !m_bIsOld );
439 m_xEditBtn->set_item_visible("replacetext", m_bSelection && bExists && !bIsGroup && !m_bIsOld );
440 m_xEditBtn->set_item_visible("edit", bExists && !bIsGroup );
441 m_xEditBtn->set_item_visible("rename", bExists && !bIsGroup );
442 m_xEditBtn->set_item_visible("delete", bExists && !bIsGroup );
443 m_xEditBtn->set_item_visible("macro", bExists && !bIsGroup && !m_bIsOld &&
444 !m_pGlossaryHdl->IsReadOnly() );
445 m_xEditBtn->set_item_visible("import", bIsGroup && !m_bIsOld && !m_pGlossaryHdl->IsReadOnly() );
448 IMPL_LINK(SwGlossaryDlg, MenuHdl, const OString&, rItemIdent, void)
450 if (rItemIdent == "edit")
452 std::unique_ptr<SwTextBlocks> pGroup = ::GetGlossaries()->GetGroupDoc ( GetCurrGrpName () );
453 pGroup.reset();
454 m_xDialog->response(RET_EDIT);
456 else if (rItemIdent == "replace")
458 m_pGlossaryHdl->NewGlossary(m_xNameED->get_text(),
459 m_xShortNameEdit->get_text());
461 else if (rItemIdent == "replacetext")
463 m_pGlossaryHdl->NewGlossary(m_xNameED->get_text(),
464 m_xShortNameEdit->get_text(),
465 false, true);
467 else if (rItemIdent == "new" || rItemIdent == "newtext")
469 bool bNoAttr = rItemIdent == "newtext";
471 const OUString aStr(m_xNameED->get_text());
472 const OUString aShortName(m_xShortNameEdit->get_text());
473 if(m_pGlossaryHdl->HasShortName(aShortName))
475 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
476 VclMessageType::Info, VclButtonsType::Ok,
477 SwResId(STR_DOUBLE_SHORTNAME)));
478 xInfoBox->run();
479 m_xShortNameEdit->select_region(0, -1);
480 m_xShortNameEdit->grab_focus();
482 if(m_pGlossaryHdl->NewGlossary(aStr, aShortName, false, bNoAttr ))
484 std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
485 if (!m_xCategoryBox->get_selected(xEntry.get()))
486 xEntry.reset();
487 else if (m_xCategoryBox->get_iter_depth(*xEntry))
488 m_xCategoryBox->iter_parent(*xEntry);
489 m_xCategoryBox->insert(xEntry.get(), -1, &aStr, &aShortName,
490 nullptr, nullptr, nullptr, false, nullptr);
492 m_xNameED->set_text(aStr);
493 m_xShortNameEdit->set_text(aShortName);
494 NameModify(*m_xNameED); // for toggling the buttons
496 if( SfxRequest::HasMacroRecorder( m_pShell->GetView().GetViewFrame() ) )
498 SfxRequest aReq(m_pShell->GetView().GetViewFrame(), FN_NEW_GLOSSARY);
499 aReq.AppendItem(SfxStringItem(FN_NEW_GLOSSARY, getCurrentGlossary()));
500 aReq.AppendItem(SfxStringItem(FN_PARAM_1, aShortName));
501 aReq.AppendItem(SfxStringItem(FN_PARAM_2, aStr));
502 aReq.Done();
506 else if (rItemIdent == "copy")
508 m_pGlossaryHdl->CopyToClipboard(*m_pShell, m_xShortNameEdit->get_text());
510 else if (rItemIdent == "rename")
512 m_xShortNameEdit->set_text(m_pGlossaryHdl->GetGlossaryShortName(m_xNameED->get_text()));
513 SwNewGlosNameDlg aNewNameDlg(this, m_xNameED->get_text(), m_xShortNameEdit->get_text());
514 if (aNewNameDlg.run() == RET_OK && m_pGlossaryHdl->Rename(m_xShortNameEdit->get_text(),
515 aNewNameDlg.GetNewShort(),
516 aNewNameDlg.GetNewName()))
518 std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
519 m_xCategoryBox->get_selected(xEntry.get());
520 std::unique_ptr<weld::TreeIter> xOldEntry = m_xCategoryBox->make_iterator(xEntry.get());
521 if (m_xCategoryBox->get_iter_depth(*xEntry))
522 m_xCategoryBox->iter_parent(*xEntry);
524 std::unique_ptr<weld::TreeIter> xNewEntry = m_xCategoryBox->make_iterator();
525 OUString sId(aNewNameDlg.GetNewShort());
526 OUString sName(aNewNameDlg.GetNewName());
528 m_xCategoryBox->insert(xEntry.get(), -1, &sName, &sId,
529 nullptr, nullptr, nullptr, false, xNewEntry.get());
531 m_xCategoryBox->remove(*xOldEntry);
532 m_xCategoryBox->select(*xNewEntry);
533 m_xCategoryBox->scroll_to_row(*xNewEntry);
535 GrpSelect(*m_xCategoryBox);
537 else if (rItemIdent == "delete")
539 DeleteEntry();
541 else if (rItemIdent == "macro")
543 SfxItemSet aSet( m_pShell->GetAttrPool(), svl::Items<RES_FRMMACRO, RES_FRMMACRO, SID_EVENTCONFIG, SID_EVENTCONFIG>{} );
545 SvxMacro aStart(OUString(), OUString(), STARBASIC);
546 SvxMacro aEnd(OUString(), OUString(), STARBASIC);
547 m_pGlossaryHdl->GetMacros(m_xShortNameEdit->get_text(), aStart, aEnd );
549 SvxMacroItem aItem(RES_FRMMACRO);
550 if( aStart.HasMacro() )
551 aItem.SetMacro( SvMacroItemId::SwStartInsGlossary, aStart );
552 if( aEnd.HasMacro() )
553 aItem.SetMacro( SvMacroItemId::SwEndInsGlossary, aEnd );
555 aSet.Put( aItem );
556 aSet.Put( SwMacroAssignDlg::AddEvents( MACASSGN_AUTOTEXT ) );
558 const SfxPoolItem* pItem;
559 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
560 ScopedVclPtr<SfxAbstractDialog> pMacroDlg(pFact->CreateEventConfigDialog(m_xDialog.get(), aSet,
561 m_pShell->GetView().GetViewFrame()->GetFrame().GetFrameInterface() ));
562 if ( pMacroDlg && pMacroDlg->Execute() == RET_OK &&
563 SfxItemState::SET == pMacroDlg->GetOutputItemSet()->GetItemState( RES_FRMMACRO, false, &pItem ) )
565 const SvxMacroTableDtor& rTable = static_cast<const SvxMacroItem*>(pItem)->GetMacroTable();
566 m_pGlossaryHdl->SetMacros( m_xShortNameEdit->get_text(),
567 rTable.Get( SvMacroItemId::SwStartInsGlossary ),
568 rTable.Get( SvMacroItemId::SwEndInsGlossary ) );
571 else if (rItemIdent == "import")
573 // call the FileOpenDialog do find WinWord - Files with templates
574 FileDialogHelper aDlgHelper(TemplateDescription::FILEOPEN_SIMPLE,
575 FileDialogFlags::NONE, m_xDialog.get());
576 uno::Reference < XFilePicker3 > xFP = aDlgHelper.GetFilePicker();
578 SvtPathOptions aPathOpt;
579 xFP->setDisplayDirectory(aPathOpt.GetWorkPath() );
581 SfxFilterMatcher aMatcher( SwDocShell::Factory().GetFactoryName() );
582 SfxFilterMatcherIter aIter( aMatcher );
583 std::shared_ptr<const SfxFilter> pFilter = aIter.First();
584 while ( pFilter )
586 if( pFilter->GetUserData() == FILTER_WW8 )
588 xFP->appendFilter( pFilter->GetUIName(),
589 pFilter->GetWildcard().getGlob() );
590 xFP->setCurrentFilter( pFilter->GetUIName() ) ;
592 else if( pFilter->GetUserData() == FILTER_DOCX )
594 xFP->appendFilter( pFilter->GetUIName(),
595 pFilter->GetWildcard().getGlob() );
596 xFP->setCurrentFilter( pFilter->GetUIName() ) ;
599 pFilter = aIter.Next();
602 if( aDlgHelper.Execute() == ERRCODE_NONE )
604 if( m_pGlossaryHdl->ImportGlossaries( xFP->getSelectedFiles().getConstArray()[0] ))
605 Init();
606 else
608 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
609 VclMessageType::Info, VclButtonsType::Ok,
610 SwResId(STR_NO_GLOSSARIES)));
611 xInfoBox->run();
617 // dialog manage regions
618 IMPL_LINK_NOARG(SwGlossaryDlg, BibHdl, weld::Button&, void)
620 SwGlossaries* pGloss = ::GetGlossaries();
621 if( pGloss->IsGlosPathErr() )
622 pGloss->ShowError();
623 else
625 //check if at least one glossary path is write enabled
626 SvtPathOptions aPathOpt;
627 const OUString& sGlosPath( aPathOpt.GetAutoTextPath() );
628 bool bIsWritable = false;
629 sal_Int32 nIdx {sGlosPath.isEmpty() ? -1 : 0};
630 while (nIdx>=0)
632 const OUString sPath = URIHelper::SmartRel2Abs(
633 INetURLObject(), sGlosPath.getToken(0, ';', nIdx),
634 URIHelper::GetMaybeFileHdl());
637 Content aTestContent( sPath,
638 uno::Reference< XCommandEnvironment >(),
639 comphelper::getProcessComponentContext() );
640 Any aAny = aTestContent.getPropertyValue( "IsReadOnly" );
641 if(aAny.hasValue())
643 bIsWritable = !*o3tl::doAccess<bool>(aAny);
646 catch (const Exception&)
649 if(bIsWritable)
650 break;
652 if(bIsWritable)
655 SwGlossaryGroupDlg aDlg(m_xDialog.get(), pGloss->GetPathArray(), m_pGlossaryHdl);
656 if (aDlg.run() == RET_OK)
658 Init();
659 //if new groups were created - select one of them
660 const OUString sNewGroup = aDlg.GetCreatedGroupName();
662 std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
663 bool bEntry = m_xCategoryBox->get_iter_first(*xEntry);
665 while (!sNewGroup.isEmpty() && bEntry)
667 if (!m_xCategoryBox->get_iter_depth(*xEntry))
669 GroupUserData* pGroupData = reinterpret_cast<GroupUserData*>(m_xCategoryBox->get_id(*xEntry).toInt64());
670 const OUString sGroup = pGroupData->sGroupName
671 + OUStringChar(GLOS_DELIM)
672 + OUString::number(pGroupData->nPathIdx);
673 if(sGroup == sNewGroup)
675 m_xCategoryBox->select(*xEntry);
676 m_xCategoryBox->scroll_to_row(*xEntry);
677 GrpSelect(*m_xCategoryBox);
678 break;
681 bEntry = m_xCategoryBox->iter_next(*xEntry);
686 else
688 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
689 VclMessageType::Question, VclButtonsType::YesNo,
690 m_sReadonlyPath));
691 if (RET_YES == xBox->run())
692 PathHdl(*m_xPathBtn);
697 // initialisation; from Ctor and after editing regions
698 void SwGlossaryDlg::Init()
700 m_xCategoryBox->freeze();
701 m_xCategoryBox->clear();
702 m_xGroupData.clear();
703 m_xCategoryBox->make_unsorted();
705 // display text block regions
706 const size_t nCnt = m_pGlossaryHdl->GetGroupCnt();
707 std::unique_ptr<weld::TreeIter> xSelEntry;
708 const OUString sSelStr(::GetCurrGlosGroup().getToken(0, GLOS_DELIM));
709 const sal_Int32 nSelPath = ::GetCurrGlosGroup().getToken(1, GLOS_DELIM).toInt32();
710 // #i66304# - "My AutoText" comes from mytexts.bau, but should be translated
711 const OUString sMyAutoTextEnglish("My AutoText");
712 const OUString sMyAutoTextTranslated(SwResId(STR_MY_AUTOTEXT));
713 for(size_t nId = 0; nId < nCnt; ++nId )
715 OUString sTitle;
716 OUString sGroupName(m_pGlossaryHdl->GetGroupName(nId, &sTitle));
717 if(sGroupName.isEmpty())
718 continue;
719 sal_Int32 nIdx{ 0 };
720 const OUString sName{ sGroupName.getToken( 0, GLOS_DELIM, nIdx ) };
721 if(sTitle.isEmpty())
722 sTitle = sName;
723 if(sTitle == sMyAutoTextEnglish)
724 sTitle = sMyAutoTextTranslated;
726 std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
727 m_xCategoryBox->append(xEntry.get());
728 m_xCategoryBox->set_text(*xEntry, sTitle, 0);
729 const sal_Int32 nPath = sGroupName.getToken( 0, GLOS_DELIM, nIdx ).toInt32();
731 GroupUserData* pData = new GroupUserData;
732 pData->sGroupName = sName;
733 pData->nPathIdx = static_cast< sal_uInt16 >(nPath);
734 pData->bReadonly = m_pGlossaryHdl->IsReadOnly(&sGroupName);
735 m_xGroupData.emplace_back(pData);
737 m_xCategoryBox->set_id(*xEntry, OUString::number(reinterpret_cast<sal_Int64>(pData)));
738 if (sSelStr == pData->sGroupName && nSelPath == nPath)
739 xSelEntry = m_xCategoryBox->make_iterator(xEntry.get());
741 // fill entries for the groups
743 m_pGlossaryHdl->SetCurGroup(sGroupName, false, true);
744 const sal_uInt16 nCount = m_pGlossaryHdl->GetGlossaryCnt();
745 for(sal_uInt16 i = 0; i < nCount; ++i)
747 OUString sEntryName = m_pGlossaryHdl->GetGlossaryName(i);
748 OUString sId = m_pGlossaryHdl->GetGlossaryShortName(i);
749 m_xCategoryBox->insert(xEntry.get(), -1, &sEntryName, &sId,
750 nullptr, nullptr, nullptr, false, nullptr);
754 // set current group and display text blocks
755 if (!xSelEntry)
757 //find a non-readonly group
758 std::unique_ptr<weld::TreeIter> xSearch = m_xCategoryBox->make_iterator();
759 if (m_xCategoryBox->get_iter_first(*xSearch))
763 if (!m_xCategoryBox->get_iter_depth(*xSearch))
765 GroupUserData* pData = reinterpret_cast<GroupUserData*>(m_xCategoryBox->get_id(*xSearch).toInt64());
766 if (!pData->bReadonly)
768 xSelEntry = std::move(xSearch);
769 break;
773 while (m_xCategoryBox->iter_next(*xSearch));
775 if (!xSelEntry)
777 xSelEntry = std::move(xSearch);
778 if (!m_xCategoryBox->get_iter_first(*xSelEntry))
779 xSelEntry.reset();
783 m_xCategoryBox->thaw();
784 m_xCategoryBox->make_sorted();
786 if (xSelEntry)
788 m_xCategoryBox->expand_row(*xSelEntry);
789 m_xCategoryBox->select(*xSelEntry);
790 m_xCategoryBox->scroll_to_row(*xSelEntry);
791 GrpSelect(*m_xCategoryBox);
794 const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
795 m_xFileRelCB->set_active( rCfg.IsSaveRelFile() );
796 m_xFileRelCB->connect_toggled(LINK(this, SwGlossaryDlg, CheckBoxHdl));
797 m_xNetRelCB->set_active( rCfg.IsSaveRelNet() );
798 m_xNetRelCB->connect_toggled(LINK(this, SwGlossaryDlg, CheckBoxHdl));
799 m_xInsertTipCB->set_active( rCfg.IsAutoTextTip() );
800 m_xInsertTipCB->set_sensitive(!officecfg::Office::Writer::AutoFunction::Text::ShowToolTip::isReadOnly());
801 m_xInsertTipCB->connect_toggled(LINK(this, SwGlossaryDlg, CheckBoxHdl));
804 // KeyInput for ShortName - Edits without Spaces
805 IMPL_LINK( SwNewGlosNameDlg, Modify, weld::Entry&, rBox, void )
807 OUString aName(m_xNewName->get_text());
808 SwGlossaryDlg* pDlg = m_pParent;
809 if (&rBox == m_xNewName.get())
810 m_xNewShort->set_text(lcl_GetValidShortCut(aName));
812 bool bEnable = !aName.isEmpty() && !m_xNewShort->get_text().isEmpty() &&
813 (!pDlg->DoesBlockExist(aName, m_xNewShort->get_text())
814 || aName == m_xOldName->get_text());
815 m_xOk->set_sensitive(bEnable);
818 IMPL_LINK_NOARG(SwNewGlosNameDlg, Rename, weld::Button&, void)
820 SwGlossaryDlg* pDlg = m_pParent;
821 OUString sNew = GetAppCharClass().uppercase(m_xNewShort->get_text());
822 if (pDlg->m_pGlossaryHdl->HasShortName(m_xNewShort->get_text())
823 && sNew != m_xOldShort->get_text())
825 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
826 VclMessageType::Info, VclButtonsType::Ok,
827 SwResId(STR_DOUBLE_SHORTNAME)));
828 xBox->run();
829 m_xNewShort->grab_focus();
831 else
832 m_xDialog->response(RET_OK);
835 IMPL_LINK(SwGlossaryDlg, CheckBoxHdl, weld::ToggleButton&, rBox, void)
837 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
838 bool bCheck = rBox.get_active();
839 if (&rBox == m_xInsertTipCB.get())
840 rCfg.SetAutoTextTip(bCheck);
841 else if (&rBox == m_xFileRelCB.get())
842 rCfg.SetSaveRelFile(bCheck);
843 else
844 rCfg.SetSaveRelNet(bCheck);
845 rCfg.Commit();
848 IMPL_LINK(SwGlossaryDlg, KeyInputHdl, const KeyEvent&, rKEvt, bool)
850 if (rKEvt.GetKeyCode().GetCode() == KEY_DELETE)
852 DeleteEntry();
853 return true;
855 return false;
858 OUString SwGlossaryDlg::GetCurrGrpName() const
860 std::unique_ptr<weld::TreeIter> xEntry = m_xCategoryBox->make_iterator();
861 if (m_xCategoryBox->get_selected(xEntry.get()))
863 if (m_xCategoryBox->get_iter_depth(*xEntry))
864 m_xCategoryBox->iter_parent(*xEntry);
865 GroupUserData* pGroupData = reinterpret_cast<GroupUserData*>(m_xCategoryBox->get_id(*xEntry).toInt64());
866 return pGroupData->sGroupName + OUStringChar(GLOS_DELIM) + OUString::number(pGroupData->nPathIdx);
868 return OUString();
871 IMPL_LINK_NOARG( SwGlossaryDlg, PathHdl, weld::Button&, void )
873 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
874 ScopedVclPtr<AbstractSvxMultiPathDialog> pDlg(pFact->CreateSvxPathSelectDialog(m_xDialog.get()));
875 SvtPathOptions aPathOpt;
876 const OUString sGlosPath( aPathOpt.GetAutoTextPath() );
877 pDlg->SetPath(sGlosPath);
878 if(RET_OK == pDlg->Execute())
880 const OUString sTmp(pDlg->GetPath());
881 if(sTmp != sGlosPath)
883 aPathOpt.SetAutoTextPath( sTmp );
884 ::GetGlossaries()->UpdateGlosPath( true );
885 Init();
890 IMPL_LINK_NOARG(SwGlossaryDlg, InsertHdl, weld::Button&, void)
892 m_xDialog->response(RET_OK);
895 void SwGlossaryDlg::ShowPreview()
897 ShowAutoText(::GetCurrGlosGroup(), m_xShortNameEdit->get_text());
900 IMPL_LINK_NOARG(SwGlossaryDlg, PreviewLoadedHdl, SwOneExampleFrame&, void)
902 ResumeShowAutoText();
905 void SwGlossaryDlg::ShowAutoText(const OUString& rGroup, const OUString& rShortName)
907 if (m_xExampleFrameWin->get_visible())
909 SetResumeData(rGroup, rShortName);
910 //try to make an Undo()
911 m_xExampleFrame->ClearDocument();
915 void SwGlossaryDlg::ResumeShowAutoText()
917 OUString sGroup;
918 OUString sShortName;
919 if(GetResumeData(sGroup, sShortName) && m_xExampleFrameWin->get_visible())
921 if(!m_xAutoText.is())
923 //now the AutoText ListBoxes have to be filled
924 m_xAutoText = text::AutoTextContainer::create( comphelper::getProcessComponentContext() );
927 uno::Reference< XTextCursor > & xCursor = m_xExampleFrame->GetTextCursor();
928 if(xCursor.is())
930 if (!sShortName.isEmpty())
932 uno::Any aGroup = m_xAutoText->getByName(sGroup);
933 uno::Reference< XAutoTextGroup > xGroup;
934 if((aGroup >>= xGroup) && xGroup->hasByName(sShortName))
936 uno::Any aEntry(xGroup->getByName(sShortName));
937 uno::Reference< XAutoTextEntry > xEntry;
938 aEntry >>= xEntry;
939 xEntry->applyTo(xCursor);
944 m_bResume = false;
947 void SwGlossaryDlg::DeleteEntry()
949 bool bEntry = m_xCategoryBox->get_selected(nullptr);
951 const OUString aTitle(m_xNameED->get_text());
952 const OUString aShortName(m_xShortNameEdit->get_text());
954 std::unique_ptr<weld::TreeIter> xParent;
955 std::unique_ptr<weld::TreeIter> xChild = DoesBlockExist(aTitle, aShortName);
956 if (xChild && m_xCategoryBox->get_iter_depth(*xChild))
958 xParent = m_xCategoryBox->make_iterator(xChild.get());
959 m_xCategoryBox->iter_parent(*xParent);
962 const bool bExists = nullptr != xChild;
963 const bool bIsGroup = bEntry && !xParent;
965 std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(m_xDialog.get(),
966 VclMessageType::Question, VclButtonsType::YesNo,
967 SwResId(STR_QUERY_DELETE)));
968 if (bExists && !bIsGroup && RET_YES == xQuery->run())
970 if (!aTitle.isEmpty() && m_pGlossaryHdl->DelGlossary(aShortName))
972 OSL_ENSURE(xChild, "entry not found!");
973 m_xCategoryBox->select(*xParent);
974 m_xCategoryBox->remove(*xChild);
975 m_xNameED->set_text(OUString());
976 NameModify(*m_xNameED);
981 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */