1 /*******************************************************************************
2  * Copyright (c) 2000, 2012 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.debug.ui.actions;
15 
16 
17 import java.util.ArrayList;
18 import java.util.Iterator;
19 import java.util.List;
20 
21 import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer;
22 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
23 import org.eclipse.jface.action.IAction;
24 import org.eclipse.jface.viewers.IStructuredSelection;
25 import org.eclipse.swt.events.SelectionAdapter;
26 import org.eclipse.swt.events.SelectionEvent;
27 import org.eclipse.swt.widgets.Button;
28 import org.eclipse.swt.widgets.Shell;
29 import org.eclipse.ui.actions.SelectionListenerAction;
30 
31 /**
32  * Action used with a runtime classpath viewer.
33  */
34 public abstract class RuntimeClasspathAction extends SelectionListenerAction {
35 
36 	public static final int DEFAULT= 0;
37 	public static final int ADD= 1;
38 	public static final int REMOVE= 2;
39 	public static final int MOVE= 3;
40 
41 	private IClasspathViewer fViewer;
42 	private Button fButton;
43 	private Shell fShell;
44 
RuntimeClasspathAction(String label, IClasspathViewer viewer)45 	public RuntimeClasspathAction(String label, IClasspathViewer viewer) {
46 		super(label);
47 		setViewer(viewer);
48 	}
49 
50 	/**
51 	 * Sets the viewer on which this action operates.
52 	 *
53 	 * @param viewer the viewer on which this action operates
54 	 */
setViewer(IClasspathViewer viewer)55 	public void setViewer(IClasspathViewer viewer) {
56 		if (fViewer != null) {
57 			fViewer.removeSelectionChangedListener(this);
58 		}
59 		fViewer = viewer;
60 		if (fViewer != null) {
61 			fViewer.addSelectionChangedListener(this);
62 			update();
63 		}
64 	}
65 
66 	/**
67 	 * Returns the viewer on which this action operates.
68 	 *
69 	 * @return the viewer on which this action operates
70 	 */
getViewer()71 	protected IClasspathViewer getViewer() {
72 		return fViewer;
73 	}
74 
75 	/**
76 	 * Returns the selected items in the list, in the order they are
77 	 * displayed.
78 	 *
79 	 * @return targets for an action
80 	 */
getOrderedSelection()81 	protected List<IRuntimeClasspathEntry> getOrderedSelection() {
82 		List<IRuntimeClasspathEntry> targets = new ArrayList<>();
83 		List<?> selection = ((IStructuredSelection)getViewer().getSelection()).toList();
84 		IRuntimeClasspathEntry[] entries = getViewer().getEntries();
85 		for (int i = 0; i < entries.length; i++) {
86 			IRuntimeClasspathEntry target = entries[i];
87 			if (selection.contains(target)) {
88 				targets.add(target);
89 			}
90 		}
91 		return targets;
92 	}
93 
94 	/**
95 	 * Returns a list (copy) of the entries in the viewer
96 	 * @return the complete listing of all of the entries in the viewer
97 	 */
getEntriesAsList()98 	protected List<IRuntimeClasspathEntry> getEntriesAsList() {
99 		IRuntimeClasspathEntry[] entries = getViewer().getEntries();
100 		List<IRuntimeClasspathEntry> list = new ArrayList<>(entries.length);
101 		for (int i = 0; i < entries.length; i++) {
102 			list.add(entries[i]);
103 		}
104 		return list;
105 	}
106 
107 	/**
108 	 * Updates the entries to the entries in the given list
109 	 * @param list the list of {@link IRuntimeClasspathEntry}s to set
110 	 */
setEntries(List<IRuntimeClasspathEntry> list)111 	protected void setEntries(List<IRuntimeClasspathEntry> list) {
112 		getViewer().setEntries(list.toArray(new IRuntimeClasspathEntry[list.size()]));
113 		// update all selection listeners
114 		getViewer().setSelection(getViewer().getSelection());
115 	}
116 
117 	/**
118 	 * Returns whether the item at the given index in the list
119 	 * (visually) is selected.
120 	 * @param selection the current selection from the viewer
121 	 * @param index the index to ask about
122 	 * @return <code>true</code> if the given index is in the selection, <code>false</code> otherwise
123 	 */
isIndexSelected(IStructuredSelection selection, int index)124 	protected boolean isIndexSelected(IStructuredSelection selection, int index) {
125 		if (selection.isEmpty()) {
126 			return false;
127 		}
128 		Iterator<?> entries = selection.iterator();
129 		List<IRuntimeClasspathEntry> list = getEntriesAsList();
130 		while (entries.hasNext()) {
131 			Object next = entries.next();
132 			if (list.indexOf(next) == index) {
133 				return true;
134 			}
135 		}
136 		return false;
137 	}
138 
139 	/**
140 	 * Sets the {@link Button} that invokes this action
141 	 * @param button the new {@link Button} to set as the backing widget for this action
142 	 */
setButton(Button button)143 	public void setButton(Button button) {
144 		fButton = button;
145 		button.addSelectionListener(new SelectionAdapter() {
146 			@Override
147 			public void widgetSelected(SelectionEvent evt) {
148 				run();
149 			}
150 		});
151 		fButton.setEnabled(false);
152 	}
153 	/**
154 	 * @see IAction#setEnabled(boolean)
155 	 */
156 	@Override
setEnabled(boolean enabled)157 	public void setEnabled(boolean enabled) {
158 		super.setEnabled(enabled);
159 		if (fButton != null) {
160 			fButton.setEnabled(enabled);
161 		}
162 	}
163 
164 	/**
165 	 * Updates the enabled state.
166 	 */
update()167 	protected void update() {
168 		selectionChanged((IStructuredSelection)getViewer().getSelection());
169 	}
170 
171 	/**
172 	 * Returns the shell used to realize this action's dialog (if any).
173 	 * @return the current {@link Shell}
174 	 */
getShell()175 	protected Shell getShell() {
176 		if (fShell == null) {
177 			fShell= getViewer().getShell();
178 		}
179 		return fShell;
180 	}
181 
182 	/**
183 	 * Sets the shell used to realize this action's dialog (if any).
184 	 * @param shell the current shell
185 	 */
setShell(Shell shell)186 	public void setShell(Shell shell) {
187 		fShell= shell;
188 	}
189 
190 
191 	/* (non-Javadoc)
192 	 * @see org.eclipse.ui.actions.SelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection)
193 	 */
194 	@Override
updateSelection(IStructuredSelection selection)195 	protected boolean updateSelection(IStructuredSelection selection) {
196 		return getViewer().updateSelection(getActionType(), selection);
197 	}
198 
199 
getActionType()200 	protected int getActionType() {
201 		return DEFAULT;
202 	}
203 }
204