Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2011-11-23 18:24:49 -0500
committerEugene Tarassov2011-11-23 18:24:49 -0500
commit27b84ebeab98e6691948bf8a3b5133920dd9d630 (patch)
treec677afe121ac4cb92293a163d86b7c6d9638f23e
parent2c8acaed11adfac26081501f8e5f7f52c773b798 (diff)
parentcb68d5435bb883fdaf8a0603e8a534263d686596 (diff)
downloadorg.eclipse.tcf-27b84ebeab98e6691948bf8a3b5133920dd9d630.tar.gz
org.eclipse.tcf-27b84ebeab98e6691948bf8a3b5133920dd9d630.tar.xz
org.eclipse.tcf-27b84ebeab98e6691948bf8a3b5133920dd9d630.zip
Merge branch 'juno-refactoring' of ssh://git.eclipse.org/gitroot/tcf/org.eclipse.tcf into juno-refactoring
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.core/META-INF/MANIFEST.MF1
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.core/plugin.xml12
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java102
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/PropertyTester.java60
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java2
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties2
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ContainerModelNode.java27
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ModelNode.java11
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/interfaces/properties/IPropertiesContainer.java7
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/properties/PropertiesContainer.java9
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj16/error.gifbin0 -> 354 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj32/delete_readonly.pngbin0 -> 367 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj32/replace_confirm.pngbin0 -> 847 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/ovr/ovr_cut.pngbin0 -> 83 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.properties17
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.xml899
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/activator/UIPlugin.java47
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSCellConfigurator.java86
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java12
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeControl.java27
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeLabelProvider.java22
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/dialogs/FSFolderSelectionDialog.java151
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/ImageConsts.java36
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilter.java20
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilterFactory.java2
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellListener.java92
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellModifier.java88
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellValidator.java83
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeEditorInput.java10
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeInput.java3
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragAdapterAssistant.java91
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragSourceListener.java98
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropAdapterAssistant.java97
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropTargetListener.java78
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CacheManager.java21
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/ClipboardPropertyTester.java65
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CopyFilesHandler.java49
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutDecorator.java46
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutFilesHandler.java50
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutImageDescriptor.java97
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/DeleteFilesHandler.java55
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/FSTreeNodePropertyTester.java36
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/MoveFilesHandler.java53
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PasteFilesHandler.java67
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PersistenceManager.java38
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RenameFilesHandler.java136
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java22
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java6
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.java82
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.properties75
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSClipboard.java90
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java220
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java277
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java212
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java679
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java132
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/PreferencesInitializer.java5
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/TargetExplorerPreferencePage.java29
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/AdvancedAttributesDialog.java19
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/GeneralInformationPage.java11
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/url/TcfURLConnection.java4
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/model/FSTreeNode.java104
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/actions/PinTerminalAction.java23
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/activator/UIPlugin.java3
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ITerminalsView.java18
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ImageConsts.java1
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/manager/ConsoleManager.java233
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/nls/Messages.java2
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/tabs/TabFolderToolbarHandler.java3
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/view/TerminalsView.java29
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml1
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/configurators.exsd135
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerConfigurator.java28
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java1
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerConfigurator.java87
75 files changed, 5157 insertions, 279 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tcf.te.core/META-INF/MANIFEST.MF
index 3c3a60530..fc52156d6 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.core/META-INF/MANIFEST.MF
+++ b/target_explorer/plugins/org.eclipse.tcf.te.core/META-INF/MANIFEST.MF
@@ -6,6 +6,7 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.tcf.te.core.activator.CoreBundleActivator
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.7.0",
+ org.eclipse.core.expressions;bundle-version="3.4.300",
org.eclipse.tcf.te.runtime;bundle-version="1.0.0",
org.eclipse.tcf.te.runtime.stepper;bundle-version="1.0.0",
org.eclipse.tcf.te.runtime.services;bundle-version="1.0.0",
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.core/plugin.xml
index 4162ecfe9..9f6bc9fc2 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.core/plugin.xml
+++ b/target_explorer/plugins/org.eclipse.tcf.te.core/plugin.xml
@@ -15,6 +15,18 @@
</factory>
</extension>
+<!-- Property tester contributions -->
+ <extension point="org.eclipse.core.expressions.propertyTesters">
+ <propertyTester
+ class="org.eclipse.tcf.te.core.adapters.PropertyTester"
+ id="org.eclipse.tcf.te.core.adapters.PropertyTester"
+ namespace="org.eclipse.tcf.te.core"
+ properties="hasAdapter,canAdaptTo"
+ type="org.eclipse.core.runtime.IAdaptable">
+ </propertyTester>
+
+ </extension>
+
<!-- Reusable core expression fragments -->
<extension point="org.eclipse.core.expressions.definitions">
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java
index 6c4bab4be..decfde327 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/ModelNodePersistableAdapter.java
@@ -10,16 +10,26 @@
package org.eclipse.tcf.te.core.adapters;
import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
import java.net.URI;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.tcf.te.core.activator.CoreBundleActivator;
+import org.eclipse.tcf.te.core.nls.Messages;
import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.runtime.persistence.PersistenceDelegateManager;
import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistable;
+import org.eclipse.tcf.te.runtime.persistence.interfaces.IPersistenceDelegate;
/**
* Model node persistable adapter implementation.
@@ -108,14 +118,98 @@ public class ModelNodePersistableAdapter implements IPersistable {
public Map<String, Object> exportFrom(Object data) throws IOException {
Assert.isNotNull(data);
- Map<String, Object> result = null;
+ // Create a new map instance that will hold the exported properties
+ Map<String, Object> result = new HashMap<String, Object>();
// Only model nodes are supported
- if (data instanceof IModelNode) {
- result = ((IModelNode)data).getProperties();
+ if (data instanceof IModelNode && !((IModelNode)data).isEmpty()) {
+ // Get a snapshot of all properties
+ Map<String, Object> properties = ((IModelNode)data).getProperties();
+ // And export the properties to the result map
+ exportFromMap(properties, result);
}
- return result;
+ // If the result map is empty, return null
+ return !result.isEmpty() ? result : null;
+ }
+
+ /**
+ * Exports the properties of a map from the given source into the given
+ * destination.
+ *
+ * @param src The map to export the properties from. Must not be <code>null</code>.
+ * @param dst The map to write the exported properties to. Must not be <code>null</code>.
+ *
+ * @throws IOException - if the operation fails.
+ */
+ @SuppressWarnings("unchecked")
+ protected void exportFromMap(Map<String, Object> src, Map<String, Object> dst) throws IOException {
+ Assert.isNotNull(src);
+ Assert.isNotNull(dst);
+
+ // Loop all properties and check for transient or complex properties
+ for (String key : src.keySet()) {
+ if (key.contains(".transient")) continue; //$NON-NLS-1$
+
+ // Get the property value
+ Object value = src.get(key);
+
+ // If the value is null, no need to go any further
+ if (value == null) continue;
+
+ // For String, Integer, Boolean, etc ... export them as string
+ boolean isSimpleType = value instanceof String || value instanceof Boolean || value instanceof Integer || value instanceof Long
+ || value instanceof Float || value instanceof Double;
+ if (isSimpleType) {
+ dst.put(key, value.toString());
+ continue;
+ }
+
+ // BigInteger, BigDecimal ... probably needs special handling, for now, export them as string
+ boolean isBigType = value instanceof BigInteger || value instanceof BigDecimal;
+ if (isBigType) {
+ dst.put(key, value.toString());
+ continue;
+ }
+
+ // For Lists and Arrays, do a deepToString
+ boolean isListType = value instanceof List<?> || value instanceof Object[];
+ if (isListType) {
+ dst.put(key, Arrays.deepToString(value instanceof List<?> ? ((List<?>)value).toArray() : (Object[])value));
+ continue;
+ }
+
+ // For Maps, create a new destination map and call ourself
+ boolean isMapType = value instanceof Map<?,?>;
+ if (isMapType) {
+ Map<String, Object> result = new HashMap<String, Object>();
+ exportFromMap((Map<String, Object>)value, result);
+ if (!result.isEmpty()) dst.put(key, result);
+ continue;
+ }
+
+ // For anything remaining, check if the value object type can be adapted to
+ // an IPersistable itself
+ IPersistable persistable = value instanceof IAdaptable ? (IPersistable)((IAdaptable)value).getAdapter(IPersistable.class) : null;
+ if (persistable == null) persistable = (IPersistable)Platform.getAdapterManager().getAdapter(value, IPersistable.class);
+ if (persistable != null) {
+ // Create a reference object
+ Map<String, String> reference = new HashMap<String, String>();
+ reference.put("storageID", persistable.getStorageID()); //$NON-NLS-1$
+ reference.put("uri", persistable.getURI(value).toString()); //$NON-NLS-1$
+
+ IPersistenceDelegate delegate = PersistenceDelegateManager.getInstance().getDelegate(persistable.getStorageID(), false);
+ if (delegate != null) {
+ delegate.write(persistable.getURI(value), persistable.exportFrom(value));
+ dst.put(key, reference);
+ continue;
+ }
+ }
+
+ // Falling through down here is a problem. We should never end up here,
+ // because it means we have no idea on how to persist an object
+ throw new IOException(NLS.bind(Messages.ModelNodePersistableAdapter_export_unknownType, value.getClass().getCanonicalName(), key));
+ }
}
/* (non-Javadoc)
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/PropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/PropertyTester.java
new file mode 100644
index 000000000..1f6d50041
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/adapters/PropertyTester.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.core.adapters;
+
+import org.eclipse.core.runtime.IAdapterManager;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * Adapter helper property tester implementation.
+ */
+public class PropertyTester extends org.eclipse.core.expressions.PropertyTester {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ IAdapterManager manager = Platform.getAdapterManager();
+ if (manager == null) return false;
+
+ // "hasAdapter": Checks if the adapter given by the arguments is registered for the given receiver
+ if ("hasAdapter".equals(property)) { //$NON-NLS-1$
+ // The class to adapt to is within the expected value
+ String adapterType = expectedValue instanceof String ? (String)expectedValue : null;
+ if (adapterType != null) {
+ return manager.hasAdapter(receiver, adapterType);
+ }
+ }
+ if ("canAdaptTo".equals(property)) { //$NON-NLS-1$
+ // Read the arguments and look for "forceAdapterLoad"
+ boolean forceAdapterLoad = false;
+ for (Object arg : args) {
+ if (arg instanceof String && "forceAdapterLoad".equalsIgnoreCase((String)arg)) { //$NON-NLS-1$
+ forceAdapterLoad = true;
+ }
+ }
+
+ // The class to adapt to is within the expected value
+ String adapterType = expectedValue instanceof String ? (String)expectedValue : null;
+ if (adapterType != null) {
+ Object adapter = manager.getAdapter(receiver, adapterType);
+ if (adapter != null) return true;
+
+ // No adapter. This can happen too if the plug-in contributing the adapter
+ // factory hasn't been loaded yet.
+ if (forceAdapterLoad) adapter = manager.loadAdapter(receiver, adapterType);
+ if (adapter != null) return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java
index a4ae19eb1..ab4825298 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.java
@@ -34,4 +34,6 @@ public class Messages extends NLS {
public static String ConnectStrategyStepExecutor_warning_stepFailed;
public static String ConnectStrategyStepExecutor_error_stepFailed;
public static String ConnectStrategyStepExecutor_stepFailed_debugInfo;
+
+ public static String ModelNodePersistableAdapter_export_unknownType;
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties
index b727f8639..292522277 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.core/src/org/eclipse/tcf/te/core/nls/Messages.properties
@@ -17,3 +17,5 @@ Context: {1}\n\
Connect Strategy: {2}\n\
Connect Step: {3}
ConnectStrategyStepExecutor_stepFailed_debugInfo=Debug info:\n{0}
+
+ModelNodePersistableAdapter_export_unknownType=No strategy to persist an object of type ''{0}'', key = ''{1}''.
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ContainerModelNode.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ContainerModelNode.java
index b6d62466e..d9c21cc14 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ContainerModelNode.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ContainerModelNode.java
@@ -18,9 +18,9 @@ import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.tcf.te.runtime.events.EventManager;
import org.eclipse.tcf.te.runtime.model.interfaces.IContainerModelNode;
import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
-import org.eclipse.tcf.te.runtime.events.EventManager;
/**
* A common (data) model container node implementation.
@@ -212,7 +212,17 @@ public class ContainerModelNode extends ModelNode implements IContainerModelNode
*/
@Override
public int size() {
- return childList.size();
+ int size = 0;
+ try { childListLock.lock(); size = childList.size(); } finally { childListLock.unlock(); }
+ return size;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.properties.PropertiesContainer#isEmpty()
+ */
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty() && !hasChildren();
}
/* (non-Javadoc)
@@ -308,11 +318,16 @@ public class ContainerModelNode extends ModelNode implements IContainerModelNode
IModelNode find = super.find(uuid);
if (find != null) return find;
- for (IModelNode child : childList) {
- find = child.find(uuid);
- if (find != null) {
- return find;
+ try {
+ childListLock.lock();
+ for (IModelNode child : childList) {
+ find = child.find(uuid);
+ if (find != null) {
+ return find;
+ }
}
+ } finally {
+ childListLock.unlock();
}
return find;
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ModelNode.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ModelNode.java
index db93a1c54..35ea1dfbd 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ModelNode.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime.model/src/org/eclipse/tcf/te/runtime/model/ModelNode.java
@@ -137,17 +137,6 @@ public class ModelNode extends PropertiesContainer implements IModelNode, IModel
}
/* (non-Javadoc)
- * @see org.eclipse.tcf.te.runtime.nodes.PropertiesContainer#getProperty(java.lang.String)
- */
- @Override
- public Object getProperty(String key) {
- if (PROPERTY_NAME.equals(key)) {
- return getName();
- }
- return super.getProperty(key);
- }
-
- /* (non-Javadoc)
* @see org.eclipse.tcf.te.runtime.interfaces.nodes.IModelNode#getDescription()
*/
@Override
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/interfaces/properties/IPropertiesContainer.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/interfaces/properties/IPropertiesContainer.java
index be8e13cf9..139bd61ff 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/interfaces/properties/IPropertiesContainer.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/interfaces/properties/IPropertiesContainer.java
@@ -214,6 +214,13 @@ public interface IPropertiesContainer extends IAdaptable {
public void clearProperties();
/**
+ * Returns whether this properties container is empty or not.
+ *
+ * @return <code>True</code> if the properties container is empty, <code>false</code> if not.
+ */
+ public boolean isEmpty();
+
+ /**
* Test if the property value stored under the given property is equal ignoring the case to the given
* expected string value.
*
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/properties/PropertiesContainer.java b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/properties/PropertiesContainer.java
index 261243275..635b6c100 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/properties/PropertiesContainer.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.runtime/src/org/eclipse/tcf/te/runtime/properties/PropertiesContainer.java
@@ -473,6 +473,15 @@ public class PropertiesContainer extends PlatformObject implements IPropertiesCo
}
/* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer#isEmpty()
+ */
+ @Override
+ public boolean isEmpty() {
+ Assert.isTrue(checkThreadAccess(), "Illegal Thread Access"); //$NON-NLS-1$
+ return properties.isEmpty();
+ }
+
+ /* (non-Javadoc)
* @see org.eclipse.tcf.te.runtime.interfaces.IPropertiesContainer#isProperty(java.lang.String, long)
*/
@Override
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj16/error.gif b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj16/error.gif
new file mode 100644
index 000000000..85ec26bb8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj16/error.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj32/delete_readonly.png b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj32/delete_readonly.png
new file mode 100644
index 000000000..4c8a7e3a8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj32/delete_readonly.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj32/replace_confirm.png b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj32/replace_confirm.png
new file mode 100644
index 000000000..455df2156
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/obj32/replace_confirm.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/ovr/ovr_cut.png b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/ovr/ovr_cut.png
new file mode 100644
index 000000000..1c59851e1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/icons/ovr/ovr_cut.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.properties
index 4a95e9626..6f12bbc52 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.properties
@@ -26,7 +26,7 @@ FSTreeViewerFilter.systemFiles=Protected operating system files (File System (TC
# ***** Actions/Commands *****
-PropertiesAction.label=P&roperties
+PropertiesAction.label=Properties
PropertiesAction.tooltip=Show Properties of Selection
navigatorContent.name = Target File System (TCF)
@@ -51,4 +51,17 @@ decorator.modified.label = Modified Cache
decorator.outdated.label = Outdated Cache
decorator.conflict.label = Conflicting Cache
preference.page.name = Target Explorer
-menu.label.openwith = Open With \ No newline at end of file
+menu.label.openwith = Open With
+command.label.cut = Cut
+command.label.copy = Copy
+command.label.paste = Paste
+command.label.delete = Delete
+command.label.rename = Rename
+command.label.move = Move
+command.label.cut.1 = Cut
+command.label.copy.1 = Copy
+command.label.paste.1 = Paste
+command.label.delete.1 = Delete
+command.label.rename.1 = Rename
+command.label.move.1 = Move
+decorator.label.cut = Cut File \ No newline at end of file
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.xml
index 8bba011c6..c5d83aeb5 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.xml
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/plugin.xml
@@ -16,6 +16,10 @@
pattern="org.eclipse.tcf.te.tcf.filesystem.navigator.*"/>
</includes>
</viewerContentBinding>
+ <dragAssistant
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.dnd.FSDragAdapterAssistant"
+ viewerId="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </dragAssistant>
</extension>
<extension point="org.eclipse.ui.navigator.navigatorContent">
@@ -28,13 +32,13 @@
name="%navigatorContent.name"
priority="normal">
<triggerPoints>
- <adapt
- type="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel">
- <test
- property="org.eclipse.tcf.te.tcf.locator.hasRemoteService"
- value="FileSystem">
- </test>
- </adapt>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.locator.hasRemoteService"
+ value="FileSystem">
+ </test>
</triggerPoints>
<possibleChildren>
<instanceof value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode"/>
@@ -43,6 +47,14 @@
class="org.eclipse.tcf.te.tcf.filesystem.controls.FSTreeViewerSorter"
id="org.eclipse.tcf.te.tcf.filesystem.navigator.sorter">
</commonSorter>
+ <dropAssistant
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.dnd.FSDropAdapterAssistant"
+ id="org.eclipse.tcf.te.tcf.filesystem.dropAssistant">
+ <possibleDropTargets>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof></possibleDropTargets>
+ </dropAssistant>
</navigatorContent>
<commonFilter
activeByDefault="true"
@@ -150,6 +162,153 @@
</dynamic>
</menu>
<separator
+ name="group.edit"
+ visible="true">
+ </separator>
+ <command
+ commandId="org.eclipse.ui.edit.cut"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Cut"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/etool16/cut_edit.gif"
+ id="cut"
+ label="%command.label.cut"
+ mnemonic="t"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.ui.edit.copy"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Copy"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/etool16/copy_edit.gif"
+ id="copy"
+ label="%command.label.copy"
+ mnemonic="C"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.ui.edit.paste"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Paste"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/etool16/paste_edit.gif"
+ id="paste"
+ label="%command.label.paste"
+ mnemonic="P"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.delete">
+ </separator>
+ <command
+ commandId="org.eclipse.ui.edit.delete"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Delete"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/obj16/delete_obj.gif"
+ id="delete"
+ label="%command.label.delete"
+ mnemonic="D"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.move"
+ visible="true">
+ </separator>
+ <command
+ commandId="org.eclipse.ui.edit.rename"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Rename"
+ id="rename"
+ label="%command.label.rename"
+ mnemonic="R"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.ui.edit.move"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Move"
+ id="move"
+ label="%command.label.move"
+ mnemonic="M"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
name="group.state"
visible="true">
</separator>
@@ -403,6 +562,153 @@
</dynamic>
</menu>
<separator
+ name="file.group.edit"
+ visible="true">
+ </separator>
+ <command
+ commandId="org.eclipse.ui.edit.cut"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Cut"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/etool16/cut_edit.gif"
+ id="cut"
+ label="%command.label.cut.1"
+ mnemonic="t"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.ui.edit.copy"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Copy"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/etool16/copy_edit.gif"
+ id="copy"
+ label="%command.label.copy.1"
+ mnemonic="C"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.ui.edit.paste"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Paste"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/etool16/paste_edit.gif"
+ id="paste"
+ label="%command.label.paste.1"
+ mnemonic="P"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.delete">
+ </separator>
+ <command
+ commandId="org.eclipse.ui.edit.delete"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Delete"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/obj16/delete_obj.gif"
+ id="delete"
+ label="%command.label.delete.1"
+ mnemonic="D"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.move"
+ visible="true">
+ </separator>
+ <command
+ commandId="org.eclipse.ui.edit.rename"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Rename"
+ id="rename"
+ label="%command.label.rename.1"
+ mnemonic="R"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.ui.edit.move"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Move"
+ id="move"
+ label="%command.label.move.1"
+ mnemonic="M"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
name="group.state"
visible="true">
</separator>
@@ -583,7 +889,7 @@
class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.FSTreeNodePropertyTester"
id="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode"
namespace="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode"
- properties="isFile,isDirectory,isBinaryFile,isReadable,isWritable,isExecutable,getCacheState"
+ properties="isFile,isDirectory,isBinaryFile,isReadable,isWritable,isExecutable,isRoot,isReadOnly,isHidden,isWindows,getCacheState,isSamePeer"
type="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
</propertyTester>
<propertyTester
@@ -593,6 +899,13 @@
properties="isAutoSavingOn"
type="java.lang.Object">
</propertyTester>
+ <propertyTester
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.ClipboardPropertyTester"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertytester.clipboard"
+ namespace="org.eclipse.tcf.te.tcf.filesystem.propertytester.clipboard"
+ properties="canPaste"
+ type="java.lang.Object">
+ </propertyTester>
</extension>
<!-- Target Explorer command contributions -->
@@ -626,6 +939,17 @@
<activeWhen>
<and>
<with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ <with
variable="selection">
<count
value="1">
@@ -650,24 +974,41 @@
</not>
</iterate>
</with>
- <with
- variable="activePartId">
- <or>
- <equals
- value="org.eclipse.tcf.te.ui.views.TargetExplorer">
- </equals>
- <equals
- value="org.eclipse.tcf.te.ui.view.Editor">
- </equals>
- </or>
- </with>
</and>
</activeWhen>
+ <enabledWhen>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile">
+ </test>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadable">
+ </test>
+ <not>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isBinaryFile">
+ </test>
+ </not>
+ </iterate>
+ </with>
+ </enabledWhen>
</handler>
<handler
class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.RefreshHandler"
commandId="org.eclipse.ui.file.refresh">
<activeWhen>
+ <and>
<with
variable="activePartId">
<or>
@@ -679,81 +1020,538 @@
</equals>
</or>
</with>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile">
+ </test>
+ </iterate>
+ </with>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn">
+ </test>
+ </not>
+ </and>
</activeWhen>
+ <enabledWhen>
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile">
+ </test>
+ </iterate>
+ </with>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn">
+ </test>
+ </not>
+ </and>
+ </enabledWhen>
</handler>
<handler
class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.UpdateHandler"
commandId="org.eclipse.tcf.te.tcf.filesystem.commands.update">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
+ <enabledWhen>
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile">
+ </test>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="outdated">
+ </test>
+ </iterate>
+ </with>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn">
+ </test>
+ </not>
+ </and>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CommitHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.commit">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
+ <enabledWhen>
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile">
+ </test>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="modified">
+ </test>
+ </iterate>
+ </with>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn">
+ </test>
+ </not>
+ </and>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.MergeHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.merge">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
+ <enabledWhen>
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile">
+ </test>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="conflict">
+ </test>
+ </iterate>
+ </with>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn">
+ </test>
+ </not>
+ </and>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.RevertHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.revert">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
+ <enabledWhen>
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile">
+ </test>
+ <or>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="modified">
+ </test>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="conflict">
+ </test>
+ </or>
+ </iterate>
+ </with>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn">
+ </test>
+ </not>
+ </and>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.DeleteFilesHandler"
+ commandId="org.eclipse.ui.edit.delete">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
<enabledWhen>
<with
variable="selection">
<count
- value="1">
+ value="+">
</count>
<iterate>
- <test
- property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
- value="outdated">
- </test>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot">
+ </test>
+ </not>
+ <or>
+ <and>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows">
+ </test>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadOnly">
+ </test>
+ </not>
+ </and>
+ <and>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows">
+ </test>
+ </not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable">
+ </test>
+ </and>
+ </or>
</iterate>
</with>
</enabledWhen>
</handler>
<handler
- class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CommitHandler"
- commandId="org.eclipse.tcf.te.tcf.filesystem.commands.commit">
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CutFilesHandler"
+ commandId="org.eclipse.ui.edit.cut">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
<enabledWhen>
<with
variable="selection">
<count
- value="1">
+ value="+">
</count>
<iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot">
+ </test>
+ </not>
+ <or>
+ <and>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows">
+ </test>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadOnly">
+ </test>
+ </not>
+ </and>
+ <and>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows">
+ </test>
+ </not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable">
+ </test>
+ </and>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CopyFilesHandler"
+ commandId="org.eclipse.ui.edit.copy">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
+ <enabledWhen>
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
<test
- property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
- value="modified">
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadable">
</test>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot">
+ </test>
+ </not>
</iterate>
</with>
</enabledWhen>
</handler>
<handler
- class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.MergeHandler"
- commandId="org.eclipse.tcf.te.tcf.filesystem.commands.merge">
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.PasteFilesHandler"
+ commandId="org.eclipse.ui.edit.paste">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
<enabledWhen>
+ <and>
<with
variable="selection">
<count
value="1">
</count>
<iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable">
+ </test>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isDirectory">
+ </test>
<test
- property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
- value="conflict">
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSamePeer">
</test>
</iterate>
</with>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.clipboard.canPaste">
+ </test>
+ </and>
</enabledWhen>
</handler>
<handler
- class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.RevertHandler"
- commandId="org.eclipse.tcf.te.tcf.filesystem.commands.revert">
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.MoveFilesHandler"
+ commandId="org.eclipse.ui.edit.move">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
<enabledWhen>
<with
variable="selection">
<count
- value="1">
+ value="+">
</count>
<iterate>
- <or>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <not>
<test
- property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
- value="modified">
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot">
</test>
+ </not>
+ <or>
+ <and>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows">
+ </test>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadOnly">
+ </test>
+ </not>
+ </and>
+ <and>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows">
+ </test>
+ </not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable">
+ </test>
+ </and>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.RenameFilesHandler"
+ commandId="org.eclipse.ui.edit.rename">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <or>
+ <equals
+ value="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </equals>
+ <equals
+ value="org.eclipse.tcf.te.ui.view.Editor">
+ </equals>
+ </or>
+ </with>
+ </activeWhen>
+ <enabledWhen>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode">
+ </instanceof>
+ <not>
<test
- property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
- value="conflict">
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot">
</test>
+ </not>
+ <or>
+ <and>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows">
+ </test>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadOnly">
+ </test>
+ </not>
+ </and>
+ <and>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows">
+ </test>
+ </not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable">
+ </test>
+ </and>
</or>
</iterate>
</with>
@@ -804,6 +1602,18 @@
</objectState>
</enablement>
</decorator>
+ <decorator
+ class="org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CutDecorator"
+ id="org.eclipse.tcf.te.tcf.filesystem.decorators.cut"
+ label="%decorator.label.cut"
+ state="true">
+ <enablement>
+ <objectState
+ name="edit.cut"
+ value="true">
+ </objectState>
+ </enablement>
+ </decorator>
</extension>
<extension point="org.eclipse.ui.preferencePages">
@@ -823,5 +1633,12 @@
</adapter>
</factory>
</extension>
+ <extension
+ point="org.eclipse.tcf.te.ui.views.configurators">
+ <configurator
+ class="org.eclipse.tcf.te.tcf.filesystem.controls.FSCellConfigurator"
+ viewerId="org.eclipse.tcf.te.ui.views.TargetExplorer">
+ </configurator>
+ </extension>
</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/activator/UIPlugin.java
index 298c54676..0c74b43e3 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/activator/UIPlugin.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/activator/UIPlugin.java
@@ -8,6 +8,8 @@
* Wind River Systems - initial API and implementation
* William Chen (Wind River) - [345387] Open the remote files with a proper editor
* William Chen (Wind River) - [345552] Edit the remote files with a proper editor
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * system of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.activator;
@@ -25,8 +27,10 @@ import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts;
import org.eclipse.tcf.te.tcf.filesystem.internal.autosave.SaveAllListener;
import org.eclipse.tcf.te.tcf.filesystem.internal.autosave.SaveListener;
import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.PersistenceManager;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard;
import org.eclipse.tcf.te.tcf.filesystem.internal.url.TcfURLConnection;
import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.ui.jface.images.AbstractImageDescriptor;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
@@ -49,6 +53,8 @@ public class UIPlugin extends AbstractUIPlugin {
private IExecutionListener saveListener;
// The listener which listens to command "SAVE ALL" and synchronize the local file with the target.
private IExecutionListener saveAllListener;
+ // The shared instance of Clipboard
+ private FSClipboard clipboard;
/**
* The constructor
@@ -82,6 +88,7 @@ public class UIPlugin extends AbstractUIPlugin {
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
+ clipboard = new FSClipboard();
// Register the "tcf" URL stream handler service.
Hashtable<String, String[]> properties = new Hashtable<String, String[]>();
@@ -106,6 +113,13 @@ public class UIPlugin extends AbstractUIPlugin {
}
}
+ /**
+ * Get the shared instance of clipboard
+ */
+ public FSClipboard getClipboard() {
+ return clipboard;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
@@ -126,6 +140,7 @@ public class UIPlugin extends AbstractUIPlugin {
Command saveAllCmd = commandService.getCommand(IWorkbenchCommandConstants.FILE_SAVE_ALL);
saveAllCmd.removeExecutionListener(saveAllListener);
}
+ clipboard = null;
plugin = null;
super.stop(context);
}
@@ -144,6 +159,16 @@ public class UIPlugin extends AbstractUIPlugin {
registry.put(ImageConsts.ROOT_DRIVE_OPEN, ImageDescriptor.createFromURL(url));
url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ + "synch_synch.gif"); //$NON-NLS-1$
registry.put(ImageConsts.COMPARE_EDITOR, ImageDescriptor.createFromURL(url));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ32 + "replace_confirm.png"); //$NON-NLS-1$
+ registry.put(ImageConsts.REPLACE_FOLDER_CONFIRM, ImageDescriptor.createFromURL(url));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ32 + "delete_readonly.png"); //$NON-NLS-1$
+ registry.put(ImageConsts.DELETE_READONLY_CONFIRM, ImageDescriptor.createFromURL(url));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OVR + "ovr_cut.png"); //$NON-NLS-1$
+ registry.put(ImageConsts.CUT_DECORATOR_IMAGE, ImageDescriptor.createFromURL(url));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ32 + "banner.png"); //$NON-NLS-1$
+ registry.put(ImageConsts.BANNER_IMAGE, ImageDescriptor.createFromURL(url));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ + "error.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.ERROR_IMAGE, ImageDescriptor.createFromURL(url));
}
/**
@@ -167,4 +192,26 @@ public class UIPlugin extends AbstractUIPlugin {
public static ImageDescriptor getImageDescriptor(String key) {
return getDefault().getImageRegistry().getDescriptor(key);
}
+
+ /**
+ * Loads the image given by the specified image descriptor from the image
+ * registry. If the image has been loaded ones before already, the cached
+ * <code>Image</code> object instance is returned. Otherwise, the <code>
+ * Image</code> object instance will be created and cached before returned.
+ *
+ * @param descriptor The image descriptor.
+ * @return The corresponding <code>Image</code> object instance or <code>null</code>.
+ */
+ public static Image getSharedImage(AbstractImageDescriptor descriptor) {
+ ImageRegistry registry = getDefault().getImageRegistry();
+
+ String imageKey = descriptor.getDecriptorKey();
+ Image image = registry.get(imageKey);
+ if (image == null) {
+ registry.put(imageKey, descriptor);
+ image = registry.get(imageKey);
+ }
+
+ return image;
+ }
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSCellConfigurator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSCellConfigurator.java
new file mode 100644
index 000000000..27bca50e2
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSCellConfigurator.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.controls;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ColumnViewerEditor;
+import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
+import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.TreeViewerEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellListener;
+import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellModifier;
+import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellValidator;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.RenameFilesHandler;
+import org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator;
+import org.eclipse.ui.navigator.CommonViewer;
+
+/**
+ * FSCellConfigurator implements <code>IViewerConfigurator</code> to configure the
+ * editor for renaming in the file system tree of Target Explorer.
+ */
+public class FSCellConfigurator implements IViewerConfigurator {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator#configure(org.eclipse.ui.navigator.CommonViewer)
+ */
+ @Override
+ public void configure(final CommonViewer viewer) {
+ addEditingSupport(viewer);
+ }
+
+ /**
+ * Add the editing support for the specified tree viewer with those editing assistants which
+ * have the specified viewId.
+ *
+ * @param viewer The tree viewer to which the editing support is added.
+ */
+ static void addEditingSupport(final TreeViewer viewer) {
+ // Define an editor activation strategy for the common viewer so as to be invoked only programmatically.
+ ColumnViewerEditorActivationStrategy activationStrategy = new ColumnViewerEditorActivationStrategy(viewer) {
+ @Override
+ protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
+ // Activated only when a single node is selected and invoked programmatically.
+ boolean singleSelect = ((IStructuredSelection) viewer.getSelection()).size() == 1;
+ return singleSelect && (event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC);
+ }
+ };
+ TreeViewerEditor.create(viewer, null, activationStrategy, ColumnViewerEditor.DEFAULT);
+
+ // Set the column properties, the cell editor, and the modifier.
+ viewer.setColumnProperties(new String[] { FSCellModifier.PROPERTY_NAME });
+ TextCellEditor cellEditor = new TextCellEditor((Composite) viewer.getControl(), SWT.BORDER);
+ cellEditor.setValidator(new FSCellValidator(viewer));
+ cellEditor.addListener(new FSCellListener(cellEditor));
+ viewer.setCellEditors(new CellEditor[] { cellEditor });
+ viewer.setCellModifier(new FSCellModifier());
+
+ // Trace the currently focused tree viewer.
+ Control control = viewer.getControl();
+ control.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ RenameFilesHandler.setCurrentViewer(viewer);
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ }
+ });
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java
index 37796d03b..04ae0cef2 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeContentProvider.java
@@ -6,6 +6,8 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.controls;
@@ -594,12 +596,18 @@ public class FSTreeContentProvider implements ITreeContentProvider, INodeStateLi
// Make sure that this node is inside of this viewer.
Display display = PlatformUI.getWorkbench().getDisplay();
if (display.getThread() == Thread.currentThread()) {
- viewer.refresh(node);
+ if (node != null) {
+ viewer.refresh(node);
+ }
+ else {
+ //Refresh the whole tree.
+ viewer.refresh();
+ }
} else {
display.asyncExec(new Runnable() {
@Override
public void run() {
- viewer.refresh(node);
+ stateChanged(node);
}
});
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeControl.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeControl.java
index bf5ae14a0..cf81f63c4 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeControl.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeControl.java
@@ -7,6 +7,8 @@
* Contributors:
* Wind River Systems - initial API and implementation
* William Chen (Wind River) - [345384] Provide property pages for remote file system nodes
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.controls;
@@ -15,6 +17,8 @@ import java.util.Collections;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelDecorator;
@@ -27,8 +31,13 @@ import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.tcf.te.tcf.filesystem.internal.dnd.FSDragSourceListener;
+import org.eclipse.tcf.te.tcf.filesystem.internal.dnd.FSDropTargetListener;
import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
import org.eclipse.tcf.te.ui.interfaces.IUIConstants;
import org.eclipse.tcf.te.ui.trees.AbstractTreeControl;
@@ -64,6 +73,17 @@ public class FSTreeControl extends AbstractTreeControl implements ISelectionChan
super(parentPart);
}
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.trees.AbstractTreeControl#doCreateTreeViewer(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected TreeViewer doCreateTreeViewer(Composite parent) {
+ Assert.isNotNull(parent);
+ // Override the parent method to create a multiple-selection tree.
+ return new TreeViewer(parent, SWT.FULL_SELECTION | SWT.MULTI);
+ }
+
/* (non-Javadoc)
* @see org.eclipse.tcf.te.tcf.vtl.ui.datasource.controls.trees.AbstractTreeControl#configureTreeViewer(org.eclipse.jface.viewers.TreeViewer)
*/
@@ -87,6 +107,13 @@ public class FSTreeControl extends AbstractTreeControl implements ISelectionChan
}
tree.setHeaderVisible(hasColumns());
viewer.addDoubleClickListener(this);
+ //Add DnD support.
+ int operations = DND.DROP_MOVE;
+ Transfer[] transferTypes = {LocalSelectionTransfer.getTransfer()};
+ viewer.addDragSupport(operations, transferTypes, new FSDragSourceListener(viewer));
+ viewer.addDropSupport(operations, transferTypes, new FSDropTargetListener(viewer));
+ // Add editing support to rename files/folders.
+ FSCellConfigurator.addEditingSupport(viewer);
}
/**
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeLabelProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeLabelProvider.java
index a569db763..dd934bc1b 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeLabelProvider.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/controls/FSTreeLabelProvider.java
@@ -6,12 +6,15 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.controls;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.List;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ITableLabelProvider;
@@ -20,6 +23,7 @@ import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation;
import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
import org.eclipse.ui.IEditorRegistry;
@@ -61,6 +65,15 @@ public class FSTreeLabelProvider extends LabelProvider implements ITableLabelPro
}
/**
+ * Set the parent viewer who will use this label provider for rendering.
+ *
+ * @param viewer The parent tree viewer.
+ */
+ public void setParentViewer(TreeViewer viewer) {
+ parentViewer = viewer;
+ }
+
+ /**
* Returns the parent tree viewer instance.
*
* @return The parent tree viewer or <code>null</code>.
@@ -101,9 +114,9 @@ public class FSTreeLabelProvider extends LabelProvider implements ITableLabelPro
if (element instanceof FSTreeNode) {
FSTreeNode node = (FSTreeNode)element;
if ("FSRootDirNode".equals(node.type)) {//$NON-NLS-1$
- return isExpanded ? UIPlugin.getImage(ImageConsts.ROOT_DRIVE_OPEN) : UIPlugin.getImage(ImageConsts.ROOT_DRIVE);
+ return (isExpanded && hasChildren(node)) ? UIPlugin.getImage(ImageConsts.ROOT_DRIVE_OPEN) : UIPlugin.getImage(ImageConsts.ROOT_DRIVE);
} else if ("FSDirNode".equals(node.type)) { //$NON-NLS-1$
- return isExpanded ? PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER) : UIPlugin.getImage(ImageConsts.FOLDER);
+ return (isExpanded && hasChildren(node)) ? PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER) : UIPlugin.getImage(ImageConsts.FOLDER);
} else if ("FSFileNode".equals(node.type)) { //$NON-NLS-1$
String key = node.name;
Image image = UIPlugin.getImage(key);
@@ -122,6 +135,11 @@ public class FSTreeLabelProvider extends LabelProvider implements ITableLabelPro
return super.getImage(element);
}
+ private boolean hasChildren(FSTreeNode folder) {
+ List<FSTreeNode> children = FSOperation.getCurrentChildren(folder);
+ return children != null && !children.isEmpty();
+ }
+
/**
* Returns the workbench's editor registry.
*/
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/dialogs/FSFolderSelectionDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/dialogs/FSFolderSelectionDialog.java
new file mode 100644
index 000000000..9f9ca52df
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/dialogs/FSFolderSelectionDialog.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.dialogs;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.controls.FSTreeContentProvider;
+import org.eclipse.tcf.te.tcf.filesystem.controls.FSTreeLabelProvider;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.MoveFilesHandler;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+
+/**
+ * <p>
+ * The folder selection dialog for a remote file system. To populate the tree of the selection
+ * dialog with the file system, you should call <code>
+ * ElementTreeSelectionDialog.setInput</code> to specify the peer model of the remote target. In
+ * order to validate the destination folder, you should also specify the nodes to be moved. The file
+ * selection dialog is of single selection. You can get the selected result by calling
+ * <code>getFirstResult</code>. The type of selected folder is an instance of FSTreeNode.
+ * </p>
+ * <p>
+ * The following is a snippet of example code:
+ *
+ * <pre>
+ * FSFolderSelectionDialog dialog = new FSFolderSelectionDialog(shell);
+ * dialog.setInput(peer);
+ * dialog.setMovedNodes(nodes);
+ * if (dialog.open() == Window.OK) {
+ * Object obj = dialog.getFirstResult();
+ * Assert.isTrue(obj instanceof FSTreeNode);
+ * FSTreeNode folder = (FSTreeNode) obj;
+ * // Use folder ...
+ * }
+ * </pre>
+ *
+ * @see MoveFilesHandler
+ */
+public class FSFolderSelectionDialog extends ElementTreeSelectionDialog {
+ // Label provider used by the file system tree.
+ private FSTreeLabelProvider labelProvider;
+ // The nodes that are being moved.
+ private List<FSTreeNode> movedNodes;
+
+ /**
+ * Create an FSFolderSelectionDialog using the specified shell as the parent.
+ *
+ * @param parentShell The parent shell.
+ */
+ public FSFolderSelectionDialog(Shell parentShell) {
+ this(parentShell, new FSTreeLabelProvider(), new FSTreeContentProvider());
+ }
+
+ /**
+ * Create an FSFolderSelectionDialog using the specified shell, an FSTreeLabelProvider, and a
+ * content provider that provides the tree nodes.
+ *
+ * @param parentShell The parent shell.
+ * @param labelProvider The label provider.
+ * @param contentProvider The content provider.
+ */
+ private FSFolderSelectionDialog(Shell parentShell, FSTreeLabelProvider labelProvider, ITreeContentProvider contentProvider) {
+ super(parentShell, labelProvider, contentProvider);
+ this.labelProvider = labelProvider;
+ setTitle(Messages.FSFolderSelectionDialog_MoveDialogTitle);
+ setMessage(Messages.FSFolderSelectionDialog_MoveDialogMessage);
+ this.setAllowMultiple(false);
+ this.addFilter(new ViewerFilter() {
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ return node.isDirectory() || node.type != null && node.type
+ .equals("FSPendingNode"); //$NON-NLS-1$
+ }
+ return false;
+ }
+ });
+ this.setStatusLineAboveButtons(false);
+ this.setValidator(new ISelectionStatusValidator() {
+
+ @Override
+ public IStatus validate(Object[] selection) {
+ return isValidFolder(selection);
+ }
+ });
+ }
+
+ /**
+ * Set the nodes that are about to be moved.
+ *
+ * @param movedNodes The nodes.
+ */
+ public void setMovedNodes(List<FSTreeNode> movedNodes) {
+ this.movedNodes = movedNodes;
+ }
+
+ /**
+ * Create the tree viewer and set it to the label provider.
+ */
+ @Override
+ protected TreeViewer doCreateTreeViewer(Composite parent, int style) {
+ TreeViewer viewer = super.doCreateTreeViewer(parent, style);
+ viewer.getTree().setLinesVisible(false);
+ labelProvider.setParentViewer(viewer);
+ return viewer;
+ }
+
+ /**
+ * If the specified selection is a valid folder to be selected.
+ *
+ * @param selection The selected folders.
+ * @return An error status if it is invalid or an OK status indicating it is valid.
+ */
+ IStatus isValidFolder(Object[] selection) {
+ String pluginId = UIPlugin.getUniqueIdentifier();
+ IStatus error = new Status(IStatus.ERROR, pluginId, null);
+ if (selection == null || selection.length == 0) {
+ return error;
+ }
+ if (!(selection[0] instanceof FSTreeNode)) {
+ return error;
+ }
+ FSTreeNode target = (FSTreeNode) selection[0];
+ for (FSTreeNode node : movedNodes) {
+ if (node == target || node.isAncestorOf(target)) {
+ return error;
+ }
+ }
+ return new Status(IStatus.OK, pluginId, null);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/ImageConsts.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/ImageConsts.java
index d51e06701..8fd1770ab 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/ImageConsts.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/ImageConsts.java
@@ -28,6 +28,17 @@ public interface ImageConsts {
*/
public final static String IMAGE_DIR_OBJ = "obj16/"; //$NON-NLS-1$
+ /**
+ * The directory where to load model object images from,
+ * relative to the image root directory.
+ */
+ public final static String IMAGE_DIR_OBJ32 = "obj32/"; //$NON-NLS-1$
+
+ /**
+ * The directory where to load the decorator image from.
+ */
+ public final static String IMAGE_DIR_OVR = "ovr/"; //$NON-NLS-1$
+
// ***** The image constants *****
/**
@@ -49,4 +60,29 @@ public interface ImageConsts {
* The key to access the image of compare editor.
*/
public static final String COMPARE_EDITOR = "CompareEditor"; //$NON-NLS-1$
+
+ /**
+ * The key to access the title image of "replace folder confirm" dialog.
+ */
+ public static final String REPLACE_FOLDER_CONFIRM = "ReplaceFolderConfirm"; //$NON-NLS-1$
+
+ /**
+ * The key to access the title image of "confirm read only delete" dialog.
+ */
+ public static final String DELETE_READONLY_CONFIRM = "ConfirmReadOnlyDelete"; //$NON-NLS-1$
+
+ /**
+ * The key to access the cut decorator image.
+ */
+ public static final String CUT_DECORATOR_IMAGE = "CutDecorator"; //$NON-NLS-1$
+
+ /**
+ * The key to access the banner image of the advanced attributes dialog.
+ */
+ public static final String BANNER_IMAGE = "BannerImage"; //$NON-NLS-1$
+
+ /**
+ * The key to access the error image used in the tool tip popped up during renaming.
+ */
+ public static final String ERROR_IMAGE = "ErrorImage"; //$NON-NLS-1$
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilter.java
index bd9c75bd5..d7c38a760 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilter.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilter.java
@@ -7,11 +7,18 @@
* Contributors:
* Wind River Systems - initial API and implementation
* William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.internal.adapters;
+import java.net.URL;
+import java.util.List;
+
import org.eclipse.core.runtime.Assert;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.StateManager;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard;
import org.eclipse.tcf.te.tcf.filesystem.model.CacheState;
import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
import org.eclipse.ui.IActionFilter;
@@ -45,6 +52,19 @@ public class NodeStateFilter implements IActionFilter {
value = CacheState.consistent.name();
return value.equals(state.name());
}
+ else if (name.equals("edit.cut")) { //$NON-NLS-1$
+ FSClipboard cb = UIPlugin.getDefault().getClipboard();
+ if (!cb.isEmpty()) {
+ int operation = cb.getOperation();
+ if (operation == FSClipboard.CUT) {
+ URL nodeURL = node.getLocationURL();
+ List<URL> files = cb.getFiles();
+ for (URL file : files) {
+ if (nodeURL.equals(file)) return true;
+ }
+ }
+ }
+ }
return false;
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilterFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilterFactory.java
index 1d66b04e0..f828eddd0 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilterFactory.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/adapters/NodeStateFilterFactory.java
@@ -40,7 +40,7 @@ public class NodeStateFilterFactory implements IAdapterFactory {
*/
@Override
public Object getAdapter(Object adaptableObject, Class adapterType) {
- if(adaptableObject instanceof FSTreeNode){
+ if(adaptableObject instanceof FSTreeNode && adapterType == IActionFilter.class){
FSTreeNode node = (FSTreeNode) adaptableObject;
NodeStateFilter filter = filters.get(node);
if(filter == null){
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellListener.java
new file mode 100644
index 000000000..1cbc83dd0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellListener.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.celleditor;
+
+import org.eclipse.jface.viewers.ICellEditorListener;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.window.DefaultToolTip;
+import org.eclipse.jface.window.ToolTip;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts;
+
+/**
+ * FSCellListener is an <code>ICellEditorListener</code> that listens to the modification event and displays
+ * error messages in a tool tip when the new name entered is not valid.
+ */
+public class FSCellListener implements ICellEditorListener {
+ // The cell editor used to enter the new name for renaming.
+ private TextCellEditor editor;
+ // The tool tip used to display the error message.
+ private DefaultToolTip tooltip;
+
+ /**
+ * Create an FSCellListener using the specified cell editor.
+ *
+ * @param editor The cell editor
+ */
+ public FSCellListener(TextCellEditor editor) {
+ this.editor = editor;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ICellEditorListener#applyEditorValue()
+ */
+ @Override
+ public void applyEditorValue() {
+ disposeToolTip();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ICellEditorListener#cancelEditor()
+ */
+ @Override
+ public void cancelEditor() {
+ disposeToolTip();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ICellEditorListener#editorValueChanged(boolean, boolean)
+ */
+ @Override
+ public void editorValueChanged(boolean oldValidState, boolean newValidState) {
+ if (!newValidState) {
+ // If it is an invalid input, then display a tool tip showing the error.
+ if (tooltip == null) {
+ tooltip = new DefaultToolTip(editor.getControl(), ToolTip.RECREATE, true);
+ tooltip.setImage(UIPlugin.getImage(ImageConsts.ERROR_IMAGE));
+ }
+ tooltip.setText(editor.getErrorMessage());
+ Control control = editor.getControl();
+ Point pOnScr = control.getSize();
+ pOnScr.x = 0;
+ tooltip.show(pOnScr);
+ }
+ else {
+ // Dispose the tool tip if it is valid.
+ disposeToolTip();
+ }
+ }
+
+ /**
+ * Dispose the tool tip used to display error message.
+ */
+ private void disposeToolTip() {
+ if (tooltip != null) {
+ tooltip.hide();
+ tooltip = null;
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellModifier.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellModifier.java
new file mode 100644
index 000000000..ead56eb8a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellModifier.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.celleditor;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSRename;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+
+/**
+ * FSCellModifier is an <code>ICellModifier</code> of the file system tree of the target explorer.
+ */
+public class FSCellModifier implements ICellModifier {
+ // The column property used to get the name of a given file system node.
+ public static final String PROPERTY_NAME = "name"; //$NON-NLS-1$
+
+ public FSCellModifier() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ICellModifier#canModify(java.lang.Object, java.lang.String)
+ */
+ @Override
+ public boolean canModify(Object element, String property) {
+ if (property.equals(PROPERTY_NAME)) {
+ if (element instanceof Item) {
+ element = ((Item) element).getData();
+ }
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ if (!node.isRoot()) {
+ return node.isWindowsNode() && !node.isReadOnly() || !node.isWindowsNode() && node.isWritable();
+ }
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ICellModifier#getValue(java.lang.Object, java.lang.String)
+ */
+ @Override
+ public Object getValue(Object element, String property) {
+ if (property.equals(PROPERTY_NAME)) {
+ if (element instanceof Item) {
+ element = ((Item) element).getData();
+ }
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ return node.name;
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ICellModifier#modify(java.lang.Object, java.lang.String,
+ * java.lang.Object)
+ */
+ @Override
+ public void modify(Object element, String property, Object value) {
+ if (property.equals(PROPERTY_NAME)) {
+ if (element instanceof Item) {
+ element = ((Item) element).getData();
+ }
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ Assert.isTrue(value != null && value instanceof String);
+ String newName = (String) value;
+ // Rename the node with the new name using an FSRename.
+ FSRename op = new FSRename(node, newName);
+ op.doit();
+ }
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellValidator.java
new file mode 100644
index 000000000..a12db0f47
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/celleditor/FSCellValidator.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.celleditor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.ICellEditorValidator;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+
+/**
+ * FSCellValidator is an <code>ICellEditorValidator</code> that validates the name input in the file system
+ * tree cell editor.
+ */
+public class FSCellValidator implements ICellEditorValidator {
+ // The regular expression to define the pattern of a valid Unix file name(not '/').
+ public static final String UNIX_FILENAME_REGEX = "[^/]+"; //$NON-NLS-1$
+ // The regular expression to define the pattern of a valid Windows file name.
+ // (not '?', '\', '/','*','<','>' and '|').
+ public static final String WIN_FILENAME_REGEX = "[^(\\?|\\\\|/|:|\\*|<|>|\\|)]+"; //$NON-NLS-1$
+
+ // The tree viewer used to display the file system.
+ private TreeViewer viewer;
+ /**
+ * Create an FSCellValidator for the specified file system tree.
+ *
+ * @param viewer The tree viewer for the file system.
+ */
+ public FSCellValidator(TreeViewer viewer) {
+ this.viewer = viewer;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ICellEditorValidator#isValid(java.lang.Object)
+ */
+ @Override
+ public String isValid(Object value) {
+ IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
+ Object element = selection.getFirstElement();
+ Assert.isTrue(element instanceof FSTreeNode);
+ FSTreeNode node = (FSTreeNode) element;
+ if (value == null) return Messages.FSRenamingAssistant_SpecifyNonEmptyName;
+ String text = value.toString().trim();
+ if (text.length() == 0) return Messages.FSRenamingAssistant_SpecifyNonEmptyName;
+ if (node == null) return Messages.FSRenamingAssistant_NoNodeSelected;
+ if (hasChild(node, text)) {
+ return Messages.FSRenamingAssistant_NameAlreadyExists;
+ }
+ String formatRegex = node.isWindowsNode() ? WIN_FILENAME_REGEX : UNIX_FILENAME_REGEX;
+ if (!text.matches(formatRegex)) {
+ return node.isWindowsNode() ? Messages.FSRenamingAssistant_WinIllegalCharacters : Messages.FSRenamingAssistant_UnixIllegalCharacters;
+ }
+ return null;
+ }
+ /**
+ * To test if the folder has a child with the specified name.
+ *
+ * @param folder The folder node.
+ * @param name The name.
+ * @return true if it has a child with the name.
+ */
+ private boolean hasChild(FSTreeNode folder, String name) {
+ List<FSTreeNode> nodes = new ArrayList<FSTreeNode>(FSOperation.getCurrentChildren(folder.parent));
+ for (FSTreeNode node : nodes) {
+ if (node.name.equals(name)) return true;
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeEditorInput.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeEditorInput.java
index eea67060f..bd2ca22ab 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeEditorInput.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeEditorInput.java
@@ -25,6 +25,7 @@ import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.osgi.util.NLS;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
@@ -35,6 +36,7 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.ISaveablesSource;
@@ -88,11 +90,11 @@ public class MergeEditorInput extends CompareEditorInput implements
cc.setRightEditable(false);
String name = TextProcessor.process(left.getName());
- String label = "Local: " + name; //$NON-NLS-1$
+ String label = NLS.bind(Messages.MergeEditorInput_LocalFile, name);
cc.setLeftLabel(label);
name = TextProcessor.process(right.toString());
- label = "Remote: " + name; //$NON-NLS-1$
+ label = NLS.bind(Messages.MergeEditorInput_RemoteFile, name);
cc.setRightLabel(label);
}
@@ -136,7 +138,7 @@ public class MergeEditorInput extends CompareEditorInput implements
*/
@Override
public String getToolTipText() {
- return "Compare " + left + " and " + right; //$NON-NLS-1$ //$NON-NLS-2$
+ return NLS.bind(Messages.MergeEditorInput_CompareLeftAndRight, left, right);
}
/* (non-Javadoc)
@@ -144,7 +146,7 @@ public class MergeEditorInput extends CompareEditorInput implements
*/
@Override
public String getTitle() {
- return "Compare " + left.getName() + " with Local Cache"; //$NON-NLS-1$ //$NON-NLS-2$
+ return NLS.bind(Messages.MergeEditorInput_CompareWithLocalCache, left.getName());
}
/**
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeInput.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeInput.java
index db6f077b3..12647fd7b 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeInput.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/compare/MergeInput.java
@@ -19,6 +19,7 @@ import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
/**
* An abstract compare input whose purpose is to support change notification
@@ -88,7 +89,7 @@ public class MergeInput implements ICompareInput {
*/
@Override
public void copy(boolean leftToRight) {
- Assert.isTrue(false, "Copy is not support by this type of compare input"); //$NON-NLS-1$
+ Assert.isTrue(false, Messages.MergeInput_CopyNotSupported);
}
/* (non-Javadoc)
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragAdapterAssistant.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragAdapterAssistant.java
new file mode 100644
index 000000000..5cd526589
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragAdapterAssistant.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.dnd;
+
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.ui.navigator.CommonDragAdapterAssistant;
+
+/**
+ * The drag assistant used by Target Explorer to extend its DnD support to FSTreeNode elements.
+ */
+public class FSDragAdapterAssistant extends CommonDragAdapterAssistant {
+
+ /**
+ * Create an instance.
+ */
+ public FSDragAdapterAssistant() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonDragAdapterAssistant#dragStart(org.eclipse.swt.dnd.DragSourceEvent, org.eclipse.jface.viewers.IStructuredSelection)
+ */
+ @Override
+ public void dragStart(DragSourceEvent anEvent, IStructuredSelection aSelection) {
+ anEvent.doit = isDraggable(aSelection);
+ LocalSelectionTransfer.getTransfer().setSelection(aSelection);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonDragAdapterAssistant#getSupportedTransferTypes()
+ */
+ @Override
+ public Transfer[] getSupportedTransferTypes() {
+ return new Transfer[] {};
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonDragAdapterAssistant#setDragData(org.eclipse.swt.dnd.DragSourceEvent, org.eclipse.jface.viewers.IStructuredSelection)
+ */
+ @Override
+ public boolean setDragData(DragSourceEvent anEvent, IStructuredSelection aSelection) {
+ return false;
+ }
+
+ /**
+ * If the current selection is draggable.
+ *
+ * @param selection The currently selected nodes.
+ * @return true if it is draggable.
+ */
+ private boolean isDraggable(IStructuredSelection selection) {
+ if (selection.isEmpty()) {
+ return false;
+ }
+ Object[] objects = selection.toArray();
+ for (Object object : objects) {
+ if (!isDraggableObject(object)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * If the specified object is a draggable element.
+ *
+ * @param object The object to be dragged.
+ * @return true if it is draggable.
+ */
+ private boolean isDraggableObject(Object object) {
+ if (object instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) object;
+ return !node.isRoot() && (node.isWindowsNode() && !node.isReadOnly() || !node.isWindowsNode() && node.isWritable());
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragSourceListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragSourceListener.java
new file mode 100644
index 000000000..f14644612
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDragSourceListener.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.dnd;
+
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+
+/**
+ * The drag source listener for the file tree of Target Explorer.
+ */
+public class FSDragSourceListener implements DragSourceListener {
+ // The tree viewer in which the DnD gesture happens.
+ private TreeViewer viewer;
+
+ /**
+ * Create an FSDragSourceListener using the specified tree viewer.
+ *
+ * @param viewer The file system tree viewer.
+ */
+ public FSDragSourceListener(TreeViewer viewer) {
+ this.viewer = viewer;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.dnd.DragSourceListener#dragStart(org.eclipse.swt.dnd.DragSourceEvent)
+ */
+ @Override
+ public void dragStart(DragSourceEvent event) {
+ IStructuredSelection aSelection = (IStructuredSelection) viewer.getSelection();
+ event.doit = isDraggable(aSelection);
+ LocalSelectionTransfer.getTransfer().setSelection(aSelection);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.dnd.DragSourceListener#dragSetData(org.eclipse.swt.dnd.DragSourceEvent)
+ */
+ @Override
+ public void dragSetData(DragSourceEvent event) {
+ if (LocalSelectionTransfer.getTransfer().isSupportedType(event.dataType)) {
+ event.data = LocalSelectionTransfer.getTransfer().getSelection();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.dnd.DragSourceListener#dragFinished(org.eclipse.swt.dnd.DragSourceEvent)
+ */
+ @Override
+ public void dragFinished(DragSourceEvent event) {
+ }
+
+ /**
+ * If the current selection is draggable.
+ *
+ * @param selection The currently selected nodes.
+ * @return true if it is draggable.
+ */
+ private boolean isDraggable(IStructuredSelection selection) {
+ if (selection.isEmpty()) {
+ return false;
+ }
+ Object[] objects = selection.toArray();
+ for (Object object : objects) {
+ if (!isDraggableObject(object)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * If the specified object is a draggable element.
+ *
+ * @param object The object to be dragged.
+ * @return true if it is draggable.
+ */
+ private boolean isDraggableObject(Object object) {
+ if (object instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) object;
+ return !node.isRoot() && (node.isWindowsNode() && !node.isReadOnly() || !node.isWindowsNode() && node.isWritable());
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropAdapterAssistant.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropAdapterAssistant.java
new file mode 100644
index 000000000..702aba18d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropAdapterAssistant.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.dnd;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSMove;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.ui.navigator.CommonDropAdapter;
+import org.eclipse.ui.navigator.CommonDropAdapterAssistant;
+
+/**
+ * The drop assistant used by Target Explorer to extend its DnD support to FSTreeNode elements.
+ */
+public class FSDropAdapterAssistant extends CommonDropAdapterAssistant {
+ /**
+ * Create an instance.
+ */
+ public FSDropAdapterAssistant() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#validateDrop(java.lang.Object, int, org.eclipse.swt.dnd.TransferData)
+ */
+ @Override
+ public IStatus validateDrop(Object target, int operation, TransferData transferType) {
+ if (validateDropping(target, operation, transferType)) {
+ return Status.OK_STATUS;
+ }
+ return new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), Messages.FSTreeNodeDropAdapterAssistant_DragError);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#handleDrop(org.eclipse.ui.navigator.CommonDropAdapter, org.eclipse.swt.dnd.DropTargetEvent, java.lang.Object)
+ */
+ @Override
+ public IStatus handleDrop(CommonDropAdapter aDropAdapter, DropTargetEvent aDropTargetEvent, Object aTarget) {
+ Object data = aDropTargetEvent.data;
+ FSTreeNode dest = (FSTreeNode) aTarget;
+ IStructuredSelection selection = (IStructuredSelection) data;
+ List<FSTreeNode> nodes = selection.toList();
+ FSMove move = new FSMove(nodes, dest);
+ return move.doit() ? Status.OK_STATUS : new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), Messages.FSTreeNodeDropAdapterAssistant_MoveFailure);
+ }
+
+ /**
+ * Validates dropping on the given object.
+ *
+ * @param target the object that the mouse is currently hovering over, or
+ * <code>null</code> if the mouse is hovering over empty space
+ * @param operation the current drag operation (copy, move, etc.)
+ * @param transferType the current transfer type
+ * @return <code>true</code> if the drop is valid, and <code>false</code>
+ * otherwise
+ */
+ private boolean validateDropping(Object target, int operation, TransferData transferType) {
+ LocalSelectionTransfer transfer = LocalSelectionTransfer.getTransfer();
+ if (target != null && transfer.isSupportedType(transferType) && operation == DND.DROP_MOVE && target instanceof FSTreeNode) {
+ FSTreeNode hovered = (FSTreeNode) target;
+ if (hovered.isDirectory()) {
+ IStructuredSelection selection = (IStructuredSelection) transfer.getSelection();
+ List<FSTreeNode> nodes = selection.toList();
+ FSTreeNode head = nodes.get(0);
+ String hid = head.peerNode.getPeer().getID();
+ String tid = hovered.peerNode.getPeer().getID();
+ if (hid.equals(tid)) {
+ for (FSTreeNode node : nodes) {
+ if (node == hovered || node.isAncestorOf(hovered)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropTargetListener.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropTargetListener.java
new file mode 100644
index 000000000..5e6136879
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/dnd/FSDropTargetListener.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.dnd;
+
+import java.util.List;
+
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerDropAdapter;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSMove;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+
+/**
+ * The drop target listener for the file tree of Target Explorer.
+ */
+public class FSDropTargetListener extends ViewerDropAdapter {
+ /**
+ * Create FSDropTargetListener using the viewer.
+ *
+ * @param viewer The file system tree viewer.
+ */
+ public FSDropTargetListener(TreeViewer viewer) {
+ super(viewer);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerDropAdapter#validateDrop(java.lang.Object, int, org.eclipse.swt.dnd.TransferData)
+ */
+ @Override
+ public boolean validateDrop(Object target, int operation, TransferData transferType) {
+ LocalSelectionTransfer transfer = LocalSelectionTransfer.getTransfer();
+ if (target != null && transfer.isSupportedType(transferType) && operation == DND.DROP_MOVE && target instanceof FSTreeNode) {
+ FSTreeNode hovered = (FSTreeNode) target;
+ if (hovered.isDirectory()) {
+ IStructuredSelection selection = (IStructuredSelection) transfer.getSelection();
+ List<FSTreeNode> nodes = selection.toList();
+ FSTreeNode head = nodes.get(0);
+ String hid = head.peerNode.getPeer().getID();
+ String tid = hovered.peerNode.getPeer().getID();
+ if (hid.equals(tid)) {
+ for (FSTreeNode node : nodes) {
+ if (node == hovered || node.isAncestorOf(hovered)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerDropAdapter#performDrop(java.lang.Object)
+ */
+ @Override
+ public boolean performDrop(Object data) {
+ Object aTarget = getCurrentTarget();
+ FSTreeNode dest = (FSTreeNode) aTarget;
+ IStructuredSelection selection = (IStructuredSelection) data;
+ List<FSTreeNode> nodes = selection.toList();
+ FSMove move = new FSMove(nodes, dest);
+ return move.doit();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CacheManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CacheManager.java
index 2da3b1136..9fbab82fa 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CacheManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CacheManager.java
@@ -8,6 +8,8 @@
* Wind River Systems - initial API and implementation
* William Chen (Wind River)- [345387] Open the remote files with a proper editor
* William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
@@ -25,7 +27,9 @@ import java.text.DecimalFormat;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.osgi.util.NLS;
@@ -379,11 +383,18 @@ public class CacheManager {
}
if(!monitor.isCanceled()){
// Once upload is successful, synchronize the modified time.
- try {
- StateManager.getInstance().commitState(nodes[i]);
- } catch (TCFException tcfe) {
- throw new IOException(tcfe.getLocalizedMessage());
- }
+ final FSTreeNode node = nodes[i];
+ SafeRunner.run(new ISafeRunnable() {
+ @Override
+ public void handleException(Throwable exception) {
+ // Just ignore it.
+ }
+
+ @Override
+ public void run() throws Exception {
+ StateManager.getInstance().updateState(node);
+ }
+ });
}
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/ClipboardPropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/ClipboardPropertyTester.java
new file mode 100644
index 000000000..389d3bfec
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/ClipboardPropertyTester.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
+
+import java.net.URL;
+import java.util.List;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+/**
+ * Provide a tester to test if the paste operation is enabled.
+ */
+public class ClipboardPropertyTester extends PropertyTester {
+
+ /**
+ * Create an instance.
+ */
+ public ClipboardPropertyTester() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if (property.equals("canPaste")) { //$NON-NLS-1$
+ FSClipboard cb = UIPlugin.getDefault().getClipboard();
+ if (!cb.isEmpty()) {
+ int operation = cb.getOperation();
+ List<URL> urls = cb.getFiles();
+ for (URL url : urls) {
+ FSTreeNode node = FSModel.getInstance().getTreeNode(url);
+ if (node != null) {
+ if (operation == FSClipboard.COPY) {
+ // If it is not a windows node and it is not readable,
+ // then it cannot be moved.
+ if (!node.isWindowsNode() && !node.isReadable()) return false;
+ }
+ else if (operation == FSClipboard.CUT) {
+ // If it is a windows node and is read only, or it is not
+ // a windows node and is not writable, then it cannot be moved.
+ if (node.isWindowsNode() && node.isReadOnly() || !node.isWindowsNode() && !node.isWritable()) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CopyFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CopyFilesHandler.java
new file mode 100644
index 000000000..bb70e169f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CopyFilesHandler.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.ui.handlers.HandlerUtil;
+/**
+ * The handler that copies the selected files or folders to the clip board.
+ */
+public class CopyFilesHandler extends AbstractHandler {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ FSClipboard cb = UIPlugin.getDefault().getClipboard();
+ List<URL> files = new ArrayList<URL>();
+ IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelection(event);
+ List<FSTreeNode> nodes = selection.toList();
+ for (FSTreeNode node : nodes) {
+ files.add(node.getLocationURL());
+ }
+ // Copy these files to the clip board.
+ cb.copyFiles(files);
+ // Refresh the file system tree to display the decorations of the cut nodes.
+ FSModel.getInstance().fireNodeStateChanged(null);
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutDecorator.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutDecorator.java
new file mode 100644
index 000000000..7063fce46
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutDecorator.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
+
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.tcf.te.ui.jface.images.AbstractImageDescriptor;
+/**
+ * The label decorator to decorate the FSTreeNodes that are cut to the clip board.
+ */
+public class CutDecorator extends LabelProvider implements ILabelDecorator {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ILabelDecorator#decorateImage(org.eclipse.swt.graphics.Image, java.lang.Object)
+ */
+ @Override
+ public Image decorateImage(Image image, Object element) {
+ if (element instanceof FSTreeNode && image != null) {
+ // Create the cut image for the image to be decorated.
+ AbstractImageDescriptor descriptor = new CutImageDescriptor(image);
+ return UIPlugin.getSharedImage(descriptor);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ILabelDecorator#decorateText(java.lang.String, java.lang.Object)
+ */
+ @Override
+ public String decorateText(String text, Object element) {
+ // Do not decorate its label.
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutFilesHandler.java
new file mode 100644
index 000000000..4c22b616f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutFilesHandler.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * The handler that cuts the selected files or folders to the clip board.
+ */
+public class CutFilesHandler extends AbstractHandler {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ FSClipboard cb = UIPlugin.getDefault().getClipboard();
+ List<URL> files = new ArrayList<URL>();
+ IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelection(event);
+ List<FSTreeNode> nodes = selection.toList();
+ for (FSTreeNode node : nodes) {
+ files.add(node.getLocationURL());
+ }
+ // Cut these files to the clip board.
+ cb.cutFiles(files);
+ // Refresh the file system tree to display the decorations of the cut nodes.
+ FSModel.getInstance().fireNodeStateChanged(null);
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutImageDescriptor.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutImageDescriptor.java
new file mode 100644
index 000000000..f4410831e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/CutImageDescriptor.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts;
+import org.eclipse.tcf.te.ui.jface.images.AbstractImageDescriptor;
+
+/**
+ * Cut image descriptor implementation.
+ */
+public class CutImageDescriptor extends AbstractImageDescriptor {
+ // The key to store the cut mask image.
+ private static final String ID_FS_NODE_CUT_MASK = "FS_NODE_CUT_MASK@"; //$NON-NLS-1$
+ // The key to store the cut decoration image.
+ private static final String ID_FS_NODE_CUT = "FS_NODE_CUT@"; //$NON-NLS-1$
+ // the base image to decorate with overlays
+ private Image baseImage;
+
+ /**
+ * Constructor.
+ */
+ public CutImageDescriptor(final Image baseImage) {
+ super(UIPlugin.getDefault().getImageRegistry());
+ this.baseImage = baseImage;
+ // build up the key for the image registry
+ String key = ID_FS_NODE_CUT + baseImage.hashCode();
+ setDecriptorKey(key);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.resource.CompositeImageDescriptor#drawCompositeImage(int, int)
+ */
+ @Override
+ protected void drawCompositeImage(int width, int height) {
+ drawCentered(baseImage, width, height);
+ drawCentered(getMaskImage(), width, height);
+ }
+
+ /**
+ * Get the mask image of the base image. The mask image is an image which
+ * has the data of the decorator image and the transparent mask of the
+ * base image. The decorator image (the key of which is CUT_DECORATOR_IMAGE)
+ * is a translucent white board, which will be drawn over the base image and
+ * make the base image sightly lighter. Try to the cut a file in a file explorer
+ * on Windows host, you'll see its icon is changed to a lighter version. The
+ * mask image created by this method will be drawn over the base image and
+ * generate the similar effect.
+ *
+ * @return The mask image used to decorate the base image.
+ */
+ private Image getMaskImage() {
+ String maskKey = ID_FS_NODE_CUT_MASK + baseImage.hashCode();
+ Image maskImage = UIPlugin.getImage(maskKey);
+ if (maskImage == null) {
+ Image cutImage = UIPlugin.getImage(ImageConsts.CUT_DECORATOR_IMAGE);
+ ImageData cutSrcData = cutImage.getImageData();
+ ImageData baseData = baseImage.getImageData();
+ // Get the base image's transparency mask.
+ ImageData transparencyMask = baseData.getTransparencyMask();
+ // Mask the decorator image.
+ maskImage = new Image(baseImage.getDevice(), cutSrcData, transparencyMask);
+ UIPlugin.getDefault().getImageRegistry().put(maskKey, maskImage);
+ }
+ return maskImage;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.resource.CompositeImageDescriptor#getSize()
+ */
+ @Override
+ protected Point getSize() {
+ return new Point(baseImage.getImageData().width, baseImage.getImageData().height);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.ide.util.ui.AbstractImageDescriptor#getBaseImage()
+ */
+ @Override
+ protected Image getBaseImage() {
+ return baseImage;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/DeleteFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/DeleteFilesHandler.java
new file mode 100644
index 000000000..e5283de7e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/DeleteFilesHandler.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
+
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSDelete;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.ui.handlers.HandlerUtil;
+/**
+ * The handler that deletes the selected files or folders from the file system.
+ */
+public class DeleteFilesHandler extends AbstractHandler {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IStructuredSelection selection = (IStructuredSelection) HandlerUtil
+ .getCurrentSelection(event);
+ List<FSTreeNode> nodes = selection.toList();
+ String question;
+ if (nodes.size() == 1) {
+ FSTreeNode node = nodes.get(0);
+ question = NLS.bind(Messages.DeleteFilesHandler_DeleteOneFileConfirmation, node.name);
+ }
+ else {
+ question = NLS.bind(Messages.DeleteFilesHandler_DeleteMultipleFilesConfirmation, Integer.valueOf(nodes.size()));
+ }
+ Shell parent = HandlerUtil.getActiveShellChecked(event);
+ if (MessageDialog.openQuestion(parent, Messages.DeleteFilesHandler_ConfirmDialogTitle, question)) {
+ FSDelete delete = new FSDelete(nodes);
+ delete.doit();
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/FSTreeNodePropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/FSTreeNodePropertyTester.java
index 1d8e5b2b5..c915a6c1d 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/FSTreeNodePropertyTester.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/FSTreeNodePropertyTester.java
@@ -9,22 +9,32 @@
* William Chen (Wind River) - [345387]Open the remote files with a proper editor
* William Chen (Wind River) - [352302]Opening a file in an editor depending on
* the client's permissions.
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
import java.io.File;
+import java.net.URL;
+import java.util.List;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard;
import org.eclipse.tcf.te.tcf.filesystem.model.CacheState;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
/**
* The property tester of an FSTreeNode. The properties include "isFile"
* if it is a file node, "isDirectory" if it is a directory, "isBinaryFile"
* if it is a binary file, "isReadable" if it is readable, "isWritable" if
- * it is writable, "isExecutable" if it is executable and "getCacheState" to
- * get a node's state.
+ * it is writable, "isExecutable" if it is executable, "isRoot" if it is a
+ * root directory, "isWindows" if it is a windows file node, "isReadOnly"
+ * if it is read only, "isHidden" if it is hidden, "getCacheState" to
+ * get a node's state, and "isSamePeer" to test if the selected folder is
+ * from the same peer with the files in the clip board.
*/
public class FSTreeNodePropertyTester extends PropertyTester {
@@ -47,12 +57,34 @@ public class FSTreeNodePropertyTester extends PropertyTester {
return node.isWritable();
} else if (property.equals("isExecutable")){ //$NON-NLS-1$
return node.isExecutable();
+ } else if (property.equals("isRoot")) { //$NON-NLS-1$
+ return node.isRoot();
+ } else if (property.equals("isWindows")) { //$NON-NLS-1$
+ return node.isWindowsNode();
+ } else if (property.equals("isReadOnly")) { //$NON-NLS-1$
+ return node.isReadOnly();
+ } else if (property.equals("isHidden")) { //$NON-NLS-1$
+ return node.isHidden();
} else if (property.equals("getCacheState")){ //$NON-NLS-1$
File file = CacheManager.getInstance().getCacheFile(node);
if(!file.exists())
return false;
CacheState state = StateManager.getInstance().getCacheState(node);
return state.name().equals(expectedValue);
+ } else if (property.equals("isSamePeer")) { //$NON-NLS-1$
+ String id = node.peerNode.getPeer().getID();
+ FSClipboard cb = UIPlugin.getDefault().getClipboard();
+ if (!cb.isEmpty()) {
+ List<URL> urls = cb.getFiles();
+ for (URL url : urls) {
+ FSTreeNode clipped = FSModel.getInstance().getTreeNode(url);
+ String cid = clipped.peerNode.getPeer().getID();
+ if(!id.equals(cid)){
+ return false;
+ }
+ }
+ return true;
+ }
}
return false;
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/MoveFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/MoveFilesHandler.java
new file mode 100644
index 000000000..f4b452fbe
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/MoveFilesHandler.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
+
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.dialogs.FSFolderSelectionDialog;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSMove;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.ui.handlers.HandlerUtil;
+/**
+ * The handler that moves the selected files or folders to a destination folder.
+ */
+public class MoveFilesHandler extends AbstractHandler {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ Shell shell = HandlerUtil.getActiveShellChecked(event);
+ FSFolderSelectionDialog dialog = new FSFolderSelectionDialog(shell);
+ IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelection(event);
+ List<FSTreeNode> nodes = selection.toList();
+ IPeerModel peer = nodes.get(0).peerNode;
+ dialog.setInput(peer);
+ dialog.setMovedNodes(nodes);
+ if (dialog.open() == Window.OK) {
+ Object obj = dialog.getFirstResult();
+ Assert.isTrue(obj instanceof FSTreeNode);
+ FSTreeNode dest = (FSTreeNode) obj;
+ FSMove fsop = new FSMove(nodes, dest);
+ fsop.doit();
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PasteFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PasteFilesHandler.java
new file mode 100644
index 000000000..f48ec1b65
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PasteFilesHandler.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSClipboard;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSCopy;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSMove;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.ui.handlers.HandlerUtil;
+/**
+ * The handler that pastes the files or folders in the clip board.
+ */
+public class PasteFilesHandler extends AbstractHandler {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ FSClipboard cb = UIPlugin.getDefault().getClipboard();
+ if (!cb.isEmpty()) {
+ // Get the files/folders from the clip board.
+ List<FSTreeNode> nodes = new ArrayList<FSTreeNode>();
+ List<URL> files = cb.getFiles();
+ for (URL file : files) {
+ FSTreeNode node = FSModel.getInstance().getTreeNode(file);
+ nodes.add(node);
+ }
+ // Get the destination folder.
+ IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(event);
+ FSTreeNode dest = (FSTreeNode) selection.getFirstElement();
+ int operation = cb.getOperation();
+ FSOperation fsop;
+ if (operation == FSClipboard.COPY) {
+ // Copy action.
+ fsop = new FSCopy(nodes, dest);
+ }
+ else {
+ // Cut action.
+ fsop = new FSMove(nodes, dest);
+ }
+ fsop.doit();
+ }
+ return null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PersistenceManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PersistenceManager.java
index 2b0d8405f..fa9015259 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PersistenceManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/PersistenceManager.java
@@ -7,6 +7,8 @@
* Contributors:
* William Chen (Wind River) [360494]Provide an "Open With" action in the pop
* up menu of file system nodes of Target Explorer.
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
@@ -181,6 +183,42 @@ public class PersistenceManager {
}
/**
+ * If the option of "in-place editor" is set to on.
+ *
+ * @return true if it uses in-place editor when renaming files/folders.
+ */
+ public boolean isInPlaceEditor() {
+ IPreferenceStore preferenceStore = UIPlugin.getDefault().getPreferenceStore();
+ boolean autoSaving = preferenceStore
+ .getBoolean(TargetExplorerPreferencePage.PREF_RENAMING_IN_PLACE_EDITOR);
+ return autoSaving;
+ }
+
+ /**
+ * If the option of "copy permissions" is set to on.
+ *
+ * @return true if it should copy source file permissions.
+ */
+ public boolean isCopyPermission() {
+ IPreferenceStore preferenceStore = UIPlugin.getDefault().getPreferenceStore();
+ boolean autoSaving = preferenceStore
+ .getBoolean(TargetExplorerPreferencePage.PREF_COPY_PERMISSION);
+ return autoSaving;
+ }
+
+ /**
+ * If the option of "copy ownership" is set to on.
+ *
+ * @return true if it should copy source file ownership.
+ */
+ public boolean isCopyOwnership() {
+ IPreferenceStore preferenceStore = UIPlugin.getDefault().getPreferenceStore();
+ boolean autoSaving = preferenceStore
+ .getBoolean(TargetExplorerPreferencePage.PREF_COPY_OWNERSHIP);
+ return autoSaving;
+ }
+
+ /**
* Load the persistent properties from the persistent file in the cache's root directory.
*/
private void loadPersistentProperties() {
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RenameFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RenameFilesHandler.java
new file mode 100644
index 000000000..a4b9d1368
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/RenameFilesHandler.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.internal.celleditor.FSCellValidator;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation;
+import org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSRename;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.tcf.te.ui.dialogs.RenameDialog;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * The handler that renames the selected file or folder.
+ */
+public class RenameFilesHandler extends AbstractHandler {
+ // The currently focused viewer.
+ private static TreeViewer CurrentViewer;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IStructuredSelection sel = (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(event);
+ if (!sel.isEmpty()) {
+ FSTreeNode node = (FSTreeNode) sel.getFirstElement();
+ boolean inPlaceEditor = PersistenceManager.getInstance().isInPlaceEditor();
+ if (inPlaceEditor) {
+ // If it is configured to use in-place editor, then invoke the editor.
+ if (CurrentViewer != null) {
+ Control control = CurrentViewer.getControl();
+ if (!control.isDisposed()) {
+ CurrentViewer.editElement(node, 0);
+ }
+ }
+ }
+ else {
+ Shell shell = HandlerUtil.getActiveShellChecked(event);
+ RenameDialog dialog = createRenameDialog(shell, node);
+ int ok = dialog.open();
+ if (ok == Window.OK) {
+ // Do the renaming.
+ String newName = dialog.getNewName();
+ FSRename op = new FSRename(node, newName);
+ op.doit();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create a renaming dialog for the specified file/folder node.
+ *
+ * @param shell The parent shell.
+ * @param node The file/folder node.
+ * @return The renaming dialog.
+ */
+ private RenameDialog createRenameDialog(Shell shell, FSTreeNode node) {
+ String[] names = getUsedNames(node);
+ String title;
+ if (node.isFile()) {
+ title = Messages.RenameFilesHandler_TitleRenameFile;
+ }
+ else if (node.isDirectory()) {
+ title = Messages.RenameFilesHandler_TitleRenameFolder;
+ }
+ else {
+ title = Messages.RenameFilesHandler_TitleRename;
+ }
+ String formatRegex;
+ if (node.isWindowsNode()) {
+ formatRegex = FSCellValidator.WIN_FILENAME_REGEX;
+ }
+ else {
+ formatRegex = FSCellValidator.UNIX_FILENAME_REGEX;
+ }
+ String error;
+ if (node.isWindowsNode()) {
+ error = Messages.FSRenamingAssistant_WinIllegalCharacters;
+ }
+ else {
+ error = Messages.FSRenamingAssistant_UnixIllegalCharacters;
+ }
+ String prompt = Messages.RenameFilesHandler_RenamePromptMessage;
+ String usedError = Messages.FSRenamingAssistant_NameAlreadyExists;
+ String label = Messages.RenameFilesHandler_PromptNewName;
+ return new RenameDialog(shell, title, prompt, usedError, error, label, node.name, formatRegex, names, null);
+ }
+
+ /**
+ * Get the used names in the specified folder.
+ *
+ * @param folder The folder.
+ * @return Used names.
+ */
+ private String[] getUsedNames(FSTreeNode folder) {
+ List<String> usedNames = new ArrayList<String>();
+ List<FSTreeNode> nodes = new ArrayList<FSTreeNode>(FSOperation.getCurrentChildren(folder.parent));
+ for (FSTreeNode node : nodes) {
+ usedNames.add(node.name);
+ }
+ return usedNames.toArray(new String[usedNames.size()]);
+ }
+
+ /**
+ * Set the currently focused tree viewer. Called by Target Explorer and FSTreeControl to set the
+ * current viewer.
+ *
+ * @param viewer The currently focused tree viewer.
+ */
+ public static void setCurrentViewer(TreeViewer viewer) {
+ CurrentViewer = viewer;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java
index 905a3f8f1..ede34d842 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/StateManager.java
@@ -7,6 +7,8 @@
* Contributors:
* Wind River Systems - initial API and implementation
* William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
@@ -150,22 +152,6 @@ public class StateManager {
}
/**
- * Commit the content of the local file to the target.
- *
- * @param node The tree node whose local file is going to committed.
- * @throws TCFException
- */
- public void commitState(final FSTreeNode node) throws TCFException {
- File file = CacheManager.getInstance().getCacheFile(node);
- Assert.isTrue(file.exists());
- long mtime = file.lastModified();
- // Create the new file attribute based on the file's last modified time.
- IFileSystem.FileAttrs attrs = new IFileSystem.FileAttrs(node.attr.flags, node.attr.size, node.attr.uid, node.attr.gid, node.attr.permissions, node.attr.atime, mtime,
- node.attr.attributes);
- setFileAttrs(node, attrs);
- }
-
- /**
* Set the file's attributes using the new attributes.
*
* @param node The file's node.
@@ -227,7 +213,7 @@ public class StateManager {
@Override
public void doneOpenChannel(Throwable error, IChannel channel) {
if(error!=null){
- String message = NLS.bind(Messages.TCFUtilities_OpeningFailureMessage,
+ String message = NLS.bind(Messages.OpeningChannelFailureMessage,
new Object[]{peer.getID(), error.getLocalizedMessage()});
errors[0] = new TCFChannelException(message, error);
}else{
@@ -238,7 +224,7 @@ public class StateManager {
try {
rendezvous.waiting(5000L);
} catch (InterruptedException e) {
- String message = NLS.bind(Messages.TCFUtilities_OpeningFailureMessage,
+ String message = NLS.bind(Messages.OpeningChannelFailureMessage,
new Object[]{peer.getID(), e.getLocalizedMessage()});
errors[0] = new TCFChannelException(message, e);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java
index c929f200b..c57926f84 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/handlers/UserManager.java
@@ -7,6 +7,8 @@
* Contributors:
* Wind River Systems - initial API and implementation
* William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.internal.handlers;
@@ -139,7 +141,7 @@ public class UserManager {
@Override
public void doneOpenChannel(Throwable error, IChannel channel) {
if(error!=null){
- String message = NLS.bind(Messages.TCFUtilities_OpeningFailureMessage,
+ String message = NLS.bind(Messages.OpeningChannelFailureMessage,
new Object[]{peer.getID(), error.getLocalizedMessage()});
errors[0] = new TCFChannelException(message, error);
}else{
@@ -150,7 +152,7 @@ public class UserManager {
try {
rendezvous.waiting(5000L);
} catch (InterruptedException e) {
- String message = NLS.bind(Messages.TCFUtilities_OpeningFailureMessage,
+ String message = NLS.bind(Messages.OpeningChannelFailureMessage,
new Object[]{peer.getID(), e.getLocalizedMessage()});
errors[0] = new TCFChannelException(message, e);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.java
index 4f53d7fea..6965b4306 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.java
@@ -115,11 +115,28 @@ public class Messages extends NLS {
public static String CmmitHandler_StateChangedDialogTitle;
public static String CmmitHandler_StateChangedMessage;
+ public static String FSDelete_ButtonCancel;
+ public static String FSDelete_ButtonNo;
+ public static String FSDelete_ButtonYes;
+ public static String FSDelete_ButtonYes2All;
+ public static String FSDelete_CannotRemoveFile;
+ public static String FSDelete_CannotRemoveFolder;
+ public static String FSDelete_ConfirmDelete;
+ public static String FSDelete_ConfirmMessage;
+ public static String FSDelete_Deleting;
+ public static String FSDelete_PrepareToDelete;
+ public static String FSDelete_RemovingFileFolder;
+
+ public static String DeleteFilesHandler_DeleteMultipleFilesConfirmation;
+ public static String DeleteFilesHandler_DeleteOneFileConfirmation;
+ public static String DeleteFilesHandler_ConfirmDialogTitle;
+
public static String GeneralInformationPage_Accessed;
public static String GeneralInformationPage_Advanced;
public static String GeneralInformationPage_Attributes;
public static String GeneralInformationPage_Computer;
public static String GeneralInformationPage_File;
+ public static String GeneralInformationPage_FileSizeInfo;
public static String GeneralInformationPage_Folder;
public static String GeneralInformationPage_Hidden;
public static String GeneralInformationPage_Location;
@@ -128,17 +145,25 @@ public class Messages extends NLS {
public static String GeneralInformationPage_ReadOnly;
public static String GeneralInformationPage_Size;
public static String GeneralInformationPage_Type;
+ public static String GeneralInformationPage_PermissionText;
public static String GeneralInformationPage_PropertiesChangeFailure;
public static String GeneralInformationPage_PropertiesChangeTitle;
public static String GeneralInformationPage_UnknownFileType;
public static String FSExplorerTreeControl_section_title;
+ public static String FSFolderSelectionDialog_MoveDialogMessage;
+ public static String FSFolderSelectionDialog_MoveDialogTitle;
public static String FSTreeControl_column_name_label;
public static String FSTreeControl_column_size_label;
public static String FSTreeControl_column_modified_label;
+ public static String FSTreeNodeDropAdapterAssistant_DragError;
+ public static String FSTreeNodeDropAdapterAssistant_MoveFailure;
+ public static String FSTreeNodeDropAdapterAssistant_NoFileSelected;
public static String FSOpenFileDialog_title;
+ public static String FSOperation_CopyNOfFile;
+ public static String FSOperation_CopyOfFile;
public static String LocalTypedElement_SavingFile;
@@ -155,6 +180,39 @@ public class Messages extends NLS {
public static String OpenWithMenu_NoEditorFound;
public static String OpenWithMenu_OpenWith;
+ public static String FSCopy_CannotCopyFile;
+ public static String FSCopy_CopyFileFolderTitle;
+ public static String FSCopy_Copying;
+ public static String FSCopy_CopyingFile;
+ public static String FSCopy_PrepareToCopy;
+
+ public static String FSMove_CannotMove;
+ public static String FSMove_FileExistsError;
+ public static String FSMove_FolderExistsError;
+ public static String FSMove_MovingFile;
+ public static String FSMove_Moving;
+ public static String FSMove_PrepareToMove;
+ public static String FSMove_MoveFileFolderTitle;
+
+ public static String FSDelete_DeleteFileFolderTitle;
+
+ public static String FSRename_CannotRename;
+ public static String FSRename_RenameFileFolderTitle;
+
+ public static String FSOperation_CannotCreateDirectory;
+ public static String FSOperation_ConfirmDialogCancel;
+ public static String FSOperation_ConfirmDialogNo;
+ public static String FSOperation_ConfirmDialogYes;
+ public static String FSOperation_ConfirmDialogYesToAll;
+ public static String FSOperation_ConfirmFileReplace;
+ public static String FSOperation_ConfirmFileReplaceMessage;
+ public static String FSOperation_ConfirmFolderReplaceMessage;
+ public static String FSOperation_ConfirmFolderReplaceTitle;
+ public static String FSOperation_NoFileSystemError;
+ public static String FSOperation_CannotOpenDir;
+ public static String FSOperation_CannotReadDir;
+ public static String FSOperation_TimedOutWhenOpening;
+
public static String PermissionsGroup_Executable;
public static String PermissionsGroup_GroupPermissions;
public static String PermissionsGroup_OtherPermissions;
@@ -163,6 +221,16 @@ public class Messages extends NLS {
public static String PermissionsGroup_Writable;
public static String RemoteTypedElement_GettingRemoteContent;
+ public static String RenameFilesHandler_PromptNewName;
+ public static String RenameFilesHandler_RenamePromptMessage;
+ public static String RenameFilesHandler_TitleRename;
+ public static String RenameFilesHandler_TitleRenameFile;
+ public static String RenameFilesHandler_TitleRenameFolder;
+ public static String FSRenamingAssistant_NameAlreadyExists;
+ public static String FSRenamingAssistant_NoNodeSelected;
+ public static String FSRenamingAssistant_SpecifyNonEmptyName;
+ public static String FSRenamingAssistant_UnixIllegalCharacters;
+ public static String FSRenamingAssistant_WinIllegalCharacters;
public static String SaveAllListener_Cancel;
public static String SaveAllListener_Merge;
@@ -186,6 +254,10 @@ public class Messages extends NLS {
public static String StateManager_TCFNotProvideFSMessage2;
public static String StateManager_UpdateFailureTitle;
+ public static String TargetExplorerPreferencePage_AutoSavingText;
+ public static String TargetExplorerPreferencePage_CopyOwnershipText;
+ public static String TargetExplorerPreferencePage_CopyPermissionText;
+ public static String TargetExplorerPreferencePage_RenamingOptionText;
public static String TcfInputStream_CloseTimeout;
public static String TcfInputStream_NoDataAvailable;
public static String TcfInputStream_NoFileReturned;
@@ -205,8 +277,8 @@ public class Messages extends NLS {
public static String TcfURLConnection_OpenFileTimeout;
public static String TcfURLConnection_OpenTCFChannelTimeout;
- public static String TCFUtilities_OpeningFailureMessage;
- public static String TCFUtilities_OpeningFailureTitle;
+ public static String OpeningChannelFailureMessage;
+ public static String OpeningChannelFailureTitle;
public static String UpdateHandler_Cancel;
public static String UpdateHandler_Merge;
@@ -218,4 +290,10 @@ public class Messages extends NLS {
public static String UserManager_CannotGetUserAccountMessage2;
public static String UserManager_TCFNotProvideFSMessage;
public static String UserManager_UserAccountTitle;
+
+ public static String MergeEditorInput_CompareLeftAndRight;
+ public static String MergeEditorInput_CompareWithLocalCache;
+ public static String MergeEditorInput_LocalFile;
+ public static String MergeEditorInput_RemoteFile;
+ public static String MergeInput_CopyNotSupported;
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.properties
index 1744e2a71..2a90699db 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.properties
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/nls/Messages.properties
@@ -4,17 +4,25 @@
#
FSExplorerTreeControl_section_title=Exploring File System
+FSFolderSelectionDialog_MoveDialogMessage=Choose destination for the files to be moved:
+FSFolderSelectionDialog_MoveDialogTitle=Move Files and Folders
FSTreeControl_column_name_label=Name
FSTreeControl_column_size_label=Size
FSTreeControl_column_modified_label=Date Modified
+FSTreeNodeDropAdapterAssistant_DragError=Cannot drag to itself you its ancestor\!
+FSTreeNodeDropAdapterAssistant_MoveFailure=Moving failed\!
+FSTreeNodeDropAdapterAssistant_NoFileSelected=No file is selected yet\!
FSOpenFileDialog_title=Select Process Image
+FSOperation_CopyNOfFile=Copy ({0}) of {1}
+FSOperation_CopyOfFile=Copy of {0}
GeneralInformationPage_Accessed=Accessed:
GeneralInformationPage_Advanced=\ A&dvanced...
GeneralInformationPage_Attributes=Attributes:
GeneralInformationPage_File=File ({0})
+GeneralInformationPage_FileSizeInfo={0} KB ({1} bytes)
GeneralInformationPage_Folder=Folder
GeneralInformationPage_Hidden=Hidden
GeneralInformationPage_ReadOnly=Read-only
@@ -24,6 +32,7 @@ GeneralInformationPage_Modified=Modified:
GeneralInformationPage_Name=Name:
GeneralInformationPage_Size=Size:
GeneralInformationPage_Type=Type:
+GeneralInformationPage_PermissionText=Permissions:
GeneralInformationPage_PropertiesChangeFailure=Properties changes to {0} failed due to the following reason:{1}
GeneralInformationPage_PropertiesChangeTitle=Properties Change
GeneralInformationPage_UnknownFileType=Unknown File
@@ -72,6 +81,20 @@ CmmitHandler_FileDeleted=The local file {0} that you are trying to commit has be
CmmitHandler_Merge=Merge
CmmitHandler_StateChangedDialogTitle=State Changed
CmmitHandler_StateChangedMessage={0} on the target has changed and is conflicting with the local file. What do you want?
+FSDelete_ButtonCancel=Cancel
+FSDelete_ButtonNo=&No
+FSDelete_ButtonYes=&Yes
+FSDelete_ButtonYes2All=Yes to &All
+FSDelete_CannotRemoveFile=Cannot remove the file {0}\!. Caused by {1}
+FSDelete_CannotRemoveFolder=Cannot remove the folder {0}\!. Caused by {1}
+FSDelete_ConfirmDelete=Confirm Delete
+DeleteFilesHandler_ConfirmDialogTitle=Confirm Delete
+FSDelete_ConfirmMessage=Are you sure you want to remove the read-only file {0}?
+DeleteFilesHandler_DeleteMultipleFilesConfirmation=Are you sure you want to delete these {0} files/folders?
+DeleteFilesHandler_DeleteOneFileConfirmation=Are you sure you want to delete {0}?
+FSDelete_Deleting=Deleting files
+FSDelete_PrepareToDelete=Prepare to delete files ...
+FSDelete_RemovingFileFolder=Removing {0} ...
LocalTypedElement_SavingFile=Saving file:
@@ -88,6 +111,31 @@ OpenWithMenu_DefaultEditor=&Default Editor
OpenWithMenu_NoEditorFound=No editor found to edit the file resource.
OpenWithMenu_OpenWith=Open With
+FSCopy_CannotCopyFile=Cannot copy file {0} because: {1}
+FSOperation_CannotCreateDirectory=Cannot create the directory {0} because: {1}
+FSMove_CannotMove=Cannot move {0} because {1}
+FSMove_FileExistsError=Cannot replace {0}: There is already a file with the same name as the folder you are moving.
+FSMove_FolderExistsError=Cannot replace {0}: There is already a folder with the same name as the file you are moving.
+FSRename_CannotRename=Cannot rename {0} because {1}
+FSOperation_ConfirmDialogCancel=Cancel
+FSOperation_ConfirmDialogNo=&No
+FSOperation_ConfirmDialogYes=&Yes
+FSOperation_ConfirmDialogYesToAll=Yes to &All
+FSOperation_ConfirmFileReplace=Confirm File Replace
+FSOperation_ConfirmFileReplaceMessage=This folder already contains a file named {0}.\n\n If the files in the existing folder have the same name as files in the folder you are moving or copying, they will be replaced. Do you still want to move or copy the file?
+FSOperation_ConfirmFolderReplaceMessage=This folder already contains a folder named {0}.\n\n If the files in the existing folder have the same name as files in the folder you are moving or copying, they will be replaced. Do you still want to move or copy the folder?
+FSOperation_ConfirmFolderReplaceTitle=Confirm Folder Replace
+FSCopy_CopyFileFolderTitle=Error Copying File or Folder
+FSMove_MoveFileFolderTitle=Error Moving File or Folder
+FSRename_RenameFileFolderTitle=Error Renaming File or Folder
+FSDelete_DeleteFileFolderTitle=Error Deleting File or Folder
+FSCopy_Copying=Copying {0} ...
+FSCopy_CopyingFile=Copying files
+FSMove_MovingFile=Moving files
+FSMove_Moving=Moving {0} ...
+FSOperation_NoFileSystemError=This TCF agent, {0}, does not provide a file system service\!
+FSCopy_PrepareToCopy=Prepare to copy files ...
+FSMove_PrepareToMove=Prepare to move files...
PermissionsGroup_Executable=Executable
PermissionsGroup_GroupPermissions=Group:
PermissionsGroup_OtherPermissions=Other:
@@ -96,6 +144,16 @@ PermissionsGroup_UserPermissions=User:
PermissionsGroup_Writable=Writable
RemoteTypedElement_GettingRemoteContent=Getting content from the remote file:
+RenameFilesHandler_PromptNewName=New name:
+RenameFilesHandler_RenamePromptMessage=Please enter a new name
+RenameFilesHandler_TitleRename=Rename
+RenameFilesHandler_TitleRenameFile=Rename File
+RenameFilesHandler_TitleRenameFolder=Rename Folder
+FSRenamingAssistant_NameAlreadyExists=A file/folder with the name you specified already exists\! Specify a different name.
+FSRenamingAssistant_NoNodeSelected=No node is selected.
+FSRenamingAssistant_SpecifyNonEmptyName=Specify a non-empty name.
+FSRenamingAssistant_UnixIllegalCharacters=A file/folder name cannot contain any of the following characters:\n/
+FSRenamingAssistant_WinIllegalCharacters=A file/folder name cannot contain any of the following characters:\n\\/:*?<>|
SaveAllListener_Cancel=Cancel
SaveAllListener_Merge=Merge
@@ -119,6 +177,10 @@ StateManager_TCFNotProvideFSMessage=This TCF agent, {0}, does not provide a file
StateManager_TCFNotProvideFSMessage2=This TCF agent, {0}, does not provide a file system service\!
StateManager_UpdateFailureTitle=Update Failure
+TargetExplorerPreferencePage_AutoSavingText=Automatically upload files to targets upon saving.
+TargetExplorerPreferencePage_CopyOwnershipText=Copy source UID and GID when copying files.
+TargetExplorerPreferencePage_CopyPermissionText=Copy source permissions when copying files.
+TargetExplorerPreferencePage_RenamingOptionText=Use In-place Editor when renaming a file/folder.
TcfInputStream_CloseTimeout=Closing has timed out\!
TcfInputStream_NoDataAvailable=No data available
TcfInputStream_NoFileReturned=No file handle returned\!
@@ -138,8 +200,8 @@ TcfURLConnection_NoSuchTcfAgent=TCF agent is already disconnected\!
TcfURLConnection_OpenFileTimeout=Opening file has timed out\!
TcfURLConnection_OpenTCFChannelTimeout=Opening TCF channel has timed out\!
-TCFUtilities_OpeningFailureMessage=We cannot open a TCF channel to the target: {0}. It is caused by {1}.
-TCFUtilities_OpeningFailureTitle=Opening Channel
+OpeningChannelFailureMessage=We cannot open a TCF channel to the target: {0}. It is caused by {1}.
+OpeningChannelFailureTitle=Opening Channel
UpdateHandler_Cancel=Cancel
UpdateHandler_Merge=Merge
@@ -151,3 +213,12 @@ UserManager_CannotGetUserAccountMessage=Cannot get the user account from the age
UserManager_CannotGetUserAccountMessage2=Cannot get the user account from the agent {0}. Caused by: networking too slow.
UserManager_TCFNotProvideFSMessage=This TCF agent, {0}, does not provide a file system service\!
UserManager_UserAccountTitle=User Account
+
+FSOperation_CannotOpenDir=Cannot open directory {0} because {1}
+FSOperation_CannotReadDir=Cannot read directory {0} because {1}
+FSOperation_TimedOutWhenOpening=it has timed out when opening the directory\!
+MergeEditorInput_CompareLeftAndRight=Compare {0} and {1}
+MergeEditorInput_CompareWithLocalCache=Compare {0} with Local Cache
+MergeEditorInput_LocalFile=Local: {0}
+MergeEditorInput_RemoteFile=Remote: {0}
+MergeInput_CopyNotSupported=Copy is not support by this type of compare input
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSClipboard.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSClipboard.java
new file mode 100644
index 000000000..4f36d32e6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSClipboard.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.operations;
+
+import java.net.URL;
+import java.util.List;
+
+/**
+ * The clip board to which copy or cut files/folders.
+ */
+public class FSClipboard {
+ // The constants to define the current operation type of the clip board.
+ public static final int NONE = -1;
+ public static final int CUT = 0;
+ public static final int COPY = 1;
+ // The operation type, CUT, COPY or NONE.
+ private int operation;
+ // The currently selected files/folders.
+ private List<URL> files;
+
+ /**
+ * Create a clip board instance.
+ */
+ public FSClipboard() {
+ operation = NONE;
+ }
+
+ /**
+ * If the clip board is empty.
+ *
+ * @return true if the operation is NONE and no files are selected.
+ */
+ public boolean isEmpty() {
+ return operation == NONE && (files == null || files.isEmpty());
+ }
+
+ /**
+ * Return the current operation type.
+ *
+ * @return The operation of the current clip board content.
+ */
+ public int getOperation() {
+ return operation;
+ }
+
+ /**
+ * Get the currently selected files/folders to operated.
+ *
+ * @return The file/folder list using their location URLs.
+ */
+ public List<URL> getFiles() {
+ return files;
+ }
+
+ /**
+ * Cut the specified files/folders to the clip board.
+ *
+ * @param files The file/folder nodes.
+ */
+ public void cutFiles(List<URL> files) {
+ operation = CUT;
+ this.files = files;
+ }
+
+ /**
+ * Copy the specified files/folders to the clip board.
+ *
+ * @param files The file/folder nodes.
+ */
+ public void copyFiles(List<URL> files) {
+ operation = COPY;
+ this.files = files;
+ }
+
+ /**
+ * Clear the clip board.
+ */
+ public void clear() {
+ operation = NONE;
+ this.files = null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java
new file mode 100644
index 000000000..7f2b5df13
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSCopy.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.operations;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IToken;
+import org.eclipse.tcf.services.IFileSystem;
+import org.eclipse.tcf.services.IFileSystem.DoneCopy;
+import org.eclipse.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.PersistenceManager;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.TimeTriggeredProgressMonitorDialog;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * FSCopy copies selected FSTreeNodes to a specify destination folder.
+ */
+public class FSCopy extends FSOperation {
+ // The nodes to be copied.
+ List<FSTreeNode> nodes;
+ // The destination folder to be copied to.
+ FSTreeNode dest;
+
+ /**
+ * Create a copy operation using the specified nodes and destination folder.
+ *
+ * @param nodes The file/folder nodes to be copied.
+ * @param dest The destination folder to be copied to.
+ */
+ public FSCopy(List<FSTreeNode> nodes, FSTreeNode dest) {
+ this.nodes = getTopNodes(nodes);
+ this.dest = dest;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation#doit()
+ */
+ @Override
+ public boolean doit() {
+ IRunnableWithProgress runnable = new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ FSTreeNode head = nodes.get(0);
+ IChannel channel = null;
+ try {
+ channel = openChannel(head.peerNode.getPeer());
+ if (channel != null) {
+ IFileSystem service = channel.getRemoteService(IFileSystem.class);
+ if (service != null) {
+ monitor.beginTask(Messages.FSCopy_PrepareToCopy, IProgressMonitor.UNKNOWN);
+ monitor.worked(1);
+ int count = count(service, nodes);
+ monitor.beginTask(Messages.FSCopy_CopyingFile, count);
+ for (FSTreeNode node : nodes) {
+ // Iterate the nodes and copy each of them to the destination
+ // folder.
+ copyNode(monitor, service, node, dest);
+ }
+ }
+ else {
+ String message = NLS.bind(Messages.FSOperation_NoFileSystemError, head.peerNode.getPeer().getID());
+ throw new TCFFileSystemException(message);
+ }
+ }
+ }
+ catch (TCFException e) {
+ throw new InvocationTargetException(e);
+ }
+ finally {
+ if (channel != null) channel.close();
+ // Refresh the file system tree.
+ FSModel.getInstance().fireNodeStateChanged(null);
+ monitor.done();
+ }
+ }
+ };
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ TimeTriggeredProgressMonitorDialog dialog = new TimeTriggeredProgressMonitorDialog(parent, 250);
+ dialog.setCancelable(true);
+ try {
+ dialog.run(true, true, runnable);
+ }
+ catch (InvocationTargetException e) {
+ // Display the error during copy.
+ MessageDialog.openError(parent, Messages.FSCopy_CopyFileFolderTitle, e.getLocalizedMessage());
+ }
+ catch (InterruptedException e) {
+ // It is canceled.
+ }
+ return true;
+ }
+
+ /**
+ * Copy the file/folder represented by the specified node to the destination folder.
+ *
+ * @param monitor The monitor to report the progress.
+ * @param service The file system service to do the remote copying.
+ * @param node The file/folder node to be copied.
+ * @param dest The destination folder.
+ * @throws TCFFileSystemException The exception thrown during copying
+ * @throws InterruptedException The exception thrown when the operation is canceled.
+ */
+ void copyNode(IProgressMonitor monitor, IFileSystem service, FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException, InterruptedException {
+ if (node.isFile()) {
+ copyFile(monitor, service, node, dest);
+ }
+ else if (node.isDirectory()) {
+ copyFolder(monitor, service, node, dest);
+ }
+ }
+
+ /**
+ * Copy the folder represented by the specified node to the destination folder.
+ *
+ * @param monitor The monitor to report the progress.
+ * @param service The file system service to do the remote copying.
+ * @param node The folder node to be copied.
+ * @param dest The destination folder.
+ * @throws TCFFileSystemException The exception thrown during copying
+ * @throws InterruptedException The exception thrown when the operation is canceled.
+ */
+ private void copyFolder(IProgressMonitor monitor, IFileSystem service, FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException, InterruptedException {
+ if (!monitor.isCanceled()) {
+ FSTreeNode copy = findChild(service, dest, node.name);
+ if (copy == null || confirmReplace(node)) {
+ if (copy == null) {
+ // If no existing directory with the same name, create it.
+ copy = (FSTreeNode) node.clone();
+ addChild(service, dest, copy);
+ mkdir(service, copy);
+ }
+ List<FSTreeNode> children = new ArrayList<FSTreeNode>(getChildren(node, service));
+ if (!children.isEmpty()) {
+ for (FSTreeNode child : children) {
+ // Iterate and copy its children nodes.
+ copyNode(monitor, service, child, copy);
+ }
+ }
+ }
+ monitor.worked(1);
+ }
+ else {
+ throw new InterruptedException();
+ }
+ }
+
+ /**
+ * Copy the file represented by the specified node to the destination folder.
+ *
+ * @param monitor The monitor to report the progress.
+ * @param service The file system service to do the remote copying.
+ * @param node The file node to be copied.
+ * @param dest The destination folder.
+ * @throws TCFFileSystemException The exception thrown during copying
+ * @throws InterruptedException The exception thrown when the operation is canceled.
+ */
+ private void copyFile(IProgressMonitor monitor, IFileSystem service, FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException, InterruptedException {
+ if (!monitor.isCanceled()) {
+ monitor.subTask(NLS.bind(Messages.FSCopy_Copying, node.name));
+ // Create the copy target file
+ final FSTreeNode copy = createCopyFile(service, node, dest);
+ String src_path = node.getLocation(true);
+ String dst_path = copy.getLocation(true);
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ final Rendezvous rendezvous = new Rendezvous();
+ // Get the options of copy permission and ownership.
+ boolean copyPermission = PersistenceManager.getInstance().isCopyPermission();
+ boolean copyOwnership = PersistenceManager.getInstance().isCopyOwnership();
+ service.copy(src_path, dst_path, copyPermission, copyOwnership, new DoneCopy() {
+ @Override
+ public void doneCopy(IToken token, FileSystemException error) {
+ if (error != null) {
+ String message = NLS.bind(Messages.FSCopy_CannotCopyFile, copy.name, error);
+ errors[0] = new TCFFileSystemException(message, error);
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.FSCopy_CannotCopyFile, node.name, Messages.FSOperation_TimedOutWhenOpening);
+ errors[0] = new TCFFileSystemException(message);
+ }
+ if (errors[0] != null) {
+ removeChild(service, dest, copy);
+ throw errors[0];
+ }
+ monitor.worked(1);
+ }
+ else {
+ // Canceled.
+ throw new InterruptedException();
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java
new file mode 100644
index 000000000..2642dbcc0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSDelete.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.operations;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.StateManager;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.TimeTriggeredProgressMonitorDialog;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IToken;
+import org.eclipse.tcf.services.IFileSystem;
+import org.eclipse.tcf.services.IFileSystem.DoneRemove;
+import org.eclipse.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * FSDelete deletes the selected FSTreeNode list.
+ */
+public class FSDelete extends FSOperation {
+ //The nodes to be deleted.
+ List<FSTreeNode> nodes;
+
+ /**
+ * Create a delete operation using the specified nodes.
+ *
+ * @param nodes The nodes to be deleted.
+ */
+ public FSDelete(List<FSTreeNode> nodes) {
+ this.nodes = getTopNodes(nodes);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation#doit()
+ */
+ @Override
+ public boolean doit() {
+ IRunnableWithProgress runnable = new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ FSTreeNode head = nodes.get(0);
+ IChannel channel = null;
+ try {
+ channel = openChannel(head.peerNode.getPeer());
+ if (channel != null) {
+ IFileSystem service = channel.getRemoteService(IFileSystem.class);
+ if (service != null) {
+ monitor.beginTask(Messages.FSDelete_PrepareToDelete, IProgressMonitor.UNKNOWN);
+ monitor.worked(1);
+ int count = count(service, nodes);
+ monitor.beginTask(Messages.FSDelete_Deleting, count);
+ for (FSTreeNode node : nodes) {
+ remove(monitor, node, service);
+ }
+ }
+ else {
+ String message = NLS.bind(Messages.FSOperation_NoFileSystemError, head.peerNode.getPeer().getID());
+ throw new TCFFileSystemException(message);
+ }
+ }
+ }
+ catch (TCFException e) {
+ throw new InvocationTargetException(e);
+ }
+ finally {
+ if (channel != null) channel.close();
+ // Refresh the file system tree.
+ FSModel.getInstance().fireNodeStateChanged(null);
+ monitor.done();
+ }
+ }
+ };
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ TimeTriggeredProgressMonitorDialog dialog = new TimeTriggeredProgressMonitorDialog(parent, 250);
+ dialog.setCancelable(true);
+ try {
+ dialog.run(true, true, runnable);
+ }
+ catch (InvocationTargetException e) {
+ // Display the error message during deleting.
+ MessageDialog.openError(parent, Messages.FSDelete_DeleteFileFolderTitle, e.getLocalizedMessage());
+ }
+ catch (InterruptedException e) {
+ // It is canceled.
+ }
+ return true;
+ }
+
+ /**
+ * Delete the file/folder node using the file system service.
+ *
+ * @param monitor The monitor to report the progress.
+ * @param node The file/folder node to be deleted.
+ * @param service The file system service.
+ * @throws TCFFileSystemException The exception thrown during deleting.
+ * @throws InterruptedException Thrown when the operation is canceled.
+ */
+ void remove(IProgressMonitor monitor, FSTreeNode node, IFileSystem service) throws TCFFileSystemException, InterruptedException {
+ if (node.isFile()) {
+ removeFile(monitor, node, service);
+ }
+ else if (node.isDirectory()) {
+ removeFolder(monitor, node, service);
+ }
+ }
+
+ /**
+ * Delete the folder node and its children using the file system service.
+ *
+ * @param monitor The monitor to report the progress.
+ * @param node The folder node to be deleted.
+ * @param service The file system service.
+ * @throws TCFFileSystemException The exception thrown during deleting.
+ * @throws InterruptedException Thrown when the operation is canceled.
+ */
+ private void removeFolder(IProgressMonitor monitor, final FSTreeNode node, IFileSystem service) throws TCFFileSystemException, InterruptedException {
+ List<FSTreeNode> children = new ArrayList<FSTreeNode>(getChildren(node, service));
+ if (!children.isEmpty()) {
+ for (FSTreeNode child : children) {
+ // Delete each child node.
+ remove(monitor, child, service);
+ }
+ }
+ if (!monitor.isCanceled()) {
+ monitor.subTask(NLS.bind(Messages.FSDelete_RemovingFileFolder, node.name));
+ removeFolder(service, node);
+ monitor.worked(1);
+ }
+ else throw new InterruptedException();
+ }
+
+ /**
+ * Delete the folder node using the file system service.
+ *
+ * @param monitor The monitor to report the progress.
+ * @param node The folder node to be deleted.
+ * @param service The file system service.
+ * @throws TCFFileSystemException The exception thrown during deleting.
+ * @throws InterruptedException Thrown when the operation is canceled.
+ */
+ private void removeFolder(IFileSystem service, final FSTreeNode node) throws TCFFileSystemException {
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ final Rendezvous rendezvous = new Rendezvous();
+ String path = node.getLocation(true);
+ service.rmdir(path, new DoneRemove() {
+ @Override
+ public void doneRemove(IToken token, FileSystemException error) {
+ if (error == null) {
+ cleanUpFolder(node);
+ }
+ else {
+ String message = NLS.bind(Messages.FSDelete_CannotRemoveFolder, node.name, error);
+ errors[0] = new TCFFileSystemException(message, error);
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.FSDelete_CannotRemoveFolder, node.name, Messages.FSOperation_TimedOutWhenOpening);
+ errors[0] = new TCFFileSystemException(message);
+ }
+ if (errors[0] != null) {
+ throw errors[0];
+ }
+ }
+
+ /**
+ * Delete the file node using the file system service.
+ *
+ * @param monitor The monitor to report the progress.
+ * @param node The file node to be deleted.
+ * @param service The file system service.
+ * @throws TCFFileSystemException The exception thrown during deleting.
+ * @throws InterruptedException Thrown when the operation is canceled.
+ */
+ private void removeFile(IProgressMonitor monitor, final FSTreeNode node, IFileSystem service) throws TCFFileSystemException, InterruptedException {
+ if (!monitor.isCanceled()) {
+ monitor.subTask(NLS.bind(Messages.FSDelete_RemovingFileFolder, node.name));
+ // If the file is read only on windows or not writable on unix, then make it deletable.
+ if (node.isWindowsNode() && node.isReadOnly() || !node.isWindowsNode() && !node.isWritable()) {
+ if (!yes2All) {
+ int result = confirmDelete(node);
+ if (result == 1) {
+ yes2All = true;
+ }
+ else if (result == 2) {
+ monitor.worked(1);
+ return;
+ }
+ else if (result == 3) {
+ // Cancel the whole operation
+ throw new InterruptedException();
+ }
+ }
+ final FSTreeNode clone = (FSTreeNode) node.clone();
+ if (node.isWindowsNode()) {
+ clone.setReadOnly(false);
+ }
+ else {
+ clone.setWritable(true);
+ }
+ // Make the file writable.
+ SafeRunner.run(new ISafeRunnable() {
+ @Override
+ public void handleException(Throwable exception) {
+ }
+
+ @Override
+ public void run() throws Exception {
+ StateManager.getInstance().setFileAttrs(node, clone.attr);
+ }
+ });
+ }
+ removeFile(node, service);
+ monitor.worked(1);
+ }
+ else throw new InterruptedException();
+ }
+
+ /**
+ * Confirm deleting the read only file.
+ *
+ * @param node The read only file node.
+ * @return The confirming result, 0-yes, 1-yes to all, 2-no, 3-cancel.
+ */
+ private int confirmDelete(final FSTreeNode node) {
+ final int[] results = new int[1];
+ Display display = PlatformUI.getWorkbench().getDisplay();
+ display.syncExec(new Runnable() {
+ @Override
+ public void run() {
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ String title = Messages.FSDelete_ConfirmDelete;
+ String message = NLS.bind(Messages.FSDelete_ConfirmMessage, node.name);
+ final Image titleImage = UIPlugin.getImage(ImageConsts.DELETE_READONLY_CONFIRM);
+ MessageDialog qDialog = new MessageDialog(parent, title, null, message, MessageDialog.QUESTION, new String[] { Messages.FSDelete_ButtonYes, Messages.FSDelete_ButtonYes2All, Messages.FSDelete_ButtonNo, Messages.FSDelete_ButtonCancel }, 0) {
+ @Override
+ public Image getQuestionImage() {
+ return titleImage;
+ }
+ };
+ results[0] = qDialog.open();
+ }
+ });
+ return results[0];
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java
new file mode 100644
index 000000000..b4f4b34f6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSMove.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.operations;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.TimeTriggeredProgressMonitorDialog;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IToken;
+import org.eclipse.tcf.services.IFileSystem;
+import org.eclipse.tcf.services.IFileSystem.DoneRename;
+import org.eclipse.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * FSMove moves specified tree nodes to a destination folder.
+ */
+public class FSMove extends FSOperation {
+ // The file/folder nodes to be moved.
+ List<FSTreeNode> nodes;
+ // The destination folder to be moved to.
+ FSTreeNode dest;
+
+ /**
+ * Create a move operation to move the specified nodes to the destination folder.
+ *
+ * @param nodes The nodes to be moved.
+ * @param dest the destination folder to move to.
+ */
+ public FSMove(List<FSTreeNode> nodes, FSTreeNode dest) {
+ this.nodes = getTopNodes(nodes);
+ this.dest = dest;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation#doit()
+ */
+ @Override
+ public boolean doit() {
+ IRunnableWithProgress runnable = new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ FSTreeNode head = nodes.get(0);
+ IChannel channel = null;
+ try {
+ channel = openChannel(head.peerNode.getPeer());
+ if (channel != null) {
+ IFileSystem service = channel.getRemoteService(IFileSystem.class);
+ if (service != null) {
+ monitor.beginTask(Messages.FSMove_PrepareToMove, IProgressMonitor.UNKNOWN);
+ monitor.worked(1);
+ monitor.beginTask(Messages.FSMove_MovingFile, nodes.size());
+ for (FSTreeNode node : nodes) {
+ // Move each node.
+ moveNode(monitor, service, node, dest);
+ }
+ }
+ else {
+ String message = NLS.bind(Messages.FSOperation_NoFileSystemError, head.peerNode.getPeer().getID());
+ throw new TCFFileSystemException(message);
+ }
+ }
+ }
+ catch (TCFException e) {
+ throw new InvocationTargetException(e);
+ }
+ finally {
+ // Clear the clip board.
+ UIPlugin.getDefault().getClipboard().clear();
+ if (channel != null) channel.close();
+ // Refresh the file system tree.
+ FSModel.getInstance().fireNodeStateChanged(null);
+ monitor.done();
+ }
+ }
+ };
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ TimeTriggeredProgressMonitorDialog dialog = new TimeTriggeredProgressMonitorDialog(parent, 250);
+ dialog.setCancelable(true);
+ try {
+ dialog.run(true, true, runnable);
+ }
+ catch (InvocationTargetException e) {
+ // Display the error reported during moving.
+ MessageDialog.openError(parent, Messages.FSMove_MoveFileFolderTitle, e.getLocalizedMessage());
+ }
+ catch (InterruptedException e) {
+ // It is canceled.
+ }
+ return true;
+ }
+
+ /**
+ * Move the file/folder to the destination folder using the specified file system service.
+ *
+ * @param monitor The monitor used to report the moving progress.
+ * @param service The file system service used to move the remote files.
+ * @param node The file/folder node to be moved.
+ * @param dest The destination folder.
+ * @throws TCFFileSystemException The exception thrown during moving.
+ * @throws InterruptedException Thrown when the operation is canceled.
+ */
+ void moveNode(IProgressMonitor monitor, IFileSystem service, final FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException, InterruptedException {
+ if (!monitor.isCanceled()) {
+ monitor.subTask(NLS.bind(Messages.FSMove_Moving, node.name));
+ FSTreeNode copy = findChild(service, dest, node.name);
+ if (copy == null || !copy.equals(node) && confirmReplace(node)) {
+ if (copy != null && copy.isDirectory() && node.isDirectory()) {
+ List<FSTreeNode> children = new ArrayList<FSTreeNode>(getChildren(node, service));
+ for (FSTreeNode child : children) {
+ moveNode(monitor, service, child, copy);
+ }
+ removeFolder(node, service);
+ monitor.worked(1);
+ }
+ else if (copy != null && copy.isFile() && node.isDirectory()) {
+ String error = NLS.bind(Messages.FSMove_FileExistsError, copy.name);
+ throw new TCFFileSystemException(error);
+ }
+ else if (copy != null && copy.isDirectory() && node.isFile()) {
+ String error = NLS.bind(Messages.FSMove_FolderExistsError, copy.name);
+ throw new TCFFileSystemException(error);
+ }
+ else {
+ if (copy != null && copy.isFile() && node.isFile()) {
+ removeFile(copy, service);
+ }
+ else if (copy == null) {
+ copy = (FSTreeNode) node.clone();
+ }
+ addChild(service, dest, copy);
+ String dst_path = copy.getLocation(true);
+ String src_path = node.getLocation(true);
+ final FSTreeNode copyNode = copy;
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ final Rendezvous rendezvous = new Rendezvous();
+ service.rename(src_path, dst_path, new DoneRename() {
+ @Override
+ public void doneRename(IToken token, FileSystemException error) {
+ if (error != null) {
+ String message = NLS.bind(Messages.FSMove_CannotMove, node.name, error);
+ errors[0] = new TCFFileSystemException(message, error);
+ }
+ else {
+ cleanUpNode(node, copyNode);
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.FSMove_CannotMove, node.name, Messages.FSOperation_TimedOutWhenOpening);
+ errors[0] = new TCFFileSystemException(message);
+ }
+ if (errors[0] != null) {
+ removeChild(service, dest, copy);
+ throw errors[0];
+ }
+ monitor.worked(1);
+ }
+ }
+ }
+ else {
+ throw new InterruptedException();
+ }
+ }
+
+ /**
+ * Clean up the node after successful moving.
+ *
+ * @param node The node being moved.
+ * @param copyNode The target node that is moved to.
+ */
+ void cleanUpNode(FSTreeNode node, FSTreeNode copyNode) {
+ if (node.isFile()) {
+ super.cleanUpFile(node);
+ }
+ else if (node.isDirectory()) {
+ super.cleanUpFolder(node);
+ List<FSTreeNode> children = new ArrayList<FSTreeNode>(getCurrentChildren(node));
+ getCurrentChildren(copyNode).addAll(children);
+ for (FSTreeNode child : children) {
+ child.parent = copyNode;
+ }
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java
new file mode 100644
index 000000000..73e401427
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSOperation.java
@@ -0,0 +1,679 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.operations;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFChannelException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CacheManager;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.PersistenceManager;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IPeer;
+import org.eclipse.tcf.protocol.IToken;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.services.IFileSystem;
+import org.eclipse.tcf.services.IFileSystem.DirEntry;
+import org.eclipse.tcf.services.IFileSystem.DoneMkDir;
+import org.eclipse.tcf.services.IFileSystem.DoneOpen;
+import org.eclipse.tcf.services.IFileSystem.DoneReadDir;
+import org.eclipse.tcf.services.IFileSystem.DoneRemove;
+import org.eclipse.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.tcf.services.IFileSystem.IFileHandle;
+import org.eclipse.tcf.te.tcf.core.Tcf;
+import org.eclipse.tcf.te.tcf.core.interfaces.IChannelManager.DoneOpenChannel;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * FSOperation is the base class of file system operation classes including FSCopy, FSDelete, FSMove
+ * and FSRename.
+ */
+public abstract class FSOperation {
+ // The flag indicating if the following action should be executed without asking.
+ protected boolean yes2All;
+
+ /**
+ * Create an instance.
+ */
+ public FSOperation() {
+ this.yes2All = false;
+ }
+
+ /**
+ * Get the top most nodes of the specified node list, removing those nodes whose ancestors are
+ * one of the other nodes in the list. This method is used to remove those children or grand
+ * children of the nodes that are cut, copied, moved or deleted.
+ *
+ * @param nodes The original node list.
+ * @return The top most nodes.
+ */
+ protected List<FSTreeNode> getTopNodes(List<FSTreeNode> nodes) {
+ List<FSTreeNode> result = new ArrayList<FSTreeNode>();
+ for (FSTreeNode node : nodes) {
+ if (!hasAncestor(node, nodes)) {
+ result.add(node);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * If the target node has ancestor in the specified node list.
+ *
+ * @param target The node to be tested.
+ * @param nodes The node list to search in.
+ * @return true if the target node has an ancestor in the node list.
+ */
+ private boolean hasAncestor(FSTreeNode target, List<FSTreeNode> nodes) {
+ for (FSTreeNode node : nodes) {
+ if (node.isAncestorOf(target)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Clean up the folder node after moving, deleting or copying.
+ *
+ * @param node the folder node that is to be cleaned.
+ */
+ protected void cleanUpFolder(FSTreeNode node) {
+ File file = CacheManager.getInstance().getCacheFile(node);
+ if (file.exists()) {
+ file.delete();
+ }
+ FSTreeNode parent = node.parent;
+ if (parent != null) {
+ getCurrentChildren(parent).remove(node);
+ }
+ }
+
+ /**
+ * Close the editor that opens the specified file.
+ *
+ * @param file The file that is opened.
+ */
+ protected void closeEditor(final File file) {
+ final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IEditorReference[] refs = page.getEditorReferences();
+ for (IEditorReference ref : refs) {
+ final IEditorReference editorRef = ref;
+ SafeRunner.run(new ISafeRunnable() {
+ @Override
+ public void run() throws Exception {
+ IEditorInput input = editorRef.getEditorInput();
+ if (input instanceof IURIEditorInput) {
+ IURIEditorInput editorInput = (IURIEditorInput) input;
+ URI uri = editorInput.getURI();
+ if (file.toURI().equals(uri)) {
+ IEditorPart editor = editorRef.getEditor(true);
+ page.closeEditor(editor, false);
+ }
+ }
+ }
+
+ @Override
+ public void handleException(Throwable exception) {
+ // Logged by safe runner.
+ }
+ });
+ }
+ }
+
+ /**
+ * Clean up the file node after moving, deleting or copying.
+ *
+ * @param node the file node that is to be cleaned.
+ */
+ protected void cleanUpFile(FSTreeNode node) {
+ File file = CacheManager.getInstance().getCacheFile(node);
+ if (file.exists()) {
+ closeEditor(file);
+ file.delete();
+ }
+ PersistenceManager.getInstance().removeBaseTimestamp(node.getLocationURL());
+ FSTreeNode parent = node.parent;
+ if (parent != null) {
+ getCurrentChildren(parent).remove(node);
+ }
+ }
+
+ /**
+ * Open a channel connected to the target represented by the peer.
+ *
+ * @return The channel or null if the operation fails.
+ */
+ protected IChannel openChannel(final IPeer peer) throws TCFChannelException {
+ final Rendezvous rendezvous = new Rendezvous();
+ final TCFChannelException[] errors = new TCFChannelException[1];
+ final IChannel[] channels = new IChannel[1];
+ Tcf.getChannelManager().openChannel(peer, new DoneOpenChannel() {
+ @Override
+ public void doneOpenChannel(Throwable error, IChannel channel) {
+ if (error != null) {
+ String message = NLS.bind(Messages.OpeningChannelFailureMessage, peer.getID(), error.getLocalizedMessage());
+ errors[0] = new TCFChannelException(message, error);
+ }
+ else {
+ channels[0] = channel;
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.OpeningChannelFailureMessage, peer.getID(), e.getLocalizedMessage());
+ errors[0] = new TCFChannelException(message, e);
+ }
+ if (errors[0] != null) {
+ throw errors[0];
+ }
+ return channels[0];
+ }
+
+ /**
+ * Count the total nodes in the node list including their children and grand children
+ * recursively.
+ *
+ * @param service The file system service used to open those folders that are not expanded yet.
+ * @param nodes The node list to be counted.
+ * @return The count of the total nodes.
+ * @throws TCFFileSystemException Thrown when expanding the unexpanded folders.
+ */
+ protected int count(IFileSystem service, List<FSTreeNode> nodes) throws TCFFileSystemException {
+ int count = 0;
+ for (FSTreeNode node : nodes) {
+ if (node.isFile()) {
+ count++;
+ }
+ else if (node.isDirectory()) {
+ List<FSTreeNode> children = new ArrayList<FSTreeNode>(getChildren(node, service));
+ count += count(service, children) + 1;
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Get the children of the specified folder node. If the folder node is not expanded, then
+ * expanded using the specified file system service.
+ *
+ * @param node The folder node.
+ * @param service The file system service.
+ * @return The children of the folder node.
+ * @throws TCFFileSystemException Thrown during querying the children nodes.
+ */
+ protected List<FSTreeNode> getChildren(final FSTreeNode node, final IFileSystem service) throws TCFFileSystemException {
+ if (node.childrenQueried) {
+ return getCurrentChildren(node);
+ }
+ loadChildren(node, service);
+ return getChildren(node, service);
+ }
+
+ /**
+ * Get the current children of the specified folder node.
+ *
+ * @param node The folder node.
+ * @return The children of the folder node.
+ */
+ public static List<FSTreeNode> getCurrentChildren(final FSTreeNode node) {
+ if (Protocol.isDispatchThread()) {
+ return node.getChildren();
+ }
+ @SuppressWarnings("unchecked")
+ final List<FSTreeNode>[] objects = new List[1];
+ Protocol.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ objects[0] = getCurrentChildren(node);
+ }
+ });
+ return objects[0];
+ }
+
+
+ /**
+ * Load the children of the specified folder node using the file system service.
+ *
+ * @param node The folder node.
+ * @param service The file system service.
+ * @throws TCFFileSystemException Thrown during querying the children nodes.
+ */
+ private void loadChildren(final FSTreeNode node, final IFileSystem service) throws TCFFileSystemException {
+ List<FSTreeNode> children = queryChildren(node, service);
+ List<FSTreeNode> current = getCurrentChildren(node);
+ for (FSTreeNode childNode : children) {
+ childNode.parent = node;
+ childNode.peerNode = node.peerNode;
+ current.add(childNode);
+ FSModel.getInstance().addNode(childNode);
+ }
+ node.childrenQueried = true;
+ }
+
+ /**
+ * Query the children of the specified node using the file system service.
+ *
+ * @param node The folder node.
+ * @param service The file system service.
+ * @return The children of the folder node.
+ * @throws TCFFileSystemException Thrown during querying the children nodes.
+ */
+ protected List<FSTreeNode> queryChildren(final FSTreeNode node, final IFileSystem service) throws TCFFileSystemException {
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ final IFileHandle[] handles = new IFileHandle[1];
+ final Rendezvous rendezvous = new Rendezvous();
+ try {
+ String dir = node.getLocation(true);
+ service.opendir(dir, new DoneOpen() {
+ @Override
+ public void doneOpen(IToken token, FileSystemException error, IFileHandle handle) {
+ if (error != null) {
+ String message = NLS.bind(Messages.FSOperation_CannotOpenDir, node.name, error);
+ errors[0] = new TCFFileSystemException(message, error);
+ }
+ else {
+ handles[0] = handle;
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(50000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.FSOperation_CannotOpenDir, node.name, Messages.FSOperation_TimedOutWhenOpening);
+ errors[0] = new TCFFileSystemException(message);
+ }
+ if (errors[0] != null) {
+ throw errors[0];
+ }
+ errors[0] = null;
+ final List<FSTreeNode> children = new ArrayList<FSTreeNode>();
+ final boolean[] eofs = new boolean[1];
+ while (!eofs[0]) {
+ rendezvous.reset();
+ service.readdir(handles[0], new DoneReadDir() {
+ @Override
+ public void doneReadDir(IToken token, FileSystemException error, DirEntry[] entries, boolean eof) {
+ if (eof) {
+ eofs[0] = true;
+ }
+ if (error == null) {
+ if (entries != null && entries.length > 0) {
+ for (DirEntry entry : entries) {
+ FSTreeNode childNode = createNodeFromDirEntry(entry, false);
+ if (childNode != null) {
+ children.add(childNode);
+ }
+ }
+ }
+ }
+ else {
+ String message = NLS.bind(Messages.FSOperation_CannotReadDir, node.name, error);
+ errors[0] = new TCFFileSystemException(message, error);
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.FSOperation_CannotReadDir, node.name, Messages.FSOperation_TimedOutWhenOpening);
+ errors[0] = new TCFFileSystemException(message);
+ }
+ if (errors[0] != null) throw errors[0];
+ }
+ return children;
+ }
+ finally {
+ if (handles[0] != null) {
+ rendezvous.reset();
+ service.close(handles[0], new IFileSystem.DoneClose() {
+ @Override
+ public void doneClose(IToken token, FileSystemException error) {
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Remove the child from the children list of the specified folder. If the folder has not yet
+ * expanded, then expand it.
+ *
+ * @param service The file system service.
+ * @param folder The folder node from which the node is going to be removed.
+ * @param child The child node to be removed.
+ * @throws TCFFileSystemException Thrown during children querying.
+ */
+ protected void removeChild(final IFileSystem service, final FSTreeNode folder, final FSTreeNode child) throws TCFFileSystemException {
+ if (Protocol.isDispatchThread()) {
+ getChildren(folder, service).remove(child);
+ child.parent = null;
+ }
+ else {
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ Protocol.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ removeChild(service, folder, child);
+ }
+ catch (TCFFileSystemException e) {
+ errors[0] = e;
+ }
+ }
+ });
+ if (errors[0] != null) throw errors[0];
+ }
+ }
+
+ /**
+ * Find the node with the name from the children list of the folder.
+ *
+ * @param service The file system service.
+ * @param folder The folder node.
+ * @param name The target node's name.
+ * @return The node with the specified name or null if no such node is found.
+ * @throws TCFFileSystemException Thrown when querying the children.
+ */
+ protected FSTreeNode findChild(IFileSystem service, FSTreeNode folder, String name) throws TCFFileSystemException {
+ List<FSTreeNode> children = new ArrayList<FSTreeNode>(getChildren(folder, service));
+ for (FSTreeNode child : children) {
+ if (child.name.equals(name)) return child;
+ }
+ return null;
+ }
+
+ /**
+ * Create the name for the target file that is copied. If there exists a file with the same
+ * name, then "Copy of xxxx" and "Copy (n) of xxxx" will be used as the target file name.
+ *
+ * @param service File system service used to query the children nodes of the folder.
+ * @param node The node whose target file is to be created.
+ * @param dest The destination folder.
+ * @return The new target node with the new name following the rule.
+ * @throws TCFFileSystemException Thrown during children querying.
+ */
+ protected FSTreeNode createCopyFile(IFileSystem service, FSTreeNode node, FSTreeNode dest) throws TCFFileSystemException {
+ FSTreeNode copy = (FSTreeNode) node.clone();
+ String name = node.name;
+ FSTreeNode possibleChild = findChild(service, dest, name);
+ for (int n = 0; possibleChild != null; n++) {
+ if (n > 0) {
+ name = NLS.bind(Messages.FSOperation_CopyNOfFile, Integer.valueOf(n), node.name);
+ }
+ else {
+ name = NLS.bind(Messages.FSOperation_CopyOfFile, node.name);
+ }
+ possibleChild = findChild(service, dest, name);
+ }
+ copy.name = name;
+ addChild(service, dest, copy);
+ return copy;
+ }
+
+ /**
+ * Make a new directory with for the new node.
+ *
+ * @param service The file system service.
+ * @param node The directory node to be made.
+ * @throws TCFFileSystemException Thrown during children querying.
+ */
+ protected void mkdir(IFileSystem service, final FSTreeNode node) throws TCFFileSystemException {
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ final Rendezvous rendezvous = new Rendezvous();
+ String path = node.getLocation(true);
+ service.mkdir(path, node.attr, new DoneMkDir() {
+ @Override
+ public void doneMkDir(IToken token, FileSystemException error) {
+ if (error != null) {
+ String message = NLS
+ .bind(Messages.FSOperation_CannotCreateDirectory, new Object[] { node.name, error });
+ errors[0] = new TCFFileSystemException(message, error);
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.FSOperation_CannotCreateDirectory, node.name, Messages.FSOperation_TimedOutWhenOpening);
+ errors[0] = new TCFFileSystemException(message);
+ }
+ if (errors[0] != null) {
+ throw errors[0];
+ }
+ }
+
+ /**
+ * Confirm if the file/folder represented by the specified should be replaced.
+ *
+ * @param node The file/folder node.
+ * @return The confirming result. true yes, false no.
+ * @throws InterruptedException Thrown when canceled.
+ */
+ protected boolean confirmReplace(final FSTreeNode node) throws InterruptedException {
+ if (yes2All) return true;
+ final int[] results = new int[1];
+ Display display = PlatformUI.getWorkbench().getDisplay();
+ display.syncExec(new Runnable() {
+ @Override
+ public void run() {
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ String title = node.isDirectory() ? Messages.FSOperation_ConfirmFolderReplaceTitle : Messages.FSOperation_ConfirmFileReplace;
+ String message = NLS.bind(node.isDirectory() ? Messages.FSOperation_ConfirmFolderReplaceMessage : Messages.FSOperation_ConfirmFileReplaceMessage, node.name);
+ final Image titleImage = UIPlugin.getImage(ImageConsts.REPLACE_FOLDER_CONFIRM);
+ MessageDialog qDialog = new MessageDialog(parent, title, null, message, MessageDialog.QUESTION, new String[] { Messages.FSOperation_ConfirmDialogYes, Messages.FSOperation_ConfirmDialogYesToAll, Messages.FSOperation_ConfirmDialogNo, Messages.FSOperation_ConfirmDialogCancel }, 0) {
+ @Override
+ public Image getQuestionImage() {
+ return titleImage;
+ }
+ };
+ results[0] = qDialog.open();
+ }
+ });
+ switch (results[0]) {
+ case 0:
+ return true;
+ case 1:
+ yes2All = true;
+ return true;
+ case 2:
+ return false;
+ }
+ throw new InterruptedException();
+ }
+
+ /**
+ * Add the specified child to the folder node's children list.
+ *
+ * @param service The file system service.
+ * @param folder The folder node.
+ * @param child The child node to be added.
+ * @throws TCFFileSystemException Thrown during children querying.
+ */
+ protected void addChild(final IFileSystem service, final FSTreeNode folder, final FSTreeNode child) throws TCFFileSystemException {
+ if (Protocol.isDispatchThread()) {
+ getChildren(folder, service).add(child);
+ child.parent = folder;
+ FSModel.getInstance().addNode(child);
+ }
+ else {
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ Protocol.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ addChild(service, folder, child);
+ }
+ catch (TCFFileSystemException e) {
+ errors[0] = e;
+ }
+ }
+ });
+ if (errors[0] != null) throw errors[0];
+ }
+ }
+
+ /**
+ * Create an directory entry using the specified DirEntry which contains the directory
+ * information.
+ *
+ * @param entry The directory entry node.
+ * @param entryIsRootNode If it is root node.
+ * @return An FSTreeNode representing the folder.
+ */
+ FSTreeNode createNodeFromDirEntry(DirEntry entry, boolean entryIsRootNode) {
+ Assert.isNotNull(entry);
+
+ FSTreeNode node = null;
+
+ IFileSystem.FileAttrs attrs = entry.attrs;
+
+ if (attrs == null || attrs.isDirectory()) {
+ node = new FSTreeNode();
+ node.childrenQueried = false;
+ node.childrenQueryRunning = false;
+ node.attr = attrs;
+ node.name = entry.filename;
+ node.type = entryIsRootNode ? "FSRootDirNode" : "FSDirNode"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ else if (attrs.isFile()) {
+ node = new FSTreeNode();
+ node.childrenQueried = false;
+ node.childrenQueryRunning = false;
+ node.attr = attrs;
+ node.name = entry.filename;
+ node.type = "FSFileNode"; //$NON-NLS-1$
+ }
+
+ return node;
+ }
+
+ /**
+ * Remove the file.
+ *
+ * @param node
+ * @param service
+ * @throws TCFFileSystemException
+ */
+ protected void removeFile(final FSTreeNode node, IFileSystem service) throws TCFFileSystemException {
+ // Do the actual deleting.
+ String path = node.getLocation(true);
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ final Rendezvous rendezvous = new Rendezvous();
+ service.remove(path, new DoneRemove() {
+ @Override
+ public void doneRemove(IToken token, FileSystemException error) {
+ if (error == null) {
+ cleanUpFile(node);
+ }
+ else {
+ String message = NLS.bind(Messages.FSDelete_CannotRemoveFile, node.name, error);
+ errors[0] = new TCFFileSystemException(message, error);
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.FSDelete_CannotRemoveFile, node.name, Messages.FSOperation_TimedOutWhenOpening);
+ errors[0] = new TCFFileSystemException(message);
+ }
+ if (errors[0] != null) {
+ throw errors[0];
+ }
+ }
+
+ /**
+ * Remove the folder.
+ *
+ * @param node
+ * @param service
+ * @throws TCFFileSystemException
+ */
+ protected void removeFolder(final FSTreeNode node, IFileSystem service) throws TCFFileSystemException {
+ // Do the actual deleting.
+ String path = node.getLocation(true);
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ final Rendezvous rendezvous = new Rendezvous();
+ service.rmdir(path, new DoneRemove() {
+ @Override
+ public void doneRemove(IToken token, FileSystemException error) {
+ if (error == null) {
+ cleanUpFolder(node);
+ }
+ else {
+ String message = NLS.bind(Messages.FSDelete_CannotRemoveFile, node.name, error);
+ errors[0] = new TCFFileSystemException(message, error);
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.FSDelete_CannotRemoveFile, node.name, Messages.FSOperation_TimedOutWhenOpening);
+ errors[0] = new TCFFileSystemException(message);
+ }
+ if (errors[0] != null) {
+ throw errors[0];
+ }
+ }
+
+ /**
+ * Do the actual operation.
+ *
+ * @return true if it is successful.
+ */
+ public abstract boolean doit();
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java
new file mode 100644
index 000000000..e2298fc5b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSRename.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.internal.operations;
+
+import java.io.File;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.exceptions.TCFFileSystemException;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.CacheManager;
+import org.eclipse.tcf.te.tcf.filesystem.internal.handlers.PersistenceManager;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
+import org.eclipse.tcf.te.tcf.filesystem.internal.url.Rendezvous;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSModel;
+import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.protocol.IToken;
+import org.eclipse.tcf.services.IFileSystem;
+import org.eclipse.tcf.services.IFileSystem.DoneRename;
+import org.eclipse.tcf.services.IFileSystem.FileSystemException;
+import org.eclipse.ui.PlatformUI;
+/**
+ * FSRename renames the specified file/folder to a
+ * new name.
+ *
+ */
+public class FSRename extends FSOperation {
+ // The file/folder node to be renamed.
+ FSTreeNode node;
+ // The new name the file/folder is renamed to.
+ String newName;
+
+ /**
+ * Create a rename operation that renames the node with the new name.
+ *
+ * @param node The file/folder node to be renamed.
+ * @param newName The new name of this node.
+ */
+ public FSRename(FSTreeNode node, String newName) {
+ this.node = node;
+ this.newName = newName;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSOperation#doit()
+ */
+ @Override
+ public boolean doit() {
+ IChannel channel = null;
+ try {
+ channel = openChannel(node.peerNode.getPeer());
+ if (channel != null) {
+ IFileSystem service = channel.getRemoteService(IFileSystem.class);
+ if (service != null) {
+ renameNode(service);
+ }
+ else {
+ String message = NLS.bind(Messages.FSOperation_NoFileSystemError, node.peerNode.getPeer().getID());
+ throw new TCFFileSystemException(message);
+ }
+ return true;
+ }
+ }
+ catch (TCFException e) {
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ MessageDialog.openError(parent, Messages.FSRename_RenameFileFolderTitle, e.getLocalizedMessage());
+ }
+ finally {
+ if (channel != null) channel.close();
+ FSModel.getInstance().fireNodeStateChanged(node);
+ }
+ return false;
+ }
+
+ /**
+ * Rename the node using the new name.
+ *
+ * @param service File system service used to rename.
+ * @throws TCFFileSystemException The exception thrown during renaming.
+ */
+ private void renameNode(IFileSystem service) throws TCFFileSystemException {
+ String src_path = node.getLocation(true);
+ String oldName = node.name;
+ node.name = newName;
+ String dst_path = node.getLocation(true);
+ node.name = oldName;
+ final TCFFileSystemException[] errors = new TCFFileSystemException[1];
+ final Rendezvous rendezvous = new Rendezvous();
+ service.rename(src_path, dst_path, new DoneRename() {
+ @Override
+ public void doneRename(IToken token, FileSystemException error) {
+ if (error != null) {
+ String message = NLS.bind(Messages.FSRename_CannotRename, node.name, error);
+ errors[0] = new TCFFileSystemException(message, error);
+ }
+ else {
+ File file = CacheManager.getInstance().getCacheFile(node);
+ if (file.exists()) {
+ if (node.isFile()) {
+ closeEditor(file);
+ PersistenceManager.getInstance().removeBaseTimestamp(node.getLocationURL());
+ }
+ file.delete();
+ }
+ node.name = newName;
+ }
+ rendezvous.arrive();
+ }
+ });
+ try {
+ rendezvous.waiting(5000L);
+ }
+ catch (InterruptedException e) {
+ String message = NLS.bind(Messages.FSRename_CannotRename, node.name, Messages.FSOperation_TimedOutWhenOpening);
+ errors[0] = new TCFFileSystemException(message);
+ }
+ if (errors[0] != null) {
+ throw errors[0];
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/PreferencesInitializer.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/PreferencesInitializer.java
index bfb93db5e..5bbba2255 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/PreferencesInitializer.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/PreferencesInitializer.java
@@ -6,6 +6,8 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.internal.preferences;
@@ -42,5 +44,8 @@ public class PreferencesInitializer extends AbstractPreferenceInitializer {
}
IPreferenceStore preferenceStore = UIPlugin.getDefault().getPreferenceStore();
preferenceStore.setDefault(TargetExplorerPreferencePage.PREF_AUTOSAVING, TargetExplorerPreferencePage.DEFAULT_AUTOSAVING);
+ preferenceStore.setDefault(TargetExplorerPreferencePage.PREF_RENAMING_IN_PLACE_EDITOR, TargetExplorerPreferencePage.DEFAULT_RENAMING_IN_PLACE_EDITOR);
+ preferenceStore.setDefault(TargetExplorerPreferencePage.PREF_COPY_PERMISSION, TargetExplorerPreferencePage.DEFAULT_COPY_PERMISSION);
+ preferenceStore.setDefault(TargetExplorerPreferencePage.PREF_COPY_OWNERSHIP, TargetExplorerPreferencePage.DEFAULT_COPY_OWNERSHIP);
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/TargetExplorerPreferencePage.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/TargetExplorerPreferencePage.java
index 17ffa341c..2300f6450 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/TargetExplorerPreferencePage.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/preferences/TargetExplorerPreferencePage.java
@@ -7,6 +7,8 @@
* Contributors:
* Wind River Systems - initial API and implementation
* William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.internal.preferences;
@@ -14,6 +16,7 @@ import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
@@ -27,9 +30,18 @@ public class TargetExplorerPreferencePage extends FieldEditorPreferencePage impl
public static final String PREF_AUTOSAVING = "PrefAutoSaving"; //$NON-NLS-1$
// The default value of the option of auto saving.
public static final boolean DEFAULT_AUTOSAVING = true;
-
- // The editor to edit the value of auto saving.
- protected BooleanFieldEditor fAutoSaving;
+ // The preference key to access the option using in-place editor during renaming.
+ public static final String PREF_RENAMING_IN_PLACE_EDITOR = "PrefRenamingInPlaceEditor"; //$NON-NLS-1$
+ // The default value of the option using in-place editor during renaming.
+ public static final boolean DEFAULT_RENAMING_IN_PLACE_EDITOR = true;
+ // The preference key to access the option of copy permission when copying files.
+ public static final String PREF_COPY_PERMISSION = "PrefCopyPermission"; //$NON-NLS-1$
+ // The default value of the option of copy permission.
+ public static final boolean DEFAULT_COPY_PERMISSION = true;
+ // The preference key to access the option of copy ownership when copying files.
+ public static final String PREF_COPY_OWNERSHIP = "PrefCopyOwnership"; //$NON-NLS-1$
+ // The default value of the option of copy ownership
+ public static final boolean DEFAULT_COPY_OWNERSHIP = true;
/***
* Create a preference page for Target Explorer File System Explorer.
@@ -46,9 +58,14 @@ public class TargetExplorerPreferencePage extends FieldEditorPreferencePage impl
UIPlugin plugin = UIPlugin.getDefault();
IPreferenceStore preferenceStore = plugin.getPreferenceStore();
setPreferenceStore(preferenceStore);
- fAutoSaving = new BooleanFieldEditor(PREF_AUTOSAVING, "Automatically upload files to targets upon saving.", //$NON-NLS-1$
- getFieldEditorParent());
- addField(fAutoSaving);
+ BooleanFieldEditor autoSaving = new BooleanFieldEditor(PREF_AUTOSAVING, Messages.TargetExplorerPreferencePage_AutoSavingText, getFieldEditorParent());
+ addField(autoSaving);
+ BooleanFieldEditor renamingOption = new BooleanFieldEditor(PREF_RENAMING_IN_PLACE_EDITOR, Messages.TargetExplorerPreferencePage_RenamingOptionText, getFieldEditorParent());
+ addField(renamingOption);
+ BooleanFieldEditor copyPermission = new BooleanFieldEditor(PREF_COPY_PERMISSION, Messages.TargetExplorerPreferencePage_CopyPermissionText, getFieldEditorParent());
+ addField(copyPermission);
+ BooleanFieldEditor copyOwnership = new BooleanFieldEditor(PREF_COPY_OWNERSHIP, Messages.TargetExplorerPreferencePage_CopyOwnershipText, getFieldEditorParent());
+ addField(copyOwnership);
}
/* (non-Javadoc)
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/AdvancedAttributesDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/AdvancedAttributesDialog.java
index ebc45be59..0dcb49d28 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/AdvancedAttributesDialog.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/AdvancedAttributesDialog.java
@@ -9,10 +9,7 @@
*********************************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.internal.properties;
-import java.net.URL;
-
import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
@@ -27,6 +24,7 @@ import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.tcf.te.tcf.filesystem.activator.UIPlugin;
import org.eclipse.tcf.te.tcf.filesystem.interfaces.IWindowsFileAttributes;
+import org.eclipse.tcf.te.tcf.filesystem.internal.ImageConsts;
import org.eclipse.tcf.te.tcf.filesystem.internal.nls.Messages;
import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
@@ -35,10 +33,6 @@ import org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode;
* folder.
*/
public class AdvancedAttributesDialog extends Dialog {
- // The key to store the banner image in the plug-in's image registry.
- private static final String BANNER_IMAGE_KEY = "BannerImage"; //$NON-NLS-1$
- // The path to the image used in the banner.
- private static final String BANNER_IMAGE_PATH = "icons/obj32/banner.png"; //$NON-NLS-1$
// The file or folder node whose advanced attributes are to be displayed.
FSTreeNode node;
@@ -87,14 +81,7 @@ public class AdvancedAttributesDialog extends Dialog {
* @return The image in the banner area.
*/
private Image getBannerImage() {
- Image bImg = UIPlugin.getImage(BANNER_IMAGE_KEY);
- if (bImg == null) {
- URL bannerUrl = UIPlugin.getDefault().getBundle().getResource(BANNER_IMAGE_PATH);
- ImageDescriptor desc = ImageDescriptor.createFromURL(bannerUrl);
- UIPlugin.getDefault().getImageRegistry().put(BANNER_IMAGE_KEY, desc);
- bImg = UIPlugin.getImage(BANNER_IMAGE_KEY);
- }
- return bImg;
+ return UIPlugin.getImage(ImageConsts.BANNER_IMAGE);
}
/**
@@ -196,6 +183,8 @@ public class AdvancedAttributesDialog extends Dialog {
final Button button = new Button(group, SWT.CHECK);
button.setText(label);
button.setSelection(on);
+ // Only the owner can edit the properties
+ button.setEnabled(node.isAgentOwner());
button.addSelectionListener(new SelectionAdapter(){
@Override
public void widgetSelected(SelectionEvent e) {
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/GeneralInformationPage.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/GeneralInformationPage.java
index 97210ce43..234cd6afc 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/GeneralInformationPage.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/properties/GeneralInformationPage.java
@@ -122,8 +122,7 @@ public class GeneralInformationPage extends PropertyPage {
* @return The string in the format of SIZE_FORMAT.
*/
protected String getSizeText(long size) {
- return SIZE_FORMAT.format(size / 1024)
- + " KB (" + SIZE_FORMAT.format(size) + " bytes)"; //$NON-NLS-1$ //$NON-NLS-2$
+ return NLS.bind(Messages.GeneralInformationPage_FileSizeInfo, SIZE_FORMAT.format(size / 1024), SIZE_FORMAT.format(size));
}
/**
@@ -158,6 +157,8 @@ public class GeneralInformationPage extends PropertyPage {
// Read-only
btnReadOnly = new Button(attr, SWT.CHECK);
btnReadOnly.setText(Messages.GeneralInformationPage_ReadOnly);
+ // Only the owner can edit this property
+ btnReadOnly.setEnabled(node.isAgentOwner());
btnReadOnly.addSelectionListener(new SelectionAdapter(){
@Override
public void widgetSelected(SelectionEvent e) {
@@ -169,6 +170,8 @@ public class GeneralInformationPage extends PropertyPage {
// Hidden
btnHidden = new Button(attr, SWT.CHECK);
btnHidden.setText(Messages.GeneralInformationPage_Hidden);
+ // Only the owner can edit this property
+ btnHidden.setEnabled(node.isAgentOwner());
btnHidden.addSelectionListener(new SelectionAdapter(){
@Override
public void widgetSelected(SelectionEvent e) {
@@ -219,7 +222,7 @@ public class GeneralInformationPage extends PropertyPage {
protected void createPermissionsSection(Composite parent) {
GridLayout gridLayout;
Label label = new Label(parent, SWT.NONE);
- label.setText("Permissions:"); //$NON-NLS-1$
+ label.setText(Messages.GeneralInformationPage_PermissionText);
GridData data = new GridData();
data.horizontalAlignment = SWT.LEFT;
data.verticalAlignment = SWT.TOP;
@@ -277,6 +280,8 @@ public class GeneralInformationPage extends PropertyPage {
private void createPermissionButton(String label, final int index, Composite parent) {
btnPermissions[index] = new Button(parent, SWT.CHECK);
btnPermissions[index].setText(label);
+ // Only the owner can edit its permission.
+ btnPermissions[index].setEnabled(node.isAgentOwner());
btnPermissions[index].addSelectionListener(new SelectionAdapter(){
@Override
public void widgetSelected(SelectionEvent e) {
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/url/TcfURLConnection.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/url/TcfURLConnection.java
index 174ff9162..3b8b799e1 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/url/TcfURLConnection.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/url/TcfURLConnection.java
@@ -148,7 +148,7 @@ public class TcfURLConnection extends URLConnection {
@Override
public void doneOpenChannel(Throwable error, IChannel channel) {
if(error!=null){
- String message = NLS.bind(Messages.TCFUtilities_OpeningFailureMessage,
+ String message = NLS.bind(Messages.OpeningChannelFailureMessage,
new Object[]{peer.getID(), error.getLocalizedMessage()});
errors[0] = new TCFChannelException(message, error);
}else{
@@ -159,7 +159,7 @@ public class TcfURLConnection extends URLConnection {
try {
rendezvous.waiting(5000L);
} catch (InterruptedException e) {
- String message = NLS.bind(Messages.TCFUtilities_OpeningFailureMessage,
+ String message = NLS.bind(Messages.OpeningChannelFailureMessage,
new Object[]{peer.getID(), e.getLocalizedMessage()});
errors[0] = new TCFChannelException(message, e);
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/model/FSTreeNode.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/model/FSTreeNode.java
index 3e1c0a762..a696e8c15 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/model/FSTreeNode.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/model/FSTreeNode.java
@@ -9,6 +9,8 @@
* William Chen (Wind River) - [345384] Provide property pages for remote file system nodes
* William Chen (Wind River) - [352302]Opening a file in an editor depending on
* the client's permissions.
+ * William Chen (Wind River) - [361324] Add more file operations in the file system
+ * of Target Explorer.
*******************************************************************************/
package org.eclipse.tcf.te.tcf.filesystem.model;
@@ -98,25 +100,50 @@ public final class FSTreeNode extends PlatformObject implements Cloneable{
*/
@Override
public Object clone() {
- FSTreeNode clone;
- try {
- clone = (FSTreeNode) super.clone();
- } catch (CloneNotSupportedException e) {
- clone = new FSTreeNode();
- clone.children = children;
- clone.childrenQueried = childrenQueried;
- clone.childrenQueryRunning = childrenQueryRunning;
- clone.name = name;
- clone.parent = parent;
- clone.peerNode = peerNode;
- clone.type = type;
- }
- Map<String, Object> attributes = new HashMap<String, Object>(attr.attributes);
- clone.attr = new IFileSystem.FileAttrs(attr.flags, attr.size, attr.uid, attr.gid, attr.permissions, attr.atime, attr.mtime, attributes);
- return clone;
+ if (Protocol.isDispatchThread()) {
+ FSTreeNode clone = new FSTreeNode();
+ clone.childrenQueried = childrenQueried;
+ clone.childrenQueryRunning = childrenQueryRunning;
+ clone.name = name;
+ clone.parent = parent;
+ clone.peerNode = peerNode;
+ clone.type = type;
+ Map<String, Object> attributes = new HashMap<String, Object>(attr.attributes);
+ clone.attr = new IFileSystem.FileAttrs(attr.flags, attr.size, attr.uid, attr.gid, attr.permissions, attr.atime, attr.mtime, attributes);
+ return clone;
+ }
+ final Object[] objects = new Object[1];
+ Protocol.invokeAndWait(new Runnable() {
+
+ @Override
+ public void run() {
+ objects[0] = FSTreeNode.this.clone();
+ }
+ });
+ return objects[0];
}
/**
+ * Change the file/folder's write permission.
+ * @param b true if the agent is granted with its write permission.
+ */
+ public void setWritable(boolean b) {
+ UserAccount account = UserManager.getInstance().getUserAccount(peerNode);
+ if (account != null && attr != null) {
+ int bit;
+ if (attr.uid == account.getEUID()) {
+ bit = IFileSystem.S_IWUSR;
+ } else if (attr.gid == account.getEGID()) {
+ bit = IFileSystem.S_IWGRP;
+ } else {
+ bit = IFileSystem.S_IWOTH;
+ }
+ int permissions = attr.permissions;
+ setPermissions(b ? (permissions | bit):(permissions & ~ bit));
+ }
+ }
+
+ /**
* Set the file's permissions.
* @param permissions The new permissions.
*/
@@ -284,13 +311,7 @@ public final class FSTreeNode extends PlatformObject implements Cloneable{
* @return The location of the file/folder.
*/
public String getLocation() {
- if (parent == null)
- return null;
- String location = parent.getLocation(false);
- if (parent.isRoot()) {
- return location + (isWindowsNode() ? "\\" : "/"); //$NON-NLS-1$ //$NON-NLS-2$
- }
- return location;
+ return getLocation(false);
}
/**
@@ -301,11 +322,17 @@ public final class FSTreeNode extends PlatformObject implements Cloneable{
* @return The path to the file/folder.
*/
public String getLocation(boolean cross) {
- if (parent == null)
- return null;
+ if(isRoot()) {
+ if(cross) {
+ if(isWindowsNode()) {
+ return name.substring(0, name.length() - 1) + "/"; //$NON-NLS-1$
+ }
+ }
+ return name;
+ }
String pLoc = parent.getLocation(cross);
- if (pLoc == null) {
- return name.substring(0, name.length() - 1);
+ if(parent.isRoot()) {
+ return pLoc + name;
}
String pathSep = (!cross && isWindowsNode()) ? "\\" : "/"; //$NON-NLS-1$ //$NON-NLS-2$
return pLoc + pathSep + name;
@@ -360,6 +387,19 @@ public final class FSTreeNode extends PlatformObject implements Cloneable{
}
/**
+ * If the agent is the owner of this file/folder.
+ *
+ * @return true if the agent is the owner of this file/folder.
+ */
+ public boolean isAgentOwner() {
+ UserAccount account = UserManager.getInstance().getUserAccount(peerNode);
+ if (account != null && attr != null) {
+ return attr.uid == account.getEUID();
+ }
+ return false;
+ }
+
+ /**
* If this file is writable.
*
* @return true if it is writable.
@@ -396,4 +436,14 @@ public final class FSTreeNode extends PlatformObject implements Cloneable{
}
return false;
}
+
+ /**
+ * If this node is ancestor of the specified node.
+ * @return true if it is.
+ */
+ public boolean isAncestorOf(FSTreeNode node) {
+ if (node == null) return false;
+ if (node.parent == this) return true;
+ return isAncestorOf(node.parent);
+ }
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/actions/PinTerminalAction.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/actions/PinTerminalAction.java
index af8e98a76..477841d83 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/actions/PinTerminalAction.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/actions/PinTerminalAction.java
@@ -21,8 +21,8 @@ import org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction;
*/
@SuppressWarnings("restriction")
public class PinTerminalAction extends AbstractTerminalAction {
-
- private ITerminalsView fView = null;
+
+ private ITerminalsView view = null;
/**
* Constructor.
@@ -30,25 +30,22 @@ public class PinTerminalAction extends AbstractTerminalAction {
public PinTerminalAction(ITerminalsView view) {
super(null, PinTerminalAction.class.getName(), IAction.AS_CHECK_BOX);
- fView=view;
- setupAction(Messages.PinTerminalAction_menu,
- Messages.PinTerminalAction_toolTip,
- UIPlugin.getImageDescriptor(ImageConsts.ACTION_PinTerminal_Hover),
- UIPlugin.getImageDescriptor(ImageConsts.ACTION_PinTerminal_Enabled),
- UIPlugin.getImageDescriptor(ImageConsts.ACTION_PinTerminal_Disabled),
- true);
- setChecked(fView.isPinned());
+ this.view = view;
+ setupAction(Messages.PinTerminalAction_menu, Messages.PinTerminalAction_toolTip,
+ UIPlugin.getImageDescriptor(ImageConsts.ACTION_PinTerminal_Hover),
+ UIPlugin.getImageDescriptor(ImageConsts.ACTION_PinTerminal_Enabled),
+ UIPlugin.getImageDescriptor(ImageConsts.ACTION_PinTerminal_Disabled), true);
+ setChecked(view.isPinned());
}
-
/* (non-Javadoc)
* @see org.eclipse.jface.action.IAction#run()
*/
@Override
public void run() {
- fView.setPinned(isChecked());
+ view.setPinned(isChecked());
}
-
+
/* (non-Javadoc)
* @see org.eclipse.tm.internal.terminal.control.actions.AbstractTerminalAction#updateAction(boolean)
*/
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/activator/UIPlugin.java
index dc953ce84..2cf1462bf 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/activator/UIPlugin.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/activator/UIPlugin.java
@@ -6,6 +6,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Max Weninger (Wind River) - [361363] [TERMINALS] Implement "Pin&Clone" for the "Terminals" view
*******************************************************************************/
package org.eclipse.tcf.te.ui.terminals.activator;
@@ -15,9 +16,9 @@ import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
-import org.eclipse.tcf.te.ui.terminals.interfaces.ImageConsts;
import org.eclipse.tcf.te.runtime.preferences.ScopedEclipsePreferences;
import org.eclipse.tcf.te.runtime.tracing.TraceHandler;
+import org.eclipse.tcf.te.ui.terminals.interfaces.ImageConsts;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ITerminalsView.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ITerminalsView.java
index b927cb55c..fcad40175 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ITerminalsView.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ITerminalsView.java
@@ -6,6 +6,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Max Weninger (Wind River) - [361363] [TERMINALS] Implement "Pin&Clone" for the "Terminals" view
*******************************************************************************/
package org.eclipse.tcf.te.ui.terminals.interfaces;
@@ -33,20 +34,19 @@ public interface ITerminalsView extends IViewPart {
* @return The context help id or <code>null</code> if none is associated.
*/
public String getContextHelpId();
-
+
/**
- * Set the state of the view to be pinned
- * which means a new terminal connection will be created
- * in a new view
- *
- * @param pin
+ * Set the state of the view to be pinned, which means a new terminal tab will be created
+ * in a new view instance.
+ *
+ * @param pin <code>True</code> to set the view state to pinned, <code>false</code> otherwise.
*/
public void setPinned(boolean pin);
-
+
/**
* Return the pin state of the terminal view
- *
- * @return
+ *
+ * @return <code>True</code> if the view instance is pinned, <code>false</code> if not.
*/
public boolean isPinned();
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ImageConsts.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ImageConsts.java
index 9285f4294..59fc23be6 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ImageConsts.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/interfaces/ImageConsts.java
@@ -6,6 +6,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Max Weninger (Wind River) - [361363] [TERMINALS] Implement "Pin&Clone" for the "Terminals" view
*******************************************************************************/
package org.eclipse.tcf.te.ui.terminals.interfaces;
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/manager/ConsoleManager.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/manager/ConsoleManager.java
index 54e8ebf32..a79a7197e 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/manager/ConsoleManager.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/manager/ConsoleManager.java
@@ -6,12 +6,15 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Max Weninger (Wind River) - [361363] [TERMINALS] Implement "Pin&Clone" for the "Terminals" view
*******************************************************************************/
package org.eclipse.tcf.te.ui.terminals.manager;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IStatus;
@@ -40,8 +43,6 @@ import org.eclipse.ui.PlatformUI;
*/
@SuppressWarnings("restriction")
public class ConsoleManager {
- private int secondaryIdCount;
- private boolean secondaryIdCountInit;
// Reference to the perspective listener instance
private final IPerspectiveListener perspectiveListener;
@@ -132,7 +133,7 @@ public class ConsoleManager {
* <p>
* <b>Note:</b> The method must be called within the UI thread.
*
- * @param id The terminal console view id or <code>null</code> to show the default terminal console view.
+ * @param id The terminals console view id or <code>null</code> to show the default terminal console view.
* @return The console view instance if available or <code>null</code> otherwise.
*/
public ITerminalsView findConsoleView(String id, String secondaryId) {
@@ -155,23 +156,26 @@ public class ConsoleManager {
}
/**
- * search and return a terminal view with a specific
- * secondary id
- * @param id
- * @param secondaryId
- * @return
+ * Search and return a terminal view with a specific secondary id
+ *
+ * @param id The terminals console view id. Must not be <code>null</code>.
+ * @param secondaryId The terminals console view secondary id or <code>null</code>.
+ *
+ * @return The terminals console view instance or <code>null</code> if not found.
*/
- private IViewPart getTerminalsViewWithSecondaryId(String id, String secondaryId){
+ private IViewPart getTerminalsViewWithSecondaryId(String id, String secondaryId) {
+ Assert.isNotNull(id);
+
IWorkbenchPage page = getActiveWorkbenchPage();
- IViewReference[] refs=page.getViewReferences();
- for(int i=0; i<refs.length; i++){
- IViewReference ref=refs[i];
- if(ref.getId().equals(id)){
- IViewPart part=ref.getView(true);
- if(part instanceof ITerminalsView){
- String secId=((IViewSite)part.getSite()).getSecondaryId();
- if(secId.equals(secondaryId)){
+ IViewReference[] refs = page.getViewReferences();
+ for (int i = 0; i < refs.length; i++) {
+ IViewReference ref = refs[i];
+ if (ref.getId().equals(id)) {
+ IViewPart part = ref.getView(true);
+ if (part instanceof ITerminalsView) {
+ String secId = ((IViewSite) part.getSite()).getSecondaryId();
+ if (secId != null && secId.equals(secondaryId)) {
return part;
}
}
@@ -181,20 +185,23 @@ public class ConsoleManager {
}
/**
- * search and return a terminal view that is NOT pinned
- * @param id
- * @return
+ * Search and return a terminal view that is NOT pinned
+ *
+ * @param id The terminals console view id. Must not be <code>null</code>.
+ * @return The terminals console view instance or <code>null</code> if not found.
*/
- private IViewPart getFirstNotPinnedTerminalsView(String id){
+ private IViewPart getFirstNotPinnedTerminalsView(String id) {
+ Assert.isNotNull(id);
+
IWorkbenchPage page = getActiveWorkbenchPage();
- IViewReference[] refs=page.getViewReferences();
- for(int i=0; i<refs.length; i++){
- IViewReference ref=refs[i];
- if(ref.getId().equals(id)){
- IViewPart part=ref.getView(true);
- if(part instanceof ITerminalsView){
- if(!((ITerminalsView)part).isPinned()){
+ IViewReference[] refs = page.getViewReferences();
+ for (int i = 0; i < refs.length; i++) {
+ IViewReference ref = refs[i];
+ if (ref.getId().equals(id)) {
+ IViewPart part = ref.getView(true);
+ if (part instanceof ITerminalsView) {
+ if (!((ITerminalsView) part).isPinned()) {
return part;
}
}
@@ -204,24 +211,29 @@ public class ConsoleManager {
}
/**
- * search and return a terminal view if available
- * @param id
- * @param useActive - return only an active terminal view
- * @return
+ * Search and return the first available terminal view.
+ *
+ * @param id The terminals console view id. Must not be <code>null</code>.
+ * @param useActive - return only an active terminal view.
+ *
+ * @return The terminals console view instance or <code>null</code> if not found.
*/
- private IViewPart getFirstTerminalsView(String id, boolean useActive){
+ private IViewPart getFirstTerminalsView(String id, boolean useActive) {
+ Assert.isNotNull(id);
+
IWorkbenchPage page = getActiveWorkbenchPage();
- IViewReference[] refs=page.getViewReferences();
- for(int i=0; i<refs.length; i++){
- IViewReference ref=refs[i];
- if(ref.getId().equals(id)){
- IViewPart part=ref.getView(true);
- if(useActive){
- if(page.isPartVisible(part)){
+ IViewReference[] refs = page.getViewReferences();
+ for (int i = 0; i < refs.length; i++) {
+ IViewReference ref = refs[i];
+ if (ref.getId().equals(id)) {
+ IViewPart part = ref.getView(true);
+ if (useActive) {
+ if (page.isPartVisible(part)) {
return part;
}
- } else {
+ }
+ else {
return part;
}
}
@@ -230,32 +242,49 @@ public class ConsoleManager {
}
/**
- * cycle through all terminal views and find the highest
- * secondary view id to know where to continue when
- * a new terminal view is created
- * @param id
+ * Return a new secondary id to use, based on the number of open terminal views.
+ *
+ * @param id The terminals console view id. Must not be <code>null</code>.
+ * @return The next secondary id, or <code>null</code> if it is the first one
*/
- private void countTerminalViews(String id){
- if(!secondaryIdCountInit){
- secondaryIdCountInit=true;
- secondaryIdCount=0;
- IWorkbenchPage page = getActiveWorkbenchPage();
-
- IViewReference[] refs=page.getViewReferences();
- for(int i=0; i<refs.length; i++){
- IViewReference ref=refs[i];
- if(ref.getId().equals(id)){
- String secId=ref.getSecondaryId();
- try {
- int secIdInt=Integer.parseInt(secId);
- if(secIdInt>secondaryIdCount){
- secondaryIdCount=secIdInt;
- }
- } catch(NumberFormatException e){
+ private String getNextTerminalSecondaryId(String id) {
+ Assert.isNotNull(id);
+
+ IWorkbenchPage page = getActiveWorkbenchPage();
+ Map<String, IViewReference> terminalViews = new HashMap<String, IViewReference>();
+
+ int maxNumber = 0;
+ IViewReference[] refs = page.getViewReferences();
+ for (int i = 0; i < refs.length; i++) {
+ IViewReference ref = refs[i];
+ if (ref.getId().equals(id)) {
+ if (ref.getSecondaryId() != null) {
+ terminalViews.put(ref.getSecondaryId(), ref);
+ int scondaryIdInt = Integer.parseInt(ref.getSecondaryId());
+ if (scondaryIdInt > maxNumber) {
+ maxNumber = scondaryIdInt;
}
}
+ else {
+ // add the one with secondaryId == null with 0 by default
+ terminalViews.put(Integer.toString(0), ref);
+ }
}
}
+ if (terminalViews.size() == 0) {
+ return null;
+ }
+
+ int i = 0;
+ for (; i < maxNumber; i++) {
+ String secondaryIdStr = Integer.toString(i);
+ if (!terminalViews.keySet().contains(secondaryIdStr)) {
+ // found a free slot
+ return Integer.toString(i);
+ }
+ }
+ // add a new one
+ return Integer.toString(i + 1);
}
/**
@@ -277,9 +306,9 @@ public class ConsoleManager {
// and force the view to the foreground
page.bringToTop(part);
return part;
- } catch (PartInitException e) {
- IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(),
- e.getLocalizedMessage(), e);
+ }
+ catch (PartInitException e) {
+ IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), e.getLocalizedMessage(), e);
UIPlugin.getDefault().getLog().log(status);
}
}
@@ -297,16 +326,16 @@ public class ConsoleManager {
IWorkbenchPage page = getActiveWorkbenchPage();
if (page != null) {
// Look for any terminal view
- IViewPart anyTerminal=getFirstTerminalsView(id != null ? id : IUIConstants.ID, false);
+ IViewPart anyTerminal = getFirstTerminalsView(id != null ? id : IUIConstants.ID, false);
// there is at least one terminal available
- if(anyTerminal!=null){
+ if (anyTerminal != null) {
// is there an active terminal view
- IViewPart activePart=getFirstTerminalsView(id != null ? id : IUIConstants.ID, true);
+ IViewPart activePart = getFirstTerminalsView(id != null ? id : IUIConstants.ID, true);
// no terminal view active
- if(activePart==null){
+ if (activePart == null) {
// use the first not pinned
- IViewPart notPinnedPart=getFirstNotPinnedTerminalsView(id != null ? id : IUIConstants.ID);
- if(notPinnedPart!=null){
+ IViewPart notPinnedPart = getFirstNotPinnedTerminalsView(id != null ? id : IUIConstants.ID);
+ if (notPinnedPart != null) {
if (activate) {
page.activate(notPinnedPart);
}
@@ -316,16 +345,15 @@ public class ConsoleManager {
return notPinnedPart;
}
// else we need to create a new one
- secondaryIdCount++;
- IViewPart newPart=showConsoleView(id != null ? id : IUIConstants.ID, Integer.toString(secondaryIdCount));
+ IViewPart newPart = showConsoleView(id != null ? id : IUIConstants.ID, getNextTerminalSecondaryId(id != null ? id : IUIConstants.ID));
return newPart;
}
// we found a active terminal page
// if it is pinned search for a non pinned (not active)
- if(((ITerminalsView)activePart).isPinned()){
+ if (((ITerminalsView) activePart).isPinned()) {
// we found one so use it
- IViewPart notPinnedPart=getFirstNotPinnedTerminalsView(id != null ? id : IUIConstants.ID);
- if(notPinnedPart!=null){
+ IViewPart notPinnedPart = getFirstNotPinnedTerminalsView(id != null ? id : IUIConstants.ID);
+ if (notPinnedPart != null) {
if (activate) {
page.activate(notPinnedPart);
}
@@ -335,16 +363,15 @@ public class ConsoleManager {
return notPinnedPart;
}
// else we need to create a new one
- secondaryIdCount++;
- IViewPart newPart=showConsoleView(id != null ? id : IUIConstants.ID, Integer.toString(secondaryIdCount));
+ IViewPart newPart = showConsoleView(id != null ? id : IUIConstants.ID, getNextTerminalSecondaryId(id != null ? id : IUIConstants.ID));
return newPart;
}
// else return the active one
- return activePart;
+ return activePart;
}
// create first new terminal
if (activate) {
- IViewPart newPart=showConsoleView(id != null ? id : IUIConstants.ID, Integer.toString(secondaryIdCount));
+ IViewPart newPart = showConsoleView(id != null ? id : IUIConstants.ID, getNextTerminalSecondaryId(id != null ? id : IUIConstants.ID));
return newPart;
}
}
@@ -367,8 +394,6 @@ public class ConsoleManager {
Assert.isNotNull(connector);
Assert.isNotNull(Display.findDisplay(Thread.currentThread()));
- countTerminalViews(id != null ? id : IUIConstants.ID);
-
// make the consoles view visible
IViewPart part=bringToTop(id, activate);
if(part==null){
@@ -438,6 +463,45 @@ public class ConsoleManager {
}
/**
+ * Search all console views for the one that contains a specific connector.
+ * <p>
+ * <b>Note:</b> The method will handle unified console titles itself.
+ *
+ * @param id The terminal console view id or <code>null</code> to show the default terminal console view.
+ * @param title The console title. Must not be <code>null</code>.
+ * @param connector The terminal connector. Must not be <code>null</code>.
+ * @param data The custom terminal data node or <code>null</code>.
+ *
+ * @return The corresponding console tab item or <code>null</code>.
+ */
+ private CTabItem findConsoleForTerminalConnector(String id, String title, ITerminalConnector connector, Object data) {
+ Assert.isNotNull(title);
+ Assert.isNotNull(connector);
+
+ IWorkbenchPage page = getActiveWorkbenchPage();
+
+ IViewReference[] refs = page.getViewReferences();
+ for (int i = 0; i < refs.length; i++) {
+ IViewReference ref = refs[i];
+ if (ref.getId().equals(id)) {
+ IViewPart part = ref.getView(true);
+ if (part instanceof ITerminalsView) {
+ // Get the tab folder manager associated with the view
+ TabFolderManager manager = (TabFolderManager) part.getAdapter(TabFolderManager.class);
+ if (manager == null) {
+ continue;
+ }
+ CTabItem item = manager.findTabItem(title, connector, data);
+ if (item != null) {
+ return item;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
* Close the console with the given title and the given terminal connector.
* <p>
* <b>Note:</b> The method must be called within the UI thread.
@@ -452,9 +516,8 @@ public class ConsoleManager {
Assert.isNotNull(connector);
Assert.isNotNull(Display.findDisplay(Thread.currentThread()));
- String secondaryId=Integer.toString(secondaryIdCount);
- // Lookup the console
- CTabItem console = findConsole(id, secondaryId, title, connector, data);
+ // Lookup the console with this connector
+ CTabItem console = findConsoleForTerminalConnector(id, title, connector, data);
// If found, dispose the console
if (console != null) {
console.dispose();
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/nls/Messages.java
index 52c74ed01..0550bf91f 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/nls/Messages.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/nls/Messages.java
@@ -6,6 +6,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Max Weninger (Wind River) - [361363] [TERMINALS] Implement "Pin&Clone" for the "Terminals" view
*******************************************************************************/
package org.eclipse.tcf.te.ui.terminals.nls;
@@ -34,7 +35,6 @@ public class Messages extends NLS {
public static String TabTerminalListener_consoleTerminated;
public static String PinTerminalAction_menu;
-
public static String PinTerminalAction_toolTip;
public static String ProcessSettingsPage_dialogTitle;
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/tabs/TabFolderToolbarHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/tabs/TabFolderToolbarHandler.java
index 468e5d598..12c366456 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/tabs/TabFolderToolbarHandler.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/tabs/TabFolderToolbarHandler.java
@@ -6,6 +6,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Max Weninger (Wind River) - [361363] [TERMINALS] Implement "Pin&Clone" for the "Terminals" view
*******************************************************************************/
package org.eclipse.tcf.te.ui.terminals.tabs;
@@ -265,7 +266,7 @@ public class TabFolderToolbarHandler extends PlatformObject {
// we want that at the end
PinTerminalAction pinAction=null;
-
+
// Loop all actions and add them to the menu manager
for (AbstractTerminalAction action : toolbarActions) {
// Add a separator before the clear all action or if the action is a separator
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/view/TerminalsView.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/view/TerminalsView.java
index 80f1dcd56..30130dbd9 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/view/TerminalsView.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.terminals/src/org/eclipse/tcf/te/ui/terminals/view/TerminalsView.java
@@ -6,6 +6,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
+ * Max Weninger (Wind River) - [361363] [TERMINALS] Implement "Pin&Clone" for the "Terminals" view
*******************************************************************************/
package org.eclipse.tcf.te.ui.terminals.view;
@@ -22,6 +23,7 @@ import org.eclipse.tcf.te.ui.terminals.interfaces.ITerminalsView;
import org.eclipse.tcf.te.ui.terminals.tabs.TabFolderManager;
import org.eclipse.tcf.te.ui.terminals.tabs.TabFolderMenuHandler;
import org.eclipse.tcf.te.ui.terminals.tabs.TabFolderToolbarHandler;
+import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.PageBook;
@@ -45,7 +47,7 @@ public class TerminalsView extends ViewPart implements ITerminalsView {
// Reference to the empty page control (to be show if no console is open)
private Control emptyPageControl;
// Whether this terminal is pinned.
- private boolean fPinned = false;
+ private boolean pinned = false;
/**
* Constructor.
@@ -110,6 +112,13 @@ public class TerminalsView extends ViewPart implements ITerminalsView {
// Show the empty page control by default
switchToEmptyPageControl();
+
+ String secondaryId=((IViewSite)getSite()).getSecondaryId();
+ if(secondaryId!=null){
+ String defaultTitle=getPartName();
+ // set title
+ setPartName(defaultTitle+ " "+secondaryId); //$NON-NLS-1$
+ }
}
/**
@@ -308,22 +317,20 @@ public class TerminalsView extends ViewPart implements ITerminalsView {
return super.getAdapter(adapter);
}
-
- /*
- * (non-Javadoc)
- * @see org.eclipse.tm.te.ui.terminals.interfaces.ITerminalsView#setPinned(boolean)
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.terminals.interfaces.ITerminalsView#setPinned(boolean)
*/
@Override
public void setPinned(boolean pin) {
- fPinned = pin;
+ this.pinned = pin;
}
- /*
- * (non-Javadoc)
- * @see org.eclipse.tm.te.ui.terminals.interfaces.ITerminalsView#isPinned()
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.terminals.interfaces.ITerminalsView#isPinned()
*/
@Override
- public boolean isPinned() {
- return fPinned;
+ public boolean isPinned() {
+ return pinned;
}
}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml
index 68bad2261..8c219402e 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/plugin.xml
@@ -3,6 +3,7 @@
<plugin>
<extension-point id="editorPageBindings" name="%ExtensionPoint.editorPageBindings.name" schema="schema/editorPageBindings.exsd"/>
<extension-point id="editorPages" name="%ExtensionPoint.editorPages.name" schema="schema/editorPages.exsd"/>
+ <extension-point id="configurators" name="Common Viewer Configurators" schema="schema/configurators.exsd"/>
<!-- Common Navigator contributions -->
<extension point="org.eclipse.ui.navigator.viewer">
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/configurators.exsd b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/configurators.exsd
new file mode 100644
index 000000000..a9a8e14a4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/schema/configurators.exsd
@@ -0,0 +1,135 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tcf.te.ui.views" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.tcf.te.ui.views" id="configurators" name="Target Explorer Viewer Configurators"/>
+ </appinfo>
+ <documentation>
+ &lt;p&gt;
+This extension point is used to declare Target Explorer Viewer Configurators. A Viewer Configurator is used to configure the common viewer of Target Explorer when it is created. Those who want to configure the common viewer after it is created should implement an instance of IViewerConfigurator and add a viewer configurator extension.
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="configurator" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="configurator">
+ <annotation>
+ <documentation>
+ Declares a Target Explorer Viewer Configurator.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="viewerId" type="string" use="required">
+ <annotation>
+ <documentation>
+ The id of the common viewer that this configurator contributes to. If the viewer is in a common navigator then the id must match the navigator&apos;s id defined in its &lt;b&gt;org.eclipse.ui.views&lt;/b&gt; extension.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="identifier" basedOn="org.eclipse.ui.navigator.viewer/viewer/@viewerId"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class that implements &lt;code&gt;org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator&lt;/code&gt;.
+&lt;p&gt;
+The editor page implementation class must be specified either by the class attribute!
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ Target Explorer 1.0.0
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="examples"/>
+ </appinfo>
+ <documentation>
+ &lt;pre&gt;
+ &lt;extension
+ point=&quot;org.eclipse.tcf.te.ui.views.configurators&quot;&gt;
+ &lt;configurator
+ class=&quot;org.eclipse.tcf.te.tcf.filesystem.controls.FSCellConfigurator&quot;
+ viewerId=&quot;org.eclipse.tcf.te.ui.views.TargetExplorer&quot;&gt;
+ &lt;/configurator&gt;
+ &lt;/extension&gt;
+&lt;/pre&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="apiinfo"/>
+ </appinfo>
+ <documentation>
+ Plug-ins that want to extend this extension point, the referenced class must implement &lt;samp&gt;org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator&lt;/samp&gt; interface.
+ </documentation>
+ </annotation>
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Copyright (c) 2011 Wind River Systems, Inc. and others.
+
+All rights reserved.
+
+This program and the accompanying materials are made available under the terms
+of the Eclipse Public License v1.0 which accompanies this distribution, and is
+available at http://www.eclipse.org/legal/epl-v10.html.
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerConfigurator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerConfigurator.java
new file mode 100644
index 000000000..8c899be31
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/interfaces/IViewerConfigurator.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.interfaces;
+
+import org.eclipse.ui.navigator.CommonViewer;
+
+/**
+ * An interface to configure the common viewer of Target Explorer in an abstract way.
+ * <p>
+ * This interface should be implemented by classes that wish to configure the common viewer when
+ * Target Explorer is created.
+ */
+public interface IViewerConfigurator {
+ /**
+ * Configure the common viewer of Target Explorer.
+ *
+ * @param viewer The common viewer of Target Explorer.
+ */
+ void configure(CommonViewer viewer);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java
index 7e1265d92..13d61a14d 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewer.java
@@ -35,6 +35,7 @@ public class ViewViewer extends CommonViewer {
*/
public ViewViewer(String viewerId, Composite parent, int style) {
super(viewerId, parent, style);
+ new ViewViewerConfigurator(viewerId).configure(this);
}
/* (non-Javadoc)
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerConfigurator.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerConfigurator.java
new file mode 100644
index 000000000..0255f5782
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/internal/ViewViewerConfigurator.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the terms
+ * of the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * William Chen (Wind River) - [361324] Add more file operations in the file
+ * system of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.ui.views.internal;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator;
+import org.eclipse.ui.navigator.CommonViewer;
+
+/**
+ * This viewer configurator reads the extensions from the extension point
+ * "org.eclipse.tcf.te.ui.views.configurators" and initialize the registered viewer
+ * configurators.
+ */
+public class ViewViewerConfigurator implements IViewerConfigurator {
+ private static final String EXTENSION_POINT_ID = "org.eclipse.tcf.te.ui.views.configurators"; //$NON-NLS-1$
+ // The registered viewer configurators with the specified viewer id.
+ List<IViewerConfigurator> configurators;
+
+ /**
+ * Create an instance with the specified viewer id.
+ */
+ public ViewViewerConfigurator(String viewerId) {
+ Assert.isTrue(viewerId != null);
+ configurators = Collections.synchronizedList(new ArrayList<IViewerConfigurator>());
+ IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(EXTENSION_POINT_ID);
+ IExtension[] extensions = extensionPoint.getExtensions();
+ for (IExtension extension : extensions) {
+ IConfigurationElement[] elements = extension.getConfigurationElements();
+ for (IConfigurationElement element : elements) {
+ String name = element.getName();
+ String id = element.getAttribute("viewerId"); //$NON-NLS-1$
+ if (name.equals("configurator") && viewerId.equals(id)) { //$NON-NLS-1$
+ addConfigurator(element);
+ }
+ }
+ }
+ }
+
+ /**
+ * Add the viewer configurator defined in the configuration element to the configurator list.
+ *
+ * @param element The configuration element that defines the viewer configurator.
+ */
+ private void addConfigurator(final IConfigurationElement element) {
+ SafeRunner.run(new ISafeRunnable() {
+ @Override
+ public void handleException(Throwable exception) {
+ // Ignore it.
+ }
+
+ @Override
+ public void run() throws Exception {
+ IViewerConfigurator configurator = (IViewerConfigurator) element.createExecutableExtension("class"); //$NON-NLS-1$
+ configurators.add(configurator);
+ }
+ });
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerConfigurator#configure(org.eclipse.ui.navigator.CommonViewer)
+ */
+ @Override
+ public void configure(CommonViewer viewer) {
+ for (IViewerConfigurator configurator : configurators) {
+ configurator.configure(viewer);
+ }
+ }
+}

Back to the top