| /******************************************************************************* |
| * Copyright (c) 2006, 2013 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Brock Janiczak (brockj@tpg.com.au) - Bug 180436 Use table sort indicators on CVS |
| * Brock Janiczak (brockj@tpg.com.au) - Bug 181899 CVS History wrongly ordered |
| * Brock Janiczak <brockj@tpg.com.au> - Bug 182442 Display full comment in tooltip |
| * Olexiy Buyanskyy <olexiyb@gmail.com> - Bug 76386 - [History View] CVS Resource History shows revisions from all branches |
| *******************************************************************************/ |
| package org.eclipse.team.internal.ccvs.ui; |
| |
| import java.util.Date; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.layout.PixelConverter; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.jface.util.IPropertyChangeListener; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| 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.core.history.*; |
| import org.eclipse.team.internal.ccvs.core.CVSException; |
| import org.eclipse.team.internal.ccvs.core.ICVSFile; |
| import org.eclipse.team.internal.ccvs.core.filehistory.CVSFileRevision; |
| import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; |
| import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; |
| import org.eclipse.team.internal.core.history.LocalFileRevision; |
| import org.eclipse.team.internal.ui.TeamUIMessages; |
| import org.eclipse.team.internal.ui.history.AbstractHistoryCategory; |
| import org.eclipse.team.internal.ui.history.DateHistoryCategory; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.themes.ITheme; |
| |
| import com.ibm.icu.text.DateFormat; |
| |
| public class CVSHistoryTableProvider { |
| |
| public static final String CATEGORIES_COLOR = "org.eclipse.team.cvs.ui.fontsandcolors.cvshistorypagecategories"; //$NON-NLS-1$ |
| |
| private IFileHistory currentFileHistory; |
| private IFile workspaceFile; |
| |
| /* private */TreeViewer viewer; |
| /* private */Font currentRevisionFont; |
| |
| private boolean baseModified; |
| |
| private IDialogSettings settings; |
| |
| //column constants |
| private static final int COL_REVISIONID = 0; |
| private static final int COL_BRANCHES = 1; |
| private static final int COL_TAGS = 2; |
| private static final int COL_DATE = 3; |
| private static final int COL_AUTHOR = 4; |
| private static final int COL_COMMENT = 5; |
| |
| // cvs history table provider settings section name |
| private static final String CVS_HISTORY_TABLE_PROVIDER_SECTION = CVSHistoryTableProvider.class.getName(); |
| |
| // cvs history table provider settings keys |
| private static final String COL_REVISIONID_NAME = "COL_REVISIONID"; //$NON-NLS-1$ |
| private static final String COL_BRANCHES_NAME = "COL_BRANCHES"; //$NON-NLS-1$ |
| private static final String COL_TAGS_NAME = "COL_TAGS"; //$NON-NLS-1$ |
| private static final String COL_DATE_NAME = "COL_DATE"; //$NON-NLS-1$ |
| private static final String COL_AUTHOR_NAME = "COL_AUTHOR"; //$NON-NLS-1$ |
| private static final String COL_COMMENT_NAME = "COL_COMMENT"; //$NON-NLS-1$ |
| |
| private static final String COL_NAME = "COLUMN_NAME"; //$NON-NLS-1$ |
| private static final String SORT_COL_NAME = "SORT_COL_NAME"; //$NON-NLS-1$ |
| private static final String SORT_COL_DIRECTION = "SORT_COL_DIRECTION"; //$NON-NLS-1$ |
| |
| public CVSHistoryTableProvider() { |
| IDialogSettings viewsSettings = CVSUIPlugin.getPlugin() |
| .getDialogSettings(); |
| settings = viewsSettings.getSection(CVS_HISTORY_TABLE_PROVIDER_SECTION); |
| if (settings == null) { |
| settings = viewsSettings |
| .addNewSection(CVS_HISTORY_TABLE_PROVIDER_SECTION); |
| } |
| } |
| |
| /** |
| * The history label provider. |
| */ |
| class HistoryLabelProvider extends ColumnLabelProvider { |
| |
| Image dateImage = null; |
| ImageDescriptor dateDesc = null; |
| |
| Image localRevImage = null; |
| ImageDescriptor localRevDesc = null; |
| |
| Image remoteRevImage = null; |
| ImageDescriptor remoteRevDesc = null; |
| |
| ThemeListener themeListener; |
| private DateFormat dateFormat; |
| private final int column; |
| |
| public HistoryLabelProvider(int column, CVSHistoryTableProvider provider){ |
| this.column = column; |
| PlatformUI.getWorkbench().getThemeManager().addPropertyChangeListener(themeListener= new ThemeListener(provider)); |
| } |
| |
| @Override |
| public void dispose() { |
| if (dateImage != null){ |
| dateImage.dispose(); |
| dateImage = null; |
| } |
| |
| if (localRevImage != null) { |
| localRevImage.dispose(); |
| localRevImage = null; |
| } |
| |
| if (remoteRevImage != null) { |
| remoteRevImage.dispose(); |
| remoteRevImage = null; |
| } |
| |
| if (themeListener != null){ |
| PlatformUI.getWorkbench().getThemeManager().removePropertyChangeListener(themeListener); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipText(java.lang.Object) |
| */ |
| @Override |
| public String getToolTipText(Object element) { |
| if (column == COL_COMMENT && !isSingleLine(element)) { |
| IFileRevision entry = adaptToFileRevision(element); |
| if (entry != null) |
| return entry.getComment(); |
| } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.CellLabelProvider#useNativeToolTip(java.lang.Object) |
| */ |
| @Override |
| public boolean useNativeToolTip(Object object) { |
| return column != COL_COMMENT || isSingleLine(object); |
| } |
| |
| private boolean isSingleLine(Object object) { |
| IFileRevision entry = adaptToFileRevision(object); |
| if (entry != null) |
| return entry.getComment() == null || entry.getComment().indexOf('\n') == -1; |
| return true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ColumnLabelProvider#getImage(java.lang.Object) |
| */ |
| @Override |
| public Image getImage(Object element) { |
| return getColumnImage(element, column); |
| } |
| |
| public Image getColumnImage(Object element, int columnIndex) { |
| if (element instanceof DateHistoryCategory && |
| columnIndex == COL_REVISIONID){ |
| if (dateImage == null){ |
| dateDesc = CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_DATES_CATEGORY); |
| dateImage = dateDesc.createImage(); |
| } |
| return dateImage; |
| } |
| |
| if (element instanceof LocalFileRevision && |
| columnIndex == COL_REVISIONID){ |
| if (localRevImage == null){ |
| localRevDesc = CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_LOCALREVISION_TABLE); |
| localRevImage = localRevDesc.createImage(); |
| } |
| return localRevImage; |
| } |
| |
| if (element instanceof CVSFileRevision && |
| columnIndex == COL_REVISIONID){ |
| if (remoteRevImage == null){ |
| remoteRevDesc = CVSUIPlugin.getPlugin().getImageDescriptor(ICVSUIConstants.IMG_REMOTEREVISION_TABLE); |
| remoteRevImage = remoteRevDesc.createImage(); |
| } |
| return remoteRevImage; |
| } |
| return null; |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) |
| */ |
| @Override |
| public String getText(Object element) { |
| return getColumnText(element, column); |
| } |
| |
| public String getColumnText(Object element, int columnIndex) { |
| if (element instanceof AbstractHistoryCategory){ |
| if (columnIndex != COL_REVISIONID) |
| return ""; //$NON-NLS-1$ |
| |
| return ((AbstractHistoryCategory) element).getName(); |
| } |
| |
| IFileRevision entry = adaptToFileRevision(element); |
| if (entry == null) |
| return ""; //$NON-NLS-1$ |
| switch (columnIndex) { |
| case COL_REVISIONID : |
| String revision = entry.getContentIdentifier(); |
| String currentRevision = getCurrentRevision(); |
| if (currentRevision != null && currentRevision.equals(revision)) { |
| if (baseModified) |
| revision = NLS.bind(CVSUIMessages.nameAndRevision, new String[] { revision, CVSUIMessages.CVSHistoryTableProvider_base}); //NLS.bind(CVSUIMessages.currentRevision, new String[] { revision }); |
| else |
| revision = NLS.bind(CVSUIMessages.currentRevision, new String[] {revision}); //NLS.bind(CVSUIMessages.currentRevision, new String[] { revision }); |
| } |
| return revision; |
| case COL_BRANCHES: |
| ITag[] branches = entry.getBranches(); |
| StringBuffer resultBranches = new StringBuffer(); |
| for (int i = 0; i < branches.length; i++) { |
| resultBranches.append(branches[i].getName()); |
| if (i < branches.length - 1) { |
| resultBranches.append(", "); //$NON-NLS-1$ |
| } |
| } |
| return resultBranches.toString(); |
| case COL_TAGS: |
| ITag[] 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 : |
| long date = entry.getTimestamp(); |
| Date dateFromLong = new Date(date); |
| return getDateFormat().format(dateFromLong); |
| case COL_AUTHOR : |
| return entry.getAuthor(); |
| case COL_COMMENT : |
| return getCommentAsSingleLine(entry); |
| } |
| 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) |
| */ |
| @Override |
| public Color getForeground(Object element) { |
| if (element instanceof AbstractHistoryCategory){ |
| ITheme current = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme(); |
| return current.getColorRegistry().get(CVSHistoryTableProvider.CATEGORIES_COLOR); |
| } |
| |
| IFileRevision entry = adaptToFileRevision(element); |
| if (!entry.exists()) { |
| return Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); |
| } |
| |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) |
| */ |
| @Override |
| public Color getBackground(Object element) { |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.jface.viewers.IFontProvider#getFont(java.lang.Object) |
| */ |
| @Override |
| public Font getFont(Object element) { |
| if (element instanceof AbstractHistoryCategory) { |
| return getCurrentRevisionFont(); |
| } |
| |
| IFileRevision entry = adaptToFileRevision(element); |
| if (entry == null) |
| return null; |
| String revision = entry.getContentIdentifier(); |
| //String comment = entry.getComment(); |
| String tempCurrentRevision = getCurrentRevision(); |
| Font returnFont = null; |
| |
| if (tempCurrentRevision != null && tempCurrentRevision.equals(revision)) { |
| returnFont = getCurrentRevisionFont(); |
| } |
| //Check to see if this is the local workspace file |
| if (workspaceFile != null && entry instanceof LocalFileRevision) { |
| LocalFileRevision localRevision = (LocalFileRevision) entry; |
| if (localRevision.isCurrentState()) |
| return getCurrentRevisionFont(); |
| } |
| |
| return returnFont; |
| } |
| |
| private Font getCurrentRevisionFont() { |
| 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.getTree().getDisplay(), data); |
| } |
| return currentRevisionFont; |
| } |
| |
| } |
| |
| /** |
| * The history sorter |
| */ |
| class HistoryComparator extends ViewerComparator { |
| private boolean reversed = false; |
| private int columnNumber; |
| |
| private VersionCollator versionCollator = new VersionCollator(); |
| |
| // column headings: "Revision" "Branches" "Tags" "Date" "Author" "Comment" |
| private int[][] SORT_ORDERS_BY_COLUMN = { |
| {COL_REVISIONID, COL_DATE, COL_AUTHOR, COL_COMMENT, COL_TAGS, COL_BRANCHES}, /* revision */ |
| {COL_BRANCHES, COL_DATE, COL_REVISIONID, COL_AUTHOR, COL_COMMENT, COL_TAGS}, /* tags */ |
| {COL_TAGS, COL_DATE, COL_REVISIONID, COL_AUTHOR, COL_COMMENT, COL_BRANCHES}, /* tags */ |
| {COL_DATE, COL_REVISIONID, COL_AUTHOR, COL_COMMENT, COL_TAGS, COL_BRANCHES}, /* date */ |
| {COL_AUTHOR, COL_REVISIONID, COL_DATE, COL_COMMENT, COL_TAGS, COL_BRANCHES}, /* author */ |
| {COL_COMMENT, COL_REVISIONID, COL_DATE, COL_AUTHOR, COL_TAGS, COL_BRANCHES} /* 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. |
| */ |
| @Override |
| public int compare(Viewer compareViewer, Object o1, Object o2) { |
| if (o1 instanceof AbstractHistoryCategory || o2 instanceof AbstractHistoryCategory) |
| return 0; |
| |
| IFileRevision e1 = adaptToFileRevision(o1); |
| IFileRevision e2 = adaptToFileRevision(o2); |
| int result = 0; |
| if (e1 == null || e2 == null) { |
| result = super.compare(compareViewer, 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, IFileRevision e1, IFileRevision e2) { |
| switch (columnNumber) { |
| case COL_REVISIONID : /* revision */ |
| if (e1 instanceof LocalFileRevision || |
| e2 instanceof LocalFileRevision) { |
| //compare based on dates |
| long date1 = e1.getTimestamp(); |
| long date2 = e2.getTimestamp(); |
| if (date1 == date2) |
| return 0; |
| |
| return date1 > date2 ? 1 : -1; |
| } |
| return versionCollator.compare(e1.getContentIdentifier(), e2.getContentIdentifier()); |
| case COL_BRANCHES: /* branches */ |
| ITag[] branches1 = e1.getBranches(); |
| ITag[] branches2 = e2.getBranches(); |
| if (branches2.length == 0) { |
| return -1; |
| } |
| if (branches1.length == 0) { |
| return 1; |
| } |
| return getComparator().compare(branches1[0].getName(), branches2[0].getName()); |
| case COL_TAGS: /* tags */ |
| ITag[] tags1 = e1.getTags(); |
| ITag[] 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 COL_DATE : /* date */ |
| long date1 = e1.getTimestamp(); |
| long date2 = e2.getTimestamp(); |
| if (date1 == date2) |
| return 0; |
| |
| return date1 > date2 ? 1 : -1; |
| |
| case COL_AUTHOR : /* author */ |
| String author1 = e1.getAuthor(); |
| String author2 = e2.getAuthor(); |
| if (author2 == null) |
| return -1; |
| |
| if (author1 == null) |
| return 1; |
| |
| return getComparator().compare(author1, author2); |
| case COL_COMMENT : /* comment */ |
| String comment1 = e1.getComment(); |
| String comment2 = e2.getComment(); |
| if (comment2 == null) |
| return -1; |
| |
| if (comment1 == null) |
| return 1; |
| |
| return getComparator().compare(comment1, comment2); |
| 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 IFileRevision adaptToFileRevision(Object element) { |
| // Get the log entry for the provided object |
| IFileRevision entry = null; |
| if (element instanceof IFileRevision) { |
| entry = (IFileRevision) element; |
| } else if (element instanceof IAdaptable) { |
| entry = ((IAdaptable) element).getAdapter(IFileRevision.class); |
| } else if (element instanceof AbstractHistoryCategory){ |
| if (((AbstractHistoryCategory) element).hasRevisions()) |
| entry = ((AbstractHistoryCategory) element).getRevisions()[0]; |
| } |
| return entry; |
| } |
| |
| /** |
| * Create a TableViewer that can be used to display a list of IFileRevision instances. |
| * Ths method provides the labels and sorter but does not provide a content provider |
| * |
| * @param parent |
| * @return TableViewer |
| */ |
| public TreeViewer createTree(Composite parent) { |
| Tree tree = new Tree(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); |
| tree.setHeaderVisible(true); |
| tree.setLinesVisible(true); |
| |
| GridData data = new GridData(GridData.FILL_BOTH); |
| tree.setLayoutData(data); |
| |
| TableLayout layout= new TableLayout(true); |
| tree.setLayout(layout); |
| |
| this.viewer = new TreeViewer(tree); |
| createColumns(viewer, layout); |
| |
| // Initialize the sorting |
| ColumnViewerToolTipSupport.enableFor(viewer); |
| viewer.refresh(); |
| |
| tree.addDisposeListener(e -> { |
| if (currentRevisionFont != null) { |
| currentRevisionFont.dispose(); |
| } |
| }); |
| |
| return viewer; |
| } |
| |
| /** |
| * Creates the columns for the history table. |
| */ |
| private void createColumns(TreeViewer tree, TableLayout layout) { |
| SelectionListener headerListener = getColumnListener(viewer); |
| |
| // revision |
| TreeViewerColumn viewerCol = new TreeViewerColumn(tree, SWT.NONE); |
| viewerCol.setLabelProvider(new HistoryLabelProvider(COL_REVISIONID, this)); |
| TreeColumn col = viewerCol.getColumn(); |
| col.setData(COL_NAME, COL_REVISIONID_NAME); |
| col.setResizable(true); |
| col.setText(TeamUIMessages.GenericHistoryTableProvider_Revision); |
| col.addSelectionListener(headerListener); |
| |
| // branches |
| viewerCol = new TreeViewerColumn(tree, SWT.NONE); |
| viewerCol.setLabelProvider(new HistoryLabelProvider(COL_BRANCHES, this)); |
| col = viewerCol.getColumn(); |
| col.setData(COL_NAME, COL_BRANCHES_NAME); |
| col.setResizable(true); |
| col.setText(CVSUIMessages.HistoryView_branches); |
| col.addSelectionListener(headerListener); |
| |
| // tags |
| viewerCol = new TreeViewerColumn(tree, SWT.NONE); |
| viewerCol.setLabelProvider(new HistoryLabelProvider(COL_TAGS, this)); |
| col = viewerCol.getColumn(); |
| col.setData(COL_NAME, COL_TAGS_NAME); |
| col.setResizable(true); |
| col.setText(CVSUIMessages.HistoryView_tags); |
| col.addSelectionListener(headerListener); |
| |
| // creation date |
| viewerCol = new TreeViewerColumn(tree, SWT.NONE); |
| viewerCol.setLabelProvider(new HistoryLabelProvider(COL_DATE, this)); |
| col = viewerCol.getColumn(); |
| col.setData(COL_NAME, COL_DATE_NAME); |
| col.setResizable(true); |
| col.setText(TeamUIMessages.GenericHistoryTableProvider_RevisionTime); |
| col.addSelectionListener(headerListener); |
| |
| // author |
| viewerCol = new TreeViewerColumn(tree, SWT.NONE); |
| viewerCol.setLabelProvider(new HistoryLabelProvider(COL_AUTHOR, this)); |
| col = viewerCol.getColumn(); |
| col.setData(COL_NAME, COL_AUTHOR_NAME); |
| col.setResizable(true); |
| col.setText(TeamUIMessages.GenericHistoryTableProvider_Author); |
| col.addSelectionListener(headerListener); |
| |
| //comment |
| viewerCol = new TreeViewerColumn(tree, SWT.NONE); |
| viewerCol.setLabelProvider(new HistoryLabelProvider(COL_COMMENT, this)); |
| col = viewerCol.getColumn(); |
| col.setData(COL_NAME, COL_COMMENT_NAME); |
| col.setResizable(true); |
| col.setText(TeamUIMessages.GenericHistoryTableProvider_Comment); |
| col.addSelectionListener(headerListener); |
| |
| loadColumnLayout(layout); |
| } |
| |
| public void loadColumnLayout(TableLayout layout) { |
| int widths[] = new int[] { |
| getSettingsInt(COL_REVISIONID_NAME), |
| getSettingsInt(COL_BRANCHES_NAME), |
| getSettingsInt(COL_TAGS_NAME), |
| getSettingsInt(COL_DATE_NAME), |
| getSettingsInt(COL_AUTHOR_NAME), |
| getSettingsInt(COL_COMMENT_NAME) }; |
| ColumnLayoutData weightData[] = getWeightData(widths); |
| for (int i = 0; i < weightData.length; i++) { |
| layout.addColumnData(weightData[i]); |
| } |
| |
| String sortName = settings.get(SORT_COL_NAME); |
| if (sortName == null) { |
| sortName = COL_DATE_NAME; |
| } |
| int sortDirection = SWT.DOWN; |
| try { |
| sortDirection = settings.getInt(SORT_COL_DIRECTION); |
| } catch (NumberFormatException e) { |
| // Silently ignored |
| } |
| TreeColumn sortColumn = null; |
| int columnNumber = 0; |
| TreeColumn columns[] = viewer.getTree().getColumns(); |
| for (int i = 0; i < columns.length; i++) { |
| if (columns[i].getData(COL_NAME).equals(sortName)) { |
| sortColumn = columns[i]; |
| columnNumber = i; |
| } |
| } |
| viewer.getTree().setSortColumn(sortColumn); |
| viewer.getTree().setSortDirection(sortDirection); |
| HistoryComparator sorter = new HistoryComparator(columnNumber); |
| sorter.setReversed(sortDirection == SWT.DOWN); |
| viewer.setComparator(sorter); |
| } |
| |
| private int getSettingsInt(String key) { |
| String value = settings.get(key); |
| int ret = 0; |
| try { |
| ret = Integer.parseInt(value); |
| } catch (NumberFormatException e) { |
| ret = -1; |
| } |
| return ret; |
| } |
| |
| private ColumnLayoutData[] getWeightData(int[] widths) { |
| boolean reset = true; |
| for (int i = 0; i < widths.length; i++) { |
| if (widths[i] > 0) { |
| reset = false; |
| break; |
| } |
| } |
| ColumnLayoutData[] ret = new ColumnLayoutData[widths.length]; |
| for (int i = 0; i < widths.length; i++) { |
| if (reset) { |
| // use same weight for all columns |
| ret[i] = new ColumnWeightData(10, true); |
| } else { |
| if (widths[i] < 0) |
| ret[i] = new ColumnPixelData(getWidthForColumn(i)); |
| else |
| ret[i] = new ColumnPixelData(widths[i]); |
| } |
| } |
| return ret; |
| } |
| |
| private int getWidthForColumn(int i) { |
| // see #createColumns |
| int chars = 4; |
| switch (i) { |
| case COL_REVISIONID: |
| chars += TeamUIMessages.GenericHistoryTableProvider_Revision.length(); |
| break; |
| case COL_BRANCHES: |
| chars += CVSUIMessages.HistoryView_branches.length(); |
| break; |
| case COL_TAGS: |
| chars += CVSUIMessages.HistoryView_tags.length(); |
| break; |
| case COL_DATE: |
| chars += TeamUIMessages.GenericHistoryTableProvider_RevisionTime.length(); |
| break; |
| case COL_AUTHOR: |
| chars += TeamUIMessages.GenericHistoryTableProvider_Author.length(); |
| break; |
| case COL_COMMENT: |
| chars += TeamUIMessages.GenericHistoryTableProvider_Comment.length(); |
| break; |
| } |
| return new PixelConverter(viewer.getTree()).convertWidthInCharsToPixels(chars); |
| } |
| |
| public void saveColumnLayout() { |
| TreeColumn columns[] = viewer.getTree().getColumns(); |
| for (int i = 0; i < columns.length; i++) { |
| settings.put((String) columns[i].getData(COL_NAME), columns[i] |
| .getWidth()); |
| } |
| settings.put(SORT_COL_NAME, (String) viewer.getTree().getSortColumn() |
| .getData(COL_NAME)); |
| settings.put(SORT_COL_DIRECTION, viewer.getTree().getSortDirection()); |
| } |
| |
| /** |
| * Adds the listener that sets the sorter. |
| */ |
| private SelectionListener getColumnListener(final TreeViewer treeViewer) { |
| /** |
| * 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). |
| */ |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| // column selected - need to sort |
| int column = treeViewer.getTree().indexOf((TreeColumn) e.widget); |
| HistoryComparator oldSorter = (HistoryComparator) treeViewer.getComparator(); |
| TreeColumn treeColumn = ((TreeColumn)e.widget); |
| if (oldSorter != null && column == oldSorter.getColumnNumber()) { |
| oldSorter.setReversed(!oldSorter.isReversed()); |
| |
| treeViewer.getTree().setSortColumn(treeColumn); |
| treeViewer.getTree().setSortDirection(oldSorter.isReversed() ? SWT.DOWN : SWT.UP); |
| treeViewer.refresh(); |
| } else { |
| treeViewer.getTree().setSortColumn(treeColumn); |
| treeViewer.getTree().setSortDirection(SWT.UP); |
| treeViewer.setComparator(new HistoryComparator(column)); |
| } |
| } |
| }; |
| } |
| |
| public void setFile(IFileHistory fileHistory, IFile workspaceFile) { |
| this.currentFileHistory = fileHistory; |
| this.workspaceFile = workspaceFile; |
| } |
| |
| |
| public IFileHistory getIFileHistory() { |
| return this.currentFileHistory; |
| } |
| |
| public String getCurrentRevision() { |
| |
| try { |
| if (workspaceFile != null) { |
| ICVSFile cvsWorkspaceFile = CVSWorkspaceRoot.getCVSFileFor(workspaceFile); |
| byte[] syncBytes = cvsWorkspaceFile.getSyncBytes(); |
| if (syncBytes != null) { |
| String workspaceRevision = ResourceSyncInfo.getRevision(syncBytes); |
| return workspaceRevision; |
| } |
| } |
| |
| } catch (CVSException e) { |
| } |
| |
| return null; |
| } |
| |
| public void setBaseModified(boolean modified) { |
| this.baseModified=modified; |
| } |
| |
| private static class ThemeListener implements IPropertyChangeListener { |
| |
| private final CVSHistoryTableProvider provider; |
| |
| ThemeListener(CVSHistoryTableProvider provider) { |
| this.provider= provider; |
| } |
| @Override |
| public void propertyChange(PropertyChangeEvent event) { |
| provider.viewer.refresh(); |
| } |
| } |
| |
| public void setWorkspaceFile(IFile workspaceFile) { |
| this.workspaceFile = workspaceFile; |
| } |
| |
| public static String getCommentAsSingleLine(IFileRevision entry) { |
| String comment = entry.getComment(); |
| if (comment != null){ |
| 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$ |
| } |
| } |