blob: c8a19ca2e06d44133b2ebae27ecaf010b12894ed [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Ericsson
*
* All rights reserved. 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
*******************************************************************************/
package org.eclipse.tracecompass.tmf.ui.dialog;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import com.google.common.annotations.VisibleForTesting;
/**
* A file dialog factory.
* <p>
* This allows file dialogs to be stubbed out for SWTBot tests.
*
* @author Matthew Khouzam
* @since 2.2
*/
public final class TmfFileDialogFactory {
private static @Nullable String[] fOverridePaths = null;
/**
* File dialog factory, creates a {@link FileDialog}.
* <p>
* Constructs a new instance of this class given only its parent.
* </p>
* <p>
* If the factory is overridden with {@link #setOverrideFiles(String...)},
* the FileDialog will return the set String when open is called instead of
* opening a system window
* </p>
*
* @param parent
* a shell which will be the parent of the new instance
* @return the {@link FileDialog}
*
* @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 static FileDialog create(Shell parent) {
return create(parent, SWT.APPLICATION_MODAL);
}
/**
* File dialog factory, creates a {@link FileDialog}.
* <p>
* Constructs a new instance of this class given its parent and a style
* value describing its behavior and appearance.
* </p>
* <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>
* <p>
* If the factory is overridden with {@link #setOverrideFiles(String[])},
* the FileDialog will return the set String when open is called instead of
* opening a system window
* </p>
*
* @param parent
* a shell which will be the parent of the new instance
* @param style
* the style of dialog to construct
* @return the {@link FileDialog}
*
* @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 static FileDialog create(Shell parent, int style) {
String[] overridePath = fOverridePaths;
if (overridePath != null) {
fOverridePaths = null;
return createNewFileDialog(parent, style, Arrays.asList(overridePath));
}
FileDialog fileDialog = new FileDialog(parent, style);
if ((style & SWT.SAVE) != 0) {
fileDialog.setOverwrite(true);
}
return fileDialog;
}
/**
* Set the override string name that will be returned for the next
* {@link FileDialog}. Must be called before creating the dialogs.
*
* This is a method aimed for testing, This should not be used in product
* code.
*
* @param paths
* the paths to override the {@link FileDialog}. They must be
* absolute. One or many absolute paths may be entered. When many
* paths are entered, it return an input of a multi-select action
* if paths is null, it will undo overriding, if paths is a zero
* length array, it will behave as if the dialog was cancelled.
*/
@VisibleForTesting
@SuppressWarnings("null")
public static void setOverrideFiles(String... paths) {
fOverridePaths = paths;
}
private static FileDialog createNewFileDialog(Shell parent, int style, List<String> overridePaths) {
return new FileDialog(parent, style) {
@Override
public String open() {
return !overridePaths.isEmpty() ? overridePaths.get(0) : null;
}
@Override
protected void checkSubclass() {
/*
* do nothing, allow this class to be overridden without
* throwing a runtime exception
*/
}
@Override
public String getFileName() {
return !overridePaths.isEmpty() ? getFileName(overridePaths.get(0)) : ""; //$NON-NLS-1$
}
@Override
public String[] getFileNames() {
List<String> outStrings = new ArrayList<>();
for (String entry : overridePaths) {
outStrings.add(getFileName(entry));
}
return outStrings.toArray(new String[outStrings.size()]);
}
@Override
public String getFilterPath() {
return !overridePaths.isEmpty() ? new Path(overridePaths.get(0)).removeLastSegments(1).toString() : ""; //$NON-NLS-1$
}
private String getFileName(String path) {
return new Path(path).lastSegment();
}
};
}
}