Inkscape.org
Creating New Extensions Locking/Unlocking Layers with an Extension
  1. #1
    Jacob Grobler Jacob Grobler @hemelbesem

    I'm trying to create an Inkscape extension to lock and unlock all layers in a document. The locking part works fine, but the unlocking doesn't seem to have any effect. I'm using the del layer.attrib['sodipodi:insensitive'] line to remove the attribute that controls locking, but the layers remain locked in Inkscape.

    I've tried various approaches, including using XPath to find and remove the attribute, but nothing seems to work. I'm not getting any error messages, but the layers simply don't unlock.

    Here's the relevant code snippet:
     

    import inkex
    
    class LockUnlockAllLayers(inkex.Effect):
        def __init__(self):
            inkex.Effect.__init__(self)
    
        def effect(self):
            svg = self.document.getroot()
            layers = svg.findall('.//{http://www.w3.org/2000/svg}g[@inkscape:groupmode="layer"]')
    
            # Check if ANY layer is unlocked
            any_unlocked = any(layer.get('sodipodi:insensitive') != 'true' for layer in layers)
    
            # Lock or unlock all layers
            for layer in layers:
                if any_unlocked:
                    layer.set('sodipodi:insensitive', 'true')
                else:
                    if 'sodipodi:insensitive' in layer.attrib:
                        del layer.attrib['sodipodi:insensitive']
    
            # Output the SVG
            self.document.write(self.options.input_file)
    
    if __name__ == '__main__':
        LockUnlockAllLayers().run()

    I'm using Inkscape 1.2.1 on Windows 11.

    Has anyone encountered this issue before or have any suggestions on how to reliably unlock layers using the Inkscape extension API? Any help would be greatly appreciated!

     

  2. #2
    inklinea inklinea @inklinea⛰️
    😀*

    getters and setters should be Inkscape / sodipodi namespace aware.

    Setting to None should make the attribute vanish :)

    layers = self.svg.xpath('//svg:g[@inkscape:groupmode="layer"]')
    
    for layer in layers:
        layer.set('sodipodi:insensitive', None)
    
  3. #3
    Jacob Grobler Jacob Grobler @hemelbesem

    This is great, my code finally works, thank you!!

    So I have actually tried layer.set('sodipodi:insensitive', None) before, but it did not work.

    It seems likely that my problem was in how I searched for the layer info. I used:

    layers = svg.findall('.//{http://www.w3.org/2000/svg}g[@inkscape:groupmode="layer"]')

    I have also update some of my other extensions (they were working luckily) with the XPath call.

Inkscape Inkscape.org Inkscape Forum Creating New Extensions Locking/Unlocking Layers with an Extension