summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorTamás Zolnai <tamas.zolnai@collabora.com>2019-03-09 14:44:50 +0100
committerAndras Timar <andras.timar@collabora.com>2019-03-18 10:16:12 +0100
commitfbb148af3f175ad21bc5bea61a611c52e83f9eed (patch)
treedeb12dc14329760c10ea7aadd06f2a8be73caa71 /sw
parentdf3a97ac7c430d50aba92d1a684d3e06005da5fd (diff)
MSForms: Introduce a new IFieldMark for drop-down form field
* It was weird anyway that a drop-down form field was represented as an CheckboxFieldmark. * It will be useful for later commits, to have a separate field type for drop-down field. * Needed to fix-up the API a bit because it was designed to specify the field type after initialization. I solved it in a way to not break the API behavior. Hopefully it's not very slow. Reviewed-on: https://gerrit.libreoffice.org/68960 Tested-by: Jenkins Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com> (cherry picked from commit f66a83c95c21b4311918a64bb85016857b49f4d4) Change-Id: I3103e6b1c36289b27b62ab9ca7dfeebc14901c8a Reviewed-on: https://gerrit.libreoffice.org/69194 Reviewed-by: Andras Timar <andras.timar@collabora.com> Tested-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/IDocumentMarkAccess.hxx2
-rw-r--r--sw/source/core/crsr/bookmrk.cxx33
-rw-r--r--sw/source/core/doc/docbm.cxx50
-rw-r--r--sw/source/core/inc/MarkManager.hxx1
-rw-r--r--sw/source/core/inc/bookmrk.hxx12
-rw-r--r--sw/source/core/inc/unobookmark.hxx2
-rw-r--r--sw/source/core/text/itrform2.cxx4
-rw-r--r--sw/source/core/unocore/unobkm.cxx23
8 files changed, 119 insertions, 8 deletions
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index 823326e2b8ac..cbd523c012b1 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -47,6 +47,7 @@ class IDocumentMarkAccess
ANNOTATIONMARK,
TEXT_FIELDMARK,
CHECKBOX_FIELDMARK,
+ DROPDOWN_FIELDMARK,
NAVIGATOR_REMINDER
};
@@ -255,6 +256,7 @@ class IDocumentMarkAccess
virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const=0;
virtual void deleteFieldmarkAt(const SwPosition& rPos) = 0;
+ virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) = 0;
// Annotation Marks
virtual const_iterator_t getAnnotationMarksBegin() const = 0;
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 630bfe9c11d1..c80fb490aa1b 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -478,6 +478,39 @@ namespace sw { namespace mark
pResult->second >>= bResult;
return bResult;
}
+
+ DropDownFieldmark::DropDownFieldmark(const SwPaM& rPaM)
+ : Fieldmark(rPaM)
+ {
+ }
+
+ DropDownFieldmark::~DropDownFieldmark()
+ {
+ }
+
+ void DropDownFieldmark::InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode const eMode)
+ {
+ if (eMode == sw::mark::InsertMode::New)
+ {
+ lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+
+ // For some reason the end mark is moved from 1 by the Insert:
+ // we don't want this for checkboxes
+ SwPosition aNewEndPos = GetMarkEnd();
+ aNewEndPos.nContent--;
+ SetMarkEndPos( aNewEndPos );
+ }
+ else
+ {
+ lcl_AssertFieldMarksSet(this, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+ }
+ }
+
+ void DropDownFieldmark::ReleaseDoc(SwDoc* const pDoc)
+ {
+ lcl_RemoveFieldMarks(this, pDoc,
+ CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+ }
}}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index ccc3d5382ffb..727655250a2e 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -338,6 +338,8 @@ IDocumentMarkAccess::MarkType IDocumentMarkAccess::GetType(const IMark& rBkmk)
return MarkType::TEXT_FIELDMARK;
else if(*pMarkTypeInfo == typeid(CheckboxFieldmark))
return MarkType::CHECKBOX_FIELDMARK;
+ else if(*pMarkTypeInfo == typeid(DropDownFieldmark))
+ return MarkType::DROPDOWN_FIELDMARK;
else if(*pMarkTypeInfo == typeid(NavigatorReminder))
return MarkType::NAVIGATOR_REMINDER;
else
@@ -414,6 +416,9 @@ namespace sw { namespace mark
case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
pMark = std::shared_ptr<IMark>(new CheckboxFieldmark(rPaM));
break;
+ case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
+ pMark = std::shared_ptr<IMark>(new DropDownFieldmark(rPaM));
+ break;
case IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER:
pMark = std::shared_ptr<IMark>(new NavigatorReminder(rPaM));
break;
@@ -463,6 +468,7 @@ namespace sw { namespace mark
break;
case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK:
case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
+ case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
lcl_InsertMarkSorted(m_vFieldmarks, pMark);
break;
case IDocumentMarkAccess::MarkType::ANNOTATIONMARK:
@@ -524,9 +530,20 @@ namespace sw { namespace mark
bool bEnableSetModified = m_pDoc->getIDocumentState().IsEnableSetModified();
m_pDoc->getIDocumentState().SetEnableSetModified(false);
- sw::mark::IMark* pMark = makeMark( rPaM, rName,
- IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK,
- sw::mark::InsertMode::New);
+ sw::mark::IMark* pMark = nullptr;
+ if(rType == ODF_FORMCHECKBOX)
+ {
+ pMark = makeMark( rPaM, rName,
+ IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK,
+ sw::mark::InsertMode::New);
+ }
+ else if(rType == ODF_FORMDROPDOWN)
+ {
+ pMark = makeMark( rPaM, rName,
+ IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK,
+ sw::mark::InsertMode::New);
+ }
+
sw::mark::IFieldmark* pFieldMark = dynamic_cast<sw::mark::IFieldmark*>( pMark );
if (pFieldMark)
pFieldMark->SetFieldname( rType );
@@ -939,6 +956,7 @@ namespace sw { namespace mark
case IDocumentMarkAccess::MarkType::TEXT_FIELDMARK:
case IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK:
+ case IDocumentMarkAccess::MarkType::DROPDOWN_FIELDMARK:
{
IDocumentMarkAccess::iterator_t ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark);
if ( ppFieldmark != m_vFieldmarks.end() )
@@ -1084,6 +1102,32 @@ namespace sw { namespace mark
deleteMark(lcl_FindMark(m_vAllMarks, *pFieldmark));
}
+ ::sw::mark::IFieldmark* MarkManager::changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType)
+ {
+ bool bActualChange = false;
+ if(rNewType == ODF_FORMDROPDOWN)
+ {
+ if (dynamic_cast<::sw::mark::CheckboxFieldmark*>(pFieldmark))
+ bActualChange = true;
+ }
+ else if(rNewType == ODF_FORMCHECKBOX)
+ {
+ if (dynamic_cast<::sw::mark::DropDownFieldmark*>(pFieldmark))
+ bActualChange = true;
+ }
+
+ if (!bActualChange)
+ return nullptr;
+
+ // Store attributes needed to create the new fieldmark
+ OUString sName = pFieldmark->GetName();
+ SwPaM aPaM(pFieldmark->GetMarkPos());
+
+ // Remove the old fieldmark and create a new one with the new type
+ deleteFieldmarkAt(*aPaM.GetPoint());
+ return makeNoTextFieldBookmark(aPaM, sName, rNewType);
+ }
+
IFieldmark* MarkManager::getDropDownFor(const SwPosition& rPos) const
{
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index 7a3612bb6131..4544bae57b85 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -86,6 +86,7 @@ namespace sw {
virtual std::vector< ::sw::mark::IFieldmark* > getDropDownsFor(const SwPaM &rPaM) const override;
virtual void deleteFieldmarkAt(const SwPosition& rPos) override;
+ virtual ::sw::mark::IFieldmark* changeNonTextFieldmarkType(::sw::mark::IFieldmark* pFieldmark, const OUString& rNewType) override;
void dumpAsXml(struct _xmlTextWriter* pWriter) const;
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 6daa37d1d7e4..59089c846d43 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -234,6 +234,7 @@ namespace sw {
virtual void ReleaseDoc(SwDoc* const pDoc) override;
};
+ /// Fieldmark representing a checkbox form field.
class CheckboxFieldmark
: virtual public ICheckboxFieldmark
, public Fieldmark
@@ -245,6 +246,17 @@ namespace sw {
bool IsChecked() const override;
void SetChecked(bool checked) override;
};
+
+ /// Fieldmark representing a drop-down form field.
+ class DropDownFieldmark
+ : public Fieldmark
+ {
+ public:
+ DropDownFieldmark(const SwPaM& rPaM);
+ virtual ~DropDownFieldmark() override;
+ virtual void InitDoc(SwDoc* const io_pDoc, sw::mark::InsertMode eMode) override;
+ virtual void ReleaseDoc(SwDoc* const pDoc) override;
+ };
}
}
#endif
diff --git a/sw/source/core/inc/unobookmark.hxx b/sw/source/core/inc/unobookmark.hxx
index 7ec058e086bd..569cf8b8d5b3 100644
--- a/sw/source/core/inc/unobookmark.hxx
+++ b/sw/source/core/inc/unobookmark.hxx
@@ -67,6 +67,8 @@ protected:
const ::sw::mark::IMark* GetBookmark() const;
+ IDocumentMarkAccess* GetIDocumentMarkAccess();
+
void registerInMark( SwXBookmark& rXMark, ::sw::mark::IMark* const pMarkBase );
virtual ~SwXBookmark() override;
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 93f4aa72df4b..d0ddd033aef7 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -915,10 +915,6 @@ SwTextPortion *SwTextFormatter::WhichTextPor( SwTextFormatInfo &rInf ) const
{
pPor = new SwFieldMarkPortion();
}
- else
- {
- assert( false ); // unknown type...
- }
}
}
if( !pPor )
diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx
index d3212fbbe245..7b2d93467316 100644
--- a/sw/source/core/unocore/unobkm.cxx
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -124,6 +124,11 @@ const ::sw::mark::IMark* SwXBookmark::GetBookmark() const
return m_pImpl->m_pRegisteredBookmark;
}
+IDocumentMarkAccess* SwXBookmark::GetIDocumentMarkAccess()
+{
+ return m_pImpl->m_pDoc->getIDocumentMarkAccess();
+}
+
SwXBookmark::SwXBookmark(SwDoc *const pDoc)
: m_pImpl( new SwXBookmark::Impl(pDoc) )
{
@@ -551,7 +556,21 @@ void SwXFieldmark::setFieldType(const OUString & fieldType)
dynamic_cast<const IFieldmark*>(GetBookmark()));
if(!pBkm)
throw uno::RuntimeException();
- pBkm->SetFieldname(fieldType);
+ if(fieldType != getFieldType())
+ {
+ if(fieldType == ODF_FORMDROPDOWN || fieldType == ODF_FORMCHECKBOX)
+ {
+ ::sw::mark::IFieldmark* pNewFieldmark = GetIDocumentMarkAccess()->changeNonTextFieldmarkType(pBkm, fieldType);
+ if (pNewFieldmark)
+ {
+ registerInMark(*this, pNewFieldmark);
+ return;
+ }
+ }
+
+ // We did not generate a new fieldmark, so set the type ID
+ pBkm->SetFieldname(fieldType);
+ }
}
uno::Reference<container::XNameContainer> SwXFieldmark::getParameters()
@@ -585,6 +604,8 @@ SwXFieldmark::CreateXFieldmark(SwDoc & rDoc, ::sw::mark::IMark *const pMark,
pXBkmk = new SwXFieldmark(false, &rDoc);
else if (dynamic_cast< ::sw::mark::CheckboxFieldmark* >(pMark))
pXBkmk = new SwXFieldmark(true, &rDoc);
+ else if (dynamic_cast< ::sw::mark::DropDownFieldmark* >(pMark))
+ pXBkmk = new SwXFieldmark(true, &rDoc);
else
pXBkmk = new SwXFieldmark(isReplacementObject, &rDoc);