/*******************************************************************************
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.widgets;
import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.*;
/**
* Instances of this class allow the user to navigate
* the file system and select or enter a file name.
*
* - Styles:
* - SAVE, OPEN, MULTI
* - Events:
* - (none)
*
*
* Note: Only one of the styles SAVE and OPEN may be specified.
*
* IMPORTANT: This class is intended to be subclassed only
* within the SWT implementation.
*
*/
public class FileDialog extends Dialog {
String [] filterNames = new String [0];
String [] filterExtensions = new String [0];
String [] fileNames = new String [0];
String filterPath = "", fileName = "";
static final String FILTER = "*.*";
static int BUFFER_SIZE = 1024 * 32;
/**
* 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
* - ERROR_NULL_ARGUMENT - if the parent is null
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
* - ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
*
*/
public FileDialog (Shell parent) {
this (parent, SWT.PRIMARY_MODAL);
}
/**
* Constructs a new instance of this class given its parent
* and a style value describing its behavior and appearance.
*
* The style value is either one of the style constants defined in
* class SWT
which is applicable to instances of this
* class, or must be built by bitwise OR'ing together
* (that is, using the int
"|" operator) two or more
* of those SWT
style constants. The class description
* lists the style constants that are applicable to the class.
* Style bits are also inherited from superclasses.
*
*
* @param parent a shell which will be the parent of the new instance
* @param style the style of dialog to construct
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the parent is null
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
* - ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
*
*/
public FileDialog (Shell parent, int style) {
super (parent, style);
checkSubclass ();
}
/**
* 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;
}
/**
* 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;
}
/**
* 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
* - ERROR_WIDGET_DISPOSED - if the dialog has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the dialog
*
*/
public String open () {
int hHeap = OS.GetProcessHeap ();
/* Get the owner HWND for the dialog */
int hwndOwner = 0;
if (parent != null) hwndOwner = parent.handle;
/* Convert the title and copy it into lpstrTitle */
if (title == null) title = "";
/* Use the character encoding for the default locale */
TCHAR buffer3 = new TCHAR (0, title, true);
int byteCount3 = buffer3.length () * TCHAR.sizeof;
int lpstrTitle = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount3);
OS.MoveMemory (lpstrTitle, buffer3, byteCount3);
/* Compute filters and copy into lpstrFilter */
String strFilter = "";
if (filterNames == null) filterNames = new String [0];
if (filterExtensions == null) filterExtensions = new String [0];
for (int i=0; i 0) {
/* Use the character encoding for the default locale */
TCHAR prefix = new TCHAR (0, nFileOffset - 1);
int byteCount2 = prefix.length () * TCHAR.sizeof;
OS.MoveMemory (prefix, lpstrFile, byteCount2);
filterPath = prefix.toString (0, prefix.length ());
/*
* Get each file from the buffer. Files are delimited
* by a NULL character with 2 NULL characters at the end.
*/
int count = 0;
fileNames = new String [(style & SWT.MULTI) != 0 ? 4 : 1];
int start = nFileOffset;
do {
int end = start;
while (end < buffer.length () && buffer.tcharAt (end) != 0) end++;
String string = buffer.toString (start, end - start);
start = end;
if (count == fileNames.length) {
String [] newFileNames = new String [fileNames.length + 4];
System.arraycopy (fileNames, 0, newFileNames, 0, fileNames.length);
fileNames = newFileNames;
}
fileNames [count++] = string;
if ((style & SWT.MULTI) == 0) break;
start++;
} while (start < buffer.length () && buffer.tcharAt (start) != 0);
if (fileNames.length > 0) fileName = fileNames [0];
String separator = "";
int length = filterPath.length ();
if (length > 0 && filterPath.charAt (length - 1) != '\\') {
separator = "\\";
}
fullPath = filterPath + separator + fileName;
if (count < fileNames.length) {
String [] newFileNames = new String [count];
System.arraycopy (fileNames, 0, newFileNames, 0, count);
fileNames = newFileNames;
}
}
}
/* Free the memory that was allocated. */
OS.HeapFree (hHeap, 0, lpstrFile);
OS.HeapFree (hHeap, 0, lpstrFilter);
OS.HeapFree (hHeap, 0, lpstrInitialDir);
OS.HeapFree (hHeap, 0, lpstrTitle);
if (lpstrDefExt != 0) OS.HeapFree (hHeap, 0, lpstrDefExt);
/*
* This code is intentionally commented. On some
* platforms, the owner window is repainted right
* away when a dialog window exits. This behavior
* is currently unspecified.
*/
// if (hwndOwner != 0) OS.UpdateWindow (hwndOwner);
/* Answer the full path or null */
return fullPath;
}
/**
* 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.
*
* The strings are platform specific. For example, on
* Windows, an extension filter string is typically of
* the form "*.extension", where "*.*" matches all files.
*
*
* @param extensions the file extension filter
*/
public void setFilterExtensions (String [] extensions) {
filterExtensions = extensions;
}
/**
* Sets the 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.
*
* @param names the list of filter names
*/
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.
*
* Note that the path string is platform dependent.
* For convenience, either '/' or '\' can be used
* as a path separator.
*
*
* @param string the directory path
*
* @see #setFilterExtensions
*/
public void setFilterPath (String string) {
filterPath = string;
}
}