com.intellij.application.options.codeStyle.ManageCodeStyleSchemesDialog.java Source code

Java tutorial

Introduction

Here is the source code for com.intellij.application.options.codeStyle.ManageCodeStyleSchemesDialog.java

Source

/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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 com.intellij.application.options.codeStyle;

import com.intellij.application.options.ImportSchemeChooserDialog;
import com.intellij.application.options.ImportSourceChooserDialog;
import com.intellij.application.options.SaveSchemeDialog;
import com.intellij.application.options.SchemesToImportPopup;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDialog;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.options.SchemeImportException;
import com.intellij.openapi.options.SchemeImporter;
import com.intellij.openapi.options.SchemeImporterEP;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.BalloonBuilder;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.codeStyle.CodeStyleScheme;
import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.table.JBTable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: rvishnyakov
 */
public class ManageCodeStyleSchemesDialog extends DialogWrapper {
    private JPanel myContentPane;
    private JBTable mySchemesTable;
    private JButton myDeleteButton;
    private JButton mySaveAsButton;
    private JButton myCopyToProjectButton;
    private JButton myCloseButton;
    private JButton myExportButton;
    private JButton myImportButton;
    private final MySchemesTableModel mySchemesTableModel;
    private final CodeStyleSchemesModel myModel;
    private final Component myParent;

    protected ManageCodeStyleSchemesDialog(final Component parent, CodeStyleSchemesModel schemesModel) {
        super(parent, true);
        myParent = parent;
        myModel = schemesModel;
        setTitle("Code Style Schemes");
        mySchemesTableModel = new MySchemesTableModel(schemesModel);
        mySchemesTable.setModel(mySchemesTableModel);
        mySchemesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        mySchemesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(@NotNull ListSelectionEvent e) {
                updateActions();
            }
        });
        setDefaultSelection();

        myDeleteButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(@NotNull ActionEvent e) {
                deleteSelected();
            }
        });
        mySaveAsButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(@NotNull ActionEvent e) {
                onSaveAs();
            }
        });
        myCopyToProjectButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(@NotNull ActionEvent e) {
                onCopyToProject();
            }
        });
        myCloseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(@NotNull ActionEvent e) {
                doCancelAction();
            }
        });

        myExportButton.setVisible(false);

        if (SchemeImporterEP.getExtensions(CodeStyleScheme.class).isEmpty()) {
            myImportButton.setVisible(false);
        } else {
            myImportButton.setVisible(true);
            myImportButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(@NotNull final ActionEvent e) {
                    chooseAndImport();
                }
            });
        }

        init();
    }

    private void chooseAndImport() {
        ImportSourceChooserDialog<CodeStyleScheme> importSourceChooserDialog = new ImportSourceChooserDialog<CodeStyleScheme>(
                myContentPane, CodeStyleScheme.class);
        if (importSourceChooserDialog.showAndGet()) {
            if (importSourceChooserDialog.isImportFromSharedSelected()) {
                new SchemesToImportPopup<CodeStyleScheme>(myContentPane) {
                    @Override
                    protected void onSchemeSelected(CodeStyleScheme scheme) {
                        if (scheme != null) {
                            myModel.addScheme(scheme, true);
                        }
                    }
                }.show(myModel.getSchemes());
            } else {
                String selectedImporterName = importSourceChooserDialog.getSelectedSourceName();
                if (selectedImporterName != null) {
                    try {
                        String schemeName = importExternalCodeStyle(selectedImporterName);
                        if (schemeName != null) {
                            showStatus(myImportButton,
                                    ApplicationBundle.message("message.code.style.scheme.import.success",
                                            selectedImporterName, schemeName),
                                    MessageType.INFO);
                        }
                    } catch (SchemeImportException e) {
                        showStatus(myImportButton,
                                ApplicationBundle.message("message.code.style.scheme.import.failure",
                                        selectedImporterName, e.getMessage()),
                                MessageType.ERROR);
                    }
                }
            }
        }
    }

    private static void showStatus(final Component component, final String message, MessageType messageType) {
        BalloonBuilder balloonBuilder = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(message,
                messageType.getDefaultIcon(), messageType.getPopupBackground(), null);
        balloonBuilder.setFadeoutTime(5000);
        final Balloon balloon = balloonBuilder.createBalloon();
        final Rectangle rect = component.getBounds();
        final Point p = new Point(rect.x, rect.y + rect.height);
        final RelativePoint point = new RelativePoint(component, p);
        balloon.show(point, Balloon.Position.below);
        Disposer.register(ProjectManager.getInstance().getDefaultProject(), balloon);
    }

    @Nullable
    private String importExternalCodeStyle(String importerName) throws SchemeImportException {
        final SchemeImporter<CodeStyleScheme> importer = SchemeImporterEP.getImporter(importerName,
                CodeStyleScheme.class);
        if (importer != null) {
            FileChooserDialog fileChooser = FileChooserFactory.getInstance()
                    .createFileChooser(new FileChooserDescriptor(true, false, false, false, false, false) {
                        @Override
                        public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
                            return file.isDirectory() || importer.getSourceExtension().equals(file.getExtension());
                        }

                        @Override
                        public boolean isFileSelectable(VirtualFile file) {
                            return !file.isDirectory() && importer.getSourceExtension().equals(file.getExtension());
                        }
                    }, null, myContentPane);
            VirtualFile[] selection = fileChooser.choose(null,
                    CodeStyleSchemesUIConfiguration.Util.getRecentImportFile());
            if (selection.length == 1) {
                VirtualFile selectedFile = selection[0];
                selectedFile.refresh(false, false);
                CodeStyleSchemesUIConfiguration.Util.setRecentImportFile(selectedFile);
                try {
                    InputStream nameInputStream = selectedFile.getInputStream();
                    String[] schemeNames;
                    try {
                        schemeNames = importer.readSchemeNames(nameInputStream);
                    } finally {
                        nameInputStream.close();
                    }
                    CodeStyleScheme currScheme = myModel.getSelectedScheme();
                    ImportSchemeChooserDialog schemeChooserDialog = new ImportSchemeChooserDialog(myContentPane,
                            schemeNames, !currScheme.isDefault() ? currScheme.getName() : null);
                    if (schemeChooserDialog.showAndGet()) {
                        String schemeName = schemeChooserDialog.getSelectedName();
                        String targetName = schemeChooserDialog.getTargetName();
                        CodeStyleScheme targetScheme = null;
                        if (schemeChooserDialog.isUseCurrentScheme()) {
                            targetScheme = myModel.getSelectedScheme();
                        } else {
                            if (targetName == null)
                                targetName = ApplicationBundle.message("code.style.scheme.import.unnamed");
                            for (CodeStyleScheme scheme : myModel.getSchemes()) {
                                if (targetName.equals(scheme.getName())) {
                                    targetScheme = scheme;
                                    break;
                                }
                            }
                            if (targetScheme == null) {
                                int row = mySchemesTableModel.createNewScheme(getSelectedScheme(), targetName);
                                mySchemesTable.getSelectionModel().setSelectionInterval(row, row);
                                targetScheme = mySchemesTableModel.getSchemeAt(row);
                            } else {
                                int result = Messages.showYesNoDialog(myContentPane,
                                        ApplicationBundle.message("message.code.style.scheme.already.exists",
                                                targetName),
                                        ApplicationBundle.message("title.code.style.settings.import"),
                                        Messages.getQuestionIcon());
                                if (result != Messages.YES) {
                                    return null;
                                }
                            }
                        }
                        InputStream dataInputStream = selectedFile.getInputStream();
                        try {
                            importer.importScheme(dataInputStream, schemeName, targetScheme);
                            myModel.fireSchemeChanged(targetScheme);
                        } finally {
                            dataInputStream.close();
                        }
                        return targetScheme.getName();
                    }
                } catch (IOException e) {
                    throw new SchemeImportException(e);
                }
            }
        }
        return null;
    }

    private void updateActions() {
        CodeStyleScheme selectedScheme = getSelectedScheme();
        myDeleteButton
                .setEnabled(!(selectedScheme.isDefault() || mySchemesTableModel.isProjectScheme(selectedScheme)));
        myCopyToProjectButton.setEnabled(!mySchemesTableModel.isProjectScheme(selectedScheme));
    }

    @NotNull
    private CodeStyleScheme getSelectedScheme() {
        int row = mySchemesTable.getSelectedRow();
        assert row >= 0;
        return mySchemesTableModel.getSchemeAt(row);
    }

    @NotNull
    @Override
    protected Action[] createActions() {
        return new Action[] {};
    }

    private void deleteSelected() {
        int row = mySchemesTable.getSelectedRow();
        if (row >= 0) {
            int rowToSelect = row + 1;
            if (rowToSelect >= mySchemesTableModel.getRowCount()) {
                rowToSelect = mySchemesTableModel.getDefaultRow();
            }
            mySchemesTable.getSelectionModel().setSelectionInterval(rowToSelect, rowToSelect);
            mySchemesTableModel.deleteAt(row);
        }
    }

    @Override
    protected JComponent createCenterPanel() {
        return myContentPane;
    }

    private void createUIComponents() {
        mySchemesTable = new MySchemesTable();
    }

    private class MySchemesTable extends JBTable {
        private final TableCellRenderer myFixedItemsRenderer;

        private MySchemesTable() {
            myFixedItemsRenderer = new DefaultTableCellRenderer() {
                @NotNull
                @Override
                public Component getTableCellRendererComponent(@NotNull JTable table, Object value,
                        boolean isSelected, boolean hasFocus, int row, int column) {
                    Component defaultComponent = super.getTableCellRendererComponent(table, value, isSelected,
                            hasFocus, row, column);
                    if (value instanceof CodeStyleScheme) {
                        CodeStyleScheme scheme = (CodeStyleScheme) value;
                        if (scheme.isDefault() || myModel.isProjectScheme(scheme)) {
                            defaultComponent.setFont(defaultComponent.getFont().deriveFont(Font.BOLD));
                        }
                    }
                    return defaultComponent;
                }
            };
        }

        @Override
        public TableCellRenderer getCellRenderer(int row, int column) {
            return myFixedItemsRenderer;
        }
    }

    private static class MySchemesTableModel extends AbstractTableModel {
        private final CodeStyleSchemesModel mySchemesModel;
        private final List<CodeStyleScheme> mySchemes;

        public MySchemesTableModel(CodeStyleSchemesModel schemesModel) {
            mySchemesModel = schemesModel;
            mySchemes = new ArrayList<CodeStyleScheme>();
            updateSchemes();
        }

        @NotNull
        @Override
        public String getColumnName(int column) {
            assert column == 0;
            return "Name";
        }

        @Override
        public int getRowCount() {
            return mySchemes.size();
        }

        @Override
        public int getColumnCount() {
            return 1;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            assert columnIndex == 0;
            return mySchemes.get(rowIndex);
        }

        public CodeStyleScheme getSchemeAt(int row) {
            return mySchemes.get(row);
        }

        public void deleteAt(int row) {
            CodeStyleScheme scheme = mySchemes.get(row);
            mySchemesModel.removeScheme(scheme);
            updateSchemes();
            fireTableRowsDeleted(row, row);
        }

        public int createNewScheme(CodeStyleScheme selectedScheme, String schemeName) {
            CodeStyleScheme newScheme = mySchemesModel.createNewScheme(schemeName, selectedScheme);
            mySchemesModel.addScheme(newScheme, true);
            updateSchemes();
            int row = 0;
            for (CodeStyleScheme scheme : mySchemes) {
                if (scheme == newScheme) {
                    fireTableRowsInserted(row, row);
                    break;
                }
                row++;
            }
            return row;
        }

        public int getDefaultRow() {
            int row = 0;
            for (CodeStyleScheme scheme : mySchemes) {
                if (scheme.isDefault())
                    return row;
                row++;
            }
            return 0;
        }

        public void copyToProject(CodeStyleScheme scheme) {
            mySchemesModel.copyToProject(scheme);
            int switchToProject = Messages.showYesNoDialog(
                    "Scheme '" + scheme.getName() + "' was copied to be used as the project scheme.\n"
                            + "Switch to this created scheme?",
                    "Copy Scheme to Project", Messages.getQuestionIcon());
            if (switchToProject == Messages.YES) {
                mySchemesModel.setUsePerProjectSettings(true, true);
            }
        }

        public int exportProjectScheme() {
            String name = Messages.showInputDialog("Enter new scheme name:", "Copy Project Scheme to Global List",
                    Messages.getQuestionIcon());
            if (name != null && !CodeStyleSchemesModel.PROJECT_SCHEME_NAME.equals(name)) {
                CodeStyleScheme newScheme = mySchemesModel.exportProjectScheme(name);
                updateSchemes();
                int switchToGlobal = Messages.showYesNoDialog(
                        "Project scheme was copied to global scheme list as '" + newScheme.getName() + "'.\n"
                                + "Switch to this created scheme?",
                        "Copy Project Scheme to Global List", Messages.getQuestionIcon());
                if (switchToGlobal == Messages.YES) {
                    mySchemesModel.setUsePerProjectSettings(false);
                    mySchemesModel.selectScheme(newScheme, null);
                }
                int row = 0;
                for (CodeStyleScheme scheme : mySchemes) {
                    if (scheme == newScheme) {
                        fireTableRowsInserted(row, row);
                        return switchToGlobal == 0 ? row : -1;
                    }
                    row++;
                }
            }
            return -1;
        }

        private void updateSchemes() {
            mySchemes.clear();
            mySchemes.addAll(mySchemesModel.getAllSortedSchemes());
        }

        public boolean isProjectScheme(CodeStyleScheme scheme) {
            return mySchemesModel.isProjectScheme(scheme);
        }

    }

    private void onSaveAs() {
        if (mySchemesTableModel.isProjectScheme(getSelectedScheme())) {
            int rowToSelect = mySchemesTableModel.exportProjectScheme();
            if (rowToSelect > 0) {
                mySchemesTable.getSelectionModel().setSelectionInterval(rowToSelect, rowToSelect);
            }
        } else {
            CodeStyleScheme[] schemes = CodeStyleSchemes.getInstance().getSchemes();
            ArrayList<String> names = new ArrayList<String>();
            for (CodeStyleScheme scheme : schemes) {
                names.add(scheme.getName());
            }
            String selectedName = getSelectedScheme().getName();
            SaveSchemeDialog saveDialog = new SaveSchemeDialog(myParent,
                    ApplicationBundle.message("title.save.code.style.scheme.as"), names, selectedName);
            if (saveDialog.showAndGet()) {
                int row = mySchemesTableModel.createNewScheme(getSelectedScheme(), saveDialog.getSchemeName());
                mySchemesTable.getSelectionModel().setSelectionInterval(row, row);
            }
        }
    }

    private void onCopyToProject() {
        mySchemesTableModel.copyToProject(getSelectedScheme());
    }

    private void setDefaultSelection() {
        CodeStyleScheme selectedScheme = myModel.getSelectedScheme();
        for (int i = 0; i < mySchemesTableModel.getRowCount(); i++) {
            if (mySchemesTableModel.getSchemeAt(i).equals(selectedScheme)) {
                mySchemesTable.getSelectionModel().setSelectionInterval(i, i);
                return;
            }
        }
    }

}