com.perl5.lang.perl.idea.configuration.settings.sdk.Perl5SdkConfigurable.java Source code

Java tutorial

Introduction

Here is the source code for com.perl5.lang.perl.idea.configuration.settings.sdk.Perl5SdkConfigurable.java

Source

/*
 * Copyright 2015-2017 Alexandr Evstigneev
 *
 * 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.perl5.lang.perl.idea.configuration.settings.sdk;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.SdkModificator;
import com.intellij.openapi.projectRoots.impl.PerlSdkTable;
import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl;
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.InputValidator;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.ui.ColoredListCellRenderer;
import com.intellij.util.messages.MessageBusConnection;
import com.perl5.PerlBundle;
import com.perl5.PerlIcons;
import com.perl5.lang.perl.idea.configuration.settings.sdk.wrappers.Perl5RealSdkWrapper;
import com.perl5.lang.perl.idea.configuration.settings.sdk.wrappers.Perl5SdkWrapper;
import com.perl5.lang.perl.idea.configuration.settings.sdk.wrappers.Perl5TextSdkWrapper;
import com.perl5.lang.perl.idea.sdk.PerlSdkType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.io.File;
import java.util.Arrays;
import java.util.List;

public class Perl5SdkConfigurable implements UnnamedConfigurable, ProjectJdkTable.Listener {
    public static final Perl5SdkWrapper DISABLE_PERL_ITEM = new Perl5TextSdkWrapper(
            PerlBundle.message("perl.settings.disable.perl.support"));
    public static final Perl5SdkWrapper NOT_SELECTED_ITEM = new Perl5TextSdkWrapper(
            PerlBundle.message("perl.settings.sdk.not.selected"));

    private Perl5SdkPanel myPanel;
    @NotNull
    private MessageBusConnection myConnection;
    @NotNull
    private Perl5SdkManipulator mySdkManipulator;
    private boolean myChange = false;

    public Perl5SdkConfigurable(@NotNull Perl5SdkManipulator sdkManipulator) {
        myConnection = ApplicationManager.getApplication().getMessageBus().connect();
        mySdkManipulator = sdkManipulator;
    }

    @NotNull
    @Override
    public JComponent createComponent() {
        if (myPanel == null) {
            initPanel();
        }
        return myPanel.getMainPanel();
    }

    private void initPanel() {
        myPanel = new Perl5SdkPanel();

        // combo box
        JComboBox<Perl5SdkWrapper> sdkComboBox = myPanel.getSdkComboBox();
        //noinspection unchecked
        sdkComboBox.setModel(new CollectionComboBoxModel<>(mySdkManipulator.getAllSdkWrappers()));
        sdkComboBox.setRenderer(new ColoredListCellRenderer<Perl5SdkWrapper>() {
            @Override
            protected void customizeCellRenderer(@NotNull JList<? extends Perl5SdkWrapper> list,
                    Perl5SdkWrapper wrapper, int index, boolean selected, boolean hasFocus) {
                if (wrapper != null) {
                    wrapper.customizeRenderer(this);
                }
            }
        });
        sdkComboBox.addItemListener(e -> {
            if (e.getStateChange() != ItemEvent.SELECTED) {
                return;
            }
            updateSdkButtons();
        });

        myConnection.subscribe(PerlSdkTable.PERL_TABLE_TOPIC, this);

        // add sdk button
        myPanel.getAddButton()
                .addActionListener(e -> SdkConfigurationUtil.selectSdkHome(PerlSdkType.INSTANCE, this::addSdk));
        myPanel.getDeleteButton().addActionListener(this::removeSdk);
        myPanel.getEditButton().addActionListener(this::renameSdk);
    }

    private void updateSdkModel(@Nullable Perl5SdkWrapper itemToSelect) {
        JComboBox<Perl5SdkWrapper> sdkComboBox = myPanel.getSdkComboBox();
        List<Perl5SdkWrapper> allItems = mySdkManipulator.getAllSdkWrappers();
        if (itemToSelect == null || !allItems.contains(itemToSelect)) {
            itemToSelect = allItems.isEmpty() ? null : allItems.get(0);
        }
        sdkComboBox.setModel(new CollectionComboBoxModel<>(allItems, itemToSelect));
        updateSdkButtons();
    }

    private void updateSdkButtons() {
        boolean buttonsState = getSelectedSdk() != null;
        myPanel.getDeleteButton().setEnabled(buttonsState);
        myPanel.getEditButton().setEnabled(buttonsState);
    }

    @Nullable
    public Sdk getSelectedSdk() {
        Perl5SdkWrapper selectedWrapper = getSelectedSdkWrapper();
        return selectedWrapper instanceof Perl5RealSdkWrapper ? ((Perl5RealSdkWrapper) selectedWrapper).getSdk()
                : null;
    }

    @Nullable
    public Perl5SdkWrapper getSelectedSdkWrapper() {
        ComboBox<Perl5SdkWrapper> sdkComboBox = myPanel.getSdkComboBox();
        return sdkComboBox == null ? null : (Perl5SdkWrapper) sdkComboBox.getSelectedItem();
    }

    private void addSdk(@NotNull String home) {
        File perlDir = new File(home);
        if (perlDir.exists() && perlDir.isFile()) {
            home = perlDir.getParent();
        }
        PerlSdkType sdkType = PerlSdkType.getInstance();
        String newSdkName = SdkConfigurationUtil.createUniqueSdkName(sdkType, home,
                Arrays.asList(PerlSdkTable.getInstance().getAllJdks()));
        final ProjectJdkImpl newSdk = new ProjectJdkImpl(newSdkName, sdkType);
        newSdk.setHomePath(home);
        sdkType.setupSdkPaths(newSdk);
        // should we check for version string?
        myChange = true;
        PerlSdkTable.getInstance().addJdk(newSdk);
    }

    private void removeSdk(ActionEvent e) {
        Sdk selectedSdk = getSelectedSdk();
        if (selectedSdk != null) {
            PerlSdkTable.getInstance().removeJdk(selectedSdk);
        }
    }

    private void renameSdk(ActionEvent e) {
        Sdk selectedSdk = getSelectedSdk();
        if (selectedSdk == null) {
            return;
        }
        PerlSdkTable perlSdkTable = PerlSdkTable.getInstance();
        Messages.showInputDialog(myPanel.getSdkComboBox(), PerlBundle.message("perl.rename.sdk.text"),
                PerlBundle.message("perl.rename.sdk.title"), PerlIcons.PERL_LANGUAGE_ICON, selectedSdk.getName(),
                new InputValidator() {
                    @Override
                    public boolean checkInput(String inputString) {
                        if (StringUtil.isEmpty(inputString)) {
                            return false;
                        }
                        Sdk perlSdk = perlSdkTable.findJdk(inputString);
                        return perlSdk == null || perlSdk.equals(selectedSdk);
                    }

                    @Override
                    public boolean canClose(String inputString) {
                        if (StringUtil.equals(selectedSdk.getName(), inputString)) {
                            return true;
                        }
                        SdkModificator modificator = selectedSdk.getSdkModificator();
                        modificator.setName(inputString);
                        assert modificator instanceof Sdk;
                        perlSdkTable.updateJdk(selectedSdk, (Sdk) modificator);
                        myPanel.getSdkComboBox().repaint();
                        return true;
                    }
                });
    }

    private boolean isSdkModified() {
        return !mySdkManipulator.getCurrentSdkWrapper().equals(getSelectedSdkWrapper());
    }

    @Override
    public boolean isModified() {
        return isSdkModified();
    }

    @Override
    public void apply() throws ConfigurationException {
        if (isSdkModified()) {
            mySdkManipulator.setSdk(getSelectedSdk());
        }
    }

    @Override
    public void reset() {
        myPanel.getSdkComboBox().setSelectedItem(mySdkManipulator.getCurrentSdkWrapper());
        updateSdkButtons();
    }

    @Override
    public void disposeUIResources() {
        myConnection.deliverImmediately();
        myConnection.disconnect();
        myConnection = null;
        mySdkManipulator = null;
        myPanel = null;
    }

    @Override
    public void jdkAdded(@NotNull Sdk sdk) {
        Perl5SdkWrapper itemToSelect = getSelectedSdkWrapper();
        if (myChange) {
            myChange = false;
            itemToSelect = new Perl5RealSdkWrapper(sdk);
        }
        updateSdkModel(itemToSelect);
    }

    @Override
    public void jdkRemoved(@NotNull Sdk sdk) {
        updateSdkModel(getSelectedSdkWrapper());
    }

    @Override
    public void jdkNameChanged(@NotNull Sdk jdk, @NotNull String previousName) {
    }
}