javauis/eswt_qt/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/FileDialog.java
branchRCL_3
changeset 65 ae942d28ec0e
equal deleted inserted replaced
60:6c158198356e 65:ae942d28ec0e
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2000, 2007 IBM Corporation and others.
       
     3  * Portion Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     4  * All rights reserved. This program and the accompanying materials
       
     5  * are made available under the terms of the Eclipse Public License v1.0
       
     6  * which accompanies this distribution, and is available at
       
     7  * http://www.eclipse.org/legal/epl-v10.html
       
     8  *
       
     9  * Contributors:
       
    10  *     IBM Corporation - initial API and implementation
       
    11  *     Nokia Corporation - Qt implementation
       
    12  *******************************************************************************/
       
    13 package org.eclipse.swt.widgets;
       
    14 
       
    15 import org.eclipse.swt.SWT;
       
    16 import org.eclipse.swt.SWTException;
       
    17 import org.eclipse.swt.events.DisposeEvent;
       
    18 import org.eclipse.swt.events.DisposeListener;
       
    19 import org.eclipse.swt.internal.qt.OS;
       
    20 
       
    21 /**
       
    22  * Instances of this class allow the user to navigate the file system and select
       
    23  * or enter a file name.
       
    24  * <dl>
       
    25  * <dt><b>Styles:</b></dt>
       
    26  * <dd>SAVE, OPEN, MULTI</dd>
       
    27  * <dt><b>Events:</b></dt>
       
    28  * <dd>(none)</dd>
       
    29  * </dl>
       
    30  * <p>
       
    31  * Note: Only one of the styles SAVE and OPEN may be specified.
       
    32  * </p>
       
    33  * <p>
       
    34  * IMPORTANT: This class is intended to be subclassed <em>only</em> within the
       
    35  * SWT implementation.
       
    36  * </p>
       
    37  */
       
    38 public class FileDialog extends Dialog {
       
    39 	String[] filterNames;
       
    40 	String[] filterExtensions;
       
    41 	String filterPath = "";
       
    42 	String fileName;
       
    43 	String[] fileNames = new String[] {};
       
    44 	int filterIndex = -1;
       
    45 	static final char SEPARATOR = System.getProperty("file.separator")
       
    46 			.charAt(0);
       
    47 	static final String EXTENSION_SEPARATOR = ";;";
       
    48 	String dialogID;
       
    49 	static int dialogCount;
       
    50 
       
    51 	/**
       
    52 	 * Constructs a new instance of this class given only its parent.
       
    53 	 *
       
    54 	 * @param parent
       
    55 	 *            a shell which will be the parent of the new instance
       
    56 	 *
       
    57 	 * @exception IllegalArgumentException
       
    58 	 *                <ul>
       
    59 	 *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
       
    60 	 *                </ul>
       
    61 	 * @exception SWTException
       
    62 	 *                <ul>
       
    63 	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
       
    64 	 *                thread that created the parent</li>
       
    65 	 *                <li>ERROR_INVALID_SUBCLASS - if this class is not an
       
    66 	 *                allowed subclass</li>
       
    67 	 *                </ul>
       
    68 	 */
       
    69 	public FileDialog(Shell parent) {
       
    70 		this(parent, SWT.NULL);
       
    71 	}
       
    72 
       
    73 	/**
       
    74 	 * Constructs a new instance of this class given its parent and a style
       
    75 	 * value describing its behavior and appearance.
       
    76 	 * <p>
       
    77 	 * The style value is either one of the style constants defined in class
       
    78 	 * <code>SWT</code> which is applicable to instances of this class, or must
       
    79 	 * be built by <em>bitwise OR</em>'ing together (that is, using the
       
    80 	 * <code>int</code> "|" operator) two or more of those <code>SWT</code>
       
    81 	 * style constants. The class description lists the style constants that are
       
    82 	 * applicable to the class. Style bits are also inherited from superclasses.
       
    83 	 * </p>
       
    84 	 *
       
    85 	 * @param parent
       
    86 	 *            a shell which will be the parent of the new instance
       
    87 	 * @param style
       
    88 	 *            the style of dialog to construct
       
    89 	 *
       
    90 	 * @exception IllegalArgumentException
       
    91 	 *                <ul>
       
    92 	 *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
       
    93 	 *                </ul>
       
    94 	 * @exception SWTException
       
    95 	 *                <ul>
       
    96 	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
       
    97 	 *                thread that created the parent</li>
       
    98 	 *                <li>ERROR_INVALID_SUBCLASS - if this class is not an
       
    99 	 *                allowed subclass</li>
       
   100 	 *                </ul>
       
   101 	 */
       
   102 	public FileDialog(Shell parent, int style) {
       
   103 		super(parent, checkStyle(parent, style));
       
   104 		checkSubclass();
       
   105 		dialogCount++;
       
   106 		dialogID = toString() + String.valueOf(dialogCount);
       
   107 	}
       
   108 
       
   109 	static int checkStyle(Shell parent, int style) {
       
   110 		style &= ~SWT.MIRRORED;
       
   111 		if ((style & SWT.RIGHT_TO_LEFT) == 0) {
       
   112 			if (parent != null) {
       
   113 				if ((parent.style & SWT.RIGHT_TO_LEFT) != 0)
       
   114 					style |= SWT.RIGHT_TO_LEFT;
       
   115 			}
       
   116 		}
       
   117 
       
   118 		if ((style & SWT.OPEN) != 0 && (style & SWT.SAVE) != 0) {
       
   119 			style &= ~SWT.OPEN;
       
   120 		}
       
   121 
       
   122 		if ((style & SWT.SAVE) != 0 && (style & SWT.MULTI) != 0) {
       
   123 			style &= ~SWT.MULTI;
       
   124 		}
       
   125 
       
   126 		if ((style & SWT.LEFT_TO_RIGHT) != 0
       
   127 				&& (style & SWT.RIGHT_TO_LEFT) != 0) {
       
   128 			style &= ~SWT.LEFT_TO_RIGHT;
       
   129 		}
       
   130 		return style;
       
   131 	}
       
   132 
       
   133 	/**
       
   134 	 * Returns the path of the first file that was selected in the dialog
       
   135 	 * relative to the filter path, or an empty string if no such file has been
       
   136 	 * selected.
       
   137 	 *
       
   138 	 * @return the relative path of the file
       
   139 	 */
       
   140 	public String getFileName() {
       
   141 		return fileName;
       
   142 	}
       
   143 
       
   144 	/**
       
   145 	 * Returns a (possibly empty) array with the paths of all files that were
       
   146 	 * selected in the dialog relative to the filter path.
       
   147 	 *
       
   148 	 * @return the relative paths of the files
       
   149 	 */
       
   150 	public String[] getFileNames() {
       
   151 		return fileNames;
       
   152 	}
       
   153 
       
   154 	/**
       
   155 	 * Returns the file extensions which the dialog will use to filter the files
       
   156 	 * it shows.
       
   157 	 *
       
   158 	 * @return the file extensions filter
       
   159 	 */
       
   160 	public String[] getFilterExtensions() {
       
   161 		return filterExtensions;
       
   162 	}
       
   163 
       
   164 	/**
       
   165 	 * Get the 0-based index of the file extension filter which was selected by
       
   166 	 * the user, or -1 if no filter was selected.
       
   167 	 * <p>
       
   168 	 * This is an index into the FilterExtensions array and the FilterNames
       
   169 	 * array.
       
   170 	 * </p>
       
   171 	 *
       
   172 	 * @return index the file extension filter index
       
   173 	 *
       
   174 	 * @see #getFilterExtensions
       
   175 	 * @see #getFilterNames
       
   176 	 *
       
   177 	 * @since 3.4
       
   178 	 */
       
   179 	public int getFilterIndex() {
       
   180 		return filterIndex;
       
   181 	}
       
   182 
       
   183 	/**
       
   184 	 * Returns the names that describe the filter extensions which the dialog
       
   185 	 * will use to filter the files it shows.
       
   186 	 *
       
   187 	 * @return the list of filter names
       
   188 	 */
       
   189 	public String[] getFilterNames() {
       
   190 		return filterNames;
       
   191 	}
       
   192 
       
   193 	/**
       
   194 	 * Returns the directory path that the dialog will use, or an empty string
       
   195 	 * if this is not set. File names in this path will appear in the dialog,
       
   196 	 * filtered according to the filter extensions.
       
   197 	 *
       
   198 	 * @return the directory path string
       
   199 	 *
       
   200 	 * @see #setFilterExtensions
       
   201 	 */
       
   202 	public String getFilterPath() {
       
   203 		return filterPath;
       
   204 	}
       
   205 
       
   206 	/**
       
   207 	 * Makes the dialog visible and brings it to the front of the display.
       
   208 	 *
       
   209 	 * @return a string describing the absolute path of the first selected file,
       
   210 	 *         or null if the dialog was cancelled or an error occurred
       
   211 	 *
       
   212 	 * @exception SWTException
       
   213 	 *                <ul>
       
   214 	 *                <li>ERROR_WIDGET_DISPOSED - if the dialog has been
       
   215 	 *                disposed</li>
       
   216 	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
       
   217 	 *                thread that created the dialog</li>
       
   218 	 *                </ul>
       
   219 	 */
       
   220 	public String open() {
       
   221 		checkDialog();
       
   222 
       
   223 		/*
       
   224 		 * put filters and filter names into single string
       
   225 		 */
       
   226 		String filter = "";
       
   227 		int filterCount = filterExtensions != null ? filterExtensions.length
       
   228 				: -1;
       
   229 		int filterNameCount = filterNames != null ? filterNames.length : -1;
       
   230 		if (filterCount > 0) {
       
   231 			filter += (filterNameCount > 0 ? filterNames[0] + " " : "") + "("
       
   232 					+ filterExtensions[0] + ")";
       
   233 			for (int i = 1; i < filterCount; i++) {
       
   234 				filter += EXTENSION_SEPARATOR
       
   235 						+ (i < filterNameCount ? filterNames[i] + " " : "")
       
   236 						+ "(" + filterExtensions[i] + ")";
       
   237 			}
       
   238 		}
       
   239 
       
   240 		/*
       
   241 		 * get selected filter
       
   242 		 */
       
   243 		String selectedFilter = filterIndex > -1 && filterIndex < filterCount ? filterExtensions[filterIndex]
       
   244 				: "";
       
   245 
       
   246 		/*
       
   247 		 * form full path
       
   248 		 */
       
   249 		int filterPathLength = filterPath != null ? filterPath.length() : 0;
       
   250 		String fullPath = filterPathLength > 0 ? filterPath : "";
       
   251 		int fileNameLength = fileName != null ? fileName.length() : 0;
       
   252 		if (filterPathLength > 0 && fileNameLength > 0
       
   253 				&& filterPath.charAt(filterPathLength - 1) != SEPARATOR) {
       
   254 			/*
       
   255 			 * adding a separator between filterPath and file name
       
   256 			 */
       
   257 			fullPath += SEPARATOR;
       
   258 		}
       
   259 		if (fileNameLength > 0) {
       
   260 			fullPath += fileName;
       
   261 		}
       
   262 
       
   263 		DisposeListener listener = new DisposeListener() {
       
   264 			public void widgetDisposed(DisposeEvent e) {
       
   265 				if (e.widget == parent) {
       
   266 					/*
       
   267 					 * close dialogs which opened on top of parent
       
   268 					 */
       
   269 					OS.QDialog_swt_closeDialogs(parent.handle,
       
   270 							dialogID);
       
   271 				}
       
   272 
       
   273 			}
       
   274 		};
       
   275 
       
   276 		/*
       
   277 		 * listen to parent dispose event
       
   278 		 */
       
   279 		parent.addDisposeListener(listener);
       
   280 
       
   281 		/*
       
   282 		 * open dialog
       
   283 		 */
       
   284 		int qtLayoutDirection = (style & SWT.RIGHT_TO_LEFT) != 0 ? OS.QT_RIGHTTOLEFT
       
   285 				: OS.QT_LEFTTORIGHT;
       
   286 		String[] resultStrings;
       
   287 		if ((style & SWT.SAVE) != 0) {
       
   288 			resultStrings = OS.QFileDialog_swt_getSaveFileName(parent.handle,
       
   289 					title, fullPath, filter, selectedFilter, dialogID,
       
   290 					qtLayoutDirection);
       
   291 		} else {
       
   292 			if ((style & SWT.MULTI) != 0) {
       
   293 				resultStrings = OS.QFileDialog_swt_getOpenFileNames(
       
   294 						parent.handle, title, fullPath, filter, selectedFilter,
       
   295 						dialogID, qtLayoutDirection);
       
   296 			} else {
       
   297 				resultStrings = OS.QFileDialog_swt_getOpenFileName(
       
   298 						parent.handle, title, fullPath, filter, selectedFilter,
       
   299 						dialogID, qtLayoutDirection);
       
   300 			}
       
   301 		}
       
   302 
       
   303 		if (parent != null && !parent.isDisposed()) {
       
   304 			parent.removeDisposeListener(listener);
       
   305 		}
       
   306 
       
   307 		parseResult(resultStrings);
       
   308 		return resultStrings != null && resultStrings.length > 0 ? resultStrings[0]
       
   309 				: null;
       
   310 	}
       
   311 
       
   312 	/*
       
   313 	 * Array Parameter 'result' stores full paths of selected files with the
       
   314 	 * last one in the array storing the selected filter
       
   315 	 */
       
   316 	private void parseResult(String[] result) {
       
   317 
       
   318 		filterPath = null;
       
   319 		fileNames = null;
       
   320 		fileName = null;
       
   321 		filterIndex = -1;
       
   322 
       
   323 		if (result == null) {
       
   324 			return;
       
   325 		}
       
   326 		int count = result.length;
       
   327 		if (count < 1) {
       
   328 			return;
       
   329 		}
       
   330 
       
   331 		/*
       
   332 		 * get the first file name and filter path from dialog result
       
   333 		 */
       
   334 		fileNames = new String[count - 1];
       
   335 		String fullPath = result[0];
       
   336 		int separatorPos = -1;
       
   337 		if (fullPath != null && fullPath.length() > 0) {
       
   338 			separatorPos = fullPath.lastIndexOf(SEPARATOR);
       
   339 			fileName = fullPath.substring(separatorPos + 1);
       
   340 			fileNames[0] = fileName;
       
   341 			filterPath = fullPath.substring(0, separatorPos);
       
   342 		}
       
   343 
       
   344 		/*
       
   345 		 * get rest file names from dialog result
       
   346 		 */
       
   347 		for (int i = 1; i < count - 1; i++) {
       
   348 			fullPath = result[i];
       
   349 			if (fullPath != null && fullPath.length() > 0) {
       
   350 				separatorPos = fullPath.lastIndexOf(SEPARATOR);
       
   351 				fileNames[i] = fullPath.substring(separatorPos + 1);
       
   352 			} else {
       
   353 				fileNames[i] = null;
       
   354 			}
       
   355 		}
       
   356 
       
   357 		/*
       
   358 		 * get filter index
       
   359 		 */
       
   360 		int filterCount = filterExtensions==null ? 0 : filterExtensions.length;
       
   361 		String selectedFilter = result[count - 1];
       
   362 		filterIndex = -1;
       
   363 		if (filterCount > 0 && selectedFilter != null) {
       
   364 			selectedFilter = selectedFilter.substring(selectedFilter
       
   365 					.indexOf('(') + 1);
       
   366 			selectedFilter = selectedFilter.substring(0, selectedFilter
       
   367 					.indexOf(')'));
       
   368 			for (int i = 0; i < filterCount; i++) {
       
   369 				if (filterExtensions[i].equals(selectedFilter)) {
       
   370 					filterIndex = i;
       
   371 					break;
       
   372 				}
       
   373 			}
       
   374 
       
   375 		}
       
   376 
       
   377 	}
       
   378 
       
   379 	/**
       
   380 	 * Set the initial filename which the dialog will select by default when
       
   381 	 * opened to the argument, which may be null. The name will be prefixed with
       
   382 	 * the filter path when one is supplied.
       
   383 	 *
       
   384 	 * @param string
       
   385 	 *            the file name
       
   386 	 */
       
   387 	public void setFileName(String string) {
       
   388 		fileName = string;
       
   389 	}
       
   390 
       
   391 	/**
       
   392 	 * Set the file extensions which the dialog will use to filter the files it
       
   393 	 * shows to the argument, which may be null.
       
   394 	 * <p>
       
   395 	 * The strings are platform specific. For example, on Windows, an extension
       
   396 	 * filter string is typically of the form "*.extension", where "*.*" matches
       
   397 	 * all files.
       
   398 	 * </p>
       
   399 	 *
       
   400 	 * @param extensions
       
   401 	 *            the file extension filter
       
   402 	 *
       
   403 	 * @see #setFilterNames to specify the user-friendly names corresponding to
       
   404 	 *      the extensions
       
   405 	 */
       
   406 	public void setFilterExtensions(String[] extensions) {
       
   407 		filterExtensions = extensions;
       
   408 	}
       
   409 
       
   410 	/**
       
   411 	 * Set the 0-based index of the file extension filter which the dialog will
       
   412 	 * use initially to filter the files it shows to the argument.
       
   413 	 * <p>
       
   414 	 * This is an index into the FilterExtensions array and the FilterNames
       
   415 	 * array.
       
   416 	 * </p>
       
   417 	 *
       
   418 	 * @param index
       
   419 	 *            the file extension filter index
       
   420 	 *
       
   421 	 * @see #setFilterExtensions
       
   422 	 * @see #setFilterNames
       
   423 	 *
       
   424 	 * @since 3.4
       
   425 	 */
       
   426 	public void setFilterIndex(int index) {
       
   427 		filterIndex = index;
       
   428 	}
       
   429 
       
   430 	/**
       
   431 	 * Sets the the names that describe the filter extensions which the dialog
       
   432 	 * will use to filter the files it shows to the argument, which may be null.
       
   433 	 * <p>
       
   434 	 * Each name is a user-friendly short description shown for its
       
   435 	 * corresponding filter. The <code>names</code> array must be the same
       
   436 	 * length as the <code>extensions</code> array.
       
   437 	 * </p>
       
   438 	 *
       
   439 	 * @param names
       
   440 	 *            the list of filter names, or null for no filter names
       
   441 	 *
       
   442 	 * @see #setFilterExtensions
       
   443 	 */
       
   444 	public void setFilterNames(String[] names) {
       
   445 		filterNames = names;
       
   446 	}
       
   447 
       
   448 	/**
       
   449 	 * Sets the directory path that the dialog will use to the argument, which
       
   450 	 * may be null. File names in this path will appear in the dialog, filtered
       
   451 	 * according to the filter extensions. If the string is null, then the
       
   452 	 * operating system's default filter path will be used.
       
   453 	 * <p>
       
   454 	 * Note that the path string is platform dependent. For convenience, either
       
   455 	 * '/' or '\' can be used as a path separator.
       
   456 	 * </p>
       
   457 	 *
       
   458 	 * @param string
       
   459 	 *            the directory path
       
   460 	 *
       
   461 	 * @see #setFilterExtensions
       
   462 	 */
       
   463 	public void setFilterPath(String string) {
       
   464 		filterPath = string;
       
   465 	}
       
   466 
       
   467 	void checkDialog() {
       
   468 		if (parent == null)
       
   469 			error(SWT.ERROR_WIDGET_DISPOSED);
       
   470 		if (parent.isDisposed())
       
   471 			error(SWT.ERROR_WIDGET_DISPOSED);
       
   472 		Display display = parent.display;
       
   473 		if (display == null)
       
   474 			error(SWT.ERROR_WIDGET_DISPOSED);
       
   475 		if (display.thread != Thread.currentThread())
       
   476 			error(SWT.ERROR_THREAD_INVALID_ACCESS);
       
   477 	}
       
   478 
       
   479 }