summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svx/svdlayer.hxx4
-rw-r--r--include/svx/svdsob.hxx4
-rw-r--r--sd/qa/unit/data/tdf119392_InsertLayer.odgbin0 -> 12765 bytes
-rw-r--r--sd/qa/unit/misc-tests.cxx47
-rw-r--r--sd/source/ui/view/frmview.cxx7
-rw-r--r--svx/source/svdraw/svdlayer.cxx74
6 files changed, 103 insertions, 33 deletions
diff --git a/include/svx/svdlayer.hxx b/include/svx/svdlayer.hxx
index 2f2a32f33bd7..b36a1e9fdb1e 100644
--- a/include/svx/svdlayer.hxx
+++ b/include/svx/svdlayer.hxx
@@ -163,6 +163,10 @@ public:
void getVisibleLayersODF( SdrLayerIDSet& rOutSet) const;
void getPrintableLayersODF( SdrLayerIDSet& rOutSet) const;
void getLockedLayersODF( SdrLayerIDSet& rOutSet) const;
+
+ // Generates a bitfield for settings.xml from the SdrLayerIDSet.
+ // Output is a uno sequence of BYTE (which is 'short' in API).
+ void QueryValue(const SdrLayerIDSet& rViewLayerSet, css::uno::Any& rAny);
};
#endif // INCLUDED_SVX_SVDLAYER_HXX
diff --git a/include/svx/svdsob.hxx b/include/svx/svdsob.hxx
index 21ef323040ff..3d3f8c03488d 100644
--- a/include/svx/svdsob.hxx
+++ b/include/svx/svdsob.hxx
@@ -82,11 +82,9 @@ public:
void operator&=(const SdrLayerIDSet& r2ndSet);
- // initialize this set with a uno sequence of sal_Int8
+ // initialize this set with a uno sequence of sal_Int8 (e.g. as stored in settings.xml)
void PutValue(const css::uno::Any & rAny);
- // returns a uno sequence of sal_Int8
- void QueryValue(css::uno::Any & rAny) const;
};
#endif // INCLUDED_SVX_SVDSOB_HXX
diff --git a/sd/qa/unit/data/tdf119392_InsertLayer.odg b/sd/qa/unit/data/tdf119392_InsertLayer.odg
new file mode 100644
index 000000000000..617624ce9b60
--- /dev/null
+++ b/sd/qa/unit/data/tdf119392_InsertLayer.odg
Binary files differ
diff --git a/sd/qa/unit/misc-tests.cxx b/sd/qa/unit/misc-tests.cxx
index 43828255e0c0..270a0f527178 100644
--- a/sd/qa/unit/misc-tests.cxx
+++ b/sd/qa/unit/misc-tests.cxx
@@ -66,6 +66,7 @@ public:
void testTdf38225();
void testTdf101242_ODF();
void testTdf101242_settings();
+ void testTdf119392();
CPPUNIT_TEST_SUITE(SdMiscTest);
CPPUNIT_TEST(testTdf96206);
@@ -77,6 +78,7 @@ public:
CPPUNIT_TEST(testTdf38225);
CPPUNIT_TEST(testTdf101242_ODF);
CPPUNIT_TEST(testTdf101242_settings);
+ CPPUNIT_TEST(testTdf119392);
CPPUNIT_TEST_SUITE_END();
virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) override
@@ -488,6 +490,51 @@ void SdMiscTest::testTdf101242_settings()
xDocShRef->DoClose();
}
+void SdMiscTest::testTdf119392()
+{
+ // Loads a document which has two user layers "V--" and "V-L". Inserts a new layer "-P-" between them.
+ // Checks, that the bitfields in the saved file have the bits in the correct order.
+
+ sd::DrawDocShellRef xDocShRef = Load(m_directories.getURLFromSrc("/sd/qa/unit/data/tdf119392_InsertLayer.odg"), ODG);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocShRef.is());
+ // Insert layer "-P-", not visible, printable, not locked
+ SdrView* pView = xDocShRef -> GetViewShell()->GetView();
+ pView -> InsertNewLayer("-P-", 6); // 0..4 standard layer, 5 layer "V--"
+ SdrPageView* pPageView = pView -> GetSdrPageView();
+ pPageView -> SetLayerVisible("-P-", false);
+ pPageView -> SetLayerPrintable("-P-", true);
+ pPageView -> SetLayerLocked("-P-", false);
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ save(xDocShRef.get(), getFormat(ODG), aTempFile );
+
+ // Verify correct bit order in bitfield in the items in settings.xml
+ xmlDocPtr pXmlDoc = parseExport(aTempFile, "settings.xml");
+ CPPUNIT_ASSERT_MESSAGE("Failed to get 'settings.xml'", pXmlDoc);
+ const OString sPathStart("/office:document-settings/office:settings/config:config-item-set[@config:name='ooo:view-settings']/config:config-item-map-indexed[@config:name='Views']/config:config-item-map-entry");
+ // First Byte is in order 'V-L -P- V-- measurelines controls backgroundobjects background layout'
+ // Bits need to be: visible=10111111=0xbf=191 printable=01011111=0x5f=95 locked=10000000=0x80=128
+ // The values in file are Base64 encoded.
+ OUString sBase64;
+ uno::Sequence<sal_Int8> aDecodedSeq;
+ sBase64 = getXPathContent(pXmlDoc, sPathStart + "/config:config-item[@config:name='VisibleLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item VisibleLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0xbF, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0xff); // & 0xff forces unambigious types for CPPUNIT_ASSERT_EQUAL
+
+ sBase64 = getXPathContent(pXmlDoc, sPathStart + "/config:config-item[@config:name='PrintableLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item PrintableLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x5f, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0xff);
+
+ sBase64 = getXPathContent(pXmlDoc, sPathStart + "/config:config-item[@config:name='LockedLayers']");
+ CPPUNIT_ASSERT_MESSAGE( "Item LockedLayers does not exists.", !sBase64.isEmpty());
+ comphelper::Base64::decode(aDecodedSeq, sBase64);
+ CPPUNIT_ASSERT_EQUAL( 0x80, static_cast<sal_uInt8>(aDecodedSeq[0]) & 0xff);
+
+ xDocShRef->DoClose();
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SdMiscTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/ui/view/frmview.cxx b/sd/source/ui/view/frmview.cxx
index 1232d9f23692..aa4f7af1a51e 100644
--- a/sd/source/ui/view/frmview.cxx
+++ b/sd/source/ui/view/frmview.cxx
@@ -395,14 +395,15 @@ void FrameView::WriteUserDataSequence ( css::uno::Sequence < css::beans::Propert
aUserData.addValue( sUNO_View_EliminatePolyPointLimitAngle, makeAny( static_cast<sal_Int32>(GetEliminatePolyPointLimitAngle()) ) );
aUserData.addValue( sUNO_View_IsEliminatePolyPoints, makeAny( IsEliminatePolyPoints() ) );
+ SdrLayerAdmin& rLayerAdmin = getSdrModelFromSdrView().GetLayerAdmin();
Any aAny;
- GetVisibleLayers().QueryValue( aAny );
+ rLayerAdmin.QueryValue(GetVisibleLayers(), aAny);
aUserData.addValue( sUNO_View_VisibleLayers, aAny );
- GetPrintableLayers().QueryValue( aAny );
+ rLayerAdmin.QueryValue(GetPrintableLayers(), aAny);
aUserData.addValue( sUNO_View_PrintableLayers, aAny );
- GetLockedLayers().QueryValue( aAny );
+ rLayerAdmin.QueryValue(GetLockedLayers(), aAny);
aUserData.addValue( sUNO_View_LockedLayers, aAny );
aUserData.addValue( sUNO_View_NoAttribs, makeAny( IsNoAttribs() ) );
diff --git a/svx/source/svdraw/svdlayer.cxx b/svx/source/svdraw/svdlayer.cxx
index d17b61dbf1f0..b40f3fa0dc90 100644
--- a/svx/source/svdraw/svdlayer.cxx
+++ b/svx/source/svdraw/svdlayer.cxx
@@ -43,7 +43,7 @@ void SdrLayerIDSet::operator&=(const SdrLayerIDSet& r2ndSet)
}
}
-/** initialize this set with a uno sequence of sal_Int8
+/** initialize this set with a uno sequence of sal_Int8 (e.g. as stored in settings.xml)
*/
void SdrLayerIDSet::PutValue( const css::uno::Any & rAny )
{
@@ -67,32 +67,6 @@ void SdrLayerIDSet::PutValue( const css::uno::Any & rAny )
}
}
-/** returns a uno sequence of sal_Int8
-*/
-void SdrLayerIDSet::QueryValue( css::uno::Any & rAny ) const
-{
- sal_Int16 nNumBytesSet = 0;
- sal_Int16 nIndex;
- for( nIndex = 31; nIndex >= 00; nIndex-- )
- {
- if( 0 != aData[nIndex] )
- {
- nNumBytesSet = nIndex + 1;
- break;
- }
- }
-
- css::uno::Sequence< sal_Int8 > aSeq( nNumBytesSet );
-
- for( nIndex = 0; nIndex < nNumBytesSet; nIndex++ )
- {
- aSeq[nIndex] = static_cast<sal_Int8>(aData[nIndex]);
- }
-
- rAny <<= aSeq;
-}
-
-
SdrLayer::SdrLayer(SdrLayerID nNewID, const OUString& rNewName) :
maName(rNewName), pModel(nullptr), nType(0), nID(nNewID)
{
@@ -366,5 +340,51 @@ void SdrLayerAdmin::getLockedLayersODF( SdrLayerIDSet& rOutSet) const
}
}
+ // Generates a bitfield for settings.xml from the SdrLayerIDSet.
+ // Output is a uno sequence of BYTE (which is 'short' in API).
+void SdrLayerAdmin::QueryValue(const SdrLayerIDSet& rViewLayerSet, css::uno::Any& rAny)
+{
+ // tdf#119392 The SdrLayerIDSet in a view is ordered according LayerID, but in file
+ // the bitfield is interpreted in order of layers in <draw:layer-set>.
+ // First generate a new bitfield based on rViewLayerSet in the needed order.
+ sal_uInt8 aTmp[32]; // 256 bits in settings.xml makes byte 0 to 31
+ for (auto nIndex = 0; nIndex <32; nIndex++)
+ {
+ aTmp[nIndex] = 0;
+ }
+ sal_uInt8 nByteIndex = 0;
+ sal_uInt8 nBitpos = 0;
+ sal_uInt16 nLayerPos = 0; // Position of the layer in member aLayer and in <draw:layer-set> in file
+ for( SdrLayer* pCurrentLayer : aLayer )
+ {
+ SdrLayerID nCurrentID = pCurrentLayer->GetID();
+ if ( rViewLayerSet.IsSet(nCurrentID) )
+ {
+ nLayerPos = GetLayerPos(pCurrentLayer);
+ nByteIndex = nLayerPos / 8;
+ if (nByteIndex > 31)
+ continue; // skip position, if too large for bitfield
+ nBitpos = nLayerPos % 8;
+ aTmp[nByteIndex] |= (1 << nBitpos);
+ }
+ }
+
+ // Second transform the bitfield to byte sequence, same as in previous version of QueryValue
+ sal_uInt8 nNumBytesSet = 0;
+ for( auto nIndex = 31; nIndex >= 0; nIndex--)
+ {
+ if( 0 != aTmp[nIndex] )
+ {
+ nNumBytesSet = nIndex + 1;
+ break;
+ }
+ }
+ css::uno::Sequence< sal_Int8 > aSeq( nNumBytesSet );
+ for( auto nIndex = 0; nIndex < nNumBytesSet; nIndex++ )
+ {
+ aSeq[nIndex] = static_cast<sal_Int8>(aTmp[nIndex]);
+ }
+ rAny <<= aSeq;
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */