Merge remote branch 'origin/master'

This commit is contained in:
irengrig
2012-11-15 16:32:04 +04:00
27 changed files with 578 additions and 504 deletions
+63 -3
View File
@@ -39,7 +39,7 @@
</option>
<option name="ANNOTATION_NAME_ATTRIBUTES">
<value>
<option name="FOREGROUND" value="fcf629" />
<option name="FOREGROUND" value="bbb529" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
@@ -467,6 +467,36 @@
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.AL4.LOCAL_VARIABLE">
<value>
<option name="FOREGROUND" value="458383" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="-1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.ATTRIBUTE">
<value>
<option name="FOREGROUND" value="bbb529" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="-1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.INSTANCE_MEMBER_FUNCTION">
<value>
<option name="FOREGROUND" value="9876aa" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="-1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.KEYWORD">
<value>
<option name="FOREGROUND" value="cc7832" />
@@ -477,6 +507,36 @@
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.PARAMETER">
<value>
<option name="FOREGROUND" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="2" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.REGEXP">
<value>
<option name="FOREGROUND" value="3fa29a" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="-1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.STATIC_MEMBER_FUNCTION">
<value>
<option name="FOREGROUND" value="9876aa" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="2" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="0" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="EL.BOUNDS">
<value>
<option name="FOREGROUND" />
@@ -2510,7 +2570,7 @@
<option name="SEARCH_RESULT_ATTRIBUTES">
<value>
<option name="FOREGROUND" />
<option name="BACKGROUND" value="006300" />
<option name="BACKGROUND" value="6300" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="0" />
@@ -2860,7 +2920,7 @@
<option name="TEXT_SEARCH_RESULT_ATTRIBUTES">
<value>
<option name="FOREGROUND" />
<option name="BACKGROUND" value="006300" />
<option name="BACKGROUND" value="6300" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="0" />
@@ -1305,9 +1305,25 @@ public class HighlightUtil extends HighlightUtilBase {
return HighlightClassUtil.reportIllegalEnclosingUsage(expr, null, aClass, expr);
}
if (expr instanceof PsiThisExpression && PsiTreeUtil.getParentOfType(expr, PsiMethod.class) == null) {
if (aClass.isInterface()) {
return thisNotFoundInInterfaceInfo(expr);
}
if (aClass instanceof PsiAnonymousClass && PsiTreeUtil.isAncestor(((PsiAnonymousClass)aClass).getArgumentList(), expr, true)) {
final PsiClass parentClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true);
if (parentClass != null && parentClass.isInterface()) {
return thisNotFoundInInterfaceInfo(expr);
}
}
}
return null;
}
private static HighlightInfo thisNotFoundInInterfaceInfo(PsiExpression expr) {
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expr, "Cannot find symbol variable this");
}
private static boolean resolvesToImmediateSuperInterface(@NotNull PsiExpression expr,
@Nullable PsiJavaCodeReferenceElement qualifier,
@NotNull PsiClass aClass) {
@@ -134,6 +134,7 @@ public class MethodParameterInfoHandler implements ParameterInfoHandlerWithTabAc
for (int i = 0; i < candidates.length; i++) {
CandidateInfo candidate = (CandidateInfo)candidates[i];
PsiMethod method = (PsiMethod)candidate.getElement();
if (!method.isValid()) continue;
PsiSubstitutor substitutor = getCandidateInfoSubstitutor(candidate);
assert substitutor != null;
@@ -475,7 +475,10 @@ public class CreateTestDialog extends DialogWrapper {
for (SourceFolder f : e.getSourceFolders()) {
final VirtualFile file = f.getFile();
if (file != null && f.isTestSource()) {
dirs.add(PsiManager.getInstance(myProject).findDirectory(file));
final PsiDirectory dir = PsiManager.getInstance(myProject).findDirectory(file);
if (dir != null) {
dirs.add(dir);
}
}
}
}
@@ -0,0 +1,8 @@
class C implements A {
C(A a) {}
}
interface A {
A a = new C(<error descr="Cannot find symbol variable this">this</error>);
A a1 = new C(<error descr="Cannot find symbol variable this">this</error>){};
}
@@ -359,4 +359,5 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testUnsupportedFeatures() throws Exception { doTest(false, false); }
public void testThisBeforeSuper() throws Exception { doTest(false, false); }
public void testExplicitConstructorInvocation() throws Exception { doTest(false, false); }
public void testThisInInterface() throws Exception { doTest(false, false); }
}
@@ -602,14 +602,14 @@ public class IncProjectBuilder {
onChunkBuildComplete(context, chunk);
if (doneSomething && GENERATE_CLASSPATH_INDEX) {
myAsyncTasks.add(SharedThreadPool.getInstance().executeOnPooledThread(new Runnable() {
@Override
public void run() {
createClasspathIndex(chunk);
}
}));
}
//if (doneSomething && GENERATE_CLASSPATH_INDEX) {
// myAsyncTasks.add(SharedThreadPool.getInstance().executeOnPooledThread(new Runnable() {
// @Override
// public void run() {
// createClasspathIndex(chunk);
// }
// }));
//}
}
catch (ProjectBuildException e) {
throw e;
@@ -20,7 +20,7 @@ import java.util.Map;
* Date: 10/7/11
*/
public class BuildDataManager implements StorageOwner {
private static final int VERSION = 17;
private static final int VERSION = 18;
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String SRC_TO_FORM_STORAGE = "src-form";
private static final String MAPPINGS_STORAGE = "mappings";
@@ -15,10 +15,14 @@
*/
package com.intellij.psi.codeStyle.arrangement;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementCompositeMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import com.intellij.util.containers.ContainerUtilRt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,11 +34,13 @@ import java.util.Set;
* @author Denis Zhdanov
* @since 10/31/12 12:30 PM
*/
public class ArrangementConditionInfo {
public class ArrangementRuleInfo {
@NotNull private final Set<ArrangementAtomMatchCondition> myAtomConditions = ContainerUtilRt.newHashSet();
@NotNull private final Set<Object> myConditions = ContainerUtilRt.newHashSet();
@NotNull private ArrangementEntryOrderType myOrderType = ArrangementMatchRule.DEFAULT_ORDER_TYPE;
@Nullable private String myNamePattern;
@Nullable
@@ -46,6 +52,15 @@ public class ArrangementConditionInfo {
myNamePattern = namePattern;
}
@NotNull
public ArrangementEntryOrderType getOrderType() {
return myOrderType;
}
public void setOrderType(@NotNull ArrangementEntryOrderType orderType) {
myOrderType = orderType;
}
public void addAtomCondition(@NotNull ArrangementAtomMatchCondition condition) {
switch (condition.getType()) {
case NAME: myNamePattern = condition.getValue().toString(); break;
@@ -72,6 +87,32 @@ public class ArrangementConditionInfo {
}
}
public void copyConditionsFrom(@NotNull ArrangementRuleInfo info) {
clearConditions();
myConditions.addAll(info.myConditions);
myAtomConditions.addAll(info.myAtomConditions);
}
public void clear() {
clearConditions();
myOrderType = ArrangementMatchRule.DEFAULT_ORDER_TYPE;
myNamePattern = null;
}
public void clearConditions() {
myConditions.clear();
myAtomConditions.clear();
}
@Nullable
public StdArrangementMatchRule buildRule() {
ArrangementMatchCondition condition = buildCondition();
if (condition == null) {
return null;
}
return new StdArrangementMatchRule(new StdArrangementEntryMatcher(condition), myOrderType);
}
@Nullable
public ArrangementMatchCondition buildCondition() {
if (myAtomConditions.isEmpty()) {
@@ -164,8 +164,8 @@ public class ArrangementUtil {
}
@NotNull
public static ArrangementConditionInfo extractConditions(@NotNull ArrangementMatchCondition condition) {
final ArrangementConditionInfo result = new ArrangementConditionInfo();
public static ArrangementRuleInfo extractConditions(@NotNull ArrangementMatchCondition condition) {
final ArrangementRuleInfo result = new ArrangementRuleInfo();
condition.invite(new ArrangementMatchConditionVisitor() {
@Override
public void visit(@NotNull ArrangementAtomMatchCondition condition) {
@@ -20,5 +20,5 @@ package com.intellij.psi.codeStyle.arrangement.model;
* @since 8/6/12 5:02 PM
*/
public enum ArrangementSettingType {
TYPE, MODIFIER, NAME
TYPE, MODIFIER, NAME, ORDER
}
@@ -18,6 +18,7 @@ package com.intellij.application.options.codeStyle.arrangement;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.application.options.codeStyle.arrangement.util.ArrangementConfigUtil;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.psi.codeStyle.arrangement.group.ArrangementGroupingType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryType;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementModifier;
@@ -98,6 +99,8 @@ public class ArrangementNodeDisplayManager {
return ApplicationBundle.message("arrangement.text.type");
case MODIFIER:
return ApplicationBundle.message("arrangement.text.modifier");
case NAME:
return ApplicationBundle.message("arrangement.text.name");
}
return type.toString().toLowerCase();
}
@@ -133,6 +136,23 @@ public class ArrangementNodeDisplayManager {
return myMaxWidths.get(type);
}
public int getMaxWidth(@NotNull ArrangementEntryOrderType... orderTypes) {
SimpleColoredComponent renderer = new SimpleColoredComponent();
int result = 0;
for (ArrangementEntryOrderType type : orderTypes) {
renderer.clear();
TextAttributes attributes = myColorsProvider.getTextAttributes(ArrangementSettingType.ORDER, true);
renderer.append(getDisplayValue(type), SimpleTextAttributes.fromTextAttributes(attributes));
result = Math.max(result, renderer.getPreferredSize().width);
renderer.clear();
attributes = myColorsProvider.getTextAttributes(ArrangementSettingType.ORDER, false);
renderer.append(getDisplayValue(type), SimpleTextAttributes.fromTextAttributes(attributes));
result = Math.max(result, renderer.getPreferredSize().width);
}
return result;
}
/**
* Asks current manager to sort in-place given arrangement condition ids ('field', 'class', 'method', 'public', 'static', 'final' etc).
*
@@ -58,7 +58,6 @@ public class ArrangementAtomMatchConditionComponent implements ArrangementMatchC
PredefinedConditionBorderStrategy strategy = new PredefinedConditionBorderStrategy();
BORDER_STRATEGIES.put(ArrangementSettingType.TYPE, strategy);
BORDER_STRATEGIES.put(ArrangementSettingType.MODIFIER, strategy);
assert BORDER_STRATEGIES.size() == ArrangementSettingType.values().length;
}
@NotNull
@@ -22,15 +22,15 @@ import com.intellij.application.options.codeStyle.arrangement.util.ArrangementCo
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.arrangement.ArrangementConditionInfo;
import com.intellij.psi.codeStyle.arrangement.ArrangementRuleInfo;
import com.intellij.psi.codeStyle.arrangement.ArrangementUtil;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.ArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementEntryMatcher;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementAtomMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementMatchCondition;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.components.JBTextField;
@@ -40,20 +40,15 @@ import com.intellij.util.ui.GridBag;
import com.intellij.util.ui.MultiRowFlowPanel;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Control for managing {@link ArrangementEntryMatcher matching rule conditions} for a single {@link ArrangementMatchRule}.
@@ -65,19 +60,22 @@ import java.util.Set;
*/
public class ArrangementMatchingRuleEditor extends JPanel {
@NotNull private final Map<Object, ArrangementAtomMatchConditionComponent> myComponents = ContainerUtilRt.newHashMap();
@NotNull private final List<MultiRowFlowPanel> myRows = ContainerUtilRt.newArrayList();
@NotNull private final Map<Object, ArrangementAtomMatchConditionComponent> myConditionComponents = ContainerUtilRt.newHashMap();
@NotNull private final List<MultiRowFlowPanel> myRows = ContainerUtilRt.newArrayList();
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@NotNull private final JBTextField myNameField = new JBTextField(20);
@NotNull private final Map<ArrangementEntryOrderType, ArrangementOrderTypeComponent> myOrderTypeComponents
= new EnumMap<ArrangementEntryOrderType, ArrangementOrderTypeComponent>(ArrangementEntryOrderType.class);
@NotNull private final ArrangementRuleInfo myRuleInfo = new ArrangementRuleInfo();
@NotNull private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
@NotNull private final JBTextField myNameField = new JBTextField(20);
@NotNull private final ArrangementMatchingRulesControl myControl;
@NotNull private final ArrangementStandardSettingsAware myFilter;
@NotNull private final ArrangementColorsProvider myColorsProvider;
@Nullable private ArrangementConditionInfo myConditionInfo;
private int myRow = -1;
private int myLabelWidth;
private int myLabelWidth;
private boolean myRequestFocus;
public ArrangementMatchingRuleEditor(@NotNull ArrangementStandardSettingsAware filter,
@@ -110,9 +108,63 @@ public class ArrangementMatchingRuleEditor extends JPanel {
addRowIfPossible(ArrangementSettingType.TYPE, supportedSettings, displayManager);
addRowIfPossible(ArrangementSettingType.MODIFIER, supportedSettings, displayManager);
addNameFilterIfPossible();
addOrderRowIfPossible(displayManager);
applyBackground(UIUtil.getListBackground());
}
private void addRowIfPossible(@NotNull ArrangementSettingType key,
@NotNull Map<ArrangementSettingType, Set<?>> supportedSettings,
@NotNull ArrangementNodeDisplayManager manager)
{
Set<?> values = supportedSettings.get(key);
if (values == null || values.isEmpty()) {
return;
}
MultiRowFlowPanel valuesPanel = newRow(manager.getDisplayLabel(key));
for (Object value : manager.sort(values)) {
ArrangementAtomMatchConditionComponent component =
new ArrangementAtomMatchConditionComponent(manager, myColorsProvider, new ArrangementAtomMatchCondition(key, value), null);
myConditionComponents.put(value, component);
valuesPanel.add(component.getUiComponent());
}
}
private void addNameFilterIfPossible() {
if (!myFilter.isNameFilterSupported()) {
return;
}
MultiRowFlowPanel panel = newRow(ApplicationBundle.message("arrangement.text.name"));
panel.add(myNameField);
}
private void addOrderRowIfPossible(@NotNull ArrangementNodeDisplayManager displayManager) {
if (!myFilter.isNameFilterSupported()) {
return;
}
MultiRowFlowPanel panel = newRow(ApplicationBundle.message("arrangement.order.name"));
ArrangementEntryOrderType[] orderTypes = { ArrangementEntryOrderType.KEEP, ArrangementEntryOrderType.BY_NAME };
int maxWidth = displayManager.getMaxWidth(orderTypes);
for (ArrangementEntryOrderType type : orderTypes) {
ArrangementOrderTypeComponent component = new ArrangementOrderTypeComponent(type, displayManager, myColorsProvider, maxWidth);
panel.add(component);
myOrderTypeComponents.put(type, component);
}
}
private MultiRowFlowPanel newRow(@NotNull String rowLabel) {
MultiRowFlowPanel result = new MultiRowFlowPanel(
FlowLayout.LEFT, ArrangementConstants.HORIZONTAL_GAP, ArrangementConstants.VERTICAL_GAP
);
JLabel label = new JLabel(rowLabel + ":");
add(label, new GridBag().anchor(GridBagConstraints.NORTHWEST).insets(ArrangementConstants.VERTICAL_PADDING, 0, 0, 0));
myLabelWidth = Math.max(myLabelWidth, label.getPreferredSize().width);
add(result, new GridBag().anchor(GridBagConstraints.WEST).weightx(1).fillCellHorizontally().coverLine());
myRows.add(result);
return result;
}
private void scheduleNameUpdate() {
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
@@ -125,7 +177,7 @@ public class ArrangementMatchingRuleEditor extends JPanel {
private void updateName() {
myAlarm.cancelAllRequests();
if (myRow < 0 || myConditionInfo == null) {
if (myRow < 0) {
return;
}
@@ -133,55 +185,11 @@ public class ArrangementMatchingRuleEditor extends JPanel {
if (StringUtil.isEmpty(namePattern)) {
namePattern = null;
}
if (Comparing.equal(namePattern, myConditionInfo.getNamePattern())) {
if (Comparing.equal(namePattern, myRuleInfo.getNamePattern())) {
return;
}
myConditionInfo.setNamePattern(namePattern);
ArrangementMatchCondition newCondition = myConditionInfo.buildCondition();
Object modelValue = newCondition == null
? new EmptyArrangementRuleComponent(myControl.getRowHeight(myRow))
: new StdArrangementMatchRule(new StdArrangementEntryMatcher(newCondition));
myControl.getModel().set(myRow, modelValue);
myControl.repaintRows(myRow, myRow, true);
}
private void addRowIfPossible(@NotNull ArrangementSettingType key,
@NotNull Map<ArrangementSettingType, Set<?>> supportedSettings,
@NotNull ArrangementNodeDisplayManager manager)
{
Set<?> values = supportedSettings.get(key);
if (values == null || values.isEmpty()) {
return;
}
MultiRowFlowPanel valuesPanel = newRow(manager.getDisplayLabel(key));
for (Object value : manager.sort(values)) {
ArrangementAtomMatchConditionComponent component =
new ArrangementAtomMatchConditionComponent(manager, myColorsProvider, new ArrangementAtomMatchCondition(key, value), null);
myComponents.put(value, component);
valuesPanel.add(component.getUiComponent());
}
}
private void addNameFilterIfPossible() {
if (!myFilter.isNameFilterSupported()) {
return;
}
MultiRowFlowPanel panel = newRow(ApplicationBundle.message("arrangement.text.name"));
panel.add(myNameField);
}
private MultiRowFlowPanel newRow(@NotNull String rowLabel) {
MultiRowFlowPanel result = new MultiRowFlowPanel(
FlowLayout.LEFT, ArrangementConstants.HORIZONTAL_GAP, ArrangementConstants.VERTICAL_GAP
);
JLabel label = new JLabel(rowLabel + ":");
add(label, new GridBag().anchor(GridBagConstraints.NORTHWEST).insets(ArrangementConstants.VERTICAL_PADDING, 0, 0, 0));
myLabelWidth = Math.max(myLabelWidth, label.getPreferredSize().width);
add(result, new GridBag().anchor(GridBagConstraints.WEST).weightx(1).fillCellHorizontally().coverLine());
myRows.add(result);
return result;
myRuleInfo.setNamePattern(namePattern);
updateModelValue();
}
@Override
@@ -211,14 +219,14 @@ public class ArrangementMatchingRuleEditor extends JPanel {
myAlarm.cancelAllRequests();
if (newModel) {
myRow = row;
myConditionInfo = null;
myRuleInfo.clear();
myNameField.setText("");
myAlarm.cancelAllRequests();
myRequestFocus = true;
}
// Reset state.
for (ArrangementAtomMatchConditionComponent component : myComponents.values()) {
for (ArrangementAtomMatchConditionComponent component : myConditionComponents.values()) {
component.setEnabled(false);
component.setSelected(false);
}
@@ -231,44 +239,61 @@ public class ArrangementMatchingRuleEditor extends JPanel {
Object element = model.getElementAt(row);
if (element instanceof EmptyArrangementRuleComponent) {
for (ArrangementAtomMatchConditionComponent component : myComponents.values()) {
for (ArrangementAtomMatchConditionComponent component : myConditionComponents.values()) {
ArrangementAtomMatchCondition condition = component.getMatchCondition();
Map<ArrangementSettingType, Set<?>> map = ArrangementConfigUtil.buildAvailableConditions(myFilter, condition);
component.setEnabled(map.get(condition.getType()).contains(condition.getValue()));
}
myConditionInfo = new ArrangementConditionInfo();
myRuleInfo.clearConditions();
ArrangementOrderTypeComponent orderTypeComponent = myOrderTypeComponents.get(myRuleInfo.getOrderType());
if (orderTypeComponent != null) {
orderTypeComponent.setSelected(true);
}
return;
}
if (!(element instanceof StdArrangementMatchRule)) {
return;
}
ArrangementMatchCondition condition = ((StdArrangementMatchRule)element).getMatcher().getCondition();
myConditionInfo = ArrangementUtil.extractConditions(condition);
myNameField.setText(myConditionInfo.getNamePattern() == null ? "" : myConditionInfo.getNamePattern());
StdArrangementMatchRule rule = (StdArrangementMatchRule)element;
ArrangementMatchCondition condition = rule.getMatcher().getCondition();
ArrangementRuleInfo infoWithConditions = ArrangementUtil.extractConditions(condition);
myRuleInfo.copyConditionsFrom(infoWithConditions);
myNameField.setText(myRuleInfo.getNamePattern() == null ? "" : myRuleInfo.getNamePattern());
Map<ArrangementSettingType, Set<?>> available = ArrangementConfigUtil.buildAvailableConditions(myFilter, condition);
for (Collection<?> ids : available.values()) {
for (Object id : ids) {
ArrangementAtomMatchConditionComponent component = myComponents.get(id);
ArrangementAtomMatchConditionComponent component = myConditionComponents.get(id);
if (component != null) {
component.setEnabled(true);
component.setSelected(myConditionInfo.hasCondition(id));
component.setSelected(myRuleInfo.hasCondition(id));
}
}
}
for (ArrangementOrderTypeComponent component : myOrderTypeComponents.values()) {
component.setSelected(false);
}
ArrangementOrderTypeComponent orderTypeComponent = myOrderTypeComponents.get(rule.getOrderType());
if (orderTypeComponent != null) {
orderTypeComponent.setSelected(true);
}
repaint();
}
private void updateState() {
assert myConditionInfo != null;
ArrangementMatchCondition newCondition = myConditionInfo.buildCondition();
Object modelValue = newCondition == null
? new EmptyArrangementRuleComponent(myControl.getRowHeight(myRow))
: new StdArrangementMatchRule(new StdArrangementEntryMatcher(newCondition));
updateModelValue();
updateState(myRow, false);
}
private void updateModelValue() {
Object modelValue = myRuleInfo.buildRule();
if (modelValue == null) {
modelValue = new EmptyArrangementRuleComponent(myControl.getRowHeight(myRow));
}
myControl.getModel().set(myRow, modelValue);
myControl.repaintRows(myRow, myRow, true);
updateState(myRow, false);
}
public void applyAvailableWidth(int width) {
@@ -286,22 +311,41 @@ public class ArrangementMatchingRuleEditor extends JPanel {
}
private void onMouseClicked(@NotNull MouseEvent e) {
if (myRow < 0 || myConditionInfo == null) {
if (myRow < 0) {
return;
}
ArrangementAtomMatchConditionComponent clickedComponent = getNodeComponentAt(e.getLocationOnScreen());
if (clickedComponent != null && clickedComponent.isEnabled()) {
onComponentSelected(clickedComponent);
Point locationOnScreen = e.getLocationOnScreen();
for (ArrangementAtomMatchConditionComponent component : myConditionComponents.values()) {
Rectangle screenBounds = component.getScreenBounds();
if (screenBounds == null || !screenBounds.contains(locationOnScreen)) {
continue;
}
if (component.isEnabled()) {
onComponentSelected(component);
}
return;
}
for (ArrangementOrderTypeComponent component : myOrderTypeComponents.values()) {
Rectangle bounds = component.getScreenBounds();
if (bounds == null || !bounds.contains(locationOnScreen)) {
continue;
}
if (component.getOrderType() != myRuleInfo.getOrderType()) {
myRuleInfo.setOrderType(component.getOrderType());
updateState();
}
return;
}
}
private void onComponentSelected(@NotNull ArrangementAtomMatchConditionComponent component) {
ArrangementAtomMatchCondition chosenCondition = component.getMatchCondition();
boolean remove = myConditionInfo.hasCondition(chosenCondition.getValue());
boolean remove = myRuleInfo.hasCondition(chosenCondition.getValue());
component.setSelected(!remove);
repaintComponent(component);
if (remove) {
myConditionInfo.removeCondition(chosenCondition.getValue());
myRuleInfo.removeCondition(chosenCondition.getValue());
ensureConsistency();
updateState();
return;
@@ -313,16 +357,16 @@ public class ArrangementMatchingRuleEditor extends JPanel {
continue;
}
for (Object key : mutex) {
if (myConditionInfo.hasCondition(key)) {
ArrangementAtomMatchConditionComponent componentToDeselect = myComponents.get(key);
myConditionInfo.removeCondition(componentToDeselect.getMatchCondition().getValue());
myConditionInfo.addAtomCondition(chosenCondition);
ArrangementMatchCondition newCondition = myConditionInfo.buildCondition();
for (ArrangementAtomMatchConditionComponent componentToCheck : myComponents.values()) {
if (myRuleInfo.hasCondition(key)) {
ArrangementAtomMatchConditionComponent componentToDeselect = myConditionComponents.get(key);
myRuleInfo.removeCondition(componentToDeselect.getMatchCondition().getValue());
myRuleInfo.addAtomCondition(chosenCondition);
ArrangementMatchCondition newCondition = myRuleInfo.buildCondition();
for (ArrangementAtomMatchConditionComponent componentToCheck : myConditionComponents.values()) {
Object value = componentToCheck.getMatchCondition().getValue();
if (myConditionInfo.hasCondition(value) && !ArrangementConfigUtil.isEnabled(value, myFilter, newCondition)) {
myConditionInfo.removeCondition(componentToCheck.getMatchCondition().getValue());
newCondition = myConditionInfo.buildCondition();
if (myRuleInfo.hasCondition(value) && !ArrangementConfigUtil.isEnabled(value, myFilter, newCondition)) {
myRuleInfo.removeCondition(componentToCheck.getMatchCondition().getValue());
newCondition = myRuleInfo.buildCondition();
}
}
@@ -333,19 +377,16 @@ public class ArrangementMatchingRuleEditor extends JPanel {
}
}
}
myConditionInfo.addAtomCondition(chosenCondition);
myRuleInfo.addAtomCondition(chosenCondition);
updateState();
}
private void ensureConsistency() {
if (myConditionInfo == null) {
return;
}
ArrangementMatchCondition condition = myConditionInfo.buildCondition();
ArrangementMatchCondition condition = myRuleInfo.buildCondition();
Map<ArrangementSettingType, Set<?>> map = ArrangementConfigUtil.buildAvailableConditions(myFilter, condition);
for (ArrangementAtomMatchConditionComponent c : myComponents.values()) {
for (ArrangementAtomMatchConditionComponent c : myConditionComponents.values()) {
Object v = c.getMatchCondition().getValue();
if (!myConditionInfo.hasCondition(v)) {
if (!myRuleInfo.hasCondition(v)) {
continue;
}
boolean remain = false;
@@ -356,24 +397,13 @@ public class ArrangementMatchingRuleEditor extends JPanel {
}
}
if (!remain) {
myConditionInfo.removeCondition(v);
myRuleInfo.removeCondition(v);
ensureConsistency();
return;
}
}
}
@Nullable
private ArrangementAtomMatchConditionComponent getNodeComponentAt(@NotNull Point screenPoint) {
for (ArrangementAtomMatchConditionComponent component : myComponents.values()) {
Rectangle screenBounds = component.getScreenBounds();
if (screenBounds != null && screenBounds.contains(screenPoint)) {
return component;
}
}
return null;
}
private void repaintComponent(@NotNull ArrangementMatchConditionComponent component) {
Rectangle bounds = component.getScreenBounds();
if (bounds != null) {
@@ -24,6 +24,7 @@ import com.intellij.application.options.codeStyle.arrangement.util.IntObjectMap;
import com.intellij.openapi.application.ApplicationBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.codeStyle.arrangement.match.StdArrangementMatchRule;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import com.intellij.psi.codeStyle.arrangement.settings.ArrangementStandardSettingsAware;
import com.intellij.ui.table.JBTable;
import com.intellij.util.ui.AbstractTableCellEditor;
@@ -423,12 +424,14 @@ public class ArrangementMatchingRulesControl extends JBTable {
if (value instanceof ArrangementRepresentationAware) {
return ((ArrangementRepresentationAware)value).getComponent();
}
if (!(value instanceof StdArrangementMatchRule)) {
return EMPTY_RENDERER;
}
StdArrangementMatchRule rule = (StdArrangementMatchRule)value;
ArrangementListRowDecorator component = myComponents.get(row);
if (component == null) {
if (!(value instanceof StdArrangementMatchRule)) {
return EMPTY_RENDERER;
}
StdArrangementMatchRule rule = (StdArrangementMatchRule)value;
ArrangementMatchConditionComponent ruleComponent = myFactory.getComponent(rule.getMatcher().getCondition(), rule, true);
component = new ArrangementListRowDecorator(ruleComponent, ArrangementMatchingRulesControl.this);
myComponents.set(row, component);
@@ -438,6 +441,7 @@ public class ArrangementMatchingRulesControl extends JBTable {
component.setRowIndex((myEditorRow >= 0 && row > myEditorRow) ? row : row + 1);
component.setSelected(getSelectionModel().isSelectedIndex(row) || (myEditorRow >= 0 && row == myEditorRow - 1));
component.setBeingEdited(myEditorRow >= 0 && myEditorRow == row + 1);
component.setShowSortIcon(rule.getOrderType() == ArrangementEntryOrderType.BY_NAME);
return component.getUiComponent();
}
}
@@ -0,0 +1,104 @@
/*
* 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.match;
import com.intellij.application.options.codeStyle.arrangement.ArrangementNodeDisplayManager;
import com.intellij.application.options.codeStyle.arrangement.color.ArrangementColorsProvider;
import com.intellij.application.options.codeStyle.arrangement.util.ArrangementConfigUtil;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.psi.codeStyle.arrangement.model.ArrangementSettingType;
import com.intellij.psi.codeStyle.arrangement.order.ArrangementEntryOrderType;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SideBorder;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.GridBag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
/**
* @author Denis Zhdanov
* @since 11/15/12 1:01 PM
*/
public class ArrangementOrderTypeComponent extends JPanel {
@NotNull
private final SimpleColoredComponent myTextControl = new SimpleColoredComponent() {
@Override public Dimension getMinimumSize() { return getPreferredSize(); }
@Override public Dimension getMaximumSize() { return getPreferredSize(); }
@Override public Dimension getPreferredSize() { return myTextControlSize == null ? super.getPreferredSize() : myTextControlSize; }
@Override public String toString() { return "text component for " + this; }
};
@NotNull private final ArrangementEntryOrderType myOrderType;
@NotNull private final ArrangementColorsProvider myColorsProvider;
@NotNull private final String myText;
@NotNull private final SideBorder myBorder;
@Nullable private final Dimension myTextControlSize;
@Nullable private Rectangle myScreenBounds;
public ArrangementOrderTypeComponent(@NotNull ArrangementEntryOrderType orderType,
@NotNull ArrangementNodeDisplayManager displayManager,
@NotNull ArrangementColorsProvider colorsProvider,
int width)
{
super(new GridBagLayout());
myOrderType = orderType;
myColorsProvider = colorsProvider;
myTextControl.setTextAlign(SwingConstants.CENTER);
myText = displayManager.getDisplayValue(orderType);
TextAttributes attributes = colorsProvider.getTextAttributes(ArrangementSettingType.ORDER, false);
myTextControl.append(myText, SimpleTextAttributes.fromTextAttributes(attributes));
myTextControlSize = new Dimension(width, myTextControl.getPreferredSize().height);
add(myTextControl, new GridBag().anchor(GridBagConstraints.WEST));
setBorder(myBorder = (SideBorder)IdeBorderFactory.createBorder());
}
public void setSelected(boolean selected) {
myTextControl.clear();
TextAttributes attributes = myColorsProvider.getTextAttributes(ArrangementSettingType.ORDER, selected);
myTextControl.append(myText, SimpleTextAttributes.fromTextAttributes(attributes));
myBorder.setLineColor(myColorsProvider.getBorderColor(selected));
Color myBackgroundColor = attributes.getBackgroundColor();
myTextControl.setBackground(myBackgroundColor);
}
@Override
protected void paintComponent(Graphics g) {
Point point = ArrangementConfigUtil.getLocationOnScreen(this);
if (point != null) {
Rectangle bounds = getBounds();
myScreenBounds = new Rectangle(point.x, point.y, bounds.width, bounds.height);
}
super.paintComponent(g);
}
@NotNull
public ArrangementEntryOrderType getOrderType() {
return myOrderType;
}
@Nullable
public Rectangle getScreenBounds() {
return myScreenBounds;
}
}
@@ -18,6 +18,7 @@ package com.intellij.application.options.codeStyle.arrangement.util;
import com.intellij.application.options.codeStyle.arrangement.ArrangementConstants;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchConditionComponent;
import com.intellij.application.options.codeStyle.arrangement.match.ArrangementMatchingRulesControl;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.Presentation;
@@ -41,6 +42,8 @@ import java.awt.event.MouseEvent;
*/
public class ArrangementListRowDecorator extends JPanel implements ArrangementMatchConditionComponent {
@NotNull private final JLabel mySortLabel = new JLabel(AllIcons.Icons.Inspector.SortByName);
@NotNull private final ArrangementRuleIndexControl myRowIndexControl;
@NotNull private final ArrangementMatchConditionComponent myDelegate;
@NotNull private final ArrangementMatchingRulesControl myControl;
@@ -56,7 +59,9 @@ public class ArrangementListRowDecorator extends JPanel implements ArrangementMa
{
myDelegate = delegate;
myControl = control;
mySortLabel.setVisible(false);
AnAction action = ActionManager.getInstance().getAction("Arrangement.Rule.Edit");
Presentation presentation = action.getTemplatePresentation().clone();
Icon editIcon = presentation.getIcon();
@@ -82,6 +87,7 @@ public class ArrangementListRowDecorator extends JPanel implements ArrangementMa
GridBag constraints = new GridBag().anchor(GridBagConstraints.CENTER)
.insets(0, ArrangementConstants.HORIZONTAL_PADDING, 0, ArrangementConstants.HORIZONTAL_GAP * 2);
add(myRowIndexControl, constraints);
add(new InsetsPanel(mySortLabel), new GridBag().anchor(GridBagConstraints.CENTER).insets(0, 0, 0, ArrangementConstants.HORIZONTAL_GAP));
add(myDelegate.getUiComponent(), new GridBag().weightx(1).anchor(GridBagConstraints.WEST));
add(myEditButton, new GridBag().anchor(GridBagConstraints.EAST));
setBorder(IdeBorderFactory.createEmptyBorder(ArrangementConstants.VERTICAL_GAP));
@@ -154,6 +160,10 @@ public class ArrangementListRowDecorator extends JPanel implements ArrangementMa
myDelegate.setSelected(selected);
}
public void setShowSortIcon(boolean show) {
mySortLabel.setVisible(show);
}
@Override
public Rectangle onMouseEntered(@NotNull MouseEvent e) {
setBackground(UIUtil.getDecoratedRowColor());
@@ -1,310 +0,0 @@
/*
* 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.ide.util.projectWizard;
import com.intellij.ide.startup.StartupManagerEx;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.platform.DirectoryProjectGenerator;
import com.intellij.platform.WebProjectGenerator;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.io.File;
import java.util.Map;
/**
* @author Sergey Simonchik
*/
public class WebModuleGenerationStep extends ModuleWizardStep {
private final ModuleBuilder myModuleBuilder;
private final Icon myIcon;
private final String myHelpId;
private final Map<WebProjectGenerator, WebProjectGenerator.GeneratorPeer> myGeneratorPeers = ContainerUtil.newHashMap();
private JComponent myRootComponent;
private WebProjectGenerator myCurrentGenerator;
private JPanel myRightPanel;
public WebModuleGenerationStep(@NotNull ModuleBuilder moduleBuilder,
@NotNull Icon icon,
@NotNull String helpId) {
myModuleBuilder = moduleBuilder;
myIcon = icon;
myHelpId = helpId;
}
@Override
public JComponent getComponent() {
if (myRootComponent == null) {
myRootComponent = createComponent();
}
return myRootComponent;
}
@NotNull
private JComponent createComponent() {
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
final JBList generatorList = new JBList();
DirectoryProjectGenerator[] generators = Extensions.getExtensions(DirectoryProjectGenerator.EP_NAME);
DefaultListModel listModel = new DefaultListModel();
EmptyProjectGenerator emptyProjectGenerator = new EmptyProjectGenerator();
listModel.addElement(emptyProjectGenerator);
for (DirectoryProjectGenerator generator : generators) {
if (generator instanceof WebProjectGenerator) {
listModel.addElement(generator);
}
}
generatorList.setModel(listModel);
generatorList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
generatorList.getExpandableItemsHandler().setEnabled(false);
generatorList.setCellRenderer(new ListCellRendererWrapper<DirectoryProjectGenerator>() {
@Override
public void customize(JList list,
DirectoryProjectGenerator value,
int index,
boolean selected,
boolean hasFocus) {
setText(" " + value.getName());
}
});
generatorList.addListSelectionListener(new ListSelectionListener() {
@SuppressWarnings({"HardCodedStringLiteral"})
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
return;
}
@SuppressWarnings("unchecked")
WebProjectGenerator<Object> selectedGenerator =
(WebProjectGenerator<Object>) generatorList.getSelectedValue();
myCurrentGenerator = selectedGenerator;
showGenerator(selectedGenerator);
ApplicationManager.getApplication().invokeLater(new Runnable() {
public void run() {
generatorList.requestFocusInWindow();
}
});
}
});
JPanel leftPanel = createLeftPanel(generatorList);
splitPane.setLeftComponent(leftPanel);
myRightPanel = new JPanel(new CardLayout());
splitPane.setRightComponent(myRightPanel);
generatorList.setSelectedValue(emptyProjectGenerator, true);
return splitPane;
}
private <T> void showGenerator(@NotNull WebProjectGenerator<T> generator) {
WebProjectGenerator.GeneratorPeer peer = myGeneratorPeers.get(generator);
if (peer == null) {
peer = generator.createPeer();
JComponent component = peer.getComponent();
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 25));
panel.add(component);
myRightPanel.add(panel, generator.getName());
myRightPanel.revalidate();
myRightPanel.repaint();
myGeneratorPeers.put(generator, peer);
}
CardLayout cardLayout = (CardLayout) myRightPanel.getLayout();
cardLayout.show(myRightPanel, generator.getName());
}
@NotNull
private static JPanel createLeftPanel(@NotNull JList generatorList) {
JPanel panel = new JPanel();
LayoutManager boxLayoutManager = new BoxLayout(panel, BoxLayout.Y_AXIS);
panel.setLayout(boxLayoutManager);
JLabel label = new JLabel("Select Web Module Type:");
panel.add(label, Component.LEFT_ALIGNMENT);
label.setAlignmentX(Component.LEFT_ALIGNMENT);
panel.add(Box.createVerticalStrut(5));
JBScrollPane scrollPane = new JBScrollPane(
generatorList,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
);
Dimension listPrefSize = calcTypeListPreferredSize(generatorList);
scrollPane.setPreferredSize(listPrefSize);
panel.add(scrollPane, Component.LEFT_ALIGNMENT);
scrollPane.setAlignmentX(Component.LEFT_ALIGNMENT);
return panel;
}
@NotNull
private static Dimension calcTypeListPreferredSize(@NotNull JList list) {
FontMetrics fontMetrics = list.getFontMetrics(list.getFont());
int fontHeight = fontMetrics.getMaxAscent() + fontMetrics.getMaxDescent();
int width = 0;
int height = 0;
ListModel listModel = list.getModel();
int size = listModel.getSize();
for (int i = 0; i < size; i++) {
DirectoryProjectGenerator generator = (DirectoryProjectGenerator) listModel.getElementAt(i);
height += fontHeight + 6;
width = Math.max(width, fontMetrics.stringWidth(generator.getName()));
}
return new Dimension(width, height);
}
@Override
public boolean validate() throws ConfigurationException {
if (myCurrentGenerator == null) {
throw new RuntimeException("Current generator should be not-null");
}
WebProjectGenerator.GeneratorPeer peer = myGeneratorPeers.get(myCurrentGenerator);
if (peer == null) {
throw new ConfigurationException("Peer should be not-null for " + myCurrentGenerator.getName());
}
ValidationInfo validate = peer.validate();
if (validate != null) {
throw new ConfigurationException(validate.message);
}
return true;
}
@SuppressWarnings("unchecked")
@Override
public void updateDataModel() {
final WebProjectGenerator generator = myCurrentGenerator;
if (generator == null) {
throw new RuntimeException("Current generator should be not-null");
}
WebProjectGenerator.GeneratorPeer peer = myGeneratorPeers.get(myCurrentGenerator);
if (peer == null) {
throw new RuntimeException("Peer should be not-null for " + myCurrentGenerator.getName());
}
final Object settings = peer.getSettings();
File dir = new File(myModuleBuilder.getModuleFileDirectory());
final VirtualFile moduleDir = VfsUtil.findFileByIoFile(dir, true);
if (moduleDir != null && moduleDir.isValid()) {
myModuleBuilder.addListener(new ModuleBuilderListener() {
@Override
public void moduleCreated(@NotNull final Module module) {
myModuleBuilder.removeListener(this);
final Project project = module.getProject();
final Runnable task = new Runnable() {
@Override
public void run() {
generator.generateProject(project, moduleDir, settings, module);
}
};
final boolean scheduledAsPostStartupActivity;
StartupManagerEx startupManager = StartupManagerEx.getInstanceEx(project);
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (startupManager) {
scheduledAsPostStartupActivity = !startupManager.postStartupActivityPassed();
if (scheduledAsPostStartupActivity) {
startupManager.registerPostStartupActivity(task);
}
}
if (!scheduledAsPostStartupActivity) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
if (!project.isDisposed()) {
task.run();
}
}
});
}
}
});
}
}
public Icon getIcon() {
return myIcon;
}
@Override
public String getHelpId() {
return myHelpId;
}
private static class EmptyProjectGenerator extends WebProjectGenerator<Object> {
@NotNull
@Nls
@Override
public String getName() {
return "Empty module";
}
@Override
public String getDescription() {
return "";
}
@Override
public void generateProject(@NotNull Project project, @NotNull VirtualFile baseDir, @NotNull Object settings, @NotNull Module module) {}
@NotNull
@Override
public WebProjectGenerator.GeneratorPeer<Object> createPeer() {
return new WebProjectGenerator.GeneratorPeer<Object>() {
@NotNull
@Override
public JComponent getComponent() {
return new JLabel("No extra files will be created.");
}
@Nullable
@Override
public Pair<String, JComponent> getSettingsField() {
return null;
}
@NotNull
@Override
public Object getSettings() {
return new Object();
}
@Override
@Nullable
public ValidationInfo validate() {
return null;
}
@Override
public void addSettingsStateListener(@NotNull WebProjectGenerator.SettingsStateListener listener) {}
};
}
}
}
@@ -25,7 +25,6 @@ import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.NotNullLazyValue;
import com.intellij.openapi.util.Pair;
import com.intellij.platform.ProjectTemplate;
import com.intellij.platform.WebProjectGenerator;
import org.jetbrains.annotations.NotNull;
@@ -77,13 +76,7 @@ public abstract class WebProjectTemplate<T> extends WebProjectGenerator<T> imple
@Override
public ModuleWizardStep modifySettingsStep(SettingsStep settingsStep) {
GeneratorPeer<T> peer = myPeer.getValue();
Pair<String, JComponent> pair = peer.getSettingsField();
if (pair != null) {
settingsStep.addSettingsField(pair.first, pair.second);
}
else {
settingsStep.addSettingsComponent(peer.getComponent());
}
peer.buildUI(settingsStep);
return new ModuleWizardStep() {
@Override
public JComponent getComponent() {
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.lang.javascript.boilerplate.GithubProjectGeneratorPeer">
<grid id="27dc6" binding="myComponent" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myComponent" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="107"/>
@@ -10,19 +10,9 @@
<children>
<vspacer id="61e03">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="6cca1" class="javax.swing.JLabel" binding="myErrorMessage">
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-52429"/>
<foreground color="-65434"/>
<text value="Error message"/>
</properties>
</component>
<grid id="55618" binding="myVersionPanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
@@ -4,12 +4,13 @@ import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.projectWizard.SettingsStep;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.platform.WebProjectGenerator;
import com.intellij.platform.templates.github.GithubTagInfo;
import com.intellij.ui.ListCellRendererWrapper;
@@ -42,13 +43,15 @@ public class GithubProjectGeneratorPeer implements WebProjectGenerator.Generator
private final GithubTagInfo myMasterTag;
private final GithubTagListProvider myTagListProvider;
private final AsyncProcessIcon myLoadingVersionIcon = new AsyncProcessIcon("Getting github tags");
private final JLabel myErrorMessage = new JLabel();
private JComboBox myComboBox;
private JComponent myComponent;
private JLabel myErrorMessage;
private JPanel myVersionPanel;
private JPanel myActionPanel;
private UpdateStatus myUpdateStatus;
public GithubProjectGeneratorPeer(@NotNull AbstractGithubTagDownloadedProjectGenerator generator) {
myErrorMessage.setForeground(Color.RED);
String ghUserName = generator.getGithubUserName();
String ghRepoName = generator.getGithubRepositoryName();
myMasterTag = new GithubTagInfo(
@@ -59,9 +62,8 @@ public class GithubProjectGeneratorPeer implements WebProjectGenerator.Generator
myComboBox.setRenderer(new ListCellRendererWrapper<GithubTagInfo>() {
@Override
public void customize(JList list, GithubTagInfo tag, int index, boolean selected, boolean hasFocus) {
if (tag != null) {
setText(tag.getName());
}
String text = tag == null ? "Unavailable" : tag.getName();
setText(text);
}
});
@@ -69,20 +71,19 @@ public class GithubProjectGeneratorPeer implements WebProjectGenerator.Generator
fillActionPanel();
ImmutableSet<GithubTagInfo> cachedTags = myTagListProvider.getCachedTags();
if (cachedTags != null) {
tagsUpdated(cachedTags);
onTagsUpdated(cachedTags);
}
myErrorMessage.setText(null);
reloadTagsInBackground();
}
void tagsUpdated(@NotNull ImmutableSet<GithubTagInfo> tags) {
show(UpdateStatus.IDLE);
void onTagsUpdated(@NotNull ImmutableSet<GithubTagInfo> tags) {
changeUpdateStatus(UpdateStatus.IDLE);
if (!shouldUpdate(tags)) {
return;
}
List<GithubTagInfo> sortedTags = createSortedTagList(tags);
GithubTagInfo selectedItem = GithubTagInfo.tryCast(myComboBox.getSelectedItem());
GithubTagInfo previouslySelectedTag = getSelectedTag();
GithubTagInfo selectedItem = previouslySelectedTag;
if (selectedItem == null && sortedTags.size() > 0) {
selectedItem = sortedTags.get(0);
}
@@ -102,13 +103,19 @@ public class GithubProjectGeneratorPeer implements WebProjectGenerator.Generator
}
}
myComboBox.updateUI();
if (previouslySelectedTag == null && selectedItem != null) {
fireStateChanged();
}
}
void setErrorMessage(@Nullable final String message) {
void onTagsUpdateError(@NotNull final String errorMessage) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
myErrorMessage.setText(message);
if (getSelectedTag() == null) {
myErrorMessage.setText(errorMessage);
}
changeUpdateStatus(UpdateStatus.IDLE);
}
});
}
@@ -150,28 +157,38 @@ public class GithubProjectGeneratorPeer implements WebProjectGenerator.Generator
}
@Override
public Pair<String, JComponent> getSettingsField() {
return new Pair<String, JComponent>("\u001BVersion:", myVersionPanel);
public void buildUI(@NotNull SettingsStep settingsStep) {
settingsStep.addSettingsField("\u001BVersion:", myVersionPanel);
settingsStep.addSettingsComponent(myErrorMessage);
}
@NotNull
@Override
public GithubTagInfo getSettings() {
Object obj = myComboBox.getSelectedItem();
if (obj instanceof GithubTagInfo) {
return (GithubTagInfo) obj;
GithubTagInfo tag = getSelectedTag();
if (tag == null) {
throw new RuntimeException("[internal error] No versions available.");
}
throw new RuntimeException("Can't handle selected version: " + obj);
return tag;
}
@Override
@Nullable
public ValidationInfo validate() {
Object obj = myComboBox.getSelectedItem();
if (obj instanceof GithubTagInfo) {
GithubTagInfo tag = getSelectedTag();
if (tag != null) {
return null;
}
return new ValidationInfo("Can't handle selected version: " + obj);
String errorMessage = StringUtil.notNullize(myErrorMessage.getText());
if (errorMessage.isEmpty()) {
errorMessage = "Versions have not been loaded yet.";
}
return new ValidationInfo(errorMessage);
}
@Override
public boolean isBackgroundJobRunning() {
return myUpdateStatus == UpdateStatus.UPDATING;
}
@Override
@@ -179,23 +196,40 @@ public class GithubProjectGeneratorPeer implements WebProjectGenerator.Generator
myListeners.add(listener);
}
@Nullable
private GithubTagInfo getSelectedTag() {
return GithubTagInfo.tryCast(myComboBox.getSelectedItem());
}
private void fireStateChanged() {
GithubTagInfo tag = getSelectedTag();
for (WebProjectGenerator.SettingsStateListener listener : myListeners) {
listener.stateChanged(tag != null);
}
}
private void reloadTagsInBackground() {
show(UpdateStatus.UPDATING);
changeUpdateStatus(UpdateStatus.UPDATING);
myErrorMessage.setText(null);
myTagListProvider.updateTagListAsynchronously(this);
}
private void show(@NotNull UpdateStatus status) {
private void changeUpdateStatus(@NotNull UpdateStatus status) {
CardLayout cardLayout = (CardLayout) myActionPanel.getLayout();
cardLayout.show(myActionPanel, status.name());
if (status == UpdateStatus.UPDATING) {
myLoadingVersionIcon.resume();
}
else {
myLoadingVersionIcon.suspend();
}
myUpdateStatus = status;
}
private void fillActionPanel() {
myActionPanel.add(createReloadButtonPanel(), UpdateStatus.IDLE.name());
myActionPanel.add(createReloadInProgressPanel(), UpdateStatus.UPDATING.name());
show(UpdateStatus.IDLE);
changeUpdateStatus(UpdateStatus.IDLE);
}
@NotNull
@@ -215,7 +249,6 @@ public class GithubProjectGeneratorPeer implements WebProjectGenerator.Generator
@NotNull
private JPanel createReloadInProgressPanel() {
JPanel panel = new JPanel(new BorderLayout(3, 0));
myLoadingVersionIcon.suspend();
panel.add(myLoadingVersionIcon, BorderLayout.CENTER);
panel.add(new JLabel("Loading..."), BorderLayout.EAST);
return panel;
@@ -64,15 +64,15 @@ public class GithubTagListProvider {
@Override
public void run() {
final String[] urls = formatTagListDownloadUrls();
String firstErrorMessage = null;
String errorMessage = null;
peer.setErrorMessage(null);
for (String url : urls) {
try {
final ImmutableSet<GithubTagInfo> tags = fetchGithubTagsByUrl(url);
LOG.info(getGeneratorName() + "Cache has been successfully updated");
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
peer.tagsUpdated(tags);
peer.onTagsUpdated(tags);
}
});
return;
@@ -85,9 +85,12 @@ public class GithubTagListProvider {
errorMessage = "Malformed JSON received from " + url;
LOG.warn(getGeneratorName() + errorMessage, e);
}
if (firstErrorMessage == null) {
firstErrorMessage = errorMessage;
}
}
if (errorMessage != null) {
peer.setErrorMessage(errorMessage);
if (firstErrorMessage != null) {
peer.onTagsUpdateError(firstErrorMessage);
}
}
};
@@ -528,7 +528,8 @@ public abstract class PropertyTable extends JBTable {
int size = properties.size();
for (int i = 0; i < size; i++) {
if (name.equals(properties.get(i).getName())) {
Property nextProperty = properties.get(i);
if (Comparing.equal(nextProperty.getGroup(), property.getGroup()) && name.equals(nextProperty.getName())) {
return i;
}
}
@@ -38,7 +38,7 @@ public class DarculaInstaller {
}
private static void restart() {
if (Messages.showOkCancelDialog("You must restart the IDE to changes take effect. Restart now?", "Restart", Messages.getQuestionIcon()) == Messages.OK) {
if (Messages.showOkCancelDialog("You must restart the IDE to changes take effect. Restart now?", "Restart Is Required", "Restart", "Postpone", Messages.getQuestionIcon()) == Messages.OK) {
ApplicationManagerEx.getApplicationEx().restart();
}
}
@@ -16,13 +16,13 @@
package com.intellij.platform;
import com.intellij.facet.ui.ValidationResult;
import com.intellij.ide.util.projectWizard.SettingsStep;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.ValidationInfo;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.IdeBorderFactory;
import org.jetbrains.annotations.Nls;
@@ -82,8 +82,7 @@ public abstract class WebProjectGenerator<T> implements DirectoryProjectGenerato
@NotNull
JComponent getComponent();
@Nullable
Pair<String, JComponent> getSettingsField();
void buildUI(@NotNull SettingsStep settingsStep);
@NotNull
T getSettings();
@@ -91,6 +90,8 @@ public abstract class WebProjectGenerator<T> implements DirectoryProjectGenerato
@Nullable
ValidationInfo validate();
boolean isBackgroundJobRunning();
void addSettingsStateListener(@NotNull SettingsStateListener listener);
}
@@ -109,7 +110,7 @@ public abstract class WebProjectGenerator<T> implements DirectoryProjectGenerato
myPeer = peer;
myCenterComponent = peer.getComponent();
myDescriptionPane = new JTextPane();
myDescriptionPane.setBorder(IdeBorderFactory.createEmptyBorder(5, 0, 5, 0));
myDescriptionPane.setBorder(IdeBorderFactory.createEmptyBorder(5, 0, 10, 0));
Messages.configureMessagePaneUi(myDescriptionPane, getDescription());
getOKAction().setEnabled(peer.validate() == null);
@@ -117,6 +118,7 @@ public abstract class WebProjectGenerator<T> implements DirectoryProjectGenerato
@Override
public void stateChanged(boolean validSettings) {
getOKAction().setEnabled(validSettings);
initValidation();
}
});
setTitle(WebProjectGenerator.this.getName());
@@ -130,7 +132,11 @@ public abstract class WebProjectGenerator<T> implements DirectoryProjectGenerato
@Override
protected ValidationInfo doValidate() {
return myPeer.validate();
ValidationInfo validationInfo = myPeer.validate();
if (validationInfo != null && myPeer.isBackgroundJobRunning()) {
return null;
}
return validationInfo;
}
@Nullable
@@ -558,6 +558,7 @@ arrangement.text.empty.rule=<empty rule>
arrangement.text.type=Type
arrangement.text.modifier=Modifier
arrangement.text.name=Name
arrangement.order.name=Order
arrangement.action.rule.add.text=Add rule
arrangement.action.rule.add.description=Add new arrangement rule
arrangement.action.rule.remove.text=Remove rule(s)
+63 -3
View File
@@ -39,7 +39,7 @@
</option>
<option name="ANNOTATION_NAME_ATTRIBUTES">
<value>
<option name="FOREGROUND" value="fcf629" />
<option name="FOREGROUND" value="bbb529" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
@@ -467,6 +467,36 @@
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.AL4.LOCAL_VARIABLE">
<value>
<option name="FOREGROUND" value="458383" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="-1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.ATTRIBUTE">
<value>
<option name="FOREGROUND" value="bbb529" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="-1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.INSTANCE_MEMBER_FUNCTION">
<value>
<option name="FOREGROUND" value="9876aa" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="-1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.KEYWORD">
<value>
<option name="FOREGROUND" value="cc7832" />
@@ -477,6 +507,36 @@
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.PARAMETER">
<value>
<option name="FOREGROUND" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="2" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.REGEXP">
<value>
<option name="FOREGROUND" value="3fa29a" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="-1" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="ECMAL4.STATIC_MEMBER_FUNCTION">
<value>
<option name="FOREGROUND" value="9876aa" />
<option name="BACKGROUND" />
<option name="FONT_TYPE" value="2" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="0" />
<option name="ERROR_STRIPE_COLOR" />
</value>
</option>
<option name="EL.BOUNDS">
<value>
<option name="FOREGROUND" />
@@ -2510,7 +2570,7 @@
<option name="SEARCH_RESULT_ATTRIBUTES">
<value>
<option name="FOREGROUND" />
<option name="BACKGROUND" value="006300" />
<option name="BACKGROUND" value="6300" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="0" />
@@ -2860,7 +2920,7 @@
<option name="TEXT_SEARCH_RESULT_ATTRIBUTES">
<value>
<option name="FOREGROUND" />
<option name="BACKGROUND" value="006300" />
<option name="BACKGROUND" value="6300" />
<option name="FONT_TYPE" value="0" />
<option name="EFFECT_COLOR" />
<option name="EFFECT_TYPE" value="0" />