Merge remote-tracking branch 'origin/master'

This commit is contained in:
anna
2012-11-16 14:27:50 +01:00
25 changed files with 344 additions and 207 deletions
@@ -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.ide.util.newProjectWizard.SelectTemplateStep">
<grid id="27dc6" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="true" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="608" height="393"/>
@@ -8,35 +8,6 @@
<properties/>
<border type="none"/>
<children>
<grid id="ac540" binding="myLeftPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false">
<preferred-size width="155" height="44"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="3580d" class="com.intellij.ui.SearchTextField" binding="mySearchField" custom-create="true">
<constraints border-constraint="North"/>
<properties/>
</component>
<scrollpane id="474de" class="com.intellij.ui.components.JBScrollPane">
<constraints border-constraint="Center"/>
<properties/>
<border type="none"/>
<children>
<component id="a0023" class="com.intellij.ui.treeStructure.SimpleTree" binding="myTemplatesTree">
<constraints/>
<properties/>
<clientProperties>
<JTree.lineStyle class="java.lang.String" value="Angled"/>
</clientProperties>
</component>
</children>
</scrollpane>
</children>
</grid>
<grid id="e5cc3" binding="myRightPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="5" bottom="0" right="0"/>
<constraints>
@@ -65,7 +36,7 @@
<properties>
<contentType value="text/html"/>
<editable value="false"/>
<text value="&lt;html&gt;&#13;&#10; &lt;head&gt;&#13;&#10;&#13;&#10; &lt;/head&gt;&#13;&#10; &lt;body&gt;&#13;&#10; &lt;p style=&quot;margin-top: 0&quot;&gt;&#13;&#10; &#13;&#10; &lt;/p&gt;&#13;&#10; &lt;/body&gt;&#13;&#10;&lt;/html&gt;&#13;&#10;"/>
<text value="&lt;html&gt;&#13;&#10; &lt;head&gt;&#13;&#10; &#13;&#10; &lt;/head&gt;&#13;&#10; &lt;body&gt;&#13;&#10; &lt;/body&gt;&#13;&#10;&lt;/html&gt;&#13;&#10;"/>
</properties>
</component>
</children>
@@ -166,6 +137,40 @@
</vspacer>
</children>
</grid>
<grid id="90483" binding="myLeftPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<minimum-size width="200" height="-1"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="3580d" class="com.intellij.ui.SearchTextField" binding="mySearchField" custom-create="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<scrollpane id="474de" class="com.intellij.ui.components.JBScrollPane">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="a0023" class="com.intellij.ui.treeStructure.SimpleTree" binding="myTemplatesTree">
<constraints/>
<properties/>
<clientProperties>
<JTree.lineStyle class="java.lang.String" value="Angled"/>
</clientProperties>
</component>
</children>
</scrollpane>
</children>
</grid>
</children>
</grid>
</form>
@@ -254,8 +254,9 @@ public class SelectTemplateStep extends ModuleWizardStep implements SettingsStep
addField("Project \u001bformat:", myFormatPanel.getStorageFormatComboBox(), myModulePanel);
}
mySplitter = new JBSplitter(false, 0.3f);
mySplitter = new JBSplitter(false, 0.3f, 0.3f, 0.6f);
mySplitter.setSplitterProportionKey("select.template.proportion");
myLeftPanel.setMinimumSize(new Dimension(200, 200));
mySplitter.setFirstComponent(myLeftPanel);
mySplitter.setSecondComponent(myRightPanel);
// mySettingsPanel.setVisible(false);
@@ -36,6 +36,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.zip.ZipInputStream;
@@ -66,6 +67,9 @@ public class RemoteTemplatesFactory implements ProjectTemplatesFactory {
String text = StreamUtil.readText(stream);
return createFromText(text);
}
catch (InterruptedIOException ex) { // timeouts etc
return ProjectTemplate.EMPTY_ARRAY;
}
catch (Exception e) {
LOG.error(e);
return ProjectTemplate.EMPTY_ARRAY;
@@ -112,7 +112,7 @@ public class DuplicatesImpl {
if (!ApplicationManager.getApplication().isUnitTestMode()) {
if ((!skipPromptWhenOne || size > 1) && (showAll.get() == null || !showAll.get())) {
final String prompt = provider.getConfirmDuplicatePrompt(match);
final ReplacePromptDialog promptDialog = new ReplacePromptDialog(false, provider.getReplaceDuplicatesTitle(idx, size), project){
final ReplacePromptDialog promptDialog = new ReplacePromptDialog(false, provider.getReplaceDuplicatesTitle(idx, size), project) {
@Override
protected String getMessage() {
final String message = super.getMessage();
@@ -355,7 +355,7 @@ public class FindManagerTest extends DaemonAnalyzerTestCase {
List<Usage> usages = FindUtil.findAll(getProject(), myEditor, findModel);
for (Usage usage : usages) {
ReplaceInProjectManager.getInstance(getProject()).doReplace(usage, findModel, Collections.<Usage>emptySet());
ReplaceInProjectManager.getInstance(getProject()).doReplace(usage, findModel, Collections.<Usage>emptySet(), false);
}
String newText = StringUtil.repeat(toReplace + "\n",6);
assertEquals(newText, getEditor().getDocument().getText());
@@ -1,6 +1,8 @@
package org.jetbrains.jps.model.library.impl;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.*;
@@ -11,9 +13,7 @@ import org.jetbrains.jps.model.library.*;
import org.jetbrains.jps.util.JpsPathUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.*;
/**
* @author nik
@@ -147,6 +147,8 @@ public class JpsLibraryImpl<P extends JpsElement> extends JpsNamedCompositeEleme
return urls;
}
private static final Set<String> AR_EXTENSIONS = ContainerUtil.newTroveSet(FileUtil.PATH_HASHING_STRATEGY, "jar", "zip", "swc", "ane");
private static void collectArchives(File file, boolean recursively, List<String> result) {
final File[] children = file.listFiles();
if (children != null) {
@@ -158,7 +160,7 @@ public class JpsLibraryImpl<P extends JpsElement> extends JpsNamedCompositeEleme
}
}
// todo [nik] get list of extensions mapped to Archive file type from IDE settings
else if (extension.equals("jar") || extension.equals("zip") || extension.equals("swc") || extension.equals("ane")) {
else if (AR_EXTENSIONS.contains(extension)) {
result.add(JpsPathUtil.getLibraryRootUrl(child));
}
}
@@ -66,7 +66,7 @@ public abstract class FindManager {
*
* @param model the model containing the settings of the replace operation.
* @param title the title of the dialog to show.
* @return the exit code of the dialog, as defined by the {@link PromptResult}
* @return the exit code of the dialog, as defined by the {@link com.intellij.find.FindManager.PromptResult}
* interface.
*/
public abstract int showPromptDialog(FindModel model, String title);
@@ -118,6 +118,18 @@ public abstract class FindManager {
public abstract FindResult findString(@NotNull CharSequence text, int offset, @NotNull FindModel model,
@Nullable VirtualFile findContextFile);
/**
* Shows a replace prompt dialog for the bad replace operation.
*
* @param model the model containing the settings of the replace operation.
* @param title the title of the dialog to show.
* @param exception exception from {@link FindManager#getStringToReplace}
* @return the exit code of the dialog, as defined by the {@link PromptResult}
* interface. May be only {@link PromptResult.CANCEL} or {@link PromptResult.SKIP} for bad replace operation
*/
public abstract int showMalformedReplacementPrompt(FindModel model, String title, MalformedReplacementStringException exception);
public static class MalformedReplacementStringException extends Exception {
public MalformedReplacementStringException(String s) {
super(s); //To change body of overridden methods use File | Settings | File Templates.
@@ -15,8 +15,10 @@
*/
package com.intellij.application.options.codeStyle.arrangement.action;
import com.intellij.lang.Language;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.ServiceManager;
@@ -27,6 +29,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.arrangement.Rearranger;
import com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine;
import java.util.ArrayList;
@@ -40,6 +43,16 @@ import java.util.List;
*/
public class RearrangeCodeAction extends AnAction {
@Override
public void update(AnActionEvent e) {
Language language = LangDataKeys.LANGUAGE.getData(e.getDataContext());
boolean enabled = false;
if (language != null) {
enabled = Rearranger.EXTENSION.forLanguage(language) != null;
}
e.getPresentation().setEnabled(enabled);
}
@Override
public void actionPerformed(AnActionEvent e) {
final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
@@ -88,18 +88,21 @@ public class ArrangementMatchNodeComponentFactory {
ArrangementAnimationManager.Callback
{
@NotNull private final StdArrangementMatchRule myRule;
@NotNull private final StdArrangementMatchRule myRule;
@NotNull private Object myModelValue;
private int myRow;
RemoveAtomConditionCallback(@NotNull StdArrangementMatchRule rule) {
myRule = rule;
myModelValue = myRule;
}
@Override
public void consume(@NotNull ArrangementAtomMatchConditionComponent component) {
ArrangementAtomMatchCondition condition = component.getMatchCondition();
ArrangementMatchingRulesModel model = myList.getModel();
int i = getRuleIndex();
int i = getModelIndex();
if (i < 0) {
return;
}
@@ -108,7 +111,7 @@ public class ArrangementMatchNodeComponentFactory {
ArrangementMatchCondition existingCondition = myRule.getMatcher().getCondition();
if (existingCondition.equals(condition)) {
// We can't just remove an element at this time because that breaks last row rendering.
model.set(i, new DummyElement());
model.set(i, myModelValue = new DummyElement());
}
else {
assert existingCondition instanceof ArrangementCompositeMatchCondition;
@@ -116,13 +119,15 @@ public class ArrangementMatchNodeComponentFactory {
operands.remove(condition);
if (operands.isEmpty()) {
// We can't just remove an element at this time because that breaks last row rendering.
model.set(i, new DummyElement());
model.set(i, myModelValue = new DummyElement());
}
else if (operands.size() == 1) {
model.set(i, new StdArrangementMatchRule(new StdArrangementEntryMatcher(operands.iterator().next()), myRule.getOrderType()));
myModelValue = new StdArrangementMatchRule(new StdArrangementEntryMatcher(operands.iterator().next()), myRule.getOrderType());
model.set(i, myModelValue);
}
else if (ArrangementConstants.LOG_RULE_MODIFICATION) {
LOG.info(String.format("Removed '%s' condition. Current rule state: %s", condition, myRule));
myModelValue = myRule;
}
}
@@ -132,37 +137,46 @@ public class ArrangementMatchNodeComponentFactory {
@Override
public void onAnimationIteration(boolean finished) {
refreshRow();
if (myRow < 0) {
return;
}
myList.repaintRows(myRow, myRow, finished);
if (!finished) {
return;
}
ArrangementMatchingRulesModel model = myList.getModel();
boolean repaintToBottom = getRuleIndex() < 0;
if (repaintToBottom) {
Object removeCandidate = model.getElementAt(myRow);
if (removeCandidate instanceof DummyElement) {
model.removeRow(myRow);
}
}
if (repaintToBottom && myRow < model.getSize()) {
myList.repaintRows(myRow, model.getSize() - 1, true);
if (myModelValue instanceof DummyElement) {
model.removeRow(myRow);
}
}
private int getRuleIndex() {
private void refreshRow() {
ArrangementMatchingRulesModel model = myList.getModel();
if (myRow < 0 || myRow >= model.getSize()) {
myRow = getModelIndex();
}
else {
Object o = model.getElementAt(myRow);
if (o != myModelValue) {
myRow = getModelIndex();
}
}
}
private int getModelIndex() {
// We can't just use model.indexOf(myRule) because there is a possible case that the model contain equal
// rules (rule1.equals(rule2) == true). That's why we have a helper method for search by reference identity.
ArrangementMatchingRulesModel model = myList.getModel();
for (int i = 0, max = model.getSize(); i < max; i++) {
if (model.getElementAt(i) == myRule) {
if (model.getElementAt(i) == myModelValue) {
return i;
}
}
return -1;
}
}
private static class DummyElement {
@Override
public String toString() {
@@ -421,17 +421,19 @@ public class ArrangementMatchingRulesControl extends JBTable {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (isEditing() && getEditingRow() == row) {
return EMPTY_RENDERER;
}
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);
@@ -441,7 +443,9 @@ 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);
boolean showSortIcon = value instanceof StdArrangementMatchRule
&& ((StdArrangementMatchRule)value).getOrderType() == ArrangementEntryOrderType.BY_NAME;
component.setShowSortIcon(showSortIcon);
return component.getUiComponent();
}
}
@@ -638,7 +638,7 @@ public class FindUtil {
}
}
ReplaceInProjectManager.reportNumberReplacedOccurences(project, occurrences);
ReplaceInProjectManager.reportNumberReplacedOccurrences(project, occurrences);
return replaced;
}
@@ -155,7 +155,11 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
@Override
public int showPromptDialog(final FindModel model, String title) {
ReplacePromptDialog replacePromptDialog = new ReplacePromptDialog(model.isMultipleFiles(), title, myProject) {
return showPromptDialogImpl(model, title, null);
}
public int showPromptDialogImpl(final FindModel model, String title, @Nullable final MalformedReplacementStringException exception) {
ReplacePromptDialog replacePromptDialog = new ReplacePromptDialog(model.isMultipleFiles(), title, myProject, exception) {
@Override
@Nullable
public Point getInitialLocation() {
@@ -313,6 +317,11 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
}
}
@Override
public int showMalformedReplacementPrompt(FindModel model, String title, MalformedReplacementStringException exception) {
return showPromptDialogImpl(model, title, exception);
}
@Override
public FindModel getPreviousFindModel() {
return myPreviousFindModel;
@@ -626,10 +635,14 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
return replaced.substring(matcher.start());
}
catch (Exception e) {
throw new MalformedReplacementStringException(FindBundle.message("find.replace.invalid.replacement.string", model.getStringToReplace()), e);
throw createMalformedReplacementException(model, e);
}
}
private static MalformedReplacementStringException createMalformedReplacementException(FindModel model, Exception e) {
return new MalformedReplacementStringException(FindBundle.message("find.replace.invalid.replacement.string", model.getStringToReplace()), e);
}
private static String getStringToReplaceByRegexp0(String foundString, final FindModel model) throws MalformedReplacementStringException{
String toFind = model.getStringToFind();
String toReplace = model.getStringToReplace();
@@ -651,7 +664,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo
return matcher.replaceAll(StringUtil.unescapeStringCharacters(toReplace));
}
catch (Exception e) {
throw new MalformedReplacementStringException(FindBundle.message("find.replace.invalid.replacement.string", model.getStringToReplace()), e);
throw createMalformedReplacementException(model, e);
}
}
else {
@@ -19,6 +19,7 @@ package com.intellij.find.replaceInProject;
import com.intellij.find.*;
import com.intellij.find.findInProject.FindInProjectManager;
import com.intellij.find.impl.FindInProjectUtil;
import com.intellij.notification.NotificationGroup;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
@@ -27,14 +28,17 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Factory;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.Segment;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
@@ -47,12 +51,11 @@ import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
public class ReplaceInProjectManager {
static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup("FindInPath", ToolWindowId.FIND, false);
private final Project myProject;
private boolean myIsFindInProgress = false;
@@ -214,7 +217,16 @@ public class ReplaceInProjectManager {
CommandProcessor.getInstance()
.executeCommand(myProject, selectOnEditorRunnable, FindBundle.message("find.replace.select.on.editor.command"), null);
String title = FindBundle.message("find.replace.found.usage.title", i + 1, usages.length);
int result = FindManager.getInstance(myProject).showPromptDialog(replaceContext.getFindModel(), title);
int result;
try {
doReplace(usage, replaceContext.getFindModel(), replaceContext.getExcludedSet(), true);
result = FindManager.getInstance(myProject).showPromptDialog(replaceContext.getFindModel(), title);
}
catch (FindManager.MalformedReplacementStringException e) {
markAsMalformedReplacement(replaceContext, usage);
result = FindManager.getInstance(myProject).showMalformedReplacementPrompt(replaceContext.getFindModel(), title, e);
}
if (result == FindManager.PromptResult.CANCEL) {
return;
@@ -225,16 +237,15 @@ public class ReplaceInProjectManager {
final int currentNumber = i;
if (result == FindManager.PromptResult.OK) {
final Ref<Boolean> success = Ref.create();
Runnable runnable = new Runnable() {
@Override
public void run() {
doReplace(usage, replaceContext.getFindModel(), replaceContext.getExcludedSet());
replaceContext.getUsageView().removeUsage(usage);
success.set(doReplace(usage, replaceContext));
}
};
CommandProcessor.getInstance().executeCommand(myProject, runnable, FindBundle.message("find.replace.command"), null);
if (i + 1 == usages.length) {
replaceContext.getUsageView().close();
if (closeUsageViewIfEmpty(replaceContext.getUsageView(), success.get())) {
return;
}
}
@@ -246,7 +257,7 @@ public class ReplaceInProjectManager {
@Override
public void run() {
int j = currentNumber;
boolean success = true;
for (; j < usages.length; j++) {
final Usage usage = usages[j];
final UsageInfo usageInfo = ((UsageInfo2UsageAdapter)usage).getUsageInfo();
@@ -257,12 +268,11 @@ public class ReplaceInProjectManager {
if (!otherPsiFile.equals(psiFile)) {
break;
}
doReplace(usage, replaceContext.getFindModel(), replaceContext.getExcludedSet());
replaceContext.getUsageView().removeUsage(usage);
}
if (j == usages.length) {
replaceContext.getUsageView().close();
if (!doReplace(usage, replaceContext)) {
success = false;
}
}
closeUsageViewIfEmpty(replaceContext.getUsageView(), success);
nextNumber[0] = j;
}
};
@@ -277,8 +287,8 @@ public class ReplaceInProjectManager {
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
@Override
public void run() {
doReplace(replaceContext, _usages);
replaceContext.getUsageView().close();
final boolean success = doReplace(replaceContext, _usages);
closeUsageViewIfEmpty(replaceContext.getUsageView(), success);
}
}, FindBundle.message("find.replace.command"), null);
break;
@@ -286,15 +296,28 @@ public class ReplaceInProjectManager {
}
}
private boolean doReplace(Usage usage, ReplaceContext replaceContext) {
try {
doReplace(usage, replaceContext.getFindModel(), replaceContext.getExcludedSet(), false);
replaceContext.getUsageView().removeUsage(usage);
}
catch (FindManager.MalformedReplacementStringException e) {
markAsMalformedReplacement(replaceContext, usage);
return false;
}
return true;
}
private void addReplaceActions(final ReplaceContext replaceContext) {
final Runnable replaceRunnable = new Runnable() {
@Override
public void run() {
doReplace(replaceContext, replaceContext.getUsageView().getUsages());
final UsageView usageView = replaceContext.getUsageView();
final boolean success = doReplace(replaceContext, usageView.getUsages());
closeUsageViewIfEmpty(usageView, success);
}
};
replaceContext.getUsageView().addPerformOperationAction(replaceRunnable, FindBundle.message("find.replace.all.action"), null,
FindBundle.message("find.replace.all.action.description"));
replaceContext.getUsageView().addButtonToLowerPane(replaceRunnable, FindBundle.message("find.replace.all.action"));
final Runnable replaceSelectedRunnable = new Runnable() {
@Override
@@ -306,14 +329,29 @@ public class ReplaceInProjectManager {
replaceContext.getUsageView().addButtonToLowerPane(replaceSelectedRunnable, FindBundle.message("find.replace.selected.action"));
}
private void doReplace(final ReplaceContext replaceContext, Collection<Usage> usages) {
private boolean doReplace(final ReplaceContext replaceContext, Collection<Usage> usages) {
boolean success = true;
int replacedCount = 0;
for (final Usage usage : usages) {
doReplace(usage, replaceContext.getFindModel(), replaceContext.getExcludedSet());
try {
doReplace(usage, replaceContext.getFindModel(), replaceContext.getExcludedSet(), false);
replaceContext.getUsageView().removeUsage(usage);
replacedCount++;
}
catch (FindManager.MalformedReplacementStringException e) {
markAsMalformedReplacement(replaceContext, usage);
success = false;
}
}
reportNumberReplacedOccurences(myProject, usages.size());
reportNumberReplacedOccurrences(myProject, replacedCount);
return success;
}
public static void reportNumberReplacedOccurences(Project project, int occurrences) {
private static void markAsMalformedReplacement(ReplaceContext replaceContext, Usage usage) {
replaceContext.getUsageView().excludeUsages(new Usage[]{usage});
}
public static void reportNumberReplacedOccurrences(Project project, int occurrences) {
if (occurrences != 0) {
final StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
if (statusBar != null) {
@@ -322,7 +360,12 @@ public class ReplaceInProjectManager {
}
}
public void doReplace(@NotNull final Usage usage, @NotNull final FindModel findModel, @NotNull final Set<Usage> excludedSet) {
public void doReplace(@NotNull final Usage usage,
@NotNull final FindModel findModel,
@NotNull final Set<Usage> excludedSet,
final boolean justCheck)
throws FindManager.MalformedReplacementStringException {
final Ref<FindManager.MalformedReplacementStringException> exceptionResult = Ref.create();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -331,41 +374,55 @@ public class ReplaceInProjectManager {
}
final Document document = ((UsageInfo2UsageAdapter)usage).getDocument();
if (!document.isWritable()) return;
((UsageInfo2UsageAdapter)usage).processRangeMarkers(new Processor<Segment>() {
@Override
public boolean process(Segment segment) {
if (!document.isWritable()) return false;
final int textOffset = segment.getStartOffset();
if (textOffset < 0 || textOffset >= document.getTextLength()) {
return true;
}
final int textEndOffset = segment.getEndOffset();
if (textEndOffset < 0 || textOffset > document.getTextLength()) {
return true;
}
FindManager findManager = FindManager.getInstance(myProject);
final CharSequence foundString = document.getCharsSequence().subSequence(textOffset, textEndOffset);
FindResult findResult = findManager.findString(document.getCharsSequence(), textOffset, findModel);
if (!findResult.isStringFound()) {
return true;
}
String stringToReplace = null;
final Ref<String> stringToReplace = Ref.create();
try {
stringToReplace =
findManager.getStringToReplace(foundString.toString(), findModel, textOffset, document.getText());
if (!getStringToReplace(textOffset, textEndOffset, document, findModel, stringToReplace)) return true;
if (!stringToReplace.isNull() && !justCheck) {
document.replaceString(textOffset, textEndOffset, stringToReplace.get());
}
}
catch (FindManager.MalformedReplacementStringException e) {
Messages.showErrorDialog(myProject, e.getMessage(), FindBundle.message("find.replace.invalid.replacement.string.title"));
}
if (stringToReplace != null) {
document.replaceString(textOffset, textEndOffset, stringToReplace);
exceptionResult.set(e);
return false;
}
return true;
}
});
}
});
if (!exceptionResult.isNull()) {
throw exceptionResult.get();
}
}
private boolean getStringToReplace(int textOffset,
int textEndOffset,
Document document, FindModel findModel, Ref<String> stringToReplace)
throws FindManager.MalformedReplacementStringException {
if (textOffset < 0 || textOffset >= document.getTextLength()) {
return false;
}
if (textEndOffset < 0 || textOffset > document.getTextLength()) {
return false;
}
FindManager findManager = FindManager.getInstance(myProject);
final CharSequence foundString = document.getCharsSequence().subSequence(textOffset, textEndOffset);
FindResult findResult = findManager.findString(document.getCharsSequence(), textOffset, findModel);
if (!findResult.isStringFound()) {
return false;
}
stringToReplace.set(
FindManager.getInstance(myProject).getStringToReplace(foundString.toString(), findModel, textOffset, document.getText()));
return true;
}
private void doReplaceSelected(final ReplaceContext replaceContext) {
@@ -401,20 +458,25 @@ public class ReplaceInProjectManager {
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
@Override
public void run() {
doReplace(replaceContext, selectedUsages);
for (final Usage selectedUsage : selectedUsages) {
replaceContext.getUsageView().removeUsage(selectedUsage);
}
final boolean success = doReplace(replaceContext, selectedUsages);
final UsageView usageView = replaceContext.getUsageView();
if (replaceContext.getUsageView().getUsages().isEmpty()) {
replaceContext.getUsageView().close();
return;
}
replaceContext.getUsageView().getComponent().requestFocus();
if (closeUsageViewIfEmpty(usageView, success)) return;
usageView.getComponent().requestFocus();
}
}, FindBundle.message("find.replace.command"), null);
}
private boolean closeUsageViewIfEmpty(UsageView usageView, boolean success) {
if (usageView.getUsages().isEmpty()) {
usageView.close();
return true;
} else if (!success) {
NOTIFICATION_GROUP.createNotification("One or more malformed replacement strings", MessageType.ERROR).notify(myProject);
}
return false;
}
public boolean isWorkInProgress() {
return myIsFindInProgress;
}
@@ -48,69 +48,13 @@ import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
/**
* @author Alexey
*/
public class CopyReferenceAction extends DumbAwareAction {
public static final DataFlavor ourFlavor;
static {
try {
ourFlavor = FileCopyPasteUtil.createJvmDataFlavor(MyTransferable.class);
}
catch (Exception e) {
// todo[r.sh] delete in IDEA 12
final StringBuilder msg = new StringBuilder();
final ClassLoader loader = CopyReferenceAction.class.getClassLoader();
msg.append("loader=").append(loader);
if (loader != null) {
final URL url = loader.getResource("com/intellij/ide/actions/CopyReferenceAction.class");
msg.append(" url=").append(url);
if (url != null) {
if ("jar".equals(url.getProtocol())) {
String path = url.getFile();
msg.append(" path=").append(path);
if (path != null && !path.isEmpty()) {
if (path.startsWith("file:") && path.length() > 5) path = path.substring(5);
if (path.startsWith("//") && path.length() > 2) path = path.substring(2);
final String[] parts = path.split("!/");
if (parts.length == 2) {
try {
final JarFile jar = new JarFile(parts[0]);
try {
msg.append(" jar=").append(jar);
final ZipEntry entry = jar.getEntry(parts[1].replace("CopyReferenceAction.class", "CopyReferenceAction$MyTransferable.class"));
msg.append(" entry=").append(entry);
}
finally {
jar.close();
}
}
catch (IOException e1) {
msg.append(" io=").append(e1.getMessage());
throw new RuntimeException(msg.toString(), e);
}
}
}
}
else {
final String path = url.getFile();
msg.append(" path=").append(path);
if (path != null && !path.isEmpty()) {
final boolean exists = new File(path.replace("CopyReferenceAction.class", "CopyReferenceAction$MyTransferable.class")).exists();
msg.append(" exists=").append(exists);
}
}
}
}
throw new RuntimeException(msg.toString(), e);
}
}
public static final DataFlavor ourFlavor = FileCopyPasteUtil.createJvmDataFlavor(MyTransferable.class);
public CopyReferenceAction() {
super();
@@ -16,10 +16,12 @@
package com.intellij.ui;
import com.intellij.find.FindManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.find.FindManager;
import com.intellij.openapi.ui.Messages;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
@@ -27,10 +29,16 @@ import java.awt.event.ActionEvent;
public class ReplacePromptDialog extends DialogWrapper {
private final boolean myIsMultiple;
@Nullable private FindManager.MalformedReplacementStringException myException;
public ReplacePromptDialog(boolean isMultipleFiles, String title, Project project) {
this(isMultipleFiles, title, project, null);
}
public ReplacePromptDialog(boolean isMultipleFiles, String title, Project project, @Nullable FindManager.MalformedReplacementStringException exception) {
super(project, true);
myIsMultiple = isMultipleFiles;
myException = exception;
setButtonsAlignment(SwingUtilities.CENTER);
setTitle(title);
init();
@@ -39,24 +47,35 @@ public class ReplacePromptDialog extends DialogWrapper {
protected Action[] createActions(){
DoAction replaceAction = new DoAction(UIBundle.message("replace.prompt.replace.button"), FindManager.PromptResult.OK);
replaceAction.putValue(DEFAULT_ACTION,Boolean.TRUE);
if (myIsMultiple){
return new Action[]{
replaceAction,
new DoAction(UIBundle.message("replace.prompt.skip.button"), FindManager.PromptResult.SKIP),
new DoAction(UIBundle.message("replace.prompt.all.in.this.file.button"), FindManager.PromptResult.ALL_IN_THIS_FILE),
new DoAction(UIBundle.message("replace.prompt.all.files.action"), FindManager.PromptResult.ALL_FILES),
getCancelAction()
};
}else{
return new Action[]{
replaceAction,
new DoAction(UIBundle.message("replace.prompt.skip.button"), FindManager.PromptResult.SKIP),
new DoAction(UIBundle.message("replace.prompt.all.button"), FindManager.PromptResult.ALL),
if (myException == null) {
if (myIsMultiple){
return new Action[]{
replaceAction,
createSkipAction(),
new DoAction(UIBundle.message("replace.prompt.all.in.this.file.button"), FindManager.PromptResult.ALL_IN_THIS_FILE),
new DoAction(UIBundle.message("replace.prompt.all.files.action"), FindManager.PromptResult.ALL_FILES),
getCancelAction()
};
} else {
return new Action[]{
replaceAction,
createSkipAction(),
new DoAction(UIBundle.message("replace.prompt.all.button"), FindManager.PromptResult.ALL),
getCancelAction()
};
}
} else {
return new Action[] {
createSkipAction(),
getCancelAction()
};
}
}
private DoAction createSkipAction() {
return new DoAction(UIBundle.message("replace.prompt.skip.button"), FindManager.PromptResult.SKIP);
}
public JComponent createNorthPanel() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));
@@ -73,7 +92,7 @@ public class ReplacePromptDialog extends DialogWrapper {
}
protected String getMessage() {
return UIBundle.message("replace.propmt.replace.occurrence.label");
return myException == null ? UIBundle.message("replace.propmt.replace.occurrence.label") : myException.getMessage();
}
public JComponent createCenterPanel() {
@@ -90,13 +90,17 @@ public class BackgroundableProcessIndicator extends ProgressWindow {
setTitle(info.getTitle());
final Project nonDefaultProject = project == null || project.isDisposed() ? null : project.isDefault() ? null : project;
final IdeFrame frame = ((WindowManagerEx)WindowManager.getInstance()).findFrameFor(nonDefaultProject);
myStatusBar = (StatusBarEx)frame.getStatusBar();
myBackgrounded = option.shouldStartInBackground();
if (option.shouldStartInBackground()) {
myStatusBar = frame != null ? (StatusBarEx)frame.getStatusBar() : null;
myBackgrounded = shouldStartInBackground();
if (myBackgrounded) {
doBackground();
}
}
private boolean shouldStartInBackground() {
return myOption.shouldStartInBackground() && myStatusBar != null;
}
public BackgroundableProcessIndicator(Project project,
@Nls final String progressTitle,
@NotNull PerformInBackgroundOption option,
@@ -133,7 +137,7 @@ public class BackgroundableProcessIndicator extends ProgressWindow {
protected void showDialog() {
if (myDisposed) return;
if (myOption.shouldStartInBackground()) {
if (shouldStartInBackground()) {
return;
}
@@ -26,11 +26,15 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.ui.ClickListener;
import com.intellij.ui.Gray;
import com.intellij.ui.ListUtil;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBScrollPane;
import com.intellij.ui.speedSearch.ListWithFilter;
import com.intellij.util.Function;
import com.intellij.util.SystemProperties;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -74,6 +78,7 @@ public class RecentProjectPanel extends JPanel {
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
ActionListener deleteAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -114,7 +119,19 @@ public class RecentProjectPanel extends JPanel {
JBScrollPane scroll = new JBScrollPane(myList);
scroll.setBorder(null);
add(scroll, BorderLayout.CENTER);
add(ListWithFilter.wrap(myList, scroll, new Function<Object, String>() {
@Override
public String fun(Object o) {
ReopenProjectAction item = (ReopenProjectAction)o;
String home = SystemProperties.getUserHome();
String path = item.getProjectPath();
if (FileUtil.startsWith(path, home)) {
path = path.substring(home.length());
}
return item.getProjectName() + " " + path;
}
}), BorderLayout.CENTER);
JPanel title = new JPanel() {
@Override
@@ -72,7 +72,7 @@ memory.usage.panel.statistics.message=Allocated heap size: {0}M Used: {1}M
memory.usage.panel.run.garbage.collector.action.name=Run Garbage Collector
memory.usage.panel.run.garbage.collector.action.description=Run Garbage Collector
#0 - used, 1 - total
memory.usage.panel.message.text={0}M of {1}M
memory.usage.panel.message.text={0,number,0000}M of {1,number,0000}M
go.to.line.command.name=Go to Line
go.to.line.command.double.click=Click to go to line
status.bar.insert.status.text=Insert
@@ -193,11 +193,21 @@ public class ContainerUtil extends ContainerUtilRt {
return new THashSet<T>();
}
@NotNull
public static <T> THashSet<T> newTroveSet(TObjectHashingStrategy<T> strategy) {
return new THashSet<T>(strategy);
}
@NotNull
public static <T> THashSet<T> newTroveSet(T... elements) {
return newTroveSet(Arrays.asList(elements));
}
@NotNull
public static <T> THashSet<T> newTroveSet(TObjectHashingStrategy<T> strategy, T... elements) {
return new THashSet<T>(Arrays.asList(elements), strategy);
}
@NotNull
public static <T> THashSet<T> newTroveSet(@NotNull Collection<T> elements) {
return new THashSet<T>(elements);
@@ -28,7 +28,7 @@ build.android.module.process.title=Create Android main package
package.name.must.contain.2.ids.error=A package name must contain 2 segments (i.e. com.example)
specify.platform.error=Please specify Android SDK
specify.main.package.error=Android main package in module {0} not specified
android.module.type.name=Android Application Module
android.module.type.name=Application Module
android.module.type.description=Android application modules are used for developing mobile applications targeting the Android OS.
not.valid.acvitiy.name.error=Not a valid Activity name "{0}"
specify.package.name.error=A package name must be specified
@@ -32,6 +32,9 @@ import org.jetbrains.annotations.Nullable;
public class AndroidProjectTemplatesFactory implements ProjectTemplatesFactory {
public static final String ANDROID = "Android";
public static final String EMPTY_MODULE = "Empty Module";
public static final String LIBRARY_MODULE = "Library Module";
public static final String TEST_MODULE = "Test Module";
@NotNull
@Override
@@ -44,7 +47,7 @@ public class AndroidProjectTemplatesFactory implements ProjectTemplatesFactory {
public ProjectTemplate[] createTemplates(String group, WizardContext context) {
ProjectTemplate[] templates = {
new BuilderBasedTemplate(new AndroidModuleBuilder()),
new AndroidProjectTemplate("Empty Android Module",
new AndroidProjectTemplate(EMPTY_MODULE,
"Simple Android module with configured Android SDK and without any pre-defined structure",
new AndroidModuleBuilder(null) {
@@ -60,7 +63,7 @@ public class AndroidProjectTemplatesFactory implements ProjectTemplatesFactory {
}
}),
new AndroidProjectTemplate("Android Library Module",
new AndroidProjectTemplate(LIBRARY_MODULE,
"Android library modules hold shared Android source code and resources " +
"that can be referenced by other Android modules",
new AndroidModuleBuilder.Library())
@@ -69,7 +72,7 @@ public class AndroidProjectTemplatesFactory implements ProjectTemplatesFactory {
return templates;
}
else {
AndroidProjectTemplate test = new AndroidProjectTemplate("Android Test Module",
AndroidProjectTemplate test = new AndroidProjectTemplate(TEST_MODULE,
"Android test modules contain Android applications that you write using " +
"the <a href='http://developer.android.com/tools/testing/index.html'>" +
"Testing and Instrumentation framework</a>",
@@ -40,7 +40,7 @@ import java.util.Arrays;
public class AndroidProjectWizardTest extends ProjectWizardTestCase {
public void testCreateProject() throws Exception {
createProjectFromTemplate(AndroidProjectTemplatesFactory.ANDROID, "Android Application Module", new Consumer<ModuleWizardStep>() {
createProjectFromTemplate(AndroidProjectTemplatesFactory.ANDROID, "Application Module", new Consumer<ModuleWizardStep>() {
@Override
public void consume(ModuleWizardStep step) {
if (step instanceof AndroidModuleWizardStep) {
@@ -54,7 +54,7 @@ public class AndroidProjectWizardTest extends ProjectWizardTestCase {
}
public void testCreateLibrary() throws Exception {
createProjectFromTemplate(AndroidProjectTemplatesFactory.ANDROID, "Android Library Module", new Consumer<ModuleWizardStep>() {
createProjectFromTemplate(AndroidProjectTemplatesFactory.ANDROID, AndroidProjectTemplatesFactory.LIBRARY_MODULE, new Consumer<ModuleWizardStep>() {
@Override
public void consume(ModuleWizardStep step) {
if (step instanceof AndroidModuleWizardStep) {
@@ -68,7 +68,7 @@ public class AndroidProjectWizardTest extends ProjectWizardTestCase {
}
public void testCreateEmptyProject() throws Exception {
createProjectFromTemplate(AndroidProjectTemplatesFactory.ANDROID, "Empty Android Module", null);
createProjectFromTemplate(AndroidProjectTemplatesFactory.ANDROID, AndroidProjectTemplatesFactory.EMPTY_MODULE, null);
}
@Override
@@ -28,5 +28,6 @@ public class WebEditorAppearanceConfigurable extends BeanConfigurable<WebEditorO
checkBox("breadcrumbsEnabled", XmlBundle.message("xml.editor.options.breadcrumbs.title"));
checkBox("breadcrumbsEnabledInXml", XmlBundle.message("xml.editor.options.breadcrumbs.for.xml.title"));
checkBox("showCssColorPreviewInGutter", "Show CSS color preview icon in gutter");
checkBox("showCssInlineColorPreview", "Show CSS color preview as background");
}
}
@@ -41,6 +41,7 @@ public class WebEditorOptions implements PersistentStateComponent<WebEditorOptio
private boolean myBreadcrumbsEnabled = true;
private boolean myBreadcrumbsEnabledInXml = false;
private boolean myShowCssColorPreviewInGutter = true;
private boolean myShowCssInlineColorPreview = false;
private boolean myAutomaticallyInsertClosingTag = true;
private boolean myAutomaticallyInsertRequiredAttributes = true;
private boolean myAutomaticallyInsertRequiredSubTags = true;
@@ -76,6 +77,14 @@ public class WebEditorOptions implements PersistentStateComponent<WebEditorOptio
return myBreadcrumbsEnabledInXml;
}
public boolean isShowCssInlineColorPreview() {
return myShowCssInlineColorPreview;
}
public void setShowCssInlineColorPreview(final boolean showCssInlineColorPreview) {
myShowCssInlineColorPreview = showCssInlineColorPreview;
}
public boolean isShowCssColorPreviewInGutter() {
return myShowCssColorPreviewInGutter;
}