[Libreoffice-commits] core.git: sw/inc sw/source
Michael Stahl (via logerrit)
logerrit at kemper.freedesktop.org
Mon Apr 8 14:08:36 UTC 2019
sw/inc/crsrsh.hxx | 3
sw/source/core/crsr/crstrvl.cxx | 18 -
sw/source/core/doc/DocumentFieldsManager.cxx | 25 +
sw/source/core/doc/docfld.cxx | 379 +++++++++++++--------------
sw/source/core/edit/edfld.cxx | 6
sw/source/core/fields/expfld.cxx | 16 +
sw/source/core/inc/unofield.hxx | 2
sw/source/core/txtnode/atrfld.cxx | 37 ++
sw/source/core/unocore/unofield.cxx | 62 ++++
sw/source/ui/fldui/fldedt.cxx | 13
sw/source/uibase/docvw/edtwin.cxx | 1
sw/source/uibase/shells/textfld.cxx | 5
12 files changed, 369 insertions(+), 198 deletions(-)
New commits:
commit 742baabbe4d077e1ba913a7989300908f4637ac7
Author: Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Mar 19 12:29:09 2019 +0100
Commit: Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Mon Apr 8 16:08:11 2019 +0200
tdf#123968 sw: use inline editing for input fields for variables
* set these to RES_TXTATR_INPUTFIELD so they get a SwTextInputField
* only for string fields, the numeric ones break when editing
* SwCursorShell::CursorInsideInputField() must check type of the hint,
not type of the field
* DocumentFieldsManager::UpdateExpFieldsImpl() is called with one field
when it is inserted, and must expand the field into the SwTextNode then,
and it's called when the user edits inside the field, and must *not*
expand the field into the SwTextNode then
* SwDocUpdateField::MakeFieldList_() must iterate RES_TXTATR_INPUTFIELD
* SwEditWin::MouseButtonDown() must still pop up the edit dialog on
double-click
* SetFieldsDirty() should check RES_TXTATR_INPUTFIELD because SwGetExp
may depend on them
* a very odd API design: SwSetExpField::PutValue() allows to change the
"InputFlag", which is actually used by the ODF import!
This needs some alchemy to convert between SwTextField and
SwTextInputField hints, see SwXTextField::TransmuteLeadToInputField().
* etc.
Change-Id: I45c471703f102ebcb04b8567f9d76c17d5a063e7
Co-authored-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Reviewed-on: https://gerrit.libreoffice.org/69414
Tested-by: Jenkins
Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index cfe9ef023cd0..fb105b00e524 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -701,6 +701,9 @@ public:
static SwTextField* GetTextFieldAtPos(
const SwPosition* pPos,
const bool bIncludeInputFieldAtStart );
+ static SwTextField* GetTextFieldAtCursor(
+ const SwPaM* pCursor,
+ const bool bIncludeInputFieldAtStart );
static SwField* GetFieldAtCursor(
const SwPaM* pCursor,
const bool bIncludeInputFieldAtStart );
diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index bf45898fd82f..a2c13b838f4d 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -893,11 +893,11 @@ SwTextField * SwCursorShell::GetTextFieldAtPos(
return pTextField;
}
-SwField* SwCursorShell::GetFieldAtCursor(
+SwTextField* SwCursorShell::GetTextFieldAtCursor(
const SwPaM* pCursor,
const bool bIncludeInputFieldAtStart )
{
- SwField* pFieldAtCursor = nullptr;
+ SwTextField* pFieldAtCursor = nullptr;
SwTextField* pTextField = GetTextFieldAtPos( pCursor->Start(), bIncludeInputFieldAtStart );
if ( pTextField != nullptr
@@ -909,13 +909,23 @@ SwField* SwCursorShell::GetFieldAtCursor(
: 1;
if ( ( pCursor->End()->nContent.GetIndex() - pCursor->Start()->nContent.GetIndex() ) <= nTextFieldLength )
{
- pFieldAtCursor = const_cast<SwField*>(pTextField->GetFormatField().GetField());
+ pFieldAtCursor = pTextField;
}
}
return pFieldAtCursor;
}
+SwField* SwCursorShell::GetFieldAtCursor(
+ const SwPaM *const pCursor,
+ const bool bIncludeInputFieldAtStart)
+{
+ SwTextField *const pField(GetTextFieldAtCursor(pCursor, bIncludeInputFieldAtStart));
+ return pField
+ ? const_cast<SwField*>(pField->GetFormatField().GetField())
+ : nullptr;
+}
+
SwField* SwCursorShell::GetCurField( const bool bIncludeInputFieldAtStart ) const
{
SwPaM* pCursor = GetCursor();
@@ -941,7 +951,7 @@ bool SwCursorShell::CursorInsideInputField() const
{
for(SwPaM& rCursor : GetCursor()->GetRingContainer())
{
- if(dynamic_cast<const SwInputField*>(GetFieldAtCursor( &rCursor, false )))
+ if (dynamic_cast<const SwTextInputField*>(GetTextFieldAtCursor(&rCursor, false)))
return true;
}
return false;
diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx b/sw/source/core/doc/DocumentFieldsManager.cxx
index bbb8b0d03ba8..9f05f74f2785 100644
--- a/sw/source/core/doc/DocumentFieldsManager.cxx
+++ b/sw/source/core/doc/DocumentFieldsManager.cxx
@@ -55,6 +55,7 @@
#include <pam.hxx>
#include <o3tl/deleter.hxx>
#include <unotools/transliterationwrapper.hxx>
+#include <comphelper/scopeguard.hxx>
#include <com/sun/star/uno/Any.hxx>
using namespace ::com::sun::star::uno;
@@ -1265,7 +1266,26 @@ void DocumentFieldsManager::UpdateExpFieldsImpl(
default: break;
} // switch
- pFormatField->ModifyNotification( nullptr, nullptr ); // trigger formatting
+ {
+ // avoid calling ReplaceText() for input fields, it is pointless
+ // here and moves the cursor if it's inside the field ...
+ SwTextInputField *const pInputField(
+ pUpdateField == pTextField // ... except once, when the dialog
+ ? nullptr // is used to change content via UpdateOneField()
+ : dynamic_cast<SwTextInputField *>(pTextField));
+ if (pInputField)
+ {
+ pInputField->LockNotifyContentChange();
+ }
+ ::comphelper::ScopeGuard g([pInputField]()
+ {
+ if (pInputField)
+ {
+ pInputField->UnlockNotifyContentChange();
+ }
+ });
+ pFormatField->ModifyNotification(nullptr, nullptr); // trigger formatting
+ }
if (pUpdateField == pTextField) // if only this one is updated
{
@@ -1407,7 +1427,8 @@ bool DocumentFieldsManager::SetFieldsDirty( bool b, const SwNode* pChk, sal_uLon
for( size_t n = 0 ; n < nEnd; ++n )
{
const SwTextAttr* pAttr = pTNd->GetSwpHints().Get(n);
- if ( pAttr->Which() == RES_TXTATR_FIELD )
+ if ( pAttr->Which() == RES_TXTATR_FIELD
+ || pAttr->Which() == RES_TXTATR_INPUTFIELD)
{
b = true;
break;
diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx
index f9327a782996..a9c3f251849e 100644
--- a/sw/source/core/doc/docfld.cxx
+++ b/sw/source/core/doc/docfld.cxx
@@ -450,53 +450,56 @@ void SwDoc::GetAllUsedDB( std::vector<OUString>& rDBNameList,
}
}
- sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
- for (sal_uInt32 n = 0; n < nMaxItems; ++n)
+ for (sal_uInt16 const nWhichHint : { RES_TXTATR_FIELD, RES_TXTATR_INPUTFIELD })
{
- const SfxPoolItem* pItem;
- if( nullptr == (pItem = GetAttrPool().GetItem2( RES_TXTATR_FIELD, n ) ))
- continue;
+ sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2(nWhichHint);
+ for (sal_uInt32 n = 0; n < nMaxItems; ++n)
+ {
+ const SfxPoolItem *const pItem(GetAttrPool().GetItem2(nWhichHint, n));
+ if (nullptr == pItem)
+ continue;
- const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
- const SwTextField* pTextField = pFormatField->GetTextField();
- if( !pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes() )
- continue;
+ const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
+ const SwTextField* pTextField = pFormatField->GetTextField();
+ if (!pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes())
+ continue;
- const SwField* pField = pFormatField->GetField();
- switch( pField->GetTyp()->Which() )
- {
- case SwFieldIds::Database:
- AddUsedDBToList( rDBNameList,
+ const SwField* pField = pFormatField->GetField();
+ switch (pField->GetTyp()->Which())
+ {
+ case SwFieldIds::Database:
+ AddUsedDBToList( rDBNameList,
lcl_DBDataToString(static_cast<const SwDBField*>(pField)->GetDBData() ));
- break;
+ break;
- case SwFieldIds::DbSetNumber:
- case SwFieldIds::DatabaseName:
- AddUsedDBToList( rDBNameList,
+ case SwFieldIds::DbSetNumber:
+ case SwFieldIds::DatabaseName:
+ AddUsedDBToList( rDBNameList,
lcl_DBDataToString(static_cast<const SwDBNameInfField*>(pField)->GetRealDBData() ));
- break;
+ break;
- case SwFieldIds::DbNumSet:
- case SwFieldIds::DbNextSet:
- AddUsedDBToList( rDBNameList,
+ case SwFieldIds::DbNumSet:
+ case SwFieldIds::DbNextSet:
+ AddUsedDBToList( rDBNameList,
lcl_DBDataToString(static_cast<const SwDBNameInfField*>(pField)->GetRealDBData() ));
- [[fallthrough]]; // JP: is that right like that?
+ [[fallthrough]]; // JP: is that right like that?
- case SwFieldIds::HiddenText:
- case SwFieldIds::HiddenPara:
- AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames,
+ case SwFieldIds::HiddenText:
+ case SwFieldIds::HiddenPara:
+ AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames,
pField->GetPar1(), aUsedDBNames ));
- aUsedDBNames.clear();
- break;
+ aUsedDBNames.clear();
+ break;
- case SwFieldIds::SetExp:
- case SwFieldIds::GetExp:
- case SwFieldIds::Table:
- AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames,
+ case SwFieldIds::SetExp:
+ case SwFieldIds::GetExp:
+ case SwFieldIds::Table:
+ AddUsedDBToList(rDBNameList, FindUsedDBs( *pAllDBNames,
pField->GetFormula(), aUsedDBNames ));
- aUsedDBNames.clear();
- break;
- default: break;
+ aUsedDBNames.clear();
+ break;
+ default: break;
+ }
}
}
#endif
@@ -608,79 +611,82 @@ void SwDoc::ChangeDBFields( const std::vector<OUString>& rOldNames,
}
}
- sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
-
- for (sal_uInt32 n = 0; n < nMaxItems; ++n )
+ for (sal_uInt16 const nWhichHint : { RES_TXTATR_FIELD, RES_TXTATR_INPUTFIELD })
{
- const SfxPoolItem* pItem = GetAttrPool().GetItem2( RES_TXTATR_FIELD, n );
- if( !pItem )
- continue;
+ sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2(nWhichHint);
+
+ for (sal_uInt32 n = 0; n < nMaxItems; ++n)
+ {
+ const SfxPoolItem* pItem = GetAttrPool().GetItem2(nWhichHint, n);
+ if (!pItem)
+ continue;
- SwFormatField* pFormatField = const_cast<SwFormatField*>(static_cast<const SwFormatField*>(pItem));
- SwTextField* pTextField = pFormatField->GetTextField();
- if( !pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes() )
- continue;
+ SwFormatField* pFormatField = const_cast<SwFormatField*>(static_cast<const SwFormatField*>(pItem));
+ SwTextField* pTextField = pFormatField->GetTextField();
+ if (!pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes())
+ continue;
- SwField* pField = pFormatField->GetField();
- bool bExpand = false;
+ SwField* pField = pFormatField->GetField();
+ bool bExpand = false;
- switch( pField->GetTyp()->Which() )
- {
- case SwFieldIds::Database:
+ switch( pField->GetTyp()->Which() )
+ {
+ case SwFieldIds::Database:
#if HAVE_FEATURE_DBCONNECTIVITY
- if( IsNameInArray( rOldNames, lcl_DBDataToString(static_cast<SwDBField*>(pField)->GetDBData())))
- {
- SwDBFieldType* pOldTyp = static_cast<SwDBFieldType*>(pField->GetTyp());
+ if (IsNameInArray(rOldNames, lcl_DBDataToString(static_cast<SwDBField*>(pField)->GetDBData())))
+ {
+ SwDBFieldType* pOldTyp = static_cast<SwDBFieldType*>(pField->GetTyp());
- SwDBFieldType* pTyp = static_cast<SwDBFieldType*>(getIDocumentFieldsAccess().InsertFieldType(
+ SwDBFieldType* pTyp = static_cast<SwDBFieldType*>(getIDocumentFieldsAccess().InsertFieldType(
SwDBFieldType(this, pOldTyp->GetColumnName(), aNewDBData)));
- pFormatField->RegisterToFieldType( *pTyp );
- pField->ChgTyp(pTyp);
+ pFormatField->RegisterToFieldType( *pTyp );
+ pField->ChgTyp(pTyp);
- static_cast<SwDBField*>(pField)->ClearInitialized();
- static_cast<SwDBField*>(pField)->InitContent();
+ static_cast<SwDBField*>(pField)->ClearInitialized();
+ static_cast<SwDBField*>(pField)->InitContent();
- bExpand = true;
- }
+ bExpand = true;
+ }
#endif
- break;
+ break;
- case SwFieldIds::DbSetNumber:
- case SwFieldIds::DatabaseName:
- if( IsNameInArray( rOldNames,
+ case SwFieldIds::DbSetNumber:
+ case SwFieldIds::DatabaseName:
+ if (IsNameInArray(rOldNames,
lcl_DBDataToString(static_cast<SwDBNameInfField*>(pField)->GetRealDBData())))
- {
- static_cast<SwDBNameInfField*>(pField)->SetDBData(aNewDBData);
- bExpand = true;
- }
- break;
+ {
+ static_cast<SwDBNameInfField*>(pField)->SetDBData(aNewDBData);
+ bExpand = true;
+ }
+ break;
- case SwFieldIds::DbNumSet:
- case SwFieldIds::DbNextSet:
- if( IsNameInArray( rOldNames,
+ case SwFieldIds::DbNumSet:
+ case SwFieldIds::DbNextSet:
+ if (IsNameInArray(rOldNames,
lcl_DBDataToString(static_cast<SwDBNameInfField*>(pField)->GetRealDBData())))
- {
- static_cast<SwDBNameInfField*>(pField)->SetDBData(aNewDBData);
- }
- [[fallthrough]];
- case SwFieldIds::HiddenText:
- case SwFieldIds::HiddenPara:
- pField->SetPar1( ReplaceUsedDBs(rOldNames, rNewName, pField->GetPar1()) );
- bExpand = true;
- break;
+ {
+ static_cast<SwDBNameInfField*>(pField)->SetDBData(aNewDBData);
+ }
+ [[fallthrough]];
+ case SwFieldIds::HiddenText:
+ case SwFieldIds::HiddenPara:
+ pField->SetPar1( ReplaceUsedDBs(rOldNames, rNewName, pField->GetPar1()) );
+ bExpand = true;
+ break;
- case SwFieldIds::SetExp:
- case SwFieldIds::GetExp:
- case SwFieldIds::Table:
- pField->SetPar2( ReplaceUsedDBs(rOldNames, rNewName, pField->GetFormula()) );
- bExpand = true;
- break;
- default: break;
- }
+ case SwFieldIds::SetExp:
+ case SwFieldIds::GetExp:
+ case SwFieldIds::Table:
+ pField->SetPar2( ReplaceUsedDBs(rOldNames, rNewName, pField->GetFormula()) );
+ bExpand = true;
+ break;
+ default: break;
+ }
- if (bExpand)
- pTextField->ExpandTextField( true );
+ if (bExpand)
+ pTextField->ExpandTextField( true );
+ }
}
getIDocumentState().SetModified();
#endif
@@ -891,113 +897,118 @@ void SwDocUpdateField::MakeFieldList_( SwDoc& rDoc, int eGetMode )
bool bIsDBManager = nullptr != rDoc.GetDBManager();
#endif
- const sal_uInt32 nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
- for( sal_uInt32 n = 0; n < nMaxItems; ++n )
+ for (sal_uInt16 const nWhichHint : { RES_TXTATR_FIELD, RES_TXTATR_INPUTFIELD })
{
- const SfxPoolItem* pItem = rDoc.GetAttrPool().GetItem2( RES_TXTATR_FIELD, n );
- if( !pItem )
- continue;
-
- const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
- const SwTextField* pTextField = pFormatField->GetTextField();
- if( !pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes() )
- continue;
-
- OUString sFormula;
- const SwField* pField = pFormatField->GetField();
- const SwFieldIds nWhich = pField->GetTyp()->Which();
- switch( nWhich )
+ const sal_uInt32 nMaxItems = rDoc.GetAttrPool().GetItemCount2(nWhichHint);
+ for (sal_uInt32 n = 0; n < nMaxItems; ++n)
{
- case SwFieldIds::DbSetNumber:
- case SwFieldIds::GetExp:
- if( GETFLD_ALL == eGetMode )
- sFormula = sTrue;
- break;
+ const SfxPoolItem* pItem = rDoc.GetAttrPool().GetItem2(nWhichHint, n);
+ if (!pItem)
+ continue;
+
+ const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
+ const SwTextField* pTextField = pFormatField->GetTextField();
+ if (!pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes())
+ continue;
+
+ OUString sFormula;
+ const SwField* pField = pFormatField->GetField();
+ const SwFieldIds nWhich = pField->GetTyp()->Which();
+ switch (nWhich)
+ {
+ case SwFieldIds::DbSetNumber:
+ case SwFieldIds::GetExp:
+ if (GETFLD_ALL == eGetMode)
+ sFormula = sTrue;
+ break;
- case SwFieldIds::Database:
- if( GETFLD_EXPAND & eGetMode )
- sFormula = sTrue;
- break;
+ case SwFieldIds::Database:
+ if (GETFLD_EXPAND & eGetMode)
+ sFormula = sTrue;
+ break;
- case SwFieldIds::SetExp:
- if ( (eGetMode != GETFLD_EXPAND) ||
- (nsSwGetSetExpType::GSE_STRING & pField->GetSubType()) )
- {
- sFormula = sTrue;
- }
- break;
+ case SwFieldIds::SetExp:
+ if ((eGetMode != GETFLD_EXPAND) ||
+ (nsSwGetSetExpType::GSE_STRING & pField->GetSubType()))
+ {
+ sFormula = sTrue;
+ }
+ break;
- case SwFieldIds::HiddenPara:
- if( GETFLD_ALL == eGetMode )
- {
- sFormula = pField->GetPar1();
- if (sFormula.isEmpty() || sFormula==sFalse)
- const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField))->SetHidden( false );
- else if (sFormula==sTrue)
- const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField))->SetHidden( true );
- else
- break;
-
- sFormula.clear();
- // trigger formatting
- const_cast<SwFormatField*>(pFormatField)->ModifyNotification( nullptr, nullptr );
- }
- break;
+ case SwFieldIds::HiddenPara:
+ if (GETFLD_ALL == eGetMode)
+ {
+ sFormula = pField->GetPar1();
+ if (sFormula.isEmpty() || sFormula==sFalse)
+ const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField))->SetHidden( false );
+ else if (sFormula==sTrue)
+ const_cast<SwHiddenParaField*>(static_cast<const SwHiddenParaField*>(pField))->SetHidden( true );
+ else
+ break;
+
+ sFormula.clear();
+ // trigger formatting
+ const_cast<SwFormatField*>(pFormatField)->ModifyNotification( nullptr, nullptr );
+ }
+ break;
- case SwFieldIds::HiddenText:
- if( GETFLD_ALL == eGetMode )
- {
- sFormula = pField->GetPar1();
- if (sFormula.isEmpty() || sFormula==sFalse)
- const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField))->SetValue( true );
- else if (sFormula==sTrue)
- const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField))->SetValue( false );
- else
- break;
-
- sFormula.clear();
-
- // evaluate field
- const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField))->Evaluate(&rDoc);
- // trigger formatting
- const_cast<SwFormatField*>(pFormatField)->ModifyNotification( nullptr, nullptr );
- }
- break;
+ case SwFieldIds::HiddenText:
+ if (GETFLD_ALL == eGetMode)
+ {
+ sFormula = pField->GetPar1();
+ if (sFormula.isEmpty() || sFormula==sFalse)
+ const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField))->SetValue( true );
+ else if (sFormula==sTrue)
+ const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField))->SetValue( false );
+ else
+ break;
+
+ sFormula.clear();
+
+ // evaluate field
+ const_cast<SwHiddenTextField*>(static_cast<const SwHiddenTextField*>(pField))->Evaluate(&rDoc);
+ // trigger formatting
+ const_cast<SwFormatField*>(pFormatField)->ModifyNotification( nullptr, nullptr );
+ }
+ break;
#if HAVE_FEATURE_DBCONNECTIVITY
- case SwFieldIds::DbNumSet:
- {
- SwDBData aDBData(const_cast<SwDBNumSetField*>(static_cast<const SwDBNumSetField*>(pField))->GetDBData(&rDoc));
-
- if (
- (bIsDBManager && rDoc.GetDBManager()->OpenDataSource(aDBData.sDataSource, aDBData.sCommand)) &&
- (GETFLD_ALL == eGetMode || (GETFLD_CALC & eGetMode && static_cast<const SwDBNumSetField*>(pField)->IsCondValid()))
- )
+ case SwFieldIds::DbNumSet:
{
- sFormula = pField->GetPar1();
- }
- }
- break;
- case SwFieldIds::DbNextSet:
- {
- SwDBData aDBData(const_cast<SwDBNextSetField*>(static_cast<const SwDBNextSetField*>(pField))->GetDBData(&rDoc));
+ SwDBData aDBData(const_cast<SwDBNumSetField*>(static_cast<const SwDBNumSetField*>(pField))->GetDBData(&rDoc));
- if (
- (bIsDBManager && rDoc.GetDBManager()->OpenDataSource(aDBData.sDataSource, aDBData.sCommand)) &&
- (GETFLD_ALL == eGetMode || (GETFLD_CALC & eGetMode && static_cast<const SwDBNextSetField*>(pField)->IsCondValid()))
- )
+ if ( (bIsDBManager && rDoc.GetDBManager()->OpenDataSource(aDBData.sDataSource, aDBData.sCommand))
+ && (GETFLD_ALL == eGetMode
+ || (GETFLD_CALC & eGetMode
+ && static_cast<const SwDBNumSetField*>(pField)->IsCondValid()))
+ )
+ {
+ sFormula = pField->GetPar1();
+ }
+ }
+ break;
+ case SwFieldIds::DbNextSet:
{
- sFormula = pField->GetPar1();
+ SwDBData aDBData(const_cast<SwDBNextSetField*>(static_cast<const SwDBNextSetField*>(pField))->GetDBData(&rDoc));
+
+ if ( (bIsDBManager && rDoc.GetDBManager()->OpenDataSource(aDBData.sDataSource, aDBData.sCommand))
+ && (GETFLD_ALL == eGetMode
+ || (GETFLD_CALC & eGetMode
+ && static_cast<const SwDBNextSetField*>(pField)->IsCondValid()))
+ )
+ {
+ sFormula = pField->GetPar1();
+ }
}
- }
- break;
+ break;
#endif
- default: break;
- }
+ default: break;
+ }
- if (!sFormula.isEmpty())
- {
- GetBodyNode( *pTextField, nWhich );
+ if (!sFormula.isEmpty())
+ {
+ GetBodyNode( *pTextField, nWhich );
+ }
}
}
m_nFieldListGetMode = eGetMode;
diff --git a/sw/source/core/edit/edfld.cxx b/sw/source/core/edit/edfld.cxx
index 787eb13c02a6..8b744bfd33b6 100644
--- a/sw/source/core/edit/edfld.cxx
+++ b/sw/source/core/edit/edfld.cxx
@@ -173,7 +173,11 @@ static SwTextField* lcl_FindInputField( SwDoc* pDoc, SwField& rField )
{
// Search field via its address. For input fields this needs to be done in protected fields.
SwTextField* pTField = nullptr;
- if( SwFieldIds::Input == rField.Which() )
+ if (SwFieldIds::Input == rField.Which()
+ || (SwFieldIds::SetExp == rField.Which()
+ && static_cast<SwSetExpField&>(rField).GetInputFlag()
+ && (static_cast<SwSetExpFieldType*>(rField.GetTyp())->GetType()
+ & nsSwGetSetExpType::GSE_STRING)))
{
const sal_uInt32 nMaxItems =
pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INPUTFIELD );
diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx
index b12ae69cdfc7..7bcfd443c027 100644
--- a/sw/source/core/fields/expfld.cxx
+++ b/sw/source/core/fields/expfld.cxx
@@ -1128,7 +1128,21 @@ bool SwSetExpField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
mnSubType &= (~nsSwExtendedSubType::SUB_CMD);
break;
case FIELD_PROP_BOOL1:
- SetInputFlag(*o3tl::doAccess<bool>(rAny));
+ {
+ bool newInput(*o3tl::doAccess<bool>(rAny));
+ if (newInput != GetInputFlag())
+ {
+ if (static_cast<SwSetExpFieldType*>(GetTyp())->GetType()
+ & nsSwGetSetExpType::GSE_STRING)
+ {
+ SwXTextField::TransmuteLeadToInputField(*this);
+ }
+ else
+ {
+ SetInputFlag(newInput);
+ }
+ }
+ }
break;
case FIELD_PROP_PAR4:
{
diff --git a/sw/source/core/inc/unofield.hxx b/sw/source/core/inc/unofield.hxx
index b54480c97c3b..723b954e0dad 100644
--- a/sw/source/core/inc/unofield.hxx
+++ b/sw/source/core/inc/unofield.hxx
@@ -139,6 +139,8 @@ private:
public:
SwServiceType GetServiceId() const;
+ static void TransmuteLeadToInputField(SwSetExpField & rField);
+
/// @return an SwXTextField, either an already existing one or a new one
static css::uno::Reference< css::text::XTextField>
CreateXTextField(SwDoc * pDoc, SwFormatField const* pFormat,
diff --git a/sw/source/core/txtnode/atrfld.cxx b/sw/source/core/txtnode/atrfld.cxx
index 87d6ca5a4ae2..66ccc2670f73 100644
--- a/sw/source/core/txtnode/atrfld.cxx
+++ b/sw/source/core/txtnode/atrfld.cxx
@@ -69,7 +69,16 @@ SwFormatField::SwFormatField( const SwField &rField )
else if (mpField->GetTyp()->Which() == SwFieldIds::SetExp)
{
// see SwWrtShell::StartInputFieldDlg
- static_cast<SwSetExpField *>(mpField.get())->SetFormatField(*this);
+ SwSetExpField *const pSetField(static_cast<SwSetExpField *>(mpField.get()));
+ if (pSetField->GetInputFlag()
+ // only for string fields for now - inline editing of number fields
+ // tends to produce error messages...
+ && (static_cast<SwSetExpFieldType*>(pSetField->GetTyp())->GetType()
+ & nsSwGetSetExpType::GSE_STRING))
+ {
+ SetWhich( RES_TXTATR_INPUTFIELD );
+ }
+ pSetField->SetFormatField(*this);
}
else if ( mpField->GetTyp()->Which() == SwFieldIds::Postit )
{
@@ -103,8 +112,15 @@ SwFormatField::SwFormatField( const SwFormatField& rAttr )
}
else if (mpField->GetTyp()->Which() == SwFieldIds::SetExp)
{
+ SwSetExpField *const pSetField(static_cast<SwSetExpField *>(mpField.get()));
+ if (pSetField->GetInputFlag()
+ && (static_cast<SwSetExpFieldType*>(pSetField->GetTyp())->GetType()
+ & nsSwGetSetExpType::GSE_STRING))
+ {
+ SetWhich( RES_TXTATR_INPUTFIELD );
+ }
// see SwWrtShell::StartInputFieldDlg
- static_cast<SwSetExpField *>(mpField.get())->SetFormatField(*this);
+ pSetField->SetFormatField(*this);
}
else if ( mpField->GetTyp()->Which() == SwFieldIds::Postit )
{
@@ -543,6 +559,7 @@ SwTextInputField::~SwTextInputField()
void SwTextInputField::LockNotifyContentChange()
{
+ assert(!m_bLockNotifyContentChange); // not nestable
m_bLockNotifyContentChange = true;
}
@@ -582,9 +599,19 @@ void SwTextInputField::UpdateFieldContent()
const sal_Int32 nLen = static_cast<sal_Int32>(std::max<sal_Int32>( 0, ( (*End()) - 1 - nIdx ) ));
const OUString aNewFieldContent = GetTextNode().GetExpandText(nullptr, nIdx, nLen);
- auto pInputField = dynamic_cast<const SwInputField*>(GetFormatField().GetField());
- assert(pInputField);
- const_cast<SwInputField*>(pInputField)->applyFieldContent( aNewFieldContent );
+ const SwField* pField = GetFormatField().GetField();
+ const SwInputField* pInputField = dynamic_cast<const SwInputField*>(pField);
+ if (pInputField)
+ const_cast<SwInputField*>(pInputField)->applyFieldContent( aNewFieldContent );
+
+ const SwSetExpField* pExpField = dynamic_cast<const SwSetExpField*>(pField);
+ if (pExpField)
+ {
+ assert(pExpField->GetInputFlag());
+ const_cast<SwSetExpField*>(pExpField)->SetPar2(aNewFieldContent);
+ }
+ assert(pInputField || pExpField);
+
// trigger update of fields for scenarios in which the Input Field's content is part of e.g. a table formula
GetTextNode().GetDoc()->getIDocumentFieldsAccess().GetUpdateFields().SetFieldsDirty(true);
}
diff --git a/sw/source/core/unocore/unofield.cxx b/sw/source/core/unocore/unofield.cxx
index 5bf539324d0b..4bb314c5a4bd 100644
--- a/sw/source/core/unocore/unofield.cxx
+++ b/sw/source/core/unocore/unofield.cxx
@@ -1269,6 +1269,66 @@ SwServiceType SwXTextField::GetServiceId() const
return m_pImpl->m_nServiceId;
}
+/** Convert between SwSetExpField with InputFlag false and InputFlag true.
+ Unfortunately the InputFlag is exposed in the API as "Input" property
+ and is mutable; in the UI and in ODF these are 2 different types of
+ fields, so the API design is very questionable.
+ In order to keep the mutable property, the whole thing has to be
+ reconstructed from scratch, to replace the SwTextField hint with
+ SwTextInputField or vice versa.
+ The SwFormatField will be replaced - it must be, because the Which
+ changes - but the SwXTextField *must not* be disposed in the operation,
+ it has to be disconnected first and at the end connected to the
+ new instance!
+ */
+void SwXTextField::TransmuteLeadToInputField(SwSetExpField & rField)
+{
+ assert(rField.GetFormatField()->Which() == (rField.GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD));
+ uno::Reference<text::XTextField> const xField(
+ rField.GetFormatField()->GetXTextField());
+ SwXTextField *const pXField = xField.is()
+ ? reinterpret_cast<SwXTextField*>(
+ sal::static_int_cast<sal_IntPtr>(
+ uno::Reference<lang::XUnoTunnel>(xField, uno::UNO_QUERY_THROW)
+ ->getSomething(getUnoTunnelId())))
+ : nullptr;
+ if (xField.is())
+ {
+ assert(pXField->m_pImpl->m_pFormatField == rField.GetFormatField());
+ rField.GetFormatField()->Remove(pXField->m_pImpl.get());
+ pXField->m_pImpl->m_pFormatField = nullptr;
+ }
+ SwTextField *const pOldAttr(rField.GetFormatField()->GetTextField());
+ SwSetExpField tempField(rField);
+ tempField.SetInputFlag(!rField.GetInputFlag());
+ SwFormatField tempFormat(tempField);
+ assert(tempFormat.GetField() != &rField);
+ assert(tempFormat.GetField() != &tempField); // this copies it again?
+ assert(tempFormat.Which() == (static_cast<SwSetExpField const*>(tempFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD));
+ SwTextNode & rNode(pOldAttr->GetTextNode());
+ std::shared_ptr<SwPaM> pPamForTextField;
+ IDocumentContentOperations & rIDCO(rNode.GetDoc()->getIDocumentContentOperations());
+ SwTextField::GetPamForTextField(*pOldAttr, pPamForTextField);
+ assert(pPamForTextField);
+ sal_Int32 const nStart(pPamForTextField->Start()->nContent.GetIndex());
+ rIDCO.DeleteAndJoin(*pPamForTextField);
+ // ATTENTION: rField is dead now! hope nobody accesses it...
+ bool bSuccess = rIDCO.InsertPoolItem(*pPamForTextField, tempFormat);
+ assert(bSuccess);
+ (void) bSuccess;
+ SwTextField const* pNewAttr(rNode.GetFieldTextAttrAt(nStart, true));
+ assert(pNewAttr);
+ SwFormatField const& rNewFormat(pNewAttr->GetFormatField());
+ assert(rNewFormat.Which() == (static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag() ? RES_TXTATR_INPUTFIELD : RES_TXTATR_FIELD));
+ assert(static_cast<SwSetExpField const*>(rNewFormat.GetField())->GetInputFlag() == (dynamic_cast<SwTextInputField const*>(pNewAttr) != nullptr));
+ if (xField.is())
+ {
+ pXField->m_pImpl->m_pFormatField = &rNewFormat;
+ const_cast<SwFormatField&>(rNewFormat).Add(pXField->m_pImpl.get());
+ const_cast<SwFormatField&>(rNewFormat).SetXTextField(xField);
+ }
+}
+
void SAL_CALL SwXTextField::attachTextFieldMaster(
const uno::Reference< beans::XPropertySet > & xFieldMaster)
{
@@ -1965,6 +2025,8 @@ void SAL_CALL SwXTextField::attach(
assert(m_pImpl->m_pFormatField);
m_pImpl->m_pDoc = pDoc;
const_cast<SwFormatField *>(m_pImpl->m_pFormatField)->Add(m_pImpl.get());
+ const_cast<SwFormatField *>(m_pImpl->m_pFormatField)->SetXTextField(this);
+ m_pImpl->m_wThis = *this;
m_pImpl->m_bIsDescriptor = false;
m_pImpl->ClearFieldType();
m_pImpl->m_pProps.reset();
diff --git a/sw/source/ui/fldui/fldedt.cxx b/sw/source/ui/fldui/fldedt.cxx
index f94aef325372..d4108ef3b7f0 100644
--- a/sw/source/ui/fldui/fldedt.cxx
+++ b/sw/source/ui/fldui/fldedt.cxx
@@ -57,6 +57,19 @@ void SwFieldEditDlg::EnsureSelection(SwField *pCurField, SwFieldMgr &rMgr)
{
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.
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 59b0114e5707..4d932c8de1ae 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -3337,6 +3337,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt)
break;
case TYP_INPUTFLD:
case TYP_DROPDOWN:
+ case TYP_SETINPFLD:
pVFrame->GetBindings().Execute(FN_UPDATE_INPUTFIELDS);
break;
default:
diff --git a/sw/source/uibase/shells/textfld.cxx b/sw/source/uibase/shells/textfld.cxx
index 9f809738f12e..ec6d8b5f6449 100644
--- a/sw/source/uibase/shells/textfld.cxx
+++ b/sw/source/uibase/shells/textfld.cxx
@@ -27,6 +27,7 @@
#include <editeng/outliner.hxx>
#include <sfx2/lnkbase.hxx>
#include <fmtfld.hxx>
+#include <txtfld.hxx>
#include <svl/itempool.hxx>
#include <unotools/useroptions.hxx>
#include <svl/whiter.hxx>
@@ -186,7 +187,9 @@ void SwTextShell::ExecField(SfxRequest &rReq)
bAddSetExpressionFields ) )
{
rSh.ClearMark();
- if ( dynamic_cast<SwInputField*>(rSh.GetCurField( true )) != nullptr )
+ if (!rSh.IsMultiSelection()
+ && (nullptr != dynamic_cast<const SwTextInputField*>(
+ SwCursorShell::GetTextFieldAtCursor(rSh.GetCursor(), true))))
{
rSh.SttSelect();
rSh.SelectText(
More information about the Libreoffice-commits
mailing list