Dialogless rename implementation for Code Style and Color schemes

This commit is contained in:
Rustam Vishnyakov
2017-01-13 15:18:46 +03:00
parent 8a0d6fc6cb
commit bfa0784302
10 changed files with 460 additions and 166 deletions
@@ -18,7 +18,7 @@ package com.intellij.application.options.codeStyle;
import com.intellij.application.options.SaveSchemeDialog;
import com.intellij.application.options.SchemesToImportPopup;
import com.intellij.application.options.schemes.AbstractSchemesPanel;
import com.intellij.application.options.schemes.DefaultSchemeActions;
import com.intellij.application.options.schemes.AbstractSchemeActions;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
@@ -44,7 +44,7 @@ import java.io.OutputStream;
import java.util.Collection;
import java.util.List;
abstract class CodeStyleSchemesActions extends DefaultSchemeActions<CodeStyleScheme> {
abstract class CodeStyleSchemesActions extends AbstractSchemeActions<CodeStyleScheme> {
private final static String SHARED_IMPORT_SOURCE = ApplicationBundle.message("import.scheme.shared");
@@ -135,16 +135,6 @@ abstract class CodeStyleSchemesActions extends DefaultSchemeActions<CodeStyleSch
getSchemesModel().removeScheme(scheme);
}
@Override
protected boolean isDeleteAvailable(@NotNull CodeStyleScheme scheme) {
return !getSchemesModel().isProjectScheme(scheme) && !scheme.isDefault();
}
@Override
protected boolean isCopyToAvailable(@NotNull CodeStyleScheme scheme) {
return !getSchemesModel().isProjectScheme(scheme);
}
@Override
protected void doImport(@NotNull String importerName) {
CodeStyleScheme currentScheme = getCurrentScheme();
@@ -18,9 +18,11 @@
package com.intellij.application.options.codeStyle;
import com.intellij.application.options.schemes.AbstractSchemesPanel;
import com.intellij.application.options.schemes.DefaultSchemeActions;
import com.intellij.application.options.schemes.AbstractSchemeActions;
import com.intellij.application.options.schemes.SchemeListItem;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.codeStyle.CodeStyleScheme;
import com.intellij.psi.impl.source.codeStyle.CodeStyleSchemeImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -94,7 +96,7 @@ public class CodeStyleSchemesPanel extends AbstractSchemesPanel<CodeStyleScheme>
@Override
protected DefaultSchemeActions<CodeStyleScheme> createSchemeActions() {
protected AbstractSchemeActions<CodeStyleScheme> createSchemeActions() {
return
new CodeStyleSchemesActions(this) {
@@ -103,23 +105,61 @@ public class CodeStyleSchemesPanel extends AbstractSchemesPanel<CodeStyleScheme>
return myModel;
}
@Nullable
@Override
protected CodeStyleScheme getCurrentScheme() {
return getSelectedScheme();
}
@Override
public SchemeLevel getSchemeLevel(@NotNull CodeStyleScheme scheme) {
return myModel.isProjectScheme(scheme) ? SchemeLevel.Project : SchemeLevel.IDE;
}
@Override
protected void onSchemeChanged(@Nullable CodeStyleScheme scheme) {
if (!myIsReset) {
ApplicationManager.getApplication().invokeLater(() -> onCombo());
}
}
@Override
protected void doRename(@NotNull CodeStyleScheme scheme, @NotNull String newName) {
CodeStyleSchemeImpl newScheme = new CodeStyleSchemeImpl(newName, false, scheme);
myModel.addScheme(newScheme, false);
myModel.removeScheme(scheme);
myModel.selectScheme(newScheme, null);
}
};
}
@Override
public SchemeListItem<CodeStyleScheme> createItem(@NotNull CodeStyleScheme scheme) {
return new SchemeListItem<CodeStyleScheme>(scheme) {
@Override
public boolean isDuplicateAvailable() {
return !myModel.isProjectScheme(scheme);
}
@Override
public boolean isResetAvailable() {
return true;
}
@Override
public boolean isDeleteAvailable() {
return !myModel.isProjectScheme(scheme) && !scheme.isDefault();
}
@Override
public SchemeLevel getSchemeLevel() {
return myModel.isProjectScheme(scheme) ? SchemeLevel.Project : SchemeLevel.IDE;
}
@Override
public boolean isRenameAvailable() {
return isDeleteAvailable();
}
@Nullable
@Override
public String validateSchemeName(@NotNull String name) {
for (CodeStyleScheme scheme : myModel.getSchemes()) {
if (name.equals(scheme.getName()) && scheme != getScheme()) {
return NAME_ALREADY_EXISTS_MESSAGE;
}
}
return super.validateSchemeName(name);
}
};
}
}
@@ -201,22 +201,30 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
public void saveSchemeAs(String name) {
MyColorScheme scheme = mySelectedScheme;
if (scheme == null) return;
saveSchemeAs(scheme, name);
}
EditorColorsScheme clone = (EditorColorsScheme)scheme.getOriginalScheme().clone();
scheme.apply(clone);
if (clone instanceof AbstractColorsScheme) {
((AbstractColorsScheme)clone).setSaveNeeded(true);
public boolean saveSchemeAs(@NotNull EditorColorsScheme editorScheme, @NotNull String name) {
if (editorScheme instanceof MyColorScheme) {
MyColorScheme scheme = (MyColorScheme)editorScheme;
EditorColorsScheme clone = (EditorColorsScheme)scheme.getOriginalScheme().clone();
scheme.apply(clone);
if (clone instanceof AbstractColorsScheme) {
((AbstractColorsScheme)clone).setSaveNeeded(true);
}
clone.setName(name);
MyColorScheme newScheme = new MyColorScheme(clone);
initScheme(newScheme);
newScheme.setIsNew();
mySchemes.put(name, newScheme);
selectScheme(newScheme.getName());
resetSchemesCombo(null);
return true;
}
clone.setName(name);
MyColorScheme newScheme = new MyColorScheme(clone);
initScheme(newScheme);
newScheme.setIsNew();
mySchemes.put(name, newScheme);
selectScheme(newScheme.getName());
resetSchemesCombo(null);
return false;
}
public void addImportedScheme(@NotNull EditorColorsScheme imported) {
@@ -17,13 +17,12 @@ package com.intellij.application.options.colors;
import com.intellij.application.options.SaveSchemeDialog;
import com.intellij.application.options.schemes.AbstractSchemesPanel;
import com.intellij.application.options.schemes.DefaultSchemeActions;
import com.intellij.application.options.schemes.AbstractSchemeActions;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme;
import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl;
import com.intellij.openapi.editor.colors.impl.EmptyColorScheme;
import com.intellij.openapi.editor.colors.impl.ReadOnlyColorsScheme;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.*;
import com.intellij.openapi.project.DefaultProjectFactory;
@@ -37,7 +36,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public abstract class ColorSchemeActions extends DefaultSchemeActions<EditorColorsScheme> {
public abstract class ColorSchemeActions extends AbstractSchemeActions<EditorColorsScheme> {
protected ColorSchemeActions(@NotNull AbstractSchemesPanel<EditorColorsScheme> schemesPanel) {
super(schemesPanel);
@@ -120,21 +119,6 @@ public abstract class ColorSchemeActions extends DefaultSchemeActions<EditorColo
getOptions().removeScheme(scheme.getName());
}
@Override
protected boolean isDeleteAvailable(@NotNull EditorColorsScheme scheme) {
return !ColorAndFontOptions.isReadOnly(scheme) && ColorAndFontOptions.canBeDeleted(scheme);
}
@Override
protected boolean isResetAvailable(@NotNull EditorColorsScheme scheme) {
AbstractColorsScheme originalScheme =
scheme instanceof AbstractColorsScheme ? ((AbstractColorsScheme)scheme).getOriginal() : null;
return
!ColorAndFontOptions.isReadOnly(scheme) &&
scheme.getName().startsWith(SchemeManager.EDITABLE_COPY_PREFIX) &&
originalScheme instanceof ReadOnlyColorsScheme;
}
@Override
protected void doExport(@NotNull EditorColorsScheme scheme, @NotNull String exporterName) {
// Unsupported for now.
@@ -18,8 +18,12 @@ package com.intellij.application.options.colors;
import com.intellij.application.options.SkipSelfSearchComponent;
import com.intellij.application.options.schemes.AbstractSchemesPanel;
import com.intellij.application.options.schemes.DefaultSchemeActions;
import com.intellij.application.options.schemes.AbstractSchemeActions;
import com.intellij.application.options.schemes.SchemeListItem;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme;
import com.intellij.openapi.editor.colors.impl.ReadOnlyColorsScheme;
import com.intellij.openapi.options.SchemeManager;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -72,7 +76,7 @@ public class SchemesPanel extends AbstractSchemesPanel<EditorColorsScheme> imple
}
@Override
protected DefaultSchemeActions<EditorColorsScheme> createSchemeActions() {
protected AbstractSchemeActions<EditorColorsScheme> createSchemeActions() {
return
new ColorSchemeActions(this) {
@@ -92,19 +96,62 @@ public class SchemesPanel extends AbstractSchemesPanel<EditorColorsScheme> imple
}
}
@Nullable
@Override
protected EditorColorsScheme getCurrentScheme() {
EditorColorsScheme selectedScheme = getSelectedScheme();
return selectedScheme != null ? myOptions.getScheme(selectedScheme.getName()) : null;
}
@Override
public SchemeLevel getSchemeLevel(@NotNull EditorColorsScheme scheme) {
return SchemeLevel.IDE_Only;
protected void doRename(@NotNull EditorColorsScheme scheme, @NotNull String newName) {
if (myOptions.saveSchemeAs(scheme, newName)) {
myOptions.removeScheme(scheme.getName());
myOptions.selectScheme(newName);
}
}
};
}
@Override
public SchemeListItem<EditorColorsScheme> createItem(@NotNull EditorColorsScheme scheme) {
return new SchemeListItem<EditorColorsScheme>(scheme) {
@Override
public boolean isDuplicateAvailable() {
return true;
}
@Override
public boolean isResetAvailable() {
AbstractColorsScheme originalScheme =
scheme instanceof AbstractColorsScheme ? ((AbstractColorsScheme)scheme).getOriginal() : null;
return
!ColorAndFontOptions.isReadOnly(scheme) &&
scheme.getName().startsWith(SchemeManager.EDITABLE_COPY_PREFIX) &&
originalScheme instanceof ReadOnlyColorsScheme;
}
@Override
public boolean isDeleteAvailable() {
return !ColorAndFontOptions.isReadOnly(scheme) && ColorAndFontOptions.canBeDeleted(scheme);
}
@Override
public SchemeLevel getSchemeLevel() {
return SchemeLevel.IDE_Only;
}
@Override
public boolean isRenameAvailable() {
return isDeleteAvailable();
}
@Nullable
@Override
public String validateSchemeName(@NotNull String name) {
EditorColorsScheme scheme = myOptions.getScheme(name);
if (scheme == null) {
scheme = myOptions.getScheme(SchemeManager.EDITABLE_COPY_PREFIX + name);
}
if (scheme != null && name.equals(SchemeManager.getDisplayName(scheme)) && scheme != getScheme()) {
return NAME_ALREADY_EXISTS_MESSAGE;
}
return super.validateSchemeName(name);
}
};
}
}
@@ -30,16 +30,12 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public abstract class DefaultSchemeActions<T extends Scheme> {
public abstract class AbstractSchemeActions<T extends Scheme> {
private final Collection<String> mySchemeImportersNames;
private final Collection<String> mySchemeExporterNames;
private AbstractSchemesPanel<T> mySchemesPanel;
public enum SchemeLevel {
IDE_Only, IDE, Project
}
protected DefaultSchemeActions(@NotNull AbstractSchemesPanel<T> schemesPanel) {
protected AbstractSchemeActions(@NotNull AbstractSchemesPanel<T> schemesPanel) {
mySchemesPanel = schemesPanel;
mySchemeImportersNames = getSchemeImportersNames();
mySchemeExporterNames = getSchemeExporterNames();
@@ -65,6 +61,7 @@ public abstract class DefaultSchemeActions<T extends Scheme> {
public final Collection<AnAction> getActions() {
List<AnAction> actions = new ArrayList<>();
actions.add(new CopyAction());
actions.add(new RenameAction());
actions.add(new ResetAction());
actions.add(new DeleteAction());
if (!mySchemeExporterNames.isEmpty()) {
@@ -109,8 +106,8 @@ public abstract class DefaultSchemeActions<T extends Scheme> {
@Override
public void update(AnActionEvent e) {
Presentation p = e.getPresentation();
T currentScheme = getCurrentScheme();
p.setEnabled(currentScheme != null && isResetAvailable(currentScheme));
SchemeListItem<T> item = mySchemesPanel.getSelectedItem();
p.setEnabled(item != null && item.isResetAvailable());
}
}
@@ -131,8 +128,30 @@ public abstract class DefaultSchemeActions<T extends Scheme> {
@Override
public void update(AnActionEvent e) {
Presentation p = e.getPresentation();
SchemeListItem<T> item = mySchemesPanel.getSelectedItem();
p.setEnabledAndVisible(item != null && item.isDuplicateAvailable());
}
}
private class RenameAction extends DumbAwareAction {
public RenameAction() {
super("Rename...");
}
@Override
public void actionPerformed(AnActionEvent e) {
T currentScheme = getCurrentScheme();
p.setEnabledAndVisible(currentScheme != null && isCopyToAvailable(currentScheme));
if (currentScheme != null) {
mySchemesPanel.startEdit();
}
}
@Override
public void update(AnActionEvent e) {
Presentation p = e.getPresentation();
SchemeListItem<T> item = mySchemesPanel.getSelectedItem();
p.setEnabled(item != null && item.isRenameAvailable());
}
}
@@ -152,8 +171,8 @@ public abstract class DefaultSchemeActions<T extends Scheme> {
@Override
public void update(AnActionEvent e) {
Presentation p = e.getPresentation();
T currentScheme = getCurrentScheme();
p.setEnabledAndVisible(currentScheme != null && isDeleteAvailable(currentScheme));
SchemeListItem<T> item = mySchemesPanel.getSelectedItem();
p.setEnabledAndVisible(item != null && item.isDeleteAvailable());
}
}
@@ -225,29 +244,21 @@ public abstract class DefaultSchemeActions<T extends Scheme> {
protected abstract void doDelete(@NotNull T scheme);
protected abstract boolean isDeleteAvailable(@NotNull T scheme);
protected boolean isResetAvailable(@NotNull T scheme) {
return true;
}
protected boolean isCopyToAvailable(@NotNull T scheme) {
return true;
}
protected abstract void doExport(@NotNull T scheme, @NotNull String exporterName);
protected abstract void onSchemeChanged(@Nullable T scheme);
protected abstract void doRename(@NotNull T scheme, @NotNull String newName);
@Nullable
protected abstract T getCurrentScheme();
protected final T getCurrentScheme() {
return mySchemesPanel.getSelectedScheme();
}
protected abstract Class<T> getSchemeType();
public AbstractSchemesPanel<T> getSchemesPanel() {
return mySchemesPanel;
}
public abstract SchemeLevel getSchemeLevel(@NotNull T scheme);
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.options.Scheme;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.ui.MessageType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,11 +28,12 @@ import javax.swing.*;
import java.awt.*;
import java.util.Collection;
public abstract class AbstractSchemesPanel<T extends Scheme> extends JPanel {
public abstract class AbstractSchemesPanel<T extends Scheme> extends JPanel implements SchemeListItemFactory<T> {
private SchemesCombo<T> mySchemesCombo;
private DefaultSchemeActions<T> myActions;
private AbstractSchemeActions<T> myActions;
private JComponent myToolbar;
private JLabel myInfoLabel;
public AbstractSchemesPanel() {
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
@@ -44,11 +46,14 @@ public abstract class AbstractSchemesPanel<T extends Scheme> extends JPanel {
controlsPanel.add(new JLabel(ApplicationBundle.message("editbox.scheme.name")));
controlsPanel.add(Box.createRigidArea(new Dimension(10, 0)));
myActions = createSchemeActions();
mySchemesCombo = new SchemesCombo<>(myActions);
controlsPanel.add(mySchemesCombo.getComboBox());
mySchemesCombo = new SchemesCombo<>(this);
controlsPanel.add(mySchemesCombo.getComponent());
myToolbar = createToolbar();
controlsPanel.add(myToolbar);
controlsPanel.setMaximumSize(new Dimension(controlsPanel.getMaximumSize().width, mySchemesCombo.getComboBox().getPreferredSize().height));
myInfoLabel = new JLabel();
controlsPanel.add(myInfoLabel);
controlsPanel.add(Box.createHorizontalGlue());
controlsPanel.setMaximumSize(new Dimension(controlsPanel.getMaximumSize().width, mySchemesCombo.getComponent().getPreferredSize().height));
add(controlsPanel);
add(Box.createVerticalGlue());
add(Box.createRigidArea(new Dimension(0, 10)));
@@ -58,7 +63,9 @@ public abstract class AbstractSchemesPanel<T extends Scheme> extends JPanel {
DefaultActionGroup toolbarActionGroup = new DefaultActionGroup();
toolbarActionGroup.add(new TopActionGroup());
ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.TOOLBAR, toolbarActionGroup, true);
return toolbar.getComponent();
JComponent toolbarComponent = toolbar.getComponent();
toolbarComponent.setMaximumSize(new Dimension(toolbarComponent.getPreferredSize().width, Short.MAX_VALUE));
return toolbarComponent;
}
@@ -85,12 +92,16 @@ public abstract class AbstractSchemesPanel<T extends Scheme> extends JPanel {
return myToolbar;
}
protected abstract DefaultSchemeActions<T> createSchemeActions();
protected abstract AbstractSchemeActions<T> createSchemeActions();
public T getSelectedScheme() {
return mySchemesCombo.getSelectedScheme();
}
public SchemeListItem<T> getSelectedItem() {
return mySchemesCombo.getSelectedItem();
}
public void selectScheme(@Nullable T scheme) {
mySchemesCombo.selectScheme(scheme);
}
@@ -102,4 +113,72 @@ public abstract class AbstractSchemesPanel<T extends Scheme> extends JPanel {
public void disposeUIResources() {
removeAll();
}
public void startEdit() {
mySchemesCombo.startEdit();
}
public void showInfo(@Nullable String message, @NotNull MessageType messageType) {
myInfoLabel.setText(message);
myInfoLabel.setForeground(messageType.getTitleForeground());
}
public void clearInfo() {
myInfoLabel.setText(null);
}
public AbstractSchemeActions<T> getActions() {
return myActions;
}
@Override
public SchemeListItem<T> createSeparator(@NotNull String title) {
return new SeparatorItem(title);
}
private class SeparatorItem extends SchemeListItem<T> {
private String myTitle;
public SeparatorItem(@NotNull String title) {
super(null);
myTitle = title;
}
@Override
public boolean isSeparator() {
return true;
}
@Override
public boolean isDuplicateAvailable() {
return false;
}
@Override
public boolean isResetAvailable() {
return false;
}
@Override
public boolean isDeleteAvailable() {
return false;
}
@Override
public SchemeLevel getSchemeLevel() {
return SchemeLevel.IDE_Only;
}
@Override
public boolean isRenameAvailable() {
return false;
}
@NotNull
@Override
public String getPresentableText() {
return myTitle;
}
}
}
@@ -0,0 +1,74 @@
/*
* Copyright 2000-2017 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.schemes;
import com.intellij.openapi.options.Scheme;
import com.intellij.openapi.options.SchemeManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class SchemeListItem<T extends Scheme> {
public static final String EMPTY_NAME_MESSAGE = "The name must not be empty";
public static final String NAME_ALREADY_EXISTS_MESSAGE = "The name already exists";
public enum SchemeLevel {
IDE_Only, IDE, Project
}
private @Nullable T myScheme;
public SchemeListItem(@Nullable T scheme) {
myScheme = scheme;
}
@Nullable
public String getSchemeName() {
return myScheme != null ? myScheme.getName() : null;
}
@Nullable
public T getScheme() {
return myScheme;
}
@NotNull
public String getPresentableText() {
return myScheme != null ? SchemeManager.getDisplayName(myScheme) : "";
}
public boolean isSeparator() {
return false;
}
public abstract boolean isDuplicateAvailable();
public abstract boolean isResetAvailable();
public abstract boolean isDeleteAvailable();
public abstract SchemeLevel getSchemeLevel();
public abstract boolean isRenameAvailable();
@Nullable
public String validateSchemeName(@NotNull String name) {
if (name.isEmpty()) {
return EMPTY_NAME_MESSAGE;
}
return null;
}
}
@@ -0,0 +1,26 @@
/*
* Copyright 2000-2017 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.schemes;
import com.intellij.openapi.options.Scheme;
import org.jetbrains.annotations.NotNull;
public interface SchemeListItemFactory<T extends Scheme> {
SchemeListItem<T> createItem(@NotNull T scheme);
SchemeListItem<T> createSeparator(@NotNull String title);
}
@@ -16,8 +16,8 @@
package com.intellij.application.options.schemes;
import com.intellij.openapi.options.Scheme;
import com.intellij.openapi.options.SchemeManager;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.MessageType;
import com.intellij.ui.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -26,26 +26,81 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Collection;
public class SchemesCombo<T extends Scheme> {
private ComboBox<MySchemeItem> myComboBox;
private DefaultSchemeActions<T> myActions;
private ComboBox<SchemeListItem<T>> myComboBox;
private JPanel myRootPanel;
private AbstractSchemesPanel<T> mySchemesPanel;
private final CardLayout myLayout;
private final JTextField myNameEditorField;
private final static KeyStroke ESC_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
private final static KeyStroke ENTER_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false);
public SchemesCombo(@NotNull DefaultSchemeActions<T> actions) {
myActions = actions;
public SchemesCombo(@NotNull AbstractSchemesPanel<T> schemesPanel) {
mySchemesPanel = schemesPanel;
myLayout = new CardLayout();
myRootPanel = new JPanel(myLayout);
createCombo();
myRootPanel.add(myComboBox);
myNameEditorField = createNameEditorField();
myRootPanel.add(myNameEditorField);
myRootPanel.setMaximumSize(new Dimension(myNameEditorField.getPreferredSize().width, Short.MAX_VALUE));
}
private JTextField createNameEditorField() {
JTextField nameEditorField = new JTextField(15);
nameEditorField.registerKeyboardAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cancelEdit();
}
}, ESC_KEY_STROKE, JComponent.WHEN_FOCUSED);
nameEditorField.registerKeyboardAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
stopEdit();
}
}, ENTER_KEY_STROKE, JComponent.WHEN_FOCUSED);
return nameEditorField;
}
private void stopEdit() {
String newName = myNameEditorField.getText();
SchemeListItem<T> selectedItem = getSelectedItem();
String validationMessage = selectedItem != null ? selectedItem.validateSchemeName(newName) : null;
if (validationMessage != null) {
mySchemesPanel.showInfo(validationMessage, MessageType.ERROR);
}
else {
cancelEdit();
if (selectedItem != null && selectedItem.getScheme() != null) {
mySchemesPanel.getActions().doRename(selectedItem.getScheme(), newName);
}
}
}
private void cancelEdit() {
mySchemesPanel.clearInfo();
myLayout.first(myRootPanel);
myRootPanel.requestFocus();
}
private void createCombo() {
myComboBox = new ComboBox<>();
myComboBox.setRenderer(new MyListCellRenderer());
myComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myActions.onSchemeChanged(getSelectedScheme());
mySchemesPanel.getActions().onSchemeChanged(getSelectedScheme());
}
});
myComboBox.setModel(new DefaultComboBoxModel<MySchemeItem>() {
myComboBox.setModel(new DefaultComboBoxModel<SchemeListItem<T>>() {
@Override
public void setSelectedItem(Object anObject) {
if (anObject instanceof OptionalSeparatorItem && ((OptionalSeparatorItem)anObject).isSeparator()) {
if (anObject instanceof SchemeListItem && ((SchemeListItem)anObject).isSeparator()) {
return;
}
super.setSelectedItem(anObject);
@@ -53,30 +108,40 @@ public class SchemesCombo<T extends Scheme> {
});
}
private SimpleTextAttributes getSchemeAttributes(@NotNull T scheme) {
return myActions.isDeleteAvailable(scheme) ? SimpleTextAttributes.REGULAR_ATTRIBUTES : SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES;
public void startEdit() {
T scheme = getSelectedScheme();
if (scheme != null) {
myNameEditorField.setText(scheme.getName());
myLayout.last(myRootPanel);
myNameEditorField.requestFocus();
}
}
private SimpleTextAttributes getSchemeAttributes(@NotNull SchemeListItem<T> item) {
return item.isDeleteAvailable() ? SimpleTextAttributes.REGULAR_ATTRIBUTES : SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES;
}
public void resetSchemes(@NotNull Collection<T> schemes) {
myComboBox.removeAllItems();
DefaultSchemeActions.SchemeLevel currSchemeLevel = DefaultSchemeActions.SchemeLevel.IDE_Only;
SchemeListItem.SchemeLevel currSchemeLevel = SchemeListItem.SchemeLevel.IDE_Only;
for (T scheme : schemes) {
DefaultSchemeActions.SchemeLevel schemeLevel = myActions.getSchemeLevel(scheme);
SchemeListItem<T> item = mySchemesPanel.createItem(scheme);
SchemeListItem.SchemeLevel schemeLevel = item.getSchemeLevel();
if (!currSchemeLevel.equals(schemeLevel)) {
currSchemeLevel = schemeLevel;
if (!schemeLevel.equals(DefaultSchemeActions.SchemeLevel.IDE_Only)) {
myComboBox.addItem(new MySchemeItem(currSchemeLevel.toString()));
if (!schemeLevel.equals(SchemeListItem.SchemeLevel.IDE_Only)) {
myComboBox.addItem(mySchemesPanel.createSeparator(currSchemeLevel.toString()));
}
}
myComboBox.addItem(new MySchemeItem(scheme));
myComboBox.addItem(item);
}
}
private class MyListCellRenderer extends ColoredListCellRenderer<MySchemeItem> {
private ListCellRendererWrapper<MySchemeItem> myWrapper = new ListCellRendererWrapper<MySchemeItem>() {
private class MyListCellRenderer extends ColoredListCellRenderer<SchemeListItem<T>> {
private ListCellRendererWrapper<SchemeListItem> myWrapper = new ListCellRendererWrapper<SchemeListItem>() {
@Override
public void customize(JList list,
MySchemeItem value,
SchemeListItem value,
int index,
boolean selected,
boolean hasFocus) {
@@ -88,8 +153,8 @@ public class SchemesCombo<T extends Scheme> {
};
@Override
public Component getListCellRendererComponent(JList<? extends MySchemeItem> list,
MySchemeItem value,
public Component getListCellRendererComponent(JList<? extends SchemeListItem<T>> list,
SchemeListItem<T> value,
int index,
boolean selected,
boolean hasFocus) {
@@ -104,15 +169,15 @@ public class SchemesCombo<T extends Scheme> {
}
@Override
protected void customizeCellRenderer(@NotNull JList<? extends MySchemeItem> list,
MySchemeItem value,
protected void customizeCellRenderer(@NotNull JList<? extends SchemeListItem<T>> list,
SchemeListItem<T> value,
int index,
boolean selected,
boolean hasFocus) {
if (value.getScheme() != null) {
append(value.getPresentableText(), getSchemeAttributes(value.getScheme()));
DefaultSchemeActions.SchemeLevel schemeLevel = myActions.getSchemeLevel(value.getScheme());
if (index == -1 && !DefaultSchemeActions.SchemeLevel.IDE_Only.equals(schemeLevel)) {
append(value.getPresentableText(), getSchemeAttributes(value));
SchemeListItem.SchemeLevel schemeLevel = value.getSchemeLevel();
if (index == -1 && !SchemeListItem.SchemeLevel.IDE_Only.equals(schemeLevel)) {
append(" " + schemeLevel.toString(), SimpleTextAttributes.GRAY_ATTRIBUTES);
}
}
@@ -121,8 +186,14 @@ public class SchemesCombo<T extends Scheme> {
@Nullable
public T getSelectedScheme() {
SchemeListItem<T> item = getSelectedItem();
return item != null ? item.getScheme() : null;
}
@Nullable
public SchemeListItem<T> getSelectedItem() {
int i = myComboBox.getSelectedIndex();
return i >= 0 ? myComboBox.getItemAt(i).getScheme() : null;
return i >= 0 ? myComboBox.getItemAt(i) : null;
}
public void selectScheme(@Nullable T scheme) {
@@ -134,44 +205,8 @@ public class SchemesCombo<T extends Scheme> {
}
}
public ComboBox getComboBox() {
return myComboBox;
}
private interface OptionalSeparatorItem {
boolean isSeparator();
}
private final class MySchemeItem implements OptionalSeparatorItem {
private @Nullable T myScheme;
private @Nullable String myText;
public MySchemeItem(@NotNull String text) {
myText = text;
}
public MySchemeItem(@Nullable T scheme) {
myScheme = scheme;
}
@Nullable
public String getSchemeName() {
return myScheme != null ? myScheme.getName() : null;
}
@Nullable
public T getScheme() {
return myScheme;
}
@NotNull
public String getPresentableText() {
return myScheme != null ? SchemeManager.getDisplayName(myScheme) : myText != null ? myText : "";
}
@Override
public boolean isSeparator() {
return myScheme == null;
}
public JComponent getComponent() {
return myRootPanel;
}
}