<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 15, 2014 at 6:32 PM, Sandro Santilli <span dir="ltr"><<a href="mailto:strk@keybit.net" target="_blank">strk@keybit.net</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">On Mon, Dec 15, 2014 at 03:21:15PM +0700, Martin Dobias wrote:<br>
> On Mon, Dec 15, 2014 at 1:03 AM, Sandro Santilli <<a href="mailto:strk@keybit.net">strk@keybit.net</a>> wrote:<br>
> ><br>
> ><br>
> > I'm guessing ::refreshLayerLegend is called to _force_ re-asking for<br>
> > the data() whenever the map extent changes. Anyway I'll follow your<br>
> > suggestion about implementing lazy load of the legend.<br>
> ><br>
><br>
> There is a softer way to ask to call legend node's data() again - the<br>
> legend node can emit dataChanged() signal. This is used e.g. for symbols<br>
> defined in map units - when the scale changes they will tell the model to<br>
> update (QgsSymbolV2LegendNode::invalidateMapBasedData()).<br>
<br>
</span>Ah, interesting. But I see invalidateMapBasedData is invoked on all legend<br>
nodes by QgsLayerTreeModel::setLegendMapViewData but not by<br>
QgsLayerTreeModel::setLegendFilterByMap. Should the latter also invoke<br>
the invalidation method ?<br></blockquote><div><br></div><div>That sounds reasonably. The invalidateMapBasedData() could have optional pointer to QgsMapSettings, so the WMS legend node would have a way to find out about the details of the map view (bbox, dpi, etc).</div><div> <br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Another thing. The QgsMapLayerLegend object is currently independent<br>
from a QgsMapCanvas, and thus from the settings of the map (extent).<br>
In my PR (#1735) I've added an optional QgsMapSetting parameter to<br>
the virtual QgsMapLayerLegend::createLayerTreeModelLegendNodes method.<br>
That way the settings can be embedded in the nodes, but if we have to<br>
rely on data() updating the legend, we'd need a way to pass the updated<br>
map settings again, or keep the old settings by pointer.<br></blockquote><div><br></div><div>I'm not sure I like the fact that QgsMapSettings would be passed when legend nodes are created. I guess with invalidateMapBasedData() having QgsMapSettings pointer that would not be necessary.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Would it be inappropriate to store a pointer to the QgsLayerTreeModel<br>
into a QgsLayerTreeModelLegendNode ? Or is there already such link ?<br></blockquote><div><br></div><div>Yes there is QgsLayerTreeModelLegendNode::model()</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">> Indeed the filter-by-map removes all legend nodes and re-adds them - the<br>
> comment is valid that ideally we should do less work and not request all<br>
> legend nodes again from QgsMapLayerLegend. We already keep the legend nodes<br>
> in mOriginalLegendNodes, so it is mainly about writing a new function to<br>
> reuse them when filtering by map content. One could go even further and not<br>
> to do a bulk remove+insert rows operations - instead one could just compare<br>
> two lists "before" and "after" and insert/remove rows only where needed.<br>
<br>
</span>Good idea, but also the "filtering" would need to be posibly done by<br>
nodes themself. I mean there would be a "removing nodes" kind of filtering<br>
and a "modify node contents" kind of filtering. Maybe there could be a<br>
QgsLayerTreeModelLegendNode::filterByMap() method that would return<br>
a value indicating if the node should be kept or removed, and would have<br>
a chance to update its contents. What would you think about that ?<br></blockquote><div><br></div><div>That would be nice to have it directly inside legend nodes, but you would still need something that would run QgsMapHitTest and then pass it to individual nodes. So I am not sure if that would actually help.</div><div><br></div><div>Cheers</div><div>Martin</div><div><br></div></div></div></div>