/******************************************************************************* * 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.*; 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. *
*
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 filterPath = ""; String fileName = ""; String[] fileNames = new String [0]; String fullPath = ""; int /*long*/ handle; static final char SEPARATOR = System.getProperty ("file.separator").charAt (0); static final char 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 * @exception SWTException */ 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 * @exception SWTException */ public FileDialog (Shell parent, int style) { super (parent, style); checkSubclass (); } String computeResultChooserDialog () { /* MULTI is only valid if the native dialog's action is Open */ fullPath = null; if ((style & (SWT.SAVE | SWT.MULTI)) == SWT.MULTI) { int /*long*/ list = OS.gtk_file_chooser_get_filenames (handle); int listLength = OS.g_slist_length (list); fileNames = new String [listLength]; int /*long*/ current = list; int writePos = 0; for (int i = 0; i < listLength; i++) { int /*long*/ name = OS.g_slist_data (current); int /*long*/ utf8Ptr = OS.g_filename_to_utf8 (name, -1, null, null, null); OS.g_free (name); if (utf8Ptr != 0) { int /*long*/ [] items_written = new int /*long*/ [1]; int /*long*/ 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]; OS.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 { int /*long*/ path = OS.gtk_file_chooser_get_filename (handle); if (path != 0) { int /*long*/ utf8Ptr = OS.g_filename_to_utf8 (path, -1, null, null, null); OS.g_free (path); if (utf8Ptr != 0) { int /*long*/ [] items_written = new int /*long*/ [1]; int /*long*/ 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]; OS.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); } } } } if (fullPath != null) { int separatorIndex = fullPath.lastIndexOf (SEPARATOR); fileName = fullPath.substring (separatorIndex + 1); filterPath = fullPath.substring (0, separatorIndex); } return fullPath; } String computeResultClassicDialog () { GtkFileSelection selection = new GtkFileSelection (); OS.memmove (selection, handle); int /*long*/ entry = selection.selection_entry; int /*long*/ entryText = OS.gtk_entry_get_text (entry); int entryLength = OS.strlen (entryText); if (entryLength == 0) { int /*long*/ fileList = selection.file_list; int /*long*/ listSelection = OS.gtk_tree_view_get_selection (fileList); int /*long*/[] model = new int /*long*/[1]; int /*long*/ selectedList = OS.gtk_tree_selection_get_selected_rows (listSelection, model); if (selectedList == 0) return null; int listLength = OS.g_list_length (selectedList); if (listLength == 0) { OS.g_list_free (selectedList); return null; } int /*long*/ path = OS.g_list_nth_data (selectedList, 0); int /*long*/ [] ptr = new int /*long*/[1]; int /*long*/ iter = OS.g_malloc (OS.GtkTreeIter_sizeof ()); if (OS.gtk_tree_model_get_iter (model [0], iter, path)) { OS.gtk_tree_model_get (model [0], iter, 0, ptr, -1); } OS.g_free (iter); for (int i = 0; i < listLength; i++) { OS.gtk_tree_path_free (OS.g_list_nth_data (selectedList, i)); } OS.g_list_free (selectedList); if (ptr [0] == 0) return null; int length = OS.strlen (ptr [0]); byte [] buffer = new byte [length]; OS.memmove (buffer, ptr [0], length); OS.g_free (ptr [0]); OS.gtk_entry_set_text (entry, buffer); } int /*long*/ fileNamePtr = OS.gtk_file_selection_get_filename (handle); int /*long*/ utf8Ptr = OS.g_filename_to_utf8 (fileNamePtr, -1, null, null, null); int /*long*/ [] items_written = new int /*long*/ [1]; int /*long*/ utf16Ptr = OS.g_utf8_to_utf16 (utf8Ptr, -1, null, items_written, null); entryLength = (int)/*64*/items_written [0]; char [] buffer = new char [entryLength]; OS.memmove (buffer, utf16Ptr, entryLength * 2); String osAnswer = new String (buffer); OS.g_free (utf16Ptr); OS.g_free (utf8Ptr); if (osAnswer == null) return null; int separatorIndex = osAnswer.lastIndexOf (SEPARATOR); if (separatorIndex+1 == osAnswer.length ()) return null; String answer = fullPath = osAnswer; fileName = fullPath.substring (separatorIndex+1); filterPath = fullPath.substring (0, separatorIndex); if ((style & SWT.MULTI) == 0) { fileNames = new String[] {fileName}; } else { int /*long*/ namesPtr = OS.gtk_file_selection_get_selections (handle); int /*long*/ namesPtr1 = namesPtr; int /*long*/ [] namePtr = new int /*long*/ [1]; OS.memmove (namePtr, namesPtr1, OS.PTR_SIZEOF); int length = 0; while (namePtr[0] != 0) { length++; namesPtr1+=OS.PTR_SIZEOF; OS.memmove(namePtr, namesPtr1, OS.PTR_SIZEOF); } fileNames = new String [length]; namePtr = new int /*long*/ [length]; OS.memmove (namePtr, namesPtr, length * OS.PTR_SIZEOF); for (int i = 0; i < length; i++) { utf8Ptr = OS.g_filename_to_utf8 (namePtr [i], -1, null, null, null); items_written = new int /*long*/ [1]; utf16Ptr = OS.g_utf8_to_utf16 (utf8Ptr, -1, null, items_written, null); buffer = new char [(int)/*64*/items_written [0]]; OS.memmove (buffer, utf16Ptr, items_written [0] * 2); String name = new String (buffer); fileNames [i] = name.substring (name.lastIndexOf (SEPARATOR) + 1); OS.g_free (utf16Ptr); OS.g_free (utf8Ptr); } OS.g_strfreev (namesPtr); } return answer; } /** * 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 */ public String open () { boolean useChooserDialog = OS.GTK_VERSION >= OS.VERSION (2, 4, 10); if (useChooserDialog) { return openChooserDialog (); } else { return openClassicDialog (); } } String openChooserDialog () { byte [] titleBytes = Converter.wcsToMbcs (null, title, true); int action = (style & SWT.SAVE) != 0 ? OS.GTK_FILE_CHOOSER_ACTION_SAVE : OS.GTK_FILE_CHOOSER_ACTION_OPEN; int /*long*/ shellHandle = parent.topHandle (); handle = OS.gtk_file_chooser_dialog_new ( titleBytes, shellHandle, action, OS.GTK_STOCK_CANCEL (), OS.GTK_RESPONSE_CANCEL, OS.GTK_STOCK_OK (), OS.GTK_RESPONSE_OK, 0); int /*long*/ pixbufs = OS.gtk_window_get_icon_list (shellHandle); if (pixbufs != 0) { OS.gtk_window_set_icon_list (handle, pixbufs); OS.g_list_free (pixbufs); } presetChooserDialog (); String answer = null; if (OS.gtk_dialog_run (handle) == OS.GTK_RESPONSE_OK) { answer = computeResultChooserDialog (); } OS.gtk_widget_destroy (handle); return answer; } String openClassicDialog () { byte [] titleBytes = Converter.wcsToMbcs (null, title, true); handle = OS.gtk_file_selection_new (titleBytes); if (parent != null) { int /*long*/ shellHandle = parent.topHandle (); OS.gtk_window_set_transient_for (handle, shellHandle); int /*long*/ pixbufs = OS.gtk_window_get_icon_list (shellHandle); if (pixbufs != 0) { OS.gtk_window_set_icon_list (handle, pixbufs); OS.g_list_free (pixbufs); } } presetClassicDialog (); String answer = null; if (OS.gtk_dialog_run (handle) == OS.GTK_RESPONSE_OK) { answer = computeResultClassicDialog (); } OS.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) { OS.gtk_file_chooser_set_select_multiple (handle, true); } if (filterPath == null) filterPath = ""; if (fileName == null) fileName = ""; if (filterPath.length () > 0) { StringBuffer stringBuffer = new StringBuffer (); /* filename must be a full path */ if (filterPath.charAt (0) != SEPARATOR) { stringBuffer.append (SEPARATOR); } stringBuffer.append (filterPath); if (filterPath.charAt (filterPath.length () - 1) != SEPARATOR) { stringBuffer.append (SEPARATOR); } if (fileName.length () > 0) { stringBuffer.append (fileName); } else { /* go into the specified directory */ stringBuffer.append ('.'); } byte [] buffer = Converter.wcsToMbcs (null, stringBuffer.toString (), true); OS.gtk_file_chooser_set_filename (handle, buffer); } if ((style & SWT.SAVE) != 0 && fileName.length () > 0) { byte [] buffer = Converter.wcsToMbcs (null, fileName, true); OS.gtk_file_chooser_set_current_name (handle, buffer); } /* Set the extension filters */ if (filterNames == null) filterNames = new String [0]; if (filterExtensions == null) filterExtensions = new String [0]; for (int i = 0; i < filterExtensions.length; i++) { if (filterExtensions [i] != null) { int /*long*/ filter = OS.gtk_file_filter_new (); if (filterNames.length > i && filterNames [i] != null) { byte [] name = Converter.wcsToMbcs (null, filterNames [i], true); OS.gtk_file_filter_set_name (filter, name); } else { byte [] name = Converter.wcsToMbcs (null, filterExtensions [i], true); OS.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 (null, current, true); OS.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 (null, current, true); OS.gtk_file_filter_add_pattern (filter, filterString); OS.gtk_file_chooser_add_filter (handle, filter); } } fullPath = null; fileNames = new String [0]; } void presetClassicDialog () { OS.gtk_file_selection_set_select_multiple(handle, (style & SWT.MULTI) != 0); /* Calculate the fully-specified file name and convert to bytes */ StringBuffer stringBuffer = new StringBuffer (); if (filterPath == null) { filterPath = ""; } else { if (filterPath.length () > 0) { stringBuffer.append (filterPath); if (filterPath.charAt (filterPath.length () - 1) != SEPARATOR) { stringBuffer.append (SEPARATOR); } } } if (fileName == null) { fileName = ""; } else { stringBuffer.append (fileName); } fullPath = stringBuffer.toString (); int length = fullPath.length (); char [] buffer = new char [length + 1]; fullPath.getChars (0, length, buffer, 0); int /*long*/ utf8Ptr = OS.g_utf16_to_utf8 (buffer, -1, null, null, null); int /*long*/ fileNamePtr = OS.g_filename_from_utf8 (utf8Ptr, -1, null, null, null); OS.gtk_file_selection_set_filename (handle, fileNamePtr); OS.g_free (utf8Ptr); OS.g_free (fileNamePtr); if (filterNames == null) filterNames = new String [0]; if (filterExtensions == null) filterExtensions = new String [0]; fullPath = null; fileNames = new String [0]; } /** * 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; } }