Need code pointer for import of <draw:layer> attributes

Michael Stahl mstahl at
Tue Nov 28 22:05:20 UTC 2017

On 26.11.2017 23:01, Regina Henschel wrote:
> Hi Michael,
> Michael Stahl schrieb am 23.11.2017 um 21:37:
>> On 22.11.2017 17:32, Regina Henschel wrote:
>>> Hi all,
>>> I've started on
>>> My current
>>> work is in the attachment.
>>> Problem: Although I remove the config-items IsVisible, IsPrintable,
>>> IsLocked from the settings.xml of a file, the values from draw:display
>>> and draw:locked of the <draw:layer> element are not used. It seems to
>>> me, that somewhere the read values are overwritten with a default.
>>> Where and when are the values from settings.xml transformed to
>>> properties of the layers of a newly opened draw document?
>> probably in sd/source/ui/view/frmview.cxx,
>> FrameView::ReadUserDataSequence(), around line 858
> There the values from settings.xml are indeed read, but it sets no 
> defaults. If the node does not exists, nothing is changed.
>>> Any other hint, where to look?
>> there are SetVisibleLayers functions on 3 different classes, maybe
>> setting breakpoints on those would be helpful.
> "setting breakpoints" was a good tip.
> I use VS2017 and there is no "vs2017-ide-integration" yet. But I have 
> tried the "vs2015-ide-integration" and it seems to work :)
> I looked a little bit around for SetVisibleLayers and SdrLayerIDSet 
> without success.
> Then I started from the other end and looked what happens with my not 
> working
> xLayer->setPropertyValue("IsLocked",(msbProtected == "true") ? Any(true) 
> : Any(false) );
> compared to the working
> xLayer->setPropertyValue("Title", Any( sTitleBuffer.makeStringAndClear() 
> ) );
> I found this:
> setPropertyValue is a method of class SdLayer [in 
> sd\source\ui\unoidl\unolayer.hxx]
> The SdLayer itself has no members to store the information. In case of 
> "Title" the SdrLayer is used, for which the SdLayer has a pointer. This 
> SdrLayer has the member maTitle to take the information. It has no 
> members to take IsLocked, IsVisible or IsPrintable.
> In case of "IsLocked" the SdLayer uses its member mxLayerManager to get 
> a View of a page or a FrameView of the DocShell. But both doesn't exists 
> at this stage, when loading a document. So the call of set(...) returns 
> false; the source has the comment "//TODO: uno::Exception?"
> The result is, that the information is not overwritten as I first 
> thought, but is simple lost.

the properties can only be initialised once the View is created, after
the document has been imported.

well that is unfortunate.

> A <draw:page> can have its own <draw:layer-set>. But the 
> <draw:layer-set> to be used for the page can also be inherited from a 
> master page via <style:master-page> or <office:master-styles>. Therefore 
> a solution is needed, which can be extended to support all three places.

looking at xmloff, there is exactly one draw:layer-set per document, in
office:master-styles, and it's written by a call to

the other 2 parents of draw:layer-set in ODF, we currently don't support.

> As you know, currently the IsLocked/IsVisible/IsPrintable is not stored 
> in the document itself, but in the settings.xml, despite the fact, that 
> ODF can express the information. [Remember ODF TC discussion on 
> OFFICE-3693 to not use settings.xml in those cases.]

looking at the structure of an ODG settings.xml, it's clear that there
can be multiple "View"s, each with a different "VisibleLayers" etc.

such a document can be created in Draw with Window->New and
right-clicking on the layer tabs, you can set the visibilities so that
one window shows a shape and the other not.

however it appears this is currently quite broken: the settings.xml
contains 2 config-item-map-entry elements; the first one looks correct
and the second one has the wrong ViewId "view1" identical to the first
one, and also all of the config-items of the first one are duplicated
inside it (it has twice as many items).

if i manually fix these problems and load the document, still only a
single window is created.

OOo 3.3 already has all of these problems.

> New members mbIsLocked, mbIsVisible and mbIsPrintable for the SdrLayer 
> would likely work [not worked out yet] as long as the layer settings are 
> unique throughout the document, but they need not be unique in ODF.

this would store the properties in the document model, while
(apparently) they currently exist only in the view?

... i think there's an argument to be made that we need to retain these
as view properties: while that cannot be persisted to files currently
due to all the bugs, it's still useful to have purely at run-time.

on the other hand, as view properties they obviously can't support the
currently missing feature of layers inside draw:page or style:master-page.

guess one way to handle it is to set the styles.xml attributes on the
one and only view that is created after loading - but because the view
is created so late, the attributes need to be stored temporarily in some
place and then later applied...

maybe it's possible to create the same 3 Sequence<sal_uInt8> that the
FrameView::ReadUserDataSequence() expects, from the attributes on
draw:layer?  apparently the encoding is simply one bit per layer, just
it's not immediately obvious how the order of the bits corresponds to
the order of the layers, but i guess it's either ascending or
descending. ... descending, apparently, i.e. the first draw:layer is the
rightmost bit, so you can just "shift in" a bit from the left as each
new layer occurs...

once we have the Sequences in xmloff, we can store them where
SfxBaseController::ConnectSfxFrame_Impl() can find them:

>                     Reference< XViewDataSupplier > xViewDataSupplier( getModel(), UNO_QUERY_THROW );
>                     Reference< XIndexAccess > xViewData( xViewDataSupplier->getViewData() );

>                         const ::comphelper::NamedValueCollection aViewData( xViewData->getByIndex(i) );

what happens if there are both styles.xml attributes and settings.xml
config-items? i think in that case just let one override the other; i
hope the "ViewDataSupplier" thing already works that way.

More information about the LibreOffice mailing list