Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: f91f368733daa79f1ff5a4b1e4b8963ba43fa668 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*******************************************************************************
 * Copyright (c) 2000, 2018 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.ui.externaltools.internal.ui;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.externaltools.internal.model.IExternalToolsHelpContextIds;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;

/**
 * Dialog for selecting a file in the workspace. Derived from
 * org.eclipse.ui.dialogs.ResourceSelectionDialog
 */
public class FileSelectionDialog extends MessageDialog {
	// the root element to populate the viewer with
	private IAdaptable root;

	// the visual selection widget group
	private TreeAndListGroup selectionGroup;
	// constants
	private final static int SIZING_SELECTION_WIDGET_WIDTH = 400;
	private final static int SIZING_SELECTION_WIDGET_HEIGHT = 300;
	/**
	 * The file(s) selected by the user.
	 */
	private IStructuredSelection result = null;

	private boolean allowMultiselection= false;

    private Pattern fPattern;
	/**
	 * Creates a resource selection dialog rooted at the given element.
	 *
	 * @param parentShell
	 *            the parent shell
	 * @param rootElement
	 *            the root element to populate this dialog with
	 * @param message
	 *            the message to be displayed at the top of this dialog, or
	 *            <code>null</code> to display a default message
	 */
	public FileSelectionDialog(Shell parentShell, IAdaptable rootElement, String message) {
		super(parentShell, ExternalToolsUIMessages.FileSelectionDialog_Choose_Location_1, null, message, MessageDialog.NONE, new String[] { ExternalToolsUIMessages.FileSelectionDialog_Ok_2, ExternalToolsUIMessages.FileSelectionDialog_Cancel_3}, 0);
		root = rootElement;
		setShellStyle(getShellStyle() | SWT.RESIZE);
	}

	/**
	 * Limits the files displayed in this dialog to files matching the given
	 * pattern. The string can be a filename or a regular expression containing
	 * '*' for any series of characters or '?' for any single character.
	 *
	 * @param pattern
	 *            a pattern used to filter the displayed files or <code>null</code>
	 *            to display all files. If a pattern is supplied, only files
	 *            whose names match the given pattern will be available for
	 *            selection.
	 * @param ignoreCase
	 *            if true, case is ignored. If the pattern argument is <code>null</code>,
	 *            this argument is ignored.
	 */
	public void setFileFilter(String pattern, boolean ignoreCase) {
	    if (pattern != null) {
	        if (ignoreCase) {
	            fPattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
	        } else {
	            fPattern = Pattern.compile(pattern);
	        }
	    } else {
	        fPattern = null;
	    }
	}

	@Override
	protected void configureShell(Shell shell) {
		super.configureShell(shell);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IExternalToolsHelpContextIds.FILE_SELECTION_DIALOG);
	}

	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		super.createButtonsForButtonBar(parent);
		initializeDialog();
	}

	@Override
	protected Control createDialogArea(Composite parent) {
		// page group
		Composite composite = (Composite) super.createDialogArea(parent);

		//create the input element, which has the root resource
		//as its only child
		selectionGroup =
			new TreeAndListGroup(
				composite,
				root,
				getResourceProvider(
					IResource.FOLDER | IResource.PROJECT | IResource.ROOT),
				new WorkbenchLabelProvider(),
				getResourceProvider(IResource.FILE),
				new WorkbenchLabelProvider(),
				SWT.NONE,
				// since this page has no other significantly-sized
				// widgets we need to hardcode the combined widget's
				// size, otherwise it will open too small
				SIZING_SELECTION_WIDGET_WIDTH, SIZING_SELECTION_WIDGET_HEIGHT,
				allowMultiselection);

		composite.addControlListener(new ControlListener() {
			@Override
			public void controlMoved(ControlEvent e) {
			}
			@Override
			public void controlResized(ControlEvent e) {
				//Also try and reset the size of the columns as appropriate
				TableColumn[] columns =
					selectionGroup.getListTable().getColumns();
				for (int i = 0; i < columns.length; i++) {
					columns[i].pack();
				}
			}
		});

		return composite;
	}
	/**
	 * Returns a content provider for <code>IResource</code> s that returns
	 * only children of the given resource type.
	 */
	private ITreeContentProvider getResourceProvider(final int resourceType) {
		return new WorkbenchContentProvider() {
			@Override
			public Object[] getChildren(Object o) {
				if (o instanceof IContainer) {
					IResource[] members = null;
					try {
						members = ((IContainer) o).members();
						List<IResource> accessibleMembers = new ArrayList<>(members.length);
						for (int i = 0; i < members.length; i++) {
							IResource resource = members[i];
							if (resource.isAccessible()) {
								accessibleMembers.add(resource);
							}
						}
						members = accessibleMembers.toArray(new IResource[accessibleMembers.size()]);
					} catch (CoreException e) {
						//just return an empty set of children
						return new Object[0];
					}

					//filter out the desired resource types
					ArrayList<IResource> results = new ArrayList<>();
					for (int i = 0; i < members.length; i++) {
						//And the test bits with the resource types to see if
						// they are what we want
						if ((members[i].getType() & resourceType) > 0) {
							if (members[i].getType() == IResource.FILE
								&& fPattern != null
								&& !fPattern.matcher(members[i].getName()).find()) {
								continue;
							}
							results.add(members[i]);
						}
					}
					return results.toArray();
				}

				return new Object[0];
			}
		};
	}
	/**
	 * Initializes this dialog's controls.
	 */
	private void initializeDialog() {
		selectionGroup
			.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				getButton(IDialogConstants.OK_ID).setEnabled(
					!selectionGroup.getListTableSelection().isEmpty());
			}
		});
		selectionGroup.addDoubleClickListener(new IDoubleClickListener() {
			@Override
			public void doubleClick(DoubleClickEvent event) {
				buttonPressed(IDialogConstants.OK_ID);
			}
		});

		getButton(IDialogConstants.OK_ID).setEnabled(false);
	}

	/**
	 * Returns the file the user chose or <code>null</code> if none.
	 */
	public IStructuredSelection getResult() {
		return result;
	}

	@Override
	protected void buttonPressed(int buttonId) {
		if (buttonId == IDialogConstants.OK_ID) {
			result= selectionGroup.getListTableSelection();
		}
		super.buttonPressed(buttonId);
	}
	/**
	 * Sets whether this dialog will allow multi-selection.
	 * Must be called before <code>open</code>
	 * @param allowMultiselection whether to allow multi-selection in the dialog
	 */
	public void setAllowMultiselection(boolean allowMultiselection) {
		this.allowMultiselection= allowMultiselection;
	}
}

Back to the top