/*
* Copyright (c) John C. Landers
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*******************************************************************************/
package net.sf.cvschangelog;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;
/**
* @author jcl
*
* To change the template for this generated type comment go to Window -
* Preferences - Java - Code Generation - Code and Comments
*/
public class ChangeLogView extends ViewPart {
private TableViewer viewer;
private SashForm sashForm;
private TextViewer textViewer;
private List changeLogEntries = null;
private Job changeLogJob = null;
private CVSChangeLogPlugin plugin = CVSChangeLogPlugin.getDefault();
private IMemento memento = null;
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
sashForm = new SashForm(parent, SWT.VERTICAL);
sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
this.createTable(sashForm);
textViewer = new TextViewer(sashForm, SWT.H_SCROLL | SWT.V_SCROLL
| SWT.MULTI | SWT.BORDER | SWT.READ_ONLY);
sashForm.setWeights(new int[]{70, 30});
viewer.setContentProvider(new IStructuredContentProvider() {
List entries = null;
public Object[] getElements(Object inputElement) {
if (inputElement instanceof List) {
return ((List) inputElement).toArray();
}
return new Object[0];
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput,
Object newInput) {
entries = (List) newInput;
}
});
viewer.setLabelProvider(new ITableLabelProvider() {
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
ChangeLogEntry entry = (ChangeLogEntry) element;
switch (columnIndex) {
case 0 :
return entry.getDate().toString();
case 1 :
return entry.getAuthor();
case 2 :
return entry.getComment();
}
return "";
}
public void addListener(ILabelProviderListener listener) {
}
public void dispose() {
}
public boolean isLabelProperty(Object element, String property) {
return true;
}
public void removeListener(ILabelProviderListener listener) {
}
});
// Create the local tool bar
IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager();
Action allAction = new Action("All", plugin.getImageRegistry()
.getDescriptor(ICVSChangeLogConstants.IMG_ALL)) {
public void run() {
Document doc = new Document();
doc.set(ChangeLogView.this.getChangeLog());
ChangeLogView.this.textViewer.setDocument(doc);
}
};
allAction.setToolTipText("Write All Entries");
allAction.setDisabledImageDescriptor(plugin.getImageRegistry()
.getDescriptor(ICVSChangeLogConstants.IMG_ALL_DISABLED));
allAction.setHoverImageDescriptor(plugin.getImageRegistry()
.getDescriptor(ICVSChangeLogConstants.IMG_ALL_HOVER));
tbm.add(allAction);
Action saveAction = new Action("Save", plugin.getImageRegistry()
.getDescriptor(ICVSChangeLogConstants.IMG_SAVEAS)) {
public void run() {
FileDialog dialog = new FileDialog(viewer.getControl()
.getShell(), SWT.SAVE);
dialog.setText("Save As");
dialog.setFileName("ChangeLog.txt");
String fileName = dialog.open();
if (fileName != null) {
try {
FileWriter fw = new FileWriter(fileName);
fw.write(ChangeLogView.this.textViewer.getDocument()
.get().toCharArray());
fw.close();
} catch (IOException ex) {
IWorkbenchWindow workbench = plugin.getWorkbench().getActiveWorkbenchWindow();
if (workbench != null) {
Status pluginStatus = new Status(Status.ERROR, "net.sf.cvschangelog",
Status.OK, ex.getMessage(), ex);
ErrorDialog.openError(workbench.getShell(),
"ChangeLog Error",
ex.getMessage(),
pluginStatus);
} else {
ex.printStackTrace();
}
}
}
}
};
saveAction.setToolTipText("Save Comments As");
saveAction
.setDisabledImageDescriptor(plugin.getImageRegistry()
.getDescriptor(ICVSChangeLogConstants.IMG_SAVEAS_DISABLED));
saveAction.setHoverImageDescriptor(plugin.getImageRegistry()
.getDescriptor(ICVSChangeLogConstants.IMG_SAVEAS_HOVER));
tbm.add(saveAction);
Action refreshAction = new Action("Refresh", plugin.getImageRegistry()
.getDescriptor(ICVSChangeLogConstants.IMG_REFRESH)) {
public void run() {
ChangeLogView.this.refresh();
}
};
refreshAction.setToolTipText("Refresh"); //$NON-NLS-1$
refreshAction
.setDisabledImageDescriptor(plugin.getImageRegistry()
.getDescriptor(ICVSChangeLogConstants.IMG_REFRESH_DISABLED));
refreshAction.setHoverImageDescriptor(plugin.getImageRegistry()
.getDescriptor(ICVSChangeLogConstants.IMG_REFRESH_HOVER));
tbm.add(refreshAction);
tbm.update(false);
restoreState();
}
protected void refresh() {
if ( this.changeLogJob != null )
{
this.changeLogJob.schedule();
}
}
protected void 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);
this.viewer = new TableViewer(table);
// creation date
TableColumn col = new TableColumn(table, SWT.NONE);
col.setResizable(true);
col.setText("Date");
layout.addColumnData(new ColumnWeightData(20, true));
col.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ChangeLogEntrySorter oldSorter = ((ChangeLogEntrySorter)ChangeLogView.this.viewer.getSorter());
if(oldSorter != null && oldSorter.getSortBy() == ChangeLogEntrySorter.SORT_DATE) {
boolean sortDescending = oldSorter.getSortDescending();
ChangeLogView.this.viewer.setSorter((new ChangeLogEntrySorter(
ChangeLogEntrySorter.SORT_DATE, !sortDescending)));
} else {
ChangeLogView.this.viewer.setSorter((new ChangeLogEntrySorter(
ChangeLogEntrySorter.SORT_DATE, false)));
}
}
});
// author
col = new TableColumn(table, SWT.NONE);
col.setResizable(true);
col.setText("Author");
layout.addColumnData(new ColumnWeightData(20, true));
col.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ChangeLogEntrySorter oldSorter = ((ChangeLogEntrySorter)ChangeLogView.this.viewer.getSorter());
if(oldSorter != null && oldSorter.getSortBy() == ChangeLogEntrySorter.SORT_AUTHOR) {
boolean sortDescending = oldSorter.getSortDescending();
ChangeLogView.this.viewer.setSorter((new ChangeLogEntrySorter(
ChangeLogEntrySorter.SORT_AUTHOR, !sortDescending)));
} else {
ChangeLogView.this.viewer.setSorter((new ChangeLogEntrySorter(
ChangeLogEntrySorter.SORT_AUTHOR, true)));
}
}
});
//comment
col = new TableColumn(table, SWT.NONE);
col.setResizable(true);
col.setText("Comment");
layout.addColumnData(new ColumnWeightData(60, true));
col.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ChangeLogEntrySorter oldSorter = ((ChangeLogEntrySorter)ChangeLogView.this.viewer.getSorter());
if(oldSorter != null && oldSorter.getSortBy() == ChangeLogEntrySorter.SORT_COMMENT) {
boolean sortDescending = oldSorter.getSortDescending();
ChangeLogView.this.viewer.setSorter((new ChangeLogEntrySorter(
ChangeLogEntrySorter.SORT_COMMENT, !sortDescending)));
} else {
ChangeLogView.this.viewer.setSorter((new ChangeLogEntrySorter(
ChangeLogEntrySorter.SORT_COMMENT, true)));
}
}
});
ChangeLogViewOpenListener openListener = new ChangeLogViewOpenListener(plugin);
viewer.addOpenListener(openListener);
viewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
private String generateTextField(ChangeLogEntry entry) {
StringBuffer retval = new StringBuffer();
retval.append("Comments:\n");
retval.append(entry.getOriginalComment());
retval.append("\n\nFiles:\n");
retval.append(entry.getFilesAsString());
return(retval.toString());
}
public void selectionChanged(SelectionChangedEvent event) {
Object selectedItem = ((IStructuredSelection) event
.getSelection()).getFirstElement();
if ((selectedItem instanceof ChangeLogEntry)) {
Document doc = new Document();
doc.set(((ChangeLogEntry) selectedItem)
.getFilesAsString());
//doc.set(generateTextField((ChangeLog.ChangeLogEntry) selectedItem));
ChangeLogView.this.textViewer.setDocument(doc);
return;
}
}
});
return;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPart#setFocus()
*/
public void setFocus() {
if (this.viewer != null) {
Table control = this.viewer.getTable();
if (control != null && !control.isDisposed()) {
control.setFocus();
}
}
}
public void showChangeLog(List changeLogEntries) {
if (viewer != null) {
this.changeLogEntries = changeLogEntries;
viewer.setInput(this.changeLogEntries);
}
}
public String getChangeLog() {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
if (this.changeLogEntries != null) {
for (int cc = 0; cc < this.changeLogEntries.size(); cc++) {
ChangeLogEntry entry = (ChangeLogEntry) this.changeLogEntries
.get(cc);
if (cc > 0) {
pw.println();
}
pw.print(entry.getDate().toString());
pw.print("\t");
pw.println(entry.getAuthor());
pw.println();
pw.print("\t");
pw.println(entry.getComment());
pw.println();
for (int xx = 0; xx < entry.getFiles().size(); xx++) {
pw.print("\t");
pw.println(entry.getFiles().get(xx));
}
}
}
return sw.toString();
}
/**
* @return Returns the viewer.
*/
public TableViewer getViewer() {
return viewer;
}
public void init(IViewSite site,IMemento memento) throws PartInitException {
init(site);
this.memento = memento;
}
private void restoreState() {
// Currently we only restore the state if changLogEntries is null
// That's because I don't want to worry about the possibility of
// duplicate entries. If this becomes a problem, it should be fixed.
if ((memento == null) || (changeLogEntries != null))
return;
IMemento children[] = memento.getChildren("ChangeLog.ChangeLogEntry");
if (children.length > 0) {
changeLogEntries = new ArrayList();
for (int i=0; i < children.length; i++) {
String author = children[i].getString("author");
String comment = children[i].getString("comment");
String originalComment = children[i].getString("originalComment");
Date date = new Date(new Long(children[i].getString("date")).longValue());
String projectName = children[i].getString("project");
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
ChangeLogEntry entry = new ChangeLogEntry(author, comment, originalComment, date, project);
changeLogEntries.add(entry);
IMemento fileList = children[i].getChild("fileList");
IMemento fileNames[] = fileList.getChildren("filename");
for (int j=0; j < fileNames.length; j++) {
entry.addFiles(fileNames[j].getID());
}
}
viewer.setInput(changeLogEntries);
memento = null; // ensure that restoreState() only runs once
}
}
public void saveState(IMemento memento) {
if (changeLogEntries != null) {
IMemento child;
for(Iterator logIterator = changeLogEntries.iterator(); logIterator.hasNext(); ) {
ChangeLogEntry entry = (ChangeLogEntry) logIterator.next();
child = memento.createChild("ChangeLog.ChangeLogEntry");
child.putString("author", entry.getAuthor());
child.putString("comment", entry.getComment());
child.putString("originalComment", entry.getOriginalComment());
child.putString("date", new Long(entry.getDate().getTime()).toString());
child.putString("filesToString", entry.getFilesAsString());
child.putString("project", entry.getProject().getName());
IMemento files = child.createChild("fileList");
for(Iterator filesIterator = entry.getFiles().iterator(); filesIterator.hasNext(); ) {
IMemento fileMemento = files.createChild("filename", (String) filesIterator.next());
}
}
}
}
/**
* @return Returns the changeLogJob.
*/
public Job getChangeLogJob() {
return changeLogJob;
}
/**
* @param changeLogJob The changeLogJob to set.
*/
public void setChangeLogJob(Job changeLogJob) {
this.changeLogJob = changeLogJob;
}
}