Package altn8.filechooser

Source Code of altn8.filechooser.AlternateFilePopupChooser

/*
* Copyright 2012 The AltN8-Team
*
* Licensed 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 altn8.filechooser;

import altn8.AlternateFileGroup;
import com.intellij.ide.util.gotoByName.GotoFileCellRenderer;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.psi.PsiFile;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
* @see #prompt(String, List, Project, FileHandler)
*/
public final class AlternateFilePopupChooser {
    /**
     * only static methods
     */
    private AlternateFilePopupChooser() {
    }

    /**
     * Let user choose from a list of files and do something with it. If only one item is present, the file will be processed
     * directly without user prompt. Nothing happens with an emtpy list.
     *
     * @param title          Popup's title
     * @param fileGroups     List of fileGroups
     * @param currentProject
     * @param fileHandler    FileHandler to process choosed files
     */
    public static void prompt(String title, List<AlternateFileGroup> fileGroups, Project currentProject, final FileHandler fileHandler) {
        if (fileGroups != null && !fileGroups.isEmpty()) {
            // if we have only one group with 1 file...
            if (fileGroups.size() == 1 && fileGroups.get(0).getFiles().size() == 1) {
                // ...then open file directly
                fileHandler.processFile(fileGroups.get(0).getFiles().get(0));
            } else {
                // let user choose...

                // list of Objects for out JList
                List<Object> list = new ArrayList<Object>();

                // if we have only 1 group, we dont show title, just adding all PsiFiles
                if (fileGroups.size() == 1) {
                    list.addAll(fileGroups.get(0).getFiles());
                } else {
                    // go thru all groups
                    for (AlternateFileGroup fileGroup : fileGroups) {
                        // add basefilename (will be presented as title) and all files
                        list.add(fileGroup.getGroupTitle());
                        list.addAll(fileGroup.getFiles());
                    }
                }

                final JList valueList = new JList(list.toArray());
                valueList.setCellRenderer(new AlternateCellRenderer(currentProject));
                valueList.setSelectionModel(new AlternateListSelectionModel(list));

                PopupChooserBuilder listPopupBuilder = JBPopupFactory.getInstance().createListPopupBuilder(valueList);
                listPopupBuilder.setTitle(title);
                listPopupBuilder.setItemChoosenCallback(new Runnable() {
                    public void run() {
                        for (Object item : valueList.getSelectedValues()) {
                            if (item instanceof PsiFile) {
                                fileHandler.processFile((PsiFile) item);
                            }
                        }
                    }
                });
                listPopupBuilder.createPopup().showCenteredInCurrentWindow(currentProject);
            }
        }
    }

    /**
     * CellRenderer, renders PsiFile with ideas GotoFileCellRenderer and all other with DefaultListCellRenderer like a title (bgcolor: control)
     */
    static class AlternateCellRenderer extends DefaultListCellRenderer {
        private ListCellRenderer gotoFileCellRenderer;

        AlternateCellRenderer(Project project) {
            this.gotoFileCellRenderer = new GotoFileCellRenderer(WindowManagerEx.getInstanceEx().getFrame(project).getSize().width);
        }

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            if (value instanceof PsiFile) {
                return gotoFileCellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            } else {
                if (value.toString().length() == 0) {
                    value = " "; // we need a caracter to have correct height
                }
                Component c = super.getListCellRendererComponent(list, value, index, false, cellHasFocus);
                c.setBackground(UIManager.getColor("control"));
                return c;
            }
        }
    }

    /**
     * Selection model accepts only PsiFile for selecting (no group headers)
     */
    static class AlternateListSelectionModel extends DefaultListSelectionModel {
        private List<Object> list;
        private int first = -1;
        private int last = -1;
        private int current0 = -1;
        private int current1 = -1;

        AlternateListSelectionModel(List<Object> list) {
            this.list = list;
            // first psiFile in list
            for (int i = 0, listSize = list.size(); i < listSize; i++) {
                if (list.get(i) instanceof PsiFile){
                    first = i;
                    break;
                }
            }
            // last psiFile in list
            for (int i = list.size() - 1; i >= 0; i--) {
                if (list.get(i) instanceof PsiFile){
                    last = i;
                    break;
                }
            }
        }

        @Override
        public void addSelectionInterval(int index0, int index1) {
            adjustCurrent(index0, index1);
            super.addSelectionInterval(current0, current1);
        }

        @Override
        public void setSelectionInterval(int index0, int index1) {
            adjustCurrent(index0, index1);
            super.setSelectionInterval(current0, current1);
        }

        private void adjustCurrent(int index0, int index1) {
            if (index0 == index1) {
                // single line select
                current0 = calcIndex(current0, index0, true);
                current1 = current0;
            } else {
                // multiline select
                current0 = calcIndex(current0, index0, false);
                current1 = calcIndex(current1, index1, false);
            }
        }

        private int calcIndex(int current, int newIndex, boolean cycle) {
            // we was on first item and go to last
            if (cycle && current == first && (newIndex < current || newIndex == list.size() - 1)) {
                return last;
            }
            // we was on last item and go to first
            if (cycle && current == last && (newIndex > current || newIndex == 0)) {
                return first;
            }
            // next
            if (current < newIndex) {
                current = newIndex;
                while (current < list.size() && !(list.get(current) instanceof PsiFile)) {
                    current++;
                }
            } else if (current > newIndex) {
                // previous
                current = newIndex;
                while (current >= 0 && !(list.get(current) instanceof PsiFile)) {
                    current--;
                }
            }
            return current;
        }
    }
}
TOP

Related Classes of altn8.filechooser.AlternateFilePopupChooser

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.