blob: 788cfe5ec76427d38c3e765505bdf2b2246b748a [file] [log] [blame]
package org.eclipse.ui.internal.dialogs;
/**********************************************************************
Copyright (c) 2000, 2002 IBM Corp.
All rights reserved.   This program and the accompanying materials
are made available under the terms of the Common Public License v0.5
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v05.html
 
Contributors:
**********************************************************************/
import java.text.Collator;
import java.util.*;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.dialogs.SelectionDialog;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.ui.internal.*;
/**
* Implements a dialog showing all opened editors in the workbench
* and the recent closed editors
*/
public class WorkbenchEditorsDialog extends SelectionDialog {
private WorkbenchWindow window;
private Table editorsTable;
private Button saveSelected;
private Button closeSelected;
private Button selectClean;
private Button invertSelection;
private boolean showAllPersp = false;
private int sortColumn;
private List elements = new ArrayList();
private HashMap imageCache = new HashMap(11);
private HashMap disabledImageCache = new HashMap(11);
private boolean reverse = false;
private Collator collator = Collator.getInstance();
private Rectangle bounds;
private int columnsWidth[];
private static final String SORT = "sort"; //$NON-NLS-1$
private static final String HISTORY = "history"; //$NON-NLS-1$
private static final String ALLPERSP = "allPersp"; //$NON-NLS-1$
private static final String BOUNDS = "bounds"; //$NON-NLS-1$
private static final String COLUMNS = "columns"; //$NON-NLS-1$
private SelectionListener headerListener = new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
int index = editorsTable.indexOf((TableColumn) e.widget);
if(index == sortColumn)
reverse = !reverse;
else
sortColumn = index;
updateItems();
}
};
/**
* Constructor for WorkbenchEditorsDialog.
*/
public WorkbenchEditorsDialog(WorkbenchWindow window) {
super(window.getShell());
this.window = window;
setTitle(WorkbenchMessages.getString("WorkbenchEditorsDialog.title")); //$NON-NLS-1$
setShellStyle(getShellStyle() | SWT.RESIZE);
IDialogSettings s = getDialogSettings();
if(s.get(ALLPERSP) == null) {
sortColumn = 0;
} else {
showAllPersp = s.getBoolean(ALLPERSP);
sortColumn = s.getInt(SORT);
String[] array = s.getArray(BOUNDS);
if(array != null) {
bounds = new Rectangle(0,0,0,0);
bounds.x = new Integer(array[0]).intValue();
bounds.y = new Integer(array[1]).intValue();
bounds.width = new Integer(array[2]).intValue();
bounds.height = new Integer(array[3]).intValue();
}
array = s.getArray(COLUMNS);
if(array != null) {
columnsWidth = new int[array.length];
for (int i = 0; i < columnsWidth.length; i++)
columnsWidth[i] = new Integer(array[i]).intValue();
}
}
}
/* (non-Javadoc)
* Method declared on Window.
*/
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
WorkbenchHelp.setHelp(newShell, IHelpContextIds.WORKBENCH_EDITORS_DIALOG);
}
/**
* Initialize the dialog bounds with the bounds saved
* from the settings.
*/
protected void initializeBounds() {
if(bounds != null) {
getShell().setBounds(bounds);
} else {
super.initializeBounds();
}
}
/**
* Creates the contents of this dialog, initializes the
* listener and the update thread.
*/
protected Control createDialogArea(Composite parent) {
initializeDialogUnits(parent);
Font font = parent.getFont();
Composite dialogArea = (Composite) super.createDialogArea(parent);
//Label over the table
Label l = new Label(dialogArea, SWT.NONE);
l.setText(WorkbenchMessages.getString("WorkbenchEditorsDialog.label")); //$NON-NLS-1$
l.setFont(font);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
l.setLayoutData(data);
//Table showing the editors name, full path and perspective
editorsTable = new Table(dialogArea, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
editorsTable.setLinesVisible(true);
editorsTable.setHeaderVisible(true);
editorsTable.setFont(font);
final GridData tableData = new GridData(GridData.FILL_BOTH);
tableData.heightHint = 16 * editorsTable.getItemHeight();
tableData.widthHint = (int) (2.5 * tableData.heightHint);
editorsTable.setLayoutData(tableData);
editorsTable.setLayout(new Layout() {
protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache){
return new Point(tableData.widthHint, tableData.heightHint);
}
protected void layout(Composite composite, boolean flushCache){
TableColumn c[] = editorsTable.getColumns();
if(columnsWidth == null) {
int w = editorsTable.getClientArea().width;
c[0].setWidth(w * 1 / 3);
c[1].setWidth(w - c[0].getWidth());
} else {
c[0].setWidth(columnsWidth[0]);
c[1].setWidth(columnsWidth[1]);
}
editorsTable.setLayout(null);
}
});
//Name column
TableColumn tc = new TableColumn(editorsTable,SWT.NONE);
tc.setResizable(true);
tc.setText(WorkbenchMessages.getString("WorkbenchEditorsDialog.name")); //$NON-NLS-1$
tc.addSelectionListener(headerListener);
//Full path column
tc = new TableColumn(editorsTable,SWT.NONE);
tc.setResizable(true);
tc.setText(WorkbenchMessages.getString("WorkbenchEditorsDialog.path")); //$NON-NLS-1$
tc.addSelectionListener(headerListener);
//A composite for save editors and close editors buttons
Composite selectionButtons = new Composite(dialogArea,SWT.NULL);
GridLayout layout = new GridLayout();
layout.numColumns = 4;
selectionButtons.setLayout(layout);
//Close editors button
closeSelected = new Button(selectionButtons,SWT.PUSH);
closeSelected.setText(WorkbenchMessages.getString("WorkbenchEditorsDialog.closeSelected")); //$NON-NLS-1$
closeSelected.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
closeItems(editorsTable.getSelection());
}
});
closeSelected.setFont(font);
setButtonLayoutData(closeSelected);
//Save editors button
saveSelected = new Button(selectionButtons,SWT.PUSH);
saveSelected.setText(WorkbenchMessages.getString("WorkbenchEditorsDialog.saveSelected")); //$NON-NLS-1$
saveSelected.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
saveItems(editorsTable.getSelection(),null);
}
});
saveSelected.setFont(font);
setButtonLayoutData(saveSelected);
//Select clean editors button
selectClean = new Button(selectionButtons,SWT.PUSH);
selectClean.setText(WorkbenchMessages.getString("WorkbenchEditorsDialog.selectClean")); //$NON-NLS-1$
selectClean.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
editorsTable.setSelection(selectClean(editorsTable.getItems()));
updateButtons();
}
});
selectClean.setFont(font);
setButtonLayoutData(selectClean);
//Invert selection button
invertSelection = new Button(selectionButtons,SWT.PUSH);
invertSelection.setText(WorkbenchMessages.getString("WorkbenchEditorsDialog.invertSelection")); //$NON-NLS-1$
invertSelection.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
editorsTable.setSelection(invertedSelection(editorsTable.getItems(),editorsTable.getSelection()));
updateButtons();
}
});
invertSelection.setFont(font);
setButtonLayoutData(invertSelection);
//Show only active perspective button
final Button showAllPerspButton = new Button(dialogArea,SWT.CHECK);
showAllPerspButton.setText(WorkbenchMessages.getString("WorkbenchEditorsDialog.showAllPersp")); //$NON-NLS-1$
showAllPerspButton.setSelection(showAllPersp);
showAllPerspButton.setFont(font);
setButtonLayoutData(showAllPerspButton);
showAllPerspButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
showAllPersp = showAllPerspButton.getSelection();
updateItems();
}
});
//Create the items and update buttons state
updateItems();
updateButtons();
editorsTable.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
updateButtons();
}
public void widgetDefaultSelected(SelectionEvent e) {
okPressed();
}
});
editorsTable.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
for (Iterator images = imageCache.values().iterator(); images.hasNext();) {
Image i = (Image)images.next();
i.dispose();
}
for (Iterator images = disabledImageCache.values().iterator(); images.hasNext();) {
Image i = (Image)images.next();
i.dispose();
}
}
});
editorsTable.setFocus();
return dialogArea;
}
/**
* Updates the button state (enabled/disabled)
*/
private void updateButtons() {
TableItem selectedItems[] = editorsTable.getSelection();
boolean hasDirty = false;
for (int i = 0; i < selectedItems.length; i ++) {
Adapter editor = (Adapter)selectedItems[i].getData();
if(editor.isDirty()) {
hasDirty = true;
break;
}
}
saveSelected.setEnabled(hasDirty);
TableItem allItems[] = editorsTable.getItems();
boolean hasClean = false;
for (int i = 0; i < allItems.length; i ++) {
Adapter editor = (Adapter)allItems[i].getData();
if(!editor.isDirty()) {
hasClean = true;
break;
}
}
selectClean.setEnabled(hasClean);
invertSelection.setEnabled(allItems.length > 0);
closeSelected.setEnabled(selectedItems.length > 0);
Button ok = getOkButton();
if (ok != null)
ok.setEnabled(selectedItems.length == 1);
}
/**
* Closes the specified editors
*/
private void closeItems(TableItem items[]) {
if(items.length == 0)
return;
for (int i = 0; i < items.length; i++) {
Adapter e = (Adapter)items[i].getData();
e.close();
}
updateItems();
}
/**
* Saves the specified editors
*/
private void saveItems(TableItem items[],IProgressMonitor monitor) {
if(items.length == 0)
return;
ProgressMonitorDialog pmd = new ProgressMonitorDialog(getShell());
pmd.open();
for (int i = 0; i < items.length; i++) {
Adapter editor = (Adapter)items[i].getData();
editor.save(pmd.getProgressMonitor());
updateItem(items[i],editor);
}
pmd.close();
updateItems();
}
/**
* Returns all clean editors from items[];
*/
private TableItem[] selectClean(TableItem items[]) {
if(items.length == 0)
return new TableItem[0];
ArrayList cleanItems = new ArrayList(items.length);
for (int i = 0; i < items.length; i++) {
Adapter editor = (Adapter)items[i].getData();
if(!editor.isDirty())
cleanItems.add(items[i]);
}
TableItem result[] = new TableItem[cleanItems.size()];
cleanItems.toArray(result);
return result;
}
/**
* Returns all clean editors from items[];
*/
private TableItem[] invertedSelection(TableItem allItems[],TableItem selectedItems[]) {
if(allItems.length == 0)
return allItems;
ArrayList invertedSelection = new ArrayList(allItems.length - selectedItems.length);
outerLoop: for (int i = 0; i < allItems.length; i++) {
for (int j = 0; j < selectedItems.length; j++) {
if(allItems[i] == selectedItems[j])
continue outerLoop;
}
invertedSelection.add(allItems[i]);
}
TableItem result[] = new TableItem[invertedSelection.size()];
invertedSelection.toArray(result);
return result;
}
/**
* Updates the specified item
*/
private void updateItem(TableItem item,Adapter editor) {
item.setData(editor);
item.setText(editor.getText());
Image images[] = editor.getImage();
for (int i = 0; i < images.length; i++) {
if (images[i] != null)
item.setImage(i, images[i]);
}
}
/**
* Adds all editors to elements
*/
private void updateEditors(IWorkbenchPage[] pages) {
for (int j = 0; j < pages.length; j++) {
IEditorReference editors[] = pages[j].getEditorReferences();
for (int k = 0; k < editors.length; k++) {
elements.add(new Adapter(editors[k]));
}
}
}
/**
* Updates all items in the table
*/
private void updateItems() {
editorsTable.removeAll();
elements = new ArrayList();
if(showAllPersp) {
IWorkbenchWindow windows[] = window.getWorkbench().getWorkbenchWindows();
for (int i = 0; i < windows.length; i++)
updateEditors(windows[i].getPages());
} else {
IWorkbenchPage page = window.getActivePage();
if (page != null) {
updateEditors(new IWorkbenchPage[]{page});
}
}
sort();
Object selection = null;
if(window.getActivePage() != null)
selection = window.getActivePage().getActiveEditor();
for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
Adapter e = (Adapter) iterator.next();
TableItem item = new TableItem(editorsTable,SWT.NULL);
updateItem(item,e);
if((selection != null) && (selection == e.editorRef))
editorsTable.setSelection(new TableItem[]{item});
}
// update the buttons, because the selection may have changed
updateButtons();
}
/**
* Sorts all the editors according to the table header
*/
private void sort() {
//Backward compatible. Table used to have 3 columns.
if(sortColumn > (editorsTable.getColumnCount() - 1))
sortColumn = 0;
Adapter a[] = new Adapter[elements.size()];
elements.toArray(a);
Arrays.sort(a);
elements = Arrays.asList(a);
}
/**
* The user has selected a resource and the dialog is closing.
*/
protected void okPressed() {
TableItem items[] = editorsTable.getSelection();
if(items.length != 1) {
super.okPressed();
return;
}
saveDialogSettings();
Adapter selection = (Adapter)items[0].getData();
//It would be better to activate before closing the
//dialog but it does not work when the editor is in other
//window. Must investigate.
super.okPressed();
selection.activate();
}
/**
* Saves the dialog settings.
*/
private void saveDialogSettings() {
IDialogSettings s = getDialogSettings();
s.put(ALLPERSP,showAllPersp);
s.put(SORT,sortColumn);
bounds = getShell().getBounds();
String array[] = new String[4];
array[0] = String.valueOf(bounds.x);
array[1] = String.valueOf(bounds.y);
array[2] = String.valueOf(bounds.width);
array[3] = String.valueOf(bounds.height);
s.put(BOUNDS,array);
array = new String[editorsTable.getColumnCount()];
for (int i = 0; i < array.length; i++)
array[i] = String.valueOf(editorsTable.getColumn(i).getWidth());
s.put(COLUMNS,array);
}
/**
* Return a dialog setting section for this dialog
*/
private IDialogSettings getDialogSettings() {
IDialogSettings settings = WorkbenchPlugin.getDefault().getDialogSettings();
IDialogSettings thisSettings = settings.getSection(getClass().getName());
if (thisSettings == null)
thisSettings = settings.addNewSection(getClass().getName());
return thisSettings;
}
/**
* A helper inner class to adapt EditorHistoryItem and IEditorPart
* in the same type.
*/
private class Adapter implements Comparable {
IEditorReference editorRef;
IEditorInput input;
IEditorDescriptor desc;
String text[];
Image images[];
Adapter(IEditorReference ref) {
editorRef = ref;
}
Adapter(IEditorInput input,IEditorDescriptor desc) {
this.input = input;
this.desc = desc;
}
boolean isDirty() {
if(editorRef == null)
return false;
return editorRef.isDirty();
}
boolean isOpened() {
return editorRef != null;
}
void close() {
if(editorRef == null)
return;
WorkbenchPage p = ((WorkbenchPartReference)editorRef).getPane().getPage();
p.closeEditor(editorRef,true);
}
void save(IProgressMonitor monitor) {
if(editorRef == null)
return;
IEditorPart editor = (IEditorPart)editorRef.getPart(true);
if(editor != null)
editor.doSave(monitor);
}
String[] getText() {
if(text != null)
return text;
text = new String[2];
if(editorRef != null) {
if(editorRef.isDirty())
text[0] = "*" + editorRef.getTitle(); //$NON-NLS-1$
else
text[0] = editorRef.getTitle();
text[1] = editorRef.getTitleToolTip();
} else {
text[0] = input.getName();
text[1] = input.getToolTipText();
}
return text;
}
Image[] getImage() {
if(images != null)
return images;
images = new Image[2];
if(editorRef != null) {
images[0] = editorRef.getTitleImage();
WorkbenchPage p = ((WorkbenchPartReference)editorRef).getPane().getPage();
IPerspectiveDescriptor persp = p.getPerspective();
ImageDescriptor image = persp.getImageDescriptor();
if(image == null)
image = WorkbenchImages.getImageDescriptor(IWorkbenchGraphicConstants.IMG_CTOOL_DEF_PERSPECTIVE);
} else {
ImageDescriptor image = null;
if(desc != null)
image = desc.getImageDescriptor();
if(image == null) {
IEditorRegistry registry = WorkbenchPlugin.getDefault().getEditorRegistry();
image = registry.getImageDescriptor(input.getName());
if (image == null) {
image = registry.getDefaultEditor().getImageDescriptor();
}
}
if (image != null) {
images[0] = (Image)disabledImageCache.get(image);
if(images[0] == null) {
Image enabled = image.createImage();
Image disabled = new Image(editorsTable.getDisplay(), enabled, SWT.IMAGE_DISABLE);
enabled.dispose();
disabledImageCache.put(image, disabled);
images[0] = disabled;
}
}
}
return images;
}
private void activate(){
if(editorRef != null) {
IEditorPart editor = editorRef.getEditor(true);
WorkbenchPage p = (WorkbenchPage)editor.getEditorSite().getPage();
Shell s = p.getWorkbenchWindow().getShell();
if(s.getMinimized())
s.setMinimized(false);
s.moveAbove(null);
p.getWorkbenchWindow().setActivePage(p);
p.activate(editor);
} else {
IWorkbenchPage p = window.getActivePage();
try {
if(desc != null)
p.openEditor(input,desc.getId(),true);
else if(input instanceof IFileEditorInput)
p.openEditor(((IFileEditorInput)input).getFile());
} catch (PartInitException e) {
}
}
}
public int compareTo(Object another) {
Adapter adapter = (Adapter)another;
int result = collator.compare(getText()[sortColumn],adapter.getText()[sortColumn]);
if(result == 0) {
int column = sortColumn == 0 ? 1 : 0;
result = collator.compare(getText()[column],adapter.getText()[column]);
}
if(reverse)
return result * -1;
return result;
}
}
}