/* * Copyright 2003-2010 Tufts University Licensed under the * Educational Community License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. */ package tufts.vue; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.util.Collections; import java.util.List; import javax.swing.JCheckBoxMenuItem; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTextField; import javax.swing.ButtonGroup; import tufts.Util; import tufts.vue.gui.GUI; import edu.tufts.vue.metadata.VueMetadataElement; import edu.tufts.vue.metadata.action.SearchAction; import edu.tufts.vue.metadata.action.SearchAction.SearchType; import static edu.tufts.vue.metadata.action.SearchAction.*; // TODO: THIS SHOULD IGNORE SEARCH-PANEL SEARCH DOMAIN -- always do current map // TODO: DECOUPLE ENTIRELY FROM SEARCH PANEL -- either only allow select, or perhaps select/hide // Would be nice to have SearchBox that includes a SearchTextField + indeterminate progress bar. // public class SearchTextField extends javax.swing.JPanel { @SuppressWarnings("serial") public class SearchTextField extends JTextField implements FocusListener { private static final org.apache.log4j.Logger Log = org.apache.log4j.Logger.getLogger(SearchTextField.class); // "MetadataSearchMainGUI" directly modifies the selected status of these check boxes, // which is why they're public static. Would be better to handle via some kind of posted events. public static JMenuItem searcheveryWhereMenuItem; public static JMenuItem labelMenuItem; public static JMenuItem keywordMenuItem; public static JMenuItem categoriesMenuItem; public static JMenuItem categoryKeywordMenuItem; public static JMenuItem editSettingsMenuItem; private static final boolean CATEGORIES_ALONE_OPTION = false; private final boolean isWindows = VueUtil.isWindowsPlatform(); private static JPopupMenu popup; private static JPopupMenu editPopup; /** We keep a self reference to JTextField because we've been playing with * subclassing JPanel instead of JTextField */ private final JTextField textField; //private final JTextField textField = new JTextField(); //private final JProgressBar progress = new JProgressBar(); private JTextField subTextField; // an unxeplained hack... used in OSX Tiger, Windows? /** a hack to create an a smaller input area leaving room for a Mac-like spyglass icon */ private JTextField inputField; private boolean mouse_over = false; private static final String SEARCH_WORD = VueResources.local("search.popup.search"); private static final String _DEFAULT_TEXT = VueResources.local("search.text.default"); private String DEFAULT_TEXT = _DEFAULT_TEXT; private static String MINIMUM_TEXT = ""; private static SearchTextField Singleton; private boolean inUpdate = false; private static final boolean DRAW_OVER_STATUS = true; // NOTE: this class is used as a singleton: should force that on instancing, // or better yet, make it multiply instanceable. SearchTextField() { // super(VueResources.local("search.text.default"),15); //super(11); textField = this; //add(textField); //add(progress); GUI.init(); initMenuSettings(); if (isWindows) { initForPlatformWindows(); } else { if (Util.isMacTiger()) { initForPlatformMacTiger(); } else { initForPlatformMacLeopardAndLater(); } } if (!DRAW_OVER_STATUS) { inputField.setText(DEFAULT_TEXT); inputField.setForeground(Color.gray); } else { inputField.setText(MINIMUM_TEXT); } if (!DRAW_OVER_STATUS || Util.isMacTiger() || isWindows) inputField.addFocusListener(this); // progress.setIndeterminate(true); // progress.putClientProperty("JProgressBar.style", "circular"); // progress.setBorderPainted(false); // progress.setVisible(false); Singleton = this; } protected void setCursor(int cursorState) { textField.setCursor(new Cursor(cursorState)); } private static final boolean SUB_TEXT_HACK = false; public String getText() { return getRawText().trim(); } public boolean hasInput() { return getForeground().equals(Color.black) && getText().length() > 0; } private String getRawText() { if (inputField == this) return super.getText(); else return inputField.getText(); } private void resetForInput() { // Clear friendly gray reminder note, get ready for input: inputField.setText(MINIMUM_TEXT); if (!DRAW_OVER_STATUS) inputField.setForeground(Color.black); } /** FocusListener -- only used in certain cases */ public void focusGained(FocusEvent e) { if (DEBUG.FOCUS || DEBUG.SEARCH) Log.debug("focusGained " + GUI.name(e)); // BUG: if we're getting focus back from the pop-up menu, we DON'T want to do this // Apparently we can actually get the focusGained event BEFORE the menu action is run... if (getForeground().equals(Color.gray)) { resetForInput(); } } /** FocusListener -- only used in certain cases */ public void focusLost(FocusEvent e) { if (DEBUG.FOCUS || DEBUG.SEARCH) Log.debug("focusLost.. " + GUI.name(e)); // BUG: if we're losing focus to the pop-up menu, we may not want to do this... if (getText().length() <= 0) { if (DRAW_OVER_STATUS) { resetForInput(); } else { inputField.setForeground(Color.gray); updateMessage("focusLost"); } } } private String getStatusMessage() { final JMenuItem searchType = getSelectedSearchTypeMenuItem(); if (searchType == searcheveryWhereMenuItem) return DEFAULT_TEXT; else return SEARCH_WORD + " " + searchType.getLabel(); } private void updateMessage(String src) { if (DEBUG.SEARCH) Log.debug("updateMessage src=" + src + "; inUpdate=" + inUpdate); if (!inUpdate) { if (DRAW_OVER_STATUS) repaint(); // display via draw-over -- better as hides the 'x' button else inputField.setText(getStatusMessage()); // display via input text } } public static void updateSearchType() { if (!Singleton.hasInput()) Singleton.updateMessage("remoteUpdate"); } private JMenuItem getSelectedSearchTypeMenuItem() { if (searcheveryWhereMenuItem.isSelected()) return searcheveryWhereMenuItem; else if (labelMenuItem.isSelected()) return labelMenuItem; else if (keywordMenuItem.isSelected()) return keywordMenuItem; else if (categoriesMenuItem.isSelected()) return categoriesMenuItem; else if (categoryKeywordMenuItem.isSelected()) return categoryKeywordMenuItem; else return searcheveryWhereMenuItem; } private final KeyListener SearchKeyListener = new KeyAdapter() { public void keyPressed(KeyEvent ke) { if (ke.getKeyCode() == KeyEvent.VK_ENTER) { // It's important to handle this on keyPressed and NOT keyReleased, // and to consume the event, otherwise it can be passed up to the menu // and used to activate a label edit ("Rename" action) if a single // node happens to be selected on the map. ke.consume(); runConfiguredSearch(); } } }; private void runConfiguredSearch() { if (labelMenuItem.isSelected()) runSearch(SEARCH_ONLY_LABELS); else if (keywordMenuItem.isSelected()) runSearch(SEARCH_ONLY_KEYWORDS); else runSearch(SEARCH_EVERYTHING); // } else if (categoriesMenuItem.isSelected()) { setCategorySettingsAction(); // } else if (categoryKeywordMenuItem.isSelected()) { setKeywordCategorySettingsAction(); // } else { setSearchEverywhereAction(); } // //else if(editSettingsMenuItem.isSelected()){ // //setEditSettingsAction(); } } private final MouseAdapter MacMouseListener = new MouseAdapter() { public void mousePressed(MouseEvent e) { evalPopup(e); } public void mouseReleased(MouseEvent e) { evalPopup(e); } private void evalPopup(MouseEvent e) { if (e.isPopupTrigger()) popup.show(e.getComponent(), e.getX(), e.getY()); // This is pre DRAW_OVER_STATUS code now handled via FocusEvent's: // else if (getRawText().equals(DEFAULT_TEXT)) { // // Clear friendly gray reminder note, get ready for input: // inputField.setText(MINIMUM_TEXT); // inputField.setForeground(Color.black); // } } }; // comment out old code: at bottom 2012-06-12 19:42.20 Tuesday SFAir.local private void initForPlatformMacTiger() { createPopupMenu(isWindows); textField.setColumns(15); MINIMUM_TEXT = " "; // leave room for the manual spyglass if (!DRAW_OVER_STATUS) DEFAULT_TEXT = MINIMUM_TEXT + DEFAULT_TEXT; if (SUB_TEXT_HACK) { textField.setText(""); subTextField = new JTextField(22); subTextField.setBorder(null); subTextField.setText(DEFAULT_TEXT); subTextField.setForeground(Color.gray); inputField = subTextField; } else { //textField.setText(DEFAULT_TIGER_TEXT); // "indent" over the search icon inputField = textField; // Insets insets = new Insets(50, 5, 5, 50); // textField.setMargin(insets); } inputField.addMouseListener(MacMouseListener); inputField.addKeyListener(SearchKeyListener); if (SUB_TEXT_HACK) { textField.setEditable(false); textField.setLayout(new FlowLayout(FlowLayout.CENTER, 1, 0)); textField.add(subTextField, BorderLayout.CENTER); } } private void initForPlatformMacLeopardAndLater() { textField.setEditable(true); this.inputField = this.textField; // search variant width will twiggle around if we don't set colums to something // (any value will apparently do) textField.setColumns(12); this.inputField = this.textField; // Appear to be ignored when using JTextField.variant=search: // Insets noInsets = new Insets(0, 30, 0, 25); // textField.setMargin(noInsets); createPopupMenu(isWindows); textField.putClientProperty("JTextField.variant", "search"); textField.putClientProperty("JTextField.Search.FindPopup", this.popup); // use JTextField.Search.FindAction for an action instead of a pop-up when the spyglass is clicked // (e.g., re-run the search) textField.putClientProperty("JTextField.Search.CancelAction", new ActionListener() { public void actionPerformed(ActionEvent e) { setResetSettingsAction(); } }); textField.addMouseListener(MacMouseListener); textField.addKeyListener(SearchKeyListener); } private synchronized void initForPlatformWindows() { textField.setEditable(true); this.inputField = this.textField; subTextField = new JTextField(); subTextField.setBorder(null); subTextField.setText(VueResources.local("search.text.default")); subTextField.setForeground(Color.gray); subTextField.setPreferredSize(new Dimension(135,18)); textField.setPreferredSize(new Dimension(180,23)); // TODO FIX HARDCODE SIZE Insets noInsets = new Insets(0, 15, 0, 25); textField.setMargin(noInsets); subTextField.addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { mouse_over = false; textField.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); textField.repaint(); textField.revalidate(); } public void mouseExited(MouseEvent e) { mouse_over = false; textField.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); textField.repaint(); textField.revalidate(); } public void mouseClicked(MouseEvent e) { if (subTextField.getText().trim().equals(VueResources.local("search.text.default"))) { subTextField.setText(""); subTextField.setForeground(Color.black); } } public void mouseReleased(MouseEvent e) { // if (subTextField.getText().trim().equals( // VueResources.local("search.text.default"))) { // setText(""); // } if (e.isPopupTrigger()) { createEditPopupMenu(); editPopup.show(e.getComponent(), e.getX() + 5, e .getY()); } } }); textField.addMouseListener(new MouseAdapter() { public void mouseEntered(MouseEvent e) { if ((e.getX() < 23)) { mouse_over = false; textField.setCursor(Cursor .getPredefinedCursor(Cursor.DEFAULT_CURSOR)); textField.repaint(); textField.revalidate(); } /*else if (e.getX() < getWidth() - 23) { System.err.println("1"); mouse_over = false; setCursor(Cursor .getPredefinedCursor(Cursor.TEXT_CURSOR)); repaint(); revalidate(); }*/ else { mouse_over = true; textField.setCursor(Cursor .getPredefinedCursor(Cursor.DEFAULT_CURSOR)); textField.repaint(); textField.revalidate(); } } public void mouseExited(MouseEvent e) { if ((e.getX() < 23)) { mouse_over = false; textField.setCursor(Cursor .getPredefinedCursor(Cursor.DEFAULT_CURSOR)); textField.repaint(); textField.revalidate(); } else if (e.getX() < textField.getWidth() - 23) { mouse_over = false; textField.setCursor(Cursor .getPredefinedCursor(Cursor.TEXT_CURSOR)); textField.repaint(); textField.revalidate(); } else { mouse_over = false; textField.setCursor(Cursor .getPredefinedCursor(Cursor.DEFAULT_CURSOR)); textField.repaint(); textField.revalidate(); } } public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { if ((e.getX() < 23)) { } else if (e.getX() < textField.getWidth() - 23) { createEditPopupMenu(); editPopup.show(e.getComponent(), e.getX() + 5, e .getY()); } else { } } if ((e.getX() < 23)) { createPopupMenu(isWindows); popup.show(e.getComponent(), e.getX() + 5, e.getY()); } else if (e.getX() < textField.getWidth() - 23) { if (getText().trim().equals( VueResources.local("search.text.default"))) { setText(""); textField.setForeground(Color.black); } } else { if (DEBUG.Enabled) Log.debug("Windows attempting to launch actions separately", new Throwable("HERE")); if (searcheveryWhereMenuItem.isSelected()) { setSearchEverywhereAction(); }/* * else if(editSettingsMenuItem.isSelected()){ * setEditSettingsAction(); } */else if (labelMenuItem.isSelected()) { setLabelSettingsAction(); } else if (keywordMenuItem.isSelected()) { setKeywordSettingsAction(); } else if (categoryKeywordMenuItem.isSelected()) { setKeywordCategorySettingsAction(); } else if (categoriesMenuItem.isSelected()) { setCategorySettingsAction(); } else { setSearchEverywhereAction(); } } } }); subTextField.addKeyListener(SearchKeyListener); textField.setEnabled(true); textField.setLayout(new BorderLayout()); //subTextField.setSize(textField.getSize()); textField.add(subTextField, BorderLayout.CENTER); } private JMenuItem makeCheck(String key) { return makeCheck(key, VueResources.local(key)); } private JMenuItem makeCheck(String key, String label) { final JMenuItem item = new JCheckBoxMenuItem(label); item.setActionCommand(key); // if (actionListener != null) // item.addActionListener(actionListener); return item; } private void initMenuSettings() { // searcheveryWhereMenuItem = new JCheckBoxMenuItem(VueResources.local("search.popup.searcheverywhere"), true); // labelMenuItem = new JCheckBoxMenuItem(VueResources.local("search.popup.labels")); // keywordMenuItem = new JCheckBoxMenuItem(VueResources.local("search.popup.keywords")); // categoriesMenuItem = new JCheckBoxMenuItem(VueResources.local("search.popup.categories")); // categoryKeywordMenuItem = new JCheckBoxMenuItem(VueResources.local("search.popup.categories") // + " + " // + VueResources.local("search.popup.keywords")); // editSettingsMenuItem = new JCheckBoxMenuItem(VueResources.local("search.popup.edit.search.settings")); searcheveryWhereMenuItem = makeCheck("search.popup.searcheverywhere"); labelMenuItem = makeCheck("search.popup.labels"); keywordMenuItem = makeCheck("search.popup.keywords"); categoriesMenuItem = makeCheck("search.popup.categories"); categoryKeywordMenuItem = makeCheck("searchgui.categories_keywords"); // MAKES NO SENSE W/OUT UI FOR IT // searchgui.* property key: would better to have one set of property keys for this and MetadaataSearchMainGUI.java editSettingsMenuItem = makeCheck("search.popup.edit.search.settings"); // note this one is NOT part of the group below searcheveryWhereMenuItem.setSelected(true); final ButtonGroup exclusives = new ButtonGroup(); exclusives.add(searcheveryWhereMenuItem); exclusives.add(labelMenuItem); exclusives.add(keywordMenuItem); exclusives.add(categoriesMenuItem); //exclusives.add(categoryKeywordMenuItem); // MAKES NO SENSE W/OUT UI FOR IT } private JMenuItem popAdd(ActionListener actionListener, String key) { return popAdd(actionListener, new JMenuItem(VueResources.local(key)), key); // final JMenuItem item = new JMenuItem(VueResources.local(key)); // item.setActionCommand(key); // if (actionListener != null) // item.addActionListener(actionListener); // this.popup.add(item); // return item; } private JMenuItem popAdd(ActionListener actionListener, JMenuItem item, String key) { item.setActionCommand(key); if (actionListener != null) item.addActionListener(actionListener); this.popup.add(item); return item; } /** * This method is for Generating Popup menu * * @param isWindow */ private void createPopupMenu(boolean isWindows) { if (this.popup != null) return; this.popup = new JPopupMenu(); final ActionListener actionListener = new PopupActionListener(); final ActionListener al = actionListener; popAdd(al, "search.popup.search").setEnabled(false); searcheveryWhereMenuItem.addActionListener(actionListener); labelMenuItem.addActionListener(actionListener); keywordMenuItem.addActionListener(actionListener); categoryKeywordMenuItem.addActionListener(actionListener); editSettingsMenuItem.addActionListener(actionListener); popup.add(searcheveryWhereMenuItem); popup.add(labelMenuItem); popup.add(keywordMenuItem); if (CATEGORIES_ALONE_OPTION) { categoriesMenuItem.addActionListener(actionListener); popup.add(categoriesMenuItem); } // popup.add(categoryKeywordMenuItem); popup.addSeparator(); popup.add(editSettingsMenuItem); if (!isWindows) { popup.addSeparator(); popAdd(al, "search.popup.clear"); popAdd(al, "search.popup.reset"); popAdd(al, "search.popup.select.all"); popAdd(al, "search.popup.cut"); // cutMenuItem.setActionCommand(DefaultEditorKit.cutAction); popAdd(al, "search.popup.copy"); // copyMenuItem.setActionCommand(DefaultEditorKit.copyAction); popAdd(al, "search.popup.paste"); // pasteMenuItem.setActionCommand(DefaultEditorKit.pasteAction); } } class PopupActionListener implements ActionListener { // TODO: would be cleaner to handle theses via separate actions public void actionPerformed(ActionEvent actionEvent) { final String action = actionEvent.getActionCommand(); if (DEBUG.SEARCH || DEBUG.FOCUS) Log.debug("actionPerformed " + GUI.name(actionEvent)); if ("search.popup.select.all".equals(action)) { inputField.grabFocus(); inputField.selectAll(); } else if ("search.popup.cut".equals(action)) { inputField.cut(); } else if ("search.popup.copy".equals(action)) { inputField.copy(); } else if ("search.popup.paste".equals(action)) { if (!hasInput()) resetForInput(); // be sure to first clear any grey messaging inputField.paste(); runConfiguredSearch(); } else if ("search.popup.clear".equals(action)) { inputField.setText(MINIMUM_TEXT); } else if ("search.popup.searcheverywhere".equals(action)) { setSearchEverywhereAction(); } else if ("search.popup.edit.search.settings".equals(action)) { setEditSettingsAction(); } else if ("search.popup.labels".equals(action)) { setLabelSettingsAction(); } else if ("search.popup.keywords".equals(action)) { setKeywordSettingsAction(); } else if ("search.popup.reset".equals(action)) { setResetSettingsAction(); } else if ("search.popup.categories".equals(action)) { setCategorySettingsAction(); } else if ("searchgui.categories_keywords".equals(action)) { setKeywordCategorySettingsAction(); } } } public void setResetSettingsAction() { //searcheveryWhereMenuItem.setSelected(true); searcheveryWhereMenuItem.setSelected(false); keywordMenuItem.setSelected(false); categoriesMenuItem.setSelected(false); categoryKeywordMenuItem.setSelected(false); labelMenuItem.setSelected(false); editSettingsMenuItem.setSelected(false); //VUE.getMetadataSearchMainGUI().setVisible(false); // resetSettingsMenuItem.setSelected(true); SearchAction.revertGlobalSearchSelectionFromMSGUI(); VUE.getActiveViewer().repaint(); } // private static final int S_DEFAULT = 0x0; // private static final int S_BASIC = 0x1; // private static final int S_TEXT_ONLY = 0x2; // private static final int S_META_ONLY = 0x4; // private static final int S_EVERYTHING = 0x8; // private static final int S_NONE_IS_SPECIAL = 0x16; // refers to #none in VueTermOntologyNone private void fireSearch(SearchType domain) { if (DEBUG.Enabled) Log.debug("fireSearch: " + Util.tags(domain)); //editSettingsMenuItem.setSelected(false); // resetSettingsMenuItem.setSelected(false); final VueMetadataElement vme = new VueMetadataElement(); final String genericSearchStatement[] = { edu.tufts.vue.rdf.RDFIndex.VueTermOntologyNone, /* i.e.: http://vue.tufts.edu/vue.rdfs#none */ getText(), edu.tufts.vue.rdf.Query.Qualifier.CONTAINS.toString() }; vme.setObject(genericSearchStatement); // why does VME enclose a search type? // Note: VME will have set itself type CATEGORY when passing String[] to // setObject -- be sure to reset to SEARCH_STATEMENT *after* this. vme.setType(VueMetadataElement.SEARCH_STATEMENT); // Note, however, SEARCH_STATEMENT doesnt appear as a condition case in codebase -- must be a default? if (DEBUG.SEARCH) Log.debug("Search term: " + vme); final List<VueMetadataElement> searchTerms = Collections.singletonList(vme); final SearchAction search = new SearchAction(searchTerms); search.setParamsByType(domain); // search.setBasic (0 != (flags & S_BASIC)); // search.setTextOnly (0 != (flags & S_TEXT_ONLY)); // search.setMetadataOnly (0 != (flags & S_META_ONLY)); // search.setEverything (0 != (flags & S_EVERYTHING)); // search.setNoneIsSpecial (0 != (flags & S_NONE_IS_SPECIAL)); // refers to #none in VueTermOntologyNone //search.setOperator(VUE.getMetadataSearchMainPanel().getSelectedOperator()); // we only have a single term -- operator shouldn't matter, but in SearchAction, // AND works with single query, OR with a query list (???) //search.setOperator(SearchAction.AND); // // TODO: do we really want to turn this off completely? // if (VUE.getMetadataSearchMainPanel() != null) // initFromGUI(search); // else: ONLY ALLOW SELECT FOR NOW search.setResultAction(SearchAction.RA_SELECT); search.fire(this, getClass().getName()); //progress.setVisible(false); } /* private void initFromGUI(SearchAction termsAction) { // Only ever search the currently active map when using the search field // Not working? Is this being pulled from elsewhere? termsAction.setLocationType(SearchAction.SEARCH_SELECTED_MAP); // Only ever search the currently active map when using the search field // if (VUE.getMetadataSearchMainPanel().mapCmbBox != null && // VUE.getMetadataSearchMainPanel().mapCmbBox.getSelectedItem() != null && // VUE.getMetadataSearchMainPanel().mapCmbBox.getSelectedItem().toString().trim().equals // (VUE.getMetadataSearchMainPanel().ALL_MAPS_STRING)) { // termsAction.setLocationType(SearchAction.SEARCH_ALL_OPEN_MAPS); // } else { // termsAction.setLocationType(SearchAction.SEARCH_SELECTED_MAP); // } final javax.swing.JComboBox resultChoice = VUE.getMetadataSearchMainPanel().resultCmbBox; if (resultChoice != null && resultChoice.getSelectedItem() != null) { // Perhaps also only allow the "select" type? //Log.info("GSE: " + GUI.name(resultChoice.getSelectedItem())); termsAction.setResultAction(resultChoice.getSelectedItem()); } else { // holy christ -- old code using the string "Select" wouldn't // have worked in any other languages! termsAction.setResultAction(SearchAction.RA_SELECT); } } */ private void updateMetaDataGUI(SearchType domain) { if (DEBUG.Enabled) Log.debug("no longer syncing search-fields type with crap-tastic MetadataSearchMainGUI; domain=" +domain); // //VUE.getMetadataSearchMainGUI().setVisible(false); // if (typeKey != null) { // inUpdate = true; // try { // VUE.getMetadataSearchMainPanel().searchTypeCmbBox // .setSelectedItem(VueResources.local(typeKey)); // } catch (Exception e) { // Log.debug("MetaDataGUI update", e); // } finally { // inUpdate = false; // } // } } // /** set the given search type, and possibly launch / re-launch a search if there's currenlty valid input */ // private void setSearchTypeAndGo(String typeKey, int flags) { // if (DRAW_OVER_STATUS) // repaint(); // updateMetaDataGUI(typeKey); // if (hasInput()) // kickOffSearch(typeKey, flags); // } /** run the given search type */ private void runSearch(SearchType domain) { if (DRAW_OVER_STATUS) repaint(); updateMetaDataGUI(domain); if (hasInput()) fireSearch(domain); } private void setSearchEverywhereAction() { runSearch(SEARCH_EVERYTHING); } private void setLabelSettingsAction() { runSearch(SEARCH_ONLY_LABELS); } private void setKeywordSettingsAction() { runSearch(SEARCH_ONLY_KEYWORDS); } private void setKeywordCategorySettingsAction() { runSearch(SEARCH_WITH_CATEGORIES); } private void setCategorySettingsAction() { Log.warn("category-only style search no longer supported"); runSearch(SEARCH_WITH_CATEGORIES); //categoriesMenuItem.setSelected(true); //setSearchTypeAndGo(null, S_NONE_IS_SPECIAL); // Old code didn't set have a resource key, so passing null. } // private void setKeywordCategorySettingsAction() { // //categoryKeywordMenuItem.setSelected(true); // setSearchTypeAndGo("searchgui.categories_keywords", S_DEFAULT);} // private void setKeywordSettingsAction() { // //keywordMenuItem.setSelected(true); // setSearchTypeAndGo("searchgui.keywords", S_TEXT_ONLY | S_META_ONLY); /* badly named flags!*/} // private void setLabelSettingsAction() { // //labelMenuItem.setSelected(true); // setSearchTypeAndGo("searchgui.labels", S_BASIC);} // private void setSearchEverywhereAction() { // //searcheveryWhereMenuItem.setSelected(true); // setSearchTypeAndGo("searchgui.searcheverything", S_TEXT_ONLY);} // private void setCategorySettingsAction() { // //categoriesMenuItem.setSelected(true); // setSearchTypeAndGo(null, S_NONE_IS_SPECIAL); /* Old code didn't set have a resource key, so passing null.*/ } private void setEditSettingsAction() { // searcheveryWhereMenuItem.setSelected(false); // keywordMenuItem.setSelected(false); // categoriesMenuItem.setSelected(false); // categoryKeywordMenuItem.setSelected(false); // labelMenuItem.setSelected(false); if (editSettingsMenuItem.isSelected()) { VUE.getMetadataSearchMainGUI().setVisible(true); } else { VUE.getMetadataSearchMainGUI().setVisible(false); } // resetSettingsMenuItem.setSelected(false); } private void createEditPopupMenu() { if (editPopup == null) { editPopup = new JPopupMenu(); ActionListener actionListener = new PopupActionListener(); JMenuItem clearMenuItem = new JMenuItem(VueResources.local("search.popup.clear")); clearMenuItem.addActionListener(actionListener); editPopup.add(clearMenuItem); JMenuItem resetSettingsMenuItem = new JMenuItem(VueResources.local("search.popup.reset")); resetSettingsMenuItem.addActionListener(actionListener); editPopup.add(resetSettingsMenuItem); JMenuItem selectMenuItem = new JMenuItem(VueResources.local("search.popup.select.all")); selectMenuItem.addActionListener(actionListener); editPopup.add(selectMenuItem); JMenuItem cutMenuItem = new JMenuItem(VueResources.local("search.popup.cut")); cutMenuItem.addActionListener(actionListener); // cutMenuItem.setActionCommand(DefaultEditorKit.cutAction); editPopup.add(cutMenuItem); JMenuItem copyMenuItem = new JMenuItem(VueResources.local("search.popup.copy")); copyMenuItem.addActionListener(actionListener); // copyMenuItem.setActionCommand(DefaultEditorKit.copyAction); editPopup.add(copyMenuItem); JMenuItem pasteMenuItem = new JMenuItem(VueResources.local("search.popup.paste")); pasteMenuItem.addActionListener(actionListener); // pasteMenuItem.setActionCommand(DefaultEditorKit.pasteAction); editPopup.add(pasteMenuItem); } } private static final Image arrowImg = VueResources.getImage("search.downarrowicon"); private static final Image clearImg = VueResources.getImage("search.closeicon"); private static final Image searchImg = VueResources.getImage("search.searchicon"); private static final Image searchOVImg = VueResources.getImage("search.searchicon.ov"); private static final Image searchTigerImg = VueResources.getImage("search.tiger.searchicon"); // Image searchTigerImgOv = // VueResources.getImageIcon("search.tiger.searchicon.ov").getImage(); // Image clearImgOv = // VueResources.getImageIcon("search.closeicon.ov").getImage(); protected void paintComponent(Graphics g) { // Paint the default look of the button. super.paintComponent(g); int statusOffsetX = 31; // Good on Mac Leopard + later if (isWindows) { final int h = textField.getHeight(); final int w = textField.getWidth(); final int arrowWidth = arrowImg.getWidth(null); g.drawImage(arrowImg, 5, h / 2 - 5, arrowWidth, arrowImg.getHeight(null), this); if (!mouse_over) { g.drawImage(searchImg, w - 20, h / 2 - 8, searchImg.getWidth(null), searchImg.getHeight(null), this); } else { g.drawImage(searchOVImg, w - 20, h / 2 - 8, searchOVImg.getWidth(null), searchOVImg.getHeight(null), this); } // TODO: need to check and tweak statusOffsetX for Windows -- SMF 2012-06-13 statusOffsetX = 5 + arrowWidth + 3; } else if (Util.isMacTiger()) { final int h = textField.getHeight(); final int w = textField.getWidth(); final int indent = 6; final int spyglassWidth = searchTigerImg.getWidth(null); final int spyglassHeight = searchTigerImg.getHeight(null); g.drawImage(searchTigerImg, indent, h / 2 - 8, spyglassWidth, spyglassHeight, this); if (false && hasInput()) { // disabled for now -- no mouse listener for this // draw the 'x' cancel search button g.drawImage(clearImg, w - 20, h / 2 - 8, clearImg.getWidth(null), clearImg.getHeight(null), this); } statusOffsetX = indent + spyglassWidth + 3; //statusOffsetX = indent + 2; // if(mouse_over){ // g.drawImage(searchTigerImgOv,5,h/2-7, // searchTigerImg.getWidth(null) , // searchTigerImg.getHeight(null), this); // g.drawImage(clearImg,w-20,h/2-8, clearImg.getWidth(null) , // clearImg.getHeight(null), this); // }else{ // g.drawImage(searchTigerImg,5,h/2-7, // searchTigerImg.getWidth(null) , // searchTigerImg.getHeight(null), this); // g.drawImage(clearImg,w-20,h/2-8, clearImg.getWidth(null) , // clearImg.getHeight(null), this); } if (DRAW_OVER_STATUS && !hasFocus() && !hasInput()) { // We rely on the appropriate font having already been set in super.paintComponent // This is a better method of displaying the status as w/out text in the // the actual field, the 'x' button will hide in the Mac OS X search text variant. g.setColor(Color.gray); g.drawString(getStatusMessage(), statusOffsetX, 19); // todo: ideally set clip region at right so can never drow over the right // border -- a rare case that can happen with a narrow main window. } } } // paste out comments from above 2012-06-12 19:42.39 Tuesday SFAir.local: // addMouseListener(new MouseAdapter() { // public void mouseEntered(MouseEvent e){ // if((e.getX()< 23) ){ // mouse_over = true; // repaint(); // }else if(e.getX() < getWidth()-23){ // mouse_over = false; // repaint(); // }else{ // mouse_over = false; // repaint(); // } // } // public void mouseExited(MouseEvent e){ // if((e.getX()< 23) ){ // mouse_over = false; // repaint(); // }else if(e.getX() < getWidth()-23){ // mouse_over = false; // repaint(); // }else{ // mouse_over = false; // repaint(); // } // } // // });