diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2018-09-08 00:41:47 +0200 |
---|---|---|
committer | Regina Henschel <rb.henschel@t-online.de> | 2018-09-12 09:24:05 +0200 |
commit | d52c8fd4cc025ca9da474a20aa0f5514032273e2 (patch) | |
tree | 33e628c6ef9c4bd707edbe360edac69fd5a76fb9 | |
parent | 1b267db43b35cc0dcd6d50712efe52ed32fa6e7b (diff) |
tdf#119392 write bitfield in <draw:layer-set> order
The view uses the SdrLayerIDSet bitfield in layer ID order.
But file format knows no layer IDs and on loading the
bitfield is interpreted in the layer order given by
<draw:layer-set> element. Therefore reorder the bits on
saving according <draw:layer-set>, which is order in
SdrLayerAdmin.
Change-Id: Id349dc7f42338e35ca8cc3b6409d061213b01691
Reviewed-on: https://gerrit.libreoffice.org/60178
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
-rw-r--r-- | include/svx/svdlayer.hxx | 4 | ||||
-rw-r--r-- | include/svx/svdsob.hxx | 4 | ||||
-rw-r--r-- | sd/qa/unit/data/tdf119392_InsertLayer.odg | bin | 0 -> 12765 bytes | |||
-rw-r--r-- | sd/qa/unit/misc-tests.cxx | 47 | ||||
-rw-r--r-- | sd/source/ui/view/frmview.cxx | 7 | ||||
-rw-r--r-- | svx/source/svdraw/svdlayer.cxx | 74 |
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 Binary files differnew file mode 100644 index 000000000000..617624ce9b60 --- /dev/null +++ b/sd/qa/unit/data/tdf119392_InsertLayer.odg 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: */ |