Changing Layer Name with Ruby

edited June 2010 in General
I am trying to change some of the layer names with Ruby. I wrote some code like:


layout_info = layout.get_info( found_layer )
if layout_info.layer == 10
layout_info.name = "DIFF"
end

Put I get an error Ruby error: 'Cannot call non-const method name=, class LayerInfo on a const reference'

This makes sense once I check the documentation, as layout.get_info does return a const. I was wondering if there is a good way of changing an existing layer name from ruby without having to first delete the layer and then add a new layer.

Oliver

Comments

  • edited November -1

    Hi Oliver,

    "layout_info" is a reference into the internal object (that's because in general, one tries to avoid creating copies).

    To change the properties, you have to create a duplicate first (note the "dup"):

    layer_info = layout.get_info(found_layer).dup
    layout_info.name = "DIFF"
    layout.set_info(found_layer, layout_info)
    

    I admit, it does not make much sense keeping the reference in this case. From the performance point of view there is no reason to do so.

    Best regards,

    Matthias

  • edited November -1

    Hi,

    This is not a major issue but I thought I'd point it out.

    I hope to use your code above to strip all layer names out. Just keep the layer number and datatype number and remove the string.

    The following script works. However the "" string is not updated in the panel on the right. i.e. if it had a name before, it still has a string name in that panel.

    I know the script is working because if I select a layer and choose Edit > Layer > Edit layer specification, the string is gone. Or if I save and re-open, the string is gone. But the change is not reflected on the layer list immediately after running the script. Is there a command to update that panel?

    layout.layer_indices.each{ |li|
      layer_info = layout.get_info(li).dup
      layer_info.name = ""
      layout.set_info(li, layer_info)
    }
    

    Thanks,
    David

  • edited November -1

    Hi David,

    you're right. It's true that the list is not updated whenever you change something on the layer name, not just resetting the layer name.

    The reason is a bit difficult to explain - basically the layer list entry is a "view" which means it's supposed to specify what is shown and how it's shown. So it's not reflecting the database, it's independent of it. For example, if a layer list entry say's "I'm showing layer 1, datatype 0", you can change the layer's number in the database to 2. The effect won't be that the view changes but simply nothing will be shown any more: the view still looks for layer 1, datatype 0, but it's gone now.

    The same happens for the layer name. If you assign a different name, the view will still say "I'm looking for layer ABC". If there is a layer/datatype specification too, it will say "I'm looking for layer 17, datatype 0 and if there is no such layer I'll try to layer ABC.". Changing the name won't make it look elsewhere, but since layer 17, datatype 0 is still there, it knows what to display.

    Matthias

  • edited November -1
    Hi Matthias,

    So there is no function call to update the view?
    When I update the name using the menus Edit -> Layer -> Edit Layer Specification, the view gets updated on name change.
  • edited November -1

    Hi,

    there is a function, but views and database layers are not synchronized automatically. You need to update both. This is essentially what the "edit layer properties" function does.

    Here is some code:

    # rename layer 1 to 10 in both the layout and the layer view
    
    view = RBA::LayoutView::current   
    
    from_layer = 1
    from_datatype = 0
    
    to_layer = 10
    to_datatype = 0
    
    layout = view.active_cellview.layout
    cellview_index = view.active_cellview_index
    
    layer_index = layout.layer(from_layer, from_datatype)
    
    # rename the layer in the layout
    info = layout.get_info(layer_index)
    info.layer = to_layer
    info.datatype = to_datatype
    layout.set_info(layer_index, info)
    
    # rename the layer in the layer views
    iter = view.begin_layers
    while !iter.at_end?
      if iter.current.cellview == cellview_index && iter.current.source_layer == from_layer && iter.current.source_datatype == from_datatype
        lp = iter.current.dup
        lp.source_layer = to_layer
        lp.source_datatype = to_datatype
        view.replace_layer_node(iter, lp)
      end
      iter.next
    end
    

    Matthias

Sign In or Register to comment.