mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-02 00:57:59 +07:00
IDEA-19061 Integrate the Rearranger-plugin into core-IDEA
Providing ability to add new conditions
This commit is contained in:
@@ -20,10 +20,11 @@ import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementSettings;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementMatcherSettings;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
|
||||
import com.intellij.psi.codeStyle.arrangement.sort.ArrangementEntrySortType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -48,25 +49,25 @@ public class JavaRearranger implements Rearranger<JavaElementArrangementEntry>,
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNameFilterEnabled(@NotNull ArrangementSettings settings) {
|
||||
public boolean isNameFilterEnabled(@NotNull ArrangementMatcherSettings settings) {
|
||||
// TODO den implement
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(@NotNull ArrangementEntryType type) {
|
||||
public boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementMatcherSettings settings) {
|
||||
// TODO den implement
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(@NotNull ArrangementModifier modifier) {
|
||||
public boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementMatcherSettings settings) {
|
||||
// TODO den implement
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(@NotNull ArrangementEntrySortType type) {
|
||||
public boolean isEnabled(@NotNull ArrangementEntrySortType type, @Nullable ArrangementMatcherSettings settings) {
|
||||
// TODO den implement
|
||||
return true;
|
||||
}
|
||||
|
||||
+7
-4
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.codeStyle.arrangement.settings;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -24,12 +25,14 @@ import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* // TODO den add doc
|
||||
* Encapsulates information about {@link ArrangementEntryMatcher standard arrangement match rule settings}.
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/6/12 2:30 PM
|
||||
*/
|
||||
public class ArrangementSettings implements Cloneable {
|
||||
public class ArrangementMatcherSettings implements Cloneable {
|
||||
|
||||
@NotNull private final Set<ArrangementModifier> myModifiers = EnumSet.noneOf(ArrangementModifier.class);
|
||||
|
||||
@@ -58,8 +61,8 @@ public class ArrangementSettings implements Cloneable {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrangementSettings clone() {
|
||||
ArrangementSettings result = new ArrangementSettings();
|
||||
protected ArrangementMatcherSettings clone() {
|
||||
ArrangementMatcherSettings result = new ArrangementMatcherSettings();
|
||||
result.setType(myType);
|
||||
result.myModifiers.addAll(myModifiers);
|
||||
return result;
|
||||
+5
-4
@@ -19,6 +19,7 @@ import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.sort.ArrangementEntrySortType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* // TODO den add doc
|
||||
@@ -30,14 +31,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
public interface ArrangementStandardSettingsAware {
|
||||
|
||||
// TODO den add doc
|
||||
boolean isNameFilterEnabled(@NotNull ArrangementSettings settings);
|
||||
boolean isNameFilterEnabled(@Nullable ArrangementMatcherSettings settings);
|
||||
|
||||
// TODO den add doc
|
||||
boolean isSupported(@NotNull ArrangementEntryType type);
|
||||
boolean isEnabled(@NotNull ArrangementEntryType type, @Nullable ArrangementMatcherSettings settings);
|
||||
|
||||
// TODO den add doc
|
||||
boolean isSupported(@NotNull ArrangementModifier modifier);
|
||||
boolean isEnabled(@NotNull ArrangementModifier modifier, @Nullable ArrangementMatcherSettings settings);
|
||||
|
||||
// TODO den add doc
|
||||
boolean isSupported(@NotNull ArrangementEntrySortType type);
|
||||
boolean isEnabled(@NotNull ArrangementEntrySortType type, @Nullable ArrangementMatcherSettings settings);
|
||||
}
|
||||
|
||||
+10
-1
@@ -39,9 +39,12 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
|
||||
private static final int BUBBLE_CONNECTOR_LENGTH = 10;
|
||||
|
||||
@NotNull private final List<ArrangementNodeComponent> myComponents = new ArrayList<ArrangementNodeComponent>();
|
||||
@Nullable private Rectangle myScreenBounds;
|
||||
|
||||
@NotNull private final ArrangementSettingsCompositeNode mySettingsNode;
|
||||
@Nullable private Rectangle myScreenBounds;
|
||||
|
||||
public ArrangementAndNodeComponent(@NotNull ArrangementSettingsCompositeNode node, @NotNull ArrangementNodeComponentFactory factory) {
|
||||
mySettingsNode = node;
|
||||
setLayout(null);
|
||||
int x = 0;
|
||||
for (ArrangementSettingsNode operand : node.getOperands()) {
|
||||
@@ -55,6 +58,12 @@ public class ArrangementAndNodeComponent extends JPanel implements ArrangementNo
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrangementSettingsNode getSettingsNode() {
|
||||
return mySettingsNode;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JComponent getUiComponent() {
|
||||
|
||||
+12
-1
@@ -16,6 +16,7 @@
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.util.ui.GridBag;
|
||||
@@ -36,7 +37,6 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
|
||||
|
||||
private static final int PADDING = 2;
|
||||
|
||||
@Nullable private Rectangle myScreenBounds;
|
||||
@NotNull private final JPanel myRenderer = new JPanel(new GridBagLayout()) {
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
@@ -65,9 +65,14 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
|
||||
return mySize == null ? super.getPreferredSize() : mySize;
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull private final ArrangementSettingsAtomNode mySettingsNode;
|
||||
|
||||
@Nullable private Dimension mySize;
|
||||
@Nullable private Rectangle myScreenBounds;
|
||||
|
||||
public ArrangementAtomNodeComponent(@NotNull ArrangementNodeDisplayManager manager, @NotNull ArrangementSettingsAtomNode node) {
|
||||
mySettingsNode = node;
|
||||
myLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
myLabel.setText(manager.getDisplayValue(node));
|
||||
mySize = new Dimension(manager.getMaxWidth(node.getType()), myLabel.getPreferredSize().height);
|
||||
@@ -106,6 +111,12 @@ public class ArrangementAtomNodeComponent implements ArrangementNodeComponent {
|
||||
myRenderer.setOpaque(false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ArrangementSettingsNode getSettingsNode() {
|
||||
return mySettingsNode;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JComponent getUiComponent() {
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.arrangement;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/13/12 11:48 AM
|
||||
*/
|
||||
public class ArrangementConstants {
|
||||
|
||||
@NonNls public static final String ACTION_GROUP_RULE_EDITOR_CONTEXT_MENU = "Arrangement.RuleEditor.Context.Menu";
|
||||
@NonNls public static final String RULE_EDITOR_PLACE = "Arrangement.RuleEditor.Place";
|
||||
|
||||
private ArrangementConstants() {
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -29,7 +30,10 @@ import java.awt.*;
|
||||
* @since 8/10/12 11:22 AM
|
||||
*/
|
||||
public interface ArrangementNodeComponent {
|
||||
|
||||
|
||||
@NotNull
|
||||
ArrangementSettingsNode getSettingsNode();
|
||||
|
||||
// TODO den add doc
|
||||
@NotNull
|
||||
JComponent getUiComponent();
|
||||
|
||||
+8
-2
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.application.options.codeStyle.arrangement.ArrangementSettingsUtil;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsAtomNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
|
||||
@@ -40,7 +39,7 @@ public class ArrangementNodeDisplayManager {
|
||||
private final TObjectIntHashMap<ArrangementSettingType> myMaxWidths = new TObjectIntHashMap<ArrangementSettingType>();
|
||||
|
||||
public ArrangementNodeDisplayManager(@NotNull ArrangementStandardSettingsAware filter) {
|
||||
Map<ArrangementSettingType, List<?>> map = ArrangementSettingsUtil.buildAvailableOptions(filter);
|
||||
Map<ArrangementSettingType, List<?>> map = ArrangementSettingsUtil.buildAvailableOptions(filter, null);
|
||||
for (Map.Entry<ArrangementSettingType, List<?>> entry : map.entrySet()) {
|
||||
myMaxWidths.put(entry.getKey(), maxWidth(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
@@ -63,6 +62,13 @@ public class ArrangementNodeDisplayManager {
|
||||
return getDisplayValue(node.getType(), node.getValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
@NotNull
|
||||
public String getDisplayValue(@NotNull ArrangementSettingType type) {
|
||||
return type.toString().toLowerCase();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getDisplayValue(@NotNull ArrangementSettingType type, @NotNull Object value) {
|
||||
return value.toString().toLowerCase();
|
||||
}
|
||||
|
||||
+30
-10
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.*;
|
||||
@@ -22,6 +24,7 @@ import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettin
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -44,13 +47,15 @@ public class ArrangementRuleTree {
|
||||
@NotNull private final DefaultTreeModel myTreeModel;
|
||||
@NotNull private final ArrangementStandardSettingsAware myFilter;
|
||||
@NotNull private final Tree myTree;
|
||||
@NotNull private final ArrangementNodeDisplayManager myDisplayManager;
|
||||
@NotNull private final ArrangementNodeComponentFactory myFactory;
|
||||
|
||||
@Nullable private ArrangementNodeComponent myPrevComponentUnderMouse;
|
||||
|
||||
public ArrangementRuleTree(@NotNull ArrangementStandardSettingsAware filter) {
|
||||
myFilter = filter;
|
||||
myFactory = new ArrangementNodeComponentFactory(new ArrangementNodeDisplayManager(filter));
|
||||
myDisplayManager = new ArrangementNodeDisplayManager(filter);
|
||||
myFactory = new ArrangementNodeComponentFactory(myDisplayManager);
|
||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
|
||||
myTreeModel = new DefaultTreeModel(root);
|
||||
myTree = new Tree(myTreeModel) {
|
||||
@@ -61,12 +66,9 @@ public class ArrangementRuleTree {
|
||||
super.setExpandedState(path, state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectionPath(TreePath path) {
|
||||
// Don't allow selection in order to avoid standard selection background drawing.
|
||||
}
|
||||
};
|
||||
// Don't allow row selection as we're interested in particular row nodes.
|
||||
myTree.setSelectionModel(null);
|
||||
|
||||
myTree.addMouseMotionListener(new MouseAdapter() {
|
||||
@Override
|
||||
@@ -74,6 +76,24 @@ public class ArrangementRuleTree {
|
||||
onMouseMoved(e);
|
||||
}
|
||||
});
|
||||
myTree.putClientProperty(DataManager.CLIENT_PROPERTY_DATA_PROVIDER, new DataProvider() {
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (ArrangementSettingsUtil.NODE_COMPONENT.is(dataId)) {
|
||||
return myPrevComponentUnderMouse;
|
||||
}
|
||||
else if (ArrangementSettingsUtil.DISPLAY_MANAGER.is(dataId)) {
|
||||
return myDisplayManager;
|
||||
}
|
||||
else if (ArrangementSettingsUtil.FILTER.is(dataId)) {
|
||||
return myFilter;
|
||||
}
|
||||
else if (ArrangementSettingsUtil.TREE.is(dataId)) {
|
||||
return myTree;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// TODO den remove
|
||||
List<ArrangementSettingsNode> children = new ArrayList<ArrangementSettingsNode>();
|
||||
@@ -116,7 +136,7 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
|
||||
private static void map(@NotNull DefaultMutableTreeNode parentTreeNode, @NotNull HierarchicalArrangementSettingsNode settingsNode) {
|
||||
DefaultMutableTreeNode childTreeNode = new DefaultMutableTreeNode(settingsNode);
|
||||
DefaultMutableTreeNode childTreeNode = new DefaultMutableTreeNode(settingsNode.getCurrent());
|
||||
parentTreeNode.add(childTreeNode);
|
||||
for (HierarchicalArrangementSettingsNode node : settingsNode.getChildren()) {
|
||||
map(childTreeNode, node);
|
||||
@@ -129,10 +149,10 @@ public class ArrangementRuleTree {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private ArrangementNodeComponent getComponent(int row, @NotNull HierarchicalArrangementSettingsNode node) {
|
||||
private ArrangementNodeComponent getComponent(int row, @NotNull ArrangementSettingsNode node) {
|
||||
ArrangementNodeComponent result = myRenderers.get(row);
|
||||
if (result == null) {
|
||||
myRenderers.put(row, result = myFactory.getComponent(node.getCurrent()));
|
||||
myRenderers.put(row, result = myFactory.getComponent(node));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -201,7 +221,7 @@ public class ArrangementRuleTree {
|
||||
int row,
|
||||
boolean hasFocus)
|
||||
{
|
||||
HierarchicalArrangementSettingsNode node = (HierarchicalArrangementSettingsNode)((DefaultMutableTreeNode)value).getUserObject();
|
||||
ArrangementSettingsNode node = (ArrangementSettingsNode)((DefaultMutableTreeNode)value).getUserObject();
|
||||
return getComponent(row, node).getUiComponent();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -16,11 +16,13 @@
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.application.options.CodeStyleAbstractPanel;
|
||||
import com.intellij.ide.ui.customization.CustomizationUtil;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.ui.GridBag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -39,7 +41,11 @@ public abstract class ArrangementSettingsPanel extends CodeStyleAbstractPanel {
|
||||
|
||||
public ArrangementSettingsPanel(@NotNull CodeStyleSettings settings, @NotNull ArrangementStandardSettingsAware filter) {
|
||||
super(settings);
|
||||
myContent.add(new ArrangementRuleTree(filter).getTreeComponent(), new GridBag().weightx(1).weighty(1).fillCell());
|
||||
Tree component = new ArrangementRuleTree(filter).getTreeComponent();
|
||||
myContent.add(component, new GridBag().weightx(1).weighty(1).fillCell());
|
||||
CustomizationUtil.installPopupHandler(
|
||||
component, ArrangementConstants.ACTION_GROUP_RULE_EDITOR_CONTEXT_MENU, ArrangementConstants.RULE_EDITOR_PLACE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+59
-13
@@ -15,21 +15,22 @@
|
||||
*/
|
||||
package com.intellij.application.options.codeStyle.arrangement;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
|
||||
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.HierarchicalArrangementSettingsNode;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementMatcherSettings;
|
||||
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* // TODO den add doc
|
||||
@@ -39,34 +40,73 @@ import java.util.Map;
|
||||
*/
|
||||
public class ArrangementSettingsUtil {
|
||||
|
||||
public static final DataKey<ArrangementNodeComponent> NODE_COMPONENT = DataKey.create("Arrangement.Rule.Editor.Node.Component");
|
||||
public static final DataKey<ArrangementStandardSettingsAware> FILTER = DataKey.create("Arrangement.Rule.Editor.Settings.Filter");
|
||||
public static final DataKey<ArrangementNodeDisplayManager> DISPLAY_MANAGER = DataKey.create("Arrangement.Rule.Editor.Display.Manager");
|
||||
public static final DataKey<ArrangementMatcherSettings> SETTINGS = DataKey.create("Arrangement.Rule.Editor.Matcher.Settings");
|
||||
public static final DataKey<JComponent> TREE = DataKey.create("Arrangement.Rule.Editor.Tree");
|
||||
|
||||
private static final EntryTypeHelper ENTRY_TYPE_HELPER = new EntryTypeHelper();
|
||||
private static final ModifierHelper MODIFIER_HELPER = new ModifierHelper();
|
||||
|
||||
private ArrangementSettingsUtil() {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ArrangementSettingsNode getSettingsNode(@NotNull DataContext context) {
|
||||
ArrangementNodeComponent nodeComponent = NODE_COMPONENT.getData(context);
|
||||
return nodeComponent == null ? null : nodeComponent.getSettingsNode();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HierarchicalArrangementSettingsNode buildTreeStructure(@NotNull ArrangementSettingsNode modelNode) {
|
||||
// TODO den implement
|
||||
return new HierarchicalArrangementSettingsNode(modelNode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serves for the same purposes as {@link #buildAvailableOptions(ArrangementStandardSettingsAware, ArrangementMatcherSettings)} but
|
||||
* retrieves necessary information from the given context.
|
||||
*
|
||||
* @param context target information holder
|
||||
* @return map which contains information on what new new settings are available at the current situation
|
||||
*/
|
||||
@NotNull
|
||||
public static Map<ArrangementSettingType, List<?>> buildAvailableOptions(@NotNull ArrangementStandardSettingsAware filter) {
|
||||
public static Map<ArrangementSettingType, List<?>> buildAvailableOptions(@NotNull DataContext context) {
|
||||
ArrangementStandardSettingsAware filter = FILTER.getData(context);
|
||||
if (filter == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
return buildAvailableOptions(filter, SETTINGS.getData(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to answer what new settings are available for a particular {@link ArrangementMatcherSettings arrangement matcher rules}.
|
||||
*
|
||||
* @param filter filter to use
|
||||
* @param settings object that encapsulates information about current arrangement matcher settings
|
||||
* @return map which contains information on what new new settings are available at the current situation
|
||||
*/
|
||||
@NotNull
|
||||
public static Map<ArrangementSettingType, List<?>> buildAvailableOptions(@NotNull ArrangementStandardSettingsAware filter,
|
||||
@Nullable ArrangementMatcherSettings settings)
|
||||
{
|
||||
Map<ArrangementSettingType, List<?>> result = new EnumMap<ArrangementSettingType, List<?>>(ArrangementSettingType.class);
|
||||
processData(filter, result, ArrangementEntryType.values(), ENTRY_TYPE_HELPER);
|
||||
processData(filter, result, ArrangementModifier.values(), MODIFIER_HELPER);
|
||||
processData(filter, settings, result, ArrangementEntryType.values(), ENTRY_TYPE_HELPER);
|
||||
processData(filter, settings, result, ArrangementModifier.values(), MODIFIER_HELPER);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <T> void processData(@NotNull ArrangementStandardSettingsAware filter,
|
||||
@Nullable ArrangementMatcherSettings settings,
|
||||
Map<ArrangementSettingType, List<?>> result,
|
||||
@NotNull T[] values,
|
||||
@NotNull Helper<T> helper)
|
||||
{
|
||||
List<T> data = null;
|
||||
for (T v : values) {
|
||||
if (!helper.isSupported(v, filter)) {
|
||||
if (!helper.isEnabled(v, filter, settings)) {
|
||||
continue;
|
||||
}
|
||||
if (data == null) {
|
||||
@@ -100,7 +140,7 @@ public class ArrangementSettingsUtil {
|
||||
|
||||
private interface Helper<T> {
|
||||
@NotNull ArrangementSettingType getType();
|
||||
boolean isSupported(@NotNull T data, @NotNull ArrangementStandardSettingsAware filter);
|
||||
boolean isEnabled(@NotNull T data, @NotNull ArrangementStandardSettingsAware filter, @Nullable ArrangementMatcherSettings settings);
|
||||
}
|
||||
|
||||
private static class EntryTypeHelper implements Helper<ArrangementEntryType> {
|
||||
@@ -111,8 +151,11 @@ public class ArrangementSettingsUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(@NotNull ArrangementEntryType data, @NotNull ArrangementStandardSettingsAware filter) {
|
||||
return filter.isSupported(data);
|
||||
public boolean isEnabled(@NotNull ArrangementEntryType data,
|
||||
@NotNull ArrangementStandardSettingsAware filter,
|
||||
@Nullable ArrangementMatcherSettings settings)
|
||||
{
|
||||
return filter.isEnabled(data, settings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,8 +167,11 @@ public class ArrangementSettingsUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(@NotNull ArrangementModifier data, @NotNull ArrangementStandardSettingsAware filter) {
|
||||
return filter.isSupported(data);
|
||||
public boolean isEnabled(@NotNull ArrangementModifier data,
|
||||
@NotNull ArrangementStandardSettingsAware filter,
|
||||
@Nullable ArrangementMatcherSettings settings)
|
||||
{
|
||||
return filter.isEnabled(data, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.arrangement.action;
|
||||
|
||||
import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager;
|
||||
import com.intellij.application.options.codeStyle.arrangement.ArrangementSettingsUtil;
|
||||
import com.intellij.application.options.codeStyle.arrangement.editor.ArrangementNodeEditor;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingsNode;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/13/12 11:52 AM
|
||||
*/
|
||||
public class ArrangementAddAndConditionAction extends AnAction {
|
||||
|
||||
public ArrangementAddAndConditionAction() {
|
||||
getTemplatePresentation().setText(ApplicationBundle.message("arrangement.action.add.and.node.text"));
|
||||
getTemplatePresentation().setDescription(ApplicationBundle.message("arrangement.action.add.and.node.description"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
Map<ArrangementSettingType, List<?>> availableSettings = ArrangementSettingsUtil.buildAvailableOptions(e.getDataContext());
|
||||
if (availableSettings.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
ArrangementNodeDisplayManager displayManager = ArrangementSettingsUtil.DISPLAY_MANAGER.getData(e.getDataContext());
|
||||
if (displayManager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
JComponent tree = ArrangementSettingsUtil.TREE.getData(e.getDataContext());
|
||||
if (tree == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrangementSettingsNode node = ArrangementSettingsUtil.getSettingsNode(e.getDataContext());
|
||||
|
||||
if (node == null) {
|
||||
// TODO den implement
|
||||
}
|
||||
else {
|
||||
ArrangementNodeEditor editor = new ArrangementNodeEditor(displayManager, availableSettings);
|
||||
editor.applyColorsFrom(tree);
|
||||
Balloon balloon = JBPopupFactory.getInstance().createBalloonBuilder(editor).setDisposable(project).setHideOnClickOutside(true)
|
||||
.setFillColor(tree.getBackground()).createBalloon();
|
||||
Point point = MouseInfo.getPointerInfo().getLocation();
|
||||
SwingUtilities.convertPointFromScreen(point, tree);
|
||||
balloon.show(new RelativePoint(tree, point), Balloon.Position.below);
|
||||
}
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.arrangement.editor;
|
||||
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ui.GridBag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Editor for choosing a single value from a set of predefined values.
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/13/12 4:15 PM
|
||||
*/
|
||||
public class ArrangementAtomEditor extends JPanel {
|
||||
|
||||
@NotNull private final Dimension myPrefSize;
|
||||
|
||||
public ArrangementAtomEditor(@NotNull String[] values, @NotNull final Consumer<String> callback) {
|
||||
JComboBox box = new JComboBox(values);
|
||||
box.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
callback.consume((String)e.getItem());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setLayout(new GridBagLayout());
|
||||
add(box, new GridBag().anchor(GridBagConstraints.CENTER));
|
||||
|
||||
FontMetrics metrics = box.getFontMetrics(box.getFont());
|
||||
int maxWidth = 0;
|
||||
String widestText = null;
|
||||
for (String value : values) {
|
||||
int width = metrics.stringWidth(value);
|
||||
if (width > maxWidth) {
|
||||
widestText = value;
|
||||
maxWidth = width;
|
||||
}
|
||||
}
|
||||
if (widestText != null) {
|
||||
box.setSelectedItem(widestText);
|
||||
}
|
||||
myPrefSize = getPreferredSize();
|
||||
if (values.length > 0) {
|
||||
box.setSelectedItem(values[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize() {
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return myPrefSize;
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.arrangement.editor;
|
||||
|
||||
import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager;
|
||||
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
|
||||
import com.intellij.util.ui.GridBag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* // TODO den add doc
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 8/13/12 12:33 PM
|
||||
*/
|
||||
public class ArrangementNodeEditor extends JPanel {
|
||||
|
||||
@NotNull private final CardLayout myCardLayout = new CardLayout();
|
||||
@NotNull private final JPanel myValuePanel = new JPanel(myCardLayout);
|
||||
|
||||
@NotNull private final ArrangementNodeDisplayManager myDisplayManager;
|
||||
@NotNull private final Map<ArrangementSettingType, List<?>> myAvailableSettings;
|
||||
@NotNull private final JComboBox myTypeComboBox;
|
||||
@NotNull private final Dimension myPrefSize;
|
||||
|
||||
public ArrangementNodeEditor(@NotNull ArrangementNodeDisplayManager manager,
|
||||
@NotNull Map<ArrangementSettingType, List<?>> settings)
|
||||
{
|
||||
myDisplayManager = manager;
|
||||
myAvailableSettings = settings;
|
||||
|
||||
setOpaque(false);
|
||||
myTypeComboBox = new JComboBox();
|
||||
ArrangementSettingType[] types = myAvailableSettings.keySet().toArray(new ArrangementSettingType[myAvailableSettings.size()]);
|
||||
Arrays.sort(types, new Comparator<ArrangementSettingType>() {
|
||||
@Override
|
||||
public int compare(ArrangementSettingType o1, ArrangementSettingType o2) {
|
||||
return myDisplayManager.getDisplayValue(o1).compareTo(myDisplayManager.getDisplayValue(o2));
|
||||
}
|
||||
});
|
||||
|
||||
for (ArrangementSettingType type : types) {
|
||||
myTypeComboBox.addItem(myDisplayManager.getDisplayValue(type));
|
||||
}
|
||||
|
||||
setLayout(new GridBagLayout());
|
||||
add(myTypeComboBox, new GridBag());
|
||||
|
||||
// TODO den remove
|
||||
myPrefSize = getPreferredSize();
|
||||
}
|
||||
|
||||
|
||||
public void applyColorsFrom(@NotNull JComponent component) {
|
||||
myTypeComboBox.setBackground(component.getBackground());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMaximumSize() {
|
||||
return getPreferredSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return myPrefSize;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.ui.popup;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -96,4 +97,16 @@ public interface BalloonBuilder {
|
||||
|
||||
@NotNull
|
||||
BalloonBuilder setBlockClicksThroughBalloon(boolean block);
|
||||
|
||||
/**
|
||||
* Links target balloon life cycle to the given object. I.e. current balloon will be auto-hide and collected as soon
|
||||
* as given anchor is disposed.
|
||||
* <p/>
|
||||
* <b>Note:</b> given disposable anchor is assumed to correctly implement {@link #hashCode()} and {@link #equals(Object)}.
|
||||
*
|
||||
* @param anchor target anchor to link to
|
||||
* @return balloon builder which produces balloon linked to the given object life cycle
|
||||
*/
|
||||
@NotNull
|
||||
BalloonBuilder setDisposable(@NotNull Disposable anchor);
|
||||
}
|
||||
@@ -15,8 +15,12 @@
|
||||
*/
|
||||
package com.intellij.ui.popup;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.BalloonBuilder;
|
||||
import com.intellij.openapi.ui.popup.JBPopupAdapter;
|
||||
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.BalloonImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -24,15 +28,20 @@ import org.jetbrains.annotations.Nullable;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class BalloonPopupBuilderImpl implements BalloonBuilder {
|
||||
|
||||
@Nullable private final Map<Disposable, List<Balloon>> myStorage;
|
||||
@Nullable private Disposable myAnchor;
|
||||
|
||||
JComponent myContent;
|
||||
Color myBorder = Color.gray;
|
||||
Color myFill = new Color(186, 238, 186, 230);
|
||||
Color myBorder = Color.gray;
|
||||
Color myFill = new Color(186, 238, 186, 230);
|
||||
boolean myHideOnMouseOutside = true;
|
||||
boolean myHideOnKeyOutside = true;
|
||||
long myFadeoutTime = -1;
|
||||
boolean myHideOnKeyOutside = true;
|
||||
long myFadeoutTime = -1;
|
||||
|
||||
private Balloon.Position myPrefferedPosition = Balloon.Position.below;
|
||||
|
||||
@@ -41,7 +50,7 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder {
|
||||
private boolean myHideOnFrameResize = true;
|
||||
|
||||
private ActionListener myClickHandler;
|
||||
private boolean myCloseOnClick;
|
||||
private boolean myCloseOnClick;
|
||||
private int myAnimationCycle = 500;
|
||||
|
||||
private int myCalloutShift;
|
||||
@@ -49,15 +58,16 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder {
|
||||
private int myPositionChangeYShift;
|
||||
private boolean myHideOnAction = true;
|
||||
private boolean myDialogMode;
|
||||
private String myTitle;
|
||||
private Insets myContentInsets = new Insets(2, 2, 2, 2);
|
||||
private boolean myShadow = false;
|
||||
private boolean mySmallVariant = false;
|
||||
private String myTitle;
|
||||
private Insets myContentInsets = new Insets(2, 2, 2, 2);
|
||||
private boolean myShadow = false;
|
||||
private boolean mySmallVariant = false;
|
||||
|
||||
private Balloon.Layer myLayer;
|
||||
private boolean myBlockClicks = false;
|
||||
|
||||
public BalloonPopupBuilderImpl(@NotNull final JComponent content) {
|
||||
public BalloonPopupBuilderImpl(@Nullable Map<Disposable, List<Balloon>> storage, @NotNull final JComponent content) {
|
||||
myStorage = storage;
|
||||
myContent = content;
|
||||
}
|
||||
|
||||
@@ -157,8 +167,41 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder {
|
||||
|
||||
@NotNull
|
||||
public Balloon createBalloon() {
|
||||
return new BalloonImpl(myContent, myBorder, myFill, myHideOnMouseOutside, myHideOnKeyOutside, myHideOnAction, myShowCalllout, myCloseButtonEnabled, myFadeoutTime, myHideOnFrameResize, myClickHandler, myCloseOnClick, myAnimationCycle,
|
||||
myCalloutShift, myPositionChangeXShift, myPositionChangeYShift, myDialogMode, myTitle, myContentInsets, myShadow, mySmallVariant, myBlockClicks, myLayer);
|
||||
final BalloonImpl result =
|
||||
new BalloonImpl(myContent, myBorder, myFill, myHideOnMouseOutside, myHideOnKeyOutside, myHideOnAction, myShowCalllout,
|
||||
myCloseButtonEnabled, myFadeoutTime, myHideOnFrameResize, myClickHandler, myCloseOnClick, myAnimationCycle,
|
||||
myCalloutShift, myPositionChangeXShift, myPositionChangeYShift, myDialogMode, myTitle, myContentInsets, myShadow,
|
||||
mySmallVariant, myBlockClicks, myLayer);
|
||||
if (myAnchor != null) {
|
||||
List<Balloon> balloons = myStorage.get(myAnchor);
|
||||
if (balloons == null) {
|
||||
myStorage.put(myAnchor, balloons = new ArrayList<Balloon>());
|
||||
Disposer.register(myAnchor, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
List<Balloon> toDispose = myStorage.remove(myAnchor);
|
||||
if (toDispose != null) {
|
||||
for (Balloon balloon : toDispose) {
|
||||
if (!balloon.isDisposed()) {
|
||||
Disposer.dispose(balloon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
balloons.add(result);
|
||||
result.addListener(new JBPopupAdapter() {
|
||||
@Override
|
||||
public void onClosed(LightweightWindowEvent event) {
|
||||
if (!result.isDisposed()) {
|
||||
Disposer.dispose(result);
|
||||
}
|
||||
myStorage.remove(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -215,4 +258,11 @@ public class BalloonPopupBuilderImpl implements BalloonBuilder {
|
||||
myLayer = layer;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public BalloonBuilder setDisposable(@NotNull Disposable anchor) {
|
||||
myAnchor = anchor;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.ide.IdeTooltipManager;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionUtil;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionMenu;
|
||||
@@ -48,6 +49,8 @@ import com.intellij.ui.components.panels.NonOpaquePanel;
|
||||
import com.intellij.ui.popup.list.ListPopupImpl;
|
||||
import com.intellij.ui.popup.mock.MockConfirmation;
|
||||
import com.intellij.ui.popup.tree.TreePopupImpl;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.WeakHashMap;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -62,8 +65,8 @@ import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PopupFactoryImpl extends JBPopupFactory {
|
||||
|
||||
@@ -78,6 +81,8 @@ public class PopupFactoryImpl extends JBPopupFactory {
|
||||
|
||||
private static final Icon QUICK_LIST_ICON = AllIcons.Actions.QuickList;
|
||||
|
||||
private final Map<Disposable, List<Balloon>> myStorage = new WeakHashMap<Disposable, List<Balloon>>();
|
||||
|
||||
public ListPopup createConfirmation(String title, final Runnable onYes, int defaultOptionIndex) {
|
||||
return createConfirmation(title, CommonBundle.getYesButtonText(), CommonBundle.getNoButtonText(), onYes, defaultOptionIndex);
|
||||
}
|
||||
@@ -706,23 +711,24 @@ public class PopupFactoryImpl extends JBPopupFactory {
|
||||
}
|
||||
|
||||
private static class ActionStepBuilder {
|
||||
private final List<ActionItem> myListModel;
|
||||
private final DataContext myDataContext;
|
||||
private final boolean myShowNumbers;
|
||||
private final boolean myUseAlphaAsNumbers;
|
||||
private final boolean myShowDisabled;
|
||||
private final List<ActionItem> myListModel;
|
||||
private final DataContext myDataContext;
|
||||
private final boolean myShowNumbers;
|
||||
private final boolean myUseAlphaAsNumbers;
|
||||
private final boolean myShowDisabled;
|
||||
private final HashMap<AnAction, Presentation> myAction2presentation;
|
||||
private int myCurrentNumber;
|
||||
private boolean myPrependWithSeparator;
|
||||
private String mySeparatorText;
|
||||
private final boolean myHonorActionMnemonics;
|
||||
private Icon myEmptyIcon;
|
||||
private int myMaxIconWidth = -1;
|
||||
private int myCurrentNumber;
|
||||
private boolean myPrependWithSeparator;
|
||||
private String mySeparatorText;
|
||||
private final boolean myHonorActionMnemonics;
|
||||
private Icon myEmptyIcon;
|
||||
private int myMaxIconWidth = -1;
|
||||
private int myMaxIconHeight = -1;
|
||||
@NotNull private String myActionPlace;
|
||||
|
||||
private ActionStepBuilder(@NotNull DataContext dataContext, final boolean showNumbers, final boolean useAlphaAsNumbers,
|
||||
final boolean showDisabled, final boolean honorActionMnemonics) {
|
||||
final boolean showDisabled, final boolean honorActionMnemonics)
|
||||
{
|
||||
myUseAlphaAsNumbers = useAlphaAsNumbers;
|
||||
myListModel = new ArrayList<ActionItem>();
|
||||
myDataContext = dataContext;
|
||||
@@ -888,12 +894,12 @@ public class PopupFactoryImpl extends JBPopupFactory {
|
||||
}
|
||||
|
||||
public BalloonBuilder createBalloonBuilder(@NotNull final JComponent content) {
|
||||
return new BalloonPopupBuilderImpl(content);
|
||||
return new BalloonPopupBuilderImpl(myStorage, content);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BalloonBuilder createDialogBalloonBuilder(@NotNull JComponent content, String title) {
|
||||
final BalloonPopupBuilderImpl builder = new BalloonPopupBuilderImpl(content);
|
||||
final BalloonPopupBuilderImpl builder = new BalloonPopupBuilderImpl(myStorage, content);
|
||||
final Color bg = UIManager.getColor("Panel.background");
|
||||
final Color borderOriginal = Color.darkGray;
|
||||
final Color border = ColorUtil.toAlpha(borderOriginal, 75);
|
||||
@@ -913,7 +919,8 @@ public class PopupFactoryImpl extends JBPopupFactory {
|
||||
}
|
||||
|
||||
public BalloonBuilder createHtmlTextBalloonBuilder(@NotNull final String htmlContent, @Nullable final Icon icon, final Color fillColor,
|
||||
@Nullable final HyperlinkListener listener) {
|
||||
@Nullable final HyperlinkListener listener)
|
||||
{
|
||||
|
||||
|
||||
JEditorPane text = IdeTooltipManager.initPane(htmlContent, new HintHint().setAwtTooltip(true), null);
|
||||
@@ -954,7 +961,8 @@ public class PopupFactoryImpl extends JBPopupFactory {
|
||||
@Override
|
||||
public BalloonBuilder createHtmlTextBalloonBuilder(@NotNull String htmlContent,
|
||||
MessageType messageType,
|
||||
@Nullable HyperlinkListener listener) {
|
||||
@Nullable HyperlinkListener listener)
|
||||
{
|
||||
return createHtmlTextBalloonBuilder(htmlContent, messageType.getDefaultIcon(), messageType.getPopupBackground(), listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,3 +551,6 @@ title.tabs.and.indents=Tabs and Indents
|
||||
|
||||
# Arrangement
|
||||
tab.title.arrangement=Arrangement
|
||||
arrangement.action.add.and.node.text=And
|
||||
arrangement.action.add.and.node.description=Add 'and' condition
|
||||
arrangement.label.type=Type
|
||||
@@ -807,6 +807,12 @@
|
||||
<action id="DumpLookupElementWeights" internal="true" class="com.intellij.internal.DumpLookupElementWeights" text="Dump lookup element weights"/>
|
||||
<add-to-group group-id="Internal" anchor="last"/>
|
||||
</group>
|
||||
|
||||
|
||||
<group id="Arrangement.RuleEditor.Context.Menu">
|
||||
<action id="Arrangement.AddNode"
|
||||
class="com.intellij.application.options.codeStyle.arrangement.action.ArrangementAddAndConditionAction"
|
||||
icon="AllIcons.General.Add"/>
|
||||
</group>
|
||||
|
||||
</actions>
|
||||
</component>
|
||||
|
||||
+3
-1
@@ -5,6 +5,7 @@ import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.JBPopupAdapter;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
@@ -72,7 +73,8 @@ public class GradleShowConflictDetailsAction extends AbstractGradleSyncTreeNodeA
|
||||
if (hintPosition == null) {
|
||||
return;
|
||||
}
|
||||
final Balloon balloon = GradleUtil.getBalloonBuilder(control, project).setFillColor(tree.getBackground()).createBalloon();
|
||||
final Balloon balloon = JBPopupFactory.getInstance().createBalloonBuilder(control).setDisposable(project)
|
||||
.setFillColor(tree.getBackground()).createBalloon();
|
||||
final GradleUiListener publisher = project.getMessageBus().syncPublisher(GradleUiListener.TOPIC);
|
||||
publisher.beforeConflictUiShown();
|
||||
balloon.addListener(new JBPopupAdapter() {
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
package org.jetbrains.plugins.gradle.util;
|
||||
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.BalloonBuilder;
|
||||
import com.intellij.openapi.ui.popup.JBPopupAdapter;
|
||||
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 3/17/12 3:18 PM
|
||||
*/
|
||||
class GradleBalloonBuilder implements BalloonBuilder {
|
||||
|
||||
@NotNull private final BalloonBuilder myDelegate;
|
||||
@NotNull private final List<Balloon> myStorage;
|
||||
|
||||
GradleBalloonBuilder(@NotNull BalloonBuilder delegate, @NotNull List<Balloon> storage) {
|
||||
myDelegate = delegate;
|
||||
myStorage = storage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Balloon createBalloon() {
|
||||
final Balloon result = myDelegate.createBalloon();
|
||||
myStorage.add(result);
|
||||
result.addListener(new JBPopupAdapter() {
|
||||
@Override
|
||||
public void onClosed(LightweightWindowEvent event) {
|
||||
if (!result.isDisposed()) {
|
||||
Disposer.dispose(result);
|
||||
}
|
||||
myStorage.remove(result);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setPreferredPosition(Balloon.Position position) {
|
||||
myDelegate.setPreferredPosition(position);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setBorderColor(@NotNull Color color) {
|
||||
myDelegate.setBorderColor(color);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setFillColor(@NotNull Color color) {
|
||||
myDelegate.setFillColor(color);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setHideOnClickOutside(boolean hide) {
|
||||
myDelegate.setHideOnClickOutside(hide);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setHideOnKeyOutside(boolean hide) {
|
||||
myDelegate.setHideOnKeyOutside(hide);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setShowCallout(boolean show) {
|
||||
myDelegate.setShowCallout(show);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setCloseButtonEnabled(boolean enabled) {
|
||||
myDelegate.setCloseButtonEnabled(enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setFadeoutTime(long fadeoutTime) {
|
||||
myDelegate.setFadeoutTime(fadeoutTime);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setAnimationCycle(int time) {
|
||||
myDelegate.setAnimationCycle(time);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setHideOnFrameResize(boolean hide) {
|
||||
myDelegate.setHideOnFrameResize(hide);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setClickHandler(ActionListener listener, boolean closeOnClick) {
|
||||
myDelegate.setClickHandler(listener, closeOnClick);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setCalloutShift(int length) {
|
||||
myDelegate.setCalloutShift(length);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setPositionChangeXShift(int positionChangeXShift) {
|
||||
myDelegate.setPositionChangeXShift(positionChangeXShift);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setPositionChangeYShift(int positionChangeYShift) {
|
||||
myDelegate.setPositionChangeYShift(positionChangeYShift);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHideOnAction() {
|
||||
return myDelegate.isHideOnAction();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setHideOnAction(boolean hideOnAction) {
|
||||
myDelegate.setHideOnAction(hideOnAction);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setDialogMode(boolean dialogMode) {
|
||||
myDelegate.setDialogMode(dialogMode);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setTitle(@Nullable String title) {
|
||||
myDelegate.setTitle(title);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setContentInsets(Insets insets) {
|
||||
myDelegate.setContentInsets(insets);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setShadow(boolean shadow) {
|
||||
myDelegate.setShadow(shadow);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setSmallVariant(boolean smallVariant) {
|
||||
myDelegate.setSmallVariant(smallVariant);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public BalloonBuilder setLayer(Balloon.Layer layer) {
|
||||
myDelegate.setLayer(layer);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public BalloonBuilder setBlockClicksThroughBalloon(boolean block) {
|
||||
myDelegate.setBlockClicksThroughBalloon(block);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package org.jetbrains.plugins.gradle.util;
|
||||
|
||||
import com.intellij.execution.rmi.RemoteUtil;
|
||||
import com.intellij.ide.actions.OpenProjectFileChooserDescriptor;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
@@ -25,7 +24,6 @@ import com.intellij.openapi.ui.MessageType;
|
||||
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.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -38,7 +36,6 @@ import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentManager;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.WeakHashMap;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -59,9 +56,6 @@ import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -74,8 +68,6 @@ public class GradleUtil {
|
||||
|
||||
public static final String PATH_SEPARATOR = "/";
|
||||
|
||||
private static final Map<Project, List<Balloon>> PROJECT_BALLOONS = new WeakHashMap<Project, List<Balloon>>();
|
||||
private static final List<Balloon> APPLICATION_BALLOONS = new CopyOnWriteArrayList<Balloon>();
|
||||
private static final NotNullLazyValue<GradleLibraryManager> LIBRARY_MANAGER = new NotNullLazyValue<GradleLibraryManager>() {
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -116,10 +108,9 @@ public class GradleUtil {
|
||||
* @param message message to show
|
||||
*/
|
||||
public static void showBalloon(@NotNull JComponent component, @NotNull MessageType messageType, @NotNull String message) {
|
||||
final BalloonBuilder delegate = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(message, messageType, null);
|
||||
BalloonBuilder balloonBuilder = new GradleBalloonBuilder(delegate, APPLICATION_BALLOONS);
|
||||
ApplicationBalloonsDisposeActivator.ensureActivated();
|
||||
Balloon balloon = balloonBuilder.setFadeoutTime(TimeUnit.SECONDS.toMillis(1)).createBalloon();
|
||||
final BalloonBuilder builder = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(message, messageType, null)
|
||||
.setDisposable(ApplicationManager.getApplication()).setFadeoutTime(TimeUnit.SECONDS.toMillis(1));
|
||||
Balloon balloon = builder.createBalloon();
|
||||
Dimension size = component.getSize();
|
||||
Balloon.Position position;
|
||||
int x;
|
||||
@@ -429,35 +420,6 @@ public class GradleUtil {
|
||||
return new MatrixControlBuilder(gradle, intellij);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps {@link JBPopupFactory#createBalloonBuilder(JComponent) default api} in order to take care of automatic balloon disposing
|
||||
* on project close.
|
||||
*
|
||||
* @param content target balloon content
|
||||
* @param project project that should be used to bound target balloon's lifecycle to
|
||||
* @return balloon builder to use.
|
||||
*/
|
||||
@NotNull
|
||||
public static BalloonBuilder getBalloonBuilder(@NotNull JComponent content, @NotNull final Project project) {
|
||||
List<Balloon> balloons = PROJECT_BALLOONS.get(project);
|
||||
if (balloons == null) {
|
||||
PROJECT_BALLOONS.put(project, balloons = new CopyOnWriteArrayList<Balloon>());
|
||||
final List<Balloon> b = balloons;
|
||||
Disposer.register(project, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
for (Balloon balloon : b) {
|
||||
if (!balloon.isDisposed()) {
|
||||
Disposer.dispose(balloon);
|
||||
}
|
||||
}
|
||||
PROJECT_BALLOONS.remove(project);
|
||||
}
|
||||
});
|
||||
}
|
||||
return new GradleBalloonBuilder(JBPopupFactory.getInstance().createBalloonBuilder(content), balloons);
|
||||
}
|
||||
|
||||
public static boolean isGradleAvailable() {
|
||||
final Project[] projects = ProjectManager.getInstance().getOpenProjects();
|
||||
final Project project;
|
||||
@@ -498,23 +460,4 @@ public class GradleUtil {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves the same purpose as the {@link DescriptorHolder} but for application-level balloons releasing.
|
||||
*/
|
||||
private static class ApplicationBalloonsDisposeActivator {
|
||||
static {
|
||||
Disposer.register(ApplicationManager.getApplication(), new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
for (Balloon balloon : APPLICATION_BALLOONS) {
|
||||
if (!balloon.isDisposed()) {
|
||||
Disposer.dispose(balloon);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
static void ensureActivated() { /* the real job is at the static init block. */ }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user