summaryrefslogtreecommitdiffstats
path: root/sw/source/ui/fldui/flddb.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/ui/fldui/flddb.cxx')
-rw-r--r--sw/source/ui/fldui/flddb.cxx541
1 files changed, 541 insertions, 0 deletions
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: */