diff options
-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: */ |