/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include "flddinf.hxx" #include #include #include #include #include #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 (auto const& aID : FLD_SELECT) rListBox.append_text(SwResId(aID)); } SwFieldDokInfPage::SwFieldDokInfPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pCoreSet) : SwFieldPage(pPage, pController, "modules/swriter/ui/flddocinfopage.ui", "FieldDocInfoPage", pCoreSet) , m_nOldSel(0) , m_nOldFormat(0) , m_xTypeList(m_xBuilder->weld_tree_view("type-list")) , m_xTypeTree(m_xBuilder->weld_tree_view("type-tree")) // tdf#104278 have two tree views, one with expander and one without, the one with is only used // when there are custom properties which use the expander, so the common case of no custom // properties doesn't have an 'unexplained' expander margin , m_pTypeView(m_xTypeTree.get()) , 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_xTypeList->make_sorted(); m_xTypeTree->make_sorted(); FillFieldSelect(*m_xSelectionLB); auto nWidth = m_pTypeView->get_approximate_digit_width() * FIELD_COLUMN_WIDTH; auto nHeight = m_pTypeView->get_height_rows(10); m_xTypeTree->set_size_request(nWidth, nHeight); m_xTypeList->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() >>= m_xCustomPropertySet; // uitests m_pTypeView->set_buildable_name("type-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 uno::Sequence aCustomProperties; if (m_xCustomPropertySet.is()) { uno::Reference xSetInfo = m_xCustomPropertySet->getPropertySetInfo(); aCustomProperties = xSetInfo->getProperties(); } if (aCustomProperties.hasElements()) { m_xTypeList->hide(); m_xTypeList->set_buildable_name("type-list"); m_xTypeTree->show(); m_pTypeView = m_xTypeTree.get(); } else { m_xTypeTree->hide(); m_xTypeTree->set_buildable_name("type-tree"); m_xTypeList->show(); m_pTypeView = m_xTypeList.get(); } m_pTypeView->set_buildable_name("type-docinf"); // initialise TypeListBox m_pTypeView->freeze(); m_pTypeView->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(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 aLst; GetFieldMgr().GetSubTypes(SwFieldTypesEnum::DocumentInfo, aLst); std::unique_ptr xEntry(m_pTypeView->make_iterator()); std::unique_ptr 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(m_xCustomPropertySet.is() ) { if (aCustomProperties.hasElements()) { std::unique_ptr xInfo(m_pTypeView->make_iterator()); OUString sText(SwResId(STR_CUSTOM_FIELD)); OUString sEntryId(OUString::number(USHRT_MAX)); m_pTypeView->insert(nullptr, -1, &sText, &sEntryId, nullptr, nullptr, false, xInfo.get()); for (const auto& rProperty : aCustomProperties) { const OUString sEntry = rProperty.Name; m_pTypeView->insert(xInfo.get(), -1, &sEntry, &sId, nullptr, nullptr, false, xEntry.get()); if (m_sOldCustomFieldName == sEntry) { m_xSelEntry = m_pTypeView->make_iterator(xEntry.get()); xExpandEntry = m_pTypeView->make_iterator(xInfo.get()); } } } } } else { if (!(IsFieldDlgHtmlMode() && (i == DI_EDIT || i == DI_SUBJECT || i == DI_PRINT))) { m_pTypeView->insert(nullptr, -1, &aLst[i], &sId, nullptr, nullptr, false, xEntry.get()); } } if (static_cast(nSelEntryData) == i) m_xSelEntry = std::move(xEntry); } } m_pTypeView->thaw(); if (xExpandEntry) m_pTypeView->expand_row(*xExpandEntry); // select old Pos if (m_xSelEntry) { m_pTypeView->select(*m_xSelEntry); nSubType = m_pTypeView->get_id(*m_xSelEntry).toUInt32(); } else { m_xSelEntry = m_pTypeView->make_iterator(); if (m_pTypeView->get_iter_first(*m_xSelEntry)) nSubType = m_pTypeView->get_id(*m_xSelEntry).toUInt32(); else m_xSelEntry.reset(); } FillSelectionLB(nSubType); if (m_xSelEntry) TypeHdl(*m_pTypeView); m_pTypeView->connect_changed(LINK(this, SwFieldDokInfPage, TypeHdl)); m_pTypeView->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()) { m_nOldSel = m_xSelectionLB->get_selected_index(); m_nOldFormat = GetCurField()->GetFormat(); m_xFixedCB->save_state(); } } IMPL_LINK_NOARG(SwFieldDokInfPage, TypeHdl, weld::TreeView&, void) { // current ListBoxPos if (!m_pTypeView->get_selected(m_xSelEntry.get()) && m_pTypeView->get_iter_first(*m_xSelEntry)) { m_pTypeView->select(*m_xSelEntry); } FillSelectionLB(m_pTypeView->get_id(*m_xSelEntry).toUInt32()); SubTypeHdl(*m_xSelectionLB); } IMPL_LINK_NOARG(SwFieldDokInfPage, SubTypeHdl, weld::TreeView&, void) { sal_uInt16 nSubType = m_pTypeView->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_pTypeView->get_text(*m_xSelEntry); try { uno::Any aVal = m_xCustomPropertySet->getPropertyValue( sName ); const uno::Type& rValueType = aVal.getValueType(); if( rValueType == ::cppu::UnoType::get()) { nNewType = SvNumFormatType::DATETIME; } else if( rValueType == ::cppu::UnoType::get()) { nNewType = SvNumFormatType::DATE; } else if( rValueType == ::cppu::UnoType::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(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(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_pTypeView->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_pTypeView->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() || m_nOldSel != m_xSelectionLB->get_selected_index() || m_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 SwFieldDokInfPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *const pAttrSet) { return std::make_unique(pPage, pController, pAttrSet); } sal_uInt16 SwFieldDokInfPage::GetGroup() { return GRP_REG; } void SwFieldDokInfPage::FillUserData() { int nEntry = m_pTypeView->get_selected_index(); sal_uInt16 nTypeSel = nEntry != -1 ? m_pTypeView->get_id(nEntry).toUInt32() : USHRT_MAX; SetUserData(USER_DATA_VERSION ";" + OUString::number( nTypeSel )); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */