All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jlibs.nblr.editor.actions.EdgePopupProvider Maven / Gradle / Ivy

/**
 * Copyright 2015 Santhosh Kumar Tekuri
 *
 * The JLibs authors license this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package jlibs.nblr.editor.actions;

import jlibs.nblr.editor.MatcherChooser;
import jlibs.nblr.editor.RuleChooser;
import jlibs.nblr.editor.RuleScene;
import jlibs.nblr.matchers.Matcher;
import jlibs.nblr.rules.Edge;
import jlibs.nblr.rules.Node;
import jlibs.nblr.rules.RuleTarget;
import org.netbeans.api.visual.action.PopupMenuProvider;
import org.netbeans.api.visual.widget.Widget;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;

/**
 * @author Santhosh Kumar T
 */
public class EdgePopupProvider implements PopupMenuProvider{
    private RuleScene scene;
    public EdgePopupProvider(RuleScene scene){
        this.scene = scene;
    }

    private Edge edge;
    public JPopupMenu getPopupMenu(Widget widget, Point localLocation){
        edge = (Edge)scene.findObject(widget);

        JMenu insertMenu = new JMenu("Insert Node");
        insertMenu.add(insertBeforeEdgeAction);
        insertMenu.add(insertAfterEdgeAction);

        JPopupMenu popup = new JPopupMenu();
        popup.add(insertMenu);
        popup.add(setMatcherAction);
        popup.add(setRuleAction);
        popup.add(toggleFallBackAction);
        popup.add(inlineRuleAction);
        popup.add(clearAction);
        
        int count = edge.source.outgoing.size();
        for(Edge e: edge.source.outgoing){
            if(e.loop())
                count--;
        }
        if(count>1){
            popup.addSeparator();
            popup.add(moveUpAction);
            popup.add(moveDownAction);
        }

        popup.addSeparator();
        popup.add(deleteEdgeAction);
        return popup;
    }

    private Action setMatcherAction = new AbstractAction("Set Matcher..."){
        @Override
        public void actionPerformed(ActionEvent ae){
            Window owner = SwingUtilities.getWindowAncestor(scene.getView());
            Matcher matcher = MatcherChooser.prompt(owner, scene.getSyntax());
            if(matcher!=null){
                edge.matcher = matcher;
                edge.ruleTarget = null;
                scene.refresh();
            }
        }
    };

    private Action setRuleAction = new AbstractAction("Set Rule..."){
        @Override
        public void actionPerformed(ActionEvent ae){
            Window owner = SwingUtilities.getWindowAncestor(scene.getView());
            RuleTarget ruleTarget = RuleChooser.prompt(owner, scene.getSyntax());
            if(ruleTarget!=null){
                edge.ruleTarget = ruleTarget;
                edge.matcher = null;
                scene.refresh();
            }
        }

        @Override
        public boolean isEnabled(){
            return scene.getSyntax().rules.size()>1;
        }
    };

    private Action clearAction = new AbstractAction("Clear..."){
        @Override
        public void actionPerformed(ActionEvent ae){
            edge.matcher = null;
            edge.ruleTarget = null;
            edge.fallback = false;
            scene.refresh();
        }

        @Override
        public boolean isEnabled(){
            return edge.matcher!=null || edge.ruleTarget!=null;
        }
    };

    private Action insertAfterEdgeAction = new AbstractAction("After This"){
        @Override
        public void actionPerformed(ActionEvent ae){
            Node target = edge.target;
            Node newNode = new Node();
            newNode.addEdgeTo(target);
            edge.setTarget(newNode);
            scene.refresh();
        }
    };

    private Action insertBeforeEdgeAction = new AbstractAction("Before This"){
        @Override
        public void actionPerformed(ActionEvent ae){
            Node source = edge.source;
            Node newNode = new Node();
            newNode.addEdgeFrom(source);
            edge.setSource(newNode);
            scene.refresh();
        }
    };

    private Action deleteEdgeAction = new AbstractAction("Delete"){
        @Override
        public void actionPerformed(ActionEvent ae){
            edge.setSource(null);
            edge.setTarget(null);
            scene.refresh();
        }

        @Override
        public boolean isEnabled(){
            if(edge.loop())
                return true;
            else{
                if(edge.target==scene.getRule().node)
                    return true;

                // if node has atleast one incoming edge which is not loop, then we can delete
                for(Edge e: edge.target.incoming()){
                    if(e!=edge && !e.loop())
                        return true;
                }
            }
            return false;
        }
    };

    private Action toggleFallBackAction = new AbstractAction("Toggle Fallback"){
        @Override
        public void actionPerformed(ActionEvent ae){
            if(!edge.fallback){
                for(Edge e: edge.source.outgoing){
                    if(e!=edge)
                        e.fallback = false;
                }
            }
            edge.fallback = !edge.fallback;
            scene.refresh();
        }

        @Override
        public boolean isEnabled(){
            return edge.matcher!=null || edge.ruleTarget!=null;
        }
    };

    private Action inlineRuleAction = new AbstractAction("Inline Rule"){
        @Override
        public void actionPerformed(ActionEvent ae){
            edge.inlineRule();
            scene.refresh();
        }

        @Override
        public boolean isEnabled(){
            return edge.ruleTarget!=null && edge.ruleTarget.name==null;
        }
    };

    public Action moveUpAction = new AbstractAction("Move Up"){
        @Override
        public void actionPerformed(ActionEvent ae){
            int index = edge.source.outgoing.indexOf(edge);
            int another = index;
            do{
                another--;
            }while(edge.source.outgoing.get(another).loop());

            edge.source.outgoing.set(index, edge.source.outgoing.get(another));
            edge.source.outgoing.set(another, edge);
            scene.refresh();
        }

        @Override
        public boolean isEnabled(){
            int another = edge.source.outgoing.indexOf(edge);
            do{
                another--;
            }while(another>=0 && edge.source.outgoing.get(another).loop());
            return another>=0;
        }
    };

    public Action moveDownAction = new AbstractAction("Move Down"){
        @Override
        public void actionPerformed(ActionEvent ae){
            int index = edge.source.outgoing.indexOf(edge);
            int another = index;
            do{
                another++;
            }while(edge.source.outgoing.get(another).loop());

            edge.source.outgoing.set(index, edge.source.outgoing.get(another));
            edge.source.outgoing.set(another, edge);
            scene.refresh();
        }

        @Override
        public boolean isEnabled(){
            int another = edge.source.outgoing.indexOf(edge);
            do{
                another++;
            }while(another




© 2015 - 2025 Weber Informatics LLC | Privacy Policy