Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui')
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.classpath7
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.project39
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.jdt.core.prefs362
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.jdt.ui.prefs56
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.pde.prefs32
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/META-INF/MANIFEST.MF57
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/about.html28
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/build.properties17
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/error.gifbin0 -> 354 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/folder.gifbin0 -> 216 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/hidden_file_filter.pngbin0 -> 438 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/newfile_wiz.gifbin0 -> 353 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/newfolder_wiz.gifbin0 -> 349 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/refresh.gifbin0 -> 327 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/root.gifbin0 -> 909 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/rootdrive.gifbin0 -> 336 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/synch_synch.gifbin0 -> 353 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/system_file_filter.pngbin0 -> 243 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/win7_rootdrive.pngbin0 -> 250 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/win8_rootdrive.pngbin0 -> 250 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/xp_rootdrive.pngbin0 -> 525 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/banner.pngbin0 -> 2315 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/delete_readonly.pngbin0 -> 367 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/replace_confirm.pngbin0 -> 847 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_conflict.pngbin0 -> 98 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_modified.pngbin0 -> 97 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_outdated.pngbin0 -> 98 bytes
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/plugin.properties119
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/plugin.xml1997
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/pom.xml17
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/activator/UIPlugin.java251
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSNavigatorContentProvider.java74
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSTreeContentProvider.java25
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSTreeViewerSorter.java40
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/NavigatorContentProvider.java162
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/TreeContentProvider.java209
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSFolderSelectionDialog.java329
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSOpenFileDialog.java263
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/TimeTriggeredProgressMonitorDialog.java240
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/filters/HiddenFilesViewerFilter.java38
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/filters/SystemFilesViewerFilter.java35
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/help/IContextHelpIds.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/IFSConstants.java31
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/IFileSystemUIDelegate.java77
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/preferences/IPreferenceKeys.java48
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/ImageConsts.java85
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeAdapterFactory.java121
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeFactory.java50
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeLoader.java75
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/NodeStateFilter.java78
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/PeerNodeViewerInput.java40
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/PersistableNode.java52
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/ViewerInputAdapterFactory.java81
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/autosave/SaveAllListener.java131
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/autosave/SaveListener.java110
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellListener.java91
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellModifier.java90
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellValidator.java82
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSViewerCellEditorFactory.java100
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/AccessTimeComparator.java30
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/AccessTimeLabelProvider.java38
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/CacheFileImageUpdater.java53
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/DefaultImageProvider.java84
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeElementComparator.java35
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeElementLabelProvider.java70
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeNodeComparator.java63
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileExtBasedImageUpdater.java100
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileTypeComparator.java30
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileTypeLabelProvider.java32
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ImageProvider.java28
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ImageUpdateAdapter.java46
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/LabelProviderUpdateDaemon.java289
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ModificationTimeComparator.java30
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ModificationTimeLabelProvider.java38
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/SizeComparator.java30
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/SizeLabelProvider.java39
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/WindowsImageProvider.java49
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/EditableSharedDocumentAdapter.java256
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/LocalFileSaveable.java481
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/LocalTypedElement.java307
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeEditorInput.java419
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeInput.java158
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeTypedElement.java99
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/RemoteTypedElement.java102
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/decorators/PhantomDecorator.java45
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/decorators/PhantomImageDescriptor.java224
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/CommonDnD.java409
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDragAdapterAssistant.java60
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDragSourceListener.java64
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDropAdapterAssistant.java115
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDropTargetListener.java93
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CommitHandler.java40
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CopyFilesHandler.java43
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CutFilesHandler.java43
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/DeleteHandler.java128
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MergeHandler.java46
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MoveCopyCallback.java66
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MoveFilesHandler.java55
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewFileHandler.java28
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewFolderHandler.java28
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewNodeHandler.java62
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenFileHandler.java141
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenWithContribution.java77
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenWithMenu.java419
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/PasteFilesHandler.java114
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RefreshHandler.java44
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RefreshViewerHandler.java46
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RenameCallback.java46
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RenameFilesHandler.java138
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/UpdateHandler.java41
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboard.java114
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/UiExecutor.java100
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/pages/FSExplorerEditorPage.java106
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/pages/FSExplorerEventListener.java101
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/preferences/PreferencePage.java63
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/preferences/PreferencesInitializer.java50
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/properties/AdvancedAttributesDialog.java214
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/properties/GeneralInformationPage.java405
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/DateValidator.java108
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSBaseSearchable.java77
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSGeneralSearchable.java302
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSModifiedSearchable.java253
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSSizeSearchable.java255
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSTreeNodeMatcher.java79
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSTreeNodeSearchable.java87
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/NameValidator.java41
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/SizeValidator.java29
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/BasicFileSection.java49
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/BasicFolderSection.java116
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/FileFilter.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/FolderFilter.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/LinuxFilter.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/LinuxPermissionsSection.java139
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsAttributesCESection.java94
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsAttributesSection.java92
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFileAISection.java35
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFileFilter.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFilter.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFolderAISection.java114
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFolderFilter.java33
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/CachePropertyTester.java38
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/ClipboardPropertyTester.java112
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/EditorActivationEventPropertyTester.java42
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/FolderValidator.java60
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NameValidator.java112
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFileWizard.java48
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFileWizardPage.java52
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFolderWizard.java48
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFolderWizardPage.java52
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewNodeWizard.java250
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewNodeWizardPage.java359
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/TargetPatternFilter.java57
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/TargetSelectionPage.java305
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java251
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties171
155 files changed, 16471 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.classpath b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.classpath
new file mode 100644
index 000000000..ad32c83a7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.project b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.project
new file mode 100644
index 000000000..a3e804ab0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.project
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tcf.te.filesystem.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+ <filteredResources>
+ <filter>
+ <id>0</id>
+ <name></name>
+ <type>10</type>
+ <matcher>
+ <id>org.eclipse.ui.ide.multiFilter</id>
+ <arguments>1.0-name-matches-false-false-target</arguments>
+ </matcher>
+ </filter>
+ </filteredResources>
+</projectDescription>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.jdt.core.prefs b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..a069dfcf5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,362 @@
+#Fri Oct 07 16:14:06 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=warning
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=0
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=0
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=0
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=0
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=0
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=true
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=100
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=4
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=4
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.lineSplit=100
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=true
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.jdt.ui.prefs b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..88bb9570e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,56 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Target Explorer Java STD
+formatter_settings_version=12
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=true
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.pde.prefs b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.pde.prefs
new file mode 100644
index 000000000..cf80c8bc5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,32 @@
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=1
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.build.bin.includes=1
+compilers.p.build.encodings=2
+compilers.p.build.java.compiler=2
+compilers.p.build.java.compliance=1
+compilers.p.build.missing.output=2
+compilers.p.build.output.library=1
+compilers.p.build.source.library=1
+compilers.p.build.src.includes=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-packages=1
+compilers.p.missing-version-export-package=2
+compilers.p.missing-version-import-package=1
+compilers.p.missing-version-require-bundle=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+compilers.p.unknown-attribute=1
+compilers.p.unknown-class=1
+compilers.p.unknown-element=1
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=1
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+eclipse.preferences.version=1
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/META-INF/MANIFEST.MF b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..1f55305b5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,57 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tcf.te.filesystem.ui;singleton:=true
+Bundle-Version: 1.3.0.qualifier
+Bundle-Activator: org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin
+Bundle-Vendor: %providerName
+Require-Bundle: org.eclipse.compare;bundle-version="3.5.300",
+ org.eclipse.core.runtime;bundle-version="3.8.0",
+ org.eclipse.core.expressions;bundle-version="3.4.400",
+ org.eclipse.core.filesystem;bundle-version="1.3.200",
+ org.eclipse.text;bundle-version="3.5.200",
+ org.eclipse.ui.ide;bundle-version="3.8.1",
+ org.eclipse.ui.navigator;bundle-version="3.5.200",
+ org.eclipse.ui.views.properties.tabbed;bundle-version="3.5.300",
+ org.eclipse.ui.workbench.texteditor;bundle-version="3.8.0",
+ org.eclipse.tcf.core;bundle-version="1.3.0",
+ org.eclipse.tcf.te.core;bundle-version="1.3.0",
+ org.eclipse.tcf.te.runtime;bundle-version="1.3.0",
+ org.eclipse.tcf.te.runtime.model;bundle-version="1.3.0",
+ org.eclipse.tcf.te.tcf.filesystem.core;bundle-version="1.3.0",
+ org.eclipse.tcf.te.tcf.locator;bundle-version="1.3.0",
+ org.eclipse.tcf.te.tcf.ui;bundle-version="1.3.0",
+ org.eclipse.tcf.te.ui;bundle-version="1.3.0",
+ org.eclipse.tcf.te.ui.forms;bundle-version="1.3.0",
+ org.eclipse.tcf.te.ui.swt;bundle-version="1.3.0",
+ org.eclipse.tcf.te.ui.views;bundle-version="1.3.0",
+ org.eclipse.tcf.te.ui.controls;bundle-version="1.3.0",
+ org.eclipse.tcf.te.runtime.services;bundle-version="1.3.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
+Export-Package: org.eclipse.tcf.te.tcf.filesystem.ui.activator;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.controls,
+ org.eclipse.tcf.te.tcf.filesystem.ui.dialogs,
+ org.eclipse.tcf.te.tcf.filesystem.ui.filters,
+ org.eclipse.tcf.te.tcf.filesystem.ui.help;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.interfaces,
+ org.eclipse.tcf.te.tcf.filesystem.ui.interfaces.preferences,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.adapters;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.autosave;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.celleditor;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.decorators;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.dnd;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.pages;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.preferences;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.properties;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.search;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.testers;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.internal.wizards;x-internal:=true,
+ org.eclipse.tcf.te.tcf.filesystem.ui.nls;x-internal:=true
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/about.html b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/about.html
new file mode 100644
index 000000000..0f07cf034
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>May 24, 2012</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/build.properties b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/build.properties
new file mode 100644
index 000000000..bf3f1e0fb
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/build.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2012 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
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ plugin.xml,\
+ icons/,\
+ about.html
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/error.gif b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/error.gif
new file mode 100644
index 000000000..85ec26bb8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/error.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/folder.gif b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/folder.gif
new file mode 100644
index 000000000..5ae555a34
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/folder.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/hidden_file_filter.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/hidden_file_filter.png
new file mode 100644
index 000000000..7cb530b2a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/hidden_file_filter.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/newfile_wiz.gif b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/newfile_wiz.gif
new file mode 100644
index 000000000..9d050885b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/newfile_wiz.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/newfolder_wiz.gif b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/newfolder_wiz.gif
new file mode 100644
index 000000000..310eb18e3
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/newfolder_wiz.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/refresh.gif b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/refresh.gif
new file mode 100644
index 000000000..3ca04d06f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/refresh.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/root.gif b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/root.gif
new file mode 100644
index 000000000..ba39f47f4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/root.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/rootdrive.gif b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/rootdrive.gif
new file mode 100644
index 000000000..fd426343b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/rootdrive.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/synch_synch.gif b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/synch_synch.gif
new file mode 100644
index 000000000..ae7726345
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/synch_synch.gif
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/system_file_filter.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/system_file_filter.png
new file mode 100644
index 000000000..24e66a8a0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/system_file_filter.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/win7_rootdrive.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/win7_rootdrive.png
new file mode 100644
index 000000000..93e70989c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/win7_rootdrive.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/win8_rootdrive.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/win8_rootdrive.png
new file mode 100644
index 000000000..93e70989c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/win8_rootdrive.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/xp_rootdrive.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/xp_rootdrive.png
new file mode 100644
index 000000000..881717ee0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj16/xp_rootdrive.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/banner.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/banner.png
new file mode 100644
index 000000000..aa7c955b7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/banner.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/delete_readonly.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/delete_readonly.png
new file mode 100644
index 000000000..4c8a7e3a8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/delete_readonly.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/replace_confirm.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/replace_confirm.png
new file mode 100644
index 000000000..455df2156
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/obj32/replace_confirm.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_conflict.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_conflict.png
new file mode 100644
index 000000000..eb22b4cce
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_conflict.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_modified.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_modified.png
new file mode 100644
index 000000000..66e3e4e24
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_modified.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_outdated.png b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_outdated.png
new file mode 100644
index 000000000..f662aac01
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/icons/ovr/ovr_outdated.png
Binary files differ
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/plugin.properties b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/plugin.properties
new file mode 100644
index 000000000..963ec274b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/plugin.properties
@@ -0,0 +1,119 @@
+##################################################################################
+# Copyright (c) 2011, 2014 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
+##################################################################################
+
+pluginName = Target Explorer, TCF File System Extensions
+providerName = Eclipse.org - Target Explorer
+
+# ***** Navigator Content *****
+
+navigatorContent.name = File System
+
+# ***** Editor Pages *****
+
+FSExplorerEditorPage.name=File System
+
+# ***** Preference and Property Pages *****
+
+GeneralInformationPage.name=General
+
+preference.page.name = File System
+
+# ***** Wizards and Wizard Pages *****
+
+NewWizards.category.filesystem.name=Remote File System
+
+newfile.wizard.name = File
+newfile.wizard.description = Please specify the attributes of the file.
+newfolder.wizard.name = Folder
+newfolder.wizard.description = Please specify the attributes of the folder.
+
+# ***** Filter *****
+
+FSTreeViewerFilter.hiddenFiles=Hidden files and folders
+FSTreeViewerFilter.systemFiles=Protected operating system files
+
+# ***** Actions/Commands *****
+
+PropertiesAction.label=Properties
+PropertiesAction.tooltip=Show Properties of Selection
+
+fsmenu.open.label = Open
+fsmenu.refresh.label = Refresh
+fsmenu.update.label = Update
+fsmenu.commit.label = Commit
+fsmenu.merge.label = Merge
+fsmenu.revert.label = Revert
+
+temenu.open.label = Open
+temenu.refresh.label = Refresh
+temenu.update.label = Update
+temenu.commit.label = Commit
+temenu.merge.label = Merge
+temenu.revert.label = Revert
+
+command.refresh.name = Refresh File
+command.update.name = Update File
+command.commit.name = Commit File
+command.merge.name = Merge File
+command.revert.name = Revert File
+
+command.delete.label=Delete
+command.delete.description=Delete the selected node
+
+decorator.modified.label = Remote File System Modified Cache Decorator
+decorator.outdated.label = Remote File System Outdated Cache Decorator
+decorator.conflict.label = Remote File System Conflicting Cache Decorator
+decorator.label.cut = Remote File System Cut File Decorator
+decorator.hidden.label = Remote File System Hidden File Decorator
+
+menu.label.openwith = Open With
+menu.new.label = &New
+
+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.newfile.label = &File
+command.newfolder.label = &Folder
+command.newfile.name = New File
+command.newfolder.name = New Folder
+
+column.name.name = Name
+column.name.size = Size
+column.name.modified = Date Modified
+
+filter.name.hidden = Hidden files and folders
+filter.name.system = Protected operating system files
+
+column.name.type = Type
+column.name.accessed = Date Accessed
+
+filter.description.hidden = Hide hidden files and folders.
+filter.description.system = Hide protected operating system files.
+
+command.refreshViewer.label = Refresh View
+command.refreshViewer.tooltip = Refresh View
+command.refreshViewer.name = Refresh Viewer
+
+propertyTab.general.label = General
+propertyTab.advanced.label = Advanced
+propertyTab.permission.label = Permissions
+command.refresh.tooltip = Refresh the selected nodes
+command.search.label = Find...
+
+command.cut.mnemonic = t
+command.copy.mnemonic = C
+command.paste.mnemonic = P
+command.delete.mnemonic = D
+command.rename.mnemonic = R
+command.move.mnemonic = M \ No newline at end of file
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/plugin.xml b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/plugin.xml
new file mode 100644
index 000000000..1a4a500f6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/plugin.xml
@@ -0,0 +1,1997 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+<!-- Common navigator contributions -->
+ <extension point="org.eclipse.ui.navigator.viewer">
+ <viewerContentBinding viewerId="org.eclipse.tcf.te.ui.views.View">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.tcf.te.tcf.filesystem.navigator.*"/>
+ </includes>
+ </viewerContentBinding>
+ <dragAssistant
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.dnd.FSDragAdapterAssistant"
+ viewerId="org.eclipse.tcf.te.ui.views.View">
+ </dragAssistant>
+ </extension>
+
+ <extension point="org.eclipse.ui.navigator.navigatorContent">
+ <navigatorContent
+ activeByDefault="false"
+ contentProvider="org.eclipse.tcf.te.tcf.filesystem.ui.controls.FSNavigatorContentProvider"
+ icon="icons/obj16/root.gif"
+ id="org.eclipse.tcf.te.tcf.filesystem.navigator.content"
+ labelProvider="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FSTreeElementLabelProvider"
+ name="%navigatorContent.name"
+ priority="normal">
+ <triggerPoints>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.locator.hasRemoteService"
+ value="FileSystem">
+ </test>
+ </triggerPoints>
+ <possibleChildren>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </possibleChildren>
+ <commonSorter
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.controls.FSTreeViewerSorter"
+ id="org.eclipse.tcf.te.tcf.filesystem.navigator.sorter">
+ </commonSorter>
+ <dropAssistant
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.dnd.FSDropAdapterAssistant"
+ id="org.eclipse.tcf.te.tcf.filesystem.dropAssistant">
+ <possibleDropTargets>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof></possibleDropTargets>
+ </dropAssistant>
+ <commonWizard
+ type="new"
+ wizardId="org.eclipse.tcf.te.tcf.filesystem.wizards.NewFileWizard">
+ <enablement>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isDirectory">
+ </test>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable">
+ </test></enablement>
+ </commonWizard>
+ <commonWizard
+ type="new"
+ wizardId="org.eclipse.tcf.te.tcf.filesystem.wizards.NewFolderWizard">
+ <enablement>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isDirectory">
+ </test>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable">
+ </test>
+ </enablement>
+ </commonWizard>
+ </navigatorContent>
+ <commonFilter
+ activeByDefault="true"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.filters.HiddenFilesViewerFilter"
+ id="org.eclipse.tcf.te.tcf.filesystem.navigator.filter.hiddenFiles"
+ name="%FSTreeViewerFilter.hiddenFiles"
+ visibleInUI="true">
+ </commonFilter>
+ <commonFilter
+ activeByDefault="true"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.filters.SystemFilesViewerFilter"
+ id="org.eclipse.tcf.te.tcf.filesystem.navigator.filter.systemFiles"
+ name="%FSTreeViewerFilter.systemFiles"
+ visibleInUI="true">
+ </commonFilter>
+ </extension>
+
+<!-- Editor page contributions -->
+ <extension point="org.eclipse.tcf.te.ui.views.editorPages">
+ <editorPage
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.pages.FSExplorerEditorPage"
+ icon="icons/obj16/root.gif"
+ id="org.eclipse.tcf.te.tcf.filesystem.FSExplorerEditorPage"
+ name="%FSExplorerEditorPage.name">
+ </editorPage>
+ </extension>
+
+<!-- Editor page binding contributions -->
+ <extension point="org.eclipse.tcf.te.ui.views.editorPageBindings">
+ <editorPageBinding
+ id="org.eclipse.tcf.te.tcf.filesystem.binding.FSExplorerEditorPage"
+ pageId="org.eclipse.tcf.te.tcf.filesystem.FSExplorerEditorPage"
+ insertBefore="org.eclipse.tcf.te.tcf.launch.ui.MemoryMapEditorPage,org.eclipse.tcf.te.tcf.launch.ui.PathMapEditorPage,org.eclipse.tcf.te.launch.ui.SourceLookupEditorPage,org.eclipse.tcf.te.launch.ui.LaunchEditorPage">
+ <enablement>
+ <with variable="activeEditorInput">
+ <adapt type="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode">
+ <test property="org.eclipse.tcf.te.tcf.locator.hasOfflineService" value="FileSystem"/>
+ </adapt>
+ </with>
+ </enablement>
+ </editorPageBinding>
+ </extension>
+
+<!-- Menu contributions -->
+ <extension point="org.eclipse.ui.menus">
+ <menuContribution locationURI="popup:org.eclipse.tcf.te.tcf.filesystem.FSExplorerEditorPage?after=additions">
+ <separator
+ name="group.new">
+ </separator>
+ <menu
+ label="%menu.new.label">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.newFile"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_NewFile"
+ icon="icons/obj16/newfile_wiz.gif"
+ label="%command.newfile.label"
+ style="push">
+ </command>
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.newFolder"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_NewFolder"
+ icon="icons/obj16/newfolder_wiz.gif"
+ label="%command.newfolder.label"
+ style="push">
+ </command>
+ </menu>
+ <separator name="group.open" visible="true"/>
+ <command
+ commandId="org.eclipse.ui.navigator.Open"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Open"
+ id="open"
+ label="%fsmenu.open.label"
+ style="push">
+ <visibleWhen checkEnabled="false">
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadable">
+ </test>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isBinaryFile"/>
+ </not>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.openWith">
+ </separator>
+ <menu
+ label="%menu.label.openwith">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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.isReadable">
+ </test>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isBinaryFile">
+ </test>
+ </not>
+ </iterate>
+ </with>
+ </visibleWhen>
+ <dynamic
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.OpenWithContribution"
+ id="openWithMenu">
+ </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="%command.cut.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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="%command.copy.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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="%command.paste.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.delete">
+ </separator>
+ <command
+ commandId="org.eclipse.ui.edit.delete"
+ disabledIcon="platform:/plugin/org.eclipse.ui/icons/full/dtool16/delete.gif"
+ helpContextId="org.eclipse.tcf.te.ui.command_Delete"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/etool16/delete.gif"
+ id="org.eclipse.tcf.te.ui.commands.delete"
+ label="%command.label.delete"
+ mnemonic="%command.delete.mnemonic"
+ style="push"
+ tooltip="%command.delete.description">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.refresh"
+ visible="true">
+ </separator>
+ <command
+ commandId="org.eclipse.tcf.te.ui.command.refresh"
+ label="%fsmenu.refresh.label"
+ style="push"
+ tooltip="%command.refresh.tooltip">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.syncop"
+ visible="true">
+ </separator>
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.update"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Update"
+ id="update"
+ label="%fsmenu.update.label"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.commit"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Commit"
+ id="commit"
+ label="%fsmenu.commit.label"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.merge"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Merge"
+ id="merge"
+ label="%fsmenu.merge.label"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.revert"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Revert"
+ id="revert"
+ label="%fsmenu.revert.label"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.operations"
+ 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="%command.rename.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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="%command.move.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ <separator
+ name="group.search"
+ visible="true">
+ </separator>
+ <command
+ commandId="org.eclipse.tcf.te.ui.views.command.find"
+ label="%command.search.label"
+ style="push">
+ </command>
+ <separator name="group.properties" visible="true"/>
+ <command
+ commandId="org.eclipse.ui.file.properties"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Properties"
+ id="properties"
+ label="%PropertiesAction.label"
+ tooltip="%PropertiesAction.tooltip">
+ <visibleWhen>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate operator="and" ifEmpty="false">
+ <and>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot">
+ </test>
+ </not>
+ </and>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution locationURI="popup:org.eclipse.tcf.te.ui.views.View#Popup?after=group.open">
+ <command
+ commandId="org.eclipse.ui.navigator.Open"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Open"
+ id="open"
+ label="%temenu.open.label"
+ style="push">
+ <visibleWhen checkEnabled="false">
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadable">
+ </test>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isBinaryFile"/>
+ </not>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ locationURI="popup:org.eclipse.tcf.te.ui.views.View#Popup?after=group.openWith">
+ <menu
+ label="%menu.label.openwith">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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.isReadable">
+ </test>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isBinaryFile">
+ </test>
+ </not>
+ </iterate>
+ </with>
+ </visibleWhen>
+ <dynamic
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.OpenWithContribution"
+ id="openWithMenu">
+ </dynamic>
+ </menu>
+ </menuContribution>
+ <menuContribution
+ locationURI="popup:org.eclipse.tcf.te.ui.views.View#Popup?after=group.edit">
+ <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="%command.cut.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot">
+ </test>
+ </not>
+ </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="%command.copy.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot">
+ </test>
+ </not>
+ </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="%command.paste.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot">
+ </test>
+ </not>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution locationURI="popup:org.eclipse.tcf.te.ui.views.View#Popup?after=group.delete">
+ <command
+ commandId="org.eclipse.ui.edit.delete"
+ disabledIcon="platform:/plugin/org.eclipse.ui/icons/full/dtool16/delete.gif"
+ helpContextId="org.eclipse.tcf.te.ui.command_Delete"
+ icon="platform:/plugin/org.eclipse.ui/icons/full/etool16/delete.gif"
+ id="org.eclipse.tcf.te.ui.commands.delete"
+ label="%command.delete.label"
+ mnemonic="%command.delete.mnemonic"
+ style="push"
+ tooltip="%command.delete.description">
+ <visibleWhen checkEnabled="false">
+ <with variable="selection">
+ <count value="+"/>
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot">
+ </test>
+ </not>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ locationURI="popup:org.eclipse.tcf.te.ui.views.View#Popup?after=group.refresh">
+ <command
+ commandId="org.eclipse.tcf.te.ui.command.refresh"
+ label="%fsmenu.refresh.label"
+ style="push"
+ tooltip="%command.refresh.tooltip">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ locationURI="popup:org.eclipse.tcf.te.ui.views.View#Popup?after=group.syncop">
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.update"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Update"
+ id="update"
+ label="%temenu.update.label"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.commit"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Commit"
+ id="commit"
+ label="%temenu.commit.label"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.merge"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Merge"
+ id="merge"
+ label="%temenu.merge.label"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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>
+ </visibleWhen>
+ </command>
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.revert"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Revert"
+ id="revert"
+ label="%temenu.revert.label"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.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>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ locationURI="popup:org.eclipse.tcf.te.ui.views.View#Popup?after=group.operations">
+ <command
+ commandId="org.eclipse.ui.edit.rename"
+ helpContextId="org.eclipse.tcf.te.tcf.filesystem.command_Rename"
+ id="rename"
+ label="%command.label.rename"
+ mnemonic="%command.rename.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot">
+ </test>
+ </not>
+ </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="%command.move.mnemonic"
+ style="push">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="+">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot">
+ </test>
+ </not>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+
+ <menuContribution
+ locationURI="toolbar:org.eclipse.tcf.te.tcf.filesystem.FSExplorerEditorPage?before=additions">
+ <command
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.refreshViewer"
+ icon="icons/obj16/refresh.gif"
+ label="%command.refreshViewer.label"
+ style="push"
+ tooltip="%command.refreshViewer.tooltip">
+ </command>
+ </menuContribution>
+ </extension>
+
+<!-- Property page contributions -->
+ <extension point="org.eclipse.ui.propertyPages">
+ <page
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.properties.GeneralInformationPage"
+ id="org.eclipse.tcf.te.tcf.filesystem.pages.basic"
+ name="%GeneralInformationPage.name">
+ <enabledWhen>
+ <and>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ <not>
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot">
+ </test>
+ </not>
+ </and>
+ </enabledWhen>
+ </page>
+ </extension>
+
+<!-- Property tester contributions -->
+ <extension point="org.eclipse.core.expressions.propertyTesters">
+ <propertyTester
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.testers.CachePropertyTester"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache"
+ namespace="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache"
+ properties="isAutoSavingOn"
+ type="java.lang.Object">
+ </propertyTester>
+ <propertyTester
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.testers.ClipboardPropertyTester"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertytester.clipboard"
+ namespace="org.eclipse.tcf.te.tcf.filesystem.propertytester.clipboard"
+ properties="canPaste"
+ type="org.eclipse.jface.viewers.IStructuredSelection">
+ </propertyTester>
+ <propertyTester
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.testers.EditorActivationEventPropertyTester"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertytester.event"
+ namespace="org.eclipse.tcf.te.tcf.filesystem.propertytester.event"
+ properties="isEditorActivation"
+ type="org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent">
+ </propertyTester>
+ </extension>
+
+<!-- Command contributions -->
+ <extension point="org.eclipse.ui.commands">
+ <command
+ id="org.eclipse.tcf.te.tcf.filesystem.commands.update"
+ name="%command.update.name">
+ </command>
+ <command
+ id="org.eclipse.tcf.te.tcf.filesystem.commands.commit"
+ name="%command.commit.name">
+ </command>
+ <command
+ id="org.eclipse.tcf.te.tcf.filesystem.commands.merge"
+ name="%command.merge.name">
+ </command>
+ <command
+ id="org.eclipse.tcf.te.tcf.filesystem.commands.revert"
+ name="%command.revert.name">
+ </command>
+ <command
+ id="org.eclipse.tcf.te.tcf.filesystem.commands.newFile"
+ name="%command.newfile.name">
+ </command>
+ <command
+ id="org.eclipse.tcf.te.tcf.filesystem.commands.newFolder"
+ name="%command.newfolder.name">
+ </command>
+ <command
+ id="org.eclipse.tcf.te.tcf.filesystem.commands.refreshViewer"
+ name="%command.refreshViewer.name">
+ </command>
+ </extension>
+
+<!-- Command handler contributions -->
+ <extension point="org.eclipse.ui.handlers">
+ <!-- This handler contribution is for the double click behaviour in the
+ Target Explore tree view -->
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.OpenFileHandler"
+ commandId="org.eclipse.ui.navigator.Open">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <test forcePluginActivation="true"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <test forcePluginActivation="true"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadable"/>
+ <not>
+ <test forcePluginActivation="true"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isBinaryFile"/>
+ </not>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <test forcePluginActivation="true"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <test forcePluginActivation="true"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadable"/>
+ <not>
+ <test forcePluginActivation="true"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isBinaryFile"/>
+ </not>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.UpdateHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.update">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <and>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="outdated"/>
+ </iterate>
+ </with>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn"/>
+ </not>
+ </and>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.CommitHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.commit">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <and>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="modified"/>
+ </iterate>
+ </with>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn"/>
+ </not>
+ </and>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.MergeHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.merge">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <and>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="conflict"/>
+ </iterate>
+ </with>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn"/>
+ </not>
+ </and>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.UpdateHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.revert">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <and>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <or>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="modified"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.getCacheState"
+ value="conflict"/>
+ </or>
+ </iterate>
+ </with>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.cache.isAutoSavingOn"/>
+ </not>
+ </and>
+ </enabledWhen>
+ </handler>
+
+
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.CutFilesHandler"
+ commandId="org.eclipse.ui.edit.cut">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot"/>
+ </not>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot"/>
+ </not>
+ <or>
+ <and>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadOnly"/>
+ </not>
+ </and>
+ <and>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows"/>
+ </not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable"/>
+ </and>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.CopyFilesHandler"
+ commandId="org.eclipse.ui.edit.copy">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadable"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot"/>
+ </not>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot"/>
+ </not>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.PasteFilesHandler"
+ commandId="org.eclipse.ui.edit.paste">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <and>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot"/>
+ </not>
+ </iterate>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.clipboard.canPaste"/>
+ </with>
+ </and>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.MoveFilesHandler"
+ commandId="org.eclipse.ui.edit.move">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot"/>
+ </not>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot"/>
+ </not>
+ <or>
+ <and>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadOnly"/>
+ </not>
+ </and>
+ <and>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows"/>
+ </not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable"/>
+ </and>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.RenameFilesHandler"
+ commandId="org.eclipse.ui.edit.rename">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot"/>
+ </not>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot"/>
+ </not>
+ <or>
+ <and>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadOnly"/>
+ </not>
+ </and>
+ <and>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows"/>
+ </not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable"/>
+ </and>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.NewFileHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.newFile">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <or>
+ <and>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isDirectory"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable"/>
+ </and>
+ <and>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <test args="isWritable"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.testParent"/>
+ </and>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.NewFolderHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.newFolder">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <or>
+ <and>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isDirectory"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable"/>
+ </and>
+ <and>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ <test args="isWritable"
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.testParent"/>
+ </and>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.RefreshViewerHandler"
+ commandId="org.eclipse.tcf.te.tcf.filesystem.commands.refreshViewer">
+ </handler>
+
+ <handler
+ commandId="org.eclipse.ui.edit.delete"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.DeleteHandler">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot"/>
+ </not>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot"/>
+ </not>
+ <or>
+ <and>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows"/>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isReadOnly"/>
+ </not>
+ </and>
+ <and>
+ <not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWindows"/>
+ </not>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isWritable"/>
+ </and>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+ <handler
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.RefreshHandler"
+ commandId="org.eclipse.tcf.te.ui.command.refresh">
+ <activeWhen>
+ <and>
+ <with variable="activePartId">
+ <or>
+ <equals value="org.eclipse.tcf.te.ui.views.View"/>
+ <equals value="org.eclipse.tcf.te.ui.views.Editor"/>
+ </or>
+ </with>
+ <with variable="selection">
+ <iterate operator="and" ifEmpty="false">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ </iterate>
+ </with>
+ </and>
+ </activeWhen>
+ <enabledWhen>
+ <with variable="selection">
+ <iterate ifEmpty="false" operator="and">
+ <instanceof value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"/>
+ <or>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isSystemRoot"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isRoot"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isDirectory"/>
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.treenode.isFile"/>
+ </or>
+ </iterate>
+ </with>
+ </enabledWhen>
+ </handler>
+
+ </extension>
+
+<!-- Decorator contributions -->
+ <extension point="org.eclipse.ui.decorators">
+ <decorator
+ icon="icons/ovr/ovr_modified.png"
+ id="org.eclipse.tcf.te.tcf.filesystem.decorators.modified"
+ label="%decorator.modified.label"
+ lightweight="true"
+ location="TOP_RIGHT"
+ state="true">
+ <enablement>
+ <objectState
+ name="cache.state"
+ value="modified">
+ </objectState>
+ </enablement>
+ </decorator>
+ <decorator
+ icon="icons/ovr/ovr_outdated.png"
+ id="org.eclipse.tcf.te.tcf.filesystem.decorators.outdated"
+ label="%decorator.outdated.label"
+ lightweight="true"
+ location="TOP_RIGHT"
+ state="true">
+ <enablement>
+ <objectState
+ name="cache.state"
+ value="outdated">
+ </objectState>
+ </enablement>
+ </decorator>
+ <decorator
+ icon="icons/ovr/ovr_conflict.png"
+ id="org.eclipse.tcf.te.tcf.filesystem.decorators.conflict"
+ label="%decorator.conflict.label"
+ lightweight="true"
+ location="TOP_RIGHT"
+ state="true">
+ <enablement>
+ <objectState
+ name="cache.state"
+ value="conflict">
+ </objectState>
+ </enablement>
+ </decorator>
+ <decorator
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.decorators.PhantomDecorator"
+ 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>
+ <decorator
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.decorators.PhantomDecorator"
+ id="org.eclipse.tcf.te.tcf.filesystem.decorators.hidden"
+ label="%decorator.hidden.label"
+ state="true">
+ <enablement>
+ <objectState
+ name="hidden"
+ value="true">
+ </objectState>
+ </enablement>
+ </decorator>
+ </extension>
+
+<!-- Preference contributions -->
+ <extension point="org.eclipse.core.runtime.preferences">
+ <initializer class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.preferences.PreferencesInitializer"/>
+ </extension>
+
+<!-- Preference page contributions -->
+ <extension point="org.eclipse.ui.preferencePages">
+ <page
+ category="org.eclipse.tcf.te.ui.preferences.general"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.preferences.PreferencePage"
+ id="org.eclipse.tcf.te.ui.preferences.tcf.filesystem"
+ name="%preference.page.name">
+ </page>
+ </extension>
+
+<!-- Adapter contributions -->
+ <extension point="org.eclipse.core.runtime.adapters">
+ <factory
+ adaptableType="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.adapters.FSTreeNodeAdapterFactory">
+ <adapter type="org.eclipse.ui.IActionFilter"/>
+ <adapter type="org.eclipse.jface.viewers.ILabelProvider"/>
+ <adapter type="org.eclipse.ui.IPersistableElement"/>
+ <adapter type="org.eclipse.tcf.te.ui.interfaces.ILazyLoader"/>
+ <adapter type="org.eclipse.tcf.te.ui.interfaces.ISearchable"/>
+ <adapter type="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProvider"/>
+ <adapter type="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode"/>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.adapters.ViewerInputAdapterFactory">
+ <adapter
+ type="org.eclipse.tcf.te.core.interfaces.IViewerInput">
+ </adapter>
+ <adapter
+ type="org.eclipse.tcf.te.core.interfaces.IPropertyChangeProvider">
+ </adapter>
+ </factory>
+ </extension>
+
+<!-- CellEditor factory contributions -->
+ <extension point="org.eclipse.tcf.te.ui.cellEditors">
+ <cellEditor
+ editorFactory="org.eclipse.tcf.te.tcf.filesystem.ui.internal.celleditor.FSViewerCellEditorFactory">
+ <activation>
+ <and>
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate>
+ <instanceof
+ value="org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode">
+ </instanceof>
+ </iterate>
+ </with>
+ <with
+ variable="event">
+ <test
+ property="org.eclipse.tcf.te.tcf.filesystem.propertytester.event.isEditorActivation">
+ </test>
+ </with>
+ </and>
+ </activation>
+ <contributeTo
+ viewerId="org.eclipse.tcf.te.ui.views.View">
+ </contributeTo>
+ <contributeTo
+ viewerId="org.eclipse.tcf.te.ui.controls.viewer.fs">
+ </contributeTo>
+ </cellEditor>
+ </extension>
+
+<!-- New target wizard contributions -->
+ <extension point="org.eclipse.tcf.te.ui.newWizards">
+ <category
+ id="org.eclipse.tcf.te.tcf.filesystem.ui.newWizards.category"
+ name="%NewWizards.category.filesystem.name">
+ </category>
+ </extension>
+
+<!-- New wizard contributions -->
+ <extension point="org.eclipse.tcf.te.ui.newWizards">
+ <wizard
+ canFinishEarly="false"
+ category="org.eclipse.tcf.te.tcf.filesystem.ui.newWizards.category"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.wizards.NewFileWizard"
+ hasPages="true"
+ icon="icons/obj16/newfile_wiz.gif"
+ id="org.eclipse.tcf.te.tcf.filesystem.wizards.NewFileWizard"
+ name="%newfile.wizard.name">
+ <description>
+ %newfile.wizard.description
+ </description>
+ </wizard>
+ <wizard
+ canFinishEarly="false"
+ category="org.eclipse.tcf.te.tcf.filesystem.ui.newWizards.category"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.wizards.NewFolderWizard"
+ hasPages="true"
+ icon="icons/obj16/newfolder_wiz.gif"
+ id="org.eclipse.tcf.te.tcf.filesystem.wizards.NewFolderWizard"
+ name="%newfolder.wizard.name">
+ <description>
+ %newfolder.wizard.description
+ </description>
+ </wizard>
+ </extension>
+
+ <extension point="org.eclipse.tcf.te.ui.viewers">
+ <viewer
+ autoExpandLevel="0"
+ contentProvider="org.eclipse.tcf.te.tcf.filesystem.ui.controls.FSTreeContentProvider"
+ id="org.eclipse.tcf.te.ui.controls.viewer.fs"
+ persistent="true">
+ <creation>
+ <style name="SWT.FULL_SELECTION" />
+ <style name="SWT.MULTI" />
+ </creation>
+ <dragSupport
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.dnd.FSDragSourceListener">
+ <operations>
+ <operation name="DND.DROP_COPY" />
+ <operation name="DND.DROP_MOVE" />
+ <operation name="DND.DROP_LINK" />
+ </operations>
+ <transferTypes>
+ <transferType name ="LocalSelectionTransfer" />
+ <transferType
+ name="FileTransfer">
+ </transferType>
+ </transferTypes>
+ </dragSupport>
+ <dropSupport
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.dnd.FSDropTargetListener">
+ <operations>
+ <operation name="DND.DROP_COPY" />
+ <operation name="DND.DROP_MOVE" />
+ <operation name="DND.DROP_LINK" />
+ </operations>
+ <transferTypes>
+ <transferType name ="LocalSelectionTransfer" />
+ <transferType
+ name="FileTransfer">
+ </transferType>
+ </transferTypes>
+ </dropSupport>
+ </viewer>
+ <columnContribution viewerId="org.eclipse.tcf.te.ui.controls.viewer.fs">
+ <column
+ alignment="SWT.LEFT"
+ comparator="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FSTreeElementComparator"
+ id="name"
+ labelProvider="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FSTreeElementLabelProvider"
+ moveable="true"
+ name="%column.name.name"
+ resizable="true"
+ style="SWT.LEFT"
+ visible="true"
+ width="300">
+ </column>
+ <column
+ alignment="SWT.RIGHT"
+ comparator="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.SizeComparator"
+ id="size"
+ labelProvider="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.SizeLabelProvider"
+ moveable="true"
+ name="%column.name.size"
+ resizable="true"
+ style="SWT.RIGHT"
+ visible="true"
+ width="100">
+ </column>
+ <column
+ alignment="SWT.LEFT"
+ comparator="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FileTypeComparator"
+ id="type"
+ labelProvider="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FileTypeLabelProvider"
+ moveable="true"
+ name="%column.name.type"
+ resizable="true"
+ style="SWT.LEFT"
+ visible="false"
+ width="100">
+ </column>
+ <column
+ alignment="SWT.RIGHT"
+ comparator="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.ModificationTimeComparator"
+ id="modified"
+ labelProvider="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.ModificationTimeLabelProvider"
+ moveable="true"
+ name="%column.name.modified"
+ resizable="true"
+ style="SWT.RIGHT"
+ visible="true"
+ width="120">
+ </column>
+ <column
+ alignment="SWT.RIGHT"
+ comparator="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.AccessTimeComparator"
+ id="accessed"
+ labelProvider="org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.AccessTimeLabelProvider"
+ moveable="true"
+ name="%column.name.accessed"
+ resizable="true"
+ style="SWT.RIGHT"
+ visible="false"
+ width="120">
+ </column>
+ </columnContribution>
+
+ <filterContribution viewerId="org.eclipse.tcf.te.ui.controls.viewer.fs">
+ <filter
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.filters.HiddenFilesViewerFilter"
+ description="%filter.description.hidden"
+ enabled="true"
+ id="org.eclipse.tcf.te.tcf.filesystem.navigator.filter.hiddenFiles"
+ image="icons/obj16/hidden_file_filter.png"
+ name="%filter.name.hidden"
+ visibleInUI="true">
+ </filter>
+ <filter
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.filters.SystemFilesViewerFilter"
+ description="%filter.description.system"
+ enabled="true"
+ id="org.eclipse.tcf.te.tcf.filesystem.navigator.filter.systemFiles"
+ image="icons/obj16/system_file_filter.png"
+ name="%filter.name.system"
+ visibleInUI="true">
+ <activation>
+ <with variable="input">
+ <adapt type="org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode">
+ <test property="org.eclipse.tcf.te.tcf.filesystem.propertytester.peer.isWindows" />
+ </adapt>
+ </with>
+ </activation>
+ </filter>
+ </filterContribution>
+ </extension>
+ <extension
+ point="org.eclipse.ui.views.properties.tabbed.propertyTabs">
+ <propertyTabs
+ contributorId="org.eclipse.tcf.te.ui">
+ <propertyTab
+ category="org.eclipse.tcf.te"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertytab.general"
+ label="%propertyTab.general.label">
+ </propertyTab>
+ <propertyTab
+ afterTab="org.eclipse.tcf.te.tcf.filesystem.propertytab.general"
+ category="org.eclipse.tcf.te"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertytab.permissions"
+ label="%propertyTab.permission.label">
+ </propertyTab>
+ <propertyTab
+ afterTab="org.eclipse.tcf.te.tcf.filesystem.propertytab.general,org.eclipse.tcf.te.tcf.filesystem.propertytab.permissions"
+ category="org.eclipse.tcf.te"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertytab.advanced"
+ label="%propertyTab.advanced.label">
+ </propertyTab>
+ </propertyTabs>
+ </extension>
+ <extension
+ point="org.eclipse.ui.views.properties.tabbed.propertySections">
+ <propertySections
+ contributorId="org.eclipse.tcf.te.ui">
+ <propertySection
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.BasicFolderSection"
+ enablesFor="1"
+ filter="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.FolderFilter"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertysection.folder.basic"
+ tab="org.eclipse.tcf.te.tcf.filesystem.propertytab.general">
+ </propertySection>
+ <propertySection
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.BasicFileSection"
+ enablesFor="1"
+ filter="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.FileFilter"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertysection.file.basic"
+ tab="org.eclipse.tcf.te.tcf.filesystem.propertytab.general">
+ </propertySection>
+ <propertySection
+ afterSection="org.eclipse.tcf.te.tcf.filesystem.propertysection.folder.basic,org.eclipse.tcf.te.tcf.filesystem.propertysection.file.basic"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.WindowsAttributesSection"
+ enablesFor="1"
+ filter="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.WindowsFilter"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertysection.windows.attributes"
+ tab="org.eclipse.tcf.te.tcf.filesystem.propertytab.general">
+ </propertySection>
+ <propertySection
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.LinuxPermissionsSection"
+ enablesFor="1"
+ filter="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.LinuxFilter"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertysection.linux.permissions"
+ tab="org.eclipse.tcf.te.tcf.filesystem.propertytab.permissions">
+ </propertySection>
+ <propertySection
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.WindowsFolderAISection"
+ enablesFor="1"
+ filter="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.WindowsFolderFilter"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertysection.windows.folderAI"
+ tab="org.eclipse.tcf.te.tcf.filesystem.propertytab.advanced">
+ </propertySection>
+ <propertySection
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.WindowsFileAISection"
+ enablesFor="1"
+ filter="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.WindowsFileFilter"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertysection.windows.fileAI"
+ tab="org.eclipse.tcf.te.tcf.filesystem.propertytab.advanced">
+ </propertySection>
+ <propertySection
+ afterSection="org.eclipse.tcf.te.tcf.filesystem.propertysection.windows.folderAI,"
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.WindowsAttributesCESection"
+ enablesFor="1"
+ filter="org.eclipse.tcf.te.tcf.filesystem.ui.internal.tabbed.WindowsFilter"
+ id="org.eclipse.tcf.te.tcf.filesystem.propertysection.windows.attributesCE"
+ tab="org.eclipse.tcf.te.tcf.filesystem.propertytab.advanced">
+ </propertySection>
+ </propertySections>
+ </extension>
+ <extension
+ point="org.eclipse.ui.elementFactories">
+ <factory
+ class="org.eclipse.tcf.te.tcf.filesystem.ui.internal.adapters.FSTreeNodeFactory"
+ id="org.eclipse.tcf.te.tcf.filesystem.ui.nodeFactory">
+ </factory>
+ </extension>
+ <extension
+ point="org.eclipse.ui.bindings">
+ <key
+ commandId="org.eclipse.ui.navigator.Open"
+ contextId="org.eclipse.tcf.te.ui.views.View"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="F3">
+ </key>
+ <key
+ commandId="org.eclipse.ui.navigator.Open"
+ contextId="org.eclipse.tcf.te.ui.views.Editor"
+ schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="F3">
+ </key>
+ </extension>
+</plugin>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/pom.xml b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/pom.xml
new file mode 100644
index 000000000..94a76a685
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.tcf</groupId>
+ <artifactId>org.eclipse.tcf.maven-build</artifactId>
+ <version>1.3.0-SNAPSHOT</version>
+ <relativePath>../../../admin/pom-build.xml</relativePath>
+ </parent>
+
+ <version>1.3.0.qualifier</version>
+ <artifactId>org.eclipse.tcf.te.filesystem.ui</artifactId>
+ <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/activator/UIPlugin.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/activator/UIPlugin.java
new file mode 100644
index 000000000..5584c7375
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/activator/UIPlugin.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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
+ * 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
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.activator;
+
+import java.net.URL;
+
+import org.eclipse.core.commands.Command;
+import org.eclipse.core.commands.IExecutionListener;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.tcf.filesystem.ui.interfaces.preferences.IPreferenceKeys;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.autosave.SaveAllListener;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.autosave.SaveListener;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.FsClipboard;
+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;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class UIPlugin extends AbstractUIPlugin implements IPreferenceKeys {
+ // The shared instance of this plug-in.
+ private static UIPlugin plugin;
+ // The listener which listens to command "SAVE" and synchronize the local file with the target.
+ 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
+ */
+ public UIPlugin() {
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static UIPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Convenience method which returns the unique identifier of this plugin.
+ */
+ public static String getUniqueIdentifier() {
+ if (getDefault() != null && getDefault().getBundle() != null) {
+ return getDefault().getBundle().getSymbolicName();
+ }
+ return "org.eclipse.tcf.te.tcf.filesystem.ui"; //$NON-NLS-1$
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ clipboard = new FsClipboard();
+
+ // Add the two execution listeners to command "SAVE" and "SAVE ALL".
+ ICommandService commandService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
+ if (commandService != null) {
+ saveListener = new SaveListener();
+ Command saveCmd = commandService.getCommand(IWorkbenchCommandConstants.FILE_SAVE);
+ saveCmd.addExecutionListener(saveListener);
+ saveAllListener = new SaveAllListener();
+ Command saveAllCmd = commandService.getCommand(IWorkbenchCommandConstants.FILE_SAVE_ALL);
+ saveAllCmd.addExecutionListener(saveAllListener);
+ }
+ }
+
+ /**
+ * Get the shared instance of clipboard
+ */
+ public static FsClipboard getClipboard() {
+ return plugin.clipboard;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ // Remove the two execution listeners.
+ ICommandService commandService = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class);
+ if (commandService != null) {
+ Command saveCmd = commandService.getCommand(IWorkbenchCommandConstants.FILE_SAVE);
+ saveCmd.removeExecutionListener(saveListener);
+ Command saveAllCmd = commandService.getCommand(IWorkbenchCommandConstants.FILE_SAVE_ALL);
+ saveAllCmd.removeExecutionListener(saveAllListener);
+ }
+ // Ignore SWTException here, the display might be disposed already.
+ if (clipboard != null) {
+ try {
+ clipboard.dispose();
+ }
+ catch (SWTException e) { /* ignored on purpose */
+ }
+ }
+ clipboard = null;
+ plugin = null;
+ super.stop(context);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry)
+ */
+ @Override
+ protected void initializeImageRegistry(ImageRegistry registry) {
+ URL url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ + "folder.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.FOLDER, ImageDescriptor.createFromURL(url));
+
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ + "root.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.ROOT, ImageDescriptor.createFromURL(url));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ + "rootdrive.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.ROOT_DRIVE, 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_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));
+ url = UIPlugin.getDefault().getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ + "refresh.gif"); //$NON-NLS-1$
+ registry.put(ImageConsts.REFRESH_IMAGE, ImageDescriptor.createFromURL(url));
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>Image</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>Image</code> object instance or <code>null</code>.
+ */
+ public static Image getImage(String key) {
+ return getDefault().getImageRegistry().get(key);
+ }
+
+ /**
+ * Loads the image registered under the specified key from the image
+ * registry and returns the <code>ImageDescriptor</code> object instance.
+ *
+ * @param key The key the image is registered with.
+ * @return The <code>ImageDescriptor</code> object instance or <code>null</code>.
+ */
+ 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;
+ }
+
+ /**
+ * If the option of "autosaving" is set to on.
+ *
+ * @return true if it is auto saving or else false.
+ */
+ public static boolean isAutoSaving() {
+ IPreferenceStore preferenceStore = getDefault().getPreferenceStore();
+ boolean autoSaving = preferenceStore.getBoolean(PREF_AUTOSAVING);
+ return autoSaving;
+ }
+
+ /**
+ * If the option of "expanded_persisted" is set to on.
+ *
+ * @return true if the expanded state should be persisted or else false.
+ */
+ public static boolean isExpandedPersisted() {
+ IPreferenceStore preferenceStore = getDefault().getPreferenceStore();
+ boolean persisted = preferenceStore.getBoolean(PREF_EXPANDED_PERSISTED);
+ return persisted;
+ }
+
+ /**
+ * If the option of "in-place editor" is set to on.
+ *
+ * @return true if it uses in-place editor when renaming files/folders.
+ */
+ public static boolean isInPlaceEditor() {
+ IPreferenceStore preferenceStore = getDefault().getPreferenceStore();
+ boolean inPlaceEditor = preferenceStore.getBoolean(PREF_RENAMING_IN_PLACE_EDITOR);
+ return inPlaceEditor;
+ }
+
+ /**
+ * If the option of "copy permissions" is set to on.
+ *
+ * @return true if it should copy source file permissions.
+ */
+ public static boolean isCopyPermission() {
+ IPreferenceStore preferenceStore = getDefault().getPreferenceStore();
+ boolean copyPermission = preferenceStore.getBoolean(PREF_COPY_PERMISSION);
+ return copyPermission;
+ }
+
+ /**
+ * If the option of "copy ownership" is set to on.
+ *
+ * @return true if it should copy source file ownership.
+ */
+ public static boolean isCopyOwnership() {
+ IPreferenceStore preferenceStore = getDefault().getPreferenceStore();
+ boolean copyOwnership = preferenceStore.getBoolean(PREF_COPY_OWNERSHIP);
+ return copyOwnership;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSNavigatorContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSNavigatorContentProvider.java
new file mode 100644
index 000000000..00e34dac5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSNavigatorContentProvider.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.controls;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+
+
+/**
+ * File system content provider for the common navigator of Target Explorer.
+ */
+public class FSNavigatorContentProvider extends NavigatorContentProvider {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.trees.TreeContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public void inputChanged(final Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ UIPlugin.getClipboard().addPropertyChangeListener(commonViewerListener);
+ UIPlugin plugin = UIPlugin.getDefault();
+ IPreferenceStore preferenceStore = plugin.getPreferenceStore();
+ preferenceStore.addPropertyChangeListener(commonViewerListener);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.trees.TreeContentProvider#dispose()
+ */
+ @Override
+ public void dispose() {
+ UIPlugin.getClipboard().removePropertyChangeListener(commonViewerListener);
+ UIPlugin plugin = UIPlugin.getDefault();
+ IPreferenceStore preferenceStore = plugin.getPreferenceStore();
+ preferenceStore.removePropertyChangeListener(commonViewerListener);
+ super.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode)parentElement;
+ if (node.isFile()) return NO_ELEMENTS;
+ }
+ return super.getChildren(parentElement);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ @Override
+ public boolean hasChildren(final Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode)element;
+ if(node.isFile()) {
+ return false;
+ }
+ }
+ return super.hasChildren(element);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSTreeContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSTreeContentProvider.java
new file mode 100644
index 000000000..bf4e5abac
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSTreeContentProvider.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.controls;
+
+/**
+ * File system tree content provider implementation.
+ */
+public class FSTreeContentProvider extends FSNavigatorContentProvider {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.controls.FSNavigatorContentProvider#isRootNodeVisible()
+ */
+ @Override
+ protected boolean isRootNodeVisible() {
+ return false;
+ }
+} \ No newline at end of file
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSTreeViewerSorter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSTreeViewerSorter.java
new file mode 100644
index 000000000..2d53be057
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/FSTreeViewerSorter.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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.tcf.filesystem.ui.controls;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FSTreeElementComparator;
+import org.eclipse.tcf.te.ui.trees.TreeViewerSorterCaseInsensitive;
+
+/**
+ * File system tree control viewer sorter implementation.
+ */
+public class FSTreeViewerSorter extends TreeViewerSorterCaseInsensitive {
+ private final FSTreeElementComparator comparator;
+
+ /**
+ * Constructor.
+ */
+ public FSTreeViewerSorter() {
+ comparator = new FSTreeElementComparator();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ if (e1 instanceof FSTreeNode && e2 instanceof FSTreeNode) {
+ return comparator.compare(e1, e2);
+ }
+ return super.compare(viewer, e1, e2);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/NavigatorContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/NavigatorContentProvider.java
new file mode 100644
index 000000000..04416adba
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/NavigatorContentProvider.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.controls;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.runtime.IRuntimeModel;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.AbstractTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.ModelManager;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+
+
+/**
+ * The base navigator content provider for File System and Process Monitor
+ */
+public abstract class NavigatorContentProvider extends TreeContentProvider implements ITreeViewerListener {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ @Override
+ public Object getParent(Object element) {
+ if (element instanceof AbstractTreeNode) {
+ AbstractTreeNode node = (AbstractTreeNode) element;
+ AbstractTreeNode parent = node.getParent();
+ if (parent != null) {
+ if (parent.isSystemRoot()) {
+ if (isRootNodeVisible()) return parent;
+ return null;
+ }
+ return parent;
+ }
+ if (isRootNodeVisible()) return node.peerNode;
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeViewerListener#treeCollapsed(org.eclipse.jface.viewers.TreeExpansionEvent)
+ */
+ @Override
+ public void treeCollapsed(TreeExpansionEvent event) {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeViewerListener#treeExpanded(org.eclipse.jface.viewers.TreeExpansionEvent)
+ */
+ @Override
+ public void treeExpanded(TreeExpansionEvent event) {
+ Object object = event.getElement();
+ if(object instanceof AbstractTreeNode) {
+ AbstractTreeNode parent = (AbstractTreeNode) object;
+ if (parent.childrenQueried && !parent.childrenQueryRunning) {
+ parent.refreshChildren();
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.trees.TreeContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+ this.viewer.addTreeListener(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.trees.TreeContentProvider#dispose()
+ */
+ @Override
+ public void dispose() {
+ this.viewer.removeTreeListener(this);
+ super.dispose();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ super.getChildren(parentElement);
+
+ if (parentElement instanceof IPeerNode) {
+ final IPeerNode peerNode = (IPeerNode)parentElement;
+ IRuntimeModel model = ModelManager.getRuntimeModel(peerNode);
+ if (isRootNodeVisible()) {
+ AbstractTreeNode root = model.getRoot();
+ if(!root.childrenQueried && !root.childrenQueryRunning) {
+ root.queryChildren();
+ }
+ return new Object[] { root };
+ }
+ return getChildren(model.getRoot());
+ } else if (parentElement instanceof AbstractTreeNode) {
+ AbstractTreeNode node = (AbstractTreeNode)parentElement;
+ List<Object> current = new ArrayList<Object>(node.getChildren());
+ if (!node.childrenQueried) {
+ current.add(getPending(node));
+ if (!node.childrenQueryRunning) {
+ node.queryChildren();
+ }
+ }
+ return current.toArray();
+ }
+
+ return NO_ELEMENTS;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ @Override
+ public boolean hasChildren(final Object element) {
+ Assert.isNotNull(element);
+
+ boolean hasChildren = false;
+
+ if (element instanceof AbstractTreeNode) {
+ AbstractTreeNode node = (AbstractTreeNode)element;
+ if(node.isSystemRoot()) {
+ hasChildren = true;
+ }
+ else {
+ hasChildren = !node.childrenQueried || super.hasChildren(element);
+ }
+ }
+ else if (element instanceof IPeerNode) {
+ IPeerNode peerNode = (IPeerNode) element;
+ IRuntimeModel model = ModelManager.getRuntimeModel(peerNode);
+ AbstractTreeNode root = model.getRoot();
+ hasChildren = root != null ? hasChildren(root) : true;
+ }
+
+ return hasChildren;
+ }
+
+ /**
+ * If the root node of the tree is visible.
+ *
+ * @return true if it is visible.
+ */
+ protected boolean isRootNodeVisible() {
+ return true;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/TreeContentProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/TreeContentProvider.java
new file mode 100644
index 000000000..3aa693cad
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/controls/TreeContentProvider.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.controls;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+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.tcf.te.core.interfaces.IConnectable;
+import org.eclipse.tcf.te.core.interfaces.IPropertyChangeProvider;
+import org.eclipse.tcf.te.runtime.model.MessageModelNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.ui.trees.CommonViewerListener;
+import org.eclipse.tcf.te.ui.trees.Pending;
+
+/**
+ * The base tree content provider that defines several default methods.
+ */
+public abstract class TreeContentProvider implements ITreeContentProvider, PropertyChangeListener {
+
+ /**
+ * Static reference to the return value representing no elements.
+ */
+ protected final static Object[] NO_ELEMENTS = new Object[0];
+
+ // The listener to refresh the common viewer when properties change.
+ protected CommonViewerListener commonViewerListener;
+ // The viewer inputs that have been added a property change listener.
+ private Set<IPropertyChangeProvider> providers = Collections.synchronizedSet(new HashSet<IPropertyChangeProvider>());
+ // The viewer
+ protected TreeViewer viewer;
+ // The pending nodes and their direct parents.
+ private Map<Object, Pending> pendings;
+
+ // The target's peer model.
+ private IPeerNode peerNode;
+
+ /**
+ * Create a tree content provider.
+ */
+ public TreeContentProvider() {
+ pendings = new HashMap<Object, Pending>();
+ }
+
+ /**
+ * Get the pending node for the specified parent.
+ * If it exists, then return it. If not, create one
+ * and save it and return it.
+ */
+ protected Pending getPending(Object parent) {
+ Pending pending = pendings.get(parent);
+ if(pending == null && viewer != null) {
+ pending = new Pending(viewer);
+ pendings.put(parent, pending);
+ }
+ return pending;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
+ */
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ @Override
+ public void dispose() {
+ for(IPropertyChangeProvider provider : providers) {
+ provider.removePropertyChangeListener(commonViewerListener);
+ provider.removePropertyChangeListener(this);
+ }
+ commonViewerListener.cancel();
+ providers.clear();
+ pendings.clear();
+ }
+
+ /**
+ * Get the filtered children of the parent using the
+ * filters registered in the viewer.
+ *
+ * @param parent The parent element.
+ * @return The children after filtering.
+ */
+ private Object[] getFilteredChildren(Object parent) {
+ Object[] result = getChildren(parent);
+ if (viewer != null) {
+ ViewerFilter[] filters = viewer.getFilters();
+ if (filters != null) {
+ for (ViewerFilter filter : filters) {
+ Object[] filteredResult = filter.filter(viewer, parent, result);
+ result = filteredResult;
+ }
+ }
+ }
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ @Override
+ public Object[] getChildren(Object parentElement) {
+ Assert.isNotNull(parentElement);
+
+ if (parentElement instanceof IAdaptable) {
+ IAdaptable adaptable = (IAdaptable) parentElement;
+ IPropertyChangeProvider provider = (IPropertyChangeProvider) adaptable.getAdapter(IPropertyChangeProvider.class);
+ if (provider != null) {
+ installPropertyChangeListener(provider);
+ }
+ }
+
+ return NO_ELEMENTS;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ Assert.isTrue(viewer instanceof TreeViewer);
+ this.viewer = (TreeViewer) viewer;
+ this.commonViewerListener = new CommonViewerListener(this.viewer, this);
+ peerNode = getPeerNode(newInput);
+ }
+
+ protected IPeerNode getPeerNode(Object input) {
+ IPeerNode peerNode = input instanceof IPeerNode ? (IPeerNode)input : null;
+ if (peerNode == null && input instanceof IAdaptable) {
+ peerNode = (IPeerNode)((IAdaptable)input).getAdapter(IPeerNode.class);
+ }
+ return peerNode;
+ }
+
+ /**
+ * Install a property change listener to the specified element.
+ *
+ * @param provider The element node.
+ */
+ private void installPropertyChangeListener(IPropertyChangeProvider provider) {
+ if (provider != null && !providers.contains(provider)) {
+ if (commonViewerListener != null) {
+ provider.addPropertyChangeListener(commonViewerListener);
+ }
+ provider.addPropertyChangeListener(this);
+ providers.add(provider);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ @Override
+ public boolean hasChildren(Object element) {
+ Object[] children = getFilteredChildren(element);
+ return children != null && children.length > 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object)
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if (peerNode != null && peerNode.getConnectState() == IConnectable.STATE_CONNECTED) {
+ return getChildren(inputElement);
+ }
+
+ String message = null;
+ if (peerNode != null) {
+ if (peerNode.getConnectState() == IConnectable.STATE_CONNECTION_LOST ||
+ peerNode.getConnectState() == IConnectable.STATE_CONNECTION_RECOVERING) {
+ message = Messages.getStringDelegated(peerNode, "FileSystem_ContentProvider_connectionLost"); //$NON-NLS-1$
+ }
+ if (message == null) {
+ message = Messages.getStringDelegated(peerNode, "FileSystem_ContentProvider_notConnected"); //$NON-NLS-1$
+ }
+ }
+
+ return new Object[] { new MessageModelNode(message != null ? message : Messages.ContentProvider_notConnected, IStatus.INFO, false) };
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSFolderSelectionDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSFolderSelectionDialog.java
new file mode 100644
index 000000000..4ce589429
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSFolderSelectionDialog.java
@@ -0,0 +1,329 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.dialogs;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+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.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.runtime.callback.Callback;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.ModelManager;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.controls.FSTreeContentProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.controls.FSTreeViewerSorter;
+import org.eclipse.tcf.te.tcf.filesystem.ui.interfaces.IFSConstants;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FSTreeElementLabelProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.MoveFilesHandler;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.ui.trees.FilterDescriptor;
+import org.eclipse.tcf.te.ui.trees.ViewerStateManager;
+import org.eclipse.ui.IDecoratorManager;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+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 {
+ // The nodes that are being moved.
+ private List<FSTreeNode> movedNodes;
+ private final int mode;
+
+ public static final int MODE_ALL = 0;
+ public static final int MODE_ALL_WARNING_NOT_WRITABLE = 1;
+ public static final int MODE_ONLY_WRITABLE = 2;
+
+ /**
+ * Create an FSFolderSelectionDialog using the specified shell as the parent.
+ *
+ * @param parentShell The parent shell.
+ */
+ public FSFolderSelectionDialog(Shell parentShell) {
+ this(parentShell, MODE_ONLY_WRITABLE);
+ }
+
+ /**
+ * Create an FSFolderSelectionDialog using the specified shell as the parent.
+ *
+ * @param parentShell The parent shell.
+ * @param mode The mode of this dialog.
+ */
+ public FSFolderSelectionDialog(Shell parentShell, int mode) {
+ this(parentShell, new FSTreeElementLabelProvider(), new FSTreeContentProvider(), mode);
+ }
+
+ /**
+ * 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.
+ * @param mode The mode of this dialog.
+ */
+ private FSFolderSelectionDialog(Shell parentShell, ILabelProvider labelProvider, ITreeContentProvider contentProvider, int mode) {
+ super(parentShell, createDecoratingLabelProvider(labelProvider), contentProvider);
+ this.mode = mode;
+ setTitle(Messages.FSFolderSelectionDialog_MoveDialogTitle);
+ setMessage(Messages.FSFolderSelectionDialog_MoveDialogMessage);
+ this.setAllowMultiple(false);
+ this.setComparator(new FSTreeViewerSorter());
+ this.addFilter(new DirectoryFilter());
+ this.setStatusLineAboveButtons(true);
+ this.setValidator(new ISelectionStatusValidator() {
+ @Override
+ public IStatus validate(final Object[] selection) {
+ return isValidFolder(selection);
+ }
+ });
+ }
+
+ /**
+ * The viewer filter used to filter out files.
+ */
+ static class DirectoryFilter extends ViewerFilter {
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ if(node.isFile()) return false;
+ }
+ return true;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.dialogs.ElementTreeSelectionDialog#setInput(java.lang.Object)
+ */
+ @Override
+ public void setInput(Object input) {
+ super.setInput(input);
+ FilterDescriptor[] filterDescriptors = ViewerStateManager.getInstance().getFilterDescriptors(IFSConstants.ID_TREE_VIEWER_FS, input);
+ Assert.isNotNull(filterDescriptors);
+ for (FilterDescriptor descriptor : filterDescriptors) {
+ if (descriptor.isEnabled()) {
+ addFilter(descriptor.getFilter());
+ }
+ }
+ }
+
+ /**
+ * Create a decorating label provider using the specified label provider.
+ *
+ * @param labelProvider The label provider that actually provides labels and images.
+ * @return The decorating label provider.
+ */
+ private static ILabelProvider createDecoratingLabelProvider(ILabelProvider labelProvider) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IDecoratorManager manager = workbench.getDecoratorManager();
+ ILabelDecorator decorator = manager.getLabelDecorator();
+ return new DecoratingLabelProvider(labelProvider,decorator);
+ }
+
+ /**
+ * Set the nodes that are about to be moved.
+ *
+ * @param movedNodes The nodes.
+ */
+ public void setMovedNodes(List<FSTreeNode> movedNodes) {
+ this.movedNodes = movedNodes;
+ }
+
+ @Override
+ public TreeViewer getTreeViewer() {
+ return super.getTreeViewer();
+ }
+
+ /**
+ * 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);
+
+ Button refreshAll = new Button(parent, SWT.PUSH);
+ refreshAll.setText(Messages.FSFolderSelectionDialog_RefreshAll_menu);
+ refreshAll.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ refreshModel();
+ }
+ });
+
+ viewer.getTree().addKeyListener(new KeyAdapter() {
+ /* (non-Javadoc)
+ * @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent)
+ */
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if (e.keyCode == SWT.F5) {
+ refresh();
+ }
+ }
+ });
+ viewer.getTree().setLinesVisible(false);
+
+ MenuManager menuMgr = new MenuManager();
+ menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.addMenuListener(new IMenuListener() {
+ @Override
+ public void menuAboutToShow(IMenuManager manager) {
+ IAction action = new Action(Messages.FSFolderSelectionDialog_Refresh_menu, UIPlugin.getImageDescriptor(ImageConsts.REFRESH_IMAGE)) {
+ @Override
+ public void run() {
+ refresh();
+ }
+ };
+ action.setAccelerator(SWT.F5);
+ manager.add(action);
+ }
+ });
+ Menu menu = menuMgr.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+
+ return viewer;
+ }
+
+ public void refresh() {
+ ISelection sel = getTreeViewer().getSelection();
+ if (sel instanceof IStructuredSelection && !sel.isEmpty()) {
+ Iterator<Object> it = ((IStructuredSelection)sel).iterator();
+ while (it.hasNext()) {
+ Object node = it.next();
+ if (node instanceof FSTreeNode) {
+ refreshNode((FSTreeNode)node);
+ }
+ else {
+ refreshModel();
+ return;
+ }
+ }
+ }
+ else {
+ refreshModel();
+ }
+ }
+
+ protected void refreshNode(final FSTreeNode treeNode) {
+ if (!treeNode.childrenQueryRunning) {
+ treeNode.childrenQueried = false;
+ treeNode.clearChildren();
+ treeNode.refresh(new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ getShell().getDisplay().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ getTreeViewer().refresh(treeNode, true);
+ getTreeViewer().setSelection(getTreeViewer().getSelection());
+ }
+ });
+ }
+ });
+ }
+ }
+
+ protected void refreshModel() {
+ Object input = getTreeViewer().getInput();
+ if (input instanceof IPeerNode) {
+ refreshNode(ModelManager.getRuntimeModel((IPeerNode)input).getRoot());
+ }
+ }
+
+
+ private final static IStatus ok = new Status(IStatus.OK, UIPlugin.getUniqueIdentifier(), null);
+ private final static IStatus error = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), null);
+ private final static IStatus errorNotWritable = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), Messages.FSFolderSelectionDialog_notWritable_error);
+ private final static IStatus warningNotWritable = new Status(IStatus.WARNING, UIPlugin.getUniqueIdentifier(), Messages.FSFolderSelectionDialog_notWritable_warning);
+
+ /**
+ * 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) {
+ if (selection == null || selection.length == 0) {
+ return error;
+ }
+ if (!(selection[0] instanceof FSTreeNode)) {
+ return error;
+ }
+ FSTreeNode target = (FSTreeNode) selection[0];
+ if (movedNodes != null) {
+ for (FSTreeNode node : movedNodes) {
+ if (node == target || node.isAncestorOf(target)) {
+ return error;
+ }
+ }
+ }
+ if(mode != MODE_ALL && !target.isWritable()) {
+ if (target.attr == null) {
+ refreshNode(target);
+ }
+ return mode == MODE_ONLY_WRITABLE ? errorNotWritable : warningNotWritable;
+ }
+ return ok;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSOpenFileDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSOpenFileDialog.java
new file mode 100644
index 000000000..5b2629c27
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/FSOpenFileDialog.java
@@ -0,0 +1,263 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.dialogs;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.runtime.IRuntimeModel;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.ModelManager;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.controls.FSTreeContentProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.controls.FSTreeViewerSorter;
+import org.eclipse.tcf.te.tcf.filesystem.ui.interfaces.IFSConstants;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FSTreeElementLabelProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.ui.trees.FilterDescriptor;
+import org.eclipse.tcf.te.ui.trees.Pending;
+import org.eclipse.tcf.te.ui.trees.ViewerStateManager;
+import org.eclipse.ui.IDecoratorManager;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
+import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+
+
+/**
+ * File system open file dialog.
+ */
+public class FSOpenFileDialog extends ElementTreeSelectionDialog {
+ private String filterPath = null;
+ /* default */ TreeViewer viewer = null;
+
+ /**
+ * Create an FSFolderSelectionDialog using the specified shell as the parent.
+ *
+ * @param parentShell The parent shell.
+ */
+ public FSOpenFileDialog(Shell parentShell) {
+ this(parentShell, new FSTreeElementLabelProvider(), 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 FSOpenFileDialog(Shell parentShell, ILabelProvider labelProvider, ITreeContentProvider contentProvider) {
+ super(parentShell, createDecoratingLabelProvider(labelProvider), contentProvider);
+ setTitle(Messages.FSOpenFileDialog_title);
+ setMessage(Messages.FSOpenFileDialog_message);
+ this.setAllowMultiple(false);
+ this.setStatusLineAboveButtons(false);
+ this.setComparator(new FSTreeViewerSorter());
+ this.setValidator(new ISelectionStatusValidator() {
+ @Override
+ public IStatus validate(Object[] selection) {
+ return isValidSelection(selection);
+ }
+ });
+ }
+
+ /**
+ * Sets the filter path.
+ *
+ * @param filterPath The filter path or <code>null</code>.
+ */
+ public void setFilterPath(String filterPath) {
+ this.filterPath = filterPath;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.dialogs.ElementTreeSelectionDialog#setInput(java.lang.Object)
+ */
+ @Override
+ public void setInput(Object input) {
+ super.setInput(input);
+ FilterDescriptor[] filterDescriptors = ViewerStateManager.getInstance().getFilterDescriptors(IFSConstants.ID_TREE_VIEWER_FS, input);
+ Assert.isNotNull(filterDescriptors);
+ for (FilterDescriptor descriptor : filterDescriptors) {
+ if (descriptor.isEnabled()) {
+ addFilter(descriptor.getFilter());
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.dialogs.ElementTreeSelectionDialog#create()
+ */
+ @Override
+ public void create() {
+ super.create();
+
+ if (filterPath != null && !"".equals(filterPath.trim())) { //$NON-NLS-1$
+ IPath path = new Path(filterPath);
+ if (viewer.getInput() instanceof IPeerNode) {
+ Object element = null;
+ IRuntimeModel model = ModelManager.getRuntimeModel((IPeerNode)viewer.getInput());
+ if (model != null) {
+ FSTreeNode root = model.getRoot();
+ ITreeContentProvider contentProvider = (ITreeContentProvider)viewer.getContentProvider();
+ Object[] elements = contentProvider.getElements(root);
+ String segment = path.getDevice() != null ? path.getDevice() : path.segmentCount() > 0 ? path.segment(0) : null;
+ if (segment != null) {
+ for (Object elem : elements) {
+ if (!(elem instanceof FSTreeNode)) break;
+ FSTreeNode child = (FSTreeNode)elem;
+ String name = child.name;
+ if (name.endsWith("\\") || name.endsWith("/")) name = name.substring(0, name.length() - 1); //$NON-NLS-1$ //$NON-NLS-2$
+ boolean matches = child.isWindowsNode() ? name.equalsIgnoreCase(segment) : name.equals(segment);
+ if (matches) {
+ if (path.segmentCount() > (path.getDevice() != null ? 0 : 1)) {
+ // Have to drill down a bit further
+ element = findRecursive(child, path, path.getDevice() != null ? 0 : 1);
+ if (element != null) break;
+ } else {
+ element = child;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (element != null) {
+ final ISelection selection = new StructuredSelection(element);
+ final AtomicInteger counter = new AtomicInteger();
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ viewer.setSelection(selection, true);
+ if (!selection.equals(viewer.getSelection())) {
+ if (counter.incrementAndGet() <= 10) {
+ viewer.getControl().getDisplay().asyncExec(this);
+ }
+ }
+ }
+ };
+
+ viewer.getControl().getDisplay().asyncExec(runnable);
+ }
+ }
+ }
+ }
+
+ /**
+ * Finds the given path within the file system hierarchy.
+ *
+ * @param parent The parent file system node. Must not be <code>null</code>.
+ * @param path The path. Must not be <code>null</code>.
+ * @param index The segment index.
+ *
+ * @return The matching file system node or <code>null</code>.
+ */
+ private FSTreeNode findRecursive(FSTreeNode parent, IPath path, int index) {
+ Assert.isNotNull(parent);
+ Assert.isNotNull(path);
+
+ FSTreeNode node = null;
+
+ ITreeContentProvider contentProvider = (ITreeContentProvider)viewer.getContentProvider();
+ Object[] elements = contentProvider.getElements(parent);
+ while (elements.length == 1 && elements[0] instanceof Pending) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {}
+ elements = contentProvider.getElements(parent);
+ }
+
+ String segment = path.segment(index);
+
+ for (Object element : elements) {
+ if (!(element instanceof FSTreeNode)) break;
+ FSTreeNode child = (FSTreeNode)element;
+ String name = child.name;
+ if (name.endsWith("\\") || name.endsWith("/")) name = name.substring(0, name.length() - 1); //$NON-NLS-1$ //$NON-NLS-2$
+ boolean matches = child.isWindowsNode() ? name.equalsIgnoreCase(segment) : name.equals(segment);
+ if (matches) {
+ if (path.segmentCount() > index + 1) {
+ // Have to drill down a bit further
+ node = findRecursive(child, path, index + 1);
+ if (node != null) break;
+ } else {
+ node = child;
+ break;
+ }
+ }
+ }
+
+ return node;
+ }
+
+ /**
+ * Create a decorating label provider using the specified label provider.
+ *
+ * @param labelProvider The label provider that actually provides labels and images.
+ * @return The decorating label provider.
+ */
+ private static ILabelProvider createDecoratingLabelProvider(ILabelProvider labelProvider) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IDecoratorManager manager = workbench.getDecoratorManager();
+ ILabelDecorator decorator = manager.getLabelDecorator();
+ return new DecoratingLabelProvider(labelProvider,decorator);
+ }
+
+ /**
+ * Create the tree viewer and set it to the label provider.
+ */
+ @Override
+ protected TreeViewer doCreateTreeViewer(Composite parent, int style) {
+ viewer = super.doCreateTreeViewer(parent, style);
+ viewer.getTree().setLinesVisible(false);
+ 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 isValidSelection(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];
+ if(!target.isFile()) {
+ return error;
+ }
+ return new Status(IStatus.OK, pluginId, null);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/TimeTriggeredProgressMonitorDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/TimeTriggeredProgressMonitorDialog.java
new file mode 100644
index 000000000..232cc9c4b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/dialogs/TimeTriggeredProgressMonitorDialog.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.dialogs;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * The TimeTriggeredProgressMonitorDialog is a progress monitor dialog that only
+ * opens if the runnable provided exceeds the specified long operation time.
+ *
+ * @since 3.7 - Copied from
+ * org.eclipse.ui.internal.operations.TimeTriggeredProgressMonitorDialog
+ */
+public class TimeTriggeredProgressMonitorDialog extends ProgressMonitorDialog {
+
+ /**
+ * The time considered to be the long operation time.
+ */
+ /* default */ int longOperationTime;
+
+ /**
+ * The time at which the dialog should be opened.
+ */
+ /* default */ long triggerTime = -1;
+
+ /**
+ * Whether or not we've already opened a dialog.
+ */
+ /* default */ boolean dialogOpened = false;
+
+ /**
+ * Wrapped monitor so we can check ticks and open the dialog when
+ * appropriate
+ */
+ private IProgressMonitor wrappedMonitor;
+
+ /**
+ * Create a new instance of the receiver.
+ *
+ * @param parent
+ * the parent of the dialog
+ * @param longOperationTime
+ * the time (in milliseconds) considered to be a long enough
+ * execution time to warrant opening a dialog.
+ */
+ public TimeTriggeredProgressMonitorDialog(Shell parent, int longOperationTime) {
+ super(parent);
+ setOpenOnRun(false);
+ this.longOperationTime = longOperationTime;
+ }
+
+ /**
+ * Create a monitor for the receiver that wrappers the super classes monitor.
+ *
+ */
+ public void createWrappedMonitor() {
+ wrappedMonitor = new IProgressMonitor() {
+
+ @SuppressWarnings("synthetic-access")
+ IProgressMonitor superMonitor = TimeTriggeredProgressMonitorDialog.super.getProgressMonitor();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.IProgressMonitor#beginTask(java.lang.String, int)
+ */
+ @Override
+ public void beginTask(String name, int totalWork) {
+ superMonitor.beginTask(name, totalWork);
+ checkTicking();
+ }
+
+ /**
+ * Check if we have ticked in the last 800ms.
+ */
+ private void checkTicking() {
+ if (triggerTime < 0) {
+ triggerTime = System.currentTimeMillis() + longOperationTime;
+ }
+ if (!dialogOpened && System.currentTimeMillis() > triggerTime) {
+ open();
+ dialogOpened = true;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IProgressMonitor#done()
+ */
+ @Override
+ public void done() {
+ superMonitor.done();
+ checkTicking();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.IProgressMonitor#internalWorked(double)
+ */
+ @Override
+ public void internalWorked(double work) {
+ superMonitor.internalWorked(work);
+ checkTicking();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IProgressMonitor#isCanceled()
+ */
+ @Override
+ public boolean isCanceled() {
+ return superMonitor.isCanceled();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.IProgressMonitor#setCanceled(boolean)
+ */
+ @Override
+ public void setCanceled(boolean value) {
+ superMonitor.setCanceled(value);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.IProgressMonitor#setTaskName(java.lang
+ * .String)
+ */
+ @Override
+ public void setTaskName(String name) {
+ superMonitor.setTaskName(name);
+ checkTicking();
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.core.runtime.IProgressMonitor#subTask(java.lang.String
+ * )
+ */
+ @Override
+ public void subTask(String name) {
+ superMonitor.subTask(name);
+ checkTicking();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.runtime.IProgressMonitor#worked(int)
+ */
+ @Override
+ public void worked(int work) {
+ superMonitor.worked(work);
+ checkTicking();
+
+ }
+ };
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.ProgressMonitorDialog#getProgressMonitor()
+ */
+ @Override
+ public IProgressMonitor getProgressMonitor() {
+ if (wrappedMonitor == null) {
+ createWrappedMonitor();
+ }
+ return wrappedMonitor;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.operations.IRunnableContext#run(boolean, boolean,
+ * IRunnableWithProgress)
+ */
+ @Override
+ public void run(final boolean fork, final boolean cancelable,
+ final IRunnableWithProgress runnable)
+ throws InvocationTargetException, InterruptedException {
+ final InvocationTargetException[] invokes = new InvocationTargetException[1];
+ final InterruptedException[] interrupt = new InterruptedException[1];
+ Runnable dialogWaitRunnable = new Runnable() {
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() {
+ try {
+ TimeTriggeredProgressMonitorDialog.super.run(fork, cancelable, runnable);
+ } catch (InvocationTargetException e) {
+ invokes[0] = e;
+ } catch (InterruptedException e) {
+ interrupt[0] = e;
+ }
+ }
+ };
+ final Display display = PlatformUI.getWorkbench().getDisplay();
+ if (display == null) {
+ return;
+ }
+ // show a busy cursor until the dialog opens
+ BusyIndicator.showWhile(display, dialogWaitRunnable);
+ if (invokes[0] != null) {
+ throw invokes[0];
+ }
+ if (interrupt[0] != null) {
+ throw interrupt[0];
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/filters/HiddenFilesViewerFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/filters/HiddenFilesViewerFilter.java
new file mode 100644
index 000000000..fcd306e6c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/filters/HiddenFilesViewerFilter.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.filters;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * A filter implementation filtering hidden files or directories.
+ */
+public class HiddenFilesViewerFilter extends ViewerFilter {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ // The element needs to be a tree node, but not a root node
+ if (element instanceof FSTreeNode && !((FSTreeNode)element).isRoot()) {
+ FSTreeNode node = (FSTreeNode) element;
+ if(node.isWindowsNode()) {
+ return !node.isHidden();
+ }
+ return !node.name.startsWith("."); //$NON-NLS-1$
+ }
+ // Let pass all other elements unharmed
+ return true;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/filters/SystemFilesViewerFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/filters/SystemFilesViewerFilter.java
new file mode 100644
index 000000000..fe805de7e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/filters/SystemFilesViewerFilter.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.filters;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * A filter implementation filtering system files or directories.
+ */
+public class SystemFilesViewerFilter extends ViewerFilter {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ // The element needs to be a tree node, but not a root node
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode)element;
+ return !node.isSystem();
+ }
+ // Let pass all other elements unharmed
+ return true;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/help/IContextHelpIds.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/help/IContextHelpIds.java
new file mode 100644
index 000000000..ed8151006
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/help/IContextHelpIds.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.help;
+
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+
+/**
+ * Plugin context help id definitions.
+ */
+public interface IContextHelpIds {
+
+ /**
+ * Target Explorer file system UI plug-in common context help id prefix.
+ */
+ public final static String PREFIX = UIPlugin.getUniqueIdentifier() + "."; //$NON-NLS-1$
+
+ /**
+ * Target Explorer details editor page: File system explorer
+ */
+ public final static String FS_EXPLORER_EDITOR_PAGE = PREFIX + "FSExplorerEditorPage"; //$NON-NLS-1$
+
+ /**
+ * The wizard for creating a new file.
+ */
+ public final static String FS_NEW_FILE_WIZARD_PAGE = PREFIX + "FSNewFilePage"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/IFSConstants.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/IFSConstants.java
new file mode 100644
index 000000000..6fd6d9542
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/IFSConstants.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.interfaces;
+
+/**
+ * UIConstants for file system.
+ */
+public interface IFSConstants extends org.eclipse.tcf.te.ui.interfaces.IUIConstants {
+
+ /**
+ * The viewer id of the file tree of Target Explorer.
+ */
+ public static final String ID_TREE_VIEWER_FS = ID_CONTROL_MENUS_BASE + ".viewer.fs"; //$NON-NLS-1$
+
+ /**
+ * The help id of the file tree of Target Explorer.
+ */
+ public static final String ID_TREE_VIEWER_FS_HELP = ID_TREE_VIEWER_FS + ".help"; //$NON-NLS-1$
+
+ /**
+ * The menu id of the file tree of Target Explorer.
+ */
+ public static final String ID_TREE_VIEWER_FS_CONTEXT_MENU = ID_CONTROL_MENUS_BASE + ".menu.fs"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/IFileSystemUIDelegate.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/IFileSystemUIDelegate.java
new file mode 100644
index 000000000..8676bfe7a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/IFileSystemUIDelegate.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2014 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.tcf.filesystem.ui.interfaces;
+
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.ui.interfaces.ISearchable;
+
+
+/**
+ * Filesystem UI delegate.
+ */
+public interface IFileSystemUIDelegate {
+
+ /**
+ * Returns the message for the given key.
+ *
+ * @param key The message key. Must not be <code>null</code>.
+ * @return The message or <code>null</code>.
+ */
+ public String getMessage(String key);
+
+ /**
+ * Returns the process monitor table column text for the given column
+ * based on the given original text.
+ *
+ * @param context The context. Must not be <code>null</code>.
+ * @param columnId The column id. Must not be <code>null</code>.
+ * @param text The original text to show in the column fetched from the label provider, or <code>null</code>.
+ *
+ * @return The new text to show in the column or <code>null</code>.
+ */
+ public String getText(Object context, String columnId, String text);
+
+ /**
+ * Returns if or if not the given column is active for the given context.
+ *
+ * @param context The context. Must not be <code>null</code>.
+ * @param columnId The column id. Must not be <code>null</code>.
+ *
+ * @return <code>True</code> if the column is active for the given context, <code>false</code> otherwise.
+ */
+ public boolean isColumnActive(Object context, String columnId);
+
+ /**
+ * Returns if or if not the given filter is active for the given context.
+ *
+ * @param context The context. Must not be <code>null</code>.
+ * @param filterId The filter id. Must not be <code>null</code>.
+ *
+ * @return <code>True</code> if the filter is active for the given context, <code>false</code> otherwise.
+ */
+ public boolean isFilterActive(Object context, String filterId);
+
+ /**
+ * Returns the list of searchables to use to find processes in the
+ * process monitor.
+ *
+ * @param node The peer model node context. Must not be <code>null</code>.
+ * @return The list of searchables to use or <code>null</code>.
+ */
+ public ISearchable[] getSearchables(IPeerNode node);
+
+ /**
+ * Returns the number of levels to auto expand.
+ * If the method returns <code>0</code>, no auto expansion will happen
+ *
+ * @return The number of levels to auto expand or <code>0</code>.
+ */
+ public int getAutoExpandLevel();
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/preferences/IPreferenceKeys.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/preferences/IPreferenceKeys.java
new file mode 100644
index 000000000..7bcc6d246
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/interfaces/preferences/IPreferenceKeys.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.interfaces.preferences;
+
+/**
+ * The bundle's preference key identifiers.
+ */
+public interface IPreferenceKeys {
+ /**
+ * Common prefix for all core preference keys
+ */
+ public final String PREFIX = "te.tcf.filesystem.core."; //$NON-NLS-1$
+
+ /**
+ * If set to <code>true</code>, the file system content contribution to the target
+ * explorer details editor will be activated and visible to the user.
+ */
+ public static final String PREF_FEATURE_ENABLE_EDITOR_CONTENT_CONTRIBUTION = PREFIX + "feature.editor.content.enable"; //$NON-NLS-1$
+ // The default value for editor content contribution
+ public static final boolean DEFAULT_FEATURE_ENABLE_EDITOR_CONTENT_CONTRIBUTION = true;
+ // The preference key to access the option of auto saving
+ 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 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;
+ // The preference key to access the option that if expanded nodes should be persisted
+ public static final String PREF_EXPANDED_PERSISTED = "PrefExpandedPersisted"; //$NON-NLS-1$
+ // The default value of the option that if expanded nodes should be persisted
+ public static final boolean DEFAULT_EXPANDED_PERSISTED = false;
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/ImageConsts.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/ImageConsts.java
new file mode 100644
index 000000000..e46b3eaec
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/ImageConsts.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal;
+
+/**
+ * File system plug-in Image registry constants.
+ */
+public interface ImageConsts {
+
+ // ***** The directory structure constants *****
+
+ /**
+ * The root directory where to load the images from, relative to
+ * the bundle directory.
+ */
+ public final static String IMAGE_DIR_ROOT = "icons/"; //$NON-NLS-1$
+
+ /**
+ * The directory where to load model object images from,
+ * relative to the image root directory.
+ */
+ 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 *****
+
+ /**
+ * The key to access the base folder object image.
+ */
+ public static final String FOLDER = "Folder"; //$NON-NLS-1$
+
+ /**
+ * The key to access the base root node object image.
+ */
+ public static final String ROOT = "Root"; //$NON-NLS-1$
+
+ /**
+ * The key to access the base root folder object image (closed).
+ */
+ public static final String ROOT_DRIVE = "RootDrive"; //$NON-NLS-1$
+
+ /**
+ * 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 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$
+
+ public static final String REFRESH_IMAGE = "RefreshImage"; //$NON-NLS-1$
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeAdapterFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeAdapterFactory.java
new file mode 100644
index 000000000..6f2cf59af
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeAdapterFactory.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal.adapters;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.columns.FSTreeElementLabelProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.search.FSTreeNodeSearchable;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProvider;
+import org.eclipse.tcf.te.ui.interfaces.ILazyLoader;
+import org.eclipse.tcf.te.ui.interfaces.ISearchable;
+import org.eclipse.ui.IActionFilter;
+import org.eclipse.ui.IPersistableElement;
+
+/**
+ * The adapter factory of <code>FSTreeNode</code> over <code>IActionFilter</code>
+ */
+public class FSTreeNodeAdapterFactory implements IAdapterFactory {
+ private static ILabelProvider nodeLabelProvider = new FSTreeElementLabelProvider();
+ // The fFilters map caching fFilters for FS nodes.
+ private Map<FSTreeNode, NodeStateFilter> filters;
+
+ public static class FSTreeNodePeerNodeProvider extends PlatformObject implements IPeerNodeProvider {
+ private final FSTreeNode node;
+
+ /**
+ * Constructor
+ */
+ public FSTreeNodePeerNodeProvider(FSTreeNode node) {
+ Assert.isNotNull(node);
+ this.node = node;
+ }
+
+ /**
+ * Returns the associated file system tree node.
+ *
+ * @return The associated file system tree node.
+ */
+ public final FSTreeNode getFSTreeNode() {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProvider#getPeerModel()
+ */
+ @Override
+ public final IPeerNode getPeerNode() {
+ return node.peerNode;
+ }
+ }
+
+ /**
+ * Constructor.
+ */
+ public FSTreeNodeAdapterFactory() {
+ this.filters = Collections.synchronizedMap(new HashMap<FSTreeNode, NodeStateFilter>());
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if (adaptableObject instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) adaptableObject;
+ if (adapterType == IActionFilter.class) {
+ NodeStateFilter filter = filters.get(node);
+ if (filter == null) {
+ filter = new NodeStateFilter(node);
+ filters.put(node, filter);
+ }
+ return filter;
+ }
+ else if (adapterType == ILabelProvider.class) {
+ return nodeLabelProvider;
+ }
+ else if (adapterType == IPersistableElement.class && UIPlugin.isExpandedPersisted()) {
+ return new PersistableNode(node);
+ }
+ else if (adapterType == ILazyLoader.class) {
+ return new FSTreeNodeLoader(node);
+ }
+ else if (adapterType == IPeerNodeProvider.class) {
+ return new FSTreeNodePeerNodeProvider(node);
+ }
+ else if (adapterType == IPeerNode.class) {
+ return new FSTreeNodePeerNodeProvider(node).getPeerNode();
+ }
+ else if (adapterType == ISearchable.class) {
+ return new FSTreeNodeSearchable(node);
+ }
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+ */
+ @Override
+ public Class[] getAdapterList() {
+ return new Class[] { IActionFilter.class, ILabelProvider.class, IPersistableElement.class, ILazyLoader.class, ISearchable.class, IPeerNodeProvider.class };
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeFactory.java
new file mode 100644
index 000000000..3b3a67e01
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeFactory.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 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.tcf.filesystem.ui.internal.adapters;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.NullOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpParsePath;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.tcf.locator.interfaces.services.IPeerModelLookupService;
+import org.eclipse.tcf.te.tcf.locator.model.ModelManager;
+import org.eclipse.ui.IElementFactory;
+import org.eclipse.ui.IMemento;
+
+/**
+ * The element factory for FSTreeNode used to restore FSTreeNodes persisted
+ * for expanded states.
+ */
+public class FSTreeNodeFactory implements IElementFactory {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.IElementFactory#createElement(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public IAdaptable createElement(IMemento memento) {
+ String peerId = memento.getString("peerId"); //$NON-NLS-1$
+ IPeerNode peerNode = ModelManager.getPeerModel().getService(IPeerModelLookupService.class).lkupPeerModelById(peerId);
+ if(peerNode != null) {
+ String path = memento.getString("path"); //$NON-NLS-1$
+ if(path == null) {
+ return org.eclipse.tcf.te.tcf.filesystem.core.model.ModelManager.getRuntimeModel(peerNode).getRoot();
+ }
+ OpParsePath op = new OpParsePath(peerNode, path);
+ IOpExecutor executor = new NullOpExecutor();
+ IStatus status = executor.execute(op);
+ if(status.isOK()) {
+ return op.getResult();
+ }
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeLoader.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeLoader.java
new file mode 100644
index 000000000..e04fc7740
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/FSTreeNodeLoader.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.adapters;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.exceptions.TCFException;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.NullOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpRefreshRoots;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.Operation;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.ui.interfaces.ILazyLoader;
+
+/**
+ * The implementation of ILazyLoader for FSTreeNode check its data availability
+ * and load its children if not ready.
+ */
+public class FSTreeNodeLoader implements ILazyLoader {
+ // The node to be checked.
+ private FSTreeNode node;
+ /**
+ * Constructor
+ *
+ * @param node The file/folder node.
+ */
+ public FSTreeNodeLoader(FSTreeNode node) {
+ this.node = node;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ILazyLoader#isDataLoaded()
+ */
+ @Override
+ public boolean isDataLoaded() {
+ return node.isFile() || (node.isSystemRoot() || node.isDirectory()) && node.childrenQueried;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ILazyLoader#loadData(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void loadData(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ try {
+ if(node.isFile()) return;
+ if (node.isSystemRoot()) {
+ new NullOpExecutor().execute(new OpRefreshRoots(node));
+ }
+ else {
+ new Operation().getChildren(node);
+ }
+ }
+ catch (TCFException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ILazyLoader#isLeaf()
+ */
+ @Override
+ public boolean isLeaf() {
+ return node.isFile();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/NodeStateFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/NodeStateFilter.java
new file mode 100644
index 000000000..1ca440246
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/NodeStateFilter.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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.tcf.filesystem.ui.internal.adapters;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpClipboard;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.CacheState;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.ui.IActionFilter;
+
+/**
+ * This action filter wraps an FSTreeNode and test its attribute of "cache.state".
+ * It serves as the expression filter of decorations of Target Explorer.
+ */
+public class NodeStateFilter implements IActionFilter {
+ private FSTreeNode node;
+
+ /**
+ * Constructor.
+ *
+ * @param node
+ * The wrapped tree node. Must not be <code>null</code>.
+ */
+ public NodeStateFilter(FSTreeNode node) {
+ Assert.isNotNull(node);
+ this.node = node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IActionFilter#testAttribute(java.lang.Object, java.lang.String, java.lang.String)
+ */
+ @Override
+ public boolean testAttribute(Object target, String name, String value) {
+ if (name.equals("cache.state") && node.isFile()) { //$NON-NLS-1$
+ if(UIPlugin.isAutoSaving())
+ return false;
+ CacheState state = node.getCacheState();
+ if (value == null)
+ value = CacheState.consistent.name();
+ return value.equals(state.name());
+ }
+ else if (name.equals("edit.cut")) { //$NON-NLS-1$
+ OpClipboard cb = UIPlugin.getClipboard();
+ if (!cb.isEmpty()) {
+ if (cb.isCutOp()) {
+ List<FSTreeNode> files = cb.getFiles();
+ for (FSTreeNode file : files) {
+ if (node == file) return true;
+ }
+ }
+ }
+ }
+ else if (name.equals("hidden")) { //$NON-NLS-1$
+ if (value == null) value = "true"; //$NON-NLS-1$
+ boolean result = false;
+ if (!node.isRoot()) {
+ if (node.isWindowsNode()) {
+ result = node.isHidden();
+ }
+ else {
+ result = node.name.startsWith("."); //$NON-NLS-1$
+ }
+ }
+ return Boolean.toString(result).equals(value);
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/PeerNodeViewerInput.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/PeerNodeViewerInput.java
new file mode 100644
index 000000000..bdb3580c1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/PeerNodeViewerInput.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal.adapters;
+
+import org.eclipse.tcf.te.core.interfaces.IViewerInput;
+import org.eclipse.tcf.te.core.utils.PropertyChangeProvider;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+
+/**
+ * The viewer input of an IPeerNode instance.
+ */
+public class PeerNodeViewerInput extends PropertyChangeProvider implements IViewerInput {
+ // The peer model.
+ private IPeerNode peerNode;
+
+ /**
+ * Create an instance with a peer model.
+ *
+ * @param peerNode The peer model.
+ */
+ public PeerNodeViewerInput(IPeerNode peerNode) {
+ this.peerNode = peerNode;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.IViewerInput#getInputId()
+ */
+ @Override
+ public String getInputId() {
+ return peerNode.getPeerId();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/PersistableNode.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/PersistableNode.java
new file mode 100644
index 000000000..8cc6698d4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/PersistableNode.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.internal.adapters;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableElement;
+
+/**
+ * The adapter class of FSTreeNode for IPersistableElement, used to
+ * persist an FSTreeNode.
+ */
+public class PersistableNode implements IPersistableElement {
+ // The node to be persisted.
+ private FSTreeNode node;
+ /**
+ * Create an instance.
+ *
+ * @param node The node to be persisted.
+ */
+ public PersistableNode(FSTreeNode node) {
+ this.node = node;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.IPersistable#saveState(org.eclipse.ui.IMemento)
+ */
+ @Override
+ public void saveState(IMemento memento) {
+ memento.putString("peerId", node.peerNode.getPeerId()); //$NON-NLS-1$
+ String path = null;
+ if (!node.isSystemRoot()) path = node.getLocation();
+ if (path != null) memento.putString("path", path); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.IPersistableElement#getFactoryId()
+ */
+ @Override
+ public String getFactoryId() {
+ return "org.eclipse.tcf.te.tcf.filesystem.ui.nodeFactory"; //$NON-NLS-1$
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/ViewerInputAdapterFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/ViewerInputAdapterFactory.java
new file mode 100644
index 000000000..5107a78d1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/adapters/ViewerInputAdapterFactory.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal.adapters;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.te.core.interfaces.IPropertyChangeProvider;
+import org.eclipse.tcf.te.core.interfaces.IViewerInput;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+
+/**
+ * The adapter factory for IViewerInput.
+ */
+public class ViewerInputAdapterFactory implements IAdapterFactory {
+ // The key to store and access the the viewer input object.
+ private static final String VIEWER_INPUT_KEY = UIPlugin.getUniqueIdentifier()+".peer.viewerInput"; //$NON-NLS-1$
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if(adaptableObject instanceof IPeerNode) {
+ if (IViewerInput.class.equals(adapterType)
+ || IPropertyChangeProvider.class.equals(adapterType)) {
+ IPeerNode peerNode = (IPeerNode) adaptableObject;
+ return getViewerInput(peerNode);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get a viewer input from the specified peer model.
+ *
+ * @param peerNode The peer model to get the viewer input from.
+ * @return The peer model's viewer input.
+ */
+ PeerNodeViewerInput getViewerInput(final IPeerNode peerNode) {
+ if (peerNode != null) {
+ if (Protocol.isDispatchThread()) {
+ PeerNodeViewerInput model = (PeerNodeViewerInput) peerNode.getProperty(VIEWER_INPUT_KEY);
+ if (model == null) {
+ model = new PeerNodeViewerInput(peerNode);
+ peerNode.setProperty(VIEWER_INPUT_KEY, model);
+ }
+ return model;
+ }
+ final AtomicReference<PeerNodeViewerInput> reference = new AtomicReference<PeerNodeViewerInput>();
+ Protocol.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ reference.set(getViewerInput(peerNode));
+ }
+ });
+ return reference.get();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+ */
+ @Override
+ public Class[] getAdapterList() {
+ return new Class[] { IViewerInput.class, IPropertyChangeProvider.class };
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/autosave/SaveAllListener.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/autosave/SaveAllListener.java
new file mode 100644
index 000000000..74ec4d7d8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/autosave/SaveAllListener.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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) - [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.autosave;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IExecutionListener;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.NullOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpParsePath;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpUpload;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * The execution listener of command "SAVE ALL", which synchronizes the local
+ * file with the one on the target server after it is saved.
+ */
+public class SaveAllListener implements IExecutionListener {
+ // Dirty nodes that should be saved and synchronized.
+ List<FSTreeNode> fDirtyNodes;
+ /**
+ * Create the listener listening to command "SAVE ALL".
+ */
+ public SaveAllListener() {
+ this.fDirtyNodes = new ArrayList<FSTreeNode>();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IExecutionListener#postExecuteSuccess(java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void postExecuteSuccess(String commandId, Object returnValue) {
+ if (!fDirtyNodes.isEmpty()) {
+ if (UIPlugin.isAutoSaving()) {
+ FSTreeNode[] nodes = fDirtyNodes.toArray(new FSTreeNode[fDirtyNodes.size()]);
+ IOpExecutor executor = new UiExecutor();
+ executor.execute(new OpUpload(nodes));
+ }
+ else {
+ SafeRunner.run(new SafeRunnable(){
+ @Override
+ public void handleException(Throwable e) {
+ // Ignore exception
+ }
+ @Override
+ public void run() throws Exception {
+ for (FSTreeNode dirtyNode : fDirtyNodes) {
+ dirtyNode.refresh();
+ }
+ }});
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IExecutionListener#preExecute(java.lang.String, org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public void preExecute(String commandId, ExecutionEvent event) {
+ fDirtyNodes.clear();
+ // In Eclipse 4.x, the HandlerUtil.getActiveWorkbenchWindow(event) may return null
+ IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
+ if (window == null) window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ IWorkbenchPage page = window.getActivePage();
+ IEditorPart[] editors = page.getDirtyEditors();
+ for (IEditorPart editor : editors) {
+ IEditorInput input = editor.getEditorInput();
+ FSTreeNode node = null;
+ if (input instanceof IURIEditorInput) {
+ //Get the file that is being edited.
+ IURIEditorInput fileInput = (IURIEditorInput) input;
+ URI uri = fileInput.getURI();
+ try {
+ IFileStore store = EFS.getStore(uri);
+ File localFile = store.toLocalFile(0, new NullProgressMonitor());
+ if (localFile != null) {
+ // Get the file's mapped FSTreeNode.
+ OpParsePath parser = new OpParsePath(localFile.getCanonicalPath());
+ new NullOpExecutor().execute(parser);
+ node = parser.getResult();
+ if (node != null) {
+ // If it is a modified node, add it to the dirty node list.
+ fDirtyNodes.add(node);
+ }
+ }
+ }catch(Exception e){}
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IExecutionListener#notHandled(java.lang.String, org.eclipse.core.commands.NotHandledException)
+ */
+ @Override
+ public void notHandled(String commandId, NotHandledException exception) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IExecutionListener#postExecuteFailure(java.lang.String, org.eclipse.core.commands.ExecutionException)
+ */
+ @Override
+ public void postExecuteFailure(String commandId, ExecutionException exception) {
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/autosave/SaveListener.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/autosave/SaveListener.java
new file mode 100644
index 000000000..670beb8fb
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/autosave/SaveListener.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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) - [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.autosave;
+
+import java.io.File;
+import java.net.URI;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IExecutionListener;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.NullOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpParsePath;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpUpload;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IURIEditorInput;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * The execution listener of command "SAVE", which synchronizes the local file
+ * with the one on the target server after it is saved.
+ */
+public class SaveListener implements IExecutionListener {
+ // Dirty node that should be committed or merged.
+ FSTreeNode dirtyNode;
+
+ /**
+ * Create a SaveListener listening to command "SAVE".
+ */
+ public SaveListener() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IExecutionListener#postExecuteSuccess(java.lang.String, java.lang.Object)
+ */
+ @Override
+ public void postExecuteSuccess(String commandId, Object returnValue) {
+ if (dirtyNode != null) {
+ if (UIPlugin.isAutoSaving()) {
+ IOpExecutor executor = new UiExecutor();
+ executor.execute(new OpUpload(dirtyNode));
+ }
+ else {
+ SafeRunner.run(new SafeRunnable(){
+ @Override
+ public void handleException(Throwable e) {
+ // Ignore exception
+ }
+ @Override
+ public void run() throws Exception {
+ if (dirtyNode != null) dirtyNode.refresh();
+ }
+ });
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IExecutionListener#preExecute(java.lang.String, org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public void preExecute(String commandId, ExecutionEvent event) {
+ dirtyNode = null;
+ IEditorInput input = HandlerUtil.getActiveEditorInput(event);
+ if (input instanceof IURIEditorInput) {
+ IURIEditorInput fileInput = (IURIEditorInput) input;
+ URI uri = fileInput.getURI();
+ try {
+ IFileStore store = EFS.getStore(uri);
+ File localFile = store.toLocalFile(0, new NullProgressMonitor());
+ if (localFile != null) {
+ OpParsePath parser = new OpParsePath(localFile.getCanonicalPath());
+ new NullOpExecutor().execute(parser);
+ dirtyNode = parser.getResult();
+ }
+ }catch(Exception e){
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IExecutionListener#notHandled(java.lang.String, org.eclipse.core.commands.NotHandledException)
+ */
+ @Override
+ public void notHandled(String commandId, NotHandledException exception) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IExecutionListener#postExecuteFailure(java.lang.String, org.eclipse.core.commands.ExecutionException)
+ */
+ @Override
+ public void postExecuteFailure(String commandId, ExecutionException exception) {
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellListener.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellListener.java
new file mode 100644
index 000000000..0f2cac475
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellListener.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.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.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.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.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellModifier.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellModifier.java
new file mode 100644
index 000000000..b1da8c4ad
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellModifier.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.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.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.JobExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpRename;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.RenameCallback;
+
+/**
+ * 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.
+ IOpExecutor executor = new JobExecutor(new RenameCallback());
+ executor.execute(new OpRename(node, newName));
+ }
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellValidator.java
new file mode 100644
index 000000000..85b3de181
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSCellValidator.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.celleditor;
+
+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.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * 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 (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 = folder.getParent().getChildren();
+ for (FSTreeNode node : nodes) {
+ if (node.isWindowsNode()) {
+ if (node.name.equalsIgnoreCase(name)) return true;
+ }
+ else if (node.name.equals(name)) return true;
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSViewerCellEditorFactory.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSViewerCellEditorFactory.java
new file mode 100644
index 000000000..59788be3f
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/celleditor/FSViewerCellEditorFactory.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.celleditor;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.RenameFilesHandler;
+import org.eclipse.tcf.te.ui.interfaces.IViewerCellEditorFactory;
+
+/**
+ * FSViewerCellEditorFactory implements <code>IViewerCellEditorFactory</code> to add
+ * cell editors to Target Explorer for renaming files or folders in the file system tree viewer.
+ */
+public class FSViewerCellEditorFactory implements IViewerCellEditorFactory, FocusListener {
+ // The tree viewer to add cell editing.
+ private TreeViewer viewer;
+ // The cell editors used to rename a file/folder.
+ private TextCellEditor cellEditor;
+ // The cell modifier used to modify a file/folder's name.
+ private ICellModifier cellModifer;
+
+ /**
+ * Create an instance.
+ */
+ public FSViewerCellEditorFactory() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory#init(org.eclipse.jface.viewers.TreeViewer)
+ */
+ @Override
+ public void init(TreeViewer aViewer) {
+ viewer = aViewer;
+ cellEditor = new TextCellEditor(aViewer.getTree(), SWT.BORDER);
+ cellEditor.setValidator(new FSCellValidator(aViewer));
+ cellEditor.addListener(new FSCellListener(cellEditor));
+ cellModifer = new FSCellModifier();
+ Tree tree = aViewer.getTree();
+ tree.addFocusListener(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory#getCellEditors()
+ */
+ @Override
+ public CellEditor[] getCellEditors() {
+ return new CellEditor[] { cellEditor };
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory#getCellModifier()
+ */
+ @Override
+ public ICellModifier getCellModifier() {
+ return cellModifer;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.interfaces.IViewerCellEditorFactory#getColumnProperties()
+ */
+ @Override
+ public String[] getColumnProperties() {
+ return new String[] { FSCellModifier.PROPERTY_NAME };
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
+ */
+ @Override
+ public void focusGained(FocusEvent e) {
+ // Set the currently focused viewer.
+ RenameFilesHandler.setCurrentViewer(viewer);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
+ */
+ @Override
+ public void focusLost(FocusEvent e) {
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/AccessTimeComparator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/AccessTimeComparator.java
new file mode 100644
index 000000000..29374e19c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/AccessTimeComparator.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The comparator for the tree column "Date Accessed".
+ */
+public class AccessTimeComparator extends FSTreeNodeComparator {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.FSTreeNodeComparator#doCompare(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode, org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public int doCompare(FSTreeNode node1, FSTreeNode node2) {
+ long atime1 = node1.attr != null ? node1.attr.atime : 0;
+ long atime2 = node2.attr != null ? node2.attr.atime : 0;
+ return atime1 < atime2 ? -1 : (atime1 > atime2 ? 1 : 0);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/AccessTimeLabelProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/AccessTimeLabelProvider.java
new file mode 100644
index 000000000..ab84b5d73
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/AccessTimeLabelProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.columns;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The label provider for the tree column "Date Accessed".
+ */
+public class AccessTimeLabelProvider extends LabelProvider {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ if (node.attr != null) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("M/d/yyyy h:mm aa"); //$NON-NLS-1$
+ return dateFormat.format(new Date(node.attr.atime));
+ }
+ }
+ return ""; //$NON-NLS-1$
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/CacheFileImageUpdater.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/CacheFileImageUpdater.java
new file mode 100644
index 000000000..24f70fb77
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/CacheFileImageUpdater.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.internal.columns;
+
+import java.io.File;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.CacheManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The image update adapter that updates the images of the file which
+ * has a local cache copy.
+ */
+public class CacheFileImageUpdater implements ImageUpdateAdapter {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.ImageUpdateAdapter#getImageKey(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public String getImageKey(FSTreeNode node) {
+ return node.getLocationURL().toExternalForm();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.ImageUpdateAdapter#getMirrorFile(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public File getMirrorFile(FSTreeNode node) {
+ return CacheManager.getCacheFile(node);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.ImageUpdateAdapter#getImgFile(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public File getImageFile(FSTreeNode node) {
+ File cacheFile = CacheManager.getCacheFile(node);
+ File parentDir = cacheFile.getParentFile();
+ if (!parentDir.exists() && !parentDir.mkdirs()) {
+ parentDir = CacheManager.getCacheRoot();
+ }
+ return new File(parentDir, node.name + ".png"); //$NON-NLS-1$
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/DefaultImageProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/DefaultImageProvider.java
new file mode 100644
index 000000000..2f3b78a81
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/DefaultImageProvider.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.ImageConsts;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * The default implementation of ImageProvider, defining the images
+ * based on predefined images based on the node simulator.
+ */
+public class DefaultImageProvider implements ImageProvider {
+ // The editor registry used to search a file's image.
+ private IEditorRegistry editorRegistry = null;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.ImageProvider#getImage(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public Image getImage(FSTreeNode node) {
+ if (node.isSystemRoot()) {
+ return UIPlugin.getImage(ImageConsts.ROOT);
+ }
+ else if (node.isRoot()) {
+ return UIPlugin.getImage(ImageConsts.ROOT_DRIVE);
+ }
+ else if (node.isDirectory()) {
+ return UIPlugin.getImage(ImageConsts.FOLDER);
+ }
+ else if (node.isFile()) {
+ return getPredefinedImage(node);
+ }
+ return null;
+ }
+
+ /**
+ * Get a predefined image for the tree node. These images are retrieved from
+ * editor registry.
+ *
+ * @param node The file tree node.
+ * @return The editor image for this simulator.
+ */
+ protected Image getPredefinedImage(FSTreeNode node) {
+ Image image;
+ String key = node.name;
+ image = UIPlugin.getImage(key);
+ if (image == null) {
+ ImageDescriptor descriptor = getEditorRegistry().getImageDescriptor(key);
+ if (descriptor == null) {
+ descriptor = getEditorRegistry().getSystemExternalEditorImageDescriptor(key);
+ }
+ if (descriptor != null) {
+ UIPlugin.getDefault().getImageRegistry().put(key, descriptor);
+ }
+ image = UIPlugin.getImage(key);
+ }
+ return image;
+ }
+
+ /**
+ * Returns the workbench's editor registry.
+ */
+ private IEditorRegistry getEditorRegistry() {
+ if (editorRegistry == null) {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ if (workbench != null) editorRegistry = workbench.getEditorRegistry();
+ }
+ return editorRegistry;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeElementComparator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeElementComparator.java
new file mode 100644
index 000000000..5ad79dca1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeElementComparator.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The comparator for the tree column "name".
+ */
+public class FSTreeElementComparator extends FSTreeNodeComparator {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.FSTreeNodeComparator#doCompare(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode, org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public int doCompare(FSTreeNode node1, FSTreeNode node2) {
+ String name1 = node1.name;
+ String name2 = node2.name;
+ if (name1 != null && name2 != null) {
+ if (name1.startsWith(".") && !name2.startsWith(".")) return -1; //$NON-NLS-1$ //$NON-NLS-2$
+ if (!name1.startsWith(".") && name2.startsWith(".")) return 1; //$NON-NLS-1$ //$NON-NLS-2$
+ return name1.compareToIgnoreCase(name2);
+ }
+ return 0;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeElementLabelProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeElementLabelProvider.java
new file mode 100644
index 000000000..3ae7d9ae4
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeElementLabelProvider.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode;
+import org.eclipse.tcf.te.runtime.utils.Host;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.trees.PendingAwareLabelProvider;
+
+/**
+ * The label provider for the tree column "name".
+ */
+public class FSTreeElementLabelProvider extends PendingAwareLabelProvider {
+ // The image provider to provide platform specific images.
+ private ImageProvider imgProvider;
+
+ /**
+ * Constructor.
+ */
+ public FSTreeElementLabelProvider() {
+ if(Host.isWindowsHost()) {
+ imgProvider = new WindowsImageProvider();
+ }
+ else {
+ imgProvider = new DefaultImageProvider();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object element) {
+ if (element instanceof FSTreeNode) {
+ return ((FSTreeNode) element).name;
+ }
+ else if (element instanceof IModelNode) {
+ return ((IModelNode)element).getName();
+ }
+
+ return super.getText(element);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+ */
+ @Override
+ public Image getImage(Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ return imgProvider.getImage(node);
+ }
+ else if (element instanceof IModelNode) {
+ return UIPlugin.getImage(((IModelNode)element).getImageId());
+ }
+
+ return super.getImage(element);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeNodeComparator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeNodeComparator.java
new file mode 100644
index 000000000..4aaad28d0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FSTreeNodeComparator.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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.tcf.filesystem.ui.internal.columns;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The base comparator for all the file system tree column.
+ */
+public abstract class FSTreeNodeComparator implements Comparator<Object>, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * (non-Javadoc)
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public final int compare(Object o1, Object o2) {
+ if (!(o1 instanceof FSTreeNode) || !(o2 instanceof FSTreeNode)) return 0;
+
+ FSTreeNode node1 = (FSTreeNode)o1;
+ FSTreeNode node2 = (FSTreeNode)o2;
+
+ // Get the type labels
+ String type1 = node1.type;
+ String type2 = node2.type;
+
+ // Group directories and files always together before sorting by name
+ if ((node1.isRoot() || node1.isDirectory()) && !(node2.isRoot() || node2.isDirectory())) {
+ return -1;
+ }
+
+ if ((node2.isRoot() || node2.isDirectory()) && !(node1.isRoot() || node1.isDirectory())) {
+ return 1;
+ }
+
+ // If the nodes are of the same type and one entry starts
+ // with a '.', it comes before the one without a '.'
+ if (type1 != null && type2 != null && type1.equals(type2)) {
+ return doCompare(node1, node2);
+ }
+ return 0;
+ }
+
+ /**
+ * Sort the node1 and node2 when they are both directories or files.
+ *
+ * @param node1 The first node.
+ * @param node2 The second node.
+ * @return The comparison result.
+ */
+ public abstract int doCompare(FSTreeNode node1, FSTreeNode node2);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileExtBasedImageUpdater.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileExtBasedImageUpdater.java
new file mode 100644
index 000000000..90ca5dbe7
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileExtBasedImageUpdater.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.internal.columns;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The image update adapter that updates the images of the file which does
+ * not have a local cache copy. The algorithm is based its extension.
+ */
+public class FileExtBasedImageUpdater implements ImageUpdateAdapter {
+ // The label provider update daemon
+ private LabelProviderUpdateDaemon updateDaemon;
+
+ /**
+ * Create an instance with the specified daemon.
+ *
+ * @param daemon The label provider update daemon.
+ */
+ public FileExtBasedImageUpdater(LabelProviderUpdateDaemon daemon) {
+ this.updateDaemon = daemon;
+ }
+
+ /**
+ * Get the node's file extension or null if there is no extension.
+ *
+ * @param node The file tree node.
+ * @return The file's extension or null.
+ */
+ private String getFileExt(FSTreeNode node) {
+ String name = node.name;
+ String ext = "noext"; //$NON-NLS-1$
+ int index = name.lastIndexOf("."); //$NON-NLS-1$
+ if (index != -1) ext = name.substring(index + 1);
+ return ext;
+ }
+
+ /**
+ * Get the directory to store the temporary mirror files.
+ *
+ * @return The directory to contain the mirror files.
+ */
+ private File getMirrorDir() {
+ File tmpDir = updateDaemon.getTempDir();
+ File mrrDir = new File(tmpDir, ".mrr"); //$NON-NLS-1$
+ if(!mrrDir.exists() && !mrrDir.mkdirs()) {
+ mrrDir = tmpDir;
+ }
+ return mrrDir;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.ImageUpdateAdapter#getImageKey(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public String getImageKey(FSTreeNode node) {
+ String ext = getFileExt(node);
+ return "EXT_IMAGE@" + ext; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.ImageUpdateAdapter#getMirrorFile(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public File getMirrorFile(FSTreeNode node) {
+ String ext = getFileExt(node);
+ File mrrDir = getMirrorDir();
+ File file = new File(mrrDir, "mirror" + "." + ext); //$NON-NLS-1$ //$NON-NLS-2$
+ if (!file.exists()) {
+ try {
+ file.createNewFile();
+ }
+ catch (IOException e) {
+ }
+ }
+ return file;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.ImageUpdateAdapter#getImgFile(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public File getImageFile(FSTreeNode node) {
+ String ext = getFileExt(node);
+ return updateDaemon.getTempImg(ext);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileTypeComparator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileTypeComparator.java
new file mode 100644
index 000000000..8b53a6bed
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileTypeComparator.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The comparator for the tree column "simulator".
+ */
+public class FileTypeComparator extends FSTreeNodeComparator {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.FSTreeNodeComparator#doCompare(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode, org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public int doCompare(FSTreeNode node1, FSTreeNode node2) {
+ String type1 = node1.getFileType();
+ String type2 = node2.getFileType();
+ return type1.compareTo(type2);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileTypeLabelProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileTypeLabelProvider.java
new file mode 100644
index 000000000..d97fa3d31
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/FileTypeLabelProvider.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The label provider for the tree column "simulator".
+ */
+public class FileTypeLabelProvider extends LabelProvider {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ return node.getFileType();
+ }
+ return super.getText(element);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ImageProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ImageProvider.java
new file mode 100644
index 000000000..9ec98b0c8
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ImageProvider.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * An image provider provides platform specific images for each files/folders.
+ * It is used by FSTreeElementLabelProvider to provide the images of a file
+ * node.
+ */
+public interface ImageProvider {
+ /**
+ * Get the image display for the specified file node.
+ *
+ * @param node The file node.
+ * @return The image that represents the file node.
+ */
+ Image getImage(FSTreeNode node);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ImageUpdateAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ImageUpdateAdapter.java
new file mode 100644
index 000000000..1457868ad
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ImageUpdateAdapter.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.internal.columns;
+
+import java.io.File;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The interface to adapt the process of providing the image for two kinds of
+ * files, one which has a local copy or one which does not.
+ */
+public interface ImageUpdateAdapter {
+
+ /**
+ * Get an extension key as the image registry key for the
+ * specified node.
+ *
+ * @param node The node to get the key for.
+ * @return The key used to cache the image descriptor in the registry.
+ */
+ public String getImageKey(FSTreeNode node);
+
+ /**
+ * Return a mirror file that will be used to retrieve the image from.
+ *
+ * @param node The file system tree node.
+ * @return The corresponding mirror file.
+ */
+ public File getMirrorFile(FSTreeNode node);
+
+ /**
+ * Get the image file object for the specified temporary file name.
+ *
+ * @param tmpName The temporary file name.
+ * @return The file object.
+ */
+ public File getImageFile(FSTreeNode node);
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/LabelProviderUpdateDaemon.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/LabelProviderUpdateDaemon.java
new file mode 100644
index 000000000..5f5e04860
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/LabelProviderUpdateDaemon.java
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.internal.columns;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import javax.imageio.ImageIO;
+import javax.swing.Icon;
+import javax.swing.JComponent;
+import javax.swing.filechooser.FileSystemView;
+
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.core.interfaces.IPropertyChangeProvider;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.CacheManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.ImageConsts;
+
+/**
+ * The background daemon that updates the images of the file system using
+ * images retrieved by FileSystemView from Swing.
+ */
+public class LabelProviderUpdateDaemon extends Thread {
+ private static String[][] os_drives = {
+ {"windows xp", "xp_rootdrive.png"}, //$NON-NLS-1$ //$NON-NLS-2$
+ {"windows 7", "win7_rootdrive.png"}, //$NON-NLS-1$//$NON-NLS-2$
+ {"windows 8", "win8_rootdrive.png"} //$NON-NLS-1$//$NON-NLS-2$
+ };
+ private static String root_drive = createRootImage(getOSEntry());
+
+ private static int getOSEntry() {
+ String osName = System.getProperty("os.name").toLowerCase(); //$NON-NLS-1$
+ for(int i = 0; i < os_drives.length;i++) {
+ if(os_drives[i][0].equals(osName)) return i;
+ }
+ return 0;
+ }
+
+ private static String createRootImage(int i) {
+ UIPlugin plugin = UIPlugin.getDefault();
+ URL url = plugin.getBundle().getEntry(ImageConsts.IMAGE_DIR_ROOT + ImageConsts.IMAGE_DIR_OBJ + os_drives[i][1]);
+ plugin.getImageRegistry().put(os_drives[i][0], ImageDescriptor.createFromURL(url));
+ return os_drives[i][0];
+ }
+
+ // The dummy AWT component used to render the icon.
+ Component dummyComponent = new JComponent(){private static final long serialVersionUID = 5926798769323111209L;};
+ //The queue that caches the current file nodes to be updated.
+ BlockingQueue<FSTreeNode> queueNodes;
+ // The image update adapter for a file which has a local cache copy.
+ ImageUpdateAdapter cacheAdapter;
+ // The image update adapter for a file which does not has a local cache copy.
+ ImageUpdateAdapter extAdapter;
+
+ /**
+ * Constructor
+ */
+ public LabelProviderUpdateDaemon() {
+ super("Image Updater Daemon"); //$NON-NLS-1$
+ setDaemon(true);
+ this.queueNodes = new LinkedBlockingQueue<FSTreeNode>();
+ this.cacheAdapter = new CacheFileImageUpdater();
+ this.extAdapter = new FileExtBasedImageUpdater(this);
+ }
+
+ /**
+ * Cache the node which is to be updated with its icon in the file tree.
+ *
+ * @param node The node to be enqueued
+ */
+ public void enqueue(final FSTreeNode node) {
+ SafeRunner.run(new ISafeRunnable() {
+ @Override
+ public void handleException(Throwable exception) {
+ // Ignore
+ }
+
+ @Override
+ public void run() throws Exception {
+ queueNodes.put(node);
+ }
+ });
+ }
+
+ /**
+ * Take next node to be processed.
+ *
+ * @return The next node.
+ */
+ private FSTreeNode take() {
+ while (true) {
+ try {
+ return queueNodes.take();
+ }
+ catch (InterruptedException e) {
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Thread#run()
+ */
+ @Override
+ public void run() {
+ while (true) {
+ FSTreeNode node = take();
+ ImageUpdateAdapter adapter = getUpdateAdapter(node);
+ String imgKey = adapter.getImageKey(node);
+ ImageDescriptor image = UIPlugin.getImageDescriptor(imgKey);
+ if (image == null) {
+ File mrrFile = adapter.getMirrorFile(node);
+ File imgFile = adapter.getImageFile(node);
+ image = createImage(imgKey, mrrFile, imgFile);
+ }
+ if (image != null) {
+ sendNotification(node, node.name, null, image);
+ }
+ }
+ }
+
+ /**
+ * Select an image update adapter for the specified node.
+ *
+ * @param node The FSTreeNode.
+ * @return an image update adapter, either cache based or extension based.
+ */
+ private ImageUpdateAdapter getUpdateAdapter(FSTreeNode node) {
+ File cacheFile = CacheManager.getCacheFile(node);
+ if (cacheFile.exists()) {
+ return cacheAdapter;
+ }
+ return extAdapter;
+ }
+
+ /**
+ * Get the image for the specified node from its
+ * image update adapter.
+ *
+ * @param node The file system tree node.
+ * @return The image or null if there's no image yet.
+ */
+ public Image getImage(FSTreeNode node) {
+ ImageUpdateAdapter adapter = getUpdateAdapter(node);
+ String key = adapter.getImageKey(node);
+ return UIPlugin.getImage(key);
+ }
+
+ /**
+ * Create an Image Descriptor based on the mirror file and store
+ * it in the imgFile and store it using the specified image key.
+ *
+ * @param imgKey The image key.
+ * @param mrrFile The mirror file used to create the image.
+ * @param imgFile The image file used to store the image data.
+ * @return The Image Descriptor describing the image or null if it is not successful.
+ */
+ private ImageDescriptor createImage(String imgKey, File mrrFile, File imgFile) {
+ ImageDescriptor image = UIPlugin.getImageDescriptor(imgKey);
+ if (image == null) {
+ if (!imgFile.exists()) {
+ FileSystemView view = FileSystemView.getFileSystemView();
+ Icon icon = view.getSystemIcon(mrrFile);
+ if (icon != null) createImageFromIcon(icon, imgFile);
+ }
+ if (imgFile.exists()) {
+ try {
+ image = ImageDescriptor.createFromURL(imgFile.toURI().toURL());
+ UIPlugin.getDefault().getImageRegistry().put(imgKey, image);
+ }
+ catch (MalformedURLException e) {
+ // Ignore
+ }
+ }
+ }
+ return image;
+ }
+
+ /**
+ * Get the image of disk drivers on Windows platform.
+ *
+ * @return The disk driver image.
+ */
+ public Image getDiskImage() {
+ return UIPlugin.getImage(root_drive);
+ }
+
+ /**
+ * Get the folder image on Windows platform.
+ *
+ * @return The folder image.
+ */
+ public Image getFolderImage() {
+ String key = "SWING_FOLDER_IMAGE"; //$NON-NLS-1$
+ ImageDescriptor imgDesc = UIPlugin.getImageDescriptor(key);
+ if (imgDesc == null) {
+ String dir = System.getProperty("work.dir"); //$NON-NLS-1$
+ if (dir == null) dir = System.getProperty("java.home"); //$NON-NLS-1$
+ File mirror = null;
+ if (dir != null) mirror = new File(dir);
+ else mirror = new File("."); //$NON-NLS-1$
+ File imgFile = getTempImg("_directory_"); //$NON-NLS-1$
+ createImage(key, mirror, imgFile);
+ }
+ return UIPlugin.getImage(key);
+ }
+
+ /**
+ * Get the temporary directory store the images and temporary mirror files.
+ * @return
+ */
+ protected File getTempDir() {
+ File cacheRoot = CacheManager.getCacheRoot();
+ File tempDir = new File(cacheRoot, ".tmp"); //$NON-NLS-1$
+ if (!tempDir.exists() && !tempDir.mkdirs()) {
+ tempDir = cacheRoot;
+ }
+ return tempDir;
+ }
+
+ /**
+ * Get the an image file named "imgName" in the temporary image
+ * directory.
+ *
+ * @param imgName The image's file name.
+ * @return The file object of this image file.
+ */
+ protected File getTempImg(String imgName) {
+ File tempDir = getTempDir();
+ File imgDir = new File(tempDir, ".img"); //$NON-NLS-1$
+ if (!imgDir.exists() && !imgDir.mkdirs()) {
+ imgDir = tempDir;
+ }
+ return new File(imgDir, imgName + ".png"); //$NON-NLS-1$
+ }
+
+ /**
+ * Create an image file using "png" format
+ * for the specified temporary file.
+ *
+ * @param icon The icon that is used for the temporary file.
+ * @param tmpfile The temporary file.
+ */
+ private void createImageFromIcon(Icon icon, File imgFile) {
+ BufferedImage bi = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
+ Graphics g = bi.createGraphics();
+ icon.paintIcon(dummyComponent, g, 0, 0);
+ g.dispose();
+ try {
+ ImageIO.write(bi, "png", imgFile); //$NON-NLS-1$
+ }
+ catch (IOException e) {
+ }
+ }
+
+ /**
+ * Send a notification to inform the file tree for changed images.
+ *
+ * @param node The node whose image has changed.
+ * @param key The key used to store the images.
+ * @param oldImg The old image descriptor.
+ * @param newImg The new image descriptor.
+ */
+ private void sendNotification(FSTreeNode node, String key, ImageDescriptor oldImg, ImageDescriptor newImg) {
+ if (node.peerNode != null) {
+ IPropertyChangeProvider viewerInput = (IPropertyChangeProvider) node.peerNode.getAdapter(IPropertyChangeProvider.class);
+ viewerInput.firePropertyChange(new PropertyChangeEvent(node, key, oldImg, newImg));
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ModificationTimeComparator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ModificationTimeComparator.java
new file mode 100644
index 000000000..6aad6951c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ModificationTimeComparator.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The comparator for the tree column "Date Modified".
+ */
+public class ModificationTimeComparator extends FSTreeNodeComparator {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.FSTreeNodeComparator#doCompare(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode, org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public int doCompare(FSTreeNode node1, FSTreeNode node2) {
+ long mtime1 = node1.attr != null ? node1.attr.mtime : 0;
+ long mtime2 = node2.attr != null ? node2.attr.mtime : 0;
+ return mtime1 < mtime2 ? -1 : (mtime1 > mtime2 ? 1 : 0);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ModificationTimeLabelProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ModificationTimeLabelProvider.java
new file mode 100644
index 000000000..0cedfb5b9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/ModificationTimeLabelProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.columns;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The label provider for the tree column "Date Modified".
+ */
+public class ModificationTimeLabelProvider extends LabelProvider {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ if (node.attr != null) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("M/d/yyyy h:mm aa"); //$NON-NLS-1$
+ return dateFormat.format(new Date(node.attr.mtime));
+ }
+ }
+ return ""; //$NON-NLS-1$
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/SizeComparator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/SizeComparator.java
new file mode 100644
index 000000000..af9b227e6
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/SizeComparator.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The comparator for the tree column "size".
+ */
+public class SizeComparator extends FSTreeNodeComparator {
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.FSTreeNodeComparator#doCompare(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode, org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public int doCompare(FSTreeNode node1, FSTreeNode node2) {
+ long size1 = node1.attr != null ? node1.attr.size : 0;
+ long size2 = node2.attr != null ? node2.attr.size : 0;
+ return size1 < size2 ? -1 : (size1 > size2 ? 1 : 0);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/SizeLabelProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/SizeLabelProvider.java
new file mode 100644
index 000000000..489ce7940
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/SizeLabelProvider.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.columns;
+
+import java.text.DecimalFormat;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The label provider for the tree column "size".
+ */
+public class SizeLabelProvider extends LabelProvider {
+ // The size formatter.
+ private static final DecimalFormat SIZE_FORMAT = new DecimalFormat();
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+ */
+ @Override
+ public String getText(Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ // Directory nodes does not have a size
+ if (node.isFile() && node.attr != null) {
+ return SIZE_FORMAT.format(node.attr.size / 1024) + " KB"; //$NON-NLS-1$
+ }
+ }
+ return ""; //$NON-NLS-1$
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/WindowsImageProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/WindowsImageProvider.java
new file mode 100644
index 000000000..de0529528
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/columns/WindowsImageProvider.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.internal.columns;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * Windows specific image provider extending the default image provider
+ * to retrieve the file's images based on file extension or cached file.
+ */
+public class WindowsImageProvider extends DefaultImageProvider {
+ // The background daemons that updates the images of the file system nodes.
+ static LabelProviderUpdateDaemon updateDaemon;
+ static {
+ updateDaemon = new LabelProviderUpdateDaemon();
+ updateDaemon.start();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.columns.DefaultImageProvider#getImage(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode)
+ */
+ @Override
+ public Image getImage(FSTreeNode node) {
+ if (node.isRoot()) {
+ return node.isWindowsNode() ? updateDaemon.getDiskImage() : super.getImage(node);
+ }
+ else if (node.isDirectory()) {
+ return updateDaemon.getFolderImage();
+ }
+ else if(node.isFile()) {
+ Image image = updateDaemon.getImage(node);
+ if (image == null) {
+ updateDaemon.enqueue(node);
+ image = getPredefinedImage(node);
+ }
+ return image;
+ }
+ return super.getImage(node);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/EditableSharedDocumentAdapter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/EditableSharedDocumentAdapter.java
new file mode 100644
index 000000000..ae087ace0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/EditableSharedDocumentAdapter.java
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2014 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare;
+
+import org.eclipse.compare.SharedDocumentAdapter;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.IElementStateListener;
+
+/**
+ * A shared document adapter that tracks whether the element is connected to a
+ * shared document and whether the contents have been flushed from a compare
+ * viewer. When contents are flushed, this adapter will connect to the document
+ * provider to ensure that the changes are not lost (see
+ * {@link #hasBufferedContents()}). In order to avoid a leak, the buffer must
+ * either be saved (see
+ * {@link #saveDocument(IEditorInput, boolean, IProgressMonitor)}) or released
+ * (see {@link #releaseBuffer()}).
+ * <p>
+ * This adapter must have a one-to-one correspondence to a typed element.
+ *
+ * @since 3.7 - Copied from
+ * org.eclipse.team.internal.ui.synchronize.EditableSharedDocumentAdapter
+ */
+public class EditableSharedDocumentAdapter extends SharedDocumentAdapter implements IElementStateListener {
+
+ private int connectionCount;
+ private final ISharedDocumentAdapterListener listener;
+ private IEditorInput bufferedKey;
+
+ /**
+ * Interface that provides this adapter with the action of the typed element
+ * and supports call backs to the element when the adapter action changes.
+ */
+ public interface ISharedDocumentAdapterListener {
+
+ /**
+ * Method that is invoked when the adapter connects to the document
+ * provider. This method is only invoked when the adapter first connects
+ * to the document.
+ */
+ void handleDocumentConnected();
+
+ /**
+ * Method that is invoked when the adapter disconnects from the document
+ * provider. This method is only invoked when the adapter no longer has
+ * any connection to the document provider.
+ */
+ void handleDocumentDisconnected();
+
+ /**
+ * Method invoked when changes in the document are flushed to the
+ * adapter.
+ */
+ void handleDocumentFlushed();
+
+ /**
+ * Method invoked when the file behind the shared document is deleted.
+ */
+ void handleDocumentDeleted();
+
+ /**
+ * Method invoked when the document dirty action changes from dirty to
+ * clean.
+ */
+ void handleDocumentSaved();
+ }
+
+ /**
+ * Create the shared document adapter for the given element.
+ *
+ * @param listener
+ * access to element internals
+ */
+ public EditableSharedDocumentAdapter(ISharedDocumentAdapterListener listener) {
+ super();
+ this.listener = listener;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.SharedDocumentAdapter#connect(org.eclipse.ui.texteditor.IDocumentProvider, org.eclipse.ui.IEditorInput)
+ */
+ @Override
+ public void connect(IDocumentProvider provider, IEditorInput documentKey)
+ throws CoreException {
+ super.connect(provider, documentKey);
+ connectionCount++;
+ if (connectionCount == 1) {
+ provider.addElementStateListener(this);
+ listener.handleDocumentConnected();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.SharedDocumentAdapter#disconnect(org.eclipse.ui.texteditor.IDocumentProvider, org.eclipse.ui.IEditorInput)
+ */
+ @Override
+ public void disconnect(IDocumentProvider provider, IEditorInput documentKey) {
+ try {
+ super.disconnect(provider, documentKey);
+ } finally {
+ if (connectionCount > 0)
+ connectionCount--;
+ if (connectionCount == 0) {
+ provider.removeElementStateListener(this);
+ listener.handleDocumentDisconnected();
+ }
+ }
+ }
+
+ /**
+ * Return whether the element is connected to a shared document.
+ *
+ * @return whether the element is connected to a shared document
+ */
+ public boolean isConnected() {
+ return connectionCount > 0;
+ }
+
+ /**
+ * Save the shared document of the element of this adapter.
+ *
+ * @param input
+ * the document key of the element.
+ * @param monitor
+ * a progress monitor
+ * @return whether the save succeeded or not
+ * @throws CoreException
+ */
+ public boolean saveDocument(IEditorInput input, IProgressMonitor monitor)
+ throws CoreException {
+ if (isConnected()) {
+ IDocumentProvider provider = SharedDocumentAdapter
+ .getDocumentProvider(input);
+ try {
+ saveDocument(provider, input, provider.getDocument(input),
+ true, monitor);
+ } finally {
+ // When we write the document, remove out hold on the buffer
+ releaseBuffer();
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Release the buffer if this adapter has buffered the contents in response
+ * to a
+ * {@link #flushDocument(IDocumentProvider, IEditorInput, IDocument, boolean)}
+ * .
+ */
+ public void releaseBuffer() {
+ if (bufferedKey != null) {
+ IDocumentProvider provider = SharedDocumentAdapter
+ .getDocumentProvider(bufferedKey);
+ provider.disconnect(bufferedKey);
+ bufferedKey = null;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.ISharedDocumentAdapter#flushDocument(org.eclipse.ui.texteditor.IDocumentProvider, org.eclipse.ui.IEditorInput, org.eclipse.jface.text.IDocument, boolean)
+ */
+ @Override
+ public void flushDocument(IDocumentProvider provider,
+ IEditorInput documentKey, IDocument document, boolean overwrite)
+ throws CoreException {
+ if (!hasBufferedContents()) {
+ // On a flush, make an extra connection to the shared document so it
+ // will be kept even
+ // if it is no longer being viewed.
+ bufferedKey = documentKey;
+ provider.connect(bufferedKey);
+ }
+ this.listener.handleDocumentFlushed();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IElementStateListener#elementContentAboutToBeReplaced(java.lang.Object)
+ */
+ @Override
+ public void elementContentAboutToBeReplaced(Object element) {
+ // Nothing to do
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IElementStateListener#elementContentReplaced(java.lang.Object)
+ */
+ @Override
+ public void elementContentReplaced(Object element) {
+ // Nothing to do
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IElementStateListener#elementDeleted(java.lang.Object)
+ */
+ @Override
+ public void elementDeleted(Object element) {
+ listener.handleDocumentDeleted();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IElementStateListener#elementDirtyStateChanged(java.lang.Object, boolean)
+ */
+ @Override
+ public void elementDirtyStateChanged(Object element, boolean isDirty) {
+ if (!isDirty) {
+ this.listener.handleDocumentSaved();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.IElementStateListener#elementMoved(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public void elementMoved(Object originalElement, Object movedElement) {
+ // Nothing to do
+ }
+
+ /**
+ * Return whether the adapter has buffered contents. The adapter buffers
+ * contents by connecting to the document through the document provider.
+ * This means that the adapter must be disconnected either by saving or
+ * discarding the buffer.
+ *
+ * @return whether the adapter has buffered contents
+ */
+ public boolean hasBufferedContents() {
+ return bufferedKey != null;
+ }
+
+ /**
+ * Override getDocumentKey in the super class to provide an editor input
+ * when the element is a <code>LocalTypedElement</code>.
+ */
+ @Override
+ public IEditorInput getDocumentKey(Object element) {
+ if (element instanceof LocalTypedElement) {
+ LocalTypedElement localElement = (LocalTypedElement) element;
+ return localElement.getEditorInput();
+ }
+ return super.getDocumentKey(element);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/LocalFileSaveable.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/LocalFileSaveable.java
new file mode 100644
index 000000000..db636b588
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/LocalFileSaveable.java
@@ -0,0 +1,481 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare;
+
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.ICompareContainer;
+import org.eclipse.compare.IContentChangeListener;
+import org.eclipse.compare.IContentChangeNotifier;
+import org.eclipse.compare.ISharedDocumentAdapter;
+import org.eclipse.compare.SharedDocumentAdapter;
+import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpUpload;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.ISaveablesLifecycleListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartConstants;
+import org.eclipse.ui.Saveable;
+import org.eclipse.ui.SaveablesLifecycleEvent;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+
+/**
+ * A <code>LocalFileSaveable</code> is used as the saveable object that provides
+ * the save behavior for the merge editor input(<code>MergeEditorInput</code>).
+ */
+public class LocalFileSaveable extends Saveable implements
+ IPropertyChangeListener, ISharedDocumentAdapterListener,
+ IContentChangeListener {
+ // The property listener list.
+ private ListenerList listeners = new ListenerList(ListenerList.IDENTITY);
+
+ // The merge input that provides the left and the right compared elements.
+ private final MergeInput input;
+
+ // The input of the editor that provides the comparing view.
+ private final MergeEditorInput editorInput;
+
+ // If the current document of the file is being saved.
+ private boolean saving;
+
+ // The local file element.
+ private LocalTypedElement fileElement;
+
+ // The document provided by the local file.
+ private IDocument document;
+
+ // If the current document has been connected.
+ private boolean connected;
+
+ /**
+ * Create the file-based saveable comparison.
+ *
+ * @param input
+ * the compare input to be save
+ * @param editorInput
+ * the editor input containing the comparison
+ * @param fileElement
+ * the file element that handles the saving and change
+ * notification
+ */
+ public LocalFileSaveable(MergeInput input, MergeEditorInput editorInput, LocalTypedElement fileElement) {
+ Assert.isNotNull(input);
+
+ this.input = input;
+ this.editorInput = editorInput;
+ this.fileElement = fileElement;
+ this.fileElement.addContentChangeListener(this);
+ this.fileElement.setDocumentListener(this);
+ }
+
+ /**
+ * Dispose of the saveable.
+ */
+ public void dispose() {
+ fileElement.removeContentChangeListener(this);
+ fileElement.discardBuffer();
+ fileElement.setDocumentListener(null);
+ }
+
+ /**
+ * Performs the save.
+ *
+ * @param monitor The progress monitor.
+ *
+ * @throws CoreException If the save operation fails.
+ */
+ protected void performSave(IProgressMonitor monitor) throws CoreException {
+ try {
+ saving = true;
+ monitor.beginTask(null, 100);
+ // First, we need to flush the viewers so the changes get buffered
+ // in the input
+ flushViewers(monitor);
+ // Then we tell the input to commit its changes
+ // Only the left is ever saveable
+ if (fileElement.isDirty()) {
+ if (fileElement.isConnected()) {
+ fileElement.store2Document(monitor);
+ } else {
+ fileElement.store2Cache(monitor);
+ }
+ }
+ } finally {
+ // Make sure we fire a change for the compare input to update the
+ // viewers
+ fireInputChange();
+ setDirty(false);
+ saving = false;
+ monitor.done();
+ //Trigger upload action
+ FSTreeNode node = fileElement.getFSTreeNode();
+ IOpExecutor executor = new UiExecutor();
+ executor.execute(new OpUpload(node));
+ }
+ }
+
+ /**
+ * Flush the contents of any viewers into the compare input.
+ *
+ * @param monitor
+ * a progress monitor
+ * @throws CoreException
+ */
+ protected void flushViewers(IProgressMonitor monitor) throws CoreException {
+ editorInput.saveChanges(monitor);
+ }
+
+ /**
+ * Fire an input change for the compare input after it has been saved.
+ */
+ protected void fireInputChange() {
+ editorInput.getCompareResult().fireInputChanged();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.Saveable#isDirty()
+ */
+ @Override
+ public boolean isDirty() {
+ return editorInput.isSaveNeeded();
+ }
+
+ /**
+ * Marks the editor input dirty.
+ *
+ * @param dirty <code>True</code> if the editor is dirty, <code>false</code> if not.
+ */
+ protected void setDirty(boolean dirty) {
+ if (isDirty() != dirty) {
+ editorInput.setDirty(dirty);
+ firePropertyChange(IWorkbenchPartConstants.PROP_DIRTY);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.Saveable#getName()
+ */
+ @Override
+ public String getName() {
+ // Return the name of the file element as held in the compare input
+ if (fileElement.equals(input.getLeft())) {
+ return input.getLeft().getName();
+ }
+ if (fileElement.equals(input.getRight())) {
+ return input.getRight().getName();
+ }
+
+ // Fallback call returning name of the main non-null element of the input
+ //
+ // see org.eclipse.team.internal.ui.mapping.AbstractCompareInput#getMainElement()
+ return input.getName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.Saveable#getToolTipText()
+ */
+ @Override
+ public String getToolTipText() {
+ return editorInput.getToolTipText();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.Saveable#getImageDescriptor()
+ */
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ Image image = input.getImage();
+ if (image != null)
+ return ImageDescriptor.createFromImage(image);
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ @Override
+ public void propertyChange(PropertyChangeEvent e) {
+ String propertyName = e.getProperty();
+ if (CompareEditorInput.DIRTY_STATE.equals(propertyName)) {
+ boolean changed = false;
+ Object newValue = e.getNewValue();
+ if (newValue instanceof Boolean)
+ changed = ((Boolean) newValue).booleanValue();
+
+ ContentMergeViewer cmv = (ContentMergeViewer) e.getSource();
+
+ if (fileElement.equals(input.getLeft())) {
+ if (changed && cmv.internalIsLeftDirty())
+ setDirty(changed);
+ else if (!changed && !cmv.internalIsLeftDirty()) {
+ setDirty(changed);
+ }
+ }
+ if (fileElement.equals(input.getRight())) {
+ if (changed && cmv.internalIsRightDirty())
+ setDirty(changed);
+ else if (!changed && !cmv.internalIsRightDirty()) {
+ setDirty(changed);
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.Saveable#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ if (document != null) {
+ return document.hashCode();
+ }
+ return input.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.Saveable#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+
+ if (!(obj instanceof Saveable))
+ return false;
+
+ if (document != null) {
+ Object otherDocument = ((Saveable) obj).getAdapter(IDocument.class);
+
+ if (otherDocument == null)
+ return false;
+
+ return document.equals(otherDocument);
+ }
+
+ if (obj instanceof LocalFileSaveable) {
+ LocalFileSaveable saveable = (LocalFileSaveable) obj;
+ return saveable.input.equals(input);
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.Saveable#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (adapter == IDocument.class) {
+ if (document != null)
+ return document;
+ if (fileElement.isConnected()) {
+ ISharedDocumentAdapter sda = (ISharedDocumentAdapter) fileElement
+ .getAdapter(ISharedDocumentAdapter.class);
+ if (sda != null) {
+ IEditorInput input = sda.getDocumentKey(fileElement);
+ if (input != null) {
+ IDocumentProvider provider = SharedDocumentAdapter
+ .getDocumentProvider(input);
+ if (provider != null)
+ return provider.getDocument(input);
+ }
+ }
+ }
+ }
+ if (adapter == IEditorInput.class) {
+ return fileElement.getEditorInput();
+ }
+ return super.getAdapter(adapter);
+ }
+
+ /**
+ * Get an ISaveablesLifecycleListener from the specified workbench
+ * part.
+ * @param part The workbench part.
+ * @return The listener.
+ */
+ private ISaveablesLifecycleListener getSaveablesLifecycleListener(
+ IWorkbenchPart part) {
+ if (part instanceof ISaveablesLifecycleListener)
+ return (ISaveablesLifecycleListener) part;
+
+ Object adapted = part.getAdapter(ISaveablesLifecycleListener.class);
+ if (adapted instanceof ISaveablesLifecycleListener)
+ return (ISaveablesLifecycleListener) adapted;
+
+ adapted = Platform.getAdapterManager().loadAdapter(part,
+ ISaveablesLifecycleListener.class.getName());
+ if (adapted instanceof ISaveablesLifecycleListener)
+ return (ISaveablesLifecycleListener) adapted;
+
+ return (ISaveablesLifecycleListener) part.getSite().getService(
+ ISaveablesLifecycleListener.class);
+ }
+
+ /**
+ * When the document of the local file is connected, register this saveable.
+ */
+ private void registerSaveable() {
+ ICompareContainer container = editorInput.getContainer();
+ IWorkbenchPart part = container.getWorkbenchPart();
+ if (part != null) {
+ ISaveablesLifecycleListener lifecycleListener = getSaveablesLifecycleListener(part);
+ // Remove this saveable from the lifecycle listener
+ lifecycleListener.handleLifecycleEvent(new SaveablesLifecycleEvent(
+ part, SaveablesLifecycleEvent.POST_CLOSE,
+ new Saveable[] { this }, false));
+ // Now fix the hashing so it uses the fConnected fDocument
+ IDocument document = (IDocument) getAdapter(IDocument.class);
+ if (document != null) {
+ this.document = document;
+ }
+ // Finally, add this saveable back to the listener
+ lifecycleListener.handleLifecycleEvent(new SaveablesLifecycleEvent(
+ part, SaveablesLifecycleEvent.POST_OPEN,
+ new Saveable[] { this }, false));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.compare.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener#handleDocumentConnected()
+ */
+ @Override
+ public void handleDocumentConnected() {
+ if (connected)
+ return;
+ connected = true;
+ registerSaveable();
+ fileElement.setDocumentListener(null);
+ }
+
+ @Override
+ public void handleDocumentDeleted() {
+ // Ignore
+ }
+
+ @Override
+ public void handleDocumentDisconnected() {
+ // Ignore
+ }
+
+ @Override
+ public void handleDocumentFlushed() {
+ // Ignore
+ }
+
+ @Override
+ public void handleDocumentSaved() {
+ // Ignore
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.compare.IContentChangeListener#contentChanged(org.eclipse.compare.IContentChangeNotifier)
+ */
+ @Override
+ public void contentChanged(IContentChangeNotifier source) {
+ if (!saving) {
+ try {
+ performSave(new NullProgressMonitor());
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void doSave(IProgressMonitor monitor) throws CoreException {
+ if (isDirty()) {
+ performSave(monitor);
+ setDirty(false);
+ }
+ }
+
+ /**
+ * Revert any changes in the buffer back to the last saved action.
+ *
+ * @param monitor
+ * a progress monitor on <code>null</code> if progress feedback
+ * is not required
+ */
+ public void doRevert(IProgressMonitor monitor) {
+ if (!isDirty())
+ return;
+ fileElement.discardBuffer();
+ setDirty(false);
+ }
+
+ /**
+ * Add a property change listener. Adding a listener that is already
+ * registered has no effect.
+ *
+ * @param listener
+ * the listener
+ */
+ public void addPropertyListener(IPropertyListener listener) {
+ listeners.add(listener);
+ }
+
+ /**
+ * Remove a property change listener. Removing a listener that is not
+ * registered has no effect.
+ *
+ * @param listener
+ * the listener
+ */
+ public void removePropertyListener(IPropertyListener listener) {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Fire a property change event for this buffer.
+ *
+ * @param property
+ * the property that changed
+ */
+ protected void firePropertyChange(final int property) {
+ Object[] allListeners = listeners.getListeners();
+ for (int i = 0; i < allListeners.length; i++) {
+ final Object object = allListeners[i];
+ SafeRunner.run(new SafeRunnable() {
+ @Override
+ public void handleException(Throwable e) {
+ // Ignore exception
+ }
+ @Override
+ public void run() throws Exception {
+ ((IPropertyListener) object).propertyChanged(
+ LocalFileSaveable.this, property);
+ }
+ });
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/LocalTypedElement.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/LocalTypedElement.java
new file mode 100644
index 000000000..825a66743
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/LocalTypedElement.java
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.compare.IEditableContent;
+import org.eclipse.compare.ISharedDocumentAdapter;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.CacheManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.ide.FileStoreEditorInput;
+
+/**
+ * A <code>LocalTypedElement</code> extends <code>MergeTypedElement</code> and
+ * wraps an <code>FSTreeNode</code> so that it can be used as the left element
+ * of a <code>MergeEditorInput</code>. It implements the interface
+ * <code>IEditableContent</code> so that it is editable.
+ */
+public class LocalTypedElement extends MergeTypedElement implements
+ IEditableContent, IAdaptable, ISharedDocumentAdapterListener {
+ // If the current edited file is dirty.
+ private boolean dirty;
+ // The shared document adapter
+ private EditableSharedDocumentAdapter documentAdapter;
+ // The shared document listener.
+ private ISharedDocumentAdapterListener documentListener;
+
+ /**
+ * Creates a <code>LocalTypedElement</code> for the given resource.
+ *
+ * @param resource
+ * the resource
+ */
+ public LocalTypedElement(FSTreeNode node) {
+ super(node);
+ setContent(getContent());
+ dirty = false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+ */
+ @Override
+ public Object getAdapter(Class adapter) {
+ if (adapter == ISharedDocumentAdapter.class) {
+ if (documentAdapter == null)
+ documentAdapter = new EditableSharedDocumentAdapter(this);
+ return documentAdapter;
+ }
+ return Platform.getAdapterManager().getAdapter(this, adapter);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.BufferedContent#setContent(byte[])
+ */
+ @Override
+ public void setContent(byte[] contents) {
+ dirty = true;
+ super.setContent(contents);
+ }
+
+ /**
+ * Set the document listener.
+ *
+ * @param documentListener
+ * the document listener.
+ */
+ public void setDocumentListener(
+ ISharedDocumentAdapterListener documentListener) {
+ this.documentListener = documentListener;
+ }
+
+ /**
+ * Return an input stream that opens that locally cached file to provide the
+ * content.
+ *
+ * @return a buffered input stream containing the contents of this file
+ * @exception CoreException
+ * if the contents of this storage could not be accessed
+ */
+ @Override
+ protected InputStream createStream() throws CoreException {
+ try {
+ IPath cachePath = CacheManager.getCachePath(node);
+ File cacheFile = cachePath.toFile();
+ return new BufferedInputStream(new FileInputStream(cacheFile));
+ } catch (FileNotFoundException e) {
+ IStatus error = new Status(IStatus.ERROR,
+ UIPlugin.getUniqueIdentifier(), e.getMessage(), e);
+ throw new CoreException(error);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.IEditableContent#isEditable()
+ */
+ @Override
+ public boolean isEditable() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.IEditableContent#replace(org.eclipse.compare.ITypedElement, org.eclipse.compare.ITypedElement)
+ */
+ @Override
+ public ITypedElement replace(ITypedElement dest, ITypedElement src) {
+ return dest;
+ }
+
+ /**
+ * Save the shared document for this element. The save can only be performed
+ * if the element is connected to a shared document. If the element is not
+ * connected, <code>false</code> is returned.
+ *
+ * @param overwrite
+ * indicates whether overwrite should be performed while saving
+ * the given element if necessary
+ * @param monitor
+ * a progress monitor
+ * @throws CoreException
+ */
+ public boolean store2Document(IProgressMonitor monitor)
+ throws CoreException {
+ if (isConnected()) {
+ IEditorInput input = documentAdapter.getDocumentKey(this);
+ documentAdapter.saveDocument(input, monitor);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Judges whether the content has been changed.
+ *
+ * @return
+ */
+ public boolean isDirty() {
+ return dirty
+ || (documentAdapter != null && documentAdapter
+ .hasBufferedContents());
+ }
+
+ /**
+ * Set the dirty action.
+ *
+ * @param dirty
+ * The dirty action.
+ */
+ public void setDirty(boolean dirty) {
+ this.dirty = dirty;
+ }
+
+ /**
+ * If the document adapter has been connected.
+ *
+ * @return true if it is not null and connected.
+ */
+ public boolean isConnected() {
+ return documentAdapter != null && documentAdapter.isConnected();
+ }
+
+ /**
+ * Return the path to the local file of this node. It is used to compute its
+ * hash code and as the title of the comparison editor.
+ */
+ @Override
+ public String toString() {
+ File cacheFile = CacheManager.getCacheFile(node);
+ return cacheFile.toString();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.compare.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener#handleDocumentConnected()
+ */
+ @Override
+ public void handleDocumentConnected() {
+ if (documentListener != null)
+ documentListener.handleDocumentConnected();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.compare.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener#handleDocumentDeleted()
+ */
+ @Override
+ public void handleDocumentDeleted() {
+ if (documentListener != null)
+ documentListener.handleDocumentDeleted();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.compare.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener#handleDocumentDisconnected()
+ */
+ @Override
+ public void handleDocumentDisconnected() {
+ if (documentListener != null)
+ documentListener.handleDocumentDisconnected();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.compare.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener#handleDocumentFlushed()
+ */
+ @Override
+ public void handleDocumentFlushed() {
+ fireContentChanged();
+ if (documentListener != null)
+ documentListener.handleDocumentFlushed();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.compare.EditableSharedDocumentAdapter.ISharedDocumentAdapterListener#handleDocumentSaved()
+ */
+ @Override
+ public void handleDocumentSaved() {
+ if (documentListener != null)
+ documentListener.handleDocumentSaved();
+ }
+
+ /**
+ * Get an editor input for this file.
+ *
+ * @return The editor input.
+ */
+ public IEditorInput getEditorInput() {
+ IPath path = CacheManager.getCachePath(node);
+ IFileStore fileStore = EFS.getLocalFileSystem().getStore(path);
+ return new FileStoreEditorInput(fileStore);
+ }
+
+ /**
+ * Save to its local file when the document has not been connected yet.
+ *
+ * @param monitor
+ * The monitor that reports the progress.
+ */
+ public void store2Cache(IProgressMonitor monitor) throws CoreException {
+ File cacheFile = CacheManager.getCacheFile(node);
+ monitor.beginTask(NLS.bind(Messages.LocalTypedElement_SavingFile, cacheFile.getName()), 100);
+ InputStream is = getContents();
+ BufferedOutputStream bos = null;
+ try {
+ long total = cacheFile.length();
+ bos = new BufferedOutputStream(new FileOutputStream(cacheFile));
+ byte[] data = new byte[10 * 1024];
+ int length;
+ long current = 0;
+ int currProgress = 0;
+ while ((length = is.read(data)) > 0) {
+ bos.write(data, 0, length);
+ bos.flush();
+ current += length;
+ int progress = (int) (current * 100 / total);
+ if (currProgress != progress) {
+ monitor.worked(progress - currProgress);
+ currProgress = progress;
+ }
+ }
+ setDirty(false);
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR,
+ UIPlugin.getUniqueIdentifier(), e.getMessage(), e));
+ } finally {
+ if (is != null)
+ try {
+ is.close();
+ } catch (IOException ex) {
+ }
+ if (bos != null) {
+ try {
+ bos.close();
+ } catch (Exception e) {
+ }
+ }
+ // Notify the local file element that the document has changed.
+ fireContentChanged();
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeEditorInput.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeEditorInput.java
new file mode 100644
index 000000000..65f8c5846
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeEditorInput.java
@@ -0,0 +1,419 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareEditorInput;
+import org.eclipse.compare.IPropertyChangeNotifier;
+import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.SafeRunnable;
+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;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.ISaveablesSource;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPartConstants;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.Saveable;
+/**
+ * A <code>MergeEditorInput</code> is the input of a compare editor used to
+ * compare the local file and the remote file in a Target Explorer file system.
+ */
+public class MergeEditorInput extends CompareEditorInput implements
+ ISaveablesSource, IPropertyListener, ICompareInputChangeListener {
+
+ // The left element is a local file which can be editable.
+ private LocalTypedElement left;
+ // The right element is the remote file which is read only.
+ private RemoteTypedElement right;
+
+ // The active page of the current workbench.
+ private final IWorkbenchPage page;
+
+ // The current input change listener list.
+ private final ListenerList inputChangeListeners = new ListenerList(ListenerList.IDENTITY);
+ // The current saveable for the left element, i.e., the local file.
+ private LocalFileSaveable saveable;
+
+ /**
+ * Creates a new MergeEditorInput.
+ *
+ * @param left
+ * @param right
+ * @param page
+ */
+ public MergeEditorInput(LocalTypedElement left, RemoteTypedElement right, IWorkbenchPage page) {
+ super(new CompareConfiguration());
+ this.page = page;
+ this.left = left;
+ this.right = right;
+ configureCompare();
+ }
+
+ /**
+ * Configure the compare configuration using the left
+ * and right elements. Set the left and right label.
+ * Set the editable status.
+ */
+ protected void configureCompare() {
+ CompareConfiguration cc = getCompareConfiguration();
+ cc.setLeftEditable(true);
+ cc.setRightEditable(false);
+
+ String name = TextProcessor.process(left.getName());
+ String label = NLS.bind(Messages.MergeEditorInput_LocalFile, name);
+ cc.setLeftLabel(label);
+
+ name = TextProcessor.process(right.toString());
+ label = NLS.bind(Messages.MergeEditorInput_RemoteFile, name);
+ cc.setRightLabel(label);
+ }
+
+ /**
+ * Returns <code>true</code> if the other object is of simulator
+ * <code>MergeEditorInput</code> and both of their corresponding fLeft and
+ * fRight objects are identical. The content is not considered.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (obj instanceof MergeEditorInput) {
+ MergeEditorInput other = (MergeEditorInput) obj;
+ return other.left.equals(left) && other.right.equals(right);
+ }
+ return false;
+ }
+
+ /**
+ * Override hashCode to provide identical value when
+ * two MergeEditorInputs are equal to each other.
+ */
+ @Override
+ public int hashCode() {
+ return left.hashCode() + right.hashCode();
+ }
+
+ /**
+ * Prepare the compare input of this editor input. This method is not
+ * intended to be overridden of extended by subclasses (but is not final for
+ * backwards compatibility reasons). The implementation of this method in
+ * this class delegates the creation of the compare input to the
+ * {@link #prepareCompareInput(IProgressMonitor)} method which subclasses
+ * must implement.
+ *
+ * @see org.eclipse.compare.CompareEditorInput#prepareInput(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ protected Object prepareInput(IProgressMonitor monitor)
+ throws InvocationTargetException, InterruptedException {
+ right.cacheContents(monitor);
+ MergeInput input = new MergeInput(left, right);
+ setTitle(input.getName());
+ return input;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#getToolTipText()
+ */
+ @Override
+ public String getToolTipText() {
+ return NLS.bind(Messages.MergeEditorInput_CompareLeftAndRight, left, right);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#getTitle()
+ */
+ @Override
+ public String getTitle() {
+ return NLS.bind(Messages.MergeEditorInput_CompareWithLocalCache, left.getName());
+ }
+
+ /**
+ * Override the super method to provide clear typed input.
+ */
+ @Override
+ public MergeInput getCompareResult() {
+ return (MergeInput) super.getCompareResult();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#handleDispose()
+ */
+ @Override
+ protected void handleDispose() {
+ super.handleDispose();
+ ICompareInput compareInput = getCompareResult();
+ if (compareInput != null)
+ compareInput.removeCompareInputChangeListener(this);
+ if(getCompareResult()!=null){
+ getSaveable().removePropertyListener(this);
+ getSaveable().dispose();
+ }
+ left.discardBuffer();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#contentsCreated()
+ */
+ @Override
+ protected void contentsCreated() {
+ super.contentsCreated();
+ if (getCompareResult() != null) {
+ getCompareResult().addCompareInputChangeListener(this);
+ getSaveable().addPropertyListener(this);
+ setDirty(getSaveable().isDirty());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object, int)
+ */
+ @Override
+ public void propertyChanged(Object source, int propId) {
+ if (propId == IWorkbenchPartConstants.PROP_DIRTY && getCompareResult()!=null) {
+ setDirty(getSaveable().isDirty());
+ }
+ }
+
+ /**
+ * Close the editor if it is not dirty. If it is still dirty, let the
+ * content merge viewer handle the compare input change.
+ *
+ * @param checkForUnsavedChanges
+ * whether to check for unsaved changes
+ * @return <code>true</code> if the editor was closed (note that the close
+ * may be asynchronous)
+ */
+ protected boolean closeEditor(boolean checkForUnsavedChanges) {
+ if (isSaveNeeded() && checkForUnsavedChanges) {
+ return false;
+ }
+ final IWorkbenchPage page = getPage();
+ if (page == null)
+ return false;
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ Shell shell = page.getWorkbenchWindow().getShell();
+ if (shell == null)
+ return;
+
+ IEditorPart part = page.findEditor(MergeEditorInput.this);
+ getPage().closeEditor(part, false);
+ }
+ };
+ if (Display.getCurrent() != null) {
+ runnable.run();
+ } else {
+ Shell shell = page.getWorkbenchWindow().getShell();
+ if (shell == null)
+ return false;
+ Display display = shell.getDisplay();
+ display.asyncExec(runnable);
+ }
+ return true;
+ }
+
+ /**
+ * Get the current active page.
+ * @return the workbench page.
+ */
+ IWorkbenchPage getPage() {
+ if (page == null)
+ return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ return page;
+ }
+
+ /**
+ * Propagate the input change event to the compare input change listener list.
+ */
+ /* default */void propogateInputChange() {
+ if (!inputChangeListeners.isEmpty()) {
+ Object[] allListeners = inputChangeListeners.getListeners();
+ for (int i = 0; i < allListeners.length; i++) {
+ final ICompareInputChangeListener listener = (ICompareInputChangeListener) allListeners[i];
+ SafeRunner.run(new SafeRunnable() {
+ @Override
+ public void handleException(Throwable e) {
+ // Ignore exception
+ }
+ @Override
+ public void run() throws Exception {
+ listener.compareInputChanged(getCompareResult());
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Get the fSaveable that provides the save behavior for this compare editor
+ * input. The {@link #createSaveable()} is called to create the fSaveable if
+ * it does not yet exist. This method cannot be called until after the input
+ * is prepared (i.e. until after the {@link #run(IProgressMonitor)} method
+ * is called which will in turn will invoke
+ * {@link #prepareCompareInput(IProgressMonitor)}.
+ *
+ * @return fSaveable that provides the save behavior for this compare editor
+ * input.
+ */
+ public LocalFileSaveable getSaveable() {
+ if (saveable == null) {
+ Assert.isNotNull(getCompareResult());
+ saveable = new LocalFileSaveable(getCompareResult(), this, left);
+ }
+ return saveable;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.ISaveablesSource#getActiveSaveables()
+ */
+ @Override
+ public Saveable[] getActiveSaveables() {
+ if (getCompareResult() == null)
+ return new Saveable[0];
+ return new Saveable[] { getSaveable() };
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.ISaveablesSource#getSaveables()
+ */
+ @Override
+ public Saveable[] getSaveables() {
+ return getActiveSaveables();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#addCompareInputChangeListener(org.eclipse.compare.structuremergeviewer.ICompareInput, org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener)
+ */
+ @Override
+ public void addCompareInputChangeListener(ICompareInput input,
+ ICompareInputChangeListener listener) {
+ if (input == getCompareResult()) {
+ inputChangeListeners.add(listener);
+ } else {
+ super.addCompareInputChangeListener(input, listener);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#removeCompareInputChangeListener(org.eclipse.compare.structuremergeviewer.ICompareInput, org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener)
+ */
+ @Override
+ public void removeCompareInputChangeListener(ICompareInput input,
+ ICompareInputChangeListener listener) {
+ if (input == getCompareResult()) {
+ inputChangeListeners.remove(listener);
+ } else {
+ super.removeCompareInputChangeListener(input, listener);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#getTitleImage()
+ */
+ @Override
+ public Image getTitleImage() {
+ return UIPlugin.getImage(ImageConsts.COMPARE_EDITOR);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#getImageDescriptor()
+ */
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ return UIPlugin.getImageDescriptor(ImageConsts.COMPARE_EDITOR);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#findContentViewer(org.eclipse.jface.viewers.Viewer, org.eclipse.compare.structuremergeviewer.ICompareInput, org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public Viewer findContentViewer(Viewer oldViewer, ICompareInput input,
+ Composite parent) {
+ Viewer newViewer = super.findContentViewer(oldViewer, input, parent);
+ boolean isNewViewer = newViewer != oldViewer;
+ if (isNewViewer && newViewer instanceof IPropertyChangeNotifier && getCompareResult()!=null) {
+ // Register the model for change events if appropriate
+ final IPropertyChangeNotifier dsp = (IPropertyChangeNotifier) newViewer;
+ dsp.addPropertyChangeListener(getSaveable());
+ Control c = newViewer.getControl();
+ c.addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ dsp.removePropertyChangeListener(getSaveable());
+ }
+ });
+ }
+ return newViewer;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#canRunAsJob()
+ */
+ @Override
+ public boolean canRunAsJob() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.CompareEditorInput#isDirty()
+ */
+ @Override
+ public boolean isDirty() {
+ if (saveable != null)
+ return saveable.isDirty();
+ return super.isDirty();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener#compareInputChanged(org.eclipse.compare.structuremergeviewer.ICompareInput)
+ */
+ @Override
+ public void compareInputChanged(ICompareInput source) {
+ if (source == getCompareResult()) {
+ boolean closed = false;
+ if (source.getKind() == Differencer.NO_CHANGE) {
+ closed = closeEditor(true);
+ }
+ if (!closed) {
+ // The editor was closed either because the compare
+ // input still has changes or because the editor input
+ // is dirty. In either case, fire the changes
+ // to the registered listeners
+ propogateInputChange();
+ }
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeInput.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeInput.java
new file mode 100644
index 000000000..912b777ee
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeInput.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare;
+
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * An abstract compare input whose purpose is to support change notification
+ * through a {@link CompareInputChangeNotifier}.
+ */
+public class MergeInput implements ICompareInput {
+
+ // The left element.
+ private ITypedElement left;
+ // The right element.
+ private ITypedElement right;
+ // The compare input change listener list.
+ private final ListenerList listeners = new ListenerList(ListenerList.IDENTITY);
+
+ /**
+ * Create a <code>MergeInput</code>.
+ * @param left the left element.
+ * @param right the right element.
+ */
+ public MergeInput(ITypedElement left, ITypedElement right) {
+ this.left = left;
+ this.right = right;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInput#addCompareInputChangeListener(org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener)
+ */
+ @Override
+ public void addCompareInputChangeListener(ICompareInputChangeListener listener) {
+ listeners.add(listener);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInput#removeCompareInputChangeListener(org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener)
+ */
+ @Override
+ public void removeCompareInputChangeListener(ICompareInputChangeListener listener) {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Fire a compare input change event. This method must be called from the UI
+ * thread.
+ */
+ void fireInputChanged() {
+ if (!listeners.isEmpty()) {
+ Object[] _listeners = listeners.getListeners();
+ for (int i = 0; i < _listeners.length; i++) {
+ final ICompareInputChangeListener listener = (ICompareInputChangeListener) _listeners[i];
+ SafeRunner.run(new SafeRunnable() {
+ @Override
+ public void handleException(Throwable e) {
+ // Ignore exception
+ }
+ @Override
+ public void run() throws Exception {
+ listener.compareInputChanged(MergeInput.this);
+ }
+ });
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInput#copy(boolean)
+ */
+ @Override
+ public void copy(boolean leftToRight) {
+ Assert.isTrue(false, Messages.MergeInput_CopyNotSupported);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInput#getAncestor()
+ */
+ @Override
+ public ITypedElement getAncestor() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInput#getImage()
+ */
+ @Override
+ public Image getImage() {
+ ITypedElement element = getMainElement();
+ return element == null ? null : element.getImage();
+ }
+
+ /**
+ * Return the main non-null element that identifies this input. By default,
+ * the fLeft is returned if non-null. If the fLeft is null, the fRight is
+ * returned. If both the fLeft and fRight are null the ancestor is returned.
+ *
+ * @return the main non-null element that identifies this input
+ */
+ private ITypedElement getMainElement() {
+ if (left != null)
+ return left;
+ if (right != null)
+ return right;
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInput#getKind()
+ */
+ @Override
+ public int getKind() {
+ return Differencer.CHANGE;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInput#getLeft()
+ */
+ @Override
+ public ITypedElement getLeft() {
+ return left;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInput#getName()
+ */
+ @Override
+ public String getName() {
+ ITypedElement element = getMainElement();
+ return element == null ? null : element.getName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.structuremergeviewer.ICompareInput#getRight()
+ */
+ @Override
+ public ITypedElement getRight() {
+ return right;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeTypedElement.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeTypedElement.java
new file mode 100644
index 000000000..37e96269d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/MergeTypedElement.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare;
+
+import org.eclipse.compare.BufferedContent;
+import org.eclipse.compare.CompareUI;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * A <code>MergeTypedElement</code> wraps an <code>FSTreeNode</code> so that it
+ * can be used as input for the differencing engine (<code>ITypedElement</code>).
+ */
+public abstract class MergeTypedElement extends BufferedContent implements ITypedElement {
+ // The File System tree node to be wrapped.
+ protected FSTreeNode node;
+
+ /**
+ * Create a MergeTypedElement for the given node.
+ *
+ * @param node
+ * The node.
+ */
+ public MergeTypedElement(FSTreeNode node) {
+ this.node = node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.ITypedElement#getImage()
+ */
+ @Override
+ public Image getImage() {
+ return CompareUI.getImage(getType());
+ }
+
+ /**
+ * Return the tree node wrapped.
+ *
+ * @return The tree node of the file
+ */
+ public FSTreeNode getFSTreeNode() {
+ return node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.ITypedElement#getType()
+ */
+ @Override
+ public String getType() {
+ if (node != null) {
+ if (node.isDirectory()) {
+ return ITypedElement.FOLDER_TYPE;
+ }
+ String s = node.name;
+ int dot = s.lastIndexOf('.');
+ if (dot != -1) s = s.substring(dot + 1);
+ return s;
+ }
+ return ITypedElement.UNKNOWN_TYPE;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof ITypedElement) {
+ return toString().equals(other.toString());
+ }
+ return super.equals(other);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.compare.ITypedElement#getName()
+ */
+ @Override
+ public String getName() {
+ return node.name;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ *
+ * Returns the hash code of the name.
+ */
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/RemoteTypedElement.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/RemoteTypedElement.java
new file mode 100644
index 000000000..b7e82c474
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/compare/RemoteTypedElement.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IOperation;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpOutStreamOp;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * A <code>RemoteTypedElement</code> wraps an <code>FSTreeNode</code> so that it
+ * can be used as input for the differencing engine (<code>ITypedElement</code>)
+ * as the right element of the comparison editor.
+ *
+ * @since 3.7
+ */
+public class RemoteTypedElement extends MergeTypedElement {
+ /**
+ * Creates a <code>RemoteTypedElement</code> for the given node.
+ *
+ * @param node
+ * the tree node.
+ */
+ public RemoteTypedElement(FSTreeNode node) {
+ super(node);
+ }
+
+ /**
+ * Return an input stream that opens that remote file to provide the stream
+ * content.
+ *
+ * @return a buffered input stream containing the contents of this file
+ * @exception CoreException
+ * if the contents of this storage could not be accessed
+ */
+ @Override
+ protected InputStream createStream() throws CoreException {
+ try {
+ return node.getLocationURL().openStream();
+ } catch (IOException e) {
+ Status error = new Status(IStatus.ERROR,
+ UIPlugin.getUniqueIdentifier(), e.getMessage(), e);
+ throw new CoreException(error);
+ }
+ }
+
+ /**
+ * Download the remote file and save the content so that it is cached for
+ * getContents call.
+ *
+ * @param monitor
+ * The monitor used to display downloading progress.
+ * @throws InvocationTargetException
+ * throws when an exception occurs during downloading.
+ * InterruptedException
+ * throws when the loading process is canceled.
+ */
+ public void cacheContents(IProgressMonitor monitor)
+ throws InvocationTargetException, InterruptedException {
+ monitor.beginTask(NLS.bind(Messages.RemoteTypedElement_DowloadingFile, node.name), 100);
+ OutputStream output = null;
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ output = new BufferedOutputStream(baos);
+ monitor.beginTask(Messages.RemoteTypedElement_GettingRemoteContent + node.name, 100);
+ IOperation operation = new OpOutStreamOp(node, output);
+ operation.run(monitor);
+ if (!monitor.isCanceled()) {
+ setContent(baos.toByteArray());
+ }
+ }
+
+ /**
+ * Return the external form of the URL to the remote file of this node. It
+ * is used to compute its hash code and as the title of the comparison
+ * editor.
+ */
+ @Override
+ public String toString() {
+ return node.getLocationURI().toString();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/decorators/PhantomDecorator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/decorators/PhantomDecorator.java
new file mode 100644
index 000000000..8247ef500
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/decorators/PhantomDecorator.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.decorators;
+
+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.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.jface.images.AbstractImageDescriptor;
+/**
+ * The label decorator to decorate the FSTreeNodes that are cut or hidden.
+ */
+public class PhantomDecorator 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 PhantomImageDescriptor(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.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/decorators/PhantomImageDescriptor.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/decorators/PhantomImageDescriptor.java
new file mode 100644
index 000000000..1200daf7b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/decorators/PhantomImageDescriptor.java
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.decorators;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.jface.images.AbstractImageDescriptor;
+
+/**
+ * The descriptor for a phantom-like image.
+ */
+public class PhantomImageDescriptor extends AbstractImageDescriptor {
+ // The alpha data when highlight the base image.
+ private static final int HIGHLIGHT_ALPHA = 127;
+ // 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 PhantomImageDescriptor(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) {
+ ImageData baseData = baseImage.getImageData();
+ PaletteData palette = new PaletteData(new RGB[]{new RGB(255, 255, 255), new RGB(0,0,0)});
+ ImageData imageData = new ImageData(baseData.width, baseData.height, 1, palette);
+ // Get the base image's transparency mask.
+ imageData.alphaData = createAlphaData();
+ maskImage = new Image(baseImage.getDevice(), imageData);
+ UIPlugin.getDefault().getImageRegistry().put(maskKey, maskImage);
+ }
+ return maskImage;
+ }
+
+ /**
+ * Create the alpha data that will be used in the mask image data.
+ *
+ * @return The alpha data.
+ */
+ private byte[] createAlphaData() {
+ ImageData imageData = baseImage.getImageData();
+ if (imageData.maskData != null) {
+ if (imageData.depth == 32) {
+ return maskAlpha32();
+ }
+ return maskAlpha();
+ }
+ return nonMaskAlpha();
+ }
+
+ /**
+ * Create the alpha data for the base image that has no mask data.
+ *
+ * @return The alpha data.
+ */
+ private byte[] nonMaskAlpha() {
+ ImageData imageData = baseImage.getImageData();
+ Assert.isTrue(imageData.maskData == null);
+
+ byte[] alphaData = new byte[imageData.width * imageData.height];
+ int i = 0;
+ for (int y = 0; y < imageData.height; y++) {
+ for (int x = 0; x < imageData.width; x++) {
+ int pixel = imageData.getPixel(x, y);
+ int alpha = 255;
+ if (imageData.transparentPixel != -1 && imageData.transparentPixel == pixel) {
+ // If it has a transparent pixel and the current pixel is the transparent.
+ alpha = 0;
+ }
+ else if (imageData.alpha != -1) {
+ // If it has a global alpha value.
+ alpha = imageData.alpha;
+ }
+ else if (imageData.alphaData != null) {
+ // If it has alpha data.
+ alpha = imageData.getAlpha(x, y);
+ }
+ alphaData[i++] = (byte) (alpha * HIGHLIGHT_ALPHA / 255);
+ }
+ }
+ return alphaData;
+ }
+
+ /**
+ * Create the alpha data for the base image that has mask data, and the color depth is not of
+ * 32-bit.
+ *
+ * @return The alpha data
+ */
+ private byte[] maskAlpha() {
+ ImageData imageData = baseImage.getImageData();
+ Assert.isTrue(imageData.maskData != null && imageData.depth != 32);
+
+ ImageData mask = imageData.getTransparencyMask();
+ // Get the black index.
+ int blackIndex = getBlackIndex(mask);
+ byte[] alphaData = new byte[imageData.width * imageData.height];
+ int i = 0;
+ for (int y = 0; y < imageData.height; y++) {
+ for (int x = 0; x < imageData.width; x++) {
+ int alpha = mask.getPixel(x, y) == blackIndex ? 0 : 255;
+ alphaData[i++] = (byte) (alpha * HIGHLIGHT_ALPHA / 255);
+ }
+ }
+ return alphaData;
+ }
+
+ /**
+ * Create the alpha data for the base image that has mask data and the color depth is of 32-bit.
+ *
+ * @return The alpha data.
+ */
+ private byte[] maskAlpha32() {
+ ImageData imageData = baseImage.getImageData();
+ Assert.isTrue(imageData.maskData != null && imageData.depth == 32);
+
+ ImageData mask = imageData.getTransparencyMask();
+ // Get the black index.
+ int blackIndex = getBlackIndex(mask);
+ // Calculate the alpha mask and the alpha shift.
+ int alphaMask = ~(imageData.palette.redMask | imageData.palette.greenMask | imageData.palette.blueMask);
+ int alphaShift = 0;
+ while (alphaMask != 0 && ((alphaMask >>> alphaShift) & 1) == 0)
+ alphaShift++;
+ byte[] alphaData = new byte[imageData.width * imageData.height];
+ int i = 0;
+ for (int y = 0; y < imageData.height; y++) {
+ for (int x = 0; x < imageData.width; x++) {
+ int pixel = imageData.getPixel(x, y);
+ int alpha = (pixel & alphaMask) >>> alphaShift;
+ if (alpha <= 0 || alpha > 255) {
+ // If the alpha value is illegal, try to get it from the mask data.
+ alpha = mask.getPixel(x, y) == blackIndex ? 0 : 255;
+ }
+ alphaData[i++] = (byte) (alpha * HIGHLIGHT_ALPHA / 255);
+ }
+ }
+ return alphaData;
+ }
+
+ /**
+ * Get the black index from the palette of the mask data.
+ *
+ * @param mask
+ * @return
+ */
+ private int getBlackIndex(ImageData mask) {
+ RGB[] rgbs = mask.getRGBs();
+ if (rgbs != null) {
+ for (int i = 0; i < rgbs.length; i++) {
+ RGB rgb = rgbs[i];
+ if (rgb.red == 0 && rgb.green == 0 && rgb.blue == 0) {
+ return i;
+ }
+ }
+ }
+ return 0;
+ }
+
+ /*
+ * (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;
+ }
+} \ No newline at end of file
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/CommonDnD.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/CommonDnD.java
new file mode 100644
index 000000000..2a3d832de
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/CommonDnD.java
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal.dnd;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.runtime.callback.Callback;
+import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IConfirmCallback;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IOperation;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.runtime.IRuntimeModel;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.JobExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCopy;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpMove;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpRefresh;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpUpload;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.CacheManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.ModelManager;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers.MoveCopyCallback;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.ui.PlatformUI;
+/**
+ * Common DnD operations shared by File Explorer and Target Explorer.
+ */
+public class CommonDnD implements IConfirmCallback {
+
+ /**
+ * If the current selection is draggable.
+ *
+ * @param selection The currently selected nodes.
+ * @return true if it is draggable.
+ */
+ public 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;
+ }
+
+ /**
+ * Perform the drop operation over dragged files to the specified target folder.
+ *
+ * @param viewer the tree viewer to be refreshed after dragging.
+ * @param files The files being dropped.
+ * @param operations the current dnd operations.
+ * @param target the target folder the files to be dropped to.
+ * @return true if the dropping is successful.
+ */
+ public boolean dropFiles(TreeViewer viewer, String[] files, int operations, FSTreeNode target) {
+ IOpExecutor executor = null;
+ if ((operations & DND.DROP_MOVE) != 0) {
+ String question;
+ if (files.length == 1) {
+ question = NLS.bind(Messages.FSDropTargetListener_MovingWarningSingle, files[0]);
+ }
+ else {
+ question = NLS.bind(Messages.FSDropTargetListener_MovingWarningMultiple, Integer.valueOf(files.length));
+ }
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ if (MessageDialog.openQuestion(parent, Messages.FSDropTargetListener_ConfirmMoveTitle, question)) {
+ ICallback callback = getMoveCallback(viewer, files, target);
+ executor = new UiExecutor(callback);
+ }
+ }
+ else if ((operations & DND.DROP_COPY) != 0) {
+ ICallback callback = getCopyCallback(viewer, files, target);
+ executor = new UiExecutor(callback);
+ }
+ if (executor != null) {
+ IStatus status = executor.execute(new OpUpload(files, target, this));
+ return status != null && status.isOK();
+ }
+ return false;
+ }
+
+ /**
+ * Get the callback that refresh and select the files being dragged when the dragging gesture is
+ * copying.
+ *
+ * @param viewer the tree viewer to be refreshed after dragging.
+ * @param files The files being dragged.
+ * @param target The target folder to drag the files to.
+ * @return callback that handles refreshing and selection.
+ */
+ private ICallback getCopyCallback(final TreeViewer viewer, final String[] files, final FSTreeNode target) {
+ return new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ if (status.isOK()) {
+ IOpExecutor executor = new JobExecutor(getSelectionCallback(viewer, files, target));
+ executor.execute(new OpRefresh(target));
+ }
+ }
+ };
+ }
+
+ /**
+ * Get the callback that delete the dragged source files, refresh and select the files being
+ * dragged when the dragging gesture is moving.
+ *
+ * @param viewer the tree viewer to be refreshed after dragging.
+ * @param files The files being dragged.
+ * @param target The target folder to drag the files to.
+ * @return callback that handles deletion, refreshing and selection.
+ */
+ private ICallback getMoveCallback(final TreeViewer viewer, final String[] files, final FSTreeNode target) {
+ return new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ if (status.isOK()) {
+ boolean successful = true;
+ for (String path : files) {
+ File file = new File(path);
+ successful &= file.delete();
+ }
+ if (successful) {
+ IRuntimeModel model = ModelManager.getRuntimeModel(target.peerNode);
+ IOpExecutor executor = new JobExecutor(getSelectionCallback(viewer, files, target));
+ executor.execute(new OpRefresh(model.getRoot()));
+ }
+ }
+ }
+ };
+ }
+
+ /**
+ * Get the callback that refresh the files being dragged after moving or copying.
+ *
+ * @param viewer the tree viewer to be refreshed after dragging.
+ * @param paths The paths of the files being dragged.
+ * @param target The target folder to drag the files to.
+ * @return callback that handles refreshing and selection.
+ */
+ ICallback getSelectionCallback(final TreeViewer viewer, final String[] paths, final FSTreeNode target) {
+ return new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ if(status.isOK()) {
+ List<FSTreeNode> nodes = new ArrayList<FSTreeNode>();
+ List<FSTreeNode> children = target.getChildren();
+ for (String path : paths) {
+ File file = new File(path);
+ String name = file.getName();
+ for (FSTreeNode child : children) {
+ if (name.equals(child.name)) {
+ nodes.add(child);
+ break;
+ }
+ }
+ }
+ if (viewer != null) {
+ updateViewer(viewer, target, nodes);
+ }
+ }
+ }
+ };
+ }
+
+ /**
+ * Update the tree viewer after DnD and select the nodes that being dropped.
+ *
+ * @param viewer The tree viewer in which the DnD takes place.
+ * @param target The target node that the drop operation happens.
+ * @param nodes The nodes that are being dropped.
+ */
+ protected void updateViewer(final TreeViewer viewer, final FSTreeNode target, final List<FSTreeNode> nodes) {
+ if (Display.getCurrent() != null) {
+ viewer.refresh(target);
+ IStructuredSelection selection = new StructuredSelection(nodes.toArray());
+ viewer.setSelection(selection, true);
+ }
+ else {
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable(){
+ @Override
+ public void run() {
+ updateViewer(viewer, target, nodes);
+ }});
+ }
+ }
+
+ /**
+ * Perform the drop operation over dragged selection.
+ *
+ * @param aTarget the target Object to be moved to.
+ * @param operations the current dnd operations.
+ * @param selection The local selection being dropped.
+ * @return true if the dropping is successful.
+ */
+ public boolean dropLocalSelection(FSTreeNode target, int operations, IStructuredSelection selection) {
+ List<FSTreeNode> nodes = selection.toList();
+ IOpExecutor executor = null;
+ IOperation operation = null;
+ if ((operations & DND.DROP_MOVE) != 0) {
+ operation = new OpMove(nodes, target, new MoveCopyCallback());
+ executor = new UiExecutor(new Callback(){
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ UIPlugin.getClipboard().clear();
+ }
+ });
+ }
+ else if ((operations & DND.DROP_COPY) != 0) {
+ FSTreeNode dest = getCopyDestination(target, nodes);
+ boolean cpPerm = UIPlugin.isCopyPermission();
+ boolean cpOwn = UIPlugin.isCopyOwnership();
+ operation = new OpCopy(nodes, dest, cpPerm, cpOwn, new MoveCopyCallback());
+ executor = new UiExecutor();
+ }
+ if (operation != null && executor != null) {
+ IStatus status = executor.execute(operation);
+ return status != null && status.isOK();
+ }
+ return false;
+ }
+
+ /**
+ * Return an appropriate destination directory for copying according to the specified hovered
+ * node. If the hovered node is a file, then return its parent directory. If the hovered node is
+ * a directory, then return its self if it is not a node being copied. Return its parent
+ * directory if it is a node being copied.
+ *
+ * @param hovered
+ * @param nodes
+ * @return
+ */
+ private FSTreeNode getCopyDestination(FSTreeNode hovered, List<FSTreeNode> nodes) {
+ if (hovered.isFile()) {
+ return hovered.getParent();
+ }
+ else if (hovered.isDirectory()) {
+ for (FSTreeNode node : nodes) {
+ if (node == hovered) {
+ return hovered.getParent();
+ }
+ }
+ }
+ return hovered;
+ }
+
+ /**
+ * Validate dropping when the elements being dragged are files.
+ *
+ * @param target The target object.
+ * @param operation The DnD operation.
+ * @param transferType The transfered data simulator.
+ * @return true if it is valid for dropping.
+ */
+ public boolean validateFilesDrop(Object target, int operation, TransferData transferType) {
+ FileTransfer transfer = FileTransfer.getInstance();
+ String[] elements = (String[]) transfer.nativeToJava(transferType);
+ if (elements.length > 0) {
+ boolean moving = (operation & DND.DROP_MOVE) != 0;
+ boolean copying = (operation & DND.DROP_COPY) != 0;
+ FSTreeNode hovered = (FSTreeNode) target;
+ if (hovered.isFile() && copying) {
+ hovered = hovered.getParent();
+ }
+ return hovered.isDirectory() && hovered.isWritable() && (moving || copying);
+ }
+ return false;
+ }
+
+ /**
+ * Validate dropping when the elements being dragged are local selection.
+ *
+ * @param target The target object.
+ * @param operation The DnD operation.
+ * @param transferType The transfered data simulator.
+ * @return true if it is valid for dropping.
+ */
+ public boolean validateLocalSelectionDrop(Object target, int operation, TransferData transferType) {
+ FSTreeNode hovered = (FSTreeNode) target;
+ LocalSelectionTransfer transfer = LocalSelectionTransfer.getTransfer();
+ IStructuredSelection selection = (IStructuredSelection) transfer.getSelection();
+ List<FSTreeNode> nodes = selection.toList();
+ boolean moving = (operation & DND.DROP_MOVE) != 0;
+ boolean copying = (operation & DND.DROP_COPY) != 0;
+ if (hovered.isDirectory() && hovered.isWritable() && (moving || copying)) {
+ FSTreeNode head = nodes.get(0);
+ String hid = head.peerNode.getPeerId();
+ String tid = hovered.peerNode.getPeerId();
+ if (hid.equals(tid)) {
+ for (FSTreeNode node : nodes) {
+ if (moving && node == hovered || node.isAncestorOf(hovered)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ else if (hovered.isFile() && copying) {
+ hovered = hovered.getParent();
+ return validateLocalSelectionDrop(hovered, operation, transferType);
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.interfaces.IConfirmCallback#requires(java.lang.Object)
+ */
+ @Override
+ public boolean requires(Object object) {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.interfaces.IConfirmCallback#confirms(java.lang.Object)
+ */
+ @Override
+ public int confirms(Object object) {
+ final int[] results = new int[1];
+ final File file = (File) object;
+ Display display = PlatformUI.getWorkbench().getDisplay();
+ display.syncExec(new Runnable() {
+ @Override
+ public void run() {
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ String title = Messages.FSUpload_OverwriteTitle;
+ String message = NLS.bind(Messages.FSUpload_OverwriteConfirmation, file.getName());
+ final Image titleImage = UIPlugin.getImage(ImageConsts.DELETE_READONLY_CONFIRM);
+ MessageDialog qDialog = new MessageDialog(parent, title, null, message,
+ MessageDialog.QUESTION, new String[] {Messages.FSUpload_Yes,
+ Messages.FSUpload_YesToAll, Messages.FSUpload_No, Messages.FSUpload_Cancel}, 0) {
+ @Override
+ public Image getQuestionImage() {
+ return titleImage;
+ }
+ };
+ results[0] = qDialog.open();
+ }
+ });
+ return results[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.dnd.DragSourceListener#dragSetData(org.eclipse.swt.dnd.DragSourceEvent)
+ */
+ public boolean setDragData(DragSourceEvent anEvent) {
+ if (LocalSelectionTransfer.getTransfer().isSupportedType(anEvent.dataType)) {
+ anEvent.data = LocalSelectionTransfer.getTransfer().getSelection();
+ return true;
+ }
+ else if (FileTransfer.getInstance().isSupportedType(anEvent.dataType)) {
+ IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection();
+ List<FSTreeNode> nodes = selection.toList();
+ List<String> paths = new ArrayList<String>();
+ for(FSTreeNode node : nodes) {
+ File file = CacheManager.getCacheFile(node);
+ if(file.exists()) {
+ paths.add(file.getAbsolutePath());
+ }
+ }
+ if (!paths.isEmpty()) anEvent.data = paths.toArray(new String[paths.size()]);
+ return !paths.isEmpty();
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDragAdapterAssistant.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDragAdapterAssistant.java
new file mode 100644
index 000000000..aaffe7f23
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDragAdapterAssistant.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.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.FileTransfer;
+import org.eclipse.swt.dnd.Transfer;
+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 {
+ // The common dnd operation
+ CommonDnD dnd;
+
+ /**
+ * Create an instance.
+ */
+ public FSDragAdapterAssistant() {
+ dnd = new CommonDnD();
+ }
+
+ /*
+ * (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 = dnd.isDraggable(aSelection);
+ LocalSelectionTransfer.getTransfer().setSelection(aSelection);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonDragAdapterAssistant#getSupportedTransferTypes()
+ */
+ @Override
+ public Transfer[] getSupportedTransferTypes() {
+ return new Transfer[] {FileTransfer.getInstance()};
+ }
+
+ /*
+ * (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 dnd.setDragData(anEvent);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDragSourceListener.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDragSourceListener.java
new file mode 100644
index 000000000..e3854474b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDragSourceListener.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.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;
+
+/**
+ * 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;
+ // The common dnd operation
+ CommonDnD dnd;
+
+ /**
+ * Create an FSDragSourceListener using the specified tree viewer.
+ *
+ * @param viewer The file system tree viewer.
+ */
+ public FSDragSourceListener(TreeViewer viewer) {
+ this.viewer = viewer;
+ dnd = new CommonDnD();
+ }
+
+ /*
+ * (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 = dnd.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) {
+ event.doit = dnd.setDragData(event);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.swt.dnd.DragSourceListener#dragFinished(org.eclipse.swt.dnd.DragSourceEvent)
+ */
+ @Override
+ public void dragFinished(DragSourceEvent event) {
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDropAdapterAssistant.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDropAdapterAssistant.java
new file mode 100644
index 000000000..d3ab481cb
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDropAdapterAssistant.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.dnd;
+
+import org.eclipse.core.runtime.Assert;
+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.jface.viewers.TreeViewer;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.ui.views.interfaces.IUIConstants;
+import org.eclipse.ui.IViewReference;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.CommonDropAdapter;
+import org.eclipse.ui.navigator.CommonDropAdapterAssistant;
+import org.eclipse.ui.navigator.CommonNavigator;
+
+/**
+ * The drop assistant used by Target Explorer to extend its DnD support to FSTreeNode elements.
+ */
+public class FSDropAdapterAssistant extends CommonDropAdapterAssistant {
+ // The common dnd operation
+ CommonDnD dnd;
+
+ /**
+ * Create an instance.
+ */
+ public FSDropAdapterAssistant() {
+ dnd = new CommonDnD();
+ }
+
+ /*
+ * (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) {
+ boolean valid = false;
+ if (target instanceof FSTreeNode) {
+ if (LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) {
+ valid = dnd.validateLocalSelectionDrop(target, operation, transferType);
+ }
+ else if(FileTransfer.getInstance().isSupportedType(transferType)) {
+ valid = dnd.validateFilesDrop(target, operation, transferType);
+ }
+ }
+ return valid ? Status.OK_STATUS : Status.CANCEL_STATUS;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#isSupportedType(org.eclipse.swt.dnd.TransferData)
+ */
+ @Override
+ public boolean isSupportedType(TransferData aTransferType) {
+ if(FileTransfer.getInstance().isSupportedType(aTransferType))
+ return true;
+ return super.isSupportedType(aTransferType);
+ }
+
+ /*
+ * (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) {
+ boolean sucess = false;
+ TransferData transferType = aDropTargetEvent.currentDataType;
+ if (LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) {
+ IStructuredSelection selection = (IStructuredSelection) aDropTargetEvent.data;
+ int operations = aDropAdapter.getCurrentOperation();
+ FSTreeNode target = (FSTreeNode) aTarget;
+ sucess = dnd.dropLocalSelection(target, operations, selection);
+ }
+ else if(FileTransfer.getInstance().isSupportedType(transferType)) {
+ String[] files = (String[]) aDropTargetEvent.data;
+ int operations = aDropAdapter.getCurrentOperation();
+ FSTreeNode target = (FSTreeNode) aTarget;
+ sucess = dnd.dropFiles(getCommonViewer(), files, operations, target);
+ }
+ return sucess ? Status.OK_STATUS : Status.CANCEL_STATUS;
+ }
+
+ /**
+ * Get the tree viewer of Target Explorer view.
+ *
+ * @return The tree viewer of Target Explorer view or null if the view is not found.
+ */
+ private TreeViewer getCommonViewer() {
+ Assert.isNotNull(Display.getCurrent());
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ Assert.isNotNull(window);
+ IViewReference[] references = window.getActivePage().getViewReferences();
+ for(IViewReference reference : references) {
+ if(reference.getId().equals(IUIConstants.ID_EXPLORER)) {
+ CommonNavigator navigator = (CommonNavigator) reference.getPart(true);
+ return navigator.getCommonViewer();
+ }
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDropTargetListener.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDropTargetListener.java
new file mode 100644
index 000000000..be8185fd0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/dnd/FSDropTargetListener.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.dnd;
+
+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.DropTargetEvent;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The drop target listener for the file tree of Target Explorer.
+ */
+public class FSDropTargetListener extends ViewerDropAdapter {
+ // The tree viewer that the drop listener attached to.
+ TreeViewer viewer;
+ // The common dnd operation
+ CommonDnD dnd;
+ /**
+ * Create FSDropTargetListener using the viewer.
+ *
+ * @param viewer The file system tree viewer.
+ */
+ public FSDropTargetListener(TreeViewer viewer) {
+ super(viewer);
+ this.viewer = viewer;
+ dnd = new CommonDnD();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerDropAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
+ */
+ @Override
+ public void dragEnter(DropTargetEvent event) {
+ if (FileTransfer.getInstance().isSupportedType(event.currentDataType)) {
+ // Force the operation of file transfer from external application to DROP_COPY
+ event.detail = DND.DROP_COPY;
+ }
+ super.dragEnter(event);
+ }
+
+ /*
+ * (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) {
+ if (target instanceof FSTreeNode) {
+ if (LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) {
+ return dnd.validateLocalSelectionDrop(target, operation, transferType);
+ }
+ else if (FileTransfer.getInstance().isSupportedType(transferType)) {
+ return dnd.validateFilesDrop(target, operation, transferType);
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerDropAdapter#performDrop(java.lang.Object)
+ */
+ @Override
+ public boolean performDrop(Object data) {
+ boolean success = false;
+ TransferData transferType = getCurrentEvent().currentDataType;
+ if (LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) {
+ IStructuredSelection selection = (IStructuredSelection) data;
+ int operations = getCurrentOperation();
+ FSTreeNode target = (FSTreeNode) getCurrentTarget();
+ success = dnd.dropLocalSelection(target, operations, selection);
+ }
+ else if(FileTransfer.getInstance().isSupportedType(transferType)) {
+ String[] files = (String[]) data;
+ int operations = getCurrentOperation();
+ FSTreeNode target = (FSTreeNode) getCurrentTarget();
+ success = dnd.dropFiles(viewer, files, operations, target);
+ }
+ return success;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CommitHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CommitHandler.java
new file mode 100644
index 000000000..924ba72f0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CommitHandler.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers;
+
+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.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpUpload;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * The handler that commits the content of a modified file to the target file system.
+ */
+public class CommitHandler 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.getCurrentSelectionChecked(event);
+ FSTreeNode node = (FSTreeNode) selection.getFirstElement();
+ IOpExecutor executor = new UiExecutor();
+ executor.execute(new OpUpload(node));
+ return null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CopyFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CopyFilesHandler.java
new file mode 100644
index 000000000..663cf903d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CopyFilesHandler.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.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.viewers.IStructuredSelection;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpClipboard;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+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 {
+ OpClipboard cb = UIPlugin.getClipboard();
+ IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelection(event);
+ if (!selection.isEmpty()) {
+ List<FSTreeNode> nodes = selection.toList();
+ // Copy these files to the clip board.
+ cb.copyFiles(nodes);
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CutFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CutFilesHandler.java
new file mode 100644
index 000000000..cbca9c47e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/CutFilesHandler.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.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.viewers.IStructuredSelection;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpClipboard;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+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 {
+ OpClipboard cb = UIPlugin.getClipboard();
+ IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelection(event);
+ if (!selection.isEmpty()) {
+ List<FSTreeNode> nodes = selection.toList();
+ // Cut these files to the clip board.
+ cb.cutFiles(nodes);
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/DeleteHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/DeleteHandler.java
new file mode 100644
index 000000000..2cf79b44c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/DeleteHandler.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.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.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+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.core.interfaces.IConfirmCallback;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpDelete;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Delete handler implementation.
+ */
+public class DeleteHandler extends AbstractHandler {
+ // The confirmation call for read only files.
+ private IConfirmCallback readonlyCallback = new ReadOnlyConfirmCallback();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // Get the current selection
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ List<FSTreeNode> nodes = ((IStructuredSelection)selection).toList();
+ if(confirmDeletion(nodes)) {
+ IOpExecutor executor = new UiExecutor();
+ executor.execute(new OpDelete(nodes, readonlyCallback));
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Confirm the deletion of the specified nodes.
+ *
+ * @param nodes The nodes to be deleted.
+ * @return true if the user agrees to delete.
+ */
+ private boolean confirmDeletion(List<FSTreeNode> nodes) {
+ 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 = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ if (MessageDialog.openQuestion(parent, Messages.DeleteFilesHandler_ConfirmDialogTitle, question)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * The callback implementation for the user to confirm the deletion of
+ * a read-only file/folder.
+ */
+ static class ReadOnlyConfirmCallback implements IConfirmCallback {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IConfirmCallback#requires(java.lang.Object)
+ */
+ @Override
+ public boolean requires(Object object) {
+ if(object instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) object;
+ return node.isWindowsNode() && node.isReadOnly() || !node.isWindowsNode() && !node.isWritable();
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IConfirmCallback#confirms(java.lang.Object)
+ */
+ @Override
+ public int confirms(Object object) {
+ final FSTreeNode node = (FSTreeNode) object;
+ 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.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MergeHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MergeHandler.java
new file mode 100644
index 000000000..47287db7e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MergeHandler.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers;
+
+import org.eclipse.compare.CompareUI;
+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.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare.LocalTypedElement;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare.MergeEditorInput;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.compare.RemoteTypedElement;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * The handler used to merge a file which is conflicting with its remote file.
+ */
+public class MergeHandler 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.getCurrentSelectionChecked(event);
+ FSTreeNode node = (FSTreeNode) selection.getFirstElement();
+ LocalTypedElement local = new LocalTypedElement(node);
+ RemoteTypedElement remote = new RemoteTypedElement(node);
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ MergeEditorInput input = new MergeEditorInput(local, remote, page);
+ CompareUI.openCompareDialog(input);
+ return null;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MoveCopyCallback.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MoveCopyCallback.java
new file mode 100644
index 000000000..004628fbb
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MoveCopyCallback.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.internal.handlers;
+
+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.core.interfaces.IConfirmCallback;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * The confirmation callback implementation for operation "Move" and "Copy".
+ */
+public class MoveCopyCallback implements IConfirmCallback {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IConfirmCallback#requires(java.lang.Object)
+ */
+ @Override
+ public boolean requires(Object object) {
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IConfirmCallback#confirms(java.lang.Object)
+ */
+ @Override
+ public int confirms(Object object) {
+ final FSTreeNode node = (FSTreeNode) object;
+ 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();
+ }
+ });
+ return results[0];
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MoveFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MoveFilesHandler.java
new file mode 100644
index 000000000..d62a1d6b1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/MoveFilesHandler.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.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.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpMove;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.dialogs.FSFolderSelectionDialog;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+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();
+ IPeerNode 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;
+ IOpExecutor executor = new UiExecutor();
+ executor.execute(new OpMove(nodes, dest, new MoveCopyCallback()));
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewFileHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewFileHandler.java
new file mode 100644
index 000000000..5a02014a1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewFileHandler.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.handlers;
+
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.wizards.NewFileWizard;
+import org.eclipse.ui.IWorkbenchWizard;
+
+/**
+ * The handler to create a new file node in the file system of Target Explorer.
+ */
+public class NewFileHandler extends NewNodeHandler {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.handlers.NewNodeHandler#createWizard()
+ */
+ @Override
+ protected IWorkbenchWizard createWizard() {
+ return new NewFileWizard();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewFolderHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewFolderHandler.java
new file mode 100644
index 000000000..d8302f5f9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewFolderHandler.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.handlers;
+
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.wizards.NewFolderWizard;
+import org.eclipse.ui.IWorkbenchWizard;
+
+/**
+ * The handler to create a new folder node in the file system of Target Explorer.
+ */
+public class NewFolderHandler extends NewNodeHandler {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.handlers.NewNodeHandler#createWizard()
+ */
+ @Override
+ protected IWorkbenchWizard createWizard() {
+ return new NewFolderWizard();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewNodeHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewNodeHandler.java
new file mode 100644
index 000000000..332f6dbbf
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/NewNodeHandler.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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.tcf.filesystem.ui.internal.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWizard;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * The base handler to create a new file/folder node in the file system of Target Explorer.
+ */
+public abstract class NewNodeHandler extends AbstractHandler {
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ // In Eclipse 4.x, the HandlerUtil.getActiveWorkbenchWindow(event) may return null
+ IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
+ if (window == null) window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ IWorkbenchWizard wizard;
+ wizard = createWizard();
+ ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);
+ if (selection instanceof IStructuredSelection) {
+ wizard.init(PlatformUI.getWorkbench(), (IStructuredSelection) selection);
+ }
+ else {
+ wizard.init(PlatformUI.getWorkbench(), StructuredSelection.EMPTY);
+ }
+ Shell parent = window != null ? window.getShell() : null;
+ WizardDialog dialog = new WizardDialog(parent, wizard);
+ dialog.create();
+ dialog.open();
+ return null;
+ }
+
+ /**
+ * Create a "New" wizard to for creating a file/folder.
+ *
+ * @return the wizard to be used for creating a file/folder.
+ */
+ protected abstract IWorkbenchWizard createWizard();
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenFileHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenFileHandler.java
new file mode 100644
index 000000000..cb046f899
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenFileHandler.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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)- [345387]Open the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers;
+
+import java.io.File;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.runtime.callback.Callback;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCacheUpdate;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.CacheManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.ContentTypeHelper;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.PersistenceManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.CacheState;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.swt.DisplayUtil;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.ide.FileStoreEditorInput;
+import org.eclipse.ui.ide.IDE;
+
+/**
+ * The action handler to open a file on the remote file system.
+ */
+public class OpenFileHandler 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.getCurrentSelectionChecked(event);
+ final FSTreeNode node = (FSTreeNode) selection.getFirstElement();
+ final IWorkbenchPage page = HandlerUtil.getActiveSite(event).getPage();
+ if (ContentTypeHelper.isBinaryFile(node)) {
+ // If the file is a binary file.
+ Shell parent = HandlerUtil.getActiveShell(event);
+ MessageDialog.openWarning(parent, Messages.OpenFileHandler_Warning,
+ Messages.OpenFileHandler_OpeningBinaryNotSupported);
+ } else {
+ if (UIPlugin.isAutoSaving()) {
+ // Refresh the node to determine the cache state correctly
+ node.refresh(new Callback() {
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ File file = CacheManager.getCacheFile(node);
+ if (node.getCacheState() == CacheState.outdated) {
+ file.delete();
+ }
+
+ DisplayUtil.safeAsyncExec(new Runnable() {
+ @Override
+ public void run() {
+ // Open the file node.
+ openFile(node, page);
+ }
+ });
+ }
+ });
+ } else {
+ // Open the file node.
+ openFile(node, page);
+ }
+
+ }
+ return null;
+ }
+
+ /**
+ * Open the file node in an editor of the specified workbench page. If the
+ * local cache file of the node is stale, then download it. Then open its
+ * local cache file.
+ *
+ * @param node
+ * The file node to be opened.
+ * @param page
+ * The workbench page in which the editor is opened.
+ */
+ /* default */ void openFile(FSTreeNode node, IWorkbenchPage page) {
+ File file = CacheManager.getCacheFile(node);
+ if (!file.exists()) {
+ // If the file node's local cache does not exist yet, download it.
+ IOpExecutor executor = new UiExecutor();
+ IStatus status = executor.execute(new OpCacheUpdate(node));
+ if (!status.isOK()) {
+ return;
+ }
+ }
+ openEditor(page, node);
+ }
+
+ /**
+ * Open the editor to display the file node in the UI thread.
+ *
+ * @param page
+ * The workbench page in which the editor is opened.
+ * @param node
+ * The file node whose local cache file is opened.
+ */
+ private void openEditor(final IWorkbenchPage page, final FSTreeNode node) {
+ Display display = page.getWorkbenchWindow().getWorkbench().getDisplay();
+ display.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ IPath path = CacheManager.getCachePath(node);
+ IFileStore fileStore = EFS.getLocalFileSystem().getStore(path);
+ String editorID = PersistenceManager.getInstance().getPersistentProperties(node).get(IDE.EDITOR_KEY);
+ try {
+ if(editorID!=null){
+ FileStoreEditorInput input = new FileStoreEditorInput(fileStore);
+ page.openEditor(input, editorID, true, IWorkbenchPage.MATCH_INPUT|IWorkbenchPage.MATCH_ID);
+ }else{
+ IDE.openEditorOnFileStore(page, fileStore);
+ }
+ } catch (PartInitException e) {
+ }
+ }
+ });
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenWithContribution.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenWithContribution.java
new file mode 100644
index 000000000..aea1a5b3c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenWithContribution.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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) [360494]Provide an "Open With" action in the pop
+ * up menu of file system nodes of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers;
+
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.CompoundContributionItem;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.menus.IWorkbenchContribution;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * The dynamic contribution of "Open With" submenu items.
+ */
+public class OpenWithContribution extends CompoundContributionItem implements IWorkbenchContribution {
+ // Service locator to located the handler service.
+ private IServiceLocator serviceLocator;
+
+ /**
+ * Create the contribution instance.
+ */
+ public OpenWithContribution() {
+ }
+
+ /**
+ * Create the contribution instance with the specified id.
+ */
+ public OpenWithContribution(String id) {
+ super(id);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * org.eclipse.ui.menus.IWorkbenchContribution#initialize(org.eclipse.ui.services.IServiceLocator
+ * )
+ */
+ @Override
+ public void initialize(IServiceLocator serviceLocator) {
+ this.serviceLocator = serviceLocator;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.actions.CompoundContributionItem#getContributionItems()
+ */
+ @Override
+ protected IContributionItem[] getContributionItems() {
+ // Get the selected node.
+ IHandlerService service = (IHandlerService) this.serviceLocator
+ .getService(IHandlerService.class);
+ IEvaluationContext state = service.getCurrentState();
+ ISelection selection = (ISelection) state
+ .getVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME);
+ IStructuredSelection iss = (IStructuredSelection) selection;
+ Object obj = iss.getFirstElement();
+ Assert.isTrue(obj instanceof FSTreeNode);
+ FSTreeNode node = (FSTreeNode) obj;
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ return new IContributionItem[] { new OpenWithMenu(page, node) };
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenWithMenu.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenWithMenu.java
new file mode 100644
index 000000000..14c6679e1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/OpenWithMenu.java
@@ -0,0 +1,419 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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) [360494]Provide an "Open With" action in the pop
+ * up menu of file system nodes of Target Explorer.
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers;
+
+import java.io.File;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Map;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCacheUpdate;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.CacheManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.ContentTypeHelper;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.PersistenceManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.EditorSelectionDialog;
+import org.eclipse.ui.ide.FileStoreEditorInput;
+import org.eclipse.ui.ide.IDE;
+
+/**
+ * A menu for opening files in the target explorer.
+ * <p>
+ * An <code>OpenWithMenu</code> is used to populate a menu with "Open With" actions. One action is
+ * added for each editor which is applicable to the selected file. If the user selects one of these
+ * items, the corresponding editor is opened on the file.
+ * </p>
+ *
+ * @since 3.7 - Copied and modified based on org.eclipse.ui.actions.OpenWithMenu to avoid
+ * introducing org.eclipse.core.resources
+ */
+public class OpenWithMenu extends ContributionItem {
+ private static final String DEFAULT_TEXT_EDITOR = "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$
+
+ /**
+ * The id of this action.
+ */
+ public static final String ID = UIPlugin.getUniqueIdentifier() + ".OpenWithMenu";//$NON-NLS-1$
+
+ /*
+ * Compares the labels from two IEditorDescriptor objects
+ */
+ private static final Comparator<IEditorDescriptor> comparer = new Comparator<IEditorDescriptor>() {
+ private Collator collator = Collator.getInstance();
+
+ @Override
+ public int compare(IEditorDescriptor arg0, IEditorDescriptor arg1) {
+ String s1 = arg0.getLabel();
+ String s2 = arg1.getLabel();
+ return collator.compare(s1, s2);
+ }
+ };
+ // The selected tree node.
+ FSTreeNode node;
+ // The current workbench page.
+ IWorkbenchPage page;
+ // The editor registry.
+ IEditorRegistry registry;
+
+ /**
+ * Create an instance using the specified page and the specified FSTreeNode.
+ *
+ * @param page The page to open the editor.
+ * @param node The FSTreeNode to be opened.
+ */
+ public OpenWithMenu(IWorkbenchPage page, FSTreeNode node) {
+ super(ID);
+ this.node = node;
+ this.page = page;
+ this.registry = PlatformUI.getWorkbench().getEditorRegistry();
+ }
+
+ /**
+ * Returns an image to show for the corresponding editor descriptor.
+ *
+ * @param editorDesc the editor descriptor, or null for the system editor
+ * @return the image or null
+ */
+ private Image getImage(IEditorDescriptor editorDesc) {
+ ImageDescriptor imageDesc = getImageDescriptor(editorDesc);
+ if (imageDesc == null) {
+ return null;
+ }
+ return imageDesc.createImage();
+ }
+
+ /**
+ * Returns the image descriptor for the given editor descriptor, or null if it has no image.
+ */
+ private ImageDescriptor getImageDescriptor(IEditorDescriptor editorDesc) {
+ ImageDescriptor imageDesc = null;
+ if (editorDesc == null) {
+ imageDesc = registry.getImageDescriptor(node.name);
+ // TODO: is this case valid, and if so, what are the implications for content-simulator
+ // editor bindings?
+ }
+ else {
+ imageDesc = editorDesc.getImageDescriptor();
+ }
+ if (imageDesc == null) {
+ if (editorDesc != null && editorDesc.getId().equals(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID)) {
+ imageDesc = registry.getSystemExternalEditorImageDescriptor(node.name);
+ }
+ }
+ return imageDesc;
+ }
+
+ /**
+ * Creates the menu item for the editor descriptor.
+ *
+ * @param menu the menu to add the item to
+ * @param descriptor the editor descriptor, or null for the system editor
+ * @param preferredEditor the descriptor of the preferred editor, or <code>null</code>
+ */
+ private void createMenuItem(Menu menu, final IEditorDescriptor descriptor, final IEditorDescriptor preferredEditor) {
+ final MenuItem menuItem = new MenuItem(menu, SWT.RADIO);
+ boolean isPreferred = preferredEditor != null && descriptor.getId()
+ .equals(preferredEditor.getId());
+ menuItem.setSelection(isPreferred);
+ menuItem.setText(descriptor.getLabel());
+ Image image = getImage(descriptor);
+ if (image != null) {
+ menuItem.setImage(image);
+ }
+ Listener listener = new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ switch (event.type) {
+ case SWT.Selection:
+ if (menuItem.getSelection()) {
+ syncOpen(descriptor, false);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ };
+ menuItem.addListener(SWT.Selection, listener);
+ }
+
+ /**
+ * Creates the Other... menu item
+ *
+ * @param menu the menu to add the item to
+ */
+ @SuppressWarnings("unused")
+ private void createOtherMenuItem(final Menu menu) {
+ new MenuItem(menu, SWT.SEPARATOR);
+ final MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
+ menuItem.setText(Messages.OpenWithMenu_OpenWith);
+ Listener listener = new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ switch (event.type) {
+ case SWT.Selection:
+ EditorSelectionDialog dialog = new EditorSelectionDialog(menu.getShell());
+ dialog.setMessage(NLS
+ .bind(Messages.OpenWithMenu_ChooseEditorForOpening, node.name));
+ if (dialog.open() == Window.OK) {
+ IEditorDescriptor editor = dialog.getSelectedEditor();
+ if (editor != null) {
+ syncOpen(editor, editor.isOpenExternal());
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ };
+ menuItem.addListener(SWT.Selection, listener);
+ }
+
+ /**
+ * Get the default editor for this FSTreeNode.
+ *
+ * @return The descriptor of the default editor.
+ */
+ private IEditorDescriptor getDefaultEditor() {
+ // Try file specific editor.
+ try {
+ String editorID = PersistenceManager.getInstance().getPersistentProperties(node)
+ .get(IDE.EDITOR_KEY);
+ if (editorID != null) {
+ IEditorDescriptor desc = registry.findEditor(editorID);
+ if (desc != null) {
+ return desc;
+ }
+ }
+ }
+ catch (Exception e) {
+ // do nothing
+ }
+
+ IContentType contentType = null;
+ contentType = ContentTypeHelper.getContentType(node);
+ // Try lookup with filename
+ return registry.getDefaultEditor(node.name, contentType);
+ }
+
+ /*
+ * (non-Javadoc) Fills the menu with perspective items.
+ */
+ @SuppressWarnings("unused")
+ @Override
+ public void fill(Menu menu, int index) {
+
+ IEditorDescriptor defaultEditor = registry.findEditor(DEFAULT_TEXT_EDITOR);
+ IEditorDescriptor preferredEditor = getDefaultEditor();
+
+ IEditorDescriptor[] editors = registry.getEditors(node.name, ContentTypeHelper.getContentType(node));
+ Collections.sort(Arrays.asList(editors), comparer);
+
+ boolean defaultFound = false;
+
+ // Check that we don't add it twice. This is possible
+ // if the same editor goes to two mappings.
+ ArrayList<IEditorDescriptor> alreadyMapped = new ArrayList<IEditorDescriptor>();
+
+ for (int i = 0; i < editors.length; i++) {
+ IEditorDescriptor editor = editors[i];
+ if (!alreadyMapped.contains(editor)) {
+ createMenuItem(menu, editor, preferredEditor);
+ if (defaultEditor != null && editor.getId().equals(defaultEditor.getId())) {
+ defaultFound = true;
+ }
+ alreadyMapped.add(editor);
+ }
+ }
+
+ // Only add a separator if there is something to separate
+ if (editors.length > 0) {
+ new MenuItem(menu, SWT.SEPARATOR);
+ }
+
+ // Add default editor. Check it if it is saved as the preference.
+ if (!defaultFound && defaultEditor != null) {
+ createMenuItem(menu, defaultEditor, preferredEditor);
+ }
+
+ // Add system editor (should never be null)
+ IEditorDescriptor descriptor = registry
+ .findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
+ createMenuItem(menu, descriptor, preferredEditor);
+
+ createDefaultMenuItem(menu);
+
+ // add Other... menu item
+ createOtherMenuItem(menu);
+ }
+
+ /*
+ * (non-Javadoc) Returns whether this menu is dynamic.
+ */
+ @Override
+ public boolean isDynamic() {
+ return true;
+ }
+
+ /**
+ * Creates the menu item for clearing the current selection.
+ *
+ * @param menu the menu to add the item to
+ * @param file the file being edited
+ */
+ private void createDefaultMenuItem(Menu menu) {
+ final MenuItem menuItem = new MenuItem(menu, SWT.RADIO);
+ menuItem.setSelection(getDefaultEditor() == null);
+ menuItem.setText(Messages.OpenWithMenu_DefaultEditor);
+
+ Listener listener = new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ switch (event.type) {
+ case SWT.Selection:
+ if (menuItem.getSelection()) {
+ PersistenceManager.getInstance().getPersistentProperties(node)
+ .put(IDE.EDITOR_KEY, null);
+ try {
+ syncOpen(getEditorDescriptor(), false);
+ }
+ catch (PartInitException e) {
+ e.printStackTrace();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ menuItem.addListener(SWT.Selection, listener);
+ }
+
+ /**
+ * Get an appropriate editor for the FSTreeNode. If the default editor is not found, it will
+ * search the in-place editor, the external editor and finally the default text editor.
+ *
+ * @return An appropriate editor to open the node using "Default Editor".
+ * @throws PartInitException
+ */
+ protected IEditorDescriptor getEditorDescriptor() throws PartInitException {
+ IEditorDescriptor defaultDescriptor = getDefaultEditor();
+ if (defaultDescriptor != null) {
+ return defaultDescriptor;
+ }
+
+ IEditorDescriptor editorDesc = null;
+
+ // next check the OS for in-place editor (OLE on Win32)
+ if (registry.isSystemInPlaceEditorAvailable(node.name)) {
+ editorDesc = registry.findEditor(IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID);
+ }
+
+ // next check with the OS for an external editor
+ if (editorDesc == null && registry.isSystemExternalEditorAvailable(node.name)) {
+ editorDesc = registry.findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID);
+ }
+
+ // next lookup the default text editor
+ if (editorDesc == null) {
+ editorDesc = registry.findEditor(DEFAULT_TEXT_EDITOR);
+ }
+
+ // if no valid editor found, bail out
+ if (editorDesc == null) {
+ throw new PartInitException(Messages.OpenWithMenu_NoEditorFound);
+ }
+
+ return editorDesc;
+ }
+
+ /**
+ * Synchronize and open the file using the specified editor descriptor. If openUsingDescriptor
+ * is true, it will try to use an external editor to open it if an eclipse editor is not
+ * available.
+ *
+ * @param editorDescriptor The editor descriptor used to open the node.
+ * @param openUsingDescriptor If an external editor should be used to open the node.
+ */
+ protected void syncOpen(IEditorDescriptor editorDescriptor, boolean openUsingDescriptor) {
+ File file = CacheManager.getCacheFile(node);
+ if (!file.exists()) {
+ // If the file node's local cache does not exist yet, download it.
+ IOpExecutor executor = new UiExecutor();
+ IStatus status = executor.execute(new OpCacheUpdate(node));
+ if (!status.isOK()) {
+ return;
+ }
+ }
+ openInEditor(editorDescriptor, openUsingDescriptor);
+ }
+
+ /**
+ * Open the editor using the specified editor descriptor. If openUsingDescriptor is true, it
+ * will try to use an external editor to open it if an eclipse editor is not available.
+ *
+ * @param editorDescriptor The editor descriptor used to open the node.
+ * @param openUsingDescriptor If an external editor should be used to open the node.
+ */
+ private void openInEditor(IEditorDescriptor editorDescriptor, boolean openUsingDescriptor) {
+ try {
+ IPath path = CacheManager.getCachePath(node);
+ IFileStore fileStore = EFS.getLocalFileSystem().getStore(path);
+ FileStoreEditorInput input = new FileStoreEditorInput(fileStore);
+ if (openUsingDescriptor) {
+ String editorId = editorDescriptor.getId();
+ page.openEditor(input, editorId, true, IWorkbenchPage.MATCH_INPUT | IWorkbenchPage.MATCH_ID);
+ }
+ else {
+ String editorId = IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID;
+ if (editorDescriptor != null) editorId = editorDescriptor.getId();
+ page.openEditor(input, editorId, true, IWorkbenchPage.MATCH_INPUT | IWorkbenchPage.MATCH_ID);
+ Map<QualifiedName, String> properties = PersistenceManager.getInstance()
+ .getPersistentProperties(node);
+ properties.put(IDE.EDITOR_KEY, editorId);
+ }
+ }
+ catch (PartInitException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/PasteFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/PasteFilesHandler.java
new file mode 100644
index 000000000..b7f62ac59
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/PasteFilesHandler.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.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.IStatus;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.tcf.te.runtime.callback.Callback;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IOperation;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCopy;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpMove;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.dnd.CommonDnD;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.FsClipboard;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+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.getClipboard();
+ if (!cb.isEmpty()) {
+ // Get the files/folders from the clip board.
+ IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelectionChecked(event);
+ List<FSTreeNode> nodes = cb.getFiles();
+ IOpExecutor executor = null;
+ IOperation operation = null;
+ if (cb.isCutOp()) {
+ FSTreeNode dest = (FSTreeNode) selection.getFirstElement();
+ operation = new OpMove(nodes, dest, new MoveCopyCallback());
+ executor = new UiExecutor(new Callback(){
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ UIPlugin.getClipboard().clear();
+ }
+ });
+ }
+ else if (cb.isCopyOp()) {
+ FSTreeNode hovered = (FSTreeNode) selection.getFirstElement();
+ FSTreeNode dest = getCopyDestination(hovered, nodes);
+ boolean cpPerm = UIPlugin.isCopyPermission();
+ boolean cpOwn = UIPlugin.isCopyOwnership();
+ operation = new OpCopy(nodes, dest, cpPerm, cpOwn, new MoveCopyCallback());
+ executor = new UiExecutor();
+ }
+ if (executor != null && operation != null) {
+ executor.execute(operation);
+ }
+ }
+ else {
+ Clipboard clipboard = cb.getSystemClipboard();
+ Object contents = clipboard.getContents(FileTransfer.getInstance());
+ if (contents != null) {
+ String[] files = (String[]) contents;
+ // Get the files/folders from the clip board.
+ IStructuredSelection selection = (IStructuredSelection) HandlerUtil
+ .getCurrentSelectionChecked(event);
+ FSTreeNode hovered = (FSTreeNode) selection.getFirstElement();
+ CommonDnD dnd = new CommonDnD();
+ dnd.dropFiles(null, files, DND.DROP_COPY, hovered);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Return an appropriate destination directory for copying according to
+ * the specified hovered node. If the hovered node is a file, then return
+ * its parent directory. If the hovered node is a directory, then return its
+ * self if it is not a node being copied. Return its parent directory if it is
+ * a node being copied.
+ * @param hovered
+ * @param nodes
+ * @return
+ */
+ private FSTreeNode getCopyDestination(FSTreeNode hovered, List<FSTreeNode> nodes) {
+ if (hovered.isFile()) {
+ return hovered.getParent();
+ }
+ else if (hovered.isDirectory()) {
+ for (FSTreeNode node : nodes) {
+ if (node == hovered) {
+ return hovered.getParent();
+ }
+ }
+ }
+ return hovered;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RefreshHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RefreshHandler.java
new file mode 100644
index 000000000..1bedafff1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RefreshHandler.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.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.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.JobExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpRefresh;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Refresh handler implementation.
+ */
+public class RefreshHandler extends AbstractHandler {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
+ List<FSTreeNode> nodes = ((IStructuredSelection) selection).toList();
+ IOpExecutor executor = new JobExecutor();
+ executor.execute(new OpRefresh(nodes));
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RefreshViewerHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RefreshViewerHandler.java
new file mode 100644
index 000000000..5cd226d37
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RefreshViewerHandler.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.JobExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpRefresh;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.ModelManager;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * The action handler to refresh the whole file system tree.
+ */
+public class RefreshViewerHandler extends AbstractHandler {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IEditorInput editorInput = HandlerUtil.getActiveEditorInputChecked(event);
+ IPeerNode peer = (IPeerNode) editorInput.getAdapter(IPeerNode.class);
+ if (peer != null) {
+ FSTreeNode root = ModelManager.getRuntimeModel(peer).getRoot();
+ if (root != null) {
+ IOpExecutor executor = new JobExecutor();
+ executor.execute(new OpRefresh(root));
+ }
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RenameCallback.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RenameCallback.java
new file mode 100644
index 000000000..274442df0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RenameCallback.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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.tcf.filesystem.ui.internal.handlers;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.runtime.callback.Callback;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.ui.PlatformUI;
+/**
+ * The callback implementation for Renaming.
+ */
+public class RenameCallback extends Callback implements Runnable {
+ // The message to be displayed.
+ private String message;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.callback.Callback#internalDone(java.lang.Object, org.eclipse.core.runtime.IStatus)
+ */
+ @Override
+ protected void internalDone(Object caller, IStatus status) {
+ if (!status.isOK()) {
+ message = status.getMessage();
+ PlatformUI.getWorkbench().getDisplay().asyncExec(this);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run() {
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ MessageDialog.openError(parent, Messages.FSRename_RenameFileFolderTitle, message);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RenameFilesHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RenameFilesHandler.java
new file mode 100644
index 000000000..69b7c52e5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/RenameFilesHandler.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.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.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.JobExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpRename;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.celleditor.FSCellValidator;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+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 = UIPlugin.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();
+ // Rename the node with the new name using an FSRename.
+ IOpExecutor executor = new JobExecutor(new RenameCallback());
+ executor.execute(new OpRename(node, newName));
+ }
+ }
+ }
+ 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, null, 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 = folder.getParent().getChildren();
+ 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.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/UpdateHandler.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/UpdateHandler.java
new file mode 100644
index 000000000..0fc8b1b0d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/handlers/UpdateHandler.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.handlers;
+
+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.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCacheUpdate;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.UiExecutor;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * The handler to update the local file's content with the latest of its remote file.
+ *
+ */
+public class UpdateHandler 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.getCurrentSelectionChecked(event);
+ FSTreeNode node = (FSTreeNode) selection.getFirstElement();
+ IOpExecutor executor = new UiExecutor();
+ executor.execute(new OpCacheUpdate(node));
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboard.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboard.java
new file mode 100644
index 000000000..3b04debe1
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/FsClipboard.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.operations;
+
+import java.util.List;
+
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpClipboard;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * The clip board to which copy or cut files/folders.
+ */
+public class FsClipboard extends OpClipboard {
+ // The system clipboard.
+ private Clipboard clipboard;
+
+ /**
+ * Create a clip board instance.
+ */
+ public FsClipboard() {
+ super();
+ clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());
+ }
+
+ /**
+ * Cut the specified files/folders to the clip board.
+ *
+ * @param files The file/folder nodes.
+ */
+ @Override
+ public void cutFiles(List<FSTreeNode> files) {
+ super.cutFiles(files);
+ clearSystemClipboard();
+ }
+
+ /**
+ * Copy the specified files/folders to the clip board.
+ *
+ * @param files The file/folder nodes.
+ */
+ @Override
+ public void copyFiles(List<FSTreeNode> files) {
+ super.copyFiles(files);
+ clearSystemClipboard();
+ }
+
+ /**
+ * Clear the clip board.
+ */
+ @Override
+ public void clear() {
+ super.clear();
+ clearSystemClipboard();
+ }
+
+ /**
+ * Make sure the system clip board is cleared in a UI thread.
+ */
+ void clearSystemClipboard() {
+ if (Display.getCurrent() != null) {
+ clipboard.clearContents();
+ }
+ else {
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable(){
+ @Override
+ public void run() {
+ clearSystemClipboard();
+ }});
+ }
+ }
+
+ /**
+ * Dispose the clipboard.
+ */
+ @Override
+ public void dispose() {
+ if(Display.getCurrent() != null) {
+ if (!clipboard.isDisposed()) {
+ try {
+ clipboard.dispose();
+ }
+ catch (SWTException e) {
+ }
+ }
+ }
+ else {
+ PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable(){
+ @Override
+ public void run() {
+ dispose();
+ }});
+ }
+ }
+
+ /**
+ * Get the system clipboard.
+ *
+ * @return The system clipboard.
+ */
+ public Clipboard getSystemClipboard() {
+ return clipboard;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/UiExecutor.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/UiExecutor.java
new file mode 100644
index 000000000..e93449524
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/operations/UiExecutor.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.operations;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IOperation;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.exceptions.TCFException;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.dialogs.TimeTriggeredProgressMonitorDialog;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * The operation that is executed in an interactive progress dialog.
+ */
+public class UiExecutor implements IOpExecutor {
+ // The callback
+ protected ICallback callback;
+
+ /**
+ * Create a UI executor with no callback.
+ */
+ public UiExecutor() {
+ this(null);
+ }
+
+ /**
+ * Create a UI executor with a callback that will be
+ * invoked after execution.
+ *
+ * @param callback The callback to be invoked after execution.
+ */
+ public UiExecutor(ICallback callback) {
+ this.callback = callback;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.ui.internal.operations.IOpExecutor#execute(org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IOperation)
+ */
+ @Override
+ public IStatus execute(final IOperation operation) {
+ Assert.isNotNull(Display.getCurrent());
+ Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ TimeTriggeredProgressMonitorDialog dialog = new TimeTriggeredProgressMonitorDialog(parent, 250);
+ final IRunnableWithProgress runnable = new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ try {
+ monitor.setTaskName(operation.getName());
+ monitor.beginTask(operation.getName(), operation.getTotalWork());
+ operation.run(monitor);
+ }
+ finally {
+ monitor.done();
+ }
+ }};
+ dialog.setCancelable(true);
+ IStatus status = null;
+ try {
+ dialog.run(true, true, runnable);
+ status = Status.OK_STATUS;
+ }
+ catch (InvocationTargetException e) {
+ // Display the error during copy.
+ Throwable throwable = e.getTargetException();
+ if(throwable instanceof TCFException) {
+ int severity = ((TCFException)throwable).getSeverity();
+ status = new Status(severity, UIPlugin.getUniqueIdentifier(), throwable.getMessage(), throwable);
+ }
+ else {
+ status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), throwable.getMessage(), throwable);
+ }
+ MessageDialog.openError(parent, operation.getName(), throwable.getMessage());
+ }
+ catch (InterruptedException e) {
+ // It is canceled.
+ status = Status.OK_STATUS;
+ }
+ if (callback != null) callback.done(operation, status);
+ return status;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/pages/FSExplorerEditorPage.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/pages/FSExplorerEditorPage.java
new file mode 100644
index 000000000..60f12d207
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/pages/FSExplorerEditorPage.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2014 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.tcf.filesystem.ui.internal.pages;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.tcf.te.runtime.events.ChangeEvent;
+import org.eclipse.tcf.te.runtime.events.EventManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.ModelManager;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.tcf.ui.editor.AbstractTreeViewerExplorerEditorPage;
+import org.eclipse.tcf.te.ui.trees.TreeControl;
+/**
+ * The editor page for the file system explorer.
+ */
+public class FSExplorerEditorPage extends AbstractTreeViewerExplorerEditorPage {
+
+ // The event listener instance
+ private FSExplorerEventListener listener = null;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.editor.pages.AbstractTreeViewerExplorerEditorPage#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (listener != null) {
+ EventManager.getInstance().removeEventListener(listener);
+ listener = null;
+ }
+ super.dispose();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.editor.pages.AbstractTreeViewerExplorerEditorPage#getDoubleClickCommandId()
+ */
+ @Override
+ protected String getDoubleClickCommandId() {
+ return "org.eclipse.ui.navigator.Open"; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.editor.pages.AbstractTreeViewerExplorerEditorPage#getViewerId()
+ */
+ @Override
+ protected String getViewerId() {
+ return "org.eclipse.tcf.te.ui.controls.viewer.fs"; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.editor.pages.AbstractCustomFormToolkitEditorPage#getFormTitle()
+ */
+ @Override
+ protected String getFormTitle() {
+ return Messages.FSExplorerEditorPage_PageTitle;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.editor.pages.AbstractCustomFormToolkitEditorPage#getContextHelpId()
+ */
+ @Override
+ protected String getContextHelpId() {
+ return "org.eclipse.tcf.te.tcf.filesystem.FSExplorerEditorPage"; //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.editor.pages.AbstractTreeViewerExplorerEditorPage#getViewerInput()
+ */
+ @Override
+ protected Object getViewerInput() {
+ Object element = getEditorInputNode();
+ IPeerNode peerNode = element instanceof IPeerNode ? (IPeerNode)element : null;
+ if (peerNode == null && element instanceof IAdaptable) {
+ peerNode = (IPeerNode)((IAdaptable)element).getAdapter(IPeerNode.class);
+ }
+ return peerNode != null ? ModelManager.getRuntimeModel(peerNode).getRoot() : null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.editor.pages.AbstractTreeViewerExplorerEditorPage#doCreateTreeControl()
+ */
+ @Override
+ protected TreeControl doCreateTreeControl() {
+ TreeControl treeControl = super.doCreateTreeControl();
+ Assert.isNotNull(treeControl);
+
+ if (listener == null) {
+ listener = new FSExplorerEventListener(treeControl);
+ EventManager.getInstance().addEventListener(listener, ChangeEvent.class);
+ }
+
+ return treeControl;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/pages/FSExplorerEventListener.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/pages/FSExplorerEventListener.java
new file mode 100644
index 000000000..909eb167e
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/pages/FSExplorerEventListener.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2014 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.tcf.filesystem.ui.internal.pages;
+
+import java.util.EventObject;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.tcf.te.core.interfaces.IConnectable;
+import org.eclipse.tcf.te.runtime.events.ChangeEvent;
+import org.eclipse.tcf.te.runtime.events.EventManager;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.runtime.IRuntimeModel;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.ModelManager;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProperties;
+import org.eclipse.tcf.te.ui.events.AbstractEventListener;
+import org.eclipse.tcf.te.ui.trees.TreeControl;
+
+/**
+ * Filesystem page event listener implementation.
+ */
+public class FSExplorerEventListener extends AbstractEventListener {
+ // Reference to the parent tree control
+ /* default */ final TreeControl treeControl;
+
+ /**
+ * Constructor.
+ *
+ * @param treeControl The parent tree control. Must not be <code>null</code>.
+ */
+ public FSExplorerEventListener(TreeControl treeControl) {
+ Assert.isNotNull(treeControl);
+ this.treeControl = treeControl;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.runtime.interfaces.events.IEventListener#eventFired(java.util.EventObject)
+ */
+ @Override
+ public void eventFired(EventObject event) {
+ if (event instanceof ChangeEvent) {
+ final ChangeEvent changeEvent = (ChangeEvent)event;
+ final Object source = changeEvent.getSource();
+
+ if (treeControl.getViewer() != null) {
+ if (treeControl.getViewer().getControl() == null || treeControl.getViewer().getControl().isDisposed()) {
+ EventManager.getInstance().removeEventListener(this);
+ return;
+ }
+ // Property changes for the runtime model refreshes the whole tree.
+ if (source instanceof IRuntimeModel) {
+ treeControl.getViewer().refresh();
+ }
+
+ // Property changes for individual context nodes refreshes the node only
+ else if (source instanceof FSTreeNode) {
+ if ("expanded".equals(changeEvent.getEventId())) { //$NON-NLS-1$
+ // Expansion state of the node changed.
+ boolean expanded = ((Boolean)changeEvent.getNewValue()).booleanValue();
+ // Update the nodes expansion state
+ ((TreeViewer)treeControl.getViewer()).setExpandedState(source, expanded);
+ } else {
+ ((TreeViewer)treeControl.getViewer()).refresh(source, true);
+ }
+ }
+
+ else if (source instanceof IPeerNode && source == getPeerNode()) {
+ if (IPeerNodeProperties.PROPERTY_CONNECT_STATE.equals(changeEvent.getEventId())) {
+ // Peer node connect state changed to connected
+ if (changeEvent.getNewValue().equals(Integer.valueOf(IConnectable.STATE_CONNECTED))) {
+ // Get the new runtime model
+ final IRuntimeModel model = ModelManager.getRuntimeModel(getPeerNode());
+ // Update the tree viewer input element
+ treeControl.getViewer().setInput(model.getRoot());
+ }
+ // Trigger a refresh on the whole viewer to show the "Please connect ..." text
+ treeControl.getViewer().refresh();
+ }
+ }
+ }
+ }
+ }
+
+ protected IPeerNode getPeerNode() {
+ Object element = treeControl.getViewer().getInput();
+ IPeerNode peerNode = element instanceof IPeerNode ? (IPeerNode)element : null;
+ if (peerNode == null && element instanceof IAdaptable) {
+ peerNode = (IPeerNode)((IAdaptable)element).getAdapter(IPeerNode.class);
+ }
+ return peerNode;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/preferences/PreferencePage.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/preferences/PreferencePage.java
new file mode 100644
index 000000000..e3a22ad7d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/preferences/PreferencePage.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.preferences;
+
+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.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.interfaces.preferences.IPreferenceKeys;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * The preference page for configuring the preference options for
+ * the TCF File System Explorer.
+ *
+ */
+public class PreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage, IPreferenceKeys {
+
+ /***
+ * Create a preference page for Target Explorer File System Explorer.
+ */
+ public PreferencePage() {
+ super(GRID);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors()
+ */
+ @Override
+ protected void createFieldEditors() {
+ UIPlugin plugin = UIPlugin.getDefault();
+ IPreferenceStore preferenceStore = plugin.getPreferenceStore();
+ setPreferenceStore(preferenceStore);
+ BooleanFieldEditor autoSaving = new BooleanFieldEditor(PREF_AUTOSAVING, Messages.PreferencePage_AutoSavingText, getFieldEditorParent());
+ addField(autoSaving);
+ BooleanFieldEditor renamingOption = new BooleanFieldEditor(PREF_RENAMING_IN_PLACE_EDITOR, Messages.PreferencePage_RenamingOptionText, getFieldEditorParent());
+ addField(renamingOption);
+ BooleanFieldEditor copyPermission = new BooleanFieldEditor(PREF_COPY_PERMISSION, Messages.PreferencePage_CopyPermissionText, getFieldEditorParent());
+ addField(copyPermission);
+ BooleanFieldEditor copyOwnership = new BooleanFieldEditor(PREF_COPY_OWNERSHIP, Messages.PreferencePage_CopyOwnershipText, getFieldEditorParent());
+ addField(copyOwnership);
+ BooleanFieldEditor persistExpanded = new BooleanFieldEditor(PREF_EXPANDED_PERSISTED, Messages.PreferencePage_PersistExpanded, getFieldEditorParent());
+ addField(persistExpanded);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ @Override
+ public void init(IWorkbench workbench) {
+ // do nothing
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/preferences/PreferencesInitializer.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/preferences/PreferencesInitializer.java
new file mode 100644
index 000000000..228af3ced
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/preferences/PreferencesInitializer.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.preferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.interfaces.preferences.IPreferenceKeys;
+
+
+/**
+ * The bundle's preference initializer implementation.
+ */
+public class PreferencesInitializer extends AbstractPreferenceInitializer implements IPreferenceKeys {
+
+ /**
+ * Constructor.
+ */
+ public PreferencesInitializer() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ @Override
+ public void initializeDefaultPreferences() {
+ // Get the bundles preferences manager
+ IEclipsePreferences prefs = DefaultScope.INSTANCE.getNode(UIPlugin.getUniqueIdentifier());
+ if (prefs != null) {
+ // [Hidden] Editor content contribution: default on
+ prefs.putBoolean(PREF_FEATURE_ENABLE_EDITOR_CONTENT_CONTRIBUTION, DEFAULT_FEATURE_ENABLE_EDITOR_CONTENT_CONTRIBUTION);
+ }
+ IPreferenceStore preferenceStore = UIPlugin.getDefault().getPreferenceStore();
+ preferenceStore.setDefault(PREF_AUTOSAVING, DEFAULT_AUTOSAVING);
+ preferenceStore.setDefault(PREF_RENAMING_IN_PLACE_EDITOR, DEFAULT_RENAMING_IN_PLACE_EDITOR);
+ preferenceStore.setDefault(PREF_COPY_PERMISSION, DEFAULT_COPY_PERMISSION);
+ preferenceStore.setDefault(PREF_COPY_OWNERSHIP, DEFAULT_COPY_OWNERSHIP);
+ preferenceStore.setDefault(PREF_EXPANDED_PERSISTED, DEFAULT_EXPANDED_PERSISTED);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/properties/AdvancedAttributesDialog.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/properties/AdvancedAttributesDialog.java
new file mode 100644
index 000000000..4731034d0
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/properties/AdvancedAttributesDialog.java
@@ -0,0 +1,214 @@
+/*********************************************************************************************
+ * Copyright (c) 2011, 2012 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) - [345384]Provide property pages for remote file system nodes
+ *********************************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.properties;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IWindowsFileAttributes;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.ImageConsts;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * The dialog used to display the advanced attributes of a Windows file or
+ * folder.
+ */
+public class AdvancedAttributesDialog extends Dialog {
+
+ // The file or folder node whose advanced attributes are to be displayed.
+ FSTreeNode node;
+
+ /**
+ * Create the advanced attributes dialog with the specified node and a
+ * parent shell.
+ *
+ * @param parentShell
+ * The parent shell.
+ * @param node
+ * The file or folder node to be displayed.
+ */
+ public AdvancedAttributesDialog(Shell parentShell, FSTreeNode node) {
+ super(parentShell);
+ this.node = node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite) super.createDialogArea(parent);
+ Composite banner = new Composite(composite, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ banner.setLayout(layout);
+ Label label = new Label(banner, SWT.NONE);
+ Image bImg = getBannerImage();
+ label.setImage(bImg);
+ label.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
+ label = new Label(banner, SWT.NONE);
+ if (node.isFile()) {
+ label.setText(Messages.AdvancedAttributesDialog_FileBanner);
+ } else if (node.isDirectory()) {
+ label.setText(Messages.AdvancedAttributesDialog_FolderBanner);
+ }
+ createArchiveAndIndexGroup(composite);
+ createCompressAndEncryptGroup(composite);
+ return composite;
+ }
+
+ /**
+ * Get the image in the banner area.
+ *
+ * @return The image in the banner area.
+ */
+ private Image getBannerImage() {
+ return UIPlugin.getImage(ImageConsts.BANNER_IMAGE);
+ }
+
+ /**
+ * Create the compress and encrypt options group.
+ *
+ * @param parent
+ * The parent composite where they are created.
+ */
+ private void createCompressAndEncryptGroup(Composite parent) {
+ Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
+ group.setText(Messages.AdvancedAttributesDialog_CompressEncrypt);
+ group.setLayout(new GridLayout());
+ group.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ createCompress(group);
+ createEncrypt(group);
+ }
+
+ /**
+ * Create the archive and indexing options group.
+ *
+ * @param parent
+ * The parent composite where they are created.
+ */
+ private void createArchiveAndIndexGroup(Composite parent) {
+ Group group = new Group(parent, SWT.SHADOW_ETCHED_IN);
+ group.setText(Messages.AdvancedAttributesDialog_ArchiveIndex);
+ group.setLayout(new GridLayout());
+ group.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ createArchive(group);
+ createIndexField(group);
+ }
+
+ /**
+ * Create the indexing option field.
+ *
+ * @param group
+ * The group widget where the field is created.
+ */
+ private void createIndexField(Group group) {
+ String label = node.isFile() ? Messages.AdvancedAttributesDialog_IndexFile
+ : (node.isDirectory() ? Messages.AdvancedAttributesDialog_IndexFolder
+ : null);
+ boolean on = !node.isWin32AttrOn(IWindowsFileAttributes.FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
+ createOptionField(group, label, IWindowsFileAttributes.FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, on);
+ }
+
+ /**
+ * Create the archive option field.
+ *
+ * @param group
+ * The group widget where the field is created.
+ */
+ private void createArchive(Group group) {
+ String label = node.isFile() ? Messages.AdvancedAttributesDialog_FileArchive
+ : (node.isDirectory() ? Messages.AdvancedAttributesDialog_FolderArchive
+ : null);
+ boolean on = node.isWin32AttrOn(IWindowsFileAttributes.FILE_ATTRIBUTE_ARCHIVE);
+ createOptionField(group, label, IWindowsFileAttributes.FILE_ATTRIBUTE_ARCHIVE, on);
+ }
+
+ /**
+ * Create the encrypt option field.
+ *
+ * @param group
+ * The group widget where the field is created.
+ */
+ private void createEncrypt(Group group) {
+ String label = Messages.AdvancedAttributesDialog_Encrypt;
+ boolean on = node.isWin32AttrOn(IWindowsFileAttributes.FILE_ATTRIBUTE_ENCRYPTED);
+ createOptionField(group, label, IWindowsFileAttributes.FILE_ATTRIBUTE_ENCRYPTED, on);
+ }
+
+ /**
+ * Create the compress option field.
+ *
+ * @param group
+ * The group widget where the field is created.
+ */
+ private void createCompress(Group group) {
+ String label = Messages.AdvancedAttributesDialog_Compress;
+ boolean on = node.isWin32AttrOn(IWindowsFileAttributes.FILE_ATTRIBUTE_COMPRESSED);
+ createOptionField(group, label, IWindowsFileAttributes.FILE_ATTRIBUTE_COMPRESSED, on);
+ }
+
+ /**
+ * Create an option field in the specified group, using the specified label,
+ * and with the specified boolean value.
+ *
+ * @param group
+ * The group widget where the field is created.
+ * @param label
+ * The label used by the field.
+ * @param bit
+ * The bit mask to be changed once the value is changed.
+ * @param on
+ * The boolean value to be set.
+ */
+ private void createOptionField(Group group, String label, final int bit, final boolean on) {
+ 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) {
+ if (button.getSelection() != on) {
+ node.setWin32Attr(bit, on);
+ }
+ }
+ });
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+ */
+ @Override
+ protected void configureShell(Shell newShell) {
+ super.configureShell(newShell);
+ newShell.setText(Messages.AdvancedAttributesDialog_ShellTitle);
+ }
+
+ /**
+ * Get the result.
+ * @return The result.
+ */
+ public FSTreeNode getResult() {
+ return node;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/properties/GeneralInformationPage.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/properties/GeneralInformationPage.java
new file mode 100644
index 000000000..94624e244
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/properties/GeneralInformationPage.java
@@ -0,0 +1,405 @@
+/*********************************************************************************************
+ * Copyright (c) 2011, 2014 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) - [345384]Provide property pages for remote file system nodes
+ * [361322]Minor improvements to the properties dialog of a file.
+ *********************************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.properties;
+
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.util.Date;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.IOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.JobExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.NullOpExecutor;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCommitAttr;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpRefresh;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+/**
+ * The general information page of a file's properties dialog.
+ */
+public class GeneralInformationPage extends PropertyPage {
+ // The times of retrying before failure.
+ private static final int RETRY_TIMES = 3;
+ // The formatter for the size of a file.
+ private static final DecimalFormat SIZE_FORMAT = new DecimalFormat();
+ // The original node.
+ FSTreeNode node;
+ // Cloned node for modification.
+ FSTreeNode clone;
+ // The button of "Read-Only"
+ Button btnReadOnly;
+ // The button of "Hidden"
+ Button btnHidden;
+ // The button of "Permissions"
+ Button[] btnPermissions;
+
+ /**
+ * Create a horizontal separator between field sections.
+ *
+ * @param parent
+ * The parent composite of the separator.
+ */
+ protected void createSeparator(Composite parent) {
+ Label label = new Label(parent, SWT.SEPARATOR | SWT.SHADOW_ETCHED_IN | SWT.HORIZONTAL);
+ GridData data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+ }
+
+ /**
+ * Create a field displaying the a specific value with a specific label.
+ *
+ * @param text
+ * The label text for the field.
+ * @param value
+ * The value to be displayed.
+ * @param parent
+ * The parent composite of the field.
+ */
+ protected void createField(String text, String value, Composite parent) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(text);
+ GridData data = new GridData();
+ data.horizontalAlignment = SWT.LEFT;
+ data.verticalAlignment = SWT.TOP;
+ label.setLayoutData(data);
+ Text txt = new Text(parent, SWT.WRAP | SWT.READ_ONLY);
+ data = new GridData();
+ data.verticalAlignment = SWT.TOP;
+ data.widthHint = 300;
+ data.grabExcessHorizontalSpace = true;
+ data.horizontalAlignment = GridData.FILL;
+ txt.setLayoutData(data);
+ txt.setBackground(txt.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+ txt.setText(value);
+ }
+
+ /**
+ * Get the string of the file size using using the formatter, SIZE_FORMAT.
+ *
+ * @param size
+ * The size of the file to be formatted.
+ * @return The string in the format of SIZE_FORMAT.
+ */
+ protected String getSizeText(long size) {
+ return NLS.bind(Messages.GeneralInformationPage_FileSizeInfo, SIZE_FORMAT.format(size / 1024), SIZE_FORMAT.format(size));
+ }
+
+ /**
+ * Get the string of the specific time using the formatter, DATE_FORMAT.
+ *
+ * @param time
+ * The time to be formatted.
+ * @return The string in the format of DATE_FORMAT.
+ */
+ protected String getDateText(long time) {
+ DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
+ return dateFormat.format(new Date(time));
+ }
+
+ /**
+ * Create the attributes section for a Windows file/folder.
+ *
+ * @param parent
+ * The parent composite on which it is created.
+ */
+ protected void createAttributesSection(Composite parent) {
+ // Attributes
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(Messages.GeneralInformationPage_Attributes);
+ GridData data = new GridData();
+ data.horizontalAlignment = SWT.LEFT;
+ label.setLayoutData(data);
+
+ Composite attr = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(3, true);
+ layout.marginHeight = 0;
+ attr.setLayout(layout);
+ // 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) {
+ if(btnReadOnly.getSelection()!=clone.isReadOnly()){
+ clone.setReadOnly(btnReadOnly.getSelection());
+ }
+ }
+ });
+ // 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) {
+ Button btnHidden = (Button) e.getSource();
+ if(btnHidden.getSelection()!=clone.isHidden()){
+ clone.setHidden(btnHidden.getSelection());
+ }
+ }
+ });
+ // Advanced Attributes
+ Button btnAdvanced = new Button(attr, SWT.PUSH);
+ btnAdvanced.setText(Messages.GeneralInformationPage_Advanced);
+ btnAdvanced.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ showAdvancedAttributes();
+ }
+ });
+ // Update the attribute values.
+ updateAttributes();
+ }
+
+ /**
+ * Update the value of attributes section.
+ */
+ private void updateAttributes() {
+ btnReadOnly.setSelection(clone.isReadOnly());
+ btnHidden.setSelection(clone.isHidden());
+ }
+
+ /**
+ * Show the advanced attributes dialog for the specified file/folder.
+ */
+ void showAdvancedAttributes() {
+ AdvancedAttributesDialog dialog = new AdvancedAttributesDialog(this.getShell(), (FSTreeNode)(clone.clone()));
+ if (dialog.open() == Window.OK) {
+ FSTreeNode result = dialog.getResult();
+ clone.attr = result.attr;
+ }
+ }
+
+ /**
+ * Create the permissions section for a Unix/Linux file/folder.
+ *
+ * @param parent
+ * The parent composite on which it is created.
+ */
+ protected void createPermissionsSection(Composite parent) {
+ GridLayout gridLayout;
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(Messages.GeneralInformationPage_PermissionText);
+ GridData data = new GridData();
+ data.horizontalAlignment = SWT.LEFT;
+ data.verticalAlignment = SWT.TOP;
+ label.setLayoutData(data);
+ Composite perms = new Composite(parent, SWT.NONE);
+ gridLayout = new GridLayout(2, false);
+ gridLayout.marginHeight = 0;
+ perms.setLayout(gridLayout);
+ btnPermissions = new Button[9];
+ createPermissionGroup(perms, 0,
+ Messages.PermissionsGroup_UserPermissions);
+ createPermissionGroup(perms, 3,
+ Messages.PermissionsGroup_GroupPermissions);
+ createPermissionGroup(perms, 6,
+ Messages.PermissionsGroup_OtherPermissions);
+ // Update the permission values.
+ updatePermissions();
+ }
+
+ /**
+ * Create a permission group for a role, such as a user, a group or others.
+ *
+ * @param parent
+ * The parent composite.
+ * @param bit
+ * The permission bit index.
+ * @param header
+ * The group's header label.
+ */
+ protected void createPermissionGroup(Composite parent, int bit, String header) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(header);
+ GridData data = new GridData();
+ data.horizontalAlignment = SWT.LEFT;
+ label.setLayoutData(data);
+ Composite group = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(3, true);
+ layout.marginHeight = 0;
+ group.setLayout(layout);
+ createPermissionButton(Messages.PermissionsGroup_Readable, bit, group);
+ createPermissionButton(Messages.PermissionsGroup_Writable, bit + 1, group);
+ createPermissionButton(Messages.PermissionsGroup_Executable, bit + 2, group);
+ }
+
+ /**
+ * Create a check-box field for a single permission item.
+ *
+ * @param label
+ * The label of the permission.
+ * @param index
+ * The index of current permission bit mask index.
+ * @param parent
+ * The parent to hold the check-box field.
+ */
+ 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) {
+ int bit = 1 << (8 - index);
+ boolean on = clone.attr != null && (clone.attr.permissions & bit) != 0;
+ boolean newOn = btnPermissions[index].getSelection();
+ if (newOn != on) {
+ int permissions = clone.attr != null ? clone.attr.permissions : 0;
+ permissions = newOn ? (permissions | bit) : (permissions & ~bit);
+ clone.setPermissions(permissions);
+ }
+ }
+ });
+ }
+
+ /**
+ * Update the value of permissions section.
+ */
+ private void updatePermissions(){
+ for (int i = 0; i < 9; i++) {
+ final int bit = 1 << (8 - i);
+ final boolean on = clone.attr != null && (clone.attr.permissions & bit) != 0;
+ btnPermissions[i].setSelection(on);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+ */
+ @Override
+ protected void performDefaults() {
+ clone = (FSTreeNode) node.clone();
+ if (node.isWindowsNode()) {
+ updateAttributes();
+ }
+ else {
+ updatePermissions();
+ }
+ super.performDefaults();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#performOk()
+ */
+ @Override
+ public boolean performOk() {
+ if (hasAttrsChanged()) {
+ IStatus status = commitAttr();
+ if(!status.isOK()) {
+ setErrorMessage(status.getMessage());
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Commit the new attributes of the file and
+ * return a status. This operation will try
+ * several times before reporting failure.
+ *
+ * @return The committing status.
+ */
+ private IStatus commitAttr() {
+ OpCommitAttr op = new OpCommitAttr(node, clone.attr);
+ IOpExecutor executor = new NullOpExecutor();
+ IStatus status = null;
+ for (int i = 0; i < RETRY_TIMES; i++) {
+ status = executor.execute(op);
+ if (status.isOK()) {
+ if (!node.isRoot()) {
+ // Refresh the parent so that the filters work!
+ executor = new JobExecutor();
+ executor.execute(new OpRefresh(node.getParent()));
+ }
+ return status;
+ }
+ }
+ return status;
+ }
+
+ /**
+ * If the attributes has been changed.
+ * @return If the attributes has been changed.
+ */
+ private boolean hasAttrsChanged(){
+ if(node.isWindowsNode()){
+ // If it is a Windows file, only check its attributes.
+ return node.getWin32Attrs() != clone.getWin32Attrs();
+ }
+ // If it is not a Windows file, only check its permissions.
+ return node.attr != null && clone.attr != null && node.attr.permissions != clone.attr.permissions;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ protected Control createContents(Composite parent) {
+ IAdaptable element = getElement();
+ Assert.isTrue(element instanceof FSTreeNode);
+
+ node = (FSTreeNode) element;
+ clone = (FSTreeNode) node.clone();
+ Composite page = new Composite(parent, SWT.NONE);
+ GridLayout gridLayout = new GridLayout(2, false);
+ page.setLayout(gridLayout);
+ // Field "Name"
+ createField(Messages.GeneralInformationPage_Name, clone.name, page);
+ // Field "Type"
+ createField(Messages.GeneralInformationPage_Type, clone.getFileType(), page);
+ // Field "Location"
+ String location = clone.isSystemRoot() || clone.isRoot() ?
+ Messages.GeneralInformationPage_Computer : clone.getLocation();
+ createField(Messages.GeneralInformationPage_Location, location, page);
+ // Field "Size"
+ if (clone.isFile()) {
+ createField(Messages.GeneralInformationPage_Size, clone.attr != null ? getSizeText(clone.attr.size) : "", page); //$NON-NLS-1$
+ }
+ // Field "Modified"
+ createField(Messages.GeneralInformationPage_Modified, clone.attr != null ? getDateText(clone.attr.mtime) : "", page); //$NON-NLS-1$
+ // Field "Accessed"
+ if (clone.isFile()) {
+ createField(Messages.GeneralInformationPage_Accessed, clone.attr != null ? getDateText(clone.attr.atime) : "", page); //$NON-NLS-1$
+ }
+ createSeparator(page);
+ if (clone.isWindowsNode()) {
+ createAttributesSection(page);
+ } else {
+ createPermissionsSection(page);
+ }
+ return page;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/DateValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/DateValidator.java
new file mode 100644
index 000000000..0ada406c5
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/DateValidator.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.search;
+
+import java.util.Calendar;
+import java.util.StringTokenizer;
+
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.controls.validator.RegexValidator;
+
+/**
+ * The validator used to validate the date entered in the search dialog.
+ */
+public class DateValidator extends RegexValidator {
+ // The regex that defines the format of the date, i.e., MM/DD/YYYY
+ private static final String DATE_REGEX = "\\d{1,2}/\\d{1,2}/\\d{4}"; //$NON-NLS-1$
+
+ /**
+ * Constructor
+ */
+ public DateValidator() {
+ super(ATTR_MANDATORY, DATE_REGEX);
+ setMessageText(INFO_MISSING_VALUE, Messages.DateValidator_InfoPrompt);
+ setMessageText(ERROR_INVALID_VALUE, Messages.DateValidator_InfoFormat);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.controls.validator.RegexValidator#isValid(java.lang.String)
+ */
+ @Override
+ public boolean isValid(String newText) {
+ boolean valid = super.isValid(newText);
+ if(valid) {
+ try {
+ parseTimeInMillis(newText);
+ return true;
+ }
+ catch(IllegalArgumentException e) {
+ String error = e.getMessage();
+ setMessage(error, ERROR);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Parse a text string to a date expressed in milliseconds since 1/1/1970.
+ * If the format is not right, then throw an illegal argument exception containing
+ * the error message.
+ *
+ * @param newText The text string to be parsed.
+ * @return a number in milliseconds since 1/1/1970
+ * @throws IllegalArgumentException when the format is not right.
+ */
+ public static long parseTimeInMillis(String newText) throws IllegalArgumentException{
+ StringTokenizer tokenizer = new StringTokenizer(newText, "/"); //$NON-NLS-1$
+ String month_str = tokenizer.nextToken();
+ int month = 0;
+ try{
+ month = Integer.parseInt(month_str);
+ }
+ catch(NumberFormatException e){
+ throw new IllegalArgumentException(Messages.DateValidator_MonthInvalidNumber);
+ }
+ if(month <= 0 || month > 12) {
+ throw new IllegalArgumentException(Messages.DateValidator_MonthOutofRange);
+ }
+ String date_str = tokenizer.nextToken();
+ int date = 0;
+ try {
+ date = Integer.parseInt(date_str);
+ }
+ catch(NumberFormatException e) {
+ throw new IllegalArgumentException(Messages.DateValidator_DateInvalidNumber);
+ }
+ if(date <= 0 || date > 31) {
+ throw new IllegalArgumentException(Messages.DateValidator_DateOutofRange);
+ }
+ String year_str = tokenizer.nextToken();
+ int year = 0;
+ try {
+ year = Integer.parseInt(year_str);
+ }
+ catch(NumberFormatException e) {
+ throw new IllegalArgumentException(Messages.DateValidator_YearInvalidNumber);
+ }
+ if(year <= 0) {
+ throw new IllegalArgumentException(Messages.DateValidator_YearOutofRange);
+ }
+ Calendar calendar = Calendar.getInstance();
+ calendar.setLenient(false);
+ calendar.set(year, month-1, date);
+ try {
+ return calendar.getTimeInMillis();
+ }
+ catch(IllegalArgumentException e) {
+ throw new IllegalArgumentException(Messages.DateValidator_InvalidDate);
+ }
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSBaseSearchable.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSBaseSearchable.java
new file mode 100644
index 000000000..c6576dcbf
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSBaseSearchable.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.search;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tcf.te.ui.forms.FormLayoutFactory;
+import org.eclipse.tcf.te.ui.interfaces.ISearchMatcher;
+import org.eclipse.tcf.te.ui.utils.AbstractSearchable;
+import org.eclipse.ui.forms.events.ExpansionEvent;
+import org.eclipse.ui.forms.events.IExpansionListener;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.Section;
+
+/**
+ * The base searchable that provides common methods for its subclasses.
+ *
+ * @see FSModifiedSearchable
+ * @see FSSizeSearchable
+ */
+public abstract class FSBaseSearchable extends AbstractSearchable implements ISearchMatcher {
+
+ /**
+ * Create a collapseable section with the specified title and return the
+ * content composite.
+ *
+ * @param parent The parent where the section is to be created.
+ * @param title The title of the section.
+ * @return The content composite.
+ */
+ protected Composite createSection(Composite parent, String title) {
+ Section section = new Section(parent, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT);
+ section.setText(title);
+ section.setLayout(FormLayoutFactory.createSectionClientGridLayout(false, 2));
+ GridData layoutData = new GridData(GridData.FILL_HORIZONTAL);
+ section.setLayoutData(layoutData);
+
+ final Composite client = new Composite(section, SWT.NONE);
+ client.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ client.setBackground(section.getBackground());
+ section.setClient(client);
+
+ section.addExpansionListener(new IExpansionListener(){
+ @Override
+ public void expansionStateChanging(ExpansionEvent e) {
+ }
+ @Override
+ public void expansionStateChanged(ExpansionEvent e) {
+ Shell shell = client.getShell();
+ boolean state = e.getState();
+ int client_height = client.getSize().y;
+ Point p = shell.getSize();
+ p.y = state ? p.y + client_height : p.y - client_height;
+ shell.setSize(p.x, p.y);
+ }});
+ return client;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getMatcher()
+ */
+ @Override
+ public ISearchMatcher getMatcher() {
+ return this;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSGeneralSearchable.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSGeneralSearchable.java
new file mode 100644
index 000000000..e8c3976ce
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSGeneralSearchable.java
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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.tcf.filesystem.ui.internal.search;
+
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl;
+import org.eclipse.tcf.te.ui.interfaces.ISearchMatcher;
+import org.eclipse.tcf.te.ui.search.TreeViewerSearchDialog;
+import org.eclipse.tcf.te.ui.utils.AbstractSearchable;
+
+/**
+ * The searchable that provides a UI to collect and test
+ * the general operations of a file search.
+ */
+public class FSGeneralSearchable extends AbstractSearchable {
+ // The keys to access the options stored in the dialog settings.
+ private static final String INCLUDE_HIDDEN = "FS.IncludeHidden"; //$NON-NLS-1$
+ private static final String INCLUDE_SYSTEM = "FS.IncludeSystem"; //$NON-NLS-1$
+ private static final String TARGET_NAME = "FS.TargetName"; //$NON-NLS-1$
+ private static final String TARGET_TYPE = "FS.TargetType"; //$NON-NLS-1$
+ private static final String MATCH_PRECISE = "FS.MatchPrecise"; //$NON-NLS-1$
+ private static final String CASE_SENSITIVE = "FS.CaseSensitive"; //$NON-NLS-1$
+ // The check option to define if system files should be searched.
+ private Button fBtnSystem;
+ // The check option to define if hidden files should be searched.
+ private Button fBtnHidden;
+ // The case sensitive check box.
+ private Button fBtnCase;
+ // The matching rule check box.
+ private Button fBtnMatch;
+ // The input field for searching conditions.
+ private BaseEditBrowseTextControl fSearchField;
+ // The current target names.
+ private String fTargetName;
+ // Whether it is case sensitive
+ private boolean fCaseSensitive;
+ // Whether it is precise matching.
+ private boolean fMatchPrecise;
+ // The flag if system files should be searched, default to true.
+ private boolean fIncludeSystem = true;
+ // The flag if hidden files should be searched, default to true.
+ private boolean fIncludeHidden = true;
+ // The types of target files.
+ private Combo fCmbTypes;
+ // The current selected target type index.
+ private int fTargetType;
+ // The root directory node.
+ private FSTreeNode rootNode;
+
+ /**
+ * Constructor
+ *
+ * @param node the node whose sub tree will be searched.
+ */
+ public FSGeneralSearchable(FSTreeNode node) {
+ rootNode = node;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.utils.AbstractSearchable#createCommonPart(org.eclipse.tcf.te.ui.search.TreeViewerSearchDialog, org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createCommonPart(TreeViewerSearchDialog dialog, Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout glayout = new GridLayout(3, false);
+ glayout.marginHeight = 0;
+ glayout.marginWidth = 0;
+ composite.setLayout(glayout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ // Searching field.
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(Messages.FSGeneralSearchable_Find);
+
+ fSearchField = new BaseEditBrowseTextControl(null);
+ fSearchField.setIsGroup(false);
+ fSearchField.setHasHistory(false);
+ fSearchField.setHideBrowseButton(true);
+ fSearchField.setParentControlIsInnerPanel(true);
+ fSearchField.setupPanel(composite);
+ fSearchField.setEditFieldValidator(new NameValidator());
+ //fSearchField.setEditFieldValidator(new FolderValidator(this));
+ Text text = (Text) fSearchField.getEditFieldControl();
+ text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
+ text.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ searchTextModified();
+ }
+ });
+
+ SelectionListener l = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ optionChecked(e);
+ }
+ };
+
+ Group group = new Group(parent, SWT.NONE);
+ group.setText(Messages.FSGeneralSearchable_GeneralOptionText);
+ group.setLayout(new GridLayout());
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Composite cmpType = new Composite(group, SWT.NONE);
+ GridData data = new GridData(GridData.FILL_HORIZONTAL);
+ cmpType.setLayoutData(data);
+ cmpType.setLayout(new GridLayout(2, false));
+
+ label = new Label(cmpType, SWT.NONE);
+ label.setText(Messages.FSGeneralSearchable_FileType);
+
+ // Search files only
+ fCmbTypes = new Combo(cmpType, SWT.BORDER | SWT.READ_ONLY);
+ fCmbTypes.setItems(new String[]{Messages.FSTreeNodeSearchable_FilesAndFolders, Messages.FSTreeNodeSearchable_FilesOnly, Messages.FSTreeNodeSearchable_FoldersOnly});
+ fCmbTypes.setLayoutData(new GridData());
+ fCmbTypes.addSelectionListener(l);
+
+ Composite compOptions = new Composite(group, SWT.NONE);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ compOptions.setLayoutData(data);
+ compOptions.setLayout(new GridLayout(3, true));
+
+ // Case sensitive
+ fBtnCase = new Button(compOptions, SWT.CHECK);
+ fBtnCase.setText(Messages.TreeViewerSearchDialog_BtnCaseText);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ fBtnCase.setLayoutData(data);
+ fBtnCase.addSelectionListener(l);
+
+ // Matching precisely
+ fBtnMatch = new Button(compOptions, SWT.CHECK);
+ fBtnMatch.setText(Messages.TreeViewerSearchDialog_BtnPreciseText);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ fBtnMatch.setLayoutData(data);
+ fBtnMatch.addSelectionListener(l);
+
+ dialog.createSearchDirectionOptions(compOptions);
+
+ // If the target is Windows platform, then add system/hidden options.
+ if(rootNode.isWindowsNode()) {
+ fBtnSystem = new Button(compOptions, SWT.CHECK);
+ fBtnSystem.setText(Messages.FSGeneralSearchable_SearchSystemFiles);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ fBtnSystem.setLayoutData(data);
+ fBtnSystem.addSelectionListener(l);
+
+ fBtnHidden = new Button(compOptions, SWT.CHECK);
+ fBtnHidden.setText(Messages.FSGeneralSearchable_SearchHiddenFiles);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ fBtnHidden.setLayoutData(data);
+ fBtnHidden.addSelectionListener(l);
+ }
+ }
+
+ /**
+ * The text for searching is modified.
+ */
+ protected void searchTextModified() {
+ fireOptionChanged();
+ fTargetName = fSearchField.getEditFieldControlText().trim();
+ }
+
+ /**
+ * Handling the event that a button is selected and checked.
+ *
+ * @param e The selection event.
+ */
+ protected void optionChecked(SelectionEvent e) {
+ Object src = e.getSource();
+ if (src == fBtnCase) {
+ fCaseSensitive = fBtnCase.getSelection();
+ }
+ else if (src == fBtnMatch) {
+ fMatchPrecise = fBtnMatch.getSelection();
+ }
+ else if (src == fCmbTypes) {
+ fTargetType = fCmbTypes.getSelectionIndex();
+ }
+ else if (src == fBtnSystem) {
+ fIncludeSystem = fBtnSystem.getSelection();
+ }
+ else if (src == fBtnHidden) {
+ fIncludeHidden = fBtnHidden.getSelection();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.utils.AbstractSearchable#restoreValues(org.eclipse.jface.dialogs.IDialogSettings)
+ */
+ @Override
+ public void restoreValues(IDialogSettings settings) {
+ if(settings != null) {
+ fCaseSensitive = settings.getBoolean(CASE_SENSITIVE);
+ fBtnCase.setSelection(fCaseSensitive);
+ fMatchPrecise = settings.getBoolean(MATCH_PRECISE);
+ fBtnMatch.setSelection(fMatchPrecise);
+ try {
+ fTargetType = settings.getInt(TARGET_TYPE);
+ fCmbTypes.select(fTargetType);
+ }catch(NumberFormatException e) {
+ fTargetType = 0;
+ }
+ fTargetName = settings.get(TARGET_NAME);
+ if (fTargetName != null) {
+ fSearchField.setEditFieldControlText(fTargetName);
+ }
+ if (rootNode.isWindowsNode()) {
+ fIncludeSystem = settings.get(INCLUDE_SYSTEM) == null ? true : settings.getBoolean(INCLUDE_SYSTEM);
+ fIncludeHidden = settings.get(INCLUDE_HIDDEN) == null ? true : settings.getBoolean(INCLUDE_HIDDEN);
+ }
+ }
+ else {
+ fCaseSensitive = false;
+ fMatchPrecise = false;
+ fTargetType = 0;
+ fTargetName = null;
+ if(rootNode.isWindowsNode()) {
+ fIncludeHidden = true;
+ fIncludeSystem = true;
+ }
+ }
+ fBtnCase.setSelection(fCaseSensitive);
+ fBtnMatch.setSelection(fMatchPrecise);
+ fCmbTypes.select(fTargetType);
+ if (fTargetName != null) {
+ fSearchField.setEditFieldControlText(fTargetName);
+ }
+ if (rootNode.isWindowsNode()) {
+ fBtnSystem.setSelection(fIncludeSystem);
+ fBtnHidden.setSelection(fIncludeHidden);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.utils.AbstractSearchable#persistValues(org.eclipse.jface.dialogs.IDialogSettings)
+ */
+ @Override
+ public void persistValues(IDialogSettings settings) {
+ if(settings != null) {
+ settings.put(CASE_SENSITIVE, fCaseSensitive);
+ settings.put(MATCH_PRECISE, fMatchPrecise);
+ settings.put(TARGET_TYPE, fTargetType);
+ settings.put(TARGET_NAME, fTargetName);
+ if(rootNode.isWindowsNode()) {
+ settings.put(INCLUDE_SYSTEM, fIncludeSystem);
+ settings.put(INCLUDE_HIDDEN, fIncludeHidden);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getMatcher()
+ */
+ @Override
+ public ISearchMatcher getMatcher() {
+ return new FSTreeNodeMatcher(fCaseSensitive, fMatchPrecise, fTargetType, fTargetName, fIncludeSystem, fIncludeHidden);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.utils.AbstractSearchable#isInputValid()
+ */
+ @Override
+ public boolean isInputValid() {
+ return fSearchField.isValid();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.utils.AbstractSearchable#getPreferredSize()
+ */
+ @Override
+ public Point getPreferredSize() {
+ return new Point(400, rootNode.isWindowsNode() ? 200 : 180);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSModifiedSearchable.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSModifiedSearchable.java
new file mode 100644
index 000000000..df7113707
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSModifiedSearchable.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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.tcf.filesystem.ui.internal.search;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl;
+import org.eclipse.tcf.te.ui.search.TreeViewerSearchDialog;
+
+/**
+ * The searchable that provides a UI to collect and test
+ * the last modified time of a file during searching.
+ */
+public class FSModifiedSearchable extends FSBaseSearchable {
+ // Constant values of last modified options
+ private static final int OPTION_NOT_REMEMBER = 0;
+ private static final int OPTION_LAST_WEEK = 1;
+ private static final int OPTION_LAST_MONTH = 2;
+ private static final int OPTION_LAST_YEAR = 3;
+ private static final int OPTION_SPECIFIED = 4;
+
+ // Constant values of different time unit, used for matching purpose.
+ private static final long SECOND = 1000L;
+ private static final long MINUTE = 60 * SECOND;
+ private static final long HOUR = 60 * MINUTE;
+ private static final long DAY = 24 * HOUR;
+ private static final long WEEK = 7 * DAY;
+ private static final long MONTH = 30 * DAY;
+ private static final long YEAR = 365 * DAY;
+
+ // The choice selected
+ private int choice;
+ // The specified "from" date
+ private long fromTime;
+ // The specified "to" date
+ private long toTime;
+
+ // UI elements for input
+ private Button fBtnLmNotRem;
+ private Button fBtnLmLastWeek;
+ private Button fBtnLmPastMonth;
+ private Button fBtnLmPastYear;
+ private Button fBtnLmSpecified;
+ private BaseEditBrowseTextControl txtLmFrom;
+ private BaseEditBrowseTextControl txtLmTo;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.utils.AbstractSearchable#createAdvancedPart(org.eclipse.tcf.te.ui.search.TreeViewerSearchDialog, org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createAdvancedPart(TreeViewerSearchDialog dialog, Composite parent) {
+ SelectionListener l = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ optionChecked(e);
+ }
+ };
+ Composite modifiedComp = createSection(parent, Messages.FSModifiedSearchable_WhenModified);
+ modifiedComp.setLayout(new GridLayout(4, false));
+
+ fBtnLmNotRem = new Button(modifiedComp, SWT.RADIO);
+ fBtnLmNotRem.setText(Messages.FSModifiedSearchable_DontRemember);
+ fBtnLmNotRem.setSelection(true);
+ GridData data = new GridData();
+ data.horizontalSpan = 4;
+ fBtnLmNotRem.setLayoutData(data);
+ fBtnLmNotRem.addSelectionListener(l);
+
+ fBtnLmLastWeek = new Button(modifiedComp, SWT.RADIO);
+ fBtnLmLastWeek.setText(Messages.FSModifiedSearchable_LastWeek);
+ data = new GridData();
+ data.horizontalSpan = 4;
+ fBtnLmLastWeek.setLayoutData(data);
+ fBtnLmLastWeek.addSelectionListener(l);
+
+ fBtnLmPastMonth = new Button(modifiedComp, SWT.RADIO);
+ fBtnLmPastMonth.setText(Messages.FSModifiedSearchable_PastMonth);
+ data = new GridData();
+ data.horizontalSpan = 4;
+ fBtnLmPastMonth.setLayoutData(data);
+ fBtnLmPastMonth.addSelectionListener(l);
+
+ fBtnLmPastYear = new Button(modifiedComp, SWT.RADIO);
+ fBtnLmPastYear.setText(Messages.FSModifiedSearchable_PastYear);
+ data = new GridData();
+ data.horizontalSpan = 4;
+ fBtnLmPastYear.setLayoutData(data);
+ fBtnLmPastYear.addSelectionListener(l);
+
+ fBtnLmSpecified = new Button(modifiedComp, SWT.RADIO);
+ fBtnLmSpecified.setText(Messages.FSModifiedSearchable_SpecifyDates);
+ data = new GridData();
+ fBtnLmSpecified.setLayoutData(data);
+ fBtnLmSpecified.addSelectionListener(l);
+
+ Composite cmpFrom = new Composite(modifiedComp, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ cmpFrom.setLayout(layout);
+ data = new GridData();
+ cmpFrom.setLayoutData(data);
+
+ txtLmFrom = new BaseEditBrowseTextControl(null);
+ txtLmFrom.setIsGroup(false);
+ txtLmFrom.setHasHistory(false);
+ txtLmFrom.setHideBrowseButton(true);
+ txtLmFrom.setParentControlIsInnerPanel(true);
+ txtLmFrom.setupPanel(cmpFrom);
+ txtLmFrom.setEnabled(false);
+ txtLmFrom.setEditFieldValidator(new DateValidator());
+ Text text = (Text) txtLmFrom.getEditFieldControl();
+ text.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ datesModified();
+ }
+ });
+
+ Label label = new Label(modifiedComp, SWT.NONE);
+ label.setText(Messages.FSModifiedSearchable_ToDate);
+
+ Composite cmpTo = new Composite(modifiedComp, SWT.NONE);
+ layout = new GridLayout(2, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ cmpTo.setLayout(layout);
+ data = new GridData();
+ cmpTo.setLayoutData(data);
+
+ txtLmTo = new BaseEditBrowseTextControl(null);
+ txtLmTo.setIsGroup(false);
+ txtLmTo.setHasHistory(false);
+ txtLmTo.setHideBrowseButton(true);
+ txtLmTo.setParentControlIsInnerPanel(true);
+ txtLmTo.setupPanel(cmpTo);
+ txtLmTo.setEnabled(false);
+ txtLmTo.setEditFieldValidator(new DateValidator());
+ text = (Text) txtLmTo.getEditFieldControl();
+ text.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ datesModified();
+ }
+ });
+ }
+
+ /**
+ * The modified event of the date fields.
+ */
+ protected void datesModified() {
+ fireOptionChanged();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.utils.AbstractSearchable#isInputValid()
+ */
+ @Override
+ public boolean isInputValid() {
+ if(choice == OPTION_SPECIFIED && txtLmFrom != null && txtLmTo != null) {
+ boolean vFrom = txtLmFrom.isValid();
+ boolean vTo = txtLmTo.isValid();
+ if(vFrom) {
+ String fromText = txtLmFrom.getEditFieldControlText().trim();
+ this.fromTime = DateValidator.parseTimeInMillis(fromText);
+ }
+ if(vTo) {
+ String toText = txtLmTo.getEditFieldControlText().trim();
+ this.toTime = DateValidator.parseTimeInMillis(toText);
+ }
+ return vFrom && vTo;
+ }
+ return true;
+ }
+
+ /**
+ * The method handling the selection event.
+ *
+ * @param e The selection event.
+ */
+ protected void optionChecked(SelectionEvent e) {
+ Object src = e.getSource();
+ boolean specified = false;
+ if(src == fBtnLmNotRem) {
+ choice = OPTION_NOT_REMEMBER;
+ }
+ else if(src == fBtnLmLastWeek) {
+ choice = OPTION_LAST_WEEK;
+ }
+ else if(src == fBtnLmPastMonth) {
+ choice = OPTION_LAST_MONTH;
+ }
+ else if(src == fBtnLmPastYear) {
+ choice = OPTION_LAST_YEAR;
+ }
+ else if(src == fBtnLmSpecified) {
+ choice = OPTION_SPECIFIED;
+ specified = true;
+ }
+ if (txtLmFrom != null) txtLmFrom.setEnabled(specified);
+ if (txtLmTo != null) txtLmTo.setEnabled(specified);
+ fireOptionChanged();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchMatcher#match(java.lang.Object)
+ */
+ @Override
+ public boolean match(Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ long now = System.currentTimeMillis();
+ switch (choice) {
+ case OPTION_NOT_REMEMBER:
+ return true;
+ case OPTION_LAST_WEEK:
+ return node.attr.mtime > now - WEEK;
+ case OPTION_LAST_MONTH:
+ return node.attr.mtime > now - MONTH;
+ case OPTION_LAST_YEAR:
+ return node.attr.mtime > now - YEAR;
+ case OPTION_SPECIFIED:
+ return node.attr.mtime >= fromTime && node.attr.mtime < toTime;
+ }
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSSizeSearchable.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSSizeSearchable.java
new file mode 100644
index 000000000..fbd42c2ce
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSSizeSearchable.java
@@ -0,0 +1,255 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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.tcf.filesystem.ui.internal.search;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.controls.BaseEditBrowseTextControl;
+import org.eclipse.tcf.te.ui.search.TreeViewerSearchDialog;
+
+/**
+ * The searchable that provides a UI to collect and test
+ * the size of a file during searching.
+ */
+public class FSSizeSearchable extends FSBaseSearchable {
+ // Constant values of size options
+ private static final int OPTION_NOT_REMEMBER = 0;
+ private static final int OPTION_SIZE_SMALL = 1;
+ private static final int OPTION_SIZE_MEDIUM = 2;
+ private static final int OPTION_SIZE_LARGE = 3;
+ private static final int OPTION_SIZE_SPECIFIED = 4;
+
+ // Constant values of different size unit, used for matching purpose.
+ private static final long KB = 1024;
+ private static final long MB = 1024 * KB;
+
+ private static final long SIZE_SMALL = 100 * KB;
+ private static final long SIZE_MEDIUM = 1*MB;
+
+ // The choice selected
+ private int choice;
+ // The lower bound of size
+ private int lowerSize;
+ // The upper bound of size
+ private int upperSize;
+
+ // UI elements for input
+ private Button fBtnSizeNotRem;
+ private Button fBtnSizeSmall;
+ private Button fBtnSizeMedium;
+ private Button fBtnSizeLarge;
+ private Button fBtnSizeSpecified;
+ private BaseEditBrowseTextControl txtSizeFrom;
+ private BaseEditBrowseTextControl txtSizeTo;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.utils.AbstractSearchable#createAdvancedPart(org.eclipse.tcf.te.ui.search.TreeViewerSearchDialog, org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createAdvancedPart(TreeViewerSearchDialog dialog, Composite parent) {
+ SelectionListener l = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ optionChecked(e);
+ }
+ };
+
+ Composite sizeComp = createSection(parent, Messages.FSSizeSearchable_WhatSize);
+ sizeComp.setLayout(new GridLayout(5, false));
+
+ fBtnSizeNotRem = new Button(sizeComp, SWT.RADIO);
+ fBtnSizeNotRem.setText(Messages.FSSizeSearchable_DontRemember);
+ fBtnSizeNotRem.setSelection(true);
+ GridData data = new GridData();
+ data.horizontalSpan = 5;
+ fBtnSizeNotRem.setLayoutData(data);
+ fBtnSizeNotRem.addSelectionListener(l);
+
+ fBtnSizeSmall = new Button(sizeComp, SWT.RADIO);
+ fBtnSizeSmall.setText(Messages.FSSizeSearchable_Small);
+ data = new GridData();
+ data.horizontalSpan = 5;
+ fBtnSizeSmall.setLayoutData(data);
+ fBtnSizeSmall.addSelectionListener(l);
+
+ fBtnSizeMedium = new Button(sizeComp, SWT.RADIO);
+ fBtnSizeMedium.setText(Messages.FSSizeSearchable_Medium);
+ data = new GridData();
+ data.horizontalSpan = 5;
+ fBtnSizeMedium.setLayoutData(data);
+ fBtnSizeMedium.addSelectionListener(l);
+
+ fBtnSizeLarge = new Button(sizeComp, SWT.RADIO);
+ fBtnSizeLarge.setText(Messages.FSSizeSearchable_Large);
+ data = new GridData();
+ data.horizontalSpan = 5;
+ fBtnSizeLarge.setLayoutData(data);
+ fBtnSizeLarge.addSelectionListener(l);
+
+ fBtnSizeSpecified = new Button(sizeComp, SWT.RADIO);
+ fBtnSizeSpecified.setText(Messages.FSSizeSearchable_SpecifySize);
+ data = new GridData();
+ fBtnSizeSpecified.setLayoutData(data);
+ fBtnSizeSpecified.addSelectionListener(l);
+
+ Composite cmpFrom = new Composite(sizeComp, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ cmpFrom.setLayout(layout);
+ data = new GridData();
+ cmpFrom.setLayoutData(data);
+
+ txtSizeFrom = new BaseEditBrowseTextControl(null);
+ txtSizeFrom.setIsGroup(false);
+ txtSizeFrom.setHasHistory(false);
+ txtSizeFrom.setHideBrowseButton(true);
+ txtSizeFrom.setParentControlIsInnerPanel(true);
+ txtSizeFrom.setupPanel(cmpFrom);
+ txtSizeFrom.setEnabled(false);
+ txtSizeFrom.setEditFieldValidator(new SizeValidator());
+ Text text = (Text) txtSizeFrom.getEditFieldControl();
+ text.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ sizeModified();
+ }
+ });
+
+
+ Label label = new Label(sizeComp, SWT.NONE);
+ label.setText(Messages.FSSizeSearchable_ToText);
+
+ Composite cmpTo = new Composite(sizeComp, SWT.NONE);
+ layout = new GridLayout(2, false);
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.horizontalSpacing = 0;
+ layout.verticalSpacing = 0;
+ cmpTo.setLayout(layout);
+ data = new GridData();
+ cmpTo.setLayoutData(data);
+
+ txtSizeTo = new BaseEditBrowseTextControl(null);
+ txtSizeTo.setIsGroup(false);
+ txtSizeTo.setHasHistory(false);
+ txtSizeTo.setHideBrowseButton(true);
+ txtSizeTo.setParentControlIsInnerPanel(true);
+ txtSizeTo.setupPanel(cmpTo);
+ txtSizeTo.setEnabled(false);
+ txtSizeTo.setEditFieldValidator(new SizeValidator());
+ text = (Text) txtSizeTo.getEditFieldControl();
+ text.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ sizeModified();
+ }
+ });
+
+ label = new Label(sizeComp, SWT.NONE);
+ label.setText(Messages.FSSizeSearchable_KBS);
+ }
+
+ /**
+ * The modified event of the size fields.
+ */
+ protected void sizeModified() {
+ fireOptionChanged();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.utils.AbstractSearchable#isInputValid()
+ */
+ @Override
+ public boolean isInputValid() {
+ if(choice == OPTION_SIZE_SPECIFIED && txtSizeFrom != null && txtSizeTo != null) {
+ boolean vFrom = txtSizeFrom.isValid();
+ boolean vTo = txtSizeTo.isValid();
+ if(vFrom) {
+ String fromText = txtSizeFrom.getEditFieldControlText();
+ this.lowerSize = Integer.parseInt(fromText);
+ }
+ if(vTo) {
+ String toText = txtSizeTo.getEditFieldControlText();
+ this.upperSize = Integer.parseInt(toText);
+ }
+ return vFrom && vTo;
+ }
+ return true;
+ }
+
+ /**
+ * The method handling the selection event.
+ *
+ * @param e The selection event.
+ */
+ protected void optionChecked(SelectionEvent e) {
+ Object src = e.getSource();
+ boolean specified = false;
+ if(src == fBtnSizeNotRem) {
+ choice = OPTION_NOT_REMEMBER;
+ }
+ else if(src == fBtnSizeSmall) {
+ choice = OPTION_SIZE_SMALL;
+ }
+ else if(src == fBtnSizeMedium) {
+ choice = OPTION_SIZE_MEDIUM;
+ }
+ else if(src == fBtnSizeLarge) {
+ choice = OPTION_SIZE_LARGE;
+ }
+ else if(src == fBtnSizeSpecified) {
+ choice = OPTION_SIZE_SPECIFIED;
+ specified = true;
+ }
+ if (txtSizeFrom != null) txtSizeFrom.setEnabled(specified);
+ if (txtSizeTo != null) txtSizeTo.setEnabled(specified);
+ fireOptionChanged();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchMatcher#match(java.lang.Object)
+ */
+ @Override
+ public boolean match(Object element) {
+ if (element instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) element;
+ switch (choice) {
+ case OPTION_NOT_REMEMBER:
+ return true;
+ case OPTION_SIZE_SMALL:
+ return node.attr.size <= SIZE_SMALL;
+ case OPTION_SIZE_MEDIUM:
+ return node.attr.size <= SIZE_MEDIUM;
+ case OPTION_SIZE_LARGE:
+ return node.attr.size > SIZE_MEDIUM;
+ case OPTION_SIZE_SPECIFIED:
+ return node.attr.size >= lowerSize && node.attr.size < upperSize;
+ }
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSTreeNodeMatcher.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSTreeNodeMatcher.java
new file mode 100644
index 000000000..3d2c80d9a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSTreeNodeMatcher.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2014 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.tcf.filesystem.ui.internal.search;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.ui.interfaces.ISearchMatcher;
+import org.eclipse.tcf.te.ui.utils.StringMatcher;
+/**
+ * The ISearchMatcher implementation for FSTreeNode.
+ */
+public class FSTreeNodeMatcher implements ISearchMatcher {
+ // Whether it is case sensitive
+ private boolean fCaseSensitive;
+ // Whether it is precise matching.
+ private boolean fMatchPrecise;
+ // The string matcher used for matching.
+ private StringMatcher fStringMatcher;
+ // The current selected target simulator index.
+ private int fTargetType;
+ // The current target names.
+ private String fTargetName;
+ // The flag if system files should be included
+ private boolean fIncludeSystem;
+ // The flag if hidden files should be included
+ private boolean fIncludeHidden;
+
+ /**
+ * Constructor with different option parameters.
+ *
+ * @param caseSensitive Option of case sensitive
+ * @param matchPrecise Option of precise matching
+ * @param targetType Option of the target simulator
+ * @param targetName Option of the target name
+ * @param includeSystem Option if system files be included
+ * @param includeHidden Option if hidden files be included
+ */
+ public FSTreeNodeMatcher(boolean caseSensitive, boolean matchPrecise,
+ int targetType, String targetName, boolean includeSystem, boolean includeHidden) {
+ fCaseSensitive = caseSensitive;
+ fTargetName = targetName;
+ fMatchPrecise = matchPrecise;
+ if (!fMatchPrecise) {
+ fStringMatcher = new StringMatcher(fTargetName, !fCaseSensitive, false);
+ }
+ fTargetType = targetType;
+ fIncludeSystem = includeSystem;
+ fIncludeHidden = includeHidden;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchMatcher#match(java.lang.Object)
+ */
+ @Override
+ public boolean match(Object context) {
+ if (context == null) return false;
+ if (context instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) context;
+ if(fTargetType == 1 && !node.isFile() || fTargetType == 2 && !node.isDirectory()) return false;
+ if(!fIncludeSystem && node.isSystem()) return false;
+ if(!fIncludeHidden && node.isHidden()) return false;
+ String text = node.name;
+ if (text != null) {
+ if (fMatchPrecise) {
+ return fCaseSensitive ? text.equals(fTargetName) : text.equalsIgnoreCase(fTargetName);
+ }
+ return fStringMatcher.match(text);
+ }
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSTreeNodeSearchable.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSTreeNodeSearchable.java
new file mode 100644
index 000000000..b75fb2e0c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/FSTreeNodeSearchable.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2013 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.tcf.filesystem.ui.internal.search;
+
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.utils.CompositeSearchable;
+
+/**
+ * The ISearchable adapter for a FSTreeNode which creates a UI for the user to
+ * input the matching condition and returns a matcher to do the matching.
+ */
+public class FSTreeNodeSearchable extends CompositeSearchable {
+
+ /**
+ * Create an instance with the specified node.
+ *
+ * @param node The directory node.
+ */
+ public FSTreeNodeSearchable(FSTreeNode node) {
+ super();
+ setSearchables(new FSGeneralSearchable(node), new FSModifiedSearchable(), new FSSizeSearchable());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getSearchTitle(java.lang.Object)
+ */
+ @Override
+ public String getSearchTitle(Object rootElement) {
+ return Messages.FSTreeNodeSearchable_FindFilesAndFolders;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getSearchMessage(java.lang.Object)
+ */
+ @Override
+ public String getSearchMessage(Object rootElement) {
+ String message = Messages.FSTreeNodeSearchable_FindMessage;
+ FSTreeNode rootNode = (FSTreeNode) rootElement;
+ String rootName = getElementName(rootElement);
+ if (rootNode != null && !rootNode.isSystemRoot()) rootName = "\"" + rootName + "\""; //$NON-NLS-1$//$NON-NLS-2$
+ message = NLS.bind(message, rootName);
+ return message;
+ }
+
+ /**
+ * Get a name representation for each file node.
+ *
+ * @param rootElement The root element whose name is being retrieved.
+ * @return The node's name or an expression for the file system.
+ */
+ private String getElementName(Object rootElement) {
+ if(rootElement == null) {
+ return Messages.FSTreeNodeSearchable_SelectedFileSystem;
+ }
+ FSTreeNode rootNode = (FSTreeNode) rootElement;
+ if(rootNode.isSystemRoot()) {
+ return Messages.FSTreeNodeSearchable_SelectedFileSystem;
+ }
+ return rootNode.name;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getElementText(java.lang.Object)
+ */
+ @Override
+ public String getElementText(Object element) {
+ return getElementName(element);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.interfaces.ISearchable#getCustomMessage(java.lang.Object, java.lang.String)
+ */
+ @Override
+ public String getCustomMessage(Object rootElement, String key) {
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/NameValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/NameValidator.java
new file mode 100644
index 000000000..821e2e2df
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/NameValidator.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.search;
+
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.controls.validator.Validator;
+
+/**
+ * The validator used to validate the name entered in the search dialog.
+ */
+public class NameValidator extends Validator {
+ /**
+ * Constructor
+ */
+ public NameValidator() {
+ super(ATTR_MANDATORY);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.controls.validator.Validator#isValid(java.lang.String)
+ */
+ @Override
+ public boolean isValid(String newText) {
+ init();
+ boolean valid = newText != null && newText.trim().length() > 0;
+ if(!valid) {
+ if (isAttribute(ATTR_MANDATORY)) {
+ setMessage(Messages.NameValidator_InfoPrompt, INFORMATION);
+ }
+ }
+ return valid;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/SizeValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/SizeValidator.java
new file mode 100644
index 000000000..0877e3b4b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/search/SizeValidator.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.search;
+
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.controls.validator.NumberValidator;
+import org.eclipse.tcf.te.ui.controls.validator.Validator;
+
+/**
+ * The validator used to validate the size entered in the search dialog.
+ */
+public class SizeValidator extends NumberValidator {
+ /**
+ * Constructor
+ */
+ public SizeValidator() {
+ super(Validator.ATTR_MANDATORY, 0, -1);
+ setMessageText(INFO_MISSING_VALUE, Messages.SizeValidator_InfoPrompt);
+ setMessageText(ERROR_INVALID_VALUE, Messages.SizeValidator_ErrorIncorrectFormat);
+ setMessageText(ERROR_INVALID_RANGE, Messages.SizeValidator_ErrorSizeOutofRange);
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/BasicFileSection.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/BasicFileSection.java
new file mode 100644
index 000000000..9a78d3b8c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/BasicFileSection.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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.tcf.filesystem.ui.internal.tabbed;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.swt.SWTControlUtil;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * The section that displays the basic information of a file.
+ */
+public class BasicFileSection extends BasicFolderSecti