alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.ui;

import com.ibm.icu.text.DateFormat;
import java.util.Date;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.*;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;

/**
 * This class provides the table and it's required components for a file's revision
 * history
 */
public class HistoryTableProvider {

	private ICVSFile currentFile;
	private String currentRevision;
	private TableViewer viewer;
	private Font currentRevisionFont;
	
	/**
	 * Constructor for HistoryTableProvider.
	 */
	public HistoryTableProvider() {
		super();
	}

	//column constants
	private static final int COL_REVISION = 0;
	private static final int COL_TAGS = 1;
	private static final int COL_DATE = 2;
	private static final int COL_AUTHOR = 3;
	private static final int COL_COMMENT = 4;

	/**
	 * The history label provider.
	 */
	class HistoryLabelProvider extends LabelProvider implements ITableLabelProvider, IColorProvider, IFontProvider {
		private DateFormat dateFormat;
		public Image getColumnImage(Object element, int columnIndex) {
			return null;
		}
		public String getColumnText(Object element, int columnIndex) {
			ILogEntry entry = adaptToLogEntry(element);
			if (entry == null) return ""; //$NON-NLS-1$
			switch (columnIndex) {
				case COL_REVISION:
					String revision = entry.getRevision();
					String currentRevision = getCurrentRevision();
					if (currentRevision != null && currentRevision.equals(revision)) {
						revision = NLS.bind(CVSUIMessages.currentRevision, new String[] { revision }); 
					}
					return revision;
				case COL_TAGS:
					CVSTag[] tags = entry.getTags();
					StringBuffer result = new StringBuffer();
					for (int i = 0; i < tags.length; i++) {
						result.append(tags[i].getName());
						if (i < tags.length - 1) {
							result.append(", "); //$NON-NLS-1$
						}
					}
					return result.toString();
				case COL_DATE:
					Date date = entry.getDate();
					if (date == null) return CVSUIMessages.notAvailable; 
					return getDateFormat().format(date);
				case COL_AUTHOR:
					return entry.getAuthor();
				case COL_COMMENT:
					String comment = entry.getComment();
					int index = comment.indexOf("\n"); //$NON-NLS-1$
					switch (index) {
						case -1:
							return comment;
						case 0:
							return CVSUIMessages.HistoryView_______4; 
						default:
							return NLS.bind(CVSUIMessages.CVSCompareRevisionsInput_truncate, new String[] { comment.substring(0, index) }); 
					}
			}
			return ""; //$NON-NLS-1$
		}
		
		private synchronized DateFormat getDateFormat() {
			if (dateFormat == null)
				dateFormat = DateFormat.getInstance();
			return dateFormat;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object)
		 */
		public Color getForeground(Object element) {
			ILogEntry entry = adaptToLogEntry(element);
			if (entry.isDeletion())  {
				return Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
			} else  {
				return null;
			}
		}
		/* (non-Javadoc)
		 * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object)
		 */
		public Color getBackground(Object element) {
			return null;
		}
		/*
		 * (non-Javadoc)
		 * @see org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object)
		 */
		public Font getFont(Object element) {
			ILogEntry entry = adaptToLogEntry(element);
			if (entry == null)
				return null;
			String revision = entry.getRevision();
			String currentRevision = getCurrentRevision();
			if (currentRevision != null && currentRevision.equals(revision)) {
				if (currentRevisionFont == null) {
					Font defaultFont = JFaceResources.getDefaultFont();
					FontData[] data = defaultFont.getFontData();
					for (int i = 0; i < data.length; i++) {
						data[i].setStyle(SWT.BOLD);
					}				
					currentRevisionFont = new Font(viewer.getTable().getDisplay(), data);
				}
				return currentRevisionFont;
			}
			return null;
		}
	}

	/**
	 * The history sorter
	 */
	class HistoryComparator extends ViewerComparator {
		private boolean reversed = false;
		private int columnNumber;
		
		private VersionCollator versionCollator = new VersionCollator();
		
		// column headings:	"Revision" "Tags" "Date" "Author" "Comment"
		private int[][] SORT_ORDERS_BY_COLUMN = {
			{COL_REVISION, COL_DATE, COL_AUTHOR, COL_COMMENT, COL_TAGS},	/* revision */ 
			{COL_TAGS, COL_REVISION, COL_DATE, COL_AUTHOR, COL_COMMENT},	/* tags */
			{COL_DATE, COL_REVISION, COL_AUTHOR, COL_COMMENT, COL_TAGS},	/* date */
			{COL_AUTHOR, COL_REVISION, COL_DATE, COL_COMMENT, COL_TAGS},	/* author */
			{COL_COMMENT, COL_REVISION, COL_DATE, COL_AUTHOR, COL_TAGS}		/* comment */
		};
		
		/**
		 * The constructor.
		 */
		public HistoryComparator(int columnNumber) {
			this.columnNumber = columnNumber;
		}
		/**
		 * Compares two log entries, sorting first by the main column of this sorter,
		 * then by subsequent columns, depending on the column sort order.
		 */
		public int compare(Viewer viewer, Object o1, Object o2) {
			ILogEntry e1 = adaptToLogEntry(o1);
			ILogEntry e2 = adaptToLogEntry(o2);
			int result = 0;
			if (e1 == null || e2 == null) {
				result = super.compare(viewer, o1, o2);
			} else {
				int[] columnSortOrder = SORT_ORDERS_BY_COLUMN[columnNumber];
				for (int i = 0; i < columnSortOrder.length; ++i) {
					result = compareColumnValue(columnSortOrder[i], e1, e2);
					if (result != 0)
						break;
				}
			}
			if (reversed)
				result = -result;
			return result;
		}
		/**
		 * Compares two markers, based only on the value of the specified column.
		 */
		int compareColumnValue(int columnNumber, ILogEntry e1, ILogEntry e2) {
			switch (columnNumber) {
				case 0: /* revision */
					return versionCollator.compare(e1.getRevision(), e2.getRevision());
				case 1: /* tags */
					CVSTag[] tags1 = e1.getTags();
					CVSTag[] tags2 = e2.getTags();
					if (tags2.length == 0) {
						return -1;
					}
					if (tags1.length == 0) {
						return 1;
					}
					return getComparator().compare(tags1[0].getName(), tags2[0].getName());
				case 2: /* date */
					Date date1 = e1.getDate();
					Date date2 = e2.getDate();
					return date1.compareTo(date2);
				case 3: /* author */
					return getComparator().compare(e1.getAuthor(), e2.getAuthor());
				case 4: /* comment */
					return getComparator().compare(e1.getComment(), e2.getComment());
				default:
					return 0;
			}
		}
		/**
		 * Returns the number of the column by which this is sorting.
		 */
		public int getColumnNumber() {
			return columnNumber;
		}
		/**
		 * Returns true for descending, or false
		 * for ascending sorting order.
		 */
		public boolean isReversed() {
			return reversed;
		}
		/**
		 * Sets the sorting order.
		 */
		public void setReversed(boolean newReversed) {
			reversed = newReversed;
		}
	}

	protected ILogEntry adaptToLogEntry(Object element) {
		// Get the log entry for the provided object
		ILogEntry entry = null;
		if (element instanceof ILogEntry) {
			entry = (ILogEntry) element;
		} else if (element instanceof IAdaptable) {
			entry = (ILogEntry)((IAdaptable)element).getAdapter(ILogEntry.class);
		}
		return entry;
	}
	
	/**
	 * Create a TableViewer that can be used to display a list of ILogEntry instances.
	 * Ths method provides the labels and sorter but does not provide a content provider
	 * 
	 * @param parent
	 * @return TableViewer
	 */
	public TableViewer createTable(Composite parent) {
		Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		GridData data = new GridData(GridData.FILL_BOTH);
		table.setLayoutData(data);
	
		TableLayout layout = new TableLayout();
		table.setLayout(layout);
		
		TableViewer viewer = new TableViewer(table);
		
		createColumns(table, layout, viewer);

		viewer.setLabelProvider(new HistoryLabelProvider());
		
		// By default, reverse sort by revision.
		HistoryComparator sorter = new HistoryComparator(COL_REVISION);
		sorter.setReversed(true);
		viewer.setComparator(sorter);
		
		table.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				if(currentRevisionFont != null) {
					currentRevisionFont.dispose();
				}
			}
		});
		
		this.viewer = viewer;
		return viewer;
	}

	/**
	 * Create a CheckBoxTableViewer that can be used to display a list of ILogEntry instances.
	 * Ths method provides the labels and sorter but does not provide a content provider
	 * 
	 * @param parent
	 * @return TableViewer
	 */
	public CheckboxTableViewer createCheckBoxTable(Composite parent) {
		Table table = new Table(parent, SWT.CHECK | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		GridData data = new GridData(GridData.FILL_BOTH);
		table.setLayoutData(data);
	
		TableLayout layout = new TableLayout();
		table.setLayout(layout);
		
		CheckboxTableViewer viewer = new CheckboxTableViewer(table);
		
		createColumns(table, layout, viewer);

		viewer.setLabelProvider(new HistoryLabelProvider());
		
		// By default, reverse sort by revision.
		HistoryComparator sorter = new HistoryComparator(COL_REVISION);
		sorter.setReversed(true);
		viewer.setComparator(sorter);
		
		table.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				if(currentRevisionFont != null) {
					currentRevisionFont.dispose();
				}
			}
		});
		
		this.viewer = viewer;
		return viewer;
	}
	
	/**
	 * Creates the columns for the history table.
	 */
	private void createColumns(Table table, TableLayout layout, TableViewer viewer) {
		SelectionListener headerListener = getColumnListener(viewer);
		// revision
		TableColumn col = new TableColumn(table, SWT.NONE);
		col.setResizable(true);
		col.setText(CVSUIMessages.HistoryView_revision); 
		col.addSelectionListener(headerListener);
		layout.addColumnData(new ColumnWeightData(20, true));
	
		// tags
		col = new TableColumn(table, SWT.NONE);
		col.setResizable(true);
		col.setText(CVSUIMessages.HistoryView_tags); 
		col.addSelectionListener(headerListener);
		layout.addColumnData(new ColumnWeightData(20, true));
	
		// creation date
		col = new TableColumn(table, SWT.NONE);
		col.setResizable(true);
		col.setText(CVSUIMessages.HistoryView_date); 
		col.addSelectionListener(headerListener);
		layout.addColumnData(new ColumnWeightData(20, true));
	
		// author
		col = new TableColumn(table, SWT.NONE);
		col.setResizable(true);
		col.setText(CVSUIMessages.HistoryView_author); 
		col.addSelectionListener(headerListener);
		layout.addColumnData(new ColumnWeightData(20, true));
	
		//comment
		col = new TableColumn(table, SWT.NONE);
		col.setResizable(true);
		col.setText(CVSUIMessages.HistoryView_comment); 
		col.addSelectionListener(headerListener);
		layout.addColumnData(new ColumnWeightData(50, true));
	}

	/**
	 * Adds the listener that sets the sorter.
	 */
	private SelectionListener getColumnListener(final TableViewer tableViewer) {
		/**
	 	 * This class handles selections of the column headers.
		 * Selection of the column header will cause resorting
		 * of the shown tasks using that column's sorter.
		 * Repeated selection of the header will toggle
		 * sorting order (ascending versus descending).
		 */
		return new SelectionAdapter() {
			/**
			 * Handles the case of user selecting the
			 * header area.
			 * <p>If the column has not been selected previously,
			 * it will set the sorter of that column to be
			 * the current tasklist sorter. Repeated
			 * presses on the same column header will
			 * toggle sorting order (ascending/descending).
			 */
			public void widgetSelected(SelectionEvent e) {
				// column selected - need to sort
				int column = tableViewer.getTable().indexOf((TableColumn) e.widget);
				HistoryComparator oldSorter = (HistoryComparator)tableViewer.getComparator();
				if (oldSorter != null && column == oldSorter.getColumnNumber()) {
					oldSorter.setReversed(!oldSorter.isReversed());
					tableViewer.refresh();
				} else {
					tableViewer.setComparator(new HistoryComparator(column));
				}
			}
		};
	}
	
	public String getCurrentRevision() {
		return currentRevision;
	}
		
	/**
	 * Method getRevision.
	 * @param currentEdition
	 */
	private String getRevision(ICVSFile currentEdition) throws CVSException {
		if (currentEdition == null) return ""; //$NON-NLS-1$
		ResourceSyncInfo info = currentEdition.getSyncInfo();
		if (info == null) return ""; //$NON-NLS-1$
		return info.getRevision();
	}
	
	public void setFile(ICVSFile file) throws CVSException {
		this.currentFile = file;
		this.currentRevision = getRevision(this.currentFile);
	}

	public ICVSFile getICVSFile() {
		return this.currentFile;
	}
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.