Package org.robotlegs.toolwindows

Source Code of org.robotlegs.toolwindows.BrowserToolWindowFactory$MyMouseAdapter

package org.robotlegs.toolwindows;

import com.intellij.lang.javascript.JavaScriptSupportLoader;
import com.intellij.lang.javascript.psi.JSFile;
import com.intellij.lang.javascript.psi.ecmal4.JSClass;
import com.intellij.lang.javascript.psi.impl.JSChangeUtil;
import com.intellij.lang.javascript.psi.impl.JSPsiImplUtils;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
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.util.IconLoader;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.table.JBTable;
import com.intellij.usages.UsageInfo2UsageAdapter;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.SortableColumnModel;
import utils.RobotlegsMappingUtils;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;

/**
* User: John Lindquist
* Date: 6/19/11
* Time: 6:15 PM
*/
public class BrowserToolWindowFactory implements ToolWindowFactory
{
    private static final String[] COLUMN_TITLES = new String[]{"Filename", "Column 1", "Column 2", "Column 3", "Column 4"};

    //extract Strings to config
    private static final String MEDIATOR_MAP = "org.robotlegs.core.IMediatorMap";
    private static final String MAP_VIEW = "mapView";

    private static final String COMMAND_MAP = "org.robotlegs.core.ICommandMap";
    private static final String MAP_EVENT = "mapEvent";

    private static final String SIGNAL_COMMAND_MAP = "org.robotlegs.core.ISignalCommandMap";
    private static final String MAP_SIGNAL_CLASS = "mapSignalClass";

    private static final String INJECTOR = "org.robotlegs.core.IInjector";
    private static final String MAP_SINGLETON = "mapSingleton";
    private static final String MAP_SINGLETON_OF = "mapSingletonOf";
    private static final String MAP_VALUE = "mapValue";
    private static final String MAP_RULE = "mapRule";
    private static final String MAP_CLASS = "mapClass";

    //tab names
    private static final String MEDIATOR_MAP_NAME = "MediatorMap";
    private static final String COMMAND_MAP_NAME = "CommandMap";
    private static final String SIGNAL_COMMAND_MAP_NAME = "SignalCommandMap";
    private static final String INJECTOR_NAME = "Injector";
    private static final String REFRESH_ALL = "Refresh All";

    private Project project;

    private String[] mediatorFunctions = new String[]{MAP_VIEW};
    private String[] commandFunctions = new String[]{MAP_EVENT};
    private String[] injectorFunctions = new String[]{MAP_SINGLETON, MAP_SINGLETON_OF, MAP_VALUE, MAP_RULE, MAP_CLASS};
    private String[] signalFunctions = new String[]{MAP_SIGNAL_CLASS};

    private UsagesRequestValues mediatorMapValues = new UsagesRequestValues(MEDIATOR_MAP, MEDIATOR_MAP_NAME, mediatorFunctions);
    private UsagesRequestValues commandMapValues = new UsagesRequestValues(COMMAND_MAP, COMMAND_MAP_NAME, commandFunctions);
    private UsagesRequestValues signalCommandMapValues = new UsagesRequestValues(SIGNAL_COMMAND_MAP, SIGNAL_COMMAND_MAP_NAME, signalFunctions);
    private UsagesRequestValues injectorValues = new UsagesRequestValues(INJECTOR, INJECTOR_NAME, injectorFunctions);

    private UsagesRequestValues[] values = new UsagesRequestValues[]{mediatorMapValues, commandMapValues, signalCommandMapValues, injectorValues};
    private ContentManager contentManager;

    public void createToolWindowContent(Project project, ToolWindow toolWindow)
    {
        this.project = project;
        contentManager = toolWindow.getContentManager();

        refreshValues();
    }

    private void refreshValues()
    {
        contentManager.removeAllContents(true);

        for (UsagesRequestValues value : values)
        {
            Vector<UsageMapping> usageMappings = RobotlegsMappingUtils.getMappingByClassAndFunctionProject(project, value.getClassQName(), value.getFunctions());
            Content content = createTable(project, contentManager, usageMappings, value.getTabName());
        }
    }

    private Content createTable(Project project, ContentManager contentManager, Vector<UsageMapping> usageMappings, String tableName)
    {
        final Vector<Vector> names = new Vector<Vector>();
        final Vector<Vector> dataRows = new Vector<Vector>();

        prepareTableData(usageMappings, dataRows, names);

        if (names.size() > 0)
        {
            AbstractTableModel tableModel = new MappingsTableModel(names);
            final JBTable table = new JBTable(tableModel);
            table.setCellSelectionEnabled(true);
            table.setAutoCreateRowSorter(true);

            JPanel jPanel = new JPanel();
            jPanel.setLayout(new BorderLayout());
            JButton button = new JButton(REFRESH_ALL, IconLoader.getIcon("/vcs/refresh.png"));
            button.addMouseListener(new MouseAdapter()
            {
                @Override public void mouseClicked(MouseEvent e)
                {
                    refreshValues();
                }
            });
            jPanel.add(button, BorderLayout.NORTH);

            JBScrollPane jbScrollPane = new JBScrollPane(table);
            jbScrollPane.getVerticalScrollBar().setUnitIncrement(16);

            jPanel.add(jbScrollPane, BorderLayout.CENTER);

            Content content = ContentFactory.SERVICE.getInstance().createContent(jPanel, tableName, false);
            contentManager.addContent(content);

            table.addMouseListener(new MyMouseAdapter(table, dataRows, project));
            table.setEnableAntialiasing(true);

            return content;
        }

        return null;
    }

    private void prepareTableData(Vector<UsageMapping> usageMappings, Vector<Vector> dataRows, Vector<Vector> names)
    {
        for (UsageMapping usageMapping : usageMappings)
        {
            Vector<String> column = new Vector<String>();
            Vector<Object> dataColumn = new Vector<Object>();

            PsiFile psiFile = usageMapping.getUsage().getElement().getContainingFile();
            column.add(psiFile.getName()); //todo: reconsider how to approach getting names of files
            dataColumn.add(usageMapping.getUsage());

            Vector<PsiElement> mappedElements = usageMapping.getMappedElements();
            for (PsiElement mapping : mappedElements)
            {
                if (mapping instanceof PsiNamedElement)
                {
                    column.add(((PsiNamedElement) mapping).getName());
                }
                else
                {
                    column.add(mapping.getText());
                }
                dataColumn.add(mapping);
            }

            names.add(column);
            dataRows.add(dataColumn);
        }
    }

    private class MyMouseAdapter extends MouseAdapter
    {
        private final JBTable table;
        private final Vector<Vector> dataRows;
        private final Project project;

        public MyMouseAdapter(JBTable table, Vector<Vector> dataRows, Project project)
        {
            this.table = table;
            this.dataRows = dataRows;
            this.project = project;
        }

        @Override public void mouseClicked(final MouseEvent e)
        {
            int row = table.rowAtPoint(e.getPoint());
            int column = table.columnAtPoint(e.getPoint());
            Object selectionName = table.getValueAt(row, column);
            System.out.print(selectionName + "\n");

            Object itemUnderMouse = null;

            for (Vector rowVector : dataRows)
            {
                if (column < rowVector.size())
                {
                    Object columnItem = rowVector.get(column);
                    String itemName = "";

                    if (columnItem instanceof UsageInfo2UsageAdapter)
                    {
                        UsageInfo2UsageAdapter usageAdapter = (UsageInfo2UsageAdapter) columnItem;
                        itemName = usageAdapter.getElement().getContainingFile().getName();
                    }

                    if (columnItem instanceof PsiNamedElement)
                    {
                        PsiNamedElement psiElement = (PsiNamedElement) columnItem;
                        itemName = psiElement.getName();
                    }
                    else if (columnItem instanceof PsiElement)
                    {
                        PsiElement psiElement = (PsiElement) columnItem;
                        itemName = psiElement.getText();
                    }

                    if (itemName.equals(selectionName))
                    {
                        itemUnderMouse = columnItem;
                        break;
                    }
                }
            }

            if (SwingUtilities.isLeftMouseButton(e))
            {
                if (itemUnderMouse instanceof PsiElement)
                {
                    PsiElement psiElement = (PsiElement) itemUnderMouse;
                    VirtualFile virtualFile = psiElement.getContainingFile().getVirtualFile();
                    FileEditorManager.getInstance(project).openFile(virtualFile, true);
                    Editor selectedTextEditor = FileEditorManager.getInstance(project).getSelectedTextEditor();

                    selectedTextEditor.getCaretModel().moveToOffset(psiElement.getTextOffset());
                    selectedTextEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
                }

                if (itemUnderMouse instanceof UsageInfo2UsageAdapter)
                {
                    UsageInfo2UsageAdapter usageAdapter = (UsageInfo2UsageAdapter) itemUnderMouse;
                    VirtualFile virtualFile = usageAdapter.getFile();
                    FileEditorManager.getInstance(project).openFile(virtualFile, true);
                    Editor selectedTextEditor = FileEditorManager.getInstance(project).getSelectedTextEditor();

                    selectedTextEditor.getCaretModel().moveToOffset(usageAdapter.getUsageInfo().getNavigationOffset());
                    selectedTextEditor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
                }
            }


            if (SwingUtilities.isRightMouseButton(e) && itemUnderMouse != null)
            {
                ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.TODO_VIEW_TOOLBAR, createActionGroup(selectionName, itemUnderMouse));
                popupMenu.getComponent().show(table, table.getMousePosition().x, table.getMousePosition().y);

            }
        }
    }

    private ActionGroup createActionGroup(Object selectionName, final Object itemUnderMouse)
    {
        DefaultActionGroup group = new DefaultActionGroup();

        Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
        final PsiFile targetFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());

        group.add(new InjectClassIntoEditorAction(selectionName, targetFile, itemUnderMouse));

        return group;
    }

    private static class MappingsTableModel extends AbstractTableModel implements SortableColumnModel
    {
        private final Vector<Vector> rowNames;

        public MappingsTableModel(Vector<Vector> rowNames)
        {
            this.rowNames = rowNames;
        }

        public int getRowCount()
        {
            return rowNames.size();
        }

        public int getColumnCount()
        {
            return 5;
        }

        @Override
        public String getColumnName(int column)
        {
            return COLUMN_TITLES[column];
        }

        public Object getValueAt(int rowIndex, int columnIndex)
        {
            Vector rows = rowNames.get(rowIndex);
            //if there isn't enough data to fill the column, then return ""
            if (columnIndex < rows.size())
            {
                return rows.get(columnIndex);
            }
            return "";
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return String.class;
        }

        public ColumnInfo[] getColumnInfos()
        {
            return new ColumnInfo[0]//To change body of implemented methods use File | Settings | File Templates.
        }

        public void setSortable(boolean b)
        {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        public boolean isSortable()
        {
            return true;
        }

        public Object getRowValue(int i)
        {
            return null//To change body of implemented methods use File | Settings | File Templates.
        }

        public RowSorter.SortKey getDefaultSortKey()
        {
            return null//To change body of implemented methods use File | Settings | File Templates.
        }
    }

    private class InjectSelectedClassIntoEditorClass implements Runnable
    {
        private final PsiFile targetFile;
        private final Object itemUnderMouse;

        public InjectSelectedClassIntoEditorClass(PsiFile targetFile, Object itemUnderMouse)
        {
            this.targetFile = targetFile;
            this.itemUnderMouse = itemUnderMouse;
        }

        public void run()
        {
            JSClass editorClass = JSPsiImplUtils.findClass((JSFile) targetFile);
            JSClass jsClass = (JSClass) itemUnderMouse;
            String nameOfInjectedClass = jsClass.getName();
            JSFile containingFile = (JSFile) jsClass.getContainingFile();
            String importStatement = "import " + JSPsiImplUtils.findPackageStatement(containingFile).getQualifiedName() + "." + jsClass.getName();
            PsiElement importLine = JSChangeUtil.createJSTreeFromText(project, importStatement, JavaScriptSupportLoader.ECMA_SCRIPT_L4).getPsi();
            editorClass.addBefore(importLine, editorClass.getFirstChild());

            String lowercaseNameOfClass = nameOfInjectedClass.substring(0, 1).toLowerCase() + nameOfInjectedClass.substring(1, nameOfInjectedClass.length());

            String statement = "[Inject]\npublic var " + lowercaseNameOfClass + ":" + nameOfInjectedClass + ";";
            PsiElement field = JSChangeUtil.createJSTreeFromText(project, statement, JavaScriptSupportLoader.ECMA_SCRIPT_L4).getPsi();
            placeFieldInClass(editorClass, field);

            PsiDocumentManager.getInstance(project).commitAllDocuments();
        }

        private void placeFieldInClass(JSClass editorClass, PsiElement injectedField)
        {
            if (editorClass.getConstructor() != null)
            {
                editorClass.addBefore(injectedField, editorClass.getConstructor());
            }
            else if (editorClass.getFunctions() != null)
            {
                editorClass.addBefore(injectedField, editorClass.getFunctions()[0]);
            }
            else if (editorClass.getFields() != null)
            {
                editorClass.addBefore(injectedField, editorClass.getFields()[editorClass.getFields().length - 1]);
            }
            else
            {
                editorClass.add(injectedField);
            }
        }
    }

    private class InjectClassIntoEditorAction extends AnAction
    {

        private final PsiFile targetFile;
        private final Object itemUnderMouse;

        public InjectClassIntoEditorAction(Object selectionName, PsiFile targetFile, Object itemUnderMouse)
        {
            super("Inject " + selectionName + " into " + targetFile.getName());
            this.targetFile = targetFile;
            this.itemUnderMouse = itemUnderMouse;
        }

        @Override public void actionPerformed(AnActionEvent e)
        {
            if (itemUnderMouse instanceof PsiElement)
            {
                CommandProcessor.getInstance().executeCommand(project, new Runnable()
                {
                    public void run()
                    {
                        ApplicationManager.getApplication().runWriteAction(new InjectSelectedClassIntoEditorClass(targetFile, itemUnderMouse));
                    }
                }, "Inject Class as Field into File", null);

            }
        }
    }

    private class UsagesRequestValues
    {
        private String classQName;
        private String tabName;
        private String[] functions;

        public String getClassQName()
        {
            return classQName;
        }

        public String getTabName()
        {
            return tabName;
        }

        public String[] getFunctions()
        {
            return functions;
        }

        public UsagesRequestValues(String classQName, String tabName, String[] functions)
        {
            this.classQName = classQName;
            this.tabName = tabName;
            this.functions = functions;
        }
    }
}
TOP

Related Classes of org.robotlegs.toolwindows.BrowserToolWindowFactory$MyMouseAdapter

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.