├── .gitignore ├── README.md ├── release ├── update_site │ ├── README.md │ ├── content.jar │ ├── artifacts.jar │ ├── plugins │ │ ├── bookmark_1.0.0.201401261220.jar │ │ └── bookmark_1.0.1.201401272243.jar │ ├── features │ │ ├── BookmarkFeature_1.0.0.201401261220.jar │ │ └── BookmarkFeature_1.0.1.201401272243.jar │ └── site.xml └── bookmark_1.0.0.201401272151.jar ├── icons └── sample.gif ├── libs └── gson-2.2.4.jar ├── resources └── demo.gif ├── src └── bookmark │ ├── constant │ └── Constant.java │ ├── utils │ └── ValidationUtils.java │ ├── Activator.java │ └── views │ ├── TreeObject.java │ ├── TreeParent.java │ └── BookmarkView.java ├── .settings └── org.eclipse.jdt.core.prefs ├── .classpath ├── META-INF └── MANIFEST.MF ├── contexts.xml ├── .project ├── LICENSE └── plugin.xml /.gitignore: -------------------------------------------------------------------------------- 1 | bin/* 2 | *.class 3 | .DS_Store 4 | /bin/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/README.md -------------------------------------------------------------------------------- /release/update_site/README.md: -------------------------------------------------------------------------------- 1 | Use github to host bookmark plugin for eclipse marketplace 2 | -------------------------------------------------------------------------------- /icons/sample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/icons/sample.gif -------------------------------------------------------------------------------- /libs/gson-2.2.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/libs/gson-2.2.4.jar -------------------------------------------------------------------------------- /resources/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/resources/demo.gif -------------------------------------------------------------------------------- /release/update_site/content.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/release/update_site/content.jar -------------------------------------------------------------------------------- /release/update_site/artifacts.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/release/update_site/artifacts.jar -------------------------------------------------------------------------------- /release/bookmark_1.0.0.201401272151.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/release/bookmark_1.0.0.201401272151.jar -------------------------------------------------------------------------------- /release/update_site/plugins/bookmark_1.0.0.201401261220.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/release/update_site/plugins/bookmark_1.0.0.201401261220.jar -------------------------------------------------------------------------------- /release/update_site/plugins/bookmark_1.0.1.201401272243.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/release/update_site/plugins/bookmark_1.0.1.201401272243.jar -------------------------------------------------------------------------------- /release/update_site/features/BookmarkFeature_1.0.0.201401261220.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/release/update_site/features/BookmarkFeature_1.0.0.201401261220.jar -------------------------------------------------------------------------------- /release/update_site/features/BookmarkFeature_1.0.1.201401272243.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanks/Bookmark-plugin-for-eclipse/HEAD/release/update_site/features/BookmarkFeature_1.0.1.201401272243.jar -------------------------------------------------------------------------------- /src/bookmark/constant/Constant.java: -------------------------------------------------------------------------------- 1 | package bookmark.constant; 2 | 3 | public class Constant { 4 | 5 | public static final int PARENT = 1; 6 | public static final int CHILD = 0; 7 | 8 | } 9 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 4 | org.eclipse.jdt.core.compiler.compliance=1.6 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.source=1.6 8 | -------------------------------------------------------------------------------- /release/update_site/site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | A treeview bookmark plugin update site 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: Bookmark 4 | Bundle-SymbolicName: bookmark; singleton:=true 5 | Bundle-Version: 1.0.1.qualifier 6 | Bundle-Activator: bookmark.Activator 7 | Bundle-Vendor: hanks 8 | Require-Bundle: org.eclipse.ui, 9 | org.eclipse.core.runtime 10 | Bundle-RequiredExecutionEnvironment: JavaSE-1.6 11 | Bundle-ActivationPolicy: lazy 12 | Import-Package: org.eclipse.core.resources, 13 | org.eclipse.jdt.core, 14 | org.eclipse.ui, 15 | org.eclipse.ui.ide, 16 | org.eclipse.ui.part 17 | Bundle-ClassPath: ., 18 | libs/gson-2.2.4.jar 19 | -------------------------------------------------------------------------------- /contexts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | This is the context help for the sample view with a tree viewer. It was generated by a PDE template. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | bookmark 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | 25 | org.eclipse.pde.PluginNature 26 | org.eclipse.jdt.core.javanature 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/bookmark/utils/ValidationUtils.java: -------------------------------------------------------------------------------- 1 | package bookmark.utils; 2 | 3 | import java.util.regex.PatternSyntaxException; 4 | 5 | import org.eclipse.jface.dialogs.IInputValidator; 6 | 7 | public class ValidationUtils { 8 | 9 | public static IInputValidator getIInputValidatorInstance() { 10 | IInputValidator validator = new IInputValidator() { 11 | 12 | @Override 13 | public String isValid(String input) { 14 | try { 15 | if (input.matches("(?s)[^\\\\/:*?\"<>|\\x00-\\x1F]+$")) { 16 | return null; 17 | } else { 18 | return "Invalid file name"; 19 | } 20 | } catch (PatternSyntaxException ex) { 21 | // Syntax error in the regular expression 22 | } 23 | return "There occure an error in the bookmark plugin,report it to the author."; 24 | } 25 | 26 | }; 27 | return validator; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 hanks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 10 | 11 | 17 | 18 | 19 | 21 | 23 | 28 | 29 | 30 | 31 | 33 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/bookmark/Activator.java: -------------------------------------------------------------------------------- 1 | package bookmark; 2 | 3 | import org.eclipse.jface.resource.ImageDescriptor; 4 | import org.eclipse.ui.plugin.AbstractUIPlugin; 5 | import org.osgi.framework.BundleContext; 6 | 7 | /** 8 | * The activator class controls the plug-in life cycle 9 | */ 10 | public class Activator extends AbstractUIPlugin { 11 | 12 | // The plug-in ID 13 | public static final String PLUGIN_ID = "bookmark"; //$NON-NLS-1$ 14 | 15 | // The shared instance 16 | private static Activator plugin; 17 | 18 | /** 19 | * The constructor 20 | */ 21 | public Activator() { 22 | } 23 | 24 | /* 25 | * (non-Javadoc) 26 | * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) 27 | */ 28 | public void start(BundleContext context) throws Exception { 29 | super.start(context); 30 | plugin = this; 31 | } 32 | 33 | /* 34 | * (non-Javadoc) 35 | * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) 36 | */ 37 | public void stop(BundleContext context) throws Exception { 38 | plugin = null; 39 | super.stop(context); 40 | } 41 | 42 | /** 43 | * Returns the shared instance 44 | * 45 | * @return the shared instance 46 | */ 47 | public static Activator getDefault() { 48 | return plugin; 49 | } 50 | 51 | /** 52 | * Returns an image descriptor for the image file at the given 53 | * plug-in relative path 54 | * 55 | * @param path the path 56 | * @return the image descriptor 57 | */ 58 | public static ImageDescriptor getImageDescriptor(String path) { 59 | return imageDescriptorFromPlugin(PLUGIN_ID, path); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/bookmark/views/TreeObject.java: -------------------------------------------------------------------------------- 1 | package bookmark.views; 2 | 3 | import java.io.Serializable; 4 | 5 | import org.eclipse.core.runtime.IAdaptable; 6 | 7 | import bookmark.constant.Constant; 8 | 9 | /* 10 | * The content provider class is responsible for 11 | * providing objects to the view. It can wrap 12 | * existing objects in adapters or simply return 13 | * objects as-is. These objects may be sensitive 14 | * to the current input of the view, or ignore 15 | * it and always show the same content 16 | * (like Task List, for example). 17 | */ 18 | public class TreeObject implements IAdaptable, Serializable { 19 | private static final long serialVersionUID = -4275221961856278045L; 20 | private String name; 21 | private TreeParent parent; 22 | protected int flag; 23 | private String projectName; 24 | 25 | public TreeObject(String name) { 26 | this.name = name; 27 | this.flag = Constant.CHILD; 28 | this.projectName = ""; 29 | } 30 | 31 | public TreeObject(String name, String projectName) { 32 | this.name = name; 33 | this.flag = Constant.CHILD; 34 | this.projectName = projectName; 35 | } 36 | 37 | public String getName() { 38 | return name; 39 | } 40 | 41 | public void setName(String name) { 42 | this.name = name; 43 | } 44 | 45 | public String getProjectName() { 46 | return this.projectName; 47 | } 48 | 49 | public void setParent(TreeParent parent) { 50 | this.parent = parent; 51 | } 52 | 53 | public TreeParent getParent() { 54 | return parent; 55 | } 56 | 57 | public String toString() { 58 | return getName(); 59 | } 60 | 61 | /** 62 | * Override equals method to use name to compare two TreeObject 63 | */ 64 | public boolean equals(Object object) { 65 | if ((object instanceof TreeObject) && ((TreeObject) object).getName() == this.getName()) { 66 | return true; 67 | } else { 68 | return false; 69 | } 70 | } 71 | 72 | public Object getAdapter(Class key) { 73 | return null; 74 | } 75 | } -------------------------------------------------------------------------------- /src/bookmark/views/TreeParent.java: -------------------------------------------------------------------------------- 1 | package bookmark.views; 2 | 3 | import java.util.ArrayList; 4 | 5 | import bookmark.constant.Constant; 6 | 7 | /* 8 | * The content provider class is responsible for 9 | * providing objects to the view. It can wrap 10 | * existing objects in adapters or simply return 11 | * objects as-is. These objects may be sensitive 12 | * to the current input of the view, or ignore 13 | * it and always show the same content 14 | * (like Task List, for example). 15 | */ 16 | public class TreeParent extends TreeObject { 17 | 18 | /** 19 | * 20 | */ 21 | private static final long serialVersionUID = -1850997564183666463L; 22 | private ArrayList children; 23 | 24 | public TreeParent(String name) { 25 | super(name); 26 | this.flag = Constant.PARENT; 27 | children = new ArrayList(); 28 | } 29 | 30 | public void addChild(TreeObject child) { 31 | children.add(child); 32 | child.setParent(this); 33 | } 34 | 35 | public void removeChild(TreeObject child) { 36 | children.remove(child); 37 | child.setParent(null); 38 | } 39 | 40 | /** 41 | * 42 | * @return TreeObject list or TreeObject[] when no children 43 | */ 44 | public TreeObject[] getChildren() { 45 | return (TreeObject[]) children.toArray(new TreeObject[children.size()]); 46 | } 47 | 48 | public boolean hasChildren() { 49 | return children.size() > 0; 50 | } 51 | 52 | /** 53 | * Add child to specified target node 54 | * 55 | * Use recursion way to add child, if child is leaf, to find his parent and 56 | * add to its parent 57 | * 58 | * @param obj 59 | * @param path 60 | */ 61 | public boolean addChild(TreeObject target, TreeObject child) { 62 | TreeObject[] children = this.getChildren(); 63 | for (int i = 0; i < children.length; i++) { 64 | if (children[i].flag == Constant.PARENT) { 65 | // if target is folder 66 | if (target == children[i]) { 67 | // insert child 68 | ((TreeParent) children[i]).addChild(child); 69 | return true; 70 | } 71 | 72 | boolean is_ok = ((TreeParent) children[i]).addChild(target, child); 73 | 74 | if (is_ok) { 75 | return true; 76 | } 77 | } else if (children[i].flag == Constant.CHILD) { 78 | if (children[i] == target) { 79 | TreeParent parent = children[i].getParent(); 80 | parent.addChild(child); 81 | return true; 82 | } 83 | } 84 | } 85 | return false; 86 | } 87 | 88 | /** 89 | * Remove child from target node 90 | * 91 | * @param target 92 | * @return true when remove successfully or else false 93 | */ 94 | public boolean removeSelectedChild(TreeObject target) { 95 | TreeObject[] children = this.getChildren(); 96 | for (int i = 0; i < children.length; i++) { 97 | if (children[i].flag == Constant.PARENT) { 98 | // if target is folder 99 | if (target == children[i]) { 100 | // delete child 101 | this.removeChild(target); 102 | return true; 103 | } 104 | 105 | boolean is_ok = ((TreeParent) children[i]).removeSelectedChild(target); 106 | 107 | if (is_ok) { 108 | return true; 109 | } 110 | } else if (children[i].flag == Constant.CHILD) { 111 | if (children[i] == target) { 112 | TreeParent parent = children[i].getParent(); 113 | parent.removeChild(target); 114 | return true; 115 | } 116 | } 117 | } 118 | return false; 119 | } 120 | } -------------------------------------------------------------------------------- /src/bookmark/views/BookmarkView.java: -------------------------------------------------------------------------------- 1 | package bookmark.views; 2 | 3 | import org.eclipse.swt.widgets.Composite; 4 | import org.eclipse.ui.part.*; 5 | import org.eclipse.jface.viewers.*; 6 | import org.eclipse.jface.window.Window; 7 | import org.eclipse.swt.graphics.Image; 8 | import org.eclipse.jface.action.*; 9 | import org.eclipse.jface.dialogs.InputDialog; 10 | import org.eclipse.jface.dialogs.MessageDialog; 11 | import org.eclipse.ui.*; 12 | import org.eclipse.swt.widgets.Menu; 13 | import org.eclipse.swt.SWT; 14 | import org.eclipse.core.runtime.Path; 15 | 16 | import org.eclipse.core.runtime.preferences.InstanceScope; 17 | import org.eclipse.ui.part.FileEditorInput; 18 | import org.eclipse.core.resources.IFile; 19 | import org.eclipse.core.resources.IProject; 20 | import org.eclipse.core.resources.IResource; 21 | import org.eclipse.core.resources.IWorkspaceRoot; 22 | import org.eclipse.core.resources.ResourcesPlugin; 23 | import org.osgi.service.prefs.BackingStoreException; 24 | import org.osgi.service.prefs.Preferences; 25 | 26 | import com.google.gson.Gson; 27 | 28 | import bookmark.constant.Constant; 29 | import bookmark.utils.ValidationUtils; 30 | 31 | import java.io.ByteArrayInputStream; 32 | import java.io.ByteArrayOutputStream; 33 | import java.io.IOException; 34 | import java.io.ObjectInputStream; 35 | import java.io.ObjectOutputStream; 36 | 37 | import org.eclipse.jdt.core.ICompilationUnit; 38 | 39 | /** 40 | * This sample class demonstrates how to plug-in a new workbench view. The view 41 | * shows data obtained from the model. The sample creates a dummy model on the 42 | * fly, but a real implementation would connect to the model available either in 43 | * this or another plug-in (e.g. the workspace). The view is connected to the 44 | * model using a content provider. 45 | *

46 | * The view uses a label provider to define how model objects should be 47 | * presented in the view. Each view can present the same model objects using 48 | * different labels and icons, if needed. Alternatively, a single label provider 49 | * can be shared between views in order to ensure that objects of the same type 50 | * are presented in the same way everywhere. 51 | *

52 | */ 53 | 54 | public class BookmarkView extends ViewPart { 55 | 56 | /** 57 | * The ID of the view as specified by the extension. 58 | */ 59 | public static final String ID = "bookmark.views.BookmarkView"; 60 | public static final String DATA_STORE_KEY = "bookmark_datasource"; 61 | 62 | private TreeViewer viewer; 63 | 64 | private Action addFolderAction; 65 | private Action addBookmarkAction; 66 | private Action addAllBookmarkAction; 67 | private Action deleteAction; 68 | private Action renameAction; 69 | private Action doubleClickAction; 70 | 71 | class ViewContentProvider implements IStructuredContentProvider, ITreeContentProvider { 72 | 73 | public void inputChanged(Viewer v, Object oldInput, Object newInput) { 74 | } 75 | 76 | public void dispose() { 77 | } 78 | 79 | public Object[] getElements(Object parent) { 80 | return getChildren(parent); 81 | } 82 | 83 | public Object getParent(Object child) { 84 | if (child instanceof TreeObject) { 85 | return ((TreeObject) child).getParent(); 86 | } 87 | return null; 88 | } 89 | 90 | public Object[] getChildren(Object parent) { 91 | if (parent instanceof TreeParent) { 92 | return ((TreeParent) parent).getChildren(); 93 | } 94 | return new Object[0]; 95 | } 96 | 97 | public boolean hasChildren(Object parent) { 98 | if (parent instanceof TreeParent) 99 | return ((TreeParent) parent).hasChildren(); 100 | return false; 101 | } 102 | } 103 | 104 | class ViewLabelProvider extends LabelProvider { 105 | 106 | public String getText(Object obj) { 107 | return obj.toString(); 108 | } 109 | 110 | public Image getImage(Object obj) { 111 | String imageKey = ISharedImages.IMG_OBJ_FILE; 112 | if (obj instanceof TreeParent) 113 | imageKey = ISharedImages.IMG_OBJ_FOLDER; 114 | return PlatformUI.getWorkbench().getSharedImages().getImage(imageKey); 115 | // if need to change customize image 116 | // return new Image(null, new FileInputStream("images/file.gif")); 117 | } 118 | } 119 | 120 | class NameSorter extends ViewerSorter { 121 | } 122 | 123 | /** 124 | * The constructor. 125 | */ 126 | public BookmarkView() { 127 | } 128 | 129 | /** 130 | * This is a callback that will allow us to create the viewer and initialize 131 | * it. 132 | */ 133 | public void createPartControl(Composite parent) { 134 | viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); 135 | viewer.setContentProvider(new ViewContentProvider()); 136 | viewer.setLabelProvider(new ViewLabelProvider()); 137 | viewer.setSorter(new NameSorter()); 138 | 139 | // get data from store or else do initialization 140 | TreeParent invisibleRoot = this.loadPersistantData(); 141 | 142 | // set data source 143 | viewer.setInput(invisibleRoot); 144 | 145 | // Create the help context id for the viewer's control 146 | PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(), "bookmark.viewer"); 147 | makeActions(); 148 | hookContextMenu(); 149 | hookDoubleClickAction(); 150 | contributeToActionBars(); 151 | } 152 | 153 | private void hookContextMenu() { 154 | MenuManager menuMgr = new MenuManager("#PopupMenu"); 155 | menuMgr.setRemoveAllWhenShown(true); 156 | menuMgr.addMenuListener(new IMenuListener() { 157 | public void menuAboutToShow(IMenuManager manager) { 158 | 159 | IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); 160 | if (!selection.isEmpty()) { 161 | TreeObject target = (TreeObject) selection.getFirstElement(); 162 | if (target instanceof TreeParent) { 163 | manager.add(addBookmarkAction); 164 | manager.add(addFolderAction); 165 | manager.add(deleteAction); 166 | manager.add(renameAction); 167 | manager.add(addAllBookmarkAction); 168 | } else { 169 | manager.add(deleteAction); 170 | } 171 | } else { 172 | manager.add(addBookmarkAction); 173 | manager.add(addFolderAction); 174 | manager.add(addAllBookmarkAction); 175 | } 176 | } 177 | }); 178 | Menu menu = menuMgr.createContextMenu(viewer.getControl()); 179 | viewer.getControl().setMenu(menu); 180 | getSite().registerContextMenu(menuMgr, viewer); 181 | } 182 | 183 | private void contributeToActionBars() { 184 | IActionBars bars = getViewSite().getActionBars(); 185 | fillLocalPullDown(bars.getMenuManager()); 186 | fillLocalToolBar(bars.getToolBarManager()); 187 | } 188 | 189 | private void fillLocalPullDown(IMenuManager manager) { 190 | 191 | } 192 | 193 | private void fillLocalToolBar(IToolBarManager manager) { 194 | manager.add(this.addBookmarkAction); 195 | manager.add(this.addFolderAction); 196 | manager.add(this.deleteAction); 197 | } 198 | 199 | @SuppressWarnings("deprecation") 200 | private void makeActions() { 201 | 202 | // remove selected folder or bookmark 203 | this.deleteAction = new Action() { 204 | public void run() { 205 | // get invisibleRoot 206 | TreeParent invisibleRoot = (TreeParent) viewer.getInput(); 207 | 208 | // get selection 209 | ISelection selection = viewer.getSelection(); 210 | Object obj = ((IStructuredSelection) selection).getFirstElement(); 211 | if (obj == null) { 212 | showMessage("No selection in Bookmark View."); 213 | } else { 214 | TreeObject target = (TreeObject) obj; 215 | // confirm dialog 216 | String title = "Confirm"; 217 | String question = "Do you really want to delelte this whole node?"; 218 | boolean answer = MessageDialog.openConfirm(null, title, question); 219 | if (answer) { 220 | invisibleRoot.removeSelectedChild(target); 221 | } 222 | // keep expand situation 223 | Object[] expandedElements = viewer.getExpandedElements(); 224 | TreePath[] expandedTreePaths = viewer.getExpandedTreePaths(); 225 | 226 | // update data source 227 | viewer.setInput(invisibleRoot); 228 | 229 | viewer.setExpandedElements(expandedElements); 230 | viewer.setExpandedTreePaths(expandedTreePaths); 231 | 232 | // save to persistent 233 | BookmarkView.savePersistantData(invisibleRoot); 234 | } 235 | } 236 | }; 237 | this.deleteAction.setText("Delete"); 238 | this.deleteAction.setToolTipText("Delete selected folder or bookmark."); 239 | this.deleteAction.setImageDescriptor( 240 | PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_ETOOL_DELETE)); 241 | 242 | // use user input to add parent 243 | this.addFolderAction = new Action() { 244 | public void run() { 245 | String parentName; 246 | // create an input dialog to get user input 247 | String dialogTitle = "Input"; 248 | String dialogMessage = "Please enter folder name:"; 249 | String initialValue = ""; 250 | InputDialog dlg = new InputDialog(null, dialogTitle, dialogMessage, initialValue, 251 | ValidationUtils.getIInputValidatorInstance()); 252 | dlg.open(); 253 | if (dlg.getReturnCode() != Window.OK) { 254 | return; 255 | } else { 256 | parentName = dlg.getValue(); 257 | } 258 | 259 | // new a folder 260 | TreeParent newParent = new TreeParent(parentName); 261 | // get invisible root 262 | TreeParent invisibleRoot = (TreeParent) viewer.getInput(); 263 | 264 | // get selection 265 | ISelection selection = viewer.getSelection(); 266 | Object obj = ((IStructuredSelection) selection).getFirstElement(); 267 | if (obj == null) { 268 | // no selection, default to add to the invisibleRoot 269 | invisibleRoot.addChild(newParent); 270 | } else { 271 | invisibleRoot.addChild((TreeObject) obj, newParent); 272 | } 273 | 274 | // keep expand situation 275 | Object[] expandedElements = viewer.getExpandedElements(); 276 | TreePath[] expandedTreePaths = viewer.getExpandedTreePaths(); 277 | 278 | // update data source 279 | viewer.setInput(invisibleRoot); 280 | 281 | viewer.setExpandedElements(expandedElements); 282 | viewer.setExpandedTreePaths(expandedTreePaths); 283 | 284 | // save to persistent 285 | BookmarkView.savePersistantData(invisibleRoot); 286 | } 287 | }; 288 | this.addFolderAction.setText("Add folder here"); 289 | this.addFolderAction.setToolTipText("Add folder here"); 290 | this.addFolderAction.setImageDescriptor( 291 | PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FOLDER)); 292 | 293 | // add book mark to selected parent 294 | this.addBookmarkAction = new Action() { 295 | public void run() { 296 | // get active editor info 297 | String relativePath = ""; 298 | String projectName = ""; 299 | 300 | IWorkbench wb = PlatformUI.getWorkbench(); 301 | IWorkbenchWindow window = wb.getActiveWorkbenchWindow(); 302 | IWorkbenchPage page = window.getActivePage(); 303 | IEditorPart editor = page.getActiveEditor(); 304 | 305 | if (editor != null) { 306 | IFileEditorInput input = (IFileEditorInput) editor.getEditorInput(); 307 | IFile file = input.getFile(); 308 | relativePath = file.getProjectRelativePath().toOSString(); 309 | projectName = file.getProject().getName(); 310 | } else { 311 | // check selection from package explorer 312 | ISelectionService service = getSite().getWorkbenchWindow().getSelectionService(); 313 | IStructuredSelection packageExploerSelection = (IStructuredSelection) service 314 | .getSelection("org.eclipse.jdt.ui.PackageExplorer"); 315 | if (packageExploerSelection != null) { 316 | Object obj = packageExploerSelection.getFirstElement(); 317 | if (obj == null) { 318 | showMessage("No selection in package explorer"); 319 | return; 320 | } else { 321 | // get file info for selection from package explorer 322 | IResource resource = ((ICompilationUnit) obj).getResource(); 323 | 324 | if (resource.getType() == IResource.FILE) { 325 | IFile ifile = (IFile) resource; 326 | relativePath = ifile.getProjectRelativePath().toOSString(); 327 | projectName = ifile.getProject().getName(); 328 | } 329 | } 330 | } else { 331 | showMessage("No active editor or selection in package explorer"); 332 | return; 333 | } 334 | } 335 | 336 | // create leaf with file info 337 | TreeObject child = new TreeObject(relativePath, projectName); 338 | 339 | // get invisibleRoot 340 | TreeParent invisibleRoot = (TreeParent) viewer.getInput(); 341 | 342 | // get selection 343 | ISelection selection = viewer.getSelection(); 344 | Object obj = ((IStructuredSelection) selection).getFirstElement(); 345 | if (obj == null) { 346 | // default to insert invisibleRoot 347 | invisibleRoot.addChild(child); 348 | } else { 349 | TreeObject targetParent = (TreeObject) obj; 350 | invisibleRoot.addChild(targetParent, child); 351 | } 352 | 353 | // keep expand situation 354 | Object[] expandedElements = viewer.getExpandedElements(); 355 | TreePath[] expandedTreePaths = viewer.getExpandedTreePaths(); 356 | 357 | // update data source 358 | viewer.setInput(invisibleRoot); 359 | 360 | viewer.setExpandedElements(expandedElements); 361 | viewer.setExpandedTreePaths(expandedTreePaths); 362 | 363 | // save to persistent 364 | BookmarkView.savePersistantData(invisibleRoot); 365 | } 366 | }; 367 | this.addBookmarkAction.setText("Add bookmark here"); 368 | this.addBookmarkAction.setToolTipText("Add bookmark here"); 369 | this.addBookmarkAction.setImageDescriptor( 370 | PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_BKMRK_TSK)); 371 | 372 | addAllBookmarkAction = new Action() { 373 | public void run() { 374 | // get active editor info 375 | String relativePath = ""; 376 | String projectName = ""; 377 | 378 | IWorkbench wb = PlatformUI.getWorkbench(); 379 | IWorkbenchWindow window = wb.getActiveWorkbenchWindow(); 380 | IWorkbenchPage page = window.getActivePage(); 381 | IEditorPart[] editors = page.getEditors(); 382 | if (editors != null) { 383 | for (int i = 0; i < editors.length; i++) { 384 | IEditorPart editor = editors[i]; 385 | 386 | IFileEditorInput input = (IFileEditorInput) editor.getEditorInput(); 387 | IFile file = input.getFile(); 388 | relativePath = file.getProjectRelativePath().toOSString(); 389 | projectName = file.getProject().getName(); 390 | 391 | // create leaf with file info 392 | TreeObject child = new TreeObject(relativePath, projectName); 393 | 394 | // get invisibleRoot 395 | TreeParent invisibleRoot = (TreeParent) viewer.getInput(); 396 | 397 | // get selection 398 | ISelection selection = viewer.getSelection(); 399 | Object obj = ((IStructuredSelection) selection).getFirstElement(); 400 | if (obj == null) { 401 | // default to insert invisibleRoot 402 | invisibleRoot.addChild(child); 403 | } else { 404 | TreeObject targetParent = (TreeObject) obj; 405 | invisibleRoot.addChild(targetParent, child); 406 | } 407 | 408 | // keep expand situation 409 | Object[] expandedElements = viewer.getExpandedElements(); 410 | TreePath[] expandedTreePaths = viewer.getExpandedTreePaths(); 411 | 412 | // update data source 413 | viewer.setInput(invisibleRoot); 414 | 415 | viewer.setExpandedElements(expandedElements); 416 | viewer.setExpandedTreePaths(expandedTreePaths); 417 | 418 | // save to persistent 419 | BookmarkView.savePersistantData(invisibleRoot); 420 | } 421 | } else { 422 | showMessage("No active editor"); 423 | return; 424 | } 425 | 426 | } 427 | }; 428 | this.addAllBookmarkAction.setText("Add opened files here"); 429 | this.addAllBookmarkAction.setToolTipText("Add opened files here"); 430 | this.addAllBookmarkAction.setImageDescriptor( 431 | PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJS_BKMRK_TSK)); 432 | 433 | // rename the node 434 | renameAction = new Action() { 435 | public void run() { 436 | 437 | ISelection selection = viewer.getSelection(); 438 | Object obj = ((IStructuredSelection) selection).getFirstElement(); 439 | 440 | if (obj != null) { 441 | TreeObject treeObject = (TreeObject) obj; 442 | if (treeObject.flag == Constant.PARENT) { 443 | 444 | String parentName = treeObject.getName(); 445 | // create an input dialog to get user input 446 | String dialogTitle = "Input"; 447 | String dialogMessage = "Please enter folder name:"; 448 | InputDialog dlg = new InputDialog(null, dialogTitle, dialogMessage, parentName, 449 | ValidationUtils.getIInputValidatorInstance()); 450 | dlg.open(); 451 | if (dlg.getReturnCode() != Window.OK) { 452 | return; 453 | } else { 454 | parentName = dlg.getValue(); 455 | } 456 | 457 | treeObject.setName(parentName); 458 | } 459 | } 460 | 461 | TreeParent invisibleRoot = (TreeParent) viewer.getInput(); 462 | viewer.setInput(invisibleRoot); 463 | BookmarkView.savePersistantData(invisibleRoot); 464 | } 465 | }; 466 | 467 | this.renameAction.setText("Rename"); 468 | this.renameAction.setToolTipText("Rename the folder."); 469 | 470 | // double click action to open file 471 | doubleClickAction = new Action() { 472 | public void run() { 473 | ISelection selection = viewer.getSelection(); 474 | Object obj = ((IStructuredSelection) selection).getFirstElement(); 475 | 476 | if (obj != null) { 477 | TreeObject treeObject = (TreeObject) obj; 478 | if (treeObject.flag == 1) { 479 | // expand and collapse folder when double click 480 | if (viewer.getExpandedState(treeObject)) { 481 | viewer.collapseToLevel(treeObject, 1); 482 | } else { 483 | viewer.expandToLevel(treeObject, 1); 484 | } 485 | return; 486 | } 487 | String relativePath = treeObject.getName(); 488 | IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); 489 | IProject project = workspaceRoot.getProject(treeObject.getProjectName()); 490 | IFile file1 = project.getFile((new Path(relativePath))); 491 | IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 492 | IWorkbenchPage page = window.getActivePage(); 493 | IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry() 494 | .getDefaultEditor(file1.getName()); 495 | 496 | // if no right editor to find, use default text editor 497 | try { 498 | if (desc == null) { 499 | page.openEditor(new FileEditorInput(file1), "org.eclipse.ui.DefaultTextEditor"); 500 | } else { 501 | page.openEditor(new FileEditorInput(file1), desc.getId()); 502 | } 503 | } catch (PartInitException e) { 504 | e.printStackTrace(); 505 | } 506 | } 507 | } 508 | }; 509 | } 510 | 511 | private void hookDoubleClickAction() { 512 | viewer.addDoubleClickListener(new IDoubleClickListener() { 513 | public void doubleClick(DoubleClickEvent event) { 514 | doubleClickAction.run(); 515 | } 516 | }); 517 | } 518 | 519 | private void showMessage(String message) { 520 | MessageDialog.openInformation(viewer.getControl().getShell(), "Bookmark View", message); 521 | } 522 | 523 | /** 524 | * Passing the focus request to the viewer's control. 525 | */ 526 | public void setFocus() { 527 | viewer.getControl().setFocus(); 528 | } 529 | 530 | /** 531 | * Use eclipse Preferences API to make data persistent 532 | * 533 | * @param dataSource 534 | */ 535 | private static void savePersistantData(TreeParent dataSource) { 536 | Preferences prefs = InstanceScope.INSTANCE.getNode(ID); 537 | 538 | // change object to string 539 | Gson gson = new Gson(); 540 | 541 | // change object byte array 542 | ByteArrayOutputStream b = new ByteArrayOutputStream(); 543 | ObjectOutputStream o; 544 | try { 545 | o = new ObjectOutputStream(b); 546 | o.writeObject(dataSource); 547 | } catch (IOException e1) { 548 | // TODO Auto-generated catch block 549 | e1.printStackTrace(); 550 | } 551 | 552 | byte[] byteDataArray = b.toByteArray(); 553 | 554 | // use gson to change byte array to string 555 | String json_str = gson.toJson(byteDataArray); 556 | 557 | prefs.put(DATA_STORE_KEY, json_str); 558 | try { 559 | // store to disk 560 | prefs.flush(); 561 | } catch (BackingStoreException e) { 562 | e.printStackTrace(); 563 | } 564 | } 565 | 566 | private TreeParent loadPersistantData() { 567 | Preferences prefs = InstanceScope.INSTANCE.getNode(ID); 568 | 569 | String json_str = prefs.get(DATA_STORE_KEY, ""); 570 | 571 | if (json_str == "") { 572 | // no data source yet, do initialization 573 | TreeParent invisibleRoot = new TreeParent(""); 574 | return invisibleRoot; 575 | } else { 576 | Gson gson = new Gson(); 577 | byte[] byteDataArray = gson.fromJson(json_str, byte[].class); 578 | 579 | // deserialize object from byteDataArray 580 | ByteArrayInputStream b = new ByteArrayInputStream(byteDataArray); 581 | ObjectInputStream o; 582 | TreeParent invisibleRoot = null; 583 | try { 584 | o = new ObjectInputStream(b); 585 | invisibleRoot = (TreeParent) o.readObject(); 586 | } catch (IOException e) { 587 | // TODO Auto-generated catch block 588 | e.printStackTrace(); 589 | } catch (ClassNotFoundException e) { 590 | // TODO Auto-generated catch block 591 | e.printStackTrace(); 592 | } 593 | return invisibleRoot; 594 | } 595 | } 596 | } --------------------------------------------------------------------------------