/* * Copyright 2000-2009 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.vcs.ex; import com.intellij.diff.util.DiffUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.markup.RangeHighlighter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; public class Range { private static final Logger LOG = Logger.getInstance(Range.class); public static final byte EQUAL = 0; public static final byte MODIFIED = 1; public static final byte INSERTED = 2; public static final byte DELETED = 3; // (2,3) - modified 2nd line // (2,2) - empty range between 1 and 2 lines // index of first line is 0 private int myLine1; private int myLine2; private final int myVcsLine1; private final int myVcsLine2; @Nullable private final List<InnerRange> myInnerRanges; @Nullable private RangeHighlighter myRangeHighlighter; private boolean myValid = true; public Range(@NotNull Range range) { this(range.getLine1(), range.getLine2(), range.getVcsLine1(), range.getVcsLine2()); } public Range(int line1, int line2, int vcsLine1, int vcsLine2) { this(line1, line2, vcsLine1, vcsLine2, null); } public Range(int line1, int line2, int vcsLine1, int vcsLine2, @Nullable List<InnerRange> innerRanges) { assert line1 != line2 || vcsLine1 != vcsLine2; myLine1 = line1; myLine2 = line2; myVcsLine1 = vcsLine1; myVcsLine2 = vcsLine2; myInnerRanges = innerRanges; } public int hashCode() { return myVcsLine1 ^ myVcsLine2 ^ myLine1 ^ myLine2; } public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Range range = (Range)o; if (myLine1 != range.myLine1) return false; if (myLine2 != range.myLine2) return false; if (myVcsLine1 != range.myVcsLine1) return false; if (myVcsLine2 != range.myVcsLine2) return false; if (myInnerRanges == null) return range.myInnerRanges == null; if (range.myInnerRanges == null) return false; if (myInnerRanges.size() != range.myInnerRanges.size()) return false; for (int i = 0; i < myInnerRanges.size(); i++) { if (!myInnerRanges.get(i).equals(range.myInnerRanges.get(i))) return false; } return true; } public String toString() { return String.format("%s, %s, %s, %s", myLine1, myLine2, myVcsLine1, myVcsLine2); } public byte getType() { if (myLine1 == myLine2) return DELETED; if (myVcsLine1 == myVcsLine2) return INSERTED; return MODIFIED; } public void shift(int shift) { myLine1 += shift; myLine2 += shift; if (myInnerRanges != null) { for (InnerRange range : myInnerRanges) { range.shift(shift); } } } @Nullable public List<InnerRange> getInnerRanges() { return myInnerRanges; } public int getLine1() { return myLine1; } public int getLine2() { return myLine2; } public int getVcsLine1() { return myVcsLine1; } public int getVcsLine2() { return myVcsLine2; } public boolean hasHighlighter() { return myRangeHighlighter != null; } public void setHighlighter(@Nullable RangeHighlighter highlighter) { myRangeHighlighter = highlighter; } @Nullable public RangeHighlighter getHighlighter() { return myRangeHighlighter; } public boolean isValid() { return myValid; } public void invalidate() { myValid = false; } public static class InnerRange { private int myLine1; private int myLine2; private final byte myType; public InnerRange(int line1, int line2, byte type) { myLine1 = line1; myLine2 = line2; myType = type; } public int getLine1() { return myLine1; } public int getLine2() { return myLine2; } public byte getType() { return myType; } public void shift(int shift) { myLine1 += shift; myLine2 += shift; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; InnerRange range = (InnerRange)o; if (myLine1 != range.myLine1) return false; if (myLine2 != range.myLine2) return false; if (myType != range.myType) return false; return true; } @Override public int hashCode() { int result = myLine1; result = 31 * result + myLine2; result = 31 * result + (int)myType; return result; } public String toString() { return String.format("%s, %s, %s", myLine1, myLine2, getTypeName(myType)); } } /* * Check, if caret at <line> is corresponds to the current range */ public boolean isSelectedByLine(int line) { return DiffUtil.isSelectedByLine(line, myLine1, myLine2); } @NotNull private static String getTypeName(byte type) { switch (type) { case MODIFIED: return "MODIFIED"; case INSERTED: return "INSERTED"; case DELETED: return "DELETED"; case EQUAL: return "EQUAL"; } return "UNKNOWN(" + type + ")"; } }