All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jmeld.ui.RevisionBar Maven / Gradle / Ivy

Go to download

A visual diff and merge tool. It is built to be fast with large files and runs on any operating system.

The newest version!
/*
   JMeld is a visual diff and merge tool.
   Copyright (C) 2007  Kees Kuip
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA  02110-1301  USA
 */
package org.jmeld.ui;

import org.jmeld.diff.JMChunk;
import org.jmeld.diff.JMDelta;
import org.jmeld.diff.JMRevision;
import org.jmeld.ui.text.BufferDocumentIF;
import org.jmeld.ui.util.ColorUtil;
import org.jmeld.ui.util.Colors;
import org.jmeld.ui.util.RevisionUtil;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class RevisionBar
    extends JComponent
{
  private BufferDiffPanel diffPanel;
  private FilePanel filePanel;
  private boolean original;

  public RevisionBar(BufferDiffPanel diffPanel, FilePanel filePanel,
      boolean original)
  {
    this.diffPanel = diffPanel;
    this.filePanel = filePanel;
    this.original = original;

    setBorder(BorderFactory.createLineBorder(ColorUtil.darker(ColorUtil
        .darker(Colors.getPanelBackground()))));

    addMouseListener(getMouseListener());
  }

  private MouseListener getMouseListener()
  {
    return new MouseAdapter()
    {
      public void mouseClicked(MouseEvent me)
      {
        Rectangle r;
        int y;
        int line;
        int lineBefore;
        int lineAfter;
        JMRevision revision;
        Point p;
        BufferDocumentIF bd;
        int offset;
        JTextComponent editor;
        JViewport viewport;
        int numberOfLines;
        JMChunk original;

        r = getDrawableRectangle();
        if (r == null)
        {
          return;
        }

        if (r.height <= 0)
        {
          return;
        }

        y = me.getY() - r.y;

        revision = diffPanel.getCurrentRevision();
        if (revision == null)
        {
          return;
        }

        numberOfLines = getNumberOfLines(revision);
        line = (y * numberOfLines) / r.height;
        if (line > numberOfLines)
        {
          line = numberOfLines;
        }

        if (line < 0)
        {
          line = 0;
        }

        // If the files are very large the resolution of one pixel contains 
        //   a lot of lines of the document. Check if there is a chunk in 
        //   the revision between those lines and if there is position on 
        //   that chunk.
        lineBefore = ((y - 3) * numberOfLines) / r.height;
        lineAfter = ((y + 3) * numberOfLines) / r.height;
        for (JMDelta delta : revision.getDeltas())
        {
          original = delta.getOriginal();

          // The chunk starts within the bounds of the line-resolution.
          if (original.getAnchor() > lineBefore
              && original.getAnchor() < lineAfter)
          {
            diffPanel.doGotoDelta(delta);
            return;
          }
        }

        diffPanel.doGotoLine(line);
      }
    };
  }

  /** Calculate the rectangle that can be used to draw the diffs.
   *    It is essentially the size of the scrollbar minus its buttons.
   */
  private Rectangle getDrawableRectangle()
  {
    JScrollBar sb;
    Rectangle r;
    int buttonHeight;

    sb = filePanel.getScrollPane().getVerticalScrollBar();
    r = sb.getBounds();
    r.x = 0;
    r.y = 0;

    for (Component c : sb.getComponents())
    {
      if (c instanceof AbstractButton)
      {
        r.y += c.getHeight();
        r.height -= (2 * c.getHeight());
        break;
      }
    }

    return r;
  }

  public void paintComponent(Graphics g)
  {
    Rectangle r;
    Graphics2D g2;
    JMRevision revision;
    JMChunk chunk;
    int y;
    int height;
    int numberOfLines;
    Rectangle clipBounds;

    g2 = (Graphics2D) g;

    clipBounds = g.getClipBounds();

    r = getDrawableRectangle();
    r.x = clipBounds.x;
    r.width = clipBounds.width;

    g2.setColor(Color.white);
    g2.fill(r);

    revision = diffPanel.getCurrentRevision();
    if (revision == null)
    {
      return;
    }

    numberOfLines = getNumberOfLines(revision);
    if (numberOfLines <= 0)
    {
      return;
    }

    for (JMDelta delta : revision.getDeltas())
    {
      chunk = original ? delta.getOriginal() : delta.getRevised();

      g.setColor(RevisionUtil.getColor(delta));
      y = r.y + (r.height * chunk.getAnchor()) / numberOfLines;
      height = (r.height * chunk.getSize()) / numberOfLines;
      if (height <= 0)
      {
        height = 1;
      }

      g.fillRect(0, y, r.width, height);
    }
  }

  private int getNumberOfLines(JMRevision revision)
  {
    return original ? revision.getOrgSize() : revision.getRevSize();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy