/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Icy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Icy. If not, see <http://www.gnu.org/licenses/>. */ package plugins.kernel.searchprovider; import icy.action.ActionManager; import icy.action.IcyAbstractAction; import icy.resource.icon.IcyIcon; import icy.search.SearchResult; import icy.search.SearchResultConsumer; import icy.search.SearchResultProducer; import icy.util.StringUtil; import java.awt.Image; import java.util.ArrayList; import org.pushingpixels.flamingo.api.common.RichTooltip; /** * This class is used to provide kernel command elements to the search engine. * * @author Stephane */ public class KernelSearchResultProducer extends SearchResultProducer { public static class KernelSearchResult extends SearchResult { private final IcyAbstractAction action; private final int priority; private String description; public KernelSearchResult(SearchResultProducer provider, IcyAbstractAction action, String searchWords[], int priority) { super(provider); this.action = action; this.priority = priority; final String longDesc = action.getLongDescription(); if (!StringUtil.isEmpty(longDesc)) { final String[] lds = longDesc.split("\n"); if (lds.length > 0) // no more than 80 characters for description description = StringUtil.limit(lds[0], 80, true); // highlight search keywords (only for more than 2 characters search) if ((searchWords.length > 1) || (searchWords[0].length() > 2)) { // highlight search keywords in description for (String word : searchWords) description = StringUtil.htmlBoldSubstring(description, word, true); } } else description = ""; } public IcyAbstractAction getAction() { return action; } @Override public Image getImage() { final IcyIcon icon = action.getIcon(); if (icon != null) return icon.getImage(); return null; } @Override public String getTitle() { final String desc = action.getDescription(); if (!StringUtil.isEmpty(desc)) return desc; return action.getName(); } @Override public String getDescription() { return description; } @Override public String getTooltip() { if (isEnabled()) return "Click to execute the action"; return "Inactive action"; // return action.getLongDescription(); } @Override public boolean isEnabled() { return action.isEnabled(); } @Override public void execute() { action.execute(); } @Override public RichTooltip getRichToolTip() { final String longDesc = action.getLongDescription(); if (!StringUtil.isEmpty(longDesc)) { if (longDesc.split("\n").length > 1) return action.getRichToolTip(); } return null; } @Override public void executeAlternate() { // nothing to do here... } @Override public int compareTo(SearchResult o) { if (o instanceof KernelSearchResult) return ((KernelSearchResult) o).priority - priority; return super.compareTo(o); } } @Override public int getOrder() { // should be first return 0; } @Override public String getName() { return "Command"; } @Override public String getTooltipText() { return "Result(s) from the internal commands and actions"; } @Override public void doSearch(String[] words, SearchResultConsumer consumer) { if (hasWaitingSearch()) return; final ArrayList<SearchResult> tmpResults = new ArrayList<SearchResult>(); final boolean shortSearch = (words.length == 1) && (words[0].length() <= 2); for (IcyAbstractAction action : ActionManager.actions) { // abort if (hasWaitingSearch()) return; // action match filter final int prio = searchInAction(action, words, shortSearch); if (prio > 0) tmpResults.add(new KernelSearchResult(this, action, words, prio)); } results = tmpResults; consumer.resultsChanged(this); } public static int searchInAction(IcyAbstractAction action, String words[], boolean startWithOnly) { int result = 0; // we accept action which contains all words only for (String word : words) { final int r = searchInAction(action, word, startWithOnly); // word not found ? --> reject if (r == 0) return 0; result += r; } // return mean score return result / words.length; } public static int searchInAction(IcyAbstractAction action, String word, boolean startWithOnly) { final String wordlc = word.trim().toLowerCase(); String text; // text = action.getName(); // if (!StringUtil.isEmpty(text) && text.toLowerCase().startsWith(wordlc)) // return 10; text = action.getDescription(); if (!StringUtil.isEmpty(text) && text.toLowerCase().startsWith(wordlc)) return 8; text = action.getLongDescription(); if (!StringUtil.isEmpty(text) && text.toLowerCase().startsWith(wordlc)) return 5; if (!startWithOnly) { // text = action.getName(); // if (!StringUtil.isEmpty(text) && text.toLowerCase().contains(wordlc)) // return 9; text = action.getDescription(); if (!StringUtil.isEmpty(text) && text.toLowerCase().contains(wordlc)) return 7; text = action.getLongDescription(); if (!StringUtil.isEmpty(text) && text.toLowerCase().contains(wordlc)) return 3; } return 0; } }