Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 300046
Collapse All | Expand All

(-)src/org/eclipse/ui/ide/dialogs/ImportTypeDialog.java (-389 / +450 lines)
Lines 52-75 Link Here
52
import org.eclipse.ui.plugin.AbstractUIPlugin;
52
import org.eclipse.ui.plugin.AbstractUIPlugin;
53
53
54
/**
54
/**
55
 * Dialog to customize how files and resources are created in a project hierarchy
55
 * Dialog to let the user customise how files and resources are created in a project 
56
 * hierarchy after the user drag and drop items on a workspace container.
57
 * 
58
 * Files and folders can be created either by copying the source objects, creating 
59
 * linked resources, and/or creating virtual folders.
56
 * @since 3.6
60
 * @since 3.6
57
 *
61
 *
58
 */
62
 */
59
public class ImportTypeDialog extends TrayDialog implements SelectionListener {
63
public class ImportTypeDialog extends TrayDialog {
60
64
61
	/**
65
	/**
62
	 * Do not perform an import operation
63
	 */
64
	public final static int IMPORT_NONE 			= 0;
65
	/**
66
	 * Copy the files and folders to the destination
66
	 * Copy the files and folders to the destination
67
	 */
67
	 */
68
	public final static int IMPORT_COPY 			= 1;
68
	public final static int IMPORT_COPY 			= 1;
69
	/**
69
	/**
70
	 * Recreate the file and folder hierarchy using groups and links
70
	 * Import only files
71
	 */
71
	 */
72
	public final static int IMPORT_VIRTUAL_FOLDERS_AND_LINKS = 2;
72
	public final static int IMPORT_FILES_ONLY		= 16;
73
	/**
73
	/**
74
	 * Create linked resources for each file and folder
74
	 * Create linked resources for each file and folder
75
	 */
75
	 */
Lines 79-291 Link Here
79
	 */
79
	 */
80
	public final static int IMPORT_MOVE 			= 8;
80
	public final static int IMPORT_MOVE 			= 8;
81
	/**
81
	/**
82
	 * Import only files
82
	 * Do not perform an import operation
83
	 */
83
	 */
84
	public final static int IMPORT_FILES_ONLY		= 16;
84
	public final static int IMPORT_NONE 			= 0;
85
	
86
	/**
85
	/**
87
	 * @param shell
86
	 * Recreate the file and folder hierarchy using groups and links
88
	 * @param dropOperation
89
	 * @param names
90
	 * @param target
91
	 */
87
	 */
92
	public ImportTypeDialog(Shell shell, int dropOperation, String[] names, IContainer target) {
88
	public final static int IMPORT_VIRTUAL_FOLDERS_AND_LINKS = 2;
93
		this(shell, selectAppropriateMask(dropOperation, names, target), getPreferredVariable(names, target), target.isVirtual());
89
	
94
	}
90
	private Button alwaysPerformThisOperation = null;
91
92
93
	private Button copyButton = null;
94
95
	private int currentSelection;
96
	private Image fileImage;
97
98
	private Image folderAndFileImage;
95
99
100
	private Button linkButton = null;
101
102
	private Image linkedFileImage;
103
104
	private Image linkedFolderAndFileImage;
105
106
	private Button moveButton = null;
96
107
108
	private int operationMask;
109
	private String preferredVariable;
110
	private IResource receivingResource = null;
111
	private Button shadowCopyButton = null;
112
	private boolean targetIsVirtual;
113
	private String variable = null;
114
	private Button variableCheckbox = null;
115
	private Combo variableCombo = null;
116
	private Image virtualFolderAndFileImage;
117
	
97
	/**
118
	/**
119
	 * Creates the Import Type Dialog when resources are dragged and dropped from an Eclipse
120
	 * view.
121
	 * 
98
	 * @param shell
122
	 * @param shell
123
	 * 			the parent Shell
99
	 * @param dropOperation
124
	 * @param dropOperation
125
	 * 		The dropOperation that was used by the user
100
	 * @param sources
126
	 * @param sources
127
	 * 		The list of resources that were dragged
101
	 * @param target
128
	 * @param target
129
	 * 		The target container onto which the resources were dropped
102
	 */
130
	 */
103
	public ImportTypeDialog(Shell shell, int dropOperation,
131
	public ImportTypeDialog(Shell shell, int dropOperation,
104
			IResource[] sources, IContainer target) {
132
			IResource[] sources, IContainer target) {
105
		this(shell, selectAppropriateMask(dropOperation, sources, target), getPreferredVariable(sources, target), target.isVirtual());
133
		this(shell, selectAppropriateMask(dropOperation, sources, target), getPreferredVariable(sources, target), target.isVirtual());
106
	}
134
	}
107
135
	
108
	/**
109
	 * @param names
110
	 * @param target
111
	 * @return the most appropriate path variable given the context
112
	 */
113
	private static String getPreferredVariable(String[] names,
114
			IContainer target) {
115
		IPath[] paths = new IPath[names.length];
116
		for (int i = 0; i < names.length; i++) {
117
			paths[i] = Path.fromOSString(names[i]);
118
		}
119
		return getPreferredVariable(paths, target);
120
	}
121
	/**
122
	 * @param sources
123
	 * @param target
124
	 * @return the most appropriate path variable given the context
125
	 */
126
	private static String getPreferredVariable(IResource[] sources,
127
			IContainer target) {
128
		IPath[] paths = new IPath[sources.length];
129
		for (int i = 0; i < sources.length; i++) {
130
			paths[i] = sources[i].getLocation();
131
		}
132
		return getPreferredVariable(paths, target);
133
	}
134
135
	/**
136
	 * Find the most appropriate path variable for a set of paths.
137
	 * The first thing is to find a common root for all the paths.
138
	 * So for the following paths:
139
	 * 		c:\foo\path\bar\dir1\file1.txt
140
	 * 		c:\foo\path\bar\dir2\file2.txt
141
	 * The following root will be selected:
142
	 * 		c:\foo\path\bar\
143
	 * Then, given all the path variable locations, the variable
144
	 * who's distance (in segments) from the common root in the smallest
145
	 * will be chosen.
146
	 * A priority is given as to variables enclosing the root, as others
147
	 * only being enclosed by the root.
148
	 *
149
	 * So if there's two variables, being 
150
	 * 		FOO - c:\foo\
151
	 * 		DIR1 - c:\foo\path\bar\dir1
152
	 * And the common root is:
153
	 * 		c:\foo\path\bar
154
	 * FOO will be selected over DIR1, even through the distance between 
155
	 * the common root and DIR1 is (1), and the distance between the 
156
	 * common root and FOO is (2).  This is because selecting DIR1 would
157
	 * cause the location to be relative to its parent.
158
	 * @param paths
159
	 * @param target
160
	 * @return the most appropriate path variable given the context
161
	 */
162
	private static String getPreferredVariable(IPath[] paths,
163
			IContainer target) {
164
		IPath commonRoot = null;
165
		for (int i = 0; i < paths.length; i++) {
166
			if (paths[i] != null) {
167
				if (commonRoot == null)
168
					commonRoot = paths[i];
169
				else  {
170
					int count = commonRoot.matchingFirstSegments(paths[i]);
171
					int remainingSegments = commonRoot.segmentCount() - count;
172
					if (remainingSegments <= 0)
173
						return null;
174
					commonRoot = commonRoot.removeLastSegments(remainingSegments);
175
				}
176
			}
177
		}
178
		
179
		String mostAppropriate = null;
180
		String mostAppropriateToParent = null;
181
		int mostAppropriateCount = Integer.MAX_VALUE;
182
		int mostAppropriateCountToParent = Integer.MAX_VALUE;
183
		IPathVariableManager pathVariableManager = target.getProject().getPathVariableManager();
184
		String [] variables = pathVariableManager.getPathVariableNames(target);
185
		
186
		for (int i = 0; i < variables.length; i++) {
187
			IPathVariable var = pathVariableManager.getPathVariable(variables[i], target);
188
			if (var.isPreferred()) {
189
				URI value = pathVariableManager.getValue(variables[i], target);
190
				if (value != null) {
191
					IPath path = URIUtil.toPath(value);
192
					if (path != null) {
193
						int difference = path.matchingFirstSegments(commonRoot);
194
						if (difference > 0) {
195
							if (difference < mostAppropriateCount) {
196
								mostAppropriateCount = difference;
197
								mostAppropriate = variables[i];
198
							}
199
						}
200
						else {
201
							// calculate if commonRoot could be relative to the parent of path
202
							difference = commonRoot.matchingFirstSegments(path);
203
							if (difference > 0) {
204
								if (difference < mostAppropriateCountToParent) {
205
									mostAppropriateCountToParent = difference;
206
									mostAppropriateToParent = variables[i];
207
								}
208
							}
209
						}
210
					}
211
				}
212
			}
213
		}
214
		
215
		if (mostAppropriate == null) {
216
			if (mostAppropriateToParent == null)
217
				return "PROJECT_LOC"; //$NON-NLS-1$
218
			return mostAppropriateToParent;
219
		}
220
		return mostAppropriate;
221
	}
222
223
	/**
136
	/**
137
	 * Creates the Import Type Dialog when files are dragged and dropped from the 
138
	 * operating system's shell (Windows Explorer on Windows Platform, for example).
139
	 * 
140
	 * @param shell
141
	 * 			the parent Shell
224
	 * @param dropOperation
142
	 * @param dropOperation
143
	 * 		The dropOperation that was used by the user
225
	 * @param names
144
	 * @param names
145
	 * 		The list of files that were dragged
226
	 * @param target
146
	 * @param target
227
	 * @return the appropriate import mask given the files dropped on the target
147
	 * 		The target container onto which the files were dropped
228
	 */
229
	private static int selectAppropriateMask(int dropOperation, String[] names, IContainer target) {
230
		int mask = ImportTypeDialog.IMPORT_VIRTUAL_FOLDERS_AND_LINKS | ImportTypeDialog.IMPORT_LINK;
231
		if (!target.isVirtual() && (dropOperation != DND.DROP_LINK))
232
			mask |= ImportTypeDialog.IMPORT_COPY;
233
		if (areOnlyFiles(names))
234
			mask |= ImportTypeDialog.IMPORT_FILES_ONLY;
235
		return mask;
236
	}
237
238
	/**
239
	 * @param dropOperation
240
	 * @param resources
241
	 * @param target
242
	 * @return the appropriate import mask given the files dropped on the target
243
	 */
148
	 */
244
	private static int selectAppropriateMask(int dropOperation, IResource[] resources, IContainer target) {
149
	public ImportTypeDialog(Shell shell, int dropOperation, String[] names, IContainer target) {
245
		int mask = ImportTypeDialog.IMPORT_VIRTUAL_FOLDERS_AND_LINKS | ImportTypeDialog.IMPORT_LINK;
150
		this(shell, selectAppropriateMask(dropOperation, names, target), getPreferredVariable(names, target), target.isVirtual());
246
		if (!target.isVirtual() && (dropOperation != DND.DROP_LINK))
247
			mask |= ImportTypeDialog.IMPORT_COPY;
248
		if (areOnlyFiles(resources))
249
			mask |= ImportTypeDialog.IMPORT_FILES_ONLY;
250
		return mask;
251
	}
252
253
	private static boolean areOnlyFiles(String[] names) {
254
		for (int i = 0; i < names.length; i++) {
255
			File file = new File(names[i]);
256
			if (file.exists() && !file.isFile())
257
				return false;
258
		}
259
		return true;
260
	}
261
262
	private static boolean areOnlyFiles(IResource[] resources) {
263
		for (int i = 0; i < resources.length; i++) {
264
			if (resources[i].getType() != IResource.FILE)
265
				return false;
266
		}
267
		return true;
268
	}
151
	}
269
152
	
270
	private Image fileImage;
271
	private Image linkedFileImage;
272
	private Image folderAndFileImage;
273
	private Image virtualFolderAndFileImage;
274
	private Image linkedFolderAndFileImage;
275
	private int operationMask;
276
	private int currentSelection;
277
	private Button copyButton = null;
278
	private Button shadowCopyButton = null;
279
	private Button linkButton = null;
280
	private Button moveButton = null;
281
	private Combo variableCombo = null;
282
	private Button alwaysPerformThisOperation = null;
283
	private Button variableCheckbox = null;
284
	private String variable = null;
285
	private IResource receivingResource = null;
286
	private boolean targetIsVirtual;
287
	private String preferredVariable;
288
289
	/**
153
	/**
290
	 * @param parentShell
154
	 * @param parentShell
291
	 * @param operationMask
155
	 * @param operationMask
Lines 340-375 Link Here
340
		desc = new AlignedCompositeImageDescriptor(linkedFileDescriptor, linkedFolderDescriptor);
204
		desc = new AlignedCompositeImageDescriptor(linkedFileDescriptor, linkedFolderDescriptor);
341
		linkedFolderAndFileImage = desc.createImage();
205
		linkedFolderAndFileImage = desc.createImage();
342
		
206
		
343
		if (Boolean.valueOf(readContextPreference(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_RELATIVE)).booleanValue())
207
		IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore();
208
		if (store.getBoolean(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_RELATIVE))
344
			variable = preferredVariable;
209
			variable = preferredVariable;
345
	}
210
	}
346
347
	class AlignedCompositeImageDescriptor extends CompositeImageDescriptor {
348
349
		ImageDescriptor first, second;
350
		
351
		private int SPACE = 4;
352
		AlignedCompositeImageDescriptor(ImageDescriptor first, ImageDescriptor second) {
353
			this.first = first;
354
			this.second = second;
355
		}
356
		/* (non-Javadoc)
357
		 * @see org.eclipse.jface.resource.CompositeImageDescriptor#drawCompositeImage(int, int)
358
		 */
359
		protected void drawCompositeImage(int width, int height) {
360
            drawImage(first.getImageData(), 0, 0);
361
            drawImage(second.getImageData(), first.getImageData().width + SPACE, 0);
362
		}
363
364
		/* (non-Javadoc)
365
		 * @see org.eclipse.jface.resource.CompositeImageDescriptor#getSize()
366
		 */
367
		protected Point getSize() {
368
			return new Point(first.getImageData().width + second.getImageData().width + SPACE, 
369
					Math.max(first.getImageData().height, second.getImageData().height));
370
		}
371
		
372
	}
373
	
211
	
374
	/* (non-Javadoc)
212
	/* (non-Javadoc)
375
	 * @see org.eclipse.jface.dialogs.TrayDialog#close()
213
	 * @see org.eclipse.jface.dialogs.TrayDialog#close()
Lines 382-387 Link Here
382
		linkedFolderAndFileImage.dispose();
220
		linkedFolderAndFileImage.dispose();
383
		return super.close();
221
		return super.close();
384
	}
222
	}
223
	
224
	/**
225
	 * Get the user selection from the dialog.
226
	 * @return The current selection (one of IMPORT_COPY, IMPORT_VIRTUAL_FOLDERS_AND_LINKS, IMPORT_LINK and IMPORT_MOVE)
227
	 */
228
	public int getSelection() {
229
		return currentSelection;
230
	}
231
	
232
	/**
233
	 * Get the selected variable if the selection is either IMPORT_VIRTUAL_FOLDERS_AND_LINKS or IMPORT_LINK 
234
	 * @return The currently selected variable, or AUTOMATIC or ABSOLUTE_PATH
235
	 */
236
	public String getVariable() {
237
		return variable;
238
	}
239
	
240
	/* (non-Javadoc)
241
	 * @see org.eclipse.jface.dialogs.MessageDialog#open()
242
	 */
243
	public int open() {
244
		IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore();
245
		
246
		String mode = store.getString(targetIsVirtual? IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_VIRTUAL_FOLDER_MODE:IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE);
247
248
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_PROMPT))
249
			return super.open();
250
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_MOVE_COPY) && hasFlag(IMPORT_COPY)) {
251
			this.currentSelection = IMPORT_COPY;
252
			return Window.OK;
253
		}
254
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_MOVE_COPY) && hasFlag(IMPORT_MOVE)) {
255
			this.currentSelection = IMPORT_MOVE;
256
			return Window.OK;
257
		}
258
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK) && hasFlag(IMPORT_LINK)) {
259
			this.currentSelection = IMPORT_LINK;
260
			return Window.OK;
261
		}
262
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK_AND_VIRTUAL_FOLDER) && hasFlag(IMPORT_VIRTUAL_FOLDERS_AND_LINKS)) {
263
			this.currentSelection = IMPORT_VIRTUAL_FOLDERS_AND_LINKS;
264
			return Window.OK;
265
		}
266
267
		return super.open();
268
	}
269
	
270
	/** Set the project that is the destination of the import operation
271
	 * @param resource
272
	 */
273
	public void setResource(IResource resource) {
274
		receivingResource = resource;
275
	}
276
	
277
	private void editVariables() {
278
		String selectedItem = variable;
279
		PathVariableEditDialog dialog = new PathVariableEditDialog(getShell());
280
		dialog.setResource(receivingResource);
281
		if (dialog.open() == IDialogConstants.OK_ID) {
282
			String[] variableNames = (String[]) dialog.getResult();
283
			if (variableNames != null && variableNames.length >= 1) {
284
				selectedItem = variableNames[0];
285
			}
286
		}
287
		setupVariableContent();
288
		if (selectedItem != null) {
289
			selectVariable(selectedItem);
290
		}
291
	}
292
	
293
	private boolean hasFlag(int flag) {
294
		return (operationMask & flag) != 0;
295
	}
385
296
386
	// the format of the context is operationMask,value:operationMask,value:operationMask,value
297
	// the format of the context is operationMask,value:operationMask,value:operationMask,value
387
	private String readContextPreference(String key) {
298
	private String readContextPreference(String key) {
Lines 397-402 Link Here
397
		return ""; //$NON-NLS-1$
308
		return ""; //$NON-NLS-1$
398
	}
309
	}
399
	
310
	
311
	private void refreshSelection() {
312
		if (copyButton != null)
313
			copyButton.setSelection(currentSelection == IMPORT_COPY);
314
		if (shadowCopyButton != null)
315
			shadowCopyButton.setSelection(currentSelection == IMPORT_VIRTUAL_FOLDERS_AND_LINKS);
316
		if (linkButton != null)
317
			linkButton.setSelection(currentSelection == IMPORT_LINK);
318
		if (moveButton != null)
319
			moveButton.setSelection(currentSelection == IMPORT_MOVE);
320
		if (variableCheckbox != null)
321
			variableCheckbox.setEnabled((currentSelection & (IMPORT_VIRTUAL_FOLDERS_AND_LINKS | IMPORT_LINK)) != 0);
322
		if (variableCombo != null)
323
			variableCombo.setEnabled(variableCheckbox.getSelection() && variableCheckbox.isEnabled());
324
		setupVariableCheckboxToolTip();
325
	}
326
	
327
	private void selectVariable(String var) {
328
		String[] items = variableCombo.getItems();
329
		for (int i = 0; i < items.length; i++) {
330
			if (var.equals(items[i])) {
331
				variableCombo.select(i);
332
				variable = items[i];
333
				return;
334
			}
335
		}
336
		variableCombo.select(0);
337
		variable = items[0];
338
	}
339
340
341
	private void setupVariableCheckboxToolTip() {
342
		if (variableCheckbox != null) {
343
			if (variableCheckbox.getSelection())
344
				variableCheckbox.setToolTipText(IDEWorkbenchMessages.ImportTypeDialog_importElementsAsTooltipSet);
345
			else
346
				variableCheckbox.setToolTipText(IDEWorkbenchMessages.ImportTypeDialog_importElementsAsTooltip);
347
		}
348
	}
349
	
350
	private void setupVariableContent() {
351
		IPathVariableManager pathVariableManager;
352
		if (receivingResource != null)
353
			pathVariableManager = receivingResource.getProject().getPathVariableManager();
354
		else
355
			pathVariableManager = ResourcesPlugin.getWorkspace().getPathVariableManager();
356
		String[] variables = pathVariableManager.getPathVariableNames(receivingResource);
357
		
358
		ArrayList items = new ArrayList();
359
		for (int i = 0; i < variables.length; i++) {
360
			if (variables[i].equals("PARENT")) //$NON-NLS-1$
361
				continue;
362
			items.add(variables[i]);
363
		}
364
		items.add(IDEWorkbenchMessages.ImportTypeDialog_editVariables);
365
		variableCombo.setItems((String[]) items.toArray(new String[0]));
366
		super.getShell().layout(true);
367
	}
368
400
	private void writeContextPreference(String key, String value) {
369
	private void writeContextPreference(String key, String value) {
401
		String oldValue = IDEWorkbenchPlugin.getDefault().getPreferenceStore().getString(key);
370
		String oldValue = IDEWorkbenchPlugin.getDefault().getPreferenceStore().getString(key);
402
		StringBuffer buffer = new StringBuffer();
371
		StringBuffer buffer = new StringBuffer();
Lines 423-472 Link Here
423
		String newValue = buffer.toString();
392
		String newValue = buffer.toString();
424
		IDEWorkbenchPlugin.getDefault().getPreferenceStore().setValue(key, newValue);
393
		IDEWorkbenchPlugin.getDefault().getPreferenceStore().setValue(key, newValue);
425
	}
394
	}
426
	
427
	/**
428
	 * @return The currently selected variable, or AUTOMATIC or ABSOLUTE_PATH
429
	 */
430
	public String getVariable() {
431
		return variable;
432
	}
433
395
396
	protected void buttonPressed(int buttonId) {
397
		if (buttonId == IDialogConstants.OK_ID) {
398
			writeContextPreference(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_TYPE, Integer.toString(currentSelection));
434
399
435
	/**
400
			IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore();
436
	 * @return The current selection (one of IMPORT_COPY, IMPORT_GROUPS_AND_LINKS, IMPORT_LINK and IMPORT_MOVE)
401
			store.putValue(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_RELATIVE, Boolean.toString(variable != null));
437
	 */
402
			if (alwaysPerformThisOperation.getSelection()) {
438
	public int getSelection() {
403
				String mode = IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_PROMPT;
439
		return currentSelection;
404
				switch(currentSelection) {
440
	}
405
				case IMPORT_COPY:
441
	
406
				case IMPORT_MOVE:
442
	/* (non-Javadoc)
407
					mode = IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_MOVE_COPY;
443
	 * @see org.eclipse.jface.dialogs.MessageDialog#open()
408
					break;
444
	 */
409
				case IMPORT_LINK:
445
	public int open() {
410
					mode = IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK;
446
		IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore();
411
					break;
447
		
412
				case IMPORT_VIRTUAL_FOLDERS_AND_LINKS:
448
		String mode = store.getString(targetIsVirtual? IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_VIRTUAL_FOLDER_MODE:IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE);
413
					mode = IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK_AND_VIRTUAL_FOLDER;
449
414
					break;
450
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_PROMPT))
415
				}
451
			return super.open();
416
				store.putValue(targetIsVirtual? IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_VIRTUAL_FOLDER_MODE:IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE, mode);
452
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_MOVE_COPY) && hasFlag(IMPORT_COPY)) {
417
			}
453
			this.currentSelection = IMPORT_COPY;
454
			return Window.OK;
455
		}
456
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_MOVE_COPY) && hasFlag(IMPORT_MOVE)) {
457
			this.currentSelection = IMPORT_MOVE;
458
			return Window.OK;
459
		}
460
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK) && hasFlag(IMPORT_LINK)) {
461
			this.currentSelection = IMPORT_LINK;
462
			return Window.OK;
463
		}
464
		if (mode.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK_AND_VIRTUAL_FOLDER) && hasFlag(IMPORT_VIRTUAL_FOLDERS_AND_LINKS)) {
465
			this.currentSelection = IMPORT_VIRTUAL_FOLDERS_AND_LINKS;
466
			return Window.OK;
467
		}
418
		}
468
419
		super.buttonPressed(buttonId);
469
		return super.open();
470
	}
420
	}
471
421
472
	protected void configureShell(Shell shell) {
422
	protected void configureShell(Shell shell) {
Lines 478-508 Link Here
478
				IIDEHelpContextIds.IMPORT_TYPE_DIALOG);
428
				IIDEHelpContextIds.IMPORT_TYPE_DIALOG);
479
	}
429
	}
480
430
481
	protected Control createMessageArea(Composite parent) {
482
		Composite composite = new Composite(parent, 0);
483
		GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
484
 		composite.setLayoutData(gridData);
485
486
		
487
		GridLayout layout = new GridLayout();
488
		layout.numColumns = 1;
489
		layout.marginTop= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
490
		layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
491
		composite.setLayout(layout);
492
493
		String message = (operationMask & IMPORT_FILES_ONLY) != 0 ? IDEWorkbenchMessages.ImportTypeDialog_questionFilesOnly:
494
			IDEWorkbenchMessages.ImportTypeDialog_question;
495
496
		// create message
497
		if (message != null) {
498
			Label messageLabel = new Label(composite, SWT.WRAP);
499
			messageLabel.setText(message);
500
			gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
501
			messageLabel.setLayoutData(gridData);
502
		}
503
		return composite;
504
	}
505
506
	protected Control createDialogArea(Composite parent) {
431
	protected Control createDialogArea(Composite parent) {
507
		boolean linkIsOnlyChoice = hasFlag(IMPORT_LINK) && !(hasFlag(IMPORT_COPY | IMPORT_MOVE) || (hasFlag(IMPORT_VIRTUAL_FOLDERS_AND_LINKS) && !hasFlag(IMPORT_FILES_ONLY)));
432
		boolean linkIsOnlyChoice = hasFlag(IMPORT_LINK) && !(hasFlag(IMPORT_COPY | IMPORT_MOVE) || (hasFlag(IMPORT_VIRTUAL_FOLDERS_AND_LINKS) && !hasFlag(IMPORT_FILES_ONLY)));
508
433
Lines 523-528 Link Here
523
448
524
		layout.marginWidth += indent;
449
		layout.marginWidth += indent;
525
		composite.setLayout(layout);
450
		composite.setLayout(layout);
451
		SelectionListener listener = new SelectionListener() {
452
			public void widgetDefaultSelected(SelectionEvent e) {
453
				currentSelection = ((Integer) e.widget.getData()).intValue();
454
				refreshSelection();
455
			}
456
457
			public void widgetSelected(SelectionEvent e) {
458
				currentSelection = ((Integer) e.widget.getData()).intValue();
459
				refreshSelection();
460
			}
461
		};
526
		
462
		
527
		if (hasFlag(IMPORT_COPY)) {
463
		if (hasFlag(IMPORT_COPY)) {
528
			copyButton = new Button(composite, SWT.RADIO);
464
			copyButton = new Button(composite, SWT.RADIO);
Lines 530-536 Link Here
530
			gridData = new GridData(GridData.FILL_HORIZONTAL);
466
			gridData = new GridData(GridData.FILL_HORIZONTAL);
531
			copyButton.setLayoutData(gridData);
467
			copyButton.setLayoutData(gridData);
532
			copyButton.setData(new Integer(IMPORT_COPY));
468
			copyButton.setData(new Integer(IMPORT_COPY));
533
			copyButton.addSelectionListener(this);
469
			copyButton.addSelectionListener(listener);
534
			if (hasFlag(IMPORT_VIRTUAL_FOLDERS_AND_LINKS | IMPORT_LINK))
470
			if (hasFlag(IMPORT_VIRTUAL_FOLDERS_AND_LINKS | IMPORT_LINK))
535
				copyButton.setImage(hasFlag(IMPORT_FILES_ONLY) ? fileImage:folderAndFileImage);
471
				copyButton.setImage(hasFlag(IMPORT_FILES_ONLY) ? fileImage:folderAndFileImage);
536
		}
472
		}
Lines 541-547 Link Here
541
			gridData = new GridData(GridData.FILL_HORIZONTAL);
477
			gridData = new GridData(GridData.FILL_HORIZONTAL);
542
			moveButton.setLayoutData(gridData);
478
			moveButton.setLayoutData(gridData);
543
			moveButton.setData(new Integer(IMPORT_MOVE));
479
			moveButton.setData(new Integer(IMPORT_MOVE));
544
			moveButton.addSelectionListener(this);
480
			moveButton.addSelectionListener(listener);
545
		}
481
		}
546
482
547
		if (hasFlag(IMPORT_LINK) && !linkIsOnlyChoice) {
483
		if (hasFlag(IMPORT_LINK) && !linkIsOnlyChoice) {
Lines 550-556 Link Here
550
			gridData = new GridData(GridData.FILL_HORIZONTAL);
486
			gridData = new GridData(GridData.FILL_HORIZONTAL);
551
			linkButton.setLayoutData(gridData);
487
			linkButton.setLayoutData(gridData);
552
			linkButton.setData(new Integer(IMPORT_LINK));
488
			linkButton.setData(new Integer(IMPORT_LINK));
553
			linkButton.addSelectionListener(this);
489
			linkButton.addSelectionListener(listener);
554
			linkButton.setImage(hasFlag(IMPORT_FILES_ONLY) ? linkedFileImage:linkedFolderAndFileImage);
490
			linkButton.setImage(hasFlag(IMPORT_FILES_ONLY) ? linkedFileImage:linkedFolderAndFileImage);
555
		}
491
		}
556
492
Lines 560-566 Link Here
560
			gridData = new GridData(GridData.FILL_HORIZONTAL);
496
			gridData = new GridData(GridData.FILL_HORIZONTAL);
561
			shadowCopyButton.setLayoutData(gridData);
497
			shadowCopyButton.setLayoutData(gridData);
562
			shadowCopyButton.setData(new Integer(IMPORT_VIRTUAL_FOLDERS_AND_LINKS));
498
			shadowCopyButton.setData(new Integer(IMPORT_VIRTUAL_FOLDERS_AND_LINKS));
563
			shadowCopyButton.addSelectionListener(this);
499
			shadowCopyButton.addSelectionListener(listener);
564
			shadowCopyButton.setImage(virtualFolderAndFileImage);
500
			shadowCopyButton.setImage(virtualFolderAndFileImage);
565
		}
501
		}
566
502
Lines 579-588 Link Here
579
			gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
515
			gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
580
			variableCheckbox.setLayoutData(gridData);
516
			variableCheckbox.setLayoutData(gridData);
581
			variableCheckbox.addSelectionListener(new SelectionListener() {
517
			variableCheckbox.addSelectionListener(new SelectionListener() {
582
				public void widgetSelected(SelectionEvent e) {
518
				public void widgetDefaultSelected(SelectionEvent e) {
583
					selectRelativeCombo();
519
					selectRelativeCombo();
584
				}
520
				}
585
				public void widgetDefaultSelected(SelectionEvent e) {
521
				public void widgetSelected(SelectionEvent e) {
586
					selectRelativeCombo();
522
					selectRelativeCombo();
587
				}
523
				}
588
				private void selectRelativeCombo() {
524
				private void selectRelativeCombo() {
Lines 639-761 Link Here
639
		return composite;
575
		return composite;
640
	}
576
	}
641
577
642
	private void setupVariableCheckboxToolTip() {
578
	protected Control createMessageArea(Composite parent) {
643
		if (variableCheckbox != null) {
579
		Composite composite = new Composite(parent, 0);
644
			if (variableCheckbox.getSelection())
580
		GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
645
				variableCheckbox.setToolTipText(IDEWorkbenchMessages.ImportTypeDialog_importElementsAsTooltipSet);
581
 		composite.setLayoutData(gridData);
646
			else
647
				variableCheckbox.setToolTipText(IDEWorkbenchMessages.ImportTypeDialog_importElementsAsTooltip);
648
		}
649
	}
650
582
651
	private boolean hasFlag(int flag) {
583
		
652
		return (operationMask & flag) != 0;
584
		GridLayout layout = new GridLayout();
585
		layout.numColumns = 1;
586
		layout.marginTop= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
587
		layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
588
		composite.setLayout(layout);
589
590
		String message = (operationMask & IMPORT_FILES_ONLY) != 0 ? IDEWorkbenchMessages.ImportTypeDialog_questionFilesOnly:
591
			IDEWorkbenchMessages.ImportTypeDialog_question;
592
593
		// create message
594
		if (message != null) {
595
			Label messageLabel = new Label(composite, SWT.WRAP);
596
			messageLabel.setText(message);
597
			gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
598
			messageLabel.setLayoutData(gridData);
599
		}
600
		return composite;
653
	}
601
	}
654
	
602
	
655
	private void editVariables() {
603
	/**
656
		String selectedItem = variable;
604
	 * @param resources
657
		PathVariableEditDialog dialog = new PathVariableEditDialog(getShell());
605
	 * 		The list of items that were dragged
658
		dialog.setResource(receivingResource);
606
	 * @return true if a set of paths are files only or a mix of files and folders, false otherwise
659
		if (dialog.open() == IDialogConstants.OK_ID) {
607
	 */
660
			String[] variableNames = (String[]) dialog.getResult();
608
	private static boolean areOnlyFiles(IResource[] resources) {
661
			if (variableNames != null && variableNames.length >= 1) {
609
		for (int i = 0; i < resources.length; i++) {
662
				selectedItem = variableNames[0];
610
			if (resources[i].getType() != IResource.FILE)
663
			}
611
				return false;
664
		}
665
		setupVariableContent();
666
		if (selectedItem != null) {
667
			selectVariable(selectedItem);
668
		}
612
		}
613
		return true;
669
	}
614
	}
670
615
671
	private void selectVariable(String var) {
616
	/**
672
		String[] items = variableCombo.getItems();
617
	 * @param names
673
		for (int i = 0; i < items.length; i++) {
618
	 * 		The list of items that were dragged
674
			if (var.equals(items[i])) {
619
	 * @return true if a set of paths are files only or a mix of files and folders, false otherwise
675
				variableCombo.select(i);
620
	 */
676
				variable = items[i];
621
	private static boolean areOnlyFiles(String[] names) {
677
				return;
622
		for (int i = 0; i < names.length; i++) {
678
			}
623
			File file = new File(names[i]);
624
			if (file.exists() && !file.isFile())
625
				return false;
679
		}
626
		}
680
		variableCombo.select(0);
627
		return true;
681
		variable = items[0];
682
	}
628
	}
683
629
684
	private void setupVariableContent() {
630
	/**
685
		IPathVariableManager pathVariableManager;
631
	 * Find the most appropriate path variable for a set of paths.
686
		if (receivingResource != null)
632
	 * The first thing is to find a common root for all the paths.
687
			pathVariableManager = receivingResource.getProject().getPathVariableManager();
633
	 * So for the following paths:
688
		else
634
	 * 		c:\foo\path\bar\dir1\file1.txt
689
			pathVariableManager = ResourcesPlugin.getWorkspace().getPathVariableManager();
635
	 * 		c:\foo\path\bar\dir2\file2.txt
690
		String[] variables = pathVariableManager.getPathVariableNames(receivingResource);
636
	 * The following root will be selected:
637
	 * 		c:\foo\path\bar\
638
	 * Then, given all the path variable locations, the variable
639
	 * who's distance (in segments) from the common root in the smallest
640
	 * will be chosen.
641
	 * A priority is given as to variables enclosing the root, as others
642
	 * only being enclosed by the root.
643
	 *
644
	 * So if there's two variables, being 
645
	 * 		FOO - c:\foo\
646
	 * 		DIR1 - c:\foo\path\bar\dir1
647
	 * And the common root is:
648
	 * 		c:\foo\path\bar
649
	 * FOO will be selected over DIR1, even through the distance between 
650
	 * the common root and DIR1 is (1), and the distance between the 
651
	 * common root and FOO is (2).  This is because selecting DIR1 would
652
	 * cause the location to be relative to its parent.
653
654
	 * @param paths
655
	 * 		The list of items that were dragged
656
	 * @param target
657
	 * 		The target container onto which the items were dropped
658
	 * @return the most appropriate path variable given the context
659
	 */
660
	private static String getPreferredVariable(IPath[] paths,
661
			IContainer target) {
662
		IPath commonRoot = null;
663
		for (int i = 0; i < paths.length; i++) {
664
			if (paths[i] != null) {
665
				if (commonRoot == null)
666
					commonRoot = paths[i];
667
				else  {
668
					int count = commonRoot.matchingFirstSegments(paths[i]);
669
					int remainingSegments = commonRoot.segmentCount() - count;
670
					if (remainingSegments <= 0)
671
						return null;
672
					commonRoot = commonRoot.removeLastSegments(remainingSegments);
673
				}
674
			}
675
		}
676
		
677
		String mostAppropriate = null;
678
		String mostAppropriateToParent = null;
679
		int mostAppropriateCount = Integer.MAX_VALUE;
680
		int mostAppropriateCountToParent = Integer.MAX_VALUE;
681
		IPathVariableManager pathVariableManager = target.getProject().getPathVariableManager();
682
		String [] variables = pathVariableManager.getPathVariableNames(target);
691
		
683
		
692
		ArrayList items = new ArrayList();
693
		for (int i = 0; i < variables.length; i++) {
684
		for (int i = 0; i < variables.length; i++) {
694
			if (variables[i].equals("PARENT")) //$NON-NLS-1$
685
			IPathVariable var = pathVariableManager.getPathVariable(variables[i], target);
695
				continue;
686
			if (var.isPreferred()) {
696
			items.add(variables[i]);
687
				URI rawValue = pathVariableManager.getValue(variables[i], target);
688
				URI value = pathVariableManager.resolveURI(rawValue, target);
689
				if (value != null) {
690
					IPath path = URIUtil.toPath(value);
691
					if (path != null) {
692
						int difference = path.matchingFirstSegments(commonRoot);
693
						if (difference > 0) {
694
							if (difference < mostAppropriateCount) {
695
								mostAppropriateCount = difference;
696
								mostAppropriate = variables[i];
697
							}
698
						}
699
						else {
700
							// calculate if commonRoot could be relative to the parent of path
701
							difference = commonRoot.matchingFirstSegments(path);
702
							if (difference > 0) {
703
								if (difference < mostAppropriateCountToParent) {
704
									mostAppropriateCountToParent = difference;
705
									mostAppropriateToParent = variables[i];
706
								}
707
							}
708
						}
709
					}
710
				}
711
			}
697
		}
712
		}
698
		items.add(IDEWorkbenchMessages.ImportTypeDialog_editVariables);
713
		
699
		variableCombo.setItems((String[]) items.toArray(new String[0]));
714
		if (mostAppropriate == null) {
700
		super.getShell().layout(true);
715
			if (mostAppropriateToParent == null)
716
				return "PROJECT_LOC"; //$NON-NLS-1$
717
			return mostAppropriateToParent;
718
		}
719
		return mostAppropriate;
701
	}
720
	}
702
	
721
	
703
	protected void buttonPressed(int buttonId) {
722
	/**
704
		if (buttonId == IDialogConstants.OK_ID) {
723
	 * Return the most appropriate path variable given the context
705
			writeContextPreference(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_TYPE, Integer.toString(currentSelection));
724
	 * @param sources
706
			writeContextPreference(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_RELATIVE, Boolean.toString(variable != null));
725
	 * 		The list of resources that were dragged
707
726
	 * @param target
708
			IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore();
727
	 * 		The target container onto which the resources were dropped
709
			if (alwaysPerformThisOperation.getSelection()) {
728
	 * @return the most appropriate path variable given the context
710
				String mode = IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_PROMPT;
729
	 */
711
				switch(currentSelection) {
730
	private static String getPreferredVariable(IResource[] sources,
712
				case IMPORT_COPY:
731
			IContainer target) {
713
				case IMPORT_MOVE:
732
		IPath[] paths = new IPath[sources.length];
714
					mode = IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_MOVE_COPY;
733
		for (int i = 0; i < sources.length; i++) {
715
					break;
734
			paths[i] = sources[i].getLocation();
716
				case IMPORT_LINK:
717
					mode = IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK;
718
					break;
719
				case IMPORT_VIRTUAL_FOLDERS_AND_LINKS:
720
					mode = IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK_AND_VIRTUAL_FOLDER;
721
					break;
722
				}
723
				store.putValue(targetIsVirtual? IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_VIRTUAL_FOLDER_MODE:IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE, mode);
724
			}
725
		}
735
		}
726
		super.buttonPressed(buttonId);
736
		return getPreferredVariable(paths, target);
727
	}
737
	}
728
738
729
	public void widgetDefaultSelected(SelectionEvent e) {
739
	/**
730
		currentSelection = ((Integer) e.widget.getData()).intValue();
740
	 * Return the most appropriate path variable given the context
731
		refreshSelection();
741
	 * @param names
742
	 * 		The list of files that were dragged
743
	 * @param target
744
	 * 		The target container onto which the files were dropped
745
	 * @return the most appropriate path variable given the context
746
	 */
747
	private static String getPreferredVariable(String[] names,
748
			IContainer target) {
749
		IPath[] paths = new IPath[names.length];
750
		for (int i = 0; i < names.length; i++) {
751
			paths[i] = Path.fromOSString(names[i]);
752
		}
753
		return getPreferredVariable(paths, target);
732
	}
754
	}
733
755
734
	public void widgetSelected(SelectionEvent e) {
756
	/**
735
		currentSelection = ((Integer) e.widget.getData()).intValue();
757
	 * Select the most appropriate mode that should be used for the dialog given
736
		refreshSelection();
758
	 * the items dropped on the container, the container type, and the drop operation.
759
	 *
760
	 * @param dropOperation
761
	 * @param resources
762
	 * 		The list of items that were dragged
763
	 * @param target
764
	 * 		The target container onto which the items were dropped
765
	 * @return the appropriate import mask given the files dropped on the target
766
	 */
767
	private static int selectAppropriateMask(int dropOperation, IResource[] resources, IContainer target) {
768
		int mask = ImportTypeDialog.IMPORT_VIRTUAL_FOLDERS_AND_LINKS | ImportTypeDialog.IMPORT_LINK;
769
		if (!target.isVirtual() && (dropOperation != DND.DROP_LINK))
770
			mask |= ImportTypeDialog.IMPORT_COPY;
771
		if (areOnlyFiles(resources))
772
			mask |= ImportTypeDialog.IMPORT_FILES_ONLY;
773
		return mask;
737
	}
774
	}
738
	
775
	
739
	private void refreshSelection() {
776
	/**
740
		if (copyButton != null)
777
	 * Select the most appropriate mode that should be used for the dialog given
741
			copyButton.setSelection(currentSelection == IMPORT_COPY);
778
	 * the items dropped on the container, the container type, and the drop operation.
742
		if (shadowCopyButton != null)
779
	 * 
743
			shadowCopyButton.setSelection(currentSelection == IMPORT_VIRTUAL_FOLDERS_AND_LINKS);
780
	 * @param dropOperation
744
		if (linkButton != null)
781
	 * @param names
745
			linkButton.setSelection(currentSelection == IMPORT_LINK);
782
	 * 		The list of items that were dragged
746
		if (moveButton != null)
783
	 * @param target
747
			moveButton.setSelection(currentSelection == IMPORT_MOVE);
784
	 * 		The target container onto which the items were dropped
748
		if (variableCheckbox != null)
785
	 * @return the appropriate import mask given the files dropped on the target
749
			variableCheckbox.setEnabled((currentSelection & (IMPORT_VIRTUAL_FOLDERS_AND_LINKS | IMPORT_LINK)) != 0);
786
	 */
750
		if (variableCombo != null)
787
	private static int selectAppropriateMask(int dropOperation, String[] names, IContainer target) {
751
			variableCombo.setEnabled(variableCheckbox.getSelection() && variableCheckbox.isEnabled());
788
		int mask = ImportTypeDialog.IMPORT_VIRTUAL_FOLDERS_AND_LINKS | ImportTypeDialog.IMPORT_LINK;
752
		setupVariableCheckboxToolTip();
789
		if (!target.isVirtual() && (dropOperation != DND.DROP_LINK))
790
			mask |= ImportTypeDialog.IMPORT_COPY;
791
		if (areOnlyFiles(names))
792
			mask |= ImportTypeDialog.IMPORT_FILES_ONLY;
793
		return mask;
753
	}
794
	}
754
795
755
	/** Set the project that is the destination of the import operation
796
	private class AlignedCompositeImageDescriptor extends CompositeImageDescriptor {
756
	 * @param resource
797
757
	 */
798
		private int SPACE = 4;
758
	public void setResource(IResource resource) {
799
		
759
		receivingResource = resource;
800
		ImageDescriptor first, second;
801
		AlignedCompositeImageDescriptor(ImageDescriptor first, ImageDescriptor second) {
802
			this.first = first;
803
			this.second = second;
804
		}
805
		/* (non-Javadoc)
806
		 * @see org.eclipse.jface.resource.CompositeImageDescriptor#drawCompositeImage(int, int)
807
		 */
808
		protected void drawCompositeImage(int width, int height) {
809
            drawImage(first.getImageData(), 0, 0);
810
            drawImage(second.getImageData(), first.getImageData().width + SPACE, 0);
811
		}
812
813
		/* (non-Javadoc)
814
		 * @see org.eclipse.jface.resource.CompositeImageDescriptor#getSize()
815
		 */
816
		protected Point getSize() {
817
			return new Point(first.getImageData().width + second.getImageData().width + SPACE, 
818
					Math.max(first.getImageData().height, second.getImageData().height));
819
		}
820
		
760
	}
821
	}
761
}
822
}

Return to bug 300046