/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *******************************************************************************/
package org.eclipse.swt.widgets;


import java.io.*;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;

/**
 * Instances of this class allow the user to navigate
 * the file system and select or enter a file name.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>SAVE, OPEN, MULTI</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * Note: Only one of the styles SAVE and OPEN may be specified.
 * </p><p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 *
 * @see <a href="http://www.eclipse.org/swt/snippets/#filedialog">FileDialog snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample, Dialog tab</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class FileDialog extends Dialog {
	String [] filterNames = new String [0];
	String [] filterExtensions = new String [0];
	String filterPath = "";
	String fileName = "";
	String[] fileNames = new String [0];
	String fullPath = "";
	int filterIndex = -1;
	boolean overwrite = false;
	boolean uriMode;
	long /*int*/ handle;
	static final char SEPARATOR = File.separatorChar;
	static final char EXTENSION_SEPARATOR = ';';
	static final char FILE_EXTENSION_SEPARATOR = '.';

/**
 * Constructs a new instance of this class given only its parent.
 *
 * @param parent a shell which will be the parent of the new instance
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 */
public FileDialog (Shell parent) {
	this (parent, SWT.APPLICATION_MODAL);
}
/**
 * Constructs a new instance of this class given its parent
 * and a style value describing its behavior and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p>
 *
 * @param parent a shell which will be the parent of the new instance
 * @param style the style of dialog to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT#SAVE
 * @see SWT#OPEN
 * @see SWT#MULTI
 */
public FileDialog (Shell parent, int style) {
	super (parent, checkStyle (parent, style));
	checkSubclass ();
}
String computeResultChooserDialog () {
	/* MULTI is only valid if the native dialog's action is Open */
	fullPath = null;
	if ((style & SWT.MULTI) != 0) {
		long /*int*/ list = 0;
		if (uriMode) {
			list = GTK.gtk_file_chooser_get_uris (handle);
		} else {
			list = GTK.gtk_file_chooser_get_filenames (handle);
		}
		int listLength = OS.g_slist_length (list);
		fileNames = new String [listLength];
		long /*int*/ current = list;
		int writePos = 0;
		for (int i = 0; i < listLength; i++) {
			long /*int*/ name = OS.g_slist_data (current);
			long /*int*/ utf8Ptr = 0;
			if (uriMode) {
				utf8Ptr = name;
			} else {
				utf8Ptr = OS.g_filename_to_utf8 (name, -1, null, null, null);
				if (utf8Ptr == 0) utf8Ptr = OS.g_filename_display_name (name);
			}
			if (name != utf8Ptr) OS.g_free (name);
			if (utf8Ptr != 0) {
				long /*int*/ [] items_written = new long /*int*/ [1];
				long /*int*/ utf16Ptr = OS.g_utf8_to_utf16 (utf8Ptr, -1, null, items_written, null);
				OS.g_free (utf8Ptr);
				if (utf16Ptr != 0) {
					int clength = (int)/*64*/items_written [0];
					char [] chars = new char [clength];
					C.memmove (chars, utf16Ptr, clength * 2);
					OS.g_free (utf16Ptr);
					fullPath = new String (chars);
					fileNames [writePos++] = fullPath.substring (fullPath.lastIndexOf (SEPARATOR) + 1);
				}
			}
			current = OS.g_slist_next (current);
		}
		if (writePos != 0 && writePos != listLength) {
			String [] validFileNames = new String [writePos];
			System.arraycopy (fileNames, 0, validFileNames, 0, writePos);
			fileNames = validFileNames;
		}
		OS.g_slist_free (list);
	} else {
		long /*int*/ utf8Ptr = 0;
		if (uriMode) {
			utf8Ptr = GTK.gtk_file_chooser_get_uri (handle);
		} else {
			long /*int*/ path = GTK.gtk_file_chooser_get_filename (handle);
			if (path != 0) {
				utf8Ptr = OS.g_filename_to_utf8 (path, -1, null, null, null);
				if (utf8Ptr == 0) utf8Ptr = OS.g_filename_display_name (path);
				if (path != utf8Ptr) OS.g_free (path);
			}
		}
		if (utf8Ptr != 0) {
			long /*int*/ [] items_written = new long /*int*/ [1];
			long /*int*/ utf16Ptr = OS.g_utf8_to_utf16 (utf8Ptr, -1, null, items_written, null);
			OS.g_free (utf8Ptr);
			if (utf16Ptr != 0) {
				int clength = (int)/*64*/items_written [0];
				char [] chars = new char [clength];
				C.memmove (chars, utf16Ptr, clength * 2);
				OS.g_free (utf16Ptr);
				fullPath = new String (chars);
				fileNames = new String [1];
				fileNames[0] = fullPath.substring (fullPath.lastIndexOf (SEPARATOR) + 1);
			}
		}
	}
	filterIndex = -1;
	long /*int*/ filter = GTK.gtk_file_chooser_get_filter (handle);
	if (filter != 0) {
		long /*int*/ filterNamePtr = GTK.gtk_file_filter_get_name (filter);
		if (filterNamePtr != 0) {
			int length = C.strlen (filterNamePtr);
			byte[] buffer = new byte [length];
			C.memmove (buffer, filterNamePtr, length);
			//OS.g_free (filterNamePtr); //GTK owns this pointer - do not free
			String filterName = new String (Converter.mbcsToWcs (buffer));
			for (int i = 0; i < filterExtensions.length; i++) {
				if (filterNames.length > 0) {
					if (filterNames[i].equals(filterName)) {
						filterIndex = i;
						break;
					}
				} else {
					if (filterExtensions[i].equals(filterName)) {
						filterIndex = i;
						break;
					}
				}
			}
		}
	}
	if (fullPath != null) {
		int separatorIndex = fullPath.lastIndexOf (SEPARATOR);
		fileName = fullPath.substring (separatorIndex + 1);
		filterPath = fullPath.substring (0, separatorIndex);
	}
	return fullPath;
}

/**
 * Returns the path of the first file that was
 * selected in the dialog relative to the filter path, or an
 * empty string if no such file has been selected.
 *
 * @return the relative path of the file
 */
public String getFileName () {
	return fileName;
}
/**
 * Returns a (possibly empty) array with the paths of all files
 * that were selected in the dialog relative to the filter path.
 *
 * @return the relative paths of the files
 */
public String [] getFileNames () {
	return fileNames;
}
/**
 * Returns the file extensions which the dialog will
 * use to filter the files it shows.
 *
 * @return the file extensions filter
 */
public String [] getFilterExtensions () {
	return filterExtensions;
}
/**
 * Get the 0-based index of the file extension filter
 * which was selected by the user, or -1 if no filter
 * was selected.
 * <p>
 * This is an index into the FilterExtensions array and
 * the FilterNames array.
 * </p>
 *
 * @return index the file extension filter index
 *
 * @see #getFilterExtensions
 * @see #getFilterNames
 *
 * @since 3.4
 */
public int getFilterIndex () {
	return filterIndex;
}
/**
 * Returns the names that describe the filter extensions
 * which the dialog will use to filter the files it shows.
 *
 * @return the list of filter names
 */
public String [] getFilterNames () {
	return filterNames;
}
/**
 * Returns the directory path that the dialog will use, or an empty
 * string if this is not set.  File names in this path will appear
 * in the dialog, filtered according to the filter extensions.
 *
 * @return the directory path string
 *
 * @see #setFilterExtensions
 */
public String getFilterPath () {
	return filterPath;
}
/**
 * Returns the flag that the dialog will use to
 * determine whether to prompt the user for file
 * overwrite if the selected file already exists.
 *
 * @return true if the dialog will prompt for file overwrite, false otherwise
 *
 * @since 3.4
 */
public boolean getOverwrite () {
	return overwrite;
}
/**
 * Makes the dialog visible and brings it to the front
 * of the display.
 *
 * @return a string describing the absolute path of the first selected file,
 *         or null if the dialog was cancelled or an error occurred
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the dialog has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog</li>
 * </ul>
 */
public String open () {
	if (GTK.GTK_VERSION >= OS.VERSION(3, 20, 0)) {
		return openNativeChooserDialog();
	} else {
		return openChooserDialog();
	}
}
/**
 * Open the file chooser dialog using the GtkFileChooserNative API (GTK3.20+) for running applications
 * without direct filesystem access (such as Flatpak). API for GtkFileChoosernative does not
 * give access to any GtkWindow or GtkWidget for the dialog, thus this method omits calls that
 * requires such access. These are be handled by the GtkNativeDialog API.
 *
 * @return a string describing the absolute path of the first selected file, or null
 */
String openNativeChooserDialog () {
	assert GTK.GTK_VERSION >= OS.VERSION(3, 20, 0);
	byte [] titleBytes = Converter.wcsToMbcs (title, true);
	int action = (style & SWT.SAVE) != 0 ? GTK.GTK_FILE_CHOOSER_ACTION_SAVE : GTK.GTK_FILE_CHOOSER_ACTION_OPEN;
	long /*int*/ shellHandle = parent.topHandle ();
	Display display = parent != null ? parent.getDisplay (): Display.getCurrent ();
	handle = GTK.gtk_file_chooser_native_new(titleBytes, shellHandle, action, GTK.GTK_NAMED_LABEL_OK, GTK.GTK_NAMED_LABEL_CANCEL);
	if (handle == 0) error (SWT.ERROR_NO_HANDLES);

	if (uriMode) {
		GTK.gtk_file_chooser_set_local_only (handle, false);
	}
	presetChooserDialog ();
	display.addIdleProc ();
	String answer = null;
	int signalId = 0;
	long /*int*/ hookId = 0;
	if ((style & SWT.RIGHT_TO_LEFT) != 0) {
		signalId = OS.g_signal_lookup (OS.map, GTK.GTK_TYPE_WIDGET());
		hookId = OS.g_signal_add_emission_hook (signalId, 0, display.emissionProc, handle, 0);
	}
	display.sendPreExternalEventDispatchEvent ();
	int response = 0;
	response = GTK.gtk_native_dialog_run(handle);
	/*
	* This call to gdk_threads_leave() is a temporary work around
	* to avoid deadlocks when gdk_threads_init() is called by native
	* code outside of SWT (i.e AWT, etc). It ensures that the current
	* thread leaves the GTK lock acquired by the function above.
	*/
	GDK.gdk_threads_leave();
	display.sendPostExternalEventDispatchEvent ();
	if ((style & SWT.RIGHT_TO_LEFT) != 0) {
		OS.g_signal_remove_emission_hook (signalId, hookId);
	}
	if (response == GTK.GTK_RESPONSE_ACCEPT) {
		answer = computeResultChooserDialog ();
	}
	display.removeIdleProc ();
	return answer;
}
String openChooserDialog () {
	byte [] titleBytes = Converter.wcsToMbcs (title, true);
	int action = (style & SWT.SAVE) != 0 ?
		GTK.GTK_FILE_CHOOSER_ACTION_SAVE :
		GTK.GTK_FILE_CHOOSER_ACTION_OPEN;
	long /*int*/ shellHandle = parent.topHandle ();
	Display display = parent != null ? parent.getDisplay (): Display.getCurrent ();
	if (display.getDismissalAlignment() == SWT.RIGHT) {
		handle = GTK.gtk_file_chooser_dialog_new (titleBytes, shellHandle, action, GTK.GTK_NAMED_LABEL_CANCEL, GTK.GTK_RESPONSE_CANCEL, GTK.GTK_NAMED_LABEL_OK, GTK.GTK_RESPONSE_OK, 0);
	} else {
		handle = GTK.gtk_file_chooser_dialog_new (titleBytes, shellHandle, action, GTK.GTK_NAMED_LABEL_OK, GTK.GTK_RESPONSE_OK, GTK.GTK_NAMED_LABEL_CANCEL, GTK.GTK_RESPONSE_CANCEL, 0);
	}
	if (handle == 0) error (SWT.ERROR_NO_HANDLES);
	GTK.gtk_window_set_modal (handle, true);
	long /*int*/ group = GTK.gtk_window_get_group(0);
	GTK.gtk_window_group_add_window (group, handle);
	long /*int*/ pixbufs = GTK.gtk_window_get_icon_list (shellHandle);
	if (pixbufs != 0) {
		GTK.gtk_window_set_icon_list (handle, pixbufs);
		OS.g_list_free (pixbufs);
	}
	if (uriMode) {
		GTK.gtk_file_chooser_set_local_only (handle, false);
	}
	presetChooserDialog ();
	display.addIdleProc ();
	String answer = null;
	Dialog oldModal = null;
	if (GTK.gtk_window_get_modal (handle)) {
		oldModal = display.getModalDialog ();
		display.setModalDialog (this);
	}
	int signalId = 0;
	long /*int*/ hookId = 0;
	if ((style & SWT.RIGHT_TO_LEFT) != 0) {
		signalId = OS.g_signal_lookup (OS.map, GTK.GTK_TYPE_WIDGET());
		hookId = OS.g_signal_add_emission_hook (signalId, 0, display.emissionProc, handle, 0);
	}
	display.sendPreExternalEventDispatchEvent ();
	int response = GTK.gtk_dialog_run (handle);
	/*
	* This call to gdk_threads_leave() is a temporary work around
	* to avoid deadlocks when gdk_threads_init() is called by native
	* code outside of SWT (i.e AWT, etc). It ensures that the current
	* thread leaves the GTK lock acquired by the function above.
	*/
	GDK.gdk_threads_leave();
	display.sendPostExternalEventDispatchEvent ();
	if ((style & SWT.RIGHT_TO_LEFT) != 0) {
		OS.g_signal_remove_emission_hook (signalId, hookId);
	}
	if (GTK.gtk_window_get_modal (handle)) {
		display.setModalDialog (oldModal);
	}
	if (response == GTK.GTK_RESPONSE_OK) {
		answer = computeResultChooserDialog ();
	}
	display.removeIdleProc ();
	GTK.gtk_widget_destroy (handle);
	return answer;
}
void presetChooserDialog () {
	/* MULTI is only valid if the native dialog's action is Open */
	if ((style & (SWT.SAVE | SWT.MULTI)) == SWT.MULTI) {
		GTK.gtk_file_chooser_set_select_multiple (handle, true);
	}
	if (filterPath == null) filterPath = "";
	if (fileName == null) fileName = "";
	if ((style & SWT.SAVE) != 0) {
		if (fileName.equals ("")) {
			fileName = "Untitled";
		}
		if (filterPath.length () > 0) {
			if (uriMode) {
				byte [] buffer = Converter.wcsToMbcs (filterPath, true);
				GTK.gtk_file_chooser_set_current_folder_uri (handle, buffer);
			} else {
				/* filename must be a full path */
				byte [] buffer = Converter.wcsToMbcs (SEPARATOR + filterPath, true);
				/*
				 * in GTK version 2.10, gtk_file_chooser_set_current_folder requires path
				 * to be true canonical path. So using realpath to convert the path to
				 * true canonical path.
				 */
				long /*int*/ ptr = OS.realpath (buffer, null);
				if (ptr != 0) {
					GTK.gtk_file_chooser_set_current_folder (handle, ptr);
					OS.g_free (ptr);
				}
			}
		}
		if (fileName.length () > 0) {
			StringBuilder filenameWithExt = new StringBuilder();
			filenameWithExt.append (fileName);
			if ((fileName.lastIndexOf (FILE_EXTENSION_SEPARATOR) == -1) &&
					(filterExtensions.length != 0)) {  // Filename doesn't contain the extension and user has provided filter extensions
				String selectedFilter = null;
				if (this.filterIndex == -1) {
					selectedFilter = filterExtensions[0];
				} else {
					selectedFilter = filterExtensions[filterIndex];
				}
				String extFilter = null;
				int index = selectedFilter.indexOf (EXTENSION_SEPARATOR);
				if (index == -1) {
					extFilter = selectedFilter.trim ();
				} else {
					extFilter = selectedFilter.substring (0, index).trim ();
				}

				int separatorIndex = extFilter.lastIndexOf (FILE_EXTENSION_SEPARATOR);
				String extension = extFilter.substring (separatorIndex);

				if (!isGlobPattern (extension)) { //if the extension is of type glob pattern we should not add the extension
					filenameWithExt.append (extension);
				}
			}
			byte [] buffer = Converter.wcsToMbcs (filenameWithExt.toString (), true);
			GTK.gtk_file_chooser_set_current_name (handle, buffer);
		}
	} else {
		StringBuilder stringBuilder = new StringBuilder();
		if (filterPath.length () > 0) {
			if (!uriMode) {
				/* filename must be a full path */
				stringBuilder.append(SEPARATOR);
			}
			stringBuilder.append(filterPath);
			stringBuilder.append(SEPARATOR);
		}
		if (fileName.length () > 0) {
			stringBuilder.append(fileName);
		}
		byte [] buffer = Converter.wcsToMbcs (stringBuilder.toString(), true);
		if (uriMode) {
			GTK.gtk_file_chooser_set_uri (handle, buffer);
		} else {
			/*
			 * in GTK version 2.10, gtk_file_chooser_set_current_folder requires path
			 * to be true canonical path. So using realpath to convert the path to
			 * true canonical path.
			 */
			long /*int*/ ptr = OS.realpath (buffer, null);
			if (ptr != 0) {
				if (fileName.length() > 0) {
					GTK.gtk_file_chooser_set_filename (handle, ptr);
				} else {
					GTK.gtk_file_chooser_set_current_folder (handle, ptr);
				}
				OS.g_free (ptr);
			}
		}
	}

	/* Set overwrite mode */
	if ((style & SWT.SAVE) != 0) {
		GTK.gtk_file_chooser_set_do_overwrite_confirmation (handle, overwrite);
	}

	/* Set the extension filters */
	if (filterNames == null) filterNames = new String [0];
	if (filterExtensions == null) filterExtensions = new String [0];
	long /*int*/ initialFilter = 0;
	for (int i = 0; i < filterExtensions.length; i++) {
		if (filterExtensions [i] != null) {
			long /*int*/ filter = GTK.gtk_file_filter_new ();
			if (filterNames.length > i && filterNames [i] != null) {
				byte [] name = Converter.wcsToMbcs (filterNames [i], true);
				GTK.gtk_file_filter_set_name (filter, name);
			} else {
				byte [] name = Converter.wcsToMbcs (filterExtensions [i], true);
				GTK.gtk_file_filter_set_name (filter, name);
			}
			int start = 0;
			int index = filterExtensions [i].indexOf (EXTENSION_SEPARATOR);
			while (index != -1) {
				String current = filterExtensions [i].substring (start, index);
				byte [] filterString = Converter.wcsToMbcs (current, true);
				GTK.gtk_file_filter_add_pattern (filter, filterString);
				start = index + 1;
				index = filterExtensions [i].indexOf (EXTENSION_SEPARATOR, start);
			}
			String current = filterExtensions [i].substring (start);
			byte [] filterString = Converter.wcsToMbcs (current, true);
			GTK.gtk_file_filter_add_pattern (filter, filterString);
			GTK.gtk_file_chooser_add_filter (handle, filter);
			if (i == filterIndex) {
				initialFilter = filter;
			}
		}
	}
	if (initialFilter != 0) {
		GTK.gtk_file_chooser_set_filter(handle, initialFilter);
	}
	fullPath = null;
	fileNames = new String [0];
}
/**
 * Check whether the file extension is a glob pattern.
 * For example, *.* is a glob pattern which corresponds to all files
 * *.jp* corresponds to all the files with extension starting with jp like jpg,jpeg etc
 * *.jp? corresponds to 3 letter extension starting with jp with any 3rd letter
 * *.[pq]ng this corresponds to *.png and *.qng
 *
 * @param extension file extension as a string
 *
 * @returns true if the extension contains any of the glob pattern wildcards
 */
private boolean isGlobPattern (String extension) {
	if (extension.contains ("*") ||
			extension.contains ("?") ||
			(extension.contains ("[") && extension.contains ("]"))) {
		return true;
	}
	return false;
}
/**
 * Set the initial filename which the dialog will
 * select by default when opened to the argument,
 * which may be null.  The name will be prefixed with
 * the filter path when one is supplied.
 *
 * @param string the file name
 */
public void setFileName (String string) {
	fileName = string;
}
/**
 * Set the file extensions which the dialog will
 * use to filter the files it shows to the argument,
 * which may be null.
 * <p>
 * The strings are platform specific. For example, on
 * some platforms, an extension filter string is typically
 * of the form "*.extension", where "*.*" matches all files.
 * For filters with multiple extensions, use semicolon as
 * a separator, e.g. "*.jpg;*.png".
 * </p>
 * <p>
 * Note: On Mac, setting the file extension filter affects how
 * app bundles are treated by the dialog. When a filter extension
 * having the app extension (.app) is selected, bundles are treated
 * as files. For all other extension filters, bundles are treated
 * as directories. When no filter extension is set, bundles are
 * treated as files.
 * </p>
 *
 * @param extensions the file extension filter
 *
 * @see #setFilterNames to specify the user-friendly
 * names corresponding to the extensions
 */
public void setFilterExtensions (String [] extensions) {
	filterExtensions = extensions;
}
/**
 * Set the 0-based index of the file extension filter
 * which the dialog will use initially to filter the files
 * it shows to the argument.
 * <p>
 * This is an index into the FilterExtensions array and
 * the FilterNames array.
 * </p>
 *
 * @param index the file extension filter index
 *
 * @see #setFilterExtensions
 * @see #setFilterNames
 *
 * @since 3.4
 */
public void setFilterIndex (int index) {
	filterIndex = index;
}
/**
 * Sets the names that describe the filter extensions
 * which the dialog will use to filter the files it shows
 * to the argument, which may be null.
 * <p>
 * Each name is a user-friendly short description shown for
 * its corresponding filter. The <code>names</code> array must
 * be the same length as the <code>extensions</code> array.
 * </p>
 *
 * @param names the list of filter names, or null for no filter names
 *
 * @see #setFilterExtensions
 */
public void setFilterNames (String [] names) {
	filterNames = names;
}
/**
 * Sets the directory path that the dialog will use
 * to the argument, which may be null. File names in this
 * path will appear in the dialog, filtered according
 * to the filter extensions. If the string is null,
 * then the operating system's default filter path
 * will be used.
 * <p>
 * Note that the path string is platform dependent.
 * For convenience, either '/' or '\' can be used
 * as a path separator.
 * </p>
 *
 * @param string the directory path
 *
 * @see #setFilterExtensions
 */
public void setFilterPath (String string) {
	filterPath = string;
}

/**
 * Sets the flag that the dialog will use to
 * determine whether to prompt the user for file
 * overwrite if the selected file already exists.
 *
 * @param overwrite true if the dialog will prompt for file overwrite, false otherwise
 *
 * @since 3.4
 */
public void setOverwrite (boolean overwrite) {
	this.overwrite = overwrite;
}
/* Sets URI Mode.
 *
 * When the FileDialog is in URI mode it returns
 * a URI (instead of a file name) for the following
 * methods: open() and getFilterPath().
 * The input argment for setFilterPath() should also
 * be a URI.
 */
/*public*/ void setURIMode (boolean uriMode) {
	this.uriMode = uriMode;
}
}
