summaryrefslogtreecommitdiffstats
path: root/sw/source/ui/fldui
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/ui/fldui')
-rw-r--r--sw/source/ui/fldui/DateFormFieldDialog.cxx126
-rw-r--r--sw/source/ui/fldui/DropDownFieldDialog.cxx142
-rw-r--r--sw/source/ui/fldui/DropDownFormFieldDialog.cxx200
-rw-r--r--sw/source/ui/fldui/changedb.cxx258
-rw-r--r--sw/source/ui/fldui/flddb.cxx541
-rw-r--r--sw/source/ui/fldui/flddb.hxx83
-rw-r--r--sw/source/ui/fldui/flddinf.cxx483
-rw-r--r--sw/source/ui/fldui/flddinf.hxx68
-rw-r--r--sw/source/ui/fldui/flddok.cxx641
-rw-r--r--sw/source/ui/fldui/flddok.hxx72
-rw-r--r--sw/source/ui/fldui/fldedt.cxx336
-rw-r--r--sw/source/ui/fldui/fldfunc.cxx614
-rw-r--r--sw/source/ui/fldui/fldfunc.hxx95
-rw-r--r--sw/source/ui/fldui/fldpage.cxx348
-rw-r--r--sw/source/ui/fldui/fldpage.hxx89
-rw-r--r--sw/source/ui/fldui/fldref.cxx1154
-rw-r--r--sw/source/ui/fldui/fldref.hxx93
-rw-r--r--sw/source/ui/fldui/fldtdlg.cxx307
-rw-r--r--sw/source/ui/fldui/fldvar.cxx1250
-rw-r--r--sw/source/ui/fldui/fldvar.hxx84
-rw-r--r--sw/source/ui/fldui/inpdlg.cxx176
-rw-r--r--sw/source/ui/fldui/javaedit.cxx253
22 files changed, 7413 insertions, 0 deletions
diff --git a/sw/source/ui/fldui/DateFormFieldDialog.cxx b/sw/source/ui/fldui/DateFormFieldDialog.cxx
new file mode 100644
index 000000000..24461c47d
--- /dev/null
+++ b/sw/source/ui/fldui/DateFormFieldDialog.cxx
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <DateFormFieldDialog.hxx>
+#include <IMark.hxx>
+#include <xmloff/odffields.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <doc.hxx>
+
+namespace sw
+{
+DateFormFieldDialog::DateFormFieldDialog(weld::Widget* pParent,
+ sw::mark::IDateFieldmark* pDateField, SwDoc& rDoc)
+ : GenericDialogController(pParent, "modules/swriter/ui/dateformfielddialog.ui",
+ "DateFormFieldDialog")
+ , m_pDateField(pDateField)
+ , m_pNumberFormatter(rDoc.GetNumberFormatter())
+ , m_xFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("date_formats_treeview")))
+{
+ m_xFormatLB->SetFormatType(SvNumFormatType::DATE);
+ m_xFormatLB->SetAutomaticLanguage(true);
+ m_xFormatLB->SetShowLanguageControl(true);
+ m_xFormatLB->SetOneArea(true);
+
+ // Set a default height
+ weld::TreeView& rTreeView = dynamic_cast<weld::TreeView&>(m_xFormatLB->get_widget());
+ rTreeView.set_size_request(rTreeView.get_preferred_size().Width(),
+ rTreeView.get_height_rows(10));
+ InitControls();
+}
+
+DateFormFieldDialog::~DateFormFieldDialog() {}
+
+void DateFormFieldDialog::Apply()
+{
+ if (m_pDateField == nullptr)
+ return;
+
+ // Try to find out the current date value and replace the content
+ // with the right formatted date string
+ sw::mark::IFieldmark::parameter_map_t* pParameters = m_pDateField->GetParameters();
+ const SvNumberformat* pFormat = m_pNumberFormatter->GetEntry(m_xFormatLB->GetFormat());
+
+ // Get date value first
+ std::pair<bool, double> aResult = m_pDateField->GetCurrentDate();
+
+ // Then set the date format
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT] <<= pFormat->GetFormatstring();
+ (*pParameters)[ODF_FORMDATE_DATEFORMAT_LANGUAGE]
+ <<= LanguageTag(pFormat->GetLanguage()).getBcp47();
+
+ // Update current date
+ if (aResult.first)
+ {
+ m_pDateField->SetCurrentDate(aResult.second);
+ }
+ else
+ {
+ (*pParameters)[ODF_FORMDATE_CURRENTDATE] <<= OUString();
+ }
+}
+
+void DateFormFieldDialog::InitControls()
+{
+ if (m_pDateField == nullptr)
+ return;
+
+ sw::mark::IFieldmark::parameter_map_t* pParameters = m_pDateField->GetParameters();
+
+ OUString sFormatString;
+ auto pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sFormatString;
+ }
+
+ OUString sLang;
+ pResult = pParameters->find(ODF_FORMDATE_DATEFORMAT_LANGUAGE);
+ if (pResult != pParameters->end())
+ {
+ pResult->second >>= sLang;
+ }
+
+ if (sFormatString.isEmpty() || sLang.isEmpty())
+ return;
+
+ LanguageType aLangType = LanguageTag(sLang).getLanguageType();
+ sal_uInt32 nFormat = m_pNumberFormatter->GetEntryKey(sFormatString, aLangType);
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ sal_Int32 nCheckPos = 0;
+ SvNumFormatType nType;
+ m_pNumberFormatter->PutEntry(sFormatString, nCheckPos, nType, nFormat,
+ LanguageTag(sLang).getLanguageType());
+ }
+
+ if (aLangType == LANGUAGE_DONTKNOW || nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ return;
+
+ if (m_xFormatLB->GetCurLanguage() == aLangType)
+ {
+ m_xFormatLB->SetAutomaticLanguage(true);
+ }
+ else
+ {
+ m_xFormatLB->SetAutomaticLanguage(false);
+ m_xFormatLB->SetLanguage(aLangType);
+
+ // Change format and change back for regenerating the list
+ m_xFormatLB->SetFormatType(SvNumFormatType::ALL);
+ m_xFormatLB->SetFormatType(SvNumFormatType::DATE);
+ }
+ m_xFormatLB->SetDefFormat(nFormat);
+}
+
+} // namespace sw
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sw/source/ui/fldui/DropDownFieldDialog.cxx b/sw/source/ui/fldui/DropDownFieldDialog.cxx
new file mode 100644
index 000000000..d85bc5365
--- /dev/null
+++ b/sw/source/ui/fldui/DropDownFieldDialog.cxx
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <wrtsh.hxx>
+#include <fldbas.hxx>
+#include <DropDownFieldDialog.hxx>
+#include <flddropdown.hxx>
+
+#include <memory>
+
+using namespace ::com::sun::star;
+
+// edit insert-field
+sw::DropDownFieldDialog::DropDownFieldDialog(weld::Widget *pParent, SwWrtShell &rS,
+ SwField* pField, bool bPrevButton, bool bNextButton)
+ : GenericDialogController(pParent, "modules/swriter/ui/dropdownfielddialog.ui", "DropdownFieldDialog")
+ , m_rSh( rS )
+ , m_pDropField(nullptr)
+ , m_pPressedButton(nullptr)
+ , m_xListItemsLB(m_xBuilder->weld_tree_view("list"))
+ , m_xOKPB(m_xBuilder->weld_button("ok"))
+ , m_xPrevPB(m_xBuilder->weld_button("prev"))
+ , m_xNextPB(m_xBuilder->weld_button("next"))
+ , m_xEditPB(m_xBuilder->weld_button("edit"))
+{
+ m_xListItemsLB->set_size_request(m_xListItemsLB->get_approximate_digit_width() * 24,
+ m_xListItemsLB->get_height_rows(12));
+ Link<weld::TreeView&, bool> aDoubleLk = LINK(this, DropDownFieldDialog, DoubleClickHdl);
+ m_xListItemsLB->connect_row_activated( aDoubleLk );
+
+ Link<weld::Button&, void> aEditButtonLk = LINK(this, DropDownFieldDialog, EditHdl);
+ Link<weld::Button&,void> aPrevButtonLk = LINK(this, DropDownFieldDialog, PrevHdl);
+ Link<weld::Button&, void> aNextButtonLk = LINK(this, DropDownFieldDialog, NextHdl);
+ m_xEditPB->connect_clicked(aEditButtonLk);
+ if( bPrevButton || bNextButton )
+ {
+ m_xPrevPB->show();
+ m_xPrevPB->connect_clicked(aPrevButtonLk);
+ m_xPrevPB->set_sensitive(bPrevButton);
+
+ m_xNextPB->show();
+ m_xNextPB->connect_clicked(aNextButtonLk);
+ m_xNextPB->set_sensitive(bNextButton);
+ }
+ if( SwFieldIds::Dropdown == pField->GetTyp()->Which() )
+ {
+
+ m_pDropField = static_cast<SwDropDownField*>(pField);
+ OUString sTitle = m_xDialog->get_title() +
+ m_pDropField->GetPar2();
+ m_xDialog->set_title(sTitle);
+ const uno::Sequence< OUString > aItems = m_pDropField->GetItemSequence();
+ for (const OUString& rItem : aItems)
+ m_xListItemsLB->append_text(rItem);
+ m_xListItemsLB->select_text(m_pDropField->GetSelectedItem());
+ }
+
+ bool bEnable = !m_rSh.IsCursorReadonly();
+ m_xOKPB->set_sensitive(bEnable);
+
+ m_xListItemsLB->grab_focus();
+}
+
+sw::DropDownFieldDialog::~DropDownFieldDialog()
+{
+}
+
+void sw::DropDownFieldDialog::Apply()
+{
+ if (!m_pDropField)
+ return;
+
+ OUString sSelect = m_xListItemsLB->get_selected_text();
+ if (m_pDropField->GetPar1() == sSelect)
+ return;
+
+ m_rSh.StartAllAction();
+
+ std::unique_ptr<SwDropDownField> const pCopy(
+ static_cast<SwDropDownField*>(m_pDropField->CopyField().release()));
+
+ pCopy->SetPar1(sSelect);
+ m_rSh.SwEditShell::UpdateOneField(*pCopy);
+
+ m_rSh.SetUndoNoResetModified();
+ m_rSh.EndAllAction();
+}
+
+bool sw::DropDownFieldDialog::PrevButtonPressed() const
+{
+ return m_pPressedButton == m_xPrevPB.get();
+}
+
+bool sw::DropDownFieldDialog::NextButtonPressed() const
+{
+ return m_pPressedButton == m_xNextPB.get();
+}
+
+IMPL_LINK_NOARG(sw::DropDownFieldDialog, EditHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xEditPB.get();
+ m_xDialog->response(RET_YES);
+}
+
+IMPL_LINK_NOARG(sw::DropDownFieldDialog, PrevHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xPrevPB.get();
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(sw::DropDownFieldDialog, NextHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xNextPB.get();
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(sw::DropDownFieldDialog, DoubleClickHdl, weld::TreeView&, bool)
+{
+ // tdf#114144, when next is available make double-click accept and go to next field
+ if (m_xNextPB->get_visible() && m_xNextPB->get_sensitive())
+ m_pPressedButton = m_xNextPB.get();
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/DropDownFormFieldDialog.cxx b/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
new file mode 100644
index 000000000..2115bbda4
--- /dev/null
+++ b/sw/source/ui/fldui/DropDownFormFieldDialog.cxx
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <DropDownFormFieldDialog.hxx>
+#include <vcl/event.hxx>
+#include <IMark.hxx>
+#include <xmloff/odffields.hxx>
+#include <vcl/svapp.hxx>
+#include <strings.hrc>
+#include <swtypes.hxx>
+
+namespace sw
+{
+DropDownFormFieldDialog::DropDownFormFieldDialog(weld::Widget* pParent,
+ mark::IFieldmark* pDropDownField)
+ : GenericDialogController(pParent, "modules/swriter/ui/dropdownformfielddialog.ui",
+ "DropDownFormFieldDialog")
+ , m_pDropDownField(pDropDownField)
+ , m_bListHasChanged(false)
+ , m_xListItemEntry(m_xBuilder->weld_entry("item_entry"))
+ , m_xListAddButton(m_xBuilder->weld_button("add_button"))
+ , m_xListItemsTreeView(m_xBuilder->weld_tree_view("items_treeview"))
+ , m_xListRemoveButton(m_xBuilder->weld_button("remove_button"))
+ , m_xListUpButton(m_xBuilder->weld_button("up_button"))
+ , m_xListDownButton(m_xBuilder->weld_button("down_button"))
+{
+ m_xListItemEntry->connect_key_press(LINK(this, DropDownFormFieldDialog, KeyPressedHdl));
+ m_xListItemEntry->connect_changed(LINK(this, DropDownFormFieldDialog, EntryChangedHdl));
+
+ m_xListItemsTreeView->set_size_request(m_xListItemEntry->get_preferred_size().Width(),
+ m_xListItemEntry->get_preferred_size().Height() * 5);
+ m_xListItemsTreeView->connect_changed(LINK(this, DropDownFormFieldDialog, ListChangedHdl));
+
+ Link<weld::Button&, void> aPushButtonLink(LINK(this, DropDownFormFieldDialog, ButtonPushedHdl));
+ m_xListAddButton->connect_clicked(aPushButtonLink);
+ m_xListRemoveButton->connect_clicked(aPushButtonLink);
+ m_xListUpButton->connect_clicked(aPushButtonLink);
+ m_xListDownButton->connect_clicked(aPushButtonLink);
+
+ InitControls();
+}
+
+DropDownFormFieldDialog::~DropDownFormFieldDialog() {}
+
+IMPL_LINK_NOARG(DropDownFormFieldDialog, ListChangedHdl, weld::TreeView&, void) { UpdateButtons(); }
+
+IMPL_LINK(DropDownFormFieldDialog, KeyPressedHdl, const KeyEvent&, rEvent, bool)
+{
+ if (rEvent.GetKeyCode().GetCode() == KEY_RETURN && !m_xListItemEntry->get_text().isEmpty())
+ {
+ AppendItemToList();
+ return true;
+ }
+ return false;
+}
+
+IMPL_LINK_NOARG(DropDownFormFieldDialog, EntryChangedHdl, weld::Entry&, void) { UpdateButtons(); }
+
+IMPL_LINK(DropDownFormFieldDialog, ButtonPushedHdl, weld::Button&, rButton, void)
+{
+ if (&rButton == m_xListAddButton.get())
+ {
+ AppendItemToList();
+ }
+ else if (m_xListItemsTreeView->get_selected_index() != -1)
+ {
+ int nSelPos = m_xListItemsTreeView->get_selected_index();
+ if (&rButton == m_xListRemoveButton.get())
+ {
+ m_xListItemsTreeView->remove(nSelPos);
+ if (m_xListItemsTreeView->n_children() > 0)
+ m_xListItemsTreeView->select(nSelPos ? nSelPos - 1 : 0);
+ }
+ else if (&rButton == m_xListUpButton.get())
+ {
+ const OUString sEntry = m_xListItemsTreeView->get_selected_text();
+ m_xListItemsTreeView->remove(nSelPos);
+ nSelPos--;
+ m_xListItemsTreeView->insert_text(nSelPos, sEntry);
+ m_xListItemsTreeView->select(nSelPos);
+ }
+ else if (&rButton == m_xListDownButton.get())
+ {
+ const OUString sEntry = m_xListItemsTreeView->get_selected_text();
+ m_xListItemsTreeView->remove(nSelPos);
+ nSelPos++;
+ m_xListItemsTreeView->insert_text(nSelPos, sEntry);
+ m_xListItemsTreeView->select(nSelPos);
+ }
+ m_bListHasChanged = true;
+ }
+ UpdateButtons();
+}
+
+void DropDownFormFieldDialog::InitControls()
+{
+ if (m_pDropDownField != nullptr)
+ {
+ const mark::IFieldmark::parameter_map_t* const pParameters
+ = m_pDropDownField->GetParameters();
+
+ auto pListEntries = pParameters->find(ODF_FORMDROPDOWN_LISTENTRY);
+ if (pListEntries != pParameters->end())
+ {
+ css::uno::Sequence<OUString> vListEntries;
+ pListEntries->second >>= vListEntries;
+ for (const OUString& rItem : std::as_const(vListEntries))
+ m_xListItemsTreeView->append_text(rItem);
+
+ // Select the current one
+ auto pResult = pParameters->find(ODF_FORMDROPDOWN_RESULT);
+ if (pResult != pParameters->end())
+ {
+ sal_Int32 nSelection = -1;
+ pResult->second >>= nSelection;
+ if (nSelection >= 0 && nSelection < vListEntries.getLength())
+ m_xListItemsTreeView->select_text(vListEntries[nSelection]);
+ }
+ }
+ }
+ UpdateButtons();
+}
+
+void DropDownFormFieldDialog::AppendItemToList()
+{
+ if (!m_xListAddButton->get_sensitive())
+ return;
+
+ if (m_xListItemsTreeView->n_children() >= ODF_FORMDROPDOWN_ENTRY_COUNT_LIMIT)
+ {
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(
+ m_xDialog.get(), VclMessageType::Info, VclButtonsType::Ok,
+ SwResId(STR_DROP_DOWN_FIELD_ITEM_LIMIT)));
+ xInfoBox->run();
+ return;
+ }
+
+ const OUString sEntry(m_xListItemEntry->get_text());
+ if (!sEntry.isEmpty())
+ {
+ m_xListItemsTreeView->append_text(sEntry);
+ m_xListItemsTreeView->select_text(sEntry);
+ m_bListHasChanged = true;
+
+ // Clear entry
+ m_xListItemEntry->set_text(OUString());
+ m_xListItemEntry->grab_focus();
+ }
+ UpdateButtons();
+}
+
+void DropDownFormFieldDialog::UpdateButtons()
+{
+ m_xListAddButton->set_sensitive(!m_xListItemEntry->get_text().isEmpty()
+ && m_xListItemsTreeView->find_text(m_xListItemEntry->get_text())
+ == -1);
+
+ int nSelPos = m_xListItemsTreeView->get_selected_index();
+ m_xListRemoveButton->set_sensitive(nSelPos != -1);
+ m_xListUpButton->set_sensitive(nSelPos > 0);
+ m_xListDownButton->set_sensitive(nSelPos != -1
+ && nSelPos < m_xListItemsTreeView->n_children() - 1);
+}
+
+void DropDownFormFieldDialog::Apply()
+{
+ if (!(m_pDropDownField != nullptr && m_bListHasChanged))
+ return;
+
+ mark::IFieldmark::parameter_map_t* pParameters = m_pDropDownField->GetParameters();
+
+ css::uno::Sequence<OUString> vListEntries(m_xListItemsTreeView->n_children());
+ auto vListEntriesRange = asNonConstRange(vListEntries);
+ for (int nIndex = 0; nIndex < m_xListItemsTreeView->n_children(); ++nIndex)
+ {
+ vListEntriesRange[nIndex] = m_xListItemsTreeView->get_text(nIndex);
+ }
+
+ if (m_xListItemsTreeView->n_children() != 0)
+ {
+ (*pParameters)[ODF_FORMDROPDOWN_LISTENTRY] <<= vListEntries;
+ }
+ else
+ {
+ pParameters->erase(ODF_FORMDROPDOWN_LISTENTRY);
+ }
+
+ // After editing the drop down field's list we don't specify the selected item
+ pParameters->erase(ODF_FORMDROPDOWN_RESULT);
+}
+
+} // namespace sw
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sw/source/ui/fldui/changedb.cxx b/sw/source/ui/fldui/changedb.cxx
new file mode 100644
index 000000000..1fa9e140f
--- /dev/null
+++ b/sw/source/ui/fldui/changedb.cxx
@@ -0,0 +1,258 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <com/sun/star/sdb/CommandType.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <dbmgr.hxx>
+#include <changedb.hxx>
+
+#include <strings.hrc>
+#include <bitmaps.hlst>
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdb;
+using namespace ::com::sun::star::uno;
+
+// edit insert-field
+SwChangeDBDlg::SwChangeDBDlg(SwView const & rVw)
+ : SfxDialogController(rVw.GetViewFrame()->GetFrameWeld(), "modules/swriter/ui/exchangedatabases.ui",
+ "ExchangeDatabasesDialog")
+ , pSh(rVw.GetWrtShellPtr())
+ , m_xUsedDBTLB(m_xBuilder->weld_tree_view("inuselb"))
+ , m_xAvailDBTLB(new SwDBTreeList(m_xBuilder->weld_tree_view("availablelb")))
+ , m_xAddDBPB(m_xBuilder->weld_button("browse"))
+ , m_xDocDBNameFT(m_xBuilder->weld_label("dbnameft"))
+ , m_xDefineBT(m_xBuilder->weld_button("ok"))
+{
+ int nWidth = m_xUsedDBTLB->get_approximate_digit_width() * 25;
+ int nHeight = m_xUsedDBTLB->get_height_rows(8);
+ m_xUsedDBTLB->set_size_request(nWidth, nHeight);
+ m_xAvailDBTLB->set_size_request(nWidth, nHeight);
+
+ m_xAvailDBTLB->SetWrtShell(*pSh);
+ FillDBPopup();
+
+ ShowDBName(pSh->GetDBData());
+ m_xDefineBT->connect_clicked(LINK(this, SwChangeDBDlg, ButtonHdl));
+ m_xAddDBPB->connect_clicked(LINK(this, SwChangeDBDlg, AddDBHdl));
+
+ m_xUsedDBTLB->set_selection_mode(SelectionMode::Multiple);
+ m_xUsedDBTLB->make_sorted();
+
+ Link<weld::TreeView&,void> aLink = LINK(this, SwChangeDBDlg, TreeSelectHdl);
+
+ m_xUsedDBTLB->connect_changed(aLink);
+ m_xAvailDBTLB->connect_changed(aLink);
+ TreeSelect();
+}
+
+// initialise database listboxes
+void SwChangeDBDlg::FillDBPopup()
+{
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference<XDatabaseContext> xDBContext = DatabaseContext::create(xContext);
+ const SwDBData& rDBData = pSh->GetDBData();
+ m_xAvailDBTLB->Select(rDBData.sDataSource, rDBData.sCommand, u"");
+ TreeSelect();
+
+ Sequence< OUString > aDBNames = xDBContext->getElementNames();
+ auto aAllDBNames = comphelper::sequenceToContainer<std::vector<OUString>>(aDBNames);
+
+ std::vector<OUString> aDBNameList;
+ pSh->GetAllUsedDB( aDBNameList, &aAllDBNames );
+
+ size_t nCount = aDBNameList.size();
+ m_xUsedDBTLB->clear();
+ std::unique_ptr<weld::TreeIter> xFirst;
+
+ for(size_t k = 0; k < nCount; k++)
+ {
+ std::unique_ptr<weld::TreeIter> xLast = Insert(o3tl::getToken(aDBNameList[k], 0, ';'));
+ if (!xFirst)
+ xFirst = std::move(xLast);
+ }
+
+ if (xFirst)
+ {
+ m_xUsedDBTLB->expand_row(*xFirst);
+ m_xUsedDBTLB->scroll_to_row(*xFirst);
+ m_xUsedDBTLB->select(*xFirst);
+ }
+}
+
+std::unique_ptr<weld::TreeIter> SwChangeDBDlg::Insert(std::u16string_view rDBName)
+{
+ sal_Int32 nIdx{ 0 };
+ const OUString sDBName(o3tl::getToken(rDBName, 0, DB_DELIM, nIdx));
+ const OUString sTableName(o3tl::getToken(rDBName, 0, DB_DELIM, nIdx));
+ OUString sUserData( o3tl::getToken(rDBName, 0, DB_DELIM, nIdx) );
+ sal_Int32 nCommandType = sUserData.toInt32();
+
+ const OUString & rToInsert ( nCommandType ? RID_BMP_DBQUERY : RID_BMP_DBTABLE );
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xUsedDBTLB->make_iterator());
+ if (m_xUsedDBTLB->get_iter_first(*xIter))
+ {
+ do
+ {
+ if (sDBName == m_xUsedDBTLB->get_text(*xIter))
+ {
+ if (m_xUsedDBTLB->iter_has_child(*xIter))
+ {
+ std::unique_ptr<weld::TreeIter> xChild(m_xUsedDBTLB->make_iterator(xIter.get()));
+ if (m_xUsedDBTLB->iter_children(*xChild))
+ {
+ do
+ {
+ if (sTableName == m_xUsedDBTLB->get_text(*xChild))
+ return xChild;
+ } while (m_xUsedDBTLB->iter_next_sibling(*xChild));
+ }
+ }
+ m_xUsedDBTLB->insert(xIter.get(), -1, &sTableName, &sUserData, nullptr, nullptr,
+ false, xIter.get());
+ m_xUsedDBTLB->set_image(*xIter, rToInsert);
+ return xIter;
+ }
+ } while (m_xUsedDBTLB->iter_next_sibling(*xIter));
+ }
+
+ m_xUsedDBTLB->insert(nullptr, -1, &sDBName, nullptr, nullptr, nullptr,
+ false, xIter.get());
+ m_xUsedDBTLB->set_image(*xIter, RID_BMP_DB);
+ m_xUsedDBTLB->insert(xIter.get(), -1, &sTableName, &sUserData, nullptr, nullptr,
+ false, xIter.get());
+ m_xUsedDBTLB->set_image(*xIter, rToInsert);
+ return xIter;
+}
+
+// destroy dialog
+SwChangeDBDlg::~SwChangeDBDlg()
+{
+}
+
+short SwChangeDBDlg::run()
+{
+ short nRet = SfxDialogController::run();
+ if (nRet == RET_OK)
+ UpdateFields();
+ return nRet;
+}
+
+void SwChangeDBDlg::UpdateFields()
+{
+ std::vector<OUString> aDBNames;
+
+ m_xUsedDBTLB->selected_foreach([this, &aDBNames](weld::TreeIter& rEntry){
+ if (m_xUsedDBTLB->get_iter_depth(rEntry))
+ {
+ std::unique_ptr<weld::TreeIter> xIter(m_xUsedDBTLB->make_iterator(&rEntry));
+ m_xUsedDBTLB->iter_parent(*xIter);
+ OUString sTmp(m_xUsedDBTLB->get_text(*xIter) +
+ OUStringChar(DB_DELIM) + m_xUsedDBTLB->get_text(rEntry) + OUStringChar(DB_DELIM) +
+ m_xUsedDBTLB->get_id(rEntry));
+ aDBNames.push_back(sTmp);
+ }
+ return false;
+ });
+
+ pSh->StartAllAction();
+ OUString sTableName;
+ OUString sColumnName;
+ sal_Bool bIsTable = false;
+ const OUString DBName(m_xAvailDBTLB->GetDBName(sTableName, sColumnName, &bIsTable));
+ const OUString sTemp = DBName
+ + OUStringChar(DB_DELIM)
+ + sTableName
+ + OUStringChar(DB_DELIM)
+ + OUString::number(bIsTable
+ ? CommandType::TABLE
+ : CommandType::QUERY);
+ pSh->ChangeDBFields( aDBNames, sTemp);
+ pSh->EndAllAction();
+}
+
+IMPL_LINK_NOARG(SwChangeDBDlg, ButtonHdl, weld::Button&, void)
+{
+ OUString sTableName;
+ OUString sColumnName;
+ SwDBData aData;
+ sal_Bool bIsTable = false;
+ aData.sDataSource = m_xAvailDBTLB->GetDBName(sTableName, sColumnName, &bIsTable);
+ aData.sCommand = sTableName;
+ aData.nCommandType = bIsTable ? 0 : 1;
+ pSh->ChgDBData(aData);
+ ShowDBName(pSh->GetDBData());
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SwChangeDBDlg, TreeSelectHdl, weld::TreeView&, void)
+{
+ TreeSelect();
+}
+
+void SwChangeDBDlg::TreeSelect()
+{
+ bool bEnable = false;
+ std::unique_ptr<weld::TreeIter> xIter(m_xAvailDBTLB->make_iterator());
+ if (m_xAvailDBTLB->get_selected(xIter.get()))
+ {
+ if (m_xAvailDBTLB->get_iter_depth(*xIter))
+ bEnable = true;
+ }
+ m_xDefineBT->set_sensitive(bEnable);
+}
+
+
+// convert database name for display
+void SwChangeDBDlg::ShowDBName(const SwDBData& rDBData)
+{
+ if (rDBData.sDataSource.isEmpty() && rDBData.sCommand.isEmpty())
+ {
+ m_xDocDBNameFT->set_label(SwResId(SW_STR_NONE));
+ }
+ else
+ {
+ const OUString sName(rDBData.sDataSource + "." + rDBData.sCommand);
+ m_xDocDBNameFT->set_label(sName.replaceAll("~", "~~"));
+ }
+}
+
+IMPL_LINK_NOARG(SwChangeDBDlg, AddDBHdl, weld::Button&, void)
+{
+ const OUString sNewDB = SwDBManager::LoadAndRegisterDataSource(m_xDialog.get());
+ if (!sNewDB.isEmpty())
+ {
+ m_xAvailDBTLB->AddDataSource(sNewDB);
+ TreeSelect();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddb.cxx b/sw/source/ui/fldui/flddb.cxx
new file mode 100644
index 000000000..62dd538f0
--- /dev/null
+++ b/sw/source/ui/fldui/flddb.cxx
@@ -0,0 +1,541 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <dbfld.hxx>
+#include <doc.hxx>
+
+#include "flddb.hxx"
+#include <dbconfig.hxx>
+#include <dbmgr.hxx>
+#include <o3tl/string_view.hxx>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+SwFieldDBPage::SwFieldDBPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet)
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/flddbpage.ui", "FieldDbPage", pCoreSet)
+ , m_nOldFormat(0)
+ , m_nOldSubType(0)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xDatabaseTLB(new SwDBTreeList(m_xBuilder->weld_tree_view("select")))
+ , m_xAddDBPB(m_xBuilder->weld_button("browse"))
+ , m_xCondition(m_xBuilder->weld_widget("condgroup"))
+ , m_xConditionED(new ConditionEdit(m_xBuilder->weld_entry("condition")))
+ , m_xValue(m_xBuilder->weld_widget("recgroup"))
+ , m_xValueED(m_xBuilder->weld_entry("recnumber"))
+ , m_xDBFormatRB(m_xBuilder->weld_radio_button("fromdatabasecb"))
+ , m_xNewFormatRB(m_xBuilder->weld_radio_button("userdefinedcb"))
+ , m_xNumFormatLB(new NumFormatListBox(m_xBuilder->weld_combo_box("numformat")))
+ , m_xFormatLB(m_xBuilder->weld_combo_box("format"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+{
+ SetTypeSel(-1); //TODO
+
+ m_xTypeLB->make_sorted();
+ m_xFormatLB->make_sorted();
+
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_xTypeLB->get_height_rows(10);
+ m_xTypeLB->set_size_request(nWidth, nHeight);
+ m_xDatabaseTLB->set_size_request(nWidth*2, nHeight);
+
+ m_xNumFormatLB->connect_changed(LINK(this, SwFieldDBPage, NumSelectHdl));
+ m_xDatabaseTLB->connect_changed(LINK(this, SwFieldDBPage, TreeSelectHdl));
+ m_xDatabaseTLB->connect_row_activated(LINK(this, SwFieldDBPage, TreeViewInsertHdl));
+
+ m_xValueED->connect_changed(LINK(this, SwFieldDBPage, ModifyHdl));
+ m_xAddDBPB->connect_clicked(LINK(this, SwFieldDBPage, AddDBHdl));
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-db");
+ m_xNumFormatLB->set_buildable_name(m_xNumFormatLB->get_buildable_name() + "-db");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-db");
+}
+
+SwFieldDBPage::~SwFieldDBPage()
+{
+ // If we have no stored SwWrtShell, it means we didn't do anything useful - no need to revoke.
+ if (SwWrtShell* pSh = CheckAndGetWrtShell())
+ {
+ // This would cleanup in the case of cancelled dialog
+ SwDBManager* pDbManager = pSh->GetDoc()->GetDBManager();
+ if (pDbManager)
+ pDbManager->RevokeLastRegistrations();
+ }
+}
+
+// initialise TabPage
+void SwFieldDBPage::Reset(const SfxItemSet*)
+{
+ Init(); // general initialization
+
+ const sal_Int32 nOldPos = m_xTypeLB->get_selected_index();
+ m_xTypeLB->freeze();
+ m_sOldDBName = m_xDatabaseTLB->GetDBName(m_sOldTableName, m_sOldColumnName);
+
+ m_xTypeLB->clear();
+
+ if (!IsFieldEdit())
+ {
+ // initialise TypeListBox
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ for(sal_uInt16 i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ const SwFieldTypesEnum nTypeId = SwFieldMgr::GetTypeId(i);
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ }
+ }
+ else
+ {
+ const SwFieldTypesEnum nTypeId = GetCurField()->GetTypeId();
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)),
+ SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId)));
+ }
+
+ m_xTypeLB->thaw();
+
+ // select old Pos
+ if (GetTypeSel() != -1)
+ m_xTypeLB->select(GetTypeSel());
+
+ m_xFormatLB->clear();
+
+ const sal_uInt16 nSize = GetFieldMgr().GetFormatCount(SwFieldTypesEnum::DatabaseSetNumber, IsFieldDlgHtmlMode());
+ for( sal_uInt16 i = 0; i < nSize; ++i )
+ {
+ const sal_uInt16 nFormatId = GetFieldMgr().GetFormatId( SwFieldTypesEnum::DatabaseSetNumber, i );
+ OUString sId(OUString::number(nFormatId));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(SwFieldTypesEnum::DatabaseSetNumber, i));
+ if (SVX_NUM_ARABIC == nFormatId)
+ m_xFormatLB->set_active_id(sId);
+ }
+
+ if (!IsFieldEdit())
+ {
+ if (nOldPos != -1)
+ m_xTypeLB->select(nOldPos);
+
+ if (!m_sOldDBName.isEmpty())
+ {
+ m_xDatabaseTLB->Select(m_sOldDBName, m_sOldTableName, m_sOldColumnName);
+ }
+ else
+ {
+ if (SwWrtShell *pSh = CheckAndGetWrtShell())
+ {
+ SwDBData aTmp(pSh->GetDBData());
+ m_xDatabaseTLB->Select(aTmp.sDataSource, aTmp.sCommand, u"");
+ }
+ }
+ }
+
+ if( !IsRefresh() )
+ {
+ const OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if (o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ const sal_uInt16 nVal = o3tl::narrowing<sal_uInt16>(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ if (nVal != USHRT_MAX)
+ {
+ for (sal_Int32 i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ m_xTypeLB->select(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ TypeHdl(nullptr);
+
+ m_xTypeLB->connect_changed(LINK(this, SwFieldDBPage, TypeListBoxHdl));
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldDBPage, TreeViewInsertHdl));
+
+ if (IsFieldEdit())
+ {
+ m_xConditionED->save_value();
+ m_xValueED->save_value();
+ m_sOldDBName = m_xDatabaseTLB->GetDBName(m_sOldTableName, m_sOldColumnName);
+ m_nOldFormat = GetCurField()->GetFormat();
+ m_nOldSubType = GetCurField()->GetSubType();
+ }
+}
+
+// SwFieldDBPage may ask for password to select current document's data source,
+// so only do that when activating the page, not when dialog is creating all pages
+bool SwFieldDBPage::DeferResetToFirstActivation() { return true; }
+
+bool SwFieldDBPage::FillItemSet(SfxItemSet* )
+{
+ OUString sTableName;
+ OUString sColumnName;
+ SwDBData aData;
+ sal_Bool bIsTable;
+ aData.sDataSource = m_xDatabaseTLB->GetDBName(sTableName, sColumnName, &bIsTable);
+ aData.sCommand = sTableName;
+ aData.nCommandType = bIsTable ? 0 : 1;
+
+ if (SwWrtShell *pSh = CheckAndGetWrtShell())
+ {
+ SwDBManager* pDbManager = pSh->GetDoc()->GetDBManager();
+ if (pDbManager)
+ pDbManager->CommitLastRegistrations();
+
+ if (aData.sDataSource.isEmpty())
+ aData = pSh->GetDBData();
+ }
+
+ if(!aData.sDataSource.isEmpty()) // without database no new field command
+ {
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ sal_uLong nFormat = 0;
+ sal_uInt16 nSubType = 0;
+
+ OUString sDBName = aData.sDataSource
+ + OUStringChar(DB_DELIM)
+ + aData.sCommand
+ + OUStringChar(DB_DELIM)
+ + OUString::number(aData.nCommandType)
+ + OUStringChar(DB_DELIM);
+ if (!sColumnName.isEmpty())
+ {
+ sDBName += sColumnName + OUStringChar(DB_DELIM);
+ }
+ OUString aName = sDBName + m_xConditionED->get_text();
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Database:
+ nFormat = m_xNumFormatLB->GetFormat();
+ if (m_xNewFormatRB->get_sensitive() && m_xNewFormatRB->get_active())
+ nSubType = nsSwExtendedSubType::SUB_OWN_FMT;
+ aName = sDBName;
+ break;
+
+ case SwFieldTypesEnum::DatabaseSetNumber:
+ nFormat = m_xFormatLB->get_active_id().toUInt32();
+ break;
+ default: break;
+ }
+
+ const OUString aVal(m_xValueED->get_text());
+ OUString sTempTableName;
+ OUString sTempColumnName;
+ OUString sTempDBName = m_xDatabaseTLB->GetDBName(sTempTableName, sTempColumnName);
+ bool bDBListBoxChanged = m_sOldDBName != sTempDBName ||
+ m_sOldTableName != sTempTableName || m_sOldColumnName != sTempColumnName;
+ if (!IsFieldEdit() ||
+ m_xConditionED->get_value_changed_from_saved() ||
+ m_xValueED->get_saved_value() != aVal ||
+ bDBListBoxChanged ||
+ m_nOldFormat != nFormat || m_nOldSubType != nSubType)
+ {
+ InsertField( nTypeId, nSubType, aName, aVal, nFormat);
+ }
+ }
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldDBPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet )
+{
+ return std::make_unique<SwFieldDBPage>( pPage, pController, pAttrSet );
+}
+
+sal_uInt16 SwFieldDBPage::GetGroup()
+{
+ return GRP_DB;
+}
+
+IMPL_LINK( SwFieldDBPage, TypeListBoxHdl, weld::TreeView&, rBox, void )
+{
+ TypeHdl(&rBox);
+}
+
+void SwFieldDBPage::TypeHdl(const weld::TreeView* pBox)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if (GetTypeSel() == -1)
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+
+ if (nOld == GetTypeSel())
+ return;
+
+ bool bCond = false, bSetNo = false, bFormat = false, bDBFormat = false;
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ m_xDatabaseTLB->ShowColumns(nTypeId == SwFieldTypesEnum::Database);
+
+ if (IsFieldEdit())
+ {
+ SwDBData aData;
+ OUString sColumnName;
+ if (nTypeId == SwFieldTypesEnum::Database)
+ {
+ if (auto const*const pField = dynamic_cast<SwDBField*>(GetCurField()))
+ {
+ aData = pField->GetDBData();
+ sColumnName = static_cast<SwDBFieldType*>(GetCurField()->GetTyp())->GetColumnName();
+ }
+ }
+ else
+ {
+ if (auto *const pField = dynamic_cast<SwDBNameInfField*>(GetCurField()))
+ {
+ if(SwWrtShell *pSh = CheckAndGetWrtShell())
+ aData = pField->GetDBData(pSh->GetDoc());
+ }
+ }
+ m_xDatabaseTLB->Select(aData.sDataSource, aData.sCommand, sColumnName);
+ }
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Database:
+ {
+ bFormat = true;
+ bDBFormat = true;
+ m_xNumFormatLB->show();
+ m_xFormatLB->hide();
+
+ weld::Widget& rWidget = m_xNumFormatLB->get_widget();
+ rWidget.set_accessible_relation_labeled_by(m_xNewFormatRB.get());
+
+ if (pBox) // type was changed by user
+ m_xDBFormatRB->set_active(true);
+
+ if (IsFieldEdit())
+ {
+ if (GetCurField()->GetFormat() != 0 && GetCurField()->GetFormat() != SAL_MAX_UINT32)
+ m_xNumFormatLB->SetDefFormat(GetCurField()->GetFormat());
+
+ if (GetCurField()->GetSubType() & nsSwExtendedSubType::SUB_OWN_FMT)
+ m_xNewFormatRB->set_active(true);
+ else
+ m_xDBFormatRB->set_active(true);
+ }
+ break;
+ }
+ case SwFieldTypesEnum::DatabaseNumberSet:
+ bSetNo = true;
+ [[fallthrough]];
+ case SwFieldTypesEnum::DatabaseNextSet:
+ bCond = true;
+ if (IsFieldEdit())
+ {
+ m_xConditionED->set_text(GetCurField()->GetPar1());
+ m_xValueED->set_text(GetCurField()->GetPar2());
+ }
+ break;
+
+ case SwFieldTypesEnum::DatabaseName:
+ break;
+
+ case SwFieldTypesEnum::DatabaseSetNumber:
+ {
+ bFormat = true;
+ m_xNewFormatRB->set_active(true);
+ m_xNumFormatLB->hide();
+ m_xFormatLB->show();
+
+ m_xFormatLB->set_accessible_relation_labeled_by(m_xNewFormatRB.get());
+
+ if( IsFieldEdit() )
+ {
+ for (sal_Int32 nI = m_xFormatLB->get_count(); nI;)
+ {
+ if (GetCurField()->GetFormat() == m_xFormatLB->get_id(--nI).toUInt32())
+ {
+ m_xFormatLB->set_active( nI );
+ break;
+ }
+ }
+ }
+ break;
+ }
+ default: break;
+ }
+
+ m_xCondition->set_sensitive(bCond);
+ m_xValue->set_sensitive(bSetNo);
+ if (nTypeId != SwFieldTypesEnum::Database)
+ {
+ m_xDBFormatRB->set_sensitive(bDBFormat);
+ m_xNewFormatRB->set_sensitive(bDBFormat || bFormat);
+ m_xNumFormatLB->set_sensitive(bDBFormat);
+ m_xFormatLB->set_sensitive(bFormat);
+ }
+ m_xFormat->set_sensitive(bDBFormat || bFormat);
+
+ if (!IsFieldEdit())
+ {
+ m_xValueED->set_text(OUString());
+ if (bCond)
+ m_xConditionED->set_text("TRUE");
+ else
+ m_xConditionED->set_text(OUString());
+ }
+
+ CheckInsert();
+}
+
+IMPL_LINK_NOARG(SwFieldDBPage, NumSelectHdl, weld::ComboBox&, void)
+{
+ m_xNewFormatRB->set_active(true);
+ m_xNumFormatLB->CallSelectHdl();
+}
+
+void SwFieldDBPage::CheckInsert()
+{
+ bool bInsert = true;
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xDatabaseTLB->make_iterator());
+ if (m_xDatabaseTLB->get_selected(xIter.get()))
+ {
+ bool bEntry = m_xDatabaseTLB->iter_parent(*xIter);
+
+ if (nTypeId == SwFieldTypesEnum::Database && bEntry)
+ bEntry = m_xDatabaseTLB->iter_parent(*xIter);
+
+ bInsert &= bEntry;
+ }
+ else
+ bInsert = false;
+
+ if (nTypeId == SwFieldTypesEnum::DatabaseNumberSet)
+ {
+ bool bHasValue = !m_xValueED->get_text().isEmpty();
+
+ bInsert &= bHasValue;
+ }
+
+ EnableInsert(bInsert);
+}
+
+IMPL_LINK(SwFieldDBPage, TreeSelectHdl, weld::TreeView&, rBox, void)
+{
+ std::unique_ptr<weld::TreeIter> xIter(rBox.make_iterator());
+ if (!rBox.get_selected(xIter.get()))
+ return;
+
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ bool bEntry = m_xDatabaseTLB->iter_parent(*xIter);
+
+ if (nTypeId == SwFieldTypesEnum::Database && bEntry)
+ bEntry = m_xDatabaseTLB->iter_parent(*xIter);
+
+ CheckInsert();
+
+ if (nTypeId != SwFieldTypesEnum::Database)
+ return;
+
+ bool bNumFormat = false;
+
+ if (bEntry)
+ {
+ OUString sTableName;
+ OUString sColumnName;
+ sal_Bool bIsTable;
+ OUString sDBName = m_xDatabaseTLB->GetDBName(sTableName, sColumnName, &bIsTable);
+ bNumFormat = GetFieldMgr().IsDBNumeric(sDBName,
+ sTableName,
+ bIsTable,
+ sColumnName);
+ if (!IsFieldEdit())
+ m_xDBFormatRB->set_active(true);
+ }
+
+ m_xDBFormatRB->set_sensitive(bNumFormat);
+ m_xNewFormatRB->set_sensitive(bNumFormat);
+ m_xNumFormatLB->set_sensitive(bNumFormat);
+ m_xFormat->set_sensitive(bNumFormat);
+}
+
+IMPL_LINK_NOARG(SwFieldDBPage, AddDBHdl, weld::Button&, void)
+{
+ if (SwWrtShell* pSh = CheckAndGetWrtShell())
+ {
+ OUString sNewDB
+ = SwDBManager::LoadAndRegisterDataSource(GetFrameWeld(), pSh->GetDoc()->GetDocShell());
+ if (!sNewDB.isEmpty())
+ {
+ m_xDatabaseTLB->AddDataSource(sNewDB);
+ }
+ }
+}
+
+// Modify
+IMPL_LINK_NOARG(SwFieldDBPage, ModifyHdl, weld::Entry&, void)
+{
+ CheckInsert();
+}
+
+void SwFieldDBPage::FillUserData()
+{
+ const sal_Int32 nEntryPos = m_xTypeLB->get_selected_index();
+ const sal_uInt16 nTypeSel = ( -1 == nEntryPos )
+ ? USHRT_MAX : m_xTypeLB->get_id(nEntryPos).toUInt32();
+ SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel ));
+}
+
+void SwFieldDBPage::ActivateMailMergeAddress()
+{
+ m_xTypeLB->select_id(OUString::number(static_cast<sal_uInt16>(SwFieldTypesEnum::Database)));
+ TypeListBoxHdl(*m_xTypeLB);
+ const SwDBData& rData = SW_MOD()->GetDBConfig()->GetAddressSource();
+ m_xDatabaseTLB->Select(rData.sDataSource, rData.sCommand, u"");
+}
+
+void SwFieldDBPage::SetWrtShell(SwWrtShell& rSh)
+{
+ // We need to remember the shell to be able to call correct SwDBManager
+ SwFieldPage::SetWrtShell(&rSh);
+ m_xDatabaseTLB->SetWrtShell(rSh);
+}
+
+SwWrtShell* SwFieldDBPage::CheckAndGetWrtShell()
+{
+ SwWrtShell* pSh = GetWrtShell();
+ if (!pSh)
+ {
+ pSh = ::GetActiveWrtShell();
+ if (pSh) // this is not guaranteed: e.g., activating print preview with dialog active
+ SetWrtShell(*pSh);
+ }
+ return pSh;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddb.hxx b/sw/source/ui/fldui/flddb.hxx
new file mode 100644
index 000000000..b25c38699
--- /dev/null
+++ b/sw/source/ui/fldui/flddb.hxx
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDDB_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDDB_HXX
+
+#include <condedit.hxx>
+#include <dbtree.hxx>
+#include <numfmtlb.hxx>
+
+#include "fldpage.hxx"
+
+class SwFieldDBPage : public SwFieldPage
+{
+ OUString m_sOldDBName;
+ OUString m_sOldTableName;
+ OUString m_sOldColumnName;
+ sal_uLong m_nOldFormat;
+ sal_uInt16 m_nOldSubType;
+
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<SwDBTreeList> m_xDatabaseTLB;
+ std::unique_ptr<weld::Button> m_xAddDBPB;
+ std::unique_ptr<weld::Widget> m_xCondition;
+ std::unique_ptr<ConditionEdit> m_xConditionED;
+ std::unique_ptr<weld::Widget> m_xValue;
+ std::unique_ptr<weld::Entry> m_xValueED;
+ std::unique_ptr<weld::RadioButton> m_xDBFormatRB;
+ std::unique_ptr<weld::RadioButton> m_xNewFormatRB;
+ std::unique_ptr<NumFormatListBox> m_xNumFormatLB;
+ std::unique_ptr<weld::ComboBox> m_xFormatLB;
+ std::unique_ptr<weld::Widget> m_xFormat;
+
+ DECL_LINK( TypeListBoxHdl, weld::TreeView&, void );
+ DECL_LINK( NumSelectHdl, weld::ComboBox&, void );
+ DECL_LINK( TreeSelectHdl, weld::TreeView&, void );
+ DECL_LINK( ModifyHdl, weld::Entry&, void );
+ DECL_LINK( AddDBHdl, weld::Button&, void );
+ void TypeHdl(const weld::TreeView*);
+
+ void CheckInsert();
+
+ using SwFieldPage::SetWrtShell;
+ SwWrtShell* CheckAndGetWrtShell();
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldDBPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual ~SwFieldDBPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool DeferResetToFirstActivation() override;
+
+ virtual void FillUserData() override;
+ void ActivateMailMergeAddress();
+
+ void SetWrtShell(SwWrtShell& rSh);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddinf.cxx b/sw/source/ui/fldui/flddinf.cxx
new file mode 100644
index 000000000..c96cfbc0c
--- /dev/null
+++ b/sw/source/ui/fldui/flddinf.cxx
@@ -0,0 +1,483 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/frame.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <swtypes.hxx>
+#include <flddinf.hrc>
+#include <strings.hrc>
+#include <fldbas.hxx>
+#include <docufld.hxx>
+#include <wrtsh.hxx>
+#include <cmdid.h>
+
+#include "flddinf.hxx"
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/util/Time.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/util/Date.hpp>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+using namespace nsSwDocInfoSubType;
+using namespace com::sun::star;
+
+void FillFieldSelect(weld::TreeView& rListBox)
+{
+ for (size_t i = 0; i < SAL_N_ELEMENTS(FLD_SELECT); ++i)
+ rListBox.append_text(SwResId(FLD_SELECT[i]));
+}
+
+SwFieldDokInfPage::SwFieldDokInfPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet)
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/flddocinfopage.ui", "FieldDocInfoPage", pCoreSet)
+ , nOldSel(0)
+ , nOldFormat(0)
+ , m_xTypeTLB(m_xBuilder->weld_tree_view("type"))
+ , m_xSelection(m_xBuilder->weld_widget("selectframe"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("format")))
+ , m_xFixedCB(m_xBuilder->weld_check_button("fixed"))
+{
+ m_xTypeTLB->make_sorted();
+ FillFieldSelect(*m_xSelectionLB);
+
+ auto nWidth = m_xTypeTLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_xTypeTLB->get_height_rows(10);
+ m_xTypeTLB->set_size_request(nWidth, nHeight);
+ m_xFormatLB->get_widget().set_size_request(nWidth * 2, nHeight);
+ m_xSelectionLB->set_size_request(nWidth, nHeight);
+
+ //enable 'active' language selection
+ m_xFormatLB->SetShowLanguageControl(true);
+
+ const SfxUnoAnyItem* pItem = pCoreSet
+ ? pCoreSet->GetItem(FN_FIELD_DIALOG_DOC_PROPS, false)
+ : nullptr;
+ if ( pItem )
+ pItem->GetValue() >>= xCustomPropertySet;
+
+ // uitests
+ m_xTypeTLB->set_buildable_name(m_xTypeTLB->get_buildable_name() + "-docinf");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-docinf");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-docinf");
+}
+
+SwFieldDokInfPage::~SwFieldDokInfPage()
+{
+}
+
+void SwFieldDokInfPage::Reset(const SfxItemSet* )
+{
+ Init(); // general initialisation
+
+ // initialise TypeListBox
+ m_xTypeTLB->freeze();
+ m_xTypeTLB->clear();
+ m_xSelEntry.reset();
+
+ // display SubTypes in TypeLB
+ sal_uInt16 nSubType = USHRT_MAX;
+ if (IsFieldEdit())
+ {
+ const SwField* pCurField = GetCurField();
+ nSubType = pCurField->GetSubType() & 0xff;
+ if( nSubType == DI_CUSTOM )
+ {
+ if (auto const pField = dynamic_cast<SwDocInfoField const*>(pCurField))
+ {
+ m_sOldCustomFieldName = pField->GetName();
+ }
+ }
+ m_xFormatLB->SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
+ SwWrtShell *pSh = GetWrtShell();
+ if(pSh)
+ {
+ const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
+ if(pFormat)
+ m_xFormatLB->SetLanguage(pFormat->GetLanguage());
+ }
+ }
+
+ sal_Int32 nSelEntryData = -1;
+ const OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if (o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ nSelEntryData = o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx));
+ }
+
+ std::vector<OUString> aLst;
+ GetFieldMgr().GetSubTypes(SwFieldTypesEnum::DocumentInfo, aLst);
+ std::unique_ptr<weld::TreeIter> xEntry(m_xTypeTLB->make_iterator());
+ std::unique_ptr<weld::TreeIter> xExpandEntry;
+ for(size_t i = 0; i < aLst.size(); ++i)
+ {
+ if (!IsFieldEdit() || nSubType == i)
+ {
+ const OUString sId(OUString::number(i));
+ if (DI_CUSTOM == i)
+ {
+ if(xCustomPropertySet.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo > xSetInfo = xCustomPropertySet->getPropertySetInfo();
+ const uno::Sequence< beans::Property > rProperties = xSetInfo->getProperties();
+
+ if( rProperties.hasElements() )
+ {
+ std::unique_ptr<weld::TreeIter> xInfo(m_xTypeTLB->make_iterator());
+
+ OUString sText(SwResId(STR_CUSTOM_FIELD));
+ OUString sEntryId(OUString::number(USHRT_MAX));
+ m_xTypeTLB->insert(nullptr, -1, &sText, &sEntryId, nullptr,
+ nullptr, false, xInfo.get());
+ for (const auto& rProperty : rProperties)
+ {
+ const OUString sEntry = rProperty.Name;
+
+ m_xTypeTLB->insert(xInfo.get(), -1, &sEntry, &sId,
+ nullptr, nullptr, false, xEntry.get());
+ if (m_sOldCustomFieldName == sEntry)
+ {
+ m_xSelEntry = m_xTypeTLB->make_iterator(xEntry.get());
+ xExpandEntry = m_xTypeTLB->make_iterator(xInfo.get());
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (!(IsFieldDlgHtmlMode() && (i == DI_EDIT || i == DI_SUBJECT || i == DI_PRINT)))
+ {
+ m_xTypeTLB->insert(nullptr, -1, &aLst[i], &sId,
+ nullptr, nullptr, false, xEntry.get());
+ }
+ }
+ if (static_cast<size_t>(nSelEntryData) == i)
+ m_xSelEntry = std::move(xEntry);
+ }
+ }
+
+ m_xTypeTLB->thaw();
+
+ if (xExpandEntry)
+ m_xTypeTLB->expand_row(*xExpandEntry);
+
+ // select old Pos
+ if (m_xSelEntry)
+ {
+ m_xTypeTLB->select(*m_xSelEntry);
+ nSubType = m_xTypeTLB->get_id(*m_xSelEntry).toUInt32();
+ }
+ else
+ {
+ m_xSelEntry = m_xTypeTLB->make_iterator();
+ if (m_xTypeTLB->get_iter_first(*m_xSelEntry))
+ nSubType = m_xTypeTLB->get_id(*m_xSelEntry).toUInt32();
+ else
+ m_xSelEntry.reset();
+ }
+
+ FillSelectionLB(nSubType);
+ if (m_xSelEntry)
+ TypeHdl(*m_xTypeTLB);
+
+ m_xTypeTLB->connect_changed(LINK(this, SwFieldDokInfPage, TypeHdl));
+ m_xTypeTLB->connect_row_activated(LINK(this, SwFieldDokInfPage, TreeViewInsertHdl));
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldDokInfPage, SubTypeHdl));
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldDokInfPage, TreeViewInsertHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldDokInfPage, TreeViewInsertHdl));
+
+ if (IsFieldEdit())
+ {
+ nOldSel = m_xSelectionLB->get_selected_index();
+ nOldFormat = GetCurField()->GetFormat();
+ m_xFixedCB->save_state();
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldDokInfPage, TypeHdl, weld::TreeView&, void)
+{
+ // current ListBoxPos
+ if (!m_xTypeTLB->get_selected(m_xSelEntry.get()) &&
+ m_xTypeTLB->get_iter_first(*m_xSelEntry))
+ {
+ m_xTypeTLB->select(*m_xSelEntry);
+ }
+ FillSelectionLB(m_xTypeTLB->get_id(*m_xSelEntry).toUInt32());
+ SubTypeHdl(*m_xSelectionLB);
+}
+
+IMPL_LINK_NOARG(SwFieldDokInfPage, SubTypeHdl, weld::TreeView&, void)
+{
+ sal_uInt16 nSubType = m_xTypeTLB->get_id(*m_xSelEntry).toUInt32();
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ sal_uInt16 nExtSubType;
+ SvNumFormatType nNewType = SvNumFormatType::ALL;
+
+ if (nSubType != DI_EDIT)
+ {
+ if (nPos == -1)
+ {
+ if (!m_xSelectionLB->n_children())
+ {
+ m_xFormatLB->clear();
+ m_xFormat->set_sensitive(false);
+ if( nSubType == DI_CUSTOM )
+ {
+ //find out which type the custom field has - for a start set to DATE format
+ const OUString sName = m_xTypeTLB->get_text(*m_xSelEntry);
+ try
+ {
+ uno::Any aVal = xCustomPropertySet->getPropertyValue( sName );
+ const uno::Type& rValueType = aVal.getValueType();
+ if( rValueType == ::cppu::UnoType<util::DateTime>::get())
+ {
+ nNewType = SvNumFormatType::DATETIME;
+ }
+ else if( rValueType == ::cppu::UnoType<util::Date>::get())
+ {
+ nNewType = SvNumFormatType::DATE;
+ }
+ else if( rValueType == ::cppu::UnoType<util::Time>::get())
+ {
+ nNewType = SvNumFormatType::TIME;
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ }
+ }
+ else
+ return;
+ }
+ nPos = 0;
+ }
+
+ nExtSubType = m_xSelectionLB->get_id(nPos).toUInt32();
+ }
+ else
+ nExtSubType = DI_SUB_TIME;
+
+ SvNumFormatType nOldType = SvNumFormatType::ALL;
+ bool bEnable = false;
+ bool bOneArea = false;
+
+ if (m_xFormatLB->get_active())
+ nOldType = m_xFormatLB->GetFormatType();
+
+ switch (nExtSubType)
+ {
+ case DI_SUB_AUTHOR:
+ break;
+
+ case DI_SUB_DATE:
+ nNewType = SvNumFormatType::DATE;
+ bOneArea = true;
+ break;
+
+ case DI_SUB_TIME:
+ nNewType = SvNumFormatType::TIME;
+ bOneArea = true;
+ break;
+ }
+ if (nNewType == SvNumFormatType::ALL)
+ {
+ m_xFormatLB->clear();
+ }
+ else
+ {
+ if (nOldType != nNewType)
+ {
+ m_xFormatLB->SetFormatType(nNewType);
+ m_xFormatLB->SetOneArea(bOneArea);
+ }
+ bEnable = true;
+ }
+
+ sal_uInt32 nFormat = 0;
+
+ sal_uInt16 nOldSubType = 0;
+
+ if (IsFieldEdit())
+ {
+ if (auto const pField = dynamic_cast<SwDocInfoField const*>(GetCurField()))
+ {
+ nFormat = pField->GetFormat();
+ nOldSubType = pField->GetSubType() & 0xff00;
+ }
+ nPos = m_xSelectionLB->get_selected_index();
+ if (nPos != -1)
+ {
+ nSubType = m_xSelectionLB->get_id(nPos).toUInt32();
+
+ nOldSubType &= ~DI_SUB_FIXED;
+ if (nOldSubType == nSubType)
+ {
+ if (!nFormat && (nNewType == SvNumFormatType::DATE || nNewType == SvNumFormatType::TIME))
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(pSh)
+ {
+ SvNumberFormatter* pFormatter = pSh->GetNumberFormatter();
+ LanguageType eLang = m_xFormatLB->GetCurLanguage();
+ if (nNewType == SvNumFormatType::DATE)
+ nFormat = pFormatter->GetFormatIndex( NF_DATE_SYSTEM_SHORT, eLang);
+ else if (nNewType == SvNumFormatType::TIME)
+ nFormat = pFormatter->GetFormatIndex( NF_TIME_HHMM, eLang);
+ }
+ }
+ m_xFormatLB->SetDefFormat(nFormat);
+ }
+ }
+ else if( (nSubType == DI_CUSTOM) && (nNewType != SvNumFormatType::ALL) )
+ {
+ m_xFormatLB->SetDefFormat(nFormat);
+ }
+ }
+
+ // Always allow Fixed Content to be turned off if it is currently on
+ m_xFormat->set_sensitive(bEnable || m_xFixedCB->get_active());
+
+ if (!bEnable)
+ m_xFormatLB->clear();
+ else if (m_xFormatLB->get_selected_index() == -1)
+ m_xFormatLB->select(0);
+}
+
+sal_Int32 SwFieldDokInfPage::FillSelectionLB(sal_uInt16 nSubType)
+{
+ // fill Format-Listbox
+ SwFieldTypesEnum nTypeId = SwFieldTypesEnum::DocumentInfo;
+
+ EnableInsert(nSubType != USHRT_MAX);
+
+ if (nSubType == USHRT_MAX) // Info-Text
+ nSubType = DI_SUBTYPE_BEGIN;
+
+ m_xSelectionLB->clear();
+
+ sal_uInt16 nSize = 0;
+ sal_Int32 nSelPos = -1;
+ sal_uInt16 nExtSubType = 0;
+
+ if (IsFieldEdit())
+ {
+ if (auto const pField = dynamic_cast<SwDocInfoField const*>(GetCurField()))
+ {
+ nExtSubType = pField->GetSubType() & 0xff00;
+ }
+ m_xFixedCB->set_active((nExtSubType & DI_SUB_FIXED) != 0);
+ nExtSubType = ((nExtSubType & ~DI_SUB_FIXED) >> 8) - 1;
+ }
+
+ if (nSubType < DI_CREATE || nSubType == DI_DOCNO || nSubType == DI_EDIT|| nSubType == DI_CUSTOM )
+ {
+ // Format Box is empty for Title and Time
+ }
+ else
+ {
+ nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+ for (sal_uInt16 i = 0; i < nSize; ++i)
+ {
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId(nTypeId, i)));
+ m_xSelectionLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
+ if (IsFieldEdit() && i == nExtSubType)
+ nSelPos = i;
+ }
+ }
+
+ bool bEnable = nSize != 0;
+
+ if (nSize)
+ {
+ if (m_xSelectionLB->get_selected_index() == -1)
+ m_xSelectionLB->select(nSelPos == USHRT_MAX ? 0 : nSelPos);
+ bEnable = true;
+ }
+
+ m_xSelection->set_sensitive(bEnable);
+
+ return nSize;
+}
+
+bool SwFieldDokInfPage::FillItemSet(SfxItemSet* )
+{
+ if (!m_xSelEntry)
+ return false;
+
+ sal_uInt16 nSubType = m_xTypeTLB->get_id(*m_xSelEntry).toUInt32();
+ if (nSubType == USHRT_MAX)
+ return false;
+
+ sal_uInt32 nFormat = 0;
+
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+
+ OUString aName;
+ if (DI_CUSTOM == nSubType)
+ aName = m_xTypeTLB->get_text(*m_xSelEntry);
+
+ if (nPos != -1)
+ nSubType |= m_xSelectionLB->get_id(nPos).toUInt32();
+
+ if (m_xFixedCB->get_active())
+ nSubType |= DI_SUB_FIXED;
+
+ nPos = m_xFormatLB->get_selected_index();
+ if(nPos != -1)
+ nFormat = m_xFormatLB->GetFormat();
+
+ if (!IsFieldEdit() || nOldSel != m_xSelectionLB->get_selected_index() ||
+ nOldFormat != nFormat || m_xFixedCB->get_state_changed_from_saved()
+ || (DI_CUSTOM == nSubType && aName != m_sOldCustomFieldName ))
+ {
+ InsertField(SwFieldTypesEnum::DocumentInfo, nSubType, aName, OUString(), nFormat,
+ ' ', m_xFormatLB->IsAutomaticLanguage());
+ }
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldDokInfPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldDokInfPage>(pPage, pController, pAttrSet);
+}
+
+sal_uInt16 SwFieldDokInfPage::GetGroup()
+{
+ return GRP_REG;
+}
+
+void SwFieldDokInfPage::FillUserData()
+{
+ int nEntry = m_xTypeTLB->get_selected_index();
+ sal_uInt16 nTypeSel = nEntry != -1 ? m_xTypeTLB->get_id(nEntry).toUInt32() : USHRT_MAX;
+ SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel ));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddinf.hxx b/sw/source/ui/fldui/flddinf.hxx
new file mode 100644
index 000000000..fb6fffff8
--- /dev/null
+++ b/sw/source/ui/fldui/flddinf.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDDINF_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDDINF_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <numfmtlb.hxx>
+#include "fldpage.hxx"
+
+namespace com::sun::star::beans { class XPropertySet; }
+
+class SwFieldDokInfPage : public SwFieldPage
+{
+ std::unique_ptr<weld::TreeIter> m_xSelEntry;
+ css::uno::Reference < css::beans::XPropertySet > xCustomPropertySet;
+
+ sal_Int32 nOldSel;
+ sal_uLong nOldFormat;
+ OUString m_sOldCustomFieldName;
+
+ std::unique_ptr<weld::TreeView> m_xTypeTLB;
+ std::unique_ptr<weld::Widget> m_xSelection;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<SwNumFormatTreeView> m_xFormatLB;
+ std::unique_ptr<weld::CheckButton> m_xFixedCB;
+
+ DECL_LINK(TypeHdl, weld::TreeView&, void);
+ DECL_LINK(SubTypeHdl, weld::TreeView&, void);
+
+ sal_Int32 FillSelectionLB(sal_uInt16 nSubTypeId);
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldDokInfPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pSet);
+ virtual ~SwFieldDokInfPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual void FillUserData() override;
+};
+
+void FillFieldSelect(weld::TreeView& rListBox);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddok.cxx b/sw/source/ui/fldui/flddok.cxx
new file mode 100644
index 000000000..4e65a7c3f
--- /dev/null
+++ b/sw/source/ui/fldui/flddok.cxx
@@ -0,0 +1,641 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <flddat.hxx>
+#include <docufld.hxx>
+#include <strings.hrc>
+#include <chpfld.hxx>
+#include "flddok.hxx"
+#include <swmodule.hxx>
+#include <wrtsh.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zformat.hxx>
+#include <o3tl/string_view.hxx>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+SwFieldDokPage::SwFieldDokPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet)
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/flddocumentpage.ui",
+ "FieldDocumentPage", pCoreSet)
+ , nOldSel(0)
+ , nOldFormat(0)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xSelection(m_xBuilder->weld_widget("selectframe"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xValueFT(m_xBuilder->weld_label("valueft"))
+ , m_xValueED(m_xBuilder->weld_entry("value"))
+ , m_xLevelFT(m_xBuilder->weld_label("levelft"))
+ , m_xLevelED(m_xBuilder->weld_spin_button("level"))
+ , m_xDateFT(m_xBuilder->weld_label("daysft"))
+ , m_xTimeFT(m_xBuilder->weld_label("minutesft"))
+ , m_xDateOffsetED(m_xBuilder->weld_spin_button("offset"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xFormatLB(m_xBuilder->weld_tree_view("format"))
+ , m_xNumFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("numformat")))
+ , m_xFixedCB(m_xBuilder->weld_check_button("fixed"))
+{
+ m_xTypeLB->make_sorted();
+ m_xFormatLB->make_sorted();
+
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_xTypeLB->get_height_rows(10);
+
+ m_xTypeLB->set_size_request(nWidth, nHeight);
+ m_xSelectionLB->set_size_request(nWidth, nHeight);
+ m_xFormatLB->set_size_request(nWidth * 2, nHeight);
+
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldDokPage, TreeViewInsertHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldDokPage, TreeViewInsertHdl));
+ m_xNumFormatLB->connect_row_activated(LINK(this, SwFieldDokPage, NumFormatHdl));
+
+ m_xLevelED->set_max(MAXLEVEL);
+ m_xDateOffsetED->set_range(INT_MIN, INT_MAX);
+ //enable 'active' language selection
+ m_xNumFormatLB->SetShowLanguageControl(true);
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-doc");
+ m_xValueED->set_buildable_name(m_xValueED->get_buildable_name() + "-doc");
+ m_xNumFormatLB->set_buildable_name(m_xNumFormatLB->get_buildable_name() + "-doc");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-doc");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-doc");
+}
+
+SwFieldDokPage::~SwFieldDokPage()
+{
+}
+
+void SwFieldDokPage::Reset(const SfxItemSet* )
+{
+ SavePos(*m_xTypeLB);
+ Init(); // general initialisation
+
+ // initialise TypeListBox
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ m_xTypeLB->freeze();
+ m_xTypeLB->clear();
+
+ if (!IsFieldEdit())
+ {
+ bool bPage = false;
+ // fill Type-Listbox
+ for(sal_uInt16 i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ const SwFieldTypesEnum nTypeId = SwFieldMgr::GetTypeId(i);
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::PreviousPage:
+ case SwFieldTypesEnum::NextPage:
+ case SwFieldTypesEnum::PageNumber:
+ if (!bPage)
+ {
+ m_xTypeLB->append(OUString::number(USHRT_MAX), SwResId(FMT_REF_PAGE));
+ bPage = true;
+ }
+ break;
+
+ default:
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ break;
+ }
+ }
+ }
+ else
+ {
+ const SwField* pCurField = GetCurField();
+ SwFieldTypesEnum nTypeId = pCurField->GetTypeId();
+ if (nTypeId == SwFieldTypesEnum::FixedDate)
+ nTypeId = SwFieldTypesEnum::Date;
+ if (nTypeId == SwFieldTypesEnum::FixedTime)
+ nTypeId = SwFieldTypesEnum::Time;
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId)));
+ m_xNumFormatLB->SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
+ if(pFormat)
+ m_xNumFormatLB->SetLanguage(pFormat->GetLanguage());
+ }
+ }
+
+
+ m_xTypeLB->thaw();
+
+ // select old Pos
+ RestorePos(*m_xTypeLB);
+
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldDokPage, TreeViewInsertHdl));
+ m_xTypeLB->connect_changed(LINK(this, SwFieldDokPage, TypeHdl));
+ m_xFormatLB->connect_changed(LINK(this, SwFieldDokPage, FormatHdl));
+
+ if( !IsRefresh() )
+ {
+ const OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if (o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ const sal_uInt16 nVal = static_cast< sal_uInt16 >(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ if(nVal != USHRT_MAX)
+ {
+ for (int i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; i++)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ m_xTypeLB->select(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ TypeHdl(*m_xTypeLB);
+
+ if (IsFieldEdit())
+ {
+ nOldSel = m_xSelectionLB->get_selected_index();
+ nOldFormat = GetCurField()->GetFormat();
+ m_xFixedCB->save_state();
+ m_xValueED->save_value();
+ m_xLevelED->save_value();
+ m_xDateOffsetED->save_value();
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldDokPage, TypeHdl, weld::TreeView&, void)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if(GetTypeSel() == -1)
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+
+ if (nOld == GetTypeSel())
+ return;
+
+ size_t nCount;
+
+ m_xDateFT->hide();
+ m_xTimeFT->hide();
+
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ // fill Selection-Listbox
+ m_xSelectionLB->clear();
+
+ if (nTypeId != SwFieldTypesEnum::Unknown)
+ {
+ std::vector<OUString> aLst;
+ GetFieldMgr().GetSubTypes(nTypeId, aLst);
+
+ if (nTypeId != SwFieldTypesEnum::Author)
+ nCount = aLst.size();
+ else
+ nCount = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ if (!IsFieldEdit())
+ {
+ OUString sId(OUString::number(i));
+ if (nTypeId != SwFieldTypesEnum::Author)
+ m_xSelectionLB->append(sId, aLst[i]);
+ else
+ m_xSelectionLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
+ }
+ else
+ {
+ bool bInsert = false;
+
+ OUString sId(OUString::number(i));
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Date:
+ case SwFieldTypesEnum::Time:
+ m_xSelectionLB->append(sId, aLst[i]);
+ if (static_cast<SwDateTimeField*>(GetCurField())->IsFixed() && !i)
+ m_xSelectionLB->select_id(sId);
+ if (!static_cast<SwDateTimeField*>(GetCurField())->IsFixed() && i)
+ m_xSelectionLB->select_id(sId);
+ break;
+ case SwFieldTypesEnum::ExtendedUser:
+ case SwFieldTypesEnum::DocumentStatistics:
+ m_xSelectionLB->append(sId, aLst[i]);
+ if (GetCurField()->GetSubType() == i)
+ m_xSelectionLB->select_id(sId);
+ break;
+
+ case SwFieldTypesEnum::Author:
+ {
+ const OUString sFormat(GetFieldMgr().GetFormatStr(nTypeId, i));
+ m_xSelectionLB->append(sId, sFormat);
+ m_xSelectionLB->select_text(GetFieldMgr().GetFormatStr(nTypeId, GetCurField()->GetFormat()));
+ break;
+ }
+
+ default:
+ if (aLst[i] == GetCurField()->GetPar1())
+ bInsert = true;
+ break;
+ }
+ if (bInsert)
+ {
+ m_xSelectionLB->append(sId, aLst[i]);
+ break;
+ }
+ }
+ }
+ m_xSelectionLB->connect_changed(Link<weld::TreeView&,void>());
+ }
+ else
+ {
+ AddSubType(SwFieldTypesEnum::PageNumber);
+ AddSubType(SwFieldTypesEnum::PreviousPage);
+ AddSubType(SwFieldTypesEnum::NextPage);
+ nTypeId = static_cast<SwFieldTypesEnum>(m_xSelectionLB->get_id(0).toUInt32());
+ nCount = 3;
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldDokPage, SubTypeHdl));
+ }
+
+ bool bEnable = nCount != 0;
+
+ if (bEnable && m_xSelectionLB->get_selected_index() == -1)
+ m_xSelectionLB->select(0);
+
+ m_xSelection->set_sensitive( bEnable );
+
+ // fill Format-Listbox
+ sal_Int32 nSize = FillFormatLB(nTypeId);
+
+ bool bValue = false, bLevel = false, bNumFormat = false, bOffset = false;
+ bool bFormat = nSize != 0;
+ bool bOneArea = false;
+ bool bFixed = false;
+ SvNumFormatType nFormatType = SvNumFormatType::ALL;
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Date:
+ bFormat = bNumFormat = bOneArea = bOffset = true;
+
+ nFormatType = SvNumFormatType::DATE;
+
+ m_xDateFT->show();
+
+ m_xDateOffsetED->set_range(INT_MIN, INT_MAX); // no limit
+
+ if (IsFieldEdit())
+ m_xDateOffsetED->set_value( static_cast<SwDateTimeField*>(GetCurField())->GetOffset() / 24 / 60);
+ break;
+
+ case SwFieldTypesEnum::Time:
+ bFormat = bNumFormat = bOneArea = bOffset = true;
+
+ nFormatType = SvNumFormatType::TIME;
+
+ m_xTimeFT->show();
+
+ m_xDateOffsetED->set_range(-1440, 1440); // one day
+
+ if (IsFieldEdit())
+ m_xDateOffsetED->set_value( static_cast<SwDateTimeField*>(GetCurField())->GetOffset() );
+ break;
+
+ case SwFieldTypesEnum::PreviousPage:
+ case SwFieldTypesEnum::NextPage:
+ if (IsFieldEdit())
+ {
+ const sal_uInt16 nTmp = m_xFormatLB->get_selected_id().toUInt32();
+
+ if(SVX_NUM_CHAR_SPECIAL != nTmp)
+ {
+ sal_Int32 nOff = GetCurField()->GetPar2().toInt32();
+ if( SwFieldTypesEnum::NextPage == nTypeId && 1 != nOff )
+ m_xValueED->set_text(
+ OUString::number(nOff - 1) );
+ else if( SwFieldTypesEnum::PreviousPage == nTypeId && -1 != nOff )
+ m_xValueED->set_text(
+ OUString::number(nOff + 1) );
+ else
+ m_xValueED->set_text(OUString());
+ }
+ else
+ m_xValueED->set_text(static_cast<SwPageNumberField*>(GetCurField())->GetUserString());
+ }
+ bValue = true;
+ break;
+
+ case SwFieldTypesEnum::Chapter:
+ m_xValueFT->set_label(SwResId(STR_LEVEL));
+ if (IsFieldEdit())
+ m_xLevelED->set_text(OUString::number(static_cast<SwChapterField*>(GetCurField())->GetLevel(GetWrtShell()->GetLayout()) + 1));
+ bLevel = true;
+ break;
+
+ case SwFieldTypesEnum::PageNumber:
+ m_xValueFT->set_label( SwResId( STR_OFFSET ));
+ if (IsFieldEdit())
+ m_xValueED->set_text(GetCurField()->GetPar2());
+ bValue = true;
+ break;
+
+ case SwFieldTypesEnum::ExtendedUser:
+ case SwFieldTypesEnum::Author:
+ case SwFieldTypesEnum::Filename:
+ bFixed = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (bNumFormat)
+ {
+ if (IsFieldEdit())
+ {
+ m_xNumFormatLB->SetDefFormat(GetCurField()->GetFormat());
+
+ if (m_xNumFormatLB->GetFormatType() == (SvNumFormatType::DATE|SvNumFormatType::TIME))
+ {
+ // always set Format-Type because otherwise when date/time formats are combined,
+ // both formats would be displayed at the same time
+ m_xNumFormatLB->SetFormatType(SvNumFormatType::ALL);
+ m_xNumFormatLB->SetFormatType(nFormatType);
+ // set correct format once again
+ m_xNumFormatLB->SetDefFormat(GetCurField()->GetFormat());
+ }
+ }
+ else
+ m_xNumFormatLB->SetFormatType(nFormatType);
+
+ m_xNumFormatLB->SetOneArea(bOneArea);
+ }
+
+ m_xFormatLB->set_visible(!bNumFormat);
+ m_xNumFormatLB->set_visible(bNumFormat);
+
+ m_xValueFT->set_visible(bValue);
+ m_xValueED->set_visible(bValue);
+ m_xLevelFT->set_visible(bLevel);
+ m_xLevelED->set_visible(bLevel);
+ m_xDateOffsetED->set_visible(bOffset);
+ m_xFixedCB->set_visible(!bValue && !bLevel && !bOffset);
+
+ m_xFormat->set_sensitive(bFormat);
+ m_xFixedCB->set_sensitive(bFixed);
+
+ if (IsFieldEdit())
+ m_xFixedCB->set_active((GetCurField()->GetFormat() & AF_FIXED) != 0 && bFixed);
+
+ if (m_xNumFormatLB->get_selected_index() == -1)
+ m_xNumFormatLB->select(0);
+ m_xValueFT->set_sensitive(bValue || bLevel || bOffset);
+ m_xValueED->set_sensitive(bValue);
+}
+
+void SwFieldDokPage::AddSubType(SwFieldTypesEnum nTypeId)
+{
+ m_xSelectionLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldType::GetTypeStr(nTypeId));
+}
+
+IMPL_LINK_NOARG(SwFieldDokPage, SubTypeHdl, weld::TreeView&, void)
+{
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ if(nPos == -1)
+ nPos = 0;
+
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xSelectionLB->get_id(nPos).toUInt32());
+ FillFormatLB(nTypeId);
+
+ TranslateId pTextRes;
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Chapter:
+ pTextRes = STR_LEVEL;
+ break;
+
+ case SwFieldTypesEnum::PreviousPage:
+ case SwFieldTypesEnum::NextPage:
+ pTextRes = SVX_NUM_CHAR_SPECIAL == m_xFormatLB->get_selected_id().toUInt32()
+ ? STR_VALUE : STR_OFFSET;
+ break;
+
+ case SwFieldTypesEnum::PageNumber:
+ pTextRes = STR_OFFSET;
+ break;
+ default: break;
+ }
+
+ if (pTextRes)
+ m_xValueFT->set_label(SwResId(pTextRes));
+}
+
+sal_Int32 SwFieldDokPage::FillFormatLB(SwFieldTypesEnum nTypeId)
+{
+ // fill Format-Listbox
+ m_xFormatLB->clear();
+
+ if (nTypeId == SwFieldTypesEnum::Author)
+ return m_xFormatLB->n_children();
+
+ const sal_uInt16 nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+
+ for( sal_uInt16 i = 0; i < nSize; ++i )
+ {
+ const sal_uInt16 nFormatId = GetFieldMgr().GetFormatId( nTypeId, i );
+ OUString sId(OUString::number(nFormatId));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
+ }
+
+ if (IsFieldEdit())
+ {
+ m_xFormatLB->select_id(OUString::number(GetCurField()->GetFormat() & ~AF_FIXED));
+ }
+ else
+ {
+ // Select default selected value for "Insert" dialog
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::PageNumber:
+ case SwFieldTypesEnum::DocumentStatistics:
+ m_xFormatLB->select_text(SwResId(FMT_NUM_PAGEDESC));
+ break;
+ default:
+ m_xFormatLB->select(0);
+ }
+ }
+
+ FormatHdl(*m_xFormatLB);
+
+ return nSize;
+}
+
+IMPL_LINK_NOARG(SwFieldDokPage, FormatHdl, weld::TreeView&, void)
+{
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if (nTypeId == SwFieldTypesEnum::Unknown)
+ {
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ if(nPos == -1)
+ nPos = 0;
+
+ nTypeId = static_cast<SwFieldTypesEnum>(m_xSelectionLB->get_id(nPos).toUInt32());
+ }
+
+ if (nTypeId != SwFieldTypesEnum::NextPage && nTypeId != SwFieldTypesEnum::PreviousPage)
+ return;
+
+ // Prev/Next - PageNumFields special treatment:
+ sal_uInt16 nTmp = m_xFormatLB->get_selected_id().toUInt32();
+ const OUString sOldText( m_xValueFT->get_label() );
+ const OUString sNewText( SwResId( SVX_NUM_CHAR_SPECIAL == nTmp ? STR_VALUE
+ : STR_OFFSET ));
+
+ if (sOldText != sNewText)
+ m_xValueFT->set_label(sNewText);
+
+ if (sOldText != m_xValueFT->get_label())
+ m_xValueED->set_text(OUString());
+}
+
+bool SwFieldDokPage::FillItemSet(SfxItemSet* )
+{
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if (nTypeId == SwFieldTypesEnum::Unknown)
+ {
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ if(nPos == -1)
+ nPos = 0;
+ nTypeId = static_cast<SwFieldTypesEnum>(m_xSelectionLB->get_id(nPos).toUInt32());
+ }
+
+ OUString aVal(m_xValueED->get_text());
+ sal_uLong nFormat = 0;
+ sal_uInt16 nSubType = 0;
+
+ if (m_xFormatLB->get_sensitive())
+ {
+ sal_Int32 nPos = m_xFormatLB->get_selected_index();
+ if(nPos != -1)
+ nFormat = m_xFormatLB->get_id(nPos).toUInt32();
+ }
+
+ if (m_xSelectionLB->get_sensitive())
+ {
+ sal_Int32 nPos = m_xSelectionLB->get_selected_index();
+ if(nPos != -1)
+ nSubType = m_xSelectionLB->get_id(nPos).toUInt32();
+ }
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Author:
+ nFormat = nSubType;
+ nSubType = 0;
+ [[fallthrough]];
+ case SwFieldTypesEnum::ExtendedUser:
+ nFormat |= m_xFixedCB->get_active() ? AF_FIXED : 0;
+ break;
+
+ case SwFieldTypesEnum::Filename:
+ nFormat |= m_xFixedCB->get_active() ? FF_FIXED : 0;
+ break;
+
+ case SwFieldTypesEnum::Date:
+ case SwFieldTypesEnum::Time:
+ {
+ nFormat = m_xNumFormatLB->GetFormat();
+ tools::Long nVal = static_cast< tools::Long >(m_xDateOffsetED->get_value());
+ if (nTypeId == SwFieldTypesEnum::Date)
+ aVal = OUString::number(nVal * 60 * 24);
+ else
+ aVal = OUString::number(nVal);
+ break;
+ }
+
+ case SwFieldTypesEnum::NextPage:
+ case SwFieldTypesEnum::PreviousPage:
+ case SwFieldTypesEnum::PageNumber:
+ case SwFieldTypesEnum::GetRefPage:
+ {
+ if( SVX_NUM_CHAR_SPECIAL != nFormat &&
+ (SwFieldTypesEnum::PreviousPage == nTypeId || SwFieldTypesEnum::NextPage == nTypeId))
+ {
+ sal_Int32 nVal = m_xValueED->get_text().toInt32();
+ aVal = OUString::number(nVal);
+ }
+ break;
+ }
+
+ case SwFieldTypesEnum::Chapter:
+ aVal = m_xLevelED->get_text();
+ break;
+
+ default:
+ break;
+ }
+
+ if (!IsFieldEdit() ||
+ nOldSel != m_xSelectionLB->get_selected_index() ||
+ nOldFormat != nFormat ||
+ m_xFixedCB->get_state_changed_from_saved() ||
+ m_xValueED->get_value_changed_from_saved() ||
+ m_xLevelED->get_value_changed_from_saved() ||
+ m_xDateOffsetED->get_value_changed_from_saved())
+ {
+ InsertField(nTypeId, nSubType, OUString(), aVal, nFormat, ' ', m_xNumFormatLB->IsAutomaticLanguage());
+ }
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldDokPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldDokPage>(pPage, pController, pAttrSet);
+}
+
+sal_uInt16 SwFieldDokPage::GetGroup()
+{
+ return GRP_DOC;
+}
+
+void SwFieldDokPage::FillUserData()
+{
+ const sal_Int32 nEntryPos = m_xTypeLB->get_selected_index();
+ const sal_uInt16 nTypeSel = ( -1 == nEntryPos )
+ ? USHRT_MAX : m_xTypeLB->get_id(nEntryPos).toUInt32();
+ SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel ));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/flddok.hxx b/sw/source/ui/fldui/flddok.hxx
new file mode 100644
index 000000000..ce61dd15e
--- /dev/null
+++ b/sw/source/ui/fldui/flddok.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDDOK_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDDOK_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#include <numfmtlb.hxx>
+#include "fldpage.hxx"
+
+class SwFieldDokPage : public SwFieldPage
+{
+ sal_Int32 nOldSel;
+ sal_uLong nOldFormat;
+
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<weld::Widget> m_xSelection;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ std::unique_ptr<weld::Label> m_xValueFT;
+ std::unique_ptr<weld::Entry> m_xValueED;
+ std::unique_ptr<weld::Label> m_xLevelFT;
+ std::unique_ptr<weld::SpinButton> m_xLevelED;
+ std::unique_ptr<weld::Label> m_xDateFT;
+ std::unique_ptr<weld::Label> m_xTimeFT;
+ std::unique_ptr<weld::SpinButton> m_xDateOffsetED;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<weld::TreeView> m_xFormatLB;
+ std::unique_ptr<SwNumFormatTreeView> m_xNumFormatLB;
+ std::unique_ptr<weld::CheckButton> m_xFixedCB;
+
+ DECL_LINK(TypeHdl, weld::TreeView&, void);
+ DECL_LINK(FormatHdl, weld::TreeView&, void);
+ DECL_LINK(SubTypeHdl, weld::TreeView&, void);
+
+ void AddSubType(SwFieldTypesEnum nTypeId);
+ sal_Int32 FillFormatLB(SwFieldTypesEnum nTypeId);
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldDokPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet * pSet);
+
+ virtual ~SwFieldDokPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual void FillUserData() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldedt.cxx b/sw/source/ui/fldui/fldedt.cxx
new file mode 100644
index 000000000..ae009a025
--- /dev/null
+++ b/sw/source/ui/fldui/fldedt.cxx
@@ -0,0 +1,336 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+#include <config_fuzzers.h>
+
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svx/optgenrl.hxx>
+#include <docufld.hxx>
+#include <expfld.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include "flddb.hxx"
+#include "flddinf.hxx"
+#include "fldvar.hxx"
+#include "flddok.hxx"
+#include "fldfunc.hxx"
+#include "fldref.hxx"
+#include <fldedt.hxx>
+
+#include <cmdid.h>
+#include <swabstdlg.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <memory>
+#include <swuiexp.hxx>
+
+void SwFieldEditDlg::EnsureSelection(SwField *pCurField, SwFieldMgr &rMgr)
+{
+ if (pSh->CursorInsideInputField())
+ {
+ // move cursor to start of Input Field
+ SwInputField* pInputField = dynamic_cast<SwInputField*>(pCurField);
+ if (pInputField && pInputField->GetFormatField())
+ {
+ pSh->GotoField( *(pInputField->GetFormatField()) );
+ }
+ else
+ {
+ SwSetExpField *const pSetField(dynamic_cast<SwSetExpField*>(pCurField));
+ if (pSetField)
+ {
+ assert(pSetField->GetFormatField());
+ pSh->GotoField( *(pSetField->GetFormatField()) );
+ }
+ else
+ {
+ assert(!"what input field is this");
+ }
+ }
+ }
+
+ /* Only create selection if there is none already.
+ Normalize PaM instead of swapping. */
+ if (!pSh->HasSelection())
+ {
+ SwShellCursor* pCursor = pSh->getShellCursor(true);
+ SwPosition aOrigPos(*pCursor->GetPoint());
+
+ //After this attempt it is possible that rMgr.GetCurField() != pCurField if
+ //the field was in e.g. a zero height portion and so invisible in which
+ //case it will be skipped over
+ pSh->Right(CRSR_SKIP_CHARS, true, 1, false );
+ //So (fdo#50640) if it didn't work then reposition back to the original
+ //location where the field was
+ SwField *pRealCurField = rMgr.GetCurField();
+ bool bSelectionFailed = pCurField != pRealCurField;
+ if (bSelectionFailed)
+ {
+ pCursor->DeleteMark();
+ *pCursor->GetPoint() = aOrigPos;
+ }
+ }
+
+ pSh->NormalizePam();
+
+ assert(pCurField == rMgr.GetCurField());
+}
+
+SwFieldEditDlg::SwFieldEditDlg(SwView const & rVw)
+ : SfxSingleTabDialogController(rVw.GetViewFrame()->GetFrameWeld(), nullptr,
+ "modules/swriter/ui/editfielddialog.ui", "EditFieldDialog")
+ , pSh(rVw.GetWrtShellPtr())
+ , m_xPrevBT(m_xBuilder->weld_button("prev"))
+ , m_xNextBT(m_xBuilder->weld_button("next"))
+ , m_xAddressBT(m_xBuilder->weld_button("edit"))
+{
+ SwFieldMgr aMgr(pSh);
+
+ SwField *pCurField = aMgr.GetCurField();
+ if (!pCurField)
+ return;
+
+ SwViewShell::SetCareDialog(m_xDialog);
+
+ EnsureSelection(pCurField, aMgr);
+
+ sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), pCurField->GetSubType());
+
+ CreatePage(nGroup);
+
+ GetOKButton().connect_clicked(LINK(this, SwFieldEditDlg, OKHdl));
+
+ m_xPrevBT->connect_clicked(LINK(this, SwFieldEditDlg, NextPrevHdl));
+ m_xNextBT->connect_clicked(LINK(this, SwFieldEditDlg, NextPrevHdl));
+
+ m_xAddressBT->connect_clicked(LINK(this, SwFieldEditDlg, AddressHdl));
+
+ Init();
+}
+
+// initialise controls
+void SwFieldEditDlg::Init()
+{
+ SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
+ if (pTabPage)
+ {
+ SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
+
+ SwField *pCurField = rMgr.GetCurField();
+
+ if(!pCurField)
+ return;
+
+ // Traveling only when more than one field
+ pSh->StartAction();
+ pSh->ClearMark();
+ pSh->CreateCursor();
+
+ bool bMove = rMgr.GoNext();
+ if( bMove )
+ rMgr.GoPrev();
+ m_xNextBT->set_sensitive(bMove);
+
+ bMove = rMgr.GoPrev();
+ if( bMove )
+ rMgr.GoNext();
+ m_xPrevBT->set_sensitive( bMove );
+
+ if (pCurField->GetTypeId() == SwFieldTypesEnum::ExtendedUser)
+ m_xAddressBT->set_sensitive(true);
+ else
+ m_xAddressBT->set_sensitive(false);
+
+ pSh->DestroyCursor();
+ pSh->EndAction();
+ }
+
+ GetOKButton().set_sensitive(!pSh->IsReadOnlyAvailable() ||
+ !pSh->HasReadonlySel());
+}
+
+SfxTabPage* SwFieldEditDlg::CreatePage(sal_uInt16 nGroup)
+{
+ // create TabPage
+ std::unique_ptr<SfxTabPage> xTabPage;
+
+ switch (nGroup)
+ {
+ case GRP_DOC:
+ xTabPage = SwFieldDokPage::Create(get_content_area(), this, nullptr);
+ break;
+ case GRP_FKT:
+ xTabPage = SwFieldFuncPage::Create(get_content_area(), this, nullptr);
+ break;
+ case GRP_REF:
+ xTabPage = SwFieldRefPage::Create(get_content_area(), this, nullptr);
+ break;
+ case GRP_REG:
+ if (SfxObjectShell* pDocSh = SfxObjectShell::Current())
+ {
+ auto pSet = new SfxItemSetFixed<FN_FIELD_DIALOG_DOC_PROPS, FN_FIELD_DIALOG_DOC_PROPS>( pDocSh->GetPool() );
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocSh->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ uno::Reference< beans::XPropertySet > xUDProps(
+ xDocProps->getUserDefinedProperties(),
+ uno::UNO_QUERY_THROW);
+ pSet->Put( SfxUnoAnyItem( FN_FIELD_DIALOG_DOC_PROPS, uno::Any(xUDProps) ) );
+ xTabPage = SwFieldDokInfPage::Create(get_content_area(), this, pSet);
+ }
+ break;
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ case GRP_DB:
+ xTabPage = SwFieldDBPage::Create(get_content_area(), this, nullptr);
+ static_cast<SwFieldDBPage*>(xTabPage.get())->SetWrtShell(*pSh);
+ break;
+#endif
+ case GRP_VAR:
+ xTabPage = SwFieldVarPage::Create(get_content_area(), this, nullptr);
+ break;
+
+ }
+
+ assert(xTabPage);
+
+ static_cast<SwFieldPage*>(xTabPage.get())->SetWrtShell(pSh);
+ SetTabPage(std::move(xTabPage));
+
+ return GetTabPage();
+}
+
+SwFieldEditDlg::~SwFieldEditDlg()
+{
+ SwViewShell::SetCareDialog(nullptr);
+ pSh->EnterStdMode();
+}
+
+void SwFieldEditDlg::EnableInsert(bool bEnable)
+{
+ if( bEnable && pSh->IsReadOnlyAvailable() && pSh->HasReadonlySel() )
+ bEnable = false;
+ GetOKButton().set_sensitive(bEnable);
+}
+
+void SwFieldEditDlg::InsertHdl()
+{
+ GetOKButton().clicked();
+}
+
+// kick off changing of the field
+IMPL_LINK_NOARG(SwFieldEditDlg, OKHdl, weld::Button&, void)
+{
+ if (GetOKButton().get_sensitive())
+ {
+ SfxTabPage* pTabPage = GetTabPage();
+ if (pTabPage)
+ pTabPage->FillItemSet(nullptr);
+ m_xDialog->response(RET_OK);
+ }
+}
+
+short SwFieldEditDlg::run()
+{
+ // without TabPage no dialog
+ return GetTabPage() ? SfxSingleTabDialogController::run() : static_cast<short>(RET_CANCEL);
+}
+
+// Traveling between fields of the same type
+IMPL_LINK(SwFieldEditDlg, NextPrevHdl, weld::Button&, rButton, void)
+{
+ bool bNext = &rButton == m_xNextBT.get();
+
+ pSh->EnterStdMode();
+
+ SwFieldType *pOldTyp = nullptr;
+ SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
+
+ //#112462# FillItemSet may delete the current field
+ //that's why it has to be called before accessing the current field
+ if (GetOKButton().get_sensitive())
+ pTabPage->FillItemSet(nullptr);
+
+ SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
+ SwField *pCurField = rMgr.GetCurField();
+ if (pCurField->GetTypeId() == SwFieldTypesEnum::Database)
+ pOldTyp = pCurField->GetTyp();
+
+ rMgr.GoNextPrev( bNext, pOldTyp );
+ pCurField = rMgr.GetCurField();
+
+ sal_uInt16 nGroup = SwFieldMgr::GetGroup(pCurField->GetTypeId(), pCurField->GetSubType());
+
+ if (nGroup != pTabPage->GetGroup())
+ pTabPage = static_cast<SwFieldPage*>(CreatePage(nGroup));
+
+ pTabPage->EditNewField();
+
+ Init();
+ EnsureSelection(pCurField, rMgr);
+}
+
+IMPL_LINK_NOARG(SwFieldEditDlg, AddressHdl, weld::Button&, void)
+{
+ SwFieldPage* pTabPage = static_cast<SwFieldPage*>(GetTabPage());
+ SwFieldMgr& rMgr = pTabPage->GetFieldMgr();
+ SwField *pCurField = rMgr.GetCurField();
+
+ SfxItemSetFixed<SID_FIELD_GRABFOCUS, SID_FIELD_GRABFOCUS> aSet( pSh->GetAttrPool() );
+
+ EditPosition nEditPos = EditPosition::UNKNOWN;
+
+ switch(pCurField->GetSubType())
+ {
+ case EU_FIRSTNAME: nEditPos = EditPosition::FIRSTNAME; break;
+ case EU_NAME: nEditPos = EditPosition::LASTNAME; break;
+ case EU_SHORTCUT: nEditPos = EditPosition::SHORTNAME; break;
+ case EU_COMPANY: nEditPos = EditPosition::COMPANY; break;
+ case EU_STREET: nEditPos = EditPosition::STREET; break;
+ case EU_TITLE: nEditPos = EditPosition::TITLE; break;
+ case EU_POSITION: nEditPos = EditPosition::POSITION; break;
+ case EU_PHONE_PRIVATE:nEditPos = EditPosition::TELPRIV; break;
+ case EU_PHONE_COMPANY:nEditPos = EditPosition::TELCOMPANY; break;
+ case EU_FAX: nEditPos = EditPosition::FAX; break;
+ case EU_EMAIL: nEditPos = EditPosition::EMAIL; break;
+ case EU_COUNTRY: nEditPos = EditPosition::COUNTRY; break;
+ case EU_ZIP: nEditPos = EditPosition::PLZ; break;
+ case EU_CITY: nEditPos = EditPosition::CITY; break;
+ case EU_STATE: nEditPos = EditPosition::STATE; break;
+
+ default: nEditPos = EditPosition::UNKNOWN; break;
+
+ }
+ aSet.Put(SfxUInt16Item(SID_FIELD_GRABFOCUS, static_cast<sal_uInt16>(nEditPos)));
+ SwAbstractDialogFactory& rFact = swui::GetFactory();
+
+ ScopedVclPtr<SfxAbstractDialog> pDlg(rFact.CreateSwAddressAbstractDlg(m_xDialog.get(), aSet));
+ if (RET_OK == pDlg->Execute())
+ {
+ pSh->UpdateOneField(*pCurField);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldfunc.cxx b/sw/source/ui/fldui/fldfunc.cxx
new file mode 100644
index 000000000..a129f7413
--- /dev/null
+++ b/sw/source/ui/fldui/fldfunc.cxx
@@ -0,0 +1,614 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <swtypes.hxx>
+#include <strings.hrc>
+#include <fldbas.hxx>
+#include <docufld.hxx>
+#include <wrtsh.hxx>
+#include <swmodule.hxx>
+#include "fldfunc.hxx"
+#include "flddinf.hxx"
+#include <flddropdown.hxx>
+#include <o3tl/string_view.hxx>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+using namespace ::com::sun::star;
+
+SwFieldFuncPage::SwFieldFuncPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet)
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/fldfuncpage.ui", "FieldFuncPage", pCoreSet)
+ , nOldFormat(0)
+ , bDropDownLBChanged(false)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xFormatLB(m_xBuilder->weld_tree_view("format"))
+ , m_xNameFT(m_xBuilder->weld_label("nameft"))
+ , m_xNameED(new ConditionEdit(m_xBuilder->weld_entry("condFunction")))
+ , m_xValueGroup(m_xBuilder->weld_widget("valuegroup"))
+ , m_xValueFT(m_xBuilder->weld_label("valueft"))
+ , m_xValueED(m_xBuilder->weld_entry("value"))
+ , m_xCond1FT(m_xBuilder->weld_label("cond1ft"))
+ , m_xCond1ED(new ConditionEdit(m_xBuilder->weld_entry("cond1")))
+ , m_xCond2FT(m_xBuilder->weld_label("cond2ft"))
+ , m_xCond2ED(new ConditionEdit(m_xBuilder->weld_entry("cond2")))
+ , m_xMacroBT(m_xBuilder->weld_button("macro"))
+ , m_xListGroup(m_xBuilder->weld_widget("listgroup"))
+ , m_xListItemFT(m_xBuilder->weld_label("itemft"))
+ , m_xListItemED(m_xBuilder->weld_entry("item"))
+ , m_xListAddPB(m_xBuilder->weld_button("add"))
+ , m_xListItemsFT(m_xBuilder->weld_label("listitemft"))
+ , m_xListItemsLB(m_xBuilder->weld_tree_view("listitems"))
+ , m_xListRemovePB(m_xBuilder->weld_button("remove"))
+ , m_xListUpPB(m_xBuilder->weld_button("up"))
+ , m_xListDownPB(m_xBuilder->weld_button("down"))
+ , m_xListNameFT(m_xBuilder->weld_label("listnameft"))
+ , m_xListNameED(m_xBuilder->weld_entry("listname"))
+{
+ FillFieldSelect(*m_xSelectionLB);
+ FillFieldSelect(*m_xFormatLB);
+ m_xListItemsLB->set_size_request(m_xListItemED->get_preferred_size().Width(),
+ m_xListItemsLB->get_height_rows(5));
+
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_xTypeLB->get_height_rows(10);
+ m_xTypeLB->set_size_request(nWidth, nHeight);
+ m_xFormatLB->set_size_request(nWidth, nHeight);
+
+ m_xNameED->connect_changed(LINK(this, SwFieldFuncPage, ModifyHdl));
+
+ m_sOldValueFT = m_xValueFT->get_label();
+ m_sOldNameFT = m_xNameFT->get_label();
+
+ m_xCond1ED->ShowBrackets(false);
+ m_xCond2ED->ShowBrackets(false);
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-func");
+ m_xValueED->set_buildable_name(m_xValueED->get_buildable_name() + "-func");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-func");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-func");
+}
+
+SwFieldFuncPage::~SwFieldFuncPage()
+{
+}
+
+void SwFieldFuncPage::Reset(const SfxItemSet* )
+{
+ SavePos(*m_xTypeLB);
+ Init(); // general initialisation
+
+ m_xTypeLB->freeze();
+ m_xTypeLB->clear();
+
+ if (!IsFieldEdit())
+ {
+ // initialise TypeListBox
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ // fill Typ-Listbox
+ for(sal_uInt16 i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ const SwFieldTypesEnum nTypeId = SwFieldMgr::GetTypeId(i);
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ }
+ }
+ else
+ {
+ const SwFieldTypesEnum nTypeId = GetCurField()->GetTypeId();
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId)));
+
+ if (nTypeId == SwFieldTypesEnum::Macro)
+ {
+ GetFieldMgr().SetMacroPath(GetCurField()->GetPar1());
+ }
+ }
+
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldFuncPage, TreeViewInsertHdl));
+ m_xTypeLB->connect_changed(LINK(this, SwFieldFuncPage, TypeHdl));
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldFuncPage, SelectHdl));
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldFuncPage, InsertMacroHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldFuncPage, TreeViewInsertHdl));
+ m_xMacroBT->connect_clicked(LINK(this, SwFieldFuncPage, MacroHdl));
+ Link<weld::Button&,void> aListModifyLk( LINK(this, SwFieldFuncPage, ListModifyButtonHdl));
+ m_xListAddPB->connect_clicked(aListModifyLk);
+ m_xListRemovePB->connect_clicked(aListModifyLk);
+ m_xListUpPB->connect_clicked(aListModifyLk);
+ m_xListDownPB->connect_clicked(aListModifyLk);
+ m_xListItemED->connect_activate(LINK(this, SwFieldFuncPage, ListModifyReturnActionHdl));
+ Link<weld::Entry&,void> aListEnableLk = LINK(this, SwFieldFuncPage, ListEnableHdl);
+ m_xListItemED->connect_changed(aListEnableLk);
+ m_xListItemsLB->connect_changed(LINK(this, SwFieldFuncPage, ListEnableListBoxHdl));
+
+ int nSelect = -1;
+ if( !IsRefresh() )
+ {
+ const OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if(o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ const sal_uInt16 nVal = static_cast< sal_uInt16 >(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ if(nVal != USHRT_MAX)
+ {
+ for (sal_Int32 i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ nSelect = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ m_xTypeLB->thaw();
+ if (nSelect != -1)
+ m_xTypeLB->select(nSelect);
+ else
+ {
+ // select old Pos
+ RestorePos(*m_xTypeLB);
+ }
+ TypeHdl(*m_xTypeLB);
+
+ if (IsFieldEdit())
+ {
+ m_xNameED->save_value();
+ m_xValueED->save_value();
+ m_xCond1ED->save_value();
+ m_xCond2ED->save_value();
+ nOldFormat = GetCurField()->GetFormat();
+ }
+}
+
+const TranslateId FMT_MARK_ARY[] =
+{
+ FMT_MARK_TEXT,
+ FMT_MARK_TABLE,
+ FMT_MARK_FRAME,
+ FMT_MARK_GRAFIC,
+ FMT_MARK_OLE
+};
+
+IMPL_LINK_NOARG(SwFieldFuncPage, TypeHdl, weld::TreeView&, void)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if(GetTypeSel() == -1)
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+
+ if (nOld == GetTypeSel())
+ return;
+
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ // fill Selection-Listbox
+ UpdateSubType();
+
+ // fill Format-Listbox
+ m_xFormatLB->clear();
+
+ const sal_uInt16 nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ {
+ m_xFormatLB->append(OUString::number(GetFieldMgr().GetFormatId(nTypeId, i)),
+ GetFieldMgr().GetFormatStr(nTypeId, i));
+ }
+
+ if (nSize)
+ {
+ if (IsFieldEdit() && nTypeId == SwFieldTypesEnum::JumpEdit)
+ m_xFormatLB->select_text(SwResId(FMT_MARK_ARY[GetCurField()->GetFormat()]));
+
+ if (m_xFormatLB->get_selected_index() == -1)
+ m_xFormatLB->select(0);
+ }
+
+ bool bValue = false, bName = false, bMacro = false, bInsert = true;
+ bool bFormat = nSize != 0;
+
+ // two controls for conditional text
+ bool bDropDown = SwFieldTypesEnum::Dropdown == nTypeId;
+ bool bCondTextField = SwFieldTypesEnum::ConditionalText == nTypeId;
+
+ m_xCond1FT->set_visible(!bDropDown && bCondTextField);
+ m_xCond1ED->set_visible(!bDropDown && bCondTextField);
+ m_xCond2FT->set_visible(!bDropDown && bCondTextField);
+ m_xCond2ED->set_visible(!bDropDown && bCondTextField);
+ m_xValueGroup->set_visible(!bDropDown && !bCondTextField);
+ m_xMacroBT->set_visible(!bDropDown);
+ m_xNameED->set_visible(!bDropDown);
+ m_xNameFT->set_visible(!bDropDown);
+
+ m_xListGroup->set_visible(bDropDown);
+
+ m_xNameED->SetDropEnable(false);
+
+ if (IsFieldEdit())
+ {
+ if(bDropDown)
+ {
+ const SwDropDownField* pDrop = static_cast<const SwDropDownField*>(GetCurField());
+ const uno::Sequence<OUString> aItems = pDrop->GetItemSequence();
+ m_xListItemsLB->clear();
+ for (const OUString& rItem : aItems)
+ m_xListItemsLB->append_text(rItem);
+ m_xListItemsLB->select_text(pDrop->GetSelectedItem());
+ m_xListNameED->set_text(pDrop->GetPar2());
+ m_xListNameED->save_value();
+ bDropDownLBChanged = false;
+ }
+ else
+ {
+ m_xNameED->set_text(GetCurField()->GetPar1());
+ m_xValueED->set_text(GetCurField()->GetPar2());
+ }
+ }
+ else
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ }
+ if(bDropDown)
+ ListEnableHdl(*m_xListItemED);
+
+ if (m_xNameFT->get_label() != m_sOldNameFT)
+ m_xNameFT->set_label(m_sOldNameFT);
+ if (m_xValueFT->get_label() != m_sOldValueFT)
+ m_xValueFT->set_label(m_sOldValueFT);
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Macro:
+ bMacro = true;
+ if (!GetFieldMgr().GetMacroPath().isEmpty())
+ bValue = true;
+ else
+ bInsert = false;
+
+ m_xNameFT->set_label(SwResId(STR_MACNAME));
+ m_xValueFT->set_label(SwResId(STR_PROMPT));
+ m_xNameED->set_text(GetFieldMgr().GetMacroName());
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::HiddenParagraph:
+ m_xNameFT->set_label(SwResId(STR_COND));
+ m_xNameED->SetDropEnable(true);
+ bName = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::HiddenText:
+ {
+ m_xNameFT->set_label(SwResId(STR_COND));
+ m_xNameED->SetDropEnable(true);
+ m_xValueFT->set_label(SwResId(STR_INSTEXT));
+ SwWrtShell* pSh = GetActiveWrtShell();
+ if (!IsFieldEdit() && pSh)
+ m_xValueED->set_text(pSh->GetSelText());
+ bName = bValue = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ }
+ break;
+
+ case SwFieldTypesEnum::ConditionalText:
+ m_xNameFT->set_label(SwResId(STR_COND));
+ m_xNameED->SetDropEnable(true);
+ if (IsFieldEdit())
+ {
+ sal_Int32 nIdx{ 0 };
+ m_xCond1ED->set_text(GetCurField()->GetPar2().getToken(0, '|', nIdx));
+ m_xCond2ED->set_text(GetCurField()->GetPar2().getToken(0, '|', nIdx));
+ }
+
+ bName = bValue = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::JumpEdit:
+ m_xNameFT->set_label(SwResId(STR_JUMPEDITFLD));
+ m_xValueFT->set_label(SwResId(STR_PROMPT));
+ bName = bValue = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::Input:
+ m_xValueFT->set_label(SwResId(STR_PROMPT));
+ bValue = true;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ break;
+
+ case SwFieldTypesEnum::CombinedChars:
+ {
+ m_xNameFT->set_label(SwResId(STR_COMBCHRS_FT));
+ m_xNameED->SetDropEnable(true);
+ bName = true;
+
+ const sal_Int32 nLen = m_xNameED->get_text().getLength();
+ if( !nLen || nLen > MAX_COMBINED_CHARACTERS )
+ bInsert = false;
+ m_xNameED->set_accessible_name(m_xNameFT->get_label());
+ m_xValueED->set_accessible_name(m_xValueFT->get_label());
+ }
+ break;
+ case SwFieldTypesEnum::Dropdown :
+ break;
+ default:
+ break;
+ }
+
+ m_xSelectionLB->hide();
+
+ m_xFormat->set_sensitive(bFormat);
+ m_xNameFT->set_sensitive(bName);
+ m_xNameED->set_sensitive(bName);
+ m_xValueGroup->set_sensitive(bValue);
+ m_xMacroBT->set_sensitive(bMacro);
+
+ EnableInsert( bInsert );
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, SelectHdl, weld::TreeView&, void)
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if( SwFieldTypesEnum::Macro == nTypeId )
+ m_xNameED->set_text( m_xSelectionLB->get_selected_text() );
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, InsertMacroHdl, weld::TreeView&, bool)
+{
+ SelectHdl(*m_xSelectionLB);
+ InsertHdl(nullptr);
+ return true;
+}
+
+IMPL_LINK(SwFieldFuncPage, ListModifyButtonHdl, weld::Button&, rControl, void)
+{
+ ListModifyHdl(&rControl);
+}
+
+IMPL_LINK(SwFieldFuncPage, ListModifyReturnActionHdl, weld::Entry&, rControl, bool)
+{
+ ListModifyHdl(&rControl);
+ return true;
+}
+
+void SwFieldFuncPage::ListModifyHdl(const weld::Widget* pControl)
+{
+ if (pControl == m_xListAddPB.get() ||
+ (pControl == m_xListItemED.get() && m_xListAddPB->get_sensitive()))
+ {
+ const OUString sEntry(m_xListItemED->get_text());
+ m_xListItemsLB->append_text(sEntry);
+ m_xListItemsLB->select_text(sEntry);
+ }
+ else if (m_xListItemsLB->get_selected_index() != -1)
+ {
+ sal_Int32 nSelPos = m_xListItemsLB->get_selected_index();
+ if (pControl == m_xListRemovePB.get())
+ {
+ m_xListItemsLB->remove(nSelPos);
+ m_xListItemsLB->select(nSelPos ? nSelPos - 1 : 0);
+ }
+ else if (pControl == m_xListUpPB.get())
+ {
+ if(nSelPos)
+ {
+ const OUString sEntry = m_xListItemsLB->get_selected_text();
+ m_xListItemsLB->remove(nSelPos);
+ nSelPos--;
+ m_xListItemsLB->insert_text(nSelPos, sEntry);
+ m_xListItemsLB->select(nSelPos);
+ }
+ }
+ else if (pControl == m_xListDownPB.get())
+ {
+ if( nSelPos < m_xListItemsLB->n_children() - 1)
+ {
+ const OUString sEntry = m_xListItemsLB->get_selected_text();
+ m_xListItemsLB->remove(nSelPos);
+ nSelPos++;
+ m_xListItemsLB->insert_text(nSelPos, sEntry);
+ m_xListItemsLB->select(nSelPos);
+ }
+ }
+ }
+ bDropDownLBChanged = true;
+ ListEnableHdl(*m_xListItemED);
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, ListEnableListBoxHdl, weld::TreeView&, void)
+{
+ ListEnableHdl(*m_xListItemED);
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, ListEnableHdl, weld::Entry&, void)
+{
+ //enable "Add" button when text is in the Edit that's not already member of the box
+ m_xListAddPB->set_sensitive(!m_xListItemED->get_text().isEmpty() &&
+ -1 == m_xListItemsLB->find_text(m_xListItemED->get_text()));
+ bool bEnableButtons = m_xListItemsLB->get_selected_index() != -1;
+ m_xListRemovePB->set_sensitive(bEnableButtons);
+ m_xListUpPB->set_sensitive(bEnableButtons && (m_xListItemsLB->get_selected_index() > 0));
+ m_xListDownPB->set_sensitive(bEnableButtons &&
+ (m_xListItemsLB->get_selected_index() < (m_xListItemsLB->n_children() - 1)));
+}
+
+// renew types in SelectionBox
+void SwFieldFuncPage::UpdateSubType()
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ // fill Selection-Listbox
+ m_xSelectionLB->freeze();
+ m_xSelectionLB->clear();
+
+ std::vector<OUString> aLst;
+ GetFieldMgr().GetSubTypes(nTypeId, aLst);
+ const size_t nCount = aLst.size();
+
+ for (size_t i = 0; i < nCount; ++i)
+ m_xSelectionLB->append(OUString::number(i), aLst[i]);
+ m_xSelectionLB->thaw();
+
+ bool bEnable = nCount != 0;
+
+ m_xSelectionLB->set_sensitive( bEnable );
+
+ if (bEnable)
+ m_xSelectionLB->select(0);
+
+ if (nTypeId == SwFieldTypesEnum::Macro)
+ {
+ const bool bHasMacro = !GetFieldMgr().GetMacroPath().isEmpty();
+
+ if (bHasMacro)
+ {
+ m_xNameED->set_text(GetFieldMgr().GetMacroName());
+ m_xValueGroup->set_sensitive(true);
+ }
+ EnableInsert(bHasMacro);
+ }
+}
+
+// call MacroBrowser, fill Listbox with Macros
+IMPL_LINK_NOARG( SwFieldFuncPage, MacroHdl, weld::Button&, void)
+{
+ if (GetFieldMgr().ChooseMacro(GetFrameWeld()))
+ UpdateSubType();
+}
+
+bool SwFieldFuncPage::FillItemSet(SfxItemSet* )
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ sal_uInt16 nSubType = 0;
+
+ const sal_Int32 nEntryPos = m_xFormatLB->get_selected_index();
+ const sal_uLong nFormat = (nEntryPos == -1)
+ ? 0 : m_xFormatLB->get_id(nEntryPos).toUInt32();
+
+ OUString aVal(m_xValueED->get_text());
+ OUString aName(m_xNameED->get_text());
+
+ switch(nTypeId)
+ {
+ case SwFieldTypesEnum::Input:
+ nSubType = INP_TXT;
+ // to prevent removal of CR/LF restore old content
+ if (!m_xNameED->get_value_changed_from_saved() && IsFieldEdit())
+ aName = GetCurField()->GetPar1();
+
+ break;
+
+ case SwFieldTypesEnum::Macro:
+ // use the full script URL, not the name in the Edit control
+ aName = GetFieldMgr().GetMacroPath();
+ break;
+
+ case SwFieldTypesEnum::ConditionalText:
+ aVal = m_xCond1ED->get_text() + "|" + m_xCond2ED->get_text();
+ break;
+ case SwFieldTypesEnum::Dropdown :
+ {
+ aName = m_xListNameED->get_text();
+ for (sal_Int32 i = 0, nEntryCount = m_xListItemsLB->n_children(); i < nEntryCount; ++i)
+ {
+ if(i)
+ aVal += OUStringChar(DB_DELIM);
+ aVal += m_xListItemsLB->get_text(i);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!IsFieldEdit() ||
+ m_xNameED->get_value_changed_from_saved() ||
+ m_xValueED->get_value_changed_from_saved() ||
+ m_xCond1ED->get_value_changed_from_saved() ||
+ m_xCond2ED->get_value_changed_from_saved() ||
+ m_xListNameED->get_value_changed_from_saved() ||
+ bDropDownLBChanged ||
+ nOldFormat != nFormat)
+ {
+ InsertField( nTypeId, nSubType, aName, aVal, nFormat );
+ }
+
+ ModifyHdl(m_xNameED->get_widget()); // enable/disable Insert if applicable
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldFuncPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldFuncPage>(pPage, pController, pAttrSet);
+}
+
+sal_uInt16 SwFieldFuncPage::GetGroup()
+{
+ return GRP_FKT;
+}
+
+void SwFieldFuncPage::FillUserData()
+{
+ const sal_Int32 nEntryPos = m_xTypeLB->get_selected_index();
+ const sal_uInt16 nTypeSel = ( -1 == nEntryPos )
+ ? USHRT_MAX
+ : m_xTypeLB->get_id(nEntryPos).toUInt32();
+ SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel ));
+}
+
+IMPL_LINK_NOARG(SwFieldFuncPage, ModifyHdl, weld::Entry&, void)
+{
+ const sal_Int32 nLen = m_xNameED->get_text().getLength();
+
+ bool bEnable = true;
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if( SwFieldTypesEnum::CombinedChars == nTypeId &&
+ (!nLen || nLen > MAX_COMBINED_CHARACTERS ))
+ bEnable = false;
+
+ EnableInsert( bEnable );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldfunc.hxx b/sw/source/ui/fldui/fldfunc.hxx
new file mode 100644
index 000000000..364a71d8e
--- /dev/null
+++ b/sw/source/ui/fldui/fldfunc.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDFUNC_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDFUNC_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#include <condedit.hxx>
+#include "fldpage.hxx"
+
+class SwFieldFuncPage : public SwFieldPage
+{
+ OUString m_sOldValueFT;
+ OUString m_sOldNameFT;
+
+ sal_uLong nOldFormat;
+ bool bDropDownLBChanged;
+
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<weld::TreeView> m_xFormatLB;
+ std::unique_ptr<weld::Label> m_xNameFT;
+ std::unique_ptr<ConditionEdit> m_xNameED;
+ std::unique_ptr<weld::Widget> m_xValueGroup;
+ std::unique_ptr<weld::Label> m_xValueFT;
+ std::unique_ptr<weld::Entry> m_xValueED;
+ std::unique_ptr<weld::Label> m_xCond1FT;
+ std::unique_ptr<ConditionEdit> m_xCond1ED;
+ std::unique_ptr<weld::Label> m_xCond2FT;
+ std::unique_ptr<ConditionEdit> m_xCond2ED;
+ std::unique_ptr<weld::Button> m_xMacroBT;
+
+ //controls of "Input list"
+ std::unique_ptr<weld::Widget> m_xListGroup;
+ std::unique_ptr<weld::Label> m_xListItemFT;
+ std::unique_ptr<weld::Entry> m_xListItemED;
+ std::unique_ptr<weld::Button> m_xListAddPB;
+ std::unique_ptr<weld::Label> m_xListItemsFT;
+ std::unique_ptr<weld::TreeView> m_xListItemsLB;
+ std::unique_ptr<weld::Button> m_xListRemovePB;
+ std::unique_ptr<weld::Button> m_xListUpPB;
+ std::unique_ptr<weld::Button> m_xListDownPB;
+ std::unique_ptr<weld::Label> m_xListNameFT;
+ std::unique_ptr<weld::Entry> m_xListNameED;
+
+ DECL_LINK( TypeHdl, weld::TreeView&, void );
+ DECL_LINK( SelectHdl, weld::TreeView&, void );
+ DECL_LINK( InsertMacroHdl, weld::TreeView&, bool );
+ DECL_LINK( ModifyHdl, weld::Entry&, void );
+ DECL_LINK( ListModifyReturnActionHdl, weld::Entry&, bool );
+ DECL_LINK( ListModifyButtonHdl, weld::Button&, void );
+ DECL_LINK( ListEnableHdl, weld::Entry&, void );
+ DECL_LINK( ListEnableListBoxHdl, weld::TreeView&, void );
+ void ListModifyHdl(const weld::Widget*);
+
+ // select Macro
+ DECL_LINK( MacroHdl, weld::Button&, void );
+
+ void UpdateSubType();
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldFuncPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pSet);
+ virtual ~SwFieldFuncPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual void FillUserData() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldpage.cxx b/sw/source/ui/fldui/fldpage.cxx
new file mode 100644
index 000000000..00c31c9ba
--- /dev/null
+++ b/sw/source/ui/fldui/fldpage.cxx
@@ -0,0 +1,348 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svl/stritem.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <dbfld.hxx>
+#include <flddat.hxx>
+#include <fmtfld.hxx>
+#include <viewopt.hxx>
+#include <fldedt.hxx>
+#include <docsh.hxx>
+#include <swmodule.hxx>
+#include <view.hxx>
+#include <wrtsh.hxx>
+#include <expfld.hxx>
+#include <fldtdlg.hxx>
+#include "fldpage.hxx"
+#include <docufld.hxx>
+#include <cmdid.h>
+#include <sfx2/bindings.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace ::com::sun::star;
+
+// note: pAttrSet may be null if the dialog is restored on startup
+SwFieldPage::SwFieldPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription,
+ const OString& rID, const SfxItemSet *pAttrSet)
+ : SfxTabPage(pPage, pController, rUIXMLDescription, rID, pAttrSet)
+ , m_pCurField(nullptr)
+ , m_pWrtShell(nullptr)
+ , m_nTypeSel(-1)
+ , m_nSelectionSel(-1)
+ , m_bFieldEdit(false)
+ , m_bInsert(true)
+ , m_bFieldDlgHtmlMode(false)
+ , m_bRefresh(false)
+ , m_bFirstHTMLInit(true)
+{
+}
+
+SwFieldPage::~SwFieldPage()
+{
+}
+
+// initialise TabPage
+void SwFieldPage::Init()
+{
+ SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current());
+ bool bNewMode = 0 != (::GetHtmlMode(pDocSh) & HTMLMODE_ON);
+
+ m_bFieldEdit = nullptr == dynamic_cast<SwFieldDlg*>(GetDialogController());
+
+ // newly initialise FieldManager. important for
+ // Dok-Switch (fldtdlg:ReInitTabPage)
+ m_pCurField = m_aMgr.GetCurField();
+
+ if( bNewMode == m_bFieldDlgHtmlMode )
+ return;
+
+ m_bFieldDlgHtmlMode = bNewMode;
+
+ // initialise Rangelistbox
+ if( !(m_bFieldDlgHtmlMode && m_bFirstHTMLInit) )
+ return;
+
+ m_bFirstHTMLInit = false;
+ SwWrtShell *pSh = m_pWrtShell;
+ if(! pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ SwDoc* pDoc = pSh->GetDoc();
+ pSh->InsertFieldType( SwSetExpFieldType( pDoc,
+ "HTML_ON", 1));
+ pSh->InsertFieldType( SwSetExpFieldType(pDoc,
+ "HTML_OFF", 1));
+ }
+}
+
+// newly initialise page
+void SwFieldPage::Activate()
+{
+ EnableInsert(m_bInsert);
+}
+
+// complete reset; edit new field
+void SwFieldPage::EditNewField( bool bOnlyActivate )
+{
+ if (!bOnlyActivate)
+ m_nTypeSel = -1;
+ m_nSelectionSel = -1;
+ m_bRefresh = true;
+ Reset(nullptr);
+ m_bRefresh = false;
+}
+
+// insert field
+void SwFieldPage::InsertField(SwFieldTypesEnum nTypeId, sal_uInt16 nSubType, const OUString& rPar1,
+ const OUString& rPar2, sal_uInt32 nFormatId,
+ sal_Unicode cSeparator, bool bIsAutomaticLanguage)
+{
+ SwView* pView = GetActiveView();
+ if (!pView)
+ return;
+
+ SwWrtShell *pSh = m_pWrtShell ? m_pWrtShell : pView->GetWrtShellPtr();
+
+ if (!IsFieldEdit()) // insert new field
+ {
+ SwInsertField_Data aData(nTypeId, nSubType, rPar1, rPar2, nFormatId, nullptr, cSeparator, bIsAutomaticLanguage );
+ //#i26566# provide parent for SwWrtShell::StartInputFieldDlg
+ aData.m_pParent = &GetDialogController()->GetOKButton();
+ m_aMgr.InsertField( aData );
+
+ uno::Reference< frame::XDispatchRecorder > xRecorder =
+ pView->GetViewFrame()->GetBindings().GetRecorder();
+ if ( xRecorder.is() )
+ {
+ bool bRecordDB = SwFieldTypesEnum::Database == nTypeId ||
+ SwFieldTypesEnum::DatabaseSetNumber == nTypeId ||
+ SwFieldTypesEnum::DatabaseNumberSet == nTypeId ||
+ SwFieldTypesEnum::DatabaseNextSet == nTypeId ||
+ SwFieldTypesEnum::DatabaseName == nTypeId ;
+
+ SfxRequest aReq( pView->GetViewFrame(),
+ bRecordDB ? FN_INSERT_DBFIELD : FN_INSERT_FIELD );
+ if(bRecordDB)
+ {
+ sal_Int32 nIdx{ 0 };
+ aReq.AppendItem(SfxStringItem
+ (FN_INSERT_DBFIELD,rPar1.getToken(0, DB_DELIM, nIdx)));
+ aReq.AppendItem(SfxStringItem
+ (FN_PARAM_1,rPar1.getToken(0, DB_DELIM, nIdx)));
+ aReq.AppendItem(SfxInt32Item
+ (FN_PARAM_3, o3tl::toInt32(o3tl::getToken(rPar1, 0, DB_DELIM, nIdx))));
+ aReq.AppendItem(SfxStringItem
+ (FN_PARAM_2,rPar1.getToken(0, DB_DELIM, nIdx)));
+ }
+ else
+ {
+ aReq.AppendItem(SfxStringItem(FN_INSERT_FIELD, rPar1));
+ aReq.AppendItem(SfxStringItem
+ (FN_PARAM_3, OUString(cSeparator)));
+ aReq.AppendItem(SfxUInt16Item(FN_PARAM_FIELD_SUBTYPE, nSubType));
+ }
+ aReq.AppendItem(SfxUInt16Item(FN_PARAM_FIELD_TYPE , static_cast<sal_uInt16>(nTypeId)));
+ aReq.AppendItem(SfxStringItem(FN_PARAM_FIELD_CONTENT, rPar2));
+ aReq.AppendItem(SfxUInt32Item(FN_PARAM_FIELD_FORMAT , nFormatId));
+ aReq.Done();
+ }
+
+ }
+ else // change field
+ {
+ std::unique_ptr<SwField> pTmpField = m_pCurField->CopyField();
+
+ OUString sPar1(rPar1);
+ OUString sPar2(rPar2);
+ switch( nTypeId )
+ {
+ case SwFieldTypesEnum::Date:
+ case SwFieldTypesEnum::Time:
+ nSubType = static_cast< sal_uInt16 >(((nTypeId == SwFieldTypesEnum::Date) ? DATEFLD : TIMEFLD) |
+ ((nSubType == DATE_VAR) ? 0 : FIXEDFLD));
+ break;
+
+ case SwFieldTypesEnum::DatabaseName:
+ case SwFieldTypesEnum::DatabaseNextSet:
+ case SwFieldTypesEnum::DatabaseNumberSet:
+ case SwFieldTypesEnum::DatabaseSetNumber:
+ {
+ sal_Int32 nPos = 0;
+ SwDBData aData;
+
+ aData.sDataSource = rPar1.getToken(0, DB_DELIM, nPos);
+ aData.sCommand = rPar1.getToken(0, DB_DELIM, nPos);
+ aData.nCommandType = o3tl::toInt32(o3tl::getToken(rPar1, 0, DB_DELIM, nPos));
+ sPar1 = rPar1.copy(nPos);
+
+ static_cast<SwDBNameInfField*>(pTmpField.get())->SetDBData(aData);
+ }
+ break;
+
+ case SwFieldTypesEnum::Database:
+ {
+ SwDBData aData;
+ sal_Int32 nIdx{ 0 };
+ aData.sDataSource = rPar1.getToken(0, DB_DELIM, nIdx);
+ aData.sCommand = rPar1.getToken(0, DB_DELIM, nIdx);
+ aData.nCommandType = o3tl::toInt32(o3tl::getToken(rPar1, 0, DB_DELIM, nIdx));
+ OUString sColumn = rPar1.getToken(0, DB_DELIM, nIdx);
+
+ auto pOldType = static_cast<SwDBFieldType*>(pTmpField->GetTyp());
+ auto pType = static_cast<SwDBFieldType*>(pSh->InsertFieldType(SwDBFieldType(pSh->GetDoc(), sColumn, aData)));
+ if(auto pFormatField = pOldType->FindFormatForField(m_pCurField))
+ {
+ pFormatField->RegisterToFieldType(*pType);
+ pTmpField->ChgTyp(pType);
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::Sequence:
+ {
+ SwSetExpFieldType* pTyp = static_cast<SwSetExpFieldType*>(pTmpField->GetTyp());
+ pTyp->SetOutlineLvl( static_cast< sal_uInt8 >(nSubType & 0xff));
+ pTyp->SetDelimiter(OUString(cSeparator));
+
+ nSubType = nsSwGetSetExpType::GSE_SEQ;
+ }
+ break;
+
+ case SwFieldTypesEnum::Input:
+ {
+ // User- or SetField ?
+ if (m_aMgr.GetFieldType(SwFieldIds::User, sPar1) == nullptr &&
+ !(pTmpField->GetSubType() & INP_TXT)) // SETEXPFLD
+ {
+ SwSetExpField* pField = static_cast<SwSetExpField*>(pTmpField.get());
+ pField->SetPromptText(sPar2);
+ sPar2 = pField->GetPar2();
+ }
+ }
+ break;
+ case SwFieldTypesEnum::DocumentInfo:
+ {
+ if( nSubType == nsSwDocInfoSubType::DI_CUSTOM )
+ {
+ SwDocInfoField* pDocInfo = static_cast<SwDocInfoField*>( pTmpField.get() );
+ pDocInfo->SetName( rPar1 );
+ }
+ }
+ break;
+ default: break;
+ }
+
+ pSh->StartAllAction();
+
+ pTmpField->SetSubType(nSubType);
+ pTmpField->SetAutomaticLanguage(bIsAutomaticLanguage);
+
+ m_aMgr.UpdateCurField( nFormatId, sPar1, sPar2, std::move(pTmpField) );
+
+ m_pCurField = m_aMgr.GetCurField();
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::HiddenText:
+ case SwFieldTypesEnum::HiddenParagraph:
+ m_aMgr.EvalExpFields(pSh);
+ break;
+ default: break;
+ }
+
+ pSh->SetUndoNoResetModified();
+ pSh->EndAllAction();
+ }
+}
+
+void SwFieldPage::SavePos( const weld::TreeView& rLst1 )
+{
+ if (rLst1.n_children())
+ m_aLstStrArr[ 0 ] = rLst1.get_selected_text();
+ else
+ m_aLstStrArr[ 0 ].clear();
+ m_aLstStrArr[ 1 ].clear();
+ m_aLstStrArr[ 2 ].clear();
+}
+
+void SwFieldPage::RestorePos(weld::TreeView& rLst1)
+{
+ sal_Int32 nPos = 0;
+ if (rLst1.n_children() && !m_aLstStrArr[ 0 ].isEmpty() &&
+ -1 != ( nPos = rLst1.find_text(m_aLstStrArr[ 0 ] ) ) )
+ rLst1.select( nPos );
+}
+
+// Insert new fields
+IMPL_LINK( SwFieldPage, TreeViewInsertHdl, weld::TreeView&, rBox, bool )
+{
+ InsertHdl(&rBox);
+ return true;
+}
+
+void SwFieldPage::InsertHdl(weld::Widget* pBtn)
+{
+ if (SwFieldDlg *pDlg = dynamic_cast<SwFieldDlg*>(GetDialogController()))
+ {
+ pDlg->InsertHdl();
+
+ if (pBtn)
+ pBtn->grab_focus(); // because of InputField-Dlg
+ }
+ else
+ {
+ SwFieldEditDlg *pEditDlg = static_cast<SwFieldEditDlg*>(GetDialogController());
+ pEditDlg->InsertHdl();
+ }
+}
+
+// enable/disable "Insert"-Button
+void SwFieldPage::EnableInsert(bool bEnable)
+{
+ if (SwFieldDlg *pDlg = dynamic_cast<SwFieldDlg*>(GetDialogController()))
+ {
+ if (pDlg->GetCurTabPage() == this)
+ pDlg->EnableInsert(bEnable);
+ }
+ else
+ {
+ SwFieldEditDlg *pEditDlg = static_cast<SwFieldEditDlg*>(GetDialogController());
+ pEditDlg->EnableInsert(bEnable);
+ }
+
+ m_bInsert = bEnable;
+}
+
+IMPL_LINK_NOARG(SwFieldPage, NumFormatHdl, weld::TreeView&, bool)
+{
+ InsertHdl(nullptr);
+ return true;
+}
+
+void SwFieldPage::SetWrtShell( SwWrtShell* pShell )
+{
+ m_pWrtShell = pShell;
+ m_aMgr.SetWrtShell( pShell );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldpage.hxx b/sw/source/ui/fldui/fldpage.hxx
new file mode 100644
index 000000000..9c0cecf5a
--- /dev/null
+++ b/sw/source/ui/fldui/fldpage.hxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDPAGE_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDPAGE_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <fldmgr.hxx>
+
+#define FIELD_COLUMN_WIDTH 19
+
+const int coLBCount = 3;
+
+class SwFieldPage : public SfxTabPage
+{
+ OUString m_aLstStrArr[ coLBCount ];
+ SwFieldMgr m_aMgr;
+ SwField *m_pCurField;
+ SwWrtShell* m_pWrtShell;
+ sal_Int32 m_nTypeSel;
+ sal_Int32 m_nSelectionSel;
+ bool m_bFieldEdit;
+ bool m_bInsert;
+ bool m_bFieldDlgHtmlMode;
+ bool m_bRefresh;
+ bool m_bFirstHTMLInit;
+
+protected:
+
+ sal_Int32 GetTypeSel() const { return m_nTypeSel;}
+ void SetTypeSel(sal_Int32 nSet) { m_nTypeSel = nSet;}
+ sal_Int32 GetSelectionSel() const { return m_nSelectionSel;}
+ void SetSelectionSel(sal_Int32 nSet){ m_nSelectionSel = nSet;}
+ bool IsFieldDlgHtmlMode() const { return m_bFieldDlgHtmlMode;}
+ bool IsRefresh() const { return m_bRefresh;}
+ SwField* GetCurField() { return m_pCurField;}
+ SwWrtShell* GetWrtShell() { return m_pWrtShell;}
+
+ DECL_LINK( TreeViewInsertHdl, weld::TreeView&, bool );
+ DECL_LINK( NumFormatHdl, weld::TreeView&, bool );
+ void InsertHdl(weld::Widget*);
+
+ void Init();
+ void SavePos( const weld::TreeView& rLst1);
+ void RestorePos( weld::TreeView& rLst1 );
+ void EnableInsert(bool bEnable);
+ bool IsFieldEdit() const { return m_bFieldEdit; }
+
+ // insert field
+ void InsertField(SwFieldTypesEnum nTypeId,
+ sal_uInt16 nSubType,
+ const OUString& rPar1,
+ const OUString& rPar2,
+ sal_uInt32 nFormatId,
+ sal_Unicode cDelim = ' ',
+ bool bIsAutomaticLanguage = true);
+
+public:
+ SwFieldPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription,
+ const OString& rID, const SfxItemSet *pAttrSet);
+
+ virtual ~SwFieldPage() override;
+
+ virtual void Activate() override;
+
+ SwFieldMgr& GetFieldMgr() { return m_aMgr; }
+ void SetWrtShell( SwWrtShell* m_pWrtShell );
+ void EditNewField( bool bOnlyActivate = false );
+ virtual sal_uInt16 GetGroup() = 0;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldref.cxx b/sw/source/ui/fldui/fldref.cxx
new file mode 100644
index 000000000..08a44c5c8
--- /dev/null
+++ b/sw/source/ui/fldui/fldref.cxx
@@ -0,0 +1,1154 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <swtypes.hxx>
+#include <IMark.hxx>
+#include <expfld.hxx>
+#include <swmodule.hxx>
+#include "fldref.hxx"
+#include <frmatr.hxx>
+#include <reffld.hxx>
+#include <wrtsh.hxx>
+
+#include <fldref.hrc>
+#include <strings.hrc>
+#include <SwNodeNum.hxx>
+#include <IDocumentMarkAccess.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <unotools/charclass.hxx>
+#include <osl/diagnose.h>
+
+#include <comphelper/string.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include <vcl/settings.hxx>
+
+#define REFFLDFLAG 0x4000
+#define REFFLDFLAG_BOOKMARK 0x4800
+#define REFFLDFLAG_FOOTNOTE 0x5000
+#define REFFLDFLAG_ENDNOTE 0x6000
+// #i83479#
+#define REFFLDFLAG_HEADING 0x7100
+#define REFFLDFLAG_NUMITEM 0x7200
+
+static sal_uInt16 nFieldDlgFormatSel = 0;
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+SwFieldRefPage::SwFieldRefPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet )
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/fldrefpage.ui", "FieldRefPage", pCoreSet)
+ , mpSavedSelectedTextNode(nullptr)
+ , mnSavedSelectedPos(0)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xSelection(m_xBuilder->weld_widget("selectframe"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xSelectionToolTipLB(m_xBuilder->weld_tree_view("selecttip"))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xFormatLB(m_xBuilder->weld_tree_view("format"))
+ , m_xNameFT(m_xBuilder->weld_label("nameft"))
+ , m_xNameED(m_xBuilder->weld_entry("name"))
+ , m_xValueED(m_xBuilder->weld_entry("value"))
+ , m_xFilterED(m_xBuilder->weld_entry("filter"))
+{
+ m_xSelectionLB->make_sorted();
+ // #i83479#
+ for (size_t i = 0; i < SAL_N_ELEMENTS(FLD_REF_PAGE_TYPES); ++i)
+ {
+ m_xTypeLB->append_text(SwResId(FLD_REF_PAGE_TYPES[i]));
+ m_xFormatLB->append_text(SwResId(FLD_REF_PAGE_TYPES[i]));
+ }
+
+ sBookmarkText = m_xTypeLB->get_text(0);
+ sFootnoteText = m_xTypeLB->get_text(1);
+ sEndnoteText = m_xTypeLB->get_text(2);
+ // #i83479#
+ sHeadingText = m_xTypeLB->get_text(3);
+ sNumItemText = m_xTypeLB->get_text(4);
+
+ auto nHeight = m_xTypeLB->get_height_rows(8);
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ m_xTypeLB->set_size_request(nWidth * 1.33, nHeight);
+ m_xFormatLB->set_size_request(nWidth * 1.33, nHeight);
+ m_xSelection->set_size_request(nWidth * 2, nHeight);
+ nHeight = m_xTypeLB->get_height_rows(8);
+ m_xSelectionToolTipLB->set_size_request(nHeight, nWidth*2);
+
+ m_xTypeLB->clear();
+
+ m_xNameED->connect_changed(LINK(this, SwFieldRefPage, ModifyHdl));
+ m_xFilterED->connect_changed( LINK( this, SwFieldRefPage, ModifyHdl_Impl ) );
+
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldRefPage, TreeViewInsertHdl));
+ m_xTypeLB->connect_changed(LINK(this, SwFieldRefPage, TypeHdl));
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldRefPage, SubTypeListBoxHdl));
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldRefPage, TreeViewInsertHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldRefPage, TreeViewInsertHdl));
+
+ // #i83479#
+ m_xSelectionToolTipLB->connect_changed( LINK(this, SwFieldRefPage, SubTypeTreeListBoxHdl) );
+ m_xSelectionToolTipLB->connect_row_activated( LINK(this, SwFieldRefPage, TreeViewInsertHdl) );
+ m_xFilterED->grab_focus();
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-ref");
+ m_xNameED->set_buildable_name(m_xNameED->get_buildable_name() + "-ref");
+ m_xValueED->set_buildable_name(m_xValueED->get_buildable_name() + "-ref");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-ref");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-ref");
+}
+
+SwFieldRefPage::~SwFieldRefPage()
+{
+}
+
+IMPL_LINK_NOARG(SwFieldRefPage, ModifyHdl_Impl, weld::Entry&, void)
+{
+ UpdateSubType(comphelper::string::strip(m_xFilterED->get_text(), ' '));
+ // tdf#135938 - refresh cross-reference name after filter selection has changed
+ SubTypeHdl();
+}
+
+// #i83479#
+void SwFieldRefPage::SaveSelectedTextNode()
+{
+ mpSavedSelectedTextNode = nullptr;
+ mnSavedSelectedPos = 0;
+ if ( !m_xSelectionToolTipLB->get_visible() )
+ return;
+
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ const sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ if ( nTypeId == REFFLDFLAG_HEADING )
+ {
+ mnSavedSelectedPos = m_xSelectionToolTipLB->get_id(nEntry).toUInt32();
+ if ( mnSavedSelectedPos < maOutlineNodes.size() )
+ {
+ mpSavedSelectedTextNode = maOutlineNodes[mnSavedSelectedPos];
+ }
+ }
+ else if ( nTypeId == REFFLDFLAG_NUMITEM )
+ {
+ mnSavedSelectedPos = m_xSelectionToolTipLB->get_id(nEntry).toUInt32();
+ if ( mnSavedSelectedPos < maNumItems.size() )
+ {
+ mpSavedSelectedTextNode = maNumItems[mnSavedSelectedPos]->GetTextNode();
+ }
+ }
+}
+
+void SwFieldRefPage::Reset(const SfxItemSet* )
+{
+ if (!IsFieldEdit())
+ {
+ SavePos(*m_xTypeLB);
+ // #i83479#
+ SaveSelectedTextNode();
+ }
+ SetSelectionSel(-1);
+ SetTypeSel(-1);
+ Init(); // general initialisation
+
+ // initialise TypeListBox
+ m_xTypeLB->freeze();
+ m_xTypeLB->clear();
+
+ // fill Type-Listbox
+
+ // set/insert reference
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ for (short i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ const SwFieldTypesEnum nTypeId = SwFieldMgr::GetTypeId(i);
+
+ if (!IsFieldEdit() || nTypeId != SwFieldTypesEnum::SetRef)
+ {
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ }
+ }
+
+ // #i83479#
+ // entries for headings and numbered items
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_HEADING), sHeadingText);
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_NUMITEM), sNumItemText);
+
+ // fill up with the sequence types
+ SwWrtShell *pSh = GetWrtShell();
+ if (!pSh)
+ pSh = ::GetActiveWrtShell();
+ if (!pSh)
+ return;
+
+ // tdf#148432 in LTR UI override the navigator treeview direction based on
+ // the first page directionality
+ if (!AllSettings::GetLayoutRTL())
+ {
+ const SwPageDesc& rDesc = pSh->GetPageDesc(0);
+ const SvxFrameDirectionItem& rFrameDir = rDesc.GetMaster().GetFrameDir();
+ m_xSelectionToolTipLB->set_direction(rFrameDir.GetValue() == SvxFrameDirection::Horizontal_RL_TB);
+ }
+
+ const size_t nFieldTypeCnt = pSh->GetFieldTypeCount(SwFieldIds::SetExp);
+
+ OSL_ENSURE( nFieldTypeCnt < o3tl::make_unsigned(REFFLDFLAG), "<SwFieldRefPage::Reset> - Item index will overlap flags!" );
+
+ for (size_t n = 0; n < nFieldTypeCnt; ++n)
+ {
+ SwSetExpFieldType* pType = static_cast<SwSetExpFieldType*>(pSh->GetFieldType(n, SwFieldIds::SetExp));
+
+ if ((nsSwGetSetExpType::GSE_SEQ & pType->GetType()) && pType->HasWriterListeners() && pSh->IsUsed(*pType))
+ {
+ m_xTypeLB->append(OUString::number(REFFLDFLAG | n), pType->GetName());
+ }
+ }
+
+ // text marks - now always (because of globaldocuments)
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_BOOKMARK), sBookmarkText);
+
+ // footnotes:
+ if( pSh->HasFootnotes() )
+ {
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_FOOTNOTE), sFootnoteText);
+ }
+
+ // endnotes:
+ if ( pSh->HasFootnotes(true) )
+ {
+ m_xTypeLB->append(OUString::number(REFFLDFLAG_ENDNOTE), sEndnoteText);
+ }
+
+ m_xTypeLB->thaw();
+
+ // select old Pos
+ if (!IsFieldEdit())
+ RestorePos(*m_xTypeLB);
+
+ nFieldDlgFormatSel = 0;
+
+ sal_uInt16 nFormatBoxPosition = USHRT_MAX;
+ if( !IsRefresh() )
+ {
+ sal_Int32 nIdx{ 0 };
+ const OUString sUserData = GetUserData();
+ if(!IsRefresh() && o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx),
+ u"" USER_DATA_VERSION_1))
+ {
+ const sal_uInt16 nVal = static_cast< sal_uInt16 >(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ if(nVal != USHRT_MAX)
+ {
+ for(sal_Int32 i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ m_xTypeLB->select(i);
+ break;
+ }
+ }
+ if (nIdx>=0 && nIdx<sUserData.getLength())
+ {
+ nFormatBoxPosition = static_cast< sal_uInt16 >(o3tl::toInt32(o3tl::getToken(sUserData, 0, ';', nIdx)));
+ }
+ }
+ }
+ }
+ TypeHdl(*m_xTypeLB);
+ if (nFormatBoxPosition < m_xFormatLB->n_children())
+ {
+ m_xFormatLB->select(nFormatBoxPosition);
+ }
+ if (IsFieldEdit())
+ {
+ m_xTypeLB->save_value();
+ m_xSelectionLB->save_value();
+ m_xFormatLB->save_value();
+ m_xNameED->save_value();
+ m_xValueED->save_value();
+ m_xFilterED->set_text(OUString());
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldRefPage, TypeHdl, weld::TreeView&, void)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if(GetTypeSel() == -1)
+ {
+ if (IsFieldEdit())
+ {
+ // select positions
+ OUString sName;
+ sal_uInt16 nFlag = 0;
+
+ switch( GetCurField()->GetSubType() )
+ {
+ case REF_BOOKMARK:
+ {
+ // #i83479#
+ SwGetRefField* pRefField = dynamic_cast<SwGetRefField*>(GetCurField());
+ if ( pRefField &&
+ pRefField->IsRefToHeadingCrossRefBookmark() )
+ {
+ sName = sHeadingText;
+ nFlag = REFFLDFLAG_HEADING;
+ }
+ else if ( pRefField &&
+ pRefField->IsRefToNumItemCrossRefBookmark() )
+ {
+ sName = sNumItemText;
+ nFlag = REFFLDFLAG_NUMITEM;
+ }
+ else
+ {
+ sName = sBookmarkText;
+ nFlag = REFFLDFLAG_BOOKMARK;
+ }
+ }
+ break;
+
+ case REF_FOOTNOTE:
+ sName = sFootnoteText;
+ nFlag = REFFLDFLAG_FOOTNOTE;
+ break;
+
+ case REF_ENDNOTE:
+ sName = sEndnoteText;
+ nFlag = REFFLDFLAG_ENDNOTE;
+ break;
+
+ case REF_SETREFATTR:
+ sName = SwResId(STR_GETREFFLD);
+ nFlag = REF_SETREFATTR;
+ break;
+
+ case REF_SEQUENCEFLD:
+ {
+ SwGetRefField const*const pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
+ if (pRefField)
+ {
+ sName = pRefField->GetSetRefName();
+ }
+ nFlag = REFFLDFLAG;
+ break;
+ }
+ }
+
+ if (m_xTypeLB->find_text(sName) == -1) // reference to deleted mark
+ {
+ m_xTypeLB->append(OUString::number(nFlag), sName);
+ }
+
+ m_xTypeLB->select_text(sName);
+ SetTypeSel(m_xTypeLB->get_selected_index());
+ }
+ else
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+ }
+
+ if (nOld == GetTypeSel())
+ return;
+
+ sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ bool bName = false;
+ nFieldDlgFormatSel = 0;
+
+ if ( ( !IsFieldEdit() || m_xSelectionLB->n_children() ) &&
+ nOld != -1 )
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ m_xFilterED->set_text(OUString());
+ }
+
+ // fill selection-ListBox
+ UpdateSubType(comphelper::string::strip(m_xFilterED->get_text(), ' '));
+
+ switch (nTypeId)
+ {
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef):
+ if (nOld != -1 && REFFLDFLAG & m_xTypeLB->get_id(nOld).toUInt32())
+ // the old one stays
+ nFieldDlgFormatSel = m_xFormatLB->get_selected_index();
+ bName = true;
+ break;
+
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef):
+ bName = true;
+ break;
+
+ case REFFLDFLAG_BOOKMARK:
+ bName = true;
+ [[fallthrough]];
+ default:
+ if( REFFLDFLAG & nTypeId )
+ {
+ const sal_uInt16 nOldId = nOld != -1 ? m_xTypeLB->get_id(nOld).toUInt32() : 0;
+ if( nOldId & REFFLDFLAG || nOldId == static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef) )
+ // then the old one stays
+ nFieldDlgFormatSel = m_xFormatLB->get_selected_index();
+ }
+ break;
+ }
+
+ m_xNameED->set_sensitive(bName);
+ m_xNameFT->set_sensitive(bName);
+
+ // fill Format-Listbox
+ sal_Int32 nSize = FillFormatLB(nTypeId);
+ bool bFormat = nSize != 0;
+ m_xFormat->set_sensitive(bFormat);
+
+ SubTypeHdl();
+ ModifyHdl(*m_xNameED);
+ ModifyHdl(*m_xFilterED);
+}
+
+IMPL_LINK_NOARG(SwFieldRefPage, SubTypeTreeListBoxHdl, weld::TreeView&, void)
+{
+ SubTypeHdl();
+}
+
+IMPL_LINK_NOARG(SwFieldRefPage, SubTypeListBoxHdl, weld::TreeView&, void)
+{
+ SubTypeHdl();
+}
+
+void SwFieldRefPage::SubTypeHdl()
+{
+ sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ switch(nTypeId)
+ {
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef):
+ if (!IsFieldEdit() || m_xSelectionLB->get_selected_index() != -1)
+ {
+ m_xNameED->set_text(m_xSelectionLB->get_selected_text());
+ ModifyHdl(*m_xNameED);
+ }
+ break;
+
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef):
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ m_xValueED->set_text(pSh->GetSelText());
+ }
+
+ }
+ break;
+ // #i83479#
+ case REFFLDFLAG_HEADING:
+ case REFFLDFLAG_NUMITEM:
+ {
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ if (nEntry != -1)
+ m_xNameED->set_text(m_xSelectionToolTipLB->get_text(nEntry));
+ }
+ break;
+
+ default:
+ if (!IsFieldEdit() || m_xSelectionLB->get_selected_index() != -1)
+ m_xNameED->set_text(m_xSelectionLB->get_selected_text());
+ break;
+ }
+}
+
+// renew types in SelectionLB after filtering
+void SwFieldRefPage::UpdateSubType(const OUString& filterString)
+{
+ SwWrtShell *pSh = GetWrtShell();
+ if (!pSh)
+ pSh = ::GetActiveWrtShell();
+ if (!pSh)
+ return;
+
+ SwGetRefField const*const pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
+ const sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ OUString sOldSel;
+ // #i83479#
+ if ( m_xSelectionLB->get_visible() )
+ {
+ const sal_Int32 nSelectionSel = m_xSelectionLB->get_selected_index();
+ if (nSelectionSel != -1)
+ sOldSel = m_xSelectionLB->get_text(nSelectionSel);
+ }
+ if (IsFieldEdit() && pRefField && sOldSel.isEmpty())
+ sOldSel = OUString::number( pRefField->GetSeqNo() + 1 );
+
+ m_xSelectionLB->freeze();
+ m_xSelectionLB->clear();
+
+ if (REFFLDFLAG & nTypeId)
+ {
+ if (nTypeId == REFFLDFLAG_FOOTNOTE || nTypeId == REFFLDFLAG_ENDNOTE)
+ {
+ m_xSelectionLB->thaw();
+ m_xSelectionLB->make_unsorted();
+ m_xSelectionLB->freeze();
+ }
+ // #i83479#
+ else if (nTypeId != REFFLDFLAG_HEADING && nTypeId != REFFLDFLAG_NUMITEM)
+ {
+ m_xSelectionLB->thaw();
+ m_xSelectionLB->make_sorted();
+ m_xSelectionLB->freeze();
+ }
+ }
+
+ // #i83479#
+ m_xSelectionToolTipLB->freeze();
+ m_xSelectionToolTipLB->clear();
+ OUString m_sSelectionToolTipLBId;
+ bool bShowSelectionToolTipLB( false );
+
+ if( REFFLDFLAG & nTypeId )
+ {
+ if (nTypeId == REFFLDFLAG_BOOKMARK) // text marks!
+ {
+ // get all text marks
+ IDocumentMarkAccess* const pMarkAccess = pSh->getIDocumentMarkAccess();
+ for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
+ ppMark != pMarkAccess->getBookmarksEnd();
+ ++ppMark)
+ {
+ const ::sw::mark::IMark* pBkmk = *ppMark;
+ if(IDocumentMarkAccess::MarkType::BOOKMARK == IDocumentMarkAccess::GetType(*pBkmk))
+ {
+ bool isSubstring = MatchSubstring(pBkmk->GetName(), filterString);
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text( pBkmk->GetName() );
+ }
+ }
+ }
+ if (IsFieldEdit() && pRefField)
+ sOldSel = pRefField->GetSetRefName();
+ }
+ else if (nTypeId == REFFLDFLAG_FOOTNOTE)
+ {
+ SwSeqFieldList aArr;
+ const size_t nCnt = pSh->GetSeqFootnoteList( aArr );
+
+ for( size_t n = 0; n < nCnt; ++n )
+ {
+ bool isSubstring = MatchSubstring(aArr[ n ].sDlgEntry, filterString);
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text( aArr[ n ].sDlgEntry );
+ }
+ if (IsFieldEdit() && pRefField && pRefField->GetSeqNo() == aArr[ n ].nSeqNo)
+ sOldSel = aArr[n].sDlgEntry;
+ }
+ }
+ else if (nTypeId == REFFLDFLAG_ENDNOTE)
+ {
+ SwSeqFieldList aArr;
+ const size_t nCnt = pSh->GetSeqFootnoteList( aArr, true );
+
+ for( size_t n = 0; n < nCnt; ++n )
+ {
+ bool isSubstring = MatchSubstring(aArr[ n ].sDlgEntry, filterString);
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text( aArr[ n ].sDlgEntry );
+ }
+ if (IsFieldEdit() && pRefField && pRefField->GetSeqNo() == aArr[ n ].nSeqNo)
+ sOldSel = aArr[n].sDlgEntry;
+ }
+ }
+ // #i83479#
+ else if ( nTypeId == REFFLDFLAG_HEADING )
+ {
+ bShowSelectionToolTipLB = true;
+
+ const IDocumentOutlineNodes* pIDoc( pSh->getIDocumentOutlineNodesAccess() );
+ pIDoc->getOutlineNodes( maOutlineNodes );
+ bool bCertainTextNodeSelected( false );
+ for ( size_t nOutlIdx = 0; nOutlIdx < maOutlineNodes.size(); ++nOutlIdx )
+ {
+ if (!pIDoc->isOutlineInLayout(nOutlIdx, *pSh->GetLayout()))
+ {
+ continue; // skip it
+ }
+ bool isSubstring = MatchSubstring(pIDoc->getOutlineText(nOutlIdx, pSh->GetLayout(), true, true, false), filterString);
+ if(isSubstring)
+ {
+ OUString sId(OUString::number(nOutlIdx));
+ m_xSelectionToolTipLB->append(sId,
+ pIDoc->getOutlineText(nOutlIdx, pSh->GetLayout(), true, true, false));
+ if ((IsFieldEdit() && pRefField
+ && pRefField->GetReferencedTextNode() == maOutlineNodes[nOutlIdx])
+ || mpSavedSelectedTextNode == maOutlineNodes[nOutlIdx])
+ {
+ m_sSelectionToolTipLBId = sId;
+ sOldSel.clear();
+ bCertainTextNodeSelected = true;
+ }
+ else if ( !bCertainTextNodeSelected && mnSavedSelectedPos == nOutlIdx )
+ {
+ m_sSelectionToolTipLBId = sId;
+ sOldSel.clear();
+ }
+ }
+ }
+ }
+ else if ( nTypeId == REFFLDFLAG_NUMITEM )
+ {
+ bShowSelectionToolTipLB = true;
+
+ const IDocumentListItems* pIDoc( pSh->getIDocumentListItemsAccess() );
+ pIDoc->getNumItems( maNumItems );
+ bool bCertainTextNodeSelected( false );
+ for ( size_t nNumItemIdx = 0; nNumItemIdx < maNumItems.size(); ++nNumItemIdx )
+ {
+ if (!pIDoc->isNumberedInLayout(*maNumItems[nNumItemIdx], *pSh->GetLayout()))
+ {
+ continue; // skip it
+ }
+ bool isSubstring = MatchSubstring(pIDoc->getListItemText(*maNumItems[nNumItemIdx], *pSh->GetLayout()), filterString);
+ if(isSubstring)
+ {
+ OUString sId(OUString::number(nNumItemIdx));
+ m_xSelectionToolTipLB->append(sId,
+ pIDoc->getListItemText(*maNumItems[nNumItemIdx], *pSh->GetLayout()));
+ if ((IsFieldEdit() && pRefField
+ && pRefField->GetReferencedTextNode() == maNumItems[nNumItemIdx]->GetTextNode())
+ || mpSavedSelectedTextNode == maNumItems[nNumItemIdx]->GetTextNode())
+ {
+ m_sSelectionToolTipLBId = sId;
+ sOldSel.clear();
+ bCertainTextNodeSelected = true;
+ }
+ else if ( !bCertainTextNodeSelected && mnSavedSelectedPos == nNumItemIdx )
+ {
+ m_sSelectionToolTipLBId = sId;
+ sOldSel.clear();
+ }
+ }
+ }
+ }
+ else
+ {
+ // get the fields to Seq-FieldType:
+
+ SwSetExpFieldType* pType = static_cast<SwSetExpFieldType*>(pSh->GetFieldType(
+ nTypeId & ~REFFLDFLAG, SwFieldIds::SetExp ));
+ if( pType )
+ {
+ SwSeqFieldList aArr;
+ // old selection should be kept in non-edit mode
+ if(IsFieldEdit())
+ sOldSel.clear();
+
+ const size_t nCnt = pType->GetSeqFieldList(aArr, pSh->GetLayout());
+ for( size_t n = 0; n < nCnt; ++n )
+ {
+ bool isSubstring = MatchSubstring(aArr[ n ].sDlgEntry, filterString);
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text( aArr[ n ].sDlgEntry );
+ }
+ if (IsFieldEdit() && pRefField && sOldSel.isEmpty() &&
+ aArr[ n ].nSeqNo == pRefField->GetSeqNo())
+ sOldSel = aArr[ n ].sDlgEntry;
+ }
+
+ if (IsFieldEdit() && pRefField && sOldSel.isEmpty())
+ sOldSel = OUString::number( pRefField->GetSeqNo() + 1);
+ }
+ }
+ }
+ else
+ {
+ std::vector<OUString> aLst;
+ GetFieldMgr().GetSubTypes(static_cast<SwFieldTypesEnum>(nTypeId), aLst);
+ for(const OUString & i : aLst)
+ {
+ bool isSubstring = MatchSubstring( i , filterString );
+ if(isSubstring)
+ {
+ m_xSelectionLB->append_text(i);
+ }
+ }
+
+ if (IsFieldEdit() && pRefField)
+ sOldSel = pRefField->GetSetRefName();
+ }
+
+ // #i83479#
+ m_xSelectionLB->thaw();
+ m_xSelectionToolTipLB->thaw();
+ if (!m_sSelectionToolTipLBId.isEmpty())
+ m_xSelectionToolTipLB->select_id(m_sSelectionToolTipLBId);
+ m_xSelectionToolTipLB->set_visible( bShowSelectionToolTipLB );
+ m_xSelectionLB->set_visible( !bShowSelectionToolTipLB );
+ if ( bShowSelectionToolTipLB )
+ {
+ bool bEnable = m_xSelectionToolTipLB->n_children() != 0;
+ m_xSelection->set_sensitive( bEnable );
+
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ if (nEntry != -1)
+ m_xSelectionToolTipLB->scroll_to_row(nEntry);
+
+ if (IsFieldEdit() && nEntry == -1)
+ {
+ m_xNameED->set_text(sOldSel);
+ }
+ }
+ else
+ {
+ // enable or disable
+ bool bEnable = m_xSelectionLB->n_children() != 0;
+ m_xSelection->set_sensitive( bEnable );
+
+ if ( bEnable )
+ {
+ m_xSelectionLB->select_text(sOldSel);
+ if (m_xSelectionLB->get_selected_index() == -1 && !IsFieldEdit())
+ m_xSelectionLB->select(0);
+ }
+
+ if (IsFieldEdit() && m_xSelectionLB->get_selected_index() == -1) // in case the reference was already deleted...
+ m_xNameED->set_text(sOldSel);
+ }
+}
+
+bool SwFieldRefPage::MatchSubstring( const OUString& rListString, const OUString& rSubstr )
+{
+ if(rSubstr.isEmpty())
+ return true;
+ OUString aListString = GetAppCharClass().lowercase(rListString);
+ OUString aSubstr = GetAppCharClass().lowercase(rSubstr);
+ return aListString.indexOf(aSubstr) >= 0;
+}
+
+namespace {
+
+enum FMT_REF_IDX
+{
+ FMT_REF_PAGE_IDX = 0,
+ FMT_REF_CHAPTER_IDX = 1,
+ FMT_REF_TEXT_IDX = 2,
+ FMT_REF_UPDOWN_IDX = 3,
+ FMT_REF_PAGE_PGDSC_IDX = 4,
+ FMT_REF_ONLYNUMBER_IDX = 5,
+ FMT_REF_ONLYCAPTION_IDX = 6,
+ FMT_REF_ONLYSEQNO_IDX = 7,
+ FMT_REF_NUMBER_IDX = 8,
+ FMT_REF_NUMBER_NO_CONTEXT_IDX = 9,
+ FMT_REF_NUMBER_FULL_CONTEXT_IDX = 10
+};
+
+}
+
+const TranslateId FMT_REF_ARY[] =
+{
+ FMT_REF_PAGE,
+ FMT_REF_CHAPTER,
+ FMT_REF_TEXT,
+ FMT_REF_UPDOWN,
+ FMT_REF_PAGE_PGDSC,
+ FMT_REF_ONLYNUMBER,
+ FMT_REF_ONLYCAPTION,
+ FMT_REF_ONLYSEQNO,
+ FMT_REF_NUMBER,
+ FMT_REF_NUMBER_NO_CONTEXT,
+ FMT_REF_NUMBER_FULL_CONTEXT
+};
+
+sal_Int32 SwFieldRefPage::FillFormatLB(sal_uInt16 nTypeId)
+{
+ OUString sOldSel;
+
+ sal_Int32 nFormatSel = m_xFormatLB->get_selected_index();
+ if (nFormatSel != -1)
+ sOldSel = m_xFormatLB->get_text(nFormatSel);
+
+ // fill Format-Listbox
+ m_xFormatLB->clear();
+
+ // reference has less that the annotation
+ sal_uInt16 nSize( 0 );
+ bool bAddCrossRefFormats( false );
+ switch (nTypeId)
+ {
+ // #i83479#
+ case REFFLDFLAG_HEADING:
+ case REFFLDFLAG_NUMITEM:
+ bAddCrossRefFormats = true;
+ [[fallthrough]];
+
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef):
+ case REFFLDFLAG_BOOKMARK:
+ case REFFLDFLAG_FOOTNOTE:
+ case REFFLDFLAG_ENDNOTE:
+ nSize = FMT_REF_PAGE_PGDSC_IDX + 1;
+ break;
+
+ default:
+ // #i83479#
+
+ if ( REFFLDFLAG & nTypeId )
+ {
+ nSize = FMT_REF_ONLYSEQNO_IDX + 1;
+ }
+ else
+ {
+ nSize = GetFieldMgr().GetFormatCount( static_cast<SwFieldTypesEnum>(nTypeId), IsFieldDlgHtmlMode() );
+ }
+ break;
+ }
+
+ if (REFFLDFLAG & nTypeId)
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+
+ SwFieldTypesEnum nFieldType = static_cast<SwFieldTypesEnum>(nTypeId);
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ {
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId( nFieldType, i )));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(nFieldType, i));
+ }
+ // #i83479#
+
+ sal_uInt16 nExtraSize( 0 );
+ if ( bAddCrossRefFormats )
+ {
+ sal_uInt16 nFormat = FMT_REF_NUMBER_IDX;
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat)));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr( nFieldType, nFormat ));
+ nFormat = FMT_REF_NUMBER_NO_CONTEXT_IDX;
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr( nFieldType, nFormat ));
+ nFormat = FMT_REF_NUMBER_FULL_CONTEXT_IDX;
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr( nFieldType, nFormat ));
+ nExtraSize = 3;
+ }
+
+ // extra list items optionally, depending from reference-language
+ SvtSysLocaleOptions aSysLocaleOptions;
+ static const LanguageTag& rLang = aSysLocaleOptions.GetRealLanguageTag();
+
+ if (rLang.getLanguage() == "hu")
+ {
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ {
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId( nFieldType, i + SAL_N_ELEMENTS(FMT_REF_ARY))));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, i ));
+ }
+ nExtraSize += nSize;
+
+ if ( bAddCrossRefFormats )
+ {
+ sal_uInt16 nFormat = FMT_REF_NUMBER_IDX + SAL_N_ELEMENTS(FMT_REF_ARY);
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat)));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nFormat = FMT_REF_NUMBER_NO_CONTEXT_IDX + SAL_N_ELEMENTS(FMT_REF_ARY);
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nFormat = FMT_REF_NUMBER_FULL_CONTEXT_IDX + SAL_N_ELEMENTS(FMT_REF_ARY);
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_LOWERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nExtraSize += 3;
+ }
+ // uppercase article
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ {
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId( nFieldType, i + 2 * SAL_N_ELEMENTS(FMT_REF_ARY))));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, i ));
+ }
+ nExtraSize += nSize;
+ if ( bAddCrossRefFormats )
+ {
+ sal_uInt16 nFormat = FMT_REF_NUMBER_IDX + 2 * SAL_N_ELEMENTS(FMT_REF_ARY);
+ OUString sId(OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat)));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nFormat = FMT_REF_NUMBER_NO_CONTEXT_IDX + 2 * SAL_N_ELEMENTS(FMT_REF_ARY);
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nFormat = FMT_REF_NUMBER_FULL_CONTEXT_IDX + 2 * SAL_N_ELEMENTS(FMT_REF_ARY);
+ sId = OUString::number(GetFieldMgr().GetFormatId(nFieldType, nFormat));
+ m_xFormatLB->append(sId, SwResId(FMT_REF_WITH_UPPERCASE_HU_ARTICLE) + GetFieldMgr().GetFormatStr( nFieldType, nFormat % SAL_N_ELEMENTS(FMT_REF_ARY)));
+ nExtraSize += 3;
+ }
+ }
+
+ nSize += nExtraSize;
+
+ // select a certain entry
+ if (nSize)
+ {
+ if (!IsFieldEdit())
+ m_xFormatLB->select_text(sOldSel);
+ else
+ m_xFormatLB->select_text(SwResId(FMT_REF_ARY[GetCurField()->GetFormat() % SAL_N_ELEMENTS(FMT_REF_ARY)]));
+
+ if (m_xFormatLB->get_selected_index() == -1)
+ {
+ if (nFieldDlgFormatSel < m_xFormatLB->n_children())
+ m_xFormatLB->select(nFieldDlgFormatSel);
+ else
+ m_xFormatLB->select(0);
+ }
+ }
+
+ return nSize;
+}
+
+// Modify
+IMPL_LINK_NOARG(SwFieldRefPage, ModifyHdl, weld::Entry&, void)
+{
+ OUString aName(m_xNameED->get_text());
+ const bool bEmptyName = aName.isEmpty();
+
+ bool bEnable = true;
+ sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ if ((nTypeId == static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef) && !GetFieldMgr().CanInsertRefMark(aName)) ||
+ (bEmptyName && (nTypeId == static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef) || nTypeId == static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef) ||
+ nTypeId == REFFLDFLAG_BOOKMARK)))
+ bEnable = false;
+
+ EnableInsert(bEnable);
+
+ m_xSelectionLB->select_text(aName);
+}
+
+bool SwFieldRefPage::FillItemSet(SfxItemSet* )
+{
+ bool bModified = false;
+ sal_uInt16 nTypeId = m_xTypeLB->get_id(GetTypeSel()).toUInt32();
+
+ sal_uInt16 nSubType = 0;
+ const sal_Int32 nEntryPos = m_xFormatLB->get_selected_index();
+ const sal_uLong nFormat = (nEntryPos == -1)
+ ? 0 : m_xFormatLB->get_id(nEntryPos).toUInt32();
+
+ OUString aVal(m_xValueED->get_text());
+ OUString aName(m_xNameED->get_text());
+
+ switch(nTypeId)
+ {
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef):
+ nSubType = REF_SETREFATTR;
+ break;
+
+ case static_cast<sal_uInt16>(SwFieldTypesEnum::SetRef):
+ {
+ SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::SetExp, aName);
+
+ if(!pType) // Only insert when the name doesn't exist yet
+ {
+ m_xSelectionLB->append_text(aName);
+ m_xSelection->set_sensitive(true);
+ }
+ break;
+ }
+ }
+
+ SwGetRefField const*const pRefField(dynamic_cast<SwGetRefField*>(GetCurField()));
+
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+
+ if (pSh && REFFLDFLAG & nTypeId)
+ {
+ if (nTypeId == REFFLDFLAG_BOOKMARK) // text marks!
+ {
+ aName = m_xNameED->get_text();
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_BOOKMARK;
+ }
+ else if (REFFLDFLAG_FOOTNOTE == nTypeId) // footnotes
+ {
+ SwSeqFieldList aArr;
+ SeqFieldLstElem aElem( m_xSelectionLB->get_selected_text(), 0 );
+
+ size_t nPos = 0;
+
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_FOOTNOTE;
+ aName.clear();
+
+ if (pSh->GetSeqFootnoteList(aArr) && aArr.SeekEntry(aElem, &nPos))
+ {
+ aVal = OUString::number( aArr[nPos].nSeqNo );
+
+ if (IsFieldEdit() && pRefField && aArr[nPos].nSeqNo == pRefField->GetSeqNo())
+ bModified = true; // can happen with fields of which the references were deleted
+ }
+ else if (IsFieldEdit() && pRefField)
+ aVal = OUString::number( pRefField->GetSeqNo() );
+ }
+ else if (REFFLDFLAG_ENDNOTE == nTypeId) // endnotes
+ {
+ SwSeqFieldList aArr;
+ SeqFieldLstElem aElem( m_xSelectionLB->get_selected_text(), 0 );
+
+ size_t nPos = 0;
+
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_ENDNOTE;
+ aName.clear();
+
+ if (pSh->GetSeqFootnoteList(aArr, true) && aArr.SeekEntry(aElem, &nPos))
+ {
+ aVal = OUString::number( aArr[nPos].nSeqNo );
+
+ if (IsFieldEdit() && pRefField && aArr[nPos].nSeqNo == pRefField->GetSeqNo())
+ bModified = true; // can happen with fields of which the reference was deleted
+ }
+ else if (IsFieldEdit() && pRefField)
+ aVal = OUString::number( pRefField->GetSeqNo() );
+ }
+ // #i83479#
+ else if ( nTypeId == REFFLDFLAG_HEADING )
+ {
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ OSL_ENSURE( nEntry != -1,
+ "<SwFieldRefPage::FillItemSet(..)> - no entry selected in selection tool tip listbox!" );
+ if (nEntry != -1)
+ {
+ const size_t nOutlIdx(m_xSelectionToolTipLB->get_id(nEntry).toUInt32());
+ pSh->getIDocumentOutlineNodesAccess()->getOutlineNodes( maOutlineNodes );
+ if ( nOutlIdx < maOutlineNodes.size() )
+ {
+ ::sw::mark::IMark const * const pMark = pSh->getIDocumentMarkAccess()->getMarkForTextNode(
+ *(maOutlineNodes[nOutlIdx]),
+ IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK);
+ aName = pMark->GetName();
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_BOOKMARK;
+ }
+ }
+ }
+ else if ( nTypeId == REFFLDFLAG_NUMITEM )
+ {
+ int nEntry = m_xSelectionToolTipLB->get_selected_index();
+ OSL_ENSURE( nEntry != -1,
+ "<SwFieldRefPage::FillItemSet(..)> - no entry selected in selection tool tip listbox!" );
+ if (nEntry != -1)
+ {
+ const size_t nNumItemIdx(m_xSelectionToolTipLB->get_id(nEntry).toUInt32());
+ pSh->getIDocumentListItemsAccess()->getNumItems(maNumItems);
+ if ( nNumItemIdx < maNumItems.size() )
+ {
+ ::sw::mark::IMark const * const pMark = pSh->getIDocumentMarkAccess()->getMarkForTextNode(
+ *(maNumItems[nNumItemIdx]->GetTextNode()),
+ IDocumentMarkAccess::MarkType::CROSSREF_NUMITEM_BOOKMARK);
+ aName = pMark->GetName();
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_BOOKMARK;
+ }
+ }
+ }
+ else // SequenceFields
+ {
+ // get fields for Seq-FieldType:
+ SwSetExpFieldType* pType = static_cast<SwSetExpFieldType*>(pSh->GetFieldType(
+ nTypeId & ~REFFLDFLAG, SwFieldIds::SetExp ));
+ if( pType )
+ {
+ SwSeqFieldList aArr;
+ SeqFieldLstElem aElem( m_xSelectionLB->get_selected_text(), 0 );
+
+ size_t nPos = 0;
+
+ nTypeId = static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef);
+ nSubType = REF_SEQUENCEFLD;
+ aName = pType->GetName();
+
+ if (pType->GetSeqFieldList(aArr, pSh->GetLayout())
+ && aArr.SeekEntry(aElem, &nPos))
+ {
+ aVal = OUString::number( aArr[nPos].nSeqNo );
+
+ if (IsFieldEdit() && pRefField && aArr[nPos].nSeqNo == pRefField->GetSeqNo())
+ bModified = true; // can happen with fields of which the reference was deleted
+ }
+ else if (IsFieldEdit() && pRefField)
+ aVal = OUString::number( pRefField->GetSeqNo() );
+ }
+ }
+ }
+
+ if (IsFieldEdit() && nTypeId == static_cast<sal_uInt16>(SwFieldTypesEnum::GetRef))
+ {
+ aVal = OUString::number(nSubType) + "|" + aVal;
+ }
+
+ if (!IsFieldEdit() || bModified ||
+ m_xNameED->get_value_changed_from_saved() ||
+ m_xValueED->get_value_changed_from_saved() ||
+ m_xTypeLB->get_value_changed_from_saved() ||
+ m_xSelectionLB->get_value_changed_from_saved() ||
+ m_xFormatLB->get_value_changed_from_saved())
+ {
+ InsertField( static_cast<SwFieldTypesEnum>(nTypeId), nSubType, aName, aVal, nFormat );
+ }
+
+ ModifyHdl(*m_xNameED); // enable/disable insert if applicable
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldRefPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldRefPage>(pPage, pController, pAttrSet);
+}
+
+sal_uInt16 SwFieldRefPage::GetGroup()
+{
+ return GRP_REF;
+}
+
+void SwFieldRefPage::FillUserData()
+{
+ const sal_Int32 nEntryPos = m_xTypeLB->get_selected_index();
+ const sal_uInt16 nTypeSel = ( -1 == nEntryPos )
+ ? USHRT_MAX
+ : m_xTypeLB->get_id(nEntryPos).toUInt32();
+ const sal_Int32 nFormatEntryPos = m_xFormatLB->get_selected_index();
+ const sal_uInt32 nFormatSel = -1 == nFormatEntryPos ? USHRT_MAX : nFormatEntryPos;
+ SetUserData( USER_DATA_VERSION ";" +
+ OUString::number( nTypeSel ) + ";" +
+ OUString::number( nFormatSel ));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldref.hxx b/sw/source/ui/fldui/fldref.hxx
new file mode 100644
index 000000000..8dc9a311b
--- /dev/null
+++ b/sw/source/ui/fldui/fldref.hxx
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDREF_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDREF_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#include "fldpage.hxx"
+#include <IDocumentOutlineNodes.hxx>
+#include <IDocumentListItems.hxx>
+class SwTextNode;
+
+class SwFieldRefPage : public SwFieldPage
+{
+ OUString sBookmarkText;
+ OUString sFootnoteText;
+ OUString sEndnoteText;
+ // #i83479#
+ OUString sHeadingText;
+ OUString sNumItemText;
+
+ IDocumentOutlineNodes::tSortedOutlineNodeList maOutlineNodes;
+ IDocumentListItems::tSortedNodeNumList maNumItems;
+
+ // selected text node in the listbox for headings and numbered items
+ // in order to restore selection after update of selection listbox
+ const SwTextNode* mpSavedSelectedTextNode;
+ // fallback, if previously selected text node doesn't exist anymore
+ size_t mnSavedSelectedPos;
+
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<weld::Widget> m_xSelection;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ // #i83479#
+ std::unique_ptr<weld::TreeView> m_xSelectionToolTipLB;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<weld::TreeView> m_xFormatLB;
+ std::unique_ptr<weld::Label> m_xNameFT;
+ std::unique_ptr<weld::Entry> m_xNameED;
+ std::unique_ptr<weld::Entry> m_xValueED;
+ std::unique_ptr<weld::Entry> m_xFilterED;
+
+ DECL_LINK(TypeHdl, weld::TreeView&, void);
+ DECL_LINK(SubTypeListBoxHdl, weld::TreeView&, void);
+ DECL_LINK(SubTypeTreeListBoxHdl, weld::TreeView&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ DECL_LINK(ModifyHdl_Impl, weld::Entry&, void);
+
+ void SubTypeHdl();
+
+ void UpdateSubType(const OUString& filterString);
+
+ static bool MatchSubstring( const OUString& list_string, const OUString& substr );
+
+ sal_Int32 FillFormatLB(sal_uInt16 nTypeId);
+
+ // #i83479#
+ void SaveSelectedTextNode();
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldRefPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pSet);
+ virtual ~SwFieldRefPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual void FillUserData() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldtdlg.cxx b/sw/source/ui/fldui/fldtdlg.cxx
new file mode 100644
index 000000000..f0deba6d3
--- /dev/null
+++ b/sw/source/ui/fldui/fldtdlg.cxx
@@ -0,0 +1,307 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+#include <config_fuzzers.h>
+
+#include <cmdid.h>
+#include <unotools/confignode.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <osl/diagnose.h>
+#include <viewopt.hxx>
+#include <chldwrap.hxx>
+#include <docsh.hxx>
+#include "flddb.hxx"
+#include "flddinf.hxx"
+#include "fldvar.hxx"
+#include "flddok.hxx"
+#include "fldfunc.hxx"
+#include "fldref.hxx"
+#include <wrtsh.hxx>
+#include <view.hxx>
+#include <fldtdlg.hxx>
+#include <swmodule.hxx>
+#include <comphelper/lok.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+
+// carrier of the dialog
+SwFieldDlg::SwFieldDlg(SfxBindings* pB, SwChildWinWrapper* pCW, weld::Window *pParent)
+ : SfxTabDialogController(pParent, "modules/swriter/ui/fielddialog.ui", "FieldDialog")
+ , m_pChildWin(pCW)
+ , m_pBindings(pB)
+ , m_bDataBaseMode(false)
+ , m_bClosing(false)
+{
+ m_bHtmlMode = (::GetHtmlMode(static_cast<SwDocShell*>(SfxObjectShell::Current())) & HTMLMODE_ON) != 0;
+
+ GetCancelButton().connect_clicked(LINK(this, SwFieldDlg, CancelHdl));
+ GetOKButton().connect_clicked(LINK(this, SwFieldDlg, OKHdl));
+
+ AddTabPage("document", SwFieldDokPage::Create, nullptr);
+ AddTabPage("variables", SwFieldVarPage::Create, nullptr);
+ AddTabPage("docinfo", SwFieldDokInfPage::Create, nullptr);
+
+ if (!m_bHtmlMode)
+ {
+ AddTabPage("ref", SwFieldRefPage::Create, nullptr);
+ AddTabPage("functions", SwFieldFuncPage::Create, nullptr);
+
+ utl::OConfigurationTreeRoot aCfgRoot
+ = utl::OConfigurationTreeRoot::createWithComponentContext(
+ ::comphelper::getProcessComponentContext(),
+ "/org.openoffice.Office.DataAccess/Policies/Features/Writer",
+ -1,
+ utl::OConfigurationTreeRoot::CM_READONLY);
+
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ bool bDatabaseFields = true;
+ aCfgRoot.getNodeValue(
+ OUString("DatabaseFields")) >>= bDatabaseFields;
+
+ if (bDatabaseFields)
+ AddTabPage("database", SwFieldDBPage::Create, nullptr);
+ else
+#endif
+ RemoveTabPage("database");
+ }
+ else
+ {
+ RemoveTabPage("ref");
+ RemoveTabPage("functions");
+ RemoveTabPage("database");
+ }
+
+ if (comphelper::LibreOfficeKit::isActive())
+ RemoveTabPage("database");
+}
+
+SwFieldDlg::~SwFieldDlg()
+{
+}
+
+void SwFieldDlg::EndDialog(int nResponse)
+{
+ m_bClosing = true;
+ SfxTabDialogController::EndDialog(nResponse);
+ m_bClosing = false;
+}
+
+void SwFieldDlg::Close()
+{
+ if (m_bClosing)
+ return;
+ const SfxPoolItem* pResult = m_pBindings->GetDispatcher()->
+ Execute(m_bDataBaseMode ? FN_INSERT_FIELD_DATA_ONLY : FN_INSERT_FIELD,
+ SfxCallMode::SYNCHRON|SfxCallMode::RECORD);
+ if (!pResult)
+ {
+ // If Execute action did fail for whatever reason, this means that request
+ // to close did fail or wasn't delivered to SwTextShell::ExecField().
+ // Just explicitly close dialog in this case.
+ SfxTabDialogController::EndDialog(RET_CLOSE);
+ }
+}
+
+void SwFieldDlg::Initialize(SfxChildWinInfo const *pInfo)
+{
+ OString aWinState = pInfo->aWinState;
+ if (aWinState.isEmpty())
+ return;
+ m_xDialog->set_window_state(aWinState);
+}
+
+SfxItemSet* SwFieldDlg::CreateInputItemSet(const OString& rID)
+{
+ SwDocShell *const pDocSh(static_cast<SwDocShell*>(SfxObjectShell::Current()));
+ if (rID == "docinfo" && pDocSh) // might not have a shell if the dialog is restored on startup
+ {
+ mxInputItemSet = std::make_unique<SfxItemSetFixed<FN_FIELD_DIALOG_DOC_PROPS, FN_FIELD_DIALOG_DOC_PROPS>>( pDocSh->GetPool() );
+ using namespace ::com::sun::star;
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ pDocSh->GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> xDocProps
+ = xDPS->getDocumentProperties();
+ uno::Reference< beans::XPropertySet > xUDProps(
+ xDocProps->getUserDefinedProperties(),
+ uno::UNO_QUERY_THROW);
+ mxInputItemSet->Put( SfxUnoAnyItem( FN_FIELD_DIALOG_DOC_PROPS, uno::Any(xUDProps) ) );
+ return mxInputItemSet.get();
+ }
+ else
+ return nullptr;
+}
+
+// kick off inserting of new fields
+IMPL_LINK_NOARG(SwFieldDlg, OKHdl, weld::Button&, void)
+{
+ if (GetOKButton().get_sensitive())
+ {
+ SfxTabPage* pPage = GetTabPage(GetCurPageId());
+ assert(pPage);
+ pPage->FillItemSet(nullptr);
+
+ GetOKButton().grab_focus(); // because of InputField-Dlg
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldDlg, CancelHdl, weld::Button&, void)
+{
+ Close();
+}
+
+// newly initialise dialog after Doc-Switch
+void SwFieldDlg::ReInitDlg()
+{
+ SwDocShell* pDocSh = static_cast<SwDocShell*>(SfxObjectShell::Current());
+ bool bNewMode = (::GetHtmlMode(pDocSh) & HTMLMODE_ON) != 0;
+
+ if (bNewMode != m_bHtmlMode)
+ {
+ if (SfxViewFrame* pViewFrm = SfxViewFrame::Current())
+ {
+ pViewFrm->GetDispatcher()->
+ Execute(FN_INSERT_FIELD, SfxCallMode::ASYNCHRON|SfxCallMode::RECORD);
+ }
+ Close();
+ }
+
+ SwView* pActiveView = ::GetActiveView();
+ if(!pActiveView)
+ return;
+ const SwWrtShell& rSh = pActiveView->GetWrtShell();
+ GetOKButton().set_sensitive(!rSh.IsReadOnlyAvailable() ||
+ !rSh.HasReadonlySel());
+
+ ReInitTabPage("document");
+ ReInitTabPage("variables");
+ ReInitTabPage("docinfo");
+
+ if (!m_bHtmlMode)
+ {
+ ReInitTabPage("ref");
+ ReInitTabPage("functions");
+ ReInitTabPage("database");
+ }
+
+ m_pChildWin->SetOldDocShell(pDocSh);
+}
+
+// newly initialise TabPage after Doc-Switch
+void SwFieldDlg::ReInitTabPage(std::string_view rPageId, bool bOnlyActivate)
+{
+ SwFieldPage* pPage = static_cast<SwFieldPage*>(GetTabPage(rPageId));
+ if (pPage)
+ pPage->EditNewField( bOnlyActivate ); // newly initialise TabPage
+}
+
+// newly initialise after activation of a few TabPages
+void SwFieldDlg::Activate()
+{
+ SwView* pView = GetActiveView();
+ if( !pView )
+ return;
+
+ bool bHtmlMode = (::GetHtmlMode(static_cast<SwDocShell*>(SfxObjectShell::Current())) & HTMLMODE_ON) != 0;
+ const SwWrtShell& rSh = pView->GetWrtShell();
+ GetOKButton().set_sensitive(!rSh.IsReadOnlyAvailable() ||
+ !rSh.HasReadonlySel());
+
+ ReInitTabPage("variables", true);
+
+ if( !bHtmlMode )
+ {
+ ReInitTabPage("ref", true);
+ ReInitTabPage("functions", true);
+ }
+}
+
+void SwFieldDlg::EnableInsert(bool bEnable)
+{
+ if( bEnable )
+ {
+ SwView* pView = ::GetActiveView();
+ if( !pView ||
+ (pView->GetWrtShell().IsReadOnlyAvailable() &&
+ pView->GetWrtShell().HasReadonlySel()) )
+ bEnable = false;
+ }
+ GetOKButton().set_sensitive(bEnable);
+}
+
+void SwFieldDlg::InsertHdl()
+{
+ GetOKButton().clicked();
+}
+
+void SwFieldDlg::ActivateDatabasePage()
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ m_bDataBaseMode = true;
+ ShowPage("database");
+ SfxTabPage* pDBPage = GetTabPage("database");
+ if( pDBPage )
+ {
+ static_cast<SwFieldDBPage*>(pDBPage)->ActivateMailMergeAddress();
+ }
+ //remove all other pages
+ RemoveTabPage("document");
+ RemoveTabPage("variables");
+ RemoveTabPage("docinfo");
+ RemoveTabPage("ref");
+ RemoveTabPage("functions");
+#endif
+}
+
+void SwFieldDlg::ShowReferencePage()
+{
+ ShowPage("ref");
+}
+
+void SwFieldDlg::PageCreated(const OString& rId, SfxTabPage& rPage)
+{
+#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
+ if (rId != "database")
+ return;
+
+ SfxDispatcher* pDispatch = m_pBindings->GetDispatcher();
+ SfxViewFrame* pViewFrame = pDispatch ? pDispatch->GetFrame() : nullptr;
+ if(pViewFrame)
+ {
+ SfxViewShell* pViewShell = SfxViewShell::GetFirst( true, checkSfxViewShell<SwView> );
+ while(pViewShell && pViewShell->GetViewFrame() != pViewFrame)
+ {
+ pViewShell = SfxViewShell::GetNext( *pViewShell, true, checkSfxViewShell<SwView> );
+ }
+ if(pViewShell)
+ static_cast<SwFieldDBPage&>(rPage).SetWrtShell(static_cast<SwView*>(pViewShell)->GetWrtShell());
+ }
+#else
+ (void) rId;
+ (void) rPage;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldvar.cxx b/sw/source/ui/fldui/fldvar.cxx
new file mode 100644
index 000000000..13621af70
--- /dev/null
+++ b/sw/source/ui/fldui/fldvar.cxx
@@ -0,0 +1,1250 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <swtypes.hxx>
+#include <sfx2/linkmgr.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <usrfld.hxx>
+#include <docufld.hxx>
+#include <expfld.hxx>
+#include <ddefld.hxx>
+#include <wrtsh.hxx>
+#include <doc.hxx>
+#include <docary.hxx>
+#include <swmodule.hxx>
+#include "fldvar.hxx"
+#include "flddinf.hxx"
+#include <calc.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zformat.hxx>
+#include <o3tl/string_view.hxx>
+#include <strings.hrc>
+
+#define USER_DATA_VERSION_1 "1"
+#define USER_DATA_VERSION USER_DATA_VERSION_1
+
+SwFieldVarPage::SwFieldVarPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet )
+ : SwFieldPage(pPage, pController, "modules/swriter/ui/fldvarpage.ui", "FieldVarPage", pCoreSet)
+ , m_xTypeLB(m_xBuilder->weld_tree_view("type"))
+ , m_xSelection(m_xBuilder->weld_widget("selectframe"))
+ , m_xSelectionLB(m_xBuilder->weld_tree_view("select"))
+ , m_xNameFT(m_xBuilder->weld_label("nameft"))
+ , m_xNameED(m_xBuilder->weld_entry("name"))
+ , m_xValueFT(m_xBuilder->weld_label("valueft"))
+ , m_xValueED(new ConditionEdit(m_xBuilder->weld_entry("value")))
+ , m_xFormat(m_xBuilder->weld_widget("formatframe"))
+ , m_xNumFormatLB(new SwNumFormatTreeView(m_xBuilder->weld_tree_view("numformat")))
+ , m_xFormatLB(m_xBuilder->weld_tree_view("format"))
+ , m_xChapterFrame(m_xBuilder->weld_widget("chapterframe"))
+ , m_xChapterLevelLB(m_xBuilder->weld_combo_box("level"))
+ , m_xInvisibleCB(m_xBuilder->weld_check_button("invisible"))
+ , m_xSeparatorFT(m_xBuilder->weld_label("separatorft"))
+ , m_xSeparatorED(m_xBuilder->weld_entry("separator"))
+ , m_xNewPB(m_xBuilder->weld_button("apply"))
+ , m_xDelPB(m_xBuilder->weld_button("delete"))
+ , nOldFormat(0)
+ , bInit(true)
+{
+ FillFieldSelect(*m_xTypeLB);
+ m_xSelectionLB->make_sorted();
+ FillFieldSelect(*m_xFormatLB);
+
+ auto nWidth = m_xTypeLB->get_approximate_digit_width() * FIELD_COLUMN_WIDTH;
+ auto nHeight = m_xTypeLB->get_height_rows(10);
+ m_xTypeLB->set_size_request(nWidth, nHeight);
+ m_xSelectionLB->set_size_request(nWidth, nHeight);
+ m_xFormatLB->set_size_request(nWidth, nHeight/2);
+
+ sOldValueFT = m_xValueFT->get_label();
+ sOldNameFT = m_xNameFT->get_label();
+
+ for (sal_uInt16 i = 1; i <= MAXLEVEL; i++)
+ m_xChapterLevelLB->append_text(OUString::number(i));
+
+ m_xChapterLevelLB->set_active(0);
+ //enable 'active' language selection
+ m_xNumFormatLB->SetShowLanguageControl(true);
+
+ // uitests
+ m_xTypeLB->set_buildable_name(m_xTypeLB->get_buildable_name() + "-var");
+ m_xNameED->set_buildable_name(m_xNameED->get_buildable_name() + "-var");
+ m_xValueED->set_buildable_name(m_xValueED->get_buildable_name() + "-var");
+ m_xNumFormatLB->set_buildable_name(m_xNumFormatLB->get_buildable_name() + "-var");
+ m_xSelectionLB->set_buildable_name(m_xSelectionLB->get_buildable_name() + "-var");
+ m_xFormatLB->set_buildable_name(m_xFormatLB->get_buildable_name() + "-var");
+}
+
+SwFieldVarPage::~SwFieldVarPage()
+{
+}
+
+void SwFieldVarPage::Reset(const SfxItemSet* )
+{
+ SavePos(*m_xTypeLB);
+
+ Init(); // general initialisation
+
+ m_xTypeLB->freeze();
+ m_xTypeLB->clear();
+
+ SwFieldTypesEnum nTypeId;
+
+ if (!IsFieldEdit())
+ {
+ // initialise TypeListBox
+ const SwFieldGroupRgn& rRg = SwFieldMgr::GetGroupRange(IsFieldDlgHtmlMode(), GetGroup());
+
+ for (short i = rRg.nStart; i < rRg.nEnd; ++i)
+ {
+ nTypeId = SwFieldMgr::GetTypeId(i);
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(i));
+ }
+ }
+ else
+ {
+ const SwField* pCurField = GetCurField();
+ assert(pCurField && "<SwFieldVarPage::Reset(..)> - <SwField> instance missing!");
+ nTypeId = pCurField->GetTypeId();
+ if (nTypeId == SwFieldTypesEnum::SetInput)
+ nTypeId = SwFieldTypesEnum::Input;
+ m_xTypeLB->append(OUString::number(static_cast<sal_uInt16>(nTypeId)), SwFieldMgr::GetTypeStr(SwFieldMgr::GetPos(nTypeId)));
+ m_xNumFormatLB->SetAutomaticLanguage(pCurField->IsAutomaticLanguage());
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ const SvNumberformat* pFormat = pSh->GetNumberFormatter()->GetEntry(pCurField->GetFormat());
+ if(pFormat)
+ m_xNumFormatLB->SetLanguage(pFormat->GetLanguage());
+ }
+ }
+
+ m_xTypeLB->thaw();
+
+ // select old Pos
+ RestorePos(*m_xTypeLB);
+
+ m_xTypeLB->connect_row_activated(LINK(this, SwFieldVarPage, TreeViewInsertHdl));
+ m_xTypeLB->connect_changed(LINK(this, SwFieldVarPage, TypeHdl));
+ m_xSelectionLB->connect_changed(LINK(this, SwFieldVarPage, SubTypeListBoxHdl));
+ m_xSelectionLB->connect_row_activated(LINK(this, SwFieldVarPage, SubTypeInsertHdl));
+ m_xFormatLB->connect_row_activated(LINK(this, SwFieldVarPage, TreeViewInsertHdl));
+ m_xNumFormatLB->connect_row_activated(LINK(this, SwFieldVarPage, TreeViewInsertHdl));
+ m_xNameED->connect_changed(LINK(this, SwFieldVarPage, ModifyHdl));
+ m_xValueED->connect_changed(LINK(this, SwFieldVarPage, ModifyHdl));
+ m_xNewPB->connect_clicked(LINK(this, SwFieldVarPage, TBClickHdl));
+ m_xDelPB->connect_clicked(LINK(this, SwFieldVarPage, TBClickHdl));
+ m_xChapterLevelLB->connect_changed(LINK(this, SwFieldVarPage, ChapterHdl));
+ m_xSeparatorED->connect_changed(LINK(this, SwFieldVarPage, SeparatorHdl));
+
+ if( !IsRefresh() )
+ {
+ OUString sUserData = GetUserData();
+ sal_Int32 nIdx{ 0 };
+ if(!IsRefresh() && o3tl::equalsIgnoreAsciiCase(o3tl::getToken(sUserData, 0, ';', nIdx), u"" USER_DATA_VERSION_1))
+ {
+ std::u16string_view sVal = o3tl::getToken(sUserData, 0, ';', nIdx);
+ sal_uInt16 nVal = o3tl::narrowing<sal_uInt16>(o3tl::toInt32(sVal));
+ if (USHRT_MAX != nVal)
+ {
+ for (sal_Int32 i = 0, nEntryCount = m_xTypeLB->n_children(); i < nEntryCount; i++)
+ {
+ if (nVal == m_xTypeLB->get_id(i).toUInt32())
+ {
+ m_xTypeLB->select(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ TypeHdl(*m_xTypeLB);
+
+ if (IsFieldEdit())
+ {
+ m_xSelectionLB->save_value();
+ m_xFormatLB->save_value();
+ nOldFormat = m_xNumFormatLB->GetFormat();
+ m_xNameED->save_value();
+ m_xValueED->save_value();
+ m_xInvisibleCB->save_state();
+ m_xChapterLevelLB->save_value();
+ m_xSeparatorED->save_value();
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldVarPage, TypeHdl, weld::TreeView&, void)
+{
+ // save old ListBoxPos
+ const sal_Int32 nOld = GetTypeSel();
+
+ // current ListBoxPos
+ SetTypeSel(m_xTypeLB->get_selected_index());
+
+ if(GetTypeSel() == -1)
+ {
+ SetTypeSel(0);
+ m_xTypeLB->select(0);
+ }
+
+ if (nOld != GetTypeSel() || nOld == -1)
+ {
+ bInit = true;
+ if (nOld != -1)
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ }
+
+ m_xValueED->SetDropEnable(false);
+ UpdateSubType(); // initialise selection-listboxes
+ }
+
+ bInit = false;
+}
+
+IMPL_LINK( SwFieldVarPage, SubTypeListBoxHdl, weld::TreeView&, rBox, void )
+{
+ SubTypeHdl(&rBox);
+}
+
+void SwFieldVarPage::SubTypeHdl(const weld::TreeView* pBox)
+{
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ sal_Int32 nSelPos = m_xSelectionLB->get_selected_index();
+ size_t nSelData = SIZE_MAX;
+
+ if (nSelPos != -1)
+ nSelData = m_xSelectionLB->get_id(nSelPos).toUInt32();
+
+ if (IsFieldEdit() && (!pBox || bInit))
+ {
+ if (nTypeId != SwFieldTypesEnum::Formel)
+ m_xNameED->set_text(GetFieldMgr().GetCurFieldPar1());
+
+ m_xValueED->set_text(GetFieldMgr().GetCurFieldPar2());
+ }
+
+ if (m_xNameFT->get_label() != sOldNameFT)
+ m_xNameFT->set_label(sOldNameFT);
+ if (m_xValueFT->get_label() != sOldValueFT)
+ m_xValueFT->set_label(sOldValueFT);
+
+ FillFormatLB(nTypeId);
+
+ sal_Int32 nSize = m_xFormatLB->n_children();
+
+ bool bValue = false, bName = false, bNumFormat = false,
+ bInvisible = false, bShowChapterFrame = false;
+ bool bFormat = nSize != 0;
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::User:
+ {
+ // change or create user type
+ SwUserFieldType* pType = static_cast<SwUserFieldType*>(
+ GetFieldMgr().GetFieldType(SwFieldIds::User, nSelData));
+
+ if (pType)
+ {
+ if (!IsFieldEdit())
+ {
+ if (pBox || (bInit && !IsRefresh())) // only when interacting via mouse
+ {
+ m_xNameED->set_text(pType->GetName());
+
+ if (pType->GetType() == UF_STRING)
+ {
+ m_xValueED->set_text(pType->GetContent());
+ m_xNumFormatLB->select(0);
+ }
+ else
+ m_xValueED->set_text(pType->GetContent());
+ }
+ }
+ else
+ m_xValueED->set_text(pType->GetContent());
+ }
+ else
+ {
+ if (pBox) // only when interacting via mouse
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ }
+ }
+ bValue = bName = bNumFormat = bInvisible = true;
+
+ m_xValueED->SetDropEnable(true);
+ break;
+ }
+
+ case SwFieldTypesEnum::Set:
+ bValue = true;
+
+ bNumFormat = bInvisible = true;
+
+ if (!IsFieldDlgHtmlMode())
+ bName = true;
+ else
+ {
+ m_xNumFormatLB->clear();
+ m_xNumFormatLB->append(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND), SwResId(FMT_SETVAR_TEXT));
+ m_xNumFormatLB->select(0);
+ }
+ // is there a corresponding SetField
+ if (IsFieldEdit() || pBox) // only when interacting via mouse
+ {
+ if (nSelPos != -1)
+ {
+ OUString sName(m_xSelectionLB->get_selected_text());
+ m_xNameED->set_text(sName);
+
+ if (!IsFieldDlgHtmlMode())
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
+ pSh->GetFieldType(SwFieldIds::SetExp, sName));
+
+ if (pSetTyp && pSetTyp->GetType() == nsSwGetSetExpType::GSE_STRING)
+ m_xNumFormatLB->select(0); // textual
+ }
+ }
+ }
+ }
+ if (GetCurField() != nullptr && IsFieldEdit())
+ {
+ // GetFormula leads to problems with date formats because
+ // only the numeric value without formatting is returned.
+ // It must be used though because otherwise in GetPar2 only
+ // the value calculated by Kalkulator would be displayed
+ // (instead of test2 = test + 1)
+ m_xValueED->set_text(static_cast<SwSetExpField*>(GetCurField())->GetFormula());
+ }
+ m_xValueED->SetDropEnable(true);
+ break;
+
+ case SwFieldTypesEnum::Formel:
+ {
+ bValue = true;
+ bNumFormat = true;
+ m_xValueFT->set_label(SwResId(STR_FORMULA));
+ m_xValueED->SetDropEnable(true);
+ }
+ break;
+
+ case SwFieldTypesEnum::Get:
+ {
+ if (!IsFieldEdit())
+ {
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ }
+
+ if (nSelPos != -1)
+ {
+ OUString sName(m_xSelectionLB->get_selected_text());
+ if (!IsFieldEdit())
+ m_xNameED->set_text(sName);
+
+ // is there a corresponding SetField
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
+ pSh->GetFieldType(SwFieldIds::SetExp, sName));
+
+ if(pSetTyp)
+ {
+ if (pSetTyp->GetType() & nsSwGetSetExpType::GSE_STRING) // textual?
+ bFormat = true;
+ else // numeric
+ bNumFormat = true;
+ }
+ }
+ }
+ else
+ bFormat = false;
+
+ EnableInsert(bFormat || bNumFormat);
+ }
+ break;
+
+ case SwFieldTypesEnum::Input:
+ m_xValueFT->set_label(SwResId(STR_PROMPT));
+
+ if (nSelPos != -1)
+ {
+ bValue = bNumFormat = true;
+
+ OUString sName = m_xSelectionLB->get_selected_text();
+ m_xNameED->set_text( sName );
+
+ // User- or SetField ?
+ if (!GetFieldMgr().GetFieldType(SwFieldIds::User, sName)) // SetExp
+ {
+ // is there a corresponding SetField
+ SwSetExpFieldType* pSetTyp = static_cast<SwSetExpFieldType*>(
+ GetFieldMgr().GetFieldType(SwFieldIds::SetExp, sName));
+
+ if(pSetTyp)
+ {
+ if (pSetTyp->GetType() == nsSwGetSetExpType::GSE_STRING) // textual?
+ {
+ m_xNumFormatLB->clear();
+ m_xNumFormatLB->append(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND), SwResId(FMT_USERVAR_TEXT));
+ m_xNumFormatLB->select(0);
+ }
+ }
+ if (GetCurField() && IsFieldEdit() && (!pBox || bInit) )
+ m_xValueED->set_text(static_cast<SwSetExpField*>(GetCurField())->GetPromptText());
+ }
+ else // USERFLD
+ bFormat = bNumFormat = false;
+ }
+ break;
+
+ case SwFieldTypesEnum::DDE:
+ m_xValueFT->set_label(SwResId(STR_DDE_CMD));
+
+ if (IsFieldEdit() || pBox) // only when interacting via mouse
+ {
+ if (nSelPos != -1)
+ {
+ SwDDEFieldType* pType =
+ static_cast<SwDDEFieldType*>( GetFieldMgr().GetFieldType(SwFieldIds::Dde, nSelData) );
+
+ if(pType)
+ {
+ m_xNameED->set_text(pType->GetName());
+
+ //JP 28.08.95: DDE-Topics/-Items can have blanks in their names!
+ // That's not considered here yet
+ OUString sCmd( pType->GetCmd() );
+ sal_Int32 nTmpPos = 0;
+ sCmd = sCmd.replaceFirst( OUStringChar(sfx2::cTokenSeparator), " ", &nTmpPos );
+ sCmd = sCmd.replaceFirst( OUStringChar(sfx2::cTokenSeparator), " ", &nTmpPos );
+
+ m_xValueED->set_text( sCmd );
+ m_xFormatLB->select(static_cast<int>(pType->GetType()));
+ }
+ }
+ }
+ bName = bValue = true;
+ break;
+
+ case SwFieldTypesEnum::Sequence:
+ {
+ bName = bValue = bShowChapterFrame = true;
+
+ SwFieldType* pFieldTyp;
+ if( GetCurField() && IsFieldEdit() )
+ pFieldTyp = GetCurField()->GetTyp();
+ else
+ {
+ OUString sFieldTypeName(m_xSelectionLB->get_text(nSelPos));
+ if( !sFieldTypeName.isEmpty() )
+ pFieldTyp = GetFieldMgr().GetFieldType( SwFieldIds::SetExp,
+ sFieldTypeName );
+ else
+ pFieldTyp = nullptr;
+ }
+
+ if( GetCurField() && IsFieldEdit() )
+ m_xValueED->set_text( static_cast<SwSetExpField*>(GetCurField())->
+ GetFormula() );
+
+ if( IsFieldEdit() || pBox ) // only when interacting via mouse
+ m_xNameED->set_text( m_xSelectionLB->get_selected_text() );
+
+ if( pFieldTyp )
+ {
+ sal_uInt8 nLevel = static_cast<SwSetExpFieldType*>(pFieldTyp)->GetOutlineLvl();
+ if( 0x7f == nLevel )
+ m_xChapterLevelLB->set_active(0);
+ else
+ m_xChapterLevelLB->set_active(nLevel + 1);
+ OUString sDelim = static_cast<SwSetExpFieldType*>(pFieldTyp)->GetDelimiter();
+ m_xSeparatorED->set_text( sDelim );
+ ChapterHdl(*m_xChapterLevelLB);
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::SetRefPage:
+ {
+ bValue = false;
+ m_xValueFT->set_label( SwResId( STR_OFFSET ));
+
+ if (IsFieldEdit() || pBox) // only when interacting via mouse
+ m_xNameED->set_text(OUString());
+
+ if (nSelData != 0 && nSelData != SIZE_MAX)
+ {
+ bValue = true; // SubType OFF - knows no Offset
+ if (GetCurField() && IsFieldEdit())
+ m_xValueED->set_text(OUString::number(static_cast<SwRefPageSetField*>(GetCurField())->GetOffset()));
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::GetRefPage:
+ m_xNameED->set_text(OUString());
+ m_xValueED->set_text(OUString());
+ break;
+
+ default: break;
+ }
+
+ m_xNumFormatLB->set_visible(bNumFormat);
+ m_xFormatLB->set_visible(!bNumFormat);
+
+ if (IsFieldEdit())
+ bName = false;
+
+ m_xFormat->set_sensitive(bFormat || bNumFormat);
+ m_xNameFT->set_sensitive(bName);
+ m_xNameED->set_sensitive(bName);
+ m_xValueFT->set_sensitive(bValue);
+ m_xValueED->set_sensitive(bValue);
+
+ m_xInvisibleCB->set_visible(!bShowChapterFrame);
+ m_xChapterFrame->set_visible(bShowChapterFrame);
+ m_xInvisibleCB->set_sensitive(bInvisible);
+
+ ModifyHdl(*m_xNameED); // apply/insert/delete status update
+}
+
+IMPL_LINK(SwFieldVarPage, SubTypeInsertHdl, weld::TreeView&, rBox, bool)
+{
+ if (!bInit)
+ {
+ SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ if (nTypeId == SwFieldTypesEnum::Formel)
+ {
+ auto nSelPos = m_xSelectionLB->get_selected_index();
+ if (nSelPos != -1)
+ {
+ m_xValueED->replace_selection(m_xSelectionLB->get_text(nSelPos));
+ ModifyHdl(*m_xNameED);
+ return true;
+ }
+ }
+ }
+ TreeViewInsertHdl(rBox);
+ return true;
+}
+
+// renew types in SelectionBox
+void SwFieldVarPage::UpdateSubType()
+{
+ SetSelectionSel(m_xSelectionLB->get_selected_index());
+
+ OUString sOldSel;
+ if (GetSelectionSel() != -1)
+ sOldSel = m_xSelectionLB->get_text(GetSelectionSel());
+
+ // fill Selection-Listbox
+ m_xSelectionLB->freeze();
+ m_xSelectionLB->clear();
+
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ std::vector<OUString> aList;
+ GetFieldMgr().GetSubTypes(nTypeId, aList);
+ const size_t nCount = aList.size();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ if (nTypeId != SwFieldTypesEnum::Input || i)
+ {
+ if (!IsFieldEdit())
+ {
+ m_xSelectionLB->append(OUString::number(i), aList[i]);
+ }
+ else
+ {
+ bool bInsert = false;
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::Input:
+ if (GetCurField() && aList[i] == GetCurField()->GetPar1())
+ bInsert = true;
+ break;
+
+ case SwFieldTypesEnum::Formel:
+ bInsert = true;
+ break;
+
+ case SwFieldTypesEnum::Get:
+ if (GetCurField() && aList[i] == static_cast<const SwFormulaField*>(GetCurField())->GetFormula())
+ bInsert = true;
+ break;
+
+ case SwFieldTypesEnum::Set:
+ case SwFieldTypesEnum::User:
+ if (GetCurField() && aList[i] == GetCurField()->GetTyp()->GetName())
+ {
+ bInsert = true;
+ if (GetCurField()->GetSubType() & nsSwExtendedSubType::SUB_INVISIBLE)
+ m_xInvisibleCB->set_active(true);
+ }
+ break;
+
+ case SwFieldTypesEnum::SetRefPage:
+ {
+ if (GetCurField() != nullptr
+ && ((static_cast<SwRefPageSetField*>(GetCurField())->IsOn()
+ && i) || (!static_cast<SwRefPageSetField*>(GetCurField())
+ ->IsOn() && !i)))
+ {
+ sOldSel = aList[i];
+ }
+
+ // allow all entries for selection:
+ m_xSelectionLB->append(OUString::number(i), aList[i]);
+ break;
+ }
+ default:
+ if (GetCurField() && aList[i] == GetCurField()->GetPar1())
+ bInsert = true;
+ break;
+ }
+
+ if (bInsert)
+ {
+ m_xSelectionLB->append(OUString::number(i), aList[i]);
+ if (nTypeId != SwFieldTypesEnum::Formel)
+ break;
+ }
+ }
+ }
+ }
+
+ m_xSelectionLB->thaw();
+
+ const bool bEnable = m_xSelectionLB->n_children() != 0;
+ weld::TreeView* pLB = nullptr;
+
+ if (bEnable)
+ {
+ int nIndex = m_xSelectionLB->find_text(sOldSel);
+ if (nIndex != -1)
+ m_xSelectionLB->select(nIndex);
+ else
+ {
+ m_xSelectionLB->select(0);
+ pLB = m_xSelectionLB.get(); // newly initialise all controls
+ }
+ }
+
+ m_xSelection->set_sensitive(bEnable);
+
+ SubTypeHdl(pLB);
+}
+
+void SwFieldVarPage::FillFormatLB(SwFieldTypesEnum nTypeId)
+{
+ OUString sOldSel;
+ const sal_Int32 nFormatSel = m_xFormatLB->get_selected_index();
+ if (nFormatSel != -1)
+ sOldSel = m_xFormatLB->get_text(nFormatSel);
+
+ weld::TreeView& rWidget = dynamic_cast<weld::TreeView&>(m_xNumFormatLB->get_widget());
+
+ OUString sOldNumSel;
+ sal_uInt32 nOldNumFormat = 0;
+ sal_Int32 nNumFormatSel = rWidget.get_selected_index();
+ if (nNumFormatSel != -1)
+ {
+ sOldNumSel = rWidget.get_text(nNumFormatSel);
+ nOldNumFormat = m_xNumFormatLB->GetFormat();
+ }
+
+ // fill Format-Listbox
+ m_xFormatLB->freeze();
+ m_xFormatLB->clear();
+ m_xNumFormatLB->clear(); // flags list as dirty and needing refilling with stock entries
+ bool bSpecialFormat = false;
+
+ if( SwFieldTypesEnum::GetRefPage != nTypeId )
+ {
+ if (GetCurField() != nullptr && IsFieldEdit())
+ {
+ bSpecialFormat = GetCurField()->GetFormat() == NUMBERFORMAT_ENTRY_NOT_FOUND;
+
+ if (!bSpecialFormat)
+ {
+ m_xNumFormatLB->SetDefFormat(GetCurField()->GetFormat());
+ sOldNumSel.clear();
+ }
+ else if (nTypeId == SwFieldTypesEnum::Get || nTypeId == SwFieldTypesEnum::Formel)
+ {
+ m_xNumFormatLB->SetFormatType(SvNumFormatType::NUMBER);
+ }
+ }
+ else
+ {
+ if (nOldNumFormat && nOldNumFormat != NUMBERFORMAT_ENTRY_NOT_FOUND)
+ m_xNumFormatLB->SetDefFormat(nOldNumFormat);
+ else
+ m_xNumFormatLB->SetFormatType(SvNumFormatType::NUMBER);
+ }
+ }
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::User:
+ {
+ if (!IsFieldEdit() || bSpecialFormat)
+ {
+ OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
+ int nOldIndex = rWidget.get_selected_index();
+ rWidget.insert(0, SwResId(FMT_MARK_TEXT), &sId, nullptr, nullptr);
+ rWidget.insert(1, SwResId(FMT_USERVAR_CMD), &sId, nullptr, nullptr);
+ if (nOldIndex != -1)
+ rWidget.select(nOldIndex + 2);
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::Set:
+ {
+ if (!IsFieldEdit() || bSpecialFormat)
+ {
+ OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
+ int nOldIndex = rWidget.get_selected_index();
+ rWidget.insert(0, SwResId(FMT_SETVAR_TEXT), &sId, nullptr, nullptr);
+ if (nOldIndex != -1)
+ rWidget.select(nOldIndex + 1);
+ }
+ }
+ break;
+
+ case SwFieldTypesEnum::Formel:
+ {
+ OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
+ int nOldIndex = rWidget.get_selected_index();
+ rWidget.insert(0, SwResId(FMT_GETVAR_NAME), &sId, nullptr, nullptr);
+ if (nOldIndex != -1)
+ rWidget.select(nOldIndex + 1);
+ }
+ break;
+
+ case SwFieldTypesEnum::Get:
+ {
+ OUString sId(OUString::number(NUMBERFORMAT_ENTRY_NOT_FOUND));
+ int nOldIndex = rWidget.get_selected_index();
+ rWidget.insert(0, SwResId(FMT_GETVAR_NAME), &sId, nullptr, nullptr);
+ if (nOldIndex != -1)
+ rWidget.select(nOldIndex + 1);
+ }
+ break;
+
+ default: break;
+ }
+
+ if (IsFieldEdit() && bSpecialFormat)
+ {
+ if (nTypeId == SwFieldTypesEnum::User && (GetCurField()->GetSubType() & nsSwExtendedSubType::SUB_CMD))
+ rWidget.select(1);
+ else
+ rWidget.select(0);
+ }
+ else
+ {
+ if (!nOldNumFormat && (nNumFormatSel = rWidget.find_text(sOldNumSel)) != -1)
+ rWidget.select(nNumFormatSel);
+ else if (nOldNumFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ rWidget.select_text(sOldSel);
+ }
+
+ const sal_uInt16 nSize = GetFieldMgr().GetFormatCount(nTypeId, IsFieldDlgHtmlMode());
+
+ OUString sSelectId;
+
+ for (sal_uInt16 i = 0; i < nSize; i++)
+ {
+ const sal_uInt16 nFieldId = GetFieldMgr().GetFormatId( nTypeId, i );
+ OUString sId(OUString::number(nFieldId));
+ m_xFormatLB->append(sId, GetFieldMgr().GetFormatStr(nTypeId, i));
+ if (IsFieldEdit() && GetCurField() && nFieldId == GetCurField()->GetFormat())
+ sSelectId = sId;
+ }
+
+ m_xFormatLB->thaw();
+ if (!sSelectId.isEmpty())
+ m_xFormatLB->select_id(sSelectId);
+
+ if (nSize && (!IsFieldEdit() || m_xFormatLB->get_selected_index() == -1))
+ {
+ int nIndex = m_xFormatLB->find_text(sOldSel);
+ if (nIndex == -1)
+ nIndex = m_xFormatLB->find_text(SwResId(FMT_NUM_PAGEDESC));
+ if (nIndex == -1)
+ nIndex = m_xFormatLB->find_text(SwResId(FMT_NUM_ARABIC));
+ if (nIndex == -1)
+ nIndex = 0;
+ m_xFormatLB->select(nIndex);
+ }
+}
+
+// Modify
+IMPL_LINK_NOARG(SwFieldVarPage, ModifyHdl, weld::Entry&, void)
+{
+ OUString sValue(m_xValueED->get_text());
+ bool bHasValue = !sValue.isEmpty();
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+ bool bInsert = false, bApply = false, bDelete = false;
+
+ OUString sName( m_xNameED->get_text() );
+ sal_Int32 nLen = sName.getLength();
+
+ switch( nTypeId )
+ {
+ case SwFieldTypesEnum::DDE:
+ case SwFieldTypesEnum::User:
+ case SwFieldTypesEnum::Set:
+ case SwFieldTypesEnum::Sequence:
+ SwCalc::IsValidVarName( sName, &sName );
+ if ( sName.getLength() != nLen )
+ {
+ nLen = sName.getLength();
+ int nStartPos, nEndPos;
+ m_xNameED->get_selection_bounds(nStartPos, nEndPos);
+ m_xNameED->set_text( sName );
+ m_xNameED->select_region(nStartPos, nEndPos); // restore Cursorpos
+ }
+ break;
+ default: break;
+ }
+
+ // check buttons
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::DDE:
+ if( nLen )
+ {
+ // is there already a corresponding type
+ bInsert = bApply = true;
+
+ SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::Dde, sName);
+
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh && pType)
+ bDelete = !pSh->IsUsed( *pType );
+ }
+ break;
+
+ case SwFieldTypesEnum::User:
+ if( nLen )
+ {
+ // is there already a corresponding type
+ SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::User, sName);
+
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh && pType)
+ bDelete = !pSh->IsUsed( *pType );
+
+ pType = GetFieldMgr().GetFieldType(SwFieldIds::SetExp, sName);
+ if (!pType) // no name conflict with variables
+ {
+ // user fields can also be inserted without content!
+ // Bug #56845
+ bInsert = bApply = true;
+ }
+ }
+ break;
+
+ default:
+ bInsert = true;
+
+ if (nTypeId == SwFieldTypesEnum::Set || nTypeId == SwFieldTypesEnum::Sequence)
+ {
+ SwSetExpFieldType* pFieldType = static_cast<SwSetExpFieldType*>(
+ GetFieldMgr().GetFieldType(SwFieldIds::SetExp, sName));
+
+ if (pFieldType)
+ {
+
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ const SwFieldTypes* p = pSh->GetDoc()->getIDocumentFieldsAccess().GetFieldTypes();
+ sal_uInt16 i;
+
+ for (i = 0; i < INIT_FLDTYPES; i++)
+ {
+ SwFieldType* pType = (*p)[ i ].get();
+ if (pType == pFieldType)
+ break;
+ }
+
+ if (i >= INIT_FLDTYPES && !pSh->IsUsed(*pFieldType))
+ bDelete = true;
+
+ if (nTypeId == SwFieldTypesEnum::Sequence && !(pFieldType->GetType() & nsSwGetSetExpType::GSE_SEQ))
+ bInsert = false;
+
+ if (nTypeId == SwFieldTypesEnum::Set && (pFieldType->GetType() & nsSwGetSetExpType::GSE_SEQ))
+ bInsert = false;
+ }
+ }
+ if (GetFieldMgr().GetFieldType(SwFieldIds::User, sName))
+ bInsert = false;
+ }
+
+ if (!nLen && (nTypeId == SwFieldTypesEnum::Set || nTypeId == SwFieldTypesEnum::Input ||
+ (!IsFieldEdit() && nTypeId == SwFieldTypesEnum::Get ) ) )
+ bInsert = false;
+
+ if( (nTypeId == SwFieldTypesEnum::Set || nTypeId == SwFieldTypesEnum::Formel) &&
+ !bHasValue )
+ bInsert = false;
+ break;
+ }
+
+ m_xNewPB->set_sensitive(bApply);
+ m_xDelPB->set_sensitive(bDelete);
+ EnableInsert(bInsert);
+}
+
+IMPL_LINK(SwFieldVarPage, TBClickHdl, weld::Button&, rBox, void)
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ if (&rBox == m_xDelPB.get())
+ {
+ if( nTypeId == SwFieldTypesEnum::User )
+ GetFieldMgr().RemoveFieldType(SwFieldIds::User, m_xSelectionLB->get_selected_text());
+ else
+ {
+ SwFieldIds nWhich;
+
+ switch(nTypeId)
+ {
+ case SwFieldTypesEnum::Set:
+ case SwFieldTypesEnum::Sequence:
+ nWhich = SwFieldIds::SetExp;
+ break;
+ default:
+ nWhich = SwFieldIds::Dde;
+ break;
+ }
+
+ GetFieldMgr().RemoveFieldType(nWhich, m_xSelectionLB->get_selected_text());
+ }
+
+ UpdateSubType();
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ pSh->SetModified();
+ }
+ }
+ else if (&rBox == m_xNewPB.get())
+ {
+ OUString sName(m_xNameED->get_text()), sValue(m_xValueED->get_text());
+ SwFieldType* pType = nullptr;
+ SwFieldIds nId = SwFieldIds::Database;
+ sal_Int32 nNumFormatPos = m_xNumFormatLB->get_selected_index();
+
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::User: nId = SwFieldIds::User; break;
+ case SwFieldTypesEnum::DDE: nId = SwFieldIds::Dde; break;
+ case SwFieldTypesEnum::Set: nId = SwFieldIds::SetExp;break;
+ default: break;
+ }
+ pType = GetFieldMgr().GetFieldType(nId, sName);
+
+ int nFormat = m_xFormatLB->get_selected_index();
+ if (nFormat != -1)
+ nFormat = m_xFormatLB->get_id(nFormat).toUInt32();
+
+ if (pType) // change
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ pSh->StartAllAction();
+
+ if (nTypeId == SwFieldTypesEnum::User)
+ {
+ if (nNumFormatPos != -1)
+ {
+ sal_uLong nNumberFormat = nNumFormatPos == 0 ? 0 : m_xNumFormatLB->GetFormat();
+ if (nNumberFormat)
+ { // Switch language to office-language because Kalkulator expects
+ // String in office format and it should be fed into dialog like
+ // that
+ nNumberFormat = SwValueField::GetSystemFormat(pSh->GetNumberFormatter(), nNumberFormat);
+ }
+ static_cast<SwUserFieldType*>(pType)->SetContent(m_xValueED->get_text(), nNumberFormat);
+ static_cast<SwUserFieldType*>(pType)->SetType(
+ nNumFormatPos == 0 ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR );
+ }
+ }
+ else
+ {
+ if (nFormat != -1)
+ {
+ // DDE-Topics/-Items can have blanks in their names!
+ // That's not being considered here yet.
+ sal_Int32 nTmpPos = 0;
+ sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
+ sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
+ static_cast<SwDDEFieldType*>(pType)->SetCmd(sValue);
+ static_cast<SwDDEFieldType*>(pType)->SetType(static_cast<SfxLinkUpdateMode>(nFormat));
+ }
+ }
+ pType->UpdateFields();
+
+ pSh->EndAllAction();
+ }
+ }
+ else // new
+ {
+ if(nTypeId == SwFieldTypesEnum::User)
+ {
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ SwUserFieldType aType( pSh->GetDoc(), sName );
+
+ if (nNumFormatPos != -1)
+ {
+ aType.SetType(nNumFormatPos == 0 ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR);
+ aType.SetContent( sValue, nNumFormatPos == 0 ? 0 : m_xNumFormatLB->GetFormat() );
+ m_xSelectionLB->append_text(sName);
+ m_xSelectionLB->select_text(sName);
+ GetFieldMgr().InsertFieldType( aType ); // Userfld new
+ }
+ }
+ }
+ else
+ {
+ if (nFormat != -1)
+ {
+ // DDE-Topics/-Items can have blanks in their names!
+ // That's not being considered here yet.
+ sal_Int32 nTmpPos = 0;
+ sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
+ sValue = sValue.replaceFirst( " ", OUStringChar(sfx2::cTokenSeparator), &nTmpPos );
+
+ SwDDEFieldType aType(sName, sValue, static_cast<SfxLinkUpdateMode>(nFormat));
+ m_xSelectionLB->append_text(sName);
+ m_xSelectionLB->select_text(sName);
+ GetFieldMgr().InsertFieldType(aType); // DDE-Field new
+ }
+ }
+ }
+ if (IsFieldEdit())
+ GetFieldMgr().GetCurField(); // update FieldManager
+
+ UpdateSubType();
+ }
+}
+
+IMPL_LINK_NOARG(SwFieldVarPage, ChapterHdl, weld::ComboBox&, void)
+{
+ bool bEnable = m_xChapterLevelLB->get_active() != 0;
+
+ m_xSeparatorED->set_sensitive(bEnable);
+ m_xSeparatorFT->set_sensitive(bEnable);
+ SeparatorHdl(*m_xSeparatorED);
+}
+
+IMPL_LINK_NOARG(SwFieldVarPage, SeparatorHdl, weld::Entry&, void)
+{
+ bool bEnable = !m_xSeparatorED->get_text().isEmpty() ||
+ m_xChapterLevelLB->get_active() == 0;
+ EnableInsert(bEnable);
+}
+
+bool SwFieldVarPage::FillItemSet(SfxItemSet* )
+{
+ const SwFieldTypesEnum nTypeId = static_cast<SwFieldTypesEnum>(m_xTypeLB->get_id(GetTypeSel()).toUInt32());
+
+ OUString aVal(m_xValueED->get_text());
+ OUString aName(m_xNameED->get_text());
+
+ const sal_Int32 nSubPos = m_xSelectionLB->get_selected_index();
+ sal_uInt16 nSubType = (nSubPos == -1) ? 0 : m_xSelectionLB->get_id(nSubPos).toUInt32();
+
+ sal_uInt32 nFormat;
+
+ if (!m_xNumFormatLB->get_visible())
+ {
+ sal_Int32 nFormatPos = m_xFormatLB->get_selected_index();
+
+ if(nFormatPos == -1)
+ nFormat = 0;
+ else
+ nFormat = m_xFormatLB->get_id(nFormatPos).toUInt32();
+ }
+ else
+ {
+ nFormat = m_xNumFormatLB->GetFormat();
+
+ if (nFormat && nFormat != NUMBERFORMAT_ENTRY_NOT_FOUND && m_xNumFormatLB->IsAutomaticLanguage())
+ {
+ // Switch language to office language because Kalkulator expects
+ // String in office format and it should be fed into the dialog
+ // like that
+ SwWrtShell *pSh = GetWrtShell();
+ if(!pSh)
+ pSh = ::GetActiveWrtShell();
+ if(pSh)
+ {
+ nFormat = SwValueField::GetSystemFormat(pSh->GetNumberFormatter(), nFormat);
+ }
+ }
+ }
+ sal_Unicode cSeparator = ' ';
+ switch (nTypeId)
+ {
+ case SwFieldTypesEnum::User:
+ {
+ nSubType = (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR;
+
+ if (nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND && m_xNumFormatLB->get_selected_text() == SwResId(FMT_USERVAR_CMD))
+ nSubType |= nsSwExtendedSubType::SUB_CMD;
+
+ if (m_xInvisibleCB->get_active())
+ nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
+ break;
+ }
+ case SwFieldTypesEnum::Formel:
+ {
+ nSubType = nsSwGetSetExpType::GSE_FORMULA;
+ if (m_xNumFormatLB->get_visible() && nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ nSubType |= nsSwExtendedSubType::SUB_CMD;
+ break;
+ }
+ case SwFieldTypesEnum::Get:
+ {
+ nSubType &= 0xff00;
+ if (m_xNumFormatLB->get_visible() && nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ nSubType |= nsSwExtendedSubType::SUB_CMD;
+ break;
+ }
+ case SwFieldTypesEnum::Input:
+ {
+ SwFieldType* pType = GetFieldMgr().GetFieldType(SwFieldIds::User, aName);
+ nSubType = static_cast< sal_uInt16 >((nSubType & 0xff00) | (pType ? INP_USR : INP_VAR));
+ break;
+ }
+
+ case SwFieldTypesEnum::Set:
+ {
+ if (IsFieldDlgHtmlMode())
+ {
+ nSubType = 0x0100;
+ nSubType = (nSubType & 0xff00) | nsSwGetSetExpType::GSE_STRING;
+ }
+ else
+ nSubType = (nSubType & 0xff00) | ((nFormat == NUMBERFORMAT_ENTRY_NOT_FOUND) ? nsSwGetSetExpType::GSE_STRING : nsSwGetSetExpType::GSE_EXPR);
+
+ if (m_xInvisibleCB->get_active())
+ nSubType |= nsSwExtendedSubType::SUB_INVISIBLE;
+ break;
+ }
+ case SwFieldTypesEnum::Sequence:
+ {
+ nSubType = static_cast< sal_uInt16 >(m_xChapterLevelLB->get_active());
+ if (nSubType == 0)
+ nSubType = 0x7f;
+ else
+ {
+ nSubType--;
+ OUString sSeparator(m_xSeparatorED->get_text()[0]);
+ cSeparator = !sSeparator.isEmpty() ? sSeparator[0] : ' ';
+ }
+ break;
+ }
+ case SwFieldTypesEnum::GetRefPage:
+ if( SVX_NUM_CHAR_SPECIAL == nFormat )
+ aVal = m_xValueED->get_text();
+ break;
+ default: break;
+ }
+
+ if (!IsFieldEdit() ||
+ m_xNameED->get_value_changed_from_saved() ||
+ m_xValueED->get_value_changed_from_saved() ||
+ m_xSelectionLB->get_value_changed_from_saved() ||
+ m_xFormatLB->get_value_changed_from_saved() ||
+ nOldFormat != m_xNumFormatLB->GetFormat() ||
+ m_xInvisibleCB->get_state_changed_from_saved() ||
+ m_xChapterLevelLB->get_value_changed_from_saved() ||
+ m_xSeparatorED->get_value_changed_from_saved())
+ {
+ InsertField( nTypeId, nSubType, aName, aVal, nFormat,
+ cSeparator, m_xNumFormatLB->IsAutomaticLanguage() );
+ }
+
+ UpdateSubType();
+
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> SwFieldVarPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet *const pAttrSet)
+{
+ return std::make_unique<SwFieldVarPage>( pPage, pController, pAttrSet );
+}
+
+sal_uInt16 SwFieldVarPage::GetGroup()
+{
+ return GRP_VAR;
+}
+
+void SwFieldVarPage::FillUserData()
+{
+ OUString sData = USER_DATA_VERSION ";";
+ sal_Int32 nTypeSel = m_xTypeLB->get_selected_index();
+ if( -1 == nTypeSel )
+ nTypeSel = USHRT_MAX;
+ else
+ nTypeSel = m_xTypeLB->get_id(nTypeSel).toUInt32();
+ sData += OUString::number( nTypeSel );
+ SetUserData(sData);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/fldvar.hxx b/sw/source/ui/fldui/fldvar.hxx
new file mode 100644
index 000000000..b214e5adf
--- /dev/null
+++ b/sw/source/ui/fldui/fldvar.hxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_SW_SOURCE_UI_FLDUI_FLDVAR_HXX
+#define INCLUDED_SW_SOURCE_UI_FLDUI_FLDVAR_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+#include "fldpage.hxx"
+#include <condedit.hxx>
+#include <numfmtlb.hxx>
+
+class SwFieldVarPage;
+
+class SwFieldVarPage : public SwFieldPage
+{
+ std::unique_ptr<weld::TreeView> m_xTypeLB;
+ std::unique_ptr<weld::Widget> m_xSelection;
+ std::unique_ptr<weld::TreeView> m_xSelectionLB;
+ std::unique_ptr<weld::Label> m_xNameFT;
+ std::unique_ptr<weld::Entry> m_xNameED;
+ std::unique_ptr<weld::Label> m_xValueFT;
+ std::unique_ptr<ConditionEdit> m_xValueED;
+ std::unique_ptr<weld::Widget> m_xFormat;
+ std::unique_ptr<SwNumFormatTreeView> m_xNumFormatLB;
+ std::unique_ptr<weld::TreeView> m_xFormatLB;
+ std::unique_ptr<weld::Widget> m_xChapterFrame;
+ std::unique_ptr<weld::ComboBox> m_xChapterLevelLB;
+ std::unique_ptr<weld::CheckButton> m_xInvisibleCB;
+ std::unique_ptr<weld::Label> m_xSeparatorFT;
+ std::unique_ptr<weld::Entry> m_xSeparatorED;
+ std::unique_ptr<weld::Button> m_xNewPB;
+ std::unique_ptr<weld::Button> m_xDelPB;
+
+ OUString sOldValueFT;
+ OUString sOldNameFT;
+
+ sal_uInt32 nOldFormat;
+ bool bInit;
+
+ DECL_LINK( TypeHdl, weld::TreeView&, void );
+ DECL_LINK( SubTypeListBoxHdl, weld::TreeView&, void );
+ DECL_LINK( ModifyHdl, weld::Entry&, void );
+ DECL_LINK( TBClickHdl, weld::Button&, void );
+ DECL_LINK( ChapterHdl, weld::ComboBox&, void );
+ DECL_LINK( SeparatorHdl, weld::Entry&, void );
+ DECL_LINK( SubTypeInsertHdl, weld::TreeView&, bool );
+ void SubTypeHdl(const weld::TreeView*);
+
+ void UpdateSubType();
+ void FillFormatLB(SwFieldTypesEnum nTypeId);
+
+protected:
+ virtual sal_uInt16 GetGroup() override;
+
+public:
+ SwFieldVarPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* pSet);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+ virtual ~SwFieldVarPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual void FillUserData() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/inpdlg.cxx b/sw/source/ui/fldui/inpdlg.cxx
new file mode 100644
index 000000000..7eaa19e9f
--- /dev/null
+++ b/sw/source/ui/fldui/inpdlg.cxx
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/lineend.hxx>
+#include <unotools/charclass.hxx>
+#include <wrtsh.hxx>
+#include <fldbas.hxx>
+#include <expfld.hxx>
+#include <usrfld.hxx>
+#include <inpdlg.hxx>
+
+// edit field-insert
+SwFieldInputDlg::SwFieldInputDlg(weld::Widget *pParent, SwWrtShell &rS,
+ SwField* pField, bool bPrevButton, bool bNextButton)
+ : GenericDialogController(pParent, "modules/swriter/ui/inputfielddialog.ui", "InputFieldDialog")
+ , rSh( rS )
+ , pInpField(nullptr)
+ , pSetField(nullptr)
+ , pUsrType(nullptr)
+ , m_pPressedButton(nullptr)
+ , m_xLabelED(m_xBuilder->weld_entry("name"))
+ , m_xEditED(m_xBuilder->weld_text_view("text"))
+ , m_xPrevBT(m_xBuilder->weld_button("prev"))
+ , m_xNextBT(m_xBuilder->weld_button("next"))
+ , m_xOKBT(m_xBuilder->weld_button("ok"))
+{
+ m_xEditED->set_size_request(-1, m_xEditED->get_height_rows(8));
+
+ if( bPrevButton || bNextButton )
+ {
+ m_xPrevBT->show();
+ m_xPrevBT->connect_clicked(LINK(this, SwFieldInputDlg, PrevHdl));
+ m_xPrevBT->set_sensitive(bPrevButton);
+
+ m_xNextBT->show();
+ m_xNextBT->connect_clicked(LINK(this, SwFieldInputDlg, NextHdl));
+ m_xNextBT->set_sensitive(bNextButton);
+ }
+
+ // evaluation here
+ OUString aStr;
+ if( SwFieldIds::Input == pField->GetTyp()->Which() )
+ { // it is an input field
+
+ pInpField = static_cast<SwInputField*>(pField);
+ m_xLabelED->set_text(pInpField->GetPar2());
+ sal_uInt16 nSubType = pInpField->GetSubType();
+
+ switch(nSubType & 0xff)
+ {
+ case INP_TXT:
+ aStr = pInpField->GetPar1();
+ break;
+
+ case INP_USR:
+ // user field
+ pUsrType = static_cast<SwUserFieldType*>(rSh.GetFieldType(
+ SwFieldIds::User, pInpField->GetPar1() ));
+ if( nullptr != pUsrType )
+ aStr = pUsrType->GetContent();
+ break;
+ }
+ }
+ else
+ {
+ // it is a SetExpression
+ pSetField = static_cast<SwSetExpField*>(pField);
+ OUString sFormula(pSetField->GetFormula());
+ //values are formatted - formulas are not
+ CharClass aCC( LanguageTag( pSetField->GetLanguage() ));
+ if( aCC.isNumeric( sFormula ))
+ {
+ aStr = pSetField->ExpandField(true, rS.GetLayout());
+ }
+ else
+ aStr = sFormula;
+ m_xLabelED->set_text(pSetField->GetPromptText());
+ }
+
+ // JP 31.3.00: Inputfields in readonly regions must be allowed to
+ // input any content. - 74639
+ bool bEnable = !rSh.IsCursorReadonly();
+
+ m_xOKBT->set_sensitive( bEnable );
+ m_xEditED->set_editable( bEnable );
+
+ if( !aStr.isEmpty() )
+ m_xEditED->set_text(convertLineEnd(aStr, GetSystemLineEnd()));
+ m_xEditED->grab_focus();
+
+ // preselect all text to allow quickly changing the content
+ if (bEnable)
+ m_xEditED->select_region(0, -1);
+}
+
+SwFieldInputDlg::~SwFieldInputDlg()
+{
+}
+
+// Close
+void SwFieldInputDlg::Apply()
+{
+ OUString aTmp = m_xEditED->get_text().replaceAll("\r", "");
+ rSh.StartAllAction();
+ bool bModified = false;
+ if(pInpField)
+ {
+ if(pUsrType)
+ {
+ if( aTmp != pUsrType->GetContent() )
+ {
+ pUsrType->SetContent(aTmp);
+ pUsrType->UpdateFields();
+ bModified = true;
+ }
+ }
+ else if( aTmp != pInpField->GetPar1() )
+ {
+ pInpField->SetPar1(aTmp);
+ rSh.SwEditShell::UpdateOneField(*pInpField);
+ bModified = true;
+ }
+ }
+ else if( aTmp != pSetField->GetPar2())
+ {
+ pSetField->SetPar2(aTmp);
+ rSh.SwEditShell::UpdateOneField(*pSetField);
+ bModified = true;
+ }
+
+ if( bModified )
+ rSh.SetUndoNoResetModified();
+
+ rSh.EndAllAction();
+}
+
+bool SwFieldInputDlg::PrevButtonPressed() const
+{
+ return m_pPressedButton == m_xPrevBT.get();
+}
+
+bool SwFieldInputDlg::NextButtonPressed() const
+{
+ return m_pPressedButton == m_xNextBT.get();
+}
+
+IMPL_LINK_NOARG(SwFieldInputDlg, PrevHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xPrevBT.get();
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SwFieldInputDlg, NextHdl, weld::Button&, void)
+{
+ m_pPressedButton = m_xNextBT.get();
+ m_xDialog->response(RET_OK);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/fldui/javaedit.cxx b/sw/source/ui/fldui/javaedit.cxx
new file mode 100644
index 000000000..b13c9828d
--- /dev/null
+++ b/sw/source/ui/fldui/javaedit.cxx
@@ -0,0 +1,253 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <svl/urihelper.hxx>
+#include <view.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <docsh.hxx>
+#include <wrtsh.hxx>
+#include <fldbas.hxx>
+#include <fldmgr.hxx>
+#include <docufld.hxx>
+#include <javaedit.hxx>
+
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+
+SwJavaEditDialog::SwJavaEditDialog(weld::Window* pParent, SwWrtShell* pWrtSh)
+ : GenericDialogController(pParent, "modules/swriter/ui/insertscript.ui", "InsertScriptDialog")
+ , m_bNew(true)
+ , m_bIsUrl(false)
+ , m_pSh(pWrtSh)
+ , m_xTypeED(m_xBuilder->weld_entry("scripttype"))
+ , m_xUrlRB(m_xBuilder->weld_radio_button("url"))
+ , m_xEditRB(m_xBuilder->weld_radio_button("text"))
+ , m_xUrlPB(m_xBuilder->weld_button("browse"))
+ , m_xUrlED(m_xBuilder->weld_entry("urlentry"))
+ , m_xEditED(m_xBuilder->weld_text_view("textentry"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xPrevBtn(m_xBuilder->weld_button("previous"))
+ , m_xNextBtn(m_xBuilder->weld_button("next"))
+{
+ // install handler
+ m_xPrevBtn->connect_clicked( LINK( this, SwJavaEditDialog, PrevHdl ) );
+ m_xNextBtn->connect_clicked( LINK( this, SwJavaEditDialog, NextHdl ) );
+ m_xOKBtn->connect_clicked( LINK( this, SwJavaEditDialog, OKHdl ) );
+
+ Link<weld::Toggleable&,void> aLk = LINK(this, SwJavaEditDialog, RadioButtonHdl);
+ m_xUrlRB->connect_toggled(aLk);
+ m_xEditRB->connect_toggled(aLk);
+ m_xUrlPB->connect_clicked(LINK(this, SwJavaEditDialog, InsertFileHdl));
+
+ m_pMgr.reset(new SwFieldMgr(m_pSh));
+ m_pField = static_cast<SwScriptField*>(m_pMgr->GetCurField());
+
+ m_bNew = !(m_pField && m_pField->GetTyp()->Which() == SwFieldIds::Script);
+
+ CheckTravel();
+
+ if (!m_bNew)
+ m_xDialog->set_title(SwResId(STR_JAVA_EDIT));
+
+ UpdateFromRadioButtons();
+}
+
+SwJavaEditDialog::~SwJavaEditDialog()
+{
+ m_pSh->EnterStdMode();
+ m_pMgr.reset();
+ m_pFileDlg.reset();
+}
+
+IMPL_LINK_NOARG(SwJavaEditDialog, PrevHdl, weld::Button&, void)
+{
+ m_pSh->EnterStdMode();
+
+ SetField();
+ m_pMgr->GoPrev();
+ m_pField = static_cast<SwScriptField*>(m_pMgr->GetCurField());
+ CheckTravel();
+ UpdateFromRadioButtons();
+}
+
+IMPL_LINK_NOARG(SwJavaEditDialog, NextHdl, weld::Button&, void)
+{
+ m_pSh->EnterStdMode();
+
+ SetField();
+ m_pMgr->GoNext();
+ m_pField = static_cast<SwScriptField*>(m_pMgr->GetCurField());
+ CheckTravel();
+ UpdateFromRadioButtons();
+}
+
+IMPL_LINK_NOARG(SwJavaEditDialog, OKHdl, weld::Button&, void)
+{
+ SetField();
+ m_xDialog->response(RET_OK);
+}
+
+void SwJavaEditDialog::CheckTravel()
+{
+ bool bTravel = false;
+ bool bNext(false), bPrev(false);
+
+ if (!m_bNew)
+ {
+ // Traveling only when more than one field
+ m_pSh->StartAction();
+ m_pSh->CreateCursor();
+
+ bNext = m_pMgr->GoNext();
+ if( bNext )
+ m_pMgr->GoPrev();
+
+ bPrev = m_pMgr->GoPrev();
+ if( bPrev )
+ m_pMgr->GoNext();
+ bTravel |= bNext || bPrev;
+
+ m_pSh->DestroyCursor();
+ m_pSh->EndAction();
+
+ if (m_pField->IsCodeURL())
+ {
+ OUString sURL(m_pField->GetPar2());
+ if(!sURL.isEmpty())
+ {
+ INetURLObject aINetURL(sURL);
+ if(INetProtocol::File == aINetURL.GetProtocol())
+ sURL = aINetURL.PathToFileName();
+ }
+ m_xUrlED->set_text(sURL);
+ m_xEditED->set_text(OUString());
+ m_xUrlRB->set_active(true);
+ }
+ else
+ {
+ m_xEditED->set_text(m_pField->GetPar2());
+ m_xUrlED->set_text(OUString());
+ m_xEditRB->set_active(true);
+ }
+ m_xTypeED->set_text(m_pField->GetPar1());
+ }
+
+ if ( !bTravel )
+ {
+ m_xPrevBtn->hide();
+ m_xNextBtn->hide();
+ }
+ else
+ {
+ m_xPrevBtn->set_sensitive(bPrev);
+ m_xNextBtn->set_sensitive(bNext);
+ }
+}
+
+void SwJavaEditDialog::SetField()
+{
+ if( !m_xOKBtn->get_sensitive() )
+ return ;
+
+ m_aType = m_xTypeED->get_text();
+ m_bIsUrl = m_xUrlRB->get_active();
+
+ if (m_bIsUrl)
+ {
+ m_aText = m_xUrlED->get_text();
+ if (!m_aText.isEmpty())
+ {
+ SfxMedium* pMedium = m_pSh->GetView().GetDocShell()->GetMedium();
+ INetURLObject aAbs;
+ if( pMedium )
+ aAbs = pMedium->GetURLObject();
+
+ m_aText = URIHelper::SmartRel2Abs(
+ aAbs, m_aText, URIHelper::GetMaybeFileHdl());
+ }
+ }
+ else
+ m_aText = m_xEditED->get_text();
+
+ if (m_aType.isEmpty())
+ m_aType = "JavaScript";
+}
+
+bool SwJavaEditDialog::IsUpdate() const
+{
+ return m_pField && ( sal_uInt32(m_bIsUrl ? 1 : 0) != m_pField->GetFormat() || m_pField->GetPar2() != m_aType || m_pField->GetPar1() != m_aText );
+}
+
+IMPL_LINK(SwJavaEditDialog, RadioButtonHdl, weld::Toggleable&, rButton, void)
+{
+ if (!rButton.get_active())
+ return;
+ UpdateFromRadioButtons();
+}
+
+void SwJavaEditDialog::UpdateFromRadioButtons()
+{
+ bool bEnable = m_xUrlRB->get_active();
+ m_xUrlPB->set_sensitive(bEnable);
+ m_xUrlED->set_sensitive(bEnable);
+ m_xEditED->set_sensitive(!bEnable);
+
+ if (!m_bNew)
+ {
+ bEnable = !m_pSh->IsReadOnlyAvailable() || !m_pSh->HasReadonlySel();
+ m_xOKBtn->set_sensitive(bEnable);
+ m_xUrlED->set_editable(bEnable);
+ m_xEditED->set_editable(bEnable);
+ m_xTypeED->set_editable(bEnable);
+ if( m_xUrlPB->get_sensitive() && !bEnable )
+ m_xUrlPB->set_sensitive( false );
+ }
+}
+
+IMPL_LINK_NOARG( SwJavaEditDialog, InsertFileHdl, weld::Button&, void )
+{
+ if (!m_pFileDlg)
+ {
+ m_pFileDlg.reset(new ::sfx2::FileDialogHelper(
+ ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::Insert, "swriter", SfxFilterFlags::NONE, SfxFilterFlags::NONE, m_xDialog.get()));
+ }
+ m_pFileDlg->SetContext(sfx2::FileDialogHelper::WriterInsertScript);
+ m_pFileDlg->StartExecuteModal( LINK( this, SwJavaEditDialog, DlgClosedHdl ) );
+}
+
+IMPL_LINK_NOARG(SwJavaEditDialog, DlgClosedHdl, sfx2::FileDialogHelper *, void)
+{
+ if (m_pFileDlg->GetError() == ERRCODE_NONE)
+ {
+ OUString sFileName = m_pFileDlg->GetPath();
+ if ( !sFileName.isEmpty() )
+ {
+ INetURLObject aINetURL( sFileName );
+ if ( INetProtocol::File == aINetURL.GetProtocol() )
+ sFileName = aINetURL.PathToFileName();
+ }
+ m_xUrlED->set_text(sFileName);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */