/******************************************************************************* * Copyright 2005-2007, CHISEL Group, University of Victoria, Victoria, BC, Canada * and IBM Corporation. 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: * The Chisel Group, University of Victoria *******************************************************************************/ package net.sourceforge.tagsea.core.ui; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Timer; import java.util.TimerTask; import net.sourceforge.tagsea.TagSEAPlugin; import net.sourceforge.tagsea.core.ITag; import net.sourceforge.tagsea.core.ITagChangeListener; import net.sourceforge.tagsea.core.IWaypoint; import net.sourceforge.tagsea.core.IWaypointChangeListener; import net.sourceforge.tagsea.core.TagDelta; import net.sourceforge.tagsea.core.WaypointDelta; import net.sourceforge.tagsea.core.internal.TagSEADelegatingStyledCellLabelProvider; import net.sourceforge.tagsea.core.ui.internal.TagSEAUI; import net.sourceforge.tagsea.core.ui.internal.TagSEAUIEvent; import net.sourceforge.tagsea.core.ui.internal.clouds.CloudTreeViewer; import net.sourceforge.tagsea.core.ui.internal.controls.HorizontalHandleToggle; import net.sourceforge.tagsea.core.ui.internal.tags.TagTreeItem; import net.sourceforge.tagsea.core.ui.internal.tags.TagTreeItemTransfer; import net.sourceforge.tagsea.core.ui.internal.tags.TagWaypointViewerFilter; import net.sourceforge.tagsea.core.ui.internal.tags.TagsDragListener; import net.sourceforge.tagsea.core.ui.internal.tags.TagsTree; import net.sourceforge.tagsea.core.ui.internal.tags.TagsViewDropListener; import net.sourceforge.tagsea.core.ui.internal.views.CachingTreePatternFilter; import net.sourceforge.tagsea.core.ui.internal.views.FilteredTable; import net.sourceforge.tagsea.core.ui.internal.views.PatternFilteredTree; import net.sourceforge.tagsea.core.ui.internal.views.SimpleSubStringPatternFilter; import net.sourceforge.tagsea.core.ui.internal.waypoints.WaypointExtensionsFilter; import net.sourceforge.tagsea.core.ui.internal.waypoints.WaypointTableDoubleClickListener; import net.sourceforge.tagsea.core.ui.internal.waypoints.WaypointTableDragListener; import net.sourceforge.tagsea.core.ui.internal.waypoints.WaypointTableViewDropAdapter; import net.sourceforge.tagsea.core.ui.tags.TagNameTransfer; import net.sourceforge.tagsea.core.ui.tags.TagsViewSorter; import net.sourceforge.tagsea.core.ui.tags.WaypointPropertiesDialog; import net.sourceforge.tagsea.core.ui.waypoints.WaypointTableColumnLabelProvider; import net.sourceforge.tagsea.core.ui.waypoints.WaypointTableColumnSorter; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.DialogSettings; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; 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.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.IPartListener; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionContext; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.events.IHyperlinkListener; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.model.BaseWorkbenchContentProvider; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.progress.IWorkbenchSiteProgressService; /** * A combined view for Tags/Waypoints. * @author Del Myers * @author Chris Callendar * */ public class TagSEAView extends ViewPart { public static final String ID = "net.sourceforge.tagsea.tagseaview"; private static final String TAGSEA_VIEW_SETTINGS = "tagseaview"; private static final String WAYPOINTS_SETTINGS = "waypointsection"; private static final String WAYPOINT_SORT_COLUMN = "waypointsorter"; private static final String WAYPOINT_COLUMN_ORDER = "waypointorder"; private static final String WAYPOINT_COLUMN_SIZES = "waypointcolumnsizes"; private static final String TAGS_SETTINGS = "tagssection"; private static final String TAGS_FLAT = "tagsflat"; IPartListener aboutToCloseListener = new IPartListener() { public void partActivated(IWorkbenchPart part) {} public void partBroughtToTop(IWorkbenchPart part) {} public void partClosed(IWorkbenchPart part) { if (part == TagSEAView.this) saveState(); } public void partDeactivated(IWorkbenchPart part) {} public void partOpened(IWorkbenchPart part) {} }; /** * The page that contains the views. */ private SashForm page; private PatternFilteredTree tagTreeViewer; //private SashForm waypointTableSash; private Composite waypointTableSash; private TableViewer waypointTableViewer; private WaypointExtensionsFilter fWaypointFilter; private Timer refreshTimer; private TimerTask refreshTask; private TagSEAModelListener tagseaModelListener; private FormToolkit formToolKit; private FormText tagsFormText; // private Button tagEditButton; private TagActionGroup tagActions; private WaypointActionGroup waypointActions; private TagsTree tagsTree; private Group tagsGroup; private CloudTreeViewer cloudViewer; private TagTreeSelectionListener tagSelectionListener; private ISelectionListener localWorkbenchSelectionListener; private TagWaypointViewerFilter waypointTagFilter; private Composite fTagsArea; /** * Listener used in the tree viewer that opens an item for editing or opens the waypoint view. The * editor is opened when one of the following occurs: * 1) F2 is pressed & released * 2) "space" is pressed & released * 3) An item is selected for the second time. * * The waypoints view is opened when an item is double-clicked. * @author Del Myers * * @tag tagsea.todo : Add actions */ private final class ItemEditListener implements Listener { boolean doubleClicked = false; //timer to make sure that a double-click isn't pressed. private Timer doubleClickTimer = null; private Display display; private Item thisSelection; private Item lastSelection; public void handleEvent(Event event) { this.display = event.widget.getDisplay(); switch (event.type) { case SWT.Dispose: if (doubleClickTimer != null) { doubleClickTimer.cancel(); doubleClickTimer = null; } break; case SWT.KeyUp: if (event.detail == 0) { if (event.keyCode == SWT.F2 || event.character == ' ') { tagActions.runEditAction(); } } break; case SWT.Selection: lastSelection = thisSelection; thisSelection = (Item) event.item; if (this.doubleClickTimer != null) { this.doubleClickTimer.cancel(); this.doubleClickTimer = null; } if (doubleClicked) { doubleClicked = false; } else { if (event.widget instanceof Tree) { if (thisSelection == lastSelection && lastSelection != null) { doubleClickTimer = new Timer(); doubleClickTimer.schedule(new TimerTask(){ @Override public void run() { display.asyncExec(new Runnable(){ public void run() { if (!doubleClicked) { tagActions.runEditAction(); } } }); } }, display.getDoubleClickTime()+25); } } } break; case SWT.MouseDoubleClick: doubleClicked = true; if (this.doubleClickTimer != null) { this.doubleClickTimer.cancel(); this.doubleClickTimer = null; } //actionGroup.runDefaultAction(event); break; } } } class TagSEAModelListener implements IWaypointChangeListener, ITagChangeListener { public void waypointsChanged(WaypointDelta delta) { scheduleRefresh(); } public void tagsChanged(TagDelta delta) { scheduleRefresh(); } } class WaypointTableSelectionListener implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { refreshWaypointTagsArea(); waypointActions.setContext(new ActionContext(event.getSelection())); } } class TagTreeSelectionListener implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { tagActions.setContext(new ActionContext(event.getSelection())); waypointTableViewer.refresh(); } } private class WaypointTableContentProvider implements IStructuredContentProvider { public Object[] getElements(Object inputElement) { ITag[] selectedTags = getSelectedTags(); if (selectedTags.length == 0) { return TagSEAPlugin.getWaypointsModel().getAllWaypoints(); } else { HashSet<IWaypoint> waypointSet = new HashSet<IWaypoint>(); for (ITag tag : selectedTags) { waypointSet.addAll(Arrays.asList(tag.getWaypoints())); } return waypointSet.toArray(); } } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } public TagSEAView() { refreshTimer = new Timer(); } /** * Sets a timer to do a refresh. */ public void scheduleRefresh() { if (this.refreshTask != null) { this.refreshTask.cancel(); } this.refreshTask = new TimerTask() { @Override public void run() { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable(){ public void run() { //refreshing and disposal checking can't be done outside of the display thread. if (page.isDisposed()) { return; } waypointTableViewer.refresh(); tagTreeViewer.refresh(); ISelection cloudSelection = cloudViewer.getSelection(); cloudViewer.refresh(); cloudViewer.getViewer().setSelection(cloudSelection); } }); } }; refreshTimer.schedule(refreshTask, 500); } @Override public void createPartControl(Composite parent) { this.waypointTagFilter =new TagWaypointViewerFilter(); page = new SashForm(parent, SWT.HORIZONTAL); page.addControlListener(new ControlAdapter(){ @Override public void controlResized(ControlEvent e) { Point size = page.getSize(); //avoid divide by zero. if (size.y == 0) { return; } //it doesn't matter if we use a float or integers. Integer division will result in 0 //if size.y > size.x, and we still get the right result. if (((size.x/size.y) < 1)) { if (page.getOrientation() != SWT.VERTICAL) { page.setOrientation(SWT.VERTICAL); } } else if (page.getOrientation() != SWT.HORIZONTAL) { page.setOrientation(SWT.HORIZONTAL); } super.controlResized(e); } }); createTagsArea(page); createWaypointsArea(page); page.setWeights(new int[] {1, 4}); this.tagseaModelListener = new TagSEAModelListener(); TagSEAPlugin.addWaypointChangeListener(tagseaModelListener); IWorkbenchSiteProgressService service = (IWorkbenchSiteProgressService) getSite().getAdapter(IWorkbenchSiteProgressService.class); if (service != null) { service.showBusyForFamily(TagSEAPlugin.getDefault()); } getSite().getPage().addPartListener(aboutToCloseListener); restoreState(); makeActions(); fillActionBars(); this.localWorkbenchSelectionListener = new ISelectionListener() { public void selectionChanged(IWorkbenchPart part, ISelection selection) { if (waypointTagFilter.isImportantSelection(selection)) { scheduleRefresh(); } } }; getViewSite().getWorkbenchWindow().getSelectionService().addSelectionListener(localWorkbenchSelectionListener); } /** * */ private void fillActionBars() { waypointActions.fillActionBars(getViewSite().getActionBars()); tagActions.fillActionBars(getViewSite().getActionBars()); getViewSite().getActionBars().getToolBarManager().add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } /** * */ private void makeActions() { tagActions = new TagActionGroup(this); waypointActions = new WaypointActionGroup(this); } /** * @param page */ private void createWaypointsArea(SashForm form) { Group parent = new Group(form, SWT.FLAT); parent.setLayout(new FillLayout()); fWaypointFilter = new WaypointExtensionsFilter(); //waypointTableSash = new SashForm(parent,SWT.VERTICAL); waypointTableSash = new Composite(parent,SWT.VERTICAL); if(waypointTableSash.getVerticalBar()!=null) { waypointTableSash.getVerticalBar().setEnabled(false); waypointTableSash.getVerticalBar().setVisible(false); } waypointTableSash.setLayoutData(new GridData(GridData.FILL_BOTH)); //composite.setBackground(JFaceColors.getBannerBackground(Display.getDefault())); GridLayout layout = new GridLayout(); layout.marginWidth = 3; layout.marginHeight = 3; layout.verticalSpacing = 0; layout.marginTop = 0; layout.marginBottom = 0; layout.marginLeft = 0; layout.marginRight = 0; layout.horizontalSpacing = 0; waypointTableSash.setLayout(layout); SimpleSubStringPatternFilter patternFilter = new SimpleSubStringPatternFilter(); FilteredTable waypointFilteredTable = new FilteredTable(waypointTableSash, SWT.FULL_SELECTION | SWT.MULTI | SWT.BORDER | SWT.FLAT, patternFilter); waypointTableViewer = waypointFilteredTable.getViewer(); TableViewer tableViewer = waypointTableViewer; //fFilteredTable.setBackground(JFaceColors.getBannerBackground(Display.getDefault())); tableViewer.addFilter(fWaypointFilter); tableViewer.setContentProvider(new WaypointTableContentProvider()); tableViewer.setComparator(new WaypointTableColumnSorter()); tableViewer.addDragSupport(DND.DROP_MOVE|DND.DROP_COPY, new Transfer[]{WaypointTransfer.getInstance()/*, PluginTransfer.getInstance()*/}, new WaypointTableDragListener(tableViewer)); tableViewer.addDropSupport(DND.DROP_COPY, new Transfer[] {TagNameTransfer.getInstance()}, new WaypointTableViewDropAdapter(tableViewer)); tableViewer.addDoubleClickListener(new WaypointTableDoubleClickListener()); tableViewer.addSelectionChangedListener(new WaypointTableSelectionListener()); Table table = tableViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(true); table.setSortDirection(SWT.DOWN); for (int i = 0; i < WaypointTableColumnLabelProvider.COLUMN_LABELS.length; i++) { TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.FLAT); viewerColumn.setLabelProvider(new TagSEADelegatingStyledCellLabelProvider(new WaypointTableColumnLabelProvider(patternFilter, i))); TableColumn column = viewerColumn.getColumn(); final int columnIndex = i; column.setMoveable(true); column.setText(WaypointTableColumnLabelProvider.COLUMN_LABELS[i]); column.setData(WaypointTableColumnLabelProvider.COLUMNS[i]); column.addSelectionListener(new SelectionAdapter(){ @Override public void widgetSelected(SelectionEvent e) { TableColumn column = (TableColumn) e.widget; waypointTableViewer.getTable().setSortColumn(column); ((WaypointTableColumnSorter)waypointTableViewer.getComparator()).setColumn(columnIndex); waypointTableViewer.refresh(); } }); } TableLayout tableLayout = new TableLayout(); tableLayout.addColumnData(new ColumnWeightData(25)); tableLayout.addColumnData(new ColumnWeightData(25)); tableLayout.addColumnData(new ColumnWeightData(25)); tableLayout.addColumnData(new ColumnWeightData(25)); table.setLayout(tableLayout); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); tableViewer.setInput(new Object()); createWaypointTagsArea(waypointTableSash); MenuManager contextMenu = new MenuManager(); contextMenu.setRemoveAllWhenShown(true); Menu menu = contextMenu.createContextMenu(table); contextMenu.addMenuListener(new IMenuListener(){ public void menuAboutToShow(IMenuManager manager) { waypointContextMenuAboutToShow(manager); } }); table.setMenu(menu); table.addFocusListener(new FocusListener(){ public void focusGained(FocusEvent e) { getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(), waypointActions.getDeleteAction()); getViewSite().getActionBars().updateActionBars(); } public void focusLost(FocusEvent e) { } }); getViewSite().registerContextMenu(contextMenu, tableViewer); //waypointTableSash.setWeights(new int[] {10, 1}); } /** * @param manager */ protected void waypointContextMenuAboutToShow(IMenuManager manager) { waypointActions.fillContextMenu(manager); manager.add(new Action("Properties..."){ @Override public void run() { IWaypoint waypoint = getSelectedWaypoint(); if (waypoint != null) { new WaypointPropertiesDialog(getSite().getShell(), waypoint).open(); } } }); // Other plug-ins can contribute there actions here manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } private void createToggle(Composite parent) { HorizontalHandleToggle fToggle = new HorizontalHandleToggle(parent,SWT.NONE); GridData data = new GridData(GridData.FILL_HORIZONTAL); data.horizontalSpan = 2; data.heightHint = 10; data.minimumHeight = 10; fToggle.setLayoutData(data); fToggle.setTooltips("Show tags", "Hide tags"); fToggle.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { if(e.detail == SWT.CLOSE) { fTagsArea.setVisible(false); GridData data = (GridData)fTagsArea.getLayoutData(); data.exclude = true; fTagsArea.setLayoutData(data); waypointTableSash.layout(true,true); } else if(e.detail == SWT.OPEN) { fTagsArea.setVisible(true); GridData data = (GridData)fTagsArea.getLayoutData(); data.exclude = false; fTagsArea.setLayoutData(data); waypointTableSash.layout(true,true); } } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); } /** * @param waypointTableComposite2 */ private void createWaypointTagsArea(Composite parent) { // Create the toggle createToggle(parent); // Add a seperator line, it looks odd without this Label seperator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_SOLID); GridData data = new GridData(GridData.FILL_HORIZONTAL); data.horizontalSpan = 2; seperator.setLayoutData(data); // Set up the tags view formToolKit = new FormToolkit(parent.getDisplay()); fTagsArea = new Composite(parent, SWT.FLAT); data = new GridData(GridData.FILL_HORIZONTAL); data.heightHint = 24; fTagsArea.setLayoutData(data); fTagsArea.setLayout(new GridLayout(2, false)); //fTagsArea.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE)); tagsFormText = formToolKit.createFormText(fTagsArea, true); data = new GridData(GridData.FILL_BOTH); tagsFormText.setLayoutData(data); tagsFormText.setBackground(parent.getBackground()); tagsFormText.addHyperlinkListener(new IHyperlinkListener(){ public void linkActivated(HyperlinkEvent e) { String tagName = (String) e.getHref(); ITag tag = TagSEAPlugin.getTagsModel().getTag(tagName); if (tag != null) { setSelectedTags(new ITag[] {tag}); } } public void linkEntered(HyperlinkEvent e) {} public void linkExited(HyperlinkEvent e) {} }); // tagEditButton = new Button(tagsArea, SWT.FLAT | SWT.PUSH); // tagEditButton.setText("Edit..."); // tagEditButton.addSelectionListener(new SelectionListener(){ // // public void widgetDefaultSelected(SelectionEvent e) { // widgetSelected(e); // } // public void widgetSelected(SelectionEvent e) { // TagEditDialog dialog = new TagEditDialog(getViewSite().getShell()); // if (getSelectedWaypoint() != null) { // dialog.setInitialTags(getSelectedWaypoint().getTags()); // final IWaypoint selectedWaypoint = getSelectedWaypoint(); // int result = dialog.open(); // if (result == Dialog.OK) { // final String[] tagNames = dialog.getTagNames(); // TagSEAPlugin.run(new TagSEAOperation("Checking Tag Names..."){ // @Override // public IStatus run(IProgressMonitor monitor) throws InvocationTargetException { // TreeSet<String> oldTagNames = new TreeSet<String>(); // TreeSet<String> newTagNames = new TreeSet<String>(Arrays.asList(tagNames)); // for (ITag tag : selectedWaypoint.getTags()) { // oldTagNames.add(tag.getName()); // } // MultiStatus status = new MultiStatus(TagSEAPlugin.PLUGIN_ID, IStatus.OK, "", null); // for (String oldName : oldTagNames) { // if (!newTagNames.contains(oldName)) { // ITag tag = TagSEAPlugin.getTagsModel().getTag(oldName); // if (tag != null) { // status.merge(selectedWaypoint.removeTag(tag).getStatus()); // } // } // } // for (String newName : newTagNames) { // if (!oldTagNames.contains(newName)) { // ITag tag = selectedWaypoint.addTag(newName); // if (tag == null) { // status.merge(new Status( // IStatus.WARNING, // TagSEAPlugin.PLUGIN_ID, // IStatus.WARNING, // "Could not add tag " + newName, // null // )); // } // } // } // return status; // }}, false); // } // } // } // }); // tagEditButton.setLayoutData(new GridData(SWT.END, SWT.FILL, false, false)); } /** * @param tags */ public void setSelectedTags(ITag[] tags) { BaseWorkbenchContentProvider contentProvider = (BaseWorkbenchContentProvider) this.tagTreeViewer.getViewer().getContentProvider(); Object[] elements = contentProvider.getElements(this.tagTreeViewer.getViewer().getInput()); LinkedList<Object> elementList = new LinkedList<Object>(); elementList.addAll(Arrays.asList(elements)); HashSet<ITag> tagsLeft = new HashSet<ITag>(); tagsLeft.addAll(Arrays.asList(tags)); List<Object> selectionList = new LinkedList<Object>(); while (elementList.size() > 0 && tagsLeft.size() > 0) { Object element = elementList.removeFirst(); if (element instanceof TagTreeItem) { TagTreeItem tti = (TagTreeItem) element; ITag foundTag = null; for (ITag tag : tagsLeft) { if (tag.equals(tti.getTag())) { foundTag = tag; break; } } if (foundTag != null) { tagsLeft.remove(foundTag); selectionList.add(element); } elementList.addAll(Arrays.asList(tti.getChildren())); } } StructuredSelection selection = new StructuredSelection(selectionList); tagTreeViewer.getViewer().setSelection(selection, true); cloudViewer.getViewer().setSelection(selection, true); } /** * @param page2 */ private void createTagsArea(SashForm parent) { this.tagSelectionListener = new TagTreeSelectionListener(); this.tagsTree = new TagsTree(false); tagsGroup = new Group(parent, SWT.FLAT); tagsGroup.setText("Tags"); tagsGroup.setLayout(new StackLayout()); createTagsTree(tagsGroup); createTagsCloud(tagsGroup); ((StackLayout)tagsGroup.getLayout()).topControl = tagTreeViewer; tagsGroup.layout(); tagTreeViewer.getViewer().addSelectionChangedListener(tagSelectionListener); } /** * @param tagsGroup2 */ private void createTagsCloud(Composite tagsGroup) { this.cloudViewer = new CloudTreeViewer(tagsGroup, SWT.FLAT); cloudViewer.getViewer().addFilter(waypointTagFilter); cloudViewer.setInput(tagsTree); cloudViewer.getViewer().getControl().addFocusListener(new FocusListener(){ public void focusGained(FocusEvent e) { getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(), tagActions.getDeleteAction()); getViewSite().getActionBars().updateActionBars(); } public void focusLost(FocusEvent e) {} }); } private void createTagsTree(Composite tagsGroup) { CachingTreePatternFilter patternFilter = new CachingTreePatternFilter(); this.tagTreeViewer = new PatternFilteredTree(tagsGroup, SWT.FLAT | SWT.BORDER | SWT.MULTI, patternFilter); this.tagTreeViewer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this.tagTreeViewer.getViewer().setContentProvider(new BaseWorkbenchContentProvider()); this.tagTreeViewer.getViewer().setSorter(new TagsViewSorter()); tagTreeViewer.getViewer().addFilter(waypointTagFilter); tagTreeViewer.getViewer().setInput(tagsTree); tagTreeViewer.getFilterControl().addModifyListener(new ModifyListener(){ public void modifyText(ModifyEvent e) { if (e.widget instanceof Text) { ((TagSEAUI)TagSEAPlugin.getDefault().getUI()).getUIEventModel().fireEvent(TagSEAUIEvent.createViewEvent(TagSEAUIEvent.VIEW_FILTERED, ID, ((Text)e.widget).getText())); } } }); //set up columns Tree tree = tagTreeViewer.getViewer().getTree(); TreeViewerColumn nameViewerColumn = new TreeViewerColumn(tagTreeViewer.getViewer(), SWT.FLAT | SWT.LEFT); nameViewerColumn.setLabelProvider(new TagSEADelegatingStyledCellLabelProvider(new TagsViewLabelProvider(patternFilter, 0))); TreeViewerColumn sizeViewerColumn = new TreeViewerColumn(tagTreeViewer.getViewer(), SWT.FLAT | SWT.LEFT); sizeViewerColumn.setLabelProvider(new TagSEADelegatingStyledCellLabelProvider(new TagsViewLabelProvider(patternFilter, 1))); final TreeColumn nameColumn = nameViewerColumn.getColumn(); final TreeColumn sizeColumn = sizeViewerColumn.getColumn(); tree.addControlListener(new ControlListener(){ public void controlMoved(ControlEvent e) { //auto resize the columns Tree tree = (Tree) e.widget; int width = tree.getClientArea().width; sizeColumn.setWidth(30); nameColumn.setWidth(width-30); } public void controlResized(ControlEvent e) { controlMoved(e); } }); Listener openListener = new ItemEditListener(); tree.addListener(SWT.KeyUp, openListener); tree.addListener(SWT.MouseDoubleClick, openListener); tree.addListener(SWT.Selection, openListener); tree.addListener(SWT.Dispose, openListener); tagTreeViewer.getViewer().setColumnProperties(new String[] {"name", "waypointCount"}); tagTreeViewer.getViewer().addDragSupport(DND.DROP_MOVE | DND.DROP_COPY, new Transfer[] {TagTreeItemTransfer.getInstance(), TagNameTransfer.getInstance()}, new TagsDragListener(tagTreeViewer.getViewer())); tagTreeViewer.getViewer().addDropSupport(DND.DROP_MOVE, new Transfer[] {TagTreeItemTransfer.getInstance()}, new TagsViewDropListener()); tagTreeViewer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); MenuManager contextMenu = new MenuManager("Tags"); contextMenu.setRemoveAllWhenShown(true); contextMenu.addMenuListener(new IMenuListener(){ public void menuAboutToShow(IMenuManager manager) { tagsTreeContextMenuAboutToShow(manager); } }); Menu menu = contextMenu.createContextMenu(tagTreeViewer.getViewer().getTree()); tagTreeViewer.getViewer().getTree().setMenu(menu); tree.addFocusListener(new FocusListener(){ public void focusGained(FocusEvent e) { getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(), tagActions.getDeleteAction()); getViewSite().getActionBars().updateActionBars(); } public void focusLost(FocusEvent e) {} }); getViewSite().registerContextMenu(contextMenu, getTagsTreeViewer()); } /** * */ protected void tagsTreeContextMenuAboutToShow(IMenuManager manager) { tagActions.fillContextMenu(manager); } private void refreshWaypointTagsArea() { IWaypoint selected = getSelectedWaypoint(); //ITagSEAUI ui = TagSEAPlugin.getDefault().getUI(); // tagEditButton.setEnabled(selected != null && ui.canUIMove(selected)); if (selected == null) { tagsFormText.setText("<form><p>Nothing Selected</p></form>", true, false); } else { //@tag tagsea.todo : update this to parse the tag names to look for less-than, etc. String text = "<form><p>Tags: "; for (ITag tag : selected.getTags()) { text += "<a href=\"" + tag.getName() +"\">" + tag.getName() + "</a> "; } text += "</p></form>"; tagsFormText.setText(text, true, false); } tagsFormText.redraw(); } @Override public void setFocus() { } @Override public void dispose() { getSite().getPage().removePartListener(aboutToCloseListener); getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(localWorkbenchSelectionListener); TagSEAPlugin.removeWaypointChangeListener(tagseaModelListener); refreshTimer.cancel(); formToolKit.dispose(); super.dispose(); } public IWaypoint getSelectedWaypoint() { ISelection selection = waypointTableViewer.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection ss = (IStructuredSelection) selection; if (ss.size() > 0) { Object selected = ss.getFirstElement(); if (selected instanceof IAdaptable) { IWaypoint wp = (IWaypoint)((IAdaptable)selected).getAdapter(IWaypoint.class); return wp; } } } return null; } public ITag[] getSelectedTags() { ISelection selection = new StructuredSelection(); if (isViewAsCloud()) { selection = cloudViewer.getSelection(); } else { selection = tagTreeViewer.getViewer().getSelection(); } if (selection instanceof IStructuredSelection) { IStructuredSelection ss = (IStructuredSelection) selection; List<?> selectionList = ss.toList(); HashSet<ITag> tags = new HashSet<ITag>(); for (Object o : selectionList) { if (o instanceof ITag) { tags.add((ITag)o); } else if (o instanceof TagTreeItem) { TagTreeItem tti = (TagTreeItem) o; if (tti.getTag() != null) { tags.add(tti.getTag()); } tags.addAll(tti.getChildTags()); } } return tags.toArray(new ITag[tags.size()]); } return new ITag[0]; } private void saveState() { DialogSettings settings = new DialogSettings(TAGSEA_VIEW_SETTINGS); IDialogSettings waypointsSection = settings.addNewSection(WAYPOINTS_SETTINGS); //waypointsSection.put(WAYPOINT_SORT_COLUMN, ((WaypointTableColumnSorter)waypointTableViewer.getComparator()).getColumn()); TableColumn sortColumn = waypointTableViewer.getTable().getSortColumn(); waypointsSection.put(WAYPOINT_SORT_COLUMN, 0); if (sortColumn != null) { for (int i = 0; i < waypointTableViewer.getTable().getColumnCount(); i++) { if (waypointTableViewer.getTable().getColumn(i) == sortColumn) { waypointsSection.put(WAYPOINT_SORT_COLUMN, i); break; } } } int[] columnOrder = waypointTableViewer.getTable().getColumnOrder(); String[] columnOrderSettings = new String[columnOrder.length]; for (int i = 0; i < columnOrderSettings.length; i++) { columnOrderSettings[i] = "" + columnOrder[i]; } waypointsSection.put(WAYPOINT_COLUMN_ORDER, columnOrderSettings); TableColumn[] columns = waypointTableViewer.getTable().getColumns(); String[] columnSizes = new String[columns.length]; for (int i = 0; i < columnSizes.length; i++) { columnSizes[i] = columns[i].getWidth()+""; } waypointsSection.put(WAYPOINT_COLUMN_SIZES, columnSizes); IDialogSettings tagsSection = settings.addNewSection(TAGS_SETTINGS); TagsTree tagsInput = (TagsTree) tagTreeViewer.getViewer().getInput(); tagsSection.put(TAGS_FLAT, tagsInput.isFlat()); TagSEAPlugin.getDefault().getDialogSettings().addSection(settings); } private void restoreState() { IDialogSettings settings = TagSEAPlugin.getDefault().getDialogSettings().getSection(TAGSEA_VIEW_SETTINGS); if (settings == null) { return; } IDialogSettings waypointsSection = settings.getSection(WAYPOINTS_SETTINGS); int column = waypointsSection.getInt(WAYPOINT_SORT_COLUMN); String[] columnOrderStrings = waypointsSection.getArray(WAYPOINT_COLUMN_ORDER); int[] columnOrder = new int[columnOrderStrings.length]; for (int i = 0; i < columnOrder.length; i++) { columnOrder[i] = Integer.parseInt(columnOrderStrings[i]); } String[] columnSizesStrings = waypointsSection.getArray(WAYPOINT_COLUMN_SIZES); int[] columnSizes = new int[columnSizesStrings.length]; for (int i = 0; i < columnSizesStrings.length; i++) { columnSizes[i] = Integer.parseInt(columnSizesStrings[i]); } try { TableColumn sortColumn = waypointTableViewer.getTable().getColumn(column); waypointTableViewer.getTable().setSortColumn(sortColumn); } catch (IllegalArgumentException e) {} waypointTableViewer.getTable().setColumnOrder(columnOrder); TableColumn[] columns = waypointTableViewer.getTable().getColumns(); for (int i = 0; i < columns.length; i++) { columns[i].setWidth(columnSizes[i]); } IDialogSettings tagsSection = settings.getSection(TAGS_SETTINGS); boolean flat = tagsSection.getBoolean(TAGS_FLAT); tagsTree.setFlat(flat); } TreeViewer getTagsTreeViewer() { return tagTreeViewer.getViewer(); } TableViewer getWaypointsTableViewer() { return waypointTableViewer; } public void setViewAsHierachy(boolean hierarchy) { if (hierarchy == this.tagsTree.isFlat()) { this.tagsTree.setFlat(!hierarchy); this.tagTreeViewer.getViewer().refresh(); this.cloudViewer.refresh(); } } /** * @return */ public boolean isViewAsHierarchy() { return !this.tagsTree.isFlat(); } /** * @param checked */ void setViewAsCloud(boolean asCloud) { StackLayout stackLayout = (StackLayout) tagsGroup.getLayout(); if (asCloud) { if (stackLayout.topControl != cloudViewer) { stackLayout.topControl = cloudViewer; IStructuredSelection selection = (IStructuredSelection) tagTreeViewer.getViewer().getSelection(); TagTreeItem newSelection = null; tagTreeViewer.getViewer().removeSelectionChangedListener(tagSelectionListener); cloudViewer.getViewer().addSelectionChangedListener(tagSelectionListener); tagSelectionListener.selectionChanged(new SelectionChangedEvent(cloudViewer.getViewer(), cloudViewer.getSelection())); if (selection.size() > 0) { newSelection = (TagTreeItem) selection.getFirstElement(); if (newSelection.getParent() != null) { cloudViewer.getViewer().setInput(newSelection.getParent()); } else { cloudViewer.getViewer().setInput(tagsTree); } cloudViewer.refresh(); cloudViewer.getViewer().setSelection(selection); } } } else { if (stackLayout.topControl != tagTreeViewer) { stackLayout.topControl = tagTreeViewer; TagTreeItem newSelection = (TagTreeItem) cloudViewer.getViewer().getInput(); tagTreeViewer.getViewer().addSelectionChangedListener(tagSelectionListener); cloudViewer.getViewer().removeSelectionChangedListener(tagSelectionListener); tagSelectionListener.selectionChanged(new SelectionChangedEvent(tagTreeViewer.getViewer(), tagTreeViewer.getViewer().getSelection())); if (newSelection != null) { tagTreeViewer.getViewer().reveal(newSelection); } } } tagsGroup.layout(); } /** * @return */ public boolean isViewAsCloud() { return ((StackLayout)tagsGroup.getLayout()).topControl == cloudViewer; } }