View | Details | Raw Unified | Return to bug 313691 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/core/internal/events/ResourceDelta.java (+18 lines)
Lines 376-381 Link Here
376
		return ResourceInfo.isSet(newInfo.getFlags(), ICoreConstants.M_HIDDEN);
376
		return ResourceInfo.isSet(newInfo.getFlags(), ICoreConstants.M_HIDDEN);
377
	}
377
	}
378
378
379
	protected boolean isFloating() {
380
		//use old info for removals, and new info for added or changed
381
		if ((status & (REMOVED | REMOVED_PHANTOM)) != 0)
382
			return ResourceInfo.isSet(oldInfo.getFlags(), ICoreConstants.M_FLOATING);
383
		return ResourceInfo.isSet(newInfo.getFlags(), ICoreConstants.M_FLOATING);
384
	}
385
386
	protected boolean isFlatten() {
387
		//use old info for removals, and new info for added or changed
388
		if ((status & (REMOVED | REMOVED_PHANTOM)) != 0)
389
			return ResourceInfo.isSet(oldInfo.getFlags(), ICoreConstants.M_FLATTEN);
390
		return ResourceInfo.isSet(newInfo.getFlags(), ICoreConstants.M_FLATTEN);
391
	}
392
379
	protected void setChildren(ResourceDelta[] children) {
393
	protected void setChildren(ResourceDelta[] children) {
380
		this.children = children;
394
		this.children = children;
381
	}
395
	}
Lines 541-546 Link Here
541
			buffer.append(" (team private)"); //$NON-NLS-1$
555
			buffer.append(" (team private)"); //$NON-NLS-1$
542
		if (isHidden())
556
		if (isHidden())
543
			buffer.append(" (hidden)"); //$NON-NLS-1$
557
			buffer.append(" (hidden)"); //$NON-NLS-1$
558
		if (isFlatten())
559
			buffer.append(" (flatten)"); //$NON-NLS-1$
560
		if (isFloating())
561
			buffer.append(" (floating)"); //$NON-NLS-1$
544
	}
562
	}
545
563
546
	public void writeMarkerDebugString(StringBuffer buffer) {
564
	public void writeMarkerDebugString(StringBuffer buffer) {
(-)src/org/eclipse/core/internal/localstore/RefreshLocalVisitor.java (-2 / +22 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.core.internal.localstore;
11
package org.eclipse.core.internal.localstore;
12
12
13
import org.eclipse.core.internal.resources.ProjectDescription;
14
15
import org.eclipse.core.resources.IResource;
16
17
import java.net.URI;
18
13
import org.eclipse.core.internal.resources.*;
19
import org.eclipse.core.internal.resources.*;
14
import org.eclipse.core.internal.utils.Messages;
20
import org.eclipse.core.internal.utils.Messages;
15
import org.eclipse.core.internal.utils.Policy;
21
import org.eclipse.core.internal.utils.Policy;
Lines 78-93 Link Here
78
		}
84
		}
79
		/* Use the basic file creation protocol since we don't want to create any content on disk. */
85
		/* Use the basic file creation protocol since we don't want to create any content on disk. */
80
		info = workspace.createResource(target, false);
86
		info = workspace.createResource(target, false);
87
		if (node.getFlagMasks() != 0)
88
			info.set(node.getFlagMasks());
89
		
81
		/* Mark this resource as having unknown children */
90
		/* Mark this resource as having unknown children */
82
		info.set(ICoreConstants.M_CHILDREN_UNKNOWN);
91
		info.set(ICoreConstants.M_CHILDREN_UNKNOWN);
83
		target.getLocalManager().updateLocalSync(info, node.getLastModified());
92
		target.getLocalManager().updateLocalSync(info, node.getLastModified());
93
		
94
		if (info.isSet(ICoreConstants.M_LINK)) {
95
			URI localLocation = node.getStore().toURI();
96
			localLocation = target.getPathVariableManager().convertToRelative(localLocation, true, "PARENT_LOC"); //$NON-NLS-1$
97
			LinkDescription linkDescription = new LinkDescription(target, localLocation);
98
			Project project = (Project) target.getProject();
99
			project.getLocalManager().link(target, localLocation, node.fileInfo);
100
			ProjectDescription description = project.internalGetDescription();
101
			if (description.setLinkLocation(target.getProjectRelativePath(), linkDescription))
102
				project.writeDescription(IResource.NONE);
103
		}
84
	}
104
	}
85
105
86
	protected void deleteResource(UnifiedTreeNode node, Resource target) throws CoreException {
106
	protected void deleteResource(UnifiedTreeNode node, Resource target) throws CoreException {
87
		ResourceInfo info = target.getResourceInfo(false, false);
107
		ResourceInfo info = target.getResourceInfo(false, false);
88
		int flags = target.getFlags(info);
108
		int flags = target.getFlags(info);
89
		//don't delete linked resources
109
		//don't delete linked resources (but do delete floating resource)
90
		if (ResourceInfo.isSet(flags, ICoreConstants.M_LINK)) {
110
		if (ResourceInfo.isSet(flags, ICoreConstants.M_LINK) && !ResourceInfo.isSet(flags, ICoreConstants.M_FLOATING)) {
91
			//just clear local sync info
111
			//just clear local sync info
92
			info = target.getResourceInfo(false, true);
112
			info = target.getResourceInfo(false, true);
93
			//handle concurrent deletion
113
			//handle concurrent deletion
(-)src/org/eclipse/core/internal/localstore/UnifiedTree.java (-66 / +273 lines)
Lines 132-208 Link Here
132
		if (!parent.getProject().isAccessible())
132
		if (!parent.getProject().isAccessible())
133
			return;
133
			return;
134
134
135
		// get the list of resources in the file system
135
		boolean shouldBeFloating = (((IContainer) node.resource).isFlatten());
136
		// don't ask for local children if we know it doesn't exist locally
136
		if (shouldBeFloating) {
137
		IFileInfo[] list = node.existsInFileSystem() ? getLocalList(node) : NO_CHILDREN;
137
			// create linked resources for each given file store
138
		int localIndex = 0;
138
			// get the list of resources in the file system
139
139
			// don't ask for local children if we know it doesn't exist locally
140
		// See if the children of this resource have been computed before
140
			IFileStore[] list = node.existsInFileSystem() ? getLocalFlattenList(node) : new IFileStore[0];
141
		ResourceInfo resourceInfo = parent.getResourceInfo(false, false);
141
			int localIndex = 0;
142
		int flags = parent.getFlags(resourceInfo);
142
143
		boolean unknown = ResourceInfo.isSet(flags, ICoreConstants.M_CHILDREN_UNKNOWN);
143
			Project project = (Project) parent.getProject();
144
144
			UniqueFileStoreName[] uniqueList = generateUniqueList(list);
145
		// get the list of resources in the workspace
145
146
		if (!unknown && (parentType == IResource.FOLDER || parentType == IResource.PROJECT) && parent.exists(flags, true)) {
146
			// See if the children of this resource have been computed before
147
			IResource target = null;
147
			ResourceInfo resourceInfo = parent.getResourceInfo(false, false);
148
			UnifiedTreeNode child = null;
148
			int flags = parent.getFlags(resourceInfo);
149
			IResource[] members;
149
			boolean unknown = ResourceInfo.isSet(flags, ICoreConstants.M_CHILDREN_UNKNOWN);
150
			try {
150
151
				members = ((IContainer) parent).members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
151
			// get the list of resources in the workspace
152
			} catch (CoreException e) {
152
			if (!unknown && (parentType == IResource.FOLDER || parentType == IResource.PROJECT) && parent.exists(flags, true)) {
153
				members = NO_RESOURCES;
153
				IResource target = null;
154
			}
154
				UnifiedTreeNode child = null;
155
			int workspaceIndex = 0;
155
				IResource[] members;
156
			//iterate simultaneously over file system and workspace members
156
				try {
157
			while (workspaceIndex < members.length) {
157
					members = ((IContainer) parent).members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
158
				target = members[workspaceIndex];
158
				} catch (CoreException e) {
159
				String name = target.getName();
159
					members = NO_RESOURCES;
160
				IFileInfo localInfo = localIndex < list.length ? list[localIndex] : null;
160
				}
161
				int comp = localInfo != null ? name.compareTo(localInfo.getName()) : -1;
161
				int workspaceIndex = 0;
162
				//special handling for linked resources
162
				//iterate simultaneously over file system and workspace members
163
				if (target.isLinked()) {
163
				while (workspaceIndex < members.length) {
164
					//child will be null if location is undefined
164
					target = members[workspaceIndex];
165
					child = createChildForLinkedResource(target);
165
					String name = target.getName();
166
					workspaceIndex++;
166
					UniqueFileStoreName info = localIndex < uniqueList.length ? uniqueList[localIndex] : null;
167
					//if there is a matching local file, skip it - it will be blocked by the linked resource
167
					int comp = info != null ? name.compareTo(info.name) : -1;
168
					if (comp == 0)
168
					//special handling for linked resources
169
					if (!target.isLinked()) {
170
						// a flatten folder can only contain linked resources
171
						child = createNode(target, null, null, true);
172
						workspaceIndex++;
173
					} else if (!target.isFloating()) {
174
						child = createChildForLinkedResource(target);
175
						workspaceIndex++;
176
						//if there is a matching local file (a floating linked resource), skip it - it will be blocked by the linked resource
177
						if (comp == 0)
178
							localIndex++;
179
					} else if (comp == 0) {
180
						// resource exists in workspace and file system --> localInfo is non-null
181
						child = createNode(target, info.store, info.info, true);
182
						localIndex++;
183
						workspaceIndex++;
184
					} else if (comp > 0) {
185
						// resource exists only in file system
186
						//don't create a node for symbolic links that create a cycle
187
						child = createNewFloatingLinkedResourceNode(project, node, info);
169
						localIndex++;
188
						localIndex++;
170
				} else if (comp == 0) {
189
					} else {
171
					// resource exists in workspace and file system --> localInfo is non-null
190
						// resource exists only in the workspace
172
					//create workspace-only node for symbolic link that creates a cycle
173
					if (localInfo.getAttribute(EFS.ATTRIBUTE_SYMLINK) && localInfo.isDirectory() && isRecursiveLink(node.getStore(), localInfo))
174
						child = createNode(target, null, null, true);
191
						child = createNode(target, null, null, true);
175
					else
192
						workspaceIndex++;
176
						child = createNode(target, null, localInfo, true);
193
					}
177
					localIndex++;
194
					if (child != null)
178
					workspaceIndex++;
195
						addChildToTree(node, child);
179
				} else if (comp > 0) {
180
					// resource exists only in file system
181
					//don't create a node for symbolic links that create a cycle
182
					if (localInfo.getAttribute(EFS.ATTRIBUTE_SYMLINK) && localInfo.isDirectory() && isRecursiveLink(node.getStore(), localInfo))
183
						child = null;
184
					else
185
						child = createChildNodeFromFileSystem(node, localInfo);
186
					localIndex++;
187
				} else {
188
					// resource exists only in the workspace
189
					child = createNode(target, null, null, true);
190
					workspaceIndex++;
191
				}
196
				}
192
				if (child != null)
197
				/* process any remaining resource from the file system */
193
					addChildToTree(node, child);
198
				addChildrenFromFileSystem(project, node, uniqueList, localIndex);
194
			}
199
			}
195
		}
196
200
197
		/* process any remaining resource from the file system */
201
			/* Mark the children as now known */
198
		addChildrenFromFileSystem(node, list, localIndex);
202
			if (unknown) {
203
				// Don't open the info - we might not be inside a workspace-modifying operation
204
				resourceInfo = parent.getResourceInfo(false, false);
205
				if (resourceInfo != null)
206
					resourceInfo.clear(ICoreConstants.M_CHILDREN_UNKNOWN);
207
			}
208
		} else {
209
			// get the list of resources in the file system
210
			// don't ask for local children if we know it doesn't exist locally
211
			IFileInfo[] list = node.existsInFileSystem() ? getLocalList(node) : NO_CHILDREN;
212
			int localIndex = 0;
213
214
			// See if the children of this resource have been computed before
215
			ResourceInfo resourceInfo = parent.getResourceInfo(false, false);
216
			int flags = parent.getFlags(resourceInfo);
217
			boolean unknown = ResourceInfo.isSet(flags, ICoreConstants.M_CHILDREN_UNKNOWN);
218
219
			// get the list of resources in the workspace
220
			if (!unknown && (parentType == IResource.FOLDER || parentType == IResource.PROJECT) && parent.exists(flags, true)) {
221
				IResource target = null;
222
				UnifiedTreeNode child = null;
223
				IResource[] members;
224
				try {
225
					members = ((IContainer) parent).members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS | IContainer.INCLUDE_HIDDEN);
226
				} catch (CoreException e) {
227
					members = NO_RESOURCES;
228
				}
229
				int workspaceIndex = 0;
230
				//iterate simultaneously over file system and workspace members
231
				while (workspaceIndex < members.length) {
232
					target = members[workspaceIndex];
233
					String name = target.getName();
234
					IFileInfo localInfo = localIndex < list.length ? list[localIndex] : null;
235
					int comp = localInfo != null ? name.compareTo(localInfo.getName()) : -1;
236
					//special handling for linked resources
237
					if (target.isFloating()) {
238
						// remove all floating resources
239
						child = createNode(target, null, null, true);
240
						workspaceIndex++;
241
					} else if (target.isLinked()) {
242
						//child will be null if location is undefined
243
						child = createChildForLinkedResource(target);
244
						workspaceIndex++;
245
						//if there is a matching local file, skip it - it will be blocked by the linked resource
246
						if (comp == 0)
247
							localIndex++;
248
					} else if (comp == 0) {
249
						// resource exists in workspace and file system --> localInfo is non-null
250
						//create workspace-only node for symbolic link that creates a cycle
251
						if (localInfo.getAttribute(EFS.ATTRIBUTE_SYMLINK) && localInfo.isDirectory() && isRecursiveLink(node.getStore(), localInfo))
252
							child = createNode(target, null, null, true);
253
						else
254
							child = createNode(target, null, localInfo, true);
255
						localIndex++;
256
						workspaceIndex++;
257
					} else if (comp > 0) {
258
						// resource exists only in file system
259
						//don't create a node for symbolic links that create a cycle
260
						if (localInfo.getAttribute(EFS.ATTRIBUTE_SYMLINK) && localInfo.isDirectory() && isRecursiveLink(node.getStore(), localInfo))
261
							child = null;
262
						else
263
							child = createChildNodeFromFileSystem(node, localInfo);
264
						localIndex++;
265
					} else {
266
						// resource exists only in the workspace
267
						child = createNode(target, null, null, true);
268
						workspaceIndex++;
269
					}
270
					if (child != null)
271
						addChildToTree(node, child);
272
				}
273
			}
274
			/* process any remaining resource from the file system */
275
			addChildrenFromFileSystem(node, list, localIndex);
199
276
200
		/* Mark the children as now known */
277
			/* Mark the children as now known */
201
		if (unknown) {
278
			if (unknown) {
202
			// Don't open the info - we might not be inside a workspace-modifying operation
279
				// Don't open the info - we might not be inside a workspace-modifying operation
203
			resourceInfo = parent.getResourceInfo(false, false);
280
				resourceInfo = parent.getResourceInfo(false, false);
204
			if (resourceInfo != null)
281
				if (resourceInfo != null)
205
				resourceInfo.clear(ICoreConstants.M_CHILDREN_UNKNOWN);
282
					resourceInfo.clear(ICoreConstants.M_CHILDREN_UNKNOWN);
283
			}
206
		}
284
		}
207
285
208
		/* if we added children, add the childMarker separator */
286
		/* if we added children, add the childMarker separator */
Lines 210-215 Link Here
210
			addChildrenMarker();
288
			addChildrenMarker();
211
	}
289
	}
212
290
291
	private static class UniqueFileStoreName {
292
		public UniqueFileStoreName(String name, IFileStore store, IFileInfo info) {
293
			this.name = name;
294
			this.store = store;
295
			this.info = info;
296
		}
297
298
		public String name;
299
		public IFileStore store;
300
		public IFileInfo info;
301
	}
302
303
	// The names are suffixed with the directory in which they belong, if there's a conflict.
304
	// For instance, if two files (foo/bar.txt and folder/bar.txt) shared the same name, the second
305
	// file will have its immediate parent appended as follows: "bar.txt (folder)".
306
	// if multiple files share the same name, the parent directory names are appended with a "-" 
307
	// delimiter, as follows: "bar.txt (root-folder)" since the "/" delimiter isn't a valid name
308
	// character.
309
	private UniqueFileStoreName[] generateUniqueList(IFileStore[] list) {
310
		// the list is already sorted by name, so identical named items are consecutives
311
		UniqueFileStoreName[] uniqueList = new UniqueFileStoreName[list.length];
312
		boolean changed = false;
313
		uniqueList[0] = new UniqueFileStoreName(list[0].getName(), list[0], list[0].fetchInfo());
314
		for (int i = 1; i < list.length; i++) {
315
			String name = list[i].getName();
316
			if (list[i - 1].getName().equals(name)) {
317
				IFileStore parent = list[i].getParent();
318
				String suffix = parent.getName();
319
				String tentativeName = name + " (" + suffix + ")"; //$NON-NLS-1$ //$NON-NLS-2$
320
				while (nameExistsInList(tentativeName, uniqueList, list, i - 1)) {
321
					parent = parent.getParent();
322
					suffix = parent.getName() + ' ' + suffix;
323
					tentativeName = name + " (" + suffix + ")"; //$NON-NLS-1$ //$NON-NLS-2$
324
				}
325
				name = tentativeName;
326
				changed = true;
327
			}
328
			uniqueList[i] = new UniqueFileStoreName(name, list[i], list[i].fetchInfo());
329
		}
330
		if (changed) {
331
			Arrays.sort(uniqueList, new Comparator() {
332
				public int compare(Object arg0, Object arg1) {
333
					UniqueFileStoreName a = (UniqueFileStoreName) arg0;
334
					UniqueFileStoreName b = (UniqueFileStoreName) arg1;
335
					return a.name.compareTo(b.name);
336
				}
337
			});
338
		}
339
		return uniqueList;
340
	}
341
342
	private boolean nameExistsInList(String tentativeName, UniqueFileStoreName[] uniqueList, IFileStore[] list, int i) {
343
		while (i >= 0 && list[i].getName().equals(list[i + 1].getName())) {
344
			if (uniqueList[i].name.equals(tentativeName))
345
				return true;
346
			i--;
347
		}
348
		return false;
349
	}
350
213
	protected void addChildrenFromFileSystem(UnifiedTreeNode node, IFileInfo[] childInfos, int index) {
351
	protected void addChildrenFromFileSystem(UnifiedTreeNode node, IFileInfo[] childInfos, int index) {
214
		if (childInfos == null)
352
		if (childInfos == null)
215
			return;
353
			return;
Lines 221-226 Link Here
221
		}
359
		}
222
	}
360
	}
223
361
362
	protected void addChildrenFromFileSystem(Project project, UnifiedTreeNode node, UniqueFileStoreName[] elements, int index) {
363
		if (elements == null)
364
			return;
365
		for (int i = index; i < elements.length; i++) {
366
			UnifiedTreeNode child = createNewFloatingLinkedResourceNode(project, node, elements[i]);
367
			addChildToTree(node, child);
368
		}
369
	}
370
371
	private UnifiedTreeNode createNewFloatingLinkedResourceNode(Project project, UnifiedTreeNode node, UniqueFileStoreName element) {
372
		UnifiedTreeNode child = createChildNodeFromFileSystem(node, element);
373
		child.setFlagMasks(ICoreConstants.M_LINK | ICoreConstants.M_FLOATING);
374
		return child;
375
	}
376
224
	protected void addChildrenMarker() {
377
	protected void addChildrenMarker() {
225
		addElementToQueue(childrenMarker);
378
		addElementToQueue(childrenMarker);
226
	}
379
	}
Lines 283-288 Link Here
283
	}
436
	}
284
437
285
	/**
438
	/**
439
	 * Creates a child node for a location in the file system. Does nothing and returns null if the location does not correspond to a valid file/folder.
440
	 */
441
	protected UnifiedTreeNode createChildNodeFromFileSystem(UnifiedTreeNode parent, UniqueFileStoreName element) {
442
		IPath childPath = parent.getResource().getFullPath().append(element.name);
443
		int type = element.info.isDirectory() ? IResource.FOLDER : IResource.FILE;
444
		IResource target = getWorkspace().newResource(childPath, type);
445
		return createNode(target, element.store, element.info, false);
446
	}
447
448
	/**
286
	 * Factory method for creating a node for this tree.  If the file exists on
449
	 * Factory method for creating a node for this tree.  If the file exists on
287
	 * disk, either the parent store or child store can be provided. Providing
450
	 * disk, either the parent store or child store can be provided. Providing
288
	 * only the parent store avoids creation of the child store in cases where
451
	 * only the parent store avoids creation of the child store in cases where
Lines 335-347 Link Here
335
		return level;
498
		return level;
336
	}
499
	}
337
500
501
	protected IFileStore[] getLocalFlattenList(UnifiedTreeNode node) {
502
		try {
503
			final IFileStore store = node.getStore();
504
			IFileStore[] list = fileTree != null ? fileTree.getChildStores(store) : store.childStores(EFS.NONE, null);
505
			if (list == null || list.length == 0)
506
				return new IFileStore[0];
507
			list = (IFileStore[]) ((Resource) node.getResource()).filterChildren(list, false);
508
509
			// flatten the directory structure
510
			ArrayList finalList = new ArrayList();
511
			Stack foldersToFlatten = new Stack();
512
			for (int i = 0; i < list.length; i++) {
513
				if (list[i].fetchInfo().isDirectory())
514
					foldersToFlatten.push(list[i]);
515
				else
516
					finalList.add(list[i]);
517
			}
518
			while (!foldersToFlatten.isEmpty()) {
519
				IFileStore folder = (IFileStore) foldersToFlatten.pop();
520
				IFileStore[] children = fileTree != null ? fileTree.getChildStores(folder) : folder.childStores(EFS.NONE, null);
521
				children = (IFileStore[]) ((Resource) node.getResource()).filterChildren(children, false);
522
				for (int i = 0; i < children.length; i++) {
523
					if (children[i].fetchInfo().isDirectory())
524
						foldersToFlatten.push(children[i]);
525
					else
526
						finalList.add(children[i]);
527
				}
528
			}
529
530
			IFileStore[] uriList = (IFileStore[]) finalList.toArray(new IFileStore[0]);
531
			Arrays.sort(uriList, new Comparator() {
532
				public int compare(Object arg0, Object arg1) {
533
					IFileStore a = (IFileStore) arg0;
534
					IFileStore b = (IFileStore) arg1;
535
					return a.getName().compareTo(b.getName());
536
				}
537
			});
538
			return uriList;
539
		} catch (CoreException e) {
540
			//treat failure to access the directory as a non-existent directory
541
			return new IFileStore[0];
542
		}
543
	}
544
338
	protected IFileInfo[] getLocalList(UnifiedTreeNode node) {
545
	protected IFileInfo[] getLocalList(UnifiedTreeNode node) {
339
		try {
546
		try {
340
			final IFileStore store = node.getStore();
547
			final IFileStore store = node.getStore();
341
			IFileInfo[] list = fileTree != null ? fileTree.getChildInfos(store) : store.childInfos(EFS.NONE, null);
548
			IFileInfo[] list = fileTree != null ? fileTree.getChildInfos(store) : store.childInfos(EFS.NONE, null);
342
			if (list == null || list.length == 0)
549
			if (list == null || list.length == 0)
343
				return NO_CHILDREN;
550
				return NO_CHILDREN;
344
			list = ((Resource) node.getResource()).filterChildren(list, false);
551
			list = (IFileInfo[]) ((Resource) node.getResource()).filterChildren(list, false);
345
			int size = list.length;
552
			int size = list.length;
346
			if (size > 1)
553
			if (size > 1)
347
				quickSort(list, 0, size - 1);
554
				quickSort(list, 0, size - 1);
(-)src/org/eclipse/core/internal/localstore/UnifiedTreeNode.java (+9 lines)
Lines 28-33 Link Here
28
	protected IResource resource;
28
	protected IResource resource;
29
	protected IFileStore store;
29
	protected IFileStore store;
30
	protected UnifiedTree tree;
30
	protected UnifiedTree tree;
31
	protected int flags = 0;
31
32
32
	public UnifiedTreeNode(UnifiedTree tree, IResource resource, IFileStore store, IFileInfo fileInfo, boolean existsWorkspace) {
33
	public UnifiedTreeNode(UnifiedTree tree, IResource resource, IFileStore store, IFileInfo fileInfo, boolean existsWorkspace) {
33
		this.tree = tree;
34
		this.tree = tree;
Lines 60-65 Link Here
60
		return fileInfo == null ? 0 : fileInfo.getLastModified();
61
		return fileInfo == null ? 0 : fileInfo.getLastModified();
61
	}
62
	}
62
63
64
	public int getFlagMasks() {
65
		return flags;
66
	}
67
	
63
	public int getLevel() {
68
	public int getLevel() {
64
		return tree.getLevel();
69
		return tree.getLevel();
65
	}
70
	}
Lines 129-134 Link Here
129
		this.child = child;
134
		this.child = child;
130
	}
135
	}
131
136
137
	public void setFlagMasks(int flags) {
138
		this.flags = flags;
139
	}
140
	
132
	public void setResource(IResource resource) {
141
	public void setResource(IResource resource) {
133
		this.resource = resource;
142
		this.resource = resource;
134
	}
143
	}
(-)src/org/eclipse/core/internal/resources/Filter.java (-15 / +50 lines)
Lines 11-16 Link Here
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.core.internal.resources;
12
package org.eclipse.core.internal.resources;
13
13
14
import org.eclipse.core.filesystem.IFileStore;
15
14
import org.eclipse.core.internal.utils.Policy;
16
import org.eclipse.core.internal.utils.Policy;
15
17
16
import java.util.Iterator;
18
import java.util.Iterator;
Lines 86-103 Link Here
86
		return (getType() & IResourceFilterDescription.FILES) != 0;
88
		return (getType() & IResourceFilterDescription.FILES) != 0;
87
	}
89
	}
88
90
89
	public static IFileInfo[] filter(IProject project, LinkedList/*Filter*/includeFilters, LinkedList/*Filter*/excludeFilters, IContainer parent, IFileInfo[] list) throws CoreException {
91
	interface IFileInfoAccessor
90
		IFileInfo[] result = filterIncludes(project, includeFilters, parent, list);
92
	{
91
		return filterExcludes(project, excludeFilters, parent, result);
93
		IFileInfo get(Object obj);
94
		Object[] newArray(int length);
95
	}
96
	
97
	static class FileInfoAccessor implements IFileInfoAccessor {
98
		public IFileInfo get(Object obj) {
99
			return (IFileInfo) obj;
100
		}
101
102
		public Object[] newArray(int length) {
103
			return new IFileInfo[length];
104
		}
105
	}
106
107
	static class FileStoreAccessor implements IFileInfoAccessor {
108
		public IFileInfo get(Object obj) {
109
			return ((IFileStore) obj).fetchInfo();
110
		}
111
112
		public Object[] newArray(int length) {
113
			return new IFileStore[length];
114
		}
115
	}
116
117
	public static Object[] filter(IProject project, LinkedList/*Filter*/includeFilters, LinkedList/*Filter*/excludeFilters, IContainer parent, Object[] list) throws CoreException {
118
119
		IFileInfoAccessor accessor;
120
		if (list[0] instanceof IFileInfo)
121
			accessor = new FileInfoAccessor();
122
		else
123
			accessor = new FileStoreAccessor();
124
125
		Object[] result = filterIncludes(project, includeFilters, parent, list, accessor);
126
		return filterExcludes(project, excludeFilters, parent, result, accessor);
92
	}
127
	}
93
128
94
	public static IFileInfo[] filterIncludes(IProject project, LinkedList/*Filter*/filters, IContainer parent, IFileInfo[] list) throws CoreException {
129
	public static Object[] filterIncludes(IProject project, LinkedList/*Filter*/filters, IContainer parent, Object[] list, IFileInfoAccessor accessor) throws CoreException {
95
		if (filters.size() > 0) {
130
		if (filters.size() > 0) {
96
			IFileInfo[] result = new IFileInfo[list.length];
131
			Object[] result = accessor.newArray(list.length);
97
			int outputIndex = 0;
132
			int outputIndex = 0;
98
133
				
99
			for (int i = 0; i < list.length; i++) {
134
			for (int i = 0; i < list.length; i++) {
100
				IFileInfo info = list[i];
135
				IFileInfo info = accessor.get(list[i]);
101
				Iterator objIt = filters.iterator();
136
				Iterator objIt = filters.iterator();
102
				boolean filtersWereApplicable = false;
137
				boolean filtersWereApplicable = false;
103
				while (objIt.hasNext()) {
138
				while (objIt.hasNext()) {
Lines 105-120 Link Here
105
					if (filter.appliesTo(info)) {
140
					if (filter.appliesTo(info)) {
106
						filtersWereApplicable = true;
141
						filtersWereApplicable = true;
107
						if (filter.match(parent, info)) {
142
						if (filter.match(parent, info)) {
108
							result[outputIndex++] = info;
143
							result[outputIndex++] = list[i];
109
							break;
144
							break;
110
						}
145
						}
111
					}
146
					}
112
				}
147
				}
113
				if (!filtersWereApplicable)
148
				if (!filtersWereApplicable)
114
					result[outputIndex++] = info;
149
					result[outputIndex++] = list[i];
115
			}
150
			}
116
			if (outputIndex != result.length) {
151
			if (outputIndex != result.length) {
117
				IFileInfo[] tmp = new IFileInfo[outputIndex];
152
				Object[] tmp = accessor.newArray(outputIndex);
118
				System.arraycopy(result, 0, tmp, 0, outputIndex);
153
				System.arraycopy(result, 0, tmp, 0, outputIndex);
119
				result = tmp;
154
				result = tmp;
120
			}
155
			}
Lines 123-135 Link Here
123
		return list;
158
		return list;
124
	}
159
	}
125
160
126
	public static IFileInfo[] filterExcludes(IProject project, LinkedList/*Filter*/filters, IContainer parent, IFileInfo[] list) throws CoreException {
161
	public static Object[] filterExcludes(IProject project, LinkedList/*Filter*/filters, IContainer parent, Object[] list, IFileInfoAccessor accessor) throws CoreException {
127
		if (filters.size() > 0) {
162
		if (filters.size() > 0) {
128
			IFileInfo[] result = new IFileInfo[list.length];
163
			Object[] result = accessor.newArray(list.length);
129
			int outputIndex = 0;
164
			int outputIndex = 0;
130
165
131
			for (int i = 0; i < list.length; i++) {
166
			for (int i = 0; i < list.length; i++) {
132
				IFileInfo info = list[i];
167
				IFileInfo info = accessor.get(list[i]);
133
				Iterator objIt = filters.iterator();
168
				Iterator objIt = filters.iterator();
134
				boolean shouldBeExcluded = false;
169
				boolean shouldBeExcluded = false;
135
				while (objIt.hasNext()) {
170
				while (objIt.hasNext()) {
Lines 142-151 Link Here
142
					}
177
					}
143
				}
178
				}
144
				if (!shouldBeExcluded)
179
				if (!shouldBeExcluded)
145
					result[outputIndex++] = info;
180
					result[outputIndex++] = list[i];
146
			}
181
			}
147
			if (outputIndex != result.length) {
182
			if (outputIndex != result.length) {
148
				IFileInfo[] tmp = new IFileInfo[outputIndex];
183
				Object[] tmp = accessor.newArray(outputIndex);
149
				System.arraycopy(result, 0, tmp, 0, outputIndex);
184
				System.arraycopy(result, 0, tmp, 0, outputIndex);
150
				result = tmp;
185
				result = tmp;
151
			}
186
			}
(-)src/org/eclipse/core/internal/resources/ICoreConstants.java (+10 lines)
Lines 64-69 Link Here
64
	 */
64
	 */
65
	static final int M_VIRTUAL = 0x80000;
65
	static final int M_VIRTUAL = 0x80000;
66
	/**
66
	/**
67
	 * Marks this resource as flatten.
68
	 * @since 3.7
69
	 */
70
	static final int M_FLATTEN = 0x400000;
71
	/**
72
	 * Marks this resource as floating.
73
	 * @since 3.7
74
	 */
75
	static final int M_FLOATING = 0x800000;
76
	/**
67
	 * The file has no content description.
77
	 * The file has no content description.
68
	 * @since 3.0
78
	 * @since 3.0
69
	 */
79
	 */
(-)src/org/eclipse/core/internal/resources/LinkDescription.java (-1 / +1 lines)
Lines 79-85 Link Here
79
		return type;
79
		return type;
80
	}
80
	}
81
	
81
	
82
	public boolean isGroup() {
82
	public boolean isVirtual() {
83
		return localLocation.equals(VIRTUAL_LOCATION);
83
		return localLocation.equals(VIRTUAL_LOCATION);
84
	}
84
	}
85
85
(-)src/org/eclipse/core/internal/resources/Project.java (-1 / +1 lines)
Lines 1112-1118 Link Here
1112
				if (parent != null && !parent.exists() && parent.getType() == FOLDER)
1112
				if (parent != null && !parent.exists() && parent.getType() == FOLDER)
1113
					((Folder) parent).ensureExists(Policy.monitorFor(null));
1113
					((Folder) parent).ensureExists(Policy.monitorFor(null));
1114
				if (!toLink.exists() || !toLink.isLinked()) {
1114
				if (!toLink.exists() || !toLink.isLinked()) {
1115
					if (newLink.isGroup())
1115
					if (newLink.isVirtual())
1116
						((Folder) toLink).create(IResource.REPLACE | IResource.VIRTUAL, true, null);
1116
						((Folder) toLink).create(IResource.REPLACE | IResource.VIRTUAL, true, null);
1117
					else
1117
					else
1118
						toLink.createLink(newLink.getLocationURI(), IResource.REPLACE | IResource.ALLOW_MISSING_LOCAL, null);
1118
						toLink.createLink(newLink.getLocationURI(), IResource.REPLACE | IResource.ALLOW_MISSING_LOCAL, null);
(-)src/org/eclipse/core/internal/resources/Resource.java (-4 / +109 lines)
Lines 17-22 Link Here
17
 *******************************************************************************/
17
 *******************************************************************************/
18
package org.eclipse.core.internal.resources;
18
package org.eclipse.core.internal.resources;
19
19
20
import org.eclipse.core.internal.utils.Messages;
21
import org.eclipse.core.internal.utils.Policy;
22
import org.eclipse.core.resources.IResource;
23
import org.eclipse.core.runtime.OperationCanceledException;
24
25
import org.eclipse.core.runtime.CoreException;
26
import org.eclipse.core.runtime.IProgressMonitor;
27
20
import java.net.URI;
28
import java.net.URI;
21
import java.net.URISyntaxException;
29
import java.net.URISyntaxException;
22
import java.util.*;
30
import java.util.*;
Lines 663-672 Link Here
663
				ResourceInfo info = workspace.createResource(this, false);
671
				ResourceInfo info = workspace.createResource(this, false);
664
				if ((updateFlags & IResource.HIDDEN) != 0)
672
				if ((updateFlags & IResource.HIDDEN) != 0)
665
					info.set(M_HIDDEN);
673
					info.set(M_HIDDEN);
674
				if ((updateFlags & IResource.FLATTEN) != 0)
675
					info.set(M_FLATTEN);
676
				
666
				info.set(M_LINK);
677
				info.set(M_LINK);
667
				localLocation = FileUtil.canonicalURI(localLocation);
678
				localLocation = FileUtil.canonicalURI(localLocation);
668
				LinkDescription linkDescription = new LinkDescription(this, localLocation);
679
				LinkDescription linkDescription = new LinkDescription(this, localLocation);
669
				if (linkDescription.isGroup())
680
				if (linkDescription.isVirtual())
670
					info.set(M_VIRTUAL);
681
					info.set(M_VIRTUAL);
671
				getLocalManager().link(this, localLocation, fileInfo);
682
				getLocalManager().link(this, localLocation, fileInfo);
672
				monitor.worked(Policy.opWork * 5 / 100);
683
				monitor.worked(Policy.opWork * 5 / 100);
Lines 2064-2070 Link Here
2064
						info.setDirectory(currentResource.getType() == IResource.FOLDER);
2075
						info.setDirectory(currentResource.getType() == IResource.FOLDER);
2065
						fileInfo = info;
2076
						fileInfo = info;
2066
					}
2077
					}
2067
					IFileInfo[] filtered = parent.filterChildren(new IFileInfo[] {fileInfo}, throwExeception);
2078
					Object[] filtered = parent.filterChildren(new Object[] {fileInfo}, throwExeception);
2068
					if (filtered.length == 0)
2079
					if (filtered.length == 0)
2069
						return true;
2080
						return true;
2070
				}
2081
				}
Lines 2073-2083 Link Here
2073
		}
2084
		}
2074
		return false;
2085
		return false;
2075
	}
2086
	}
2076
	
2087
2077
	public IFileInfo[] filterChildren(IFileInfo[] list, boolean throwException) throws CoreException {
2088
	/**
2089
	 * Filter the list of file entries according to the existing resource filters
2090
	 * @param list can be either an array of IFileInfo or IFileStore
2091
	 * @param throwException
2092
	 * @return the filtered list (either an array of IFileInfo or IFileStore
2093
	 * @throws CoreException
2094
	 */
2095
	public Object[] filterChildren(Object[] list, boolean throwException) throws CoreException {
2078
		Project project = (Project) getProject();
2096
		Project project = (Project) getProject();
2079
		if (project == null)
2097
		if (project == null)
2080
			return list;
2098
			return list;
2099
		if (list.length == 0)
2100
			return list;
2081
		final ProjectDescription description = project.internalGetDescription();
2101
		final ProjectDescription description = project.internalGetDescription();
2082
		if (description == null)
2102
		if (description == null)
2083
			return list;
2103
			return list;
Lines 2181-2184 Link Here
2181
				setLinkLocation(URIUtil.toURI(location.toPortableString()), updateFlags, monitor);
2201
				setLinkLocation(URIUtil.toURI(location.toPortableString()), updateFlags, monitor);
2182
			}
2202
			}
2183
	}
2203
	}
2204
	
2205
	/*
2206
	 * (non-Javadoc)
2207
	 * 
2208
	 * @see IContainer#isFlatten()
2209
	 */
2210
	public boolean isFloating() {
2211
		ResourceInfo info = getResourceInfo(false, false);
2212
		return info != null && info.isSet(M_FLOATING);
2213
	}
2214
2215
	/*
2216
	 * Set the floating flag
2217
	 */
2218
	public void setFloating(boolean floating) {
2219
		ResourceInfo info = getResourceInfo(true, true);
2220
		if (info != null) {
2221
			if (floating)
2222
				info.isSet(M_FLOATING);
2223
			else
2224
				info.clear(M_FLOATING);
2225
		}
2226
	}
2227
2228
	/*
2229
	 * (non-Javadoc)
2230
	 * 
2231
	 * @see IContainer#isFlatten()
2232
	 */
2233
	public boolean isFlatten() {
2234
		ResourceInfo info = getResourceInfo(false, false);
2235
		return info != null && info.isSet(M_FLATTEN);
2236
	}
2237
2238
	/**
2239
	 * 
2240
	 * @exception CoreException 
2241
	 * 
2242
	 * @see #isFlatten()
2243
	 * @since 3.7
2244
	 */
2245
	public void setFlatten(boolean flatten, int updateFlags, IProgressMonitor monitor) throws CoreException {
2246
		monitor = Policy.monitorFor(monitor);
2247
		try {
2248
			String message = NLS.bind(Messages.resources_settingFlattenFlag, getFullPath());
2249
			monitor.beginTask(message, Policy.totalWork);
2250
			Policy.checkCanceled(monitor);
2251
			checkValidPath(path, FOLDER | PROJECT, true);
2252
			final ISchedulingRule rule = workspace.getRuleFactory().createRule(this);
2253
			try {
2254
				workspace.prepareOperation(rule, monitor);
2255
				workspace.beginOperation(true);
2256
				monitor.worked(Policy.opWork * 5 / 100);
2257
				ResourceInfo info = getResourceInfo(true, true);
2258
				// ignore attempts to set flatten flag on anything except projects and folders
2259
				if (info.getType() != PROJECT && info.getType() != FOLDER)
2260
					return;				
2261
2262
				if (flatten)
2263
					info.set(ICoreConstants.M_FLATTEN);
2264
				else {
2265
					info.clear(ICoreConstants.M_FLATTEN);
2266
				}
2267
				//refresh to update resources below this container location
2268
				if (getType() != IResource.FILE) {
2269
					//refresh either in background or foreground
2270
					if ((updateFlags & IResource.BACKGROUND_REFRESH) != 0) {
2271
						workspace.refreshManager.refresh(this);
2272
						monitor.worked(Policy.opWork * 90 / 100);
2273
					} else {
2274
						refreshLocal(DEPTH_INFINITE, Policy.subMonitorFor(monitor, Policy.opWork * 90 / 100));
2275
					}
2276
				} else
2277
					monitor.worked(Policy.opWork * 90 / 100);
2278
			} catch (OperationCanceledException e) {
2279
				workspace.getWorkManager().operationCanceled();
2280
				throw e;
2281
			} finally {
2282
				workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork));
2283
			}
2284
		} finally {
2285
			monitor.done();
2286
		}
2287
	}
2288
2184
}
2289
}
(-)src/org/eclipse/core/internal/resources/Workspace.java (+4 lines)
Lines 13-18 Link Here
13
 *******************************************************************************/
13
 *******************************************************************************/
14
package org.eclipse.core.internal.resources;
14
package org.eclipse.core.internal.resources;
15
15
16
import org.eclipse.core.resources.IResource;
17
16
import java.io.IOException;
18
import java.io.IOException;
17
import java.io.InputStream;
19
import java.io.InputStream;
18
import java.net.URI;
20
import java.net.URI;
Lines 985-990 Link Here
985
			info.set(M_TEAM_PRIVATE_MEMBER);
987
			info.set(M_TEAM_PRIVATE_MEMBER);
986
		if ((updateFlags & IResource.HIDDEN) != 0)
988
		if ((updateFlags & IResource.HIDDEN) != 0)
987
			info.set(M_HIDDEN);
989
			info.set(M_HIDDEN);
990
		if ((updateFlags & IResource.FLATTEN) != 0)
991
			info.set(M_FLATTEN);
988
		//		if ((updateFlags & IResource.VIRTUAL) != 0)
992
		//		if ((updateFlags & IResource.VIRTUAL) != 0)
989
		//			info.set(M_VIRTUAL);
993
		//			info.set(M_VIRTUAL);
990
		return info;
994
		return info;
(-)src/org/eclipse/core/internal/utils/Messages.java (+1 lines)
Lines 276-281 Link Here
276
	public static String resources_settingContents;
276
	public static String resources_settingContents;
277
	public static String resources_settingDefaultCharsetContainer;
277
	public static String resources_settingDefaultCharsetContainer;
278
	public static String resources_settingDerivedFlag;
278
	public static String resources_settingDerivedFlag;
279
	public static String resources_settingFlattenFlag;
279
	public static String resources_shutdown;
280
	public static String resources_shutdown;
280
	public static String resources_shutdownProblems;
281
	public static String resources_shutdownProblems;
281
	public static String resources_snapInit;
282
	public static String resources_snapInit;
(-)src/org/eclipse/core/internal/utils/messages.properties (+1 lines)
Lines 275-280 Link Here
275
resources_settingDefaultCharsetContainer = Setting default character set for resource ''{0}''.
275
resources_settingDefaultCharsetContainer = Setting default character set for resource ''{0}''.
276
resources_settingContents = Setting contents for ''{0}''.
276
resources_settingContents = Setting contents for ''{0}''.
277
resources_settingDerivedFlag = Setting derived flag for resource ''{0}''.
277
resources_settingDerivedFlag = Setting derived flag for resource ''{0}''.
278
resources_settingFlattenFlag = Setting flatten flag for resource ''{0}''.
278
resources_shutdown = Workspace was not properly initialized or has already shutdown.
279
resources_shutdown = Workspace was not properly initialized or has already shutdown.
279
resources_shutdownProblems = Problem on shutdown.
280
resources_shutdownProblems = Problem on shutdown.
280
resources_snapInit = Could not initialize snapshot file.
281
resources_snapInit = Could not initialize snapshot file.
(-)src/org/eclipse/core/resources/IContainer.java (+18 lines)
Lines 524-527 Link Here
524
	 * @since 3.6
524
	 * @since 3.6
525
	 */
525
	 */
526
	public IResourceFilterDescription[] getFilters() throws CoreException;
526
	public IResourceFilterDescription[] getFilters() throws CoreException;
527
528
	/**
529
	 * 
530
	 * @return true if this container flattens his file system hierarchy
531
	 * 
532
	 * @see #setFlatten(boolean, int, IProgressMonitor)
533
	 * @since 3.7
534
	 */
535
	public boolean isFlatten();
536
537
	/**
538
	 * 
539
	 * @exception CoreException 
540
	 * 
541
	 * @see #isFlatten()
542
	 * @since 3.7
543
	 */
544
	public void setFlatten(boolean flatten, int updateFlags, IProgressMonitor monitor) throws CoreException;
527
}
545
}
(-)src/org/eclipse/core/resources/IResource.java (+24 lines)
Lines 291-296 Link Here
291
	 */
291
	 */
292
	public static final int VIRTUAL = 0x2000;
292
	public static final int VIRTUAL = 0x2000;
293
293
294
	/**
295
	 * Update flag constant (bit mask value 0x4000) indicating that a 
296
	 * container should flatten the underlying file system hierarchy.
297
	 * 
298
	 * @see IContainer#setFlatten(boolean, int, IProgressMonitor)
299
	 * @see IContainer#isFlatten()
300
	 * @since 3.7
301
	 */
302
	public static final int FLATTEN = 0x4000;
303
294
	/*====================================================================
304
	/*====================================================================
295
	 * Other constants:
305
	 * Other constants:
296
	 *====================================================================*/
306
	 *====================================================================*/
Lines 1735-1740 Link Here
1735
	public boolean isVirtual();
1745
	public boolean isVirtual();
1736
1746
1737
	/**
1747
	/**
1748
	 * Returns whether this resource is a floating resource. Returns <code>true</code>
1749
	 * for resources that have been generated by a flatten container refresh operation.
1750
	 * Returns <code>false</code> in all other cases, including 
1751
	 * the case where this resource does not exist.  The workspace root and projects
1752
	 * currently cannot be floating.
1753
	 * 
1754
	 * @return <code>true</code> if this resource is floating, and
1755
	 *         <code>false</code> otherwise
1756
	 * @see IContainer#setFlatten(boolean, int, IProgressMonitor)
1757
	 * @since 3.7
1758
	 */
1759
	public boolean isFloating();
1760
1761
	/**
1738
	 * Returns <code>true</code> if this resource has been linked to 
1762
	 * Returns <code>true</code> if this resource has been linked to 
1739
	 * a location other than the default location calculated by the platform. This
1763
	 * a location other than the default location calculated by the platform. This
1740
	 * location can be outside the project's content area or another location
1764
	 * location can be outside the project's content area or another location
(-)plugin.properties (+2 lines)
Lines 93-98 Link Here
93
GoToResourceAction.label = &Resource...
93
GoToResourceAction.label = &Resource...
94
DecoratorLinkedResource.label = Linked Resources
94
DecoratorLinkedResource.label = Linked Resources
95
DecoratorLinkedResource.description = Adds an icon decoration to linked resources.
95
DecoratorLinkedResource.description = Adds an icon decoration to linked resources.
96
DecoratorFloatingResource.label = Floating Resources
97
DecoratorFloatingResource.description = Adds an icon decoration to floating resources.
96
DecoratorVirtualResource.label = Virtual Folders
98
DecoratorVirtualResource.label = Virtual Folders
97
DecoratorVirtualResource.description = Shows an icon for virtual folders. 
99
DecoratorVirtualResource.description = Shows an icon for virtual folders. 
98
DecoratorSpecificContentType.label = File Icons Based On Content Analysis
100
DecoratorSpecificContentType.label = File Icons Based On Content Analysis
(-)plugin.xml (+17 lines)
Lines 376-381 Link Here
376
            lightweight="true"
376
            lightweight="true"
377
            adaptable="true"
377
            adaptable="true"
378
            location="BOTTOM_RIGHT"
378
            location="BOTTOM_RIGHT"
379
            label="%DecoratorFloatingResource.label"
380
            class="org.eclipse.ui.internal.ide.FloatingResourceDecorator"
381
            state="true"
382
            id="org.eclipse.ui.FloatingResourceDecorator">
383
         <description>
384
            %DecoratorFloatingResource.description
385
         </description>
386
         <enablement>
387
            <objectClass
388
                  name="org.eclipse.core.resources.IResource">
389
            </objectClass>
390
         </enablement>
391
      </decorator>
392
      <decorator
393
            lightweight="true"
394
            adaptable="true"
395
            location="BOTTOM_RIGHT"
379
            label="%DecoratorVirtualResource.label"
396
            label="%DecoratorVirtualResource.label"
380
            class="org.eclipse.ui.internal.ide.VirtualResourceDecorator"
397
            class="org.eclipse.ui.internal.ide.VirtualResourceDecorator"
381
            state="true"
398
            state="true"
(-)src/org/eclipse/ui/internal/ide/FloatingResourceDecorator.java (+85 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.internal.ide;
12
13
import org.eclipse.core.resources.IResource;
14
import org.eclipse.jface.resource.ImageDescriptor;
15
import org.eclipse.jface.viewers.IDecoration;
16
import org.eclipse.jface.viewers.ILabelProviderListener;
17
import org.eclipse.jface.viewers.ILightweightLabelDecorator;
18
import org.eclipse.ui.plugin.AbstractUIPlugin;
19
20
/**
21
 * A LinkedResourceDecorator decorates an element's image with a linked 
22
 * resource overlay. 
23
 * 
24
 * @since 2.1
25
 */
26
public class FloatingResourceDecorator implements ILightweightLabelDecorator {
27
    private static final ImageDescriptor FLOATING;
28
29
    static {
30
    	FLOATING = AbstractUIPlugin.imageDescriptorFromPlugin(
31
                IDEWorkbenchPlugin.IDE_WORKBENCH,
32
                "$nl$/icons/full/ovr16/floating_ovr.gif"); //$NON-NLS-1$
33
    }
34
35
    /**
36
     * Creates a new <code>LinkedResourceDecorator</code>.
37
     */
38
    public FloatingResourceDecorator() {
39
    }
40
41
    /**
42
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(ILabelProviderListener)
43
     */
44
    public void addListener(ILabelProviderListener listener) {
45
    }
46
47
    /**
48
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
49
     */
50
    public void dispose() {
51
        // no resources to dispose
52
    }
53
54
    /**
55
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
56
     */
57
    public boolean isLabelProperty(Object element, String property) {
58
        return false;
59
    }
60
61
    /**
62
     * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(ILabelProviderListener)
63
     */
64
    public void removeListener(ILabelProviderListener listener) {
65
    }
66
67
    /**
68
     * Adds the linked resource overlay if the given element is a linked
69
     * resource.
70
     * 
71
     * @param element element to decorate
72
     * @param decoration  The decoration we are adding to
73
     * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(Object, IDecoration)
74
     */
75
    public void decorate(Object element, IDecoration decoration) {
76
77
        if (element instanceof IResource == false) {
78
			return;
79
		}
80
        IResource resource = (IResource) element;
81
        if (resource.isFloating())
82
			decoration.addOverlay(FLOATING);
83
    }
84
85
}
(-)src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java (+3 lines)
Lines 613-618 Link Here
613
	public static String ResourceInfo_folder;
613
	public static String ResourceInfo_folder;
614
	public static String ResourceInfo_project;
614
	public static String ResourceInfo_project;
615
	public static String ResourceInfo_linkedFile;
615
	public static String ResourceInfo_linkedFile;
616
	public static String ResourceInfo_floatingFile;
616
	public static String ResourceInfo_linkedFolder;
617
	public static String ResourceInfo_linkedFolder;
617
	public static String ResourceInfo_virtualFolder;
618
	public static String ResourceInfo_virtualFolder;
618
	public static String ResourceInfo_unknown;
619
	public static String ResourceInfo_unknown;
Lines 622-627 Link Here
622
	public static String ResourceInfo_fileNotExist;
623
	public static String ResourceInfo_fileNotExist;
623
	public static String ResourceInfo_path;
624
	public static String ResourceInfo_path;
624
	public static String ResourceInfo_lastModified;
625
	public static String ResourceInfo_lastModified;
626
	public static String ResourceInfo_folderHierarchy;
627
	public static String ResourceInfo_flatten;
625
	public static String ResourceInfo_fileEncodingTitle;
628
	public static String ResourceInfo_fileEncodingTitle;
626
	public static String ResourceInfo_fileContentEncodingFormat;
629
	public static String ResourceInfo_fileContentEncodingFormat;
627
	public static String ResourceInfo_fileContainerEncodingFormat;
630
	public static String ResourceInfo_fileContainerEncodingFormat;
(-)src/org/eclipse/ui/internal/ide/LinkedResourceDecorator.java (-1 / +1 lines)
Lines 87-93 Link Here
87
			return;
87
			return;
88
		}
88
		}
89
        IResource resource = (IResource) element;
89
        IResource resource = (IResource) element;
90
        if (resource.isLinked() && !resource.isVirtual()) {
90
        if (resource.isLinked() && !resource.isVirtual() && !resource.isFloating()) {
91
			IFileInfo fileInfo = null;
91
			IFileInfo fileInfo = null;
92
			URI location = resource.getLocationURI();
92
			URI location = resource.getLocationURI();
93
			if (location != null) {
93
			if (location != null) {
(-)src/org/eclipse/ui/internal/ide/messages.properties (+3 lines)
Lines 570-575 Link Here
570
ResourceInfo_locked = L&ocked
570
ResourceInfo_locked = L&ocked
571
ResourceInfo_archive = Ar&chive
571
ResourceInfo_archive = Ar&chive
572
ResourceInfo_derived = Deri&ved
572
ResourceInfo_derived = Deri&ved
573
ResourceInfo_flatten = &Flatten
573
ResourceInfo_type = &Type:
574
ResourceInfo_type = &Type:
574
ResourceInfo_location = &Location:
575
ResourceInfo_location = &Location:
575
ResourceInfo_resolvedLocation = Resolved locatio&n:
576
ResourceInfo_resolvedLocation = Resolved locatio&n:
Lines 632-637 Link Here
632
ResourceInfo_folder = Folder
633
ResourceInfo_folder = Folder
633
ResourceInfo_project = Project
634
ResourceInfo_project = Project
634
ResourceInfo_linkedFile = Linked File
635
ResourceInfo_linkedFile = Linked File
636
ResourceInfo_floatingFile = Floating File
635
ResourceInfo_linkedFolder = Linked Folder
637
ResourceInfo_linkedFolder = Linked Folder
636
ResourceInfo_virtualFolder = Virtual Folder
638
ResourceInfo_virtualFolder = Virtual Folder
637
ResourceInfo_unknown = Unknown
639
ResourceInfo_unknown = Unknown
Lines 642-647 Link Here
642
ResourceInfo_fileNotExist = {0} - (does not exist)
644
ResourceInfo_fileNotExist = {0} - (does not exist)
643
ResourceInfo_path = &Path:
645
ResourceInfo_path = &Path:
644
ResourceInfo_lastModified = Last &modified:
646
ResourceInfo_lastModified = Last &modified:
647
ResourceInfo_folderHierarchy = Folder hierarchy:
645
ResourceInfo_fileEncodingTitle = Default encoding for &text files
648
ResourceInfo_fileEncodingTitle = Default encoding for &text files
646
ResourceInfo_fileContentEncodingFormat = &Default (determined from content: {0})
649
ResourceInfo_fileContentEncodingFormat = &Default (determined from content: {0})
647
ResourceInfo_fileContainerEncodingFormat = Default (&inherited from container: {0})
650
ResourceInfo_fileContainerEncodingFormat = Default (&inherited from container: {0})
(-)src/org/eclipse/ui/internal/ide/dialogs/IDEResourceInfoUtils.java (+5 lines)
Lines 60-65 Link Here
60
	private static String FOLDER_LABEL = IDEWorkbenchMessages.ResourceInfo_folder;
60
	private static String FOLDER_LABEL = IDEWorkbenchMessages.ResourceInfo_folder;
61
61
62
	private static String LINKED_FILE_LABEL = IDEWorkbenchMessages.ResourceInfo_linkedFile;
62
	private static String LINKED_FILE_LABEL = IDEWorkbenchMessages.ResourceInfo_linkedFile;
63
	
64
	private static String FLOATING_FILE_LABEL = IDEWorkbenchMessages.ResourceInfo_floatingFile;
63
65
64
	private static String LINKED_FOLDER_LABEL = IDEWorkbenchMessages.ResourceInfo_linkedFolder;
66
	private static String LINKED_FOLDER_LABEL = IDEWorkbenchMessages.ResourceInfo_linkedFolder;
65
67
Lines 351-356 Link Here
351
			IContentDescription description) {
353
			IContentDescription description) {
352
354
353
		if (resource.getType() == IResource.FILE) {
355
		if (resource.getType() == IResource.FILE) {
356
			if (resource.isFloating()) {
357
				return FLOATING_FILE_LABEL;
358
			}
354
			if (resource.isLinked()) {
359
			if (resource.isLinked()) {
355
				return LINKED_FILE_LABEL;
360
				return LINKED_FILE_LABEL;
356
			}
361
			}
(-)src/org/eclipse/ui/internal/ide/dialogs/ResourceInfoPage.java (-20 / +55 lines)
Lines 67-72 Link Here
67
 */
67
 */
68
public class ResourceInfoPage extends PropertyPage {
68
public class ResourceInfoPage extends PropertyPage {
69
69
70
	private Button flattenBox;
71
70
	private Button editableBox;
72
	private Button editableBox;
71
73
72
	private Button executableBox;
74
	private Button executableBox;
Lines 86-91 Link Here
86
	private boolean previousArchiveValue;
88
	private boolean previousArchiveValue;
87
89
88
	private boolean previousDerivedValue;
90
	private boolean previousDerivedValue;
91
	
92
	private boolean previousFlattenValue;
89
93
90
	private int previousPermissionsValue;
94
	private int previousPermissionsValue;
91
95
Lines 104-110 Link Here
104
	private static String ARCHIVE = IDEWorkbenchMessages.ResourceInfo_archive;
108
	private static String ARCHIVE = IDEWorkbenchMessages.ResourceInfo_archive;
105
109
106
	private static String DERIVED = IDEWorkbenchMessages.ResourceInfo_derived;
110
	private static String DERIVED = IDEWorkbenchMessages.ResourceInfo_derived;
107
111
	
108
	private static String TYPE_TITLE = IDEWorkbenchMessages.ResourceInfo_type;
112
	private static String TYPE_TITLE = IDEWorkbenchMessages.ResourceInfo_type;
109
113
110
	private static String LOCATION_TITLE = IDEWorkbenchMessages.ResourceInfo_location;
114
	private static String LOCATION_TITLE = IDEWorkbenchMessages.ResourceInfo_location;
Lines 116-121 Link Here
116
	private static String PATH_TITLE = IDEWorkbenchMessages.ResourceInfo_path;
120
	private static String PATH_TITLE = IDEWorkbenchMessages.ResourceInfo_path;
117
121
118
	private static String TIMESTAMP_TITLE = IDEWorkbenchMessages.ResourceInfo_lastModified;
122
	private static String TIMESTAMP_TITLE = IDEWorkbenchMessages.ResourceInfo_lastModified;
123
	
124
	private static String FOLDER_HIERARCHY_TITLE = IDEWorkbenchMessages.ResourceInfo_folderHierarchy;
125
126
	private static String FLATTEN = IDEWorkbenchMessages.ResourceInfo_flatten;
119
127
120
	private static String FILE_ENCODING_TITLE = IDEWorkbenchMessages.WorkbenchPreference_encoding;
128
	private static String FILE_ENCODING_TITLE = IDEWorkbenchMessages.WorkbenchPreference_encoding;
121
129
Lines 196-202 Link Here
196
			Composite locationComposite = new Composite(basicInfoComposite,
204
			Composite locationComposite = new Composite(basicInfoComposite,
197
					SWT.NULL);
205
					SWT.NULL);
198
			layout = new GridLayout();
206
			layout = new GridLayout();
199
			layout.numColumns = 2;
207
			layout.numColumns = resource.isFloating() ? 1:2;
200
			layout.marginWidth = 0;
208
			layout.marginWidth = 0;
201
			layout.marginHeight = 0;
209
			layout.marginHeight = 0;
202
			locationComposite.setLayout(layout);
210
			locationComposite.setLayout(layout);
Lines 221-244 Link Here
221
			locationValue.setBackground(locationValue.getDisplay().getSystemColor(
229
			locationValue.setBackground(locationValue.getDisplay().getSystemColor(
222
					SWT.COLOR_WIDGET_BACKGROUND));
230
					SWT.COLOR_WIDGET_BACKGROUND));
223
231
224
			Button editButton = new Button(locationComposite, SWT.PUSH);
232
			if (!resource.isFloating()) {
225
			editButton.setText(EDIT_TITLE);
233
				Button editButton = new Button(locationComposite, SWT.PUSH);
226
			setButtonLayoutData(editButton);
234
				editButton.setText(EDIT_TITLE);
227
			((GridData) editButton.getLayoutData()).verticalAlignment = SWT.TOP;
235
				setButtonLayoutData(editButton);
228
			int locationValueHeight = locationValue.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
236
				((GridData) editButton.getLayoutData()).verticalAlignment = SWT.TOP;
229
			int editButtonHeight = editButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
237
				int locationValueHeight = locationValue.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
230
			int verticalIndent = (editButtonHeight - locationValueHeight) / 2 ;
238
				int editButtonHeight = editButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
231
			((GridData) locationTitle.getLayoutData()).verticalIndent = verticalIndent;
239
				int verticalIndent = (editButtonHeight - locationValueHeight) / 2 ;
232
			((GridData) locationValue.getLayoutData()).verticalIndent = verticalIndent;
240
				((GridData) locationTitle.getLayoutData()).verticalIndent = verticalIndent;
233
			editButton.addSelectionListener(new SelectionListener() {
241
				((GridData) locationValue.getLayoutData()).verticalIndent = verticalIndent;
234
				public void widgetDefaultSelected(SelectionEvent e) {
242
				editButton.addSelectionListener(new SelectionListener() {
235
					editLinkLocation();
243
					public void widgetDefaultSelected(SelectionEvent e) {
236
				}
244
						editLinkLocation();
237
245
					}
238
				public void widgetSelected(SelectionEvent e) {
246
	
239
					editLinkLocation();
247
					public void widgetSelected(SelectionEvent e) {
240
				}
248
						editLinkLocation();
241
			});
249
					}
250
				});
251
			}
242
252
243
			// displayed in all cases since the link can be changed to a path variable any time by the user in this dialog
253
			// displayed in all cases since the link can be changed to a path variable any time by the user in this dialog
244
			Label resolvedLocationTitle = new Label(basicInfoComposite,
254
			Label resolvedLocationTitle = new Label(basicInfoComposite,
Lines 311-316 Link Here
311
		timeStampValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
321
		timeStampValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
312
				| GridData.GRAB_HORIZONTAL));
322
				| GridData.GRAB_HORIZONTAL));
313
323
324
		if (resource instanceof IContainer)
325
		{
326
			Label folderHierarchyLabel = new Label(basicInfoComposite, SWT.NONE);
327
			folderHierarchyLabel.setText(FOLDER_HIERARCHY_TITLE);
328
			
329
			flattenBox = new Button(basicInfoComposite, SWT.CHECK | SWT.RIGHT);
330
			flattenBox.setAlignment(SWT.LEFT);
331
			flattenBox.setText(FLATTEN);
332
			previousFlattenValue = ((IContainer) resource).isFlatten();
333
			flattenBox.setSelection(previousFlattenValue);
334
		}
335
314
		return basicInfoComposite;
336
		return basicInfoComposite;
315
	}
337
	}
316
338
Lines 899-904 Link Here
899
			this.derivedBox.setSelection(false);
921
			this.derivedBox.setSelection(false);
900
		}
922
		}
901
923
924
		if (this.flattenBox != null) {
925
			this.flattenBox.setSelection(false);
926
		}
927
		
902
		if (permissionBoxes != null) {
928
		if (permissionBoxes != null) {
903
			int defaultPermissionValues = getDefaulPermissions(resource.getType() == IResource.FOLDER);
929
			int defaultPermissionValues = getDefaulPermissions(resource.getType() == IResource.FOLDER);
904
			setPermissionsSelection(defaultPermissionValues);
930
			setPermissionsSelection(defaultPermissionValues);
Lines 1000-1005 Link Here
1000
					derivedBox.setSelection(isDerived);
1026
					derivedBox.setSelection(isDerived);
1001
				}
1027
				}
1002
			}
1028
			}
1029
			if (this.flattenBox != null) {
1030
				boolean localFlattenValue = flattenBox.getSelection();
1031
				if (previousFlattenValue != localFlattenValue) {
1032
					((IContainer)resource).setFlatten(localFlattenValue, 0, null);
1033
					boolean isFlatten = ((IContainer)resource).isFlatten();
1034
					previousFlattenValue = isFlatten;
1035
					flattenBox.setSelection(isFlatten);
1036
				}
1037
			}
1003
		} catch (CoreException exception) {
1038
		} catch (CoreException exception) {
1004
			ErrorDialog.openError(getShell(),
1039
			ErrorDialog.openError(getShell(),
1005
					IDEWorkbenchMessages.InternalError, exception
1040
					IDEWorkbenchMessages.InternalError, exception

Return to bug 313691