diff --git a/.idea/modules.xml b/.idea/modules.xml index 7dd2c78681b2..8720385396a2 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -71,6 +71,7 @@ + diff --git a/bin/log.xml b/bin/log.xml index a85a744b1c38..d8fca779f651 100644 --- a/bin/log.xml +++ b/bin/log.xml @@ -1,6 +1,6 @@ - + @@ -29,9 +29,9 @@ - - - + + + @@ -52,19 +52,10 @@ - - - + diff --git a/community-resources/src/idea/IdeaApplicationInfo.xml b/community-resources/src/idea/IdeaApplicationInfo.xml index 035e49f13af7..081eac6c941c 100644 --- a/community-resources/src/idea/IdeaApplicationInfo.xml +++ b/community-resources/src/idea/IdeaApplicationInfo.xml @@ -5,7 +5,7 @@ - + diff --git a/community-resources/src/idea/PlatformLangXmlApplicationInfo.xml b/community-resources/src/idea/PlatformLangXmlApplicationInfo.xml index 1bcdca8d3b40..4b701bebb5cd 100644 --- a/community-resources/src/idea/PlatformLangXmlApplicationInfo.xml +++ b/community-resources/src/idea/PlatformLangXmlApplicationInfo.xml @@ -4,7 +4,7 @@ - + diff --git a/images/src/org/intellij/images/editor/impl/ImageEditorUI.java b/images/src/org/intellij/images/editor/impl/ImageEditorUI.java index c4f80c1742cf..e8589aaf0949 100644 --- a/images/src/org/intellij/images/editor/impl/ImageEditorUI.java +++ b/images/src/org/intellij/images/editor/impl/ImageEditorUI.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; +import com.intellij.ui.PopupHandler; import com.intellij.ui.ScrollPaneFactory; import org.intellij.images.ImagesBundle; import org.intellij.images.editor.ImageDocument; @@ -318,24 +319,21 @@ final class ImageEditorUI extends JPanel implements DataProvider { } private class FocusRequester extends MouseAdapter { - public void mouseClicked(MouseEvent e) { + public void mousePressed(MouseEvent e) { requestFocus(); } } - private static final class EditorMouseAdapter extends MouseAdapter { - public void mouseClicked(MouseEvent e) { - if (MouseEvent.BUTTON3 == e.getButton() && e.getClickCount() == 1) { + private static final class EditorMouseAdapter extends PopupHandler { + @Override + public void invokePopup(Component comp, int x, int y) { // Single right click ActionManager actionManager = ActionManager.getInstance(); ActionGroup actionGroup = (ActionGroup) actionManager.getAction(ImageEditorActions.GROUP_POPUP); ActionPopupMenu menu = actionManager.createActionPopupMenu(ImageEditorActions.ACTION_PLACE, actionGroup); JPopupMenu popupMenu = menu.getComponent(); popupMenu.pack(); - popupMenu.show(e.getComponent(), e.getX(), e.getY()); - - e.consume(); - } + popupMenu.show(comp, x, y); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java index d149e8c388f0..8aebe9e5a86c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java @@ -31,11 +31,11 @@ import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; +import com.intellij.ui.DoubleClickListener; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.tree.TreePath; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; @@ -114,22 +114,23 @@ public abstract class DebuggerAction extends AnAction { } public static Disposable installEditAction(final JTree tree, String actionName) { - final MouseAdapter mouseListener = new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() != 2) return; - if (tree.getPathForLocation(e.getX(), e.getY()) == null) return; + final DoubleClickListener listener = new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + if (tree.getPathForLocation(e.getX(), e.getY()) == null) return false; DataContext dataContext = DataManager.getInstance().getDataContext(tree); GotoFrameSourceAction.doAction(dataContext); + return true; } }; - tree.addMouseListener(mouseListener); - + listener.installOn(tree); + final AnAction action = ActionManager.getInstance().getAction(actionName); action.registerCustomShortcutSet(CommonShortcuts.getEditSource(), tree); return new Disposable() { public void dispose() { - tree.removeMouseListener(mouseListener); + listener.uninstall(tree); action.unregisterCustomShortcutSet(tree); } }; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java index 68c6049d4cdc..6153608513de 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java @@ -38,13 +38,13 @@ import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.ClickListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -102,18 +102,18 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{ myChooseFactory.setToolTipText("Click to change the language"); myChooseFactory.setBorder(new EmptyBorder(0, 3, 0, 3)); - myChooseFactory.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { ListPopup oldPopup = myPopup != null ? myPopup.get() : null; if (oldPopup != null && !oldPopup.isDisposed()) { oldPopup.cancel(); myPopup = null; - return; + return true; } if (!myChooseFactory.isEnabled()) { - return; + return true; } DefaultActionGroup actions = new DefaultActionGroup(); @@ -134,8 +134,9 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{ false); popup.showUnderneathOf(myChooseFactory); myPopup = new WeakReference(popup); + return true; } - }); + }.installOn(myChooseFactory); } @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/GetJPDADialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/GetJPDADialog.java index 7348beedcc76..f6504b525357 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/GetJPDADialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/GetJPDADialog.java @@ -21,17 +21,16 @@ */ package com.intellij.debugger.ui; +import com.intellij.debugger.DebuggerBundle; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.debugger.DebuggerBundle; +import com.intellij.ui.DoubleClickListener; +import org.jetbrains.annotations.NonNls; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import org.jetbrains.annotations.NonNls; - public class GetJPDADialog extends DialogWrapper { private static final @NonNls String JPDA_URL = "http://java.sun.com/products/jpda"; @@ -55,14 +54,13 @@ public class GetJPDADialog extends DialogWrapper { JLabel label1 = new JLabel(DebuggerBundle.message("label.get.jpda.dialog.prompt")); //label1.setForeground(Color.black); JLabel label2 = new JLabel(JPDA_URL); - label2.addMouseListener( - new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - BrowserUtil.launchBrowser(JPDA_URL); - } - + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + BrowserUtil.launchBrowser(JPDA_URL); + return true; } - ); + }.installOn(label2); label2.setForeground(Color.blue.darker()); label2.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); _panel2.add(new JLabel(DebuggerBundle.message("label.get.jpda.dialog.error.description")), BorderLayout.NORTH); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointChooser.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointChooser.java index 3eaf0476498e..cc94f6be4b59 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointChooser.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointChooser.java @@ -24,7 +24,9 @@ import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupListener; import com.intellij.openapi.ui.popup.LightweightWindowEvent; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.ui.popup.util.DetailView; +import com.intellij.ui.popup.util.ItemWrapper; import com.intellij.xdebugger.breakpoints.ui.BreakpointItem; import com.intellij.xdebugger.impl.breakpoints.ui.tree.BreakpointMasterDetailPopupBuilder; import org.jetbrains.annotations.NotNull; @@ -62,8 +64,7 @@ public class BreakpointChooser { public void setSelectedBreakpoint(Object selectedBreakpoint) { mySelectedBreakpoint = selectedBreakpoint; myBreakpointItem = selectedBreakpoint != null ? new JavaBreakpointItem(null, (Breakpoint)selectedBreakpoint) : null; - updatePresentation(myComboBoxAction.getTemplatePresentation(), myBreakpointItem); - myActionToolbar.getComponent().repaint(); + updatePresentation(myComboBoxAction.getTemplatePresentation(), myBreakpointItem); } private void pop(DetailView.PreviewEditorState pushed) { @@ -80,7 +81,7 @@ public class BreakpointChooser { void breakpointChosen(Project project, BreakpointItem breakpointItem, JBPopup popup); } - public BreakpointChooser(Project project, Delegate delegate) { + public BreakpointChooser(Project project, Delegate delegate, Breakpoint baseBreakpoint) { myProject = project; myDelegate = delegate; @@ -146,7 +147,7 @@ public class BreakpointChooser { return null; } }; - + setSelectedBreakpoint(baseBreakpoint); myActionToolbar = ActionManager.getInstance().createActionToolbar("asdad", new DefaultActionGroup(myComboBoxAction), true); } @@ -156,7 +157,7 @@ public class BreakpointChooser { } private void updatePresentation(Presentation presentation, BreakpointItem breakpointItem) { - if (breakpointItem != null) { + if (breakpointItem != null && breakpointItem.getBreakpoint() != null) { presentation.setIcon(breakpointItem.getIcon()); presentation.setText(breakpointItem.getDisplayText()); } @@ -173,9 +174,11 @@ public class BreakpointChooser { private class MyDetailView implements DetailView { private final PreviewEditorState myPushed; + private ItemWrapper myCurrentItem; public MyDetailView(PreviewEditorState pushed) { myPushed = pushed; + putUserData(BreakpointItem.EDITOR_ONLY, Boolean.TRUE); } @Override @@ -210,14 +213,30 @@ public class BreakpointChooser { return myDetailView.getEditorState(); } + public void setCurrentItem(ItemWrapper currentItem) { + myCurrentItem = currentItem; + } + + @Override + public ItemWrapper getCurrentItem() { + return myCurrentItem; + } + + @Override + public boolean hasEditorOnly() { + return true; + } + + UserDataHolderBase myDataHolderBase = new UserDataHolderBase(); + @Override public T getUserData(@NotNull Key key) { - return myDetailView.getUserData(key); + return myDataHolderBase.getUserData(key); } @Override public void putUserData(@NotNull Key key, @Nullable T value) { - myDetailView.putUserData(key, value); + myDataHolderBase.putUserData(key, value); } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form index aa9ca7fb74a4..a447e37e0e09 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form @@ -82,7 +82,7 @@ - + diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java index ce2bc0a5a938..c4dee4bc0638 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java @@ -20,6 +20,7 @@ */ package com.intellij.debugger.ui.breakpoints; +import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.InstanceFilter; import com.intellij.debugger.engine.evaluation.CodeFragmentKind; @@ -42,6 +43,7 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.ui.FieldPanel; import com.intellij.ui.MultiLineTooltipUI; +import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.components.JBCheckBox; import com.intellij.ui.popup.util.DetailView; import com.intellij.util.IJSwingUtilities; @@ -61,7 +63,7 @@ import java.util.List; public abstract class BreakpointPropertiesPanel { - private final BreakpointChooser myMasterBreakpointChooser; + private BreakpointChooser myMasterBreakpointChooser; public void setDetailView(DetailView detailView) { myDetailView = detailView; @@ -284,24 +286,6 @@ public abstract class BreakpointPropertiesPanel { myLogExpressionCombo = new DebuggerExpressionComboBox(project, "LineBreakpoint logMessage"); - myMasterBreakpointChooser = new BreakpointChooser(project, new BreakpointChooser.Delegate() { - @Override - public void breakpointChosen(Project project, BreakpointItem item, JBPopup popup) { - final boolean enabled = item != null && item.getBreakpoint() != null; - myLeaveEnabledRadioButton.setEnabled(enabled); - myDisableAgainRadio.setEnabled(enabled); - myEnableOrDisableLabel.setEnabled(enabled); - - if (item != null) { - - saveMasterBreakpoint(); - } - - updateMasterBreakpointPanel(findMasterBreakpointRule()); - - } - }); - myInstanceFiltersField = new FieldPanel(new MyTextField(), "", null, new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -357,8 +341,7 @@ public abstract class BreakpointPropertiesPanel { insert(myConditionComboPanel, conditionPanel); insert(myLogExpressionComboPanel, myLogExpressionCombo); - //insert(myDependentBreakpointComboPanel, baseBreakpointCombo); - insert(myDependentBreakpointComboPanel, myMasterBreakpointChooser.getComponent()); + insert(myInstanceFiltersFieldPanel, myInstanceFiltersField); insert(myClassFiltersFieldPanel, myClassFiltersField); @@ -390,6 +373,68 @@ public abstract class BreakpointPropertiesPanel { break; } } + items.add(new BreakpointItem() { + @Override + public Object getBreakpoint() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean isEnabled() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void setEnabled(boolean state) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected void setupGenericRenderer(SimpleColoredComponent renderer, boolean plainView) { + renderer.clear(); + renderer.append(getDisplayText()); + } + + @Override + public Icon getIcon() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getDisplayText() { + return DebuggerBundle.message("value.none"); + } + + @Override + public boolean navigate() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String speedSearchText() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String footerText() { + return ""; + } + + @Override + protected void doUpdateDetailView(DetailView panel, boolean editorOnly) { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean allowedToRemove() { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public void removed(Project project) { + //To change body of implemented methods use File | Settings | File Templates. + } + }); return items; } @@ -414,9 +459,13 @@ public abstract class BreakpointPropertiesPanel { else { EnableBreakpointRule rule = findMasterBreakpointRule(); boolean selected = myLeaveEnabledRadioButton.isSelected(); - if (rule != null && (rule.getMasterBreakpoint() != masterBreakpoint || rule.isLeaveEnabled() != selected ) ) { - getBreakpointManager(myProject).removeBreakpointRule(rule); - + if (rule != null) { + if (rule.getMasterBreakpoint() != masterBreakpoint || rule.isLeaveEnabled() != selected) { + getBreakpointManager(myProject).removeBreakpointRule(rule); + } + else { + return; + } } getBreakpointManager(myProject).addBreakpointRule(new EnableBreakpointRule(getBreakpointManager(myProject), masterBreakpoint, @@ -569,14 +618,35 @@ public abstract class BreakpointPropertiesPanel { } private void initMasterBreakpointPanel() { - myMasterBreakpointChooser.setBreakpointItems(getBreakpointItemsExceptMy()); - final EnableBreakpointRule rule = findMasterBreakpointRule(); final Breakpoint baseBreakpoint = rule != null ? rule.getMasterBreakpoint() : null; updateMasterBreakpointPanel(rule); - myMasterBreakpointChooser.setSelectedBreakpoint(baseBreakpoint); + + myMasterBreakpointChooser = new BreakpointChooser(myProject, new BreakpointChooser.Delegate() { + @Override + public void breakpointChosen(Project project, BreakpointItem item, JBPopup popup) { + final boolean enabled = item != null && item.getBreakpoint() != null; + myLeaveEnabledRadioButton.setEnabled(enabled); + myDisableAgainRadio.setEnabled(enabled); + myEnableOrDisableLabel.setEnabled(enabled); + + if (item != null) { + + saveMasterBreakpoint(); + } + + updateMasterBreakpointPanel(findMasterBreakpointRule()); + + } + }, baseBreakpoint); + + insert(myDependentBreakpointComboPanel, myMasterBreakpointChooser.getComponent()); + + + myMasterBreakpointChooser.setBreakpointItems(getBreakpointItemsExceptMy()); + } private @Nullable EnableBreakpointRule findMasterBreakpointRule() { @@ -793,37 +863,6 @@ public abstract class BreakpointPropertiesPanel { return myPanel; } - private static class ComboboxItem { - private final Breakpoint breakpoint; - - public ComboboxItem() { - breakpoint = null; - } - - public ComboboxItem(@NotNull final Breakpoint breakpoint) { - this.breakpoint = breakpoint; - } - - public Breakpoint getBreakpoint() { - return breakpoint; - } - - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final ComboboxItem comboboxItem = (ComboboxItem)o; - - if (breakpoint != null ? !breakpoint.equals(comboboxItem.breakpoint) : comboboxItem.breakpoint != null) return false; - - return true; - } - - public int hashCode() { - return breakpoint != null ? breakpoint.hashCode() : 0; - } - } - private BreakpointManager getBreakpointManager(Project project) { return DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java index 7ef5417ca915..a285463aeea4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java @@ -25,6 +25,7 @@ import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.engine.requests.RequestManagerImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.JavaDebuggerSupport; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.AnAction; @@ -49,6 +50,7 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.jsp.JspFile; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.StringBuilderSpinAllocator; +import com.intellij.xdebugger.impl.DebuggerSupport; import com.intellij.xdebugger.impl.actions.EditBreakpointAction; import com.intellij.xdebugger.impl.actions.ViewBreakpointsAction; import com.intellij.xdebugger.impl.actions.XDebuggerActions; @@ -594,67 +596,6 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { } } - @NotNull - private ActionGroup createMenuActions() { - final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager(); - /** - * Used from Popup Menu - */ - class RemoveAction extends AnAction { - @Nullable private Breakpoint myBreakpoint; - - public RemoveAction(Breakpoint breakpoint) { - super(DebuggerBundle.message("action.remove.text")); - myBreakpoint = breakpoint; - } - - @Override - public void actionPerformed(AnActionEvent e) { - if (myBreakpoint != null) { - breakpointManager.removeBreakpoint(myBreakpoint); - myBreakpoint = null; - } - } - } - - /** - * Used from Popup Menu - */ - class SetEnabledAction extends AnAction { - private final boolean myNewValue; - private final Breakpoint myBreakpoint; - - public SetEnabledAction(Breakpoint breakpoint, boolean newValue) { - super(newValue ? DebuggerBundle.message("action.enable.text") : DebuggerBundle.message("action.disable.text")); - myBreakpoint = breakpoint; - myNewValue = newValue; - } - - @Override - public void actionPerformed(AnActionEvent e) { - myBreakpoint.ENABLED = myNewValue; - breakpointManager.fireBreakpointChanged(myBreakpoint); - myBreakpoint.updateUI(); - } - } - - - AnAction viewBreakpointsAction = - new ViewBreakpointsAction(ActionsBundle.actionText(XDebuggerActions.VIEW_BREAKPOINTS), this); - - DefaultActionGroup group = new DefaultActionGroup(); - RangeHighlighter highlighter = getHighlighter(); - if (highlighter != null) { - group.add(new EditBreakpointAction()); - group.addSeparator(); - } - group.add(new SetEnabledAction(this, !ENABLED)); - group.add(new RemoveAction(this)); - group.addSeparator(); - group.add(viewBreakpointsAction); - return group; - } - private class MyGutterIconRenderer extends GutterIconRenderer { private final Icon myIcon; private final String myDescription; @@ -699,7 +640,63 @@ public abstract class BreakpointWithHighlighter extends Breakpoint { @Override public ActionGroup getPopupMenuActions() { - return createMenuActions(); + final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager(); + /** + * Used from Popup Menu + */ + class RemoveAction extends AnAction { + @Nullable private Breakpoint myBreakpoint; + + public RemoveAction(Breakpoint breakpoint) { + super(DebuggerBundle.message("action.remove.text")); + myBreakpoint = breakpoint; + } + + @Override + public void actionPerformed(AnActionEvent e) { + if (myBreakpoint != null) { + breakpointManager.removeBreakpoint(myBreakpoint); + myBreakpoint = null; + } + } + } + + /** + * Used from Popup Menu + */ + class SetEnabledAction extends AnAction { + private final boolean myNewValue; + private final Breakpoint myBreakpoint; + + public SetEnabledAction(Breakpoint breakpoint, boolean newValue) { + super(newValue ? DebuggerBundle.message("action.enable.text") : DebuggerBundle.message("action.disable.text")); + myBreakpoint = breakpoint; + myNewValue = newValue; + } + + @Override + public void actionPerformed(AnActionEvent e) { + myBreakpoint.ENABLED = myNewValue; + breakpointManager.fireBreakpointChanged(myBreakpoint); + myBreakpoint.updateUI(); + } + } + + + AnAction viewBreakpointsAction = + new ViewBreakpointsAction(ActionsBundle.actionText(XDebuggerActions.VIEW_BREAKPOINTS), BreakpointWithHighlighter.this); + + DefaultActionGroup group = new DefaultActionGroup(); + RangeHighlighter highlighter = getHighlighter(); + if (highlighter != null) { + group.add(new EditBreakpointAction.ContextAction(this, BreakpointWithHighlighter.this, DebuggerSupport.getDebuggerSupport(JavaDebuggerSupport.class))); + group.addSeparator(); + } + group.add(new SetEnabledAction(BreakpointWithHighlighter.this, !ENABLED)); + group.add(new RemoveAction(BreakpointWithHighlighter.this)); + group.addSeparator(); + group.add(viewBreakpointsAction); + return group; } @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java index 170eec164c2f..e46e7103fd45 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java @@ -72,21 +72,23 @@ class JavaBreakpointItem extends BreakpointItem { } @Override - protected void doUpdateDetailView(DetailView panel) { - BreakpointPropertiesPanel breakpointPropertiesPanel = myBreakpointFactory != null ? myBreakpointFactory - .createBreakpointPropertiesPanel(myBreakpoint.getProject(), false) : null; - if (breakpointPropertiesPanel != null) { - breakpointPropertiesPanel.setSaveOnRemove(true); - breakpointPropertiesPanel.setDetailView(panel); - } + protected void doUpdateDetailView(DetailView panel, boolean editorOnly) { + if (!editorOnly) { + BreakpointPropertiesPanel breakpointPropertiesPanel = myBreakpointFactory != null ? myBreakpointFactory + .createBreakpointPropertiesPanel(myBreakpoint.getProject(), false) : null; - if (breakpointPropertiesPanel != null) { - breakpointPropertiesPanel.initFrom(myBreakpoint, true); - final JPanel mainPanel = breakpointPropertiesPanel.getPanel(); - panel.setDetailPanel(mainPanel); - } - else { - panel.setDetailPanel(null); + if (breakpointPropertiesPanel != null) { + breakpointPropertiesPanel.initFrom(myBreakpoint, true); + + breakpointPropertiesPanel.setSaveOnRemove(true); + breakpointPropertiesPanel.setDetailView(panel); + + final JPanel mainPanel = breakpointPropertiesPanel.getPanel(); + panel.setDetailPanel(mainPanel); + } + else { + panel.setDetailPanel(null); + } } if (myBreakpoint instanceof BreakpointWithHighlighter) { @@ -98,6 +100,15 @@ class JavaBreakpointItem extends BreakpointItem { } } + @Override + public boolean navigate() { + if (myBreakpoint instanceof BreakpointWithHighlighter) { + ((BreakpointWithHighlighter)myBreakpoint).getSourcePosition().navigate(true); + return true; + } + return false; + } + @Override public boolean allowedToRemove() { return myBreakpointFactory != null && myBreakpointFactory.breakpointCanBeRemoved(myBreakpoint); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/MainWatchPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/MainWatchPanel.java index 1674be4a3b11..d890a4601813 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/MainWatchPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/MainWatchPanel.java @@ -52,7 +52,6 @@ import javax.swing.*; import java.awt.*; import java.awt.datatransfer.DataFlavor; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class MainWatchPanel extends WatchPanel implements DataProvider { @@ -67,25 +66,25 @@ public class MainWatchPanel extends WatchPanel implements DataProvider { final AnAction newWatchAction = ActionManager.getInstance().getAction(DebuggerActions.NEW_WATCH); newWatchAction.registerCustomShortcutSet(CommonShortcuts.INSERT, watchTree); - final MouseAdapter mouseListener = new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) { - AnAction editWatchAction = ActionManager.getInstance().getAction(DebuggerActions.EDIT_WATCH); - Presentation presentation = (Presentation)editWatchAction.getTemplatePresentation().clone(); - DataContext context = DataManager.getInstance().getDataContext(watchTree); + final ClickListener mouseListener = new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + AnAction editWatchAction = ActionManager.getInstance().getAction(DebuggerActions.EDIT_WATCH); + Presentation presentation = editWatchAction.getTemplatePresentation().clone(); + DataContext context = DataManager.getInstance().getDataContext(watchTree); - AnActionEvent actionEvent = new AnActionEvent(null, context, "WATCH_TREE", presentation, ActionManager.getInstance(), 0); - editWatchAction.actionPerformed(actionEvent); - } + AnActionEvent actionEvent = new AnActionEvent(null, context, "WATCH_TREE", presentation, ActionManager.getInstance(), 0); + editWatchAction.actionPerformed(actionEvent); + return true; } }; - ListenerUtil.addMouseListener(watchTree, mouseListener); + ListenerUtil.addClickListener(watchTree, mouseListener); final AnAction editWatchAction = ActionManager.getInstance().getAction(DebuggerActions.EDIT_WATCH); editWatchAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), watchTree); registerDisposable(new Disposable() { public void dispose() { - ListenerUtil.removeMouseListener(watchTree, mouseListener); + ListenerUtil.removeClickListener(watchTree, mouseListener); removeWatchesAction.unregisterCustomShortcutSet(watchTree); newWatchAction.unregisterCustomShortcutSet(watchTree); editWatchAction.unregisterCustomShortcutSet(watchTree); diff --git a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteManager.java b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteManager.java index b3c8af6564d8..5aa1bf611e7a 100644 --- a/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteManager.java +++ b/java/idea-ui/src/com/intellij/ide/palette/impl/PaletteManager.java @@ -71,7 +71,7 @@ public class PaletteManager implements ProjectComponent { ToolWindowAnchor.RIGHT, myProject, true); - myPaletteToolWindow.setIcon(AllIcons.General.ToolWindowPalette); + myPaletteToolWindow.setIcon(AllIcons.Toolwindows.ToolWindowPalette); setContent(); final MyFileEditorManagerListener myListener = new MyFileEditorManagerListener(); myFileEditorManager.addFileEditorManagerListener(myListener, myProject); diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectCreateModeStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectCreateModeStep.java index c507c78e8063..81a02dee1a7e 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectCreateModeStep.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectCreateModeStep.java @@ -29,6 +29,7 @@ import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.util.Disposer; +import com.intellij.ui.DoubleClickListener; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -37,7 +38,6 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; @@ -91,14 +91,13 @@ public class ProjectCreateModeStep extends ModuleWizardStep { setMode(mode); } }); - rb.addMouseListener(new MouseAdapter() { + new DoubleClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) { - wizardContext.requestNextStep(); - } + protected boolean onDoubleClick(MouseEvent e) { + wizardContext.requestNextStep(); + return true; } - }); + }.installOn(rb); myWholePanel.add(rb, gc); group.add(rb); diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectNameWithTypeStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectNameWithTypeStep.java index f90961a0ba77..90a5f94e794e 100644 --- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectNameWithTypeStep.java +++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/ProjectNameWithTypeStep.java @@ -40,6 +40,7 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.components.JBScrollPane; import com.intellij.util.IJSwingUtilities; import com.intellij.util.ui.UIUtil; @@ -47,7 +48,10 @@ import com.intellij.util.ui.UIUtil; import javax.swing.*; import javax.swing.event.*; import java.awt.*; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.io.File; import java.util.List; @@ -153,13 +157,13 @@ public class ProjectNameWithTypeStep extends ProjectNameStep { } }); myTypesList.setSelectedIndex(0); - myTypesList.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) { - myWizardContext.requestNextStep(); - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + myWizardContext.requestNextStep(); + return true; } - }); + }.installOn(myTypesList); final Dimension preferredSize = calcTypeListPreferredSize(ModuleBuilder.getAllBuilders()); final JBScrollPane pane = IJSwingUtilities.findParentOfType(myTypesList, JBScrollPane.class); diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/JdkChooserPanel.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/JdkChooserPanel.java index 20234f22f4b2..42a3e3265160 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/JdkChooserPanel.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/JdkChooserPanel.java @@ -30,6 +30,8 @@ import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.ui.ClickListener; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ListScrollingUtil; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.components.JBList; @@ -42,7 +44,6 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.event.ActionEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.*; @@ -66,13 +67,15 @@ public class JdkChooserPanel extends JPanel { myCurrentJdk = (Sdk)myList.getSelectedValue(); } }); - myList.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2 && myProject == null) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { + if (myProject == null) { editJdkTable(); } + return true; } - }); + }.installOn(myList); JPanel panel = new JPanel(new BorderLayout()); panel.add(ScrollPaneFactory.createScrollPane(myList), BorderLayout.CENTER); @@ -219,14 +222,13 @@ public class JdkChooserPanel extends JPanel { } else { ListScrollingUtil.ensureSelectionExists(jdkChooserPanel.myList); } - jdkChooserPanel.myList.addMouseListener(new MouseAdapter() { + new DoubleClickListener() { @Override - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) { - dialog.clickDefaultButton(); - } + protected boolean onDoubleClick(MouseEvent e) { + dialog.clickDefaultButton(); + return true; } - }); + }.installOn(jdkChooserPanel.myList); dialog.show(); return dialog.isOK() ? jdkChooserPanel.getChosenJdk() : null; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java index 9713f136b917..52b7802daf6e 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/classpath/ClasspathPanelImpl.java @@ -74,7 +74,10 @@ import javax.swing.event.ListSelectionListener; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import java.awt.*; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -188,13 +191,13 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel { myEntryTable.getSelectionModel().setSelectionInterval(0,0); } - myEntryTable.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2){ - navigate(true); - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + navigate(true); + return true; } - }); + }.installOn(myEntryTable); DefaultActionGroup actionGroup = new DefaultActionGroup(); final AnAction navigateAction = new AnAction(ProjectBundle.message("classpath.panel.navigate.action.text")) { diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java index c583216282ec..40837d333a15 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java @@ -925,7 +925,7 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple private class AddModuleAction extends AnAction implements DumbAware { public AddModuleAction() { - super(ProjectBundle.message("add.new.module.text.full"), null, AllIcons.Actions.Modul); + super(ProjectBundle.message("add.new.module.text.full"), null, AllIcons.Actions.Module); } public void actionPerformed(final AnActionEvent e) { diff --git a/java/idea-ui/src/com/intellij/projectImport/ImportChooserStep.java b/java/idea-ui/src/com/intellij/projectImport/ImportChooserStep.java index 08b6334ea172..0ce3cee53834 100644 --- a/java/idea-ui/src/com/intellij/projectImport/ImportChooserStep.java +++ b/java/idea-ui/src/com/intellij/projectImport/ImportChooserStep.java @@ -24,6 +24,7 @@ import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.newProjectWizard.StepSequence; import com.intellij.ide.util.projectWizard.WizardContext; import com.intellij.openapi.util.Comparing; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.components.JBList; import org.jetbrains.annotations.NonNls; @@ -32,7 +33,6 @@ import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collections; @@ -87,14 +87,14 @@ public class ImportChooserStep extends ProjectImportWizardStep { } } } - myList.addMouseListener(new MouseAdapter() { + + new DoubleClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) { - context.requestNextStep(); - } + protected boolean onDoubleClick(MouseEvent e) { + context.requestNextStep(); + return true; } - }); + }.installOn(myList); } private static List sorted(ProjectImportProvider[] providers) { diff --git a/java/idea-ui/src/com/intellij/util/ui/classpath/ChooseLibrariesDialogBase.java b/java/idea-ui/src/com/intellij/util/ui/classpath/ChooseLibrariesDialogBase.java index 97649e847afb..d63545c3cecf 100644 --- a/java/idea-ui/src/com/intellij/util/ui/classpath/ChooseLibrariesDialogBase.java +++ b/java/idea-ui/src/com/intellij/util/ui/classpath/ChooseLibrariesDialogBase.java @@ -44,6 +44,7 @@ import com.intellij.openapi.roots.ui.OrderEntryAppearanceService; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; @@ -66,7 +67,6 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import java.awt.*; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.*; import java.util.List; @@ -188,15 +188,17 @@ public abstract class ChooseLibrariesDialogBase extends DialogWrapper { updateOKAction(); } }); - myTree.addMouseListener(new MouseAdapter() { + new DoubleClickListener() { @Override - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() != 2) return; + protected boolean onDoubleClick(MouseEvent e) { if (isOKActionEnabled()) { doOKAction(); + return true; } + return false; } - }); + }.installOn(myTree); + myTree.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ENTER"); myTree.getActionMap().put("ENTER", getOKAction()); final JScrollPane pane = ScrollPaneFactory.createScrollPane(myTree); diff --git a/java/java-impl/java-impl.iml b/java/java-impl/java-impl.iml index d19011b3e584..9735a4a7fad1 100644 --- a/java/java-impl/java-impl.iml +++ b/java/java-impl/java-impl.iml @@ -32,7 +32,6 @@ - diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java index 5bb12243485f..b9b531f20153 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -417,7 +417,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor { element = LookupElementDecorator.withInsertHandler(element, new InsertHandler>() { @Override public void handleInsert(InsertionContext context, LookupElementDecorator item) { - callback.nameChoosen(item.getLookupString()); + callback.nameChosen(item.getLookupString()); } }); } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java index bf7305100d6f..4ab59906589d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java @@ -22,6 +22,7 @@ import com.intellij.codeInsight.daemon.LineMarkerProvider; import com.intellij.codeInsight.daemon.MergeableLineMarkerInfo; import com.intellij.icons.AllIcons; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.colors.CodeInsightColors; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; @@ -32,6 +33,8 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.searches.AllOverridingMethodsSearch; import com.intellij.psi.search.searches.ClassInheritorsSearch; @@ -71,8 +74,9 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware { @Override @Nullable public LineMarkerInfo getLineMarkerInfo(@NotNull final PsiElement element) { - if (element instanceof PsiIdentifier && element.getParent() instanceof PsiMethod) { - PsiMethod method = (PsiMethod)element.getParent(); + PsiElement parent; + if (element instanceof PsiIdentifier && (parent = element.getParent()) instanceof PsiMethod) { + PsiMethod method = (PsiMethod)parent; MethodSignatureBackedByPsiMethod superSignature = null; try { superSignature = SuperMethodsSearch.search(method, null, true, false).findFirst(); @@ -101,13 +105,19 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware { } } if (isMember && !(element1 instanceof PsiAnonymousClass || element1.getParent() instanceof PsiAnonymousClass)) { + PsiFile file = element1.getContainingFile(); + Document document = file == null ? null : PsiDocumentManager.getInstance(file.getProject()).getDocument(file); boolean drawSeparator = false; - int category = getCategory(element1); - for (PsiElement child = element1.getPrevSibling(); child != null; child = child.getPrevSibling()) { - int category1 = getCategory(child); - if (category1 == 0) continue; - drawSeparator = category != 1 || category1 != 1; - break; + + if (document != null) { + CharSequence documentChars = document.getCharsSequence(); + int category = getCategory(element1, documentChars); + for (PsiElement child = element1.getPrevSibling(); child != null; child = child.getPrevSibling()) { + int category1 = getCategory(child, documentChars); + if (category1 == 0) continue; + drawSeparator = category != 1 || category1 != 1; + break; + } } if (drawSeparator) { @@ -125,20 +135,18 @@ public class JavaLineMarkerProvider implements LineMarkerProvider, DumbAware { return null; } - protected static int getCategory(PsiElement element) { + protected static int getCategory(@NotNull PsiElement element, @NotNull CharSequence documentChars) { if (element instanceof PsiField || element instanceof PsiTypeParameter) return 1; if (element instanceof PsiClass || element instanceof PsiClassInitializer) return 2; if (element instanceof PsiMethod) { if (((PsiMethod)element).hasModifierProperty(PsiModifier.ABSTRACT)) { return 1; } - String text = element.getText(); - if (text.indexOf('\n') < 0 && text.indexOf('\r') < 0) { - return 1; - } - else { - return 2; - } + TextRange textRange = element.getTextRange(); + int start = textRange.getStartOffset(); + int end = Math.min(documentChars.length(), textRange.getEndOffset()); + int crlf = StringUtil.getLineBreakCount(documentChars.subSequence(start, end)); + return crlf == 0 ? 1 : 2; } return 0; } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java index 883c17f21592..399b5d624ef0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java @@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.CodeInsightUtilBase; import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.intention.impl.RunRefactoringAction; import com.intellij.codeInsight.navigation.NavigationUtil; import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement; import com.intellij.ide.util.PsiClassListCellRenderer; @@ -163,13 +164,13 @@ public class PullAsAbstractUpFix extends LocalQuickFixAndIntentionActionOnPsiEle name+= " and make it abstract"; } } - QuickFixAction.registerQuickFixAction(highlightInfo, new RunRefactoringIntention(new ExtractInterfaceHandler(), "Extract interface")); - QuickFixAction.registerQuickFixAction(highlightInfo, new RunRefactoringIntention(new ExtractSuperclassHandler(), "Extract superclass")); + QuickFixAction.registerQuickFixAction(highlightInfo, new RunRefactoringAction(new ExtractInterfaceHandler(), "Extract interface")); + QuickFixAction.registerQuickFixAction(highlightInfo, new RunRefactoringAction(new ExtractSuperclassHandler(), "Extract superclass")); } if (canBePulledUp) { - QuickFixAction.registerQuickFixAction(highlightInfo, new RunRefactoringIntention(new JavaPullUpHandler(), "Pull members up")); + QuickFixAction.registerQuickFixAction(highlightInfo, new RunRefactoringAction(new JavaPullUpHandler(), "Pull members up")); } QuickFixAction.registerQuickFixAction(highlightInfo, new PullAsAbstractUpFix(methodWithOverrides, name)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java index 7a74b3b31fef..9ec174fdf21c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java +++ b/java/java-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilder.java @@ -569,7 +569,7 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar } } - private static boolean hasOnlyOneMethod(@NotNull PsiAnonymousClass anonymousClass, boolean checkResolve) { + private static boolean hasOnlyOneLambdaMethod(@NotNull PsiAnonymousClass anonymousClass, boolean checkResolve) { PsiField[] fields = anonymousClass.getFields(); if (fields.length != 0) { if (fields.length == 1 && HighlightUtil.SERIAL_VERSION_UID_FIELD_NAME.equals(fields[0].getName()) && @@ -590,8 +590,13 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar return false; } + PsiMethod method = anonymousClass.getMethods()[0]; + if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) { + return false; + } + if (checkResolve) { - PsiReferenceList throwsList = anonymousClass.getMethods()[0].getThrowsList(); + PsiReferenceList throwsList = method.getThrowsList(); for (PsiClassType type : throwsList.getReferencedTypes()) { if (type.resolve() == null) { return false; @@ -617,7 +622,7 @@ public class JavaFoldingBuilder extends CustomFoldingBuilder implements DumbAwar final PsiExpressionList argumentList = expression.getArgumentList(); if (argumentList != null && argumentList.getExpressions().length == 0) { final PsiMethod[] methods = anonymousClass.getMethods(); - if (hasOnlyOneMethod(anonymousClass, !quick) && (quick || seemsLikeLambda(anonymousClass.getBaseClassType().resolve()))) { + if (hasOnlyOneLambdaMethod(anonymousClass, !quick) && (quick || seemsLikeLambda(anonymousClass.getBaseClassType().resolve()))) { final PsiMethod method = methods[0]; final PsiCodeBlock body = method.getBody(); if (body != null) { diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/ui/SimpleFieldChooser.java b/java/java-impl/src/com/intellij/codeInsight/generation/ui/SimpleFieldChooser.java index ff013dec0d16..26360dbb9f8a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/ui/SimpleFieldChooser.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/ui/SimpleFieldChooser.java @@ -21,11 +21,11 @@ import com.intellij.psi.PsiField; import com.intellij.psi.PsiSubstitutor; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.psi.util.PsiFormatUtilBase; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.components.JBList; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** @@ -48,17 +48,16 @@ public class SimpleFieldChooser extends DialogWrapper { } myList = new JBList(model); myList.setCellRenderer(new MyListCellRenderer()); - myList.addMouseListener( - new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - if (myList.getSelectedValues().length > 0) { - doOKAction(); - } - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + if (myList.getSelectedValues().length > 0) { + doOKAction(); + return true; } + return false; } - ); + }.installOn(myList); myList.setPreferredSize(new Dimension(300, 400)); return myList; diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseRunRefactoringAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseRunRefactoringAction.java new file mode 100644 index 000000000000..b9fbab23fa76 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/BaseRunRefactoringAction.java @@ -0,0 +1,49 @@ +/* + * 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.codeInsight.intention.impl; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.intention.LowPriorityAction; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.util.Iconable; +import com.intellij.refactoring.RefactoringActionHandler; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * @author Danila Ponomarenko + */ +public abstract class BaseRunRefactoringAction implements IntentionAction, Iconable, LowPriorityAction { + public static final Icon REFACTORING_BULB = AllIcons.Actions.RefactoringBulb; + + @NotNull + @Override + public final String getFamilyName() { + return CodeInsightBundle.message("intention.refactoring.family"); + } + + @Override + public final boolean startInWriteAction() { + return false; + } + + @Override + public final Icon getIcon(int flags) { + return REFACTORING_BULB; + } +} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java index 5cefd9fbfd20..20ee44b6ee3a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/CreateFieldFromParameterAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * 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. @@ -351,7 +351,7 @@ public class CreateFieldFromParameterAction implements IntentionAction { fieldNameToCalc = dialog.getEnteredName(); isFinalToCalc = dialog.isDeclareFinal(); - suggestedNameInfo.nameChoosen(fieldNameToCalc); + suggestedNameInfo.nameChosen(fieldNameToCalc); } else { isFinalToCalc = !isMethodStatic && method.isConstructor(); diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/EncapsulateFieldAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/EncapsulateFieldAction.java new file mode 100644 index 000000000000..685f37b375b0 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/EncapsulateFieldAction.java @@ -0,0 +1,86 @@ +/* + * 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.codeInsight.intention.impl; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.openapi.editor.CaretModel; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.refactoring.encapsulateFields.EncapsulateFieldsHandler; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Danila Ponomarenko + */ +public class EncapsulateFieldAction extends BaseRunRefactoringAction { + + @NotNull + @Override + public String getText() { + return CodeInsightBundle.message("intention.encapsulate.field.text"); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + final PsiField field = getField(getElement(editor, file)); + return field != null && !field.hasModifierProperty(PsiModifier.FINAL) && !field.hasModifierProperty(PsiModifier.PRIVATE); + } + + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + final PsiField field = getField(getElement(editor, file)); + if (field == null) { + return; + } + + new EncapsulateFieldsHandler().invoke(project, new PsiElement[]{field}, null); + } + + @Nullable + protected static PsiField getField(@Nullable PsiElement element) { + if (element == null || !(element instanceof PsiIdentifier)) { + return null; + } + + final PsiElement parent = element.getParent(); + if (parent == null || !(parent instanceof PsiReferenceExpression)) { + return null; + } + final PsiReferenceExpression ref = (PsiReferenceExpression)parent; + final PsiExpression qualifier = ref.getQualifierExpression(); + if (qualifier == null || qualifier instanceof PsiThisExpression) { + return null; + } + + final PsiElement resolved = ref.resolve(); + if (resolved == null || !(resolved instanceof PsiField)) { + return null; + } + return (PsiField)resolved; + } + + @Nullable + protected static PsiElement getElement(Editor editor, @NotNull PsiFile file) { + if (!file.getManager().isInProject(file)) return null; + final CaretModel caretModel = editor.getCaretModel(); + final int position = caretModel.getOffset(); + return file.findElementAt(position); + } +} \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExtractIfConditionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExtractIfConditionAction.java new file mode 100644 index 000000000000..4328e37054fb --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ExtractIfConditionAction.java @@ -0,0 +1,253 @@ +/* + * 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.codeInsight.intention.impl; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Danila Ponomarenko + */ +public class ExtractIfConditionAction extends PsiElementBaseIntentionAction { + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { + final PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class); + if (ifStatement == null || ifStatement.getCondition() == null) { + return false; + } + + final PsiExpression condition = ifStatement.getCondition(); + + if (condition == null || !(condition instanceof PsiPolyadicExpression)) { + return false; + } + + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)condition; + final PsiType expressionType = polyadicExpression.getType(); + if (expressionType == null || !PsiType.BOOLEAN.isAssignableFrom(expressionType)) { + return false; + } + + final IElementType operation = polyadicExpression.getOperationTokenType(); + + if (operation != JavaTokenType.OROR && operation != JavaTokenType.ANDAND) { + return false; + } + + final PsiExpression operand = findOperand(element, polyadicExpression); + + if (operand == null) { + return false; + } + setText(CodeInsightBundle.message("intention.extract.if.condition.text", operand.getText())); + return true; + } + + @Override + public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException { + final PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class); + if (ifStatement == null) { + return; + } + + final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); + + final PsiStatement newIfStatement = create(factory, ifStatement, element); + if (newIfStatement == null) { + return; + } + + ifStatement.replace(codeStyleManager.reformat(newIfStatement)); + } + + @Nullable + private static PsiStatement create(@NotNull PsiElementFactory factory, + @NotNull PsiIfStatement ifStatement, + @NotNull PsiElement element) { + + final PsiExpression condition = ifStatement.getCondition(); + + if (condition == null || !(condition instanceof PsiPolyadicExpression)) { + return null; + } + + final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)condition; + + final PsiExpression operand = findOperand(element, polyadicExpression); + + if (operand == null) { + return null; + } + + + return create( + factory, + ifStatement.getThenBranch(), ifStatement.getElseBranch(), + operand, + removeOperand(factory, polyadicExpression, operand), + polyadicExpression.getOperationTokenType() + ); + } + + @NotNull + private static PsiExpression removeOperand(@NotNull PsiElementFactory factory, + @NotNull PsiPolyadicExpression expression, + @NotNull PsiExpression operand) { + final StringBuilder sb = new StringBuilder(); + for (PsiExpression e : expression.getOperands()) { + if (e == operand) continue; + final PsiJavaToken token = expression.getTokenBeforeOperand(e); + if (token != null && sb.length() != 0) { + sb.append(token.getText()).append(" "); + } + sb.append(e.getText()); + } + return factory.createExpressionFromText(sb.toString(), expression); + } + + @Nullable + private static PsiStatement create(@NotNull PsiElementFactory factory, + @Nullable PsiStatement thenBranch, + @Nullable PsiStatement elseBranch, + @NotNull PsiExpression extract, + @NotNull PsiExpression leave, + @NotNull IElementType operation) { + if (thenBranch == null) { + return null; + } + + if (operation == JavaTokenType.OROR) { + return createOrOr(factory, thenBranch, elseBranch, extract, leave); + } + if (operation == JavaTokenType.ANDAND) { + return createAndAnd(factory, thenBranch, elseBranch, extract, leave); + } + + return null; + } + + @NotNull + private static PsiStatement createAndAnd(@NotNull PsiElementFactory factory, + @NotNull PsiStatement thenBranch, + @Nullable PsiStatement elseBranch, + @NotNull PsiExpression extract, + @NotNull PsiExpression leave) { + + return factory.createStatementFromText( + createIfString(extract, + createIfString(leave, thenBranch, elseBranch), + elseBranch + ), + thenBranch + ); + } + + @NotNull + private static PsiStatement createOrOr(@NotNull PsiElementFactory factory, + @NotNull PsiStatement thenBranch, + @Nullable PsiStatement elseBranch, + @NotNull PsiExpression extract, + @NotNull PsiExpression leave) { + + return factory.createStatementFromText( + createIfString(extract, thenBranch, + createIfString(leave, thenBranch, elseBranch) + ), + thenBranch + ); + } + + @NotNull + private static String createIfString(@NotNull PsiExpression condition, + @NotNull PsiStatement thenBranch, + @Nullable PsiStatement elseBranch) { + return createIfString(condition.getText(), toThenBranchString(thenBranch), toElseBranchString(elseBranch)); + } + + @NotNull + private static String createIfString(@NotNull PsiExpression condition, + @NotNull PsiStatement thenBranch, + @Nullable String elseBranch) { + return createIfString(condition.getText(), toThenBranchString(thenBranch), elseBranch); + } + + @NotNull + private static String createIfString(@NotNull PsiExpression condition, + @NotNull String thenBranch, + @Nullable PsiStatement elseBranch) { + return createIfString(condition.getText(), thenBranch, toElseBranchString(elseBranch)); + } + + @NotNull + private static String createIfString(@NotNull String condition, + @NotNull String thenBranch, + @Nullable String elseBranch) { + final String elsePart = elseBranch != null ? " else " + elseBranch : ""; + return "if (" + condition + ")\n" + thenBranch + elsePart; + } + + @NotNull + private static String toThenBranchString(@NotNull PsiStatement statement) { + if (!(statement instanceof PsiBlockStatement)) { + return "{ " + statement.getText() + " }"; + } + + return statement.getText(); + } + + @Nullable + private static String toElseBranchString(@Nullable PsiStatement statement) { + if (statement == null) { + return null; + } + + if (statement instanceof PsiBlockStatement || statement instanceof PsiIfStatement) { + return statement.getText(); + } + + return "{ " + statement.getText() + " }"; + } + + @Nullable + private static PsiExpression findOperand(@NotNull PsiElement e, @NotNull PsiPolyadicExpression expression) { + final TextRange elementTextRange = e.getTextRange(); + + for (PsiExpression operand : expression.getOperands()) { + final TextRange operandTextRange = operand.getTextRange(); + if (operandTextRange != null && operandTextRange.contains(elementTextRange)) { + return operand; + } + } + return null; + } + + @NotNull + @Override + public String getFamilyName() { + return CodeInsightBundle.message("intention.extract.if.condition.family"); + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/IntroduceVariableAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/IntroduceVariableAction.java index c3244099a525..f629c1bfc21c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/IntroduceVariableAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/IntroduceVariableAction.java @@ -16,14 +16,12 @@ package com.intellij.codeInsight.intention.impl; import com.intellij.codeInsight.CodeInsightBundle; -import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.refactoring.JavaRefactoringActionHandlerFactory; -import com.intellij.refactoring.RefactoringActionHandler; +import com.intellij.refactoring.introduceVariable.IntroduceVariableHandler; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,7 +29,7 @@ import org.jetbrains.annotations.Nullable; /** * @author Danila Ponomarenko */ -public class IntroduceVariableAction implements IntentionAction { +public class IntroduceVariableAction extends BaseRunRefactoringAction { @NotNull @Override @@ -39,30 +37,30 @@ public class IntroduceVariableAction implements IntentionAction { return CodeInsightBundle.message("intention.introduce.variable.text"); } - @NotNull - @Override - public String getFamilyName() { - return getText(); - } - @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { final PsiElement element = getElement(editor, file); if (element == null) { return false; } - final PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class, false); - if (statement == null || !(statement instanceof PsiExpressionStatement)) { + final PsiExpression expression = getExpression(element); + if (expression == null || !(expression.getParent() instanceof PsiExpressionStatement)) { return false; } - final PsiExpressionStatement expressionStatement = (PsiExpressionStatement)statement; - final PsiExpression expression = expressionStatement.getExpression(); - return expression.getType() != PsiType.VOID && !(expression instanceof PsiAssignmentExpression); } + @Nullable + private static PsiExpression getExpression(@NotNull PsiElement element) { + PsiExpression expression = PsiTreeUtil.getParentOfType(element, PsiExpression.class, false); + while (expression != null && expression instanceof PsiReferenceExpression) { + expression = PsiTreeUtil.getParentOfType(expression, PsiExpression.class, true); + } + return expression; + } + @Nullable protected static PsiElement getElement(Editor editor, @NotNull PsiFile file) { if (!file.getManager().isInProject(file)) return null; @@ -73,12 +71,6 @@ public class IntroduceVariableAction implements IntentionAction { @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - final RefactoringActionHandler refactoringActionHandler = JavaRefactoringActionHandlerFactory.getInstance().createIntroduceVariableHandler(); - refactoringActionHandler.invoke(project, editor, file, null); - } - - @Override - public boolean startInWriteAction() { - return true; + new IntroduceVariableHandler().invoke(project, editor, file, null); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RunRefactoringIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/RunRefactoringAction.java similarity index 59% rename from java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RunRefactoringIntention.java rename to java/java-impl/src/com/intellij/codeInsight/intention/impl/RunRefactoringAction.java index f053a18527b7..6462dbe404b9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RunRefactoringIntention.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/RunRefactoringAction.java @@ -13,31 +13,24 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.codeInsight.daemon.impl.quickfix; +package com.intellij.codeInsight.intention.impl; -import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.codeInsight.intention.LowPriorityAction; -import com.intellij.icons.AllIcons; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Iconable; import com.intellij.psi.PsiFile; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import javax.swing.*; - /** * User: anna * Date: 9/5/11 */ -public class RunRefactoringIntention implements IntentionAction, Iconable, LowPriorityAction { - public static final Icon REFACTORING_BULB = AllIcons.Actions.RefactoringBulb; +public class RunRefactoringAction extends BaseRunRefactoringAction { private final RefactoringActionHandler myHandler; private final String myCommandName; - public RunRefactoringIntention(RefactoringActionHandler handler, String commandName) { + public RunRefactoringAction(RefactoringActionHandler handler, String commandName) { myHandler = handler; myCommandName = commandName; } @@ -48,29 +41,13 @@ public class RunRefactoringIntention implements IntentionAction, Iconable, LowPr return myCommandName; } - @NotNull - @Override - public String getFamilyName() { - return "Refactorings"; - } - @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { return true; } @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + public final void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { myHandler.invoke(project, editor, file, null); } - - @Override - public boolean startInWriteAction() { - return false; - } - - @Override - public Icon getIcon(int flags) { - return REFACTORING_BULB; - } } diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java index 42704f238231..c0b79edc33cb 100644 --- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaMethodParameterUnwrapper.java @@ -32,7 +32,7 @@ public class JavaMethodParameterUnwrapper extends JavaUnwrapper { public String getDescription(PsiElement e) { String text = e.getText(); if (text.length() > 20) text = text.substring(0, 17) + "..."; - return CodeInsightBundle.message("unwrap.method.parameter", text); + return CodeInsightBundle.message("unwrap.with.placeholder", text); } public boolean isApplicableTo(PsiElement e) { diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaPolyadicExpressionUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaPolyadicExpressionUnwrapper.java new file mode 100644 index 000000000000..1fa629365025 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaPolyadicExpressionUnwrapper.java @@ -0,0 +1,79 @@ +/* + * 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.codeInsight.unwrap; + +import com.intellij.codeInsight.CodeInsightBundle; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiPolyadicExpression; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Danila Ponomarenko + */ +public class JavaPolyadicExpressionUnwrapper extends JavaUnwrapper { + public JavaPolyadicExpressionUnwrapper() { + super(""); + } + + @Override + public String getDescription(PsiElement e) { + return CodeInsightBundle.message("unwrap.with.placeholder", e.getText()); + } + + @Override + public boolean isApplicableTo(PsiElement e) { + if (!(e.getParent() instanceof PsiPolyadicExpression)) { + return false; + } + + final PsiPolyadicExpression expression = (PsiPolyadicExpression)e.getParent(); + + final PsiExpression operand = findOperand(e, expression); + + return operand != null; + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + final PsiPolyadicExpression parent = (PsiPolyadicExpression)element.getParent(); + + final PsiExpression operand = findOperand(element, parent); + + if (operand == null) { + return; + } + + context.extractElement(operand, parent); + context.delete(parent); + } + + @Nullable + private static PsiExpression findOperand(@NotNull PsiElement e, @NotNull PsiPolyadicExpression expression) { + final TextRange elementTextRange = e.getTextRange(); + + for (PsiExpression operand : expression.getOperands()) { + final TextRange operandTextRange = operand.getTextRange(); + if (operandTextRange != null && operandTextRange.contains(elementTextRange)) { + return operand; + } + } + return null; + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java index 7a5a48883908..ead2eff79ade 100644 --- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java +++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java @@ -32,7 +32,8 @@ public class JavaUnwrapDescriptor extends UnwrapDescriptorBase { new JavaCatchRemover(), new JavaSynchronizedUnwrapper(), new JavaAnonymousUnwrapper(), - new JavaConditionalUnwrapper() + new JavaConditionalUnwrapper(), + new JavaPolyadicExpressionUnwrapper() }; } } diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java b/java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java index 502055854d22..c5037ac91c3f 100644 --- a/java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java +++ b/java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java @@ -40,6 +40,18 @@ public class PsiDiamondTypeUtil { public static boolean canCollapseToDiamond(final PsiNewExpression expression, final PsiNewExpression context, final @Nullable PsiType expectedType) { + return canCollapseToDiamond(expression, context, expectedType, false); + } + + public static boolean canChangeContextForDiamond(final PsiNewExpression expression, final PsiType expectedType) { + final PsiNewExpression copy = (PsiNewExpression)expression.copy(); + return canCollapseToDiamond(copy, copy, expectedType, true); + } + + private static boolean canCollapseToDiamond(final PsiNewExpression expression, + final PsiNewExpression context, + final @Nullable PsiType expectedType, + boolean skipDiamonds) { if (PsiUtil.getLanguageLevel(context).isAtLeast(LanguageLevel.JDK_1_7)) { final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference(); if (classReference != null) { @@ -47,7 +59,7 @@ public class PsiDiamondTypeUtil { if (parameterList != null) { final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements(); if (typeElements.length > 0) { - if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) return false; + if (!skipDiamonds && typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) return false; final PsiDiamondTypeImpl.DiamondInferenceResult inferenceResult = PsiDiamondTypeImpl.resolveInferredTypes(expression, context); if (inferenceResult.getErrorMessage() == null) { final List types = inferenceResult.getInferredTypes(); diff --git a/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanProperty.java b/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanProperty.java index 1fd0d8e03a8d..3c5fd4d6e88e 100644 --- a/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanProperty.java +++ b/java/java-impl/src/com/intellij/psi/impl/beanProperties/BeanProperty.java @@ -28,6 +28,9 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; +/** + * Provide {@link com.intellij.refactoring.rename.BeanPropertyRenameHandler} if necessary. + */ @Presentation(icon = "AllIcons.Nodes.Property") public class BeanProperty { @@ -104,5 +107,4 @@ public class BeanProperty { public static BeanProperty createBeanProperty(@NotNull PsiMethod method) { return PropertyUtil.isSimplePropertyAccessor(method) ? new BeanProperty(method) : null; } - } diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java b/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java index b78e9cd0e11e..611992bd2914 100644 --- a/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java +++ b/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java @@ -1,3 +1,18 @@ +/* + * 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.psi.impl.light; import com.intellij.lang.Language; @@ -9,6 +24,7 @@ import org.jetbrains.annotations.NotNull; */ public class LightParameter extends LightVariableBuilder implements PsiParameter { public static final LightParameter[] EMPTY_ARRAY = new LightParameter[0]; + private final String myName; private final PsiElement myDeclarationScope; private final boolean myVarArgs; @@ -46,16 +62,9 @@ public class LightParameter extends LightVariableBuilder i return myVarArgs; } - @Override - @NotNull - public PsiAnnotation[] getAnnotations() { - return PsiAnnotation.EMPTY_ARRAY; - } - @Override @NotNull public String getName() { return myName; } - } diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java index 175b3a143b4a..5d86dc4ec0a0 100644 --- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -42,6 +42,11 @@ import java.util.Set; public class SmartTypePointerManagerImpl extends SmartTypePointerManager { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.SmartTypePointerManagerImpl"); + private static final SmartTypePointer NULL_POINTER = new SmartTypePointer() { + @Override + public PsiType getType() { return null; } + }; + private final SmartPointerManager myPsiPointerManager; private final Project myProject; @@ -53,7 +58,8 @@ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { @Override @NotNull public SmartTypePointer createSmartTypePointer(@NotNull PsiType type) { - return type.accept(new SmartTypeCreatingVisitor()); + final SmartTypePointer pointer = type.accept(new SmartTypeCreatingVisitor()); + return pointer != null ? pointer : NULL_POINTER; } private static class SimpleTypePointer implements SmartTypePointer { @@ -77,6 +83,7 @@ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { myComponentTypePointer = componentTypePointer; } + @Nullable @Override protected PsiArrayType calcType() { final PsiType type = myComponentTypePointer.getType(); @@ -164,6 +171,7 @@ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { return myType; } + @Nullable protected abstract T calcType(); } @@ -228,7 +236,8 @@ public class SmartTypePointerManagerImpl extends SmartTypePointerManager { @Override public SmartTypePointer visitArrayType(PsiArrayType arrayType) { - return new ArrayTypePointer(arrayType, arrayType.getComponentType().accept(this)); + final SmartTypePointer componentTypePointer = arrayType.getComponentType().accept(this); + return componentTypePointer != null ? new ArrayTypePointer(arrayType, componentTypePointer) : null; } @Override diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java index 55d19be86fc5..5047b0f7c4e2 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/JavaCodeStyleManagerImpl.java @@ -245,7 +245,7 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager { final PsiType _type = type; return new SuggestedNameInfo(namesArray) { @Override - public void nameChoosen(String name) { + public void nameChosen(String name) { if (_propertyName != null || _type != null && _type.isValid()) { JavaStatisticsManager.incVariableNameUseCount(name, kind, _propertyName, _type); } @@ -862,8 +862,8 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager { return new SuggestedNameInfo(ArrayUtil.toStringArray(uniqueNames)) { @Override - public void nameChoosen(String name) { - baseNameInfo.nameChoosen(name); + public void nameChosen(String name) { + baseNameInfo.nameChosen(name); } }; } diff --git a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java index f53f8523253b..5ae7c8613e07 100644 --- a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerHandler.java @@ -26,6 +26,7 @@ import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.impl.PsiDiamondTypeUtil; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiTreeUtil; @@ -184,8 +185,12 @@ public class AnonymousToInnerHandler implements RefactoringActionHandler { } } buf.append(")"); - PsiExpression newClassExpression = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory().createExpressionFromText(buf.toString(), null); - newExpr.replace(newClassExpression); + PsiNewExpression newClassExpression = + (PsiNewExpression)JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory().createExpressionFromText(buf.toString(), null); + newClassExpression = (PsiNewExpression)newExpr.replace(newClassExpression); + if (PsiDiamondTypeUtil.canCollapseToDiamond(newClassExpression, newClassExpression, newClassExpression.getType())) { + PsiDiamondTypeUtil.replaceExplicitWithDiamond(newClassExpression.getClassOrAnonymousClassReference().getParameterList()); + } } @Nullable @@ -240,7 +245,7 @@ public class AnonymousToInnerHandler implements RefactoringActionHandler { } private Boolean cachedNeedsThis = null; - private boolean needsThis() { + public boolean needsThis() { if(cachedNeedsThis == null) { ElementNeedsThis memberNeedsThis = new ElementNeedsThis(myTargetClass, myAnonClass); diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index 2d99c94337d0..a5ead200d950 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -741,8 +741,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters(); PsiSubstitutor substitutor = baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod); + final PsiClass aClass = changeInfo.getMethod().getContainingClass(); + final PsiClass callerContainingClass = caller.getContainingClass(); + final PsiSubstitutor psiSubstitutor = aClass != null && callerContainingClass != null && callerContainingClass.isInheritor(aClass, true) + ? TypeConversionUtil.getSuperClassSubstitutor(aClass, callerContainingClass, substitutor) + : PsiSubstitutor.EMPTY; for (JavaParameterInfo info : primaryNewParms) { - if (info.getOldIndex() < 0) newParameters.add(createNewParameter(changeInfo, info, substitutor)); + if (info.getOldIndex() < 0) newParameters.add(createNewParameter(changeInfo, info, psiSubstitutor, substitutor)); } PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]); boolean[] toRemoveParm = new boolean[arrayed.length]; @@ -802,10 +807,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } private static PsiParameter createNewParameter(JavaChangeInfo changeInfo, JavaParameterInfo newParm, - PsiSubstitutor substitutor) throws IncorrectOperationException { + PsiSubstitutor... substitutor) throws IncorrectOperationException { final PsiParameterList list = changeInfo.getMethod().getParameterList(); final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); - final PsiType type = substitutor.substitute(newParm.createType(list, list.getManager())); + PsiType type = newParm.createType(list, list.getManager()); + for (PsiSubstitutor psiSubstitutor : substitutor) { + type = psiSubstitutor.substitute(type); + } return factory.createParameter(newParm.getName(), type); } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java index 46ca81d384f7..80fd509f233e 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java @@ -116,7 +116,8 @@ class JavaChangeSignatureUsageSearcher { final int oldParameterIndex = parameterInfo.getOldIndex(); final String newName = parameterInfo.getName(); if (oldParameterIndex >= 0 ) { - if (isOriginal&& oldParameterIndex < parameters.length) { //Name changes take place only in primary method + if (isOriginal && oldParameterIndex < parameters.length && !newName.equals(myChangeInfo.getOldParameterNames()[oldParameterIndex])) { + //Name changes take place only in primary method when name was actually changed final PsiParameter parameter = parameters[oldParameterIndex]; if (!newName.equals(parameter.getName())) { JavaUnresolvableLocalCollisionDetector.visitLocalsCollisions( diff --git a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodDialog.java index df96bfd2a8c8..be2b088dd6b4 100644 --- a/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/convertToInstanceMethod/ConvertToInstanceMethodDialog.java @@ -23,12 +23,11 @@ import com.intellij.psi.PsiVariable; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.move.moveInstanceMethod.MoveInstanceMethodDialogBase; +import com.intellij.ui.DoubleClickListener; import com.intellij.util.ui.UIUtil; import javax.swing.*; -import javax.swing.border.LineBorder; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** @@ -66,16 +65,17 @@ public class ConvertToInstanceMethodDialog extends MoveInstanceMethodDialogBase @Override protected JList createTargetVariableChooser() { final JList variableChooser = super.createTargetVariableChooser(); - variableChooser.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() != 2) return; + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { Point point = e.getPoint(); int index = variableChooser.locationToIndex(point); - if (index == -1) return; - if (!variableChooser.getCellBounds(index, index).contains(point)) return; + if (index == -1) return false; + if (!variableChooser.getCellBounds(index, index).contains(point)) return false; doRefactorAction(); + return true; } - }); + }.installOn(variableChooser); return variableChooser; } } diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java index aae30f20540f..ff4bc6f5b392 100644 --- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java @@ -138,10 +138,14 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { private static void fillResultsMap(Map result, PsiFile containingFile, PsiClass[] topLevelClasses) { PsiClass[] classes = result.get(containingFile); - if (classes != null) { - topLevelClasses = ArrayUtil.mergeArrays(classes, topLevelClasses, PsiClass.ARRAY_FACTORY); + if (topLevelClasses != null) { + if (classes != null) { + topLevelClasses = ArrayUtil.mergeArrays(classes, topLevelClasses, PsiClass.ARRAY_FACTORY); + } + result.put(containingFile, topLevelClasses); + } else { + result.put(containingFile, classes); } - result.put(containingFile, topLevelClasses); } public void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) { diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java index e56b93ec3f5b..7aef0d8214f1 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodHandler.java @@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.ReadonlyStatusHandler; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; @@ -87,10 +88,14 @@ class InlineMethodHandler extends JavaInlineActionHandler { CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_CONSTRUCTOR); return; } - if (!isChainingConstructor(method)) { - String message = RefactoringBundle.message("refactoring.cannot.be.applied.to.inline.non.chaining.constructors", REFACTORING_NAME); - CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_CONSTRUCTOR); - return; + final boolean chainingConstructor = isChainingConstructor(method); + if (!chainingConstructor) { + if (!isThisReference(reference)) { + String message = RefactoringBundle.message("refactoring.cannot.be.applied.to.inline.non.chaining.constructors", REFACTORING_NAME); + CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_CONSTRUCTOR); + return; + } + allowInlineThisOnly = true; } if (reference != null) { final PsiElement refElement = reference.getElement(); @@ -148,4 +153,16 @@ class InlineMethodHandler extends JavaInlineActionHandler { return false; } + + public static boolean isThisReference(PsiReference reference) { + if (reference != null) { + final PsiElement referenceElement = reference.getElement(); + if (referenceElement instanceof PsiJavaCodeReferenceElement && + referenceElement.getParent() instanceof PsiMethodCallExpression && + "this".equals(((PsiJavaCodeReferenceElement)referenceElement).getReferenceName())) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java index 8dd9acaed0dc..a64a4cc75298 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java @@ -323,7 +323,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor { private void doRefactoring(UsageInfo[] usages) { try { if (myInlineThisOnly) { - if (myMethod.isConstructor()) { + if (myMethod.isConstructor() && InlineMethodHandler.isChainingConstructor(myMethod)) { PsiCall constructorCall = RefactoringUtil.getEnclosingConstructorCall(myReference); if (constructorCall != null) { inlineConstructorCall(constructorCall); diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassHandler.java index 3f5442e637e7..00501d5d6b49 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineToAnonymousClassHandler.java @@ -83,8 +83,13 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler { return inheritors.size() == 0; } - public boolean canInlineElementInEditor(PsiElement element) { - return canInlineElement(element); + @Override + public boolean canInlineElementInEditor(PsiElement element, Editor editor) { + if (canInlineElement(element)) { + PsiReference reference = editor != null ? TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset()) : null; + return !InlineMethodHandler.isThisReference(reference); + } + return false; } public void inlineElement(final Project project, final Editor editor, final PsiElement psiElement) { diff --git a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java index c98e6b8da9d4..453dc14687dd 100644 --- a/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java @@ -221,7 +221,7 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori super.performRefactoring(pushDownUsages); RefactoringUtil.sortDepthFirstRightLeftOrder(usages); for (UsageInfo usageInfo : usages) { - if (!(usageInfo instanceof ReplaceExtendsListUsageInfo)) { + if (!(usageInfo instanceof ReplaceExtendsListUsageInfo || usageInfo instanceof RemoveImportUsageInfo)) { try { ((FixableUsageInfo)usageInfo).fixUsage(); } @@ -234,8 +234,8 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori //postpone broken hierarchy for (UsageInfo usage : usages) { - if (usage instanceof ReplaceExtendsListUsageInfo) { - ((ReplaceExtendsListUsageInfo)usage).fixUsage(); + if (usage instanceof ReplaceExtendsListUsageInfo || usage instanceof RemoveImportUsageInfo) { + ((FixableUsageInfo)usage).fixUsage(); } } try { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java index 827540c785a4..3f16cfb1e0eb 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/JavaIntroduceParameterMethodUsagesProcessor.java @@ -94,7 +94,9 @@ public class JavaIntroduceParameterMethodUsagesProcessor implements IntroducePar ExpressionConverter.getExpression(data.getParameterInitializer().getExpression(), StdLanguages.JAVA, data.getProject()); assert initializer instanceof PsiExpression; if (initializer instanceof PsiNewExpression) { - initializer = PsiDiamondTypeUtil.expandTopLevelDiamondsInside((PsiNewExpression)initializer); + if (!PsiDiamondTypeUtil.canChangeContextForDiamond((PsiNewExpression)initializer, ((PsiNewExpression)initializer).getType())) { + initializer = PsiDiamondTypeUtil.expandTopLevelDiamondsInside((PsiNewExpression)initializer); + } } substituteTypeParametersInInitializer(initializer, callExpression, argList, methodToSearchFor); ChangeContextUtil.encodeContextInfo(initializer, true); diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java index aa7f8d617d00..71305101c8d1 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java @@ -33,8 +33,10 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; @@ -62,6 +64,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.Query; import com.intellij.util.VisibilityUtil; import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -148,7 +151,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{ final Set methodsToSearchDuplicates = new HashSet(); for (PsiMember psiMember : myMembersAfterMove) { if (psiMember instanceof PsiMethod && ((PsiMethod)psiMember).getBody() != null) { - methodsToSearchDuplicates.add((PsiMethod)psiMember); + methodsToSearchDuplicates.add(psiMember); } } @@ -289,7 +292,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{ PsiJavaCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ? RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass) : RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass); - if (ref != null) { + if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) { RefactoringUtil.replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final PsiReferenceList referenceList = myTargetSuperClass.isInterface() ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList(); diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java index c2e1399893ab..1d4afb77e665 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -288,7 +288,7 @@ public class MoveInnerDialog extends RefactoringDialog { JavaRefactoringSettings.getInstance().MOVE_INNER_PREVIEW_USAGES = isPreviewUsages(); if (myCbPassOuterClass.isSelected() && mySuggestedNameInfo != null) { - mySuggestedNameInfo.nameChoosen(getParameterName()); + mySuggestedNameInfo.nameChosen(getParameterName()); } final PsiElement target = getTargetContainer(); diff --git a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java index 0b6366742815..4c41a438cffc 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java @@ -44,12 +44,16 @@ public abstract class BeanPropertyRenameHandler implements RenameHandler { } public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { - final BeanProperty property = getProperty(dataContext); - new PropertyRenameDialog(property, editor).show(); + performInvoke(editor, dataContext); } public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { + performInvoke(null, dataContext); + } + private void performInvoke(@Nullable Editor editor, DataContext dataContext) { + final BeanProperty property = getProperty(dataContext); + new PropertyRenameDialog(property, editor).show(); } public static void doRename(@NotNull final BeanProperty property, final String newName, final boolean searchInComments) { @@ -89,6 +93,5 @@ public abstract class BeanPropertyRenameHandler implements RenameHandler { doRename(myProperty, newName, searchInComments); close(DialogWrapper.OK_EXIT_CODE); } - } } diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java index 9069c92bf963..d98870a493f6 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaClassProcessor.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; +import com.intellij.psi.impl.light.LightElement; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.SearchScope; @@ -134,10 +135,11 @@ public class RenameJavaClassProcessor extends RenamePsiElementProcessor { final PsiElement prototype = ((PsiMirrorElement)constructor).getPrototype(); if (prototype instanceof PsiNamedElement) { allRenames.put(prototype, newName); - continue; } } - allRenames.put(constructor, newName); + else if (!(constructor instanceof LightElement)) { + allRenames.put(constructor, newName); + } } } diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java index 7b12bc349967..67e643841567 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java @@ -200,8 +200,7 @@ public class TypeEvaluator { return elseType; case 3: - LOG.error("Condition type conflict."); - return null; + return expr.getType(); default: LOG.error("Must not happen."); diff --git a/java/java-impl/src/com/intellij/refactoring/ui/NameSuggestionsManager.java b/java/java-impl/src/com/intellij/refactoring/ui/NameSuggestionsManager.java index dd3673b0e1cf..95377dccfa91 100644 --- a/java/java-impl/src/com/intellij/refactoring/ui/NameSuggestionsManager.java +++ b/java/java-impl/src/com/intellij/refactoring/ui/NameSuggestionsManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -53,7 +53,7 @@ public class NameSuggestionsManager { SuggestedNameInfo nameInfo = myTypesToSuggestions.get(myTypeSelector.getSelectedType()); if (nameInfo != null) { - nameInfo.nameChoosen(myNameField.getEnteredName()); + nameInfo.nameChosen(myNameField.getEnteredName()); } } diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index 2eda3ad6425f..1da9d5095981 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -175,7 +175,11 @@ public class RefactoringUtil { public int compare(final UsageInfo usage1, final UsageInfo usage2) { final PsiElement element1 = usage1.getElement(); final PsiElement element2 = usage2.getElement(); - if (element1 == null || element2 == null) return 0; + if (element1 == null) { + if (element2 == null) return 0; + return 1; + } + if (element2 == null) return -1; return element2.getTextRange().getStartOffset() - element1.getTextRange().getStartOffset(); } }); @@ -1200,13 +1204,13 @@ public class RefactoringUtil { } @Nullable - public static PsiTypeParameterList createTypeParameterListWithUsedTypeParameters(final PsiTypeParameterList fromList, + public static PsiTypeParameterList createTypeParameterListWithUsedTypeParameters(@Nullable final PsiTypeParameterList fromList, @NotNull final PsiElement... elements) { return createTypeParameterListWithUsedTypeParameters(fromList, Condition.TRUE, elements); } @Nullable - public static PsiTypeParameterList createTypeParameterListWithUsedTypeParameters(final PsiTypeParameterList fromList, + public static PsiTypeParameterList createTypeParameterListWithUsedTypeParameters(@Nullable final PsiTypeParameterList fromList, Condition filter, @NotNull final PsiElement... elements) { if (elements.length == 0) return null; diff --git a/java/java-impl/src/com/intellij/refactoring/util/classMembers/ElementNeedsThis.java b/java/java-impl/src/com/intellij/refactoring/util/classMembers/ElementNeedsThis.java index 97a898a3cf0b..9531eccdace8 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/classMembers/ElementNeedsThis.java +++ b/java/java-impl/src/com/intellij/refactoring/util/classMembers/ElementNeedsThis.java @@ -41,9 +41,14 @@ public class ElementNeedsThis extends ClassThisReferencesVisitor { if (classMember == null || classMember.equals(myMember)) return; if (classMember.hasModifierProperty(PsiModifier.STATIC)) return; + if (ignoreUsedTypeParams() && classMember instanceof PsiTypeParameter) return; myResult = true; } + protected boolean ignoreUsedTypeParams() { + return myMember != null; + } + protected void visitExplicitThis(PsiClass referencedClass, PsiThisExpression reference) { myResult = true; } diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java index 3b38008516db..573a8c7dba60 100644 --- a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java +++ b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestDialog.java @@ -69,6 +69,7 @@ import java.util.List; public class CreateTestDialog extends DialogWrapper { private static final String RECENTS_KEY = "CreateTestDialog.RecentsKey"; + private static final String RECENT_SUPERS_KEY = "CreateTestDialog.Recents.Supers"; private static final String DEFAULT_LIBRARY_NAME_PROPERTY = CreateTestDialog.class.getName() + ".defaultLibrary"; private static final String SHOW_INHERITED_MEMBERS_PROPERTY = CreateTestDialog.class.getName() + ".includeInheritedMembers"; @@ -81,7 +82,7 @@ public class CreateTestDialog extends DialogWrapper { private final List myLibraryButtons = new ArrayList(); private EditorTextField myTargetClassNameField; - private ReferenceEditorWithBrowseButton mySuperClassField; + private ReferenceEditorComboWithBrowseButton mySuperClassField; private ReferenceEditorComboWithBrowseButton myTargetPackageField; private JCheckBox myGenerateBeforeBox; private JCheckBox myGenerateAfterBox; @@ -176,7 +177,8 @@ public class CreateTestDialog extends DialogWrapper { } }); - mySuperClassField = JavaReferenceEditorUtil.createReferenceEditorWithBrowseButton(new MyChooseSuperClassAction(), "", myProject, true); + mySuperClassField = new ReferenceEditorComboWithBrowseButton(new MyChooseSuperClassAction(), null, myProject, true, + JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE, RECENT_SUPERS_KEY); mySuperClassField.setMinimumSize(mySuperClassField.getPreferredSize()); String targetPackageName = targetPackage != null ? targetPackage.getQualifiedName() : ""; @@ -209,7 +211,7 @@ public class CreateTestDialog extends DialogWrapper { myFixLibraryPanel.setVisible(!descriptor.isLibraryAttached(myTargetModule)); String superClass = descriptor.getDefaultSuperClass(); - mySuperClassField.setText(superClass == null ? "" : superClass); + mySuperClassField.appendItem(superClass == null ? "" : superClass); mySelectedFramework = descriptor; } @@ -416,6 +418,7 @@ public class CreateTestDialog extends DialogWrapper { protected void doOKAction() { RecentsManager.getInstance(myProject).registerRecentEntry(RECENTS_KEY, myTargetPackageField.getText()); + RecentsManager.getInstance(myProject).registerRecentEntry(RECENT_SUPERS_KEY, mySuperClassField.getText()); String errorMessage; try { diff --git a/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java b/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java index 286e897e82ec..718a8c2fcdc7 100644 --- a/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java +++ b/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java @@ -19,6 +19,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComponentWithBrowseButton; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; @@ -42,7 +43,7 @@ public class ReferenceEditorComboWithBrowseButton extends ComponentWithBrowseBut @NotNull final Project project, boolean toAcceptClasses, final JavaCodeFragment.VisibilityChecker visibilityChecker, final String recentsKey) { - super(new EditorComboBox(createDocument(text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA), + super(new EditorComboBox(createDocument(StringUtil.isEmpty(text) ? "" : text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA), browseActionListener); final List recentEntries = RecentsManager.getInstance(project).getRecentEntries(recentsKey); if (recentEntries != null) { @@ -82,4 +83,8 @@ public class ReferenceEditorComboWithBrowseButton extends ComponentWithBrowseBut public void prependItem(String item) { getChildComponent().prependItem(item); } + + public void appendItem(String item) { + getChildComponent().appendItem(item); + } } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiLambdaExpression.java b/java/java-psi-api/src/com/intellij/psi/PsiLambdaExpression.java index 43633328c66d..471597a0a529 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiLambdaExpression.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiLambdaExpression.java @@ -22,14 +22,6 @@ import org.jetbrains.annotations.Nullable; * Represents a Java lambda expression. */ public interface PsiLambdaExpression extends PsiExpression { - /** - * Returns this lambda expression's type parameter list (if any). - * - * @return type parameter list or null. - */ - @Nullable - PsiTypeParameterList getTypeParameterList(); - /** * Returns this lambda expression's parameter list. * diff --git a/java/java-psi-api/src/com/intellij/psi/PsiParameter.java b/java/java-psi-api/src/com/intellij/psi/PsiParameter.java index 5ea7e84e2fca..025d37ff5b37 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiParameter.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiParameter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -51,13 +51,6 @@ public interface PsiParameter extends PsiVariable { */ boolean isVarArgs(); - /** - * @return the list of annotations. - * @use getModifierList().getAnnotations() - */ - @Deprecated - @NotNull PsiAnnotation[] getAnnotations(); - /** * {@inheritDoc} */ diff --git a/java/java-psi-api/src/com/intellij/psi/PsiType.java b/java/java-psi-api/src/com/intellij/psi/PsiType.java index 5ed21bd5fdd0..2c3af2dd9499 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiType.java @@ -174,6 +174,7 @@ public abstract class PsiType implements PsiAnnotationOwner { * @param visitor the visitor to accept the type. * @return the value returned by the visitor. */ + @Nullable public abstract A accept(@NotNull PsiTypeVisitor visitor); /** diff --git a/java/java-psi-api/src/com/intellij/psi/PsiTypeVisitor.java b/java/java-psi-api/src/com/intellij/psi/PsiTypeVisitor.java index bd2add5b490a..29b1bce17fb4 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiTypeVisitor.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiTypeVisitor.java @@ -15,44 +15,55 @@ */ package com.intellij.psi; +import org.jetbrains.annotations.Nullable; + /** * Visitor which can be used to visit Java types. * * @author dsl */ public class PsiTypeVisitor { + @Nullable public A visitType(PsiType type) { return null; } + @Nullable public A visitPrimitiveType(PsiPrimitiveType primitiveType) { return visitType(primitiveType); } + @Nullable public A visitArrayType(PsiArrayType arrayType) { return visitType(arrayType); } + @Nullable public A visitClassType(PsiClassType classType) { return visitType(classType); } + @Nullable public A visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) { return visitWildcardType(capturedWildcardType.getWildcard()); } + @Nullable public A visitWildcardType(PsiWildcardType wildcardType) { return visitType(wildcardType); } + @Nullable public A visitEllipsisType(PsiEllipsisType ellipsisType) { return visitArrayType(ellipsisType); } + @Nullable public A visitDisjunctionType(PsiDisjunctionType disjunctionType) { return visitType(disjunctionType); } - + + @Nullable public A visitDiamondType(PsiDiamondType diamondType) { return visitType(diamondType); } diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java index a0cc7a36a34c..ff2f21a5e07d 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java @@ -163,7 +163,7 @@ public class ExpressionParser { return parseBinary(builder, ExprType.UNARY, MULTIPLICATIVE_OPS); case UNARY: - return parseUnary(builder, false); + return parseUnary(builder); case TYPE: return myParser.getReferenceParser().parseType(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD); @@ -246,14 +246,14 @@ public class ExpressionParser { } @Nullable - private PsiBuilder.Marker parseUnary(final PsiBuilder builder, final boolean afterCast) { + private PsiBuilder.Marker parseUnary(final PsiBuilder builder) { final IElementType tokenType = builder.getTokenType(); if (PREFIX_OPS.contains(tokenType)) { final PsiBuilder.Marker unary = builder.mark(); builder.advanceLexer(); - final PsiBuilder.Marker operand = parseUnary(builder, false); + final PsiBuilder.Marker operand = parseUnary(builder); if (operand == null) { error(builder, JavaErrorMessages.message("expected.expression")); } @@ -269,19 +269,19 @@ public class ExpressionParser { myParser.getReferenceParser().parseTypeInfo(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD); if (typeInfo == null || !expect(builder, JavaTokenType.RPARENTH)) { typeCast.rollbackTo(); - return parsePostfix(builder, false); + return parsePostfix(builder); } if (PREF_ARITHMETIC_OPS.contains(builder.getTokenType()) && !typeInfo.isPrimitive) { typeCast.rollbackTo(); - return parsePostfix(builder, false); + return parsePostfix(builder); } - final PsiBuilder.Marker expr = parseUnary(builder, true); + final PsiBuilder.Marker expr = parseUnary(builder); if (expr == null) { if (!typeInfo.isParameterized) { // cannot parse correct parenthesized expression after correct parameterized type typeCast.rollbackTo(); - return parsePostfix(builder, false); + return parsePostfix(builder); } else { error(builder, JavaErrorMessages.message("expected.expression")); @@ -292,13 +292,13 @@ public class ExpressionParser { return typeCast; } else { - return parsePostfix(builder, afterCast); + return parsePostfix(builder); } } @Nullable - private PsiBuilder.Marker parsePostfix(final PsiBuilder builder, final boolean afterCast) { - PsiBuilder.Marker operand = parsePrimary(builder, null, -1, afterCast); + private PsiBuilder.Marker parsePostfix(final PsiBuilder builder) { + PsiBuilder.Marker operand = parsePrimary(builder, null, -1); if (operand == null) return null; while (POSTFIX_OPS.contains(builder.getTokenType())) { @@ -315,13 +315,10 @@ public class ExpressionParser { // todo[r.sh] make 'this', 'super' and 'class' reference expressions @Nullable - private PsiBuilder.Marker parsePrimary(final PsiBuilder builder, - @Nullable final BreakPoint breakPoint, - final int breakOffset, - final boolean afterCast) { + private PsiBuilder.Marker parsePrimary(final PsiBuilder builder, @Nullable final BreakPoint breakPoint, final int breakOffset) { PsiBuilder.Marker startMarker = builder.mark(); - PsiBuilder.Marker expr = parsePrimaryExpressionStart(builder, afterCast); + PsiBuilder.Marker expr = parsePrimaryExpressionStart(builder); if (expr == null) { startMarker.drop(); return null; @@ -349,7 +346,7 @@ public class ExpressionParser { final PsiBuilder.Marker classObjAccess = parseClassAccessOrMethodReference(builder); if (classObjAccess == null || builder.getCurrentOffset() < offset) { copy.rollbackTo(); - return parsePrimary(builder, BreakPoint.P1, offset, false); + return parsePrimary(builder, BreakPoint.P1, offset); } startMarker = copy; @@ -373,13 +370,13 @@ public class ExpressionParser { final PsiBuilder.Marker ref = myParser.getReferenceParser().parseJavaCodeReference(builder, false, true, false, false, false); if (ref == null || builder.getTokenType() != JavaTokenType.DOT || builder.getCurrentOffset() != dotOffset) { copy.rollbackTo(); - return parsePrimary(builder, BreakPoint.P2, offset, false); + return parsePrimary(builder, BreakPoint.P2, offset); } builder.advanceLexer(); if (builder.getTokenType() != dotTokenType) { copy.rollbackTo(); - return parsePrimary(builder, BreakPoint.P2, offset, false); + return parsePrimary(builder, BreakPoint.P2, offset); } builder.advanceLexer(); @@ -420,7 +417,7 @@ public class ExpressionParser { final PsiBuilder.Marker copy = startMarker.precede(); startMarker.rollbackTo(); - final PsiBuilder.Marker qualifier = parsePrimaryExpressionStart(builder, false); + final PsiBuilder.Marker qualifier = parsePrimaryExpressionStart(builder); if (qualifier != null) { final PsiBuilder.Marker refExpr = qualifier.precede(); if (builder.getTokenType() == JavaTokenType.DOT) { @@ -436,7 +433,7 @@ public class ExpressionParser { } copy.rollbackTo(); - return parsePrimary(builder, BreakPoint.P3, -1, false); + return parsePrimary(builder, BreakPoint.P3, -1); } else { startMarker.drop(); @@ -465,7 +462,7 @@ public class ExpressionParser { final PsiBuilder.Marker classObjAccess = parseClassAccessOrMethodReference(builder); if (classObjAccess == null || builder.getCurrentOffset() <= pos) { copy.rollbackTo(); - return parsePrimary(builder, BreakPoint.P4, -1, false); + return parsePrimary(builder, BreakPoint.P4, -1); } startMarker = copy; @@ -505,7 +502,7 @@ public class ExpressionParser { } @Nullable - private PsiBuilder.Marker parsePrimaryExpressionStart(final PsiBuilder builder, final boolean afterCast) { + private PsiBuilder.Marker parsePrimaryExpressionStart(final PsiBuilder builder) { IElementType tokenType = builder.getTokenType(); if (LITERALS.contains(tokenType)) { @@ -597,29 +594,6 @@ public class ExpressionParser { if (tokenType == JavaTokenType.LT) { expr = builder.mark(); - if (!afterCast) { - final PsiBuilder.Marker typeParams = myParser.getReferenceParser().parseTypeParameters(builder, true); - - if (typeParams != null) { - tokenType = builder.getTokenType(); - - PsiBuilder.Marker lambda = null; - if (tokenType == JavaTokenType.LPARENTH) { - lambda = parseLambdaAfterParenth(builder, typeParams); - } - else if (tokenType == JavaTokenType.IDENTIFIER && builder.lookAhead(1) == JavaTokenType.ARROW) { - lambda = parseLambdaExpression(builder, false, typeParams); - } - if (lambda != null) { - expr.drop(); - return lambda; - } - - expr.rollbackTo(); - expr = builder.mark(); - } - } - if (!myParser.getReferenceParser().parseReferenceParameterList(builder, false, false)) { expr.rollbackTo(); return null; diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java index 1eca52592faa..0555b567fcaa 100644 --- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java +++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java @@ -297,13 +297,6 @@ public class ReferenceParser { @NotNull public PsiBuilder.Marker parseTypeParameters(final PsiBuilder builder) { - final PsiBuilder.Marker marker = parseTypeParameters(builder, false); - assert marker != null; - return marker; - } - - @Nullable - public PsiBuilder.Marker parseTypeParameters(final PsiBuilder builder, final boolean stopOnErrors) { final PsiBuilder.Marker list = builder.mark(); if (!expect(builder, JavaTokenType.LT)) { list.done(JavaElementType.TYPE_PARAMETER_LIST); @@ -313,10 +306,6 @@ public class ReferenceParser { while (true) { final PsiBuilder.Marker param = parseTypeParameter(builder); if (param == null) { - if (stopOnErrors) { - list.rollbackTo(); - return null; - } error(builder, JavaErrorMessages.message("expected.type.parameter")); } if (!expect(builder, JavaTokenType.COMMA)) { @@ -325,11 +314,6 @@ public class ReferenceParser { } if (!expect(builder, JavaTokenType.GT)) { - if (stopOnErrors) { - list.rollbackTo(); - return null; - } - // hack for completion if (builder.getTokenType() == JavaTokenType.IDENTIFIER) { if (builder.lookAhead(1) == JavaTokenType.GT) { diff --git a/java/java-psi-impl/src/com/intellij/psi/Bottom.java b/java/java-psi-impl/src/com/intellij/psi/Bottom.java index 4b640f1b3b92..942d7792d80e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/Bottom.java +++ b/java/java-psi-impl/src/com/intellij/psi/Bottom.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -66,7 +66,9 @@ public class Bottom extends PsiType { if (visitor instanceof PsiTypeVisitorEx) { return ((PsiTypeVisitorEx)visitor).visitBottom(this); } - return visitor.visitType(this); + else { + return visitor.visitType(this); + } } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/PsiTypeVariable.java b/java/java-psi-impl/src/com/intellij/psi/PsiTypeVariable.java index 8625b26292a0..872c8ded71ea 100644 --- a/java/java-psi-impl/src/com/intellij/psi/PsiTypeVariable.java +++ b/java/java-psi-impl/src/com/intellij/psi/PsiTypeVariable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -33,7 +33,8 @@ public abstract class PsiTypeVariable extends PsiType { if (visitor instanceof PsiTypeVisitorEx) { return ((PsiTypeVisitorEx)visitor).visitTypeVariable(this); } - - return visitor.visitType(this); + else { + return visitor.visitType(this); + } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/PsiTypeVisitorEx.java b/java/java-psi-impl/src/com/intellij/psi/PsiTypeVisitorEx.java index eb31de2bcbc8..47eac032290e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/PsiTypeVisitorEx.java +++ b/java/java-psi-impl/src/com/intellij/psi/PsiTypeVisitorEx.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -15,14 +15,18 @@ */ package com.intellij.psi; +import org.jetbrains.annotations.Nullable; + /** * @author ven */ public class PsiTypeVisitorEx extends PsiTypeVisitor { + @Nullable public A visitTypeVariable(PsiTypeVariable var) { return visitType(var); } + @Nullable public A visitBottom (Bottom bottom) { return visitType(bottom); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java index 102087ed75c0..0187be53a9fa 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java @@ -187,7 +187,7 @@ public class PsiImplUtil { final boolean fromBody = lastParent instanceof PsiCodeBlock; final PsiTypeParameterList typeParameterList = method.getTypeParameterList(); final PsiParameterList parameterList = method.getParameterList(); - return processDeclarationsInMethodLike(method, processor, state, fromBody, place, typeParameterList, parameterList); + return processDeclarationsInMethodLike(method, processor, state, place, fromBody, typeParameterList, parameterList); } public static boolean processDeclarationsInLambda(@NotNull final PsiLambdaExpression lambda, @@ -196,23 +196,24 @@ public class PsiImplUtil { final PsiElement lastParent, @NotNull final PsiElement place) { final boolean fromBody = lastParent != null && lastParent == lambda.getBody(); - final PsiTypeParameterList typeParameterList = lambda.getTypeParameterList(); final PsiParameterList parameterList = lambda.getParameterList(); - return processDeclarationsInMethodLike(lambda, processor, state, fromBody, place, typeParameterList, parameterList); + return processDeclarationsInMethodLike(lambda, processor, state, place, fromBody, null, parameterList); } private static boolean processDeclarationsInMethodLike(@NotNull final PsiElement element, @NotNull final PsiScopeProcessor processor, @NotNull final ResolveState state, - final boolean fromBody, @NotNull final PsiElement place, + final boolean fromBody, @Nullable final PsiTypeParameterList typeParameterList, @NotNull final PsiParameterList parameterList) { processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, element); - final ElementClassHint hint = processor.getHint(ElementClassHint.KEY); - if (hint == null || hint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { - if (typeParameterList != null && !typeParameterList.processDeclarations(processor, state, null, place)) return false; + if (typeParameterList != null) { + final ElementClassHint hint = processor.getHint(ElementClassHint.KEY); + if (hint == null || hint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) { + if (!typeParameterList.processDeclarations(processor, state, null, place)) return false; + } } if (fromBody) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java index 99107f54c2cd..e510a8dfeecc 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java @@ -17,7 +17,10 @@ package com.intellij.psi.impl; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.lang.PsiBuilder; -import com.intellij.lang.java.parser.*; +import com.intellij.lang.java.parser.DeclarationParser; +import com.intellij.lang.java.parser.JavaParser; +import com.intellij.lang.java.parser.JavaParserUtil; +import com.intellij.lang.java.parser.ReferenceParser; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.util.text.StringUtil; @@ -46,6 +49,8 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { protected final PsiManager myManager; private PsiJavaFile myDummyJavaFile; + private static final String DUMMY_FILE_NAME = "_Dummy_." + JavaFileType.INSTANCE.getDefaultExtension(); + public PsiJavaParserFacadeImpl(PsiManager manager) { myManager = manager; } @@ -323,9 +328,8 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { } protected PsiJavaFile createDummyJavaFile(final String text) { - final String fileName = "_Dummy_." + JavaFileType.INSTANCE.getDefaultExtension(); final FileType type = JavaFileType.INSTANCE; - return (PsiJavaFile)PsiFileFactory.getInstance(myManager.getProject()).createFileFromText(type, fileName, text, 0, text.length()); + return (PsiJavaFile)PsiFileFactory.getInstance(myManager.getProject()).createFileFromText(DUMMY_FILE_NAME, type, text); } @NotNull diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java index 593fd3ac4180..6e2856937e46 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -253,12 +253,6 @@ public class ClsParameterImpl extends ClsRepositoryPsiElement return method.isVarArgs() && getIndex() == paramList.getParametersCount() - 1; } - @Override - @NotNull - public PsiAnnotation[] getAnnotations() { - return getModifierList().getAnnotations(); - } - @Override protected boolean isVisibilitySupported() { return true; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java index 0a569cf4a33e..fd0b61ab31c1 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java @@ -251,12 +251,6 @@ public class PsiParameterImpl extends JavaStubPsiElement imple return typeElement != null && SourceTreeToPsiMap.psiToTreeNotNull(typeElement).findChildByType(JavaTokenType.ELLIPSIS) != null; } - @Override - @NotNull - public PsiAnnotation[] getAnnotations() { - return getModifierList().getAnnotations(); - } - @Override public ItemPresentation getPresentation() { return ItemPresentationProviders.getItemPresentation(this); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java index 3d80882b8d53..8ca6fce91d88 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiLambdaExpressionImpl.java @@ -27,12 +27,6 @@ public class PsiLambdaExpressionImpl extends ExpressionPsiElement implements Psi super(JavaElementType.LAMBDA_EXPRESSION); } - @Override - public PsiTypeParameterList getTypeParameterList() { - final PsiElement element = getFirstChild(); - return element instanceof PsiTypeParameterList ? (PsiTypeParameterList)element : null; - } - @NotNull @Override public PsiParameterList getParameterList() { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java index e7a5e3d51d99..e87c5db28998 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting/InnerClassesShadowing.java @@ -1,16 +1,98 @@ +import java.io.*; + +public class Main { + static interface A + { + interface B { } + } + + static class D implements A + { + private interface B { } + } + + + static class C extends D implements A + { + interface E extends B { } + interface E1 extends D.B { } + interface E2 extends A.B { } + } + +} + + + +class Main1 { + static interface A + { + interface B { } + } + + static class D implements A + { + interface B { } + } + + + static class C extends D implements A + { + interface E extends B { } + interface E1 extends D.B { + } + interface E2 extends A.B { } + } + +} + + interface A { + interface B { } interface B1 { } } class D implements A { + private interface B { } interface B1 { } } class C extends D implements A { + interface E extends B { } + interface E1 extends D.B { } + interface E2 extends A.B { } + interface F extends B1 { } + interface F1 extends D.B1 { } + interface F2 extends A.B1 { } + } + +class AO {} +class BAO { + AO bar = new AO(); + { + bar.foo(); + } + private class AO { + void foo(){} + } + +} + +class WithFileInputStream { + private static final Runnable runn = new Runnable() { + public void run() { + new FileInputStream("path"); + } + }; + + private static class FileInputStream { + private FileInputStream(String str) { + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/LambdaExpressions.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/LambdaExpressions.java index 14ce1ba5cffd..9a979bf22893 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/LambdaExpressions.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/LambdaExpressions.java @@ -26,15 +26,14 @@ class C { int parse(String s); } - interface ListProducer { - List produce(); - } - void test() { Simplest simplest = () -> { }; use(() -> { }); IntParser intParser = (String s) -> Integer.parseInt(s); - ListProducer listProducer = () -> new ArrayList(); + } + + Runnable foo() { + return () -> { System.out.println("foo"); }; } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforeFinal.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforeFinal.java new file mode 100644 index 000000000000..e082b01cf8fb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforeFinal.java @@ -0,0 +1,13 @@ +// "Encapsulate field" "false" + +class A { + public final boolean m_bool; +} + +public class B { + void method() { + A a = new A(); + + a.m_bool = true; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforePrivate.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforePrivate.java new file mode 100644 index 000000000000..061d152e95e6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforePrivate.java @@ -0,0 +1,13 @@ +// "Encapsulate field" "false" + +class A { + private boolean m_bool; +} + +public class B { + void method() { + A a = new A(); + + a.m_bool = true; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforeThisClass.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforeThisClass.java new file mode 100644 index 000000000000..4721b752ed5e --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforeThisClass.java @@ -0,0 +1,9 @@ +// "Encapsulate field" "false" + +class A { + public final boolean m_bool; + + void method() { + m_bool = true; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforeThisClassQualified.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforeThisClassQualified.java new file mode 100644 index 000000000000..a4aa102c4a85 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField/beforeThisClassQualified.java @@ -0,0 +1,9 @@ +// "Encapsulate field" "false" + +class A { + public final boolean m_bool; + + void method() { + this.m_bool = true; + } +} diff --git a/java/java-tests/testData/psi/parser-partial/expressions/LambdaExpression12.txt b/java/java-tests/testData/psi/parser-partial/expressions/LambdaExpression12.txt index ca651c993104..576a40ebec84 100644 --- a/java/java-tests/testData/psi/parser-partial/expressions/LambdaExpression12.txt +++ b/java/java-tests/testData/psi/parser-partial/expressions/LambdaExpression12.txt @@ -1,33 +1,18 @@ PsiJavaFile:LambdaExpression12.java - PsiLambdaExpression:() -> new C() - PsiTypeParameterList - PsiJavaToken:LT('<') - PsiTypeParameter:T - PsiIdentifier:T('T') - PsiElement(EXTENDS_BOUND_LIST) - - PsiJavaToken:GT('>') - PsiParameterList:() - PsiJavaToken:LPARENTH('(') - PsiJavaToken:RPARENTH(')') + PsiErrorElement:Unparsed tokens + PsiJavaToken:LT('<') + PsiIdentifier:T('T') + PsiJavaToken:GT('>') + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') PsiWhiteSpace(' ') PsiJavaToken:ARROW('->') PsiWhiteSpace(' ') - PsiNewExpression:new C() - PsiKeyword:new('new') - PsiReferenceParameterList - - PsiWhiteSpace(' ') - PsiJavaCodeReferenceElement:C - PsiIdentifier:C('C') - PsiReferenceParameterList - PsiJavaToken:LT('<') - PsiTypeElement:T - PsiJavaCodeReferenceElement:T - PsiIdentifier:T('T') - PsiReferenceParameterList - - PsiJavaToken:GT('>') - PsiExpressionList - PsiJavaToken:LPARENTH('(') - PsiJavaToken:RPARENTH(')') \ No newline at end of file + PsiKeyword:new('new') + PsiWhiteSpace(' ') + PsiIdentifier:C('C') + PsiJavaToken:LT('<') + PsiIdentifier:T('T') + PsiJavaToken:GT('>') + PsiJavaToken:LPARENTH('(') + PsiJavaToken:RPARENTH(')') \ No newline at end of file diff --git a/java/java-tests/testData/psi/parser-partial/expressions/LambdaExpression13.txt b/java/java-tests/testData/psi/parser-partial/expressions/LambdaExpression13.txt index 2d0cfcd4ed32..2b6c6786cfbb 100644 --- a/java/java-tests/testData/psi/parser-partial/expressions/LambdaExpression13.txt +++ b/java/java-tests/testData/psi/parser-partial/expressions/LambdaExpression13.txt @@ -1,21 +1,10 @@ PsiJavaFile:LambdaExpression13.java - PsiLambdaExpression:t -> t - PsiTypeParameterList - PsiJavaToken:LT('<') - PsiTypeParameter:T - PsiIdentifier:T('T') - PsiElement(EXTENDS_BOUND_LIST) - - PsiJavaToken:GT('>') - PsiParameterList:t - PsiParameter:t - PsiModifierList: - - PsiIdentifier:t('t') + PsiErrorElement:Unparsed tokens + PsiJavaToken:LT('<') + PsiIdentifier:T('T') + PsiJavaToken:GT('>') + PsiIdentifier:t('t') PsiWhiteSpace(' ') PsiJavaToken:ARROW('->') PsiWhiteSpace(' ') - PsiReferenceExpression:t - PsiReferenceParameterList - - PsiIdentifier:t('t') \ No newline at end of file + PsiIdentifier:t('t') \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/anonymousToInner/canBeStatic.java b/java/java-tests/testData/refactoring/anonymousToInner/canBeStatic.java new file mode 100644 index 000000000000..dd7ca4915b75 --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/canBeStatic.java @@ -0,0 +1,14 @@ +public class Foo { + public void foo() { + Predicate predicate = new Predicate() { + @Override + public boolean test(T t) { + return false; + } + }; + } + + private interface Predicate { + boolean test(K t); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/anonymousToInner/canBeStatic_after.java b/java/java-tests/testData/refactoring/anonymousToInner/canBeStatic_after.java new file mode 100644 index 000000000000..4bcfab1cb5bd --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/canBeStatic_after.java @@ -0,0 +1,16 @@ +public class Foo { + public void foo() { + Predicate predicate = new MyPredicate<>(); + } + + private interface Predicate { + boolean test(K t); + } + + private static class MyPredicate implements Predicate { + @Override + public boolean test(T t) { + return false; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/anonymousToInner/collapseDiamonds.java b/java/java-tests/testData/refactoring/anonymousToInner/collapseDiamonds.java new file mode 100644 index 000000000000..dd7ca4915b75 --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/collapseDiamonds.java @@ -0,0 +1,14 @@ +public class Foo { + public void foo() { + Predicate predicate = new Predicate() { + @Override + public boolean test(T t) { + return false; + } + }; + } + + private interface Predicate { + boolean test(K t); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/anonymousToInner/collapseDiamonds_after.java b/java/java-tests/testData/refactoring/anonymousToInner/collapseDiamonds_after.java new file mode 100644 index 000000000000..4bcfab1cb5bd --- /dev/null +++ b/java/java-tests/testData/refactoring/anonymousToInner/collapseDiamonds_after.java @@ -0,0 +1,16 @@ +public class Foo { + public void foo() { + Predicate predicate = new MyPredicate<>(); + } + + private interface Predicate { + boolean test(K t); + } + + private static class MyPredicate implements Predicate { + @Override + public boolean test(T t) { + return false; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/anonymousToInner/genericTypeParameters_after.java b/java/java-tests/testData/refactoring/anonymousToInner/genericTypeParameters_after.java index aa7fe1d30f5d..9ee35687cb2a 100644 --- a/java/java-tests/testData/refactoring/anonymousToInner/genericTypeParameters_after.java +++ b/java/java-tests/testData/refactoring/anonymousToInner/genericTypeParameters_after.java @@ -2,7 +2,7 @@ import java.util.*; class A { public Iterator> iterator(long revision) { - return new MyIterator(); + return new MyIterator<>(); } private static class MyIterator implements Iterator> { diff --git a/java/java-tests/testData/refactoring/changeSignature/ParamNameNoConflict.java b/java/java-tests/testData/refactoring/changeSignature/ParamNameNoConflict.java new file mode 100644 index 000000000000..a98e37640762 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/ParamNameNoConflict.java @@ -0,0 +1,11 @@ +class D { + void foo(Object o){} +} + +class DImpl extends D { + void foo(Object o1) { + super.foo(o1); + int o = 0; + System.out.println(o); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/changeSignature/ParamNameNoConflict_after.java b/java/java-tests/testData/refactoring/changeSignature/ParamNameNoConflict_after.java new file mode 100644 index 000000000000..6b29466ed297 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/ParamNameNoConflict_after.java @@ -0,0 +1,11 @@ +class D { + void foo(Object o, boolean b){} +} + +class DImpl extends D { + void foo(Object o1, boolean b) { + super.foo(o1, b); + int o = 0; + System.out.println(o); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java b/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java new file mode 100644 index 000000000000..374f3cccbad1 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java @@ -0,0 +1,10 @@ +class Base { + void m() { + } +} + +class A extends Base { + void x() { + m(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java.after b/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java.after new file mode 100644 index 000000000000..070698a3d8c6 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignaturePropagation/ParamTypeSubst.java.after @@ -0,0 +1,10 @@ +class Base { + void m(T clazz) { + } +} + +class A extends Base { + void x(String clazz) { + m(clazz); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor.java b/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor.java new file mode 100644 index 000000000000..a64d2759ef10 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor.java @@ -0,0 +1,21 @@ +public class InlineThis { + public InlineThis() { + System.out.println("code block here"); + } + + public InlineThis(int i) { + this(); + } + + public InlineThis(String str) { + this(Integer.parseInt(str)); + } + + + + + public static void main(String[] args) { + InlineThis aInlineThis = new InlineThis(); + InlineThis aInlineThis1 = new InlineThis(1); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor.java.after b/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor.java.after new file mode 100644 index 000000000000..104f8b3722a1 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor.java.after @@ -0,0 +1,21 @@ +public class InlineThis { + public InlineThis() { + System.out.println("code block here"); + } + + public InlineThis(int i) { + System.out.println("code block here"); + } + + public InlineThis(String str) { + this(Integer.parseInt(str)); + } + + + + + public static void main(String[] args) { + InlineThis aInlineThis = new InlineThis(); + InlineThis aInlineThis1 = new InlineThis(1); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor1.java b/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor1.java new file mode 100644 index 000000000000..a99133cd1594 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor1.java @@ -0,0 +1,21 @@ +public class InlineThis { + public InlineThis() { + System.out.println("code block here"); + } + + public InlineThis(int i) { + this(); + } + + public InlineThis(String str) { + this(Integer.parseInt(str)); + } + + + + + public static void main(String[] args) { + InlineThis aInlineThis = new InlineThis(); + InlineThis aInlineThis1 = new InlineThis(1); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor1.java.after b/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor1.java.after new file mode 100644 index 000000000000..5143141fd436 --- /dev/null +++ b/java/java-tests/testData/refactoring/inlineMethod/ChainedConstructor1.java.after @@ -0,0 +1,17 @@ +public class InlineThis { + public InlineThis() { + System.out.println("code block here"); + } + + public InlineThis(String str) { + this(); + } + + + + + public static void main(String[] args) { + InlineThis aInlineThis = new InlineThis(); + InlineThis aInlineThis1 = new InlineThis(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceParameter/afterPreserveDiamondOccurrences.java b/java/java-tests/testData/refactoring/introduceParameter/afterPreserveDiamondOccurrences.java new file mode 100644 index 000000000000..4f62137d7950 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceParameter/afterPreserveDiamondOccurrences.java @@ -0,0 +1,22 @@ + +public class TestCompletion { + + public static ParallelPipeline test(T base, V newStage, T upstream, final ParallelPipeline anObject) { + if (base != null){ + return anObject; + } + else { + return new ParallelPipeline<>(upstream, newStage); + } + + } + + + void f() { + test(null, null, null, new ParallelPipeline<>(null, null)); + } + private static class ParallelPipeline { + public ParallelPipeline(T p0, V p1) { + } + } +} diff --git a/java/java-tests/testData/refactoring/introduceParameter/beforePreserveDiamondOccurrences.java b/java/java-tests/testData/refactoring/introduceParameter/beforePreserveDiamondOccurrences.java new file mode 100644 index 000000000000..2bf9a854544d --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceParameter/beforePreserveDiamondOccurrences.java @@ -0,0 +1,22 @@ + +public class TestCompletion { + + public static ParallelPipeline test(T base, V newStage, T upstream) { + if (base != null){ + return new ParallelPipeline<>(base, newStage); + } + else { + return new ParallelPipeline<>(upstream, newStage); + } + + } + + + void f() { + test(null, null, null); + } + private static class ParallelPipeline { + public ParallelPipeline(T p0, V p1) { + } + } +} diff --git a/java/java-tests/testData/refactoring/pullUp/MergeInterfaces.java b/java/java-tests/testData/refactoring/pullUp/MergeInterfaces.java new file mode 100644 index 000000000000..68f3d11cf803 --- /dev/null +++ b/java/java-tests/testData/refactoring/pullUp/MergeInterfaces.java @@ -0,0 +1,3 @@ +class Base implements I {} +class Test extends Base implements I {} +interface I{} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/pullUp/MergeInterfaces_after.java b/java/java-tests/testData/refactoring/pullUp/MergeInterfaces_after.java new file mode 100644 index 000000000000..dfad6f6eb34f --- /dev/null +++ b/java/java-tests/testData/refactoring/pullUp/MergeInterfaces_after.java @@ -0,0 +1,3 @@ +class Base implements I {} +class Test extends Base {} +interface I{} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy index a362c06bff2f..178087bf8e8d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/folding/JavaFoldingTest.groovy @@ -283,6 +283,22 @@ class Test { assert !foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable")) } + public void "test no closure folding for synchronized methods"() { + def text = """\ +class Test { + void test() { new Runnable() { + public synchronized void run() { + System.out.println(); + } + }; + } +} +""" + configure text + def foldingModel = myFixture.editor.foldingModel as FoldingModelImpl + assert !foldingModel.getCollapsedRegionAtOffset(text.indexOf("Runnable")) + } + public void testFindInFolding() { def text = """\ class Test { diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/intention/EncapsulateFieldTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/intention/EncapsulateFieldTest.java new file mode 100644 index 000000000000..165073beedbd --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/intention/EncapsulateFieldTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.intention; + +import com.intellij.codeInsight.daemon.LightIntentionActionTestCase; + +/** + * @author Danila Ponomarenko + */ +public class EncapsulateFieldTest extends LightIntentionActionTestCase { + + public void test() throws Exception { doAllTests(); } + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/encapsulateField"; + } +} diff --git a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java index f54cc3443386..8f5726aba7f3 100644 --- a/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java +++ b/java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java @@ -134,8 +134,8 @@ public class ExpressionParserTest extends JavaParsingTestCase { public void testLambdaExpression9() { doParserTest("(I)p -> null"); } public void testLambdaExpression10() { doParserTest("(I)(p -> null)"); } public void testLambdaExpression11() { doParserTest("() -> { }"); } - public void testLambdaExpression12() { doParserTest("() -> new C()"); } - public void testLambdaExpression13() { doParserTest("t -> t"); } + public void testLambdaExpression12() { doParserTest("() -> new C()"); } // these two expressions + public void testLambdaExpression13() { doParserTest("t -> t"); } // should no longer be parsed public void testLambdaExpression14() { doParserTest("(String t) -> t"); } public void testLambdaExpression15() { doParserTest("(int a, int b) -> a + b"); } public void testLambdaExpression16() { doParserTest("(final int x) -> x"); } diff --git a/java/java-tests/testSrc/com/intellij/psi/PsiModificationTrackerTest.java b/java/java-tests/testSrc/com/intellij/psi/PsiModificationTrackerTest.java index 0dc335947726..7cba4a83f4a3 100644 --- a/java/java-tests/testSrc/com/intellij/psi/PsiModificationTrackerTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/PsiModificationTrackerTest.java @@ -3,8 +3,10 @@ package com.intellij.psi; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.util.PsiModificationTracker; +import com.intellij.testFramework.IdeaTestCase; import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; import com.intellij.util.Processor; import org.jetbrains.annotations.NonNls; @@ -15,6 +17,12 @@ import java.io.IOException; * @author Dmitry Avdeev */ public class PsiModificationTrackerTest extends LightPlatformCodeInsightFixtureTestCase { + @Override + public void setUp() throws Exception { + IdeaTestCase.initPlatformPrefix(); + super.setUp(); + } + public void testAnnotationNotChanged() throws Exception { doReplaceTest("@SuppressWarnings(\"zz\")\n" + "public class Foo { }", @@ -86,6 +94,7 @@ public class PsiModificationTrackerTest extends LightPlatformCodeInsightFixtureT try { final VirtualFile vFile = psiFile.getVirtualFile(); assert vFile != null : psiFile; + FileEditorManager.getInstance(getProject()).closeFile(vFile); vFile.delete(this); } catch (IOException e) { diff --git a/java/java-tests/testSrc/com/intellij/refactoring/AnonymousToInnerTest.java b/java/java-tests/testSrc/com/intellij/refactoring/AnonymousToInnerTest.java index 171393c03a47..71fa16179846 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/AnonymousToInnerTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/AnonymousToInnerTest.java @@ -37,6 +37,26 @@ public class AnonymousToInnerTest extends LightCodeInsightTestCase { public void testInsideInterface() throws Exception { // IDEADEV-29446 doTest("MyRunnable", true); } + + public void testCollapseDiamonds() throws Exception { // IDEADEV-29446 + doTest("MyPredicate", true); + } + + public void testCanBeStatic() throws Exception { + configureByFile(TEST_ROOT + getTestName(true) + ".java"); + AnonymousToInnerHandler handler = new AnonymousToInnerHandler(){ + @Override + protected boolean showRefactoringDialog() { + myNewClassName = "MyPredicate"; + myMakeStatic = !needsThis(); + return true; + } + }; + handler.invoke(getProject(), myEditor, myFile, null); + assertFalse(handler.needsThis()); + checkResultByFile(TEST_ROOT + getTestName(true) + "_after.java"); + } + private void doTest(final String newClassName, final boolean makeStatic) throws Exception { configureByFile(TEST_ROOT + getTestName(true) + ".java"); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignaturePropagationTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignaturePropagationTest.java index bdb1445df3ce..6daec4d62b1d 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignaturePropagationTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignaturePropagationTest.java @@ -6,6 +6,8 @@ import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.search.searches.MethodReferencesSearch; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; import com.intellij.refactoring.changeSignature.JavaThrownExceptionInfo; import com.intellij.refactoring.changeSignature.ParameterInfoImpl; @@ -29,6 +31,18 @@ public class ChangeSignaturePropagationTest extends LightRefactoringTestCase { parameterPropagationTest(); } + public void testParamTypeSubst() throws Exception { + final PsiMethod method = getPrimaryMethod(); + final HashSet methods = new HashSet(); + for (PsiReference reference : ReferencesSearch.search(method)) { + final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(reference.getElement(), PsiMethod.class); + if (psiMethod != null) { + methods.add(psiMethod); + } + } + parameterPropagationTest(method, methods, JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("T")); + } + public void testExceptionSimple() throws Exception { exceptionPropagationTest(); } @@ -39,7 +53,7 @@ public class ChangeSignaturePropagationTest extends LightRefactoringTestCase { public void testParamWithNoConstructor() throws Exception { final PsiMethod method = getPrimaryMethod(); - parameterPropagationTest(method, collectNonPhysicalMethodsToPropagate(method)); + parameterPropagationTest(method, collectNonPhysicalMethodsToPropagate(method), JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject()))); } public void testExceptionWithNoConstructor() throws Exception { @@ -62,12 +76,12 @@ public class ChangeSignaturePropagationTest extends LightRefactoringTestCase { public void testParamWithImplicitConstructor() throws Exception { final PsiMethod method = getPrimaryMethod(); - parameterPropagationTest(method, collectDefaultConstructorsToPropagate(method)); + parameterPropagationTest(method, collectDefaultConstructorsToPropagate(method), JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject()))); } public void testParamWithImplicitConstructors() throws Exception { final PsiMethod method = getPrimaryMethod(); - parameterPropagationTest(method, collectDefaultConstructorsToPropagate(method)); + parameterPropagationTest(method, collectDefaultConstructorsToPropagate(method), JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject()))); } public void testExceptionWithImplicitConstructor() throws Exception { @@ -84,13 +98,18 @@ public class ChangeSignaturePropagationTest extends LightRefactoringTestCase { } private void parameterPropagationTest() throws Exception { - final PsiMethod method = getPrimaryMethod(); - parameterPropagationTest(method, new HashSet(Arrays.asList(method.getContainingClass().getMethods()))); + parameterPropagationTest(JavaPsiFacade.getElementFactory(getProject()) + .createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject()))); } - private void parameterPropagationTest(final PsiMethod method, final HashSet psiMethods) throws Exception { - PsiType newParamType = JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName("java.lang.Class", GlobalSearchScope.allScope(getProject())); - final ParameterInfoImpl[] newParameters = new ParameterInfoImpl[]{new ParameterInfoImpl(-1, "clazz", newParamType, "null")}; + private void parameterPropagationTest(final PsiClassType paramType) throws Exception { + final PsiMethod method = getPrimaryMethod(); + parameterPropagationTest(method, new HashSet(Arrays.asList(method.getContainingClass().getMethods())), + paramType); + } + + private void parameterPropagationTest(final PsiMethod method, final HashSet psiMethods, final PsiType paramType) throws Exception { + final ParameterInfoImpl[] newParameters = new ParameterInfoImpl[]{new ParameterInfoImpl(-1, "clazz", paramType, "null")}; doTest(newParameters, new ThrownExceptionInfo[0], psiMethods, null, method); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java index 77d7fcdea41e..41acb241a84c 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ChangeSignatureTest.java @@ -134,6 +134,13 @@ public class ChangeSignatureTest extends LightRefactoringTestCase { }, false); } + public void testParamNameNoConflict() throws Exception { + doTest(null, new ParameterInfoImpl[]{ + new ParameterInfoImpl(0), + new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN) + }, false); + } + public void testParamJavadoc() throws Exception { doTest(null, new ParameterInfoImpl[] { new ParameterInfoImpl(1, "z", PsiType.INT), diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java index 4893ce72e001..0cad5462136e 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java @@ -275,6 +275,10 @@ public class IntroduceParameterTest extends LightRefactoringTestCase { doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false); } + public void testPreserveDiamondOccurrences() throws Exception { + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false); + } + public void testSubstituteTypeParams() throws Exception { doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_ALL, true, false, true, false); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java index b17563b2f75c..c4f5a7aa0e89 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/PullUpTest.java @@ -111,6 +111,10 @@ public class PullUpTest extends LightRefactoringTestCase { doTest(false, new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class)); } + public void testMergeInterfaces() throws Exception { + doTest(false, new RefactoringTestUtil.MemberDescriptor("I", PsiClass.class)); + } + private void doTest(RefactoringTestUtil.MemberDescriptor... membersToFind) throws Exception { doTest(true, membersToFind); } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java index 99b98075ce1d..8870d33c8791 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java @@ -176,6 +176,14 @@ public class InlineMethodTest extends LightRefactoringTestCase { doTest(); } + public void testChainedConstructor() throws Exception { + doTestInlineThisOnly(); + } + + public void testChainedConstructor1() throws Exception { + doTest(); + } + public void testMethodUsedInJavadoc() throws Exception { try { doTest(); @@ -187,6 +195,10 @@ public class InlineMethodTest extends LightRefactoringTestCase { } public void testInlineRunnableRun() throws Exception { + doTestInlineThisOnly(); + } + + private void doTestInlineThisOnly() { @NonNls String fileName = "/refactoring/inlineMethod/" + getTestName(false) + ".java"; configureByFile(fileName); performAction(new MockInlineMethodOptions(){ diff --git a/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java b/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java index ac7e6d84061b..fa8b3faf6e67 100644 --- a/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java +++ b/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java @@ -106,6 +106,7 @@ public class PatternPackageSet extends PatternBasedPackageSet { return StringUtil.getQualifiedName(fileIndex.getPackageNameByDirectory(file.isDirectory() ? file : file.getParent()), file.getNameWithoutExtension()); } + @NotNull @Override public PackageSet createCopy() { return new PatternPackageSet(myAspectJSyntaxPattern, myScope, myModulePatternText); @@ -116,6 +117,7 @@ public class PatternPackageSet extends PatternBasedPackageSet { return 0; } + @NotNull @Override public String getText() { StringBuilder buf = new StringBuilder(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java index e1a634a869ae..8b1e97111783 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/storage/BuildDataManager.java @@ -18,7 +18,7 @@ import java.util.Map; * Date: 10/7/11 */ public class BuildDataManager implements StorageOwner { - private static final int VERSION = 3; + private static final int VERSION = 4; private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager"); private static final String SRC_TO_OUTPUTS_STORAGE = "src-out"; private static final String SRC_TO_FORM_STORAGE = "src-form"; diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java b/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java index 1e25c2197573..d94c2711bf68 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsElementFactory.java @@ -1,8 +1,12 @@ package org.jetbrains.jps.model; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.library.JpsLibraryType; +import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleReference; +import org.jetbrains.jps.model.module.JpsModuleType; import org.jetbrains.jps.service.JpsServiceManager; /** @@ -13,6 +17,10 @@ public abstract class JpsElementFactory { return JpsServiceManager.getInstance().getService(JpsElementFactory.class); } + public abstract JpsModule createModule(String name, JpsModuleType type); + + public abstract JpsLibrary createLibrary(@NotNull String name, @NotNull JpsLibraryType type); + @NotNull public abstract JpsModuleReference createModuleReference(@NotNull String moduleName); @@ -20,4 +28,9 @@ public abstract class JpsElementFactory { public abstract JpsLibraryReference createLibraryReference(@NotNull String libraryName, @NotNull JpsElementReference parentReference); + @NotNull + public abstract JpsElementReference createProjectReference(); + + @NotNull + public abstract JpsElementReference createGlobalReference(); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java b/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java index 0beb26b8a514..9855a4b3d5d8 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java +++ b/jps/model-api/src/org/jetbrains/jps/model/JpsProject.java @@ -24,4 +24,8 @@ public interface JpsProject extends JpsCompositeElement, JpsReferenceableElement @NotNull List getModules(); + + void addModule(JpsModule module); + + void addLibrary(JpsLibrary library); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/ExplodedDirectoryModuleExtension.java b/jps/model-api/src/org/jetbrains/jps/model/java/ExplodedDirectoryModuleExtension.java new file mode 100644 index 000000000000..a1fcdb97e3e8 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/ExplodedDirectoryModuleExtension.java @@ -0,0 +1,18 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.JpsElement; + +/** + * @author nik + */ +//todo[nik] move to j2me plugin +public interface ExplodedDirectoryModuleExtension extends JpsElement { + + String getExplodedUrl(); + + void setExplodedUrl(String explodedUrl); + + boolean isExcludeExploded(); + + void setExcludeExploded(boolean excludeExploded); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsAnnotationRootType.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsAnnotationRootType.java new file mode 100644 index 000000000000..51669166ac94 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsAnnotationRootType.java @@ -0,0 +1,10 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.jps.model.library.JpsOrderRootType; + +/** + * @author nik + */ +public class JpsAnnotationRootType extends JpsOrderRootType { + public static final JpsAnnotationRootType INSTANCE = new JpsAnnotationRootType(); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java new file mode 100644 index 000000000000..a7334ea52c87 --- /dev/null +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaExtensionService.java @@ -0,0 +1,31 @@ +package org.jetbrains.jps.model.java; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.module.JpsDependencyElement; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.service.JpsServiceManager; + +/** + * @author nik + */ +public abstract class JpsJavaExtensionService { + public static JpsJavaExtensionService getInstance() { + return JpsServiceManager.getInstance().getService(JpsJavaExtensionService.class); + } + + @NotNull + public abstract JpsJavaModuleExtension getOrCreateModuleExtension(@NotNull JpsModule module); + + @NotNull + public abstract JpsJavaDependencyExtension getOrCreateDependencyExtension(@NotNull JpsDependencyElement dependency); + + @NotNull + public abstract JpsElementKind getModuleExtensionKind(); + + @NotNull + public abstract JpsElementKind getDependencyExtensionKind(); + + @NotNull + public abstract ExplodedDirectoryModuleExtension getOrCreateExplodedDirectoryExtension(@NotNull JpsModule module); +} diff --git a/jps/model-api/src/org/jetbrains/jps/model/java/JavaModuleExtension.java b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleExtension.java similarity index 51% rename from jps/model-api/src/org/jetbrains/jps/model/java/JavaModuleExtension.java rename to jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleExtension.java index 1ac6c18b42a4..f2c7bdcc2986 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/java/JavaModuleExtension.java +++ b/jps/model-api/src/org/jetbrains/jps/model/java/JpsJavaModuleExtension.java @@ -1,11 +1,15 @@ package org.jetbrains.jps.model.java; import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.JpsUrlList; /** * @author nik */ -public interface JavaModuleExtension extends JpsElement { +public interface JpsJavaModuleExtension extends JpsElement { + JpsUrlList getJavadocRoots(); + + JpsUrlList getAnnotationRoots(); String getOutputUrl(); @@ -18,4 +22,12 @@ public interface JavaModuleExtension extends JpsElement { LanguageLevel getLanguageLevel(); void setLanguageLevel(LanguageLevel languageLevel); + + boolean isInheritOutput(); + + void setInheritOutput(boolean inheritOutput); + + boolean isExcludeOutput(); + + void setExcludeOutput(boolean excludeOutput); } diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootType.java b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootType.java index 70afc3f5e8ee..707344331440 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootType.java +++ b/jps/model-api/src/org/jetbrains/jps/model/library/JpsLibraryRootType.java @@ -4,14 +4,16 @@ package org.jetbrains.jps.model.library; * @author nik */ public class JpsLibraryRootType { - public static final JpsLibraryRootType COMPILED = new JpsLibraryRootType(JpsOrderRootType.COMPILED, false); - public static final JpsLibraryRootType SOURCES = new JpsLibraryRootType(JpsOrderRootType.SOURCES, false); + public static final JpsLibraryRootType COMPILED = new JpsLibraryRootType(JpsOrderRootType.COMPILED, false, false); + public static final JpsLibraryRootType SOURCES = new JpsLibraryRootType(JpsOrderRootType.SOURCES, false, false); private final boolean myJarDirectory; + private final boolean myRecursive; private final JpsOrderRootType myType; - public JpsLibraryRootType(JpsOrderRootType type, boolean jarDirectory) { - myType = type; + public JpsLibraryRootType(JpsOrderRootType type, boolean jarDirectory, boolean recursive) { myJarDirectory = jarDirectory; + myRecursive = recursive; + myType = type; } public boolean isJarDirectory() { @@ -21,4 +23,8 @@ public class JpsLibraryRootType { public JpsOrderRootType getType() { return myType; } + + public boolean isRecursive() { + return myRecursive; + } } diff --git a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java index fdc54705c502..88aa5b375f8e 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java +++ b/jps/model-api/src/org/jetbrains/jps/model/module/JpsModule.java @@ -42,6 +42,9 @@ public interface JpsModule extends JpsNamedElement, JpsReferenceableElement type, @NotNull String name); + @NotNull + JpsLibrary addModuleLibrary(@NotNull JpsLibrary library); + void delete(); @NotNull diff --git a/jps/model-api/src/org/jetbrains/jps/service/JpsServiceManager.java b/jps/model-api/src/org/jetbrains/jps/service/JpsServiceManager.java index d24524ca3664..2f86a7898341 100644 --- a/jps/model-api/src/org/jetbrains/jps/service/JpsServiceManager.java +++ b/jps/model-api/src/org/jetbrains/jps/service/JpsServiceManager.java @@ -12,8 +12,11 @@ public abstract class JpsServiceManager { public abstract T getService(Class serviceClass); + public abstract Iterable getExtensions(Class extensionClass); + private static class InstanceHolder { private static final JpsServiceManager INSTANCE; + static { INSTANCE = ServiceLoader.load(JpsServiceManager.class).iterator().next(); } diff --git a/jps/model-impl/src/META-INF/services/org.jetbrains.jps.model.java.JpsJavaExtensionService b/jps/model-impl/src/META-INF/services/org.jetbrains.jps.model.java.JpsJavaExtensionService new file mode 100644 index 000000000000..3d58916622f6 --- /dev/null +++ b/jps/model-impl/src/META-INF/services/org.jetbrains.jps.model.java.JpsJavaExtensionService @@ -0,0 +1 @@ +org.jetbrains.jps.model.java.impl.JpsJavaExtensionServiceImpl \ No newline at end of file diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementBase.java index df9e701f815e..dd53713729d0 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementBase.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementBase.java @@ -10,7 +10,7 @@ import org.jetbrains.jps.model.*; */ public abstract class JpsElementBase> implements JpsElement, JpsElement.BulkModificationSupport { private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.model.impl.JpsElementBase"); - protected JpsElementBase myParent; + protected JpsElementBase myParent; protected JpsElementBase() { } @@ -60,7 +60,7 @@ public abstract class JpsElementBase> implemen public abstract void applyChanges(@NotNull Self modified); - public JpsElementBase getParent() { + public JpsElementBase getParent() { return myParent; } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionKind.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionKind.java index aae141b3b861..288f33e97dc2 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionKind.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementCollectionKind.java @@ -6,11 +6,12 @@ import org.jetbrains.jps.model.*; /** * @author nik */ -public class JpsElementCollectionKind extends JpsElementKind> +public class JpsElementCollectionKind extends JpsElementKindBase> implements JpsElementCreator> { private final JpsElementKind myElementKind; public JpsElementCollectionKind(JpsElementKind elementKind) { + super("collection of " + elementKind); myElementKind = elementKind; } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementFactoryImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementFactoryImpl.java index 70492b460fe7..21902607503a 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementFactoryImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementFactoryImpl.java @@ -2,15 +2,32 @@ package org.jetbrains.jps.model.impl; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsLibraryReference; +import org.jetbrains.jps.model.library.JpsLibraryType; +import org.jetbrains.jps.model.library.impl.JpsLibraryImpl; import org.jetbrains.jps.model.library.impl.JpsLibraryReferenceImpl; +import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleReference; +import org.jetbrains.jps.model.module.JpsModuleType; +import org.jetbrains.jps.model.module.impl.JpsModuleImpl; import org.jetbrains.jps.model.module.impl.JpsModuleReferenceImpl; /** * @author nik */ public class JpsElementFactoryImpl extends JpsElementFactory { + + @Override + public JpsModule createModule(String name, JpsModuleType type) { + return new JpsModuleImpl(type, name); + } + + @Override + public JpsLibrary createLibrary(@NotNull String name, @NotNull JpsLibraryType type) { + return new JpsLibraryImpl(name, type); + } + @NotNull @Override public JpsModuleReference createModuleReference(@NotNull String moduleName) { @@ -23,4 +40,16 @@ public class JpsElementFactoryImpl extends JpsElementFactory { @NotNull JpsElementReference parentReference) { return new JpsLibraryReferenceImpl(libraryName, parentReference); } + + @NotNull + @Override + public JpsElementReference createProjectReference() { + return new JpsProjectElementReference(); + } + + @NotNull + @Override + public JpsElementReference createGlobalReference() { + return new JpsGlobalElementReference(); + } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementKindBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementKindBase.java new file mode 100644 index 000000000000..faf964675b97 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsElementKindBase.java @@ -0,0 +1,20 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.jps.model.JpsElement; +import org.jetbrains.jps.model.JpsElementKind; + +/** + * @author nik + */ +public class JpsElementKindBase extends JpsElementKind { + private String myDebugName; + + public JpsElementKindBase(String debugName) { + myDebugName = debugName; + } + + @Override + public String toString() { + return myDebugName; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java index c5bb2c500b64..f48ad0d0f365 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsGlobalImpl.java @@ -23,7 +23,7 @@ public class JpsGlobalImpl extends JpsRootElementBase implements @NotNull @Override public JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, @NotNull final String name) { - final JpsElementCollectionImpl collection = myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); + final JpsElementCollectionImpl collection = myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); return collection.addChild(new JpsLibraryImpl(name, libraryType)); } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java index 3e00ac907e7e..94bbe930b864 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java @@ -9,7 +9,7 @@ import java.util.List; * @author nik */ public abstract class JpsNamedElementReferenceBase> extends JpsCompositeElementBase implements JpsElementReference { - private static final JpsElementKind> PARENT_REFERENCE_KIND = new JpsElementKind>(); + private static final JpsElementKind> PARENT_REFERENCE_KIND = new JpsElementKindBase>("parent"); private final JpsElementCollectionKind myCollectionKind; protected final String myElementName; diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java index 3720c0ba1190..e70099f276da 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsProjectImpl.java @@ -17,7 +17,8 @@ import java.util.List; * @author nik */ public class JpsProjectImpl extends JpsRootElementBase implements JpsProject { - private static final JpsElementCollectionKind> EXTERNAL_REFERENCES_COLLECTION_KIND = new JpsElementCollectionKind>(new JpsElementKind>()); + private static final JpsElementCollectionKind> EXTERNAL_REFERENCES_COLLECTION_KIND = + new JpsElementCollectionKind>(new JpsElementKindBase>("external reference")); public JpsProjectImpl(JpsModel model, JpsEventDispatcher eventDispatcher) { super(model, eventDispatcher); @@ -37,14 +38,14 @@ public class JpsProjectImpl extends JpsRootElementBase implement @NotNull @Override public JpsModule addModule(@NotNull JpsModuleType moduleType, @NotNull final String name) { - final JpsElementCollectionImpl collection = myContainer.getChild(JpsModuleKind.MODULE_COLLECTION_KIND); + final JpsElementCollectionImpl collection = myContainer.getChild(JpsModuleKind.MODULE_COLLECTION_KIND); return collection.addChild(new JpsModuleImpl(moduleType, name)); } @NotNull @Override public JpsLibrary addLibrary(@NotNull JpsLibraryType libraryType, @NotNull final String name) { - final JpsElementCollectionImpl collection = myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); + final JpsElementCollectionImpl collection = myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); return collection.addChild(new JpsLibraryImpl(name, libraryType)); } @@ -60,6 +61,16 @@ public class JpsProjectImpl extends JpsRootElementBase implement return myContainer.getChild(JpsModuleKind.MODULE_COLLECTION_KIND).getElements(); } + @Override + public void addModule(JpsModule module) { + myContainer.getChild(JpsModuleKind.MODULE_COLLECTION_KIND).addChild(module); + } + + @Override + public void addLibrary(JpsLibrary library) { + myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND).addChild(library); + } + @NotNull @Override public JpsElementReference createReference() { diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataKind.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataKind.java index 16805bb40611..7033d720cda2 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataKind.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsTypedDataKind.java @@ -1,10 +1,12 @@ package org.jetbrains.jps.model.impl; -import org.jetbrains.jps.model.JpsElementKind; import org.jetbrains.jps.model.JpsElementType; /** * @author nik */ -public class JpsTypedDataKind> extends JpsElementKind> { +public class JpsTypedDataKind> extends JpsElementKindBase> { + public JpsTypedDataKind() { + super("typed data"); + } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsUrlListKind.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsUrlListKind.java new file mode 100644 index 000000000000..95c6f2e1ac0f --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsUrlListKind.java @@ -0,0 +1,20 @@ +package org.jetbrains.jps.model.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementCreator; +import org.jetbrains.jps.model.JpsUrlList; + +/** + * @author nik + */ +public class JpsUrlListKind extends JpsElementKindBase implements JpsElementCreator { + public JpsUrlListKind(String debugName) { + super(debugName); + } + + @NotNull + @Override + public JpsUrlList create() { + return new JpsUrlListImpl(); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementKind.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementKind.java index 9e670f918f04..d7bd4ea531b6 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementKind.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/SimpleJpsElementKind.java @@ -1,11 +1,13 @@ package org.jetbrains.jps.model.impl; -import org.jetbrains.jps.model.JpsElementKind; import org.jetbrains.jps.model.JpsElementProperties; /** * @author nik */ public class SimpleJpsElementKind

> extends - JpsElementKind> { + JpsElementKindBase> { + public SimpleJpsElementKind(String debugName) { + super(debugName); + } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/ExplodedDirectoryModuleExtensionImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/ExplodedDirectoryModuleExtensionImpl.java new file mode 100644 index 000000000000..e8a03bf27cb2 --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/ExplodedDirectoryModuleExtensionImpl.java @@ -0,0 +1,65 @@ +package org.jetbrains.jps.model.java.impl; + +import com.intellij.openapi.util.Comparing; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.impl.JpsElementBase; +import org.jetbrains.jps.model.impl.JpsElementKindBase; +import org.jetbrains.jps.model.java.ExplodedDirectoryModuleExtension; + +/** + * @author nik + */ +public class ExplodedDirectoryModuleExtensionImpl extends JpsElementBase implements + ExplodedDirectoryModuleExtension { + public static final JpsElementKindBase KIND = + new JpsElementKindBase("exploded directory"); + + private String myExplodedUrl; + private boolean myExcludeExploded; + + public ExplodedDirectoryModuleExtensionImpl() { + } + + public ExplodedDirectoryModuleExtensionImpl(ExplodedDirectoryModuleExtensionImpl original) { + myExcludeExploded = original.myExcludeExploded; + myExplodedUrl = original.myExplodedUrl; + } + + @Override + public String getExplodedUrl() { + return myExplodedUrl; + } + + @Override + public void setExplodedUrl(String explodedUrl) { + if (!Comparing.equal(myExplodedUrl, explodedUrl)) { + myExplodedUrl = explodedUrl; + fireElementChanged(); + } + } + + @Override + public boolean isExcludeExploded() { + return myExcludeExploded; + } + + @Override + public void setExcludeExploded(boolean excludeExploded) { + if (myExcludeExploded != excludeExploded) { + myExcludeExploded = excludeExploded; + fireElementChanged(); + } + } + + @NotNull + @Override + public ExplodedDirectoryModuleExtensionImpl createCopy() { + return new ExplodedDirectoryModuleExtensionImpl(this); + } + + @Override + public void applyChanges(@NotNull ExplodedDirectoryModuleExtensionImpl modified) { + setExcludeExploded(modified.myExcludeExploded); + setExplodedUrl(modified.myExplodedUrl); + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionImpl.java deleted file mode 100644 index 4bf2a2b70bc5..000000000000 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionImpl.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.jetbrains.jps.model.java.impl; - -import com.intellij.openapi.util.Comparing; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.impl.JpsElementBase; -import org.jetbrains.jps.model.java.JavaModuleExtension; -import org.jetbrains.jps.model.java.LanguageLevel; - -/** - * @author nik - */ -public class JavaModuleExtensionImpl extends JpsElementBase implements JavaModuleExtension { - private String myOutputUrl; - private String myTestOutputUrl; - private LanguageLevel myLanguageLevel; - - public JavaModuleExtensionImpl() { - } - - public JavaModuleExtensionImpl(JavaModuleExtensionImpl original) { - myOutputUrl = original.myOutputUrl; - myTestOutputUrl = original.myTestOutputUrl; - myLanguageLevel = original.myLanguageLevel; - } - - @NotNull - @Override - public JavaModuleExtensionImpl createCopy() { - return new JavaModuleExtensionImpl(this); - } - - @Override - public String getOutputUrl() { - return myOutputUrl; - } - - @Override - public void setOutputUrl(String outputUrl) { - if (!Comparing.equal(myOutputUrl, outputUrl)) { - myOutputUrl = outputUrl; - fireElementChanged(); - } - } - - @Override - public String getTestOutputUrl() { - return myTestOutputUrl; - } - - @Override - public void setTestOutputUrl(String testOutputUrl) { - if (!Comparing.equal(myTestOutputUrl, testOutputUrl)) { - myTestOutputUrl = testOutputUrl; - fireElementChanged(); - } - } - - @Override - public LanguageLevel getLanguageLevel() { - return myLanguageLevel; - } - - @Override - public void setLanguageLevel(LanguageLevel languageLevel) { - if (!Comparing.equal(myLanguageLevel, languageLevel)) { - myLanguageLevel = languageLevel; - fireElementChanged(); - } - } - - public void applyChanges(@NotNull JavaModuleExtensionImpl modified) { - setLanguageLevel(modified.myLanguageLevel); - setOutputUrl(modified.myOutputUrl); - setTestOutputUrl(modified.myTestOutputUrl); - } -} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionKind.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionKind.java index 2bf771e90fc1..d46529ff5010 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionKind.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JavaModuleExtensionKind.java @@ -1,28 +1,23 @@ package org.jetbrains.jps.model.java.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.*; -import org.jetbrains.jps.model.java.JavaModuleExtension; -import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.JpsElementCreator; +import org.jetbrains.jps.model.impl.JpsElementKindBase; /** * @author nik */ -public class JavaModuleExtensionKind extends JpsElementKind implements JpsElementCreator { - private static final JavaModuleExtensionKind INSTANCE = new JavaModuleExtensionKind(); +public class JavaModuleExtensionKind extends JpsElementKindBase + implements JpsElementCreator { + public static final JavaModuleExtensionKind INSTANCE = new JavaModuleExtensionKind(); + + private JavaModuleExtensionKind() { + super("java module extension"); + } @NotNull @Override - public JavaModuleExtensionImpl create() { - return new JavaModuleExtensionImpl(); - } - - @NotNull - public static JavaModuleExtension getExtension(@NotNull JpsModule module) { - JavaModuleExtension child = module.getContainer().getChild(INSTANCE); - if (child == null) { - child = module.getContainer().setChild(INSTANCE); - } - return child; + public JpsJavaModuleExtensionImpl create() { + return new JpsJavaModuleExtensionImpl(); } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaDependencyExtensionKind.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaDependencyExtensionKind.java index c15df483d74e..48555c5b7de7 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaDependencyExtensionKind.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaDependencyExtensionKind.java @@ -1,28 +1,24 @@ package org.jetbrains.jps.model.java.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.*; -import org.jetbrains.jps.model.java.JpsJavaDependencyExtension; +import org.jetbrains.jps.model.JpsElementCreator; +import org.jetbrains.jps.model.impl.JpsElementKindBase; import org.jetbrains.jps.model.java.JpsJavaDependencyScope; -import org.jetbrains.jps.model.module.JpsDependencyElement; /** * @author nik */ -public class JpsJavaDependencyExtensionKind extends JpsElementKind implements JpsElementCreator { +public class JpsJavaDependencyExtensionKind extends JpsElementKindBase + implements JpsElementCreator { public static final JpsJavaDependencyExtensionKind INSTANCE = new JpsJavaDependencyExtensionKind(); + private JpsJavaDependencyExtensionKind() { + super("java dependency extension"); + } + @NotNull @Override public JpsJavaDependencyExtensionImpl create() { return new JpsJavaDependencyExtensionImpl(false, JpsJavaDependencyScope.COMPILE); } - - public static JpsJavaDependencyExtension getExtension(@NotNull JpsDependencyElement element) { - JpsJavaDependencyExtensionImpl extension = element.getContainer().getChild(INSTANCE); - if (extension == null) { - extension = element.getContainer().setChild(INSTANCE); - } - return extension; - } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java new file mode 100644 index 000000000000..c85f1ec5746f --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaExtensionServiceImpl.java @@ -0,0 +1,57 @@ +package org.jetbrains.jps.model.java.impl; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.java.ExplodedDirectoryModuleExtension; +import org.jetbrains.jps.model.java.JpsJavaModuleExtension; +import org.jetbrains.jps.model.java.JpsJavaDependencyExtension; +import org.jetbrains.jps.model.java.JpsJavaExtensionService; +import org.jetbrains.jps.model.module.JpsDependencyElement; +import org.jetbrains.jps.model.module.JpsModule; + +/** + * @author nik + */ +public class JpsJavaExtensionServiceImpl extends JpsJavaExtensionService { + @NotNull + @Override + public JpsJavaModuleExtension getOrCreateModuleExtension(@NotNull JpsModule module) { + JpsJavaModuleExtension child = module.getContainer().getChild(JavaModuleExtensionKind.INSTANCE); + if (child == null) { + child = module.getContainer().setChild(JavaModuleExtensionKind.INSTANCE); + } + return child; + } + + @NotNull + @Override + public JpsJavaDependencyExtension getOrCreateDependencyExtension(@NotNull JpsDependencyElement dependency) { + JpsJavaDependencyExtensionImpl extension = dependency.getContainer().getChild(JpsJavaDependencyExtensionKind.INSTANCE); + if (extension == null) { + extension = dependency.getContainer().setChild(JpsJavaDependencyExtensionKind.INSTANCE); + } + return extension; + } + + @NotNull + @Override + public JpsElementKind getModuleExtensionKind() { + return JavaModuleExtensionKind.INSTANCE; + } + + @NotNull + @Override + public JpsElementKind getDependencyExtensionKind() { + return JpsJavaDependencyExtensionKind.INSTANCE; + } + + @Override + @NotNull + public ExplodedDirectoryModuleExtension getOrCreateExplodedDirectoryExtension(@NotNull JpsModule module) { + ExplodedDirectoryModuleExtension extension = module.getContainer().getChild(ExplodedDirectoryModuleExtensionImpl.KIND); + if (extension == null) { + extension = module.getContainer().setChild(ExplodedDirectoryModuleExtensionImpl.KIND, new ExplodedDirectoryModuleExtensionImpl()); + } + return extension; + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaModuleExtensionImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaModuleExtensionImpl.java new file mode 100644 index 000000000000..0dba7526275a --- /dev/null +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsJavaModuleExtensionImpl.java @@ -0,0 +1,121 @@ +package org.jetbrains.jps.model.java.impl; + +import com.intellij.openapi.util.Comparing; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsUrlList; +import org.jetbrains.jps.model.impl.JpsCompositeElementBase; +import org.jetbrains.jps.model.impl.JpsUrlListKind; +import org.jetbrains.jps.model.java.JpsJavaModuleExtension; +import org.jetbrains.jps.model.java.LanguageLevel; + +/** + * @author nik + */ +public class JpsJavaModuleExtensionImpl extends JpsCompositeElementBase implements JpsJavaModuleExtension { + private static final JpsUrlListKind JAVADOC_ROOTS_KIND = new JpsUrlListKind("javadoc roots"); + private static final JpsUrlListKind ANNOTATIONS_ROOTS_KIND = new JpsUrlListKind("annotation roots"); + private String myOutputUrl; + private String myTestOutputUrl; + private boolean myInheritOutput; + private boolean myExcludeOutput; + private LanguageLevel myLanguageLevel; + + public JpsJavaModuleExtensionImpl() { + myContainer.setChild(JAVADOC_ROOTS_KIND); + myContainer.setChild(ANNOTATIONS_ROOTS_KIND); + } + + public JpsJavaModuleExtensionImpl(JpsJavaModuleExtensionImpl original) { + super(original); + myOutputUrl = original.myOutputUrl; + myTestOutputUrl = original.myTestOutputUrl; + myLanguageLevel = original.myLanguageLevel; + } + + @NotNull + @Override + public JpsJavaModuleExtensionImpl createCopy() { + return new JpsJavaModuleExtensionImpl(this); + } + + @Override + public JpsUrlList getAnnotationRoots() { + return myContainer.getChild(ANNOTATIONS_ROOTS_KIND); + } + + @Override + public JpsUrlList getJavadocRoots() { + return myContainer.getChild(JAVADOC_ROOTS_KIND); + } + + @Override + public String getOutputUrl() { + return myOutputUrl; + } + + @Override + public void setOutputUrl(String outputUrl) { + if (!Comparing.equal(myOutputUrl, outputUrl)) { + myOutputUrl = outputUrl; + fireElementChanged(); + } + } + + @Override + public String getTestOutputUrl() { + return myTestOutputUrl; + } + + @Override + public void setTestOutputUrl(String testOutputUrl) { + if (!Comparing.equal(myTestOutputUrl, testOutputUrl)) { + myTestOutputUrl = testOutputUrl; + fireElementChanged(); + } + } + + @Override + public LanguageLevel getLanguageLevel() { + return myLanguageLevel; + } + + @Override + public void setLanguageLevel(LanguageLevel languageLevel) { + if (!Comparing.equal(myLanguageLevel, languageLevel)) { + myLanguageLevel = languageLevel; + fireElementChanged(); + } + } + + public void applyChanges(@NotNull JpsJavaModuleExtensionImpl modified) { + setLanguageLevel(modified.myLanguageLevel); + setOutputUrl(modified.myOutputUrl); + setTestOutputUrl(modified.myTestOutputUrl); + } + + @Override + public boolean isInheritOutput() { + return myInheritOutput; + } + + @Override + public void setInheritOutput(boolean inheritOutput) { + if (myInheritOutput != inheritOutput) { + myInheritOutput = inheritOutput; + fireElementChanged(); + } + } + + @Override + public boolean isExcludeOutput() { + return myExcludeOutput; + } + + @Override + public void setExcludeOutput(boolean excludeOutput) { + if (myExcludeOutput != excludeOutput) { + myExcludeOutput = excludeOutput; + fireElementChanged(); + } + } +} diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java index fb3794aae814..beb49333b109 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryImpl.java @@ -15,7 +15,8 @@ import java.util.List; * @author nik */ public class JpsLibraryImpl extends JpsNamedCompositeElementBase implements JpsLibrary { - private static final JpsElementCollectionKind LIBRARY_ROOTS_COLLECTION = new JpsElementCollectionKind(JpsLibraryRootKind.INSTANCE); + private static final JpsElementCollectionKind LIBRARY_ROOTS_COLLECTION = + new JpsElementCollectionKind(JpsLibraryRootKind.INSTANCE); private static final JpsTypedDataKind> TYPED_DATA_KIND = new JpsTypedDataKind>(); public JpsLibraryImpl(@NotNull String name, @NotNull JpsLibraryType type) { @@ -65,8 +66,9 @@ public class JpsLibraryImpl extends JpsNamedCompositeElementBase getParent() { - return (JpsElementCollectionImpl)myParent; + public JpsElementCollectionImpl getParent() { + //noinspection unchecked + return (JpsElementCollectionImpl)myParent; } @NotNull @@ -79,7 +81,8 @@ public class JpsLibraryImpl extends JpsNamedCompositeElementBase parentReference = ((JpsReferenceableElement)getParent().getParent()).createReference(); + final JpsElementReference parentReference = + ((JpsReferenceableElement)getParent().getParent()).createReference(); return new JpsLibraryReferenceImpl(getName(), parentReference); } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryKind.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryKind.java index 834ada9984fb..c6da7110d833 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryKind.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryKind.java @@ -1,28 +1,30 @@ package org.jetbrains.jps.model.library.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.JpsElementKind; import org.jetbrains.jps.model.JpsEventDispatcher; import org.jetbrains.jps.model.impl.JpsElementCollectionKind; +import org.jetbrains.jps.model.impl.JpsElementKindBase; +import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.library.JpsLibraryListener; /** * @author nik */ -public class JpsLibraryKind extends JpsElementKind { +public class JpsLibraryKind extends JpsElementKindBase { public static final JpsLibraryKind INSTANCE = new JpsLibraryKind(); - public static final JpsElementCollectionKind LIBRARIES_COLLECTION_KIND = new JpsElementCollectionKind(INSTANCE); + public static final JpsElementCollectionKind LIBRARIES_COLLECTION_KIND = new JpsElementCollectionKind(INSTANCE); private JpsLibraryKind() { + super("library"); } @Override - public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryImpl element) { + public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibrary element) { dispatcher.getPublisher(JpsLibraryListener.class).libraryAdded(element); } @Override - public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryImpl element) { + public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibrary element) { dispatcher.getPublisher(JpsLibraryListener.class).libraryRemoved(element); } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootKind.java b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootKind.java index 4043b76287ce..f01d8cc843c6 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootKind.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/library/impl/JpsLibraryRootKind.java @@ -1,16 +1,20 @@ package org.jetbrains.jps.model.library.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.impl.JpsElementKindBase; import org.jetbrains.jps.model.JpsEventDispatcher; import org.jetbrains.jps.model.library.JpsLibraryRootListener; /** * @author nik */ -public class JpsLibraryRootKind extends JpsElementKind { +public class JpsLibraryRootKind extends JpsElementKindBase { public static final JpsLibraryRootKind INSTANCE = new JpsLibraryRootKind(); + public JpsLibraryRootKind() { + super("library root"); + } + @Override public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsLibraryRootImpl element) { dispatcher.getPublisher(JpsLibraryRootListener.class).rootAdded(element); diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java index e5c04b68cacb..6281eb2ed117 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsDependenciesListImpl.java @@ -1,7 +1,7 @@ package org.jetbrains.jps.model.module.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.impl.JpsElementKindBase; import org.jetbrains.jps.model.impl.JpsCompositeElementBase; import org.jetbrains.jps.model.impl.JpsElementCollectionKind; import org.jetbrains.jps.model.library.JpsLibrary; @@ -15,8 +15,8 @@ import java.util.List; * @author nik */ public class JpsDependenciesListImpl extends JpsCompositeElementBase implements JpsDependenciesList { - public static final JpsElementKind> DEPENDENCY_ELEMENT_KIND = new JpsElementKind>(); - public static final JpsElementCollectionKind> DEPENDENCY_COLLECTION_KIND = new JpsElementCollectionKind>(DEPENDENCY_ELEMENT_KIND); + public static final JpsElementCollectionKind> DEPENDENCY_COLLECTION_KIND = + new JpsElementCollectionKind>(new JpsElementKindBase>("dependency")); public JpsDependenciesListImpl() { super(); diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsLibraryDependencyImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsLibraryDependencyImpl.java index 7e2eba50a317..d9586addd602 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsLibraryDependencyImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsLibraryDependencyImpl.java @@ -2,6 +2,7 @@ package org.jetbrains.jps.model.module.impl; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.impl.JpsElementKindBase; import org.jetbrains.jps.model.library.JpsLibraryReference; import org.jetbrains.jps.model.module.JpsLibraryDependency; @@ -9,7 +10,7 @@ import org.jetbrains.jps.model.module.JpsLibraryDependency; * @author nik */ public class JpsLibraryDependencyImpl extends JpsDependencyElementBase implements JpsLibraryDependency { - public static final JpsElementKind LIBRARY_REFERENCE_KIND = new JpsElementKind(); + public static final JpsElementKind LIBRARY_REFERENCE_KIND = new JpsElementKindBase("library reference"); public JpsLibraryDependencyImpl(final JpsLibraryReference reference) { super(); diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java index 6fe796883168..143702c104cf 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleDependencyImpl.java @@ -2,6 +2,7 @@ package org.jetbrains.jps.model.module.impl; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.*; +import org.jetbrains.jps.model.impl.JpsElementKindBase; import org.jetbrains.jps.model.module.JpsModuleDependency; import org.jetbrains.jps.model.module.JpsModuleReference; @@ -9,7 +10,7 @@ import org.jetbrains.jps.model.module.JpsModuleReference; * @author nik */ public class JpsModuleDependencyImpl extends JpsDependencyElementBase implements JpsModuleDependency { - private static final JpsElementKind MODULE_REFERENCE_KIND = new JpsElementKind(); + private static final JpsElementKind MODULE_REFERENCE_KIND = new JpsElementKindBase("module reference"); public JpsModuleDependencyImpl(final JpsModuleReference moduleReference) { super(); diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java index 7aabc147cae2..adb148b5da3d 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleImpl.java @@ -16,16 +16,17 @@ import java.util.List; */ public class JpsModuleImpl extends JpsNamedCompositeElementBase implements JpsModule { private static final JpsTypedDataKind> TYPED_DATA_KIND = new JpsTypedDataKind>(); - private static final JpsElementKind CONTENT_ROOTS_KIND = new JpsElementKind(); - private static final JpsElementKind EXCLUDED_ROOTS_KIND = new JpsElementKind(); - public static final JpsElementKind DEPENDENCIES_LIST_KIND = new JpsElementKind(); + private static final JpsUrlListKind CONTENT_ROOTS_KIND = new JpsUrlListKind("content roots"); + private static final JpsUrlListKind EXCLUDED_ROOTS_KIND = new JpsUrlListKind("excluded roots"); + public static final JpsElementKind DEPENDENCIES_LIST_KIND = + new JpsElementKindBase("dependencies"); public JpsModuleImpl(JpsModuleType type, @NotNull String name) { super(name); myContainer.setChild(TYPED_DATA_KIND, new JpsTypedDataImpl>(type)); - myContainer.setChild(CONTENT_ROOTS_KIND, new JpsUrlListImpl()); - myContainer.setChild(EXCLUDED_ROOTS_KIND, new JpsUrlListImpl()); + myContainer.setChild(CONTENT_ROOTS_KIND); + myContainer.setChild(EXCLUDED_ROOTS_KIND); myContainer.setChild(DEPENDENCIES_LIST_KIND, new JpsDependenciesListImpl()); myContainer.setChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); myContainer.setChild(JpsModuleSourceRootKind.ROOT_COLLECTION_KIND); @@ -115,7 +116,12 @@ public class JpsModuleImpl extends JpsNamedCompositeElementBase type, @NotNull String name) { - final JpsElementCollectionImpl collection = myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND); - return collection.addChild(new JpsLibraryImpl(name, type)); + return addModuleLibrary(new JpsLibraryImpl(name, type)); + } + + @NotNull + @Override + public JpsLibrary addModuleLibrary(final @NotNull JpsLibrary library) { + return myContainer.getChild(JpsLibraryKind.LIBRARIES_COLLECTION_KIND).addChild(library); } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleKind.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleKind.java index 74621d367f0c..affce588f0b5 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleKind.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleKind.java @@ -4,22 +4,28 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.JpsElementKind; import org.jetbrains.jps.model.JpsEventDispatcher; import org.jetbrains.jps.model.impl.JpsElementCollectionKind; +import org.jetbrains.jps.model.impl.JpsElementKindBase; +import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.module.JpsModuleListener; /** * @author nik */ -public class JpsModuleKind extends JpsElementKind { - public static final JpsElementKind INSTANCE = new JpsModuleKind(); - public static final JpsElementCollectionKind MODULE_COLLECTION_KIND = new JpsElementCollectionKind(INSTANCE); +public class JpsModuleKind extends JpsElementKindBase { + public static final JpsElementKind INSTANCE = new JpsModuleKind(); + public static final JpsElementCollectionKind MODULE_COLLECTION_KIND = new JpsElementCollectionKind(INSTANCE); + + public JpsModuleKind() { + super("module"); + } @Override - public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsModuleImpl element) { + public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsModule element) { dispatcher.getPublisher(JpsModuleListener.class).moduleAdded(element); } @Override - public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsModuleImpl element) { + public void fireElementRemoved(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsModule element) { dispatcher.getPublisher(JpsModuleListener.class).moduleRemoved(element); } } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootKind.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootKind.java index 70e25abff2dc..11532f8a5f1b 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootKind.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsModuleSourceRootKind.java @@ -1,7 +1,7 @@ package org.jetbrains.jps.model.module.impl; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.impl.JpsElementKindBase; import org.jetbrains.jps.model.JpsEventDispatcher; import org.jetbrains.jps.model.impl.JpsElementCollectionKind; import org.jetbrains.jps.model.module.JpsModuleSourceRootListener; @@ -9,10 +9,14 @@ import org.jetbrains.jps.model.module.JpsModuleSourceRootListener; /** * @author nik */ -public class JpsModuleSourceRootKind extends JpsElementKind { +public class JpsModuleSourceRootKind extends JpsElementKindBase { public static final JpsModuleSourceRootKind INSTANCE = new JpsModuleSourceRootKind(); public static final JpsElementCollectionKind ROOT_COLLECTION_KIND = new JpsElementCollectionKind(INSTANCE); + public JpsModuleSourceRootKind() { + super("module source root"); + } + @Override public void fireElementAdded(@NotNull JpsEventDispatcher dispatcher, @NotNull JpsModuleSourceRootImpl element) { dispatcher.getPublisher(JpsModuleSourceRootListener.class).sourceRootAdded(element); diff --git a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkReferencesTableImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkReferencesTableImpl.java index 4b7c81cbecd6..b8c0462ffcb7 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkReferencesTableImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/module/impl/JpsSdkReferencesTableImpl.java @@ -2,6 +2,7 @@ package org.jetbrains.jps.model.module.impl; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.JpsElementKind; +import org.jetbrains.jps.model.impl.JpsElementKindBase; import org.jetbrains.jps.model.impl.JpsCompositeElementBase; import org.jetbrains.jps.model.library.JpsLibraryReference; import org.jetbrains.jps.model.library.JpsSdkType; @@ -11,7 +12,7 @@ import org.jetbrains.jps.model.module.JpsSdkReferencesTable; * @author nik */ public class JpsSdkReferencesTableImpl extends JpsCompositeElementBase implements JpsSdkReferencesTable { - public static final JpsElementKind KIND = new JpsElementKind(); + public static final JpsElementKind KIND = new JpsElementKindBase("sdk references"); public JpsSdkReferencesTableImpl() { super(); @@ -37,10 +38,11 @@ public class JpsSdkReferencesTableImpl extends JpsCompositeElementBase { + private static class JpsSdkReferenceKind extends JpsElementKindBase { private final JpsSdkType myType; private JpsSdkReferenceKind(@NotNull JpsSdkType type) { + super("sdk reference " + type); myType = type; } diff --git a/jps/model-impl/src/org/jetbrains/jps/service/impl/JpsServiceManagerImpl.java b/jps/model-impl/src/org/jetbrains/jps/service/impl/JpsServiceManagerImpl.java index 4f9c546a4cef..960bcff17879 100644 --- a/jps/model-impl/src/org/jetbrains/jps/service/impl/JpsServiceManagerImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/service/impl/JpsServiceManagerImpl.java @@ -3,6 +3,7 @@ package org.jetbrains.jps.service.impl; import org.jetbrains.jps.service.JpsServiceManager; import java.util.Iterator; +import java.util.List; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; import java.util.concurrent.ConcurrentHashMap; @@ -12,6 +13,7 @@ import java.util.concurrent.ConcurrentHashMap; */ public class JpsServiceManagerImpl extends JpsServiceManager { private final ConcurrentHashMap myServices = new ConcurrentHashMap(); + private final ConcurrentHashMap> myExtensions = new ConcurrentHashMap>(); @Override public T getService(Class serviceClass) { @@ -24,10 +26,16 @@ public class JpsServiceManagerImpl extends JpsServiceManager { } service = iterator.next(); if (iterator.hasNext()) { - throw new ServiceConfigurationError("More than one implementation for " + serviceClass + " found: " + service.getClass() + " and " + iterator.next().getClass()); + throw new ServiceConfigurationError( + "More than one implementation for " + serviceClass + " found: " + service.getClass() + " and " + iterator.next().getClass()); } myServices.putIfAbsent(serviceClass, service); } return service; } + + @Override + public Iterable getExtensions(Class extensionClass) { + return ServiceLoader.load(extensionClass); + } } diff --git a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsJavaExtensionTest.java b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsJavaExtensionTest.java index 0b5609390503..3e66b86643d5 100644 --- a/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsJavaExtensionTest.java +++ b/jps/model-impl/testSrc/org/jetbrains/jps/model/JpsJavaExtensionTest.java @@ -1,11 +1,6 @@ package org.jetbrains.jps.model; -import org.jetbrains.jps.model.java.JpsJavaDependencyExtension; -import org.jetbrains.jps.model.java.JpsJavaDependencyScope; -import org.jetbrains.jps.model.java.JpsJavaLibraryType; -import org.jetbrains.jps.model.java.JpsJavaModuleType; -import org.jetbrains.jps.model.java.impl.JavaModuleExtensionKind; -import org.jetbrains.jps.model.java.impl.JpsJavaDependencyExtensionKind; +import org.jetbrains.jps.model.java.*; import org.jetbrains.jps.model.library.JpsLibrary; import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsLibraryDependency; @@ -17,8 +12,10 @@ import org.jetbrains.jps.model.module.JpsModule; public class JpsJavaExtensionTest extends JpsModelTestCase { public void testModule() { final JpsModule module = myModel.getProject().addModule(JpsJavaModuleType.INSTANCE, "m"); - JavaModuleExtensionKind.getExtension(module).setOutputUrl("file://path"); - assertEquals("file://path", JavaModuleExtensionKind.getExtension(module).getOutputUrl()); + final JpsJavaModuleExtension extension = JpsJavaExtensionService.getInstance().getOrCreateModuleExtension(module); + extension.setOutputUrl("file://path"); + assertEquals("file://path", + module.getContainer().getChild(JpsJavaExtensionService.getInstance().getModuleExtensionKind()).getOutputUrl()); } public void testDependency() { @@ -26,12 +23,14 @@ public class JpsJavaExtensionTest extends JpsModelTestCase { final JpsModule module = model.getProject().addModule(JpsJavaModuleType.INSTANCE, "m"); final JpsLibrary library = model.getProject().addLibrary(JpsJavaLibraryType.INSTANCE, "l"); final JpsLibraryDependency dependency = module.getDependenciesList().addLibraryDependency(library); - JpsJavaDependencyExtensionKind.getExtension(dependency).setScope(JpsJavaDependencyScope.TEST); - JpsJavaDependencyExtensionKind.getExtension(dependency).setExported(true); + JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(dependency).setScope(JpsJavaDependencyScope.TEST); + JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(dependency).setExported(true); model.commit(); - final JpsDependencyElement dep = assertOneElement(assertOneElement(myModel.getProject().getModules()).getDependenciesList().getDependencies()); - final JpsJavaDependencyExtension extension = dep.getContainer().getChild(JpsJavaDependencyExtensionKind.INSTANCE); + final JpsDependencyElement dep = + assertOneElement(assertOneElement(myModel.getProject().getModules()).getDependenciesList().getDependencies()); + final JpsJavaDependencyExtension extension = + dep.getContainer().getChild(JpsJavaExtensionService.getInstance().getDependencyExtensionKind()); assertTrue(extension.isExported()); assertSame(JpsJavaDependencyScope.TEST, extension.getScope()); } diff --git a/jps/model-serialization/jps-model-serialization.iml b/jps/model-serialization/jps-model-serialization.iml new file mode 100644 index 000000000000..2ed39f108303 --- /dev/null +++ b/jps/model-serialization/jps-model-serialization.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/jps/model-serialization/src/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelLoaderExtension b/jps/model-serialization/src/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelLoaderExtension new file mode 100644 index 000000000000..4a1c8009b1c3 --- /dev/null +++ b/jps/model-serialization/src/META-INF/services/org.jetbrains.jps.model.serialization.JpsModelLoaderExtension @@ -0,0 +1 @@ +org.jetbrains.jps.model.serialization.java.JpsJavaModelLoaderExtension \ No newline at end of file diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableLoader.java new file mode 100644 index 000000000000..ee53d55a93a9 --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLibraryTableLoader.java @@ -0,0 +1,84 @@ +package org.jetbrains.jps.model.serialization; + +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.util.containers.MultiMap; +import org.jdom.Element; +import org.jetbrains.jps.model.JpsElementFactory; +import org.jetbrains.jps.model.java.JpsJavaLibraryType; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsLibraryRootType; +import org.jetbrains.jps.model.library.JpsLibraryType; +import org.jetbrains.jps.model.library.JpsOrderRootType; +import org.jetbrains.jps.service.JpsServiceManager; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author nik + */ +public class JpsLibraryTableLoader { + private static final Map PREDEFINED_ROOT_TYPES = new HashMap(); + + static { + PREDEFINED_ROOT_TYPES.put("CLASSES", JpsOrderRootType.COMPILED); + PREDEFINED_ROOT_TYPES.put("SOURCES", JpsOrderRootType.SOURCES); + } + + public static void loadLibraries(Element libraryTableElement, List result) { + for (Element libraryElement : JDOMUtil.getChildren(libraryTableElement, "library")) { + JpsLibrary library = loadLibrary(libraryElement); + result.add(library); + } + } + + public static JpsLibrary loadLibrary(Element libraryElement) { + String name = libraryElement.getAttributeValue("name"); + String typeId = libraryElement.getAttributeValue("type"); + JpsLibrary library = JpsElementFactory.getInstance().createLibrary(name, getLibraryType(typeId)); + + MultiMap jarDirectories = new MultiMap(); + MultiMap recursiveJarDirectories = new MultiMap(); + for (Element jarDirectory : JDOMUtil.getChildren(libraryElement, "jarDirectory")) { + String url = jarDirectory.getAttributeValue("url"); + String rootType = jarDirectory.getAttributeValue("type"); + boolean recursive = Boolean.parseBoolean(jarDirectory.getAttributeValue("recursive")); + jarDirectories.putValue(getRootType(rootType), url); + if (recursive) { + recursiveJarDirectories.putValue(getRootType(rootType), url); + } + } + for (Element rootsElement : JDOMUtil.getChildren(libraryElement)) { + final String rootTypeId = rootsElement.getName(); + if (!rootTypeId.equals("jarDirectory")) { + final JpsOrderRootType rootType = getRootType(rootTypeId); + for (Element rootElement : JDOMUtil.getChildren(rootsElement, "root")) { + String url = rootElement.getAttributeValue("url"); + final boolean jarDirectory = jarDirectories.get(rootType).contains(url); + final boolean recursive = recursiveJarDirectories.get(rootType).contains(url); + library.addUrl(url, new JpsLibraryRootType(rootType, jarDirectory, recursive)); + } + } + } + return library; + } + + private static JpsOrderRootType getRootType(String rootTypeId) { + final JpsOrderRootType type = PREDEFINED_ROOT_TYPES.get(rootTypeId); + if (type != null) { + return type; + } + for (JpsModelLoaderExtension extension : JpsServiceManager.getInstance().getExtensions(JpsModelLoaderExtension.class)) { + final JpsOrderRootType rootType = extension.getRootType(rootTypeId); + if (rootType != null) { + return rootType; + } + } + return JpsOrderRootType.COMPILED; + } + + private static JpsLibraryType getLibraryType(String typeId) { + return JpsJavaLibraryType.INSTANCE; + } +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java new file mode 100644 index 000000000000..6a889b3b7f65 --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModelLoaderExtension.java @@ -0,0 +1,38 @@ +package org.jetbrains.jps.model.serialization; + +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.JpsElementReference; +import org.jetbrains.jps.model.library.JpsOrderRootType; +import org.jetbrains.jps.model.library.JpsSdkType; +import org.jetbrains.jps.model.module.JpsDependencyElement; +import org.jetbrains.jps.model.module.JpsModule; + +/** + * @author nik + */ +public abstract class JpsModelLoaderExtension { + + public void loadRootModel(@NotNull JpsModule module, @NotNull Element rootModel) { + } + + @Nullable + public JpsOrderRootType getRootType(@NotNull String typeId) { + return null; + } + + @Nullable + public JpsSdkType getSdkType(@NotNull String typeId) { + return null; + } + + public void loadModuleDependencyProperties(JpsDependencyElement dependency, Element orderEntry) { + } + + @Nullable + public JpsElementReference createLibraryTableReference(String tableLevel) { + return null; + } +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleComponentSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleComponentSerializer.java new file mode 100644 index 000000000000..08befb67ee9b --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleComponentSerializer.java @@ -0,0 +1,15 @@ +package org.jetbrains.jps.model.serialization; + +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; + +/** + * @author nik + */ +public abstract class JpsModuleComponentSerializer { + + @NotNull + public abstract String getComponentName(); + + public abstract void loadComponent(@NotNull Element component); +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleLoader.java new file mode 100644 index 000000000000..17b560a893be --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsModuleLoader.java @@ -0,0 +1,120 @@ +package org.jetbrains.jps.model.serialization; + +import org.jdom.Element; +import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.JpsElementFactory; +import org.jetbrains.jps.model.JpsElementReference; +import org.jetbrains.jps.model.java.*; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.JpsSdkType; +import org.jetbrains.jps.model.module.*; +import org.jetbrains.jps.service.JpsServiceManager; + +import static com.intellij.openapi.util.JDOMUtil.getChildren; + +/** + * @author nik + */ +public class JpsModuleLoader { + private static final String URL_ATTRIBUTE = "url"; + + public static void loadRootModel(JpsModule module, Element rootModelComponent) { + for (Element contentElement : getChildren(rootModelComponent, "content")) { + final String url = contentElement.getAttributeValue(URL_ATTRIBUTE); + module.getContentRootsList().addUrl(url); + for (Element sourceElement : getChildren(contentElement, "sourceFolder")) { + final String sourceUrl = sourceElement.getAttributeValue(URL_ATTRIBUTE); + final String packagePrefix = sourceElement.getAttributeValue("packagePrefix"); + final boolean testSource = Boolean.parseBoolean(sourceElement.getAttributeValue("isTestSource")); + final JavaSourceRootType rootType = testSource ? JavaSourceRootType.SOURCE : JavaSourceRootType.TEST_SOURCE; + module.addSourceRoot(rootType, sourceUrl, new JavaSourceRootProperties(packagePrefix)); + } + for (Element excludeElement : getChildren(contentElement, "excludeFolder")) { + module.getExcludeRootsList().addUrl(excludeElement.getAttributeValue(URL_ATTRIBUTE)); + } + } + + final JpsDependenciesList dependenciesList = module.getDependenciesList(); + final JpsElementFactory elementFactory = JpsElementFactory.getInstance(); + int moduleLibraryNum = 0; + for (Element orderEntry : getChildren(rootModelComponent, "orderEntry")) { + String type = orderEntry.getAttributeValue("type"); + if ("sourceFolder".equals(type)) { + dependenciesList.addModuleSourceDependency(); + } + else if ("jdk".equals(type)) { + String sdkName = orderEntry.getAttributeValue("jdkName"); + String sdkTypeId = orderEntry.getAttributeValue("jskType"); + final JpsSdkType sdkType = getSdkType(sdkTypeId); + dependenciesList.addSdkDependency(sdkType); + module.getSdkReferencesTable() + .setSdkReference(sdkType, elementFactory.createLibraryReference(sdkName, elementFactory.createGlobalReference())); + } + else if ("inheritedJdk".equals(type)) { + dependenciesList.addSdkDependency(JpsJavaSdkType.INSTANCE); + } + else if ("library".equals(type)) { + String name = orderEntry.getAttributeValue("name"); + String level = orderEntry.getAttributeValue("level"); + final JpsLibraryDependency dependency = + dependenciesList.addLibraryDependency(elementFactory.createLibraryReference(name, createLibraryTableReference(level))); + loadModuleDependencyProperties(dependency, orderEntry); + } + else if ("module-library".equals(type)) { + final Element moduleLibraryElement = orderEntry.getChild("library"); + final JpsLibrary library = JpsLibraryTableLoader.loadLibrary(moduleLibraryElement); + module.addModuleLibrary(library); + + final JpsLibraryDependency dependency = dependenciesList.addLibraryDependency(library); + loadModuleDependencyProperties(dependency, orderEntry); + moduleLibraryNum++; + } + else if ("module".equals(type)) { + String name = orderEntry.getAttributeValue("module-name"); + final JpsModuleDependency dependency = dependenciesList.addModuleDependency(elementFactory.createModuleReference(name)); + loadModuleDependencyProperties(dependency, orderEntry); + } + } + + for (JpsModelLoaderExtension extension : getLoaderExtensions()) { + extension.loadRootModel(module, rootModelComponent); + } + } + + private static void loadModuleDependencyProperties(JpsDependencyElement dependency, Element orderEntry) { + for (JpsModelLoaderExtension extension : getLoaderExtensions()) { + extension.loadModuleDependencyProperties(dependency, orderEntry); + } + } + + private static JpsElementReference createLibraryTableReference(String level) { + JpsElementFactory elementFactory = JpsElementFactory.getInstance(); + if (level.equals("project")) { + return elementFactory.createProjectReference(); + } + if (level.equals("application")) { + return elementFactory.createGlobalReference(); + } + for (JpsModelLoaderExtension extension : getLoaderExtensions()) { + final JpsElementReference reference = extension.createLibraryTableReference(level); + if (reference != null) { + return reference; + } + } + throw new UnsupportedOperationException(); + } + + private static Iterable getLoaderExtensions() { + return JpsServiceManager.getInstance().getExtensions(JpsModelLoaderExtension.class); + } + + public static JpsSdkType getSdkType(String typeId) { + for (JpsModelLoaderExtension extension : getLoaderExtensions()) { + final JpsSdkType type = extension.getSdkType(typeId); + if (type != null) { + return type; + } + } + return JpsJavaSdkType.INSTANCE; + } +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java new file mode 100644 index 000000000000..9e68ed669178 --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsProjectLoader.java @@ -0,0 +1,144 @@ +package org.jetbrains.jps.model.serialization; + +import com.intellij.openapi.components.ExpandMacroToPathMap; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; +import org.jdom.Element; +import org.jdom.JDOMException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsElementFactory; +import org.jetbrains.jps.model.JpsGlobal; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.java.JpsJavaModuleType; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.module.JpsModuleType; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; + +/** + * @author nik + */ +public class JpsProjectLoader { + private final JpsGlobal myGlobal; + private final JpsProject myProject; + private ExpandMacroToPathMap myMacroToPathMap; + + public JpsProjectLoader(JpsGlobal global, JpsProject project) { + myGlobal = global; + myProject = project; + } + + public static void loadProject(JpsGlobal global, final JpsProject project, String projectPath) throws IOException { + new JpsProjectLoader(global, project).loadFromPath(projectPath); + } + + public void loadFromPath(String path) throws IOException { + File file = new File(path).getCanonicalFile(); + if (file.isFile() && path.endsWith(".ipr")) { + loadFromIpr(file); + } + else if (file.getName().equals(".idea")) { + loadFromDirectory(file); + } + else { + File ideaDirectory = new File(file, ".idea"); + if (ideaDirectory.exists()) { + loadFromDirectory(ideaDirectory); + } + else { + throw new IOException("Cannot find IntelliJ IDEA project files at " + path); + } + } + } + + private void loadFromDirectory(File dir) { + initMacroMap(dir.getParentFile()); + loadModules(loadRootElement(new File(dir, "modules.xml"))); + final File[] libraryFiles = new File(dir, "libraries").listFiles(); + if (libraryFiles != null) { + for (File libraryFile : libraryFiles) { + if (isXmlFile(libraryFile)) { + loadProjectLibraries(loadRootElement(libraryFile)); + } + } + } + } + + private void loadFromIpr(File iprFile) { + initMacroMap(iprFile.getParentFile()); + final Element root = loadRootElement(iprFile); + loadModules(root); + loadProjectLibraries(findComponent(root, "libraryTable")); + } + + private void initMacroMap(File projectBaseDir) { + myMacroToPathMap = new ExpandMacroToPathMap(); + myMacroToPathMap.addMacroExpand("PROJECT_DIR", FileUtil.toSystemIndependentName(projectBaseDir.getAbsolutePath())); + } + + private Element loadRootElement(final File file) { + try { + final Element element = JDOMUtil.loadDocument(file).getRootElement(); + myMacroToPathMap.substitute(element, SystemInfo.isFileSystemCaseSensitive); + return element; + } + catch (JDOMException e) { + throw new RuntimeException(e); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static boolean isXmlFile(File file) { + return file.isFile() && FileUtil.getNameWithoutExtension(file).equalsIgnoreCase("xml"); + } + + private void loadProjectLibraries(Element libraryTableElement) { + final ArrayList libraries = new ArrayList(); + JpsLibraryTableLoader.loadLibraries(libraryTableElement, libraries); + for (JpsLibrary library : libraries) { + myProject.addLibrary(library); + } + } + + private void loadModules(Element root) { + Element componentRoot = findComponent(root, "ProjectModuleManager"); + if (componentRoot == null) return; + final Element modules = componentRoot.getChild("modules"); + for (Element moduleElement : JDOMUtil.getChildren(modules, "module")) { + final String path = moduleElement.getAttributeValue("filepath"); + JpsModule module = loadModule(path); + myProject.addModule(module); + } + } + + private JpsModule loadModule(String path) { + final File file = new File(path); + String name = FileUtil.getNameWithoutExtension(file); + final Element moduleRoot = loadRootElement(file); + final String typeId = moduleRoot.getAttributeValue("type"); + final JpsModule module = JpsElementFactory.getInstance().createModule(name, getModuleType(typeId)); + JpsModuleLoader.loadRootModel(module, findComponent(moduleRoot, "NewModuleRootManager")); + return module; + } + + @Nullable + private static Element findComponent(Element root, String componentName) { + for (Element element : JDOMUtil.getChildren(root, "component")) { + if (componentName.equals(element.getAttributeValue("name"))) { + return element; + } + } + return null; + } + + private static JpsModuleType getModuleType(@NotNull String typeId) { + return JpsJavaModuleType.INSTANCE; + } +} diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelLoaderExtension.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelLoaderExtension.java new file mode 100644 index 000000000000..79f70d0383c4 --- /dev/null +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/java/JpsJavaModelLoaderExtension.java @@ -0,0 +1,83 @@ +package org.jetbrains.jps.model.serialization.java; + +import com.intellij.openapi.util.JDOMUtil; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.JpsUrlList; +import org.jetbrains.jps.model.java.*; +import org.jetbrains.jps.model.library.JpsOrderRootType; +import org.jetbrains.jps.model.module.JpsDependencyElement; +import org.jetbrains.jps.model.module.JpsModule; +import org.jetbrains.jps.model.serialization.JpsModelLoaderExtension; + +/** + * @author nik + */ +public class JpsJavaModelLoaderExtension extends JpsModelLoaderExtension { + @Override + public void loadRootModel(@NotNull JpsModule module, @NotNull Element rootModel) { + loadExplodedDirectoryExtension(module, rootModel); + loadJavaModuleExtension(module, rootModel); + } + + @Override + public void loadModuleDependencyProperties(JpsDependencyElement dependency, Element entry) { + boolean exported = entry.getAttributeValue("exported") != null; + String scopeName = entry.getAttributeValue("scope"); + JpsJavaDependencyScope scope = scopeName != null ? JpsJavaDependencyScope.valueOf(scopeName) : JpsJavaDependencyScope.COMPILE; + + final JpsJavaDependencyExtension extension = JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(dependency); + extension.setExported(exported); + extension.setScope(scope); + } + + @Override + public JpsOrderRootType getRootType(@NotNull String typeId) { + if (typeId.equals("JAVADOC")) { + return JpsOrderRootType.DOCUMENTATION; + } + else if (typeId.equals("ANNOTATIONS")) { + return JpsAnnotationRootType.INSTANCE; + } + return null; + } + + private static void loadExplodedDirectoryExtension(JpsModule module, Element rootModelComponent) { + final Element exploded = rootModelComponent.getChild("exploded"); + if (exploded != null) { + final ExplodedDirectoryModuleExtension extension = + JpsJavaExtensionService.getInstance().getOrCreateExplodedDirectoryExtension(module); + extension.setExcludeExploded(rootModelComponent.getChild("exclude-exploded") != null); + extension.setExplodedUrl(exploded.getAttributeValue("url")); + } + } + + private static void loadJavaModuleExtension(JpsModule module, Element rootModelComponent) { + final JpsJavaModuleExtension extension = JpsJavaExtensionService.getInstance().getOrCreateModuleExtension(module); + final Element outputTag = rootModelComponent.getChild("output"); + if (outputTag != null) { + extension.setOutputUrl(outputTag.getAttributeValue("url")); + } + final Element testOutputTag = rootModelComponent.getChild("output-test"); + if (testOutputTag != null) { + extension.setOutputUrl(testOutputTag.getAttributeValue("url")); + } + extension.setInheritOutput(Boolean.parseBoolean(rootModelComponent.getAttributeValue("inherit-compiler-output"))); + extension.setExcludeOutput(rootModelComponent.getChild("exclude-output") != null); + + loadAdditionalRoots(rootModelComponent, "annotation-paths", extension.getAnnotationRoots()); + loadAdditionalRoots(rootModelComponent, "javadoc-paths", extension.getJavadocRoots()); + + final String languageLevel = rootModelComponent.getAttributeValue("LANGUAGE_LEVEL"); + if (languageLevel != null) { + extension.setLanguageLevel(LanguageLevel.valueOf(languageLevel)); + } + } + + private static void loadAdditionalRoots(Element rootModelComponent, final String rootsTagName, final JpsUrlList result) { + final Element roots = rootModelComponent.getChild(rootsTagName); + for (Element root : JDOMUtil.getChildren(roots, "root")) { + result.addUrl(root.getAttributeValue("url")); + } + } +} diff --git a/jps/model-serialization/testData/iprProject/iprProject.iml b/jps/model-serialization/testData/iprProject/iprProject.iml new file mode 100644 index 000000000000..dbf84a250f51 --- /dev/null +++ b/jps/model-serialization/testData/iprProject/iprProject.iml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jps/model-serialization/testData/iprProject/iprProject.ipr b/jps/model-serialization/testData/iprProject/iprProject.ipr new file mode 100644 index 000000000000..341eae6831cd --- /dev/null +++ b/jps/model-serialization/testData/iprProject/iprProject.ipr @@ -0,0 +1,59 @@ + + + + + $PROJECT_DIR$/out/artifacts/explodedWar + + + + + + + + + + + + + + + $PROJECT_DIR$/out/artifacts/archive + + + + + + + + + + + $PROJECT_DIR$/out/artifacts/files + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsModuleSerializationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsModuleSerializationTest.java new file mode 100644 index 000000000000..20087a1e0326 --- /dev/null +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsModuleSerializationTest.java @@ -0,0 +1,31 @@ +package org.jetbrains.jps.model.serialization; + +import com.intellij.openapi.application.PathManager; +import org.jetbrains.jps.model.JpsModelTestCase; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.module.JpsModule; + +import java.io.IOException; + +/** + * @author nik + */ +public class JpsModuleSerializationTest extends JpsModelTestCase { + public void test() { + loadProject("iprProject/iprProject.ipr"); + final JpsModule module = assertOneElement(myModel.getProject().getModules()); + assertEquals("iprProject", module.getName()); + final JpsLibrary library = assertOneElement(myModel.getProject().getLibraries()); + assertEquals("junit", library.getName()); + } + + private void loadProject(final String path) { + try { + final String projectPath = PathManager.getHomePath() + "/community/jps/model-serialization/testData/" + path; + JpsProjectLoader.loadProject(myModel.getGlobal(), myModel.getProject(), projectPath); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java index bd739573dcfd..825d66cd93d9 100644 --- a/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java +++ b/jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java @@ -78,6 +78,14 @@ public class Mappings { private IntObjectMultiMaplet mySourceFileToUsages; private IntIntMaplet myClassToSourceFile; + private IntIntTransientMultiMaplet myRemovedSuperClasses; + + private void registerRemovedSuperClass (final int aClass, final int superClass) { + assert (myRemovedSuperClasses != null); + myIsDifferentiated = true; + myRemovedSuperClasses.put(superClass, aClass); + } + private Mappings(final Mappings base) throws IOException { myLock = base.myLock; myIsDelta = true; @@ -115,6 +123,8 @@ public class Mappings { myDebugS = myContext.getLogger(LOG); } + myRemovedSuperClasses = myIsDelta ? new IntIntTransientMultiMaplet() : null; + if (myIsDelta && myDeltaIsTransient) { myClassToSubclasses = new IntIntTransientMultiMaplet(); myClassToClassDependency = new IntIntTransientMultiMaplet(); @@ -193,6 +203,10 @@ public class Mappings { } } + public IntIntTransientMultiMaplet getRemovedSuperClasses() { + return myRemovedSuperClasses; + } + private static class Option { final X myValue; @@ -653,10 +667,6 @@ public class Mappings { } } - void affectAll(final int className, final Collection affectedFiles) { - affectAll(className, affectedFiles, null); - } - void affectAll(final int className, final Collection affectedFiles, final DependentFilesFilter filter) { final TIntHashSet dependants = myClassToClassDependency.get(className); @@ -1533,6 +1543,16 @@ public class Mappings { final boolean interfacesChanged = !diff.interfaces().unchanged(); final boolean signatureChanged = (diff.base() & Difference.SIGNATURE) > 0; + if (superClassChanged) { + myDelta.registerRemovedSuperClass(it.name, ((TypeRepr.ClassType)it.superClass).className); + } + + if (interfacesChanged) { + for (final TypeRepr.AbstractType typ: diff.interfaces().removed()) { + myDelta.registerRemovedSuperClass(it.name, ((TypeRepr.ClassType)typ).className); + } + } + if (superClassChanged || interfacesChanged || signatureChanged) { debug("Superclass changed: ", superClassChanged); debug("Interfaces changed: ", interfacesChanged); @@ -1975,6 +1995,22 @@ public class Mappings { return true; } }); + + delta.getRemovedSuperClasses ().forEachEntry(new TIntObjectProcedure() { + @Override + public boolean execute(final int a, final TIntHashSet b) { + if (!compiledClasses.contains(a)) { + final TIntHashSet old = myClassToSubclasses.get(a); + + if (old != null) { + old.removeAll(b.toArray()); + myClassToSubclasses.replace(a, old); + } + } + + return true; + } + }); } else { subclassesTrashBin.forEachEntry(new TIntObjectProcedure() { diff --git a/lib/log4j.dtd b/lib/log4j.dtd new file mode 100644 index 000000000000..1aabd96c3beb --- /dev/null +++ b/lib/log4j.dtd @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/platform/core-api/src/com/intellij/psi/codeStyle/SuggestedNameInfo.java b/platform/core-api/src/com/intellij/psi/codeStyle/SuggestedNameInfo.java index 8aa64bbac7b2..a68e7ccb59b0 100644 --- a/platform/core-api/src/com/intellij/psi/codeStyle/SuggestedNameInfo.java +++ b/platform/core-api/src/com/intellij/psi/codeStyle/SuggestedNameInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -22,13 +22,15 @@ import com.intellij.util.ArrayUtil; * Represents an array of suggested variable names and allows to keep statistics on * which of the suggestions has been accepted. * - * @see JavaCodeStyleManager#suggestVariableName(VariableKind, String, com.intellij.psi.PsiExpression, com.intellij.psi.PsiType) + * (see JavaCodeStyleManager.suggestVariableName() methods). */ public abstract class SuggestedNameInfo { + @SuppressWarnings("UnusedDeclaration") public static final Key SUGGESTED_NAME_INFO_KEY = Key.create("SUGGESTED_NAME_INFO_KEY"); + public static final SuggestedNameInfo NULL_INFO = new SuggestedNameInfo(ArrayUtil.EMPTY_STRING_ARRAY) { @Override - public void nameChoosen(String name) {} + public void nameChosen(String name) {} }; /** @@ -41,13 +43,17 @@ public abstract class SuggestedNameInfo { } /** - * Should be called when one of the suggested names has been chosen by the user, to - * update the statistics on name usage. + *

Should be called when one of the suggested names has been chosen by the user, to + * update the statistics on name usage.

+ *

Note to implementers: do not leave this method non-overridden as it going to be abstract.

* * @param name the accepted suggestion. */ - public abstract void nameChoosen(String name); + public void nameChosen(String name) { } + /** @deprecated override {@linkplain #nameChosen(String)} instead (to remove in IDEA 13) */ + @SuppressWarnings("UnusedDeclaration") + public void nameChoosen(String name) { nameChosen(name); } public static class Delegate extends SuggestedNameInfo { SuggestedNameInfo myDelegate; @@ -58,9 +64,8 @@ public abstract class SuggestedNameInfo { } @Override - public void nameChoosen(final String name) { - myDelegate.nameChoosen(name); + public void nameChosen(final String name) { + myDelegate.nameChosen(name); } } - } diff --git a/platform/core-api/src/com/intellij/util/PlatformIcons.java b/platform/core-api/src/com/intellij/util/PlatformIcons.java index 1fcb335de91e..2974eeee030b 100644 --- a/platform/core-api/src/com/intellij/util/PlatformIcons.java +++ b/platform/core-api/src/com/intellij/util/PlatformIcons.java @@ -72,7 +72,6 @@ public interface PlatformIcons { Icon UI_FORM_ICON = AllIcons.FileTypes.UiForm; Icon JSP_ICON = AllIcons.FileTypes.Jsp; Icon SMALL_VCS_CONFIGURABLE = AllIcons.General.SmallConfigurableVcs; - Icon VCS_SMALL_TAB = AllIcons.General.VcsSmallTab; Icon GROUP_BY_PACKAGES = AllIcons.Toolbar.Folders; Icon ADD_ICON = IconUtil.getAddIcon(); Icon DELETE_ICON = IconUtil.getRemoveIcon(); diff --git a/platform/core-impl/src/com/intellij/openapi/editor/ex/util/SegmentArray.java b/platform/core-impl/src/com/intellij/openapi/editor/ex/util/SegmentArray.java index 5d27e366e4f6..1a254ff25812 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/ex/util/SegmentArray.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/ex/util/SegmentArray.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -72,8 +72,11 @@ public class SegmentArray { if (newArraySize == 0) { newArraySize = 16; } - while (newArraySize <= index) { - newArraySize = newArraySize * 120 / 100; + else { + newArraySize = newArraySize * 12 / 10; + } + if (index >= newArraySize) { + newArraySize = index * 12 / 10; } int[] newArray = new int[newArraySize]; System.arraycopy(array, 0, newArray, 0, array.length); @@ -89,8 +92,11 @@ public class SegmentArray { if (newArraySize == 0) { newArraySize = 16; } - while (newArraySize <= index) { - newArraySize = newArraySize * 120 / 100; + else { + newArraySize = newArraySize * 12 / 10; + } + if (index >= newArraySize) { + newArraySize = index * 12 / 10; } T[] newArray = (T[])Array.newInstance(array.getClass().getComponentType(), newArraySize); @@ -107,9 +113,12 @@ public class SegmentArray { if (newArraySize == 0) { newArraySize = 16; } - while (newArraySize <= index) { + else { newArraySize = newArraySize * 12 / 10; } + if (index >= newArraySize) { + newArraySize = index * 12 / 10; + } short[] newArray = new short[newArraySize]; System.arraycopy(array, 0, newArray, 0, array.length); return newArray; diff --git a/platform/icons/src/actions/exception.png b/platform/icons/src/actions/exception.png deleted file mode 100644 index 3c0afdaf49a8..000000000000 Binary files a/platform/icons/src/actions/exception.png and /dev/null differ diff --git a/platform/icons/src/actions/import.png b/platform/icons/src/actions/import.png deleted file mode 100644 index 860be14ca16a..000000000000 Binary files a/platform/icons/src/actions/import.png and /dev/null differ diff --git a/platform/icons/src/actions/modul.png b/platform/icons/src/actions/module.png similarity index 100% rename from platform/icons/src/actions/modul.png rename to platform/icons/src/actions/module.png diff --git a/platform/icons/src/ant/allJarsInDir.png b/platform/icons/src/ant/allJarsInDir.png deleted file mode 100644 index 5f61672cb487..000000000000 Binary files a/platform/icons/src/ant/allJarsInDir.png and /dev/null differ diff --git a/platform/icons/src/ant/filterError.png b/platform/icons/src/ant/filterError.png deleted file mode 100644 index 4ecc76c04e6b..000000000000 Binary files a/platform/icons/src/ant/filterError.png and /dev/null differ diff --git a/platform/icons/src/ant/filterInfo.png b/platform/icons/src/ant/filterInfo.png deleted file mode 100644 index b6e002a4ac7e..000000000000 Binary files a/platform/icons/src/ant/filterInfo.png and /dev/null differ diff --git a/platform/icons/src/ant/filterWarning.png b/platform/icons/src/ant/filterWarning.png deleted file mode 100644 index 6b6e92af1b9f..000000000000 Binary files a/platform/icons/src/ant/filterWarning.png and /dev/null differ diff --git a/platform/icons/src/debugger/attach.png b/platform/icons/src/debugger/attach.png deleted file mode 100644 index 8a09f79e1b3f..000000000000 Binary files a/platform/icons/src/debugger/attach.png and /dev/null differ diff --git a/platform/icons/src/debugger/detach.png b/platform/icons/src/debugger/detach.png deleted file mode 100644 index fd867a661d06..000000000000 Binary files a/platform/icons/src/debugger/detach.png and /dev/null differ diff --git a/platform/icons/src/debugger/pattern.png b/platform/icons/src/debugger/pattern.png deleted file mode 100644 index f5eb69857060..000000000000 Binary files a/platform/icons/src/debugger/pattern.png and /dev/null differ diff --git a/platform/icons/src/general/errorsOK.png b/platform/icons/src/general/errorsOK.png deleted file mode 100644 index 38d9a0841017..000000000000 Binary files a/platform/icons/src/general/errorsOK.png and /dev/null differ diff --git a/platform/icons/src/general/fix.png b/platform/icons/src/general/fix.png deleted file mode 100644 index 8ef10c9a0857..000000000000 Binary files a/platform/icons/src/general/fix.png and /dev/null differ diff --git a/platform/icons/src/general/separator.png b/platform/icons/src/general/separator.png deleted file mode 100644 index 2cb190e686df..000000000000 Binary files a/platform/icons/src/general/separator.png and /dev/null differ diff --git a/platform/icons/src/general/separatorV.png b/platform/icons/src/general/separatorV.png deleted file mode 100644 index 6f6ef147c66f..000000000000 Binary files a/platform/icons/src/general/separatorV.png and /dev/null differ diff --git a/platform/icons/src/general/template.png b/platform/icons/src/general/template.png deleted file mode 100644 index 01c35f470da8..000000000000 Binary files a/platform/icons/src/general/template.png and /dev/null differ diff --git a/platform/icons/src/general/warningsFound.png b/platform/icons/src/general/warningsFound.png deleted file mode 100644 index 0caeb9c4ec18..000000000000 Binary files a/platform/icons/src/general/warningsFound.png and /dev/null differ diff --git a/platform/icons/src/icons/inspector/collapseall.png b/platform/icons/src/icons/inspector/collapseall.png deleted file mode 100644 index a2b5f7e65004..000000000000 Binary files a/platform/icons/src/icons/inspector/collapseall.png and /dev/null differ diff --git a/platform/icons/src/icons/inspector/expandall.png b/platform/icons/src/icons/inspector/expandall.png deleted file mode 100644 index 0049c522ca4c..000000000000 Binary files a/platform/icons/src/icons/inspector/expandall.png and /dev/null differ diff --git a/platform/icons/src/ide/dnd/error.png b/platform/icons/src/ide/dnd/error.png deleted file mode 100644 index 1e41b4203638..000000000000 Binary files a/platform/icons/src/ide/dnd/error.png and /dev/null differ diff --git a/platform/icons/src/ide/tab.png b/platform/icons/src/ide/tab.png deleted file mode 100644 index ad44adead8c0..000000000000 Binary files a/platform/icons/src/ide/tab.png and /dev/null differ diff --git a/platform/icons/src/modules/edit.png b/platform/icons/src/modules/edit.png new file mode 100644 index 000000000000..bd9bca941726 Binary files /dev/null and b/platform/icons/src/modules/edit.png differ diff --git a/platform/icons/src/modules/excludeFolder.png b/platform/icons/src/modules/excludeFolder.png deleted file mode 100644 index 54f2ae2499b9..000000000000 Binary files a/platform/icons/src/modules/excludeFolder.png and /dev/null differ diff --git a/platform/icons/src/nodes/servletMapping.png b/platform/icons/src/nodes/servletMapping.png deleted file mode 100644 index 00a873b1b266..000000000000 Binary files a/platform/icons/src/nodes/servletMapping.png and /dev/null differ diff --git a/platform/icons/src/nodes/sql.png b/platform/icons/src/nodes/sql.png deleted file mode 100644 index 5ead39b675f3..000000000000 Binary files a/platform/icons/src/nodes/sql.png and /dev/null differ diff --git a/platform/icons/src/objectBrowser/bean.png b/platform/icons/src/objectBrowser/bean.png deleted file mode 100644 index deffd2d52604..000000000000 Binary files a/platform/icons/src/objectBrowser/bean.png and /dev/null differ diff --git a/platform/icons/src/objectBrowser/variable.png b/platform/icons/src/objectBrowser/variable.png deleted file mode 100644 index 2d95a75cd2de..000000000000 Binary files a/platform/icons/src/objectBrowser/variable.png and /dev/null differ diff --git a/platform/icons/src/general/documentation.png b/platform/icons/src/toolwindows/documentation.png similarity index 100% rename from platform/icons/src/general/documentation.png rename to platform/icons/src/toolwindows/documentation.png diff --git a/platform/icons/src/general/toolWindowAnt.png b/platform/icons/src/toolwindows/toolWindowAnt.png similarity index 100% rename from platform/icons/src/general/toolWindowAnt.png rename to platform/icons/src/toolwindows/toolWindowAnt.png diff --git a/platform/icons/src/general/toolWindowChanges.png b/platform/icons/src/toolwindows/toolWindowChanges.png similarity index 100% rename from platform/icons/src/general/toolWindowChanges.png rename to platform/icons/src/toolwindows/toolWindowChanges.png diff --git a/platform/icons/src/general/toolWindowCommander.png b/platform/icons/src/toolwindows/toolWindowCommander.png similarity index 100% rename from platform/icons/src/general/toolWindowCommander.png rename to platform/icons/src/toolwindows/toolWindowCommander.png diff --git a/platform/icons/src/general/toolWindowCoverage.png b/platform/icons/src/toolwindows/toolWindowCoverage.png similarity index 100% rename from platform/icons/src/general/toolWindowCoverage.png rename to platform/icons/src/toolwindows/toolWindowCoverage.png diff --git a/platform/icons/src/general/toolWindowCvs.png b/platform/icons/src/toolwindows/toolWindowCvs.png similarity index 100% rename from platform/icons/src/general/toolWindowCvs.png rename to platform/icons/src/toolwindows/toolWindowCvs.png diff --git a/platform/icons/src/general/toolWindowDebugger.png b/platform/icons/src/toolwindows/toolWindowDebugger.png similarity index 100% rename from platform/icons/src/general/toolWindowDebugger.png rename to platform/icons/src/toolwindows/toolWindowDebugger.png diff --git a/platform/icons/src/general/toolWindowFavorites.png b/platform/icons/src/toolwindows/toolWindowFavorites.png similarity index 100% rename from platform/icons/src/general/toolWindowFavorites.png rename to platform/icons/src/toolwindows/toolWindowFavorites.png diff --git a/platform/icons/src/general/toolWindowFind.png b/platform/icons/src/toolwindows/toolWindowFind.png similarity index 100% rename from platform/icons/src/general/toolWindowFind.png rename to platform/icons/src/toolwindows/toolWindowFind.png diff --git a/platform/icons/src/general/toolWindowHierarchy.png b/platform/icons/src/toolwindows/toolWindowHierarchy.png similarity index 100% rename from platform/icons/src/general/toolWindowHierarchy.png rename to platform/icons/src/toolwindows/toolWindowHierarchy.png diff --git a/platform/icons/src/general/toolWindowInspection.png b/platform/icons/src/toolwindows/toolWindowInspection.png similarity index 100% rename from platform/icons/src/general/toolWindowInspection.png rename to platform/icons/src/toolwindows/toolWindowInspection.png diff --git a/platform/icons/src/general/toolWindowMessages.png b/platform/icons/src/toolwindows/toolWindowMessages.png similarity index 100% rename from platform/icons/src/general/toolWindowMessages.png rename to platform/icons/src/toolwindows/toolWindowMessages.png diff --git a/platform/icons/src/general/toolWindowModuleDependencies.png b/platform/icons/src/toolwindows/toolWindowModuleDependencies.png similarity index 100% rename from platform/icons/src/general/toolWindowModuleDependencies.png rename to platform/icons/src/toolwindows/toolWindowModuleDependencies.png diff --git a/platform/icons/src/general/toolWindowPalette.png b/platform/icons/src/toolwindows/toolWindowPalette.png similarity index 100% rename from platform/icons/src/general/toolWindowPalette.png rename to platform/icons/src/toolwindows/toolWindowPalette.png diff --git a/platform/icons/src/general/toolWindowProject.png b/platform/icons/src/toolwindows/toolWindowProject.png similarity index 100% rename from platform/icons/src/general/toolWindowProject.png rename to platform/icons/src/toolwindows/toolWindowProject.png diff --git a/platform/icons/src/general/toolWindowRun.png b/platform/icons/src/toolwindows/toolWindowRun.png similarity index 100% rename from platform/icons/src/general/toolWindowRun.png rename to platform/icons/src/toolwindows/toolWindowRun.png diff --git a/platform/icons/src/general/toolWindowStructure.png b/platform/icons/src/toolwindows/toolWindowStructure.png similarity index 100% rename from platform/icons/src/general/toolWindowStructure.png rename to platform/icons/src/toolwindows/toolWindowStructure.png diff --git a/platform/icons/src/general/toolWindowTodo.png b/platform/icons/src/toolwindows/toolWindowTodo.png similarity index 100% rename from platform/icons/src/general/toolWindowTodo.png rename to platform/icons/src/toolwindows/toolWindowTodo.png diff --git a/platform/icons/src/general/vcsSmallTab.png b/platform/icons/src/toolwindows/vcsSmallTab.png similarity index 100% rename from platform/icons/src/general/vcsSmallTab.png rename to platform/icons/src/toolwindows/vcsSmallTab.png diff --git a/platform/icons/src/javaee/webToolWindow.png b/platform/icons/src/toolwindows/webToolWindow.png similarity index 100% rename from platform/icons/src/javaee/webToolWindow.png rename to platform/icons/src/toolwindows/webToolWindow.png diff --git a/platform/icons/src/webreferences/add.png b/platform/icons/src/webreferences/add.png deleted file mode 100644 index 2ffcd5f95d2a..000000000000 Binary files a/platform/icons/src/webreferences/add.png and /dev/null differ diff --git a/platform/icons/src/webreferences/properties.png b/platform/icons/src/webreferences/properties.png deleted file mode 100644 index 8eda095c85e5..000000000000 Binary files a/platform/icons/src/webreferences/properties.png and /dev/null differ diff --git a/platform/icons/src/webreferences/remove.png b/platform/icons/src/webreferences/remove.png deleted file mode 100644 index f9399c5aa6ea..000000000000 Binary files a/platform/icons/src/webreferences/remove.png and /dev/null differ diff --git a/platform/icons/src/xml/actions/add_column_after.png b/platform/icons/src/xml/actions/add_column_after.png deleted file mode 100644 index 4628f00f025b..000000000000 Binary files a/platform/icons/src/xml/actions/add_column_after.png and /dev/null differ diff --git a/platform/icons/src/xml/actions/add_column_before.png b/platform/icons/src/xml/actions/add_column_before.png deleted file mode 100644 index 95f08d75ce01..000000000000 Binary files a/platform/icons/src/xml/actions/add_column_before.png and /dev/null differ diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/NextPrevParameterAction.java b/platform/lang-api/src/com/intellij/codeInsight/completion/NextPrevParameterAction.java index 859da99d24af..87248caa69e6 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/NextPrevParameterAction.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/NextPrevParameterAction.java @@ -38,7 +38,7 @@ public abstract class NextPrevParameterAction extends CodeInsightAction { } @Override - protected CodeInsightActionHandler getHandler() { + public CodeInsightActionHandler getHandler() { return new Handler(); } diff --git a/platform/lang-api/src/com/intellij/execution/ExecutionManager.java b/platform/lang-api/src/com/intellij/execution/ExecutionManager.java index abb7212d2e2b..22a8bcd4beb5 100644 --- a/platform/lang-api/src/com/intellij/execution/ExecutionManager.java +++ b/platform/lang-api/src/com/intellij/execution/ExecutionManager.java @@ -40,4 +40,9 @@ public abstract class ExecutionManager { public abstract void startRunProfile(@NotNull RunProfileStarter starter, @NotNull RunProfileState state, @NotNull Project project, @NotNull Executor executor, @NotNull ExecutionEnvironment env); + + public abstract void restartRunProfile(@NotNull Project project, + @NotNull Executor executor, + @NotNull RunnerAndConfigurationSettings configuration); + } diff --git a/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java b/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java index 26a0944f9267..b483163243e7 100644 --- a/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java +++ b/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java @@ -56,4 +56,8 @@ public interface RunnerAndConfigurationSettings { void setEditBeforeRun(boolean b); boolean isEditBeforeRun(); + + void setSingleton(boolean singleton); + + boolean isSingleton(); } diff --git a/platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java b/platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java index bb97b8f80efc..47b7e35715d5 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/ConfigurationFactory.java @@ -76,4 +76,8 @@ public abstract class ConfigurationFactory { */ public void configureBeforeRunTaskDefaults(Key providerID, BeforeRunTask task) { } + + public boolean canConfigurationBeSingleton() { + return true; // Configuration may be marked as singleton by default + } } diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java new file mode 100644 index 000000000000..732976cf73a7 --- /dev/null +++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationsSettings.java @@ -0,0 +1,27 @@ +/* + * 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.execution.configurations; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.options.UnnamedConfigurable; +import org.jetbrains.annotations.NotNull; + +public interface RunConfigurationsSettings { + ExtensionPointName EXTENSION_POINT = ExtensionPointName.create("com.intellij.runConfigurationsSettings"); + + @NotNull + UnnamedConfigurable createConfigurable(); +} \ No newline at end of file diff --git a/platform/lang-api/src/com/intellij/execution/configurations/UnknownConfigurationType.java b/platform/lang-api/src/com/intellij/execution/configurations/UnknownConfigurationType.java index 9a86b783e389..ba5b0511dc9c 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/UnknownConfigurationType.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/UnknownConfigurationType.java @@ -55,6 +55,11 @@ public class UnknownConfigurationType implements ConfigurationType { public RunConfiguration createTemplateConfiguration(final Project project) { return new UnknownRunConfiguration(this, project); } + + @Override + public boolean canConfigurationBeSingleton() { + return false; + } }}; } } diff --git a/platform/lang-api/src/com/intellij/execution/executors/DefaultRunExecutor.java b/platform/lang-api/src/com/intellij/execution/executors/DefaultRunExecutor.java index 8ba013dc13f0..78d829f05048 100644 --- a/platform/lang-api/src/com/intellij/execution/executors/DefaultRunExecutor.java +++ b/platform/lang-api/src/com/intellij/execution/executors/DefaultRunExecutor.java @@ -34,7 +34,7 @@ public class DefaultRunExecutor extends Executor { @NonNls public static final String EXECUTOR_ID = ToolWindowId.RUN; private static final Icon ICON = AllIcons.Actions.Execute; - private static final Icon TOOLWINDOW_ICON = AllIcons.General.ToolWindowRun; + private static final Icon TOOLWINDOW_ICON = AllIcons.Toolwindows.ToolWindowRun; private static final Icon DISABLED_ICON = AllIcons.Process.DisabledRun; @NotNull diff --git a/platform/lang-api/src/com/intellij/execution/runners/ExecutionEnvironment.java b/platform/lang-api/src/com/intellij/execution/runners/ExecutionEnvironment.java index 4fc694ee0295..9ffd921a8ed9 100644 --- a/platform/lang-api/src/com/intellij/execution/runners/ExecutionEnvironment.java +++ b/platform/lang-api/src/com/intellij/execution/runners/ExecutionEnvironment.java @@ -41,6 +41,7 @@ public class ExecutionEnvironment { private RunProfile myRunProfile; private RunnerSettings myRunnerSettings; private ConfigurationPerRunnerSettings myConfigurationSettings; + @Nullable private RunnerAndConfigurationSettings myRunnerAndConfigurationSettings; @TestOnly public ExecutionEnvironment() { @@ -52,18 +53,29 @@ public class ExecutionEnvironment { @NotNull final RunnerAndConfigurationSettings configuration, Project project) { this(configuration.getConfiguration(), project, configuration.getRunnerSettings(runner), configuration.getConfigurationSettings(runner), - null); + null, configuration); } public ExecutionEnvironment(@NotNull RunProfile runProfile, Project project, RunnerSettings runnerSettings, - ConfigurationPerRunnerSettings configurationSettings, @Nullable RunContentDescriptor contentToReuse) { + ConfigurationPerRunnerSettings configurationSettings, + @Nullable RunContentDescriptor contentToReuse) { + this(runProfile, project, runnerSettings, configurationSettings, contentToReuse, null); + } + + public ExecutionEnvironment(@NotNull RunProfile runProfile, + Project project, + RunnerSettings runnerSettings, + ConfigurationPerRunnerSettings configurationSettings, + @Nullable RunContentDescriptor contentToReuse, + @Nullable RunnerAndConfigurationSettings settings) { myRunProfile = runProfile; myRunnerSettings = runnerSettings; myConfigurationSettings = configurationSettings; myProject = project; myContentToReuse = contentToReuse; + myRunnerAndConfigurationSettings = settings; } /** @@ -71,7 +83,7 @@ public class ExecutionEnvironment { */ @Deprecated public ExecutionEnvironment(@NotNull final ProgramRunner runner, @NotNull final RunnerAndConfigurationSettings configuration, final DataContext context) { - this(configuration.getConfiguration(), PlatformDataKeys.PROJECT.getData(context), configuration.getRunnerSettings(runner), configuration.getConfigurationSettings(runner), null); + this(configuration.getConfiguration(), PlatformDataKeys.PROJECT.getData(context), configuration.getRunnerSettings(runner), configuration.getConfigurationSettings(runner), null, configuration); } /** @@ -93,6 +105,11 @@ public class ExecutionEnvironment { this(runProfile, PlatformDataKeys.PROJECT.getData(dataContext), runnerSettings, configurationSettings, null); } + @Nullable + public RunnerAndConfigurationSettings getRunnerAndConfigurationSettings() { + return myRunnerAndConfigurationSettings; + } + @NotNull public RunProfile getRunProfile() { return myRunProfile; diff --git a/platform/lang-api/src/com/intellij/lang/refactoring/InlineActionHandler.java b/platform/lang-api/src/com/intellij/lang/refactoring/InlineActionHandler.java index 5cd8c6a6acbf..7bcdfdc5da54 100644 --- a/platform/lang-api/src/com/intellij/lang/refactoring/InlineActionHandler.java +++ b/platform/lang-api/src/com/intellij/lang/refactoring/InlineActionHandler.java @@ -47,7 +47,7 @@ public abstract class InlineActionHandler { public abstract boolean canInlineElement(PsiElement element); - public boolean canInlineElementInEditor(PsiElement element) { + public boolean canInlineElementInEditor(PsiElement element, Editor editor) { return canInlineElement(element); } diff --git a/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java b/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java index df9badfb808e..a7235246ee96 100644 --- a/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java +++ b/platform/lang-api/src/com/intellij/openapi/actionSystem/LangDataKeys.java @@ -21,6 +21,7 @@ import com.intellij.ide.IdeView; import com.intellij.lang.Language; import com.intellij.openapi.module.ModifiableModuleModel; import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElement; @@ -48,6 +49,7 @@ public class LangDataKeys extends PlatformDataKeys { * Returns {@link com.intellij.ide.IdeView} (one of project, packages, commander or favorites view). */ public static final DataKey IDE_VIEW = DataKey.create("IDEView"); + public static final DataKey NO_NEW_ACTION = DataKey.create("IDEview.no.create.element.action"); public static final DataKey> PRESELECT_NEW_ACTION_CONDITION = DataKey.create("newElementAction.preselect.id"); public static final DataKey TARGET_PSI_ELEMENT = DataKey.create("psi.TargetElement"); @@ -58,4 +60,7 @@ public class LangDataKeys extends PlatformDataKeys { public static final DataKey POSITION_ADJUSTER_POPUP = DataKey.create("chooseByNameDropDown"); public static final DataKey PARENT_POPUP = DataKey.create("chooseByNamePopup"); + + + public static final DataKey LIBRARY = DataKey.create("project.model.library"); } diff --git a/platform/lang-api/src/com/intellij/profile/ApplicationProfileManager.java b/platform/lang-api/src/com/intellij/profile/ApplicationProfileManager.java index 13e33d5a7bb7..9fdf3eca2232 100644 --- a/platform/lang-api/src/com/intellij/profile/ApplicationProfileManager.java +++ b/platform/lang-api/src/com/intellij/profile/ApplicationProfileManager.java @@ -43,7 +43,6 @@ public abstract class ApplicationProfileManager implements ProfileManager{ public abstract void addProfile(Profile profile); - @Nullable public NamedScopesHolder getScopesManager() { return null; } diff --git a/platform/lang-api/src/com/intellij/profile/DefaultProjectProfileManager.java b/platform/lang-api/src/com/intellij/profile/DefaultProjectProfileManager.java index babb9f1077ac..02f8b8973ad3 100644 --- a/platform/lang-api/src/com/intellij/profile/DefaultProjectProfileManager.java +++ b/platform/lang-api/src/com/intellij/profile/DefaultProjectProfileManager.java @@ -160,17 +160,20 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager } } + @NotNull @Override public NamedScopesHolder getScopesManager() { return myHolder; } + @NotNull @Override public synchronized Collection getProfiles() { getProjectProfileImpl(); return myProfiles.values(); } + @NotNull @Override public synchronized String[] getAvailableProfileNames() { return ArrayUtil.toStringArray(myProfiles.keySet()); diff --git a/platform/lang-api/src/com/intellij/profile/ProfileManager.java b/platform/lang-api/src/com/intellij/profile/ProfileManager.java index 3d89f01aa885..d10d6ccb21d7 100644 --- a/platform/lang-api/src/com/intellij/profile/ProfileManager.java +++ b/platform/lang-api/src/com/intellij/profile/ProfileManager.java @@ -17,7 +17,6 @@ package com.intellij.profile; import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Collection; @@ -26,9 +25,9 @@ import java.util.Collection; * Date: 09-Dec-2005 */ public interface ProfileManager { - @Nullable NamedScopesHolder getScopesManager(); + @NotNull Collection getProfiles(); Profile getProfile(@NotNull String name, boolean returnRootProfileIfNamedIsAbsent); @@ -37,6 +36,7 @@ public interface ProfileManager { void updateProfile(Profile profile); + @NotNull String[] getAvailableProfileNames(); void deleteProfile(String name); diff --git a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/AbstractPackageSet.java b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/AbstractPackageSet.java index 0bf2ca76b74b..2f00759cbc4f 100644 --- a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/AbstractPackageSet.java +++ b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/AbstractPackageSet.java @@ -33,6 +33,7 @@ public abstract class AbstractPackageSet extends PackageSetBase { myPriority = priority; } + @NotNull public AbstractPackageSet createCopy() { return this; } @@ -41,6 +42,7 @@ public abstract class AbstractPackageSet extends PackageSetBase { return myPriority; } + @NotNull @Override public String getText() { return myText; diff --git a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/ComplementPackageSet.java b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/ComplementPackageSet.java index 5294ce11dd3b..7c1f22da9881 100644 --- a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/ComplementPackageSet.java +++ b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/ComplementPackageSet.java @@ -16,6 +16,7 @@ package com.intellij.psi.search.scope.packageSet; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; public class ComplementPackageSet extends PackageSetBase { private final PackageSet myComplementarySet; @@ -29,10 +30,12 @@ public class ComplementPackageSet extends PackageSetBase { : myComplementarySet.contains(getPsiFile(file, holder), holder); } + @NotNull public PackageSet createCopy() { return new ComplementPackageSet(myComplementarySet.createCopy()); } + @NotNull public String getText() { StringBuffer buf = new StringBuffer(); boolean needParen = myComplementarySet.getNodePriority() > getNodePriority(); diff --git a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java index 7218322e2fd1..2d76d7a22bfe 100644 --- a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java +++ b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/FilePatternPackageSet.java @@ -31,12 +31,13 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.regex.Pattern; public class FilePatternPackageSet extends PatternBasedPackageSet { - public static final @NonNls String SCOPE_FILE = "file"; + @NonNls public static final String SCOPE_FILE = "file"; private Pattern myModulePattern; private Pattern myModuleGroupPattern; private final String myPathPattern; @@ -48,7 +49,7 @@ public class FilePatternPackageSet extends PatternBasedPackageSet { @NonNls String filePattern) { myPathPattern = filePattern; myModulePatternText = modulePattern; - if (modulePattern == null || modulePattern.length() == 0) { + if (modulePattern == null || modulePattern.isEmpty()) { myModulePattern = null; } else { @@ -66,6 +67,7 @@ public class FilePatternPackageSet extends PatternBasedPackageSet { myFilePattern = filePattern != null ? Pattern.compile(convertToRegexp(filePattern, '/')) : null; } + @Override public boolean contains(VirtualFile file, NamedScopesHolder holder) { Project project = holder.getProject(); ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); @@ -147,14 +149,19 @@ public class FilePatternPackageSet extends PatternBasedPackageSet { return buf.toString(); } + @Override + @NotNull public PackageSet createCopy() { return new FilePatternPackageSet(myModulePatternText, myPathPattern); } + @Override public int getNodePriority() { return 0; } + @Override + @NotNull public String getText() { @NonNls StringBuffer buf = new StringBuffer("file"); diff --git a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/IntersectionPackageSet.java b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/IntersectionPackageSet.java index 49478442199a..7d47f9e5e52c 100644 --- a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/IntersectionPackageSet.java +++ b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/IntersectionPackageSet.java @@ -16,6 +16,7 @@ package com.intellij.psi.search.scope.packageSet; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; public class IntersectionPackageSet extends PackageSetBase { private final PackageSet myFirstSet; @@ -35,6 +36,7 @@ public class IntersectionPackageSet extends PackageSetBase { return false; } + @NotNull public PackageSet createCopy() { return new IntersectionPackageSet(myFirstSet.createCopy(), mySecondSet.createCopy()); } @@ -43,6 +45,7 @@ public class IntersectionPackageSet extends PackageSetBase { return 2; } + @NotNull public String getText() { StringBuffer buf = new StringBuffer(); boolean needParen = myFirstSet.getNodePriority() > getNodePriority(); diff --git a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java index c344bfbebbff..bd22fb7ce479 100644 --- a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java +++ b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/NamedPackageSetReference.java @@ -16,6 +16,7 @@ package com.intellij.psi.search.scope.packageSet; import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; public class NamedPackageSetReference extends PackageSetBase { private final String myName; @@ -35,10 +36,12 @@ public class NamedPackageSetReference extends PackageSetBase { return false; } + @NotNull public PackageSet createCopy() { return new NamedPackageSetReference(myName); } + @NotNull public String getText() { return "$" + myName; } diff --git a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/PackageSet.java b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/PackageSet.java index 59f8c8f16fdb..5e59d8c7bbf4 100644 --- a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/PackageSet.java +++ b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/PackageSet.java @@ -17,10 +17,13 @@ package com.intellij.psi.search.scope.packageSet; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; public interface PackageSet { boolean contains(PsiFile file, NamedScopesHolder holder); + @NotNull PackageSet createCopy(); - @NonNls String getText(); + @NonNls @NotNull + String getText(); int getNodePriority(); } \ No newline at end of file diff --git a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/UnionPackageSet.java b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/UnionPackageSet.java index 52fedd70caab..896431e432a6 100644 --- a/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/UnionPackageSet.java +++ b/platform/lang-api/src/com/intellij/psi/search/scope/packageSet/UnionPackageSet.java @@ -33,6 +33,7 @@ public class UnionPackageSet extends PackageSetBase { (mySecondSet instanceof PackageSetBase ? ((PackageSetBase)mySecondSet).contains(file, holder) : mySecondSet.contains(getPsiFile(file, holder), holder)); } + @NotNull public PackageSet createCopy() { return new UnionPackageSet(myFirstSet.createCopy(), mySecondSet.createCopy()); } @@ -41,6 +42,7 @@ public class UnionPackageSet extends PackageSetBase { return 3; } + @NotNull public String getText() { return myFirstSet.getText() + "||" + mySecondSet.getText(); } diff --git a/platform/lang-api/src/com/intellij/ui/popup/util/DetailView.java b/platform/lang-api/src/com/intellij/ui/popup/util/DetailView.java index c195f9789f62..8c174602d27d 100644 --- a/platform/lang-api/src/com/intellij/ui/popup/util/DetailView.java +++ b/platform/lang-api/src/com/intellij/ui/popup/util/DetailView.java @@ -45,6 +45,12 @@ public interface DetailView extends UserDataHolder { PreviewEditorState getEditorState(); + ItemWrapper getCurrentItem(); + + boolean hasEditorOnly(); + + void setCurrentItem(ItemWrapper item); + class PreviewEditorState { public static PreviewEditorState EMPTY = new PreviewEditorState(null, null, null); diff --git a/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java b/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java index c1c4d0bcc221..5852d175a7d8 100644 --- a/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java +++ b/platform/lang-api/src/com/intellij/ui/popup/util/ItemWrapper.java @@ -22,21 +22,31 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; -public interface ItemWrapper { - void setupRenderer(ColoredListCellRenderer renderer, Project project, boolean selected); +public abstract class ItemWrapper { + public abstract void setupRenderer(ColoredListCellRenderer renderer, Project project, boolean selected); - void setupRenderer(ColoredTreeCellRenderer renderer); + public abstract void setupRenderer(ColoredTreeCellRenderer renderer); - void updateAccessoryView(JComponent label); + public abstract void updateAccessoryView(JComponent label); - String speedSearchText(); + public abstract String speedSearchText(); @Nullable - String footerText(); + public abstract String footerText(); - void updateDetailView(DetailView panel); + public void updateDetailView(DetailView panel) { + if (equals(panel.getCurrentItem())) { + return; + } - boolean allowedToRemove(); + doUpdateDetailView(panel, panel.hasEditorOnly()); - void removed(Project project); + panel.setCurrentItem(this); + } + + protected abstract void doUpdateDetailView(DetailView panel, boolean editorOnly); + + public abstract boolean allowedToRemove(); + + public abstract void removed(Project project); } diff --git a/platform/lang-api/src/com/intellij/ui/popup/util/SplitterItem.java b/platform/lang-api/src/com/intellij/ui/popup/util/SplitterItem.java index 1b3bf2bd64cc..79ebb95aca68 100644 --- a/platform/lang-api/src/com/intellij/ui/popup/util/SplitterItem.java +++ b/platform/lang-api/src/com/intellij/ui/popup/util/SplitterItem.java @@ -16,7 +16,6 @@ package com.intellij.ui.popup.util; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.ui.ColoredListCellRenderer; import com.intellij.ui.ColoredTreeCellRenderer; @@ -29,7 +28,7 @@ import javax.swing.*; * Time: 21:55 * To change this template use File | Settings | File Templates. */ -public class SplitterItem implements ItemWrapper { +public class SplitterItem extends ItemWrapper { private String myText; @@ -58,7 +57,7 @@ public class SplitterItem implements ItemWrapper { @Override public String speedSearchText() { - return ""; //To change body of implemented methods use File | Settings | File Templates. + return ""; } @Override @@ -67,7 +66,7 @@ public class SplitterItem implements ItemWrapper { } @Override - public void updateDetailView(DetailView panel) { + protected void doUpdateDetailView(DetailView panel, boolean editorOnly) { //To change body of implemented methods use File | Settings | File Templates. } diff --git a/platform/lang-api/src/com/intellij/usageView/UsageInfo.java b/platform/lang-api/src/com/intellij/usageView/UsageInfo.java index 37aacd8539e5..719c0fe54db2 100644 --- a/platform/lang-api/src/com/intellij/usageView/UsageInfo.java +++ b/platform/lang-api/src/com/intellij/usageView/UsageInfo.java @@ -69,6 +69,31 @@ public class UsageInfo { this.isNonCodeUsage = isNonCodeUsage; } + public UsageInfo(@NotNull SmartPsiElementPointer smartPointer, + SmartPsiFileRange psiFileRange, boolean dynamicUsage, + boolean nonCodeUsage) { + myDynamicUsage = dynamicUsage; + isNonCodeUsage = nonCodeUsage; + myPsiFileRange = psiFileRange; + mySmartPointer = smartPointer; + } + + public SmartPsiElementPointer getSmartPointer() { + return mySmartPointer; + } + + public SmartPsiFileRange getPsiFileRange() { + return myPsiFileRange; + } + + public boolean isNonCodeUsage() { + return isNonCodeUsage; + } + + public void setDynamicUsage(boolean dynamicUsage) { + myDynamicUsage = dynamicUsage; + } + public UsageInfo(@NotNull PsiElement element, boolean isNonCodeUsage) { this(element, -1, -1, isNonCodeUsage); } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTreeWithPreviewPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTreeWithPreviewPanel.java index a53a19ea4d7a..891773573ec6 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTreeWithPreviewPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/OptionTreeWithPreviewPanel.java @@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.codeStyle.CustomCodeStyleSettings; +import com.intellij.ui.ClickListener; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.containers.MultiMap; @@ -35,7 +36,6 @@ import javax.swing.tree.*; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.lang.reflect.Field; import java.util.*; @@ -213,14 +213,15 @@ public abstract class OptionTreeWithPreviewPanel extends MultilanguageCodeStyleA } }); - optionsTree.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (!optionsTree.isEnabled()) return; + public boolean onClick(MouseEvent e, int clickCount) { + if (!optionsTree.isEnabled()) return false; TreePath treePath = optionsTree.getPathForLocation(e.getX(), e.getY()); selectCheckbox(treePath); + return true; } - }); + }.installOn(optionsTree); int row = 0; while (row < optionsTree.getRowCount()) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 4fba4ab21670..98303e02eab9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -624,7 +624,7 @@ public class CodeCompletionHandlerBase implements CodeInsightActionHandler { return invokedExplicitly && CodeInsightSettings.getInstance().AUTOCOMPLETE_COMMON_PREFIX; } - protected static void lookupItemSelected(final CompletionProgressIndicator indicator, @NotNull final LookupElement item, final char completionChar, + protected void lookupItemSelected(final CompletionProgressIndicator indicator, @NotNull final LookupElement item, final char completionChar, final List items) { if (indicator.isAutopopupCompletion()) { FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_BASIC); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 2868f0ca6123..b0f57ae05d52 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -108,7 +108,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement setMergeCommand(); - CodeCompletionHandlerBase.lookupItemSelected(CompletionProgressIndicator.this, item, event.getCompletionChar(), myLookup.getItems()); + myHandler.lookupItemSelected(CompletionProgressIndicator.this, item, event.getCompletionChar(), myLookup.getItems()); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java index 2df59cd5fa37..f298603491f0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/PrefixMatchingWeigher.java @@ -18,10 +18,14 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.impl.CamelHumpMatcher; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; import org.jetbrains.annotations.NotNull; +import java.util.Iterator; + /** * @author peter */ @@ -33,13 +37,7 @@ public class PrefixMatchingWeigher extends CompletionWeigher { } public static int getPrefixMatchingDegree(LookupElement item, CompletionLocation location) { - final String prefix = location.getCompletionParameters().getLookup().itemPattern(item); - - final int setting = CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE; - final NameUtil.MatchingCaseSensitivity sensitivity = - setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE : - setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL; - final MinusculeMatcher matcher = new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity); + final MinusculeMatcher matcher = getMinusculeMatcher(location.getCompletionParameters().getLookup().itemPattern(item)); int max = Integer.MIN_VALUE; for (String lookupString : item.getAllLookupStrings()) { @@ -47,4 +45,37 @@ public class PrefixMatchingWeigher extends CompletionWeigher { } return max; } + + private static MinusculeMatcher getMinusculeMatcher(String prefix) { + final int setting = CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE; + final NameUtil.MatchingCaseSensitivity sensitivity = + setting == CodeInsightSettings.NONE ? NameUtil.MatchingCaseSensitivity.NONE : + setting == CodeInsightSettings.FIRST_LETTER ? NameUtil.MatchingCaseSensitivity.FIRST_LETTER : NameUtil.MatchingCaseSensitivity.ALL; + return new MinusculeMatcher(CamelHumpMatcher.applyMiddleMatching(prefix), sensitivity); + } + + public static StartMatchingDegree getStartMatchingDegree(LookupElement element, CompletionLocation location) { + StartMatchingDegree result = StartMatchingDegree.middleMatch; + String prefix = location.getCompletionParameters().getLookup().itemPattern(element); + if (StringUtil.isNotEmpty(prefix)) { + MinusculeMatcher matcher = getMinusculeMatcher(prefix); + for (String ls : element.getAllLookupStrings()) { + Iterable fragments = matcher.matchingFragments(ls); + if (fragments != null) { + Iterator iterator = fragments.iterator(); + if (!ls.isEmpty() && prefix.charAt(0) == ls.charAt(0)) { + return StartMatchingDegree.startMatchSameCase; + } + if (iterator.hasNext() && iterator.next().contains(0)) { + result = StartMatchingDegree.startMatchDifferentCase; + } + } + } + } + return result; + } + + public enum StartMatchingDegree { + startMatchSameCase, startMatchDifferentCase, middleMatch + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java index 85fa88ced441..c57c4a7567f0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/impl/CompletionServiceImpl.java @@ -25,7 +25,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerAdapter; import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.ElementPattern; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -238,24 +237,18 @@ public class CompletionServiceImpl extends CompletionService{ final CompletionLocation location = new CompletionLocation(parameters); CompletionSorterImpl sorter = emptySorter(); - final String prefix = matcher.getPrefix(); - if (!prefix.isEmpty()) { - final String prefixHumps = StringUtil.capitalsOnly(prefix); - if (prefixHumps.length() > 0) { - sorter = sorter.weigh(new LookupElementWeigher("prefixHumps") { + sorter = sorter.withClassifier(new ClassifierFactory("prefixHumps") { + @Override + public Classifier createClassifier(Classifier next) { + return new ComparingClassifier(next, "prefixHumps") { @NotNull @Override - public Comparable weigh(@NotNull LookupElement element) { - for (String itemString : element.getAllLookupStrings()) { - if (StringUtil.capitalsOnly(itemString).startsWith(prefixHumps) && StringUtil.isCapitalized(itemString)) { - return false; - } - } - return true; + public Comparable getWeight(LookupElement element) { + return PrefixMatchingWeigher.getStartMatchingDegree(element, location); } - }); + }; } - } + }); for (final Weigher weigher : WeighingService.getWeighers(CompletionService.RELEVANCE_KEY)) { final String id = weigher.toString(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java index 8bfaabded0ea..78d294258eb6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java @@ -67,6 +67,7 @@ import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.*; import com.intellij.psi.impl.PsiDocumentManagerImpl; +import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; @@ -246,9 +247,10 @@ class DaemonListeners implements Disposable { String propertyName = event.getPropertyName(); if (VirtualFile.PROP_NAME.equals(propertyName)) { stopDaemonAndRestartAllFiles(); - PsiFile psiFile = PsiManager.getInstance(myProject).findFile(event.getFile()); + VirtualFile virtualFile = event.getFile(); + PsiFile psiFile = ((PsiManagerEx)PsiManager.getInstance(myProject)).getFileManager().getCachedPsiFile(virtualFile); if (psiFile != null && !myDaemonCodeAnalyzer.isHighlightingAvailable(psiFile)) { - Document document = FileDocumentManager.getInstance().getCachedDocument(event.getFile()); + Document document = FileDocumentManager.getInstance().getCachedDocument(virtualFile); if (document != null) { // highlight markers no more //todo clear all highlights regardless the pass id @@ -303,6 +305,7 @@ class DaemonListeners implements Disposable { for (FileEditor fe : editors) { if (!(fe instanceof TextEditor)) continue; Editor editor = ((TextEditor)fe).getEditor(); + if (editor.getProject() != myProject) continue; final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument()); if (psiFile == null) continue; // optimization: do expensive classloading outside readaction diff --git a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java index b704d190cc80..d1ae61a6bcdd 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/documentation/DockablePopupManager.java @@ -83,7 +83,7 @@ public abstract class DockablePopupManager { myToolWindow = toolWindow == null ? toolWindowManagerEx.registerToolWindow(getToolwindowId(), true, ToolWindowAnchor.RIGHT, myProject) : toolWindow; - myToolWindow.setIcon(AllIcons.General.Documentation); + myToolWindow.setIcon(AllIcons.Toolwindows.Documentation); myToolWindow.setAvailable(true, null); myToolWindow.setToHideOnEmptyContent(false); @@ -100,14 +100,7 @@ public abstract class DockablePopupManager { contentManager.addContentManagerListener(new ContentManagerAdapter() { @Override public void contentRemoved(ContentManagerEvent event) { - if (contentManager.getContentCount() == 0) { - final JComponent c = event.getContent().getComponent(); - if (c instanceof Disposable) { - Disposer.dispose((Disposable)c); - } - - restorePopupBehavior(); - } + restorePopupBehavior(); } }); @@ -214,10 +207,7 @@ public abstract class DockablePopupManager { final Content[] contents = myToolWindow.getContentManager().getContents(); for (final Content content : contents) { - final JComponent c = content.getComponent(); - if (c instanceof Disposable) { - Disposer.dispose((Disposable)c); - } + myToolWindow.getContentManager().removeContent(content, true); } ToolWindowManagerEx.getInstanceEx(myProject).unregisterToolWindow(getToolwindowId()); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java index e68bcb345be5..f91feb6c5613 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/HighlightUsagesHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -268,6 +268,9 @@ public class HighlightUsagesHandler extends HighlightHandlerBase { final PsiDeclaredTarget declaredTarget = (PsiDeclaredTarget)target; final TextRange range = declaredTarget.getNameIdentifierRange(); if (range != null) { + if (range.getStartOffset() < 0 || range.getLength() <= 0) { + return null; + } final PsiElement navElement = declaredTarget.getNavigationElement(); if (PsiUtilBase.isUnderPsiRoot(file, navElement)) { return injectedManager.injectedToHost(navElement, range.shiftRight(navElement.getTextRange().getStartOffset())); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/TemplateLanguageErrorFilter.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/TemplateLanguageErrorFilter.java index c70ffd4f3576..3b58b7602ea1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/TemplateLanguageErrorFilter.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/TemplateLanguageErrorFilter.java @@ -19,18 +19,23 @@ import com.intellij.lang.Language; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiErrorElement; -import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; /** * @author Dennis.Ushakov */ public abstract class TemplateLanguageErrorFilter extends HighlightErrorFilter { - private final IElementType myTemplateExpressionStart; + @NotNull + private final TokenSet myTemplateExpressionStartTokens; + @NotNull private final Class myTemplateFileViewProviderClass; - protected TemplateLanguageErrorFilter(IElementType templateExpressionStart, Class templateFileViewProviderClass) { - myTemplateExpressionStart = templateExpressionStart; + protected TemplateLanguageErrorFilter( + final @NotNull TokenSet templateExpressionStartTokens, + final @NotNull Class templateFileViewProviderClass) + { + myTemplateExpressionStartTokens = TokenSet.create(templateExpressionStartTokens.getTypes()); myTemplateFileViewProviderClass = templateFileViewProviderClass; } @@ -45,7 +50,7 @@ public abstract class TemplateLanguageErrorFilter extends HighlightErrorFilter { final Language css = Language.findLanguageByID("CSS"); if (javaScript != null && parentLanguage.is(javaScript) || css != null && parentLanguage.is(css)) { final PsiElement next = viewProvider.findElementAt(element.getTextOffset() + 1, viewProvider.getBaseLanguage()); - if (next != null && next.getNode().getElementType() == myTemplateExpressionStart) { + if (next != null && myTemplateExpressionStartTokens.contains(next.getNode().getElementType())) { return false; } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java index 7250f6fecbbd..d59e083557db 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/FileLevelIntentionComponent.java @@ -29,12 +29,12 @@ import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiFile; +import com.intellij.ui.ClickListener; import com.intellij.ui.EditorNotificationPanel; import com.intellij.ui.LightColors; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.List; @@ -76,8 +76,9 @@ public class FileLevelIntentionComponent extends EditorNotificationPanel { myLabel.setIcon(SeverityRegistrar.getInstance(project).compare(severity, HighlightSeverity.ERROR) >= 0 ? ourQuickFixIcon : ourIntentionIcon); setBackground(getColor(severity)); - myLabel.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { IntentionListStep step = new IntentionListStep(null, info, editor, psiFile, project); if (intentions != null && !intentions.isEmpty()) { HighlightInfo.IntentionActionDescriptor descriptor = intentions.get(0).getFirst(); @@ -87,10 +88,9 @@ public class FileLevelIntentionComponent extends EditorNotificationPanel { } } JBPopupFactory.getInstance().createListPopup(step).showUnderneathOf(myLabel); + return true; } - }); - - + }.installOn(myLabel); } private Color getColor(HighlightSeverity severity) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java index cf2ebaea9d26..775756da4373 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/intention/impl/config/IntentionSettingsConfigurable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -65,7 +65,7 @@ public class IntentionSettingsConfigurable extends BaseConfigurable implements S } public boolean isModified() { - return myPanel.isModified(); + return myPanel != null && myPanel.isModified(); } public String getDisplayName() { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java index 7d80227fb1b6..43b01646d15a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/Advertiser.java @@ -17,13 +17,13 @@ package com.intellij.codeInsight.lookup.impl; import com.google.common.collect.ImmutableMap; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.ui.ClickListener; import com.intellij.util.ui.GridBag; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.TextAttribute; import java.util.List; @@ -71,13 +71,15 @@ public class Advertiser { myNextLabel = new JLabel(">>"); myNextLabel.setFont(adFont().deriveFont(ImmutableMap.builder().put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON).build())); myNextLabel.setForeground(Color.blue); - myNextLabel.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { myCurrentItem++; updateAdvertisements(); + return true; } - }); + }.installOn(myNextLabel); + myNextLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); GridBag gb = new GridBag(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index 5ec61742dc5b..1c5a55681ae7 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -41,6 +41,7 @@ import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.event.*; +import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; @@ -56,10 +57,7 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.DebugUtil; -import com.intellij.ui.ExpandableItemsHandler; -import com.intellij.ui.LightweightHint; -import com.intellij.ui.ListScrollingUtil; -import com.intellij.ui.ScreenUtil; +import com.intellij.ui.*; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.JBList; import com.intellij.ui.components.JBScrollPane; @@ -225,14 +223,15 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable mySortingLabel.setBorder(new LineBorder(Color.LIGHT_GRAY)); mySortingLabel.setOpaque(true); - mySortingLabel.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { FeatureUsageTracker.getInstance().triggerFeatureUsed(CodeCompletionFeatures.EDITING_COMPLETION_CHANGE_SORTING); UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = !UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY; updateSorting(); + return true; } - }); + }.installOn(mySortingLabel); updateSorting(); } @@ -897,20 +896,22 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable } }); - myList.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e){ + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { setFocused(true); markSelectionTouched(); - if (e.getClickCount() == 2){ + if (clickCount == 2){ CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { public void run() { finishLookup(NORMAL_SELECT_CHAR); } }, "", null); } + return true; } - }); + }.installOn(myList); } private void updateHint(@NotNull final LookupElement item) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java index 68f42ce81276..76e1d92784fe 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java @@ -176,6 +176,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler { return true; } }). + setAdText(getAdText(gotoData.source, targets.length)). createPopup(); if (gotoData.listUpdaterTask != null) { gotoData.listUpdaterTask.init((AbstractPopup)popup, list); @@ -237,6 +238,10 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler { protected abstract String getChooserTitle(PsiElement sourceElement, String name, int length); protected abstract String getNotFoundMessage(Project project, Editor editor, PsiFile file); + @Nullable + protected String getAdText(PsiElement source, int length) { + return null; + } public interface AdditionalAction { String getText(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java index f409f82a0739..37474ae965f1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java @@ -326,16 +326,17 @@ public class LiveTemplateSettingsEditor extends JPanel { } }; - change.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (disposeContextPopup()) return; + public boolean onClick(MouseEvent e, int clickCount) { + if (disposeContextPopup()) return false; JPanel content = createPopupContextPanel(updateLabel); myContextPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(content, null).setResizable(true).createPopup(); myContextPopup.show(new RelativePoint(change, new Point(change.getWidth() , -content.getPreferredSize().height - 10))); + return true; } - }); + }.installOn(change); updateLabel.run(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TableSorter.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TableSorter.java index b68a53fb894b..3994e114dea4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TableSorter.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TableSorter.java @@ -35,15 +35,14 @@ package com.intellij.codeInsight.template.impl; */ import com.intellij.openapi.diagnostic.Logger; +import com.intellij.ui.ClickListener; import com.intellij.util.ArrayUtil; import javax.swing.*; import javax.swing.event.TableModelEvent; -import javax.swing.table.JTableHeader; import javax.swing.table.TableColumnModel; import javax.swing.table.TableModel; import java.awt.event.InputEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Date; import java.util.Vector; @@ -332,20 +331,21 @@ order diminishes - it may drop very quickly. */ final TableSorter sorter = this; final JTable tableView = table; tableView.setColumnSelectionAllowed(false); - MouseAdapter listMouseListener = new MouseAdapter() { - public void mouseClicked(MouseEvent e) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { TableColumnModel columnModel = tableView.getColumnModel(); int viewColumn = columnModel.getColumnIndexAtX(e.getX()); int column = tableView.convertColumnIndexToModel(viewColumn); - if (e.getClickCount() == 1 && column != -1) { + if (clickCount == 1 && column != -1) { //System.out.println("Sorting ..."); int shiftPressed = e.getModifiers() & InputEvent.SHIFT_MASK; boolean ascending = (shiftPressed == 0); sorter.sortByColumn(column, ascending); + return true; } + return false; } - }; - JTableHeader th = tableView.getTableHeader(); - th.addMouseListener(listMouseListener); + }.installOn(tableView.getTableHeader()); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java index 6209296da403..be4c2cc9094d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java @@ -54,7 +54,10 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.*; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.util.*; import java.util.List; @@ -611,14 +614,13 @@ public class TemplateListPanel extends JPanel implements Disposable { } }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED); - myTree.addMouseListener(new MouseAdapter() { + new DoubleClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - renameGroup(); - } + protected boolean onDoubleClick(MouseEvent e) { + renameGroup(); + return true; } - }); + }.installOn(myTree); installPopup(); @@ -1016,4 +1018,4 @@ public class TemplateListPanel extends JPanel implements Disposable { return checkInput(inputString); } } -} \ No newline at end of file +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java index 093045ec662f..8346f8939ce6 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java @@ -68,7 +68,7 @@ public class InspectionManagerEx extends InspectionManager { ToolWindow toolWindow = toolWindowManager.registerToolWindow(ToolWindowId.INSPECTION, true, ToolWindowAnchor.BOTTOM, myProject); ContentManager contentManager = toolWindow.getContentManager(); - toolWindow.setIcon(AllIcons.General.ToolWindowInspection); + toolWindow.setIcon(AllIcons.Toolwindows.ToolWindowInspection); new ContentManagerWatcher(toolWindow, contentManager); return contentManager; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNode.java index f3bdab06ee0c..14d04e1691a7 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNode.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionNode.java @@ -31,7 +31,7 @@ public class InspectionNode extends InspectionTreeNode { public static final Icon TOOL; static { - TOOL = LayeredIcon.create(AllIcons.General.ToolWindowInspection, IconUtil.getEmptyIcon(false)); + TOOL = LayeredIcon.create(AllIcons.Toolwindows.ToolWindowInspection, IconUtil.getEmptyIcon(false)); } public InspectionNode(InspectionTool tool) { diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java index f2c909fdeca4..bb9857e20879 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -55,10 +55,7 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiUtilBase; -import com.intellij.ui.PopupHandler; -import com.intellij.ui.ScrollPaneFactory; -import com.intellij.ui.SideBorder; -import com.intellij.ui.SmartExpander; +import com.intellij.ui.*; import com.intellij.util.OpenSourceUtil; import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NonNls; @@ -71,7 +68,10 @@ import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import java.awt.*; -import java.awt.event.*; +import java.awt.event.InputEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.*; @@ -172,13 +172,13 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } }); - myTree.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (!e.isPopupTrigger() && e.getClickCount() == 2) { - OpenSourceUtil.openSourcesFrom(DataManager.getInstance().getDataContext(InspectionResultsView.this), true); - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + OpenSourceUtil.openSourcesFrom(DataManager.getInstance().getDataContext(InspectionResultsView.this), true); + return true; } - }); + }.installOn(myTree); myTree.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java index 04471074818d..4360edec45a0 100644 --- a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java @@ -25,6 +25,7 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.*; +import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Trinity; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashSet; @@ -33,6 +34,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.util.*; /** @@ -40,6 +42,8 @@ import java.util.*; */ public class ExecutorRegistryImpl extends ExecutorRegistry { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.ExecutorRegistryImpl"); + private static final Icon STOP_AND_START_ICON = IconLoader.getIcon("/actions/restart.png"); + @NonNls public static final String RUNNERS_GROUP = "RunnerActions"; @NonNls public static final String RUN_CONTEXT_GROUP = "RunContextGroup"; @@ -240,7 +244,11 @@ public class ExecutorRegistryImpl extends ExecutorRegistry { if (configuration == null) { return; } - ProgramRunnerUtil.executeConfiguration(project, configuration, myExecutor); + if (configuration.isSingleton()) { + ExecutionManager.getInstance(project).restartRunProfile(project, myExecutor, configuration); + } else { + ProgramRunnerUtil.executeConfiguration(project, configuration, myExecutor); + } } } } diff --git a/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java b/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java index d7fd9e783393..b4b2c9e07286 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/CreateAction.java @@ -122,7 +122,9 @@ public class CreateAction extends BaseRunConfigurationAction { final RunnerAndConfigurationSettings configuration = context.getConfiguration(); final RunnerAndConfigurationSettings template = runManager.getConfigurationTemplate(configuration.getFactory()); final RunConfiguration templateConfiguration = template.getConfiguration(); - runManager.addConfiguration(configuration, runManager.isConfigurationShared(template), runManager.getBeforeRunTasks( templateConfiguration), + runManager.addConfiguration(configuration, + runManager.isConfigurationShared(template), + runManager.getBeforeRunTasks(templateConfiguration), false); runManager.setActiveConfiguration(configuration); } diff --git a/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationsComboBoxAction.java similarity index 99% rename from platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java rename to platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationsComboBoxAction.java index 44a934ee0e2a..8b8535f85fe5 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationsComboBoxAction.java @@ -41,7 +41,7 @@ import javax.swing.*; import java.awt.*; import java.util.ArrayList; -public class RunConfigurationAction extends ComboBoxAction implements DumbAware { +public class RunConfigurationsComboBoxAction extends ComboBoxAction implements DumbAware { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.actions.RunConfigurationAction"); private static final Key BUTTON_KEY = Key.create("COMBOBOX_BUTTON"); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java b/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java index 0d1e0a76b703..d3d392761031 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/BeforeRunStepsPanel.java @@ -51,8 +51,9 @@ import java.util.Set; * @author Vassiliy Kudryashov */ class BeforeRunStepsPanel extends JPanel { - private JCheckBox myShowSettingsBeforeRunCheckBox; - private JBList myList; + private final JCheckBox myShowSettingsBeforeRunCheckBox; + private final JCheckBox mySingletonCheckBox; + private final JBList myList; private final CollectionListModel myModel; private RunConfiguration myRunConfiguration; @@ -129,11 +130,14 @@ class BeforeRunStepsPanel extends JPanel { }); myShowSettingsBeforeRunCheckBox = new JCheckBox(ExecutionBundle.message("configuration.edit.before.run")); + mySingletonCheckBox = new JCheckBox(ExecutionBundle.message("configuration.singleton")); + myPanel = myDecorator.createPanel(); setLayout(new MigLayout("fill, ins 0, gap 10, hidemode 3")); - add(myShowSettingsBeforeRunCheckBox, "shrinky, ay bottom, wrap"); - myPanel = myDecorator.createPanel(); - add(myPanel, "grow, push"); + add(myShowSettingsBeforeRunCheckBox, "shrink, split 2"); + add(mySingletonCheckBox, "shrink"); + add(Box.createHorizontalGlue(), "push, grow, wrap"); + add(myPanel, "grow, push, spanx 2"); } @Nullable @@ -154,7 +158,10 @@ class BeforeRunStepsPanel extends JPanel { originalTasks.addAll(RunManagerImpl.getInstanceImpl(myRunConfiguration.getProject()).getBeforeRunTasks(myRunConfiguration)); myModel.replaceAll(originalTasks); myShowSettingsBeforeRunCheckBox.setSelected(settings.isEditBeforeRun()); - myShowSettingsBeforeRunCheckBox.setEnabled(!(myRunConfiguration instanceof UnknownRunConfiguration)); + myShowSettingsBeforeRunCheckBox.setEnabled(!(isUnknown())); + mySingletonCheckBox.setSelected(settings.isSingleton()); + mySingletonCheckBox.setEnabled(!(isUnknown())); + mySingletonCheckBox.setVisible(myRunConfiguration.getFactory().canConfigurationBeSingleton()); myPanel.setVisible(checkBeforeRunTasksAbility(false)); } @@ -171,8 +178,12 @@ class BeforeRunStepsPanel extends JPanel { return myShowSettingsBeforeRunCheckBox.isSelected(); } + public boolean isSingleton() { + return myRunConfiguration.getFactory().canConfigurationBeSingleton() && mySingletonCheckBox.isSelected(); + } + private boolean checkBeforeRunTasksAbility(boolean checkOnlyAddAction) { - if (myRunConfiguration instanceof UnknownRunConfiguration) { + if (isUnknown()) { return false; } Set activeProviderKeys = getActiveProviderKeys(); @@ -191,8 +202,12 @@ class BeforeRunStepsPanel extends JPanel { return false; } + private boolean isUnknown() { + return myRunConfiguration instanceof UnknownRunConfiguration; + } + void doAddAction(AnActionButton button) { - if (myRunConfiguration instanceof UnknownRunConfiguration) { + if (isUnknown()) { return; } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java index 61602caf11fc..71aadd855153 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConfigurationSettingsEditorWrapper.java @@ -117,8 +117,10 @@ public class ConfigurationSettingsEditorWrapper extends SettingsEditor> myRunningConfigurations = + new ArrayList>(); /** * reflection @@ -157,6 +167,7 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom final RunContentDescriptor descriptor = starter.execute(project, executor, state, reuseContent, env); if (descriptor != null) { + myRunningConfigurations.add(Trinity.create(descriptor, env.getRunnerAndConfigurationSettings(), executor)); ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor, reuseContent); final ProcessHandler processHandler = descriptor.getProcessHandler(); if (processHandler != null) { @@ -194,6 +205,116 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom } } + @Override + public void restartRunProfile(@NotNull final Project project, + @NotNull final Executor executor, + @NotNull final RunnerAndConfigurationSettings configuration) { + RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(project); + final RunManagerConfig config = runManager.getConfig(); + final List> pairs = getRunningDescriptors(configuration); + + for (Pair pair : pairs) { + ProcessHandler processHandler = pair.getFirst().getProcessHandler(); + if (processHandler == null) + continue; + if (!processHandler.isProcessTerminated()) { + if (config.isRestartRequiresConfirmation()) { + DialogWrapper.DoNotAskOption option = new DialogWrapper.DoNotAskOption() { + @Override + public boolean isToBeShown() { + return config.isRestartRequiresConfirmation(); + } + + @Override + public void setToBeShown(boolean value, int exitCode) { + config.setRestartRequiresConfirmation(value); + } /**/ + + @Override + public boolean canBeHidden() { + return true; + } + + @Override + public boolean shouldSaveOptionsOnCancel() { + return false; + } + + @Override + public String getDoNotShowMessage() { + return CommonBundle.message("dialog.options.do.not.show"); + } + }; + if (Messages.OK != Messages.showOkCancelDialog(ExecutionBundle.message("rerun.confirmation.message", configuration.getName()), + ExecutionBundle.message("rerun.confirmation.title") + " ("+pair.getSecond().getId()+")", + CommonBundle.message("button.ok"), + CommonBundle.message("button.cancel"), + Messages.getQuestionIcon(), option)) { + return; + } + } + stop(processHandler); + for ( + Iterator> iterator = myRunningConfigurations.iterator(); + iterator.hasNext(); ) { + Trinity trinity = iterator.next(); + if (trinity.getFirst() == pair.getFirst()) { + iterator.remove(); + break; + } + } + } + } + + if (pairs.isEmpty()) { + ProgramRunnerUtil.executeConfiguration(project, configuration, executor); + return; + } + + Runnable runnable = new Runnable() { + @Override + public void run() { + for (Pair pair : pairs) { + ProcessHandler processHandler = pair.getFirst().getProcessHandler(); + if (processHandler == null) + continue; + if (!processHandler.isProcessTerminated()) { + awaitingTerminationAlarm.addRequest(this, 100); + return; + } + } + ProgramRunnerUtil.executeConfiguration(project, configuration, executor); + } + }; + awaitingTerminationAlarm.addRequest(runnable, 100); + } + + private List> getRunningDescriptors(RunnerAndConfigurationSettings configuration) { + List> result = new ArrayList>(); + for (Trinity trinity : myRunningConfigurations) { + if (trinity.getSecond() == configuration) { + result.add(Pair.create(trinity.getFirst(), trinity.getThird())); + } + } + return result; + } + + + + private static void stop(ProcessHandler processHandler) { + if (processHandler instanceof KillableProcess && processHandler.isProcessTerminating()) { + ((KillableProcess)processHandler).killProcess(); + return; + } + + if (processHandler.detachIsDefault()) { + processHandler.detachProcess(); + } + else { + processHandler.destroyProcess(); + } + } + @NotNull public String getComponentName() { return "ExecutionManager"; diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java index b132670a75e3..40ae8e7048f4 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java @@ -22,6 +22,7 @@ import com.intellij.execution.configurations.*; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.options.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; @@ -32,6 +33,7 @@ import com.intellij.openapi.ui.popup.ListPopupStep; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.*; import com.intellij.ui.components.JBScrollPane; @@ -43,10 +45,10 @@ import com.intellij.util.config.StorageAccessors; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.HashMap; +import com.intellij.util.ui.GridBag; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.tree.TreeUtil; import gnu.trove.THashSet; -import net.miginfocom.swing.MigLayout; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -65,6 +67,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; class RunConfigurable extends BaseConfigurable { + private static final Icon ADD_ICON = IconUtil.getAddIcon(); private static final Icon REMOVE_ICON = IconUtil.getRemoveIcon(); @NonNls private static final String DIVIDER_PROPORTION = "dividerProportion"; @@ -84,6 +87,7 @@ class RunConfigurable extends BaseConfigurable { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.impl.RunConfigurable"); private final JTextField myRecentsLimit = new JTextField("5", 2); private final JCheckBox myConfirmation = new JCheckBox(ExecutionBundle.message("rerun.confirmation.checkbox"), true); + private final List> myAdditionalSettings = new ArrayList>(); private Map myStoredComponents = new HashMap(); public RunConfigurable(final Project project) { @@ -392,7 +396,19 @@ class RunConfigurable extends BaseConfigurable { myRightPanel.removeAll(); myRightPanel.add(scrollPane, BorderLayout.CENTER); if (configurationType == null) { - myRightPanel.add(createRecentLimitPanel(), BorderLayout.SOUTH); + JPanel settingsPanel = new JPanel(new GridBagLayout()); + GridBag grid = new GridBag().setDefaultAnchor(GridBagConstraints.NORTHWEST); + + for (Pair each : myAdditionalSettings) { + settingsPanel.add(each.second, grid.nextLine().next()); + } + settingsPanel.add(createSettingsPanel(), grid.nextLine().next()); + + JPanel wrapper = new JPanel(new BorderLayout()); + wrapper.add(settingsPanel, BorderLayout.WEST); + wrapper.add(Box.createGlue(), BorderLayout.CENTER); + + myRightPanel.add(wrapper, BorderLayout.SOUTH); } myRightPanel.revalidate(); myRightPanel.repaint(); @@ -412,12 +428,14 @@ class RunConfigurable extends BaseConfigurable { return leftPanel; } - private JPanel createRecentLimitPanel() { - final JPanel bottomPanel = new JPanel(new MigLayout("ins 5, gap 5")); + private JPanel createSettingsPanel() { + JPanel bottomPanel = new JPanel(new GridBagLayout()); + GridBag g = new GridBag(); + + bottomPanel.add(myConfirmation, g.nextLine().coverLine()); + bottomPanel.add(new JLabel("Temporary configurations limit:"), g.nextLine().next()); + bottomPanel.add(myRecentsLimit, g.next().anchor(GridBagConstraints.WEST)); - bottomPanel.add(new JLabel("Temporary configurations limit:")); - bottomPanel.add(myRecentsLimit, "wrap, h pref!, w pref!"); - bottomPanel.add(myConfirmation, "spanx 2"); myRecentsLimit.getDocument().addDocumentListener(new DocumentAdapter() { @Override protected void textChanged(DocumentEvent e) { @@ -475,6 +493,11 @@ class RunConfigurable extends BaseConfigurable { } public JComponent createComponent() { + for (RunConfigurationsSettings each : Extensions.getExtensions(RunConfigurationsSettings.EXTENSION_POINT)) { + UnnamedConfigurable configurable = each.createConfigurable(); + myAdditionalSettings.add(Pair.create(configurable, configurable.createComponent())); + } + myWholePanel = new JPanel(new BorderLayout()); mySplitter.setFirstComponent(createLeftPanel()); mySplitter.setSecondComponent(myRightPanel); @@ -497,6 +520,11 @@ class RunConfigurable extends BaseConfigurable { final RunManagerConfig config = manager.getConfig(); myRecentsLimit.setText(Integer.toString(config.getRecentsLimit())); myConfirmation.setSelected(config.isRestartRequiresConfirmation()); + + for (Pair each : myAdditionalSettings) { + each.first.reset(); + } + setModified(false); } @@ -545,6 +573,10 @@ class RunConfigurable extends BaseConfigurable { } } + for (Pair each : myAdditionalSettings) { + each.first.apply(); + } + manager.saveOrder(); setModified(false); } @@ -683,6 +715,10 @@ class RunConfigurable extends BaseConfigurable { if (configurable.isModified()) return true; } + for (Pair each : myAdditionalSettings) { + if (each.first.isModified()) return true; + } + return false; } @@ -693,6 +729,10 @@ class RunConfigurable extends BaseConfigurable { } myStoredComponents.clear(); + for (Pair each : myAdditionalSettings) { + each.first.disposeUIResources(); + } + TreeUtil.traverseDepth(myRoot, new TreeUtil.Traverse() { public boolean accept(Object node) { if (node instanceof DefaultMutableTreeNode) { diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java index 5f3116c907f2..9dfe97b09c78 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.java @@ -59,6 +59,8 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C private static final String TEMPORARY_ATTRIBUTE = "temporary"; @NonNls private static final String EDIT_BEFORE_RUN = "editBeforeRun"; + @NonNls + private static final String SINGLETON = "singleton"; /** for compatibility */ @@ -77,6 +79,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C private boolean myTemporary; private boolean myEditBeforeRun; + private boolean mySingleton; public RunnerAndConfigurationSettingsImpl(RunManagerImpl manager) { myManager = manager; @@ -136,6 +139,16 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C return myEditBeforeRun; } + @Override + public void setSingleton(boolean singleton) { + mySingleton = singleton; + } + + @Override + public boolean isSingleton() { + return mySingleton; + } + @Nullable private ConfigurationFactory getFactory(final Element element) { final String typeName = element.getAttributeValue(CONFIGURATION_TYPE_ATTRIBUTE); @@ -147,6 +160,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C myIsTemplate = Boolean.valueOf(element.getAttributeValue(TEMPLATE_FLAG_ATTRIBUTE)).booleanValue(); myTemporary = Boolean.valueOf(element.getAttributeValue(TEMPORARY_ATTRIBUTE)).booleanValue() || TEMP_CONFIGURATION.equals(element.getName()); myEditBeforeRun = Boolean.valueOf(element.getAttributeValue(EDIT_BEFORE_RUN)).booleanValue(); + mySingleton = Boolean.valueOf(element.getAttributeValue(SINGLETON)).booleanValue(); final ConfigurationFactory factory = getFactory(element); if (factory == null) return; @@ -208,6 +222,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C element.setAttribute(FACTORY_NAME_ATTRIBUTE, factory.getName()); if (isEditBeforeRun()) element.setAttribute(EDIT_BEFORE_RUN, String.valueOf(true)); + if (isSingleton()) element.setAttribute(SINGLETON, String.valueOf(true)); if (myTemporary) { element.setAttribute(TEMPORARY_ATTRIBUTE, Boolean.toString(myTemporary)); } diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java index ebceccc36430..3d6a332f8fcd 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java @@ -15,9 +15,7 @@ */ package com.intellij.execution.runners; -import com.intellij.CommonBundle; import com.intellij.execution.*; -import com.intellij.execution.impl.RunManagerImpl; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.icons.AllIcons; @@ -26,9 +24,8 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; -import com.intellij.util.Alarm; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -44,14 +41,13 @@ public class RestartAction extends AnAction implements DumbAware { private final Executor myExecutor; private final Icon myIcon; private final ExecutionEnvironment myEnvironment; - private final Alarm awaitingTerminationAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); public RestartAction(final Executor executor, final ProgramRunner runner, final ProcessHandler processHandler, final Icon icon, final RunContentDescriptor descritor, - final ExecutionEnvironment env) { + @NotNull final ExecutionEnvironment env) { super(null, null, icon); myIcon = icon; myEnvironment = env; @@ -64,61 +60,7 @@ public class RestartAction extends AnAction implements DumbAware { } public void actionPerformed(final AnActionEvent e) { - final DataContext dataContext = e.getDataContext(); - final RunManagerConfig config = RunManagerImpl.getInstanceImpl(myEnvironment.getProject()).getConfig(); - if (myProcessHandler != null && !myProcessHandler.isProcessTerminated() && config.isRestartRequiresConfirmation()) { - DialogWrapper.DoNotAskOption option = new DialogWrapper.DoNotAskOption() { - @Override - public boolean isToBeShown() { - return config.isRestartRequiresConfirmation(); - } - - @Override - public void setToBeShown(boolean value, int exitCode) { - config.setRestartRequiresConfirmation(value); - } - - @Override - public boolean canBeHidden() { - return true; - } - - @Override - public boolean shouldSaveOptionsOnCancel() { - return false; - } - - @Override - public String getDoNotShowMessage() { - return CommonBundle.message("dialog.options.do.not.show"); - } - }; - if (Messages.OK != Messages.showOkCancelDialog(ExecutionBundle.message("rerun.confirmation.message", myEnvironment.getRunProfile().getName()), - ExecutionBundle.message("rerun.confirmation.title"), CommonBundle.message("button.ok"), - CommonBundle.message("button.cancel"), - Messages.getQuestionIcon(), option)) { - return; - } - } - ActionManager.getInstance().getAction(IdeActions.ACTION_STOP_PROGRAM).actionPerformed(e); - update(e); - if (myProcessHandler != null) { - Runnable runnable = new Runnable() { - @Override - public void run() { - if (myProcessHandler == null || myProcessHandler.isProcessTerminated()) { - doRestart(dataContext); - } - else { - awaitingTerminationAlarm.addRequest(this, 100); - } - } - }; - awaitingTerminationAlarm.addRequest(runnable, 100); - } - else { - doRestart(dataContext); - } + ExecutionManager.getInstance(myEnvironment.getProject()).restartRunProfile(myEnvironment.getProject(), myExecutor, myEnvironment.getRunnerAndConfigurationSettings()); } public void restart() { @@ -133,7 +75,7 @@ public class RestartAction extends AnAction implements DumbAware { try { final ExecutionEnvironment old = myEnvironment; myRunner.execute(myExecutor, new ExecutionEnvironment(old.getRunProfile(), project, old.getRunnerSettings(), - old.getConfigurationSettings(), myDescriptor)); + old.getConfigurationSettings(), myDescriptor, old.getRunnerAndConfigurationSettings())); } catch (RunCanceledByUserException ignore) { } diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java index 6bcbd42a0ebf..f522efea13fc 100644 --- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java +++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * 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. @@ -460,7 +460,8 @@ public class ShowUsagesAction extends AnAction implements PopupAction { else { s = title + " (" + UsageViewBundle.message("usages.n", usages.size()) + " found)"; } - builder.setTitle(suggestSecondInvocation(options, handler, s)); + builder.setTitle("" + s + ""); + builder.setAdText(getSecondInvocationTitle(options, handler)); } builder.setMovable(true).setResizable(true); @@ -500,7 +501,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction { usageView.addFilteringActions(toolbar); toolbar.add(UsageGroupingRuleProviderImpl.createGroupByFileStructureAction(usageView)); - toolbar.add(new AnAction("Open Find Usages Toolwindow", "Show all usages in a separate toolwindow", AllIcons.General.ToolWindowFind) { + toolbar.add(new AnAction("Open Find Usages Toolwindow", "Show all usages in a separate toolwindow", AllIcons.Toolwindows.ToolWindowFind) { { AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES); setShortcutSet(action.getShortcutSet()); @@ -555,16 +556,26 @@ public class ShowUsagesAction extends AnAction implements PopupAction { } private static String suggestSecondInvocation(FindUsagesOptions options, FindUsagesHandler handler, String s) { - if (getShowUsagesShortcut() != null) { - GlobalSearchScope maximalScope = getMaximalScope(handler); - if (!notNullizeScope(options, handler.getProject()).equals(maximalScope)) { - s += "
Press " + KeymapUtil.getShortcutText(getShowUsagesShortcut()) + - " again to search in " + maximalScope.getDisplayName() + ""; - } + final String title = getSecondInvocationTitle(options, handler); + + if (title != null) { + s += "
Press " + title + ""; } return "" + s + ""; } + @Nullable + private static String getSecondInvocationTitle(FindUsagesOptions options, FindUsagesHandler handler) { + if (getShowUsagesShortcut() != null) { + GlobalSearchScope maximalScope = getMaximalScope(handler); + if (!notNullizeScope(options, handler.getProject()).equals(maximalScope)) { + return "Press " + KeymapUtil.getShortcutText(getShowUsagesShortcut()) + + " again to search in " + maximalScope.getDisplayName(); + } + } + return null; + } + private void searchEverywhere(FindUsagesOptions options, FindUsagesHandler handler, Editor editor, diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java index e09e8f129f45..3a0e76644bd4 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindSettingsImpl.java @@ -29,6 +29,7 @@ import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizableStringList; import com.intellij.openapi.util.WriteExternalException; import com.intellij.util.ArrayUtil; +import com.intellij.util.PlatformUtils; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -55,6 +56,26 @@ public class FindSettingsImpl extends FindSettings implements PersistentStateCom private static final int MAX_RECENT_SIZE = 30; + public FindSettingsImpl() { + RECENT_FILE_MASKS.add("*.properties"); + RECENT_FILE_MASKS.add("*.html"); + RECENT_FILE_MASKS.add("*.jsp"); + RECENT_FILE_MASKS.add("*.xml"); + RECENT_FILE_MASKS.add("*.java"); + RECENT_FILE_MASKS.add("*.js"); + RECENT_FILE_MASKS.add("*.as"); + RECENT_FILE_MASKS.add("*.css"); + RECENT_FILE_MASKS.add("*.mxml"); + if (PlatformUtils.isPyCharm()) { + RECENT_FILE_MASKS.add("*.py"); + } + else if (PlatformUtils.isRubyMine()) { + RECENT_FILE_MASKS.add("*.rb"); + } + else if (PlatformUtils.isPhpStorm()) { + RECENT_FILE_MASKS.add("*.php"); + } + } @Override public boolean isSearchOverloadedMethods() { @@ -103,20 +124,6 @@ public class FindSettingsImpl extends FindSettings implements PersistentStateCom catch (InvalidDataException e) { LOG.info(e); } - if (RECENT_FILE_MASKS.isEmpty()) { - RECENT_FILE_MASKS.add("*.properties"); - RECENT_FILE_MASKS.add("*.html"); - RECENT_FILE_MASKS.add("*.jsp"); - RECENT_FILE_MASKS.add("*.xml"); - RECENT_FILE_MASKS.add("*.java"); - RECENT_FILE_MASKS.add("*.php"); - RECENT_FILE_MASKS.add("*.js"); - RECENT_FILE_MASKS.add("*.as"); - RECENT_FILE_MASKS.add("*.css"); - RECENT_FILE_MASKS.add("*.mxml"); - RECENT_FILE_MASKS.add("*.py"); - RECENT_FILE_MASKS.add("*.rb"); - } } @Override diff --git a/platform/lang-impl/src/com/intellij/ide/actions/NewElementAction.java b/platform/lang-impl/src/com/intellij/ide/actions/NewElementAction.java index b5b2d40817db..31d879ea72e1 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/NewElementAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/NewElementAction.java @@ -90,6 +90,10 @@ public class NewElementAction extends AnAction implements DumbAware, PopupActio presentation.setEnabled(false); return; } + if (Boolean.TRUE.equals(LangDataKeys.NO_NEW_ACTION.getData(context))) { + presentation.setEnabled(false); + return; + } final IdeView ideView = LangDataKeys.IDE_VIEW.getData(context); if (ideView == null) { presentation.setEnabled(false); diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkItem.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkItem.java index 75d3dd2da9fa..6415d3cf6baf 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkItem.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/BookmarkItem.java @@ -42,7 +42,7 @@ import java.awt.*; * Time: 2:06 AM * To change this template use File | Settings | File Templates. */ -public class BookmarkItem implements ItemWrapper { +public class BookmarkItem extends ItemWrapper { private final Bookmark myBookmark; public BookmarkItem(Bookmark bookmark) { @@ -112,12 +112,7 @@ public class BookmarkItem implements ItemWrapper { return myBookmark.getFile().getPresentableUrl(); } - @Override - public void updateDetailView(final DetailView panel) { - doUpdateDetailView(panel); - } - - private void doUpdateDetailView(DetailView panel) { + protected void doUpdateDetailView(DetailView panel, boolean editorOnly) { panel.navigateInPreviewEditor(DetailView.PreviewEditorState.create(myBookmark.getFile(), myBookmark.getLine())); } diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java index 4e513fad4c78..ad17b92a5a15 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/BookmarksAction.java @@ -33,7 +33,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.components.JBList; -import com.intellij.ui.popup.util.DetailViewImpl; import com.intellij.ui.popup.util.ItemWrapper; import com.intellij.ui.popup.util.MasterDetailPopupBuilder; import com.intellij.ui.speedSearch.FilteringListModel; @@ -125,7 +124,7 @@ public class BookmarksAction extends AnAction implements DumbAware, MasterDetail } @Override - public void itemChosen(ItemWrapper item, Project project, JBPopup popup) { + public void itemChosen(ItemWrapper item, Project project, JBPopup popup, boolean withEnterOrDoubleClick) { if (item instanceof BookmarkItem) { Bookmark bookmark = ((BookmarkItem)item).getBookmark(); popup.cancel(); diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MnemonicChooser.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MnemonicChooser.java index 6897fb9780e1..d9b50fd3e8f9 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MnemonicChooser.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/MnemonicChooser.java @@ -20,6 +20,7 @@ package com.intellij.ide.bookmarks.actions; import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.ui.ClickListener; import com.intellij.ui.LightColors; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.util.ui.UIUtil; @@ -110,12 +111,15 @@ public class MnemonicChooser extends JPanel { setForeground(UIUtil.getListForeground()); setBackground(backgroundForMnemonic(c)); } - - @Override - public void mouseClicked(MouseEvent e) { - onMnemonicChosen(c); - } }); + + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { + onMnemonicChosen(c); + return true; + } + }.installOn(this); } } } diff --git a/platform/lang-impl/src/com/intellij/ide/commander/CommanderPanel.java b/platform/lang-impl/src/com/intellij/ide/commander/CommanderPanel.java index d34eb16104d1..289818283749 100644 --- a/platform/lang-impl/src/com/intellij/ide/commander/CommanderPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/commander/CommanderPanel.java @@ -130,13 +130,14 @@ public class CommanderPanel extends JPanel { drillDown(); } }); - myList.addMouseListener(new MouseAdapter() { - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() == 2) { - drillDown(); - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + drillDown(); + return true; } - }); + }.installOn(myList); + myList.getInputMap(WHEN_FOCUSED) .put(KeyStroke.getKeyStroke(KeyEvent.VK_PAGE_UP, SystemInfo.isMac ? KeyEvent.META_MASK : KeyEvent.CTRL_MASK), ACTION_GO_UP); myList.getInputMap(WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0), ACTION_GO_UP); diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/Concept.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/Concept.java new file mode 100644 index 000000000000..e4a2d3c57b1f --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/Concept.java @@ -0,0 +1,27 @@ +/* + * 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.favoritesTreeView; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/1/12 + * Time: 2:14 PM + */ +public class Concept { + private String myTagName; + private String myDescription; +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesListNode.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesListNode.java index ea14a7a7d644..2415484f26ce 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesListNode.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesListNode.java @@ -22,6 +22,7 @@ import com.intellij.ide.projectView.impl.AbstractUrl; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; +import com.intellij.util.TreeItem; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -35,51 +36,78 @@ import java.util.List; public class FavoritesListNode extends AbstractTreeNode { private final Project myProject; private final String myListName; + private final boolean myAllowsTree; - protected FavoritesListNode(Project project, String listName) { + protected FavoritesListNode(Project project, String listName, boolean tree) { super(project, listName); myProject = project; myListName = listName; + myAllowsTree = tree; + } + + public boolean isAllowsTree() { + return myAllowsTree; } @NotNull @Override public Collection getChildren() { - return getFavoritesRoots(myProject, myListName); + return getFavoritesRoots(myProject, myListName, this); } @Override protected void update(PresentationData presentation) { - presentation.setIcons(AllIcons.General.ToolWindowFavorites); + presentation.setIcons(AllIcons.Toolwindows.ToolWindowFavorites); presentation.setPresentableText(myListName); } - @NotNull public static Collection getFavoritesRoots(Project project, String listName) { - final Collection> pairs = FavoritesManager.getInstance(project).getFavoritesListRootUrls(listName); + @NotNull public static Collection getFavoritesRoots(Project project, String listName, final FavoritesListNode listNode) { + final Collection>> pairs = FavoritesManager.getInstance(project).getFavoritesListRootUrls(listName); if (pairs == null) return Collections.emptyList(); - return createFavoriteRoots(project, pairs); + return createFavoriteRoots(project, pairs, listNode); } @NotNull - private static Collection createFavoriteRoots(Project project, @NotNull Collection> urls) { - List result = new ArrayList(); - for (Pair pair : urls) { - AbstractUrl abstractUrl = pair.getFirst(); + private static Collection createFavoriteRoots(Project project, @NotNull Collection>> urls, + final AbstractTreeNode me) { + Collection result = new ArrayList(); + processUrls(project, urls, result, me); + return result; + } + + private static void processUrls(Project project, + Collection>> urls, + Collection result, final AbstractTreeNode me) { + for (TreeItem> pair : urls) { + AbstractUrl abstractUrl = pair.getData().getFirst(); final Object[] path = abstractUrl.createPath(project); if (path == null || path.length < 1 || path[0] == null) { continue; } try { - final String className = pair.getSecond(); + final String className = pair.getData().getSecond(); @SuppressWarnings("unchecked") final Class nodeClass = (Class)Class.forName(className); - final AbstractTreeNode node = ProjectViewNode.createTreeNode(nodeClass, project, path[path.length - 1], FavoritesManager.getInstance(project).getViewSettings()); + final AbstractTreeNode node = ProjectViewNode + .createTreeNode(nodeClass, project, path[path.length - 1], FavoritesManager.getInstance(project).getViewSettings()); + node.setParent(me); + node.setIndex(result.size()); result.add(node); + + if (node instanceof ProjectViewNodeWithChildrenList) { + final List>> children = pair.getChildren(); + if (children != null && ! children.isEmpty()) { + Collection childList = new ArrayList(); + processUrls(project, children, childList, node); + for (AbstractTreeNode treeNode : childList) { + ((ProjectViewNodeWithChildrenList)node).addChild(treeNode); + } + } + } } catch (Exception ignored) { } } - return result; - } + } } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesListProvider.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesListProvider.java new file mode 100644 index 000000000000..a80ab7f13fa9 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesListProvider.java @@ -0,0 +1,51 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.ide.dnd.aware.DnDAwareTree; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; + +import javax.swing.tree.TreeCellRenderer; +import java.util.Comparator; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/7/12 + * Time: 4:17 PM + */ +public interface FavoritesListProvider { + ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.favoritesListProvider"); + + String getListName(final Project project); + boolean canBeRemoved(); + boolean isTreeLike(); + + Comparator getNodeDescriptorComparator(); + + Operation getCustomDeleteOperation(); + Operation getCustomAddOperation(); + Operation getCustomEditOperation(); + + TreeCellRenderer getTreeCellRenderer(); + + interface Operation { + boolean willHandle(final DnDAwareTree tree); + String getCustomName(); + void handle(Project project, final DnDAwareTree tree); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesManager.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesManager.java index 44744c76c999..80d1f6a7118e 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesManager.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesManager.java @@ -34,21 +34,31 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.ArrayUtil; +import com.intellij.util.Consumer; +import com.intellij.util.TreeItem; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.tree.TreeCellRenderer; import java.util.*; public class FavoritesManager implements ProjectComponent, JDOMExternalizable { // fav list name -> list of (root: root url, root class) - private final Map>> myName2FavoritesRoots = - new LinkedHashMap>>(); + private final Map>>> myName2FavoritesRoots = + new LinkedHashMap>>>(); + private final Set myReadOnlyLists = new HashSet(); + private final Set myAllowsTreeLists = new HashSet(); private final Project myProject; private final List myListeners = new ArrayList(); private final FavoritesViewSettings myViewSettings = new FavoritesViewSettings(); - + private final Map myEditHandlers = new HashMap(); + private final Map myAddHandlers = new HashMap(); + private final Map myDeleteHandlers = new HashMap(); + private final Map myCustomRenderers = new HashMap(); + private final Map> myComparators = new HashMap>(); + private final FavoritesListener fireListeners = new FavoritesListener() { public void rootsChanged(String listName) { FavoritesListener[] listeners = myListeners.toArray(new FavoritesListener[myListeners.size()]); @@ -79,6 +89,31 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { myListeners.remove(listener); } + public synchronized FavoritesListProvider.Operation getCustomAdd(final String name) { + return myAddHandlers.get(name); + } + + public synchronized FavoritesListProvider.Operation getCustomEdit(final String name) { + return myEditHandlers.get(name); + } + + public synchronized FavoritesListProvider.Operation getCustomDelete(final String name) { + return myDeleteHandlers.get(name); + } + + public void removeRootByIndexes(String name, List elementsIndexes) { + List>> list = getFavoritesListRootUrls(name); + assert list != null; + for (Integer index : elementsIndexes.subList(0, elementsIndexes.size() - 1)) { + assert index >= 0 && index < list.size(); + final TreeItem> item = list.get(index); + list = item.getChildren(); + } + assert list != null && ! list.isEmpty(); + list.remove(elementsIndexes.get(elementsIndexes.size() - 1).intValue()); + fireListeners.rootsChanged(name); + } + public static FavoritesManager getInstance(Project project) { return project.getComponent(FavoritesManager.class); } @@ -87,31 +122,45 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { myProject = project; } - @NotNull public String[] getAvailableFavoritesLists(){ + @NotNull public String[] getAvailableFavoritesListNames(){ final Set keys = myName2FavoritesRoots.keySet(); return ArrayUtil.toStringArray(keys); } - public synchronized void createNewList(@NotNull String name){ - myName2FavoritesRoots.put(name, new LinkedHashSet>()); + public synchronized boolean allowsTree(@NotNull final String name) { + return myAllowsTreeLists.contains(name); + } + + public synchronized void createNewList(@NotNull String name, boolean readOnly, boolean allowsTree){ + myName2FavoritesRoots.put(name, new ArrayList>>()); + if (readOnly) { + myReadOnlyLists.add(name); + } + if (allowsTree) { + myAllowsTreeLists.add(name); + } fireListeners.listAdded(name); } + public synchronized void fireListeners(@NotNull final String listName) { + fireListeners.rootsChanged(listName); + } + public FavoritesViewSettings getViewSettings() { return myViewSettings; } public synchronized boolean removeFavoritesList(@NotNull String name){ - if (name.equals(myProject.getName())) return false; + if (myReadOnlyLists.contains(name)) return false; boolean result = myName2FavoritesRoots.remove(name) != null; fireListeners.listRemoved(name); return result; } @NotNull - public Collection> getFavoritesListRootUrls(@NotNull String name) { - final LinkedHashSet> pairs = myName2FavoritesRoots.get(name); - return pairs == null ? Collections.>emptyList() : pairs; + public List>> getFavoritesListRootUrls(@NotNull String name) { + final List>> pairs = myName2FavoritesRoots.get(name); + return pairs == null ? Collections.>>emptyList() : pairs; } public synchronized boolean addRoots(@NotNull String name, Module moduleContext, @NotNull Object elements) { @@ -119,27 +168,139 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { return !nodes.isEmpty() && addRoots(name, nodes); } + public synchronized Comparator getCustomComparator(@NotNull final String name) { + return myComparators.get(name); + } + + private Pair createPairForNode(AbstractTreeNode node) { + final String className = node.getClass().getName(); + final Object value = node.getValue(); + final AbstractUrl url = createUrlByElement(value, myProject); + if (url == null) return null; + return Pair.create(url, className); + } + public boolean addRoots(final String name, final Collection nodes) { - final Collection> list = getFavoritesListRootUrls(name); + final Collection>> list = getFavoritesListRootUrls(name); for (AbstractTreeNode node : nodes) { - final String className = node.getClass().getName(); - final Object value = node.getValue(); - final AbstractUrl url = createUrlByElement(value, myProject); - if (url != null) { - list.add(Pair.create(url, className)); + final Pair pair = createPairForNode(node); + if (pair != null) { + final TreeItem> treeItem = new TreeItem>(pair); + list.add(treeItem); + appendChildNodes(node, treeItem); } } fireListeners.rootsChanged(name); return true; } - public synchronized boolean removeRoot(@NotNull String name, @NotNull Object element) { - AbstractUrl url = createUrlByElement(element, myProject); + private void appendChildNodes(AbstractTreeNode node, TreeItem> treeItem) { + final Collection children = node.getChildren(); + for (AbstractTreeNode child : children) { + final TreeItem> childTreeItem = new TreeItem>(createPairForNode(child)); + treeItem.addChild(childTreeItem); + appendChildNodes(child, childTreeItem); + } + } + + public synchronized boolean addRoot(@NotNull String name, + @NotNull List parentElements, + final AbstractTreeNode newElement, + @Nullable AbstractTreeNode sibling) { + final List>> items = myName2FavoritesRoots.get(name); + if (items == null) return false; + AbstractUrl url = createUrlByElement(newElement.getValue(), myProject); if (url == null) return false; - Collection> list = getFavoritesListRootUrls(name); - Pair found = null; - for (Pair pair : list) { - if (url.equals(pair.getFirst())) { + final TreeItem> newItem = + new TreeItem>(Pair.create(url, newElement.getClass().getName())); + + if (parentElements.isEmpty()) { + // directly to list + if (sibling != null) { + TreeItem> after = null; + AbstractUrl siblingUrl = createUrlByElement(sibling.getValue(), myProject); + int idx = -1; + for (int i = 0; i < items.size(); i++) { + TreeItem> item = items.get(i); + if (item.getData().getFirst().equals(siblingUrl)) { + idx = i; + break; + } + } + if (idx != -1) { + items.add(idx, newItem); + } else { + items.add(newItem); + } + } else { + items.add(newItem); + } + + fireListeners.rootsChanged(name); + return true; + } + + Collection>> list = items; + TreeItem> item = null; + for (AbstractTreeNode obj : parentElements) { + item = findNextItem(obj, list); + if (item == null) return false; + list = item.getChildren(); + } + + if (sibling != null) { + TreeItem> after = null; + AbstractUrl siblingUrl = createUrlByElement(sibling.getValue(), myProject); + for (TreeItem> treeItem : list) { + if (treeItem.getData().getFirst().equals(siblingUrl)) { + after = treeItem; + break; + } + } + if (after == null) { + item.addChild(newItem); + } else { + item.addChildAfter(newItem, after); + } + } else { + item.addChild(newItem); + } + fireListeners.rootsChanged(name); + return true; + } + + public synchronized boolean editRoot(@NotNull String name, @NotNull List elementsIndexes, final AbstractTreeNode newElement) { + List>> list = getFavoritesListRootUrls(name); + assert list != null; + for (Integer index : elementsIndexes.subList(0, elementsIndexes.size() - 1)) { + assert index >= 0 && index < list.size(); + final TreeItem> item = list.get(index); + list = item.getChildren(); + } + assert list != null && ! list.isEmpty(); + final Object value = newElement.getValue(); + final AbstractUrl urlByElement = createUrlByElement(value, myProject); + if (urlByElement == null) return false; + list.set(elementsIndexes.get(elementsIndexes.size() - 1).intValue(), new TreeItem>(Pair.create(urlByElement, newElement.getClass().getName()))); + return true; + } + + public synchronized boolean removeRoot(@NotNull String name, @NotNull List elements) { + Collection>> list = getFavoritesListRootUrls(name); + if (elements.size() > 1) { + final List sublist = elements.subList(0, elements.size() - 1); + for (AbstractTreeNode obj : sublist) { + final TreeItem> item = findNextItem(obj, list); + if (item == null || item.getChildren() == null) return false; + list = item.getChildren(); + } + } + + TreeItem> found = null; + AbstractUrl url = createUrlByElement(elements.get(elements.size() - 1).getValue(), myProject); + if (url == null) return false; + for (TreeItem> pair : list) { + if (url.equals(pair.getData().getFirst())) { found = pair; break; } @@ -149,11 +310,23 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { fireListeners.rootsChanged(name); return true; } + return false; } + private TreeItem> findNextItem(AbstractTreeNode obj, Collection>> list) { + AbstractUrl url = createUrlByElement(obj.getValue(), myProject); + for (TreeItem> pair : list) { + if (url.equals(pair.getData().getFirst())) { + return pair; + } + } + return null; + } + public synchronized boolean renameFavoritesList(@NotNull String oldName, @NotNull String newName) { - LinkedHashSet> list = myName2FavoritesRoots.remove(oldName); + if (myReadOnlyLists.contains(oldName)) return false; + List>> list = myName2FavoritesRoots.remove(oldName); if (list != null && newName.length() > 0) { myName2FavoritesRoots.put(newName, list); fireListeners.listRemoved(oldName); @@ -163,6 +336,10 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { return false; } + public synchronized boolean isReadOnly(@NotNull final String listName) { + return myReadOnlyLists.contains(listName); + } + public void initComponent() { } @@ -171,9 +348,34 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { public void projectOpened() { StartupManager.getInstance(myProject).registerPostStartupActivity(new DumbAwareRunnable() { public void run() { - if (myName2FavoritesRoots.isEmpty()) { - final String name = myProject.getName(); - createNewList(name); + final FavoritesListProvider[] extensions = Extensions.getExtensions(FavoritesListProvider.EP_NAME, myProject); + for (FavoritesListProvider extension : extensions) { + final String name = extension.getListName(myProject); + if (! myName2FavoritesRoots.containsKey(name)) { + createNewList(name, extension.canBeRemoved(), extension.isTreeLike()); + } else if (! myReadOnlyLists.contains(name) && ! extension.canBeRemoved()) { + myReadOnlyLists.add(name); + } + final FavoritesListProvider.Operation addOperation = extension.getCustomAddOperation(); + if (! myAddHandlers.containsKey(name)) { + myAddHandlers.put(name, addOperation); + } + final FavoritesListProvider.Operation editOperation = extension.getCustomEditOperation(); + if (! myEditHandlers.containsKey(name)) { + myEditHandlers.put(name, editOperation); + } + final FavoritesListProvider.Operation deleteOperation = extension.getCustomDeleteOperation(); + if (! myDeleteHandlers.containsKey(name)) { + myDeleteHandlers.put(name, deleteOperation); + } + final TreeCellRenderer treeCellRenderer = extension.getTreeCellRenderer(); + if (treeCellRenderer != null && ! myCustomRenderers.containsKey(name)) { + myCustomRenderers.put(name, treeCellRenderer); + } + final Comparator comparator = extension.getNodeDescriptorComparator(); + if (comparator != null && ! myComparators.containsKey(name)) { + myComparators.put(name, comparator); + } } final MyRootsChangeAdapter myPsiTreeChangeAdapter = new MyRootsChangeAdapter(); @@ -190,11 +392,15 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { return "FavoritesManager"; } + public synchronized TreeCellRenderer getCustomRenderer(@NotNull final String name) { + return myCustomRenderers.get(name); + } + public void readExternal(Element element) throws InvalidDataException { myName2FavoritesRoots.clear(); for (Object list : element.getChildren(ELEMENT_FAVORITES_LIST)) { final String name = ((Element)list).getAttributeValue(ATTRIBUTE_NAME); - LinkedHashSet> roots = readRoots((Element)list, myProject); + List>> roots = readRoots((Element)list, myProject); myName2FavoritesRoots.put(name, roots); } DefaultJDOMExternalizer.readExternal(this, element); @@ -204,16 +410,26 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { @NonNls private static final String FAVORITES_ROOT = "favorite_root"; @NonNls private static final String ELEMENT_FAVORITES_LIST = "favorites_list"; @NonNls private static final String ATTRIBUTE_NAME = "name"; - private static LinkedHashSet> readRoots(final Element list, Project project) { - LinkedHashSet> result = new LinkedHashSet>(); - for (Object favorite : list.getChildren(FAVORITES_ROOT)) { - final String className = ((Element)favorite).getAttributeValue(CLASS_NAME); - final AbstractUrl abstractUrl = readUrlFromElement((Element)favorite, project); + private static List>> readRoots(final Element list, Project project) { + List>> result = new ArrayList>>(); + readFavoritesOneLevel(list, project, result); + return result; + } + + private static void readFavoritesOneLevel(Element list, Project project, Collection>> result) { + final List listChildren = list.getChildren(FAVORITES_ROOT); + if (listChildren == null || listChildren.isEmpty()) return; + + for (Object favorite : listChildren) { + final Element favoriteElement = (Element)favorite; + final String className = favoriteElement.getAttributeValue(CLASS_NAME); + final AbstractUrl abstractUrl = readUrlFromElement(favoriteElement, project); if (abstractUrl != null) { - result.add(Pair.create(abstractUrl, className)); + final TreeItem> treeItem = new TreeItem>(Pair.create(abstractUrl, className)); + result.add(treeItem); + readFavoritesOneLevel(favoriteElement, project, treeItem.getChildren()); } } - return result; } private static final ArrayList ourAbstractUrlProviders = new ArrayList(); @@ -279,18 +495,22 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { return null; } - private static void writeRoots(Element element, LinkedHashSet> roots) { - for (Pair root : roots) { - final AbstractUrl url = root.getFirst(); + private static void writeRoots(Element element, Collection>> roots) { + for (TreeItem> root : roots) { + final AbstractUrl url = root.getData().getFirst(); if (url == null) continue; final Element list = new Element(FAVORITES_ROOT); url.write(list); - list.setAttribute(CLASS_NAME, root.getSecond()); + list.setAttribute(CLASS_NAME, root.getData().getSecond()); element.addContent(list); + final List>> children = root.getChildren(); + if (children != null && ! children.isEmpty()) { + writeRoots(list, children); + } } } - + // currently only one level here.. public boolean contains(@NotNull String name, @NotNull final VirtualFile vFile){ final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex(); final Set find = new HashSet(); @@ -303,9 +523,9 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { } }; - Collection> urls = getFavoritesListRootUrls(name); - for (Pair pair : urls) { - AbstractUrl abstractUrl = pair.getFirst(); + Collection>> urls = getFavoritesListRootUrls(name); + for (TreeItem> pair : urls) { + AbstractUrl abstractUrl = pair.getData().getFirst(); if (abstractUrl == null) { continue; } @@ -377,6 +597,19 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { return false; } + private void iterateTreeItems(final Collection>> coll, Consumer>> consumer) { + final ArrayDeque>> queue = new ArrayDeque>>(); + queue.addAll(coll); + while (! queue.isEmpty()) { + final TreeItem> item = queue.removeFirst(); + consumer.consume(item); + final List>> children = item.getChildren(); + if (children != null && ! children.isEmpty()) { + queue.addAll(children); + } + } + } + private class MyRootsChangeAdapter extends PsiTreeChangeAdapter { public void beforeChildMovement(@NotNull final PsiTreeChangeEvent event) { final PsiElement oldParent = event.getOldParent(); @@ -393,26 +626,29 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { childUrl = new DirectoryUrl(((PsiDirectory)newParent).getVirtualFile().getUrl() + "/" + ((PsiDirectory)child).getName(), module.getName()); } + for (String listName : myName2FavoritesRoots.keySet()) { - final LinkedHashSet> roots = myName2FavoritesRoots.get(listName); - final LinkedHashSet> newRoots = new LinkedHashSet>(); - for (Pair root : roots) { - final Object[] path = root.first.createPath(myProject); - if (path == null || path.length < 1 || path[0] == null) { - continue; - } - final Object element = path[path.length - 1]; - if (element == child && childUrl != null) { - newRoots.add(Pair.create(childUrl, root.second)); - } - else { - if (element == oldParent) { - newRoots.add(Pair.create(root.first.createUrlByElement(newParent), root.second)); + final List>> roots = myName2FavoritesRoots.get(listName); + final AbstractUrl finalChildUrl = childUrl; + iterateTreeItems(roots, new Consumer>>() { + @Override + public void consume(TreeItem> item) { + final Pair root = item.getData(); + final Object[] path = root.first.createPath(myProject); + if (path == null || path.length < 1 || path[0] == null) { + return; + } + final Object element = path[path.length - 1]; + if (element == child && finalChildUrl != null) { + item.setData(Pair.create(finalChildUrl, root.second)); + } + else { + if (element == oldParent) { + item.setData(Pair.create(root.first.createUrlByElement(newParent), root.second)); + } } - newRoots.add(root); } - } - myName2FavoritesRoots.put(listName, newRoots); + }); } } } @@ -425,22 +661,26 @@ public class FavoritesManager implements ProjectComponent, JDOMExternalizable { if (module == null) return; final String url = ((PsiDirectory)psiElement.getParent()).getVirtualFile().getUrl() + "/" + event.getNewValue(); final AbstractUrl childUrl = psiElement instanceof PsiFile ? new PsiFileUrl(url) : new DirectoryUrl(url, module.getName()); + for (String listName : myName2FavoritesRoots.keySet()) { - final LinkedHashSet> roots = myName2FavoritesRoots.get(listName); - final LinkedHashSet> newRoots = new LinkedHashSet>(); - for (Pair root : roots) { - final Object[] path = root.first.createPath(myProject); - if (path == null || path.length < 1 || path[0] == null) { - continue; + final List>> roots = myName2FavoritesRoots.get(listName); + iterateTreeItems(roots, new Consumer>>() { + @Override + public void consume(TreeItem> item) { + final Pair root = item.getData(); + final Object[] path = root.first.createPath(myProject); + if (path == null || path.length < 1 || path[0] == null) { + return; + } + final Object element = path[path.length - 1]; + if (element == psiElement && psiElement instanceof PsiFile) { + item.setData(Pair.create(childUrl, root.second)); + } + else { + item.setData(root); + } } - final Object element = path[path.length - 1]; - if (element == psiElement && psiElement instanceof PsiFile) { - newRoots.add(Pair.create(childUrl, root.second)); - } else { - newRoots.add(root); - } - } - myName2FavoritesRoots.put(listName, newRoots); + }); } } } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesPanel.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesPanel.java index d2e0864f3941..a2066fbed8fe 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesPanel.java @@ -34,6 +34,7 @@ import javax.swing.tree.TreePath; import java.awt.*; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; /** * @author Konstantin Bulenkov @@ -73,6 +74,7 @@ public class FavoritesPanel { return new DnDDragStartBean(""); } }) + // todo process drag-and-drop here for tasks .setTargetChecker(new DnDTargetChecker() { @Override public boolean update(DnDEvent event) { @@ -132,9 +134,9 @@ public class FavoritesPanel { final String listFrom = getListNodeFromPath(path).getValue(); if (listTo.equals(listFrom)) return; if (path.getPathCount() == 3) { - final Object element = ((FavoritesTreeNodeDescriptor)((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject()) + final AbstractTreeNode element = (AbstractTreeNode)((FavoritesTreeNodeDescriptor)((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject()) .getElement().getValue(); - mgr.removeRoot(listFrom, element); + mgr.removeRoot(listFrom, Collections.singletonList(element)); mgr.addRoots(listTo, null, element); } } @@ -143,7 +145,8 @@ public class FavoritesPanel { if (elements != null && elements.length > 0) { ArrayList nodes = new ArrayList(); for (PsiElement element : elements) { - final Collection tmp = AddToFavoritesAction.createNodes(myProject, null, element, true, FavoritesManager.getInstance(myProject).getViewSettings()); + final Collection tmp = AddToFavoritesAction + .createNodes(myProject, null, element, true, FavoritesManager.getInstance(myProject).getViewSettings()); nodes.addAll(tmp); mgr.addRoots(listTo, nodes); } @@ -171,7 +174,7 @@ public class FavoritesPanel { } return null; } - + @Nullable private FavoritesListNode findFavoritesListNode(Point point) { diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesProjectViewPane.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesProjectViewPane.java index d8e95c715fcd..b0c9b0a69c28 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesProjectViewPane.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesProjectViewPane.java @@ -69,7 +69,7 @@ public class FavoritesProjectViewPane extends AbstractProjectViewPane { myProjectView.addProjectPane(FavoritesProjectViewPane.this); myFavoritesManager.addFavoritesListener(myFavoritesListener); - if (ArrayUtil.find(myFavoritesManager.getAvailableFavoritesLists(), listName) == -1) { + if (ArrayUtil.find(myFavoritesManager.getAvailableFavoritesListNames(), listName) == -1) { listName = null; } myProjectView.changeView(ID, listName); @@ -83,7 +83,7 @@ public class FavoritesProjectViewPane extends AbstractProjectViewPane { } public Icon getIcon() { - return AllIcons.General.ToolWindowFavorites; + return AllIcons.Toolwindows.ToolWindowFavorites; } @NotNull @@ -113,7 +113,7 @@ public class FavoritesProjectViewPane extends AbstractProjectViewPane { @NotNull public String[] getSubIds() { - return myFavoritesManager.getAvailableFavoritesLists(); + return myFavoritesManager.getAvailableFavoritesListNames(); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesRootNode.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesRootNode.java index 03b690e33698..cdbf688563de 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesRootNode.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesRootNode.java @@ -39,8 +39,9 @@ public class FavoritesRootNode extends AbstractTreeNode { public Collection getChildren() { if (myFavoritesRoots == null) { myFavoritesRoots = new ArrayList(); - for (String list : FavoritesManager.getInstance(myProject).getAvailableFavoritesLists()) { - myFavoritesRoots.add(new FavoritesListNode(myProject, list)); + final FavoritesManager favoritesManager = FavoritesManager.getInstance(myProject); + for (String list : favoritesManager.getAvailableFavoritesListNames()) { + myFavoritesRoots.add(new FavoritesListNode(myProject, list, favoritesManager.allowsTree(list))); } } return myFavoritesRoots; diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeNodeDescriptor.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeNodeDescriptor.java index 87b5cea954c8..dfae403c17eb 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeNodeDescriptor.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeNodeDescriptor.java @@ -55,7 +55,11 @@ public class FavoritesTreeNodeDescriptor extends PresentableNodeDescriptor result = new HashSet(); - for (AbstractTreeNode abstractTreeNode : FavoritesListNode.getFavoritesRoots(myProject, ((FavoritesListNode)element).getName())) { + final List result = new ArrayList(); + final FavoritesListNode listNode = (FavoritesListNode)element; + final Collection roots = FavoritesListNode.getFavoritesRoots(myProject, listNode.getName(), listNode); + for (AbstractTreeNode abstractTreeNode : roots) { final Object value = abstractTreeNode.getValue(); if (value == null) continue; diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeUtil.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeUtil.java new file mode 100644 index 000000000000..3abb8d3a08d1 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeUtil.java @@ -0,0 +1,120 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.ide.dnd.aware.DnDAwareTree; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import org.jetbrains.annotations.NotNull; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/9/12 + * Time: 5:33 PM + */ +public class FavoritesTreeUtil { + @NotNull + public static FavoritesTreeNodeDescriptor[] getSelectedNodeDescriptors(final DnDAwareTree tree) { + TreePath[] path = tree.getSelectionPaths(); + if (path == null) { + return FavoritesTreeNodeDescriptor.EMPTY_ARRAY; + } + ArrayList result = new ArrayList(); + for (TreePath treePath : path) { + DefaultMutableTreeNode lastPathNode = (DefaultMutableTreeNode)treePath.getLastPathComponent(); + Object userObject = lastPathNode.getUserObject(); + if (!(userObject instanceof FavoritesTreeNodeDescriptor)) { + continue; + } + FavoritesTreeNodeDescriptor treeNodeDescriptor = (FavoritesTreeNodeDescriptor)userObject; + result.add(treeNodeDescriptor); + } + return result.toArray(new FavoritesTreeNodeDescriptor[result.size()]); + } + + public static List getLogicalPathToSelected(final DnDAwareTree tree) { + final List result = new ArrayList(); + final TreePath selectionPath = tree.getSelectionPath(); + return getLogicalPathTo(result, selectionPath); + } + + public static List getLogicalIndexPathTo(TreePath selectionPath) { + final List result = new ArrayList(); + final Object component = selectionPath.getLastPathComponent(); + if (component instanceof DefaultMutableTreeNode) { + final Object uo = ((DefaultMutableTreeNode)component).getUserObject(); + if (uo instanceof FavoritesTreeNodeDescriptor) { + AbstractTreeNode treeNode = ((FavoritesTreeNodeDescriptor)uo).getElement(); + while ((! (treeNode instanceof FavoritesListNode)) && treeNode != null) { +// final int idx = getIndex(treeNode.getParent().getChildren(), treeNode); +// if (idx == -1) return null; + result.add(treeNode.getIndex()); + treeNode = treeNode.getParent(); + } + Collections.reverse(result); + return result; + } + } + return Collections.emptyList(); + } + + /*private static int getIndex(Collection children, AbstractTreeNode node) { + int idx = 0; + for (AbstractTreeNode child : children) { + if (child == node) { + return idx; + } + ++ idx; + } + assert false; + return -1; + }*/ + + public static List getLogicalPathTo(List result, TreePath selectionPath) { + final Object component = selectionPath.getLastPathComponent(); + if (component instanceof DefaultMutableTreeNode) { + final Object uo = ((DefaultMutableTreeNode)component).getUserObject(); + if (uo instanceof FavoritesTreeNodeDescriptor) { + AbstractTreeNode treeNode = ((FavoritesTreeNodeDescriptor)uo).getElement(); + while ((! (treeNode instanceof FavoritesListNode)) && treeNode != null) { + result.add(treeNode); + treeNode = treeNode.getParent(); + } + Collections.reverse(result); + return result; + } + } + return Collections.emptyList(); + } + + public static FavoritesListNode extractParentList(FavoritesTreeNodeDescriptor descriptor) { + final AbstractTreeNode node = descriptor.getElement(); + AbstractTreeNode current = node; + while (current != null) { + if (current instanceof FavoritesListNode) { + return (FavoritesListNode) current; + } + current = current.getParent(); + } + return null; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java index 510ce562be71..d8aadd19df70 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java @@ -19,12 +19,10 @@ package com.intellij.ide.favoritesTreeView; import com.intellij.history.LocalHistory; import com.intellij.history.LocalHistoryAction; import com.intellij.icons.AllIcons; -import com.intellij.ide.CopyPasteDelegator; -import com.intellij.ide.DeleteProvider; -import com.intellij.ide.IdeBundle; -import com.intellij.ide.IdeView; +import com.intellij.ide.*; import com.intellij.ide.dnd.aware.DnDAwareTree; import com.intellij.ide.favoritesTreeView.actions.*; +import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.projectView.impl.ModuleGroup; import com.intellij.ide.projectView.impl.nodes.LibraryGroupElement; import com.intellij.ide.projectView.impl.nodes.NamedLibraryElement; @@ -34,6 +32,7 @@ import com.intellij.ide.util.DeleteHandler; import com.intellij.ide.util.DirectoryChooserUtil; import com.intellij.ide.util.EditorHelper; import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.ide.util.treeView.NodeRenderer; import com.intellij.navigation.ItemPresentation; import com.intellij.openapi.actionSystem.*; @@ -43,7 +42,9 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ui.configuration.actions.ModuleDeleteProvider; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -62,13 +63,14 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.ChangeListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; +import javax.swing.tree.TreeCellRenderer; import java.awt.*; import java.awt.event.MouseListener; -import java.util.ArrayList; -import java.util.Arrays; +import java.io.File; +import java.util.*; import java.util.List; /** @@ -76,12 +78,14 @@ import java.util.List; * @author Konstantin Bulenkov */ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { + public static final String NEW_FAVORITES_LIST = "New Favorites List..."; private final FavoritesTreeStructure myFavoritesTreeStructure; private FavoritesViewTreeBuilder myBuilder; private final CopyPasteDelegator myCopyPasteDelegator; private final MouseListener myTreePopupHandler; public static final DataKey CONTEXT_FAVORITES_ROOTS_DATA_KEY = DataKey.create("FavoritesRoot"); + public static final DataKey FAVORITES_TREE_KEY = DataKey.create("Favorites.Tree"); public static final DataKey FAVORITES_LIST_NAME_DATA_KEY = DataKey.create("FavoritesListName"); protected Project myProject; @@ -89,25 +93,16 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { private final MyDeletePSIElementProvider myDeletePSIElementProvider = new MyDeletePSIElementProvider(); private final ModuleDeleteProvider myDeleteModuleProvider = new ModuleDeleteProvider(); - private final AutoScrollToSourceHandler myAutoScrollToSourceHandler = new AutoScrollToSourceHandler() { - @Override - protected boolean isAutoScrollMode() { - return FavoritesManager.getInstance(myProject).getViewSettings().isAutoScrollToSource(); - } - - @Override - protected void setAutoScrollMode(boolean state) { - FavoritesManager.getInstance(myProject).getViewSettings().setAutoScrollToSource(state); - } - }; - - + private final AutoScrollToSourceHandler myAutoScrollToSourceHandler; private final IdeView myIdeView = new MyIdeView(); + private final FavoritesManager myFavoritesManager; + private final NodeRenderer myNodeRenderer; public FavoritesTreeViewPanel(Project project) { super(new BorderLayout()); myProject = project; + myFavoritesManager = FavoritesManager.getInstance(myProject); myFavoritesTreeStructure = new FavoritesTreeStructure(project); DefaultMutableTreeNode root = new DefaultMutableTreeNode(); @@ -121,9 +116,26 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { myTree.setRootVisible(false); myTree.setShowsRootHandles(true); myTree.setLargeModel(true); + myTree.setRowHeight(0); new TreeSpeedSearch(myTree); ToolTipManager.sharedInstance().registerComponent(myTree); - myTree.setCellRenderer(new NodeRenderer() { + myBuilder.setNodeDescriptorComparator(new Comparator() { + @Override + public int compare(NodeDescriptor o1, NodeDescriptor o2) { + if (o1 instanceof FavoritesTreeNodeDescriptor && o2 instanceof FavoritesTreeNodeDescriptor) { + final FavoritesListNode listNode1 = FavoritesTreeUtil.extractParentList((FavoritesTreeNodeDescriptor)o1); + final FavoritesListNode listNode2 = FavoritesTreeUtil.extractParentList((FavoritesTreeNodeDescriptor)o2); + if (listNode1.equals(listNode2)) { + final Comparator comparator = myFavoritesManager.getCustomComparator(listNode1.getName()); + if (comparator != null) { + return comparator.compare((FavoritesTreeNodeDescriptor) o1, (FavoritesTreeNodeDescriptor) o2); + } + } + } + return o1.getIndex() - o2.getIndex(); + } + }); + myNodeRenderer = new NodeRenderer() { public void customizeCellRenderer(JTree tree, Object value, boolean selected, @@ -153,6 +165,41 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { } } } + }; + myTree.setCellRenderer(new TreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + if (value instanceof DefaultMutableTreeNode) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; + //only favorites roots to explain + final Object userObject = node.getUserObject(); + if (userObject instanceof FavoritesTreeNodeDescriptor) { + final FavoritesTreeNodeDescriptor favoritesTreeNodeDescriptor = (FavoritesTreeNodeDescriptor)userObject; + AbstractTreeNode treeNode = favoritesTreeNodeDescriptor.getElement(); + while (treeNode != null && (!(treeNode instanceof FavoritesListNode))) { + treeNode = treeNode.getParent(); + } + if (treeNode != null) { + final String name = ((FavoritesListNode)treeNode).getValue(); + final TreeCellRenderer customRenderer = myFavoritesManager.getCustomRenderer(name); + if (customRenderer != null) { + final Component component = + customRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + if (component != null) { + return component; + } + } + } + } + } + return myNodeRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + } }); myTreePopupHandler = CustomizationUtil.installPopupHandler(myTree, IdeActions.GROUP_FAVORITES_VIEW_POPUP, ActionPlaces.FAVORITES_VIEW_POPUP); @@ -167,18 +214,43 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { } }; - ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTree) - .setAddAction(new AnActionButtonRunnable() { - @Override - public void run(AnActionButton button) { - AddNewFavoritesListAction.doAddNewFavoritesList(myProject); + final AnActionButtonRunnable addListOrNoteAction = new AnActionButtonRunnable() { + @Override + public void run(AnActionButton button) { + final List nodes = getSelectedListsNodes(); + if (nodes.size() == 1) { + final FavoritesListProvider.Operation customAdd = myFavoritesManager.getCustomAdd(nodes.get(0).getName()); + if (customAdd != null && customAdd.willHandle(myTree)) { + customAdd.handle(myProject, myTree); + return; + } } - }) + AddNewFavoritesListAction.doAddNewFavoritesList(myProject); + } + }; + CommonActionsManager actionsManager = CommonActionsManager.getInstance(); + final AnAction exportToTextFileAction = actionsManager.createExportToTextFileAction(createTextExporter()); + final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTree) + .setAddAction(addListOrNoteAction) .setLineBorder(0, 0, 1, 0) - .setAddActionName("New Favorites List") + .setAddActionName(NEW_FAVORITES_LIST) .disableRemoveAction() .disableDownAction() .disableUpAction() + .setAddActionUpdater(new AnActionButtonUpdater() { + @Override + public boolean isEnabled(AnActionEvent e) { + e.getPresentation().setText(NEW_FAVORITES_LIST); + final List nodes = getSelectedListsNodes(); + if (nodes.size() == 1) { + final FavoritesListProvider.Operation customAdd = myFavoritesManager.getCustomAdd(nodes.get(0).getName()); + if (customAdd != null && customAdd.willHandle(myTree)) { + e.getPresentation().setText(customAdd.getCustomName()); + } + } + return true; + } + }) .addExtraAction(new DeleteFromFavoritesAction() { { getTemplatePresentation().setIcon(IconUtil.getRemoveIcon()); @@ -188,18 +260,162 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { public ShortcutSet getShortcut() { return CustomShortcutSet.fromString("DELETE"); } + }).addExtraAction(new AnActionButton("Edit", AllIcons.Actions.Edit) { + @Override + public ShortcutSet getShortcut() { + return CommonShortcuts.getRename(); + } + + @Override + public void actionPerformed(AnActionEvent e) { + final List nodes = getSelectedListsNodes(); + if (nodes.size() == 1) { + final FavoritesListProvider.Operation customEdit = myFavoritesManager.getCustomEdit(nodes.get(0).getName()); + if (customEdit != null && customEdit.willHandle(myTree)) { + customEdit.handle(myProject, myTree); + } + } + } + + @Override + public boolean isEnabled() { + final List nodes = getSelectedListsNodes(); + if (nodes.size() == 1) { + final FavoritesListProvider.Operation customEdit = myFavoritesManager.getCustomEdit(nodes.get(0).getName()); + if (customEdit != null && customEdit.willHandle(myTree)) { + return true; + } + } + return false; + } + }).addExtraAction(new AnActionButton(exportToTextFileAction.getTemplatePresentation().getText(), + exportToTextFileAction.getTemplatePresentation().getIcon()) { + @Override + public void actionPerformed(AnActionEvent e) { + exportToTextFileAction.actionPerformed(e); + } + + @Override + public ShortcutSet getShortcut() { + return exportToTextFileAction.getShortcutSet(); + } + + @Override + public boolean isEnabled() { + return true; + } }); - AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_NEW_ELEMENT); + final AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_NEW_ELEMENT); action.registerCustomShortcutSet(action.getShortcutSet(), myTree); final JPanel panel = decorator.createPanel(); panel.setBorder(IdeBorderFactory.createEmptyBorder(0)); add(panel, BorderLayout.CENTER); setBorder(IdeBorderFactory.createEmptyBorder(0)); + myAutoScrollToSourceHandler = new AutoScrollToSourceHandler() { + @Override + protected boolean isAutoScrollMode() { + return myFavoritesManager.getViewSettings().isAutoScrollToSource(); + } + + @Override + protected void setAutoScrollMode(boolean state) { + myFavoritesManager.getViewSettings().setAutoScrollToSource(state); + } + }; myAutoScrollToSourceHandler.install(myTree); } + private ExporterToTextFile createTextExporter() { + return new ExporterToTextFile() { + @Override + public JComponent getSettingsEditor() { + return null; + } + @Override + public void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException { + } + @Override + public void removeSettingsChangedListener(ChangeListener listener) { + } + + @Override + public String getReportText() { + final StringBuilder sb = new StringBuilder(); + + final Ref previousNode = new Ref(); + final int[] depth = new int[1]; + depth[0] = 0; + final Object[] elements = myBuilder.getStructure().getChildElements(myBuilder.getRoot()); + + final TreeUtil.Traverse traverse = new TreeUtil.Traverse() { + @Override + public boolean accept(Object node) { + if (node instanceof LoadingNode) return true; + final AbstractTreeNode abstractTreeNode = (AbstractTreeNode)node; + final AbstractTreeNode parent = abstractTreeNode.getParent(); + if (Comparing.equal(previousNode.get(), parent)) { + ++depth[0]; + } + else if (previousNode.get() != null && Comparing.equal(previousNode.get().getParent(), parent)) { + //-- depth[0]; + } + else if (previousNode.get() != null) { + --depth[0]; + } + if (sb.length() > 0) { + sb.append('\n'); + } + assert depth[0] >= 0; + for (int i = 0; i < depth[0]; i++) { + sb.append('\t'); + } + abstractTreeNode.update(); + final PresentationData presentation = abstractTreeNode.getPresentation(); + sb.append(presentation.getPresentableText()); + String locationString = presentation.getLocationString(); + if (locationString == null) { + locationString = FavoritesTreeNodeDescriptor.getLocation(abstractTreeNode, myProject); + } + if (locationString != null) { + sb.append(" (").append(locationString).append(")"); + } + previousNode.set(abstractTreeNode); + return true; + } + }; + for (Object element : elements) { + traveseDepth((AbstractTreeNode)element, traverse); + } + return sb.toString(); + } + + @Override + public String getDefaultFilePath() { + return myProject.getBasePath() + File.separator + "CurrentTask.txt"; + } + + @Override + public void exportedTo(String filePath) { + } + + @Override + public boolean canExport() { + return true; + } + }; + } + + private boolean traveseDepth(final AbstractTreeNode node, final TreeUtil.Traverse traverse) { + if (! traverse.accept(node)) return false; + final Collection children = node.getChildren(); + for (Object child : children) { + if (! traveseDepth((AbstractTreeNode)child, traverse)) return false; + } + return true; + } + public void selectElement(final Object selector, final VirtualFile file, final boolean requestFocus) { myBuilder.select(selector, file, requestFocus); } @@ -251,7 +467,7 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { return myProject; } if (PlatformDataKeys.NAVIGATABLE.is(dataId)) { - final FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors(); + final FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = FavoritesTreeUtil.getSelectedNodeDescriptors(myTree); return selectedNodeDescriptors.length == 1 ? selectedNodeDescriptors[0].getElement() : null; } if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { @@ -271,6 +487,9 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { if (PlatformDataKeys.HELP_ID.is(dataId)) { return "reference.toolWindows.favorites"; } + if (LangDataKeys.NO_NEW_ACTION.is(dataId)) { + return Boolean.TRUE; + } if (LangDataKeys.PSI_ELEMENT.is(dataId)) { PsiElement[] elements = getSelectedPsiElements(); if (elements.length != 1) { @@ -326,7 +545,7 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { } if (CONTEXT_FAVORITES_ROOTS_DATA_KEY.is(dataId)) { List result = new ArrayList(); - FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors(); + FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = FavoritesTreeUtil.getSelectedNodeDescriptors(myTree); for (FavoritesTreeNodeDescriptor selectedNodeDescriptor : selectedNodeDescriptors) { FavoritesTreeNodeDescriptor root = selectedNodeDescriptor.getFavoritesRoot(); if (root != null && root.getElement() instanceof FavoritesListNode) { @@ -335,8 +554,11 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { } return result.toArray(new FavoritesTreeNodeDescriptor[result.size()]); } + if (FAVORITES_TREE_KEY.is(dataId)) { + return myTree; + } if (FAVORITES_LIST_NAME_DATA_KEY.is(dataId)) { - final FavoritesTreeNodeDescriptor[] descriptors = getSelectedNodeDescriptors(); + final FavoritesTreeNodeDescriptor[] descriptors = FavoritesTreeUtil.getSelectedNodeDescriptors(myTree); if (descriptors.length == 1) { final AbstractTreeNode node = descriptors[0].getElement(); if (node instanceof FavoritesListNode) { @@ -345,7 +567,7 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { } return null; } - FavoritesTreeNodeDescriptor[] descriptors = getSelectedNodeDescriptors(); + FavoritesTreeNodeDescriptor[] descriptors = FavoritesTreeUtil.getSelectedNodeDescriptors(myTree); if (descriptors.length > 0) { List nodes = new ArrayList(); for (FavoritesTreeNodeDescriptor descriptor : descriptors) { @@ -356,6 +578,18 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { return null; } + private List getSelectedListsNodes() { + final List result = new SmartList(); + final FavoritesTreeNodeDescriptor[] descriptors = FavoritesTreeUtil.getSelectedNodeDescriptors(myTree); + for (FavoritesTreeNodeDescriptor descriptor : descriptors) { + final FavoritesListNode listNode = FavoritesTreeUtil.extractParentList(descriptor); + if (listNode != null) { + result.add(listNode); + } + } + return result; + } + private List getSelectedElements(Class klass) { final Object[] elements = getSelectedNodeElements(); ArrayList result = new ArrayList(); @@ -390,7 +624,7 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { } private Object[] getSelectedNodeElements() { - final FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors(); + final FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = FavoritesTreeUtil.getSelectedNodeDescriptors(myTree); ArrayList result = new ArrayList(); for (FavoritesTreeNodeDescriptor selectedNodeDescriptor : selectedNodeDescriptors) { if (selectedNodeDescriptor != null) { @@ -404,25 +638,6 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider { return ArrayUtil.toObjectArray(result); } - @NotNull - public FavoritesTreeNodeDescriptor[] getSelectedNodeDescriptors() { - TreePath[] path = myTree.getSelectionPaths(); - if (path == null) { - return FavoritesTreeNodeDescriptor.EMPTY_ARRAY; - } - ArrayList result = new ArrayList(); - for (TreePath treePath : path) { - DefaultMutableTreeNode lastPathNode = (DefaultMutableTreeNode)treePath.getLastPathComponent(); - Object userObject = lastPathNode.getUserObject(); - if (!(userObject instanceof FavoritesTreeNodeDescriptor)) { - continue; - } - FavoritesTreeNodeDescriptor treeNodeDescriptor = (FavoritesTreeNodeDescriptor)userObject; - result.add(treeNodeDescriptor); - } - return result.toArray(new FavoritesTreeNodeDescriptor[result.size()]); - } - public void setupToolWindow(ToolWindowEx window) { final CollapseAllAction collapseAction = new CollapseAllAction(myTree); collapseAction.getTemplatePresentation().setIcon(AllIcons.General.CollapseAll); diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesViewSelectInTarget.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesViewSelectInTarget.java index ed52ffd3afee..254f0d0ce22c 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesViewSelectInTarget.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesViewSelectInTarget.java @@ -112,7 +112,7 @@ public class FavoritesViewSelectInTarget extends SelectInTargetPsiWrapper { public static String findSuitableFavoritesList(VirtualFile file, Project project, final String currentSubId) { final FavoritesManager favoritesManager = FavoritesManager.getInstance(project); if (currentSubId != null && favoritesManager.contains(currentSubId, file)) return currentSubId; - final String[] lists = favoritesManager.getAvailableFavoritesLists(); + final String[] lists = favoritesManager.getAvailableFavoritesListNames(); for (String name : lists) { if (favoritesManager.contains(name, file)) return name; } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FileGroupingProjectNode.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FileGroupingProjectNode.java new file mode 100644 index 000000000000..4f7704a0e40d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FileGroupingProjectNode.java @@ -0,0 +1,87 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.favoritesTreeView; + +import com.intellij.icons.AllIcons; +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/8/12 + * Time: 12:23 PM + */ +public class FileGroupingProjectNode extends ProjectViewNodeWithChildrenList { + private VirtualFile myVirtualFile; + + public FileGroupingProjectNode(Project project, File file, ViewSettings viewSettings) { + super(project, file, viewSettings); + final LocalFileSystem lfs = LocalFileSystem.getInstance(); + myVirtualFile = lfs.findFileByIoFile(file); + if (myVirtualFile == null) { + myVirtualFile = lfs.refreshAndFindFileByIoFile(file); + } + } + + @Override + public boolean contains(@NotNull VirtualFile file) { + return file.equals(myVirtualFile); + } + + @Override + protected void update(PresentationData presentation) { + if (myVirtualFile != null && myVirtualFile.isDirectory()) { + presentation.setOpenIcon(AllIcons.Nodes.TreeOpen); + presentation.setClosedIcon(AllIcons.Nodes.TreeClosed); + } else if (myVirtualFile != null) { + presentation.setIcons(myVirtualFile.getFileType().getIcon()); + } else { + presentation.setIcons(AllIcons.FileTypes.Unknown); + } + presentation.setPresentableText(getValue().getName()); + } + + @Override + public VirtualFile getVirtualFile() { + return myVirtualFile; + } + + @Override + public void navigate(boolean requestFocus) { + if (myVirtualFile != null) { + new OpenFileDescriptor(myProject, myVirtualFile).navigate(requestFocus); + } + } + + // todo possibly we need file + @Override + public boolean canNavigate() { + return myVirtualFile != null && myVirtualFile.isValid(); + } + + @Override + public boolean canNavigateToSource() { + return myVirtualFile != null && myVirtualFile.isValid(); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FileSerializable.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FileSerializable.java new file mode 100644 index 000000000000..b409b84e3851 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FileSerializable.java @@ -0,0 +1,54 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.openapi.project.Project; + +import java.io.File; +import java.io.IOException; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/8/12 + * Time: 12:43 PM + */ +public class FileSerializable implements WorkingSetSerializable { + @Override + public String getId() { + return File.class.getName(); + } + + @Override + public int getVersion() { + return 0; + } + + @Override + public void serializeMe(File t, StringBuilder oos) throws IOException { + oos.append(t.getPath()); + } + + @Override + public File deserializeMe(Project project, String ois) throws IOException { + return new File(ois); + } + + @Override + public File deserializeMeInvalid(Project project, String ois) throws IOException { + return new File(ois); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/Flag.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/Flag.java new file mode 100644 index 000000000000..5d2a7805c69e --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/Flag.java @@ -0,0 +1,46 @@ +/* + * 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.favoritesTreeView; + +import java.awt.*; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/1/12 + * Time: 2:03 PM + */ +public enum Flag { + orange(new Color(255,128,0)), + blue(new Color(0,102,204)), + green(new Color(0, 130,130)), + red(new Color(255,45,45)), + brown(new Color(128,64,0)), + magenta(new Color(255,0,255)), + violet(new Color(128,0,255)), + yellow(new Color(255,255,0)), + grey(new Color(140,140,140)); + + private final Color myColor; + + private Flag(Color color) { + myColor = color; + } + + public Color getColor() { + return myColor; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/ImportUsagesAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/ImportUsagesAction.java new file mode 100644 index 000000000000..bd837f38862c --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/ImportUsagesAction.java @@ -0,0 +1,69 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.icons.AllIcons; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.project.Project; +import com.intellij.usages.Usage; +import com.intellij.usages.UsageView; + +import java.util.Collection; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/1/12 + * Time: 11:22 PM + */ +public class ImportUsagesAction extends AnAction { + public ImportUsagesAction() { + super("To Favorites", "To Favorites", AllIcons.Toolwindows.ToolWindowFavorites); + } + + @Override + public void update(AnActionEvent e) { + final DataContext dc = e.getDataContext(); + final boolean enabled = isEnabled(dc); + e.getPresentation().setEnabled(enabled); + } + + private boolean isEnabled(DataContext dc) { + final Project project = PlatformDataKeys.PROJECT.getData(dc); + final Usage[] usages = UsageView.USAGES_KEY.getData(dc); + return project != null && usages != null && usages.length > 0; + } + + @Override + public void actionPerformed(AnActionEvent e) { + final DataContext dc = e.getDataContext(); + final boolean enabled = isEnabled(dc); + if (! enabled) return; + + final Project project = PlatformDataKeys.PROJECT.getData(dc); + + final Collection nodes = new UsageFavoriteNodeProvider().getFavoriteNodes(dc, ViewSettings.DEFAULT); + final FavoritesManager favoritesManager = FavoritesManager.getInstance(project); + if (nodes != null && ! nodes.isEmpty()) { + favoritesManager.addRoots(TaskDefaultFavoriteListProvider.CURRENT_TASK, nodes); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/InvalidUsageNoteNode.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/InvalidUsageNoteNode.java new file mode 100644 index 000000000000..366eba3f1fec --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/InvalidUsageNoteNode.java @@ -0,0 +1,55 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.usages.TextChunk; + +import java.util.List; +import java.util.Set; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/7/12 + * Time: 1:26 PM + */ +public class InvalidUsageNoteNode { + private PercentDone myPercentDone = PercentDone._0; + private Set myFlags; + private Set myConcepts; + + final List myText; + + public InvalidUsageNoteNode(List text) { + myText = text; + } + + public PercentDone getPercentDone() { + return myPercentDone; + } + + public Set getFlags() { + return myFlags; + } + + public Set getConcepts() { + return myConcepts; + } + + public List getText() { + return myText; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/InvalidUsageNoteProjectNode.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/InvalidUsageNoteProjectNode.java new file mode 100644 index 000000000000..f1f4cd09e0c4 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/InvalidUsageNoteProjectNode.java @@ -0,0 +1,50 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.usages.TextChunk; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/7/12 + * Time: 1:28 PM + */ +public class InvalidUsageNoteProjectNode extends ProjectViewNodeWithChildrenList { + public InvalidUsageNoteProjectNode(Project project, InvalidUsageNoteNode node, ViewSettings viewSettings) { + super(project, node, viewSettings); + } + + @Override + public boolean contains(@NotNull VirtualFile file) { + return false; + } + + @Override + protected void update(PresentationData presentation) { + final List text = getValue().getText(); + if (! text.isEmpty()) { + UsageProjectTreeNode.updatePresentationWithTextChunks(presentation, text.toArray(new TextChunk[text.size()])); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/NoteNode.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/NoteNode.java new file mode 100644 index 000000000000..f99fd0ffa436 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/NoteNode.java @@ -0,0 +1,74 @@ +/* + * 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.favoritesTreeView; + +import java.util.Set; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 5/31/12 + * Time: 8:47 PM + */ +public class NoteNode { + private PercentDone myPercentDone = PercentDone._0; + private Set myFlags; + private Set myConcepts; + + private String myText; + private boolean myReadonly; + + public NoteNode(String text, boolean readonly) { + myText = text; + myReadonly = readonly; + } + + public PercentDone getPercentDone() { + return myPercentDone; + } + + public void setPercentDone(PercentDone percentDone) { + myPercentDone = percentDone; + } + + public Set getFlags() { + return myFlags; + } + + public void setFlags(Set flags) { + myFlags = flags; + } + + public Set getConcepts() { + return myConcepts; + } + + public void setConcepts(Set concepts) { + myConcepts = concepts; + } + + public String getText() { + return myText; + } + + public void setText(String text) { + myText = text; + } + + public boolean isReadonly() { + return myReadonly; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/NoteProjectNode.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/NoteProjectNode.java new file mode 100644 index 000000000000..1ea507dcfe46 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/NoteProjectNode.java @@ -0,0 +1,52 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/7/12 + * Time: 12:15 PM + */ +public class NoteProjectNode extends ProjectViewNodeWithChildrenList { + public NoteProjectNode(Project project, NoteNode node, ViewSettings viewSettings) { + super(project, node, viewSettings); + } + + @Override + public boolean contains(@NotNull VirtualFile file) { + return false; + } + + @Override + public String toString() { + return getValue().getText(); + } + + @Override + protected void update(PresentationData presentation) { + presentation.setPresentableText(getValue().getText()); + // todo define own color + presentation.setForcedTextForeground(FileStatus.COLOR_SWITCHED); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/NoteSerializable.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/NoteSerializable.java new file mode 100644 index 000000000000..86d8847fed49 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/NoteSerializable.java @@ -0,0 +1,63 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; + +import java.io.IOException; +import java.util.List; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/9/12 + * Time: 4:11 PM + */ +public class NoteSerializable implements WorkingSetSerializable { + + @Override + public String getId() { + return NoteNode.class.getName(); + } + + @Override + public int getVersion() { + return 0; + } + + @Override + public void serializeMe(NoteNode t, StringBuilder oos) throws IOException { + oos.append(StringUtil.escapeXml(t.getText())); + oos.append("<>"); + oos.append(String.valueOf(t.isReadonly())); + oos.append("<>"); + } + + @Override + public NoteNode deserializeMe(Project project, String ois) throws IOException { + final List strings = StringUtil.split(ois, "<>", true); + if (strings.size() == 2) { + return new NoteNode(StringUtil.unescapeXml(strings.get(0)), Boolean.parseBoolean(strings.get(1))); + } + return null; + } + + @Override + public NoteNode deserializeMeInvalid(Project project, String ois) throws IOException { + return null; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/PercentDone.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/PercentDone.java new file mode 100644 index 000000000000..0dfaa4115169 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/PercentDone.java @@ -0,0 +1,36 @@ +/* + * 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.favoritesTreeView; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/1/12 + * Time: 1:53 PM + */ +public enum PercentDone { + _0(0),_05(5),_20(20),_50(50),_70(70),_100(100); + + private final int myPercent; + + private PercentDone(int percent) { + myPercent = percent; + } + + public int getPercent() { + return myPercent; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/ProjectDefaultFavoriteListProvider.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/ProjectDefaultFavoriteListProvider.java new file mode 100644 index 000000000000..2b763a180133 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/ProjectDefaultFavoriteListProvider.java @@ -0,0 +1,69 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.openapi.project.Project; + +import javax.swing.tree.TreeCellRenderer; +import java.util.Comparator; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/7/12 + * Time: 4:30 PM + */ +public class ProjectDefaultFavoriteListProvider implements FavoritesListProvider { + @Override + public String getListName(Project project) { + return project.getName(); + } + + @Override + public boolean canBeRemoved() { + return false; + } + + @Override + public boolean isTreeLike() { + return false; + } + + @Override + public Comparator getNodeDescriptorComparator() { + return null; + } + + @Override + public Operation getCustomDeleteOperation() { + return null; + } + + @Override + public Operation getCustomAddOperation() { + return null; + } + + @Override + public Operation getCustomEditOperation() { + return null; + } + + @Override + public TreeCellRenderer getTreeCellRenderer() { + return null; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/ProjectViewNodeWithChildrenList.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/ProjectViewNodeWithChildrenList.java new file mode 100644 index 000000000000..08cee563a32d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/ProjectViewNodeWithChildrenList.java @@ -0,0 +1,69 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.ide.projectView.ProjectViewNode; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/7/12 + * Time: 12:41 PM + */ +public abstract class ProjectViewNodeWithChildrenList extends ProjectViewNode { + protected final List myChildren; + + protected ProjectViewNodeWithChildrenList(Project project, T t, ViewSettings viewSettings) { + super(project, t, viewSettings); + myChildren = new ArrayList(); + } + + @NotNull + @Override + public Collection getChildren() { + return myChildren; + } + + public void addChild(final AbstractTreeNode node) { + myChildren.add(node); + node.setParent(this); + } + + public void addChildBefore(final AbstractTreeNode newNode, final AbstractTreeNode existingNode) { + int idx = -1; + for (int i = 0; i < myChildren.size(); i++) { + AbstractTreeNode node = myChildren.get(i); + // exactly the same node! + if (node == existingNode) { + idx = i; + break; + } + } + if (idx == -1) { + addChild(newNode); + } else { + myChildren.add(idx, newNode); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/TaskDefaultFavoriteListProvider.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/TaskDefaultFavoriteListProvider.java new file mode 100644 index 000000000000..760c10b4168e --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/TaskDefaultFavoriteListProvider.java @@ -0,0 +1,283 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.ide.dnd.aware.DnDAwareTree; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonShortcuts; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.keymap.KeymapUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ex.MultiLineLabel; +import com.intellij.openapi.ui.popup.ComponentPopupBuilder; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.MultilineTreeCellRenderer; +import com.intellij.ui.components.JBScrollPane; +import com.intellij.util.Consumer; +import com.intellij.util.ui.UIUtil; + +import javax.swing.*; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/7/12 + * Time: 4:33 PM + */ +public class TaskDefaultFavoriteListProvider implements FavoritesListProvider { + public static final String CURRENT_TASK = "Current task"; + + @Override + public String getListName(Project project) { + return CURRENT_TASK; + } + + @Override + public boolean canBeRemoved() { + return false; + } + + @Override + public boolean isTreeLike() { + return false; + } + + @Override + public Comparator getNodeDescriptorComparator() { + return new Comparator() { + @Override + public int compare(FavoritesTreeNodeDescriptor o1, FavoritesTreeNodeDescriptor o2) { + return o1.getIndex() - o2.getIndex(); + } + }; + } + + @Override + public Operation getCustomDeleteOperation() { + return null; + } + + @Override + public Operation getCustomAddOperation() { + return new Operation() { + @Override + public boolean willHandle(DnDAwareTree tree) { + final int count = tree.getSelectionCount(); + if (count != 1) { + return false; + } + final TreePath path = tree.getSelectionPath(); + if (path.getPathCount() > 2) return true; + return false; + } + + @Override + public String getCustomName() { + return "New Note"; + } + + @Override + public void handle(final Project project, final DnDAwareTree tree) { + final Object component = tree.getSelectionPath().getLastPathComponent(); + if (component instanceof DefaultMutableTreeNode) { + final Object uo = ((DefaultMutableTreeNode)component).getUserObject(); + if (uo instanceof FavoritesTreeNodeDescriptor) { + final FavoritesManager favoritesManager = FavoritesManager.getInstance(project); + + final AbstractTreeNode treeNode = ((FavoritesTreeNodeDescriptor)uo).getElement(); + final NoteNode node = new NoteNode("Test text", false); + final NoteProjectNode noteNode = new NoteProjectNode(project, node, favoritesManager.getViewSettings()); + final Consumer after = new Consumer() { + @Override + public void consume(String text) { + node.setText(text); + // above it + final AbstractTreeNode parent = treeNode.getParent(); + noteNode.setParent(parent); + if (parent instanceof ProjectViewNodeWithChildrenList) { + // add through manager + //((ProjectViewNodeWithChildrenList)parent).addChildBefore(noteNode, treeNode); + final List pathToSelected = FavoritesTreeUtil.getLogicalPathToSelected(tree); + final List elements; + AbstractTreeNode sibling; + if (pathToSelected.isEmpty()) { + elements = pathToSelected; + sibling = null; + } + else { + elements = pathToSelected.subList(0, pathToSelected.size() - 1); + sibling = pathToSelected.get(pathToSelected.size() - 1); + } + favoritesManager.addRoot(CURRENT_TASK, elements, noteNode, sibling); + } else if (parent instanceof FavoritesListNode) { + favoritesManager.addRoot(CURRENT_TASK, Collections.emptyList(), noteNode, treeNode); + } + } + }; + showNotePopup(project, tree, after, ""); + } + } + } + }; + } + + private void showNotePopup(Project project, + final DnDAwareTree tree, + final Consumer after, final String initText) { + final JTextArea textArea = new JTextArea(3, 50); + textArea.setFont(UIUtil.getTreeFont()); + textArea.setText(initText); + final JBScrollPane pane = new JBScrollPane(textArea); + final ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(pane, textArea) + .setCancelOnClickOutside(true) + .setAdText(KeymapUtil.getShortcutsText(CommonShortcuts.CTRL_ENTER.getShortcuts()) + " to finish") + .setTitle("Comment") + .setMovable(true) + .setRequestFocus(true).setResizable(true).setMayBeParent(true); + final JBPopup popup = builder.createPopup(); + final JComponent content = popup.getContent(); + final AnAction action = new AnAction() { + @Override + public void actionPerformed(AnActionEvent e) { + popup.closeOk(e.getInputEvent()); + unregisterCustomShortcutSet(content); + after.consume(textArea.getText()); + } + }; + action.registerCustomShortcutSet(CommonShortcuts.CTRL_ENTER, content); + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + popup.showInCenterOf(tree); + } + }, ModalityState.NON_MODAL, project.getDisposed()); + } + + @Override + public Operation getCustomEditOperation() { + return new Operation() { + @Override + public boolean willHandle(DnDAwareTree tree) { + final int count = tree.getSelectionCount(); + if (count != 1) { + return false; + } + final TreePath path = tree.getSelectionPath(); + if (path.getPathCount() < 2) return false; + // todo temporarily + if (path.getLastPathComponent() instanceof DefaultMutableTreeNode) { + final Object uo = ((DefaultMutableTreeNode)path.getLastPathComponent()).getUserObject(); + if (uo instanceof FavoritesTreeNodeDescriptor) { + return ((FavoritesTreeNodeDescriptor)uo).getElement() instanceof NoteProjectNode; + } + } + return false; + } + + @Override + public String getCustomName() { + return null; + } + + @Override + public void handle(Project project, final DnDAwareTree tree) { + final Object component = tree.getSelectionPath().getLastPathComponent(); + if (component instanceof DefaultMutableTreeNode) { + final Object uo = ((DefaultMutableTreeNode)component).getUserObject(); + if (uo instanceof FavoritesTreeNodeDescriptor) { + final FavoritesManager favoritesManager = FavoritesManager.getInstance(project); + + final AbstractTreeNode treeNode = ((FavoritesTreeNodeDescriptor)uo).getElement(); + + if (treeNode instanceof NoteProjectNode) { + showNotePopup(project, tree, new Consumer() { + @Override + public void consume(String s) { + ((NoteProjectNode)treeNode).getValue().setText(s); + favoritesManager.editRoot(CURRENT_TASK, FavoritesTreeUtil.getLogicalIndexPathTo(tree.getSelectionPath()), treeNode); + favoritesManager.fireListeners(CURRENT_TASK); + } + }, ((NoteProjectNode)treeNode).getValue().getText()); + } + } + } + } + }; + } + + @Override + public TreeCellRenderer getTreeCellRenderer() { + return new MyRenderer(); + } + + private static class MyRenderer implements TreeCellRenderer { + private AbstractTreeNode myNode; + + private final MultilineTreeCellRenderer myMultilineTreeCellRenderer = new MultilineTreeCellRenderer() { + @Override + protected void initComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + if (myNode instanceof NoteProjectNode) { + setForeground(UIUtil.getListSelectionBackground()); + final NoteNode note = ((NoteProjectNode)myNode).getValue(); + final String[] lines = StringUtil.splitByLines(note.getText()); + setText(lines, null); + } + } + }; + + private final MultiLineLabel myLabel = new MultiLineLabel(); + + @Override + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + if (value instanceof DefaultMutableTreeNode) { + final DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; + //only favorites roots to explain + final Object userObject = node.getUserObject(); + if (userObject instanceof FavoritesTreeNodeDescriptor) { + final FavoritesTreeNodeDescriptor favoritesTreeNodeDescriptor = (FavoritesTreeNodeDescriptor)userObject; + AbstractTreeNode treeNode = favoritesTreeNodeDescriptor.getElement(); + if (treeNode instanceof NoteProjectNode) { + myNode = treeNode; + myLabel.setText(((NoteProjectNode)myNode).getValue().getText()); + //myLabel.setBackground(selected ? ); + myMultilineTreeCellRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); + return myMultilineTreeCellRenderer; + //return myLabel; + } + } + } + return null; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageFavoriteNodeProvider.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageFavoriteNodeProvider.java new file mode 100644 index 000000000000..ac9f38092b89 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageFavoriteNodeProvider.java @@ -0,0 +1,313 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.ide.util.treeView.AbstractTreeNode; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.usageView.UsageInfo; +import com.intellij.usages.Usage; +import com.intellij.usages.UsageInfo2UsageAdapter; +import com.intellij.usages.UsageView; +import com.intellij.usages.impl.NullUsage; +import com.intellij.usages.rules.UsageInFile; +import com.intellij.usages.rules.UsageInFiles; +import com.intellij.util.ProxyComparator; +import com.intellij.util.SmartList; +import com.intellij.util.containers.Convertor; +import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/6/12 + * Time: 6:51 PM + */ +public class UsageFavoriteNodeProvider extends FavoriteNodeProvider { + private final static Map> ourSerializables = new HashMap>(); + private final static Comparator VIRTUAL_FILE_COMPARATOR = + new ProxyComparator(new Convertor() { + @Override + public String convert(VirtualFile o) { + return o.getPath(); + } + }); + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.favoritesTreeView.UsageFavoriteNodeProvider"); + + static { + final TreeSet usageSet = createSet(); + final UsageSerializable serializable = new UsageSerializable(); + ourSerializables.put(serializable.getId(), usageSet); + usageSet.add(serializable); + + final TreeSet fileSet = createSet(); + final FileSerializable fileSerializable = new FileSerializable(); + ourSerializables.put(fileSerializable.getId(), fileSet); + fileSet.add(fileSerializable); + + final TreeSet noteSet = createSet(); + final NoteSerializable noteSerializable = new NoteSerializable(); + ourSerializables.put(noteSerializable.getId(), noteSet); + noteSet.add(noteSerializable); + } + + private static TreeSet createSet() { + return new TreeSet(new Comparator() { + @Override + public int compare(WorkingSetSerializable o1, WorkingSetSerializable o2) { + assert o1.getId().equals(o1.getId()); + return Comparing.compare(o1.getVersion(), o2.getVersion()); + } + }); + } + + @Override + public Collection getFavoriteNodes(DataContext context, ViewSettings viewSettings) { + final Project project = PlatformDataKeys.PROJECT.getData(context); + if (project == null) { + return null; + } + final Usage[] usages = UsageView.USAGES_KEY.getData(context); + if (usages != null) { + + final List result = new SmartList(); + final MultiMap map = new MultiMap(); + final List nonMapped = new ArrayList(); + for (Usage usage : usages) { + if (usage instanceof UsageInFile) { + map.putValue(((UsageInFile)usage).getFile(), usage); + } else if (usage instanceof UsageInFiles) { + final VirtualFile[] files = ((UsageInFiles)usage).getFiles(); + for (VirtualFile file : files) { + map.putValue(file, usage); + } + } else { + nonMapped.add(usage); + } + } + + final TreeSet keys = new TreeSet(VIRTUAL_FILE_COMPARATOR); + keys.addAll(map.keySet()); + for (VirtualFile key : keys) { + final FileGroupingProjectNode grouping = new FileGroupingProjectNode(project, new File(key.getPath()), viewSettings); + result.add(grouping); + final Collection subUsages = map.get(key); + for (Usage usage : subUsages) { + if (usage instanceof UsageInfo2UsageAdapter) { + final UsageProjectTreeNode node = + new UsageProjectTreeNode(project, ((UsageInfo2UsageAdapter)usage).getUsageInfo(), viewSettings); + grouping.addChild(node); + } else if (NullUsage.INSTANCE.equals(usage)) { + continue; + } else { + grouping.addChild(new NoteProjectNode(project, new NoteNode(usage.getPresentation().getPlainText(), true), viewSettings)); + } + } + } + for (Usage usage : nonMapped) { + if (usage instanceof UsageInfo2UsageAdapter) { + final UsageProjectTreeNode node = + new UsageProjectTreeNode(project, ((UsageInfo2UsageAdapter)usage).getUsageInfo(), viewSettings); + result.add(node); + } else if (NullUsage.INSTANCE.equals(usage)) { + continue; + } else { + result.add(new NoteProjectNode(project, new NoteNode(usage.getPresentation().getPlainText(), true), viewSettings)); + } + } + + return result; + } + return null; + } + + @Override + public AbstractTreeNode createNode(Project project, Object element, ViewSettings viewSettings) { + if (element instanceof UsageInfo) { + return new UsageProjectTreeNode(project, (UsageInfo)element, viewSettings); + } else if (element instanceof InvalidUsageNoteNode) { + return new InvalidUsageNoteProjectNode(project, (InvalidUsageNoteNode)element, viewSettings); + } else if (element instanceof NoteNode) { + return new NoteProjectNode(project, (NoteNode)element, viewSettings); + } else if (element instanceof File) { + return new FileGroupingProjectNode(project, (File)element, viewSettings); + } + return super.createNode(project, element, viewSettings); + } + + @Override + public PsiElement getPsiElement(Object element) { + if (element instanceof UsageInfo) { + return ((UsageInfo)element).getElement(); + } + return super.getPsiElement(element); + } + + @Override + public boolean elementContainsFile(Object element, VirtualFile vFile) { + return false; + } + + @Override + public int getElementWeight(Object element, boolean isSortByType) { + return 0; + } + + @Override + public String getElementLocation(Object element) { + if (element instanceof UsageInfo) { + final PsiElement psiElement = ((UsageInfo)element).getElement(); + final PsiFile file = psiElement.getContainingFile(); + /*if (parent != null) { + return ClassPresentationUtil.getNameForClass(parent, true); + }*/ + return file.getPresentation().getPresentableText();//+- // todo do smthg for invalid usage + } else if (element instanceof File) { + return ((File)element).getParent(); + } + return null; + } + + @Override + public boolean isInvalidElement(Object element) { + /*if (element instanceof UsageInfo) { + return ((UsageInfo)element).getElement().isValid(); + } else if (element instanceof InvalidUsageNoteNode) { + return true; + } */ + return false; + } + + @NotNull + @Override + public String getFavoriteTypeId() { + return "usage"; + } + + @Override + public String getElementUrl(Object element) { + //if (element instanceof UsageInfo) { + final TreeSet serializables = ourSerializables.get(element.getClass().getName()); + if (serializables != null && ! serializables.isEmpty()) { + final WorkingSetSerializable last = serializables.last(); + //final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + //final ObjectOutputStream os = new ObjectOutputStream(baos); + final StringBuilder sb = new StringBuilder(); + sb.append(last.getId()); + sb.append(' '); + sb.append("" + last.getVersion()); + sb.append(' '); + + //os.writeUTF(last.getId()); + //os.writeInt(last.getVersion()); + last.serializeMe(element, sb); + //os.close(); + //final byte[] bytes = baos.toByteArray(); + return sb.toString(); + //return new String(bytes, 4, bytes.length - 4); + } + catch (IOException e) { + LOG.info(e); + return null; + } + } + //} + return null; + } + + @Override + public String getElementModuleName(Object element) { + if (element instanceof UsageInfo) { + Module module = ModuleUtil.findModuleForPsiElement(((UsageInfo)element).getElement()); + return module != null ? module.getName() : null; + } + return null; + } + + @Override + public Object[] createPathFromUrl(Project project, String url, String moduleName) { + try { + //final byte[] bytes = url.getBytes(CharsetToolkit.UTF8_CHARSET); + /*final byte[] wrapped = new byte[bytes.length + 4]; + final ByteArrayOutputStream bas = new ByteArrayOutputStream(); + final ObjectOutputStream oos = new ObjectOutputStream(bas); + oos.close(); + final byte[] header = bas.toByteArray(); + System.arraycopy(header, 0, wrapped, 0, 4); + System.arraycopy(bytes, 0, wrapped, 0, bytes.length);*/ + + //ObjectInputStream is = new ObjectInputStream(new ByteArrayInputStream(bytes)); + final List parts = StringUtil.split(url, " ", true); + if (parts.size() < 3) return null; + + final String id = parts.get(0); + final TreeSet set = ourSerializables.get(id); + if (set != null && ! set.isEmpty()) { + final int version = Integer.parseInt(parts.get(1)); + final String cut = StringUtil.join(parts.subList(2, parts.size()), " "); + for (java.util.Iterator iterator = set.descendingIterator(); iterator.hasNext(); ) { + WorkingSetSerializable serializable = iterator.next(); + if (serializable.getVersion() == version) { + return readWithSerializable(project, url, cut, serializable); + } + } + readWithSerializable(project, url, cut, set.last()); + } + } + catch (IOException e) { + LOG.info(e); + } + return null; + } + + private Object[] readWithSerializable(Project project, String url, String is, WorkingSetSerializable serializable) + throws IOException { + Object obj = serializable.deserializeMe(project, is); + if (obj == null) { + obj = serializable.deserializeMeInvalid(project, is); + } + return obj == null ? null : new Object[] {obj}; + /*Object obj = serializable.deserializeMe(project, is); + if (obj == null) { + is.close(); + is = new ObjectInputStream(new ByteArrayInputStream(url.getBytes(CharsetToolkit.UTF8_CHARSET))); + is.readUTF(); + is.readInt(); + obj = serializable.deserializeMeInvalid(project, is); + } + if (obj != null) { + return new Object[]{obj}; + } else { + return null; + }*/ + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageNode.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageNode.java new file mode 100644 index 000000000000..e9be02390e3d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageNode.java @@ -0,0 +1,61 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.pom.Navigatable; +import com.intellij.usages.Usage; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/1/12 + * Time: 1:51 PM + */ +public class UsageNode implements Navigatable { + private Usage myUsage; + private NoteNode myComment; + + public Usage getUsage() { + return myUsage; + } + + public void setUsage(Usage usage) { + myUsage = usage; + } + + public NoteNode getComment() { + return myComment; + } + + public void setComment(NoteNode comment) { + myComment = comment; + } + + @Override + public void navigate(boolean requestFocus) { + myUsage.navigate(requestFocus); + } + + @Override + public boolean canNavigate() { + return myUsage.isValid() && myUsage.canNavigate(); + } + + @Override + public boolean canNavigateToSource() { + return myUsage.isValid() && myUsage.canNavigate(); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageProjectTreeNode.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageProjectTreeNode.java new file mode 100644 index 000000000000..1e1268bf9fab --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageProjectTreeNode.java @@ -0,0 +1,99 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.projectView.ViewSettings; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.usageView.UsageInfo; +import com.intellij.usages.TextChunk; +import com.intellij.usages.UsageInfo2UsageAdapter; +import com.intellij.usages.UsagePresentation; +import com.intellij.util.Function; +import org.jetbrains.annotations.NotNull; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/6/12 + * Time: 7:24 PM + * + */ +public class UsageProjectTreeNode extends ProjectViewNodeWithChildrenList { + private final UsagePresentation myUsagePresentation; + + public UsageProjectTreeNode(Project project, UsageInfo usage, ViewSettings viewSettings) { + super(project, usage, viewSettings); + final UsageInfo2UsageAdapter adapter = new UsageInfo2UsageAdapter(usage); + myUsagePresentation = adapter.getPresentation(); + } + + @Override + public boolean contains(@NotNull VirtualFile file) { + final UsageInfo info = getValue(); + if (info == null) return false; + final PsiElement element = info.getElement(); + return element != null && file.equals(element.getContainingFile().getVirtualFile()); + } + + @Override + public String toString() { + return myUsagePresentation.getPlainText(); + } + + @Override + protected void update(PresentationData presentation) { + presentation.setOpenIcon(myUsagePresentation.getIcon()); + presentation.setClosedIcon(myUsagePresentation.getIcon()); + presentation.setTooltip(myUsagePresentation.getTooltipText()); + final TextChunk[] text = myUsagePresentation.getText(); + updatePresentationWithTextChunks(presentation, text); + presentation.setPresentableText(StringUtil.join(text, new Function() { + @Override + public String fun(TextChunk chunk) { + return chunk.getText(); + } + }, "")); + } + + public static void updatePresentationWithTextChunks(PresentationData presentation, TextChunk[] text) { + for (TextChunk chunk : text) { + final TextAttributes attributes = chunk.getAttributes(); + presentation.addText(chunk.getText(), new SimpleTextAttributes(attributes.getBackgroundColor(), attributes.getForegroundColor(), + attributes.getEffectColor(), attributes.getFontType())); + } + } + + @Override + public void navigate(boolean requestFocus) { + getValue().navigateTo(requestFocus); + } + + @Override + public boolean canNavigate() { + return getValue().getElement().isValid(); + } + + @Override + public boolean canNavigateToSource() { + return getValue().getElement().isValid(); + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageSerializable.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageSerializable.java new file mode 100644 index 000000000000..0e8edac12fed --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/UsageSerializable.java @@ -0,0 +1,165 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.codeInsight.folding.impl.GenericElementSignatureProvider; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.ProperTextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.usageView.UsageInfo; +import com.intellij.usages.UsageInfo2UsageAdapter; + +import java.io.File; +import java.io.IOException; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/7/12 + * Time: 1:58 PM + */ +public class UsageSerializable implements WorkingSetSerializable { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.favoritesTreeView.UsageSerializable"); + private final static String separator = "<>"; + + @Override + public String getId() { + return UsageInfo.class.getName(); + } + + @Override + public int getVersion() { + return 0; + } + + @Override + public void serializeMe(UsageInfo info, StringBuilder os) throws IOException { + //final SmartPsiElementPointer pointer = info.getSmartPointer(); + final GenericElementSignatureProvider provider = new GenericElementSignatureProvider(); + final String signature = provider.getSignature(info.getElement()); + append(os, info.getElement().getContainingFile().getVirtualFile().getPath()); + os.append(separator); + append(os, signature); + os.append(separator); + final ProperTextRange rangeInElement = info.getRangeInElement(); + if (rangeInElement == null) { + append(os, "-1"); + os.append(separator); + append(os, "-1"); + os.append(separator); + } else { + append(os, String.valueOf(rangeInElement.getStartOffset())); + os.append(separator); + append(os, String.valueOf(rangeInElement.getEndOffset())); + os.append(separator); + } + append(os, String.valueOf(info.isNonCodeUsage())); + os.append(separator); + append(os, String.valueOf(info.isDynamicUsage())); + os.append(separator); + final String text = new UsageInfo2UsageAdapter(info).getPlainText(); + append(os, text); + os.append(separator); + } + + private void append(final StringBuilder sb, final String s) { + sb.append(StringUtil.escapeXml(s)); + } + + @Override + public UsageInfo deserializeMe(Project project, String is) throws IOException { + return new Reader(is).execute(project); + } + + private static class Reader { + private int idx; + private String is; + + private Reader(String is) { + this.idx = 0; + this.is = is; + } + + private String readNext(final boolean allowEnd) { + int idxNext = is.indexOf(separator, idx); + if (idxNext == -1) { + if (allowEnd) { + return StringUtil.unescapeXml(new String(is.substring(idx))); + } + } + final String s = new String(is.substring(idx, idxNext)); + idx = idxNext + separator.length(); + return s; + } + + public UsageInfo execute(final Project project) { + final GenericElementSignatureProvider provider = new GenericElementSignatureProvider(); + + final String path = readNext(false); + if (path == null) return null; + final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(path)); + if (file == null) return null; + PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + if (psiFile == null) return null; + final String signature = readNext(false); + final PsiElement element = provider.restoreBySignature(psiFile, signature, new StringBuilder()); + if (element == null) return null; + final String startStr = readNext(false); + if (startStr == null) return null; + final int start = Integer.parseInt(startStr); + final String endStr = readNext(false); + if (endStr == null) return null; + final int end = Integer.parseInt(endStr); + final String nonCodeUsageStr = readNext(false); + if (nonCodeUsageStr == null) return null; + final boolean nonCodeUsage = Boolean.parseBoolean(nonCodeUsageStr); + final String dynamicUsageStr = readNext(false); + if (dynamicUsageStr == null) return null; + final boolean dynamicUsage = Boolean.parseBoolean(dynamicUsageStr); + + final String text = readNext(true); + if (text == null) return null; + + final UsageInfo info = new UsageInfo(element, start, end, nonCodeUsage); + info.setDynamicUsage(dynamicUsage); + + return info; + /*final String newText = new UsageInfo2UsageAdapter(info).getPlainText(); + if (! Comparing.equal(newText, text)) { + LOG.info("Usage not restored, oldText:\n'" + text + "'\nnew text: '\n" + newText + "'"); + return null; + }*/ + } + } + + @Override + public InvalidUsageNoteNode deserializeMeInvalid(Project project, String is) throws IOException { + /*is.readUTF(); //file + is.readUTF(); + is.readInt(); + is.readInt(); + is.readBoolean(); + is.readBoolean(); + return new InvalidUsageNoteNode(Collections.singletonList(new TextChunk(new TextAttributes(), is.readUTF())));*/ + return null; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/WorkingSetSerializable.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/WorkingSetSerializable.java new file mode 100644 index 000000000000..c8eae474e69d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/WorkingSetSerializable.java @@ -0,0 +1,34 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.openapi.project.Project; + +import java.io.IOException; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/7/12 + * Time: 1:55 PM + */ +public interface WorkingSetSerializable { + String getId(); + int getVersion(); + void serializeMe(final Valid t, final StringBuilder oos) throws IOException; + Valid deserializeMe(Project project, final String ois) throws IOException; + Invalid deserializeMeInvalid(Project project, final String ois) throws IOException; +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/WorkingSetUsageActionProvider.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/WorkingSetUsageActionProvider.java new file mode 100644 index 000000000000..5b2f82393e46 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/WorkingSetUsageActionProvider.java @@ -0,0 +1,45 @@ +/* + * 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.favoritesTreeView; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.project.Project; +import com.intellij.usages.UsageView; +import com.intellij.usages.rules.UsageGroupingRule; +import com.intellij.usages.rules.UsageGroupingRuleProvider; +import org.jetbrains.annotations.NotNull; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/2/12 + * Time: 5:01 PM + */ +public class WorkingSetUsageActionProvider implements UsageGroupingRuleProvider { + private UsageGroupingRule[] myRules = new UsageGroupingRule[0]; + + @NotNull + @Override + public UsageGroupingRule[] getActiveRules(Project project) { + return myRules; + } + + @NotNull + @Override + public AnAction[] createGroupingActions(UsageView view) { + return new AnAction[]{new ImportUsagesAction()}; + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddAllToFavoritesActionGroup.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddAllToFavoritesActionGroup.java index e733b277bdfd..ef95d71717e3 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddAllToFavoritesActionGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddAllToFavoritesActionGroup.java @@ -32,7 +32,7 @@ public class AddAllToFavoritesActionGroup extends ActionGroup { if (project == null){ return AnAction.EMPTY_ARRAY; } - final String[] availableFavoritesLists = FavoritesManager.getInstance(project).getAvailableFavoritesLists(); + final String[] availableFavoritesLists = FavoritesManager.getInstance(project).getAvailableFavoritesListNames(); if (availableFavoritesLists == null) return AnAction.EMPTY_ARRAY; AnAction[] actions = new AnAction[availableFavoritesLists.length + 2]; int idx = 0; diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddNewFavoritesListAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddNewFavoritesListAction.java index 3ddd4a917a01..a3b6d2f988ab 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddNewFavoritesListAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddNewFavoritesListAction.java @@ -50,7 +50,7 @@ public class AddNewFavoritesListAction extends AnAction { } public boolean canClose(String inputString) { - final boolean isNew = ArrayUtil.find(favoritesManager.getAvailableFavoritesLists(), inputString.trim()) == -1; + final boolean isNew = ArrayUtil.find(favoritesManager.getAvailableFavoritesListNames(), inputString.trim()) == -1; if (!isNew) { Messages.showErrorDialog(project, IdeBundle.message("error.favorites.list.already.exists", inputString.trim()), @@ -61,12 +61,12 @@ public class AddNewFavoritesListAction extends AnAction { } }); if (name == null || name.length() == 0) return null; - favoritesManager.createNewList(name); + favoritesManager.createNewList(name, false, false); return name; } private static String getUniqueName(Project project) { - String[] names = FavoritesManager.getInstance(project).getAvailableFavoritesLists(); + String[] names = FavoritesManager.getInstance(project).getAvailableFavoritesListNames(); for (int i = 0; ; i++) { String newName = IdeBundle.message("favorites.list.unnamed", i > 0 ? i : ""); if (ArrayUtil.find(names, newName) > -1) continue; diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesAction.java index bc0a655b3a75..994b10f06c9d 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesAction.java @@ -106,6 +106,7 @@ public class AddToFavoritesAction extends AnAction { final boolean inProjectView = e.getPlace().equals(ActionPlaces.J2EE_VIEW_POPUP) || e.getPlace().equals(ActionPlaces.STRUCTURE_VIEW_POPUP) || e.getPlace().equals(ActionPlaces.PROJECT_VIEW_POPUP); + //com.intellij.openapi.actionSystem.ActionPlaces.USAGE_VIEW_TOOLBAR return getNodesToAdd(dataContext, inProjectView) != null; } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesActionGroup.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesActionGroup.java index c10a4d5ec25e..49f0b8ed7d1c 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesActionGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesActionGroup.java @@ -35,7 +35,7 @@ public class AddToFavoritesActionGroup extends ActionGroup { if (project == null){ return AnAction.EMPTY_ARRAY; } - final String[] availableFavoritesLists = FavoritesManager.getInstance(project).getAvailableFavoritesLists(); + final String[] availableFavoritesLists = FavoritesManager.getInstance(project).getAvailableFavoritesListNames(); AnAction[] actions = new AnAction[availableFavoritesLists.length + 2]; int idx = 0; for (String favoritesList : availableFavoritesLists) { diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesPopupAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesPopupAction.java index 76339f366b7c..385ea6e1fc55 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesPopupAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/AddToFavoritesPopupAction.java @@ -29,7 +29,7 @@ import com.intellij.openapi.project.Project; public class AddToFavoritesPopupAction extends QuickSwitchSchemeAction { protected void fillActions(Project project, DefaultActionGroup group, DataContext dataContext) { group.removeAll(); - final String[] availableFavoritesLists = FavoritesManager.getInstance(project).getAvailableFavoritesLists(); + final String[] availableFavoritesLists = FavoritesManager.getInstance(project).getAvailableFavoritesListNames(); for (String favoritesList : availableFavoritesLists) { group.add(new AddToFavoritesAction(favoritesList)); } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteAllFavoritesListsButThisAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteAllFavoritesListsButThisAction.java index bbcd092946ff..e18682915c65 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteAllFavoritesListsButThisAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteAllFavoritesListsButThisAction.java @@ -40,7 +40,7 @@ public class DeleteAllFavoritesListsButThisAction extends AnAction implements Du } FavoritesManager favoritesManager = FavoritesManager.getInstance(project); String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); - String[] lists = favoritesManager.getAvailableFavoritesLists(); + String[] lists = favoritesManager.getAvailableFavoritesListNames(); for (String list : lists) { if (!list.equals(listName)) { favoritesManager.removeFavoritesList(list); @@ -59,7 +59,7 @@ public class DeleteAllFavoritesListsButThisAction extends AnAction implements Du final String listName = FavoritesTreeViewPanel.FAVORITES_LIST_NAME_DATA_KEY.getData(dataContext); presentation.setEnabled(false); if (listName != null) { - final String[] favoritesLists = FavoritesManager.getInstance(project).getAvailableFavoritesLists(); + final String[] favoritesLists = FavoritesManager.getInstance(project).getAvailableFavoritesListNames(); if (listName.equals(project.getName())) { presentation.setEnabled(favoritesLists.length > 1); } else { diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFromFavoritesAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFromFavoritesAction.java index c16ba8013970..e3ee3763db5a 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFromFavoritesAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/DeleteFromFavoritesAction.java @@ -17,12 +17,9 @@ package com.intellij.ide.favoritesTreeView.actions; import com.intellij.ide.IdeBundle; -import com.intellij.ide.favoritesTreeView.FavoritesListNode; -import com.intellij.ide.favoritesTreeView.FavoritesManager; -import com.intellij.ide.favoritesTreeView.FavoritesTreeNodeDescriptor; -import com.intellij.ide.favoritesTreeView.FavoritesTreeViewPanel; +import com.intellij.ide.dnd.aware.DnDAwareTree; +import com.intellij.ide.favoritesTreeView.*; import com.intellij.ide.util.treeView.AbstractTreeNode; -import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; @@ -31,6 +28,8 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.ui.AnActionButton; +import java.util.List; + /** * @author anna * @author Konstantin Bulenkov @@ -50,6 +49,8 @@ public class DeleteFromFavoritesAction extends AnActionButton implements DumbAwa } FavoritesManager favoritesManager = FavoritesManager.getInstance(project); FavoritesTreeNodeDescriptor[] roots = FavoritesTreeViewPanel.CONTEXT_FAVORITES_ROOTS_DATA_KEY.getData(dataContext); + final DnDAwareTree tree = FavoritesTreeViewPanel.FAVORITES_TREE_KEY.getData(dataContext); + assert roots != null; for (FavoritesTreeNodeDescriptor root : roots) { final AbstractTreeNode node = root.getElement(); @@ -59,10 +60,14 @@ public class DeleteFromFavoritesAction extends AnActionButton implements DumbAwa else { final Object value = node.getValue(); LOG.assertTrue(value != null, node); - final NodeDescriptor parent = root.getParentDescriptor(); - if (parent instanceof FavoritesTreeNodeDescriptor) { - final String name = ((FavoritesTreeNodeDescriptor)parent).getName(); - favoritesManager.removeRoot(name, value); + final FavoritesListNode listNode = FavoritesTreeUtil.extractParentList(root); + LOG.assertTrue(listNode != null); + + //final List pathToSelected = FavoritesTreeUtil.getLogicalPathToSelected(tree); + //favoritesManager.removeRoot(listNode.getName(), pathToSelected); + final List pathTo = FavoritesTreeUtil.getLogicalIndexPathTo(tree.getSelectionPath()); + if (pathTo != null) { + favoritesManager.removeRootByIndexes(listNode.getName(), pathTo); } } } @@ -81,9 +86,10 @@ public class DeleteFromFavoritesAction extends AnActionButton implements DumbAwa return; } + final FavoritesManager fm = FavoritesManager.getInstance(project); if (roots.length == 1 && roots[0].getElement() instanceof FavoritesListNode - && project.getName().equals(roots[0].getElement().getValue())) { + && fm.isReadOnly(((FavoritesListNode) roots[0].getElement()).getName())) { e.getPresentation().setEnabled(false); return; } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/RenameFavoritesListAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/RenameFavoritesListAction.java index 6fdf7b9c400f..00a60a0ea410 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/RenameFavoritesListAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/RenameFavoritesListAction.java @@ -56,7 +56,7 @@ public class RenameFavoritesListAction extends AnAction implements DumbAware { } public boolean canClose(String inputString) { - String[] lists = favoritesManager.getAvailableFavoritesLists(); + String[] lists = favoritesManager.getAvailableFavoritesListNames(); final boolean isNew = ArrayUtil.find(lists, inputString.trim()) == -1; if (!isNew) { Messages.showErrorDialog(project, IdeBundle.message("error.favorites.list.already.exists", inputString.trim()), diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesAction.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesAction.java index 5f9c1834e59a..55fd06221e70 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesAction.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesAction.java @@ -79,7 +79,7 @@ public class SendToFavoritesAction extends AnAction{ if (name == null) { name = root.getFavoritesRoot().getName(); } - favoritesManager.removeRoot(name, rootElement.getValue()); + favoritesManager.removeRoot(name, Collections.singletonList(rootElement)); favoritesManager.addRoots(toName, Collections.singletonList(rootElement)); } } diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesGroup.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesGroup.java index 61c0f90d2c85..d06afdbb4e49 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/actions/SendToFavoritesGroup.java @@ -76,7 +76,7 @@ public class SendToFavoritesGroup extends ActionGroup{ } - final String[] allLists = favoritesManager.getAvailableFavoritesLists(); + final String[] allLists = favoritesManager.getAvailableFavoritesListNames(); List actions = new ArrayList(); for (String list : allLists) { diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java index b6e24d3aa25b..f690b338d76b 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserManager.java @@ -49,7 +49,7 @@ public final class HierarchyBrowserManager implements PersistentStateComponent implements NavigatableWith public void navigate(boolean requestFocus) { VirtualFile jarRoot = getJarRoot(); final Project project = getProject(); - if (jarRoot != null && ProjectRootsUtil.isLibraryRoot(jarRoot, project)) { + if (requestFocus && jarRoot != null && ProjectRootsUtil.isLibraryRoot(jarRoot, project)) { final OrderEntry orderEntry = LibraryUtil.findLibraryEntry(jarRoot, project); if (orderEntry != null) { ProjectSettingsService.getInstance(project).openLibraryOrSdkSettings(orderEntry); diff --git a/platform/lang-impl/src/com/intellij/ide/todo/configurable/TodoConfigurable.java b/platform/lang-impl/src/com/intellij/ide/todo/configurable/TodoConfigurable.java index eb5d453c5e68..5c3582130f63 100644 --- a/platform/lang-impl/src/com/intellij/ide/todo/configurable/TodoConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/todo/configurable/TodoConfigurable.java @@ -38,7 +38,6 @@ import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellEditor; import javax.swing.table.TableColumn; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; @@ -221,14 +220,15 @@ public class TodoConfigurable extends BaseConfigurable implements SearchableConf return new JButton[]{}; } }; + // double click in "Patterns" table should also start editing of selected pattern - myPatternsTable.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - editSelectedPattern(); - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + editSelectedPattern(); + return true; } - }); + }.installOn(myPatternsTable); // Panel with filters PanelWithButtons filtersPanel = new PanelWithButtons() { @@ -294,15 +294,13 @@ public class TodoConfigurable extends BaseConfigurable implements SearchableConf } }; // double click in "Filters" table should also start editing of selected filter - myFiltersTable.addMouseListener( - new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - editSelectedFilter(); - } - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + editSelectedFilter(); + return true; } - ); + }.installOn(myFiltersTable); myPanel = new JPanel(new GridBagLayout()); myPanel.add(patternsPanel, new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTH, GridBagConstraints.BOTH, diff --git a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java index 04dde9854cda..05dd4c188f5b 100644 --- a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java +++ b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java @@ -17,8 +17,12 @@ package com.intellij.ide.ui.search; import com.intellij.application.options.OptionsContainingConfigurable; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable; import com.intellij.ide.plugins.AvailablePluginsManagerMain; import com.intellij.ide.plugins.PluginManagerConfigurable; +import com.intellij.internal.ImageDuplicateResultsDialog; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.impl.ActionManagerImpl; @@ -90,9 +94,7 @@ public class TraverseUIStarter implements ApplicationStarter { configurableElement.setAttribute(ID, id); configurableElement.setAttribute(CONFIGURABLE_NAME, configurable.getDisplayName()); final TreeSet sortedOptions = options.get(configurable); - for (OptionDescription option : sortedOptions) { - append(option.getPath(), option.getHit(), option.getOption(), configurableElement); - } + writeOptions(configurableElement, sortedOptions); if (configurable instanceof KeymapPanel){ processKeymap(configurableElement); } else if (configurable instanceof OptionsContainingConfigurable){ @@ -102,6 +104,8 @@ public class TraverseUIStarter implements ApplicationStarter { for (OptionDescription description : descriptions) { append(null, AvailablePluginsManagerMain.MANAGE_REPOSITORIES, description.getOption(), configurableElement); } + } else if (configurable instanceof AllFileTemplatesConfigurable) { + processFileTemplates(configurableElement); } root.addContent(configurableElement); configurable.disposeUIResources(); @@ -118,13 +122,39 @@ public class TraverseUIStarter implements ApplicationStarter { ((ApplicationEx)ApplicationManager.getApplication()).exit(true); } + private static void processFileTemplates(Element configurableElement) { + final SearchableOptionsRegistrar optionsRegistrar = SearchableOptionsRegistrar.getInstance(); + TreeSet options = new TreeSet(); + + processTemplates(optionsRegistrar, options, FileTemplateManager.getInstance().getAllTemplates()); + processTemplates(optionsRegistrar, options, FileTemplateManager.getInstance().getAllPatterns()); + processTemplates(optionsRegistrar, options, FileTemplateManager.getInstance().getAllCodeTemplates()); + processTemplates(optionsRegistrar, options, FileTemplateManager.getInstance().getAllJ2eeTemplates()); + + writeOptions(configurableElement, options); + } + + private static void processTemplates(SearchableOptionsRegistrar optionsRegistrar, + TreeSet options, + FileTemplate[] templates) { + for (FileTemplate template : templates) { + collectOptions(optionsRegistrar, options, template.getName()); + //collectOptions(optionsRegistrar, options, template.getDescription()); + } + } + + private static void collectOptions(SearchableOptionsRegistrar optionsRegistrar, TreeSet options, String text) { + final Set strings = optionsRegistrar.getProcessedWordsWithoutStemming(text); + for (String word : strings) { + options.add(new OptionDescription(word, text, null)); + } + } + private static void processOptionsContainingConfigurable(final OptionsContainingConfigurable configurable, final Element configurableElement) { final Set optionsPath = configurable.processListOptions(); final TreeSet result = wordsToOptionDescriptors(optionsPath); - for (OptionDescription option : result) { - append(option.getPath(), option.getHit(), option.getOption(), configurableElement); - } + writeOptions(configurableElement, result); } private static TreeSet wordsToOptionDescriptors(Set optionsPath) { @@ -150,24 +180,22 @@ public class TraverseUIStarter implements ApplicationStarter { final AnAction anAction = actionManager.getAction(id); final String text = anAction.getTemplatePresentation().getText(); if (text != null) { - final Set strings = searchableOptionsRegistrar.getProcessedWordsWithoutStemming(text); - for (String word : strings) { - options.add(new OptionDescription(word, text, null)); - } + collectOptions(searchableOptionsRegistrar, options, text); } final String description = anAction.getTemplatePresentation().getDescription(); if (description != null) { - final Set strings = searchableOptionsRegistrar.getProcessedWordsWithoutStemming(description); - for (String word : strings) { - options.add(new OptionDescription(word, description, null)); - } + collectOptions(searchableOptionsRegistrar, options, description); } } + writeOptions(configurableElement, options); + } + + private static void writeOptions(Element configurableElement, TreeSet options) { for (OptionDescription opt : options) { append(opt.getPath(), opt.getHit(), opt.getOption(), configurableElement); } } - + private static void append(String path, String hit, final String word, final Element configurableElement) { Element optionElement = new Element(OPTION); optionElement.setAttribute(NAME, word); diff --git a/platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java b/platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java index 756fdfdf9d9c..3cdcc9d1e05d 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/util/AbstractTreeClassChooserDialog.java @@ -38,6 +38,7 @@ import com.intellij.psi.PsiNamedElement; import com.intellij.psi.presentation.java.SymbolPresentationUtil; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiUtilBase; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.TabbedPaneWrapper; import com.intellij.ui.TreeSpeedSearch; @@ -61,7 +62,6 @@ import javax.swing.tree.TreeSelectionModel; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; @@ -175,16 +175,17 @@ abstract public class AbstractTreeClassChooserDialog } }); - myTree.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - TreePath path = myTree.getPathForLocation(e.getX(), e.getY()); - if (path != null && myTree.isPathSelected(path)) { - doOKAction(); - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent event) { + TreePath path = myTree.getPathForLocation(event.getX(), event.getY()); + if (path != null && myTree.isPathSelected(path)) { + doOKAction(); + return true; } + return false; } - }); + }.installOn(myTree); myTree.addTreeSelectionListener( new TreeSelectionListener() { diff --git a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java index 270c94735c07..162f52d21834 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java @@ -75,7 +75,6 @@ import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.lang.reflect.Field; import java.util.*; @@ -462,14 +461,13 @@ public class FileStructurePopup implements Disposable { } }.registerCustomShortcutSet(CustomShortcutSet.fromString("ESCAPE"), myTree); - myTree.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() > 1) { - navigateSelectedElement(); - } + public boolean onClick(MouseEvent e, int clickCount) { + navigateSelectedElement(); + return true; } - }); + }.installOn(myTree); for(FileStructureFilter filter: fileStructureFilters) { addCheckbox(comboPanel, filter); diff --git a/platform/lang-impl/src/com/intellij/ide/util/MemberChooser.java b/platform/lang-impl/src/com/intellij/ide/util/MemberChooser.java index 8e87db8885be..492ae956e701 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/MemberChooser.java +++ b/platform/lang-impl/src/com/intellij/ide/util/MemberChooser.java @@ -337,17 +337,17 @@ public class MemberChooser extends DialogWrapper implemen } }); - myTree.addMouseListener( - new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - if (myTree.getPathForLocation(e.getX(), e.getY()) != null) { - doOKAction(); - } - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + if (myTree.getPathForLocation(e.getX(), e.getY()) != null) { + doOKAction(); + return true; } + return false; } - ); + }.installOn(myTree); + TreeUtil.installActions(myTree); JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTree); scrollPane.setPreferredSize(new Dimension(350, 450)); diff --git a/platform/lang-impl/src/com/intellij/ide/util/TreeFileChooserDialog.java b/platform/lang-impl/src/com/intellij/ide/util/TreeFileChooserDialog.java index c179d7d48648..478f76a4332e 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/TreeFileChooserDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/util/TreeFileChooserDialog.java @@ -45,6 +45,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.TabbedPaneWrapper; import com.intellij.ui.TreeSpeedSearch; @@ -67,7 +68,6 @@ import javax.swing.tree.TreeSelectionModel; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Arrays; @@ -180,16 +180,17 @@ public final class TreeFileChooserDialog extends DialogWrapper implements TreeFi } }); - myTree.addMouseListener(new MouseAdapter() { - public void mouseClicked(final MouseEvent e) { - if (e.getClickCount() == 2) { - final TreePath path = myTree.getPathForLocation(e.getX(), e.getY()); - if (path != null && myTree.isPathSelected(path)) { - doOKAction(); - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + final TreePath path = myTree.getPathForLocation(e.getX(), e.getY()); + if (path != null && myTree.isPathSelected(path)) { + doOKAction(); + return true; } + return false; } - }); + }.installOn(myTree); myTree.addTreeSelectionListener( new TreeSelectionListener() { diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 680db9fdb11f..b7eccea397bc 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -52,6 +52,7 @@ import com.intellij.psi.codeStyle.NameUtil; import com.intellij.psi.statistics.StatisticsInfo; import com.intellij.psi.statistics.StatisticsManager; import com.intellij.psi.util.PsiUtilCore; +import com.intellij.ui.ClickListener; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.ListScrollingUtil; import com.intellij.ui.ScrollPaneFactory; @@ -609,14 +610,14 @@ public abstract class ChooseByNameBase { myList.setFocusable(false); myList.setSelectionMode(allowMultipleSelection ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : ListSelectionModel.SINGLE_SELECTION); - myList.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(@NotNull MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { if (!myTextField.hasFocus()) { myTextField.requestFocus(); } - if (e.getClickCount() == 2) { + if (clickCount == 2) { int selectedIndex = myList.getSelectedIndex(); Rectangle selectedCellBounds = myList.getCellBounds(selectedIndex, selectedIndex); @@ -624,15 +625,19 @@ public abstract class ChooseByNameBase { if (myList.getSelectedValue() == EXTRA_ELEM) { myMaximumListSizeLimit += MAXIMUM_LIST_SIZE_LIMIT; rebuildList(selectedIndex, REBUILD_DELAY, null, ModalityState.current(), e); - e.consume(); } else { doClose(true); + } } + return true; } + + return false; } - }); + }.installOn(myList); + myList.setCellRenderer(myModel.getListCellRenderer()); myList.setFont(editorFont); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java index e938b1786640..bce981756da1 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -343,7 +343,7 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP String path = matcher.group(2); if (path != null) { path = path.trim(); - if (path.endsWith("$")) { + if (path.endsWith("$") && path.length() >= 2) { path = path.substring(0, path.length() - 2); } if (!path.isEmpty()) return path; diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java index dea601d8705f..78dc71be077a 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java +++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java @@ -50,6 +50,7 @@ import com.intellij.usages.UsageView; import com.intellij.usages.UsageViewManager; import com.intellij.usages.rules.PsiElementUsage; import com.intellij.util.PlatformUtils; +import com.intellij.util.TreeItem; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -353,8 +354,8 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo final FavoritesManager favoritesManager = FavoritesManager.getInstance(project); if (favoritesManager != null) { - for (final String favorite : favoritesManager.getAvailableFavoritesLists()) { - final Collection> rootUrls = favoritesManager.getFavoritesListRootUrls(favorite); + for (final String favorite : favoritesManager.getAvailableFavoritesListNames()) { + final Collection>> rootUrls = favoritesManager.getFavoritesListRootUrls(favorite); if (rootUrls.isEmpty()) continue; // ignore unused root result.add(new GlobalSearchScope(project) { @Override diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorForm.form b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorForm.form index 1b5332962a23..f93b6d7c9553 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorForm.form +++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorForm.form @@ -77,18 +77,9 @@ - - - - - - - - - @@ -110,6 +101,12 @@ + + + + + + diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java index b17e874c866b..e99b4fc3da27 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeEditorPanel.java @@ -60,7 +60,7 @@ import java.util.ArrayList; public class ScopeEditorPanel { private JPanel myButtonsPanel; - private JTextField myPatternField; + private RawCommandLineEditor myPatternField; private JPanel myTreeToolbar; private final Tree myPackageTree; private JPanel myPanel; @@ -107,20 +107,21 @@ public class ScopeEditorPanel { } }; + myPatternField.setDialogCaption("Pattern"); myPatternField.getDocument().addDocumentListener(new DocumentAdapter() { public void textChanged(DocumentEvent event) { onTextChange(); } }); - myPatternField.addCaretListener(new CaretListener() { + myPatternField.getTextField().addCaretListener(new CaretListener() { public void caretUpdate(CaretEvent e) { myCaretPosition = e.getDot(); updateCaretPositionText(); } }); - myPatternField.addFocusListener(new FocusListener() { + myPatternField.getTextField().addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { if (myErrorMessage != null) { myPositionPanel.setVisible(true); @@ -615,7 +616,7 @@ public class ScopeEditorPanel { if (requestFocus) { SwingUtilities.invokeLater(new Runnable() { public void run() { - myPatternField.requestFocusInWindow(); + myPatternField.getTextField().requestFocusInWindow(); } }); } diff --git a/platform/lang-impl/src/com/intellij/ide/util/treeView/AbstractTreeStructureBase.java b/platform/lang-impl/src/com/intellij/ide/util/treeView/AbstractTreeStructureBase.java index bc47efcd5f5f..c1bef72d1519 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/treeView/AbstractTreeStructureBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/treeView/AbstractTreeStructureBase.java @@ -45,7 +45,7 @@ public abstract class AbstractTreeStructureBase extends AbstractTreeStructure { LOG.assertTrue(element instanceof AbstractTreeNode, element != null ? element.getClass().getName() : null); AbstractTreeNode treeNode = (AbstractTreeNode)element; Collection elements = treeNode.getChildren(); - List providers = getProvidersDumbAware(); + List providers = getProvidersDumbAware(); if (providers != null && !providers.isEmpty()) { ViewSettings settings = treeNode instanceof ProjectViewNode ? ((ProjectViewNode) treeNode).getSettings() : ViewSettings.DEFAULT; for (TreeStructureProvider provider : providers) { diff --git a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java index 26c2616f4597..06c4c3075e33 100644 --- a/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java +++ b/platform/lang-impl/src/com/intellij/internal/psiView/PsiViewerDialog.java @@ -1248,9 +1248,9 @@ public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disp ViewerTreeStructure treeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure(); if (treeStructure == null) return; final PsiElement rootElement = treeStructure.getRootPsiElement(); + if (rootElement == null) return; final SelectionModel selection = myEditor.getSelectionModel(); - PsiElement rootPsiElement = treeStructure.getRootPsiElement(); - final TextRange textRange = rootPsiElement.getTextRange(); + final TextRange textRange = rootElement.getTextRange(); int baseOffset = textRange != null ? textRange.getStartOffset() : 0; final int start = selection.getSelectionStart()+baseOffset; final int end = selection.getSelectionEnd()+baseOffset - 1; diff --git a/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java b/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java index d0062512e0e3..d5a4fa9703f8 100644 --- a/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java +++ b/platform/lang-impl/src/com/intellij/lang/LanguagePerFileMappings.java @@ -137,7 +137,7 @@ public abstract class LanguagePerFileMappings implements PersistentStateCompo handleMappingChange(mappings.keySet(), oldFiles, !getProject().isDefault()); } - public void setMapping(final VirtualFile file, T dialect) { + public void setMapping(@Nullable final VirtualFile file, @Nullable T dialect) { synchronized (myMappings) { if (dialect == null) { myMappings.remove(file); diff --git a/platform/lang-impl/src/com/intellij/moduleDependencies/DependenciesAnalyzeManager.java b/platform/lang-impl/src/com/intellij/moduleDependencies/DependenciesAnalyzeManager.java index 592779460dba..2213c04103e7 100644 --- a/platform/lang-impl/src/com/intellij/moduleDependencies/DependenciesAnalyzeManager.java +++ b/platform/lang-impl/src/com/intellij/moduleDependencies/DependenciesAnalyzeManager.java @@ -56,7 +56,7 @@ public class DependenciesAnalyzeManager implements PersistentStateComponent myModuleTypes = new LinkedHashMap(); - public ModuleTypeManagerImpl() { registerModuleType(getDefaultModuleType(), true); } @@ -40,17 +39,18 @@ public class ModuleTypeManagerImpl extends ModuleTypeManager { public void registerModuleType(ModuleType type, boolean classpathProvider) { for (ModuleType oldType : myModuleTypes.keySet()) { if (oldType.getId().equals(type.getId())) { - LOG.error("Trying to register a module type that claunches with existing one. Old=" + oldType + ", new = " + type); + LOG.error("Trying to register a module type that clashes with existing one. Old=" + oldType + ", new = " + type); return; } } + myModuleTypes.put(type, classpathProvider); } public ModuleType[] getRegisteredTypes() { List result = new ArrayList(); result.addAll(myModuleTypes.keySet()); - for(ModuleTypeEP moduleTypeEP: Extensions.getExtensions(ModuleTypeEP.EP_NAME)) { + for (ModuleTypeEP moduleTypeEP : Extensions.getExtensions(ModuleTypeEP.EP_NAME)) { result.add(moduleTypeEP.getModuleType()); } @@ -64,18 +64,17 @@ public class ModuleTypeManagerImpl extends ModuleTypeManager { return type; } } - for(ModuleTypeEP ep: Extensions.getExtensions(ModuleTypeEP.EP_NAME)) { + for (ModuleTypeEP ep : Extensions.getExtensions(ModuleTypeEP.EP_NAME)) { if (ep.id.equals(moduleTypeID)) { return ep.getModuleType(); } } - return new UnknownModuleType(moduleTypeID, getDefaultModuleType()); } public boolean isClasspathProvider(final ModuleType moduleType) { - for(ModuleTypeEP ep: Extensions.getExtensions(ModuleTypeEP.EP_NAME)) { + for (ModuleTypeEP ep : Extensions.getExtensions(ModuleTypeEP.EP_NAME)) { if (ep.id.equals(moduleType.getId())) { return ep.classpathProvider; } diff --git a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java index 3cc157a9291d..91bca1ccdaa4 100644 --- a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java +++ b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java @@ -168,7 +168,7 @@ public class SdkConfigurationUtil { return sdk; } - public static void setDirectoryProjectSdk(@NotNull final Project project, final Sdk sdk) { + public static void setDirectoryProjectSdk(@NotNull final Project project, @Nullable final Sdk sdk) { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { ProjectRootManager.getInstance(project).setProjectSdk(sdk); diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/RenameLibraryHandler.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/RenameLibraryHandler.java new file mode 100644 index 000000000000..501201fffeb1 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/libraries/RenameLibraryHandler.java @@ -0,0 +1,129 @@ +/* + * 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.openapi.roots.impl.libraries; + +import com.intellij.ide.IdeBundle; +import com.intellij.ide.TitledHandler; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.undo.BasicUndoableAction; +import com.intellij.openapi.command.undo.UndoManager; +import com.intellij.openapi.command.undo.UndoableAction; +import com.intellij.openapi.command.undo.UnexpectedUndoException; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.ui.InputValidator; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.refactoring.rename.RenameHandler; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Konstantin Bulenkov + */ +public class RenameLibraryHandler implements RenameHandler, TitledHandler { + private static final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.actions.RenameModuleHandler"); + + public boolean isAvailableOnDataContext(DataContext dataContext) { + Library library = LangDataKeys.LIBRARY.getData(dataContext); + return library != null; + } + + public boolean isRenaming(DataContext dataContext) { + return isAvailableOnDataContext(dataContext); + } + + public void invoke(@NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { + LOG.assertTrue(false); + } + + public void invoke(@NotNull final Project project, @NotNull PsiElement[] elements, @NotNull DataContext dataContext) { + final Library library = LangDataKeys.LIBRARY.getData(dataContext); + LOG.assertTrue(library != null); + Messages.showInputDialog(project, + IdeBundle.message("prompt.enter.new.library.name"), + IdeBundle.message("title.rename.library"), + Messages.getQuestionIcon(), + library.getName(), + new MyInputValidator(project, library)); + } + + public String getActionTitle() { + return IdeBundle.message("title.rename.library"); + } + + private static class MyInputValidator implements InputValidator { + private final Project myProject; + private final Library myLibrary; + public MyInputValidator(Project project, Library library) { + myProject = project; + myLibrary = library; + } + + public boolean checkInput(String inputString) { + return inputString != null && inputString.length() > 0 && myLibrary.getTable().getLibraryByName(inputString) == null; + } + + public boolean canClose(final String inputString) { + final String oldName = myLibrary.getName(); + final Library.ModifiableModel modifiableModel = renameLibrary(inputString); + if (modifiableModel == null) return false; + final Ref success = Ref.create(Boolean.TRUE); + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + UndoableAction action = new BasicUndoableAction() { + public void undo() throws UnexpectedUndoException { + final Library.ModifiableModel modifiableModel = renameLibrary(oldName); + if (modifiableModel != null) { + modifiableModel.commit(); + } + } + + @Override + public void redo() throws UnexpectedUndoException { + final Library.ModifiableModel modifiableModel = renameLibrary(inputString); + if (modifiableModel != null) { + modifiableModel.commit(); + } + } + }; + UndoManager.getInstance(myProject).undoableActionPerformed(action); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + modifiableModel.commit(); + } + }); + } + }, IdeBundle.message("command.renaming.module", oldName), null); + return success.get().booleanValue(); + } + + @Nullable + private Library.ModifiableModel renameLibrary(String inputString) { + final Library.ModifiableModel modifiableModel = myLibrary.getModifiableModel(); + modifiableModel.setName(inputString); + return modifiableModel; + } + } + +} diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java index 0db1e91078f8..254761951dbd 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/libraries/ui/impl/CheckboxTreeTable.java @@ -17,6 +17,7 @@ package com.intellij.openapi.roots.libraries.ui.impl; import com.intellij.ui.CheckboxTree; import com.intellij.ui.CheckedTreeNode; +import com.intellij.ui.ClickListener; import com.intellij.ui.dualView.TreeTableView; import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns; import com.intellij.ui.treeStructure.treetable.TreeTableTree; @@ -30,7 +31,6 @@ import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.lang.reflect.Array; import java.util.ArrayList; @@ -54,12 +54,13 @@ public class CheckboxTreeTable extends TreeTableView { tree.setLineStyleAngled(); TreeUtil.installActions(tree); - addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { int row = tree.getRowForLocation(e.getX(), e.getY()); - if (row < 0) return; + if (row < 0) return false; final Object o = tree.getPathForRow(row).getLastPathComponent(); - if (!(o instanceof CheckedTreeNode)) return; + if (!(o instanceof CheckedTreeNode)) return false; Rectangle rowBounds = tree.getRowBounds(row); cellRenderer.setBounds(rowBounds); Rectangle checkBounds = cellRenderer.myCheckbox.getBounds(); @@ -72,11 +73,13 @@ public class CheckboxTreeTable extends TreeTableView { if (node.isEnabled()) { toggleNode(node); tree.setSelectionRow(row); + return true; } - e.consume(); } + + return false; } - }); + }.installOn(this); addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ChangeListsScopesProvider.java b/platform/lang-impl/src/com/intellij/packageDependencies/ChangeListsScopesProvider.java index 64f8867eeae8..8fa3c197ba45 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ChangeListsScopesProvider.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ChangeListsScopesProvider.java @@ -103,11 +103,13 @@ public class ChangeListsScopesProvider extends CustomScopesProviderEx { return files.contains(file); } + @NotNull @Override public PackageSet createCopy() { return this; } + @NotNull @Override public String getText() { return "file:*//*"; diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/DependenciesToolWindow.java b/platform/lang-impl/src/com/intellij/packageDependencies/DependenciesToolWindow.java index c72821fef78b..56f8cf77e193 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/DependenciesToolWindow.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/DependenciesToolWindow.java @@ -50,7 +50,7 @@ public class DependenciesToolWindow { project); myContentManager = toolWindow.getContentManager(); - toolWindow.setIcon(AllIcons.General.ToolWindowInspection); + toolWindow.setIcon(AllIcons.Toolwindows.ToolWindowInspection); new ContentManagerWatcher(toolWindow, myContentManager); } }); diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java index c29801d58402..91daed97ef45 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/InspectionProfileManager.java @@ -134,6 +134,7 @@ public class InspectionProfileManager extends ApplicationProfileManager implemen return InspectionsBundle.message("inspection.profiles.presentable.name"); } + @NotNull public Collection getProfiles() { initProfiles(); return mySchemesManager.getAllSchemes(); @@ -343,6 +344,7 @@ public class InspectionProfileManager extends ApplicationProfileManager implemen return directory; } + @NotNull public String[] getAvailableProfileNames() { final Collection names = mySchemesManager.getAllSchemeNames(); return ArrayUtil.toStringArray(names); diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java index 5067129f78fb..fe306e537246 100644 --- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/InspectionToolsConfigurable.java @@ -27,7 +27,6 @@ import com.intellij.codeInsight.daemon.impl.SeverityRegistrar; import com.intellij.codeInspection.ModifiableModel; import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.codeInspection.ex.InspectionToolRegistrar; -import com.intellij.icons.AllIcons; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.openapi.diagnostic.Logger; @@ -173,7 +172,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple profile.setLocal(true); profile.initInspectionTools(null); profile.setModified(true); - if (myPanels.get(profile.getName()) != null) { + if (getProfilePanel(profile) != null) { if (Messages.showOkCancelDialog(myWholePanel, "Profile with name \'" + profile.getName() + "\' already exists. Do you want to overwrite it?", "Warning", Messages.getInformationIcon()) != DialogWrapper.OK_EXIT_CODE) return; } addProfile((InspectionProfileImpl)profile.getModifiableModel()); @@ -247,7 +246,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple if (!myPanels.containsKey(modelName)) { ((DefaultComboBoxModel)myProfiles.getModel()).addElement(model); } - myPanels.put(modelName, panel); + putProfile(model, panel); myProfiles.setSelectedItem(model); } @@ -281,7 +280,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple public void customize(final JList list, final Profile value, final int index, final boolean selected, final boolean hasFocus) { final String profileName = value.getName(); setText(profileName); - final SingleInspectionProfilePanel panel = myPanels.get(profileName); + final SingleInspectionProfilePanel panel = getProfilePanel(value); setIcon(panel != null && panel.isProfileShared() ? Profile.PROJECT_PROFILE : Profile.LOCAL_PROFILE); } }); @@ -320,15 +319,36 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple } public void apply() throws ConfigurationException { - for (final Iterator it = myPanels.keySet().iterator(); it.hasNext();) { - final String name = it.next(); + final Map panels = new LinkedHashMap(); + for (final String name : myPanels.keySet()) { if (myDeletedProfiles.remove(name)) { deleteProfile(name); - it.remove(); - } else { - myPanels.get(name).apply(); + } + else { + final SingleInspectionProfilePanel panel = getProfilePanel(name); + panel.apply(); + final ModifiableModel profile = panel.getSelectedProfile(); + panels.put(getProfilePrefix(profile) + profile.getName(), panel); } } + myPanels.clear(); + myPanels.putAll(panels); + } + + private SingleInspectionProfilePanel getProfilePanel(String name) { + return myPanels.get(name); + } + + private SingleInspectionProfilePanel getProfilePanel(Profile inspectionProfile) { + return getProfilePanel(getProfilePrefix(inspectionProfile) + inspectionProfile.getName()); + } + + private void putProfile(Profile profile, SingleInspectionProfilePanel panel) { + myPanels.put(getProfilePrefix(profile) + profile.getName(), panel); + } + + private static String getProfilePrefix(Profile profile) { + return (profile.isLocal() ? "L" : "S"); } protected void deleteProfile(String name) { @@ -349,7 +369,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple model.addElement(profile); final String profileName = profile.getName(); final SingleInspectionProfilePanel panel = new SingleInspectionProfilePanel(myProjectProfileManager, profileName, ((InspectionProfileImpl)profile).getModifiableModel()); - myPanels.put(profileName, panel); + putProfile(profile, panel); myPanel.add(profileName, panel); } final InspectionProfileImpl inspectionProfile = getCurrentProfile(); @@ -426,7 +446,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple public void selectInspectionTool(String selectedToolShortName) { final InspectionProfileImpl inspectionProfile = getSelectedObject(); assert inspectionProfile != null : configuredProfiles(); - final SingleInspectionProfilePanel panel = myPanels.get(inspectionProfile.getName()); + final SingleInspectionProfilePanel panel = getProfilePanel(inspectionProfile); LOG.assertTrue(panel != null, "No settings panel for: " + inspectionProfile.getName() + "; " + configuredProfiles()); panel.selectInspectionTool(selectedToolShortName); } @@ -434,7 +454,7 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple protected SingleInspectionProfilePanel getSelectedPanel() { final InspectionProfileImpl inspectionProfile = getSelectedObject(); assert inspectionProfile != null : configuredProfiles(); - return myPanels.get(inspectionProfile.getName()); + return getProfilePanel(inspectionProfile); } private String configuredProfiles() { @@ -453,6 +473,6 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable imple public JComponent getPreferredFocusedComponent() { final InspectionProfileImpl inspectionProfile = getSelectedObject(); assert inspectionProfile != null : configuredProfiles(); - return myPanels.get(inspectionProfile.getName()).getTree(); + return getProfilePanel(inspectionProfile).getTree(); } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/inline/InlineRefactoringActionHandler.java b/platform/lang-impl/src/com/intellij/refactoring/inline/InlineRefactoringActionHandler.java index 02099b506a84..564996b61912 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/inline/InlineRefactoringActionHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/inline/InlineRefactoringActionHandler.java @@ -72,7 +72,7 @@ public class InlineRefactoringActionHandler implements RefactoringActionHandler } if (element != null) { for(InlineActionHandler handler: Extensions.getExtensions(InlineActionHandler.EP_NAME)) { - if (handler.canInlineElementInEditor(element)) { + if (handler.canInlineElementInEditor(element, editor)) { handler.inlineElement(project, editor, element); return; } diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesHandler.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesHandler.java index 7c74b3522101..18649c075b23 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesHandler.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesHandler.java @@ -27,6 +27,7 @@ import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.move.MoveHandlerDelegate; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; import java.util.HashSet; public class MoveFilesOrDirectoriesHandler extends MoveHandlerDelegate { @@ -70,7 +71,8 @@ public class MoveFilesOrDirectoriesHandler extends MoveHandlerDelegate { } public void doMove(final Project project, final PsiElement[] elements, final PsiElement targetContainer, @Nullable final MoveCallback callback) { - if (!LOG.assertTrue(targetContainer == null || targetContainer instanceof PsiDirectory || targetContainer instanceof PsiDirectoryContainer, targetContainer)) { + if (!LOG.assertTrue(targetContainer == null || targetContainer instanceof PsiDirectory || targetContainer instanceof PsiDirectoryContainer, + "container: " + targetContainer + "; elements: " + Arrays.toString(elements))) { return; } MoveFilesOrDirectoriesUtil.doMove(project, adjustForMove(project, elements, targetContainer), new PsiElement[] {targetContainer}, callback); diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java index 00a7d80e3a66..0c759ca07580 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -265,7 +265,7 @@ public class RenameDialog extends RefactoringDialog { elementProcessor.setToSearchForTextOccurrences(myPsiElement, isSearchInNonJavaFiles()); } if (mySuggestedNameInfo != null) { - mySuggestedNameInfo.nameChoosen(newName); + mySuggestedNameInfo.nameChosen(newName); } final RenameProcessor processor = new RenameProcessor(getProject(), myPsiElement, newName, isSearchInComments(), diff --git a/platform/lang-impl/src/com/intellij/testIntegration/GotoTestOrCodeHandler.java b/platform/lang-impl/src/com/intellij/testIntegration/GotoTestOrCodeHandler.java index cdd9ec709d36..41ec65b1ce54 100644 --- a/platform/lang-impl/src/com/intellij/testIntegration/GotoTestOrCodeHandler.java +++ b/platform/lang-impl/src/com/intellij/testIntegration/GotoTestOrCodeHandler.java @@ -20,7 +20,12 @@ import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.navigation.GotoTargetHandler; import com.intellij.codeInsight.navigation.NavigationUtil; import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; import com.intellij.pom.Navigatable; import com.intellij.psi.PsiElement; @@ -75,7 +80,7 @@ public class GotoTestOrCodeHandler extends GotoTargetHandler { } } - return new GotoData(sourceElement, PsiUtilBase.toPsiElementArray(candidates), actions); + return new GotoData(sourceElement, PsiUtilCore.toPsiElementArray(candidates), actions); } @NotNull @@ -102,6 +107,19 @@ public class GotoTestOrCodeHandler extends GotoTargetHandler { return CodeInsightBundle.message("goto.test.notFound"); } + @Nullable + @Override + protected String getAdText(PsiElement source, int length) { + if (length > 0 && !TestFinderHelper.isTest(source)) { + final Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); + final Shortcut[] shortcuts = keymap.getShortcuts(IdeActions.ACTION_DEFAULT_RUNNER); + if (shortcuts.length > 0) { + return ("Press " + KeymapUtil.getShortcutText(shortcuts[0]) + " to run selected tests"); + } + } + return null; + } + @Override protected void navigateToElement(Navigatable element) { if (element instanceof PsiElement) { diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java index 494b1d649b3d..6b0f0fbc6c40 100644 --- a/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/popup/util/DetailViewImpl.java @@ -30,6 +30,8 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.UserDataHolder; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.SideBorder; import com.intellij.ui.components.JBScrollPane; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -47,16 +49,17 @@ import java.awt.*; public class DetailViewImpl extends JPanel implements DetailView, UserDataHolder { private final Project myProject; private Editor myEditor; - private ItemWrapper myWrapper; - private JPanel myDetailPanel; + private ItemWrapper myWrapper; + + private JPanel myDetailPanel; private JBScrollPane myDetailScrollPanel; + private JPanel myDetailPanelWrapper; private JLabel myNothingToShow = new JLabel("Nothing to show"); private JLabel myNothingToShowInEditor = new JLabel("Nothing to show"); private RangeHighlighter myHighlighter; private PreviewEditorState myEditorState = PreviewEditorState.EMPTY; - public DetailViewImpl(Project project) { super(new BorderLayout()); myProject = project; @@ -78,11 +81,25 @@ public class DetailViewImpl extends JPanel implements DetailView, UserDataHolder } } + public void setCurrentItem(ItemWrapper wrapper) { + myWrapper = wrapper; + } + @Override public PreviewEditorState getEditorState() { return myEditorState; } + @Override + public ItemWrapper getCurrentItem() { + return myWrapper; + } + + @Override + public boolean hasEditorOnly() { + return false; + } + @Override public void removeNotify() { super.removeNotify(); @@ -133,6 +150,8 @@ public class DetailViewImpl extends JPanel implements DetailView, UserDataHolder validate(); getEditor().getScrollingModel().scrollToCaret(ScrollType.CENTER); + getEditor().setBorder(IdeBorderFactory.createBorder(SideBorder.BOTTOM)); + clearHightlighting(); if (lineAttributes != null) { myHighlighter = getEditor().getMarkupModel().addLineHighlighter(positionToNavigate.line, HighlighterLayer.SELECTION - 1, diff --git a/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java b/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java index 37d4add0c33d..b8de9a93159f 100644 --- a/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java +++ b/platform/lang-impl/src/com/intellij/ui/popup/util/MasterDetailPopupBuilder.java @@ -15,18 +15,14 @@ */ package com.intellij.ui.popup.util; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.ActionToolbar; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupListener; import com.intellij.openapi.ui.popup.LightweightWindowEvent; import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.ui.ColoredListCellRenderer; -import com.intellij.ui.Gray; -import com.intellij.ui.TitledSeparator; +import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.ui.speedSearch.FilteringListModel; import com.intellij.util.Alarm; @@ -61,6 +57,7 @@ public class MasterDetailPopupBuilder { private JComponent myChooserComponent; private ActionToolbar myActionToolbar; private boolean myAddDetailViewToEast = true; + private Dimension myMinSize; public MasterDetailPopupBuilder setDetailView(DetailView detailView) { @@ -148,12 +145,12 @@ public class MasterDetailPopupBuilder { public void run() { Object[] values = getSelectedItems(); if (values.length == 1) { - myDelegate.itemChosen((ItemWrapper)values[0], myProject, myPopup); + myDelegate.itemChosen((ItemWrapper)values[0], myProject, myPopup, false); } else { for (Object value : values) { if (value instanceof ItemWrapper) { - myDelegate.itemChosen((ItemWrapper)value, myProject, myPopup); + myDelegate.itemChosen((ItemWrapper)value, myProject, myPopup, false); } } } @@ -196,14 +193,18 @@ public class MasterDetailPopupBuilder { setItemChoosenCallback(runnable). setCloseOnEnter(myCloseOnEnter). setMayBeParent(true). - setMinSize(new Dimension(-1, 700)). setFilteringEnabled(new Function() { public String fun(Object o) { return ((ItemWrapper)o).speedSearchText(); } }); + if (myMinSize != null) { + builder.setMinSize(myMinSize); + } + myPopup = builder.createPopup(); + builder.getScrollPane().setBorder(IdeBorderFactory.createBorder(SideBorder.RIGHT)); myPopup.addListener(new JBPopupListener() { @Override public void beforeShown(LightweightWindowEvent event) { @@ -235,14 +236,20 @@ public class MasterDetailPopupBuilder { return null; } - public Object[] getSelectedItems() { + public ItemWrapper[] getSelectedItems() { + Object[] values = new Object[0]; if (myChooserComponent instanceof JList) { - return ((JList)myChooserComponent).getSelectedValues(); + values = ((JList)myChooserComponent).getSelectedValues(); + } else if (myChooserComponent instanceof JTree) { - return myDelegate.getSelectedItemsInTree(); + values = myDelegate.getSelectedItemsInTree(); } - return new Object[0]; + ItemWrapper[] items = new ItemWrapper[values.length]; + for (int i = 0; i < values.length; i++) { + items[i] = (ItemWrapper)values[i]; + } + return items; } private void updateDetailViewLater() { @@ -259,6 +266,11 @@ public class MasterDetailPopupBuilder { myAddDetailViewToEast = addDetailViewToEast; } + public MasterDetailPopupBuilder setMinSize(Dimension minSize) { + myMinSize = minSize; + return this; + } + public static boolean allowedToRemoveItems(Object[] values) { for (Object value : values) { ItemWrapper item = (ItemWrapper)value; @@ -357,6 +369,16 @@ public class MasterDetailPopupBuilder { } } }); + new AnAction(){ + @Override + public void actionPerformed(AnActionEvent e) { + ItemWrapper[] items = getSelectedItems(); + if (items.length > 0) { + myDelegate.itemChosen(items[0], myProject, myPopup, true); + } + } + }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)), list); + } public MasterDetailPopupBuilder setDelegate(Delegate delegate) { @@ -380,7 +402,7 @@ public class MasterDetailPopupBuilder { Object[] getSelectedItemsInTree(); - void itemChosen(ItemWrapper item, Project project, JBPopup popup); + void itemChosen(ItemWrapper item, Project project, JBPopup popup, boolean withEnterOrDoubleClick); } public static class ListItemRenderer extends JPanel implements ListCellRenderer { diff --git a/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java b/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java index a094599f2c14..44648abcc385 100644 --- a/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java +++ b/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java @@ -19,9 +19,8 @@ package com.intellij.unscramble; import com.intellij.execution.ExecutionManager; import com.intellij.execution.Executor; import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.filters.Filter; -import com.intellij.execution.filters.TextConsoleBuilder; -import com.intellij.execution.filters.TextConsoleBuilderFactory; +import com.intellij.execution.filters.*; +import com.intellij.execution.impl.ConsoleViewImpl; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.ExecutionConsole; @@ -95,8 +94,8 @@ public class AnalyzeStacktraceUtil { for(Filter filter: Extensions.getExtensions(EP_NAME, project)) { builder.addFilter(filter); } - final ConsoleView consoleView = builder.getConsole(); + final DefaultActionGroup toolbarActions = new DefaultActionGroup(); JComponent consoleComponent = consoleFactory != null ? consoleFactory.createConsoleComponent(consoleView, toolbarActions) @@ -109,10 +108,11 @@ public class AnalyzeStacktraceUtil { }; final Executor executor = DefaultRunExecutor.getRunExecutorInstance(); - toolbarActions.add(new CloseAction(executor, descriptor, project)); for (AnAction action: consoleView.createConsoleActions()) { toolbarActions.add(action); } + toolbarActions.add(new AnnotateStackTraceAction((ConsoleViewImpl)consoleView)); + toolbarActions.add(new CloseAction(executor, descriptor, project)); ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor); consoleView.allowHeavyFilters(); printStacktrace(consoleView, text); diff --git a/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java b/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java new file mode 100644 index 000000000000..00a18b3e0479 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/unscramble/AnnotateStackTraceAction.java @@ -0,0 +1,232 @@ +/* + * 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.unscramble; + +import com.intellij.execution.filters.FileHyperlinkInfo; +import com.intellij.execution.filters.HyperlinkInfo; +import com.intellij.execution.impl.ConsoleViewImpl; +import com.intellij.execution.impl.EditorHyperlinkSupport; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.colors.ColorKey; +import com.intellij.openapi.editor.colors.EditorColors; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorFontType; +import com.intellij.openapi.editor.ex.EditorGutterComponentEx; +import com.intellij.openapi.editor.markup.RangeHighlighter; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.progress.PerformInBackgroundOption; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.vcs.AbstractVcs; +import com.intellij.openapi.vcs.FilePath; +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.actions.ActiveAnnotationGutter; +import com.intellij.openapi.vcs.actions.VcsContextFactory; +import com.intellij.openapi.vcs.annotate.AnnotationSource; +import com.intellij.openapi.vcs.history.VcsFileRevision; +import com.intellij.openapi.vcs.history.VcsHistoryProvider; +import com.intellij.openapi.vcs.history.VcsHistorySession; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.text.DateFormatUtil; +import com.intellij.vcsUtil.VcsUtil; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.util.*; +import java.util.List; + +/** +* @author Konstantin Bulenkov +*/ +class AnnotateStackTraceAction extends AnAction { + private final EditorHyperlinkSupport myHyperlinks; + private Map cache; + private int newestLine = -1; + private int maxDateLength = 0; + private final Editor myEditor; + + AnnotateStackTraceAction(ConsoleViewImpl consoleView) { + super("Annotate", null, AllIcons.Actions.Annotate); + myHyperlinks = consoleView.getHyperlinks(); + myEditor = consoleView.getEditor(); + myEditor.getColorsScheme().setColor( + EditorColors.CARET_ROW_COLOR, EditorColorsManager.getInstance().getGlobalScheme().getColor(EditorColors.CARET_ROW_COLOR)); + } + + @Override + public void actionPerformed(AnActionEvent e) { + cache = new HashMap(); + + ProgressManager.getInstance().run( + new Task.Backgroundable(myEditor.getProject(), "Getting file history", true, PerformInBackgroundOption.ALWAYS_BACKGROUND) { + @Override + public boolean shouldStartInBackground() { + return true; + } + + @Override + public void onSuccess() { + } + + private void showGutter() { + myEditor.getGutter().registerTextAnnotation(new ActiveAnnotationGutter() { + @Override + public void doAction(int lineNum) { + } + + @Override + public Cursor getCursor(int lineNum) { + return Cursor.getDefaultCursor(); + } + + @Override + public String getLineText(int line, Editor editor) { + final VcsFileRevision revision = cache.get(line); + if (revision != null) { + return String.format("%"+maxDateLength+"s", DateFormatUtil.formatPrettyDate(revision.getRevisionDate())) + " " + revision.getAuthor(); + } + return ""; + } + + @Override + public String getToolTip(int line, Editor editor) { + final VcsFileRevision revision = cache.get(line); + if (revision != null) { + return "" + + revision.getAuthor() + + " " + + DateFormatUtil.formatDateTime(revision.getRevisionDate()) + + "
" + + revision.getCommitMessage() + + ""; + } + return null; + } + + @Override + public EditorFontType getStyle(int line, Editor editor) { + return line == newestLine ? EditorFontType.BOLD : EditorFontType.PLAIN; + } + + @Override + public ColorKey getColor(int line, Editor editor) { + return AnnotationSource.LOCAL.getColor(); + } + + @Override + public Color getBgColor(int line, Editor editor) { + return null; + } + + @Override + public List getPopupActions(int line, Editor editor) { + return Collections.emptyList(); + } + + @Override + public void gutterClosed() { + } + }); + } + + @Override + public void run(@NotNull ProgressIndicator indicator) { + Date newestDate = null; + HashMap> files2lines = new HashMap>(); + List files = new ArrayList(); + for (int line = 0; line < myEditor.getDocument().getLineCount(); line++) { + indicator.checkCanceled(); + final List links = myHyperlinks.findAllHyperlinksOnLine(line); + if (links.size() > 0) { + final HyperlinkInfo info = myHyperlinks.getHyperlinks().get(links.get(links.size() - 1)); + if (info instanceof FileHyperlinkInfo) { + final OpenFileDescriptor fileDescriptor = ((FileHyperlinkInfo)info).getDescriptor(); + if (fileDescriptor != null) { + final VirtualFile file = fileDescriptor.getFile(); + if (files2lines.containsKey(file)) { + files2lines.get(file).add(line); + } else { + final ArrayList lines = new ArrayList(); + lines.add(line); + files2lines.put(file, lines); + files.add(file); + } + } + } + } + } + + + for (VirtualFile file : files) { + indicator.checkCanceled(); + final AbstractVcs vcs = VcsUtil.getVcsFor(myEditor.getProject(), file); + FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file); + if (vcs != null) { + try { + final VcsHistoryProvider provider = vcs.getVcsHistoryProvider(); + final VcsHistorySession session; + if (provider != null) { + session = provider.createSessionFor(filePath); + final List list; + if (session != null) { + list = session.getRevisionList(); + final List lines = files2lines.get(file); + if (list != null && !list.isEmpty()) { + final VcsFileRevision revision = list.get(0); + final Date date = revision.getRevisionDate(); + if (newestDate == null || date.after(newestDate)) { + newestDate = date; + newestLine = lines.get(0); + } + final int length = DateFormatUtil.formatPrettyDate(date).length(); + if (length > maxDateLength) { + maxDateLength = length; + } + for (Integer line : lines) { + cache.put(line, revision); + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (cache.keySet().size() == 1) { + showGutter(); + } else { + ((EditorGutterComponentEx)myEditor.getGutter()).revalidateMarkup(); + } + } + }); + } + } + } + } + catch (VcsException ignored) { + } + } + + } + } + }); + } + + @Override + public void update(AnActionEvent e) { + e.getPresentation().setEnabled(cache == null); + } +} diff --git a/platform/lang-impl/src/com/intellij/usageView/impl/UsageViewManagerImpl.java b/platform/lang-impl/src/com/intellij/usageView/impl/UsageViewManagerImpl.java index dcb7cb0ea5de..5387ae9e100d 100644 --- a/platform/lang-impl/src/com/intellij/usageView/impl/UsageViewManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/usageView/impl/UsageViewManagerImpl.java @@ -43,7 +43,7 @@ public class UsageViewManagerImpl extends UsageViewManager { ToolWindow toolWindow = myToolWindowManager.registerToolWindow(ToolWindowId.FIND, true, ToolWindowAnchor.BOTTOM, project, true); toolWindow.setToHideOnEmptyContent(true); - toolWindow.setIcon(AllIcons.General.ToolWindowFind); + toolWindow.setIcon(AllIcons.Toolwindows.ToolWindowFind); myFindContentManager = toolWindow.getContentManager(); myFindContentManager.addContentManagerListener(new ContentManagerAdapter() { @Override diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index a8349053520a..cfcc046a8114 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -69,6 +69,7 @@ import com.intellij.util.io.storage.HeavyProcessLatch; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; import gnu.trove.*; +import jsr166e.SequenceLock; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -81,6 +82,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Lock; /** * @author Eugene Zhuravlev @@ -1019,6 +1021,8 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } + private final Lock myCalcIndexableFilesLock = new SequenceLock(); + @Nullable public ProjectIndexableFilesFilter projectIndexableFiles(@Nullable Project project) { if (project == null) return null; @@ -1027,17 +1031,29 @@ public class FileBasedIndexImpl extends FileBasedIndex { ProjectIndexableFilesFilter data = reference != null ? reference.get() : null; if (data != null && data.myModificationCount == myFilesModCount) return data; - final TIntHashSet filesSet = new TIntHashSet(); - iterateIndexableFiles(new ContentIterator() { - @Override - public boolean processFile(@NotNull VirtualFile fileOrDir) { - filesSet.add(((VirtualFileWithId)fileOrDir).getId()); - return true; + myCalcIndexableFilesLock.lock(); // since we calculate project file set to avoid extra vfs related io, it is better to wait a little + try { + reference = project.getUserData(ourProjectFilesSetKey); + data = reference != null ? reference.get() : null; + if (data != null && data.myModificationCount == myFilesModCount) { + return data; } - }, project, ProgressManager.getInstance().getProgressIndicator()); - ProjectIndexableFilesFilter files = new ProjectIndexableFilesFilter(filesSet, myFilesModCount); - project.putUserData(ourProjectFilesSetKey, new SoftReference(files)); - return files; + + final TIntHashSet filesSet = new TIntHashSet(); + iterateIndexableFiles(new ContentIterator() { + @Override + public boolean processFile(@NotNull VirtualFile fileOrDir) { + filesSet.add(((VirtualFileWithId)fileOrDir).getId()); + return true; + } + }, project, ProgressManager.getInstance().getProgressIndicator()); + ProjectIndexableFilesFilter files = new ProjectIndexableFilesFilter(filesSet, myFilesModCount); + project.putUserData(ourProjectFilesSetKey, new SoftReference(files)); + return files; + } + finally { + myCalcIndexableFilesLock.unlock(); + } } @Nullable diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java index d30183964754..519855cd51df 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ThreeComponentsSplitter.java @@ -20,6 +20,7 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.wm.IdeGlassPane; import com.intellij.openapi.wm.IdeGlassPaneUtil; +import com.intellij.ui.ClickListener; import com.intellij.ui.UIBundle; import com.intellij.util.ui.update.Activatable; import com.intellij.util.ui.update.UiNotifyConnector; @@ -531,8 +532,9 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { splitDownlabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); splitDownlabel.setToolTipText(isVerticalSplit ? UIBundle.message("splitter.down.tooltip.text") : UIBundle .message("splitter.right.tooltip.text")); - splitDownlabel.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { if (myInnerComponent != null) { final int income = myVerticalSplit ? myInnerComponent.getHeight() : myInnerComponent.getWidth(); if (myIsFirst) { @@ -542,8 +544,10 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { setLastSize(myLastSize + income); } } + return true; } - }); + }.installOn(splitDownlabel); + add(splitDownlabel, new GridBagConstraints(isVerticalSplit ? 1 : 0, isVerticalSplit ? 0 : 5, @@ -554,11 +558,13 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { JLabel splitCenterlabel = new JLabel(isVerticalSplit ? AllIcons.General.SplitCenterV : AllIcons.General.SplitCenterH); splitCenterlabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); splitCenterlabel.setToolTipText(UIBundle.message("splitter.center.tooltip.text")); - splitCenterlabel.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { center(); + return true; } - }); + }.installOn(splitCenterlabel); add(splitCenterlabel, new GridBagConstraints(3 * xMask, 3 * yMask, 1, 1, 0, 0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); add(new JLabel(glueIcon), @@ -568,18 +574,22 @@ public class ThreeComponentsSplitter extends JPanel implements Disposable { splitUpLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); splitUpLabel.setToolTipText(isVerticalSplit ? UIBundle.message("splitter.up.tooltip.text") : UIBundle .message("splitter.left.tooltip.text")); - splitUpLabel.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { if (myInnerComponent != null) { + final int income = myVerticalSplit ? myInnerComponent.getHeight() : myInnerComponent.getWidth(); if (myIsFirst) { - setFirstSize(getMinSize(myFirstComponent)); + setFirstSize(myFirstSize + income); } else { - setLastSize(getMinSize(myLastComponent)); + setLastSize(myLastSize + income); } } + return true; } - }); + }.installOn(splitUpLabel); + add(splitUpLabel, new GridBagConstraints(isVerticalSplit ? 5 : 0, isVerticalSplit ? 0 : 1, diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java index 1d7ddf517976..6c1aea206ed0 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/PopupChooserBuilder.java @@ -83,6 +83,12 @@ public class PopupChooserBuilder { private boolean myModalContext; private boolean myCloseOnEnter = true; + public JScrollPane getScrollPane() { + return myScrollPane; + } + + private JScrollPane myScrollPane; + public PopupChooserBuilder(@NotNull JList list) { myChooserComponent = list; } @@ -232,29 +238,28 @@ public class PopupChooserBuilder { registerClosePopupKeyboardAction(keystroke, true); } - final JScrollPane scrollPane; if (myChooserComponent instanceof ListWithFilter) { - scrollPane = ((ListWithFilter)myChooserComponent).getScrollPane(); + myScrollPane = ((ListWithFilter)myChooserComponent).getScrollPane(); } else if (myChooserComponent instanceof JTable) { - scrollPane = createScrollPane((JTable)myChooserComponent); + myScrollPane = createScrollPane((JTable)myChooserComponent); } else if (myChooserComponent instanceof JTree) { - scrollPane = createScrollPane((JTree)myChooserComponent); + myScrollPane = createScrollPane((JTree)myChooserComponent); } else { throw new IllegalStateException("PopupChooserBuilder is intended to be constructed with one of JTable, JTree, JList components"); } - scrollPane.getViewport().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + myScrollPane.getViewport().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); Insets viewportPadding = UIUtil.getListViewportPadding(); - ((JComponent)scrollPane.getViewport().getView()).setBorder(BorderFactory.createEmptyBorder(viewportPadding.top, viewportPadding.left, viewportPadding.bottom, viewportPadding.right)); + ((JComponent)myScrollPane.getViewport().getView()).setBorder(BorderFactory.createEmptyBorder(viewportPadding.top, viewportPadding.left, viewportPadding.bottom, viewportPadding.right)); if (myChooserComponent instanceof ListWithFilter) { contentPane.add(myChooserComponent, BorderLayout.CENTER); } else { - contentPane.add(scrollPane, BorderLayout.CENTER); + contentPane.add(myScrollPane, BorderLayout.CENTER); } if (mySouthComponent != null) { diff --git a/platform/platform-api/src/com/intellij/ui/AddEditDeleteListPanel.java b/platform/platform-api/src/com/intellij/ui/AddEditDeleteListPanel.java index 68cb117b291b..b93c22da7d13 100644 --- a/platform/platform-api/src/com/intellij/ui/AddEditDeleteListPanel.java +++ b/platform/platform-api/src/com/intellij/ui/AddEditDeleteListPanel.java @@ -17,7 +17,6 @@ package com.intellij.ui; import org.jetbrains.annotations.Nullable; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.List; @@ -28,13 +27,13 @@ import java.util.List; public abstract class AddEditDeleteListPanel extends AddDeleteListPanel { public AddEditDeleteListPanel(final String title, final List initialList) { super(title, initialList); - myList.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) { - editSelectedItem(); - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent event) { + editSelectedItem(); + return true; } - }); + }.installOn(myList); } @Override diff --git a/platform/platform-api/src/com/intellij/ui/AddEditRemovePanel.java b/platform/platform-api/src/com/intellij/ui/AddEditRemovePanel.java index d47da3590cea..01a679f5eb27 100644 --- a/platform/platform-api/src/com/intellij/ui/AddEditRemovePanel.java +++ b/platform/platform-api/src/com/intellij/ui/AddEditRemovePanel.java @@ -25,7 +25,6 @@ import javax.swing.*; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.List; @@ -147,11 +146,13 @@ public abstract class AddEditRemovePanel extends PanelWithButtons implements myTable = new JBTable(myTableModel); myTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); myTable.setStriped(true); - myTable.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e){ - if (e.getClickCount() == 2) doEdit(); + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent event) { + doEdit(); + return true; } - }); + }.installOn(myTable); } protected JButton[] createButtons(){ diff --git a/platform/platform-api/src/com/intellij/ui/AutoScrollToSourceHandler.java b/platform/platform-api/src/com/intellij/ui/AutoScrollToSourceHandler.java index bdf0e1babd30..dea05dd95ecb 100644 --- a/platform/platform-api/src/com/intellij/ui/AutoScrollToSourceHandler.java +++ b/platform/platform-api/src/com/intellij/ui/AutoScrollToSourceHandler.java @@ -41,7 +41,6 @@ import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; @@ -53,16 +52,21 @@ public abstract class AutoScrollToSourceHandler { public void install(final JTree tree) { myAutoScrollAlarm = new Alarm(); - tree.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) return; + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { + if (clickCount > 1) return false; TreePath location = tree.getPathForLocation(e.getPoint().x, e.getPoint().y); if (location != null) { onMouseClicked(tree); + return true; } + + return false; } - }); + }.installOn(tree); + tree.addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(final MouseEvent e) { onSelectionChanged(tree); @@ -79,16 +83,20 @@ public abstract class AutoScrollToSourceHandler { public void install(final JTable table) { myAutoScrollAlarm = new Alarm(); - table.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) return; + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { + if (clickCount >= 2) return false; Component location = table.getComponentAt(e.getPoint()); if (location != null) { onMouseClicked(table); + return true; } + return false; } - }); + }.installOn(table); + table.addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(final MouseEvent e) { onSelectionChanged(table); @@ -106,16 +114,20 @@ public abstract class AutoScrollToSourceHandler { public void install(final JList jList) { myAutoScrollAlarm = new Alarm(); - jList.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) return; + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { + if (clickCount >= 2) return false; final Object source = e.getSource(); final int index = jList.locationToIndex(SwingUtilities.convertPoint(source instanceof Component ? (Component)source : null, e.getPoint(), jList)); if (index >= 0 && index < jList.getModel().getSize()) { onMouseClicked(jList); + return true; } + return false; } - }); + }.installOn(jList); + jList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { onSelectionChanged(jList); diff --git a/platform/platform-api/src/com/intellij/ui/CheckBoxList.java b/platform/platform-api/src/com/intellij/ui/CheckBoxList.java index dd171f42d83a..03c98d3f55a9 100644 --- a/platform/platform-api/src/com/intellij/ui/CheckBoxList.java +++ b/platform/platform-api/src/com/intellij/ui/CheckBoxList.java @@ -10,7 +10,6 @@ import javax.swing.plaf.basic.BasicRadioButtonUI; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Map; @@ -53,8 +52,9 @@ public class CheckBoxList extends JBList { } } }); - addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { if (isEnabled()) { int index = locationToIndex(e.getPoint()); @@ -69,11 +69,13 @@ public class CheckBoxList extends JBList { } if (e.getX() < iconArea) { setSelected(checkbox, index); + return true; } } } + return false; } - }); + }.installOn(this); } public void setStringItems(final Map items) { diff --git a/platform/platform-api/src/com/intellij/ui/CheckBoxWithColorChooser.java b/platform/platform-api/src/com/intellij/ui/CheckBoxWithColorChooser.java index 592c30780954..109acad78d48 100644 --- a/platform/platform-api/src/com/intellij/ui/CheckBoxWithColorChooser.java +++ b/platform/platform-api/src/com/intellij/ui/CheckBoxWithColorChooser.java @@ -19,7 +19,6 @@ import com.intellij.openapi.util.SystemInfo; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** @@ -74,17 +73,19 @@ public class CheckBoxWithColorChooser extends JPanel { if (SystemInfo.isMac) { putClientProperty("JButton.buttonType", "square"); } - addMouseListener(new MouseAdapter() { + + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { if (myCheckbox.isSelected()) { final Color color = ColorChooser.chooseColor(myCheckbox, "Chose color", CheckBoxWithColorChooser.this.myColor); if (color != null) { myColor = color; } } + return true; } - }); + }.installOn(this); } @Override diff --git a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java index c924393d5982..4a0a823eb9a2 100644 --- a/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java +++ b/platform/platform-api/src/com/intellij/ui/CheckboxTreeBase.java @@ -25,7 +25,6 @@ import javax.swing.tree.*; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.lang.reflect.Array; import java.util.ArrayList; @@ -48,12 +47,13 @@ public class CheckboxTreeBase extends Tree { setLineStyleAngled(); TreeUtil.installActions(this); - addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { int row = getRowForLocation(e.getX(), e.getY()); - if (row < 0) return; + if (row < 0) return false; final Object o = getPathForRow(row).getLastPathComponent(); - if (!(o instanceof CheckedTreeNode)) return; + if (!(o instanceof CheckedTreeNode)) return false; Rectangle rowBounds = getRowBounds(row); cellRenderer.setBounds(rowBounds); Rectangle checkBounds = cellRenderer.myCheckbox.getBounds(); @@ -66,14 +66,16 @@ public class CheckboxTreeBase extends Tree { if (node.isEnabled()) { toggleNode(node); setSelectionRow(row); + return true; } - e.consume(); } - else if (e.getClickCount() > 1) { + else if (clickCount > 1) { onDoubleClick(node); + return true; } + return false; } - }); + }.installOn(this); addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { diff --git a/platform/platform-api/src/com/intellij/ui/DoubleClickListener.java b/platform/platform-api/src/com/intellij/ui/DoubleClickListener.java new file mode 100644 index 000000000000..048ab41ac5a4 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/DoubleClickListener.java @@ -0,0 +1,34 @@ +/* + * 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. + */ + +/* + * @author max + */ +package com.intellij.ui; + +import java.awt.event.MouseEvent; + +public abstract class DoubleClickListener extends ClickListener { + @Override + public final boolean onClick(MouseEvent event, int clickCount) { + if (clickCount == 2 && event.getButton() == MouseEvent.BUTTON1) { + return onDoubleClick(event); + } + return false; + } + + protected abstract boolean onDoubleClick(MouseEvent event); +} diff --git a/platform/platform-api/src/com/intellij/ui/PrepareTreeRenderer.java b/platform/platform-api/src/com/intellij/ui/PrepareTreeRenderer.java new file mode 100644 index 000000000000..ad4c0da76105 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/PrepareTreeRenderer.java @@ -0,0 +1,79 @@ +/* + * 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.ui; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 6/12/12 + * Time: 4:40 PM + */ +public class PrepareTreeRenderer { +/* public static void prepare(final JTree tree, final JComponent component, final boolean selected, final boolean hasFocus) { + final boolean treeFocused = tree.hasFocus(); + // We paint background if and only if tree path is selected and tree has focus. + // If path is selected and tree is not focused then we just paint focused border. + if (UIUtil.isFullRowSelectionLAF()) { + component.setBackground(selected ? UIUtil.getTreeSelectionBackground() : null); + } + else if (UIUtil.isUnderAquaLookAndFeel() && tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection()) { + component.setPaintFocusBorder(false); + //setBackground(selected ? UIUtil.getTreeSelectionBackground() : null); + } + else { + if (selected) { + component.setPaintFocusBorder(true); + if (treeFocused) { + component.setBackground(UIUtil.getTreeSelectionBackground()); + } + else { + component.setBackground(null); + } + } + else { + component.setBackground(null); + } + } + + component.setForeground(tree.getForeground()); + component.setIcon(null); + + if (UIUtil.isUnderGTKLookAndFeel()){ + component.setOpaque(false); // avoid nasty background + component.setIconOpaque(false); + } + else if (UIUtil.isUnderNimbusLookAndFeel() && selected && hasFocus) { + component.setOpaque(false); // avoid erasing Nimbus focus frame + component.setIconOpaque(false); + } + else if (UIUtil.isUnderAquaLookAndFeel() && tree.getUI() instanceof MacTreeUI && ((MacTreeUI)tree.getUI()).isWideSelection()) { + component.setOpaque(false); // avoid erasing Nimbus focus frame + component.setIconOpaque(false); + } + else { + component.setOpaque(myOpaque || selected && hasFocus || selected && treeFocused); // draw selection background even for non-opaque tree + } + + if (tree.getUI() instanceof MacTreeUI) { + component.setMyBorder(null); + component.setIpad(new Insets(0, 2, 0, 2)); + } + + if (component.getFont() == null) { + component.setFont(tree.getFont()); + } + } */ +} diff --git a/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java b/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java index 78707b3d12c0..a0541e4dc1be 100644 --- a/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java +++ b/platform/platform-api/src/com/intellij/ui/components/labels/LinkLabel.java @@ -288,12 +288,6 @@ public class LinkLabel extends JLabel { } private class MyMouseHandler extends MouseAdapter implements MouseMotionListener { - public void mouseClicked(MouseEvent e) { - if (isInClickableArea(e.getPoint()) && e.getClickCount() == 1) { - doClick(e); - } - } - public void mousePressed(MouseEvent e) { if (isInClickableArea(e.getPoint())) { setActive(true); @@ -301,6 +295,9 @@ public class LinkLabel extends JLabel { } public void mouseReleased(MouseEvent e) { + if (myIsLinkActive && isInClickableArea(e.getPoint())) { + doClick(e); + } setActive(false); } diff --git a/platform/platform-api/src/com/intellij/ui/roots/IconActionComponent.java b/platform/platform-api/src/com/intellij/ui/roots/IconActionComponent.java index 33593eecfd07..411d5f059323 100644 --- a/platform/platform-api/src/com/intellij/ui/roots/IconActionComponent.java +++ b/platform/platform-api/src/com/intellij/ui/roots/IconActionComponent.java @@ -15,6 +15,8 @@ */ package com.intellij.ui.roots; +import com.intellij.ui.ClickListener; + import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; @@ -34,17 +36,22 @@ public class IconActionComponent extends ScalableIconComponent { setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } - public void mouseClicked(MouseEvent e) { - if (action != null) { - action.run(); - } - } - public void mouseExited(MouseEvent e) { setSelected(false); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } }); + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { + if (action != null) { + action.run(); + return true; + } + return false; + } + }.installOn(this); + if (tooltipText != null) { this.setToolTipText(tooltipText); } diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java index f0623fa5895c..20c3a1753343 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java @@ -2443,7 +2443,7 @@ public class JBTabsImpl extends JComponent } private void updateContainer(boolean forced, final boolean layoutNow) { - for (TabInfo each : myVisibleInfos) { + for (TabInfo each : new ArrayList(myVisibleInfos)) { final JComponent eachComponent = each.getComponent(); if (getSelectedInfo() == each && getSelectedInfo() != null) { unqueueFromRemove(eachComponent); diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java index 0c512c632510..ac455afd4848 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java @@ -139,7 +139,9 @@ public class TabLabel extends JPanel { } public void paintOffscreen(Graphics g) { - validateTree(); + synchronized(getTreeLock()) { + validateTree(); + } doPaint(g); } diff --git a/platform/platform-api/src/com/intellij/util/EditSourceOnDoubleClickHandler.java b/platform/platform-api/src/com/intellij/util/EditSourceOnDoubleClickHandler.java index caaf8f12479f..34791ec8f524 100644 --- a/platform/platform-api/src/com/intellij/util/EditSourceOnDoubleClickHandler.java +++ b/platform/platform-api/src/com/intellij/util/EditSourceOnDoubleClickHandler.java @@ -21,6 +21,7 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.project.Project; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.treeStructure.treetable.TreeTable; import com.intellij.util.ui.tree.MacTreeUI; import org.jetbrains.annotations.Nullable; @@ -30,14 +31,13 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class EditSourceOnDoubleClickHandler { private EditSourceOnDoubleClickHandler() { } public static void install(final JTree tree, @Nullable final Runnable whenPerformed) { - tree.addMouseListener(new TreeMouseListener(tree, whenPerformed)); + new TreeMouseListener(tree, whenPerformed).installOn(tree); } public static void install(final JTree tree) { @@ -45,50 +45,53 @@ public class EditSourceOnDoubleClickHandler { } public static void install(final TreeTable treeTable) { - treeTable.addMouseListener(new MouseAdapter(){ - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() != 2) return; - if (ModalityState.current().dominates(ModalityState.NON_MODAL)) return; - if (treeTable.getTree().getPathForLocation(e.getX(), e.getY()) == null) return; + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + if (ModalityState.current().dominates(ModalityState.NON_MODAL)) return false; + if (treeTable.getTree().getPathForLocation(e.getX(), e.getY()) == null) return false; DataContext dataContext = DataManager.getInstance().getDataContext(treeTable); Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) return; + if (project == null) return false; OpenSourceUtil.openSourcesFrom(dataContext, true); + return true; } - }); + }.installOn(treeTable); } public static void install(final JTable table) { - table.addMouseListener(new MouseAdapter(){ - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() != 2) return; - if (ModalityState.current().dominates(ModalityState.NON_MODAL)) return; - if (table.columnAtPoint(e.getPoint()) < 0) return; - if (table.rowAtPoint(e.getPoint()) < 0) return; + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + if (ModalityState.current().dominates(ModalityState.NON_MODAL)) return false; + if (table.columnAtPoint(e.getPoint()) < 0) return false; + if (table.rowAtPoint(e.getPoint()) < 0) return false; DataContext dataContext = DataManager.getInstance().getDataContext(table); Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) return; + if (project == null) return false; OpenSourceUtil.openSourcesFrom(dataContext, true); + return true; } - }); + }.installOn(table); } public static void install(final JList list, final Runnable whenPerformed) { - list.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() != 2) return; + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { Point point = e.getPoint(); int index = list.locationToIndex(point); - if (index == -1) return; - if (!list.getCellBounds(index, index).contains(point)) return; + if (index == -1) return false; + if (!list.getCellBounds(index, index).contains(point)) return false; DataContext dataContext = DataManager.getInstance().getDataContext(list); OpenSourceUtil.openSourcesFrom(dataContext, true); whenPerformed.run(); + return true; } - }); + }.installOn(list); } - public static class TreeMouseListener extends MouseAdapter { + public static class TreeMouseListener extends DoubleClickListener { private final JTree myTree; @Nullable private final Runnable myWhenPerformed; @@ -101,24 +104,25 @@ public class EditSourceOnDoubleClickHandler { myWhenPerformed = whenPerformed; } - public void mouseClicked(MouseEvent e) { - if (MouseEvent.BUTTON1 != e.getButton() || e.getClickCount() != 2) return; - + @Override + public boolean onDoubleClick(MouseEvent e) { final TreePath path = myTree.getUI() instanceof MacTreeUI ? myTree.getClosestPathForLocation(e.getX(), e.getY()) : myTree.getPathForLocation(e.getX(), e.getY()); - if (path == null) return; + if (path == null) return false; final DataContext dataContext = DataManager.getInstance().getDataContext(myTree); final Project project = PlatformDataKeys.PROJECT.getData(dataContext); - if (project == null) return; + if (project == null) return false; final TreePath selectionPath = myTree.getSelectionPath(); - if (selectionPath == null) return; + if (selectionPath == null) return false; final Object lastPathComponent = selectionPath.getLastPathComponent(); if (((TreeNode)lastPathComponent).isLeaf() || !expandOnDoubleClick(((TreeNode)lastPathComponent))) { //Node expansion for non-leafs has a higher priority processDoubleClick(e, dataContext, (TreeNode) lastPathComponent); + return true; } + return false; } @SuppressWarnings("UnusedParameters") diff --git a/platform/platform-api/src/com/intellij/util/ui/StatusText.java b/platform/platform-api/src/com/intellij/util/ui/StatusText.java index 043b377610bc..19a5edbd2c71 100644 --- a/platform/platform-api/src/com/intellij/util/ui/StatusText.java +++ b/platform/platform-api/src/com/intellij/util/ui/StatusText.java @@ -16,6 +16,7 @@ package com.intellij.util.ui; +import com.intellij.ui.ClickListener; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.UIBundle; @@ -24,10 +25,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import java.awt.event.*; import java.util.ArrayList; public abstract class StatusText { @@ -35,7 +33,8 @@ public abstract class StatusText { @Nullable private Component myOwner; - private final MouseAdapter myMouseListener; + private final MouseMotionListener myMouseMotionListener; + private final ClickListener myClickListener; private boolean myIsDefaultText; @@ -49,17 +48,21 @@ public abstract class StatusText { } public StatusText() { - myMouseListener = new MouseAdapter() { + myClickListener = new ClickListener() { @Override - public void mouseClicked(final MouseEvent e) { - if (e.getButton() == 1 && e.getClickCount() == 1) { + public boolean onClick(MouseEvent e, int clickCount) { + if (e.getButton() == MouseEvent.BUTTON1 && clickCount == 1) { ActionListener actionListener = findActionListenerAt(e.getPoint()); if (actionListener != null) { actionListener.actionPerformed(new ActionEvent(this, 0, "")); + return true; } } + return false; } + }; + myMouseMotionListener = new MouseAdapter() { @Override public void mouseMoved(final MouseEvent e) { if (findActionListenerAt(e.getPoint()) != null) { @@ -79,15 +82,15 @@ public abstract class StatusText { public void attachTo(@Nullable Component owner) { if (myOwner != null) { - myOwner.removeMouseListener(myMouseListener); - myOwner.removeMouseMotionListener(myMouseListener); + myClickListener.uninstall(myOwner); + myOwner.removeMouseMotionListener(myMouseMotionListener); } myOwner = owner; if (myOwner != null) { - myOwner.addMouseListener(myMouseListener); - myOwner.addMouseMotionListener(myMouseListener); + myClickListener.installOn(myOwner); + myOwner.addMouseMotionListener(myMouseMotionListener); } } @@ -172,4 +175,4 @@ public abstract class StatusText { public Dimension getPreferredSize() { return myComponent.getPreferredSize(); } -} \ No newline at end of file +} diff --git a/platform/platform-impl/src/com/intellij/application/options/SelectFontDialog.java b/platform/platform-impl/src/com/intellij/application/options/SelectFontDialog.java index 6a255b5053cf..ec6e723dde3c 100644 --- a/platform/platform-impl/src/com/intellij/application/options/SelectFontDialog.java +++ b/platform/platform-impl/src/com/intellij/application/options/SelectFontDialog.java @@ -18,6 +18,7 @@ package com.intellij.application.options; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ListScrollingUtil; import com.intellij.ui.ListSpeedSearch; import com.intellij.ui.ScrollPaneFactory; @@ -28,7 +29,6 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.List; @@ -57,15 +57,13 @@ public class SelectFontDialog extends DialogWrapper { myFontList.setModel(new DefaultListModel()); fillList(useOnlyMonospacedFonts); - myFontList.addMouseListener( - new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2){ - doOKAction(); - } - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + doOKAction(); + return true; } - ); + }.installOn(myFontList); myFontList.setCellRenderer(new MyListCellRenderer()); diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeFatalErrorsIcon.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeFatalErrorsIcon.java index 17b525a0a4a9..3f0b002b82ae 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeFatalErrorsIcon.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeFatalErrorsIcon.java @@ -2,12 +2,12 @@ package com.intellij.diagnostic; import com.intellij.concurrency.JobScheduler; import com.intellij.icons.AllIcons; +import com.intellij.ui.ClickListener; import com.intellij.ui.LayeredIcon; import javax.swing.*; import java.awt.*; import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -32,13 +32,16 @@ public class IdeFatalErrorsIcon extends JLabel { myListener = aListener; setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1)); - addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { if (myState != State.NoErrors) { myListener.actionPerformed(null); + return true; } + return false; } - }); + }.installOn(this); myIcon = new LayeredIcon(UNREAD_ERROR_ICON, READ_ERROR_ICON, NO_ERRORS_ICON) { @Override diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeMessagePanel.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeMessagePanel.java index bd4cd792f56e..a7892f3f98dc 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeMessagePanel.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeMessagePanel.java @@ -28,8 +28,6 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; import java.util.List; import java.util.concurrent.TimeUnit; @@ -248,97 +246,4 @@ public class IdeMessagePanel extends JPanel implements MessagePoolListener, Icon } return result; } - - private class IconPane extends JLabel { - private final IconWrapper myIcon; - private final String myEmptyText; - private boolean myIsActive; - private final ActionListener myListener; - - public IconPane(Icon aIcon, Icon offIcon, String aEmptyText, ActionListener aListener) { - myIcon = new IconWrapper(aIcon, offIcon); - myEmptyText = aEmptyText; - myListener = aListener; - setIcon(myIcon); - - setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 1)); - - addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (myIsActive) { - myListener.actionPerformed(null); - } - } - }); - - deactivate(); - } - - public IconWrapper getIconWrapper() { - return myIcon; - } - - public void activate(String aDisplayingText) { - setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - myIsActive = true; - myIcon.setIconPainted(true); - setToolTipText(aDisplayingText); - repaint(); - } - - public void deactivate() { - setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - myIsActive = false; - myIcon.setIconPainted(false); - setToolTipText(myEmptyText); - repaint(); - } - - public boolean shouldBlink() { - return myMessagePool.hasUnreadMessages(); - } - } - - private class IconWrapper implements Icon { - private final Icon myIcon; - private boolean myEnabled; - private boolean myShouldPaint = true; - private Icon myOffIcon; - - public IconWrapper(Icon aIcon, Icon offIcon) { - myIcon = aIcon; - myOffIcon = offIcon; - } - - public void setIconPainted(boolean aPainted) { - myEnabled = aPainted; - } - - public int getIconHeight() { - return myIcon.getIconHeight(); - } - - public int getIconWidth() { - return myIcon.getIconWidth(); - } - - public void paintIcon(Component c, Graphics g, int x, int y) { - if (myEnabled && myShouldPaint) { - myIcon.paintIcon(c, g, x, y); - } else if (myOffIcon != null) { - myOffIcon.paintIcon(c, g, x, y); - } - } - - public void setVisible(final boolean visible) { - if (myShouldPaint != visible) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - repaint(); - } - }); - } - myShouldPaint = visible; - } - } } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java index 6681557fb2df..9548e7e03a01 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/JetBrainsAccountDialog.java @@ -18,11 +18,11 @@ package com.intellij.diagnostic; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.ClickListener; import com.intellij.util.net.HTTPProxySettingsDialog; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** @@ -76,24 +76,27 @@ public class JetBrainsAccountDialog extends DialogWrapper { setTitle(ReportMessages.ERROR_REPORT); getContentPane().add(myMainPanel); - mySendingSettingsLabel.addMouseListener(new MouseAdapter () { - public void mouseClicked(MouseEvent e) { - + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { HTTPProxySettingsDialog settingsDialog = new HTTPProxySettingsDialog (); settingsDialog.pack(); settingsDialog.show(); + return true; } - }); + }.installOn(mySendingSettingsLabel); + mySendingSettingsLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); loadInfo(); - myCreateAccountLabel.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(final MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { BrowserUtil.launchBrowser("http://account.jetbrains.com"); + return true; } - }); + }.installOn(myCreateAccountLabel); myCreateAccountLabel.setCursor(new Cursor (Cursor.HAND_CURSOR)); super.init (); diff --git a/platform/platform-impl/src/com/intellij/ide/actions/AboutDialog.java b/platform/platform-impl/src/com/intellij/ide/actions/AboutDialog.java index 3bbefc88fca7..92058b17a2c3 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/AboutDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/AboutDialog.java @@ -25,6 +25,7 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.ui.ClickListener; import com.intellij.ui.LicensingFacade; import com.intellij.util.text.DateFormatUtil; import com.intellij.util.ui.UIUtil; @@ -111,14 +112,13 @@ public class AboutDialog extends JDialog { } }); - closeListenerOwner.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (!e.isConsumed()) { - dispose(); - e.consume(); - } + new ClickListener() { + @Override + public boolean onClick(MouseEvent event, int clickCount) { + dispose(); + return true; } - }); + }.installOn(closeListenerOwner); pack(); diff --git a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java index 325ff23bebb2..eb56e045f9ac 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java @@ -187,6 +187,22 @@ public class Switcher extends AnAction implements DumbAware { final Map twShortcuts; final Alarm myAlarm; final SwitcherSpeedSearch mySpeedSearch; + final ClickListener myClickListener = new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { + final Object source = e.getSource(); + if (source instanceof JList) { + JList jList = (JList)source; + if (jList.getSelectedIndex() == -1 && jList.getAnchorSelectionIndex() != -1) { + jList.setSelectedIndex(jList.getAnchorSelectionIndex()); + } + if (jList.getSelectedIndex() != -1) { + navigate(); + } + } + return true; + } + }; @SuppressWarnings({"ManualArrayToCollectionCopy"}) SwitcherPanel(Project project, String title, boolean pinned) { @@ -276,6 +292,7 @@ public class Switcher extends AnAction implements DumbAware { toolWindows.addKeyListener(this); toolWindows.addMouseListener(this); toolWindows.addMouseMotionListener(this); + myClickListener.installOn(toolWindows); toolWindows.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (!toolWindows.isSelectionEmpty() && !files.isSelectionEmpty()) { @@ -416,6 +433,7 @@ public class Switcher extends AnAction implements DumbAware { files.addKeyListener(this); files.addMouseListener(this); files.addMouseMotionListener(this); + myClickListener.installOn(files); this.add(toolWindows, BorderLayout.WEST); if (filesModel.size() > 0) { @@ -763,16 +781,6 @@ public class Switcher extends AnAction implements DumbAware { } public void mouseClicked(MouseEvent e) { - final Object source = e.getSource(); - if (source instanceof JList) { - JList jList = (JList)source; - if (jList.getSelectedIndex() == -1 && jList.getAnchorSelectionIndex() != -1) { - jList.setSelectedIndex(jList.getAnchorSelectionIndex()); - } - if (jList.getSelectedIndex() != -1) { - navigate(); - } - } } private boolean mouseMovedFirstTime = true; diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ToolWindowsGroup.java b/platform/platform-impl/src/com/intellij/ide/actions/ToolWindowsGroup.java index 30b2096d1135..2accb34abb58 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ToolWindowsGroup.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ToolWindowsGroup.java @@ -44,26 +44,26 @@ public final class ToolWindowsGroup extends ActionGroup { static{ ourId2Text = new HashMap(); ourId2Text.put(ToolWindowId.COMMANDER, new MyDescriptor(IdeBundle.message("action.toolwindow.commander"), - AllIcons.General.ToolWindowCommander)); + AllIcons.Toolwindows.ToolWindowCommander)); ourId2Text.put(ToolWindowId.MESSAGES_WINDOW, new MyDescriptor(IdeBundle.message("action.toolwindow.messages"), - AllIcons.General.ToolWindowMessages)); + AllIcons.Toolwindows.ToolWindowMessages)); ourId2Text.put(ToolWindowId.PROJECT_VIEW, new MyDescriptor(IdeBundle.message("action.toolwindow.project"), - AllIcons.General.ToolWindowProject)); + AllIcons.Toolwindows.ToolWindowProject)); ourId2Text.put(ToolWindowId.STRUCTURE_VIEW, new MyDescriptor(IdeBundle.message("action.toolwindow.structure"), - AllIcons.General.ToolWindowStructure)); + AllIcons.Toolwindows.ToolWindowStructure)); ourId2Text.put(ToolWindowId.ANT_BUILD, new MyDescriptor(IdeBundle.message("action.toolwindow.ant.build"), - AllIcons.General.ToolWindowAnt)); - ourId2Text.put(ToolWindowId.DEBUG, new MyDescriptor(IdeBundle.message("action.toolwindow.debug"), AllIcons.General.ToolWindowDebugger)); - ourId2Text.put(ToolWindowId.RUN, new MyDescriptor(IdeBundle.message("action.toolwindow.run"), AllIcons.General.ToolWindowRun)); - ourId2Text.put(ToolWindowId.FIND, new MyDescriptor(IdeBundle.message("action.toolwindow.find"), AllIcons.General.ToolWindowFind)); - ourId2Text.put(ToolWindowId.CVS, new MyDescriptor(IdeBundle.message("action.toolwindow.cvs"), AllIcons.General.ToolWindowCvs)); + AllIcons.Toolwindows.ToolWindowAnt)); + ourId2Text.put(ToolWindowId.DEBUG, new MyDescriptor(IdeBundle.message("action.toolwindow.debug"), AllIcons.Toolwindows.ToolWindowDebugger)); + ourId2Text.put(ToolWindowId.RUN, new MyDescriptor(IdeBundle.message("action.toolwindow.run"), AllIcons.Toolwindows.ToolWindowRun)); + ourId2Text.put(ToolWindowId.FIND, new MyDescriptor(IdeBundle.message("action.toolwindow.find"), AllIcons.Toolwindows.ToolWindowFind)); + ourId2Text.put(ToolWindowId.CVS, new MyDescriptor(IdeBundle.message("action.toolwindow.cvs"), AllIcons.Toolwindows.ToolWindowCvs)); ourId2Text.put(ToolWindowId.HIERARCHY, new MyDescriptor(IdeBundle.message("action.toolwindow.hierarchy"), - AllIcons.General.ToolWindowHierarchy)); - ourId2Text.put(ToolWindowId.TODO_VIEW, new MyDescriptor(IdeBundle.message("action.toolwindow.todo"), AllIcons.General.ToolWindowTodo)); + AllIcons.Toolwindows.ToolWindowHierarchy)); + ourId2Text.put(ToolWindowId.TODO_VIEW, new MyDescriptor(IdeBundle.message("action.toolwindow.todo"), AllIcons.Toolwindows.ToolWindowTodo)); ourId2Text.put(ToolWindowId.INSPECTION, new MyDescriptor(IdeBundle.message("action.toolwindow.inspection"), - AllIcons.General.ToolWindowInspection)); + AllIcons.Toolwindows.ToolWindowInspection)); ourId2Text.put(ToolWindowId.FAVORITES_VIEW, new MyDescriptor(IdeBundle.message("action.toolwindow.favorites"), - AllIcons.General.ToolWindowFavorites)); + AllIcons.Toolwindows.ToolWindowFavorites)); } private final ArrayList myChildren; diff --git a/platform/platform-impl/src/com/intellij/ide/errorTreeView/NewErrorTreeRenderer.java b/platform/platform-impl/src/com/intellij/ide/errorTreeView/NewErrorTreeRenderer.java index ffe59e9c2530..326cb5fa2142 100644 --- a/platform/platform-impl/src/com/intellij/ide/errorTreeView/NewErrorTreeRenderer.java +++ b/platform/platform-impl/src/com/intellij/ide/errorTreeView/NewErrorTreeRenderer.java @@ -50,7 +50,7 @@ public class NewErrorTreeRenderer extends MultilineTreeCellRenderer { public static JScrollPane install(JTree tree) { final NewErrorTreeRenderer renderer = new NewErrorTreeRenderer(); //new TreeLinkMouseListener(renderer.myColoredTreeCellRenderer).install(tree); - new TreeNodePartListener(renderer.myRightCellRenderer).install(tree); + new TreeNodePartListener(renderer.myRightCellRenderer).installOn(tree); return MultilineTreeCellRenderer.installRenderer(tree, renderer); } diff --git a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java index 5cc6a593a1bb..3db1a134f95a 100644 --- a/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java +++ b/platform/platform-impl/src/com/intellij/ide/highlighter/custom/impl/CustomFileTypeEditor.java @@ -32,7 +32,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.event.DocumentEvent; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** @@ -196,11 +195,13 @@ public class CustomFileTypeEditor extends SettingsEditor { for (int i = 0; i < myKeywordsLists.length; i++) { final int idx = i; - myKeywordsLists[i].addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) edit(idx); + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + edit(idx); + return true; } - }); + }.installOn(myKeywordsLists[i]); } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java index 2839e4a1b750..74cf3a8716f6 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/AvailablePluginsManagerMain.java @@ -22,6 +22,7 @@ import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.updateSettings.impl.UpdateSettings; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ScrollPaneFactory; import com.intellij.util.net.HTTPProxySettingsDialog; import com.intellij.util.ui.update.UiNotifyConnector; @@ -31,7 +32,6 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.TreeSet; @@ -94,11 +94,11 @@ public class AvailablePluginsManagerMain extends PluginManagerMain { @Override protected void installTableActions(final PluginTable pluginTable) { super.installTableActions(pluginTable); - pluginTable.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() != 2) return; - if (pluginTable.columnAtPoint(e.getPoint()) < 0) return; - if (pluginTable.rowAtPoint(e.getPoint()) < 0) return; + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + if (pluginTable.columnAtPoint(e.getPoint()) < 0) return false; + if (pluginTable.rowAtPoint(e.getPoint()) < 0) return false; IdeaPluginDescriptor[] selection = pluginTable.getSelectedObjects(); if (selection != null) { boolean enabled = true; @@ -117,9 +117,11 @@ public class AvailablePluginsManagerMain extends PluginManagerMain { if (enabled) { new ActionInstallPlugin(AvailablePluginsManagerMain.this, installed).install(); } + return true; } + return false; } - }); + }.installOn(pluginTable); } @Override diff --git a/platform/platform-impl/src/com/intellij/ide/startupWizard/SelectPluginsStep.java b/platform/platform-impl/src/com/intellij/ide/startupWizard/SelectPluginsStep.java index 855ea2e02e47..19cd1bad7604 100644 --- a/platform/platform-impl/src/com/intellij/ide/startupWizard/SelectPluginsStep.java +++ b/platform/platform-impl/src/com/intellij/ide/startupWizard/SelectPluginsStep.java @@ -18,6 +18,7 @@ package com.intellij.ide.startupWizard; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.ClickListener; import com.intellij.ui.CollectionListModel; import com.intellij.ui.wizard.WizardNavigationState; import com.intellij.ui.wizard.WizardStep; @@ -93,15 +94,16 @@ public class SelectPluginsStep extends WizardStep { }); final int clickableArea = new JCheckBox("").getMinimumSize().width; - myPluginsList.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(final MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { if (e.getX() < clickableArea) { toggleSelection(); } - e.consume(); + return true; } - }); + }.installOn(myPluginsList); + myPluginsList.addKeyListener(new KeyAdapter() { public void keyTyped(final KeyEvent e) { if (e.getKeyChar() == ' ') { diff --git a/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java b/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java index 06a5c624aa37..20571691f2d9 100644 --- a/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java +++ b/platform/platform-impl/src/com/intellij/ide/util/ChooseElementsDialog.java @@ -17,13 +17,17 @@ package com.intellij.ide.util; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ScrollPaneFactory; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.util.*; import java.util.List; @@ -77,14 +81,15 @@ public abstract class ChooseElementsDialog extends DialogWrapper { doOKAction(); } }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED); - myChooser.getComponent().addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2 && !e.isPopupTrigger() && !e.isConsumed()) { - e.consume(); - doOKAction(); - } + + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + doOKAction(); + return true; } - }); + }.installOn(myChooser.getComponent()); + init(); } diff --git a/platform/platform-impl/src/com/intellij/idea/LoggerFactory.java b/platform/platform-impl/src/com/intellij/idea/LoggerFactory.java index 11d6a1843479..d7a8cc8ce70d 100644 --- a/platform/platform-impl/src/com/intellij/idea/LoggerFactory.java +++ b/platform/platform-impl/src/com/intellij/idea/LoggerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -25,53 +25,42 @@ import org.apache.log4j.xml.DOMConfigurator; import java.io.File; import java.io.StringReader; -@SuppressWarnings({"HardCodedStringLiteral"}) +@SuppressWarnings({"CallToPrintStackTrace", "UseOfSystemOutOrSystemErr"}) public class LoggerFactory implements Logger.Factory { private static final String SYSTEM_MACRO = "$SYSTEM_DIR$"; private static final String APPLICATION_MACRO = "$APPLICATION_DIR$"; - private static final String COMMENT_LINE_FOR_TEST_MODE_MACRO = "$COMMENT_LINE_FOR_TEST_MODE$"; - private static final String LOGDIR_MACRO = "$LOG_DIR$"; + private static final String LOG_DIR_MACRO = "$LOG_DIR$"; private boolean myInitialized = false; private static final LoggerFactory ourInstance = new LoggerFactory(); - public static final String LOG_DIR = "log"; public static LoggerFactory getInstance() { return ourInstance; } - private LoggerFactory() { - } + private LoggerFactory() { } - public Logger getLoggerInstance(String name) { - synchronized (this) { - try { - if (!isInitialized()) { - init(); - } + @Override + public synchronized Logger getLoggerInstance(String name) { + try { + if (!myInitialized) { + init(); } - catch (Exception e) { - e.printStackTrace(); - } - - return new IdeaLogger(org.apache.log4j.Logger.getLogger(name)); } + catch (Exception e) { + e.printStackTrace(); + } + + return new IdeaLogger(org.apache.log4j.Logger.getLogger(name)); } private void init() { try { - /* - //debug code. Don't delete. - ClassLoader classLoader = Logger.class.getClassLoader(); - if (!(classLoader.getClass().getName().startsWith("com.intellij"))) { - System.err.println("Logger shouldn't be used outside the PluginManager"); - Thread.dumpStack(); - } - */ - System.setProperty("log4j.defaultInitOverride", "true"); - File logXmlFile = FileUtil.findFirstThatExist(PathManager.getHomePath() + "/bin/log.xml", PathManager.getHomePath() + "/community/bin/log.xml"); + + File logXmlFile = FileUtil.findFirstThatExist(PathManager.getHomePath() + "/bin/log.xml", + PathManager.getHomePath() + "/community/bin/log.xml"); if (logXmlFile == null) { throw new RuntimeException("log.xml file does not exist! Path: [ $home/bin/log.xml]"); } @@ -79,14 +68,12 @@ public class LoggerFactory implements Logger.Factory { String text = FileUtil.loadFile(logXmlFile); text = StringUtil.replace(text, SYSTEM_MACRO, StringUtil.replace(PathManager.getSystemPath(), "\\", "\\\\")); text = StringUtil.replace(text, APPLICATION_MACRO, StringUtil.replace(PathManager.getHomePath(), "\\", "\\\\")); - text = StringUtil.replace(text, LOGDIR_MACRO, StringUtil.replace(PathManager.getLogPath(), "\\", "\\\\")); - - if ("true".equals(System.getProperty("idea.test.test_mode"))) { - text = commentTestModeLines(text); - } + text = StringUtil.replace(text, LOG_DIR_MACRO, StringUtil.replace(PathManager.getLogPath(), "\\", "\\\\")); File file = new File(PathManager.getLogPath()); - file.mkdirs(); + if (!file.mkdirs() && !file.exists()) { + System.err.println("Cannot create log directory: " + file); + } new DOMConfigurator().doConfigure(new StringReader(text), LogManager.getLoggerRepository()); @@ -96,34 +83,4 @@ public class LoggerFactory implements Logger.Factory { e.printStackTrace(); } } - - private boolean isInitialized() { - return myInitialized; - } - - private static String commentTestModeLines(String text) { - String result = text; - int index = text.indexOf(COMMENT_LINE_FOR_TEST_MODE_MACRO); - if (index != -1) { - String str1 = result.substring(0, index); - String str2 = result.substring(index); - int firstLineChar = Math.max(str1.lastIndexOf('\n'), str1.lastIndexOf('\r')); - int lastLineChar = str2.indexOf('\n'); - int lastLineChar2 = str2.indexOf('\r'); - if (lastLineChar == -1) { - lastLineChar = lastLineChar2; - } - else if (lastLineChar2 != -1) { - lastLineChar = Math.min(lastLineChar, lastLineChar2); - } - if (firstLineChar != -1) { - str1 = str1.substring(0, firstLineChar); - } - if (lastLineChar != -1) { - str2 = str2.substring(lastLineChar); - } - result = commentTestModeLines(str1) + commentTestModeLines(str2); - } - return result; - } } diff --git a/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java b/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java index b27a66ad9683..d4ca57e26ab5 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java @@ -30,6 +30,7 @@ import com.intellij.openapi.wm.CustomStatusBarWidget; import com.intellij.openapi.wm.IconLikeCustomStatusBarWidget; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.ToolWindow; +import com.intellij.ui.ClickListener; import com.intellij.ui.LayeredIcon; import com.intellij.util.Alarm; import org.jetbrains.annotations.NotNull; @@ -37,7 +38,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; @@ -63,12 +63,13 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget updateStatus(); } }, this); - addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { EventLog.toggleLog(getProject()); + return true; } - }); + }.installOn(this); } public WidgetPresentation getPresentation(@NotNull PlatformType type) { diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java index 45e932f8399f..e8d503e2f35d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java @@ -55,7 +55,7 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern @NonNls private String myIconUrl = "/icon.png"; @NonNls private String mySmallIconUrl = "/icon_small.png"; @NonNls private String myOpaqueIconUrl = "/icon.png"; - @NonNls private String myToolWindowIconUrl = "/general/toolWindowProject.png"; + @NonNls private String myToolWindowIconUrl = "/toolwindows/toolWindowProject.png"; private Calendar myBuildDate = null; private Calendar myMajorReleaseBuildDate = null; private String myPackageCode = null; diff --git a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java index 3339ea90dadd..82741248cd9a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/command/impl/UndoManagerImpl.java @@ -252,12 +252,42 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap if (myCommandLevel == 0) return; // possible if command listener was added within command myCommandLevel--; if (myCommandLevel > 0) return; + + if (myProject != null && myCurrentMerger.hasActions() && !myCurrentMerger.isGlobal()) { + addFocusedDocumentAsAffected(); + } + myCurrentMerger.setAfterState(getCurrentState()); myMerger.commandFinished(commandName, groupId, myCurrentMerger); disposeCurrentMerger(); } + private void addFocusedDocumentAsAffected() { + VirtualFile[] selected = FileEditorManager.getInstance(myProject).getSelectedFiles(); + if (selected.length == 0) return; + + final DocumentReference[] refs = new DocumentReference[selected.length]; + for (int i = 0; i < refs.length; i++) { + refs[i] = DocumentReferenceManager.getInstance().create(selected[i]); + } + + myCurrentMerger.addAction(new BasicUndoableAction() { + @Override + public void undo() throws UnexpectedUndoException { + } + + @Override + public void redo() throws UnexpectedUndoException { + } + + @Override + public DocumentReference[] getAffectedDocuments() { + return refs; + } + }); + } + private EditorAndState getCurrentState() { FileEditor editor = myEditorProvider.getCurrentEditor(); if (editor == null) { @@ -598,7 +628,8 @@ public class UndoManagerImpl extends UndoManager implements ProjectComponent, Ap @TestOnly private void flushMergers() { // Run dummy command in order to flush all mergers... - CommandProcessor.getInstance().executeCommand(myProject, EmptyRunnable.getInstance(), CommonBundle.message("drop.undo.history.command.name"), null); + CommandProcessor.getInstance() + .executeCommand(myProject, EmptyRunnable.getInstance(), CommonBundle.message("drop.undo.history.command.name"), null); } @TestOnly diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ContentChooser.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ContentChooser.java index e35933882842..5263675a652a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ContentChooser.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ContentChooser.java @@ -24,10 +24,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.ui.ColoredListCellRenderer; -import com.intellij.ui.ListSpeedSearch; -import com.intellij.ui.ScrollPaneFactory; -import com.intellij.ui.SimpleTextAttributes; +import com.intellij.ui.*; import com.intellij.ui.components.JBList; import com.intellij.util.ArrayUtil; import com.intellij.util.ui.UIUtil; @@ -39,7 +36,6 @@ import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; @@ -88,13 +84,14 @@ public abstract class ContentChooser extends DialogWrapper { rebuildListContent(); - myList.addMouseListener(new MouseAdapter() { + new DoubleClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (e.isConsumed() || e.getClickCount() != 2 || e.isPopupTrigger()) return; + protected boolean onDoubleClick(MouseEvent e) { close(OK_EXIT_CODE); + return true; } - }); + }.installOn(myList); + myList.setCellRenderer(new MyListCellRenderer()); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java index 0de270d5b88f..bdb5f494c900 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSystemTreeImpl.java @@ -42,10 +42,7 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; import com.intellij.openapi.vfs.newvfs.RefreshQueue; -import com.intellij.ui.PopupHandler; -import com.intellij.ui.SimpleTextAttributes; -import com.intellij.ui.TreeSpeedSearch; -import com.intellij.ui.UIBundle; +import com.intellij.ui.*; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Function; import com.intellij.util.NullableFunction; @@ -60,7 +57,10 @@ import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.*; -import java.awt.event.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.io.IOException; import java.util.*; @@ -174,11 +174,14 @@ public class FileSystemTreeImpl implements FileSystemTree { } }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), JComponent.WHEN_FOCUSED ); - myTree.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) performEnterAction(false); + + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + performEnterAction(false); + return true; } - }); + }.installOn(myTree); } private void performEnterAction(boolean toggleNodeState) { diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java index 1dee7280761a..e0e79bc86566 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/ex/FileTypeChooser.java @@ -27,6 +27,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiManager; import com.intellij.psi.impl.PsiManagerEx; import com.intellij.ui.CollectionComboBoxModel; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.ListScrollingUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.Function; @@ -37,7 +38,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Arrays; import java.util.Comparator; @@ -93,16 +93,13 @@ public class FileTypeChooser extends DialogWrapper { myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); myList.setCellRenderer(new FileTypeRenderer(myList.getCellRenderer())); - myList.addMouseListener( - new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2){ - doOKAction(); - } - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + doOKAction(); + return true; } - ); + }.installOn(myList); myList.getSelectionModel().addListSelectionListener( new ListSelectionListener() { diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ChooseActionsDialog.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ChooseActionsDialog.java index c4e09d743376..8ea329e1b7b3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ChooseActionsDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ChooseActionsDialog.java @@ -31,6 +31,7 @@ import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.packageDependencies.ui.TreeExpansionMonitor; import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.FilterComponent; import com.intellij.util.Alarm; import com.intellij.util.ArrayUtil; @@ -48,7 +49,6 @@ import javax.swing.tree.TreeSelectionModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; @@ -68,14 +68,15 @@ public class ChooseActionsDialog extends DialogWrapper { myActionsTree = new ActionsTree(); myActionsTree.reset(keymap, quicklists); myActionsTree.getTree().getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); - myActionsTree.getTree().addMouseListener(new MouseAdapter() { + + new DoubleClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - doOKAction(); - } + protected boolean onDoubleClick(MouseEvent e) { + doOKAction(); + return true; } - }); + }.installOn(myActionsTree.getTree()); + myTreeExpansionMonitor = TreeExpansionMonitor.install(myActionsTree.getTree()); diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java index f1b1ab61c36a..bf7967e27bc7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/KeymapPanel.java @@ -22,7 +22,6 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.CommonActionsManager; import com.intellij.ide.DataManager; import com.intellij.ide.TreeExpander; -import com.intellij.ui.ListCellRendererWrapper; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.actionSystem.ex.QuickListsManager; @@ -47,7 +46,9 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.packageDependencies.ui.TreeExpansionMonitor; import com.intellij.ui.DocumentAdapter; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.FilterComponent; +import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.Alarm; import com.intellij.util.IJSwingUtilities; @@ -328,15 +329,17 @@ public class KeymapPanel extends JPanel implements SearchableConfigurable, Confi myTreeExpansionMonitor = TreeExpansionMonitor.install(myActionsTree.getTree()); - myActionsTree.getTree().addMouseListener(new MouseAdapter() { + new DoubleClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2 || e.isPopupTrigger()) { - editSelection(e); - e.consume(); - } + protected boolean onDoubleClick(MouseEvent e) { + editSelection(e); + return true; } + }.installOn(myActionsTree.getTree()); + + + myActionsTree.getTree().addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (e.isPopupTrigger()) { diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java index eb063f5ddf89..9b973820ff41 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/QuickListPanel.java @@ -19,7 +19,6 @@ import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.Separator; import com.intellij.openapi.actionSystem.ex.QuickList; import com.intellij.openapi.actionSystem.ex.QuickListsManager; import com.intellij.openapi.keymap.KeyMapBundle; @@ -27,19 +26,12 @@ import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.project.Project; import com.intellij.ui.*; import com.intellij.ui.components.JBList; -import com.intellij.util.ui.EmptyIcon; -import com.intellij.util.ui.UIUtil; -import org.jetbrains.annotations.NotNull; import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class QuickListPanel { - private static final Icon EMPTY_ICON = EmptyIcon.ICON_18; - private static final Icon QUICK_LIST_ICON = AllIcons.Actions.QuickList; private JPanel myPanel; private JBList myActionsList; @@ -56,13 +48,13 @@ public class QuickListPanel { myActionsList.getEmptyText().setText(KeyMapBundle.message("no.actions")); myActionsList.setEnabled(!QuickListsManager.getInstance().getSchemesManager().isShared(origin)); - myActionsList.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2 && !e.isPopupTrigger()) { - excludeSelectionAction(); - } + new DoubleClickListener() { + @Override + protected boolean onDoubleClick(MouseEvent e) { + excludeSelectionAction(); + return true; } - }); + }.installOn(myActionsList); myListPanel.add( ToolbarDecorator.createDecorator(myActionsList) @@ -154,75 +146,6 @@ public class QuickListPanel { return myPanel; } - private class MyTreeCellRenderer extends JBDefaultTreeCellRenderer { - private MyTreeCellRenderer(@NotNull JTree tree) { - super(tree); - } - - public Component getTreeCellRendererComponent(JTree tree, - Object value, - boolean sel, - boolean expanded, - boolean leaf, - int row, - boolean hasFocus) { - super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); - Icon icon = null; - if (value instanceof DefaultMutableTreeNode) { - boolean used = false; - Object userObject = ((DefaultMutableTreeNode)value).getUserObject(); - if (userObject instanceof Group) { - Group group = (Group)userObject; - final String name = group.getName(); - setText(name != null ? name : group.getId()); - icon = expanded ? group.getOpenIcon() : group.getIcon(); - - if (icon == null) { - icon = expanded ? getOpenIcon() : getClosedIcon(); - } - } - else if (userObject instanceof String) { - String actionId = (String)userObject; - used = ((DefaultListModel)myActionsList.getModel()).lastIndexOf(actionId) >= 0; - AnAction action = ActionManager.getInstance().getAction(actionId); - String text = action == null ? actionId : action.getTemplatePresentation().getText(); - if (text == null || text.length() == 0) text = actionId; - setText(text); - if (action != null) { - Icon actionIcon = action.getTemplatePresentation().getIcon(); - if (actionIcon != null) { - icon = actionIcon; - } - } - } - else if (userObject instanceof QuickList) { - QuickList list = (QuickList)userObject; - icon = QUICK_LIST_ICON; - setText(list.getDisplayName()); - used = ((DefaultListModel)myActionsList.getModel()).lastIndexOf(list.getActionId()) >= 0; - } - else if (userObject instanceof Separator) { - // TODO[vova,anton]: beautify - setText("-------------"); - } - else { - throw new IllegalArgumentException("unknown userObject: " + userObject); - } - - setIcon(ActionsTree.getEvenIcon(icon)); - - if (sel) { - setForeground(getSelectionForeground(tree)); - } - else { - Color foreground = used ? UIUtil.getInactiveTextColor() : UIUtil.getTreeForeground(); - setForeground(foreground); - } - } - return this; - } - } - private static class MyListCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, diff --git a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java index 23c09509fe06..595b5d2dd84b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/vcs/changes/issueLinks/LinkMouseListenerBase.java @@ -15,23 +15,25 @@ */ package com.intellij.openapi.vcs.changes.issueLinks; +import com.intellij.ui.ClickListener; import org.jetbrains.annotations.Nullable; -import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; -public abstract class LinkMouseListenerBase extends MouseAdapter implements MouseMotionListener { +public abstract class LinkMouseListenerBase extends ClickListener implements MouseMotionListener { @Nullable protected abstract Object getTagAt(final MouseEvent e); - public void mouseClicked(final MouseEvent e) { - if (!e.isPopupTrigger() && e.getButton() == 1) { + @Override + public boolean onClick(MouseEvent e, int clickCount) { + if (e.getButton() == 1) { Object tag = getTagAt(e); handleTagClick(tag, e); + return true; } + return false; } protected void handleTagClick(final Object tag, MouseEvent event) { @@ -54,8 +56,8 @@ public abstract class LinkMouseListenerBase extends MouseAdapter implements Mous } } - public void install(final JComponent tree) { - tree.addMouseListener(this); + public void installOn(Component tree) { + super.installOn(tree); tree.addMouseMotionListener(this); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java index 5b9eda3ce0bf..139541d85171 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java @@ -57,6 +57,9 @@ public class FileWatcher { @NonNls private static final String EXIT_COMMAND = "EXIT"; @NonNls private static final String MESSAGE_COMMAND = "MESSAGE"; + private static final int MAX_PROCESS_LAUNCH_ATTEMPT_COUNT = 10; + private static final int MAGIC_PROCESS_LAUNCH_ATTEMPT_COUNT = 88 * MAX_PROCESS_LAUNCH_ATTEMPT_COUNT; + private final Object LOCK = new Object(); private List myDirtyPaths = new ArrayList(); @@ -78,7 +81,6 @@ public class FileWatcher { private volatile BufferedWriter notifierWriter; private boolean myFailureShownToTheUser = false; private int attemptCount = 0; - private static final int MAX_PROCESS_LAUNCH_ATTEMPT_COUNT = 10; private boolean isShuttingDown = false; private final ManagingFS myManagingFS; @@ -323,7 +325,7 @@ public class FileWatcher { myFailureShownToTheUser = true; attemptCount = 0; startupProcess(false); - attemptCount = 2 * MAX_PROCESS_LAUNCH_ATTEMPT_COUNT; + attemptCount = MAGIC_PROCESS_LAUNCH_ATTEMPT_COUNT; if (notifierProcess != null) { new WatchForChangesThread().start(); } @@ -368,6 +370,11 @@ public class FileWatcher { final String command = readLine(); if (command == null) { + if (attemptCount == MAGIC_PROCESS_LAUNCH_ATTEMPT_COUNT) { + LOG.debug("Leaving watcher thread"); + return; + } + // Unexpected process exit, relaunch attempt startupProcess(true); continue; @@ -466,7 +473,7 @@ public class FileWatcher { private void writeLine(String line) throws IOException { if (LOG.isDebugEnabled()) { - LOG.debug("to fsnotifier: " + line); + LOG.debug("<< " + line); } final Process process = notifierProcess; @@ -502,7 +509,7 @@ public class FileWatcher { final String line = reader.readLine(); if (LOG.isDebugEnabled()) { - LOG.debug("fsnotifier says: " + line); + LOG.debug(">> " + line); } return line; } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java index 7c1eb96e1263..f987be6f184a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemImpl.java @@ -40,6 +40,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.*; @@ -55,14 +56,17 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap private String myFSRootPath; private boolean myDominated; - public WatchRequestImpl(String rootPath, final boolean toWatchRecursively) { + public WatchRequestImpl(String rootPath, final boolean toWatchRecursively) throws FileNotFoundException { final int index = rootPath.indexOf(JarFileSystem.JAR_SEPARATOR); if (index >= 0) rootPath = rootPath.substring(0, index); File rootFile = new File(FileUtil.toSystemDependentName(rootPath)); if (index > 0 || !rootFile.isDirectory()) { - rootFile = rootFile.getParentFile(); - assert rootFile != null : rootPath; + final File parentFile = rootFile.getParentFile(); + if (parentFile == null) { + throw new FileNotFoundException(rootPath); + } + rootFile = parentFile; } myFSRootPath = rootFile.getAbsolutePath(); @@ -437,7 +441,8 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap boolean update = false; for (String root : recursiveRoots) { - final WatchRequestImpl request = new WatchRequestImpl(root, true); + final WatchRequestImpl request = watch(root, true); + if (request == null) continue; final boolean alreadyWatched = isAlreadyWatched(request); request.myDominated = alreadyWatched; @@ -448,7 +453,8 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap } for (String root : flatRoots) { - final WatchRequestImpl request = new WatchRequestImpl(root, false); + final WatchRequestImpl request = watch(root, false); + if (request == null) continue; final boolean alreadyWatched = isAlreadyWatched(request); if (!alreadyWatched) { @@ -468,6 +474,17 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap return update; } + @Nullable + private static WatchRequestImpl watch(final String root, final boolean recursively) { + try { + return new WatchRequestImpl(root, recursively); + } + catch (FileNotFoundException e) { + LOG.warn(e); + return null; + } + } + private void syncFiles(@NotNull final Set filesToSync) { if (filesToSync.isEmpty() || ApplicationManager.getApplication().isUnitTestMode()) return; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java index 1e6483398117..e08ab5b4892c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java @@ -218,41 +218,37 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile { } } - protected int getPathLength() { - Object o = rawName(); - int length = o instanceof String ? ((String)o).length() : ((byte[]) o).length; - length += getEncodedSuffix().length(); - return myParent == null ? length : myParent.getPathLength() + length + 1; - } + protected char[] appendPathOnFileSystem(int pathLength, int[] position) { + final Object o = rawName(); + final String suffix = getEncodedSuffix(); + final int nameLength = (o instanceof String ? ((String)o).length() : ((byte[]) o).length) + suffix.length(); - protected int appendPathOnFileSystem(@NotNull char[] chars, int pos) { + final char[] chars; if (myParent != null) { - pos = myParent.appendPathOnFileSystem(chars, pos); - } - - Object o = rawName(); - String suffix = getEncodedSuffix(); - //noinspection StringEquality - if (o == EMPTY && suffix == EMPTY) { - return pos; - } - - if (pos > 0 && chars[pos - 1] != '/') { - chars[pos++] = '/'; + chars = myParent.appendPathOnFileSystem(pathLength + 1 + nameLength, position); + if (position[0] > 0 && chars[position[0] - 1] != '/') { + chars[position[0]++] = '/'; + } + } else { + chars = new char[pathLength + nameLength]; } if (o instanceof String) { - pos = copyString(chars, pos, (String)o); - return copyString(chars, pos, suffix); + position[0] = copyString(chars, position[0], (String)o); + } else { + byte[] bytes = (byte[]) o; + int pos = position[0]; + //noinspection ForLoopReplaceableByForEach + for (int i = 0, len = bytes.length; i < len; i++) { + chars[pos++] = (char)bytes[i]; + } + position[0] = pos; } - byte[] bytes = (byte[]) o; - //noinspection ForLoopReplaceableByForEach - for (int i = 0, len = bytes.length; i < len; i++) { - chars[pos++] = (char)bytes[i]; - } - return copyString(chars, pos, suffix); + position[0] = copyString(chars, position[0], suffix); + return chars; } + private static int copyString(@NotNull char[] chars, int pos, @NotNull String s) { int length = s.length(); s.getChars(0, length, chars, pos); @@ -263,23 +259,19 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile { @NotNull public String getUrl() { String protocol = getFileSystem().getProtocol(); - char[] chars = new char[getPathLength() + protocol.length() + "://".length()]; - int pos = copyString(chars, 0, protocol); - pos = copyString(chars, pos, "://"); - - return getPathImpl(chars, pos); + int prefixLen = protocol.length() + "://".length(); + int[] pos = {prefixLen}; + char[] chars = appendPathOnFileSystem(prefixLen, pos); + copyString(chars, copyString(chars, 0, protocol), "://"); + return new String(chars, 0, pos[0]); } @Override @NotNull public String getPath() { - char[] chars = new char[getPathLength()]; - return getPathImpl(chars, 0); - } - - private String getPathImpl(@NotNull char[] chars, int pos) { - int count = appendPathOnFileSystem(chars, pos); - return new String(chars, 0, count); + int[] pos = {0}; + char[] chars = appendPathOnFileSystem(0, pos); + return new String(chars, 0, pos[0]); } @Override diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index 35c0315ed446..5e29cb4ae0e1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -30,6 +30,9 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; +import com.intellij.util.concurrency.JBLock; +import com.intellij.util.concurrency.JBReentrantReadWriteLock; +import com.intellij.util.concurrency.LockFactory; import com.intellij.util.containers.IntArrayList; import com.intellij.util.io.PagedFileStorage; import com.intellij.util.io.PersistentStringEnumerator; @@ -88,7 +91,9 @@ public class FSRecords implements Forceable { private static final int CORRUPTED_MAGIC = 0xabcf7f7f; private static final String CHILDREN_ATT = "FsRecords.DIRECTORY_CHILDREN"; - private static final Object lock = new Object(); + + private static final JBLock r; + private static final JBLock w; private static volatile int ourLocalModificationCount = 0; private static volatile boolean ourIsDisposed; @@ -99,6 +104,10 @@ public class FSRecords implements Forceable { static { //noinspection ConstantConditions assert HEADER_SIZE <= RECORD_SIZE; + + JBReentrantReadWriteLock lock = LockFactory.createReadWriteLock(); + r = lock.readLock(); + w = lock.writeLock(); } private static class DbConnection { @@ -116,7 +125,8 @@ public class FSRecords implements Forceable { private static boolean myCorrupted = false; public static void connect() { - synchronized (lock) { + try { + w.lock(); if (!ourInitialized) { init(); scanFreeRecords(); @@ -124,6 +134,9 @@ public class FSRecords implements Forceable { ourInitialized = true; } } + finally { + w.unlock(); + } } private static void scanFreeRecords() { @@ -337,7 +350,8 @@ public class FSRecords implements Forceable { } public static void force() { - synchronized (lock) { + try { + w.lock(); if (myRecords != null) { markClean(); } @@ -348,12 +362,16 @@ public class FSRecords implements Forceable { myRecords.force(); } } + finally { + w.unlock(); + } } public static void flushSome() { if (!isDirty() || HeavyProcessLatch.INSTANCE.isRunning()) return; - synchronized (lock) { + try { + w.lock(); if (myFlushingFuture == null) { return; // avoid NPE when close has already taken place } @@ -366,6 +384,9 @@ public class FSRecords implements Forceable { myRecords.force(); } } + finally { + w.unlock(); + } } public static boolean isDirty() { @@ -477,9 +498,13 @@ public class FSRecords implements Forceable { } public static long getCreationTimestamp() { - synchronized (lock) { + try { + r.lock(); return DbConnection.getTimestamp(); } + finally { + r.unlock(); + } } private static ResizeableMappedFile getRecords() { @@ -499,39 +524,43 @@ public class FSRecords implements Forceable { } public static int createRecord() { - synchronized (lock) { - try { - DbConnection.markDirty(); + try { + w.lock(); + DbConnection.markDirty(); - final int free = DbConnection.getFreeRecord(); - if (free == 0) { - final int filelength = (int)getRecords().length(); - LOG.assertTrue(filelength % RECORD_SIZE == 0); - int newrecord = filelength / RECORD_SIZE; - DbConnection.cleanRecord(newrecord); - assert filelength + RECORD_SIZE == getRecords().length(); - return newrecord; - } - else { - DbConnection.cleanRecord(free); - return free; - } + final int free = DbConnection.getFreeRecord(); + if (free == 0) { + final int filelength = (int)getRecords().length(); + LOG.assertTrue(filelength % RECORD_SIZE == 0); + int newrecord = filelength / RECORD_SIZE; + DbConnection.cleanRecord(newrecord); + assert filelength + RECORD_SIZE == getRecords().length(); + return newrecord; } - catch (Throwable e) { - throw DbConnection.handleError(e); + else { + DbConnection.cleanRecord(free); + return free; } } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + w.unlock(); + } } public static void deleteRecordRecursively(int id) { - synchronized (lock) { - try { - incModCount(id); - doDeleteRecursively(id); - } - catch (Throwable e) { - throw DbConnection.handleError(e); - } + try { + w.lock(); + incModCount(id); + doDeleteRecursively(id); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + w.unlock(); } } @@ -544,17 +573,19 @@ public class FSRecords implements Forceable { } private static void deleteRecord(final int id) { - synchronized (lock) { - try { - DbConnection.markDirty(); - deleteContentAndAttributes(id); + try { + w.lock(); + DbConnection.markDirty(); + deleteContentAndAttributes(id); - DbConnection.cleanRecord(id); - addToFreeRecordsList(id); - } - catch (Throwable e) { - throw DbConnection.handleError(e); - } + DbConnection.cleanRecord(id); + addToFreeRecordsList(id); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + w.unlock(); } } @@ -583,8 +614,8 @@ public class FSRecords implements Forceable { } public static int[] listRoots() throws IOException { - synchronized (lock) { - DbConnection.markDirty(); + try { + r.lock(); final DataInputStream input = readAttribute(1, CHILDREN_ATT); if (input == null) return ArrayUtil.EMPTY_INT_ARRAY; @@ -596,12 +627,14 @@ public class FSRecords implements Forceable { input.readInt(); // Name result[i] = input.readInt(); // Id } + return result; } finally { input.close(); } - - return result; + } + finally { + r.unlock(); } } @@ -616,7 +649,8 @@ public class FSRecords implements Forceable { } public static int findRootRecord(String rootUrl) throws IOException { - synchronized (lock) { + try { + w.lock(); DbConnection.markDirty(); final int root = getNames().enumerate(rootUrl); @@ -663,10 +697,14 @@ public class FSRecords implements Forceable { return id; } + finally { + w.unlock(); + } } public static void deleteRootRecord(int id) throws IOException { - synchronized (lock) { + try { + w.lock(); DbConnection.markDirty(); final DataInputStream input = readAttribute(1, CHILDREN_ATT); assert input != null; @@ -705,80 +743,92 @@ public class FSRecords implements Forceable { output.close(); } } + finally { + w.unlock(); + } } public static int[] list(int id) { - synchronized (lock) { - try { - final DataInputStream input = readAttribute(id, CHILDREN_ATT); - if (input == null) return ArrayUtil.EMPTY_INT_ARRAY; + try { + r.lock(); + final DataInputStream input = readAttribute(id, CHILDREN_ATT); + if (input == null) return ArrayUtil.EMPTY_INT_ARRAY; - final int count = input.readInt(); - final int[] result = ArrayUtil.newIntArray(count); - for (int i = 0; i < count; i++) { - result[i] = input.readInt(); - } - input.close(); - return result; - } - catch (Throwable e) { - throw DbConnection.handleError(e); + final int count = input.readInt(); + final int[] result = ArrayUtil.newIntArray(count); + for (int i = 0; i < count; i++) { + result[i] = input.readInt(); } + input.close(); + return result; + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + r.unlock(); } } - public static Pair listAll(int parentId) { - synchronized (lock) { - try { - final DataInputStream input = readAttribute(parentId, CHILDREN_ATT); - if (input == null) return Pair.create(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_INT_ARRAY); - final int count = input.readInt(); - final int[] ids = ArrayUtil.newIntArray(count); - final String[] names = ArrayUtil.newStringArray(count); - for (int i = 0; i < count; i++) { - int id = input.readInt(); - ids[i] = id; - names[i] = getName(id); - } - input.close(); - return Pair.create(names, ids); - } - catch (Throwable e) { - throw DbConnection.handleError(e); + public static Pair listAll(int parentId) { + try { + r.lock(); + final DataInputStream input = readAttribute(parentId, CHILDREN_ATT); + if (input == null) return Pair.create(ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_INT_ARRAY); + + final int count = input.readInt(); + final int[] ids = ArrayUtil.newIntArray(count); + final String[] names = ArrayUtil.newStringArray(count); + for (int i = 0; i < count; i++) { + int id = input.readInt(); + ids[i] = id; + names[i] = getName(id); } + input.close(); + return Pair.create(names, ids); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + r.unlock(); } } public static boolean wereChildrenAccessed(int id) { try { - synchronized (lock) { - return findAttributePage(id, CHILDREN_ATT, false) != 0; - } + r.lock(); + return findAttributePage(id, CHILDREN_ATT, false) != 0; } catch (Throwable e) { throw DbConnection.handleError(e); } + finally { + r.unlock(); + } } public static void updateList(int id, int[] children) { - synchronized (lock) { - try { - DbConnection.markDirty(); - final DataOutputStream record = writeAttribute(id, CHILDREN_ATT, false); - record.writeInt(children.length); - for (int child : children) { - if (child == id) { - LOG.error("Cyclic parent child relations"); - } - else { - record.writeInt(child); - } + try { + w.lock(); + DbConnection.markDirty(); + final DataOutputStream record = writeAttribute(id, CHILDREN_ATT, false); + record.writeInt(children.length); + for (int child : children) { + if (child == id) { + LOG.error("Cyclic parent child relations"); + } + else { + record.writeInt(child); } - record.close(); - } - catch (Throwable e) { - throw DbConnection.handleError(e); } + record.close(); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + w.unlock(); } } @@ -800,25 +850,31 @@ public class FSRecords implements Forceable { } public static int getModCount() { - synchronized (lock) { + try { + r.lock(); return getRecords().getInt(HEADER_GLOBAL_MOD_COUNT_OFFSET); } + finally { + r.unlock(); + } } public static int getParent(int id) { - synchronized (lock) { - try { - final int parentId = getRecordInt(id, PARENT_OFFSET); - if (parentId == id) { - LOG.error("Cyclic parent child relations in the database. id = " + id); - return 0; - } + try { + r.lock(); + final int parentId = getRecordInt(id, PARENT_OFFSET); + if (parentId == id) { + LOG.error("Cyclic parent child relations in the database. id = " + id); + return 0; + } - return parentId; - } - catch (Throwable e) { - throw DbConnection.handleError(e); - } + return parentId; + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + r.unlock(); } } @@ -828,101 +884,129 @@ public class FSRecords implements Forceable { return; } - synchronized (lock) { - try { - incModCount(id); - putRecordInt(id, PARENT_OFFSET, parent); - } - catch (Throwable e) { - throw DbConnection.handleError(e); - } + try { + w.lock(); + incModCount(id); + putRecordInt(id, PARENT_OFFSET, parent); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + w.unlock(); } } public static String getName(int id) { - synchronized (lock) { - try { - final int nameId = getRecordInt(id, NAME_OFFSET); - return nameId != 0 ? getNames().valueOf(nameId) : ""; - } - catch (Throwable e) { - throw DbConnection.handleError(e); - } + try { + r.lock(); + final int nameId = getRecordInt(id, NAME_OFFSET); + return nameId != 0 ? getNames().valueOf(nameId) : ""; + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + r.unlock(); } } public static void setName(int id, String name) { - synchronized (lock) { - try { - incModCount(id); - putRecordInt(id, NAME_OFFSET, getNames().enumerate(name)); - } - catch (Throwable e) { - throw DbConnection.handleError(e); - } + try { + w.lock(); + incModCount(id); + putRecordInt(id, NAME_OFFSET, getNames().enumerate(name)); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + w.unlock(); } } public static int getFlags(int id) { - synchronized (lock) { + try { + r.lock(); return getRecordInt(id, FLAGS_OFFSET); } + finally { + r.unlock(); + } } public static void setFlags(int id, int flags, final boolean markAsChange) { - synchronized (lock) { - try { - if (markAsChange) { - incModCount(id); - } - putRecordInt(id, FLAGS_OFFSET, flags); - } - catch (Throwable e) { - throw DbConnection.handleError(e); + try { + w.lock(); + if (markAsChange) { + incModCount(id); } + putRecordInt(id, FLAGS_OFFSET, flags); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + w.unlock(); } } public static long getLength(int id) { - synchronized (lock) { + try { + r.lock(); return getRecords().getLong(getOffset(id, LENGTH_OFFSET)); } + finally { + r.unlock(); + } } public static void setLength(int id, long len) { - synchronized (lock) { - try { - incModCount(id); - getRecords().putLong(getOffset(id, LENGTH_OFFSET), len); - } - catch (Throwable e) { - throw DbConnection.handleError(e); - } + try { + w.lock(); + incModCount(id); + getRecords().putLong(getOffset(id, LENGTH_OFFSET), len); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + w.unlock(); } } public static long getTimestamp(int id) { - synchronized (lock) { + try { + r.lock(); return getRecords().getLong(getOffset(id, TIMESTAMP_OFFSET)); } + finally { + r.unlock(); + } } public static void setTimestamp(int id, long value) { - synchronized (lock) { - try { - incModCount(id); - getRecords().putLong(getOffset(id, TIMESTAMP_OFFSET), value); - } - catch (Throwable e) { - throw DbConnection.handleError(e); - } + try { + w.lock(); + incModCount(id); + getRecords().putLong(getOffset(id, TIMESTAMP_OFFSET), value); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + w.unlock(); } } public static int getModCount(int id) { - synchronized (lock) { + try { + r.lock(); return getRecordInt(id, MOD_COUNT_OFFSET); } + finally { + r.unlock(); + } } private static void setModCount(int id, int value) { @@ -961,10 +1045,14 @@ public class FSRecords implements Forceable { public static DataInputStream readContent(int fileId) { try { int page; - synchronized (lock) { + try { + r.lock(); page = findContentPage(fileId, false); if (page == 0) return null; } + finally { + r.unlock(); + } return getContentStorage().readStream(page); } catch (Throwable e) { @@ -987,10 +1075,14 @@ public class FSRecords implements Forceable { try { synchronized (attId) { int page; - synchronized (lock) { + try { + r.lock(); page = findAttributePage(fileId, attId, false); if (page == 0) return null; } + finally { + r.unlock(); + } return getAttributesStorage().readStream(page); } } @@ -1062,15 +1154,17 @@ public class FSRecords implements Forceable { public static int acquireFileContent(int fileId) { try { - synchronized (lock) { - int record = getContentRecordId(fileId); - if (record > 0) getContentStorage().acquireRecord(record); - return record; - } + w.lock(); + int record = getContentRecordId(fileId); + if (record > 0) getContentStorage().acquireRecord(record); + return record; } catch (Throwable e) { throw DbConnection.handleError(e); } + finally { + w.unlock(); + } } public static void releaseContent(int contentId) { @@ -1084,13 +1178,15 @@ public class FSRecords implements Forceable { public static int getContentId(int fileId) { try { - synchronized (lock) { - return getContentRecordId(fileId); - } + r.lock(); + return getContentRecordId(fileId); } catch (Throwable e) { throw DbConnection.handleError(e); } + finally { + r.unlock(); + } } @NotNull @@ -1191,10 +1287,14 @@ public class FSRecords implements Forceable { public void writeBytes(ByteSequence bytes, int fileId) throws IOException { final int page; - synchronized (lock) { + try { + w.lock(); incModCount(fileId); page = findOrCreatePage(); } + finally { + w.unlock(); + } getStorage().writeBytes(page, bytes, myFixedSize); } @@ -1205,17 +1305,17 @@ public class FSRecords implements Forceable { } public static void dispose() { - synchronized (lock) { - try { - DbConnection.force(); - DbConnection.closeFiles(); - } - catch (Throwable e) { - throw DbConnection.handleError(e); - } - finally { - ourIsDisposed = true; - } + try { + w.lock(); + DbConnection.force(); + DbConnection.closeFiles(); + } + catch (Throwable e) { + throw DbConnection.handleError(e); + } + finally { + ourIsDisposed = true; + w.unlock(); } } @@ -1226,7 +1326,8 @@ public class FSRecords implements Forceable { public static void checkSanity() { long t = System.currentTimeMillis(); - synchronized (lock) { + try { + r.lock(); final int fileLength = (int)getRecords().length(); assert fileLength % RECORD_SIZE == 0; int recordCount = fileLength / RECORD_SIZE; @@ -1245,6 +1346,9 @@ public class FSRecords implements Forceable { } } } + finally { + r.unlock(); + } t = System.currentTimeMillis() - t; LOG.info("Sanity check took " + t + " ms"); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java index d5b6ed99a05d..e0ac0f607e29 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/EncodingPanel.java @@ -43,6 +43,7 @@ import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter; import com.intellij.openapi.wm.CustomStatusBarWidget; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.StatusBarWidget; +import com.intellij.ui.ClickListener; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.Alarm; import com.intellij.util.ui.UIUtil; @@ -50,7 +51,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -77,13 +77,14 @@ public class EncodingPanel extends EditorBasedWidget implements StatusBarWidget. } } }; - myComponent.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { update(); showPopup(e); + return true; } - }); + }.installOn(myComponent); myComponent.setBorder(WidgetBorder.INSTANCE); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java index 24b4122515fd..da7ceb250f72 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/IdeStatusBarImpl.java @@ -34,6 +34,7 @@ import com.intellij.openapi.wm.*; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; import com.intellij.openapi.wm.ex.StatusBarEx; import com.intellij.openapi.wm.impl.ToolWindowManagerImpl; +import com.intellij.ui.ClickListener; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.popup.NotificationPopup; import com.intellij.util.ArrayUtil; @@ -617,17 +618,18 @@ public class IdeStatusBarImpl extends JComponent implements StatusBarEx { putClientProperty(UIUtil.CENTER_TOOLTIP_DEFAULT, Boolean.TRUE); setToolTipText(presentation.getTooltipText()); - - addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(final MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { final ListPopup popup = myPresentation.getPopupStep(); - if (popup == null) return; + if (popup == null) return false; final Dimension dimension = popup.getContent().getPreferredSize(); final Point at = new Point(0, -dimension.height); popup.show(new RelativePoint(e.getComponent(), at)); + return true; } - }); + }.installOn(this); + setOpaque(false); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java index 361d53682417..9a403bc24c09 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/StatusPanel.java @@ -26,6 +26,7 @@ import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFrame; import com.intellij.openapi.wm.WindowManager; +import com.intellij.ui.ClickListener; import com.intellij.util.Alarm; import com.intellij.util.text.DateFormatUtil; import org.jetbrains.annotations.Nullable; @@ -87,17 +88,20 @@ class StatusPanel extends JPanel { setOpaque(isOpaque() && !SystemInfo.isMac); myTextPanel.setBorder(new EmptyBorder(0, 5, 0, 0)); - myTextPanel.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { if (myLogMode || myAfterClick) { EventLog.toggleLog(getActiveProject()); myAfterClick = true; myTextPanel.setExplicitSize(myTextPanel.getSize()); myTextPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } + return true; } + }.installOn(myTextPanel); + myTextPanel.addMouseListener(new MouseAdapter() { @Override public void mouseExited(MouseEvent e) { myTextPanel.setExplicitSize(null); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/DefaultWelcomeScreen.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/DefaultWelcomeScreen.java index 270a078d8970..6e698275e31c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/DefaultWelcomeScreen.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/DefaultWelcomeScreen.java @@ -275,18 +275,19 @@ public class DefaultWelcomeScreen implements WelcomeScreen { actionLabel.setFont(new Font(CAPTION_FONT_NAME, Font.PLAIN, 12)); actionLabel.setForeground(CAPTION_COLOR); actionLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - actionLabel.addMouseListener(new MouseAdapter() { + + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { if (e.getButton() == MouseEvent.BUTTON1) { DataContext dataContext = DataManager.getInstance().getDataContext(myWelcomePanel); int fragment = actionLabel.findFragmentAt(e.getX()); if (fragment == SimpleColoredComponent.FRAGMENT_ICON) { final int rc = Messages.showOkCancelDialog(PlatformDataKeys.PROJECT.getData(dataContext), - "Remove '" + action.getTemplatePresentation().getText() + - "' from recent projects list?", - "Remove Recent Project", - Messages.getQuestionIcon()); + "Remove '" + action.getTemplatePresentation().getText() + + "' from recent projects list?", + "Remove Recent Project", + Messages.getQuestionIcon()); if (rc == 0) { final RecentProjectsManagerBase manager = RecentProjectsManagerBase.getInstance(); assert action instanceof ReopenProjectAction : action; @@ -309,8 +310,11 @@ public class DefaultWelcomeScreen implements WelcomeScreen { action.actionPerformed(event); } } + return true; } + }.installOn(actionLabel); + actionLabel.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { actionLabel.setIcon(ICON); @@ -341,13 +345,15 @@ public class DefaultWelcomeScreen implements WelcomeScreen { pluginsCaption.setForeground(CAPTION_COLOR); JLabel openPluginManager = new JLabel(UIBundle.message("welcome.screen.plugins.panel.manager.link")); - openPluginManager.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { final PluginManagerConfigurable configurable = new PluginManagerConfigurable(PluginManagerUISettings.getInstance()); ShowSettingsUtil.getInstance().editConfigurable(myPluginsPanel, configurable); + return true; } - }); + }.installOn(openPluginManager); + openPluginManager.setForeground(CAPTION_COLOR); openPluginManager.setFont(LINK_FONT); openPluginManager.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); @@ -518,16 +524,17 @@ public class DefaultWelcomeScreen implements WelcomeScreen { learnMore.setForeground(enabled ? CAPTION_COLOR : DISABLED_CAPTION_COLOR); learnMore.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); learnMore.setToolTipText(UIBundle.message("welcome.screen.plugins.panel.learn.more.tooltip.text")); - learnMore.addMouseListener(new MouseAdapter() { + new ClickListener() { @Override - public void mouseClicked(MouseEvent e) { + public boolean onClick(MouseEvent e, int clickCount) { try { BrowserUtil.launchBrowser(url); } catch (IllegalThreadStateException ignore) { } + return true; } - }); + }.installOn(learnMore); logoPanel.add(new JLabel(" "), BorderLayout.CENTER); logoPanel.add(learnMore, BorderLayout.EAST); @@ -695,11 +702,14 @@ public class DefaultWelcomeScreen implements WelcomeScreen { myCount++; JLabel name = new JLabel(underlineHtmlText(commandLink)); - name.addMouseListener(new MouseAdapter() { - public void mouseClicked(MouseEvent e) { - button.onPress(e); + new ClickListener() { + @Override + public boolean onClick(MouseEvent event, int clickCount) { + button.onPress(event); + return true; } - }); + }.installOn(name); + name.setForeground(CAPTION_COLOR); name.setFont(LINK_FONT); name.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); diff --git a/platform/platform-impl/src/com/intellij/platform/OpenOrAttachDialog.java b/platform/platform-impl/src/com/intellij/platform/OpenOrAttachDialog.java index 6d367862883f..207ff98cfa57 100644 --- a/platform/platform-impl/src/com/intellij/platform/OpenOrAttachDialog.java +++ b/platform/platform-impl/src/com/intellij/platform/OpenOrAttachDialog.java @@ -18,12 +18,13 @@ package com.intellij.platform; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.ClickListener; +import com.intellij.ui.DoubleClickListener; import com.intellij.ui.components.JBCheckBox; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** @@ -46,16 +47,15 @@ public class OpenOrAttachDialog extends DialogWrapper { myHideReplace = hideReplace; setTitle(title); init(); - MouseAdapter listener = new MouseAdapter() { + ClickListener listener = new DoubleClickListener() { @Override - public void mouseClicked(MouseEvent e) { - if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) { - doOKAction(); - } + protected boolean onDoubleClick(MouseEvent event) { + doOKAction(); + return true; } }; - myCurrentWindowButton.addMouseListener(listener); - myOpenInNewWindowButton.addMouseListener(listener); + listener.installOn(myCurrentWindowButton); + listener.installOn(myOpenInNewWindowButton); final String mode = PropertiesComponent.getInstance().getValue(MODE_PROPERTY); if (MODE_NEW.equals(mode)) { diff --git a/platform/platform-impl/src/com/intellij/ui/EditorComboBox.java b/platform/platform-impl/src/com/intellij/ui/EditorComboBox.java index e20f02484fb0..af01dd3dce83 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorComboBox.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorComboBox.java @@ -215,6 +215,20 @@ public class EditorComboBox extends JComboBox implements DocumentListener { setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(objects))); } + public void appendItem(String item) { + ArrayList objects = new ArrayList(); + + int count = getItemCount(); + for (int i = 0; i < count; i++) { + objects.add(getItemAt(i)); + } + + if (!objects.contains(item)) { + objects.add(item); + } + setModel(new DefaultComboBoxModel(ArrayUtil.toObjectArray(objects))); + } + private class MyEditor implements ComboBoxEditor { public void addActionListener(ActionListener l) { } diff --git a/platform/platform-impl/src/com/intellij/ui/HoverHyperlinkLabel.java b/platform/platform-impl/src/com/intellij/ui/HoverHyperlinkLabel.java index 8e6761161522..53bfbedf412b 100644 --- a/platform/platform-impl/src/com/intellij/ui/HoverHyperlinkLabel.java +++ b/platform/platform-impl/src/com/intellij/ui/HoverHyperlinkLabel.java @@ -46,7 +46,29 @@ public class HoverHyperlinkLabel extends JLabel { } private void setupListener() { - addMouseListener(new MouseHandler()); + addMouseListener(new MouseAdapter() { + public void mouseEntered(MouseEvent e) { + HoverHyperlinkLabel.super.setText(underlineTextInHtml(myOriginalText)); + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + } + + public void mouseExited(MouseEvent e) { + HoverHyperlinkLabel.super.setText(myOriginalText); + setCursor(Cursor.getDefaultCursor()); + } + }); + + new ClickListener() { + @Override + public boolean onClick(MouseEvent e, int clickCount) { + HyperlinkListener[] listeners = myListeners.toArray(new HyperlinkListener[myListeners.size()]); + HyperlinkEvent event = new HyperlinkEvent(HoverHyperlinkLabel.this, HyperlinkEvent.EventType.ACTIVATED, null); + for (HyperlinkListener listener : listeners) { + listener.hyperlinkUpdate(event); + } + return true; + } + }.installOn(this); } public void setText(String text) { @@ -67,27 +89,6 @@ public class HoverHyperlinkLabel extends JLabel { return myOriginalText; } - private class MouseHandler extends MouseAdapter { - public void mouseClicked(MouseEvent e) { - HyperlinkListener[] listeners = myListeners.toArray(new HyperlinkListener[myListeners.size()]); - HyperlinkEvent event = new HyperlinkEvent(HoverHyperlinkLabel.this, HyperlinkEvent.EventType.ACTIVATED, null); - for (int i = 0; i < listeners.length; i++) { - HyperlinkListener listener = listeners[i]; - listener.hyperlinkUpdate(event); - } - } - - public void mouseEntered(MouseEvent e) { - HoverHyperlinkLabel.super.setText(underlineTextInHtml(myOriginalText)); - setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - } - - public void mouseExited(MouseEvent e) { - HoverHyperlinkLabel.super.setText(myOriginalText); - setCursor(Cursor.getDefaultCursor()); - } - } - public void addHyperlinkListener(HyperlinkListener listener) { myListeners.add(listener); } diff --git a/platform/platform-impl/src/com/intellij/ui/ListenerUtil.java b/platform/platform-impl/src/com/intellij/ui/ListenerUtil.java index 4992a927918b..4622063be221 100644 --- a/platform/platform-impl/src/com/intellij/ui/ListenerUtil.java +++ b/platform/platform-impl/src/com/intellij/ui/ListenerUtil.java @@ -52,6 +52,28 @@ public class ListenerUtil { } } + public static void addClickListener(Component component, ClickListener l) { + l.installOn(component); + + if (component instanceof Container) { + Container container = (Container)component; + for (int i = 0; i < container.getComponentCount(); i++) { + addClickListener(container.getComponent(i), l); + } + } + } + + public static void removeClickListener(Component component, ClickListener l) { + l.uninstall(component); + + if (component instanceof Container) { + Container container = (Container)component; + for (int i = 0; i < container.getComponentCount(); i++) { + removeClickListener(container.getComponent(i), l); + } + } + } + public static void addMouseMotionListener(Component c, MouseMotionListener l) { c.addMouseMotionListener(l); if (c instanceof Container) { @@ -102,4 +124,4 @@ public class ListenerUtil { } } } -} \ No newline at end of file +} diff --git a/platform/platform-impl/src/com/intellij/ui/TabbedPaneImpl.java b/platform/platform-impl/src/com/intellij/ui/TabbedPaneImpl.java index 795fa4c45bb9..d7611d707a11 100644 --- a/platform/platform-impl/src/com/intellij/ui/TabbedPaneImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/TabbedPaneImpl.java @@ -52,7 +52,7 @@ public class TabbedPaneImpl extends JBTabbedPane implements TabbedPane { setFocusable(false); addMouseListener( new MouseAdapter() { - public void mouseClicked(final MouseEvent e) { + public void mousePressed(final MouseEvent e) { _requestDefaultFocus(); } } @@ -326,4 +326,4 @@ public class TabbedPaneImpl extends JBTabbedPane implements TabbedPane { public boolean isDisposed() { return false; } -} \ No newline at end of file +} diff --git a/platform/platform-impl/src/com/intellij/ui/content/impl/MessageViewImpl.java b/platform/platform-impl/src/com/intellij/ui/content/impl/MessageViewImpl.java index 599460ff26ff..c5f46efcff4f 100644 --- a/platform/platform-impl/src/com/intellij/ui/content/impl/MessageViewImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/content/impl/MessageViewImpl.java @@ -41,7 +41,7 @@ public class MessageViewImpl implements MessageView { final Runnable runnable = new Runnable() { public void run() { myToolWindow = toolWindowManager.registerToolWindow(ToolWindowId.MESSAGES_WINDOW, true, ToolWindowAnchor.BOTTOM, project, true); - myToolWindow.setIcon(AllIcons.General.ToolWindowMessages); + myToolWindow.setIcon(AllIcons.Toolwindows.ToolWindowMessages); new ContentManagerWatcher(myToolWindow, getContentManager()); for (Runnable postponedRunnable : myPostponedRunnables) { postponedRunnable.run(); diff --git a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties index 91dbe3809874..773e1c1cd3cf 100644 --- a/platform/platform-resources-en/src/messages/CodeInsightBundle.properties +++ b/platform/platform-resources-en/src/messages/CodeInsightBundle.properties @@ -87,7 +87,7 @@ unwrap.try=Unwrap 'try...' unwrap.conditional=Unwrap 'f ? a : b' remove.catch=Remove 'catch...' unwrap.synchronized=Unwrap 'synchronized...' -unwrap.method.parameter=Unwrap ''{0}'' +unwrap.with.placeholder=Unwrap ''{0}'' unwrap.anonymous=Unwrap 'anonymous...' generate.equals.hashcode.wizard.title=Generate equals() and hashCode() generate.equals.hashcode.equals.fields.chooser.title=Choose &fields to be included in equals() @@ -156,7 +156,9 @@ intention.make.type.generic.family=Make Type Generic intention.make.type.generic.text=Change type of {0} to {1} intention.split.if.family=Split If intention.split.if.text=Split into 2 if's +intention.refactoring.family=Refactoring intention.introduce.variable.text=Introduce local variable +intention.encapsulate.field.text=Encapsulate field intention.implement.abstract.method.family=Implement Abstract Method intention.implement.abstract.method.text=Implement method ''{0}'' intention.override.method.text=Override method ''{0}'' @@ -198,10 +200,13 @@ intention.implement.abstract.method.error.no.classes.title=No Classes Found intention.implement.abstract.method.class.chooser.title=Choose Implementing Class intention.implement.abstract.method.command.name=Implement method intention.invert.if.condition=Invert If Condition +intention.extract.if.condition.text=Extract if ({0}) +intention.extract.if.condition.family=Extract If Condition intention.underscores.in.literals.family=Underscores in numeric literals intention.remove.literal.underscores=Remove underscores from literal intention.insert.literal.underscores=Insert underscores into literal + intention.create.test=Create Test intention.create.test.dialog.testing.library=Testing library: intention.create.test.dialog.language=Language: diff --git a/platform/platform-resources-en/src/messages/ExecutionBundle.properties b/platform/platform-resources-en/src/messages/ExecutionBundle.properties index c0c60bb80bb0..884c7b2c4c74 100644 --- a/platform/platform-resources-en/src/messages/ExecutionBundle.properties +++ b/platform/platform-resources-en/src/messages/ExecutionBundle.properties @@ -318,6 +318,7 @@ export.test.results.output.path.empty=Output path is empty export.test.results.output.filename.empty=Output file name is empty export.test.results.footer=Generated by {0} on {1} configuration.edit.before.run=Show settings +configuration.singleton=Allow only one instance failed.to.create.output.file=Failed to create output file ''{0}'' script.execution.timeout=Script execution took more than {0} seconds. diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index f021f1c46b61..da9e2fbd340a 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -547,8 +547,10 @@ title.popup.views=Views title.project=Project error.module.already.exists=Module named ''{0}'' already exists title.rename.module=Rename Module +title.rename.library=Rename Library command.renaming.module=Renaming module {0} prompt.enter.new.module.name=Enter new module name +prompt.enter.new.library.name=Enter new library name tooltip.ui.designer.form=UI Designer Form node.projectview.libraries=Libraries node.projectview.external.libraries=External Libraries diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties index ecc25b700edb..e5385b9079b8 100644 --- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties +++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties @@ -139,6 +139,8 @@ introduce.variable.title=Extract Variable refactoring.introduce.context.error=Cannot perform refactoring in this context refactoring.introduceVariable=Extract Variable refactoring refactoring.introduce.selection.error=Cannot perform refactoring using selected element(s) +refactoring.introduce.name.error=Incorrect name +refactoring.introduce.name.used.error=This name is already used variable.of.type=Variable of &type: convert.to.instance.method.title=Convert To Instance Method diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index c3adfb7970d6..51db7ac1bef9 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -225,8 +225,6 @@ vcs.remote.management.ready=false type.ahead.logging.enabled=false fast.tree.expand.in.structure.view=false -python.exported.names.local.cache=false - ide.use.nautilus3=true ide.use.nautilus3.description=Use Nautilus if available diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml index a5c720af6b5a..c8ac1d74af1e 100644 --- a/platform/platform-resources/src/DefaultColorSchemesManager.xml +++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml @@ -435,7 +435,7 @@