001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.javadoc.search;
043:
044: import java.awt.EventQueue;
045: import java.io.Externalizable;
046: import java.io.ObjectStreamException;
047: import java.net.URL;
048: import java.util.ArrayList;
049: import java.lang.ref.Reference;
050: import java.lang.ref.SoftReference;
051: import java.util.ResourceBundle;
052: import javax.swing.ComboBoxModel;
053: import javax.swing.DefaultListModel;
054: import javax.swing.ImageIcon;
055: import javax.swing.JSplitPane;
056: import org.netbeans.api.java.source.ElementHandle;
057: import org.netbeans.api.java.source.UiUtils;
058: import org.netbeans.api.javahelp.Help;
059: import org.netbeans.modules.javadoc.settings.DocumentationSettings;
060: import org.openide.awt.HtmlBrowser;
061: import org.openide.windows.TopComponent;
062: import org.openide.util.RequestProcessor;
063: import org.openide.NotifyDescriptor;
064: import org.openide.DialogDisplayer;
065: import org.openide.awt.Mnemonics;
066: import org.openide.filesystems.FileObject;
067: import org.openide.util.HelpCtx;
068: import org.openide.util.Lookup;
069: import org.openide.util.NbBundle;
070: import org.openide.util.Utilities;
071:
072: /** Main window for documentation index search
073: *
074: * @author Petr Hrebejk, Petr Suchomel
075: */
076: public final class IndexSearch extends TopComponent implements
077: Externalizable {
078:
079: private static final String INDEX_SEARCH_HELP_CTX_KEY = "javadoc.search.window"; //NOI18N
080:
081: private static final java.awt.Dimension PREFFERED_SIZE = new java.awt.Dimension(
082: 580, 430);
083:
084: static final long serialVersionUID = 1200348578933093459L;
085:
086: /** The only instance allowed in system */
087: private static Reference refIndexSearch;
088:
089: /** cache of previously searched strings */
090: private static Object[] MRU = new Object[0];
091:
092: /** Search engine */
093: private JavadocSearchEngine searchEngine = null;
094:
095: /** The state of the window is stored in hidden options of DocumentationSettings */
096: private DocumentationSettings ds = DocumentationSettings
097: .getDefault();
098:
099: private String quickFind;
100:
101: /* Current sort mode */
102: private String currentSort = "A"; // NOI18N
103:
104: /* Hand made components */
105: private javax.swing.JScrollPane resultsScrollPane;
106: private javax.swing.JList resultsList;
107: //private HtmlBrowser.BrowserComponent quickBrowser;
108: private HtmlBrowser quickBrowser;
109: private JSplitPane splitPanel;
110:
111: /** List models for different sorts */
112: private ArrayList results = new ArrayList();
113:
114: private DefaultListModel referenceModel = null;
115: private DefaultListModel typeModel = null;
116: private DefaultListModel alphaModel = null;
117:
118: /* Holds split position if the quick view is disabled */
119: private int oldSplit = DocumentationSettings.getDefault()
120: .getIdxSearchSplit();
121:
122: private final DefaultListModel waitModel = new DefaultListModel();
123: private final DefaultListModel notModel = new DefaultListModel();
124: private boolean setDividerLocation;
125:
126: /** Initializes the Form */
127: public IndexSearch() {
128: ResourceBundle b = NbBundle.getBundle(IndexSearch.class);
129: DocIndexItem dii = new DocIndexItem(b
130: .getString("CTL_SEARCH_Wait"), "", null, ""); //NOI18N
131: dii.setIconIndex(DocSearchIcons.ICON_WAIT);
132: waitModel.addElement(dii);
133:
134: DocIndexItem diin = new DocIndexItem(b
135: .getString("CTL_SEARCH_NotFound"), "", null, ""); //NOI18N
136: diin.setIconIndex(DocSearchIcons.ICON_NOT_FOUND);
137: notModel.addElement(diin);
138:
139: initComponents();
140:
141: // Force winsys to not show tab when this comp is alone
142: putClientProperty("TabPolicy", "HideWhenAlone"); // NOI18N
143:
144: javax.swing.ComboBoxEditor editor = searchComboBox.getEditor();
145: editor.addActionListener(new java.awt.event.ActionListener() {
146: public void actionPerformed(java.awt.event.ActionEvent evt) {
147: if (searchEngine == null)
148: searchButtonActionPerformed(evt);
149: }
150: });
151:
152: // Split panel
153: splitPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
154: splitPanel.setPreferredSize(PREFFERED_SIZE);
155:
156: //splitPanel.setDividerLocation(oldSplit / 100.0);
157: //previous line does not work
158: //setDividerLocation must be set in open
159: setDividerLocation = true;
160:
161: java.awt.GridBagConstraints gridBagConstraints1 = new java.awt.GridBagConstraints();
162: gridBagConstraints1.gridwidth = 0;
163: gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
164: gridBagConstraints1.insets = new java.awt.Insets(5, 0, 0, 0);
165: gridBagConstraints1.weightx = 1.0;
166: gridBagConstraints1.weighty = 1.0;
167: add(splitPanel, gridBagConstraints1);
168:
169: // Results - SrollPane & JList
170: resultsScrollPane = new javax.swing.JScrollPane();
171:
172: resultsList = new javax.swing.JList();
173: resultsList
174: .setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
175: resultsList.addKeyListener(new java.awt.event.KeyAdapter() {
176: public void keyPressed(java.awt.event.KeyEvent evt) {
177: resultsListKeyPressed(evt);
178: }
179: });
180: resultsList.addMouseListener(new java.awt.event.MouseAdapter() {
181: public void mouseClicked(java.awt.event.MouseEvent evt) {
182: resultsListMouseClicked(evt);
183: }
184: });
185:
186: resultsScrollPane.setViewportView(resultsList);
187:
188: splitPanel.setTopComponent(resultsScrollPane);
189:
190: // Quick browser component
191: quickBrowser = new HtmlBrowser(true, false);//.BrowserComponent( true, false );
192: quickBrowser.setEnableLocation(false);
193: quickBrowser.setEnableHome(false);
194: //browser buttons without border are too top
195: quickBrowser.setBorder(new javax.swing.border.EmptyBorder(
196: new java.awt.Insets(8, 0, 0, 0)));
197: splitPanel.setBottomComponent(quickBrowser);
198:
199: DefaultListModel listModel = new DefaultListModel(); // PENDING: Change to SortedArrayList
200: resultsList.setModel(listModel);
201:
202: IndexListCellRenderer cr = new IndexListCellRenderer();
203: resultsList.setCellRenderer(cr);
204:
205: resultsList.getSelectionModel().addListSelectionListener(
206: new javax.swing.event.ListSelectionListener() {
207: public void valueChanged(
208: javax.swing.event.ListSelectionEvent evt) {
209: if (!evt.getValueIsAdjusting()) {
210: showHelp(true);
211: }
212: }
213: });
214: resultsScrollPane.validate();
215:
216: sourceButton
217: .setIcon(new ImageIcon(
218: Utilities
219: .loadImage("org/netbeans/modules/javadoc/resources/showSource.gif"))); // NOI18N
220: byReferenceButton
221: .setIcon(new ImageIcon(
222: Utilities
223: .loadImage("org/netbeans/modules/javadoc/resources/refSort.gif"))); // NOI18N
224: byTypeButton
225: .setIcon(new ImageIcon(
226: Utilities
227: .loadImage("org/netbeans/modules/javadoc/resources/typeSort.gif"))); // NOI18N
228: byNameButton
229: .setIcon(new ImageIcon(
230: Utilities
231: .loadImage("org/netbeans/modules/javadoc/resources/alphaSort.gif"))); // NOI18N
232: quickViewButton
233: .setIcon(new ImageIcon(
234: Utilities
235: .loadImage("org/netbeans/modules/javadoc/resources/list_only.gif"))); // NOI18N
236: quickViewButton
237: .setSelectedIcon(new ImageIcon(
238: Utilities
239: .loadImage("org/netbeans/modules/javadoc/resources/list_html.gif"))); // NOI18N
240:
241: javax.swing.ButtonGroup bg = new javax.swing.ButtonGroup();
242: bg.add(byReferenceButton);
243: bg.add(byTypeButton);
244: bg.add(byNameButton);
245:
246: // Adding ToolTips
247:
248: searchButton.setToolTipText(b
249: .getString("CTL_SEARCH_search_ToolTip")); //NOI18N
250: byReferenceButton.setToolTipText(b
251: .getString("CTL_SEARCH_byReference_ToolTip")); //NOI18N
252: byTypeButton.setToolTipText(b
253: .getString("CTL_SEARCH_byType_ToolTip")); //NOI18N
254: byNameButton.setToolTipText(b
255: .getString("CTL_SEARCH_byName_ToolTip")); //NOI18N
256: quickViewButton.setToolTipText(b
257: .getString("CTL_SEARCH_quickView_ToolTip")); //NOI18N
258: sourceButton.setToolTipText(b
259: .getString("CTL_SEARCH_showSource_ToolTip")); //NOI18N
260: searchComboBox.setToolTipText(b
261: .getString("ACS_SEARCH_SearchComboBoxA11yDesc")); //NOI18N
262: resultsList.setToolTipText(b
263: .getString("ACS_SEARCH_ResultsListA11yDesc")); //NOI18N
264: quickBrowser.setToolTipText(b
265: .getString("ACS_SEARCH_QuickBrowserA11yDesc")); //NOI18N
266:
267: // Adding mnemonics
268: if (!Utilities.isMac()) {
269: byReferenceButton.setMnemonic(b.getString(
270: "CTL_SEARCH_byReference_Mnemonic").charAt(0)); // NOI18N
271: byTypeButton.setMnemonic(b.getString(
272: "CTL_SEARCH_byType_Mnemonic").charAt(0)); // NOI18N
273: byNameButton.setMnemonic(b.getString(
274: "CTL_SEARCH_byName_Mnemonic").charAt(0)); // NOI18N
275: quickViewButton.setMnemonic(b.getString(
276: "CTL_SEARCH_quickView_Mnemonic").charAt(0)); // NOI18N
277: sourceButton.setMnemonic(b.getString(
278: "CTL_SEARCH_showSource_Mnemonic").charAt(0)); // NOI18N
279: }
280: Mnemonics.setLocalizedText(searchButton, NbBundle.getMessage(
281: IndexSearch.class, "CTL_SEARCH_ButtonFind"));
282: Mnemonics.setLocalizedText(helpButton, NbBundle.getMessage(
283: IndexSearch.class, "CTL_SEARCH_ButtonHelp"));
284:
285: initAccessibility();
286: resolveButtonState();
287: }
288:
289: public int getPersistenceType() {
290: return TopComponent.PERSISTENCE_NEVER;
291: }
292:
293: protected String preferredID() {
294: return "JavaDocIndexSearch"; // NOI18N
295: }
296:
297: public HelpCtx getHelpCtx() {
298: return new HelpCtx(INDEX_SEARCH_HELP_CTX_KEY);
299: }
300:
301: private void initAccessibility() {
302: ResourceBundle b = NbBundle.getBundle(IndexSearch.class);
303: getAccessibleContext().setAccessibleName(
304: b.getString("ACS_SEARCH_PanelA11yName")); // NOI18N
305: getAccessibleContext().setAccessibleDescription(
306: b.getString("ACS_SEARCH_PanelA11yDesc")); // NOI18N
307: searchComboBox.getAccessibleContext().setAccessibleName(
308: b.getString("ACS_SEARCH_SearchComboBoxA11yName")); // NOI18N
309: searchComboBox.getAccessibleContext().setAccessibleDescription(
310: b.getString("ACS_SEARCH_SearchComboBoxA11yDesc")); // NOI18N
311: resultsList.getAccessibleContext().setAccessibleName(
312: b.getString("ACS_SEARCH_ResultsListA11yName")); // NOI18N
313: resultsList.getAccessibleContext().setAccessibleDescription(
314: b.getString("ACS_SEARCH_ResultsListA11yDesc")); // NOI18N
315: quickBrowser.getAccessibleContext().setAccessibleName(
316: b.getString("ACS_SEARCH_QuickBrowserA11yName")); // NOI18N
317: quickBrowser.getAccessibleContext().setAccessibleDescription(
318: b.getString("ACS_SEARCH_QuickBrowserA11yDesc")); // NOI18N
319: }
320:
321: /** This method is called from within the constructor to
322: * initialize the form.
323: * WARNING: Do NOT modify this code. The content of this method is
324: * always regenerated by the FormEditor.
325: */
326: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
327: private void initComponents() {
328: java.awt.GridBagConstraints gridBagConstraints;
329:
330: jPanel1 = new javax.swing.JPanel();
331: searchComboBox = new javax.swing.JComboBox(MRU);
332: searchButton = new javax.swing.JButton();
333: sourceButton = new javax.swing.JButton();
334: byNameButton = new javax.swing.JToggleButton();
335: byReferenceButton = new javax.swing.JToggleButton();
336: byTypeButton = new javax.swing.JToggleButton();
337: quickViewButton = new javax.swing.JToggleButton();
338: helpButton = new javax.swing.JButton();
339:
340: FormListener formListener = new FormListener();
341:
342: setLayout(new java.awt.GridBagLayout());
343:
344: setBorder(new javax.swing.border.EmptyBorder(
345: new java.awt.Insets(8, 8, 8, 8)));
346: jPanel1.setLayout(new java.awt.GridBagLayout());
347:
348: searchComboBox.setEditable(true);
349: searchComboBox.addActionListener(formListener);
350:
351: gridBagConstraints = new java.awt.GridBagConstraints();
352: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
353: gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
354: gridBagConstraints.weightx = 1.0;
355: gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 8);
356: jPanel1.add(searchComboBox, gridBagConstraints);
357:
358: searchButton.setText("Search");
359: searchButton.addActionListener(formListener);
360:
361: gridBagConstraints = new java.awt.GridBagConstraints();
362: gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
363: gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 3);
364: jPanel1.add(searchButton, gridBagConstraints);
365:
366: sourceButton.setPreferredSize(new java.awt.Dimension(25, 25));
367: sourceButton.setMinimumSize(new java.awt.Dimension(25, 25));
368: sourceButton.addActionListener(formListener);
369:
370: gridBagConstraints = new java.awt.GridBagConstraints();
371: gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 3);
372: jPanel1.add(sourceButton, gridBagConstraints);
373:
374: byNameButton.setSelected(true);
375: byNameButton.setPreferredSize(new java.awt.Dimension(25, 25));
376: byNameButton.setActionCommand("A");
377: byNameButton.setMinimumSize(new java.awt.Dimension(25, 25));
378: byNameButton.setRequestFocusEnabled(false);
379: byNameButton.addActionListener(formListener);
380:
381: jPanel1.add(byNameButton, new java.awt.GridBagConstraints());
382:
383: byReferenceButton.setPreferredSize(new java.awt.Dimension(25,
384: 25));
385: byReferenceButton.setActionCommand("R");
386: byReferenceButton
387: .setMinimumSize(new java.awt.Dimension(25, 25));
388: byReferenceButton.setRequestFocusEnabled(false);
389: byReferenceButton.addActionListener(formListener);
390:
391: jPanel1.add(byReferenceButton,
392: new java.awt.GridBagConstraints());
393:
394: byTypeButton.setPreferredSize(new java.awt.Dimension(25, 25));
395: byTypeButton.setActionCommand("T");
396: byTypeButton.setMinimumSize(new java.awt.Dimension(25, 25));
397: byTypeButton.setRequestFocusEnabled(false);
398: byTypeButton.addActionListener(formListener);
399:
400: jPanel1.add(byTypeButton, new java.awt.GridBagConstraints());
401:
402: quickViewButton.setSelected(true);
403: quickViewButton.setRequestFocusEnabled(false);
404: quickViewButton.addActionListener(formListener);
405:
406: gridBagConstraints = new java.awt.GridBagConstraints();
407: gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
408: jPanel1.add(quickViewButton, gridBagConstraints);
409:
410: helpButton.setToolTipText(org.openide.util.NbBundle.getBundle(
411: IndexSearch.class).getString(
412: "CTL_SEARCH_ButtonHelp_tooltip"));
413: helpButton.setText("Help");
414: helpButton.addActionListener(formListener);
415:
416: gridBagConstraints = new java.awt.GridBagConstraints();
417: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
418: gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
419: jPanel1.add(helpButton, gridBagConstraints);
420:
421: gridBagConstraints = new java.awt.GridBagConstraints();
422: gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
423: gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
424: gridBagConstraints.weightx = 1.0;
425: add(jPanel1, gridBagConstraints);
426:
427: }
428:
429: // Code for dispatching events from components to event handlers.
430:
431: private class FormListener implements java.awt.event.ActionListener {
432: public void actionPerformed(java.awt.event.ActionEvent evt) {
433: if (evt.getSource() == searchComboBox) {
434: IndexSearch.this .searchComboBoxActionPerformed(evt);
435: } else if (evt.getSource() == searchButton) {
436: IndexSearch.this .searchButtonActionPerformed(evt);
437: } else if (evt.getSource() == sourceButton) {
438: IndexSearch.this .showSource(evt);
439: } else if (evt.getSource() == byNameButton) {
440: IndexSearch.this .sortButtonActionPerformed(evt);
441: } else if (evt.getSource() == byReferenceButton) {
442: IndexSearch.this .sortButtonActionPerformed(evt);
443: } else if (evt.getSource() == byTypeButton) {
444: IndexSearch.this .sortButtonActionPerformed(evt);
445: } else if (evt.getSource() == quickViewButton) {
446: IndexSearch.this .quickViewButtonActionPerformed(evt);
447: } else if (evt.getSource() == helpButton) {
448: IndexSearch.this .helpButtonActionPerformed(evt);
449: }
450: }
451: }
452:
453: // </editor-fold>//GEN-END:initComponents
454:
455: private void helpButtonActionPerformed(
456: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_helpButtonActionPerformed
457: Help help = (Help) Lookup.getDefault().lookup(Help.class);
458:
459: help.showHelp(getHelpCtx());
460: }//GEN-LAST:event_helpButtonActionPerformed
461:
462: private void showSource(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showSource
463: showSource();
464: }//GEN-LAST:event_showSource
465:
466: private void sortButtonActionPerformed(
467: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sortButtonActionPerformed
468:
469: currentSort = evt.getActionCommand();
470: ds.setIdxSearchSort(currentSort);
471: sortResults();
472:
473: }//GEN-LAST:event_sortButtonActionPerformed
474:
475: private void quickViewButtonActionPerformed(
476: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_quickViewButtonActionPerformed
477: if (quickViewButton.isSelected()) {
478: splitPanel.setDividerLocation(oldSplit == 100 ? 0.5
479: : oldSplit / 100.0);
480: ds.setIdxSearchSplit(oldSplit == 100 ? 50 : oldSplit);
481: ds.setIdxSearchNoHtml(false);
482: showHelp(true);
483: } else {
484: oldSplit = (int) (splitPanel.getDividerLocation()
485: / splitPanel.getSize().getHeight() * 100);
486: splitPanel.setDividerLocation(1.0);
487: ds.setIdxSearchSplit(100);
488: ds.setIdxSearchNoHtml(true);
489: }
490: }//GEN-LAST:event_quickViewButtonActionPerformed
491:
492: private void resultsListKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_resultsListKeyPressed
493: // Add your handling code here:
494: if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER
495: || evt.getKeyCode() == java.awt.event.KeyEvent.VK_SPACE) {
496: /*
497: if ( evt.isShiftDown() ) {
498: showSource();
499: evt.consume();
500: }
501: else
502: */
503: showHelp();
504: }
505: }//GEN-LAST:event_resultsListKeyPressed
506:
507: private void resultsListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_resultsListMouseClicked
508: // Add your handling code here:
509: if (evt.getClickCount() == 2) {
510: if (evt.isShiftDown()) {
511: showSource();
512: evt.consume();
513: } else
514: showHelp();
515: }
516: }//GEN-LAST:event_resultsListMouseClicked
517:
518: private void showHelp() {
519: showHelp(false);
520: }
521:
522: RequestProcessor.Task task = null;
523:
524: /** Invokes the browser with help */
525: private void showHelp(boolean quick) {
526:
527: if (quick && splitPanel.getDividerLocation() == 100)
528: return;
529:
530: if (resultsList.getMinSelectionIndex() < 0)
531: return;
532:
533: DocIndexItem dii = (DocIndexItem) resultsList.getModel()
534: .getElementAt(resultsList.getMinSelectionIndex());
535:
536: try {
537: URL url = dii.getURL();
538:
539: if (url == null)
540: return;
541:
542: // Workaround for bug in FileSystems
543: String strUrl = url.toString();
544:
545: if (strUrl.startsWith("nbfs:") && strUrl.charAt(5) != '/') { // NOI18N
546: url = new URL("nbfs:/" + strUrl.substring(5)); // NOI18N
547: }
548:
549: if (quick) {
550: final URL furl = url;
551: if (task != null)
552: task.cancel();
553: task = RequestProcessor.getDefault().post(
554: new Runnable() {
555: public void run() {
556: quickBrowser.setURL(furl);
557: }
558: }, 650);
559: } else
560: HtmlBrowser.URLDisplayer.getDefault().showURL(url);
561: } catch (java.net.MalformedURLException ex) {
562: // Do nothing if the URL isn't O.K.
563: }
564: }
565:
566: /** Tryies to find source code for the selected item in repository. If the
567: * is foun opens the source
568: */
569: private void showSource() {
570:
571: if (resultsList.getMinSelectionIndex() < 0) {
572: return;
573: }
574:
575: DocIndexItem dii = (DocIndexItem) resultsList.getModel()
576: .getElementAt(resultsList.getMinSelectionIndex());
577:
578: try {
579: if (dii.getURL() == null) {
580: return;
581: }
582: Object[] e = SrcFinder.findSource(dii.getPackage(), dii
583: .getURL());
584:
585: if (e != null) {
586: FileObject toOpen = (FileObject) e[0];
587: ElementHandle eh = (ElementHandle) e[1];
588: UiUtils.open(toOpen, eh);
589: } else {
590: NotifyDescriptor.Message nd = new NotifyDescriptor.Message(
591: NbBundle.getMessage(IndexSearch.class,
592: "MSG_SEARCH_SrcNotFound")); //NOI18N
593: DialogDisplayer.getDefault().notify(nd);
594: }
595:
596: } catch (java.net.MalformedURLException e) {
597: //System.out.println( e );
598: }
599: }
600:
601: private void searchComboBoxActionPerformed(
602: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchComboBoxActionPerformed
603: /*if ( searchEngine == null )
604: searchButtonActionPerformed( evt );*/
605: }//GEN-LAST:event_searchComboBoxActionPerformed
606:
607: private void searchButtonActionPerformed(
608: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
609: if (searchEngine == null) {
610: if (searchComboBox.getEditor().getItem().toString() != null
611: && searchComboBox.getEditor().getItem().toString()
612: .length() > 0) {
613: searchEngine = JavadocSearchEngine.getDefault();
614: go();
615: }
616: } else {
617: searchEngine.stop();
618: searchEngine = null;
619: }
620: }//GEN-LAST:event_searchButtonActionPerformed
621:
622: // Variables declaration - do not modify//GEN-BEGIN:variables
623: private javax.swing.JToggleButton byNameButton;
624: private javax.swing.JToggleButton byReferenceButton;
625: private javax.swing.JToggleButton byTypeButton;
626: private javax.swing.JButton helpButton;
627: private javax.swing.JPanel jPanel1;
628: private javax.swing.JToggleButton quickViewButton;
629: private javax.swing.JButton searchButton;
630: private javax.swing.JComboBox searchComboBox;
631: private javax.swing.JButton sourceButton;
632:
633: // End of variables declaration//GEN-END:variables
634:
635: private void searchStoped() {
636: searchEngine = null;
637: javax.swing.SwingUtilities.invokeLater(new Runnable() {
638: public void run() {
639: Mnemonics.setLocalizedText(searchButton, NbBundle
640: .getMessage(IndexSearch.class,
641: "CTL_SEARCH_ButtonFind"));
642: referenceModel = typeModel = alphaModel = null;
643: sortResults();
644: if (resultsList.getModel().getSize() > 0) {
645: resultsList.setSelectedIndex(0);
646: resultsList.grabFocus();
647: }
648: }
649: });
650: }
651:
652: void setTextToFind(String toFind) {
653: quickFind = toFind;
654: /*
655: if ( toFind != null ) {
656: quickFind = toFind;
657: }
658: */
659: }
660:
661: @Override
662: public void open() {
663: super .open();
664:
665: if (quickFind != null) {
666: searchComboBox.getEditor().setItem(quickFind);
667: if (searchEngine == null) {
668: searchButtonActionPerformed(null);
669: }
670: }
671:
672: quickFind = null;
673: searchComboBox.getEditor().selectAll();
674:
675: if (setDividerLocation) {
676: setDividerLocation = false;
677: EventQueue.invokeLater(new Runnable() {
678: public void run() {
679: splitPanel.setDividerLocation(oldSplit / 100.0);
680: }
681: });
682: }
683: }
684:
685: @Override
686: protected void componentClosed() {
687: super .componentClosed();
688: if (!quickViewButton.isSelected()) {
689: int split = ds.getIdxSearchSplit();
690: double proportional = (double) splitPanel
691: .getDividerLocation()
692: / (splitPanel.getHeight() - splitPanel
693: .getDividerSize());
694: final int currSplit = (int) (proportional * 100.0);
695: if (split != currSplit) {
696: ds.setIdxSearchSplit(currSplit);
697: }
698: }
699: }
700:
701: java.awt.Dimension getPrefferedSize() {
702: return PREFFERED_SIZE;
703: }
704:
705: public static IndexSearch getDefault() {
706: IndexSearch indexSearch;
707: if (refIndexSearch == null
708: || null == (indexSearch = (IndexSearch) refIndexSearch
709: .get())) {
710: indexSearch = new IndexSearch();
711: refIndexSearch = new SoftReference(indexSearch);
712:
713: indexSearch.setName(NbBundle.getMessage(IndexSearch.class,
714: "CTL_SEARCH_WindowTitle")); //NOI18N
715: indexSearch
716: .setIcon(Utilities
717: .loadImage("org/netbeans/modules/javadoc/resources/searchDoc.gif")); // NOI18N
718: }
719: return indexSearch;
720: }
721:
722: public void resolveButtonState() {
723:
724: currentSort = ds.getIdxSearchSort();
725: final boolean noHtml = ds.isIdxSearchNoHtml();
726:
727: byNameButton.setSelected(currentSort.equals("A")); // NOI18N
728: byReferenceButton.setSelected(currentSort.equals("R")); // NOI18N
729: byTypeButton.setSelected(currentSort.equals("T")); // NOI18N
730: quickViewButton.setSelected(!noHtml);
731: }
732:
733: /**
734: * Replaces previously stored instances with the default one. Just due to
735: * backward compatibility.
736: * @return the default instance
737: * @throws ObjectStreamException
738: */
739: private Object readResolve() throws ObjectStreamException {
740: return getDefault();
741: }
742:
743: void go() {
744: String toFind = searchComboBox.getEditor().getItem().toString()
745: .trim();
746:
747: // Alocate array for results
748: results = new ArrayList();
749:
750: //Clear all models
751: referenceModel = null;
752: typeModel = null;
753: alphaModel = null;
754:
755: // Try to find this string in Combo
756:
757: for (int i = 0; i < searchComboBox.getItemCount(); i++) {
758: if (searchComboBox.getItemAt(i).toString().equals(toFind)
759: || i >= 10) {
760: searchComboBox.removeItemAt(i);
761: }
762: }
763:
764: searchComboBox.insertItemAt(toFind, 0);
765: mirrorMRUStrings();
766: searchComboBox.getEditor().setItem(toFind);
767:
768: resultsList.setModel(waitModel);
769:
770: try {
771: searchEngine.search(new String[] { toFind },
772: new JavadocSearchEngine.SearchEngineCallback() {
773: public void finished() {
774: searchStoped();
775: }
776:
777: public void addItem(DocIndexItem item) {
778: results.add(item);
779: }
780: });
781: } catch (NoJavadocException noJdc) {
782: DialogDisplayer.getDefault().notify(
783: new NotifyDescriptor.Message(noJdc.getMessage())); //NOI18N
784: searchStoped();
785: return;
786: }
787:
788: Mnemonics.setLocalizedText(searchButton, NbBundle.getMessage(
789: IndexSearch.class, "CTL_SEARCH_ButtonStop"));
790: }
791:
792: private void mirrorMRUStrings() {
793: ComboBoxModel model = searchComboBox.getModel();
794: int size = model.getSize();
795: MRU = new Object[size];
796: for (int i = 0; i < size; i++) {
797: MRU[i] = model.getElementAt(i);
798: }
799: }
800:
801: DefaultListModel generateModel(java.util.Comparator comp) {
802: DefaultListModel model = new DefaultListModel();
803:
804: java.util.Collections.sort(results, comp);
805: java.util.Iterator it = results.iterator();
806:
807: String pckg = null;
808:
809: while (it.hasNext()) {
810: DocIndexItem dii = (DocIndexItem) it.next();
811: if (comp == DocIndexItem.REFERENCE_COMPARATOR
812: && !dii.getPackage().equals(pckg)
813: && dii.getIconIndex() != DocSearchIcons.ICON_PACKAGE) {
814: DocIndexItem ndii = new DocIndexItem("PACKAGE ", dii
815: .getPackage(), null, ""); // NOI18N
816: ndii.setIconIndex(DocSearchIcons.ICON_PACKAGE);
817: model.addElement(ndii);
818: pckg = dii.getPackage();
819: }
820:
821: model.addElement(dii);
822: }
823: return model;
824: }
825:
826: void sortResults() {
827:
828: if (results.size() < 1) {
829: resultsList.setModel(notModel);
830: } else if (currentSort.equals("R")) { // NOI18N
831: if (referenceModel == null) {
832: resultsList.setModel(waitModel);
833: resultsList.invalidate();
834: resultsList.revalidate();
835: referenceModel = generateModel(DocIndexItem.REFERENCE_COMPARATOR);
836: }
837: resultsList.setModel(referenceModel);
838: } else if (currentSort.equals("T")) { // NOI18N
839: if (typeModel == null) {
840: resultsList.setModel(waitModel);
841: resultsList.invalidate();
842: resultsList.revalidate();
843: typeModel = generateModel(DocIndexItem.TYPE_COMPARATOR);
844: }
845: resultsList.setModel(typeModel);
846: } else if (currentSort.equals("A")) { // NOI18N
847: if (alphaModel == null) {
848: resultsList.setModel(waitModel);
849: resultsList.invalidate();
850: resultsList.revalidate();
851: alphaModel = generateModel(DocIndexItem.ALPHA_COMPARATOR);
852: }
853: resultsList.setModel(alphaModel);
854: }
855:
856: resultsList.invalidate();
857: resultsList.revalidate();
858: resultsList.repaint();
859: }
860: }
|