1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
50 #include <swtypes.hxx>
54 #include <glossary.hxx>
55 #include <gloshdl.hxx>
56 #include <glosbib.hxx>
58 #include <glosdoc.hxx>
59 #include <macassgn.hxx>
60 #include <swevent.hxx>
62 #include <shellio.hxx>
66 #include <globals.hrc>
67 #include <swmodule.hxx>
68 #include <sfx2/filedlghelper.hxx>
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();
94 while( rName
[nStart
-1]==' ' && nStart
< nSz
)
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();
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
;
132 DECL_LINK(Modify
, weld::Entry
&, void);
133 DECL_LINK(Rename
, weld::Button
&, void);
134 DECL_LINK(TextFilterHdl
, OUString
&, bool);
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
);
151 SwNewGlosNameDlg::SwNewGlosNameDlg(SwGlossaryDlg
* pParent
, const OUString
& rOldName
, const OUString
& rOldShort
)
152 : GenericDialogController(pParent
->getDialog(), "modules/swriter/ui/renameautotextdialog.ui", "RenameAutoTextDialog")
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
);
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
)
195 , m_bSelection(pWrtShell
->IsSelection())
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
));
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);
253 SwGlossaryDlg::~SwGlossaryDlg()
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
);
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()))
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();
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());
309 m_xNameED
->set_text("");
310 m_xShortNameEdit
->set_text("");
311 m_xShortNameEdit
->set_sensitive(false);
312 ShowAutoText("", "");
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()));
324 short SwGlossaryDlg::run()
326 short nRet
= SfxDialogController::run();
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
));
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
))
368 if (rBlock
== m_xCategoryBox
->get_text(*xEntry
) &&
370 rShort
== m_xCategoryBox
->get_id(*xEntry
))
376 while (m_xCategoryBox
->iter_next_sibling(*xEntry
));
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() )
388 m_xShortNameEdit
->set_text(aName
);
389 m_xInsertBtn
->set_sensitive(false);
392 const bool bNotFound
= !DoesBlockExist(aName
, bNameED
? OUString() : rEdit
.get_text());
395 // did the text get in to the Listbox in the Edit with a click?
398 m_xShortNameEdit
->set_text( lcl_GetValidShortCut( aName
) );
403 m_xShortNameEdit
->set_text(m_pGlossaryHdl
->GetGlossaryShortName(aName
));
404 EnableShortName(!m_bReadOnly
);
406 m_xInsertBtn
->set_sensitive(!bNotFound
&& !m_bIsDocReadOnly
);
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
);
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 () );
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(),
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
)));
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()))
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
));
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")
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
);
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();
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] ))
608 std::unique_ptr
<weld::MessageDialog
> xInfoBox(Application::CreateMessageDialog(m_xDialog
.get(),
609 VclMessageType::Info
, VclButtonsType::Ok
,
610 SwResId(STR_NO_GLOSSARIES
)));
617 // dialog manage regions
618 IMPL_LINK_NOARG(SwGlossaryDlg
, BibHdl
, weld::Button
&, void)
620 SwGlossaries
* pGloss
= ::GetGlossaries();
621 if( pGloss
->IsGlosPathErr() )
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};
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" );
643 bIsWritable
= !*o3tl::doAccess
<bool>(aAny
);
646 catch (const Exception
&)
655 SwGlossaryGroupDlg
aDlg(m_xDialog
.get(), pGloss
->GetPathArray(), m_pGlossaryHdl
);
656 if (aDlg
.run() == RET_OK
)
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
);
681 bEntry
= m_xCategoryBox
->iter_next(*xEntry
);
688 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(m_xDialog
.get(),
689 VclMessageType::Question
, VclButtonsType::YesNo
,
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
)
716 OUString
sGroupName(m_pGlossaryHdl
->GetGroupName(nId
, &sTitle
));
717 if(sGroupName
.isEmpty())
720 const OUString sName
{ sGroupName
.getToken( 0, GLOS_DELIM
, nIdx
) };
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
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
);
773 while (m_xCategoryBox
->iter_next(*xSearch
));
777 xSelEntry
= std::move(xSearch
);
778 if (!m_xCategoryBox
->get_iter_first(*xSelEntry
))
783 m_xCategoryBox
->thaw();
784 m_xCategoryBox
->make_sorted();
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
)));
829 m_xNewShort
->grab_focus();
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
);
844 rCfg
.SetSaveRelNet(bCheck
);
848 IMPL_LINK(SwGlossaryDlg
, KeyInputHdl
, const KeyEvent
&, rKEvt
, bool)
850 if (rKEvt
.GetKeyCode().GetCode() == KEY_DELETE
)
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
);
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 );
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()
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();
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
;
939 xEntry
->applyTo(xCursor
);
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: */