|
1 |
| |
|
2 |
| |
|
3 |
| |
|
4 |
| |
|
5 |
| |
|
6 |
| |
|
7 |
| |
|
8 |
| |
|
9 |
| |
|
10 |
| |
|
11 |
| |
|
12 |
| |
|
13 |
| |
|
14 |
| |
|
15 |
| |
|
16 |
| |
|
17 |
| |
|
18 |
| |
|
19 |
| |
|
20 |
| |
|
21 |
| |
|
22 |
| |
|
23 |
| |
|
24 |
| |
|
25 |
| |
|
26 |
| |
|
27 |
| |
|
28 |
| |
|
29 |
| |
|
30 |
| |
|
31 |
| |
|
32 |
| |
|
33 |
| |
|
34 |
| |
|
35 |
| |
|
36 |
| |
|
37 |
| package edu.rice.cs.drjava.ui; |
|
38 |
| |
|
39 |
| import java.util.LinkedList; |
|
40 |
| import java.util.ArrayList; |
|
41 |
| import java.util.Collection; |
|
42 |
| import java.lang.ref.WeakReference; |
|
43 |
| |
|
44 |
| import javax.swing.*; |
|
45 |
| import javax.swing.event.*; |
|
46 |
| import javax.swing.text.LayeredHighlighter; |
|
47 |
| import java.awt.event.*; |
|
48 |
| import java.awt.*; |
|
49 |
| |
|
50 |
| import javax.swing.border.CompoundBorder; |
|
51 |
| import javax.swing.border.LineBorder; |
|
52 |
| import javax.swing.border.MatteBorder; |
|
53 |
| |
|
54 |
| import edu.rice.cs.drjava.model.MovingDocumentRegion; |
|
55 |
| import edu.rice.cs.drjava.model.OpenDefinitionsDocument; |
|
56 |
| import edu.rice.cs.drjava.model.RegionManager; |
|
57 |
| import edu.rice.cs.drjava.model.RegionManagerListener; |
|
58 |
| import edu.rice.cs.drjava.config.*; |
|
59 |
| import edu.rice.cs.drjava.DrJava; |
|
60 |
| import edu.rice.cs.plt.tuple.Pair; |
|
61 |
| import edu.rice.cs.drjava.config.OptionConstants; |
|
62 |
| |
|
63 |
| |
|
64 |
| |
|
65 |
| |
|
66 |
| public class FindResultsPanel extends RegionsTreePanel<MovingDocumentRegion> { |
|
67 |
| |
|
68 |
| |
|
69 |
| |
|
70 |
| protected final String _searchString; |
|
71 |
| protected final boolean _searchAll; |
|
72 |
| protected final boolean _searchSelectionOnly; |
|
73 |
| protected final boolean _matchCase; |
|
74 |
| protected final boolean _wholeWord; |
|
75 |
| protected final boolean _noComments; |
|
76 |
| protected final boolean _noTestCases; |
|
77 |
| protected final WeakReference<OpenDefinitionsDocument> _doc; |
|
78 |
| protected final FindReplacePanel _findReplace; |
|
79 |
| protected final MovingDocumentRegion _region; |
|
80 |
| |
|
81 |
| protected JButton _findAgainButton; |
|
82 |
| protected JButton _goToButton; |
|
83 |
| protected JButton _bookmarkButton; |
|
84 |
| protected JButton _removeButton; |
|
85 |
| protected JComboBox _colorBox; |
|
86 |
| protected int _lastIndex; |
|
87 |
| |
|
88 |
| |
|
89 |
| private LinkedList<Pair<Option<Color>, OptionListener<Color>>> _colorOptionListeners = |
|
90 |
| new LinkedList<Pair<Option<Color>, OptionListener<Color>>>(); |
|
91 |
| |
|
92 |
| |
|
93 |
| |
|
94 |
| |
|
95 |
| |
|
96 |
| |
|
97 |
| |
|
98 |
| |
|
99 |
| |
|
100 |
| |
|
101 |
| |
|
102 |
0
| public FindResultsPanel(MainFrame frame, RegionManager<MovingDocumentRegion> regionManager, MovingDocumentRegion region, String title,
|
|
103 |
| String searchString, boolean searchAll, boolean searchSelectionOnly, boolean matchCase, boolean wholeWord, |
|
104 |
| boolean noComments, boolean noTestCases, WeakReference<OpenDefinitionsDocument> doc, |
|
105 |
| FindReplacePanel findReplace) { |
|
106 |
0
| super(frame, title, regionManager);
|
|
107 |
| |
|
108 |
| |
|
109 |
0
| _region = region;
|
|
110 |
0
| _searchString = searchString;
|
|
111 |
0
| _searchAll = searchAll;
|
|
112 |
0
| _searchSelectionOnly = searchSelectionOnly;
|
|
113 |
0
| _matchCase = matchCase;
|
|
114 |
0
| _wholeWord = wholeWord;
|
|
115 |
0
| _noComments = noComments;
|
|
116 |
0
| _noTestCases = noTestCases;
|
|
117 |
0
| _doc = doc;
|
|
118 |
0
| _findReplace = findReplace;
|
|
119 |
| |
|
120 |
| |
|
121 |
0
| StringBuilder sb = new StringBuilder();
|
|
122 |
0
| sb.append("<html>Find '").append(title);
|
|
123 |
0
| if (!title.equals(_searchString)) sb.append("...");
|
|
124 |
0
| sb.append("'");
|
|
125 |
0
| if (_searchAll) sb.append(" in all files");
|
|
126 |
0
| else if (_searchSelectionOnly) sb.append(" only in original selection.");
|
|
127 |
0
| sb.append(".");
|
|
128 |
0
| if (_matchCase) sb.append("<br>Case must match.");
|
|
129 |
0
| if (_wholeWord) sb.append("<br>Whole words only.");
|
|
130 |
0
| if (_noComments) sb.append("<br>No comments or strings.");
|
|
131 |
0
| if (_noTestCases) sb.append("<br>No test cases.");
|
|
132 |
0
| sb.append("</html>");
|
|
133 |
0
| _findAgainButton.setToolTipText(sb.toString());
|
|
134 |
| |
|
135 |
| |
|
136 |
0
| _regionManager.addListener(new RegionManagerListener<MovingDocumentRegion>() {
|
|
137 |
0
| public void regionAdded(MovingDocumentRegion r) { addRegion(r); }
|
|
138 |
0
| public void regionChanged(MovingDocumentRegion r) {
|
|
139 |
0
| regionRemoved(r);
|
|
140 |
0
| regionAdded(r);
|
|
141 |
| } |
|
142 |
0
| public void regionRemoved(MovingDocumentRegion r) { removeRegion(r); }
|
|
143 |
| }); |
|
144 |
| |
|
145 |
0
| for(int i = 0; i < OptionConstants.FIND_RESULTS_COLORS.length; ++i) {
|
|
146 |
0
| final OptionListener<Color> listener = new FindResultsColorOptionListener(i);
|
|
147 |
0
| final Pair<Option<Color>, OptionListener<Color>> pair =
|
|
148 |
| new Pair<Option<Color>, OptionListener<Color>>(OptionConstants.FIND_RESULTS_COLORS[i], listener); |
|
149 |
0
| _colorOptionListeners.add(pair);
|
|
150 |
0
| DrJava.getConfig().addOptionListener(OptionConstants.FIND_RESULTS_COLORS[i], listener);
|
|
151 |
| } |
|
152 |
| } |
|
153 |
| |
|
154 |
| class ColorComboRenderer extends JPanel implements ListCellRenderer { |
|
155 |
| private Color _color = DrJava.getConfig().getSetting(OptionConstants.FIND_RESULTS_COLORS[_colorBox.getSelectedIndex()]); |
|
156 |
| private DefaultListCellRenderer _defaultRenderer = new DefaultListCellRenderer(); |
|
157 |
| private final Dimension _size = new Dimension(0, 20); |
|
158 |
| private final CompoundBorder _compoundBorder = |
|
159 |
| new CompoundBorder(new MatteBorder(2, 10, 2, 10, Color.white), new LineBorder(Color.black)); |
|
160 |
| |
|
161 |
0
| public ColorComboRenderer() {
|
|
162 |
0
| super();
|
|
163 |
0
| setBackground(_color);
|
|
164 |
0
| setBorder(_compoundBorder);
|
|
165 |
| } |
|
166 |
| |
|
167 |
0
| public Component getListCellRendererComponent(JList list, Object value, int row, boolean sel, boolean hasFocus) {
|
|
168 |
0
| JComponent renderer;
|
|
169 |
0
| if (value instanceof Color) {
|
|
170 |
0
| _color = (Color) value;
|
|
171 |
0
| renderer = this;
|
|
172 |
| } |
|
173 |
| else { |
|
174 |
0
| JLabel l = (JLabel) _defaultRenderer.getListCellRendererComponent(list, value, row, sel, hasFocus);
|
|
175 |
0
| l.setHorizontalAlignment(JLabel.CENTER);
|
|
176 |
0
| renderer = l;
|
|
177 |
| } |
|
178 |
| |
|
179 |
0
| renderer.setPreferredSize(_size);
|
|
180 |
0
| return renderer;
|
|
181 |
| } |
|
182 |
| |
|
183 |
0
| public void paint(Graphics g) {
|
|
184 |
0
| setBackground(_color);
|
|
185 |
0
| setBorder(_compoundBorder);
|
|
186 |
0
| super.paint(g);
|
|
187 |
| } |
|
188 |
| } |
|
189 |
| |
|
190 |
| |
|
191 |
0
| protected JComponent[] makeButtons() {
|
|
192 |
0
| Action findAgainAction = new AbstractAction("Find Again") {
|
|
193 |
0
| public void actionPerformed(ActionEvent ae) { _findAgain(); }
|
|
194 |
| }; |
|
195 |
0
| _findAgainButton = new JButton(findAgainAction);
|
|
196 |
| |
|
197 |
0
| Action goToAction = new AbstractAction("Go to") {
|
|
198 |
0
| public void actionPerformed(ActionEvent ae) { goToRegion(); }
|
|
199 |
| }; |
|
200 |
0
| _goToButton = new JButton(goToAction);
|
|
201 |
| |
|
202 |
0
| Action bookmarkAction = new AbstractAction("Bookmark") {
|
|
203 |
0
| public void actionPerformed(ActionEvent ae) { _bookmark(); }
|
|
204 |
| }; |
|
205 |
0
| _bookmarkButton = new JButton(bookmarkAction);
|
|
206 |
| |
|
207 |
0
| Action removeAction = new AbstractAction("Remove") {
|
|
208 |
0
| public void actionPerformed(ActionEvent ae) { _remove(); }
|
|
209 |
| }; |
|
210 |
0
| _removeButton = new JButton(removeAction);
|
|
211 |
| |
|
212 |
| |
|
213 |
0
| final JPanel highlightPanel = new JPanel();
|
|
214 |
0
| final Color normalColor = highlightPanel.getBackground();
|
|
215 |
0
| highlightPanel.add(new JLabel("Highlight:"));
|
|
216 |
| |
|
217 |
| |
|
218 |
0
| int smallestIndex = 0;
|
|
219 |
0
| int smallestUsage = DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[smallestIndex];
|
|
220 |
0
| for(_lastIndex = 0; _lastIndex < OptionConstants.FIND_RESULTS_COLORS.length; ++_lastIndex) {
|
|
221 |
0
| if (DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex] < smallestUsage) {
|
|
222 |
0
| smallestIndex = _lastIndex;
|
|
223 |
0
| smallestUsage = DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[smallestIndex];
|
|
224 |
| } |
|
225 |
| } |
|
226 |
0
| _lastIndex = smallestIndex;
|
|
227 |
0
| ++DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex];
|
|
228 |
0
| _colorBox = new JComboBox();
|
|
229 |
0
| for (int i = 0; i < OptionConstants.FIND_RESULTS_COLORS.length; ++i) {
|
|
230 |
0
| _colorBox.addItem(DrJava.getConfig().getSetting(OptionConstants.FIND_RESULTS_COLORS[i]));
|
|
231 |
| } |
|
232 |
0
| _colorBox.addItem("None");
|
|
233 |
0
| _colorBox.setRenderer(new ColorComboRenderer());
|
|
234 |
0
| _colorBox.addActionListener(new ActionListener() {
|
|
235 |
0
| public void actionPerformed(ActionEvent e) {
|
|
236 |
0
| if (_lastIndex<OptionConstants.FIND_RESULTS_COLORS.length) {
|
|
237 |
0
| --DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex];
|
|
238 |
| } |
|
239 |
0
| _lastIndex = _colorBox.getSelectedIndex();
|
|
240 |
0
| if (_lastIndex<OptionConstants.FIND_RESULTS_COLORS.length) {
|
|
241 |
0
| ++DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex];
|
|
242 |
0
| highlightPanel.setBackground(DrJava.getConfig().getSetting(OptionConstants.FIND_RESULTS_COLORS[_lastIndex]));
|
|
243 |
| } |
|
244 |
0
| else highlightPanel.setBackground(normalColor);
|
|
245 |
| |
|
246 |
0
| _frame.refreshFindResultsHighlightPainter(FindResultsPanel.this,
|
|
247 |
| DefinitionsPane.FIND_RESULTS_PAINTERS[_lastIndex]); |
|
248 |
| } |
|
249 |
| }); |
|
250 |
0
| _colorBox.setMaximumRowCount(OptionConstants.FIND_RESULTS_COLORS.length + 1);
|
|
251 |
0
| _colorBox.addPopupMenuListener(new PopupMenuListener() {
|
|
252 |
0
| public void popupMenuCanceled(PopupMenuEvent e) { _colorBox.revalidate(); }
|
|
253 |
0
| public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { _colorBox.revalidate(); }
|
|
254 |
0
| public void popupMenuWillBecomeVisible(PopupMenuEvent e) { _colorBox.revalidate(); }
|
|
255 |
| }); |
|
256 |
0
| _colorBox.setSelectedIndex(_lastIndex);
|
|
257 |
0
| _frame.refreshFindResultsHighlightPainter(FindResultsPanel.this,
|
|
258 |
| DefinitionsPane.FIND_RESULTS_PAINTERS[_lastIndex]); |
|
259 |
| |
|
260 |
0
| updateButtons();
|
|
261 |
0
| return new JComponent[] { _findAgainButton, _goToButton, _bookmarkButton, _removeButton, highlightPanel, _colorBox};
|
|
262 |
| } |
|
263 |
| |
|
264 |
| |
|
265 |
0
| public LayeredHighlighter.LayerPainter getSelectedPainter() {
|
|
266 |
0
| return DefinitionsPane.FIND_RESULTS_PAINTERS[_lastIndex];
|
|
267 |
| } |
|
268 |
| |
|
269 |
| |
|
270 |
0
| private void _findAgain() {
|
|
271 |
0
| _updateButtons();
|
|
272 |
0
| OpenDefinitionsDocument odd = null;
|
|
273 |
0
| if (_searchAll) odd = _model.getActiveDocument();
|
|
274 |
0
| else if (_doc != null) { odd = _doc.get(); }
|
|
275 |
0
| if (odd != null) {
|
|
276 |
| |
|
277 |
0
| _regionManager.clearRegions();
|
|
278 |
0
| assert _rootNode == _regTreeModel.getRoot();
|
|
279 |
0
| _rootNode.removeAllChildren();
|
|
280 |
0
| _docToTreeNode.clear();
|
|
281 |
0
| _regionToTreeNode.clear();
|
|
282 |
0
| _regTreeModel.nodeStructureChanged(_rootNode);
|
|
283 |
0
| _lastSelectedRegion = null;
|
|
284 |
| |
|
285 |
| |
|
286 |
0
| _findReplace.findAll(_searchString, _searchAll, _searchSelectionOnly, _matchCase, _wholeWord, _noComments, _noTestCases, odd,
|
|
287 |
| _regionManager, _region, this); |
|
288 |
0
| _regTree.scrollRowToVisible(0);
|
|
289 |
0
| _requestFocusInWindow();
|
|
290 |
| } |
|
291 |
| } |
|
292 |
| |
|
293 |
| |
|
294 |
0
| private void _bookmark() {
|
|
295 |
0
| updateButtons();
|
|
296 |
0
| RegionManager<MovingDocumentRegion> bm = _model.getBookmarkManager();
|
|
297 |
0
| for (MovingDocumentRegion r: getSelectedRegions()) {
|
|
298 |
0
| OpenDefinitionsDocument doc = r.getDocument();
|
|
299 |
0
| int start = r.getStartOffset();
|
|
300 |
0
| int end = r.getEndOffset();
|
|
301 |
0
| Collection<MovingDocumentRegion> conflictingRegions = bm.getRegionsOverlapping(doc, start, end);
|
|
302 |
0
| for (MovingDocumentRegion cr: conflictingRegions) bm.removeRegion(cr);
|
|
303 |
| |
|
304 |
0
| int lineStart = r.getLineStartOffset();
|
|
305 |
0
| int lineEnd = r.getLineEndOffset();
|
|
306 |
0
| bm.addRegion(new MovingDocumentRegion(doc, start, end, lineStart, lineEnd));
|
|
307 |
| } |
|
308 |
0
| _frame.showBookmarks();
|
|
309 |
| } |
|
310 |
| |
|
311 |
| |
|
312 |
0
| protected void performDefaultAction() { goToRegion(); }
|
|
313 |
| |
|
314 |
| |
|
315 |
0
| protected void _updateButtons() {
|
|
316 |
0
| ArrayList<MovingDocumentRegion> regs = getSelectedRegions();
|
|
317 |
0
| OpenDefinitionsDocument odd = null;
|
|
318 |
0
| if (_doc != null) { odd = _doc.get(); }
|
|
319 |
0
| _findAgainButton.setEnabled(odd != null || _searchAll);
|
|
320 |
0
| _goToButton.setEnabled(regs.size() == 1);
|
|
321 |
0
| _bookmarkButton.setEnabled(regs.size() > 0);
|
|
322 |
0
| _removeButton.setEnabled(regs.size() > 0);
|
|
323 |
| } |
|
324 |
| |
|
325 |
| |
|
326 |
0
| protected AbstractAction[] makePopupMenuActions() {
|
|
327 |
0
| AbstractAction[] acts = new AbstractAction[] {
|
|
328 |
0
| new AbstractAction("Go to") { public void actionPerformed(ActionEvent e) { goToRegion(); } },
|
|
329 |
0
| new AbstractAction("Bookmark") { public void actionPerformed(ActionEvent e) { _bookmark(); } },
|
|
330 |
0
| new AbstractAction("Remove") { public void actionPerformed(ActionEvent e) { _remove(); } }
|
|
331 |
| }; |
|
332 |
0
| return acts;
|
|
333 |
| } |
|
334 |
| |
|
335 |
| |
|
336 |
0
| protected void goToRegion() {
|
|
337 |
0
| ArrayList<MovingDocumentRegion> r = getSelectedRegions();
|
|
338 |
| |
|
339 |
0
| if (r.size() == 1) {
|
|
340 |
0
| _frame.removeCurrentLocationHighlight();
|
|
341 |
0
| _frame.goToRegionAndHighlight(r.get(0));
|
|
342 |
| } |
|
343 |
| } |
|
344 |
| |
|
345 |
| |
|
346 |
| |
|
347 |
| |
|
348 |
| |
|
349 |
0
| @Override
|
|
350 |
| protected void _close() { |
|
351 |
| |
|
352 |
0
| _regionManager.clearRegions();
|
|
353 |
0
| _model.removeFindResultsManager(_regionManager);
|
|
354 |
0
| _frame.removeCurrentLocationHighlight();
|
|
355 |
0
| freeResources();
|
|
356 |
0
| super._close();
|
|
357 |
| } |
|
358 |
| |
|
359 |
| |
|
360 |
0
| public void freeResources() {
|
|
361 |
0
| _docToTreeNode.clear();
|
|
362 |
0
| _regionToTreeNode.clear();
|
|
363 |
0
| _model.removeFindResultsManager(_regionManager);
|
|
364 |
0
| for (Pair<Option<Color>, OptionListener<Color>> p: _colorOptionListeners) {
|
|
365 |
0
| DrJava.getConfig().removeOptionListener(p.first(), p.second());
|
|
366 |
| } |
|
367 |
0
| if (_lastIndex < OptionConstants.FIND_RESULTS_COLORS.length) {
|
|
368 |
0
| --DefinitionsPane.FIND_RESULTS_PAINTERS_USAGE[_lastIndex];
|
|
369 |
| } |
|
370 |
| } |
|
371 |
| |
|
372 |
| |
|
373 |
0
| public boolean isSearchAll() { return _searchAll; }
|
|
374 |
| |
|
375 |
| |
|
376 |
| |
|
377 |
0
| public OpenDefinitionsDocument getDocument() { return _doc.get(); }
|
|
378 |
| |
|
379 |
| |
|
380 |
0
| public void disableFindAgain() {
|
|
381 |
0
| _doc.clear();
|
|
382 |
0
| updateButtons();
|
|
383 |
| } |
|
384 |
| |
|
385 |
| |
|
386 |
| private class FindResultsColorOptionListener implements OptionListener<Color> { |
|
387 |
| private int _index; |
|
388 |
0
| public FindResultsColorOptionListener(int i) { _index = i; }
|
|
389 |
0
| public void optionChanged(OptionEvent<Color> oce) {
|
|
390 |
0
| int pos = _colorBox.getSelectedIndex();
|
|
391 |
0
| _colorBox.removeItemAt(_index);
|
|
392 |
0
| _colorBox.insertItemAt(oce.value, _index);
|
|
393 |
0
| _colorBox.setSelectedIndex(pos);
|
|
394 |
0
| if (pos == _index) {
|
|
395 |
0
| _frame.refreshFindResultsHighlightPainter(FindResultsPanel.this, DefinitionsPane.FIND_RESULTS_PAINTERS[_index]);
|
|
396 |
| } |
|
397 |
| } |
|
398 |
| } |
|
399 |
| } |