diff --git a/options.api/src/org/netbeans/modules/options/OptionsPanel.java b/options.api/src/org/netbeans/modules/options/OptionsPanel.java --- a/options.api/src/org/netbeans/modules/options/OptionsPanel.java +++ b/options.api/src/org/netbeans/modules/options/OptionsPanel.java @@ -73,37 +73,30 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; +import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.AbstractAction; -import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.InputMap; -import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; -import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JTabbedPane; -import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.KeyStroke; -import javax.swing.ListModel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; -import javax.swing.border.TitledBorder; -import javax.swing.table.JTableHeader; -import javax.swing.table.TableColumnModel; -import javax.swing.table.TableModel; import javax.swing.text.JTextComponent; import org.netbeans.modules.options.advanced.AdvancedPanel; import org.netbeans.modules.options.ui.VariableBorder; @@ -111,6 +104,8 @@ import org.openide.awt.Mnemonics; import org.openide.awt.QuickSearch; import org.openide.awt.StatusDisplayer; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; import org.openide.util.HelpCtx; import org.openide.util.Mutex; import org.openide.util.NbBundle; @@ -128,7 +123,8 @@ private int selectedTabIndex = -1; private HashMap categoryid2tabbedpane = new HashMap(); - private HashMap> categoryid2words = new HashMap>(); + private HashMap> categoryid2words = new HashMap>(); + private HashMap> categoryid2tabs = new HashMap>(); private HashMap categoryid2jcomponents = new HashMap(); private HashMap> tabbedpane2tabs = new HashMap>(); private HashMap> tabbedpane2removedtabs = new HashMap>(); @@ -351,191 +347,95 @@ for (Map.Entry set : categories) { JComponent jcomp = set.getValue().getComponent(); String id = set.getValue().getID(); - ArrayList strings = categoryid2words.get(id); - if (strings == null) { - strings = new ArrayList(); - } - if (!strings.contains(id.toUpperCase())) { - strings.add(id.toUpperCase()); - } - categoryid2words.put(id, strings); if(jcomp instanceof JTabbedPane) { categoryid2tabbedpane.put(id, (JTabbedPane)jcomp); - handleJTabbedPane((JTabbedPane)jcomp, id); } else if(jcomp instanceof AdvancedPanel) { categoryid2tabbedpane.put(id, (JTabbedPane)jcomp.getComponent(0)); - handleJTabbedPane((JTabbedPane)jcomp.getComponent(0), id); } else if (jcomp instanceof Container) { - setCurrentCategory(set.getValue(), null); handleAllComponents((Container) jcomp, id, null, -1); } } + categoryid2tabs = new HashMap>(); + FileObject keywordPanels = FileUtil.getConfigRoot().getFileObject(CategoryModel.OD_LAYER_KEYWORDPANELS_FOLDER_NAME); + for(FileObject keywordPanel : keywordPanels.getChildren()) { + handlePanel(keywordPanel); + } } - private void handleJTabbedPane(JTabbedPane pane, String categoryID) { - int tabsNum = pane.getTabCount(); - selectedTabIndex = pane.getSelectedIndex(); - for (int i = 0; i < tabsNum; i++) { - pane.setSelectedIndex(i); - Component tab = pane.getComponentAt(i); - - HashMap hash = tabbedpane2tabs.get(pane); - if(hash == null) { - hash = new HashMap(); - } - hash.put(i, new TabInfo(pane.getTitleAt(i), CategoryModel.getInstance().getCategory(categoryID).getCategoryName(), tab)); - tabbedpane2tabs.put(pane, hash); - - ArrayList strings = categoryid2words.get(categoryID); - if (strings == null) { - strings = new ArrayList(); - } - if (!strings.contains(pane.getTitleAt(i).toUpperCase())) { - strings.add(pane.getTitleAt(i).toUpperCase()); - } - categoryid2words.put(categoryID, strings); - - if (tab instanceof Container) { - handleAllComponents((Container) tab, categoryID, pane, i); + private void handlePanel(FileObject keywordPanel) { + String location = ""; + String id = ""; + int index = -1; + ArrayList keywords = new ArrayList(); + + Enumeration attributes = keywordPanel.getAttributes(); + while(attributes.hasMoreElements()) { + String nextElement = attributes.nextElement(); + if(nextElement.equals("location")) { + location = keywordPanel.getAttribute(nextElement).toString(); + } else if(nextElement.equals("id")) { + id = keywordPanel.getAttribute(nextElement).toString(); + if (id.startsWith("#")) { + id = NbBundle.getMessage(keywordPanel.getClass(), id.substring(1)); + } + } else if(nextElement.equals("index")) { + index = (Integer) keywordPanel.getAttribute(nextElement); + } else if(nextElement.startsWith("keyword")) { + String keyword = keywordPanel.getAttribute(nextElement).toString(); + if (keyword.startsWith("#")) { + keyword = NbBundle.getMessage(keywordPanel.getClass(), keyword.substring(1)); + } + keywords.add(keyword); } } - pane.setSelectedIndex(selectedTabIndex); + + List words = categoryid2words.get(location); + if (words == null) { + words = new ArrayList(); + } + + Set newWords = new HashSet(); + for (String keyword : keywords) { + if (!words.contains(keyword)) { + newWords.add(keyword); + } + } + words.addAll(newWords); + categoryid2words.put(location, words); + + if (!categoryid2tabs.containsKey(location)) { + categoryid2tabs.put(location, new HashMap()); + } + HashMap categoryTabs = categoryid2tabs.get(location); + TabInfo tabInfo; + if (!categoryTabs.containsKey(index)) { + tabInfo = new TabInfo(id); + } else { + tabInfo = categoryTabs.get(index); + } + tabInfo.addWords(newWords); + categoryTabs.put(index, tabInfo); + categoryid2tabs.put(location, categoryTabs); } private void handleAllComponents(Container container, String categoryID, JTabbedPane tabbedPane, int index) { Component[] components = container.getComponents(); - Component component = null; - ArrayList strings = categoryid2words.get(categoryID); - if(strings == null) { - strings = new ArrayList(); - } - - CategoryInfo categoryInfo = categoryid2jcomponents.get(categoryID); - if (categoryInfo == null) { - categoryInfo = new CategoryInfo(); - } + Component component; for (int i = 0; i < components.length; i++) { component = components[i]; - String text = ""; - - if (component instanceof JComponent) { - final Border border = ((JComponent)component).getBorder(); - if (border instanceof TitledBorder) { - TitledBorder titledBorder = (TitledBorder) border; - text = titledBorder.getTitle(); - if (text != null && !text.isEmpty() && !strings.contains(text.toUpperCase())) { - strings.add(text.toUpperCase()); - } - } - categoryInfo.addComponent(text, (JComponent)component); - } - + String text; +// if (component instanceof JLabel) { text = ((JLabel) component).getText(); - if (text != null && !text.isEmpty() && !strings.contains(text.toUpperCase())) { - strings.add(text.toUpperCase()); - } // hack to search into Keymaps category if(categoryID.equals("Keymaps") && text.equals("Search:")) { // NOI18N keymapsSearch = (JTextField)((JLabel) component).getLabelFor(); } - } else if (component instanceof AbstractButton) { - text = ((AbstractButton) component).getText(); - if (text != null && !text.isEmpty() && !strings.contains(text.toUpperCase())) { - strings.add(text.toUpperCase()); - } - } else if (component instanceof JTextComponent) { - text = ((JTextComponent) component).getText(); - if (text != null && !text.isEmpty() && !strings.contains(text.toUpperCase())) { - strings.add(text.toUpperCase()); - } - } else if (component instanceof JComboBox) { - StringBuilder sb = new StringBuilder(); - for (int j = 0; j < ((JComboBox) component).getItemCount(); j++) { - Object object = ((JComboBox) component).getItemAt(j); - text = object.toString(); - if (text != null && !text.isEmpty()) { - if (!strings.contains(text.toUpperCase())) { - strings.add(text.toUpperCase()); - } - sb.append(text.toUpperCase().concat(" ")); - } - } - text = sb.toString().trim(); - } else if (component instanceof JList) { - StringBuilder sb = new StringBuilder(); - ListModel model = ((JList) component).getModel(); - if (model != null) { - for (int j = 0; j < model.getSize(); j++) { - Object object = model.getElementAt(j); - if (object != null) { - text = object.toString(); - if (text != null && !text.isEmpty()) { - if (!strings.contains(text.toUpperCase())) { - strings.add(text.toUpperCase()); - } - sb.append(text.toUpperCase().concat(" ")); - } - } - } - } - text = sb.toString().trim(); - } else if (component instanceof JTable) { - StringBuilder sb = new StringBuilder(); - JTableHeader header = ((JTable) component).getTableHeader(); - if (header != null) { - TableColumnModel columnModel = header.getColumnModel(); - for (int j = 0; j < columnModel.getColumnCount(); j++) { - Object object = columnModel.getColumn(j).getHeaderValue(); - if (object != null) { - text = object.toString(); - if (text != null && !text.isEmpty()) { - if (!strings.contains(text.toUpperCase())) { - strings.add(text.toUpperCase()); - } - sb.append(text.toUpperCase().concat(" ")); - } - } - } - } - - TableModel model = ((JTable) component).getModel(); - for (int j = 0; j < model.getRowCount(); j++) { - for (int k = 0; k < model.getColumnCount(); k++) { - Object object = model.getValueAt(j, k); - if(object != null) { - text = object.toString(); - if (text != null && !text.isEmpty()) { - if (!strings.contains(text.toUpperCase())) { - strings.add(text.toUpperCase()); - } - sb.append(text.toUpperCase().concat(" ")); - } - } - } - } - text = sb.toString().trim(); - } - - if (component instanceof JComponent) { - categoryInfo.addComponent(text, (JComponent) component); - } - - categoryid2jcomponents.put(categoryID, categoryInfo); - categoryid2words.put(categoryID, strings); - - if (tabbedPane != null && index > -1) { - TabInfo tabInfo = tabbedpane2tabs.get(tabbedPane).get(index); - if (text != null && !text.isEmpty() && !tabInfo.getWords().contains(text.toUpperCase())) { - tabInfo.addWord(text.toUpperCase()); - tabbedpane2tabs.get(tabbedPane).put(index, tabInfo); - } - } + } if(component instanceof JTabbedPane) { if(categoryid2tabbedpane.get(categoryID) == null) { categoryid2tabbedpane.put(categoryID, (JTabbedPane)component); } - handleJTabbedPane((JTabbedPane)component, categoryID); } else { handleAllComponents((Container)component, categoryID, tabbedPane, index); } @@ -574,6 +474,7 @@ private class TabInfo { private String tabTitle; + private String tabSubpath; private Component tab; private String categoryName; private ArrayList words; @@ -587,10 +488,19 @@ words.add(categoryName.toUpperCase()); } + public TabInfo(String tabSubpath) { + this.tabSubpath = tabSubpath; + this.words = new ArrayList(); + } + public String getTabTitle() { return tabTitle; } + public String getTabSubpath() { + return tabSubpath; + } + public Component getTab() { return tab; } @@ -606,6 +516,12 @@ public void addWord(String word) { words.add(word.toUpperCase()); } + + public void addWords(Set words) { + for (String word : words) { + addWord(word); + } + } } final class OptionsQSCallback implements QuickSearch.Callback { @@ -664,99 +580,150 @@ }); } + private int getNextEnabledTabIndex(JTabbedPane pane, int currentIndex) { + for (int i = currentIndex + 1; i < pane.getTabCount(); i++) { + if(pane.isEnabledAt(i)) { + return i; + } + } + for (int i = 0; i < currentIndex; i++) { + if(pane.isEnabledAt(i)) { + return i; + } + } + return -1; + } + private void handleSearch(String searchText) { String visibleCategory = null; String exactCategory = null; + String exactSubpath = null; int exactTabIndex = 0; for (String id : CategoryModel.getInstance().getCategoryIDs()) { - ArrayList entry = categoryid2words.get(id); - boolean found = false; - for (String text : entry) { - if (text.contains(searchText.toUpperCase())) { - found = true; - if(id.toUpperCase().contains(searchText.toUpperCase())) { - exactCategory = id; + List entry = categoryid2words.get(id); + if (entry != null) { + boolean found = false; + for (String text : entry) { + if (text.toUpperCase().contains(searchText.toUpperCase())) { + found = true; + if (id.toUpperCase().contains(searchText.toUpperCase())) { + exactCategory = id; + } + break; } - break; } - } - - if (found) { - visibleCategory = id; - removedCategories.remove(id); - buttons.get(id).setVisible(true); - JTabbedPane pane = categoryid2tabbedpane.get(id); - if (pane != null) { - HashMap tabsInfo = tabbedpane2tabs.get(pane); - for (Integer tabIndex : tabsInfo.keySet()) { - ArrayList tabWords = tabsInfo.get(tabIndex).getWords(); - boolean foundInTab = false; - for (int i = 0; i < tabWords.size(); i++) { - String txt = tabWords.get(i).toString().toUpperCase(); - if (txt.contains(searchText.toUpperCase())) { - foundInTab = true; - String tabTitle = tabsInfo.get(tabIndex).getTabTitle(); - if (tabTitle.toUpperCase().contains(searchText.toUpperCase())) { - if (exactCategory == null - || (exactCategory != null && exactCategory.equals(id) - && exactCategory.toUpperCase().contains(searchText.toUpperCase()))) { - exactTabIndex = tabIndex; - setCurrentCategory(CategoryModel.getInstance().getCategory(id), null); + + if (found) { + visibleCategory = id; + removedCategories.remove(id); + buttons.get(id).setEnabled(true); + JTabbedPane pane = categoryid2tabbedpane.get(id); + if (categoryid2tabs.get(id) != null) { + HashMap tabsInfo = categoryid2tabs.get(id); + boolean cont = true; + if (tabsInfo.containsKey(-1)) { + int tabIndex = -1; + ArrayList tabWords = tabsInfo.get(tabIndex).getWords(); + boolean foundInTab = false; + for (int i = 0; i < tabWords.size(); i++) { + String txt = tabWords.get(i).toString().toUpperCase(); + if (txt.contains(searchText.toUpperCase())) { + foundInTab = true; + String tabTitle = tabsInfo.get(tabIndex).getTabTitle(); + String tabSubpath = tabsInfo.get(tabIndex).getTabSubpath(); + exactTabIndex = tabIndex; + exactSubpath = tabSubpath; + setCurrentCategory(CategoryModel.getInstance().getCategory(id), exactSubpath); + break; + } + } + if (foundInTab) { + cont = false; + for (Integer tabIndex2 : tabsInfo.keySet()) { + if (tabIndex2 != -1) { + pane.setEnabledAt(tabIndex2, false); + } + pane.setSelectedIndex(tabIndex); + } + } + } + if (cont) { + for (Integer tabIndex : tabsInfo.keySet()) { + if (tabIndex != -1) { + ArrayList tabWords = tabsInfo.get(tabIndex).getWords(); + boolean foundInTab = false; + for (int i = 0; i < tabWords.size(); i++) { + String txt = tabWords.get(i).toString().toUpperCase(); + if (txt.contains(searchText.toUpperCase())) { + foundInTab = true; + String tabTitle = tabsInfo.get(tabIndex).getTabTitle(); + String tabSubpath = tabsInfo.get(tabIndex).getTabSubpath(); + exactTabIndex = tabIndex; + exactSubpath = tabSubpath; + setCurrentCategory(CategoryModel.getInstance().getCategory(id), exactSubpath); + break; + } + } + if (foundInTab) { + pane.setEnabledAt(tabIndex, true); + if (exactTabIndex == tabIndex) { + pane.setSelectedIndex(tabIndex); + } + } else { + pane.setEnabledAt(tabIndex, false); + pane.setSelectedIndex(getNextEnabledTabIndex(pane, tabIndex)); } } + } + } + } else { + setCurrentCategory(CategoryModel.getInstance().getCategory(id), null); + } + } else { + if (!removedCategories.contains(id)) { + removedCategories.add(id); + } + JTabbedPane pane = categoryid2tabbedpane.get(id); + if (categoryid2tabs.get(id) != null) { + HashMap tabsInfo = categoryid2tabs.get(id); + for (Integer tabIndex : tabsInfo.keySet()) { + if(tabIndex != -1) { + pane.setEnabledAt(tabIndex, false); + } + } + } + buttons.get(id).setEnabled(false); + if (removedCategories.size() == buttons.size()) { + setCurrentCategory(null, null); + visibleCategory = null; + } else { + for (String id3 : CategoryModel.getInstance().getCategoryIDs()) { + if (buttons.get(id3).isVisible() && exactCategory == null && exactSubpath == null) { + setCurrentCategory(CategoryModel.getInstance().getCategory(id3), null); + visibleCategory = id3; break; } } - HashMap removedTabsInfo = tabbedpane2removedtabs.get(pane); - if (removedTabsInfo == null) { - removedTabsInfo = new HashMap(); - } - if (foundInTab) { - int removedTabsBefore = 0; - for (Integer removedTabIndex : removedTabsInfo.keySet()) { - if (removedTabIndex < tabIndex) { - removedTabsBefore++; - } - } - if (removedTabsInfo.get(tabIndex) != null) { - pane.insertTab(removedTabsInfo.get(tabIndex).getTabTitle(), null, removedTabsInfo.get(tabIndex).getTab(), null, tabIndex - removedTabsBefore); - removedTabsInfo.remove(tabIndex); - tabbedpane2removedtabs.put(pane, removedTabsInfo); - } - if (exactTabIndex == tabIndex) { - pane.setSelectedIndex(tabIndex - removedTabsBefore); - } - } else { - int removedTabs = tabbedpane2removedtabs.get(pane) == null ? 0 : tabbedpane2removedtabs.get(pane).size(); - if (removedTabs != tabbedpane2tabs.get(pane).size()) { - if (!removedTabsInfo.containsKey(tabIndex)) { - int removedTabsBefore = 0; - for (Integer removedTabIndex : removedTabsInfo.keySet()) { - if (removedTabIndex < tabIndex) { - removedTabsBefore++; - } - } - removedTabsInfo.put(tabIndex, tabsInfo.get(tabIndex)); - tabbedpane2removedtabs.put(pane, removedTabsInfo); - pane.removeTabAt(tabIndex - removedTabsBefore); - } - } - } } - } else { - setCurrentCategory(CategoryModel.getInstance().getCategory(id), null); } } else { if (!removedCategories.contains(id)) { removedCategories.add(id); } - buttons.get(id).setVisible(false); - if(removedCategories.size() == buttons.size()) { + JTabbedPane pane = categoryid2tabbedpane.get(id); + if (categoryid2tabs.get(id) != null) { + HashMap tabsInfo = categoryid2tabs.get(id); + for (Integer tabIndex : tabsInfo.keySet()) { + pane.setEnabledAt(tabIndex, false); + } + } + buttons.get(id).setEnabled(false); + if (removedCategories.size() == buttons.size()) { setCurrentCategory(null, null); visibleCategory = null; } else { for (String id3 : CategoryModel.getInstance().getCategoryIDs()) { - if (buttons.get(id3).isVisible() && exactCategory == null) { + if (buttons.get(id3).isVisible() && exactCategory == null && exactSubpath == null) { setCurrentCategory(CategoryModel.getInstance().getCategory(id3), null); visibleCategory = id3; break; @@ -765,25 +732,7 @@ } } } - if(visibleCategory != null) { - componentsShowing.clear(); - CategoryInfo catInfo = categoryid2jcomponents.get(visibleCategory); - if (catInfo != null) { - for (String key : catInfo.getKeys()) { - if (key.contains(searchText.toUpperCase())) { - ArrayList comps = catInfo.getComponents(key); - if (comps != null) { - for (JComponent comp : comps) { - if(comp.isShowing()) { - componentsShowing.add(comp); - } - } - } - } - } - } - } - if(keymapsSearch != null) { + if (keymapsSearch != null) { keymapsSearch.setText(searchText); } } @@ -800,7 +749,7 @@ @Override public void quickSearchConfirmed() { clearAll(); - } + } @Override public void quickSearchCanceled() { @@ -808,20 +757,25 @@ } private void clearAll() { - for (String category : removedCategories) { - buttons.get(category).setVisible(true); + for (String id : CategoryModel.getInstance().getCategoryIDs()) { + JTabbedPane pane = categoryid2tabbedpane.get(id); + if (categoryid2tabs.get(id) != null) { + HashMap tabsInfo = categoryid2tabs.get(id); + for (Integer tabIndex : tabsInfo.keySet()) { + if(tabIndex != -1) { + pane.setEnabledAt(tabIndex, true); + } + } + } + buttons.get(id).setEnabled(true); } - for (JTabbedPane pane : tabbedpane2removedtabs.keySet()) { - HashMap stuff = tabbedpane2removedtabs.get(pane); - for (Integer index : stuff.keySet()) { - TabInfo stuff2 = stuff.get(index); - pane.insertTab(stuff2.getTabTitle(), null, stuff2.getTab(), null, index); - } - } setCurrentCategory(CategoryModel.getInstance().getCurrent(), null); removedCategories.clear(); tabbedpane2removedtabs.clear(); + if (keymapsSearch != null) { + keymapsSearch.setText(""); + } } }