summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorJustin Luth <jluth@mail.com>2022-08-04 19:52:23 -0400
committerJustin Luth <jluth@mail.com>2023-05-16 01:01:27 +0200
commit25fed4ae027b9680597ea498c25acc3f854db4bf (patch)
tree4b8a94073a0c6896ec875a6839ffdb1b04c55cce /sc
parent67d4fe32713070be5688eef2da9377a91e2f6b81 (diff)
tdf#79542 xls: applyGroupBox to radiobutton groups
A group box control links radiobuttons together, and so does a sheet. No matching unit tests were found. make CppunitTest_sc_subsequent_filters_test4 \ CPPUNIT_TEST_NAME=testLegacyOptionButtonGroupBox Change-Id: Ib5b03c68b5218649268f283d11981cc03fe4850a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137838 Tested-by: Jenkins Reviewed-by: Justin Luth <jluth@mail.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/qa/unit/data/xls/tdf79542_radioGroupBox.xlsbin0 -> 37376 bytes
-rw-r--r--sc/qa/unit/subsequent_filters_test4.cxx20
-rw-r--r--sc/source/filter/excel/xiescher.cxx60
-rw-r--r--sc/source/filter/inc/xiescher.hxx6
4 files changed, 86 insertions, 0 deletions
diff --git a/sc/qa/unit/data/xls/tdf79542_radioGroupBox.xls b/sc/qa/unit/data/xls/tdf79542_radioGroupBox.xls
new file mode 100644
index 000000000000..1861913020d3
--- /dev/null
+++ b/sc/qa/unit/data/xls/tdf79542_radioGroupBox.xls
Binary files differ
diff --git a/sc/qa/unit/subsequent_filters_test4.cxx b/sc/qa/unit/subsequent_filters_test4.cxx
index fcbc02ebe0a3..d6b853607e51 100644
--- a/sc/qa/unit/subsequent_filters_test4.cxx
+++ b/sc/qa/unit/subsequent_filters_test4.cxx
@@ -116,6 +116,26 @@ CPPUNIT_TEST_FIXTURE(ScFiltersTest4, testControlImport)
UNO_QUERY_THROW);
}
+CPPUNIT_TEST_FIXTURE(ScFiltersTest4, testLegacyOptionButtonGroupBox)
+{
+ createScDoc("xls/tdf79542_radioGroupBox.xls");
+ uno::Reference<sheet::XSpreadsheetDocument> xDoc(mxComponent, UNO_QUERY_THROW);
+ uno::Reference<container::XIndexAccess> xIA(xDoc->getSheets(), UNO_QUERY_THROW);
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIA->getByIndex(0),
+ UNO_QUERY_THROW);
+ uno::Reference<container::XIndexAccess> xIA_DrawPage(xDrawPageSupplier->getDrawPage(),
+ UNO_QUERY_THROW);
+
+ OUString sGroupName;
+ uno::Reference<drawing::XControlShape> xControlShape(xIA_DrawPage->getByIndex(1),
+ UNO_QUERY_THROW);
+ uno::Reference<beans::XPropertySet> xPropertySet(xControlShape->getControl(),
+ uno::UNO_QUERY_THROW);
+ // The radio buttons are grouped by GroupBoxes - so the name comes from the group shape name
+ xPropertySet->getPropertyValue("GroupName") >>= sGroupName;
+ CPPUNIT_ASSERT_EQUAL(OUString("Casella di gruppo 1"), sGroupName);
+}
+
CPPUNIT_TEST_FIXTURE(ScFiltersTest4, testActiveXOptionButtonGroup)
{
createScDoc("xlsx/tdf111980_radioButtons.xlsx");
diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx
index e9a47fada31c..1805b7a26312 100644
--- a/sc/source/filter/excel/xiescher.cxx
+++ b/sc/source/filter/excel/xiescher.cxx
@@ -378,6 +378,11 @@ void XclImpDrawObjBase::SetAnchor( const XclObjAnchor& rAnchor )
mbHasAnchor = true;
}
+const tools::Rectangle& XclImpDrawObjBase::GetDffRect() const
+{
+ return maDffRect;
+}
+
void XclImpDrawObjBase::SetDffData(
const DffObjData& rDffObjData, const OUString& rObjName, const OUString& rHyperlink,
bool bVisible, bool bAutoMargin )
@@ -388,6 +393,7 @@ void XclImpDrawObjBase::SetDffData(
maHyperlink = rHyperlink;
mbVisible = bVisible;
mbAutoMargin = bAutoMargin;
+ maDffRect = rDffObjData.aChildAnchor;
}
OUString XclImpDrawObjBase::GetObjName() const
@@ -2086,6 +2092,16 @@ void XclImpTbxObjBase::SetDffProperties( const DffPropSet& rDffPropSet )
::set_flag( maLineData.mnAuto, EXC_OBJ_FILL_AUTO, false );
}
+void XclImpControlHelper::SetStringProperty(const OUString& sName, const OUString& sVal)
+{
+ Reference<XControlModel> xCtrlModel = XclControlHelper::GetControlModel(mxShape);
+ if (!xCtrlModel.is())
+ return;
+
+ ScfPropertySet aProps(xCtrlModel);
+ aProps.SetStringProperty(sName, sVal);
+}
+
bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const
{
return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName(), GetDocShell() );
@@ -2393,6 +2409,11 @@ XclTbxEventType XclImpOptionButtonObj::DoGetEventType() const
return EXC_TBX_EVENT_ACTION;
}
+bool XclImpOptionButtonObj::IsInGroup() const
+{
+ return mnNextInGroup;
+}
+
XclImpLabelObj::XclImpLabelObj( const XclImpRoot& rRoot ) :
XclImpTbxObjBase( rRoot )
{
@@ -4070,6 +4091,43 @@ const XclImpObjTextData* XclImpDrawing::FindTextData( const DffRecordHeader& rHe
return nullptr;
}
+void XclImpDrawing::ApplyGroupBoxes()
+{
+ // sorted: smallest to largest - looking for smallest contained-in GroupBox
+ // multimap: allows duplicate key values - may have identical areas.
+ std::multimap<double, XclImpDrawObjRef> aGroupBoxAreaMap;
+ for (auto& rGroupBox : maObjMapId)
+ {
+ if (rGroupBox.second->GetObjType() != EXC_OBJTYPE_GROUPBOX)
+ continue;
+ const tools::Rectangle& rRect = rGroupBox.second->GetDffRect();
+ const double fArea = double(rRect.GetWidth()) * rRect.GetHeight();
+ aGroupBoxAreaMap.insert(std::pair<double, XclImpDrawObjRef>(fArea, rGroupBox.second));
+ }
+
+ for (auto& rGroupedObj : maObjMapId)
+ {
+ auto pRadioButton = dynamic_cast<XclImpOptionButtonObj*>(rGroupedObj.second.get());
+ if (!pRadioButton || pRadioButton->IsInGroup())
+ continue;
+
+ OUString sGroupName("autoGroup_");
+ for (auto& rGroupBox : aGroupBoxAreaMap)
+ {
+ assert(pRadioButton->GetTab() == rGroupBox.second->GetTab() && "impossible right?");
+ if (!rGroupBox.second->GetDffRect().Contains(pRadioButton->GetDffRect()))
+ continue;
+
+ sGroupName = rGroupBox.second->GetObjName();
+ if (sGroupName.isEmpty())
+ sGroupName += "autoGroup_" + OUString::number(rGroupBox.second->GetObjId());
+ // I ASSUME the smallest box wins in MS Word. (otherwise first? last?)
+ break;
+ }
+ pRadioButton->SetStringProperty("GroupName", sGroupName);
+ }
+}
+
void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId )
{
maSkipObjs.push_back( nObjId );
@@ -4097,6 +4155,8 @@ void XclImpDrawing::ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel&
rDffConv.ProcessDrawing( maRawObjs );
// process all objects in the DFF stream
rDffConv.ProcessDrawing( maDffStrm );
+ // assign groups based on being contained in the same GroupBox/sheet
+ ApplyGroupBoxes();
// unregister this drawing manager at the passed (global) DFF manager
rDffConv.FinalizeDrawing();
rSdrModel.EnableUndo(bOrigUndoStatus);
diff --git a/sc/source/filter/inc/xiescher.hxx b/sc/source/filter/inc/xiescher.hxx
index 2079d68f11c1..cf09c161fe11 100644
--- a/sc/source/filter/inc/xiescher.hxx
+++ b/sc/source/filter/inc/xiescher.hxx
@@ -98,6 +98,7 @@ public:
sal_uInt32 GetDffShapeId() const { return mnDffShapeId; }
/** Returns the shape flags from the DFF stream. */
ShapeFlag GetDffFlags() const { return mnDffFlags; }
+ const tools::Rectangle& GetDffRect() const;
/** Returns true, if the object is hidden. */
bool IsHidden() const { return mbHidden; }
@@ -191,6 +192,7 @@ private:
sal_uInt16 mnObjType; /// The Excel object type from OBJ record.
sal_uInt32 mnDffShapeId; /// Shape ID from DFF stream.
ShapeFlag mnDffFlags; /// Shape flags from DFF stream.
+ tools::Rectangle maDffRect;
OUString maObjName; /// Name of the object.
OUString maMacroName; /// Name of an attached macro.
OUString maHyperlink; /// On-click hyperlink URL.
@@ -470,6 +472,7 @@ public:
/** Sets additional properties to the form control model, calls virtual DoProcessControl(). */
void ProcessControl( const XclImpDrawObjBase& rDrawObj ) const;
+ void SetStringProperty(const OUString& sName, const OUString& sVal);
protected:
/** Reads the formula for the linked cell from the current position of the stream. */
@@ -571,6 +574,7 @@ class XclImpOptionButtonObj final : public XclImpCheckBoxObj
{
public:
explicit XclImpOptionButtonObj( const XclImpRoot& rRoot );
+ bool IsInGroup() const;
private:
/** Reads the contents of the a BIFF5 OBJ record from the passed stream. */
@@ -1062,6 +1066,8 @@ public:
/** Finds the textbox data related to the DFF shape at the passed position. */
const XclImpObjTextData* FindTextData( const DffRecordHeader& rHeader ) const;
+ void ApplyGroupBoxes();
+
/** Sets the object with the passed identification to be skipped on import. */
void SetSkipObj( sal_uInt16 nObjId );
/** Returns the size of the progress bar shown while processing all objects. */