-
Notifications
You must be signed in to change notification settings - Fork 3
/
AbstractResourceSelectionDialog.java
276 lines (244 loc) · 8.42 KB
/
AbstractResourceSelectionDialog.java
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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/*******************************************************************************
* Copyright (c) 2018, 2020 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Obeo - initial API and implementation
*
*******************************************************************************/
package org.eclipse.acceleo.aql.ide.ui.dialog;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
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.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
/**
* Resource selection dialog.
*
* @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
*/
public abstract class AbstractResourceSelectionDialog extends MessageDialog {
/**
* Filters {@link WorkbenchContentProvider}.
*
* @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
*/
private final class FilteredContentProvider extends WorkbenchContentProvider {
@Override
public Object[] getChildren(Object element) {
final List<Object> res = new ArrayList<>();
for (Object obj : super.getChildren(element)) {
if (isValidTree(obj)) {
res.add(obj);
}
}
return res.toArray();
}
@Override
public boolean hasChildren(Object element) {
return element instanceof IContainer && getChildren(element).length > 0;
}
private boolean isValidTree(Object obj) {
boolean res = false;
if (obj instanceof IResource && !((IResource)obj).isDerived()) {
if (isValid((IResource)obj)) {
res = true;
} else {
for (Object child : super.getChildren(obj)) {
if (isValidTree(child)) {
res = true;
break;
}
}
}
}
return res;
}
}
/**
* Listen to selection changes of the container tree.
*
* @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
*/
private final class ContainerSelectionChangedListener implements ISelectionChangedListener {
@Override
public void selectionChanged(SelectionChangedEvent event) {
final Object selected = ((IStructuredSelection)event.getSelection()).getFirstElement();
final Button okButton = getButton(OK);
final boolean enableOkButton;
if (selected instanceof IFile) {
final IFile file = (IFile)selected;
resourceText.setText(file.getFullPath().toString());
resourceName = file.getFullPath().toString();
enableOkButton = true;
} else if (!onlyFileSelection && selected instanceof IContainer) {
final IContainer container = (IContainer)selected;
resourceText.setText(container.getFullPath().toString());
resourceName = container.getFullPath().toString();
enableOkButton = true;
} else {
enableOkButton = false;
}
if (okButton != null && !okButton.isDisposed()) {
okButton.setEnabled(enableOkButton);
}
}
}
/**
* The table minimum height.
*/
private static final int TABLE_MINIMUM_HEIGHT = 400;
/**
* The table minimum width.
*/
private static final int TABLE_MINIMUM_WIDTH = 200;
/**
* Tells if only file selection is allowed.
*/
protected boolean onlyFileSelection;
/**
* The file {@link Text}.
*/
private Text resourceText;
/**
* The default file name.
*/
private final String defaultResourceName;
/**
* The selected resource name.
*/
private String resourceName;
/**
* Creates a file selection dialog.
*
* @param parentShell
* the parent {@link Shell}
* @param message
* the message
* @param title
* the title
* @param defaultResourceName
* the default resource name
* @param onlyFile
* tells if only file selection is allowed
*/
public AbstractResourceSelectionDialog(Shell parentShell, String title, String message,
String defaultResourceName, boolean onlyFile) {
super(parentShell, title, null, message, MessageDialog.QUESTION, new String[] {
IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL }, 0);
this.defaultResourceName = defaultResourceName;
this.onlyFileSelection = onlyFile;
}
@Override
protected Control createCustomArea(Composite parent) {
final Composite container = new Composite(parent, parent.getStyle());
container.setLayout(new GridLayout(1, false));
container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
resourceText = createFilePathComposite(container, defaultResourceName);
final TreeViewer containerTreeViewer = new TreeViewer(container, SWT.BORDER);
Tree tree = containerTreeViewer.getTree();
final GridData gdTable = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
gdTable.minimumWidth = TABLE_MINIMUM_WIDTH;
gdTable.minimumHeight = TABLE_MINIMUM_HEIGHT;
tree.setLayoutData(gdTable);
containerTreeViewer.setContentProvider(new FilteredContentProvider());
containerTreeViewer.setLabelProvider(new WorkbenchLabelProvider());
containerTreeViewer.addSelectionChangedListener(new ContainerSelectionChangedListener());
containerTreeViewer.setInput(ResourcesPlugin.getWorkspace().getRoot());
if (defaultResourceName != null && !defaultResourceName.isEmpty()) {
IResource resource = findResource(defaultResourceName);
if (resource != null && !resource.exists()) {
resource = resource.getParent();
}
containerTreeViewer.setSelection(new StructuredSelection(resource));
}
containerTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
@Override
public void doubleClick(DoubleClickEvent event) {
okPressed();
}
});
return container;
}
/**
* Creates the file path {@link Composite}.
*
* @param container
* the parent {@link Composite}
* @param defaultName
* the default file name
* @return the file path {@link Text}
*/
protected Text createFilePathComposite(final Composite container, String defaultName) {
final Composite fileComposite = new Composite(container, container.getStyle());
fileComposite.setLayout(new GridLayout(2, false));
fileComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
final Label templateURILabel = new Label(fileComposite, container.getStyle());
templateURILabel.setText("File: ");
final Text res = new Text(fileComposite, SWT.BORDER);
res.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
new Label(fileComposite, container.getStyle());
new Label(fileComposite, container.getStyle());
if (defaultName != null) {
res.setText(defaultName);
resourceName = defaultName;
}
res.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
resourceName = res.getText();
}
@Override
public void keyPressed(KeyEvent e) {
// nothing to do here
}
});
return res;
}
public String getFileName() {
return resourceName;
}
/**
* Finds an actual resource for the given name. Cannot return null.
*
* @param defaultName
* the default resource name
* @return the resource
*/
protected abstract IResource findResource(String defaultName);
/**
* Checks whether or not the resource can be displayed. If yes its containers will be displayed anyway.
*
* @param resource
* the resource to check
* @return <true> if the resource can be displayed
*/
protected abstract boolean isValid(IResource resource);
}