Package actions

Source Code of actions.ToggleToMappedClassAction

package actions;

import com.intellij.lang.javascript.flex.XmlBackedJSClassImpl;
import com.intellij.lang.javascript.psi.JSElement;
import com.intellij.lang.javascript.psi.JSFile;
import com.intellij.lang.javascript.psi.JSVariable;
import com.intellij.lang.javascript.psi.ecmal4.JSAttributeList;
import com.intellij.lang.javascript.psi.ecmal4.JSClass;
import com.intellij.lang.javascript.psi.impl.JSPsiImplUtils;
import com.intellij.lang.javascript.psi.resolve.JSInheritanceUtil;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
import com.intellij.usages.UsageInfo2UsageAdapter;
import enums.RobotlegsEnum;
import utils.FindUsagesUtils;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.List;

/**
* User: John Lindquist
* Date: 6/23/11
* Time: 5:17 PM
*/
public class ToggleToMappedClassAction extends AnAction
{
    public void actionPerformed(AnActionEvent e)
    {
        final Project project = e.getData(LangDataKeys.PROJECT);
        PsiFile file = e.getData(LangDataKeys.PSI_FILE);

        final JSClass jsClass = getJSClassFromFile(file);

        if (jsClass != null)
        {
            for (final RobotlegsEnum classType : RobotlegsEnum.values())
            {
                //todo: determine if checking type is the best approach since Command isn't always subclassed
                if (isType(jsClass, classType.getClassQName()))
                {
                    if (classType == RobotlegsEnum.EVENT)
                    {
                        showListOfPublicStatics(project, jsClass, classType);
                        return;
                    }

                    if (openMappedElement(jsClass, classType, project))
                    {
                        return;
                    }
                }
            }
        }
    }

    private void showListOfPublicStatics(final Project project, JSClass jsClass, final RobotlegsEnum classType)
    {
        DefaultListModel model = new DefaultListModel();
        for (JSVariable jsVariable : jsClass.getFields())
        {
            if (isPublicStatic(jsVariable))
            {
                model.addElement(jsVariable);
            }
        }
        final JBList list = new JBList(model);
        list.setCellRenderer(new ListCellRenderer()
        {
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
            {
                @SuppressWarnings({"unchecked"})
                final JComponent comp = new JBLabel(((JSVariable) value).getName());
                comp.setOpaque(true);
                if (isSelected)
                {
                    comp.setBackground(list.getSelectionBackground());
                    comp.setForeground(list.getSelectionForeground());
                }
                else
                {
                    comp.setBackground(list.getBackground());
                    comp.setForeground(list.getForeground());
                }
                return comp;
            }
        });


        list.getSelectionModel().addListSelectionListener(new ListSelectionListener()
        {
            public void valueChanged(ListSelectionEvent e)
            {
                Object source = e.getSource();
                System.out.println(source.toString());
            }
        });


        /* list.addKeyListener(new KeyAdapter()
{
@Override public void keyReleased(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
     Object selectedValue = list.getSelectedValue();
     openMappedElement((JSElement) selectedValue, classType, project);
}
}
});*/


        PopupChooserBuilder popupChooserBuilder = new PopupChooserBuilder(list);
        JBPopup popup = popupChooserBuilder.createPopup();
        popup.showCenteredInCurrentWindow(project);


        list.addMouseListener(new MouseAdapter()
        {
            @Override public void mousePressed(MouseEvent e)
            {
                System.out.println(e.toString());
                openMappedElement((JSElement) list.getSelectedValue(), classType, project);
            }
        });

        list.addKeyListener(new KeyAdapter()
        {
            @Override public void keyPressed(KeyEvent e)
            {
                if (e.getKeyCode() == KeyEvent.VK_ENTER)
                {
                    System.out.println(e.toString());
                    openMappedElement((JSElement) list.getSelectedValue(), classType, project);
                }
            }
        });


        return;
    }

    private boolean isPublicStatic(JSVariable jsVariable)
    {
        JSAttributeList attributeList = jsVariable.getAttributeList();
        if (attributeList.hasModifier(JSAttributeList.ModifierType.STATIC) && attributeList.getAccessType() == JSAttributeList.AccessType.PUBLIC)
        {
            return true;
        }
        return false;
    }

    private boolean openMappedElement(JSElement jsElement, RobotlegsEnum classType, Project project)
    {
        PsiElement functionContext = findMappingFunctionContext(classType.getMappingFunction(), jsElement, project);
        if (functionContext != null)
        {
            PsiElement mappedElement = getMappedElement(functionContext, classType.getMappingParamIndex());
            openClassInEditor(project, mappedElement);
            return true;
        }
        return false;
    }

    private JSClass getJSClassFromFile(PsiFile file)
    {
        JSClass jsClass = null;
        if (file instanceof XmlFile)
        {
            jsClass = XmlBackedJSClassImpl.getXmlBackedClass(getRootTag((XmlFile) file));
        }

        if (file instanceof JSFile)
        {
            jsClass = JSPsiImplUtils.findClass((JSFile) file);
        }
        return jsClass;
    }

    private static XmlTag getRootTag(XmlFile xmlFile)
    {
        final XmlDocument document = xmlFile.getDocument();
        return document != null ? document.getRootTag() : null;
    }

    private PsiElement getMappedElement(PsiElement functionElement, int paramIndex)
    {
        PsiElement paramsElement = functionElement.getChildren()[1];

        return paramsElement.getChildren()[paramIndex];
    }

    private void openClassInEditor(Project project, PsiElement classReference)
    {
        PsiReference psiReference = (PsiReference) classReference;
        PsiFile containingFile = psiReference.resolve().getContainingFile();
        VirtualFile virtualFile = containingFile.getVirtualFile();
        FileEditorManager.getInstance(project).openFile(virtualFile, true);
        Editor selectedTextEditor = FileEditorManager.getInstance(project).getSelectedTextEditor();

        if (containingFile instanceof JSFile) //it might be an MXML file
        {
            selectedTextEditor.getCaretModel().moveToOffset(JSPsiImplUtils.findClass((JSFile) containingFile).getTextOffset());
            selectedTextEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
        }
    }

    private PsiElement findMappingFunctionContext(String functionName, JSElement jsElement, Project project)
    {
        List<UsageInfo2UsageAdapter> usages = FindUsagesUtils.findUsagesOfPsiElement(jsElement, project);
        for (UsageInfo2UsageAdapter usage : usages)
        {
            PsiElement element = usage.getElement();
            PsiElement contextOneLevelUp = element.getContext();
            if (contextOneLevelUp != null)
            {
                PsiElement contextTwoLevelsUp = contextOneLevelUp.getContext();
                if (contextTwoLevelsUp != null)
                {
                    PsiElement[] children = contextTwoLevelsUp.getChildren();
                    PsiElement psiElement = children[0].getLastChild();
                    String text = null;
                    if (psiElement != null)
                    {
                        text = psiElement.getText();
                        if (text.equals(functionName))
                        {
                            return contextTwoLevelsUp;
                        }
                    }
                }
            }
        }
        return null;
    }

    private boolean isType(JSClass jsClass, String classQName)
    {
        Collection<JSClass> parents = JSInheritanceUtil.findAllParentsForClass(jsClass, true);
        for (JSClass parent : parents)
        {
            if (parent.getQualifiedName().equals(classQName))
            {
                return true;
            }
        }
        return false;
    }

    private boolean isElementFirstParam(PsiElement element)
    {
        return element == element.getContext().getChildren()[0];
    }

    private PsiElement getParamToTheRightOfElement(PsiElement element)
    {
        PsiElement psiElement = element.getContext().getChildren()[1];

        return psiElement;
    }

    private PsiElement getParamToTheLeftOfElement(PsiElement element)
    {
        PsiElement psiElement = element.getContext().getChildren()[0];

        return psiElement;
    }
}
TOP

Related Classes of actions.ToggleToMappedClassAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.