mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote branch 'origin/master'
This commit is contained in:
+2
-2
@@ -36,10 +36,10 @@ public class FormLayoutSerializer extends GridLayoutSerializer {
|
||||
|
||||
public static FormLayoutSerializer INSTANCE = new FormLayoutSerializer();
|
||||
|
||||
public static CellConstraints.Alignment[] ourHorizontalAlignments = new CellConstraints.Alignment[] {
|
||||
public static CellConstraints.Alignment[] ourHorizontalAlignments = {
|
||||
CellConstraints.LEFT, CellConstraints.CENTER, CellConstraints.RIGHT, CellConstraints.FILL
|
||||
};
|
||||
public static CellConstraints.Alignment[] ourVerticalAlignments = new CellConstraints.Alignment[] {
|
||||
public static CellConstraints.Alignment[] ourVerticalAlignments = {
|
||||
CellConstraints.TOP, CellConstraints.CENTER, CellConstraints.BOTTOM, CellConstraints.FILL
|
||||
};
|
||||
|
||||
|
||||
@@ -314,7 +314,7 @@ public class CompilerTask extends Task.Backgroundable {
|
||||
(
|
||||
CompilerWorkspaceConfiguration.getInstance(myProject).useCompileServer() /*todo: temporary*/||
|
||||
CompilerMessageCategory.ERROR.equals(category) ||
|
||||
(CompilerMessageCategory.WARNING.equals(category) && !ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings())
|
||||
!ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()
|
||||
);
|
||||
if (shouldAutoActivate) {
|
||||
myMessagesAutoActivated = true;
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.intellij.codeInsight.folding;
|
||||
import com.intellij.codeInsight.folding.impl.CodeFoldingManagerImpl
|
||||
import com.intellij.openapi.application.ex.PathManagerEx
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.codeInsight.folding.impl.JavaCodeFoldingSettingsImpl
|
||||
import com.intellij.openapi.editor.impl.FoldingModelImpl
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -26,6 +28,23 @@ import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
*/
|
||||
public class JavaFoldingTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
def JavaCodeFoldingSettingsImpl myFoldingSettings
|
||||
def JavaCodeFoldingSettingsImpl myFoldingStateToRestore
|
||||
|
||||
@Override
|
||||
public void setUp() {
|
||||
super.setUp()
|
||||
myFoldingSettings = JavaCodeFoldingSettings.instance as JavaCodeFoldingSettingsImpl
|
||||
myFoldingStateToRestore = new JavaCodeFoldingSettingsImpl()
|
||||
myFoldingStateToRestore.loadState(myFoldingSettings)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() {
|
||||
myFoldingSettings.loadState(myFoldingStateToRestore)
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
public void testEndOfLineComments() {
|
||||
myFixture.testFolding("$PathManagerEx.testDataPath/codeInsight/folding/${getTestName(false)}.java");
|
||||
}
|
||||
@@ -76,10 +95,52 @@ class Test {
|
||||
myFixture.performEditorAction 'CollapseBlock'
|
||||
assertEquals(text.indexOf('}', text.indexOf('i++')), myFixture.editor.caretModel.offset)
|
||||
}
|
||||
|
||||
public void testFoldGroup() {
|
||||
// Implied by IDEA-79420
|
||||
myFoldingSettings.COLLAPSE_CLOSURES = true
|
||||
def text = """\
|
||||
class Test {
|
||||
void test() {
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
int i = 1;
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
configure text
|
||||
def foldingModel = myFixture.editor.foldingModel as FoldingModelImpl
|
||||
def closureStartFold = foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable"))
|
||||
assertNotNull closureStartFold
|
||||
assertFalse closureStartFold.expanded
|
||||
|
||||
assertNotNull closureStartFold.group
|
||||
def closureFolds = foldingModel.getGroupedRegions(closureStartFold.group)
|
||||
assertNotNull closureFolds
|
||||
assertEquals(2, closureFolds.size())
|
||||
|
||||
def closureEndFold = closureFolds.get(1)
|
||||
assertFalse closureEndFold.expanded
|
||||
|
||||
myFixture.editor.caretModel.moveToOffset(closureEndFold.startOffset + 1)
|
||||
assertTrue closureStartFold.expanded
|
||||
assertTrue closureEndFold.expanded
|
||||
|
||||
changeFoldRegions { closureStartFold.expanded = false }
|
||||
assertTrue closureStartFold.expanded
|
||||
assertTrue closureEndFold.expanded
|
||||
}
|
||||
|
||||
private def configure(String text) {
|
||||
myFixture.configureByText("a.java", text)
|
||||
CodeFoldingManagerImpl.getInstance(getProject()).buildInitialFoldings(myFixture.editor);
|
||||
myFixture.doHighlighting()
|
||||
}
|
||||
|
||||
private def changeFoldRegions(Closure op) {
|
||||
myFixture.editor.foldingModel.runBatchFoldingOperationDoNotCollapseCaret(op)
|
||||
}
|
||||
}
|
||||
|
||||
+9
-7
@@ -564,14 +564,16 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
|
||||
Document documentRange = documentManager.getDocument(file);
|
||||
if (documentRange == null) continue;
|
||||
List<InspectionResult> resultList = entry.getValue();
|
||||
for (InspectionResult inspectionResult : resultList) {
|
||||
indicator.checkCanceled();
|
||||
LocalInspectionTool tool = inspectionResult.tool;
|
||||
HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity();
|
||||
for (ProblemDescriptor descriptor : inspectionResult.foundProblems) {
|
||||
synchronized (resultList) {
|
||||
for (InspectionResult inspectionResult : resultList) {
|
||||
indicator.checkCanceled();
|
||||
PsiElement element = descriptor.getPsiElement();
|
||||
createHighlightsForDescriptor(outInfos, emptyActionRegistered, ilManager, file, documentRange, tool, severity, descriptor, element);
|
||||
LocalInspectionTool tool = inspectionResult.tool;
|
||||
HighlightSeverity severity = inspectionProfile.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity();
|
||||
for (ProblemDescriptor descriptor : inspectionResult.foundProblems) {
|
||||
indicator.checkCanceled();
|
||||
PsiElement element = descriptor.getPsiElement();
|
||||
createHighlightsForDescriptor(outInfos, emptyActionRegistered, ilManager, file, documentRange, tool, severity, descriptor, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ public class FileStructurePopup implements Disposable {
|
||||
private String myTitle;
|
||||
private TreeSpeedSearch mySpeedSearch;
|
||||
private SmartTreeStructure myTreeStructure;
|
||||
private JComponent myPanel;
|
||||
|
||||
public FileStructurePopup(StructureViewModel structureViewModel,
|
||||
@Nullable Editor editor,
|
||||
@@ -130,20 +131,36 @@ public class FileStructurePopup implements Disposable {
|
||||
myTree.setRootVisible(false);
|
||||
myTree.setShowsRootHandles(true);
|
||||
|
||||
mySpeedSearch = new TreeSpeedSearch(myTree, TreeSpeedSearch.NODE_DESCRIPTOR_TOSTRING, true);
|
||||
mySpeedSearch = new TreeSpeedSearch(myTree, TreeSpeedSearch.NODE_DESCRIPTOR_TOSTRING, true) {
|
||||
@Override
|
||||
protected Point getComponentLocationOnScreen() {
|
||||
return myPopup.getContent().getLocationOnScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rectangle getComponentVisibleRect() {
|
||||
return myPopup.getContent().getVisibleRect();
|
||||
}
|
||||
};
|
||||
myAbstractTreeBuilder = new FilteringTreeBuilder(project, myTree, new FileStructurePopupFilter(), myTreeStructure, null) {
|
||||
@Override
|
||||
protected boolean validateNode(Object child) {
|
||||
return StructureViewComponent.isValid(child);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revalidateTree() {
|
||||
myTree.revalidate();
|
||||
myTree.repaint();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public void show() {
|
||||
final JComponent panel = createCenterPanel();
|
||||
new MnemonicHelper().register(panel);
|
||||
myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, null)
|
||||
myPanel = createCenterPanel();
|
||||
new MnemonicHelper().register(myPanel);
|
||||
myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(myPanel, null)
|
||||
.setTitle(myTitle)
|
||||
.setResizable(true)
|
||||
.setFocusable(true)
|
||||
@@ -168,21 +185,23 @@ public class FileStructurePopup implements Disposable {
|
||||
});
|
||||
}
|
||||
});
|
||||
final Alarm alarm = new Alarm(myPopup);
|
||||
final Alarm alarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myPopup);
|
||||
alarm.addRequest(new Runnable() {
|
||||
String filter = "";
|
||||
@Override
|
||||
public void run() {
|
||||
alarm.cancelAllRequests();
|
||||
String prefix = mySpeedSearch.getEnteredPrefix();
|
||||
myTree.getEmptyText().setText("Can't find '" + prefix + "'");
|
||||
if (prefix == null) prefix = "";
|
||||
|
||||
if (!filter.equals(prefix)) {
|
||||
filter = prefix;
|
||||
myAbstractTreeBuilder.refilter();
|
||||
//myAbstractTreeBuilder.refilter();
|
||||
}
|
||||
alarm.addRequest(this, 300);
|
||||
alarm.addRequest(this, 500);
|
||||
}
|
||||
}, 300);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
private void selectPsiElement(PsiElement element) {
|
||||
@@ -389,7 +408,7 @@ public class FileStructurePopup implements Disposable {
|
||||
final boolean state = chkFilter.isSelected();
|
||||
myTreeActionsOwner.setActionIncluded(action, action instanceof FileStructureFilter ? !state : state);
|
||||
myTreeStructure.rebuildTree();
|
||||
myAbstractTreeBuilder.refilter(); //todo full update
|
||||
myAbstractTreeBuilder.refilter();
|
||||
myAbstractTreeBuilder.queueUpdate();
|
||||
|
||||
if (SpeedSearchBase.hasActiveSpeedSearch(myTree)) {
|
||||
@@ -444,6 +463,15 @@ public class FileStructurePopup implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyFilter extends ElementFilter.Active.Impl<StructureViewComponent.StructureViewTreeElementWrapper> {
|
||||
|
||||
@Override
|
||||
public boolean shouldBeShowing(StructureViewComponent.StructureViewTreeElementWrapper value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class FileStructurePopupFilter implements ElementFilter {
|
||||
private String myLastFilter = null;
|
||||
private HashSet<Object> myVisibleParents = new HashSet<Object>();
|
||||
@@ -455,6 +483,7 @@ public class FileStructurePopup implements Disposable {
|
||||
? mySpeedSearch.getEnteredPrefix() : null;
|
||||
if (!StringUtil.equals(myLastFilter, filter)) {
|
||||
myVisibleParents.clear();
|
||||
myLastFilter = filter;
|
||||
}
|
||||
if (filter != null) {
|
||||
if (myVisibleParents.contains(value)) {
|
||||
|
||||
+6
@@ -101,6 +101,12 @@ public class SequentialModalProgressTask extends Task.Modal {
|
||||
}
|
||||
}
|
||||
});
|
||||
//if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
// runnable.run();
|
||||
//}
|
||||
//else {
|
||||
// ApplicationManagerEx.getApplicationEx().suspendReadAccessAndRunWriteAction(runnable);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,7 +369,7 @@ public class ParametersList implements Cloneable {
|
||||
try {
|
||||
builder.append(parameter);
|
||||
StringUtil.escapeQuotes(builder);
|
||||
if (builder.length() == 0 || StringUtil.indexOf(builder, ' ') >= 0) {
|
||||
if (builder.length() == 0 || StringUtil.indexOf(builder, ' ') >= 0 || StringUtil.indexOf(builder, '|') >= 0) {
|
||||
StringUtil.quote(builder);
|
||||
}
|
||||
return builder.toString();
|
||||
|
||||
@@ -285,7 +285,7 @@ public final class Presentation implements Cloneable {
|
||||
myChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
|
||||
}
|
||||
|
||||
public Object clone(){
|
||||
public Presentation clone(){
|
||||
try{
|
||||
Presentation presentation = (Presentation)super.clone();
|
||||
presentation.myChangeSupport = new PropertyChangeSupport(presentation);
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.ide.util.treeView.AbstractTreeStructure;
|
||||
import com.intellij.ide.util.treeView.NodeDescriptor;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.ui.CustomizeColoredTreeCellRenderer;
|
||||
@@ -41,12 +40,10 @@ public class ErrorViewStructure extends AbstractTreeStructure {
|
||||
private final ErrorTreeElement myRoot = new MyRootElement();
|
||||
private final List<String> myGroupNames = new ArrayList<String>();
|
||||
private final Map<String, GroupingElement> myGroupNameToElementMap = new HashMap<String, GroupingElement>();
|
||||
private final Map<String, List<NavigatableMessageElement>> myGroupNameToMessagesMap =
|
||||
new HashMap<String, List<NavigatableMessageElement>>();
|
||||
private final Map<ErrorTreeElementKind, List<ErrorTreeElement>> mySimpleMessages =
|
||||
new HashMap<ErrorTreeElementKind, List<ErrorTreeElement>>();
|
||||
private final Map<String, List<NavigatableMessageElement>> myGroupNameToMessagesMap = new HashMap<String, List<NavigatableMessageElement>>();
|
||||
private final Map<ErrorTreeElementKind, List<ErrorTreeElement>> mySimpleMessages = new EnumMap<ErrorTreeElementKind, List<ErrorTreeElement>>(ErrorTreeElementKind.class);
|
||||
|
||||
private static final ErrorTreeElementKind[] ourMessagesOrder = new ErrorTreeElementKind[]{
|
||||
private static final ErrorTreeElementKind[] ourMessagesOrder = {
|
||||
ErrorTreeElementKind.INFO,
|
||||
ErrorTreeElementKind.ERROR,
|
||||
ErrorTreeElementKind.WARNING,
|
||||
@@ -70,10 +67,10 @@ public class ErrorViewStructure extends AbstractTreeStructure {
|
||||
final List<Object> children = new ArrayList<Object>();
|
||||
// simple messages
|
||||
for (final ErrorTreeElementKind kind : ourMessagesOrder) {
|
||||
if (ErrorTreeElementKind.WARNING.equals(kind) || ErrorTreeElementKind.NOTE.equals(kind)) {
|
||||
if (myCanHideWarnings && ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) {
|
||||
continue;
|
||||
}
|
||||
if (!ErrorTreeElementKind.ERROR.equals(kind) &&
|
||||
myCanHideWarnings &&
|
||||
ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) {
|
||||
continue;
|
||||
}
|
||||
final List<ErrorTreeElement> elems = mySimpleMessages.get(kind);
|
||||
if (elems != null) {
|
||||
@@ -89,15 +86,15 @@ public class ErrorViewStructure extends AbstractTreeStructure {
|
||||
}
|
||||
return ArrayUtil.toObjectArray(children);
|
||||
}
|
||||
else if (element instanceof GroupingElement) {
|
||||
if (element instanceof GroupingElement) {
|
||||
synchronized (myGroupNameToMessagesMap) {
|
||||
final List<NavigatableMessageElement> children = myGroupNameToMessagesMap.get(((GroupingElement)element).getName());
|
||||
if (children != null && children.size() > 0) {
|
||||
if (children != null && !children.isEmpty()) {
|
||||
if (myCanHideWarnings && ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) {
|
||||
final List<NavigatableMessageElement> filtered = new ArrayList<NavigatableMessageElement>(children.size());
|
||||
for (final NavigatableMessageElement navigatableMessageElement : children) {
|
||||
ErrorTreeElementKind kind = navigatableMessageElement.getKind();
|
||||
if (ErrorTreeElementKind.WARNING.equals(kind) || ErrorTreeElementKind.NOTE.equals(kind)) {
|
||||
if (!ErrorTreeElementKind.ERROR.equals(kind)) {
|
||||
continue;
|
||||
}
|
||||
filtered.add(navigatableMessageElement);
|
||||
@@ -120,7 +117,7 @@ public class ErrorViewStructure extends AbstractTreeStructure {
|
||||
if (children != null) {
|
||||
for (final NavigatableMessageElement child : children) {
|
||||
ErrorTreeElementKind kind = child.getKind();
|
||||
if (!ErrorTreeElementKind.WARNING.equals(kind) && !ErrorTreeElementKind.NOTE.equals(kind)) {
|
||||
if (ErrorTreeElementKind.ERROR.equals(kind)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -187,7 +184,7 @@ public class ErrorViewStructure extends AbstractTreeStructure {
|
||||
public List<Object> getGroupChildrenData(final String groupName) {
|
||||
synchronized (myGroupNameToMessagesMap) {
|
||||
final List<NavigatableMessageElement> children = myGroupNameToMessagesMap.get(groupName);
|
||||
if (children != null && (!children.isEmpty())) {
|
||||
if (children != null && !children.isEmpty()) {
|
||||
final List<Object> result = new ArrayList<Object>();
|
||||
for (NavigatableMessageElement child : children) {
|
||||
final Object data = child.getData();
|
||||
@@ -302,12 +299,12 @@ public class ErrorViewStructure extends AbstractTreeStructure {
|
||||
|
||||
public ErrorTreeElement getFirstMessage(ErrorTreeElementKind kind) {
|
||||
if (myCanHideWarnings &&
|
||||
(ErrorTreeElementKind.WARNING.equals(kind) || ErrorTreeElementKind.NOTE.equals(kind)) &&
|
||||
!ErrorTreeElementKind.ERROR.equals(kind) &&
|
||||
ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings()) {
|
||||
return null; // no warnings are available
|
||||
}
|
||||
final List<ErrorTreeElement> simpleMessages = mySimpleMessages.get(kind);
|
||||
if (simpleMessages != null && simpleMessages.size() > 0) {
|
||||
if (simpleMessages != null && !simpleMessages.isEmpty()) {
|
||||
return simpleMessages.get(0);
|
||||
}
|
||||
for (final String path : myGroupNames) {
|
||||
@@ -348,7 +345,6 @@ public class ErrorViewStructure extends AbstractTreeStructure {
|
||||
}
|
||||
|
||||
private static class MyNavigatableWithDataElement extends NavigatableMessageElement {
|
||||
private final static Icon ourFileIcon = IconLoader.getIcon("/fileTypes/unknown.png");
|
||||
private final VirtualFile myVf;
|
||||
private final CustomizeColoredTreeCellRenderer myCustomizeColoredTreeCellRenderer;
|
||||
|
||||
@@ -370,12 +366,10 @@ public class ErrorViewStructure extends AbstractTreeStructure {
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus) {
|
||||
if (myVf != null) {
|
||||
final Icon icon = myVf.getFileType().getIcon();
|
||||
renderer.setIcon(icon);
|
||||
}
|
||||
final Icon icon = myVf.getFileType().getIcon();
|
||||
renderer.setIcon(icon);
|
||||
final String[] messages = getText();
|
||||
final String text = ((messages == null) || (messages.length == 0)) ? vf.getPath() : messages[0];
|
||||
final String text = messages == null || messages.length == 0 ? vf.getPath() : messages[0];
|
||||
renderer.append(text);
|
||||
}
|
||||
};
|
||||
|
||||
+3
-5
@@ -563,14 +563,12 @@ public class NewErrorTreeViewPanel extends JPanel implements DataProvider, Occur
|
||||
}
|
||||
|
||||
public boolean isSelected(AnActionEvent event) {
|
||||
return ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings();
|
||||
return isHideWarnings();
|
||||
}
|
||||
|
||||
public void setSelected(AnActionEvent event, boolean flag) {
|
||||
final ErrorTreeViewConfiguration configuration = ErrorTreeViewConfiguration.getInstance(myProject);
|
||||
final boolean hideWarnings = configuration.isHideWarnings();
|
||||
if (hideWarnings != flag) {
|
||||
configuration.setHideWarnings(flag);
|
||||
if (isHideWarnings() != flag) {
|
||||
ErrorTreeViewConfiguration.getInstance(myProject).setHideWarnings(flag);
|
||||
myBuilder.updateTree();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,17 @@ public class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion {
|
||||
} else {
|
||||
for (final FoldRegion region : foldingModel.getGroupedRegions(myGroup)) {
|
||||
doSetExpanded(expanded, foldingModel, region);
|
||||
// There is a possible case that we can't change expanded status of particular fold region (e.g. we can't collapse
|
||||
// if it contains caret). So, we revert all changes for the fold regions from the same group then.
|
||||
if (region.isExpanded() != expanded) {
|
||||
for (FoldRegion regionToRevert : foldingModel.getGroupedRegions(myGroup)) {
|
||||
if (regionToRevert == region) {
|
||||
break;
|
||||
}
|
||||
doSetExpanded(!expanded, foldingModel, regionToRevert);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,8 +517,8 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
|
||||
myPopupLayeredPane.add(mySearchPopup, JLayeredPane.POPUP_LAYER);
|
||||
if (myPopupLayeredPane == null) return; // See # 27482. Somewho it does happen...
|
||||
Point lPaneP = myPopupLayeredPane.getLocationOnScreen();
|
||||
Point componentP = myComponent.getLocationOnScreen();
|
||||
Rectangle r = myComponent.getVisibleRect();
|
||||
Point componentP = getComponentLocationOnScreen();
|
||||
Rectangle r = getComponentVisibleRect();
|
||||
Dimension prefSize = mySearchPopup.getPreferredSize();
|
||||
Window window = (Window)SwingUtilities.getAncestorOfClass(Window.class, myComponent);
|
||||
Point windowP;
|
||||
@@ -539,6 +539,14 @@ public abstract class SpeedSearchBase<Comp extends JComponent> extends SpeedSear
|
||||
mySearchPopup.validate();
|
||||
}
|
||||
|
||||
protected Rectangle getComponentVisibleRect() {
|
||||
return myComponent.getVisibleRect();
|
||||
}
|
||||
|
||||
protected Point getComponentLocationOnScreen() {
|
||||
return myComponent.getLocationOnScreen();
|
||||
}
|
||||
|
||||
private class MyToolWindowManagerListener extends ToolWindowManagerAdapter {
|
||||
public void stateChanged() {
|
||||
manageSearchPopup(null);
|
||||
|
||||
@@ -1104,7 +1104,7 @@ public class StringUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Iterable<String> tokenize(@NotNull String s, final StringTokenizer tokenizer) {
|
||||
public static Iterable<String> tokenize(final StringTokenizer tokenizer) {
|
||||
return new Iterable<String>() {
|
||||
public Iterator<String> iterator() {
|
||||
return new Iterator<String>() {
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.intellij.openapi.ui.VerticalFlowLayout;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
@@ -31,7 +30,7 @@ public class CheckModulePanel extends JPanel {
|
||||
private boolean myHasWarnings;
|
||||
|
||||
public CheckModulePanel() {
|
||||
super(new VerticalFlowLayout(FlowLayout.LEFT));
|
||||
super(new VerticalFlowLayout(VerticalFlowLayout.TOP));
|
||||
}
|
||||
|
||||
public void updateMessages(AndroidFacet facet) {
|
||||
|
||||
@@ -353,7 +353,7 @@ public abstract class DeviceConfiguratorPanel extends JPanel {
|
||||
rightPabel.add(new JBScrollPane(myChosenQualifiersList, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.CENTER);
|
||||
|
||||
final JPanel buttonsPanel = new JPanel(new VerticalFlowLayout(FlowLayout.CENTER, 0, 0, true, false));
|
||||
final JPanel buttonsPanel = new JPanel(new VerticalFlowLayout(VerticalFlowLayout.MIDDLE, 0, 0, true, false));
|
||||
myAddQualifierButton = new JButton(">>");
|
||||
buttonsPanel.add(myAddQualifierButton);
|
||||
myRemoveQualifierButton = new JButton("<<");
|
||||
|
||||
@@ -55,4 +55,9 @@ gradle.generic.text.error.sdk.undefined=Gradle installation is unknown
|
||||
gradle.home.setting.type.deduced=Gradle location is deduced
|
||||
gradle.home.setting.type.unknown=Gradle location is unknown
|
||||
gradle.home.setting.type.explicit.correct=Gradle location is defined
|
||||
gradle.home.setting.type.explicit.incorrect=Gradle location is incorrect
|
||||
gradle.home.setting.type.explicit.incorrect=Gradle location is incorrect
|
||||
|
||||
gradle.toolwindow.text.no.linked.project=\nThere is no linked Gradle project\nYou may use {link} to add the one.
|
||||
|
||||
gradle.action.link.project.text=Link gradle project
|
||||
gradle.action.link.project.description=Allows to link any gradle project to the current IDE project
|
||||
@@ -58,4 +58,11 @@
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<actions>
|
||||
<action id="Gradle.LinkToProject" class="org.jetbrains.plugins.gradle.config.GradleLinkToProjectAction" icon="/general/add.png"/>
|
||||
<group id="Gradle.ChangeActionsToolbar">
|
||||
<reference id="Gradle.LinkToProject"/>
|
||||
</group>
|
||||
</actions>
|
||||
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.jetbrains.plugins.gradle.config;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
|
||||
/**
|
||||
* Allows to link gradle project to the current IntelliJ IDEA project.
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 12/26/11 5:09 PM
|
||||
*/
|
||||
public class GradleLinkToProjectAction extends AnAction implements DumbAware {
|
||||
|
||||
public GradleLinkToProjectAction() {
|
||||
getTemplatePresentation().setText(GradleBundle.message("gradle.action.link.project.text"));
|
||||
getTemplatePresentation().setDescription(GradleBundle.message("gradle.action.link.project.description"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
// TODO den implement
|
||||
System.out.println("action performed");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package org.jetbrains.plugins.gradle.config;
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbar;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.ex.ActionButtonLook;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionButton;
|
||||
import com.intellij.openapi.ui.SimpleToolWindowPanel;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.util.GradleBundle;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Base class for high-level Gradle GUI controls used at the Gradle tool window. The basic idea is to encapsulate the same features in
|
||||
* this class and allow to extend it via <code>Template Method</code> pattern. The shared features are listed below:
|
||||
* <pre>
|
||||
* <ul>
|
||||
* <li>provide common actions at the toolbar;</li>
|
||||
* <li>show info control when no gradle project is linked to the current IntelliJ IDEA project;</li>
|
||||
* </ul>
|
||||
* </pre>
|
||||
* <p/>
|
||||
* Not thread-safe.
|
||||
*
|
||||
* @author Denis Zhdanov
|
||||
* @since 12/26/11 5:19 PM
|
||||
*/
|
||||
public abstract class GradleToolWindowPanel extends SimpleToolWindowPanel {
|
||||
|
||||
private static final String NON_LINKED_CARD_NAME = "NON_LINKED";
|
||||
private static final String CONTENT_CARD_NAME = "CONTENT";
|
||||
private static final String LINK_BUTTON_MARKER = "{link}";
|
||||
private static final String TOOL_WINDOW_TOOLBAR_ID = "Gradle.ChangeActionsToolbar";
|
||||
private static final String LINK_PROJECT_ACTION_ID = "Gradle.LinkToProject";
|
||||
|
||||
/** Show info control when no gradle project is linked, using {@link CardLayout} for that. */
|
||||
private final CardLayout myLayout = new CardLayout();
|
||||
/** Top-level container, managed by the card layout. */
|
||||
private final JPanel myContent = new JPanel(myLayout);
|
||||
/** Control to show when no gradle project is linked to the current IntelliJ IDEA project. */
|
||||
private final JPanel myNonLinkedInfoPanel = new JPanel();
|
||||
|
||||
protected GradleToolWindowPanel(@NotNull String place) {
|
||||
super(true);
|
||||
final ActionManager actionManager = ActionManager.getInstance();
|
||||
final ActionGroup actionGroup = (ActionGroup)actionManager.getAction(TOOL_WINDOW_TOOLBAR_ID);
|
||||
ActionToolbar actionToolbar = actionManager.createActionToolbar(place, actionGroup, true);
|
||||
setToolbar(actionToolbar.getComponent());
|
||||
initContent();
|
||||
setContent(myContent);
|
||||
}
|
||||
|
||||
private void initContent() {
|
||||
final JComponent payloadControl = buildContent();
|
||||
myContent.add(ScrollPaneFactory.createScrollPane(payloadControl), CONTENT_CARD_NAME);
|
||||
|
||||
myNonLinkedInfoPanel.setLayout(new GridBagLayout());
|
||||
final Color background = payloadControl.getBackground();
|
||||
myNonLinkedInfoPanel.setBackground(background);
|
||||
List<JComponent> rowComponents = new ArrayList<JComponent>();
|
||||
final String sentence = GradleBundle.message("gradle.toolwindow.text.no.linked.project");
|
||||
for (String s : StringUtil.tokenize(new StringTokenizer(sentence, " \n", true))) {
|
||||
if (s.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (LINK_BUTTON_MARKER.equals(s)) {
|
||||
final ActionManager actionManager = ActionManager.getInstance();
|
||||
final AnAction action = actionManager.getAction(LINK_PROJECT_ACTION_ID);
|
||||
ActionButton button= new ActionButton(
|
||||
action, action.getTemplatePresentation().clone(), GradleConstants.TOOL_WINDOW_TOOLBAR_PLACE, new Dimension(0, 0))
|
||||
{
|
||||
@Override
|
||||
protected void paintButtonLook(Graphics g) {
|
||||
// Don't draw border at the inline button.
|
||||
ActionButtonLook look = getButtonLook();
|
||||
look.paintBackground(g, this);
|
||||
look.paintIcon(g, this, getIcon());
|
||||
}
|
||||
};
|
||||
rowComponents.add(button);
|
||||
}
|
||||
else if (s.contains("\n")) {
|
||||
addRow(rowComponents, background);
|
||||
rowComponents.clear();
|
||||
}
|
||||
else {
|
||||
final JLabel label = new JLabel(s);
|
||||
label.setForeground(payloadControl.getForeground());
|
||||
label.setBackground(background);
|
||||
label.setFont(payloadControl.getFont());
|
||||
rowComponents.add(label);
|
||||
}
|
||||
}
|
||||
if (!rowComponents.isEmpty()) {
|
||||
addRow(rowComponents, background);
|
||||
}
|
||||
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.weighty = 1;
|
||||
constraints.fill = GridBagConstraints.VERTICAL;
|
||||
myNonLinkedInfoPanel.add(Box.createVerticalStrut(1), constraints);
|
||||
myContent.add(myNonLinkedInfoPanel, NON_LINKED_CARD_NAME);
|
||||
|
||||
myLayout.show(myContent, NON_LINKED_CARD_NAME);
|
||||
}
|
||||
|
||||
private void addRow(@NotNull Collection<JComponent> rowComponents, @NotNull Color backgroundColor) {
|
||||
JPanel row = new MultiRowFlowPanel(FlowLayout.CENTER, 0, 3);
|
||||
row.setBackground(backgroundColor);
|
||||
if (rowComponents.isEmpty()) {
|
||||
row.add(new JLabel(" "));
|
||||
}
|
||||
else {
|
||||
for (JComponent component : rowComponents) {
|
||||
row.add(component);
|
||||
}
|
||||
}
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.gridwidth = GridBagConstraints.REMAINDER;
|
||||
constraints.weightx = 1;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraints.insets.top = 3;
|
||||
myNonLinkedInfoPanel.add(row, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return GUI control to be displayed at the current tab
|
||||
*/
|
||||
@NotNull
|
||||
protected abstract JComponent buildContent();
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package org.jetbrains.plugins.gradle.config;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Flow layout calculates necessary size assuming that all components are layed out within a single row.
|
||||
* That may cause troubles during initial space calculation, i.e. panel with flow layout is represented as a
|
||||
* single wide row inside a scroll pane. This panel fixes that by calculating necessary size on its own.
|
||||
* It fixes the width to use as a minimum between a width offered by default flow layout and customizable value
|
||||
* and calculates the height. If the user has an ability to manually change panel size (e.g. indirectly via changing
|
||||
* size of the dialog that serves as a container for the panel), that width is used as a maximum width.
|
||||
*
|
||||
* @author: Denis Zhdanov
|
||||
* @since: Jul 28, 2008
|
||||
*/
|
||||
public class MultiRowFlowPanel extends JPanel {
|
||||
|
||||
private int maximumWidth = Toolkit.getDefaultToolkit().getScreenSize().width / 2;
|
||||
|
||||
public MultiRowFlowPanel(int align, int hGap, int vGap) {
|
||||
super(new FlowLayout(align, hGap, vGap));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a preferred size assuming that the maximum row width is a value returned from
|
||||
* {@link #getMaxRowWidth()}.
|
||||
*/
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return calculateSize(getMaxRowWidth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a preferred size assuming that the maximum row width is a value returned from
|
||||
* {@link #getMaxRowWidth()}.
|
||||
*/
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return calculateSize(getMaxRowWidth());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current representation width if the component is already showed; minimum of default preferred
|
||||
* width (when all components are layed in a single row) and half screen width
|
||||
*/
|
||||
private int getMaxRowWidth() {
|
||||
int result = getSize().width;
|
||||
if (result == 0) {
|
||||
result = Math.min(super.getPreferredSize().width, maximumWidth);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates all child components and calculates the space enough to keep all of them assuming that the width is
|
||||
* fixed.
|
||||
*/
|
||||
private Dimension calculateSize(int maxRowWidth) {
|
||||
FlowLayout layout = (FlowLayout)getLayout();
|
||||
int height = 0;
|
||||
int currentRowWidth = 0;
|
||||
int currentRowHeight = 0;
|
||||
for (int i = 0, count = getComponentCount(); i < count; ++i) {
|
||||
Component comp = getComponent(i);
|
||||
Dimension bounds = comp.getPreferredSize();
|
||||
if (!comp.isVisible()) {
|
||||
continue;
|
||||
}
|
||||
currentRowHeight = Math.max(currentRowHeight, bounds.height);
|
||||
if (currentRowWidth + layout.getHgap() + bounds.width <= maxRowWidth) {
|
||||
if (bounds.width != 0) {
|
||||
currentRowWidth += bounds.width + layout.getHgap();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
height += currentRowHeight + layout.getVgap();
|
||||
currentRowWidth = bounds.width;
|
||||
currentRowHeight = bounds.height;
|
||||
}
|
||||
return new Dimension(maxRowWidth, height + currentRowHeight + 2 * layout.getVgap());
|
||||
}
|
||||
}
|
||||
+13
-1
@@ -1,6 +1,9 @@
|
||||
package org.jetbrains.plugins.gradle.sync;
|
||||
|
||||
import com.intellij.ui.treeStructure.SimpleTree;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.config.GradleToolWindowPanel;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -10,11 +13,20 @@ import javax.swing.*;
|
||||
* @author Denis Zhdanov
|
||||
* @since 11/3/11 3:58 PM
|
||||
*/
|
||||
public class GradleProjectStructureChangesPanel extends JPanel {
|
||||
public class GradleProjectStructureChangesPanel extends GradleToolWindowPanel {
|
||||
|
||||
private final GradleProjectStructureChangesModel myModel;
|
||||
|
||||
public GradleProjectStructureChangesPanel(@NotNull GradleProjectStructureChangesModel model) {
|
||||
super(GradleConstants.TOOL_WINDOW_TOOLBAR_PLACE);
|
||||
myModel = model;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected JComponent buildContent() {
|
||||
// TODO den implement
|
||||
return new SimpleTree();
|
||||
//return new JLabel("project-structure-change-content");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@ import javax.swing.*;
|
||||
*/
|
||||
public class GradleConstants {
|
||||
|
||||
public static final Icon GRADLE_ICON = IconLoader.getIcon("/icons/gradle.png");
|
||||
@NonNls public static final String EXTENSION = "gradle";
|
||||
@NonNls public static final String DEFAULT_SCRIPT_NAME = "build.gradle";
|
||||
public static final Icon GRADLE_ICON = IconLoader.getIcon("/icons/gradle.png");
|
||||
@NonNls public static final String EXTENSION = "gradle";
|
||||
@NonNls public static final String DEFAULT_SCRIPT_NAME = "build.gradle";
|
||||
@NonNls public static final String TOOL_WINDOW_TOOLBAR_PLACE = "GRADLE_SYNC_CHANGES_TOOLBAR";
|
||||
|
||||
private GradleConstants() {
|
||||
}
|
||||
|
||||
+11
-2
@@ -102,6 +102,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
|
||||
private final Set<PropertiesFile> myBackSlashPressed = new THashSet<PropertiesFile>();
|
||||
@NonNls private static final String VALUES = "values";
|
||||
@NonNls private static final String NO_PROPERTY_SELECTED = "noPropertySelected";
|
||||
private VirtualFileListener myVfsListener;
|
||||
private PsiTreeChangeAdapter myPsiTreeChangeAdapter;
|
||||
@NonNls protected static final String PROPORTION_PROPERTY = "RESOURCE_BUNDLE_SPLITTER_PROPORTION";
|
||||
|
||||
@@ -231,7 +232,12 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
|
||||
}
|
||||
|
||||
private void installPropertiesChangeListeners() {
|
||||
VirtualFileManager.getInstance().addVirtualFileListener(new VirtualFileAdapter() {
|
||||
final VirtualFileManager virtualFileManager = VirtualFileManager.getInstance();
|
||||
if (myVfsListener != null) {
|
||||
assert false;
|
||||
virtualFileManager.removeVirtualFileListener(myVfsListener);
|
||||
}
|
||||
myVfsListener = new VirtualFileAdapter() {
|
||||
@Override
|
||||
public void fileCreated(VirtualFileEvent event) {
|
||||
if (PropertiesUtil.isPropertiesFile(event.getFile(), myProject)) {
|
||||
@@ -260,7 +266,9 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
|
||||
}
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
};
|
||||
|
||||
virtualFileManager.addVirtualFileListener(myVfsListener, this);
|
||||
myPsiTreeChangeAdapter = new PsiTreeChangeAdapter() {
|
||||
public void childAdded(PsiTreeChangeEvent event) {
|
||||
childrenChanged(event);
|
||||
@@ -607,6 +615,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
|
||||
public void dispose() {
|
||||
float proportion = getSplitter().getProportion();
|
||||
PropertiesComponent.getInstance(myProject).setValue(PROPORTION_PROPERTY, Double.toString(proportion));
|
||||
VirtualFileManager.getInstance().removeVirtualFileListener(myVfsListener);
|
||||
|
||||
myDisposed = true;
|
||||
Disposer.dispose(myStructureViewComponent);
|
||||
|
||||
Reference in New Issue
Block a user