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 BasicFolderSection {
+
+ // The text field for the size of the file.
+ protected Text sizeText;
+ // The text field for the access time of the file.
+ protected Text accessedText;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.tabbed.BasicFolderSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ @Override
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ sizeText = createTextField(null, Messages.GeneralInformationPage_Size);
+ accessedText = createTextField(sizeText, Messages.GeneralInformationPage_Accessed);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.tabbed.BasicFolderSection#refresh()
+ */
+ @Override
+ public void refresh() {
+ SWTControlUtil.setText(sizeText, clone != null ? getSizeText(clone.attr.size) : ""); //$NON-NLS-1$
+ SWTControlUtil.setText(accessedText, clone != null ? getDateText(clone.attr.atime) : ""); //$NON-NLS-1$
+ super.refresh();
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/BasicFolderSection.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/BasicFolderSection.java
new file mode 100644
index 000000000..00748f2ec
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/BasicFolderSection.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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.tabbed;
+
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.util.Date;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.adapters.FSTreeNodeAdapterFactory.FSTreeNodePeerNodeProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProvider;
+import org.eclipse.tcf.te.tcf.ui.tabbed.BaseTitledSection;
+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 folder.
+ */
+public class BasicFolderSection extends BaseTitledSection {
+ // The formatter for the size of a file.
+ private static final DecimalFormat SIZE_FORMAT = new DecimalFormat();
+
+ // The original node to be displayed and edited.
+ protected FSTreeNode node;
+ // The copy used to be edited.
+ protected FSTreeNode clone;
+
+ // The text for the name of the node.
+ protected Text nameText;
+ // The text for the type of the node.
+ protected Text typeText;
+ // The text for the location of the node.
+ protected Text locationText;
+ // The text for the modified time of the node.
+ protected Text modifiedText;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ @Override
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ nameText = createTextField(null, Messages.GeneralInformationPage_Name);
+ typeText = createTextField(nameText, Messages.GeneralInformationPage_Type);
+ locationText = createWrapTextField(typeText, Messages.GeneralInformationPage_Location);
+ modifiedText = createTextField(locationText, Messages.GeneralInformationPage_Modified);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#updateData(org.eclipse.tcf.te.ui.interfaces.IPropertyChangeProvider)
+ */
+ @Override
+ protected void updateInput(IPeerNodeProvider input) {
+ Assert.isTrue(input instanceof FSTreeNodePeerNodeProvider);
+ this.node = ((FSTreeNodePeerNodeProvider)input).getFSTreeNode();
+ this.clone = (FSTreeNode) node.clone();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ @Override
+ public void refresh() {
+ SWTControlUtil.setText(nameText, clone != null ? clone.name : ""); //$NON-NLS-1$
+ SWTControlUtil.setText(typeText, clone != null ? clone.getFileType() : ""); //$NON-NLS-1$
+ String location = clone == null || clone.isRoot() ? Messages.GeneralInformationPage_Computer : clone.getLocation();
+ SWTControlUtil.setText(locationText, location);
+ SWTControlUtil.setText(modifiedText, clone != null && clone.attr != null ? getDateText(clone.attr.mtime) : ""); //$NON-NLS-1$
+ super.refresh();
+ }
+
+ /**
+ * 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));
+ }
+
+ /**
+ * 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));
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#getText()
+ */
+ @Override
+ protected String getText() {
+ return Messages.BasicFolderSection_BasicInfoText;
+ }
+} \ 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/tabbed/FileFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/FileFilter.java
new file mode 100644
index 000000000..9ce004377
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/FileFilter.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.internal.tabbed;
+
+import org.eclipse.jface.viewers.IFilter;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The filter to test if a object is a file.
+ */
+public class FileFilter implements IFilter {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IFilter#select(java.lang.Object)
+ */
+ @Override
+ public boolean select(Object toTest) {
+ if(toTest instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) toTest;
+ return !node.isSystemRoot() && node.isFile();
+ }
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/FolderFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/FolderFilter.java
new file mode 100644
index 000000000..55b4b3e9c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/FolderFilter.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.internal.tabbed;
+
+import org.eclipse.jface.viewers.IFilter;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The filter to select the folder from the file system.
+ */
+public class FolderFilter implements IFilter {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IFilter#select(java.lang.Object)
+ */
+ @Override
+ public boolean select(Object toTest) {
+ if(toTest instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) toTest;
+ return !node.isSystemRoot() && node.isDirectory();
+ }
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/LinuxFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/LinuxFilter.java
new file mode 100644
index 000000000..ffb5b6b78
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/LinuxFilter.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.internal.tabbed;
+
+import org.eclipse.jface.viewers.IFilter;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * A filter to test if a object is a linux (non-Windows) node.
+ */
+public class LinuxFilter implements IFilter {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IFilter#select(java.lang.Object)
+ */
+ @Override
+ public boolean select(Object toTest) {
+ if(toTest instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) toTest;
+ return !node.isSystemRoot() && !node.isWindowsNode();
+ }
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/LinuxPermissionsSection.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/LinuxPermissionsSection.java
new file mode 100644
index 000000000..2178562eb
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/LinuxPermissionsSection.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * 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.tabbed;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.adapters.FSTreeNodeAdapterFactory.FSTreeNodePeerNodeProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProvider;
+import org.eclipse.tcf.te.tcf.ui.tabbed.BaseTitledSection;
+import org.eclipse.tcf.te.ui.swt.SWTControlUtil;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * The property section for displaying the permissions of a linux file/folder.
+ */
+public class LinuxPermissionsSection extends BaseTitledSection {
+ // The original node.
+ protected FSTreeNode node;
+ // The copy node to be edited.
+ protected FSTreeNode clone;
+ // The button of "Permissions"
+ protected Button[] btnPermissions;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ @Override
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+ btnPermissions = new Button[9];
+ Composite comp1 = createPermissionGroup(null, composite, 0, Messages.PermissionsGroup_UserPermissions);
+ Composite comp2 = createPermissionGroup(comp1, composite, 3, Messages.PermissionsGroup_GroupPermissions);
+ createPermissionGroup(comp2, composite, 6, Messages.PermissionsGroup_OtherPermissions);
+ }
+
+ /**
+ * Create a permission group for a role, such as a user, a group or others.
+ *
+ * @param prev The previous permission group to align with.
+ * @param parent The parent composite.
+ * @param bit The permission bit index.
+ * @param header The group's header label.
+ */
+ protected Composite createPermissionGroup(Composite prev, Composite parent, int bit, String header) {
+ Composite group = getWidgetFactory().createFlatFormComposite(parent);
+ FormLayout layout = (FormLayout) group.getLayout();
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.spacing = 0;
+
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, STANDARD_LABEL_WIDTH);
+ data.right = new FormAttachment(100, 0);
+ if (prev == null) data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ else data.top = new FormAttachment(prev, ITabbedPropertyConstants.VSPACE);
+ group.setLayoutData(data);
+
+ createPermissionButton(Messages.PermissionsGroup_Readable, bit, group);
+ createPermissionButton(Messages.PermissionsGroup_Writable, bit + 1, group);
+ createPermissionButton(Messages.PermissionsGroup_Executable, bit + 2, group);
+
+ CLabel groupLabel = getWidgetFactory().createCLabel(parent, header);
+ data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(group, -ITabbedPropertyConstants.HSPACE);
+ data.top = new FormAttachment(group, 0, SWT.TOP);
+ groupLabel.setLayoutData(data);
+
+ return 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] = getWidgetFactory().createButton(parent, label, SWT.CHECK);
+ FormData data = new FormData();
+ if ((index % 3) == 0) data.left = new FormAttachment(0, 0);
+ else data.left = new FormAttachment(btnPermissions[index - 1], ITabbedPropertyConstants.HSPACE);
+ data.right = new FormAttachment(((index % 3) + 1) * 33, 0);
+ if ((index % 3) == 0) data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ else data.top = new FormAttachment(btnPermissions[index - 1], 0, SWT.CENTER);
+ btnPermissions[index].setLayoutData(data);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#updateData(org.eclipse.tcf.te.ui.interfaces.IPropertyChangeProvider)
+ */
+ @Override
+ protected void updateInput(IPeerNodeProvider input) {
+ Assert.isTrue(input instanceof FSTreeNodePeerNodeProvider);
+ this.node = ((FSTreeNodePeerNodeProvider)input).getFSTreeNode();
+ this.clone = (FSTreeNode) node.clone();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ @Override
+ public void refresh() {
+ for (int i = 0; i < 9; i++) {
+ final int bit = 1 << (8 - i);
+ final boolean on = clone != null ? (clone.attr.permissions & bit) != 0 : false;
+ SWTControlUtil.setSelection(btnPermissions[i], on);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#getText()
+ */
+ @Override
+ protected String getText() {
+ return Messages.LinuxPermissionsSection_Permissions;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsAttributesCESection.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsAttributesCESection.java
new file mode 100644
index 000000000..1c73246b9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsAttributesCESection.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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.tabbed;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+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.internal.adapters.FSTreeNodeAdapterFactory.FSTreeNodePeerNodeProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProvider;
+import org.eclipse.tcf.te.tcf.ui.tabbed.BaseTitledSection;
+import org.eclipse.tcf.te.ui.swt.SWTControlUtil;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * The property section for compress and encrypt attributes of a file/folder on Windows.
+ */
+public class WindowsAttributesCESection extends BaseTitledSection {
+
+ // The original node.
+ protected FSTreeNode node;
+
+ // The check box to display the compress attribute.
+ protected Button compressButton;
+ // The check box to display the encrypt attributes.
+ protected Button encryptButton;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ @Override
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+
+ compressButton = getWidgetFactory().createButton(composite, Messages.AdvancedAttributesDialog_Compress, SWT.CHECK);
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ compressButton.setLayoutData(data);
+
+ encryptButton = getWidgetFactory().createButton(composite, Messages.AdvancedAttributesDialog_Compress, SWT.CHECK);
+ data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(compressButton, ITabbedPropertyConstants.VSPACE);
+ encryptButton.setLayoutData(data);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#updateData(org.eclipse.tcf.te.ui.interfaces.IPropertyChangeProvider)
+ */
+ @Override
+ protected void updateInput(IPeerNodeProvider input) {
+ Assert.isTrue(input instanceof FSTreeNodePeerNodeProvider);
+ this.node = ((FSTreeNodePeerNodeProvider)input).getFSTreeNode();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ @Override
+ public void refresh() {
+ boolean on = node != null ? node.isWin32AttrOn(IWindowsFileAttributes.FILE_ATTRIBUTE_COMPRESSED) : false;
+ SWTControlUtil.setSelection(compressButton, on);
+ on = node != null ? node.isWin32AttrOn(IWindowsFileAttributes.FILE_ATTRIBUTE_ENCRYPTED) : false;
+ SWTControlUtil.setSelection(encryptButton, on);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#getText()
+ */
+ @Override
+ protected String getText() {
+ return Messages.AdvancedAttributesDialog_CompressEncrypt;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsAttributesSection.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsAttributesSection.java
new file mode 100644
index 000000000..dfc7a701c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsAttributesSection.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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.tabbed;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.internal.adapters.FSTreeNodeAdapterFactory.FSTreeNodePeerNodeProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProvider;
+import org.eclipse.tcf.te.tcf.ui.tabbed.BaseTitledSection;
+import org.eclipse.tcf.te.ui.swt.SWTControlUtil;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * The property section for the attributes of a file/folder on Windows.
+ */
+public class WindowsAttributesSection extends BaseTitledSection {
+ // The original node.
+ protected FSTreeNode node;
+ // The copy node.
+ protected FSTreeNode clone;
+ // The check box for "Read Only" attribute.
+ protected Button readOnlyButton;
+ // The check box for "Hidden" attribute.
+ protected Button hiddenButton;
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ @Override
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+
+ readOnlyButton = getWidgetFactory().createButton(composite, Messages.GeneralInformationPage_ReadOnly, SWT.CHECK);
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, ITabbedPropertyConstants.HMARGIN );
+ data.right = new FormAttachment(50, 0);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ readOnlyButton.setLayoutData(data);
+
+ hiddenButton = getWidgetFactory().createButton(composite, Messages.GeneralInformationPage_Hidden, SWT.CHECK);
+ data = new FormData();
+ data.left = new FormAttachment(readOnlyButton, ITabbedPropertyConstants.HSPACE);
+ data.right = new FormAttachment(100, -ITabbedPropertyConstants.HMARGIN );
+ data.top = new FormAttachment(readOnlyButton, 0, SWT.CENTER);
+ hiddenButton.setLayoutData(data);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#updateData(org.eclipse.tcf.te.ui.interfaces.IPropertyChangeProvider)
+ */
+ @Override
+ protected void updateInput(IPeerNodeProvider input) {
+ Assert.isTrue(input instanceof FSTreeNodePeerNodeProvider);
+ this.node = ((FSTreeNodePeerNodeProvider)input).getFSTreeNode();
+ this.clone = (FSTreeNode) node.clone();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ @Override
+ public void refresh() {
+ SWTControlUtil.setSelection(readOnlyButton, clone != null ? clone.isReadOnly() : false);
+ SWTControlUtil.setSelection(hiddenButton, clone != null ? clone.isHidden(): false);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#getText()
+ */
+ @Override
+ protected String getText() {
+ return Messages.WindowsAttributesSection_Attributes;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFileAISection.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFileAISection.java
new file mode 100644
index 000000000..6ac4eaa44
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFileAISection.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.tabbed;
+
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * The property section to display the file's archive and index attributes on Windows.
+ */
+public class WindowsFileAISection extends WindowsFolderAISection {
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.tabbed.WindowsFolderAISection#getAchiveText()
+ */
+ @Override
+ protected String getAchiveText() {
+ return Messages.AdvancedAttributesDialog_FileArchive;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.tabbed.WindowsFolderAISection#getIndexText()
+ */
+ @Override
+ protected String getIndexText() {
+ return Messages.AdvancedAttributesDialog_IndexFile;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFileFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFileFilter.java
new file mode 100644
index 000000000..d2694c893
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFileFilter.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.internal.tabbed;
+
+import org.eclipse.jface.viewers.IFilter;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The filter to test if a object is a Windows file.
+ */
+public class WindowsFileFilter implements IFilter {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IFilter#select(java.lang.Object)
+ */
+ @Override
+ public boolean select(Object toTest) {
+ if(toTest instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) toTest;
+ return !node.isSystemRoot() && node.isWindowsNode() && node.isFile();
+ }
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFilter.java
new file mode 100644
index 000000000..85b53dc36
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFilter.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.internal.tabbed;
+
+import org.eclipse.jface.viewers.IFilter;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The filter to test if a object is a Windows node.
+ */
+public class WindowsFilter implements IFilter {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IFilter#select(java.lang.Object)
+ */
+ @Override
+ public boolean select(Object toTest) {
+ if(toTest instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) toTest;
+ return !node.isSystemRoot() && node.isWindowsNode() && (node.isFile() || node.isDirectory());
+ }
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFolderAISection.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFolderAISection.java
new file mode 100644
index 000000000..703f33ed9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFolderAISection.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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.tabbed;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+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.internal.adapters.FSTreeNodeAdapterFactory.FSTreeNodePeerNodeProvider;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNodeProvider;
+import org.eclipse.tcf.te.tcf.ui.tabbed.BaseTitledSection;
+import org.eclipse.tcf.te.ui.swt.SWTControlUtil;
+import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
+
+/**
+ * The property section to display a folder's archive and index attributes on Windows.
+ */
+public class WindowsFolderAISection extends BaseTitledSection {
+
+ // The original node.
+ protected FSTreeNode node;
+
+ // The check box for archive attribute.
+ protected Button archiveButton;
+ // The check box for index attribute.
+ protected Button indexButton;
+
+ /*
+ * (non-Javadoc)
+ * @see
+ * org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#createControls(org.eclipse.swt.widgets
+ * .Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
+ */
+ @Override
+ public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
+ super.createControls(parent, aTabbedPropertySheetPage);
+
+ archiveButton = getWidgetFactory().createButton(composite, getAchiveText(), SWT.CHECK);
+ FormData data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
+ archiveButton.setLayoutData(data);
+
+ indexButton = getWidgetFactory().createButton(composite, getIndexText(), SWT.CHECK);
+ data = new FormData();
+ data.left = new FormAttachment(0, 0);
+ data.right = new FormAttachment(100, 0);
+ data.top = new FormAttachment(archiveButton, ITabbedPropertyConstants.VSPACE);
+ indexButton.setLayoutData(data);
+ }
+
+ /**
+ * Get the archive's label text.
+ *
+ * @return The archive's label text.
+ */
+ protected String getAchiveText() {
+ return Messages.AdvancedAttributesDialog_FolderArchive;
+ }
+
+ /**
+ * Get the index's label text.
+ *
+ * @return The index's label text.
+ */
+ protected String getIndexText() {
+ return Messages.AdvancedAttributesDialog_IndexFolder;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#updateData(org.eclipse.tcf.te.ui.interfaces.IPropertyChangeProvider)
+ */
+ @Override
+ protected void updateInput(IPeerNodeProvider input) {
+ Assert.isTrue(input instanceof FSTreeNodePeerNodeProvider);
+ this.node = ((FSTreeNodePeerNodeProvider)input).getFSTreeNode();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
+ */
+ @Override
+ public void refresh() {
+ boolean on = node != null ? node.isWin32AttrOn(IWindowsFileAttributes.FILE_ATTRIBUTE_ARCHIVE) : false;
+ SWTControlUtil.setSelection(archiveButton, on);
+ on = node != null ? !node.isWin32AttrOn(IWindowsFileAttributes.FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) : false;
+ SWTControlUtil.setSelection(indexButton, on);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.views.tabbed.BaseTitledSection#getText()
+ */
+ @Override
+ protected String getText() {
+ return Messages.AdvancedAttributesDialog_ArchiveIndex;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFolderFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFolderFilter.java
new file mode 100644
index 000000000..84d8d1553
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/tabbed/WindowsFolderFilter.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.internal.tabbed;
+
+import org.eclipse.jface.viewers.IFilter;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+
+/**
+ * The filter to test if the object is a Windows folder.
+ */
+public class WindowsFolderFilter implements IFilter {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IFilter#select(java.lang.Object)
+ */
+ @Override
+ public boolean select(Object toTest) {
+ if(toTest instanceof FSTreeNode) {
+ FSTreeNode node = (FSTreeNode) toTest;
+ return !node.isSystemRoot() && node.isWindowsNode() && node.isDirectory();
+ }
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/CachePropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/CachePropertyTester.java
new file mode 100644
index 000000000..7c54c999d
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/CachePropertyTester.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
+ * William Chen (Wind River)- [345552] Edit the remote files with a proper editor
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.internal.testers;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.tcf.te.tcf.filesystem.ui.activator.UIPlugin;
+
+/**
+ * Provide a tester to test if the current auto saving mode is on or off.
+ *
+ */
+public class CachePropertyTester extends PropertyTester {
+ /**
+ * Create a cache property tester.
+ */
+ public CachePropertyTester() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if(property.equals("isAutoSavingOn")){ //$NON-NLS-1$
+ return UIPlugin.isAutoSaving();
+ }
+ return false;
+ }
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/ClipboardPropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/ClipboardPropertyTester.java
new file mode 100644
index 000000000..b01558655
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/ClipboardPropertyTester.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * 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.testers;
+
+import java.util.List;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+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.FsClipboard;
+/**
+ * Provide a tester to test if the paste operation is enabled.
+ */
+public class ClipboardPropertyTester extends PropertyTester {
+
+ /**
+ * Create an instance.
+ */
+ public ClipboardPropertyTester() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ Assert.isTrue(receiver instanceof IStructuredSelection);
+ if (property.equals("canPaste")) { //$NON-NLS-1$
+ FsClipboard cb = UIPlugin.getClipboard();
+ if (!cb.isEmpty()) {
+ List<FSTreeNode> nodes = cb.getFiles();
+ boolean moving = cb.isCutOp();
+ boolean copying = cb.isCopyOp();
+ List<FSTreeNode> selection = ((IStructuredSelection) receiver).toList();
+ FSTreeNode hovered = null;
+ Assert.isTrue(!selection.isEmpty());
+ if (selection.size() == 1) {
+ FSTreeNode node = selection.get(0);
+ if (node.isDirectory() && moving) {
+ hovered = node;
+ }
+ else if (node.isRoot()) {
+ hovered = node;
+ }
+ else {
+ hovered = node.getParent();
+ }
+ }
+ else {
+ for (FSTreeNode node : selection) {
+ if (hovered == null) hovered = node.getParent();
+ else if (hovered != node.getParent()) return false;
+ }
+ }
+ if (hovered != null && 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.getParent() == hovered || node.isAncestorOf(hovered)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ }
+ else {
+ Clipboard clipboard = cb.getSystemClipboard();
+ Object contents = clipboard.getContents(FileTransfer.getInstance());
+ if (contents != null) {
+ List<FSTreeNode> selection = ((IStructuredSelection) receiver).toList();
+ FSTreeNode hovered = null;
+ Assert.isTrue(!selection.isEmpty());
+ if (selection.size() == 1) {
+ FSTreeNode node = selection.get(0);
+ if (node.isFile()) {
+ hovered = node.getParent();
+ }
+ else {
+ hovered = node;
+ }
+ }
+ else {
+ for (FSTreeNode node : selection) {
+ if (hovered == null) hovered = node.getParent();
+ else if (hovered != node.getParent()) return false;
+ }
+ }
+ if (hovered != null && hovered.isDirectory() && hovered.isWritable()) {
+ return true;
+ }
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/EditorActivationEventPropertyTester.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/EditorActivationEventPropertyTester.java
new file mode 100644
index 000000000..0f4259f13
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/testers/EditorActivationEventPropertyTester.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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.testers;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
+
+/**
+ * The property tester of a ColumnViewerEditorActivationEvent.
+ * The properties include "isEditorActivation" which calculates
+ * if the event will trigger a cell editing action.
+ */
+public class EditorActivationEventPropertyTester extends PropertyTester {
+
+ /**
+ * Create an instance.
+ */
+ public EditorActivationEventPropertyTester() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String, java.lang.Object[], java.lang.Object)
+ */
+ @Override
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ Assert.isTrue(receiver instanceof ColumnViewerEditorActivationEvent);
+ ColumnViewerEditorActivationEvent event = (ColumnViewerEditorActivationEvent) receiver;
+ if (property.equals("isEditorActivation")) { //$NON-NLS-1$
+ return event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
+ }
+ return false;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/FolderValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/FolderValidator.java
new file mode 100644
index 000000000..6ca8422bc
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/FolderValidator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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.wizards;
+
+import org.eclipse.jface.dialogs.IMessageProvider;
+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.controls.validator.Validator;
+
+/**
+ * The validator to validate the path of the parent directory in the new file/folder wizard
+ * page is valid. It is only when it is not empty and it exists in the target peer.
+ *
+ * @see Validator
+ */
+public class FolderValidator extends Validator {
+ // The wizard page to create the new node.
+ private NewNodeWizardPage page;
+
+ /**
+ * Create a folder validator of the specified wizard page.
+ *
+ * @param page The wizard page to create the new file/folder.
+ */
+ public FolderValidator(NewNodeWizardPage page) {
+ super(ATTR_MANDATORY);
+ this.page = page;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.controls.validator.Validator#isValid(java.lang.String)
+ */
+ @Override
+ public boolean isValid(String newText) {
+ if (newText == null || newText.trim().length() == 0) {
+ setMessage(Messages.FolderValidator_SpecifyFolder, IMessageProvider.ERROR);
+ return false;
+ }
+ FSTreeNode folder = page.getInputDir();
+ if (folder == null) {
+ setMessage(NLS.bind(Messages.FolderValidator_DirNotExist, newText), IMessageProvider.ERROR);
+ return false;
+ }
+ if (!folder.isWritable()) {
+ setMessage(NLS.bind(Messages.FolderValidator_NotWritable, newText), IMessageProvider.ERROR);
+ return false;
+ }
+ setMessage(null, IMessageProvider.NONE);
+ return true;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NameValidator.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NameValidator.java
new file mode 100644
index 000000000..5329a4f7c
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NameValidator.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * 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.wizards;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.util.SafeRunnable;
+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.tcf.filesystem.ui.internal.celleditor.FSCellValidator;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.ui.controls.validator.Validator;
+
+/**
+ * The validator to validate the name of a file/folder in the file system of Target Explorer.
+ *
+ * @see Validator
+ */
+public class NameValidator extends Validator {
+ // The folder in which the new file/folder is to be created.
+ NewNodeWizardPage wizard;
+
+ /**
+ * Create a NameValidator with the folder in which the file/folder is created.
+ *
+ * @param wizard The parent folder in which the file/folder is created.
+ */
+ public NameValidator(NewNodeWizardPage wizard) {
+ super(ATTR_MANDATORY);
+ this.wizard = wizard;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.controls.validator.Validator#isValid(java.lang.String)
+ */
+ @Override
+ public boolean isValid(String newText) {
+ FSTreeNode folder = wizard.getInputDir();
+ if(folder == null) {
+ setMessage(Messages.NameValidator_SpecifyFolder, IMessageProvider.INFORMATION);
+ return false;
+ }
+ if (newText == null || newText.trim().length() == 0) {
+ setMessage(Messages.FSRenamingAssistant_SpecifyNonEmptyName, IMessageProvider.ERROR);
+ return false;
+ }
+ String text = newText.trim();
+ if (hasChild(text)) {
+ setMessage(Messages.FSRenamingAssistant_NameAlreadyExists, IMessageProvider.ERROR);
+ return false;
+ }
+ String formatRegex = folder.isWindowsNode() ? FSCellValidator.WIN_FILENAME_REGEX : FSCellValidator.UNIX_FILENAME_REGEX;
+ if (!text.matches(formatRegex)) {
+ setMessage(folder.isWindowsNode() ? Messages.FSRenamingAssistant_WinIllegalCharacters : Messages.FSRenamingAssistant_UnixIllegalCharacters, IMessageProvider.ERROR);
+ return false;
+ }
+ setMessage(null, IMessageProvider.NONE);
+ return true;
+ }
+
+ /**
+ * To test if the folder has a child with the specified name.
+ *
+ * @param name The name.
+ * @return true if it has a child with the name.
+ */
+ private boolean hasChild(String name) {
+ List<FSTreeNode> nodes = 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;
+ }
+
+ /**
+ * Get the folder's current children. If the children has not yet been loaded, then load it.
+ *
+ * @return The current children of the folder.
+ */
+ private List<FSTreeNode> getChildren() {
+ final FSTreeNode folder = wizard.getInputDir();
+ if (folder.childrenQueried) {
+ return folder.getChildren();
+ }
+ final List<FSTreeNode> result = new ArrayList<FSTreeNode>();
+ SafeRunner.run(new SafeRunnable() {
+ @Override
+ public void handleException(Throwable e) {
+ // Ignore exception
+ }
+ @Override
+ public void run() throws Exception {
+ result.addAll(new Operation().getChildren(folder));
+ }
+ });
+ return result;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFileWizard.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFileWizard.java
new file mode 100644
index 000000000..3ad1bfb76
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFileWizard.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.internal.wizards;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCreate;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCreateFile;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * The wizard to create a new file in the file system of Target Explorer.
+ */
+public class NewFileWizard extends NewNodeWizard {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizard#createWizardPage()
+ */
+ @Override
+ protected NewNodeWizardPage createWizardPage() {
+ return new NewFileWizardPage();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizard#getCreateOp(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode, java.lang.String, org.eclipse.tcf.te.runtime.interfaces.callback.ICallback)
+ */
+ @Override
+ protected OpCreate getCreateOp(FSTreeNode folder, String name) {
+ return new OpCreateFile(folder, name);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizard#getTitle()
+ */
+ @Override
+ protected String getTitle() {
+ return Messages.NewFileWizard_NewFileWizardTitle;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFileWizardPage.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFileWizardPage.java
new file mode 100644
index 000000000..af1b95b01
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFileWizardPage.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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.wizards;
+
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * The wizard page to create a new file in the file system of Target Explorer.
+ */
+public class NewFileWizardPage extends NewNodeWizardPage {
+
+ /**
+ * Create a wizard page to create a new file in the specified folder.
+ */
+ public NewFileWizardPage() {
+ super("NewFileWizardPage"); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizardPage#getPageTitle()
+ */
+ @Override
+ protected String getPageTitle() {
+ return Messages.NewFileWizardPage_NewFileWizardPageTitle;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizardPage#getPageDescription()
+ */
+ @Override
+ protected String getPageDescription() {
+ return Messages.NewFileWizardPage_NewFileWizardPageDescription;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizardPage#getNameFieldLabel()
+ */
+ @Override
+ protected String getNameFieldLabel() {
+ return Messages.NewFileWizardPage_NewFileWizardPageNameLabel;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFolderWizard.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFolderWizard.java
new file mode 100644
index 000000000..84fb4adc9
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFolderWizard.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.internal.wizards;
+
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCreate;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCreateFolder;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * The wizard to create a new folder in the file system of Target Explorer.
+ */
+public class NewFolderWizard extends NewNodeWizard {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizard#createWizardPage()
+ */
+ @Override
+ protected NewNodeWizardPage createWizardPage() {
+ return new NewFolderWizardPage();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizard#getCreateOp(org.eclipse.tcf.te.tcf.filesystem.model.FSTreeNode, java.lang.String, org.eclipse.tcf.te.runtime.interfaces.callback.ICallback)
+ */
+ @Override
+ protected OpCreate getCreateOp(FSTreeNode folder, String name) {
+ return new OpCreateFolder(folder, name);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizard#getTitle()
+ */
+ @Override
+ protected String getTitle() {
+ return Messages.NewFolderWizard_NewFolderWizardTitle;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFolderWizardPage.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFolderWizardPage.java
new file mode 100644
index 000000000..79237ca4b
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewFolderWizardPage.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * 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.wizards;
+
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+
+/**
+ * The wizard page to create a new folder in the file system of Target Explorer.
+ */
+public class NewFolderWizardPage extends NewNodeWizardPage {
+
+ /**
+ * Create a wizard page to create a new folder in the specified folder.
+ */
+ public NewFolderWizardPage() {
+ super("NewFolderWizardPage"); //$NON-NLS-1$
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizardPage#getPageTitle()
+ */
+ @Override
+ protected String getPageTitle() {
+ return Messages.NewFolderWizardPage_NewFolderWizardPageTitle;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizardPage#getPageDescription()
+ */
+ @Override
+ protected String getPageDescription() {
+ return Messages.NewFolderWizardPage_NewFolderWizardPageDescription;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.internal.wizards.NewNodeWizardPage#getNameFieldLabel()
+ */
+ @Override
+ protected String getNameFieldLabel() {
+ return Messages.NewFolderWizardPage_NewFolderWizardPageNameLabel;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewNodeWizard.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewNodeWizard.java
new file mode 100644
index 000000000..ee743fcae
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewNodeWizard.java
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * 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.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.tcf.protocol.Protocol;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.OpCreate;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+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.views.editor.pages.AbstractTreeViewerExplorerEditorPage;
+import org.eclipse.tcf.te.ui.wizards.AbstractWizard;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.editor.IFormPage;
+import org.eclipse.ui.navigator.CommonNavigator;
+
+/**
+ * The base wizard class to create a new file/folder in the file system of Target Explorer.
+ */
+public abstract class NewNodeWizard extends AbstractWizard implements INewWizard {
+ // The folder in which the new node is created.
+ private FSTreeNode folder;
+ // The target peer where the new node is created.
+ private IPeerNode peer;
+ // The wizard page used to create the new node.
+ private NewNodeWizardPage newPage;
+
+ /**
+ * Create an instance.
+ */
+ public NewNodeWizard() {
+ setNeedsProgressMonitor(true);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection)
+ */
+ @Override
+ public void init(IWorkbench workbench, IStructuredSelection selection) {
+ super.init(workbench, selection);
+ // Set the window title
+ setWindowTitle(getTitle());
+ if (!selection.isEmpty()) {
+ Object element = selection.getFirstElement();
+ if (element instanceof FSTreeNode) {
+ folder = (FSTreeNode) element;
+ if (folder.isFile()) {
+ // If the selected is a file, then create the node in the parent folder.
+ folder = folder.getParent();
+ }
+ peer = folder.peerNode;
+ }
+ else if (element instanceof IPeerNode) {
+ if(hasFileSystem((IPeerNode) element)) {
+ peer = (IPeerNode) element;
+ }
+ }
+ }
+ }
+
+ /**
+ * Test if the specified target peer has a file system service.
+ *
+ * @param peer The target peer.
+ * @return true if it has a file system service.
+ */
+ public boolean hasFileSystem(final IPeerNode peer) {
+ if(Protocol.isDispatchThread()) {
+ String services = null;
+ services = peer.getStringProperty(IPeerNodeProperties.PROPERTY_REMOTE_SERVICES);
+ if (services != null) {
+ // Lookup each service individually
+ for (String service : services.split(",")) { //$NON-NLS-1$
+ if (service != null && service.trim().equals("FileSystem")) { //$NON-NLS-1$
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ final boolean[] result = new boolean[1];
+ Protocol.invokeAndWait(new Runnable(){
+ @Override
+ public void run() {
+ result[0] = hasFileSystem(peer);
+ }});
+ return result[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.Wizard#addPages()
+ */
+ @Override
+ public void addPages() {
+ if (peer == null) {
+ addPage(new TargetSelectionPage());
+ }
+ addPage(newPage = createWizardPage());
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.Wizard#performFinish()
+ */
+ @Override
+ public boolean performFinish() {
+ if (newPage != null) {
+ // Save the value so that next time it is used as the default input.
+ newPage.saveWidgetValues();
+ // Get the new name and create the node.
+ String name = newPage.getNodeName();
+ FSTreeNode dest = newPage.getInputDir();
+ final OpCreate create = getCreateOp(dest, name);
+ IRunnableWithProgress runnable = new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ create.run(monitor);
+ }};
+ try {
+ getContainer().run(false, false, runnable);
+ final FSTreeNode newNode = create.getNode();
+ getShell().getDisplay().asyncExec(new Runnable(){
+ @Override
+ public void run() {
+ selectNewNode(newNode);
+ }});
+ return true;
+ }
+ catch (InvocationTargetException e) {
+ newPage.setErrorMessage(e.getMessage());
+ }
+ catch (InterruptedException e) {
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Select the specified node in the selection provider.
+ *
+ * @param node The node to be selected.
+ */
+ void selectNewNode(FSTreeNode node) {
+ TreeViewer viewer = getFocusedViewer();
+ if(viewer != null) {
+ viewer.refresh(folder);
+ ISelection selection = new StructuredSelection(node);
+ viewer.setSelection(selection, true);
+ }
+ }
+
+ /**
+ * Get currently focused tree viewer.
+ *
+ * @return currently focused tree viewer or null.
+ */
+ TreeViewer getFocusedViewer() {
+ IWorkbenchWindow window = getWorkbench() != null ? getWorkbench().getActiveWorkbenchWindow() : null;
+ if (window != null) {
+ IWorkbenchPage page = window.getActivePage();
+ if (page != null) {
+ IWorkbenchPart part = page.getActivePart();
+ if (part instanceof FormEditor) {
+ FormEditor formEditor = (FormEditor) part;
+ IFormPage formPage = formEditor.getActivePageInstance();
+ if (formPage instanceof AbstractTreeViewerExplorerEditorPage) {
+ AbstractTreeViewerExplorerEditorPage viewerPage = (AbstractTreeViewerExplorerEditorPage) formPage;
+ return (TreeViewer) viewerPage.getTreeControl().getViewer();
+ }
+ } else if (part instanceof CommonNavigator) {
+ CommonNavigator navigator = (CommonNavigator) part;
+ return navigator.getCommonViewer();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create a wizard page to create a new node.
+ *
+ * @return The new wizard page.
+ */
+ protected abstract NewNodeWizardPage createWizardPage();
+
+ /**
+ * Create a Create operation instance using the specified folder and the new name.
+ *
+ * @param folder The folder in which the new node is created.
+ * @param name The name of the new node.
+ * @return a FSCreate instance to do the creation.
+ */
+ protected abstract OpCreate getCreateOp(FSTreeNode folder, String name);
+
+ /**
+ * The wizard's title to be used.
+ *
+ * @return The wizard's title to be used.
+ */
+ protected abstract String getTitle();
+
+ /**
+ * Get the current target peer selected.
+ *
+ * @return The target peer selected.
+ */
+ public IPeerNode getPeer(){
+ return peer;
+ }
+
+ /**
+ * Set the currently selected target peer.
+ *
+ * @param peer The newly selected target peer.
+ */
+ public void setPeer(IPeerNode peer) {
+ this.peer = peer;
+ newPage.setPeer(peer);
+ }
+
+ /**
+ * Get the current selected folder.
+ *
+ * @return the current selected folder.
+ */
+ public FSTreeNode getFolder() {
+ return folder;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewNodeWizardPage.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewNodeWizardPage.java
new file mode 100644
index 000000000..7179beddc
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/NewNodeWizardPage.java
@@ -0,0 +1,359 @@
+/*******************************************************************************
+ * 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.wizards;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.DecoratingLabelProvider;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.wizard.IWizardContainer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+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.model.FSTreeNode;
+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.help.IContextHelpIds;
+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.controls.BaseEditBrowseTextControl;
+import org.eclipse.tcf.te.ui.forms.FormLayoutFactory;
+import org.eclipse.tcf.te.ui.trees.FilterDescriptor;
+import org.eclipse.tcf.te.ui.trees.ViewerStateManager;
+import org.eclipse.tcf.te.ui.wizards.pages.AbstractValidatingWizardPage;
+import org.eclipse.ui.IDecoratorManager;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+/**
+ * The base wizard page class to create a new file/folder in the file system of Target Explorer.
+ */
+public abstract class NewNodeWizardPage extends AbstractValidatingWizardPage {
+ // The form toolkit to create the content of the wizard page.
+ private FormToolkit toolkit;
+ // The control for the user to enter the new name.
+ private BaseEditBrowseTextControl nameControl;
+ // The control for the user to enter the parent directory
+ private BaseEditBrowseTextControl folderControl;
+ // The viewer of the file tree displaying the file system.
+ private TreeViewer treeViewer;
+
+ /**
+ * Create an instance page with the specified page name.
+ *
+ * @param pageName The page name.
+ */
+ public NewNodeWizardPage(String pageName) {
+ super(pageName);
+ }
+
+ /**
+ * Get the page's title.
+ *
+ * @return The page's title.
+ */
+ protected abstract String getPageTitle();
+
+ /**
+ * Get the page's description.
+ *
+ * @return The page's description.
+ */
+ protected abstract String getPageDescription();
+
+ /**
+ * Get the label of the text field to enter the new name.
+ *
+ * @return The label of the text field to enter the new name.
+ */
+ protected abstract String getNameFieldLabel();
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createControl(Composite parent) {
+ // Setup title and description
+ setTitle(getPageTitle());
+ setDescription(getPageDescription());
+
+ // Create the forms toolkit
+ toolkit = new FormToolkit(parent.getDisplay());
+
+ // Create the main panel
+ Composite mainPanel = toolkit.createComposite(parent);
+ mainPanel.setLayout(FormLayoutFactory.createClearGridLayout(false, 1));
+ mainPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ mainPanel.setBackground(parent.getBackground());
+
+ setControl(mainPanel);
+
+ // Setup the help
+ PlatformUI.getWorkbench().getHelpSystem()
+ .setHelp(mainPanel, IContextHelpIds.FS_NEW_FILE_WIZARD_PAGE);
+
+ // Do not validate the page while creating the controls
+ boolean changed = setValidationInProgress(true);
+ // Create the main panel sub controls
+ createMainPanelControls(mainPanel);
+ // Reset the validation in progress state
+ if (changed) setValidationInProgress(false);
+
+ // Adjust the font
+ Dialog.applyDialogFont(mainPanel);
+
+ // Validate the page for the first time
+ setPageComplete(false);
+ }
+
+ /**
+ * Create the main panel of this wizard page.
+ *
+ * @param parent The parent composite in which the page is created.
+ */
+ private void createMainPanelControls(Composite parent) {
+ Assert.isNotNull(parent);
+
+ // Create the client composite
+ Composite client = toolkit != null ? toolkit.createComposite(parent) : new Composite(parent, SWT.NONE);
+ client.setLayout(FormLayoutFactory.createSectionClientGridLayout(false, 2));
+ client.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ client.setBackground(parent.getBackground());
+
+ Label label = new Label(client, SWT.NONE);
+ GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+ label.setText(Messages.NewNodeWizardPage_PromptFolderLabel);
+
+ folderControl = new BaseEditBrowseTextControl(this);
+ folderControl.setIsGroup(false);
+ folderControl.setHasHistory(false);
+ folderControl.setHideBrowseButton(true);
+ folderControl.setHideLabelControl(true);
+ folderControl.setHideEditFieldControlDecoration(true);
+ folderControl.setFormToolkit(toolkit);
+ folderControl.setParentControlIsInnerPanel(true);
+ folderControl.setupPanel(client);
+ folderControl.setEditFieldValidator(new FolderValidator(this));
+ NewNodeWizard wizard = getWizard();
+ FSTreeNode folder = wizard.getFolder();
+ if (folder != null) folderControl.setEditFieldControlText(folder.getLocation());
+
+ treeViewer = new TreeViewer(client, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+ data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ data.horizontalSpan = 2;
+ data.heightHint = 193;
+ data.widthHint = 450;
+ treeViewer.getTree().setLayoutData(data);
+ treeViewer.setContentProvider(new FSTreeContentProvider());
+ treeViewer.setLabelProvider(createDecoratingLabelProvider(new FSTreeElementLabelProvider()));
+ treeViewer.setComparator(new FSTreeViewerSorter());
+ treeViewer.addFilter(new DirectoryFilter());
+ IPeerNode peer = wizard.getPeer();
+ if (peer != null) {
+ setInput(peer);
+ }
+ treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ onSelectionChanged();
+ }
+ });
+ if (folder != null) treeViewer.setSelection(new StructuredSelection(folder));
+
+ nameControl = new BaseEditBrowseTextControl(this);
+ nameControl.setIsGroup(false);
+ nameControl.setHasHistory(false);
+ nameControl.setHideBrowseButton(true);
+ nameControl.setEditFieldLabel(getNameFieldLabel());
+ nameControl.setFormToolkit(toolkit);
+ nameControl.setParentControlIsInnerPanel(true);
+ nameControl.setupPanel(client);
+ nameControl.setEditFieldValidator(new NameValidator(this));
+
+ if (folder == null) folderControl.getEditFieldControl().setFocus();
+ else nameControl.getEditFieldControl().setFocus();
+
+ // restore the widget values from the history
+ restoreWidgetValues();
+ }
+
+ /**
+ * The viewer filter 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;
+ }
+ }
+
+ /**
+ * Set the input of the tree viewer and apply the appropriate filters.
+ *
+ * @param input The tree viewer's input.
+ */
+ private void setInput(Object input) {
+ treeViewer.setInput(input);
+ FilterDescriptor[] filterDescriptors = ViewerStateManager.getInstance().getFilterDescriptors(IFSConstants.ID_TREE_VIEWER_FS, input);
+ Assert.isNotNull(filterDescriptors);
+ for (FilterDescriptor descriptor : filterDescriptors) {
+ if (descriptor.isEnabled()) {
+ treeViewer.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);
+ }
+
+ /**
+ * Event process handling method when the user select a new folder in the file tree.
+ */
+ protected void onSelectionChanged() {
+ if (treeViewer.getSelection() instanceof IStructuredSelection) {
+ IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();
+ if (selection.getFirstElement() instanceof FSTreeNode) {
+ FSTreeNode folder = (FSTreeNode) selection.getFirstElement();
+ folderControl.setEditFieldControlText(folder.getLocation());
+ }
+ else {
+ folderControl.setEditFieldControlText(""); //$NON-NLS-1$
+ }
+ }
+
+ // Update the wizard container UI elements
+ IWizardContainer container = getContainer();
+ if (container != null && container.getCurrentPage() != null) {
+ container.updateWindowTitle();
+ container.updateTitleBar();
+ container.updateButtons();
+ }
+ validate();
+ }
+
+ /**
+ * Set a new peer as the input of the file tree. Called
+ * by the wizard to update the file tree when an alternative
+ * target peer is selected in the target selection page.
+ *
+ * @param peer The new target peer.
+ */
+ public void setPeer(IPeerNode peer) {
+ if (peer != null) {
+ setInput(peer);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.wizards.pages.AbstractValidatingWizardPage#doValidate()
+ */
+ @Override
+ protected ValidationResult doValidate() {
+ ValidationResult result = new ValidationResult();
+
+ boolean valid = true;
+
+ if (folderControl != null) {
+ valid &= folderControl.isValid();
+ result.setResult(folderControl);
+ }
+
+ if (nameControl != null) {
+ valid &= nameControl.isValid();
+ result.setResult(nameControl);
+ }
+
+ result.setValid(valid);
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.DialogPage#dispose()
+ */
+ @Override
+ public void dispose() {
+ if (nameControl != null) { nameControl.dispose(); nameControl = null; }
+ if (toolkit != null) { toolkit.dispose(); toolkit = null; }
+ super.dispose();
+ }
+
+ /**
+ * Get the entered name of this node.
+ *
+ * @return The entered name of this node.
+ */
+ public String getNodeName() {
+ return nameControl.getEditFieldControlTextForValidation();
+ }
+
+ /**
+ * Get the parent wizard. Override the parent method to
+ * cast the result to NewNodeWizard.
+ */
+ @Override
+ public NewNodeWizard getWizard() {
+ return (NewNodeWizard) super.getWizard();
+ }
+
+ /**
+ * Get the currently input directory node. It parses
+ * the currently entered path and tries to find the
+ * corresponding directory node in the file system of
+ * the target peer.
+ *
+ * @return The directory node if it exists or else null.
+ */
+ public FSTreeNode getInputDir() {
+ NewNodeWizard wizard = getWizard();
+ IPeerNode peer = wizard.getPeer();
+ if (peer == null) return null;
+ final String text = folderControl.getEditFieldControlText();
+ if (text != null) {
+ String path = text.trim();
+ OpParsePath parser = new OpParsePath(peer, path);
+ new NullOpExecutor().execute(parser);
+ return parser.getResult();
+ }
+ return null;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/TargetPatternFilter.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/TargetPatternFilter.java
new file mode 100644
index 000000000..82baf5e34
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/TargetPatternFilter.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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.wizards;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.ui.views.navigator.DelegatingLabelProvider;
+import org.eclipse.ui.dialogs.PatternFilter;
+
+/**
+ * A class that handles filtering wizard node items based on a supplied matching
+ * string and keywords
+ * <p>
+ * This class is copied and adapted from <code>org.eclipse.ui.internal.dialogs.WizardPatternFilter</code>.
+ */
+public class TargetPatternFilter extends PatternFilter {
+ private DelegatingLabelProvider targetLabelProvider = new DelegatingLabelProvider();
+ /**
+ * Create a new instance of a WizardPatternFilter
+ * @param isMatchItem
+ */
+ public TargetPatternFilter() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.internal.dialogs.PatternFilter#isElementSelectable(java.lang.Object)
+ */
+ @Override
+ public boolean isElementSelectable(Object element) {
+ return element instanceof IPeerNode;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.internal.dialogs.PatternFilter#isElementMatch(org.eclipse.jface.viewers.Viewer, java.lang.Object)
+ */
+ @Override
+ protected boolean isLeafMatch(Viewer viewer, Object element) {
+ if ( element instanceof IPeerNode) {
+ String text = targetLabelProvider.getText(element);
+ if (wordMatches(text)) {
+ 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/wizards/TargetSelectionPage.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/TargetSelectionPage.java
new file mode 100644
index 000000000..d3b268055
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/internal/wizards/TargetSelectionPage.java
@@ -0,0 +1,305 @@
+/*******************************************************************************
+ * 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.wizards;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider;
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.IBasicPropertyConstants;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.wizard.IWizardContainer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel;
+import org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode;
+import org.eclipse.tcf.te.tcf.locator.interfaces.services.IPeerModelQueryService;
+import org.eclipse.tcf.te.tcf.locator.model.ModelManager;
+import org.eclipse.tcf.te.tcf.ui.navigator.ContentProvider;
+import org.eclipse.tcf.te.ui.activator.UIPlugin;
+import org.eclipse.tcf.te.ui.interfaces.IUIConstants;
+import org.eclipse.tcf.te.ui.views.navigator.DelegatingLabelProvider;
+import org.eclipse.tcf.te.ui.wizards.pages.AbstractValidatingWizardPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.FilteredTree;
+import org.eclipse.ui.dialogs.PatternFilter;
+
+/**
+ * The New Target creation wizard selection page implementation.
+ * <p>
+ * This class is copied and adapted from <code>org.eclipse.tcf.te.ui.wizards.newWizard.NewWizardSelectionPage</code>.
+ *
+ * @since 3.8
+ */
+public class TargetSelectionPage extends AbstractValidatingWizardPage {
+ // References to the page subcontrol's
+ private FilteredTree filteredTree;
+ private PatternFilter filteredTreeFilter;
+
+ // The tree viewer to display the targets.
+ private TreeViewer treeViewer;
+
+ /**
+ * Internal class. The wizard viewer comparator is responsible for the sorting in the tree.
+ * Current implementation is not prioritizing categories.
+ */
+ /* default */static class TargetViewerComparator extends ViewerComparator {
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ViewerComparator#isSorterProperty(java.lang.Object,
+ * java.lang.String)
+ */
+ @Override
+ public boolean isSorterProperty(Object element, String property) {
+ // The comparator is affected if the label of the elements should change.
+ return property.equals(IBasicPropertyConstants.P_TEXT);
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param wizardRegistry The new target wizard registry. Must not be <code>null</code>.
+ */
+ public TargetSelectionPage() {
+ super(TargetSelectionPage.class.getSimpleName());
+ setTitle(getDefaultTitle());
+ setDescription(getDefaultDescription());
+ initialize();
+ }
+
+ /**
+ * Refresh the remote services in target peers.
+ */
+ private void initialize() {
+ // Refresh the information of remote services.
+ IPeerModel model = ModelManager.getPeerModel();
+ Assert.isNotNull(model);
+ IPeerNode[] peers = model.getPeerNodes();
+ if (peers != null) {
+ IPeerModelQueryService service = model.getService(IPeerModelQueryService.class);
+ for (IPeerNode peer : peers) {
+ service.queryRemoteServices(peer);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.WizardPage#getWizard()
+ */
+ @Override
+ public NewNodeWizard getWizard() {
+ return (NewNodeWizard) super.getWizard();
+ }
+
+ /**
+ * Returns the default page title.
+ *
+ * @return The default page title. Must be never <code>null</code>.
+ */
+ protected String getDefaultTitle() {
+ return Messages.TargetSelectionPage_Title;
+ }
+
+ /**
+ * Returns the default page description.
+ *
+ * @return The default page description. Must be never <code>null</code>.
+ */
+ protected String getDefaultDescription() {
+ return Messages.TargetSelectionPage_Description;
+ }
+
+ /**
+ * A styled label provider for the target selection list.
+ */
+ static class TargetStyledLabelProvider extends DelegatingLabelProvider implements IStyledLabelProvider {
+ @Override
+ public StyledString getStyledText(Object element) {
+ return new StyledString(getText(element));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ @Override
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout());
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Label label = new Label(composite, SWT.NONE);
+ label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ label.setText(Messages.TargetSelectionPage_Targets);
+ label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ filteredTreeFilter = new TargetPatternFilter();
+ filteredTree = new FilteredTree(composite, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, filteredTreeFilter, true);
+ filteredTree.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
+ GridData layoutData = new GridData(GridData.FILL_BOTH);
+ layoutData.heightHint = 250;
+ layoutData.widthHint = 450;
+ filteredTree.setLayoutData(layoutData);
+
+ treeViewer = filteredTree.getViewer();
+ treeViewer.setContentProvider(new ContentProvider());
+ IBaseLabelProvider labelProvider = new DecoratingStyledCellLabelProvider(new TargetStyledLabelProvider(), new DelegatingLabelProvider(), null);
+ treeViewer.setLabelProvider(labelProvider);
+ treeViewer.setComparator(new TargetViewerComparator());
+ ViewerFilter fsPeerFilter = new ViewerFilter() {
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ if (element instanceof IPeerNode) {
+ IPeerNode peer = (IPeerNode) element;
+
+
+
+ NewNodeWizard wizard = getWizard();
+ return wizard.hasFileSystem(peer);
+ }
+ return false;
+ }
+ };
+ treeViewer.addFilter(fsPeerFilter);
+ treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ onSelectionChanged();
+ }
+ });
+ treeViewer.addDoubleClickListener(new IDoubleClickListener() {
+ @Override
+ public void doubleClick(DoubleClickEvent event) {
+ // Double-click on a connection type is triggering the sub wizard
+ if (event.getSelection() instanceof IStructuredSelection) {
+ IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+ // The tree is single selection, so look for the first element only.
+ Object element = selection.getFirstElement();
+ if (element instanceof IPeerNode) {
+ // Double-click on a connection type is triggering the sub wizard
+ getWizard().getContainer().showPage(getNextPage());
+ }
+ else if (event.getViewer() instanceof TreeViewer) {
+ TreeViewer viewer = (TreeViewer) event.getViewer();
+ if (viewer.isExpandable(element)) {
+ viewer.setExpandedState(element, !viewer.getExpandedState(element));
+ }
+ }
+ }
+ }
+ });
+
+ treeViewer.setInput(ModelManager.getPeerModel());
+ NewNodeWizard wizard = getWizard();
+ IPeerNode peer = wizard.getPeer();
+ if (wizard.getPeer() != null) {
+ treeViewer.setSelection(new StructuredSelection(peer), true);
+ }
+
+ // apply the standard dialog font
+ Dialog.applyDialogFont(composite);
+
+ setControl(composite);
+
+ // Restore the tree state
+ restoreWidgetValues();
+
+ // Initialize the context help id
+ PlatformUI.getWorkbench().getHelpSystem()
+ .setHelp(getControl(), IUIConstants.HELP_NEW_WIZARD_SELECTION_PAGE);
+
+ setPageComplete(peer != null);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.tcf.te.ui.wizards.pages.AbstractValidatingWizardPage#doValidate()
+ */
+ @Override
+ protected ValidationResult doValidate() {
+ ValidationResult result = new ValidationResult();
+
+ boolean valid = true;
+
+ ISelection selection = treeViewer.getSelection();
+ if (selection.isEmpty()) {
+ result.setResult(getDefaultDescription(), IMessageProvider.ERROR);
+ result.setValid(valid);
+ }
+
+ return result;
+ }
+
+ /**
+ * Called from the selection listener to propagate the current system type selection to the
+ * underlying wizard.
+ */
+ protected void onSelectionChanged() {
+ if (filteredTree.getViewer().getSelection() instanceof IStructuredSelection) {
+ IStructuredSelection filteredTreeSelection = (IStructuredSelection) filteredTree
+ .getViewer().getSelection();
+ NewNodeWizard wizard = getWizard();
+ if (filteredTreeSelection.getFirstElement() instanceof IPeerNode) {
+ wizard.setPeer((IPeerNode) filteredTreeSelection.getFirstElement());
+ }
+ else {
+ wizard.setPeer(null);
+ }
+ }
+
+ // Update the wizard container UI elements
+ IWizardContainer container = getContainer();
+ if (container != null && container.getCurrentPage() != null) {
+ container.updateWindowTitle();
+ container.updateTitleBar();
+ container.updateButtons();
+ }
+ validate();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.wizard.WizardPage#getDialogSettings()
+ */
+ @Override
+ protected IDialogSettings getDialogSettings() {
+ // If the wizard is set and returns dialog settings, we re-use them here
+ IDialogSettings settings = super.getDialogSettings();
+ // If the dialog settings could not set from the wizard, fallback to the plugin's
+ // dialog settings store.
+ if (settings == null) settings = UIPlugin.getDefault().getDialogSettings();
+ String sectionName = this.getClass().getName();
+ if (settings.getSection(sectionName) == null) settings.addNewSection(sectionName);
+ settings = settings.getSection(sectionName);
+
+ return settings;
+ }
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.java
new file mode 100644
index 000000000..8d68fec45
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.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) - [345384] Provide property pages for remote file system nodes
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.ui.nls;
+
+import java.lang.reflect.Field;
+
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.te.runtime.services.ServiceUtils;
+import org.eclipse.tcf.te.tcf.filesystem.ui.interfaces.IFileSystemUIDelegate;
+
+/**
+ * File System plug-in externalized strings management.
+ */
+public class Messages extends NLS {
+
+ // The plug-in resource bundle name
+ private static final String BUNDLE_NAME = "org.eclipse.tcf.te.tcf.filesystem.ui.nls.Messages"; //$NON-NLS-1$
+
+ /**
+ * Static constructor.
+ */
+ static {
+ // Load message values from bundle file
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ /**
+ * Returns if or if not this NLS manager contains a constant for
+ * the given externalized strings key.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return <code>True</code> if a constant for the given key exists, <code>false</code> otherwise.
+ */
+ public static boolean hasString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ return field != null;
+ } catch (NoSuchFieldException e) { /* ignored on purpose */ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the corresponding string for the given externalized strings
+ * key or <code>null</code> if the key does not exist.
+ *
+ * @param key The externalized strings key or <code>null</code>.
+ * @return The corresponding string or <code>null</code>.
+ */
+ public static String getString(String key) {
+ if (key != null) {
+ try {
+ Field field = Messages.class.getDeclaredField(key);
+ return (String)field.get(null);
+ } catch (Exception e) { /* ignored on purpose */ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the corresponding string for the given externalized strings key via
+ * the {@link IFileSystemUIDelegate}.
+ *
+ * @param context The context or <code>null</code>.
+ * @param key The externalized strings key or <code>null</code>.
+ *
+ * @return The corresponding string or <code>null</code>.
+ */
+ public static String getStringDelegated(Object context, String key) {
+ if (key != null) {
+ IFileSystemUIDelegate delegate = ServiceUtils.getUIServiceDelegate(context, context, IFileSystemUIDelegate.class);
+ return delegate != null ? delegate.getMessage(key) : null;
+ }
+
+ return null;
+ }
+
+ public static String FSFolderSelectionDialog_MoveDialogMessage;
+ public static String FSFolderSelectionDialog_MoveDialogTitle;
+ public static String FSFolderSelectionDialog_Refresh_menu;
+ public static String FSFolderSelectionDialog_RefreshAll_menu;
+ public static String FSFolderSelectionDialog_validate_message;
+ public static String FSFolderSelectionDialog_notWritable_error;
+ public static String FSFolderSelectionDialog_notWritable_warning;
+
+ public static String FSOpenFileDialog_message;
+ public static String FSOpenFileDialog_title;
+ public static String FSDelete_ConfirmDelete;
+ public static String FSDelete_ConfirmMessage;
+ public static String FSDelete_ButtonCancel;
+ public static String FSDelete_ButtonNo;
+ public static String FSDelete_ButtonYes;
+ public static String FSDelete_ButtonYes2All;
+ public static String DateValidator_DateInvalidNumber;
+ public static String DateValidator_DateOutofRange;
+ public static String DateValidator_InfoFormat;
+ public static String DateValidator_InfoPrompt;
+ public static String DateValidator_InvalidDate;
+ public static String DateValidator_MonthInvalidNumber;
+ public static String DateValidator_MonthOutofRange;
+ public static String DateValidator_YearInvalidNumber;
+ public static String DateValidator_YearOutofRange;
+ public static String DeleteFilesHandler_DeleteMultipleFilesConfirmation;
+ public static String DeleteFilesHandler_DeleteOneFileConfirmation;
+ public static String DeleteFilesHandler_ConfirmDialogTitle;
+ public static String FSRenamingAssistant_NameAlreadyExists;
+ public static String FSRenamingAssistant_SpecifyNonEmptyName;
+ public static String FSRenamingAssistant_UnixIllegalCharacters;
+ public static String FSRenamingAssistant_WinIllegalCharacters;
+ public static String LocalTypedElement_SavingFile;
+ public static String MergeEditorInput_LocalFile;
+ public static String MergeEditorInput_RemoteFile;
+ public static String MergeEditorInput_CompareLeftAndRight;
+ public static String MergeEditorInput_CompareWithLocalCache;
+ public static String MergeInput_CopyNotSupported;
+ public static String RemoteTypedElement_GettingRemoteContent;
+ public static String RemoteTypedElement_DowloadingFile;
+ public static String FSDropTargetListener_ConfirmMoveTitle;
+ public static String FSDropTargetListener_MovingWarningMultiple;
+ public static String FSDropTargetListener_MovingWarningSingle;
+ public static String FSExplorerEditorPage_PageTitle;
+ public static String FSGeneralSearchable_FileType;
+ public static String FSGeneralSearchable_Find;
+ public static String FSGeneralSearchable_GeneralOptionText;
+ public static String FSGeneralSearchable_SearchHiddenFiles;
+ public static String FSGeneralSearchable_SearchSystemFiles;
+ public static String FSModifiedSearchable_DontRemember;
+ public static String FSModifiedSearchable_LastWeek;
+ public static String FSModifiedSearchable_PastMonth;
+ public static String FSModifiedSearchable_PastYear;
+ public static String FSModifiedSearchable_SpecifyDates;
+ public static String FSModifiedSearchable_ToDate;
+ public static String FSModifiedSearchable_WhenModified;
+ public static String FSUpload_Cancel;
+ public static String FSUpload_No;
+ public static String FSUpload_OverwriteConfirmation;
+ public static String FSUpload_OverwriteTitle;
+ public static String FSUpload_Yes;
+ public static String FSUpload_YesToAll;
+ public static String FSOperation_ConfirmDialogCancel;
+ public static String FSOperation_ConfirmDialogNo;
+ public static String FSOperation_ConfirmDialogYes;
+ public static String FSOperation_ConfirmDialogYesToAll;
+ public static String FSOperation_ConfirmFileReplace;
+ public static String FSOperation_ConfirmFileReplaceMessage;
+ public static String FSOperation_ConfirmFolderReplaceMessage;
+ public static String FSOperation_ConfirmFolderReplaceTitle;
+ public static String OpenFileHandler_OpeningBinaryNotSupported;
+ public static String OpenFileHandler_Warning;
+ public static String OpenWithMenu_ChooseEditorForOpening;
+ public static String OpenWithMenu_DefaultEditor;
+ public static String OpenWithMenu_NoEditorFound;
+ public static String OpenWithMenu_OpenWith;
+ public static String FSRename_RenameFileFolderTitle;
+ public static String FSSizeSearchable_DontRemember;
+ public static String FSSizeSearchable_KBS;
+ public static String FSSizeSearchable_Large;
+ public static String FSSizeSearchable_Medium;
+ public static String FSSizeSearchable_Small;
+ public static String FSSizeSearchable_SpecifySize;
+ public static String FSSizeSearchable_ToText;
+ public static String FSSizeSearchable_WhatSize;
+ public static String FSTreeNodeSearchable_FilesAndFolders;
+ public static String FSTreeNodeSearchable_FilesOnly;
+ public static String FSTreeNodeSearchable_FindFilesAndFolders;
+ public static String FSTreeNodeSearchable_FindMessage;
+ public static String FSTreeNodeSearchable_FoldersOnly;
+ public static String FSTreeNodeSearchable_SearchingTargets;
+ public static String FSTreeNodeSearchable_SelectedFileSystem;
+ public static String RenameFilesHandler_TitleRename;
+ public static String RenameFilesHandler_TitleRenameFile;
+ public static String RenameFilesHandler_TitleRenameFolder;
+ public static String RenameFilesHandler_PromptNewName;
+ public static String RenameFilesHandler_RenamePromptMessage;
+ public static String PreferencePage_AutoSavingText;
+ public static String PreferencePage_CopyOwnershipText;
+ public static String PreferencePage_CopyPermissionText;
+ public static String PreferencePage_PersistExpanded;
+ public static String PreferencePage_RenamingOptionText;
+ public static String AdvancedAttributesDialog_FileBanner;
+ public static String AdvancedAttributesDialog_FolderBanner;
+ public static String AdvancedAttributesDialog_CompressEncrypt;
+ public static String AdvancedAttributesDialog_ArchiveIndex;
+ public static String AdvancedAttributesDialog_IndexFile;
+ public static String AdvancedAttributesDialog_IndexFolder;
+ public static String AdvancedAttributesDialog_FileArchive;
+ public static String AdvancedAttributesDialog_FolderArchive;
+ public static String AdvancedAttributesDialog_Encrypt;
+ public static String AdvancedAttributesDialog_Compress;
+ public static String AdvancedAttributesDialog_ShellTitle;
+ public static String GeneralInformationPage_Accessed;
+ public static String GeneralInformationPage_Advanced;
+ public static String GeneralInformationPage_Attributes;
+ public static String GeneralInformationPage_Computer;
+ public static String GeneralInformationPage_FileSizeInfo;
+ public static String GeneralInformationPage_Hidden;
+ public static String GeneralInformationPage_Location;
+ public static String GeneralInformationPage_Modified;
+ public static String GeneralInformationPage_Name;
+ public static String GeneralInformationPage_ReadOnly;
+ public static String GeneralInformationPage_Size;
+ public static String GeneralInformationPage_Type;
+ public static String GeneralInformationPage_PermissionText;
+ public static String PermissionsGroup_Executable;
+ public static String PermissionsGroup_GroupPermissions;
+ public static String PermissionsGroup_OtherPermissions;
+ public static String PermissionsGroup_Readable;
+ public static String PermissionsGroup_UserPermissions;
+ public static String PermissionsGroup_Writable;
+ public static String BasicFolderSection_BasicInfoText;
+ public static String LinuxPermissionsSection_Permissions;
+ public static String WindowsAttributesSection_Attributes;
+ public static String FolderValidator_DirNotExist;
+ public static String FolderValidator_NotWritable;
+ public static String FolderValidator_SpecifyFolder;
+ public static String NameValidator_InfoPrompt;
+ public static String NameValidator_SpecifyFolder;
+ public static String NewFileWizard_NewFileWizardTitle;
+ public static String NewFileWizardPage_NewFileWizardPageDescription;
+ public static String NewFileWizardPage_NewFileWizardPageNameLabel;
+ public static String NewFileWizardPage_NewFileWizardPageTitle;
+ public static String NewFolderWizard_NewFolderWizardTitle;
+ public static String NewFolderWizardPage_NewFolderWizardPageDescription;
+ public static String NewFolderWizardPage_NewFolderWizardPageNameLabel;
+ public static String NewFolderWizardPage_NewFolderWizardPageTitle;
+ public static String NewNodeWizardPage_PromptFolderLabel;
+ public static String SizeValidator_ErrorIncorrectFormat;
+ public static String SizeValidator_ErrorSizeOutofRange;
+ public static String SizeValidator_InfoPrompt;
+ public static String TargetSelectionPage_Description;
+ public static String TargetSelectionPage_Targets;
+ public static String TargetSelectionPage_Title;
+ public static String TreeViewerSearchDialog_LblCancelText;
+ public static String TreeViewerSearchDialog_GrpOptionsText;
+ public static String TreeViewerSearchDialog_BtnCaseText;
+ public static String TreeViewerSearchDialog_BtnPreciseText;
+
+ public static String ContentProvider_notConnected;
+
+}
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties
new file mode 100644
index 000000000..17171148a
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.ui/src/org/eclipse/tcf/te/tcf/filesystem/ui/nls/Messages.properties
@@ -0,0 +1,171 @@
+###############################################################################
+# 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
+###############################################################################
+FSFolderSelectionDialog_MoveDialogMessage=Choose destination for the files to be moved:
+FSFolderSelectionDialog_MoveDialogTitle=Move Files and Folders
+FSFolderSelectionDialog_Refresh_menu=Refresh
+FSFolderSelectionDialog_RefreshAll_menu=Refresh All
+FSFolderSelectionDialog_validate_message=Query folder attributes...
+FSFolderSelectionDialog_notWritable_error=The selected folder is not writable.
+FSFolderSelectionDialog_notWritable_warning=The selected folder is not writable.
+
+
+FSOpenFileDialog_message=Please select an image file for the process.
+FSOpenFileDialog_title=Select Process Image
+FSDelete_ConfirmDelete=Confirm Delete
+FSDelete_ConfirmMessage=Are you sure you want to remove the read-only file ''{0}''?
+FSDelete_ButtonCancel=Cancel
+FSDelete_ButtonNo=&No
+FSDelete_ButtonYes=&Yes
+FSDelete_ButtonYes2All=Yes to &All
+DateValidator_DateInvalidNumber=The date is not a valid number.
+DateValidator_DateOutofRange=The date is a number between 1 and 31.
+DateValidator_InfoFormat=The format of the date is MM/DD/YYYY
+DateValidator_InfoPrompt=Please enter a date.
+DateValidator_InvalidDate=The date entered is not a valid date\!
+DateValidator_MonthInvalidNumber=The month is not a valid number.
+DateValidator_MonthOutofRange=The month is a number between 1 and 12.
+DateValidator_YearInvalidNumber=The year is not a valid number.
+DateValidator_YearOutofRange=The year is a number which is bigger than zero.
+DeleteFilesHandler_ConfirmDialogTitle=Confirm Delete
+DeleteFilesHandler_DeleteMultipleFilesConfirmation=Are you sure you want to delete these {0} files/folders?
+DeleteFilesHandler_DeleteOneFileConfirmation=Are you sure you want to delete ''{0}''?
+FSRenamingAssistant_NameAlreadyExists=A file/folder with the name you specified already exists\! Specify a different name.
+FSRenamingAssistant_SpecifyNonEmptyName=Specify a non-empty name.
+FSRenamingAssistant_UnixIllegalCharacters=File or folder name cannot contain any of the following characters:\n/
+FSRenamingAssistant_WinIllegalCharacters=File or folder name cannot contain any of the following characters:\n\\/:*?<>|
+LocalTypedElement_SavingFile=Saving file: {0}
+MergeEditorInput_LocalFile=Local: {0}
+MergeEditorInput_RemoteFile=Remote: {0}
+MergeEditorInput_CompareLeftAndRight=Compare {0} and {1}
+MergeEditorInput_CompareWithLocalCache=Compare {0} with Local Cache
+MergeInput_CopyNotSupported=Copy is not support by this type of compare input
+RemoteTypedElement_GettingRemoteContent=Getting content from the remote file:
+RemoteTypedElement_DowloadingFile=Downloading file {0}...
+FSDropTargetListener_ConfirmMoveTitle=Confirm Move
+FSDropTargetListener_MovingWarningMultiple=This operation will delete the files after moving. You can copy them without deletion by CTRL + dragging. \n\nAre you sure you want to move these {0} files/folders?
+FSDropTargetListener_MovingWarningSingle=This operation will delete the file after moving. You can copy it without deletion by CTRL + dragging. \n\nAre you sure you want to move ''{0}''?
+FSExplorerEditorPage_PageTitle=File System Explorer
+FSGeneralSearchable_FileType=Select type of file
+FSGeneralSearchable_Find=Find:
+FSGeneralSearchable_GeneralOptionText=General options
+FSGeneralSearchable_SearchHiddenFiles=Search hidden files/folders
+FSGeneralSearchable_SearchSystemFiles=Search system files/folders
+FSModifiedSearchable_DontRemember=Don't remember
+FSModifiedSearchable_LastWeek=Within the last week
+FSModifiedSearchable_PastMonth=Past month
+FSModifiedSearchable_PastYear=Within the past year
+FSModifiedSearchable_SpecifyDates=Specify dates, from
+FSModifiedSearchable_ToDate=to
+FSModifiedSearchable_WhenModified=When was it modified?
+FSUpload_Cancel=Cancel
+FSUpload_No=No
+FSUpload_OverwriteConfirmation=A file with a same name already exists. Are you sure to overwrite {0}?
+FSUpload_OverwriteTitle=Confirm Overwrite
+FSUpload_Yes=Yes
+FSUpload_YesToAll=Yes to All
+FSOperation_ConfirmDialogCancel=Cancel
+FSOperation_ConfirmDialogNo=&No
+FSOperation_ConfirmDialogYes=&Yes
+FSOperation_ConfirmDialogYesToAll=Yes to &All
+FSOperation_ConfirmFileReplace=Confirm File Replace
+FSOperation_ConfirmFileReplaceMessage=This folder already contains a file named {0}.\n\n If the files in the existing folder have the same name as files in the folder you are moving or copying, they will be replaced. Do you still want to move or copy the file?
+FSOperation_ConfirmFolderReplaceMessage=This folder already contains a folder named {0}.\n\n If the files in the existing folder have the same name as files in the folder you are moving or copying, they will be replaced. Do you still want to move or copy the folder?
+FSOperation_ConfirmFolderReplaceTitle=Confirm Folder Replace
+OpenFileHandler_OpeningBinaryNotSupported=Opening a binary file is not supported yet.
+OpenFileHandler_Warning=Warning
+OpenWithMenu_ChooseEditorForOpening=Choose the editor for opening {0}
+OpenWithMenu_DefaultEditor=&Default Editor
+OpenWithMenu_NoEditorFound=No editor found to edit the file resource.
+OpenWithMenu_OpenWith=Open With
+FSRename_RenameFileFolderTitle=Error Renaming File or Folder
+FSSizeSearchable_DontRemember=Don't remember
+FSSizeSearchable_KBS=KB(s)
+FSSizeSearchable_Large=Large (more than 1 MB)
+FSSizeSearchable_Medium=Medium (less than 1 MB)
+FSSizeSearchable_Small=Small (less than 100 KB)
+FSSizeSearchable_SpecifySize=Specify size, from
+FSSizeSearchable_ToText=KB(s) to
+FSSizeSearchable_WhatSize=What size is it?
+FSTreeNodeSearchable_FilesAndFolders=both files and folders
+FSTreeNodeSearchable_FilesOnly=files only
+FSTreeNodeSearchable_FindFilesAndFolders=Find Files
+FSTreeNodeSearchable_FindMessage=Find files and folders under {0}.\nWarning: subsidiary files and folders will be loaded and searched.
+FSTreeNodeSearchable_FoldersOnly=folders only
+FSTreeNodeSearchable_SearchingTargets=Find in
+FSTreeNodeSearchable_SelectedFileSystem=the selected file system
+RenameFilesHandler_TitleRename=Rename
+RenameFilesHandler_TitleRenameFile=Rename File
+RenameFilesHandler_TitleRenameFolder=Rename Folder
+RenameFilesHandler_PromptNewName=New name:
+RenameFilesHandler_RenamePromptMessage=Please enter a new name
+PreferencePage_AutoSavingText=Automatically upload files to targets upon saving
+PreferencePage_CopyOwnershipText=Copy source UID and GID when copying files
+PreferencePage_CopyPermissionText=Copy source permissions when copying files
+PreferencePage_PersistExpanded=Remember expanded directories
+PreferencePage_RenamingOptionText=Use In-place Editor when renaming a file/folder
+AdvancedAttributesDialog_FileBanner=Choose the options you want for this file.
+AdvancedAttributesDialog_FolderBanner=Choose the settings you want for this folder.\n\nWhen you apply these changes you will be asked if you want the\n changes to affect all subfolders and files as well.
+AdvancedAttributesDialog_CompressEncrypt=Compress or Encrypt attributes
+AdvancedAttributesDialog_ArchiveIndex=Archive and Index attributes
+AdvancedAttributesDialog_IndexFile=For fast searching, allow Indexing Service to index this file
+AdvancedAttributesDialog_IndexFolder=For fast searching, allow Indexing Service to index this folder
+AdvancedAttributesDialog_FileArchive=File is ready for archiving
+AdvancedAttributesDialog_FolderArchive=Folder is ready for archiving
+AdvancedAttributesDialog_Encrypt=Encrypt contents to secure data
+AdvancedAttributesDialog_Compress=Compress contents to save disk space
+AdvancedAttributesDialog_ShellTitle=Advanced Attributes
+GeneralInformationPage_Accessed=Accessed:
+GeneralInformationPage_Advanced=\ A&dvanced...
+GeneralInformationPage_Attributes=Attributes:
+GeneralInformationPage_FileSizeInfo={0} KB ({1} bytes)
+GeneralInformationPage_Hidden=Hidden
+GeneralInformationPage_ReadOnly=Read-only
+GeneralInformationPage_Computer=computer
+GeneralInformationPage_Location=Location:
+GeneralInformationPage_Modified=Modified:
+GeneralInformationPage_Name=Name:
+GeneralInformationPage_Size=Size:
+GeneralInformationPage_Type=Type:
+GeneralInformationPage_PermissionText=Permissions:
+PermissionsGroup_Executable=Executable
+PermissionsGroup_GroupPermissions=Group:
+PermissionsGroup_OtherPermissions=Other:
+PermissionsGroup_Readable=Readable
+PermissionsGroup_UserPermissions=User:
+PermissionsGroup_Writable=Writable
+BasicFolderSection_BasicInfoText=Basic Information
+LinuxPermissionsSection_Permissions=Permissions
+WindowsAttributesSection_Attributes=Attributes
+FolderValidator_SpecifyFolder=Please specify the folder where the file or folder is going to be created.
+FolderValidator_DirNotExist=The directory {0} does not exist in the current target.
+FolderValidator_NotWritable=The directory {0} is not writable. Please choose a different one.
+NameValidator_InfoPrompt=Please enter a name to search.
+NameValidator_SpecifyFolder=Please specify the folder where the file or folder is going to be created.
+NewFileWizard_NewFileWizardTitle=New File Wizard
+NewFileWizardPage_NewFileWizardPageDescription=Create a new file in the directory.
+NewFileWizardPage_NewFileWizardPageNameLabel=File name:
+NewFileWizardPage_NewFileWizardPageTitle=New File
+NewFolderWizard_NewFolderWizardTitle=New Folder Wizard
+NewFolderWizardPage_NewFolderWizardPageDescription=Create a new folder in the directory.
+NewFolderWizardPage_NewFolderWizardPageNameLabel=Folder name:
+NewFolderWizardPage_NewFolderWizardPageTitle=New Folder
+NewNodeWizardPage_PromptFolderLabel=Enter or select the parent folder:
+SizeValidator_ErrorIncorrectFormat=The format of the size entered is not correct.
+SizeValidator_ErrorSizeOutofRange=The size entered is not in the expected range.
+SizeValidator_InfoPrompt=Please enter a size number.
+TargetSelectionPage_Description=Please select the target where the new file or folder is created.
+TargetSelectionPage_Targets=Targets:
+TargetSelectionPage_Title=Select the target.
+TreeViewerSearchDialog_LblCancelText=Find:
+TreeViewerSearchDialog_GrpOptionsText=Options
+TreeViewerSearchDialog_BtnCaseText=Case sensitive
+TreeViewerSearchDialog_BtnPreciseText=Precise matching
+
+ContentProvider_notConnected=Please connect to see the filesystem on the target.

Back to the top