Merge remote-tracking branch 'origin/master'

This commit is contained in:
Kirill Likhodedov
2011-11-15 16:04:18 +03:00
42 changed files with 964 additions and 435 deletions
+4
View File
@@ -233,6 +233,10 @@ public def layoutCommunityPlugins(String home) {
include(name: "ini4j*.jar")
exclude(name: "ini4j*sources.jar")
}
fileset(dir: "$home/plugins/git4idea/lib/jgit") {
include(name: "org.eclipse.jgit*.jar")
exclude(name: "*.zip")
}
}
layoutPlugin("svn4idea") {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

@@ -21,15 +21,13 @@ import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Chunk;
import com.intellij.util.graph.Graph;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* @author nik
@@ -46,38 +44,41 @@ public class GeneralProjectSettingsElement extends ProjectStructureElement {
@Override
public void check(ProjectStructureProblemsHolder problemsHolder) {
final Graph<Chunk<ModifiableRootModel>> graph = ModuleCompilerUtil.toChunkGraph(myContext.getModulesConfigurator().createGraphGenerator());
final Graph<Chunk<ModifiableRootModel>> graph = ModuleCompilerUtil.toChunkGraph(
myContext.getModulesConfigurator().createGraphGenerator());
final Collection<Chunk<ModifiableRootModel>> chunks = graph.getNodes();
String cycles = "";
int count = 0;
List<String> cycles = new ArrayList<String>();
for (Chunk<ModifiableRootModel> chunk : chunks) {
final Set<ModifiableRootModel> modules = chunk.getNodes();
String cycle = "";
List<String> names = new ArrayList<String>();
for (ModifiableRootModel model : modules) {
cycle += ", " + model.getModule().getName();
names.add(model.getModule().getName());
}
if (modules.size() > 1) {
@NonNls final String br = "<br>&nbsp;&nbsp;&nbsp;&nbsp;";
cycles += br + (++count) + ". " + cycle.substring(2);
cycles.add(StringUtil.join(names, ", "));
}
}
if (count > 0) {
@NonNls final String leftBrace = "<html>";
@NonNls final String rightBrace = "</html>";
final String fullDescription = leftBrace + ProjectBundle.message("module.circular.dependency.warning", cycles, count) + rightBrace;
if (!cycles.isEmpty()) {
final Project project = myContext.getProject();
for (Chunk<ModifiableRootModel> chunk : chunks) {
final Set<ModifiableRootModel> nodes = chunk.getNodes();
if (nodes.size() > 1) {
final PlaceInProjectStructureBase place = new PlaceInProjectStructureBase(project, ProjectStructureConfigurable.getInstance(project).createModulesPlace(), this);
StringBuilder names = new StringBuilder();
for (ModifiableRootModel model : nodes) {
if (names.length() > 0) names.append(", ");
names.append(model.getModule().getName());
}
problemsHolder.registerProblem(new CircularDependencyProblemDescription("Circular dependency between modules " + names, fullDescription, place));
final PlaceInProjectStructureBase place = new PlaceInProjectStructureBase(project, ProjectStructureConfigurable.getInstance(project).createModulesPlace(), this);
final String message;
final String description;
if (cycles.size() > 1) {
message = "Circular dependencies";
@NonNls final String br = "<br>&nbsp;&nbsp;&nbsp;&nbsp;";
StringBuilder cyclesString = new StringBuilder();
for (int i = 0; i < cycles.size(); i++) {
cyclesString.append(br).append(i + 1).append(". ").append(cycles.get(i));
}
description = ProjectBundle.message("module.circular.dependency.warning.description", cyclesString);
}
else {
message = ProjectBundle.message("module.circular.dependency.warning.short", cycles.get(0));
description = null;
}
problemsHolder.registerProblem(new ProjectStructureProblemDescription(message, description, place,
ProjectStructureProblemType.warning("module-circular-dependency"),
Collections.<ConfigurationErrorQuickFix>emptyList()));
}
}
@@ -100,21 +101,4 @@ public class GeneralProjectSettingsElement extends ProjectStructureElement {
public int hashCode() {
return 0;
}
public static class CircularDependencyProblemDescription extends ProjectStructureProblemDescription {
@NotNull private final String myFullDescription;
public CircularDependencyProblemDescription(@NotNull String message,
@NotNull String fullDescription,
@NotNull PlaceInProjectStructure place) {
super(message, null, place, ProjectStructureProblemType.warning("module-circular-dependency"),
Collections.<ConfigurationErrorQuickFix>emptyList());
myFullDescription = fullDescription;
}
@NotNull
public String getFullDescription() {
return myFullDescription;
}
}
}
@@ -32,9 +32,9 @@ import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectStructureElementConfigurable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.*;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureDaemonAnalyzer;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
import com.intellij.openapi.ui.DetailsComponent;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.openapi.util.IconLoader;
@@ -44,9 +44,7 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.FieldPanel;
import com.intellij.ui.InsertPathAction;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -73,7 +71,6 @@ public class ProjectConfigurable extends ProjectStructureElementConfigurable<Pro
private JPanel myPanel;
private final JLabel myWarningLabel = new JLabel("");
private final StructureConfigurableContext myContext;
private final ModulesConfigurator myModulesConfigurator;
private JPanel myWholePanel;
@@ -97,31 +94,9 @@ public class ProjectConfigurable extends ProjectStructureElementConfigurable<Pro
daemonAnalyzer.queueUpdate(mySettingsElement);
}
});
daemonAnalyzer.addListener(new ProjectStructureDaemonAnalyzerListener() {
@Override
public void problemsChanged(@NotNull ProjectStructureElement element) {
if (element instanceof GeneralProjectSettingsElement) {
updateCircularDependencyWarning();
}
}
});
init(model);
}
private void updateCircularDependencyWarning() {
ProjectStructureProblemsHolderImpl holder = myContext.getDaemonAnalyzer().getProblemsHolder(mySettingsElement);
final ProjectStructureProblemDescription item = holder != null ? ContainerUtil.getFirstItem(holder.getProblemDescriptions()) : null;
if (item instanceof GeneralProjectSettingsElement.CircularDependencyProblemDescription) {
myWarningLabel.setIcon(Messages.getWarningIcon());
myWarningLabel.setText(((GeneralProjectSettingsElement.CircularDependencyProblemDescription)item).getFullDescription());
}
else {
myWarningLabel.setIcon(null);
myWarningLabel.setText("");
}
myWarningLabel.repaint();
}
@Override
public ProjectStructureElement getProjectStructureElement() {
return mySettingsElement;
@@ -176,9 +151,6 @@ public class ProjectConfigurable extends ProjectStructureElementConfigurable<Pro
myPanel.add(myWholePanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.NONE, new Insets(4, 0, 0, 0), 0, 0));
//myWarningLabel.setUI(new MultiLineLabelUI());
myPanel.add(myWarningLabel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST,
GridBagConstraints.BOTH, new Insets(10, 6, 10, 0), 0, 0));
myProjectCompilerOutput.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(DocumentEvent e) {
@@ -16,7 +16,6 @@ import com.intellij.openapi.roots.ui.configuration.ConfigurationError;
import com.intellij.openapi.roots.ui.configuration.ConfigurationErrors;
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.util.registry.Registry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,10 +30,6 @@ public class ProjectConfigurationProblems {
private final ProjectStructureDaemonAnalyzer myAnalyzer;
private final StructureConfigurableContext myContext;
public static boolean isVisible() {
return Registry.is("ide.configuration.new.project.structure.errors");
}
public ProjectConfigurationProblems(ProjectStructureDaemonAnalyzer analyzer, StructureConfigurableContext context) {
myAnalyzer = analyzer;
myContext = context;
@@ -31,15 +31,11 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
private final MergingUpdateQueue myAnalyzerQueue;
private final EventDispatcher<ProjectStructureDaemonAnalyzerListener> myDispatcher = EventDispatcher.create(ProjectStructureDaemonAnalyzerListener.class);
private final AtomicBoolean myStopped = new AtomicBoolean(false);
private ProjectConfigurationProblems myProjectConfigurationProblems;
private final StructureConfigurableContext myContext;
private final ProjectConfigurationProblems myProjectConfigurationProblems;
public ProjectStructureDaemonAnalyzer(StructureConfigurableContext context) {
myContext = context;
Disposer.register(context, this);
if (ProjectConfigurationProblems.isVisible()) {
myProjectConfigurationProblems = new ProjectConfigurationProblems(this, context);
}
myProjectConfigurationProblems = new ProjectConfigurationProblems(this, context);
myAnalyzerQueue = new MergingUpdateQueue("Project Structure Daemon Analyzer", 300, false, null, this, null, false);
}
@@ -250,9 +246,6 @@ public class ProjectStructureDaemonAnalyzer implements Disposable {
public void reset() {
LOG.debug("analyzer started");
if (ProjectConfigurationProblems.isVisible() && myProjectConfigurationProblems == null) {
myProjectConfigurationProblems = new ProjectConfigurationProblems(this, myContext);
}
myAnalyzerQueue.activate();
myAnalyzerQueue.queue(new Update("reset") {
public void run() {
@@ -788,10 +788,39 @@ public class Mappings {
}
for (MethodRepr m : diff.methods().added()) {
if ((it.access & Opcodes.ACC_INTERFACE) > 0 || (m.access & Opcodes.ACC_ABSTRACT) > 0) {
if (it.isAnnotation()) {
continue;
}
if ((it.access & Opcodes.ACC_INTERFACE) > 0 ||
(it.access & Opcodes.ACC_ABSTRACT) > 0 ||
(m.access & Opcodes.ACC_ABSTRACT) > 0) {
u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, false);
}
if ((m.access & Opcodes.ACC_PRIVATE) == 0 && !myContext.getValue(m.name).equals("<init>")) {
final ClassRepr oldIt = getReprByName(it.name);
if (oldIt != null && self.findOverridenMethods(m, oldIt).size() > 0) { // oldIt.findMethods(MethodRepr.equalByJavaRules(m)).size() > 0) {
}
else {
final UsageRepr.Usage usage = it.createUsage();
affectedUsages.add(usage);
if ((m.access & Opcodes.ACC_PUBLIC) > 0) {
}
else if (isPackageLocal(m.access)) {
usageConstraints.put(usage, u.new PackageConstraint(it.getPackageName()));
}
else if ((m.access & Opcodes.ACC_PROTECTED) > 0) {
usageConstraints.put(usage, u.new InheritanceConstraint(it.name));
}
}
}
if ((m.access & Opcodes.ACC_PRIVATE) == 0) {
final Collection<Pair<MethodRepr, ClassRepr>> affectedMethods = u.findAllMethodsBySpecificity(m, it);
final MethodRepr.Predicate overrides = MethodRepr.equalByJavaRules(m);
@@ -21,7 +21,6 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.TokenType;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import org.jetbrains.annotations.NotNull;
public class PsiWhiteSpaceImpl extends LeafPsiElement implements PsiWhiteSpace {
@@ -41,8 +40,7 @@ public class PsiWhiteSpaceImpl extends LeafPsiElement implements PsiWhiteSpace {
@Override
@NotNull
public Language getLanguage() {
PsiElement master = getNextSibling();
if (master == null || master instanceof OuterLanguageElement) master = getParent();
return master.getLanguage();
final PsiElement master = getParent();
return master != null ? master.getLanguage() : Language.ANY;
}
}
@@ -15,29 +15,21 @@
*/
package com.intellij.ide.navigationToolbar;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.navigationToolbar.ui.NavBarUI;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.IconUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.ui.EmptyIcon;
import com.intellij.util.ui.JBInsets;
import com.intellij.util.ui.UIUtil;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Path2D;
/**
* @author Konstantin Bulenkov
*/
class NavBarItem extends SimpleColoredComponent implements Disposable {
private static Image SEPARATOR_ACTIVE = IconUtil.toImage(IconLoader.getIcon("/general/navbarSeparatorActive.png"));
private static Image SEPARATOR_PASSIVE = IconUtil.toImage(IconLoader.getIcon("/general/navbarSeparatorPassive.png"));
private static Image SEPARATOR_GRADIENT = IconUtil.toImage(IconLoader.getIcon("/general/navbarSeparatorGradient.png"));
public class NavBarItem extends SimpleColoredComponent implements Disposable {
//private static int count = 0;
private final String myText;
@@ -47,12 +39,13 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
private final NavBarPanel myPanel;
private Object myObject;
private final boolean isPopupElement;
private JBInsets myPadding;
private final NavBarUI myUI;
public NavBarItem(NavBarPanel panel, Object object, int idx, Disposable parent) {
//count++;
//System.out.println(count);
myPanel = panel;
myUI = panel.getNavBarUI();
myObject = object;
myIndex = idx;
isPopupElement = idx == -1;
@@ -77,17 +70,15 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
Disposer.register(parent == null ? panel : parent, this);
setOpaque(false);
setFont(UIUtil.isUnderAquaLookAndFeel() ? UIUtil.getLabelFont().deriveFont(11.0f) : getFont());
if (isPopupElement || !NavBarPanel.isDecorated()) {
setIpad(new Insets(1,2,1,2));
} else {
setIpad(new Insets(0,0,0,0));
setFont(myUI.getElementFont(this));
setIpad(myUI.getElementIpad(isPopupElement));
if (!isPopupElement) {
setMyBorder(null);
setBorder(null);
setPaintFocusBorder(false);
}
update();
myPadding = new JBInsets(3, 3, 3, 3);
}
/**
@@ -115,124 +106,52 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
clear();
setIcon(myIcon);
final boolean focused = isFocusedOrPopupElement();
final NavBarModel model = myPanel.getModel();
final boolean focused = isFocusedOrPopupElement();
final boolean selected = isSelected();
if (!NavBarPanel.isDecorated()) {
setPaintFocusBorder(selected && !isPopupElement && myPanel.isNodePopupActive());
}
setFocusBorderAroundIcon(false);
setBackground(myUI.getBackground(selected, focused));
setBackground(selected && focused
? UIUtil.getListSelectionBackground()
: (UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground()));
Color fg = myUI.getForeground(selected, focused, isInactive());
if (fg == null) fg = myAttributes.getFgColor();
final Color fg = selected && focused
? UIUtil.getListSelectionForeground()
: model.getSelectedIndex() < myIndex && model.getSelectedIndex() != -1
? UIUtil.getInactiveTextColor()
: myAttributes.getFgColor();
final Color bg = selected && focused ? UIUtil.getListSelectionBackground() : myAttributes.getBgColor();
final Color bg = getBackground();
append(myText, new SimpleTextAttributes(bg, fg, myAttributes.getWaveColor(), myAttributes.getStyle()));
repaint();
}
public boolean isInactive() {
final NavBarModel model = myPanel.getModel();
return model.getSelectedIndex() < myIndex && model.getSelectedIndex() != -1;
}
public boolean isPopupElement() {
return isPopupElement;
}
@Override
protected void doPaint(Graphics2D g) {
if (isPopupElement || !NavBarPanel.isDecorated()) {
if (isPopupElement) {
super.doPaint(g);
} else {
doPaintDecorated(g);
myUI.doPaintNavBarItem(g, this, myPanel);
}
}
private void doPaintDecorated(Graphics2D g) {
Icon icon = myIcon;
final Color bg = isSelected() && isFocused()
? UIUtil.getListSelectionBackground()
: (UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground());
final Color c = UIUtil.getListSelectionBackground();
final Color selBg = new Color(c.getRed(), c.getGreen(), c.getBlue(), getAlpha());
int w = getWidth();
int h = getHeight();
if (/*!UIUtil.isUnderAquaLookAndFeel() ||*/ myPanel.isInFloatingMode() || (isSelected() && myPanel.hasFocus())) {
g.setPaint(isSelected() && isFocused() ? selBg : bg);
g.fillRect(0, 0, w - (isLastElement() /*|| !UIUtil.isUnderAquaLookAndFeel()*/ ? 0 : getDecorationOffset()), h);
}
final int offset = isFirstElement() ? getFirstElementLeftOffset() : 0;
final int iconOffset = myPadding.left + offset;
icon.paintIcon(this, g, iconOffset, (h - icon.getIconHeight()) / 2);
final int textOffset = icon.getIconWidth() + myPadding.width() + offset;
int x = doPaintText(g, textOffset, false);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.translate(x, 0);
Path2D.Double path;
int off = getDecorationOffset();
if (isFocused()) {
if (isSelected() && !isLastElement()) {
path = new Path2D.Double();
g.translate(2, 0);
path.moveTo(0, 0);
path.lineTo(off, h / 2); // |\
path.lineTo(0, h); // |/
path.lineTo(0, 0);
g.setColor(selBg);
g.fill(path);
g.translate(-2, 0);
}
if (/*!UIUtil.isUnderAquaLookAndFeel() || */myPanel.isInFloatingMode() || isNextSelected()) {
if (! isLastElement()) {
path = new Path2D.Double();
path.moveTo(0, 0);
path.lineTo(off, h / 2); // ___
path.lineTo(0, h); // \ |
path.lineTo(off + 2, h); // /_|
path.lineTo(off + 2, 0);
path.lineTo(0, 0);
g.setColor(isNextSelected() ? selBg : UIUtil.getListBackground());
//if (UIUtil.isUnderAquaLookAndFeel() && isNextSelected() || !UIUtil.isUnderAquaLookAndFeel()) {
g.fill(path);
//}
}
}
}
if (! isLastElement() && ((!isSelected() && !isNextSelected()) || !myPanel.hasFocus())) {
Image img = SEPARATOR_PASSIVE;
final UISettings settings = UISettings.getInstance();
if (settings.SHOW_NAVIGATION_BAR) {
img = SEPARATOR_GRADIENT;
}
g.drawImage(img, null, null);
}
public int doPaintText(Graphics2D g, int offset) {
return super.doPaintText(g, offset, false);
}
private static short getAlpha() {
if ((UIUtil.isUnderAlloyLookAndFeel() && !UIUtil.isUnderAlloyIDEALookAndFeel())
|| UIUtil.isUnderMetalLookAndFeel() || UIUtil.isUnderMetalLookAndFeel()){
return 255;
}
return 150;
}
private static int getDecorationOffset() {
return 11;
}
private static int getFirstElementLeftOffset() {
return 6;
}
private boolean isLastElement() {
public boolean isLastElement() {
return myIndex == myPanel.getModel().size() - 1;
}
private boolean isFirstElement() {
public boolean isFirstElement() {
return myIndex == 0;
}
@@ -244,11 +163,8 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
@Override
public Dimension getPreferredSize() {
final Dimension size = super.getPreferredSize();
if (! isPopupElement && NavBarPanel.isDecorated()) {
size.width += getDecorationOffset() + myPadding.width() + (isFirstElement() ? getFirstElementLeftOffset() : 0);
size.height += myPadding.height();
}
return size;
final Dimension offsets = myUI.getOffsets(this);
return new Dimension(size.width + offsets.width, size.height + offsets.height);
}
@Override
@@ -260,7 +176,7 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
return isFocused() || isPopupElement;
}
private boolean isFocused() {
public boolean isFocused() {
final Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
return focusOwner == myPanel && !myPanel.isNodePopupShowing();
}
@@ -279,7 +195,7 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
@Override
protected boolean shouldDrawMacShadow() {
return UIUtil.isUnderAquaLookAndFeel() && !isSelected();
return myUI.isDrawMacShadow(isSelected(), isFocused());
}
@Override
@@ -315,7 +231,7 @@ class NavBarItem extends SimpleColoredComponent implements Disposable {
}
private boolean isNextSelected() {
public boolean isNextSelected() {
return myIndex == myPanel.getModel().getSelectedIndex() - 1;
}
}
@@ -23,6 +23,8 @@ import com.intellij.ide.IdeView;
import com.intellij.ide.dnd.DnDActionInfo;
import com.intellij.ide.dnd.DnDDragStartBean;
import com.intellij.ide.dnd.DnDSupport;
import com.intellij.ide.navigationToolbar.ui.NavBarUI;
import com.intellij.ide.navigationToolbar.ui.NavBarUIManager;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.impl.AbstractProjectViewPane;
import com.intellij.ide.projectView.impl.ProjectRootsUtil;
@@ -42,7 +44,6 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.AsyncResult;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -65,7 +66,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.TreeNode;
import java.awt.*;
import java.awt.event.MouseAdapter;
@@ -102,7 +102,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
private RelativePoint myLocationCache;
public NavBarPanel(final Project project) {
super(new FlowLayout(FlowLayout.LEFT, isDecorated() ? 0 : 5, 0));
super(new FlowLayout(FlowLayout.LEFT, 0 , 0));
myProject = project;
myModel = new NavBarModel(myProject);
myIdeView = new NavBarIdeView(this);
@@ -110,10 +110,6 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
myUpdateQueue = new NavBarUpdateQueue(this);
PopupHandler.installPopupHandler(this, IdeActions.GROUP_NAVBAR_POPUP, ActionPlaces.NAVIGATION_BAR);
if (!isDecorated()) {
setBorder(/*new NavBarBorder(false, -1)*/ new EmptyBorder(1,0,1,4));
}
setOpaque(false);
myCopyPasteDelegator = new CopyPasteDelegator(myProject, NavBarPanel.this) {
@@ -129,10 +125,6 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
Disposer.register(project, this);
}
public static boolean isDecorated() {
return Registry.is("navbar.is.decorated");
}
public boolean isNodePopupActive() {
return myNodePopup != null && myNodePopup.isVisible();
}
@@ -300,7 +292,7 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
return null;
}
boolean isInFloatingMode() {
public boolean isInFloatingMode() {
return myHint != null && myHint.isVisible();
}
@@ -833,4 +825,10 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
info.put("navBarPopup", popupText.toString());
}
}
@SuppressWarnings("MethodMayBeStatic")
@NotNull
public NavBarUI getNavBarUI() {
return NavBarUIManager.getUI();
}
}
@@ -20,6 +20,7 @@
*/
package com.intellij.ide.navigationToolbar;
import com.intellij.ide.navigationToolbar.ui.NavBarUIManager;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
@@ -27,13 +28,10 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ComboBoxAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.wm.IdeRootPaneNorthExtension;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
@@ -43,10 +41,7 @@ import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
//TODO[kb]: cleanup
public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
private static final Icon CROSS_ICON = IconLoader.getIcon("/actions/cross.png");
private JComponent myWrapperPanel;
@NonNls public static final String NAV_BAR = "NavBar";
private Project myProject;
@@ -54,7 +49,6 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
private JPanel myRunPanel;
private boolean myNavToolbarGroupExist;
private JScrollPane myScrollPane;
private JLabel myCloseIcon;
public NavBarRootPaneExtension(Project project) {
myProject = project;
@@ -92,46 +86,17 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
if (UIUtil.isUnderAquaLookAndFeel() && !isMainToolbarVisible()) {
final Rectangle r = getBounds();
//g.setColor(new Color(0,0,0, 90));
//g.drawLine(0, r.height - 4, r.width, r.height - 4);
g.setColor(new Color(0, 0, 0, 90));
g.drawLine(0, r.height - 2, r.width, r.height - 2);
g.setColor(new Color(0, 0, 0, 20));
g.drawLine(0, r.height - 1, r.width, r.height - 1);
}
NavBarUIManager.getUI().doPaintWrapperPanelChildren((Graphics2D)g, getBounds(), isMainToolbarVisible());
}
@Override
protected void paintComponent(Graphics g) {
//if (!UIUtil.isUnderAquaLookAndFeel()) {
// super.paintComponent(g);
// return;
//}
final Rectangle r = getBounds();
if (isMainToolbarVisible()) {
g.setColor(new Color(200, 200, 200));
g.fillRect(0, 0, r.width, r.height);
}
else {
final Color startColor = UIUtil.isUnderAquaLookAndFeel() ? new Color(240, 240, 240) : UIUtil.getControlColor();
final Color endColor = ColorUtil.shift(startColor, 7.0d / 8.0d);
((Graphics2D)g).setPaint(new GradientPaint(0, 0, startColor, 0, r.height, endColor));
g.fillRect(0, 0, r.width, r.height);
//UIUtil.drawGradientHToolbarBackground(g, r.width, r.height);
}
NavBarUIManager.getUI().doPaintWrapperPanel((Graphics2D)g, getBounds(), isMainToolbarVisible());
}
@Override
public Insets getInsets() {
final Insets i = super.getInsets();
if (!UIUtil.isUnderAquaLookAndFeel()) {
return new Insets(0, 0, 0, 0);
}
return new Insets(i.top, i.left, i.bottom + 1, i.right);
return NavBarUIManager.getUI().getWrapperPanelInsets(super.getInsets());
}
};
myWrapperPanel.add(buildNavBarPanel(), BorderLayout.CENTER);
@@ -149,7 +114,6 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
final DefaultActionGroup group = (DefaultActionGroup)toolbarRunGroup;
final boolean needGap = isNeedGap(group);
final ActionToolbar actionToolbar = manager.createActionToolbar(ActionPlaces.NAVIGATION_BAR, group, true);
//actionToolbar.setLayoutPolicy(ActionToolbar.NOWRAP_LAYOUT_POLICY);
final JComponent component = actionToolbar.getComponent();
component.setOpaque(false);
myRunPanel = new JPanel(new BorderLayout());
@@ -208,7 +172,6 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
laf = LafManager.getInstance().getCurrentLookAndFeel().getName();
panel.get().removeAll();
myScrollPane = null;
myCloseIcon = null;
if (myNavigationBar != null && !Disposer.isDisposed(myNavigationBar)) {
Disposer.dispose(myNavigationBar);
}
@@ -220,25 +183,12 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
myScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
myScrollPane.setHorizontalScrollBar(null);
myScrollPane.setBorder(null);
myScrollPane.setOpaque(false);
myScrollPane.getViewport().setOpaque(false);
//panel.get().setBackground(UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground());
panel.get().setOpaque(true);//!UIUtil.isUnderAquaLookAndFeel() || UISettings.getInstance().SHOW_MAIN_TOOLBAR);
panel.get().setOpaque(true);
panel.get().setBorder(new NavBarBorder(true, 0));
myNavigationBar.setBorder(null);
panel.get().add(myScrollPane, BorderLayout.CENTER);
//if (!SystemInfo.isMac) {
// myCloseIcon = new JLabel(CROSS_ICON);
// myCloseIcon.addMouseListener(new MouseAdapter() {
// public void mouseClicked(final MouseEvent e) {
// UISettings.getInstance().SHOW_NAVIGATION_BAR = false;
// uiSettingsChanged(UISettings.getInstance());
// }
// });
// panel.get().add(myCloseIcon, BorderLayout.EAST);
//}
}
};
@@ -254,42 +204,7 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//if (UIUtil.isUnderAquaLookAndFeel()) {
final Rectangle r = getBounds();
final Graphics2D g2d = (Graphics2D)g;
//if (!isMainToolbarVisible() && UIUtil.isUnderAquaLookAndFeel()) {
//if (UIUtil.isUnderAquaLookAndFeel()) {
// final Dimension d = getPreferredSize();
// final int topOffset = UIUtil.isUnderAquaLookAndFeel() ? (r.height - d.height) / 2 + 2 : 0;
// UIUtil.drawDoubleSpaceDottedLine(g2d, topOffset, topOffset + d.height - 1, r.width - 1, Color.GRAY, false);
//} else {
// g2d.setPaint(getBackground());
// g2d.fillRect(0,0, r.width, r.height);
//}
//}
//else {
final boolean undocked = isUndocked();
final Color startColor = UIUtil.isUnderAquaLookAndFeel() ? new Color(240, 240, 240) : UIUtil.getControlColor();
final Color endColor = ColorUtil.shift(startColor, 7.0d / 8.0d);
g2d.setPaint(new GradientPaint(0, 0, startColor, 0, r.height, endColor));
g.fillRect(0, 0, r.width, r.height);
if (!undocked) {
g.setColor(new Color(255, 255, 255, 220));
g.drawLine(0, 1, r.width, 1);
}
g.setColor(UIUtil.getBorderColor());
if (!undocked) g.drawLine(0, 0, r.width, 0);
g.drawLine(0, r.height-1, r.width, r.height-1);
if (!isMainToolbarVisible()) {
UIUtil.drawDottedLine(g2d, r.width - 1, 0, r.width - 1, r.height, null, Color.GRAY);
}
//}
//} else {
// super.paintComponent(g);
//}
NavBarUIManager.getUI().doPaintNavBarPanel((Graphics2D)g, getBounds(), isMainToolbarVisible(), isUndocked());
}
@Override
@@ -300,19 +215,11 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
int x = insets.left;
if (myScrollPane == null) return;
final Component navBar = myScrollPane;
final Component closeLabel = myCloseIcon;
final Dimension preferredSize = navBar.getPreferredSize();
final Dimension closePreferredSize = closeLabel == null ? new Dimension() : closeLabel.getPreferredSize();
navBar.setBounds(x, insets.top + ((r.height - preferredSize.height - insets.top - insets.bottom) / 2),
r.width - insets.left - insets.right - closePreferredSize.width, preferredSize.height);
if (closeLabel != null) {
closeLabel.setBounds(x + r.width - insets.left - insets.right - closePreferredSize.width,
insets.top + ((r.height - closePreferredSize.height - insets.top - insets.bottom) / 2),
closePreferredSize.width, closePreferredSize.height);
}
r.width - insets.left - insets.right, preferredSize.height);
}
});
@@ -331,7 +238,6 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension {
if (myWrapperPanel.getComponentCount() > 0) {
final Component c = myWrapperPanel.getComponent(0);
if (c instanceof JComponent) ((JComponent)c).setOpaque(false);
//!UIUtil.isUnderAquaLookAndFeel() || isMainToolbarVisible());
}
}
}
@@ -0,0 +1,190 @@
/*
* Copyright 2000-2011 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.navigationToolbar.ui;
import com.intellij.ide.navigationToolbar.NavBarItem;
import com.intellij.ide.navigationToolbar.NavBarPanel;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.ColorUtil;
import com.intellij.util.IconUtil;
import com.intellij.util.ui.JBInsets;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Path2D;
/**
* @author Konstantin Bulenkov
*/
public abstract class AbstractNavBarUI implements NavBarUI {
//private static Image SEPARATOR_ACTIVE = IconUtil.toImage(IconLoader.getIcon("/general/navbarSeparatorActive.png"));
static Image SEPARATOR_PASSIVE = IconUtil.toImage(IconLoader.getIcon("/general/navbarSeparatorPassive.png"));
static Image SEPARATOR_GRADIENT = IconUtil.toImage(IconLoader.getIcon("/general/navbarSeparatorGradient.png"));
@Override
public Insets getElementIpad(boolean isPopupElement) {
return isPopupElement ? new Insets(1, 2, 1, 2) : JBInsets.NONE;
}
@Override
public JBInsets getElementPadding() {
return new JBInsets(3, 3, 3, 3);
}
@Override
public Font getElementFont(NavBarItem navBarItem) {
return navBarItem.getFont();
}
@Override
public Color getBackground(boolean selected, boolean focused) {
return selected && focused ? UIUtil.getListSelectionBackground() : UIUtil.getListBackground();
}
@Nullable
@Override
public Color getForeground(boolean selected, boolean focused, boolean inactive) {
return selected && focused ? UIUtil.getListSelectionForeground()
: inactive ? UIUtil.getInactiveTextColor() : null;
}
@Override
public short getSelectionAlpha() {
if ((UIUtil.isUnderAlloyLookAndFeel() && !UIUtil.isUnderAlloyIDEALookAndFeel())
|| UIUtil.isUnderMetalLookAndFeel()
|| UIUtil.isUnderMetalLookAndFeel()) {
return 255;
}
return 150;
}
@Override
public boolean isDrawMacShadow(boolean selected, boolean focused) {
return false;
}
@Override
public void doPaintNavBarItem(Graphics2D g, NavBarItem item, NavBarPanel navbar) {
Icon icon = item.getIcon();
final Color bg = item.isSelected() && item.isFocused()
? UIUtil.getListSelectionBackground()
: (UIUtil.isUnderGTKLookAndFeel() ? Color.WHITE : UIUtil.getListBackground());
final Color c = UIUtil.getListSelectionBackground();
final Color selBg = new Color(c.getRed(), c.getGreen(), c.getBlue(), getSelectionAlpha());
int w = item.getWidth();
int h = item.getHeight();
if (navbar.isInFloatingMode() || (item.isSelected() && navbar.hasFocus())) {
g.setPaint(item.isSelected() && item.isFocused() ? selBg : bg);
g.fillRect(0, 0, w - (item.isLastElement() ? 0 : getDecorationOffset()), h);
}
final int offset = item.isFirstElement() ? getFirstElementLeftOffset() : 0;
final int iconOffset = getElementPadding().left + offset;
icon.paintIcon(item, g, iconOffset, (h - icon.getIconHeight()) / 2);
final int textOffset = icon.getIconWidth() + getElementPadding().width() + offset;
int x = item.doPaintText(g, textOffset);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.translate(x, 0);
Path2D.Double path;
int off = getDecorationOffset();
if (item.isFocused()) {
if (item.isSelected() && !item.isLastElement()) {
path = new Path2D.Double();
g.translate(2, 0);
path.moveTo(0, 0);
path.lineTo(off, h / 2); // |\
path.lineTo(0, h); // |/
path.lineTo(0, 0);
g.setColor(selBg);
g.fill(path);
g.translate(-2, 0);
}
if (navbar.isInFloatingMode() || item.isNextSelected()) {
if (! item.isLastElement()) {
path = new Path2D.Double();
path.moveTo(0, 0);
path.lineTo(off, h / 2); // ___
path.lineTo(0, h); // \ |
path.lineTo(off + 2, h); // /_|
path.lineTo(off + 2, 0);
path.lineTo(0, 0);
g.setColor(item.isNextSelected() ? selBg : UIUtil.getListBackground());
g.fill(path);
}
}
}
if (! item.isLastElement() && ((!item.isSelected() && !item.isNextSelected()) || !navbar.hasFocus())) {
Image img = SEPARATOR_PASSIVE;
final UISettings settings = UISettings.getInstance();
if (settings.SHOW_NAVIGATION_BAR) {
img = SEPARATOR_GRADIENT;
}
g.drawImage(img, null, null);
}
}
private int getDecorationOffset() {
return 11;
}
private int getFirstElementLeftOffset() {
return 6;
}
@Override
public Dimension getOffsets(NavBarItem item) {
final Dimension size = new Dimension();
if (! item.isPopupElement()) {
size.width += getDecorationOffset() + getElementPadding().width() + (item.isFirstElement() ? getFirstElementLeftOffset() : 0);
size.height += getElementPadding().height();
}
return size;
}
@Override
public void doPaintWrapperPanelChildren(Graphics2D g, Rectangle bounds, boolean mainToolbarVisible) {
}
@Override
public Insets getWrapperPanelInsets(Insets insets) {
return JBInsets.NONE;
}
@Override
public void doPaintNavBarPanel(Graphics2D g, Rectangle r, boolean mainToolbarVisible, boolean undocked) {
final Color startColor = UIUtil.getControlColor();
final Color endColor = ColorUtil.shift(startColor, 7.0d / 8.0d);
g.setPaint(new GradientPaint(0, 0, startColor, 0, r.height, endColor));
g.fillRect(0, 0, r.width, r.height);
if (!undocked) {
g.setColor(new Color(255, 255, 255, 220));
g.drawLine(0, 1, r.width, 1);
}
g.setColor(UIUtil.getBorderColor());
if (!undocked) g.drawLine(0, 0, r.width, 0);
g.drawLine(0, r.height-1, r.width, r.height-1);
if (!mainToolbarVisible) {
UIUtil.drawDottedLine(g, r.width - 1, 0, r.width - 1, r.height, null, Color.GRAY);
}
}
}
@@ -0,0 +1,81 @@
/*
* Copyright 2000-2011 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.navigationToolbar.ui;
import com.intellij.ide.navigationToolbar.NavBarItem;
import com.intellij.util.ui.UIUtil;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class AquaNavBarUI extends AbstractNavBarUI {
@Override
public Font getElementFont(NavBarItem navBarItem) {
return UIUtil.getLabelFont().deriveFont(11.0f);
}
@Override
public boolean isDrawMacShadow(boolean selected, boolean focused) {
return !selected;
}
@Override
public void doPaintWrapperPanelChildren(Graphics2D g, Rectangle bounds, boolean mainToolbarVisible) {
super.doPaintWrapperPanelChildren(g, bounds, mainToolbarVisible);
if (!mainToolbarVisible) {
g.setColor(new Color(0, 0, 0, 90));
g.drawLine(0, bounds.height - 2, bounds.width, bounds.height - 2);
g.setColor(new Color(0, 0, 0, 20));
g.drawLine(0, bounds.height - 1, bounds.width, bounds.height - 1);
}
}
@Override
public void doPaintWrapperPanel(Graphics2D g, Rectangle bounds, boolean mainToolbarVisible) {
if (mainToolbarVisible) {
g.setColor(new Color(200, 200, 200));
g.fillRect(0, 0, bounds.width, bounds.height);
} else {
UIUtil.drawGradientHToolbarBackground(g, bounds.width, bounds.height);
}
}
@Override
public Insets getWrapperPanelInsets(Insets i) {
return new Insets(i.top, i.left, i.bottom + 1, i.right);
}
@Override
public void doPaintNavBarPanel(Graphics2D g, Rectangle r, boolean mainToolbarVisible, boolean undocked) {
g.setPaint(new GradientPaint(0, 0, new Color(240, 240, 240), 0, r.height, new Color(210, 210, 210)));
g.fillRect(0, 0, r.width, r.height);
if (!undocked) {
g.setColor(new Color(255, 255, 255, 220));
g.drawLine(0, 1, r.width, 1);
}
g.setColor(UIUtil.getBorderColor());
if (!undocked) g.drawLine(0, 0, r.width, 0);
g.drawLine(0, r.height-1, r.width, r.height-1);
if (!mainToolbarVisible) {
UIUtil.drawDottedLine(g, r.width - 1, 0, r.width - 1, r.height, null, Color.GRAY);
}
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2011 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.navigationToolbar.ui;
import com.intellij.ui.ColorUtil;
import com.intellij.util.ui.UIUtil;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class CommonNavBarUI extends AbstractNavBarUI {
@Override
public void doPaintWrapperPanel(Graphics2D g, Rectangle bounds, boolean mainToolbarVisible) {
if (mainToolbarVisible) {
g.setColor(new Color(200, 200, 200));
g.fillRect(0, 0, bounds.width, bounds.height);
} else {
final Color startColor = UIUtil.getControlColor();
final Color endColor = ColorUtil.shift(startColor, 7.0d / 8.0d);
g.setPaint(new GradientPaint(0, 0, startColor, 0, bounds.height, endColor));
g.fillRect(0, 0, bounds.width, bounds.height);
}
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2000-2011 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.navigationToolbar.ui;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class GtkNavBarUI extends CommonNavBarUI {
@Override
public Color getBackground(boolean selected, boolean focused) {
return selected && focused ? super.getBackground(selected, focused) : Color.WHITE;
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2000-2011 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.navigationToolbar.ui;
import com.intellij.ide.navigationToolbar.NavBarItem;
import com.intellij.ide.navigationToolbar.NavBarPanel;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public interface NavBarUI {
Insets getElementIpad(boolean isPopupElement);
Insets getElementPadding();
Font getElementFont(NavBarItem navBarItem);
short getSelectionAlpha();
boolean isDrawMacShadow(boolean selected, boolean focused);
void doPaintNavBarItem(Graphics2D g, NavBarItem item, NavBarPanel navbar);
Dimension getOffsets(NavBarItem item);
Color getBackground(boolean selected, boolean focused);
@Nullable
Color getForeground(boolean selected, boolean focused, boolean inactive);
void doPaintWrapperPanel(Graphics2D g, Rectangle bounds, boolean mainToolbarVisible);
void doPaintWrapperPanelChildren(Graphics2D g, Rectangle bounds, boolean mainToolbarVisible);
void doPaintNavBarPanel(Graphics2D g, Rectangle bounds, boolean mainToolbarVisible, boolean undocked);
Insets getWrapperPanelInsets(Insets insets);
}
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2011 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.navigationToolbar.ui;
import com.intellij.util.ui.UIUtil;
/**
* @author Konstantin Bulenkov
*/
public class NavBarUIManager {
public static final NavBarUI AQUA = new AquaNavBarUI();
public static final NavBarUI COMMON = new CommonNavBarUI();
public static final NavBarUI GTK = new GtkNavBarUI();
public static NavBarUI getUI() {
if (UIUtil.isUnderAquaLookAndFeel()) return AQUA;
if (UIUtil.isUnderGTKLookAndFeel()) return GTK;
return COMMON;
}
}
@@ -268,7 +268,8 @@ public class ActionMenuItem extends JCheckBoxMenuItem {
if (isToggleable() && myPresentation.getIcon() == null) {
action.update(myEvent);
myToggled = Boolean.TRUE.equals(myEvent.getPresentation().getClientProperty(Toggleable.SELECTED_PROPERTY));
if (ActionPlaces.MAIN_MENU.equals(myPlace) && SystemInfo.isMacSystemMenu) {
if (ActionPlaces.MAIN_MENU.equals(myPlace) && SystemInfo.isMacSystemMenu ||
UIUtil.isUnderWindowsLookAndFeel() || UIUtil.isUnderNimbusLookAndFeel()) {
setState(myToggled);
}
else if (!(getUI() instanceof GtkMenuItemUI)) {
@@ -168,7 +168,7 @@ public class FileTypeAssocTable<T> {
}
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < myMatchingMappings.size(); i++) {
for (int i = 0, n = myMatchingMappings.size(); i < n; i++) {
final Pair<FileNameMatcher, T> mapping = myMatchingMappings.get(i);
if (mapping.getFirst().accept(fileName)) return mapping.getSecond();
}
@@ -409,14 +409,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
return ((FileTypeIdentifiableByVirtualFile)type).isMyFileType(file);
}
final List<FileNameMatcher> matchers = getAssociations(type);
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = matchers.size(); i < size; i++) {
final FileNameMatcher matcher = matchers.get(i);
if (matcher.accept(file.getName())) return true;
}
return false;
return getFileTypeByFileName(file.getName()) == type;
}
@NotNull
@@ -156,7 +156,8 @@ library.attach.sources.description=Select jar/zip files or directories in which
module.module.language.level=&Language level:
module.module.language.level.comment=(effective on project reload)
module.circular.dependency.warning=<b>There {1, choice, 1#is circular dependency|2#are circular dependencies} between modules:</b> {0}
module.circular.dependency.warning.short=There is circular dependency between modules {0}
module.circular.dependency.warning.description=<html><b>There are circular dependencies between modules:</b> {0}</html>
module.add.error.message=Error adding module to project: {0}
module.add.error.title=Add Module
module.add.action=Add
@@ -565,6 +565,7 @@ todo.handler.only.in.changed=<html><body>There {0,choice, 1#was one|2#were {0}}
todo.handler.only.both=<html><body><b>There were {0, choice, 1#one|2#{0}} added or edited,</b><br/>\
and {1, choice, 1#one|2#{1}} located in changed {1,choice, 1#fragment|2#fragments} TODO items found.<br/>\
{2,choice, 0#|1#One file was skipped.|2#{2} files were skipped.}Would you like to review them?</body></html>
paths.affected.in.revision=Paths Affected in Revision {0}
#Dir diff
refresh.failed.message=Refresh failed: {0}
@@ -96,8 +96,6 @@ editor.mouseSelectionStateResetTimeout=1000
editor.mouseSelectionStateResetDeadzone=4
editor.use.new.tabs=true
ide.configuration.new.project.structure.errors=false
ide.tabbedPane.bufferedPaint=true
ide.tabbedPane.dragOutMultiplier=1.2
@@ -60,7 +60,7 @@ public class ShowAllAffectedGenericAction extends AnAction {
final AbstractVcs vcs = ProjectLevelVcsManager.getInstance(project).findVcsByName(vcsKey.getName());
if (vcs == null) return;
final String title = "Paths affected in revision " + revision.asString();
final String title = VcsBundle.message("paths.affected.in.revision", revision.asString());
final CommittedChangeList[] list = new CommittedChangeList[1];
final VcsException[] exc = new VcsException[1];
ProgressManager.getInstance().run(new Task.Backgroundable(project, title, true, BackgroundFromStartOption.getInstance()) {
@@ -717,7 +717,7 @@ public class DirDiffTableModel extends AbstractTableModel implements DirDiffMode
public void synchronizeAll() {
synchronized (myElements) {
for (DirDiffElement element : myElements) {
for (DirDiffElement element : myElements.toArray(new DirDiffElement[myElements.size()])) {
syncElement(element);
}
selectFirstRow();
@@ -99,7 +99,8 @@ public abstract class DiffActionExecutor {
final Ref<SimpleDiffRequest> requestRef = new Ref<SimpleDiffRequest>();
final Task.Backgroundable task = new Task.Backgroundable(myProject,
VcsBundle.message("show.diff.progress.title.detailed", mySelectedFile.getPath()), true, BackgroundFromStartOption.getInstance()) {
VcsBundle.message("show.diff.progress.title.detailed", mySelectedFile.getPresentableUrl()),
true, BackgroundFromStartOption.getInstance()) {
public void run(@NotNull ProgressIndicator indicator) {
final VcsRevisionNumber revisionNumber = getRevisionNumber();
@@ -410,6 +410,8 @@ public class GraphGutter {
}
private void drawConnectors(Graphics graphics, int lastIdx, int upBound, int idx, HashSet<Integer> selected, List<Integer> wiresGroups) {
((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
final Map<VirtualFile,WireEventsIterator> groupIterators = myModel.getGroupIterators(idx);
for (Map.Entry<VirtualFile, WireEventsIterator> entry : groupIterators.entrySet()) {
final WireEventsIterator eventsIterator = entry.getValue();
@@ -458,6 +460,8 @@ public class GraphGutter {
drawConnectorsFragment(graphics, idxFrom, yOff, used, new WireEvent(lastIdx, ArrayUtil.EMPTY_INT_ARRAY), selected, wiresGroups,
grey, wireModificationSet);
}
((Graphics2D) graphics).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
}
private void drawRepoBounds(Graphics graphics, int height, List<Integer> wiresGroups) {
@@ -0,0 +1,2 @@
if (a)
if (b) println 'hi'
@@ -0,0 +1 @@
if (a <spot>&&</spot> b) println 'hi'
@@ -0,0 +1,23 @@
<!--
~ Copyright 2000-2011 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.
-->
<html>
<body>
<span style="font-family: verdana,serif; font-size: smaller;">
This intention converts <b><font color="#000080">if</font></b> statement containing conjuction operation in it its condition
into two nested <b><font color="#000080">if</font></b> statements with simplified conditions. <br> <br>
</span>
</body>
</html>
+5
View File
@@ -705,6 +705,11 @@
<categoryKey>intention.category.groovy/intention.category.control.flow</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.control.DemorgansLawIntention</className>
</intentionAction>
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
<categoryKey>intention.category.groovy/intention.category.control.flow</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.control.SplitIfIntention</className>
</intentionAction>
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
<categoryKey>intention.category.groovy/intention.category.control.flow</categoryKey>
@@ -39,6 +39,8 @@ merge.else.if.intention.name=Merge else-if
merge.else.if.intention.family.name=Merge Else If
split.else.if.intention.name=Split else-if
split.else.if.intention.family.name=Split Else If
split.if.intention.name=Split into 2 if's
split.if.intention.family.name=Split into 2 if's
flip.conditional.intention.name=Flip ?:
flip.conditional.intention.family.name=Flip Conditional
conditional.to.elvis.intention.name=Convert Conditional to Elvis
@@ -0,0 +1,81 @@
/*
* Copyright 2000-2011 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 org.jetbrains.plugins.groovy.intentions.control;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.intentions.base.Intention;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
/**
* @author Brice Dutheil
* @author Hamlet D'Arcy
*/
public class SplitIfIntention extends Intention {
@Override
protected void processIntention(@NotNull PsiElement andElement, Project project, Editor editor) throws IncorrectOperationException {
GrBinaryExpression binaryExpression = (GrBinaryExpression) andElement.getParent();
GrIfStatement ifStatement = (GrIfStatement) binaryExpression.getParent();
GrExpression leftOperand = binaryExpression.getLeftOperand();
GrExpression rightOperand = binaryExpression.getRightOperand();
GrStatement thenBranch = ifStatement.getThenBranch();
assert thenBranch != null;
assert rightOperand != null;
GrStatement newSplittedIfs = GroovyPsiElementFactory.getInstance(project)
.createStatementFromText(
"if(" + leftOperand.getText() +
") { \n" +
" if(" + rightOperand.getText() + ")" +
thenBranch.getText() + "\n" +
"}"
);
ifStatement.replaceWithStatement(newSplittedIfs);
}
@NotNull
@Override
protected PsiElementPredicate getElementPredicate() {
return new PsiElementPredicate() {
@Override
public boolean satisfiedBy(PsiElement element) {
if ("&&".equals(element.getText()) &&
element.getParent() instanceof GrBinaryExpression &&
((GrBinaryExpression)element.getParent()).getRightOperand() != null &&
element.getParent().getParent() instanceof GrIfStatement &&
((GrIfStatement) element.getParent().getParent()).getElseBranch() == null
) {
return true;
}
return false;
}
};
}
}
@@ -0,0 +1,47 @@
/*
* Copyright 2000-2011 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 org.jetbrains.plugins.groovy.intentions
/**
* @author Brice Dutheil
* @author Hamlet D'Arcy
*/
class SplitIfTest extends GrIntentionTestCase {
public void test_that_two_binary_operand_are_split_into_2_if_statements() throws Exception {
doTextTest '''if(a <caret>&& b) {
c();
}
''',
'Split into 2 if\'s',
'''if (a) {
if (b) {
c();
}
}
'''
}
public void test_that_two_binary_operand_are_not_split_when_if_statements_has_else_branch() throws Exception {
doAntiTest '''if(a <caret>&& b) {
c();
} else {
d();
}
''',
'Split into 2 if\'s'
}
}
@@ -84,7 +84,7 @@ public class IdentifierSplitter extends BaseSplitter {
}
@NotNull
public static List<TextRange> splitByCase(@NotNull String text, @NotNull TextRange range) {
private static List<TextRange> splitByCase(@NotNull String text, @NotNull TextRange range) {
//System.out.println("text = " + text + " range = " + range);
List<TextRange> result = new ArrayList<TextRange>();
int i = range.getStartOffset();
@@ -92,6 +92,21 @@ public class IdentifierSplitter extends BaseSplitter {
int prevType = Character.MATH_SYMBOL;
while (i < range.getEndOffset()) {
final char ch = text.charAt(i);
if (ch >= '\u3040' && ch <= '\u309f' || // Hiragana
ch >= '\u30A0' && ch <= '\u30ff' || // Katakana
ch >= '\u4E00' && ch <= '\u9FFF' || // CJK Unified ideographs
ch >= '\uF900' && ch <= '\uFAFF' || // CJK Compatibility Ideographs
ch >= '\uFF00' && ch <= '\uFFEF' //Halfwidth and Fullwidth Forms of Katakana & Fullwidth ASCII variants
) {
if (s >= 0) {
add(text, result, i, s);
s = -1;
}
prevType = Character.MATH_SYMBOL;
++i;
continue;
}
final int type = Character.getType(ch);
if (type == Character.LOWERCASE_LETTER ||
type == Character.UPPERCASE_LETTER ||
@@ -52,17 +52,17 @@ public class PlainTextSplitter extends BaseSplitter {
if (Verifier.checkCharacterData(substring) != null) {
return;
}
for(int i = 0; i < text.length(); ++i) {
final char ch = text.charAt(i);
if (ch >= '\u3040' && ch <= '\u309f' || // Hiragana
ch >= '\u30A0' && ch <= '\u30ff' || // Katakana
ch >= '\u4E00' && ch <= '\u9FFF' || // CJK Unified ideographs
ch >= '\uF900' && ch <= '\uFAFF' || // CJK Compatibility Ideographs
ch >= '\uFF00' && ch <= '\uFFEF' //Halfwidth and Fullwidth Forms of Katakana & Fullwidth ASCII variants
) {
return;
}
}
//for(int i = 0; i < text.length(); ++i) {
// final char ch = text.charAt(i);
// if (ch >= '\u3040' && ch <= '\u309f' || // Hiragana
// ch >= '\u30A0' && ch <= '\u30ff' || // Katakana
// ch >= '\u4E00' && ch <= '\u9FFF' || // CJK Unified ideographs
// ch >= '\uF900' && ch <= '\uFAFF' || // CJK Compatibility Ideographs
// ch >= '\uFF00' && ch <= '\uFFEF' //Halfwidth and Fullwidth Forms of Katakana & Fullwidth ASCII variants
// ) {
// return;
// }
//}
List<TextRange> toCheck;
if (text.indexOf('@')>0) {
@@ -16,7 +16,7 @@
/** CJK Compatibility Ideographs (F900 - FAFF)
* 﨎鶴﨎鶴﨎鶴
*/
/* 私は<TYPO>Jaba</TYPO>が好きです。私は<TYPO>Jaba</TYPO>が好きです。*/
/**
* プロセス毎に使われるコールスタックは一つだけ !!!
*/
@@ -33,6 +33,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.history.CopyData;
import org.jetbrains.idea.svn.history.FirstInBranch;
import org.jetbrains.idea.svn.history.FirstInBranchAccurate;
import java.io.DataInput;
import java.io.DataOutput;
@@ -248,7 +249,7 @@ public class SvnBranchPointsCalculator {
public WrapperInvertor<BranchCopyData> convert(final KeyData keyData) {
final Ref<WrapperInvertor<BranchCopyData>> result = new Ref<WrapperInvertor<BranchCopyData>>();
new FirstInBranch(myVcs, keyData.getRepoUrl(), keyData.getTargetUrl(), keyData.getSourceUrl(), new Consumer<CopyData>() {
final Consumer<CopyData> consumer = new Consumer<CopyData>() {
public void consume(CopyData copyData) {
if (copyData != null) {
final boolean correct = copyData.isTrunkSupposedCorrect();
@@ -256,19 +257,29 @@ public class SvnBranchPointsCalculator {
if (correct) {
branchCopyData = new BranchCopyData(keyData.getSourceUrl(), copyData.getCopySourceRevision(), keyData.getTargetUrl(),
copyData.getCopyTargetRevision());
} else {
}
else {
branchCopyData = new BranchCopyData(keyData.getTargetUrl(), copyData.getCopySourceRevision(), keyData.getSourceUrl(),
copyData.getCopyTargetRevision());
}
result.set(new WrapperInvertor<BranchCopyData>(! correct, branchCopyData));
result.set(new WrapperInvertor<BranchCopyData>(!correct, branchCopyData));
}
}
}).run();
};
new FirstInBranch(myVcs, keyData.getRepoUrl(), keyData.getTargetUrl(), keyData.getSourceUrl(), consumer).run();
final WrapperInvertor<BranchCopyData> invertor = result.get();
WrapperInvertor<BranchCopyData> invertor = result.get();
if (LOG.isDebugEnabled()) {
LOG.debug("Loader returned: for key: " + keyData.toString() + " result: " + (invertor == null ? null : invertor.toString()));
}
if (invertor == null) {
new FirstInBranchAccurate(myVcs, keyData.getRepoUrl(), keyData.getTargetUrl(), keyData.getSourceUrl(), consumer).run();
invertor = result.get();
if (LOG.isDebugEnabled()) {
LOG.debug("Accurate Loader returned: for key: " + keyData.toString() + " result: " + (invertor == null ? null : invertor.toString()));
}
}
return invertor;
}
}
@@ -15,73 +15,32 @@
*/
package org.jetbrains.idea.svn.history;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.ConcurrentTasks;
import com.intellij.util.Consumer;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.ISVNLogEntryHandler;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNLogClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import java.util.Map;
public class FirstInBranch implements Runnable {
private final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.FirstInBranch");
private final SvnVcs myVcs;
private final String myFullBranchUrl;
private final String myFullTrunkUrl;
private final String myBranchUrl;
private final String myTrunkUrl;
private final Consumer<CopyData> myConsumer;
public FirstInBranch(final SvnVcs vcs, final String repositoryRoot, final String branchUrl, final String trunkUrl, final Consumer<CopyData> consumer) {
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranch created with: repoRoot: " + repositoryRoot + " branchUrl: " + branchUrl +
" trunkUrl: " + trunkUrl);
}
myVcs = vcs;
myConsumer = consumer;
myFullBranchUrl = branchUrl;
myFullTrunkUrl = trunkUrl;
myBranchUrl = relativePath(repositoryRoot, branchUrl);
myTrunkUrl = relativePath(repositoryRoot, trunkUrl);
public class FirstInBranch extends FirstInBranchAbstractBase {
public FirstInBranch(SvnVcs vcs,
String repositoryRoot,
String branchUrl,
String trunkUrl,
Consumer<CopyData> consumer) {
super(vcs, repositoryRoot, branchUrl, trunkUrl, consumer);
}
private String relativePath(final String parent, final String child) {
String path = SVNPathUtil.getRelativePath(parent, child);
return path.startsWith("/") ? path : "/" + path;
}
public void run() {
final SVNURL branchURL;
final SVNURL trunkURL;
try {
branchURL = SVNURL.parseURIEncoded(myFullBranchUrl);
trunkURL = SVNURL.parseURIEncoded(myFullTrunkUrl);
}
catch (SVNException e) {
LOG.info(e);
myConsumer.consume(null);
return;
}
final ConcurrentTasks<CopyData> tasks =
new ConcurrentTasks<CopyData>(ProgressManager.getInstance().getProgressIndicator(), createTask(branchURL), createTask(trunkURL));
tasks.compute();
if (tasks.isResultKnown()) {
myConsumer.consume(tasks.getResult());
} else {
myConsumer.consume(null);
}
}
private Consumer<Consumer<CopyData>> createTask(final SVNURL branchURL) {
protected Consumer<Consumer<CopyData>> createTask(final SVNURL branchURL) {
return new Consumer<Consumer<CopyData>>() {
public void consume(final Consumer<CopyData> copyDataConsumer) {
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranch started for: " + branchURL.toString());
}
final SVNLogClient logClient = myVcs.createLogClient();
final long start1 = getStart(logClient, branchURL);
if (start1 > 0) {
@@ -96,11 +55,17 @@ public class FirstInBranch implements Runnable {
LOG.info(e);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranch finished for: " + branchURL.toString());
}
}
};
}
private static long getStart(final SVNLogClient logClient, final SVNURL url) {
if (LOG.isDebugEnabled()) {
LOG.debug("getting start revision for: " + url);
}
final Ref<Long> myRevisionCandidate = new Ref<Long>(0L);
try {
logClient.doLog(url, null, SVNRevision.UNDEFINED, SVNRevision.HEAD, SVNRevision.create(0),
@@ -109,36 +74,18 @@ public class FirstInBranch implements Runnable {
ProgressManager.checkCanceled();
myRevisionCandidate.set(logEntry.getRevision());
if (LOG.isDebugEnabled()) {
LOG.debug("setting in cycle start revision for: " + url + " as: " + myRevisionCandidate.get());
}
}
});
}
catch (SVNException e) {
LOG.info(e);
}
if (LOG.isDebugEnabled()) {
LOG.debug("start revision for: " + url + " is: " + myRevisionCandidate.get());
}
return myRevisionCandidate.get();
}
private void checkForCopy(final SVNLogEntry logEntry, final Consumer<CopyData> result) {
final Map map = logEntry.getChangedPaths();
for (Object o : map.values()) {
final SVNLogEntryPath path = (SVNLogEntryPath) o;
final String localPath = path.getPath();
final String copyPath = path.getCopyPath();
if (LOG.isDebugEnabled()) {
LOG.debug("localPath: " + localPath + " copy path: " + copyPath);
}
if ('A' == path.getType()) {
if ((myBranchUrl.equals(localPath) || SVNPathUtil.isAncestor(localPath, myBranchUrl)) &&
((myTrunkUrl.equals(copyPath)) || SVNPathUtil.isAncestor(copyPath, myTrunkUrl))) {
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), true));
} else {
if ((myBranchUrl.equals(copyPath) || SVNPathUtil.isAncestor(copyPath, myBranchUrl)) &&
((myTrunkUrl.equals(localPath)) || SVNPathUtil.isAncestor(localPath, myTrunkUrl))) {
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), false));
}
}
}
}
}
}
@@ -0,0 +1,114 @@
/*
* Copyright 2000-2011 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 org.jetbrains.idea.svn.history;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.vcs.ConcurrentTasks;
import com.intellij.util.Consumer;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 11/15/11
* Time: 1:30 PM
*/
public abstract class FirstInBranchAbstractBase implements Runnable {
protected final static Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.FirstInBranch");
protected final SvnVcs myVcs;
protected final String myFullBranchUrl;
protected final String myFullTrunkUrl;
protected final String myBranchUrl;
protected final String myTrunkUrl;
protected final Consumer<CopyData> myConsumer;
public FirstInBranchAbstractBase(final SvnVcs vcs, final String repositoryRoot, final String branchUrl, final String trunkUrl,
final Consumer<CopyData> consumer) {
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranchAbstractBase created with: repoRoot: " + repositoryRoot + " branchUrl: " + branchUrl +
" trunkUrl: " + trunkUrl);
}
myVcs = vcs;
myConsumer = consumer;
myFullBranchUrl = branchUrl;
myFullTrunkUrl = trunkUrl;
myBranchUrl = relativePath(repositoryRoot, branchUrl);
myTrunkUrl = relativePath(repositoryRoot, trunkUrl);
}
private String relativePath(final String parent, final String child) {
String path = SVNPathUtil.getRelativePath(parent, child);
return path.startsWith("/") ? path : "/" + path;
}
public void run() {
final SVNURL branchURL;
final SVNURL trunkURL;
try {
branchURL = SVNURL.parseURIEncoded(myFullBranchUrl);
trunkURL = SVNURL.parseURIEncoded(myFullTrunkUrl);
}
catch (SVNException e) {
LOG.info(e);
myConsumer.consume(null);
return;
}
final ConcurrentTasks<CopyData> tasks =
new ConcurrentTasks<CopyData>(ProgressManager.getInstance().getProgressIndicator(), createTask(branchURL), createTask(trunkURL));
tasks.compute();
if (tasks.isResultKnown()) {
myConsumer.consume(tasks.getResult());
} else {
myConsumer.consume(null);
}
}
protected abstract Consumer<Consumer<CopyData>> createTask(final SVNURL branchURL);
protected void checkForCopy(final SVNLogEntry logEntry, final Consumer<CopyData> result) {
final Map map = logEntry.getChangedPaths();
for (Object o : map.values()) {
final SVNLogEntryPath path = (SVNLogEntryPath) o;
final String localPath = path.getPath();
final String copyPath = path.getCopyPath();
if (LOG.isDebugEnabled()) {
LOG.debug("localPath: " + localPath + " copy path: " + copyPath + " revision: " + logEntry.getRevision());
}
if ('A' == path.getType()) {
if ((myBranchUrl.equals(localPath) || SVNPathUtil.isAncestor(localPath, myBranchUrl)) &&
((myTrunkUrl.equals(copyPath)) || SVNPathUtil.isAncestor(copyPath, myTrunkUrl))) {
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), true));
} else {
if ((myBranchUrl.equals(copyPath) || SVNPathUtil.isAncestor(copyPath, myBranchUrl)) &&
((myTrunkUrl.equals(localPath)) || SVNPathUtil.isAncestor(localPath, myTrunkUrl))) {
result.consume(new CopyData(path.getCopyRevision(), logEntry.getRevision(), false));
}
}
}
}
}
}
@@ -0,0 +1,65 @@
/*
* Copyright 2000-2011 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 org.jetbrains.idea.svn.history;
import com.intellij.util.Consumer;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.ISVNLogEntryHandler;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.SVNLogClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
/**
* Created by IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 11/15/11
* Time: 1:23 PM
*/
public class FirstInBranchAccurate extends FirstInBranchAbstractBase {
public FirstInBranchAccurate(SvnVcs vcs,
String repositoryRoot,
String branchUrl,
String trunkUrl,
Consumer<CopyData> consumer) {
super(vcs, repositoryRoot, branchUrl, trunkUrl, consumer);
}
@Override
protected Consumer<Consumer<CopyData>> createTask(final SVNURL branchURL) {
return new Consumer<Consumer<CopyData>>() {
public void consume(final Consumer<CopyData> copyDataConsumer) {
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranchAccurate started for: " + branchURL.toString());
}
final SVNLogClient logClient = myVcs.createLogClient();
try {
logClient.doLog(branchURL, null, SVNRevision.UNDEFINED, SVNRevision.HEAD, SVNRevision.create(0), true, true, 1, new ISVNLogEntryHandler() {
public void handleLogEntry(SVNLogEntry logEntry) throws SVNException {
checkForCopy(logEntry, copyDataConsumer);
}
});
} catch (SVNException e) {
LOG.info(e);
}
if (LOG.isDebugEnabled()) {
LOG.debug("FirstInBranchAccurate finished for: " + branchURL.toString());
}
}
};
}
}