Search code examples
javascriptadobe-illustrator

Replacing name in layers pane doesn't update


I have a script that searches for layer names and replaces them, so far it works fine. However I have run across a problem and I don't understand what is happening. I have altered the script to include certain objects (pathItems, etc), in addition to layers. However when it finds and replaces the object name (which it does find them), it does not update in the layers pane. I debugged the program and it does indeed find and replace it, but does not update the names in the layers pane of Adobe Illustrator.

#target illustrator
#targetengine main

// JavaScript Document
if (app.documents.length > 0) {
    var doc = app.activeDocument;
    var docLayers = doc.layers;
    var searchText = "";
    var replaceText = "";
    var found = false;
    var match = false;

    function replace(layers) {
        match = false;
        recurseLayers(layers);
        app.redraw();

        // When match is found, show dialog
        if (match) {
            alert("Found match!");

            match = false;
        } else {
            alert("No match found.");
            match = false;
        }
    }


    function recurseLayers(layers) {
        var length = layers.length;
        var currentLayer = null;
        var searchtext = searchText;
        var replacetext = replaceText;


        try {
            for (var i = length; i--;) {
                currentLayer = layers[i];
                var visible = checkLayerVisibility(currentLayer);
                var locked = checkLayerLocked(currentLayer);

                if (visible == true || locked == false) {
                    replaceName(currentLayer, searchText, replaceText);

                    if (currentLayer.layers) {
                        recurseLayers(currentLayer.layers);
                        recurseLayers(currentLayer.groupItems);
                        recurseLayers(currentLayer.pathItems);
                        recurseLayers(currentLayer.compoundPathItems);
                        recurseLayers(currentLayer.symbolItems);
                        recurseLayers(currentLayer.textFrames);
                    }
                }
            }
        } catch (e) {
            logger (e);
        }
    }

    function replaceName(currentLayer, searchText, replaceText) {
        try {
            currentLayer.name = currentLayer.name.replace(searchText, replaceText);
            match = true;

        } catch (e) {
            logger(e);
        }
    }

    function checkLayerLocked(layer) {
        if(!layer.locked) 
            for(var parent = layer.parent; parent.typename=='Layer'; parent = parent.parent) {
                 if(parent.locked)
                    return true;
             }
        return layer.locked;
    } 

    function checkLayerVisibility(layer) {
        if(layer.visible) 
        for(var parent = layer.parent; parent.typename=='Layer'; parent = parent.parent) {
             if(!parent.visible)
                return false;
         }
        return layer.visible;
     }

    startGUI();

    function startGUI() {

        var win = new Window("dialog", "Replace Layer name", undefined);

        win.orientation = "column";
        win.alignChildren = ["fill", "fill"];

        // Search
        var searchGrp = win.add("panel", undefined, "Search and Replace");
        searchGrp.orientation = "column";
        searchGrp.alignChildren = ["fill", "fill"];

        var titleMsgS = searchGrp.add("statictext", undefined, "Layer name to search:");
        var txt_searchText = searchGrp.add("edittext { characters: 1, justify: 'center', active: true }");

        txt_searchText.helpTip = "Input layer name to replace";

        var titleMsgR = searchGrp.add("statictext", undefined, "Layer name to replace with:");
        var txt_replaceText = searchGrp.add("edittext { characters: 1, justify: 'center', active: true }");
        txt_replaceText.helpTip = "Input layer name to replace with";

        // Set first text box to active
        txt_searchText.active = true;

        win.addEventListener ("keydown", function(kd) {enter(kd) });

        // Replace button
        var replaceBtn = searchGrp.add("button", undefined, "Replace");
        replaceBtn.helpTip = "Replace layer name";
        replaceBtn.onClick = function() {
            searchText = txt_searchText.text;
            replaceText = txt_replaceText.text;

            replace(docLayers);
            app.redraw();
        }

        function enter(k) {
            if (k.keyName == "Enter") {
                searchText = txt_searchText.text;
                replaceText = txt_replaceText.text;

                replace(docLayers);
                app.redraw();
            }
        }

        // Close button
        var quitBtn = win.add("button", undefined, "Close");
        quitBtn.helpTip = "Press Esc to Close";

        // Event listener for the quit button
        quitBtn.onClick = function() {   
            win.close();   
        }  

        // Centering & Show Window
        win.center();
        win.show(); 
    }


    // Prints stack trace
    function logger(e) {
        var errorMsg = "";

        errorMsg = errorMsg.concat("An error has occured:\n", e.line, "\n", e.message, "\n", e.stack);
        $.writeln(errorMsg);
    }

} else {
        alert("You do not have any document opened!");
}

These are the layers I am using, the lines are what I need to replace, just their display name (either full name or part of the name).

Layers

As you can see in the second picture, the name has indeed been changed (changed the 'A8900' to '1'), but only shows in when I double click the name, or hide and unhide the layers (then it updates). I can't figure out why this is happening, maybe something to do with how the objects work in AI? There doesn't seem to be any way to debug this either, since in my code it working fine, but its not updating correctly in AI. I also used an 'app.redraw()' in the hopes that it will refresh it, but it does not. Any help is appreciated

Replaced name


Solution

  • I managed to get it working, I added a line of code to select the layer and it updates the name in the layers panel.

    If anyone know why this happens, I would still like to know.

    #target illustrator
    #targetengine main
    
    // JavaScript Document
    if (app.documents.length > 0) {
        var doc = app.activeDocument;
        var docLayers = doc.layers;
        var searchText = "";
        var replaceText = "";
        var found = false;
        var match = false;
    
        function replace(layers) {
            match = false;
            recurseLayers(layers);
    
            // When match is found, show dialog
            if (match) {
                alert("Found match!");
    
                match = false;
            } else {
                alert("No match found.");
                match = false;
            }
        }
    
    
        function recurseLayers(layers) {
            var length = layers.length;
            var currentLayer = null;
            var searchtext = searchText;
            var replacetext = replaceText;
    
    
            try {
                for (var i = length; i--;) {
                    currentLayer = layers[i];
                    var visible = checkLayerVisibility(currentLayer);
                    var locked = checkLayerLocked(currentLayer);
    
                    if (visible == true || locked == false) {
                        replaceName(currentLayer, searchText, replaceText);
    
                        if (currentLayer.layers) {
                            recurseLayers(currentLayer.layers);
                            recurseLayers(currentLayer.groupItems);
                            recurseLayers(currentLayer.pathItems);
                            recurseLayers(currentLayer.compoundPathItems);
                            recurseLayers(currentLayer.symbolItems);
                            recurseLayers(currentLayer.textFrames);
                        }
                    }
                }
            } catch (e) {
                logger (e);
            }
        }
    
        function replaceName(currentLayer, searchText, replaceText) {
            try {
                var name = currentLayer.name;
                var searchIndex = name.toLowerCase().indexOf(searchText.toLowerCase());
    
                if( searchIndex != -1 ) {
    
                    currentLayer.name = currentLayer.name.replace(searchText, replaceText);
                    currentLayer.selected = true;
                    match = true;
                }
            } catch (e) {
                logger(e);
            }
        }
    
        function checkLayerLocked(layer) {
            if(!layer.locked) 
                for(var parent = layer.parent; parent.typename=='Layer'; parent = parent.parent) {
                     if(parent.locked)
                        return true;
                 }
            return layer.locked;
        } 
    
        function checkLayerVisibility(layer) {
            if(layer.visible) 
            for(var parent = layer.parent; parent.typename=='Layer'; parent = parent.parent) {
                 if(!parent.visible)
                    return false;
             }
            return layer.visible;
         }
    
        startGUI();
    
        function startGUI() {
    
            var win = new Window("dialog", "Replace Layer name", undefined);
    
            win.orientation = "column";
            win.alignChildren = ["fill", "fill"];
    
            // Search
            var searchGrp = win.add("panel", undefined, "Search and Replace");
            searchGrp.orientation = "column";
            searchGrp.alignChildren = ["fill", "fill"];
    
            var titleMsgS = searchGrp.add("statictext", undefined, "Layer name to search:");
            var txt_searchText = searchGrp.add("edittext { characters: 1, justify: 'center', active: true }");
    
            txt_searchText.helpTip = "Input layer name to replace";
    
            var titleMsgR = searchGrp.add("statictext", undefined, "Layer name to replace with:");
            var txt_replaceText = searchGrp.add("edittext { characters: 1, justify: 'center', active: true }");
            txt_replaceText.helpTip = "Input layer name to replace with";
    
            // Set first text box to active
            txt_searchText.active = true;
    
            win.addEventListener ("keydown", function(kd) {enter(kd) });
    
            // Replace button
            var replaceBtn = searchGrp.add("button", undefined, "Replace");
            replaceBtn.helpTip = "Replace layer name";
            replaceBtn.onClick = function() {
                searchText = txt_searchText.text;
                replaceText = txt_replaceText.text;
    
                replace(docLayers);
                app.redraw();
            }
    
            function enter(k) {
                if (k.keyName == "Enter") {
                    searchText = txt_searchText.text;
                    replaceText = txt_replaceText.text;
    
                    replace(docLayers);
                    app.redraw();
                }
            }
    
            // Close button
            var quitBtn = win.add("button", undefined, "Close");
            quitBtn.helpTip = "Press Esc to Close";
    
            // Event listener for the quit button
            quitBtn.onClick = function() {   
                win.close();   
            }  
    
            // Centering & Show Window
            win.center();
            win.show(); 
        }
    
    
        // Prints stack trace
        function logger(e) {
            var errorMsg = "";
    
            errorMsg = errorMsg.concat("An error has occured:\n", e.line, "\n", e.message, "\n", e.stack);
            //$.writeln(errorMsg);
        }
    
    } else {
            alert("You do not have any document opened!");
    }