tdf#156499 new SoftFixed to complement Fixed field state

Use instead of Fixed when importing DOCX and RTF DocProperty fields
whose text does not match the File - Properties - Custom variable's
content.

SoftFixed allows users to trigger updates via UI (Update All, F9, ...).
But fields won't update automatically, matching the MSO behaviour.

see also tdf#147861 and commit c4cb1d1dd5

Change-Id: Iaeecfd48a58abf0827f07be5522f3cb03e25ac8d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198894
Tested-by: Jenkins
Reviewed-by: Moritz Duge <moritz.duge@allotropia.de>
Reviewed-by: Justin Luth <jluth@mail.com>
This commit is contained in:
Moritz Duge
2026-03-02 13:19:57 +01:00
committed by Moritz Duge
parent b78438854d
commit c4189d97fb
22 changed files with 77 additions and 26 deletions
@@ -2541,7 +2541,7 @@ Ctrl+Shift+u aka U_SHIFT_MOD1 under GTK/IBUS is for unicode key input
<node oor:name="F9" oor:op="replace">
<prop oor:name="Command">
<value xml:lang="x-no-translate">L10N SHORTCUTS - NO TRANSLATE</value>
<value xml:lang="en-US">.uno:UpdateFields</value>
<value xml:lang="en-US">.uno:UpdateFields?UnlockSoftFixed:bool=1</value>
</prop>
</node>
<node oor:name="F9_MOD1" oor:op="replace">
@@ -4085,7 +4085,7 @@ Ctrl+Shift+u aka U_SHIFT_MOD1 under GTK/IBUS is for unicode key input
<node oor:name="F9" oor:op="replace">
<prop oor:name="Command">
<value xml:lang="x-no-translate">L10N SHORTCUTS - NO TRANSLATE</value>
<value xml:lang="en-US">.uno:UpdateFields</value>
<value xml:lang="en-US">.uno:UpdateFields?UnlockSoftFixed:bool=1</value>
</prop>
</node>
<node oor:name="F9_MOD1" oor:op="replace">
@@ -4882,7 +4882,7 @@ Ctrl+Shift+u aka U_SHIFT_MOD1 under GTK/IBUS is for unicode key input
<node oor:name="F9" oor:op="replace">
<prop oor:name="Command">
<value xml:lang="x-no-translate">L10N SHORTCUTS - NO TRANSLATE</value>
<value xml:lang="en-US">.uno:UpdateFields</value>
<value xml:lang="en-US">.uno:UpdateFields?UnlockSoftFixed:bool=1</value>
</prop>
</node>
<node oor:name="F9_MOD1" oor:op="replace">
@@ -5684,7 +5684,7 @@ Ctrl+Shift+u aka U_SHIFT_MOD1 under GTK/IBUS is for unicode key input
<node oor:name="F9" oor:op="replace">
<prop oor:name="Command">
<value xml:lang="x-no-translate">L10N SHORTCUTS - NO TRANSLATE</value>
<value xml:lang="en-US">.uno:UpdateFields</value>
<value xml:lang="en-US">.uno:UpdateFields?UnlockSoftFixed:bool=1</value>
</prop>
</node>
<node oor:name="F9_MOD1" oor:op="replace">
@@ -6630,7 +6630,7 @@ Ctrl+Shift+u aka U_SHIFT_MOD1 under GTK/IBUS is for unicode key input
<node oor:name="F9" oor:op="replace">
<prop oor:name="Command">
<value xml:lang="x-no-translate">L10N SHORTCUTS - NO TRANSLATE</value>
<value xml:lang="en-US">.uno:UpdateFields</value>
<value xml:lang="en-US">.uno:UpdateFields?UnlockSoftFixed:bool=1</value>
</prop>
</node>
<node oor:name="F9_MOD1" oor:op="replace">
@@ -7501,7 +7501,7 @@ Ctrl+Shift+u aka U_SHIFT_MOD1 under GTK/IBUS is for unicode key input
<node oor:name="F9" oor:op="replace">
<prop oor:name="Command">
<value xml:lang="x-no-translate">L10N SHORTCUTS - NO TRANSLATE</value>
<value xml:lang="en-US">.uno:UpdateFields</value>
<value xml:lang="en-US">.uno:UpdateFields?UnlockSoftFixed:bool=1</value>
</prop>
</node>
<node oor:name="F9_MOD1" oor:op="replace">
@@ -2120,7 +2120,7 @@
<value>1</value>
</prop>
</node>
<node oor:name=".uno:UpdateFields" oor:op="replace">
<node oor:name=".uno:UpdateFields?UnlockSoftFixed:bool=1" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">~Fields</value>
</prop>
+4
View File
@@ -97,6 +97,10 @@ enum class SwDocInfoSubType : sal_uInt16
SubTime = 0x0200,
SubDate = 0x0300,
SubFixed = 0x1000,
// SubSoftFixed: not saved to file (ephemeral / transient),
// prevents automatic updates (especially import time updates),
// unset when user explicitly triggers update (e.g. via UI button)
SubSoftFixed = 0x2000,
SubMask = 0x0f00,
Max = 0xffff // used as a flag by SwFieldDokInfPage
+1 -1
View File
@@ -6861,7 +6861,7 @@ SfxVoidItem UpdateCurIndex FN_UPDATE_CUR_TOX
]
SfxVoidItem UpdateFields FN_UPDATE_FIELDS
(SfxStringItem TypeName FN_PARAM_1, SfxStringItem NamePrefix FN_PARAM_2, SfxUnoAnyItem Fields FN_PARAM_3, SfxBoolItem NeverExpand FN_PARAM_6)
(SfxStringItem TypeName FN_PARAM_1, SfxStringItem NamePrefix FN_PARAM_2, SfxUnoAnyItem Fields FN_PARAM_3, SfxBoolItem NeverExpand FN_PARAM_6, SfxBoolItem UnlockSoftFixed FN_PARAM_7)
[
AutoUpdate = FALSE,
FastCall = TRUE,
+9
View File
@@ -1248,6 +1248,9 @@ bool SwDocInfoField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
case FIELD_PROP_BOOL1:
rAny <<= bool(m_nSubType & SwDocInfoSubType::SubFixed);
break;
case FIELD_PROP_BOOL3:
rAny <<= bool(m_nSubType & SwDocInfoSubType::SubSoftFixed);
break;
case FIELD_PROP_FORMAT:
rAny <<= static_cast<sal_Int32>(GetFormat());
@@ -1298,6 +1301,12 @@ bool SwDocInfoField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
else
m_nSubType &= ~SwDocInfoSubType::SubFixed;
break;
case FIELD_PROP_BOOL3:
if(*o3tl::doAccess<bool>(rAny))
m_nSubType |= SwDocInfoSubType::SubSoftFixed;
else
m_nSubType &= ~SwDocInfoSubType::SubSoftFixed;
break;
case FIELD_PROP_FORMAT:
{
rAny >>= nValue;
+2 -1
View File
@@ -672,7 +672,8 @@ bool SwField::IsFixed() const
break;
case SwFieldIds::DocInfo:
bRet = bool(static_cast<const SwDocInfoField*>(this)->GetSubType() & SwDocInfoSubType::SubFixed);
bRet = bool(static_cast<const SwDocInfoField*>(this)->GetSubType() &
(SwDocInfoSubType::SubFixed | SwDocInfoSubType::SubSoftFixed));
break;
default: break;
}
+2
View File
@@ -1584,6 +1584,8 @@ void SAL_CALL SwXTextField::attach(
}
if (m_pImpl->m_pProps->bBool1)
nSubType |= SwDocInfoSubType::SubFixed;
if (m_pImpl->m_pProps->bBool3)
nSubType |= SwDocInfoSubType::SubSoftFixed;
xField.reset(new SwDocInfoField(
static_cast<SwDocInfoFieldType*>(pFieldType), nSubType,
m_pImpl->m_pProps->sPar4, m_pImpl->m_pProps->nFormat));
+1
View File
@@ -1213,6 +1213,7 @@ std::span<const SfxItemPropertyMapEntry> SwUnoPropertyMapProvider::GetPropertyMa
{UNO_NAME_NAME, FIELD_PROP_PAR4, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
{UNO_NAME_CURRENT_PRESENTATION, FIELD_PROP_PAR3, cppu::UnoType<OUString>::get(), PROPERTY_NONE, 0},
{UNO_NAME_IS_FIXED, FIELD_PROP_BOOL1, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
{"IsSoftFixed", FIELD_PROP_BOOL3, cppu::UnoType<bool>::get() , PROPERTY_NONE,0},
{UNO_NAME_NUMBER_FORMAT, FIELD_PROP_FORMAT, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE, 0},
{UNO_NAME_IS_FIXED_LANGUAGE, FIELD_PROP_BOOL4, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0},
COMMON_FLDTYP_PROPERTIES
+25
View File
@@ -84,9 +84,11 @@
#include <strings.hrc>
#include <unotxdoc.hxx>
#include <doc.hxx>
#include <docufld.hxx>
#include <drawdoc.hxx>
#include <IDocumentSettingAccess.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <IDocumentUndoRedo.hxx>
#include <ThemeColorChanger.hxx>
#include <swabstdlg.hxx>
@@ -209,6 +211,20 @@ static bool lcl_UpdateContourDlg( SwWrtShell &rSh, SelectionType nSel )
return bRet;
}
/// See SubSoftFixed definition.
/// It may only be unlocked on explicit user action (e.g. "Update All" button click).
static void lcl_UnlockSoftFixed( SwWrtShell &rSh )
{
SwFieldType* pType = rSh.GetDoc()->getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocInfo);
std::vector<SwFormatField*> vFields;
pType->GatherFields(vFields);
for (auto pFormatField : vFields)
{
SwDocInfoField* pDocInfoField = static_cast<SwDocInfoField*>(pFormatField->GetField());
pDocInfoField->SetSubType(pDocInfoField->GetSubType() & ~SwDocInfoSubType::SubSoftFixed);
}
}
void SwBaseShell::ExecDelete(SfxRequest &rReq)
{
SwWrtShell &rSh = GetShell();
@@ -962,6 +978,14 @@ void SwBaseShell::Execute(SfxRequest &rReq)
break;
}
if (pArgs)
{
// FN_UPDATE_FIELDS may be triggered automatically.
// That's why SubSoftFix unlock must not happen implicitly here.
const SfxBoolItem* pUnlockSoftFixed = rReq.GetArg<SfxBoolItem>(FN_PARAM_7);
if (pUnlockSoftFixed && pUnlockSoftFixed->GetValue())
lcl_UnlockSoftFixed(rSh);
}
rSh.UpdateDocStat();
rSh.EndAllTableBoxEdit();
rSh.SwViewShell::UpdateFields(true);
@@ -1007,6 +1031,7 @@ void SwBaseShell::Execute(SfxRequest &rReq)
rSh.EndAllAction();
}
SfxDispatcher &rDis = *rTempView.GetViewFrame().GetDispatcher();
lcl_UnlockSoftFixed(rSh);
rDis.Execute( FN_UPDATE_FIELDS );
rDis.Execute( FN_UPDATE_TOX );
rDis.Execute( FN_UPDATE_CHARTS );
+7 -1
View File
@@ -225,7 +225,13 @@ void SwTextShell::ExecField(SfxRequest &rReq)
if (pField)
{
rSh.UpdateOneField(*pField);
if (pField->GetTypeId() == SwFieldTypesEnum::DocumentInfo)
{
// FN_UPDATE_SEL_FIELD is not called automatically. See SubSoftFixed definition.
SwDocInfoField* pDocInfo = static_cast<SwDocInfoField*>( pField );
pDocInfo->SetSubType(~SwDocInfoSubType::SubSoftFixed & pDocInfo->GetSubType());
}
rSh.UpdateOneField(*pField);
}
break;
}
@@ -9048,8 +9048,8 @@ void DomainMapper_Impl::SetFieldResult(OUString const& rResult)
// LO always automatically updates a DocInfo field from the File-Properties-Custom Prop
// while MS Word requires the user to manually refresh the field (with F9).
// In other words, Word lets the field to be out of sync with the controlling variable.
// Marking as FIXEDFLD solves the automatic replacement problem, but of course prevents
// Writer from making any changes, even on an F9 refresh.
// Marking as SoftFixed solves the automatic replacement problem and lets the user
// manually update the field (e.g. F9 refresh).
OUString sVariable = pContext->GetVariableValue();
if (rResult.getLength() != sVariable.getLength())
{
@@ -9057,10 +9057,13 @@ void DomainMapper_Impl::SetFieldResult(OUString const& rResult)
if (nLen >= 0)
sVariable = sVariable.copy(0, nLen);
}
bool bCustomFixedField = rResult != sVariable &&
xServiceInfo->supportsService(u"com.sun.star.text.TextField.DocInfo.Custom"_ustr);
if (rResult != sVariable &&
xServiceInfo->supportsService(u"com.sun.star.text.TextField.DocInfo.Custom"_ustr))
{
xFieldProperties->setPropertyValue(u"IsSoftFixed"_ustr, uno::Any(true));
}
if (bCustomFixedField || xServiceInfo->supportsService(
if (xServiceInfo->supportsService(
u"com.sun.star.text.TextField.DocInfo.CreateDateTime"_ustr))
{
// Creation time is const, don't try to update it.
+1 -1
View File
@@ -752,7 +752,7 @@
<menu:menuitem menu:id=".uno:UpdateAll"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Repaginate"/>
<menu:menuitem menu:id=".uno:UpdateFields"/>
<menu:menuitem menu:id=".uno:UpdateFields?UnlockSoftFixed:bool=1"/>
<menu:menuitem menu:id=".uno:UpdateAllIndexes"/>
<menu:menuitem menu:id=".uno:UpdateCurIndex"/>
<menu:menuitem menu:id=".uno:UpdateAllLinks"/>
+1 -1
View File
@@ -615,7 +615,7 @@
<menu:menuitem menu:id=".uno:UpdateAll"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Repaginate"/>
<menu:menuitem menu:id=".uno:UpdateFields"/>
<menu:menuitem menu:id=".uno:UpdateFields?UnlockSoftFixed:bool=1"/>
<menu:menuitem menu:id=".uno:UpdateAllIndexes"/>
<menu:menuitem menu:id=".uno:UpdateCurIndex"/>
<menu:menuitem menu:id=".uno:UpdateAllLinks"/>
+1 -1
View File
@@ -695,7 +695,7 @@
<menu:menuitem menu:id=".uno:UpdateAll"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Repaginate"/>
<menu:menuitem menu:id=".uno:UpdateFields"/>
<menu:menuitem menu:id=".uno:UpdateFields?UnlockSoftFixed:bool=1"/>
<menu:menuitem menu:id=".uno:UpdateAllIndexes"/>
<menu:menuitem menu:id=".uno:UpdateCurIndex"/>
<menu:menuitem menu:id=".uno:UpdateAllLinks"/>
+1 -1
View File
@@ -649,7 +649,7 @@
<menu:menuitem menu:id=".uno:UpdateAll"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Repaginate"/>
<menu:menuitem menu:id=".uno:UpdateFields"/>
<menu:menuitem menu:id=".uno:UpdateFields?UnlockSoftFixed:bool=1"/>
<menu:menuitem menu:id=".uno:UpdateAllIndexes"/>
<menu:menuitem menu:id=".uno:UpdateCurIndex"/>
<menu:menuitem menu:id=".uno:UpdateAllLinks"/>
+1 -1
View File
@@ -800,7 +800,7 @@
<menu:menuitem menu:id=".uno:Repaginate"/>
<menu:menuitem menu:id=".uno:UpdateSelectedField" menu:style="text"/>
<menu:menuitem menu:id=".uno:ConvertSelectedField" menu:style="text"/>
<menu:menuitem menu:id=".uno:UpdateFields"/>
<menu:menuitem menu:id=".uno:UpdateFields?UnlockSoftFixed:bool=1"/>
<menu:menuitem menu:id=".uno:UpdateAllIndexes"/>
<menu:menuitem menu:id=".uno:UpdateCurIndex"/>
<menu:menuitem menu:id=".uno:UpdateAllLinks"/>
+1 -1
View File
@@ -1222,7 +1222,7 @@
<property name="toolbar-style">icons</property>
<property name="show-arrow">False</property>
<child>
<object class="GtkToolButton" id=".uno:UpdateFields">
<object class="GtkToolButton" id=".uno:UpdateFields?UnlockSoftFixed:bool=1">
<property name="visible">True</property>
<property name="halign">start</property>
<property name="valign">start</property>
+1 -1
View File
@@ -1566,7 +1566,7 @@
<object class="GtkMenuItem" id="UpdateFieldsD">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="action-name">.uno:UpdateFields</property>
<property name="action-name">.uno:UpdateFields?UnlockSoftFixed:bool=1</property>
</object>
</child>
<child>
@@ -1730,7 +1730,7 @@
<object class="GtkMenuItem" id="UpdateFieldsD">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">.uno:UpdateFields</property>
<property name="action_name">.uno:UpdateFields?UnlockSoftFixed:bool=1</property>
</object>
</child>
<child>
@@ -2567,7 +2567,7 @@
<object class="GtkMenuItem" id="MenuReference-UpdateFields">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">.uno:UpdateFields</property>
<property name="action_name">.uno:UpdateFields?UnlockSoftFixed:bool=1</property>
</object>
</child>
<child>
@@ -2689,7 +2689,7 @@
<object class="GtkMenuItem" id="MenuReference-UpdateFields">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">.uno:UpdateFields</property>
<property name="action_name">.uno:UpdateFields?UnlockSoftFixed:bool=1</property>
</object>
</child>
<child>
+1 -1
View File
@@ -741,7 +741,7 @@
<menu:menuitem menu:id=".uno:UpdateAll"/>
<menu:menuseparator/>
<menu:menuitem menu:id=".uno:Repaginate"/>
<menu:menuitem menu:id=".uno:UpdateFields"/>
<menu:menuitem menu:id=".uno:UpdateFields?UnlockSoftFixed:bool=1"/>
<menu:menuitem menu:id=".uno:UpdateAllIndexes"/>
<menu:menuitem menu:id=".uno:UpdateCurIndex"/>
<menu:menuitem menu:id=".uno:UpdateAllLinks"/>