Source code: com/port80/eclipse/jdt/annotation/AnnotationView.java
1 package com.port80.eclipse.jdt.annotation;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.eclipse.core.internal.runtime.Assert;
7 import org.eclipse.core.resources.IFile;
8 import org.eclipse.core.resources.ResourcesPlugin;
9 import org.eclipse.jdt.core.IJavaElement;
10 import org.eclipse.jdt.core.IType;
11 import org.eclipse.jface.action.Action;
12 import org.eclipse.jface.action.IMenuListener;
13 import org.eclipse.jface.action.IMenuManager;
14 import org.eclipse.jface.action.IStatusLineManager;
15 import org.eclipse.jface.action.IToolBarManager;
16 import org.eclipse.jface.action.MenuManager;
17 import org.eclipse.jface.action.Separator;
18 import org.eclipse.jface.dialogs.MessageDialog;
19 import org.eclipse.jface.util.IPropertyChangeListener;
20 import org.eclipse.jface.util.PropertyChangeEvent;
21 import org.eclipse.jface.viewers.DoubleClickEvent;
22 import org.eclipse.jface.viewers.IDoubleClickListener;
23 import org.eclipse.jface.viewers.ISelection;
24 import org.eclipse.jface.viewers.ISelectionChangedListener;
25 import org.eclipse.jface.viewers.IStructuredSelection;
26 import org.eclipse.jface.viewers.SelectionChangedEvent;
27 import org.eclipse.jface.viewers.StructuredSelection;
28 import org.eclipse.jface.viewers.TreeViewer;
29 import org.eclipse.jface.window.Window;
30 import org.eclipse.swt.SWT;
31 import org.eclipse.swt.SWTError;
32 import org.eclipse.swt.dnd.DND;
33 import org.eclipse.swt.dnd.TextTransfer;
34 import org.eclipse.swt.dnd.Transfer;
35 import org.eclipse.swt.events.KeyEvent;
36 import org.eclipse.swt.events.KeyListener;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Menu;
39 import org.eclipse.swt.widgets.MessageBox;
40 import org.eclipse.ui.IActionBars;
41 import org.eclipse.ui.IEditorInput;
42 import org.eclipse.ui.IEditorPart;
43 import org.eclipse.ui.IMemento;
44 import org.eclipse.ui.IPartListener;
45 import org.eclipse.ui.ISharedImages;
46 import org.eclipse.ui.IViewSite;
47 import org.eclipse.ui.IWorkbenchPart;
48 import org.eclipse.ui.PartInitException;
49 import org.eclipse.ui.PlatformUI;
50 import org.eclipse.ui.part.FileEditorInput;
51 import org.eclipse.ui.part.ViewPart;
52
53 import com.port80.eclipse.jdt.IConstants;
54 import com.port80.eclipse.jdt.JdtPlugin;
55 import com.port80.eclipse.jdt.Util;
56 import com.port80.eclipse.jdt.util.JavaUtil;
57 import com.port80.eclipse.jdt.util.PersistentFolder;
58 import com.port80.eclipse.jdt.util.PersistentItem;
59 import com.port80.eclipse.util.IncrementalFindTreeTarget;
60 import com.port80.eclipse.util.UtilPluginImages;
61
62 /**
63 * A TreeViewer that shows content of the AnnotationModel.
64 *
65 * The View provides various filter and sorting functions for inspecting and searching in the Annotation.
66 * The Annotation machanism automatically maintain the set of IResource/IJavaElement visited in various way with
67 * access information. The Annotation can be used for backtracing to previous location and for annotation.
68 */
69 public class AnnotationView
70 extends ViewPart
71 implements KeyListener, IAnnotationModelListener, IPropertyChangeListener {
72
73 ////////////////////////////////////////////////////////////////////////
74
75 public static final String ID = "com.port80.eclipse.jdt.annotation.AnnotationView";
76
77 private static final String NAME = "AnnotationView";
78 private static final String VERSION = "v0.1";
79 private static final boolean DEBUG = true;
80 private static final boolean TRACE = true;
81
82 private static final int FIND_KEYMASK = 0;
83 private static final int FIND_FORWARD_KEYCHAR = 's';
84 private static final int FIND_BACKWARD_KEYCHAR = 'r';
85 private static final int ACTION_KEYMASK = 0;
86 private static final int DELETE_ACTION_KEYCHAR = 'd';
87
88 ////////////////////////////////////////////////////////////////////////
89
90 private TreeViewer fViewer;
91 private AnnotationManager fAnnotationManager;
92 private String fSortKey;
93 private String fDefaultFolderName; /** Current folder. */
94 private IncrementalFindTreeTarget fFindTarget;
95 //
96 private Action fActionHeader;
97 private Action fActionEdit;
98 private Action fActionClipboard;
99 private Action fActionAdd;
100 private Action fActionCopy;
101 private Action fActionMove;
102 private Action fActionDelete;
103 private Action fActionSort;
104 private Action fActionResolve;
105 private Action fActionSetInbox;
106 private Action fActionAbout;
107
108 private IPartListener fPartListener;
109
110 ////////////////////////////////////////////////////////////////////////
111
112 /**
113 * The constructor.
114 */
115 public AnnotationView() {
116 if (TRACE)
117 System.err.println(NAME + "()");
118 fSortKey = AnnotationSorter.DEF_SORTKEY;
119 }
120
121 ////////////////////////////////////////////////////////////////////////
122
123 public void init(IViewSite site, IMemento memento) throws PartInitException {
124 super.init(site, memento);
125 if (TRACE)
126 System.err.println(NAME + ".init()");
127 if (memento != null) {
128 fSortKey = memento.getString("SortBy");
129 if (fSortKey == null)
130 fSortKey = AnnotationSorter.DEF_SORTKEY;
131 fDefaultFolderName = memento.getString("Folder");
132 }
133 //NOTE: init() is called before createPartControl().
134 fAnnotationManager = JdtPlugin.getAnnotationManager();
135 if (fDefaultFolderName == null)
136 fDefaultFolderName = AnnotationManager.INBOX;
137 PersistentFolder folder = fAnnotationManager.findFolder(fDefaultFolderName);
138 folder.setActive(true);
139 }
140
141 /**
142 * @see IWorkbenchPart#dispose()
143 */
144 public void dispose() {
145 getSite().getPage().removePartListener(fPartListener);
146 JdtPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
147 fAnnotationManager.removeModelListener(this);
148 super.dispose();
149 }
150
151 /**
152 * This is a callback that will allow us to create the viewer and initialize it.
153 */
154 public void createPartControl(Composite parent) {
155 if (TRACE)
156 System.err.println(NAME + ".createPartControl()");
157 fViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
158 fViewer.setContentProvider(fAnnotationManager);
159 fViewer.setLabelProvider(fAnnotationManager);
160 fViewer.setSorter(new AnnotationSorter(fSortKey));
161 fViewer.setInput(ResourcesPlugin.getWorkspace());
162 fViewer.refresh();
163 fViewer.expandAll();
164 getViewSite().setSelectionProvider(fViewer);
165 fViewer.addSelectionChangedListener(new ISelectionChangedListener() {
166 public void selectionChanged(SelectionChangedEvent event) {
167 handleSelectionChanged(event);
168 }
169 });
170 makeActions();
171 hookContextMenu();
172 hookDoubleClickAction();
173 hookKeyListener();
174 contributeToActionBars();
175 fAnnotationManager.addModelListener(this);
176 JdtPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
177 hookPartListener();
178 JdtPlugin.getDefault().enableEditorHistory();
179 }
180
181 // IPropertyChangeListener methods //////////////////////////////
182 //
183
184 /**
185 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
186 */
187 public void propertyChange(PropertyChangeEvent event) {
188 if (IConstants.PREF_ANNOTATIONVIEW_INBOX_LIMIT.equals(event.getProperty())) {
189 fAnnotationManager.initPrefs();
190 }
191 }
192
193 // PartListener methods /////////////////////////////////////////
194 //
195
196 /** Listen to any part activation and update the method view if an editor part is activated. */
197 private void hookPartListener() {
198 fPartListener = new IPartListener() {
199 public void partActivated(IWorkbenchPart part) {
200 editorActivation(part);
201 }
202 public void partBroughtToTop(IWorkbenchPart part) {
203 }
204 public void partClosed(IWorkbenchPart part) {
205 }
206 public void partDeactivated(IWorkbenchPart part) {
207 }
208 public void partOpened(IWorkbenchPart part) {
209 }
210 };
211 getSite().getPage().addPartListener(fPartListener);
212 }
213
214 /**
215 * Select the IResources for the activated editor if it exists in the AnnotationModel.
216 * Otherwise, do nothing.
217 * //FIXME: For now, this only works for IJavaElement.
218 */
219 void editorActivation(IWorkbenchPart part) {
220 if (!(part instanceof IEditorPart))
221 return;
222 addFromEditor((IEditorPart)part, AnnotationManager.INBOX);
223 // IJavaElement element = JavaUtil.getSelectedElementFromEditor(part);
224 // if (element == null)
225 // return;
226 // IType type = Util.findJavaType(element);
227 // if (type != null)
228 // fAnnotationManager.addAutomatic(element);
229 }
230
231 ////////////////////////////////////////////////////////////////////////
232
233 public void saveState(IMemento memento) {
234 //NOTE: memento is already a child created for this view.
235 memento.putString("SortBy", fSortKey);
236 memento.putString("Folder", fDefaultFolderName);
237 if (fAnnotationManager != null)
238 fAnnotationManager.saveXMLState();
239 }
240
241 ////////////////////////////////////////////////////////////////////////
242
243 public TreeViewer getViewer() {
244 return fViewer;
245 }
246
247 ////////////////////////////////////////////////////////////////////////
248
249 /**
250 * Add and edit annotation on a object.
251 * If user cancel editing, item is not added and if item already exists, it is not modified.
252 */
253 public void addAnnotation(Object a) {
254 PersistentItem item;
255 if (a instanceof PersistentItem) {
256 item = (PersistentItem) a;
257 } else {
258 item = PersistentItem.create(a, fDefaultFolderName);
259 if (item == null) {
260 showMessage("Invalid object: " + a);
261 return;
262 }
263 }
264 PersistentItem original = fAnnotationManager.get(item);
265 if (original != null)
266 item = original;
267 String folder = editAnnotation(item);
268 if (folder == null) // Cancelled.
269 return;
270 if (original == null) {
271 fAnnotationManager.add(item, folder);
272 refresh();
273 } else {
274 if (folder.equals(item.getParent())) {
275 refresh(item);
276 } else {
277 fAnnotationManager.moveItem(item, folder);
278 }
279 }
280 }
281
282 /**
283 * Popup a dialog to edit the given item's annotation.
284 * @return null if edit cancelled, else the new folder name.
285 */
286 public String editAnnotation(PersistentItem item) {
287 // Find all existing folders.
288 Object[] aa = fAnnotationManager.getElements(null);
289 List folders = new ArrayList();
290 for (int i = 0; i < aa.length; ++i) {
291 if (aa[i] instanceof PersistentFolder) {
292 folders.add(((PersistentFolder) aa[i]).getName());
293 }
294 }
295 StringBuffer label = new StringBuffer();
296 label.append("Kind = " + item.getKindName() + "\n");
297 label.append("Name = " + item.getName() + "\n");
298 label.append("FullName = " + item.getFullName() + "\n");
299 label.append("FullPath = " + item.getFullPath() + "\n");
300 label.append("Project = " + item.getProject() + "\n");
301 label.append("Create Time = " + item.getCTime().toString() + "\n");
302 label.append("Last Access Time = " + item.getCTime().toString() + "\n");
303 label.append("Count = " + item.getCount());
304 //label.append("\n" + i18n("EditAnnotation.Label"));
305 EditAnnotationDialog dialog =
306 new EditAnnotationDialog(
307 getSite().getShell(),
308 JdtPlugin.getString("AnnotationView.editAnnotation.title"),
309 label.toString(),
310 item.getParent(),
311 folders,
312 item.getAnnotation());
313 if (dialog.open() == Window.OK) {
314 setInbox(dialog.getFolder());
315 item.setAnnotation(dialog.getText());
316 return dialog.getFolder();
317 }
318 return null;
319 }
320
321 /**
322 * Passing the focus request to the viewer's control.
323 */
324 public void setFocus() {
325 fViewer.getControl().setFocus();
326 }
327
328 public void setSortKey(String key) {
329 //NOTE: Setting key to be same as old one, effectly refresh the sorting.
330 if (AnnotationSorter.SORTKEYMAP.get(key) != null)
331 fSortKey = key;
332 fViewer.setSorter(new AnnotationSorter(fSortKey));
333 }
334
335 public String getSortKey() {
336 return fSortKey;
337 }
338
339 public String[] getSortKeys() {
340 return AnnotationSorter.SORTKEYS;
341 }
342
343 // AnnotationModelListener ///////////////////////////////////////////
344
345 public void refresh() {
346 fViewer.refresh();
347 }
348 public void refresh(PersistentItem item) {
349 fViewer.refresh(item);
350 }
351
352 public void setSelection(ISelection selection, boolean reveal) {
353 if (selection != null && selection.equals(fViewer.getSelection()))
354 return;
355 fViewer.setSelection(selection, reveal);
356 }
357
358 // ISelectionChangedListener //////////////////////////////////////////
359
360 /**
361 * Update status message on viewer selection changes. This can also be used to execute action on single click
362 * selection.
363 *
364 * @see ISelectionListener#selectionChanged(IWorkbenchPart, ISelection)
365 */
366 public void handleSelectionChanged(SelectionChangedEvent e) {
367 ISelection selection = e.getSelection();
368 if (selection == null || selection.isEmpty())
369 return;
370 if (!(selection instanceof IStructuredSelection))
371 return;
372 PersistentItem item = (PersistentItem) ((IStructuredSelection) selection).getFirstElement();
373 IStatusLineManager manager = getViewSite().getActionBars().getStatusLineManager();
374 String str = item.getFullName() + " - " + item.getFullPath();
375 manager.setMessage(str);
376 }
377
378 // KeyListener ///////////////////////////////////////////////////////
379
380 public void keyPressed(KeyEvent event) {
381 if (DEBUG)
382 System.out.println(
383 NAME
384 + ".keyPressed(): mask="
385 + event.stateMask
386 + ", code="
387 + event.keyCode
388 + ", character="
389 + event.character);
390 if (event.stateMask == FIND_KEYMASK && event.character == FIND_FORWARD_KEYCHAR) {
391 beginSession(true);
392 } else if (event.stateMask == FIND_KEYMASK && event.character == FIND_BACKWARD_KEYCHAR) {
393 beginSession(false);
394 }
395 }
396 public void keyReleased(KeyEvent event) {
397 if (DEBUG)
398 System.out.println(
399 NAME
400 + ".keyReleased(): mask="
401 + event.stateMask
402 + ", code="
403 + event.keyCode
404 + ", character="
405 + event.character);
406 if (event.stateMask == ACTION_KEYMASK && event.character == DELETE_ACTION_KEYCHAR) {
407 deleteAction();
408 }
409 }
410
411 public void beginSession(boolean forward) {
412 fFindTarget =
413 new IncrementalFindTreeTarget(
414 fViewer,
415 getViewSite().getActionBars().getStatusLineManager(),
416 this);
417 fFindTarget.beginSession(forward, null);
418 }
419
420 ////////////////////////////////////////////////////////////////////////
421
422 private void makeActions() {
423 fActionHeader = new Action() {
424 public void run() {
425 }
426 };
427 fActionHeader.setText("AnnotationView Menu:");
428 fActionHeader.setEnabled(false);
429 //
430 fActionEdit = new Action() {
431 public void run() {
432 editAction();
433 }
434 };
435 fActionEdit.setText("Edit Annotation");
436 fActionEdit.setToolTipText("Edit Annotation");
437 fActionEdit.setImageDescriptor(
438 PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
439 ISharedImages.IMG_OBJS_TASK_TSK));
440 //
441 fActionClipboard = new Action() {
442 public void run() {
443 clipboardAction();
444 }
445 };
446 fActionClipboard.setText("Clipboard");
447 fActionClipboard.setToolTipText("Copy name to clipboard");
448 fActionClipboard.setImageDescriptor(
449 PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_OBJ_FILE));
450 //
451 fActionAdd = new Action() {
452 public void run() {
453 addAction();
454 }
455 };
456 fActionAdd.setText("Add");
457 fActionAdd.setToolTipText("Add from editor");
458 //
459 fActionCopy = new Action() {
460 public void run() {
461 copyAction();
462 }
463 };
464 fActionCopy.setText("Copy");
465 fActionCopy.setToolTipText("Copy items");
466 //
467 fActionMove = new Action() {
468 public void run() {
469 moveAction();
470 }
471 };
472 fActionMove.setText("Move");
473 fActionMove.setToolTipText("Move items to another folder");
474 //
475 fActionDelete = new Action() {
476 public void run() {
477 deleteAction();
478 }
479 };
480 fActionDelete.setText("Delete");
481 fActionDelete.setToolTipText("Delete");
482 UtilPluginImages.setToolImageDescriptors(fActionDelete, UtilPluginImages.IMG_DELETE);
483 //
484 fActionResolve = new Action() {
485 public void run() {
486 resolveAction();
487 }
488 };
489 fActionResolve.setText("Resolve");
490 fActionResolve.setToolTipText("Scan for non-exist object");
491 UtilPluginImages.setLocalImageDescriptors(fActionResolve, UtilPluginImages.IMG_REFRESH);
492 //
493 fActionSetInbox = new Action() {
494 public void run() {
495 setInboxAction();
496 }
497 };
498 fActionSetInbox.setText("Set As Inbox");
499 fActionSetInbox.setToolTipText("Set folder as inbox");
500 //FIXME: Choose a better icon.
501 fActionSetInbox.setImageDescriptor(
502 PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
503 ISharedImages.IMG_OBJS_TASK_TSK));
504 //
505 fActionAbout = new Action() {
506 public void run() {
507 showMessage(NAME + " " + VERSION);
508 }
509 };
510 fActionAbout.setText("About");
511 fActionAbout.setToolTipText("About AnnotationView");
512 fActionAbout.setImageDescriptor(
513 PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
514 ISharedImages.IMG_OBJS_INFO_TSK));
515 //
516 fActionSort = new SortAction(this);
517 }
518 private void contributeToActionBars() {
519 IActionBars bars = getViewSite().getActionBars();
520 fillLocalPullDown(bars.getMenuManager());
521 fillLocalToolBar(bars.getToolBarManager());
522 }
523 private void fillLocalPullDown(IMenuManager manager) {
524 manager.add(new Separator());
525 manager.add(fActionAbout);
526 }
527 private void fillLocalToolBar(IToolBarManager manager) {
528 manager.add(fActionResolve);
529 manager.add(new Separator());
530 manager.add(fActionSort);
531 manager.add(new Separator());
532 }
533 private void hookContextMenu() {
534 MenuManager manager = new MenuManager("#PopupMenu");
535 manager.setRemoveAllWhenShown(true);
536 manager.addMenuListener(new IMenuListener() {
537 public void menuAboutToShow(IMenuManager manager) {
538 AnnotationView.this.fillContextMenu(manager);
539 }
540 });
541 Menu menu = manager.createContextMenu(fViewer.getControl());
542 fViewer.getControl().setMenu(menu);
543 // Register menu so that other plugin can contribute to it.
544 getSite().registerContextMenu(manager, fViewer);
545 }
546
547 void fillContextMenu(IMenuManager manager) {
548 manager.add(fActionHeader);
549 manager.add(new Separator());
550 manager.add(fActionSetInbox);
551 manager.add(new Separator());
552 manager.add(fActionClipboard);
553 manager.add(fActionCopy);
554 manager.add(fActionMove);
555 manager.add(fActionDelete);
556 manager.add(new Separator());
557 manager.add(fActionAdd);
558 manager.add(fActionEdit);
559 // Visited item list.
560 //JdtPlugin.getDefault().addVisitedHistoryAction(manager);
561 // Other plug-ins can contribute there actions here
562 manager.add(new Separator("Additions"));
563 }
564 private void hookDoubleClickAction() {
565 fViewer.addDoubleClickListener(new IDoubleClickListener() {
566 public void doubleClick(DoubleClickEvent event) {
567 showInEditorAction();
568 }
569 });
570 }
571
572 /** Temporary hack to do the incremental search. Should move to StructuredViewer later.
573 */
574 private void hookKeyListener() {
575 fViewer.getControl().addKeyListener(this);
576 }
577
578 void showMessage(String message) {
579 MessageDialog.openInformation(fViewer.getControl().getShell(), NAME, message);
580 }
581
582 // Actions /////////////////////////////////////////////////////////////
583 //
584 void clipboardAction() {
585 IStructuredSelection selection = getSelection();
586 if (selection == null || selection.isEmpty())
587 return;
588 PersistentItem item = (PersistentItem) selection.getFirstElement();
589 if (item == null)
590 return;
591 String text = item.toString();
592 if (DEBUG)
593 System.out.println(NAME + ".clipboardAction(): text=" + text);
594 try {
595 JdtPlugin.getClipboard().setContents(
596 new Object[] { text },
597 new Transfer[] { TextTransfer.getInstance()});
598 } catch (SWTError e) {
599 if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD)
600 throw e;
601 }
602 }
603
604 void addAction() {
605 IStructuredSelection selection = getSelection();
606 String folder = null;
607 if (selection != null && !selection.isEmpty()) {
608 Object a = selection.getFirstElement();
609 if (a instanceof PersistentFolder)
610 folder = ((PersistentFolder) a).getName();
611 else if (a instanceof PersistentItem)
612 folder = ((PersistentItem) a).getParent();
613 }
614 if (folder == null)
615 folder = promptForFolder();
616 if (folder == null)
617 return;
618 IEditorPart editor = getSite().getPage().getActiveEditor();
619 addFromEditor(editor, folder);
620 }
621
622 private void addFromEditor(IEditorPart editor, String folder) {
623 IJavaElement element = JavaUtil.getSelectedElementFromEditor(editor);
624 if (element != null) {
625 IType type = Util.findJavaType(element);
626 if (type != null) {
627 PersistentItem item = fAnnotationManager.add(PersistentItem.create(type), folder);
628 setSelection(new StructuredSelection(item), true);
629 return;
630 }
631 }
632 IEditorInput input = editor.getEditorInput();
633 if (input instanceof FileEditorInput) {
634 IFile file = ((FileEditorInput) input).getFile();
635 PersistentItem item = fAnnotationManager.add(PersistentItem.create(file), folder);
636 setSelection(new StructuredSelection(item), true);
637 }
638 }
639
640 void copyAction() {
641 IStructuredSelection selection = getSelection();
642 if (selection == null || selection.isEmpty())
643 return;
644 String newfolder = promptForFolder();
645 if (newfolder != null) {
646 fAnnotationManager.copyItems(selection.toArray(), newfolder);
647 }
648 }
649
650 void moveAction() {
651 IStructuredSelection selection = getSelection();
652 if (selection == null || selection.isEmpty())
653 return;
654 String newfolder = promptForFolder();
655 if (newfolder != null) {
656 fAnnotationManager.moveItems(selection.toArray(), newfolder);
657 }
658 }
659
660 private String promptForFolder() {
661 // Find all existing folders.
662 Object[] aa = fAnnotationManager.getElements(null);
663 List folders = new ArrayList();
664 for (int i = 0; i < aa.length; ++i) {
665 if (aa[i] instanceof PersistentFolder) {
666 folders.add(((PersistentFolder) aa[i]).getName());
667 }
668 }
669 PromptForFolderDialog dialog =
670 new PromptForFolderDialog(
671 getSite().getShell(),
672 JdtPlugin.getString(NAME, "promptForFolder", "PleaseSpecifyFolder"),
673 fDefaultFolderName,
674 folders);
675 if (dialog.open() == Window.OK)
676 return dialog.getFolder();
677 return null;
678 }
679
680 void deleteAction() {
681 IStructuredSelection selection = getSelection();
682 if (selection == null || selection.isEmpty())
683 return;
684 Object[] aa = selection.toArray();
685 if (aa.length != 0) {
686 StringBuffer buf = new StringBuffer("Do you really want to delete the following?\n\n");
687 for (int i = 0; i < aa.length; ++i) {
688 buf.append("# " + ((PersistentItem) aa[i]).getFullName());
689 buf.append("\n");
690 }
691 MessageBox box =
692 new MessageBox(
693 getSite().getShell(),
694 SWT.ICON_QUESTION | SWT.YES | SWT.NO | SWT.SYSTEM_MODAL);
695 box.setText("Confirm delete");
696 box.setMessage(buf.toString());
697 int result = box.open();
698 if (result != SWT.YES)
699 return;
700 fAnnotationManager.removeAll(aa);
701 }
702 }
703
704 void editAction() {
705 IStructuredSelection selection = getSelection();
706 if (selection == null || selection.isEmpty())
707 return;
708 Object a = selection.getFirstElement();
709 if (!(a instanceof PersistentItem))
710 return;
711 PersistentItem item = (PersistentItem) a;
712 String folder = editAnnotation(item);
713 if (folder == null)
714 return;
715 if (folder.equals(item.getParent())) {
716 refresh(item);
717 } else {
718 fAnnotationManager.moveItem(item, folder);
719 }
720 }
721
722 void resolveAction() {
723 List ret = new ArrayList();
724 resolveAction(fAnnotationManager.getRoot(), ret);
725 fViewer.setSelection(new StructuredSelection(ret));
726 fViewer.refresh();
727 }
728
729 void setInboxAction() {
730 IStructuredSelection selection = getSelection();
731 if (selection == null || selection.isEmpty())
732 return;
733 Object a = selection.getFirstElement();
734 if (!(a instanceof PersistentFolder))
735 return;
736 setInbox(((PersistentFolder) a).getName());
737 }
738
739 private void setInbox(String name) {
740 PersistentFolder folder;
741 if (name == null)
742 name = AnnotationManager.INBOX;
743 if (fDefaultFolderName != null && fDefaultFolderName.equals(name))
744 return;
745 if (fDefaultFolderName != null) {
746 folder = fAnnotationManager.findFolder(fDefaultFolderName);
747 folder.setActive(false);
748 }
749 fDefaultFolderName = name;
750 folder = fAnnotationManager.findFolder(fDefaultFolderName);
751 folder.setActive(true);
752 refresh();
753 }
754
755 /**
756 * @return List of unresolvable elements in 'ret'.
757 */
758 private void resolveAction(Object a, List ret) {
759 if (a instanceof PersistentFolder) {
760 Object[] aa = ((PersistentFolder) a).getChildren();
761 for (int i = 0; i < aa.length; ++i)
762 resolveAction(aa[i], ret);
763 } else {
764 if (a instanceof PersistentItem) {
765 if (((PersistentItem) a).resolve() != null)
766 return;
767 }
768 ret.add(a);
769 }
770 }
771
772 void showInEditorAction() {
773 IStructuredSelection selection = getSelection();
774 if (selection == null || selection.isEmpty())
775 return;
776 Object a = selection.getFirstElement();
777 if (!(a instanceof PersistentItem))
778 return;
779 Util.editItem((PersistentItem) a);
780 }
781
782 ////////////////////////////////////////////////////////////////////////
783
784 private IStructuredSelection getSelection() {
785 return (IStructuredSelection) fViewer.getSelection();
786 }
787
788 private String getSelectedItemText() {
789 IStructuredSelection selection = (IStructuredSelection) fViewer.getSelection();
790 if (selection == null || selection.isEmpty())
791 return null;
792 Object a = selection.getFirstElement();
793 if (Assert.isTrue(a instanceof PersistentItem, "selection not a annotation item"));
794 else
795 return null;
796 PersistentItem item = (PersistentItem) a;
797 return fAnnotationManager.getText(item);
798 }
799
800 ////////////////////////////////////////////////////////////////////////
801
802 }