Bug 109452 (PatchAttached) Import/Export PSF should remember last file
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetMainPage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetMainPage.java
index 3dea23c..246a29a 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetMainPage.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ExportProjectSetMainPage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * Copyright (c) 2000, 2005 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
@@ -11,7 +11,8 @@
 package org.eclipse.team.internal.ui.wizards;
 
 import java.io.File;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import org.eclipse.core.resources.IProject;
@@ -19,11 +20,20 @@
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.TableLayout;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
 import org.eclipse.team.core.RepositoryProvider;
 import org.eclipse.team.internal.ui.IHelpContextIds;
 import org.eclipse.team.internal.ui.TeamUIMessages;
@@ -32,7 +42,7 @@
 import org.eclipse.ui.model.WorkbenchLabelProvider;
 
 public class ExportProjectSetMainPage extends TeamWizardPage {
-	Text fileText;
+	Combo fileCombo;
 	String file = ""; //$NON-NLS-1$
 	Button browseButton;
 	List selectedProjects = new ArrayList();
@@ -94,11 +104,14 @@
 		inner.setLayout(layout);
 
 		createLabel(inner, TeamUIMessages.ExportProjectSetMainPage__File_name__1); 
-		fileText = createTextField(inner);
-		if (file != null) fileText.setText(file);
-		fileText.addListener(SWT.Modify, new Listener() {
+
+		fileCombo = createDropDownCombo(inner);
+		file = PsfFilenameStore.getSuggestedDefault();
+		fileCombo.setItems(PsfFilenameStore.getHistory());
+		fileCombo.setText(file);
+		fileCombo.addListener(SWT.Modify, new Listener() {
 			public void handleEvent(Event event) {
-				file = fileText.getText();
+				file = fileCombo.getText();				
 				updateEnablement();
 			}
 		});
@@ -126,7 +139,7 @@
 				d.setFilterPath(fileName);
 				String f = d.open();
 				if (f != null) {
-					fileText.setText(f);
+					fileCombo.setText(f);
 					file = f;
 				}
 			}
@@ -193,7 +206,7 @@
 	public void setVisible(boolean visible) {
 		super.setVisible(visible);
 		if (visible) {
-			fileText.setFocus();
+			fileCombo.setFocus();
 		}
 	}
 }
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java
index dee7660..b370818 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ImportProjectSetMainPage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * Copyright (c) 2000, 2005 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
@@ -17,16 +17,28 @@
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.*;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.*;
-import org.eclipse.team.internal.ui.*;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.team.internal.ui.IHelpContextIds;
+import org.eclipse.team.internal.ui.TeamUIMessages;
+import org.eclipse.team.internal.ui.TeamUIPlugin;
 import org.eclipse.ui.IWorkingSet;
 import org.eclipse.ui.PlatformUI;
 
 public class ImportProjectSetMainPage extends TeamWizardPage {
-	Text fileText;
+	Combo fileCombo;
 	String file = ""; //$NON-NLS-1$
 	Button browseButton;
 	Button createWorkingSetButton;
@@ -62,11 +74,14 @@
 		inner.setLayout(layout);
 		
 		createLabel(inner, TeamUIMessages.ImportProjectSetMainPage_Project_Set_File_Name__2); 
-		fileText = createTextField(inner);
-		if (file != null) fileText.setText(file);
-		fileText.addListener(SWT.Modify, new Listener() {
+
+		fileCombo = createDropDownCombo(inner);
+		file = PsfFilenameStore.getSuggestedDefault();
+		fileCombo.setItems(PsfFilenameStore.getHistory());
+		fileCombo.setText(file);
+		fileCombo.addListener(SWT.Modify, new Listener() {
 			public void handleEvent(Event event) {
-				file = fileText.getText();				
+				file = fileCombo.getText();				
 				updateEnablement();
 			}
 		});
@@ -95,7 +110,7 @@
 				d.setFilterPath(fileName);
 				String f = d.open();
 				if (f != null) {
-					fileText.setText(f);
+					fileCombo.setText(f);
 					file = f;
 				}
 			}
@@ -188,19 +203,15 @@
 		}
 		setPageComplete(complete);
 	}
-	
+
 	public String getFileName() {
 		return file;
 	}
-	public void setFileName(String file) {
-		if (file != null) {
-			this.file = file;
-		}
-	}
+
 	public void setVisible(boolean visible) {
 		super.setVisible(visible);
 		if (visible) {
-			fileText.setFocus();
+			fileCombo.setFocus();
 		}
 	}
 
@@ -211,5 +222,4 @@
 		if (!createWorkingSet) return null;
 		return workingSetName;
 	}
-
 }
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetExportWizard.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetExportWizard.java
index 0a4afcf..0189059 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetExportWizard.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetExportWizard.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * Copyright (c) 2000, 2005 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
@@ -35,8 +35,8 @@
 import org.eclipse.team.core.RepositoryProvider;
 import org.eclipse.team.core.RepositoryProviderType;
 import org.eclipse.team.core.TeamException;
-import org.eclipse.team.internal.ui.*;
 import org.eclipse.team.internal.ui.ITeamUIImages;
+import org.eclipse.team.internal.ui.TeamUIMessages;
 import org.eclipse.team.internal.ui.TeamUIPlugin;
 import org.eclipse.team.internal.ui.UIProjectSetSerializationContext;
 import org.eclipse.ui.IExportWizard;
@@ -55,7 +55,6 @@
 		mainPage = new ExportProjectSetMainPage("projectSetMainPage", TeamUIMessages.ProjectSetExportWizard_Export_a_Project_Set_3, TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_PROJECTSET_EXPORT_BANNER)); //$NON-NLS-1$ 
 		IProject[] projects = (IProject[])selection.toList().toArray(new IProject[0]);
 		mainPage.setSelectedProjects(projects);
-		mainPage.setFileName(ProjectSetImportWizard.lastFile);
 		addPage(mainPage);
 	}
 	public boolean performFinish() {
@@ -68,7 +67,7 @@
 					if (path.getFileExtension() == null) {
 						filename = filename + ".psf"; //$NON-NLS-1$
 					}
-					ProjectSetImportWizard.lastFile = filename;
+					PsfFilenameStore.remember(filename);
 					File file = new File(filename);
 					File parentFile = file.getParentFile();
 					if (parentFile != null && !parentFile.exists()) {
@@ -196,7 +195,7 @@
 		}
 		return result[0];
 	}
-	
+
 	public void init(IWorkbench workbench, IStructuredSelection selection) {
 		this.selection = selection;
 	}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetImportWizard.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetImportWizard.java
index cac6bc0..f580a86b 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetImportWizard.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetImportWizard.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * Copyright (c) 2000, 2005 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
@@ -35,7 +35,6 @@
 
 public class ProjectSetImportWizard extends Wizard implements IImportWizard {
 	ImportProjectSetMainPage mainPage;
-	public static String lastFile;
 
 	public ProjectSetImportWizard() {
 		setNeedsProgressMonitor(true);
@@ -44,11 +43,10 @@
 	
 	public void addPages() {
 		mainPage = new ImportProjectSetMainPage("projectSetMainPage", TeamUIMessages.ProjectSetImportWizard_Import_a_Project_Set_3, TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_PROJECTSET_IMPORT_BANNER)); //$NON-NLS-1$ 
-		mainPage.setFileName(lastFile);
 		addPage(mainPage);
 	}
+
 	public boolean performFinish() {
-		
 		// check if the desired working set exists
 		final String workingSetName = mainPage.getWorkingSetName();
 		if (workingSetName != null) {
@@ -62,8 +60,9 @@
 		try {
 			getContainer().run(true, true, new WorkspaceModifyOperation(null) {
 				public void execute(IProgressMonitor monitor) throws InvocationTargetException {
-					lastFile= mainPage.getFileName();
-					IProject[] newProjects= ProjectSetImporter.importProjectSet(lastFile, getShell(), monitor);
+					String psfFile = mainPage.getFileName();
+					PsfFilenameStore.remember(psfFile);
+					IProject[] newProjects= ProjectSetImporter.importProjectSet(psfFile, getShell(), monitor);
 					if (workingSetName != null)
 						createWorkingSet(workingSetName, newProjects);
 					result[0] = true;
@@ -102,7 +101,10 @@
 			oldSet.setElements(projects);
 		}	
 	}
-	
+
 	public void init(IWorkbench workbench, IStructuredSelection selection) {
+		// The code that finds "selection" is broken (it is always empty), so we
+		// must dig for the selection in the workbench.
+		PsfFilenameStore.setDefaultFromSelection(workbench);
 	}
 }
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/PsfFilenameStore.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/PsfFilenameStore.java
new file mode 100644
index 0000000..571fb49
--- /dev/null
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/PsfFilenameStore.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2005 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.ui.wizards;
+
+import java.util.Vector;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.team.internal.ui.TeamUIPlugin;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+
+public class PsfFilenameStore {
+	// Most recently used filename is first in the array.
+	// Least recently used filename is at the end of the list.
+	// When the list overflows, items drop off the end.
+	private static final int HISTORY_LENGTH = 10;
+
+	private static final String STORE_SECTION = "ImportPSFDialog"; //$NON-NLS-1$
+	private static final String FILENAMES = "filenames"; //$NON-NLS-1$
+	private static final String PREVIOUS = "previous"; //$NON-NLS-1$
+
+	// If a PSF file was selected when the wizard was opened, then this is it.
+	// This is only a cache; it is not part of the history until the user has used it.
+	private static String _selectedFilename = null;
+
+	private static IDialogSettings _section;
+
+	private PsfFilenameStore() {
+		// All-static
+	}
+
+	public static void setDefaultFromSelection(IWorkbench workbench) {
+		// Scan the workbench for a selected PSF file
+		IWorkbenchWindow wnd = workbench.getActiveWorkbenchWindow();
+		IWorkbenchPage pg = wnd.getActivePage();
+		ISelection sel = pg.getSelection();
+
+		if (!(sel instanceof IStructuredSelection)) {
+			return;
+		}
+		IStructuredSelection selection = (IStructuredSelection)sel;
+
+		Object firstElement = selection.getFirstElement();
+		if (!(firstElement instanceof IAdaptable)) {
+			return;
+		}
+		Object o = ((IAdaptable) firstElement).getAdapter(IResource.class);
+		if (o == null) {
+			return;
+		}
+		IResource resource = (IResource) o;
+
+		if (resource.getType() != IResource.FILE) {
+			return;
+		}
+
+		if (!resource.isAccessible()) {
+			return;
+		}
+
+		String extension = resource.getFileExtension();
+		if (extension == null || !extension.equalsIgnoreCase("psf")) { //$NON-NLS-1$
+			return;
+		}
+
+		IWorkspace workspace = resource.getWorkspace();
+		workspace.getRoot().getFullPath();
+
+		IPath path = resource.getLocation();
+		_selectedFilename = path.toOSString();
+	}
+
+	public static String getSuggestedDefault() {
+		if (_selectedFilename != null) {
+			return _selectedFilename;
+		}
+		return getPrevious();
+	}
+
+	private static String getPrevious() {
+		IDialogSettings section = getSettingsSection();
+		String retval = section.get(PREVIOUS);
+		if (retval == null) {
+			retval = ""; //$NON-NLS-1$
+		}
+		return retval;
+	}
+
+	public static String[] getHistory() {
+		IDialogSettings section = getSettingsSection();
+		String[] arr = section.getArray(FILENAMES);
+		if (arr == null) {
+			arr = new String[0];
+		}
+		return arr;
+	}
+
+	public static void remember(String filename) {
+		Vector filenames = createVector(getHistory());
+		if (filenames.contains(filename)) {
+			// The item is in the list. Remove it and add it back at the
+			// beginning. If it already was at the beginning this will be a
+			// waste of time, but it's not even measurable so I don't care.
+			filenames.remove(filename);
+		}
+		// Most recently used filename goes to the beginning of the list
+		filenames.add(0, filename);
+
+		// Forget any overflowing items
+		while (filenames.size() > HISTORY_LENGTH) {
+			filenames.remove(HISTORY_LENGTH);
+		}
+
+		// Make it an array
+		String[] arr = (String[]) filenames.toArray(new String[filenames.size()]);
+
+		IDialogSettings section = getSettingsSection();
+		section.put(FILENAMES, arr);
+		section.put(PREVIOUS, filename);
+	}
+
+	private static Vector createVector(Object[] arr) {
+		Vector v = new Vector();
+		for (int ix = 0; ix < arr.length; ++ix) {
+			v.add(ix, arr[ix]);
+		}
+		return v;
+	}
+
+	private static IDialogSettings getSettingsSection() {
+		if (_section != null)
+			return _section;
+
+		IDialogSettings settings = TeamUIPlugin.getPlugin().getDialogSettings();
+		_section = settings.getSection(STORE_SECTION);
+		if (_section != null)
+			return _section;
+
+		_section = settings.addNewSection(STORE_SECTION);
+		return _section;
+	}
+}
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/TeamWizardPage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/TeamWizardPage.java
index c0e3287..cfb8e34 100644
--- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/TeamWizardPage.java
+++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/TeamWizardPage.java
@@ -16,6 +16,7 @@
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Text;
@@ -97,4 +98,20 @@
 		text.setLayoutData(data);
 		return text;
 	}
+
+	/**
+	 * Create a drop-down combo box specific for this application
+	 * 
+	 * @param parent  the parent of the new combo box
+	 * @return the new combo box
+	 */
+	protected Combo createDropDownCombo(Composite parent) {
+		Combo combo = new Combo(parent, SWT.DROP_DOWN);
+		GridData comboData = new GridData(GridData.FILL_HORIZONTAL);
+		comboData.verticalAlignment = GridData.CENTER;
+		comboData.grabExcessVerticalSpace = false;
+		comboData.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		combo.setLayoutData(comboData);
+		return combo;
+	}
 }