| /******************************************************************************* |
| * Copyright (c) 2000, 2016 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.help.ui.internal.views; |
| |
| import java.util.ArrayList; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| import org.eclipse.help.HelpSystem; |
| import org.eclipse.help.IHelpResource; |
| import org.eclipse.help.IToc; |
| import org.eclipse.help.internal.base.HelpBasePlugin; |
| import org.eclipse.help.internal.base.IHelpBaseConstants; |
| import org.eclipse.help.search.ISearchEngineResult; |
| import org.eclipse.help.ui.internal.HelpUIResources; |
| import org.eclipse.help.ui.internal.IHelpUIConstants; |
| import org.eclipse.help.ui.internal.Messages; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.IToolBarManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.swt.custom.BusyIndicator; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.ScrollBar; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.actions.ActionFactory; |
| import org.eclipse.ui.forms.AbstractFormPart; |
| import org.eclipse.ui.forms.widgets.FormText; |
| import org.eclipse.ui.forms.widgets.FormToolkit; |
| import org.eclipse.ui.forms.widgets.ScrolledForm; |
| import org.eclipse.ui.forms.widgets.TableWrapData; |
| import org.eclipse.ui.forms.widgets.TableWrapLayout; |
| import org.osgi.service.prefs.BackingStoreException; |
| |
| public class SearchResultsPart extends AbstractFormPart implements IHelpPart { |
| ReusableHelpPart parent; |
| |
| private Composite separator; |
| |
| private Composite container; |
| |
| private ScrolledForm innerForm; |
| |
| private String id; |
| |
| //private Action removeAllAction; |
| |
| private Action showCategoriesAction; |
| |
| private Action showDescriptionAction; |
| |
| private ArrayList<EngineResultSection> results; |
| |
| //private String phrase; |
| |
| private FormToolkit innerToolkit; |
| |
| /** |
| * @param parent |
| * @param toolkit |
| * @param style |
| */ |
| public SearchResultsPart(Composite parent, FormToolkit toolkit, |
| IToolBarManager tbm) { |
| GridLayout layout = new GridLayout(); |
| layout.marginWidth = layout.marginHeight = 0; |
| layout.verticalSpacing = 0; |
| innerToolkit = new FormToolkit(parent.getDisplay()); |
| innerToolkit.getHyperlinkGroup().setHyperlinkUnderlineMode( |
| toolkit.getHyperlinkGroup().getHyperlinkUnderlineMode()); |
| container = innerToolkit.createComposite(parent); |
| container.setLayout(layout); |
| separator = innerToolkit.createCompositeSeparator(container); |
| separator.setVisible(false); |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.heightHint = 1; |
| separator.setLayoutData(gd); |
| innerForm = innerToolkit.createScrolledForm(container); |
| innerForm.setDelayedReflow(true); |
| innerForm.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| final ScrollBar scrollBar = innerForm.getVerticalBar(); |
| scrollBar.addSelectionListener(new SelectionAdapter() { |
| |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| updateSeparatorVisibility(); |
| } |
| }); |
| TableWrapLayout tlayout = new TableWrapLayout(); |
| tlayout.topMargin = 0; |
| tlayout.bottomMargin = 0; |
| innerForm.getBody().setLayout(tlayout); |
| results = new ArrayList<>(); |
| contributeToToolBar(tbm); |
| } |
| |
| void updateSeparatorVisibility() { |
| ScrollBar scrollBar = innerForm.getVerticalBar(); |
| separator.setVisible(scrollBar.getSelection()>0); |
| } |
| |
| private void contributeToToolBar(IToolBarManager tbm) { |
| /* |
| * removeAllAction = new Action() { public void run() { clearResults(); } }; |
| * removeAllAction.setImageDescriptor(HelpUIResources |
| * .getImageDescriptor(IHelpUIConstants.IMAGE_REMOVE_ALL)); |
| * removeAllAction.setToolTipText("Remove all hits"); |
| * removeAllAction.setId("removeAll"); tbm.insertBefore("back", |
| * removeAllAction); tbm.insertAfter("removeAll", new Separator()); |
| */ |
| |
| boolean descOn = Platform.getPreferencesService().getBoolean |
| (HelpBasePlugin.PLUGIN_ID, IHelpBaseConstants.P_KEY_SHOW_SEARCH_DESCRIPTION, false, null); |
| boolean showCategories = Platform.getPreferencesService().getBoolean |
| (HelpBasePlugin.PLUGIN_ID, IHelpBaseConstants.P_KEY_SHOW_SEARCH_CATEGORIES, false, null); |
| showCategoriesAction = new Action() { |
| |
| @Override |
| public void run() { |
| updateResultSections(); |
| IEclipsePreferences pref = InstanceScope.INSTANCE.getNode(HelpBasePlugin.PLUGIN_ID); |
| pref.putBoolean(IHelpBaseConstants.P_KEY_SHOW_SEARCH_CATEGORIES, showCategoriesAction.isChecked()); |
| try { |
| pref.flush(); |
| } catch (BackingStoreException e) { |
| } |
| } |
| }; |
| showCategoriesAction.setImageDescriptor(HelpUIResources |
| .getImageDescriptor(IHelpUIConstants.IMAGE_SHOW_CATEGORIES)); |
| showCategoriesAction.setChecked(showCategories); |
| showCategoriesAction.setToolTipText(Messages.SearchResultsPart_showCategoriesAction_tooltip); |
| showCategoriesAction.setId("categories"); //$NON-NLS-1$ |
| tbm.insertBefore("back", showCategoriesAction); //$NON-NLS-1$ |
| |
| showDescriptionAction = new Action() { |
| |
| @Override |
| public void run() { |
| updateResultSections(); |
| IEclipsePreferences pref = InstanceScope.INSTANCE.getNode(HelpBasePlugin.PLUGIN_ID); |
| pref.putBoolean(IHelpBaseConstants.P_KEY_SHOW_SEARCH_DESCRIPTION, showDescriptionAction.isChecked()); |
| try { |
| pref.flush(); |
| } catch (BackingStoreException e) { |
| } |
| } |
| }; |
| showDescriptionAction.setImageDescriptor(HelpUIResources |
| .getImageDescriptor(IHelpUIConstants.IMAGE_SHOW_DESC)); |
| showDescriptionAction.setChecked(descOn); |
| showDescriptionAction.setToolTipText(Messages.SearchResultsPart_showDescriptionAction_tooltip); |
| showDescriptionAction.setId("description"); //$NON-NLS-1$ |
| tbm.insertAfter("categories", showDescriptionAction); //$NON-NLS-1$ |
| tbm.insertAfter("description", new Separator()); //$NON-NLS-1$ |
| } |
| |
| @Override |
| public void dispose() { |
| innerToolkit.dispose(); |
| super.dispose(); |
| } |
| |
| private void updateResultSections() { |
| BusyIndicator.showWhile(container.getDisplay(), () -> { |
| for (int i = 0; i < results.size(); i++) { |
| EngineResultSection section = results.get(i); |
| section.updateResults(false); |
| } |
| reflow(); |
| }); |
| } |
| |
| boolean getShowCategories() { |
| return showCategoriesAction.isChecked(); |
| } |
| |
| boolean getShowDescription() { |
| return showDescriptionAction.isChecked(); |
| } |
| |
| @Override |
| public Control getControl() { |
| return container; |
| } |
| |
| @Override |
| public void init(ReusableHelpPart parent, String id, IMemento memento) { |
| this.parent = parent; |
| this.id = id; |
| } |
| |
| @Override |
| public String getId() { |
| return id; |
| } |
| |
| @Override |
| public void setVisible(boolean visible) { |
| container.setVisible(visible); |
| } |
| |
| void clearResults() { |
| clearResultSections(); |
| separator.setVisible(false); |
| reflow(); |
| } |
| |
| void clearResultSections() { |
| for (int i = 0; i < results.size(); i++) { |
| EngineResultSection section = results.get(i); |
| section.dispose(); |
| } |
| results.clear(); |
| } |
| |
| void startNewSearch(String phrase, ArrayList<EngineDescriptor> eds) { |
| //this.phrase = phrase; |
| //separator.setVisible(true); |
| // locate local help engine and add it first |
| EngineDescriptor localHelp = findLocalHelp(eds); |
| if (localHelp!=null) |
| add(localHelp); |
| // add engines other than local help |
| for (int i = 0; i < eds.size(); i++) { |
| EngineDescriptor ed = eds.get(i); |
| if (ed==localHelp) |
| continue; |
| add(ed); |
| } |
| reflow(); |
| } |
| |
| private EngineDescriptor findLocalHelp(ArrayList<EngineDescriptor> eds) { |
| for (int i=0; i<eds.size(); i++) { |
| EngineDescriptor ed = eds.get(i); |
| if (ed.getEngineTypeId().equals(IHelpUIConstants.INTERNAL_HELP_ID)) |
| return ed; |
| } |
| return null; |
| } |
| |
| void completed() { |
| for (int i = 0; i < results.size(); i++) { |
| EngineResultSection section = results.get(i); |
| section.completed(); |
| } |
| } |
| |
| void canceling() { |
| for (int i = 0; i < results.size(); i++) { |
| EngineResultSection section = results.get(i); |
| section.canceling(); |
| } |
| } |
| |
| void doOpenLink(Object href) { |
| String url = (String) href; |
| |
| if (url.startsWith("nw:")) { //$NON-NLS-1$ |
| parent.showExternalURL(url.substring(3)); |
| } else |
| parent.showURL(url); |
| } |
| |
| void doCategoryLink(String href) { |
| parent.showPage(IHelpUIConstants.HV_ALL_TOPICS_PAGE); |
| AllTopicsPart part = (AllTopicsPart) parent |
| .findPart(IHelpUIConstants.HV_TOPIC_TREE); |
| if (part != null) { |
| IToc[] tocs = HelpSystem.getTocs(); |
| IHelpResource target = null; |
| for (int i = 0; i < tocs.length; i++) { |
| if (tocs[i].getHref().equals(href)) |
| target = tocs[i]; |
| } |
| if (target != null) { |
| part.selectReveal(target); |
| } |
| } |
| } |
| |
| @Override |
| public boolean fillContextMenu(IMenuManager manager) { |
| Control focusControl = container.getDisplay().getFocusControl(); |
| if (focusControl != null && focusControl instanceof FormText) { |
| return parent.fillFormContextMenu((FormText) focusControl, manager); |
| } |
| return false; |
| } |
| |
| @Override |
| public boolean hasFocusControl(Control control) { |
| for (int i = 0; i < results.size(); i++) { |
| EngineResultSection er = results.get(i); |
| if (er.hasControl(control)) |
| return true; |
| } |
| return false; |
| } |
| |
| public synchronized void add(EngineDescriptor ed, ISearchEngineResult match) { |
| EngineResultSection ers = findEngineResult(ed); |
| if (match != null) |
| ers.add(match); |
| } |
| |
| public synchronized void add(EngineDescriptor ed, |
| ISearchEngineResult[] matches) { |
| EngineResultSection ers = findEngineResult(ed); |
| ers.add(matches); |
| } |
| |
| public synchronized void error(EngineDescriptor ed, IStatus status) { |
| EngineResultSection ers = findEngineResult(ed); |
| ers.error(status); |
| } |
| |
| private synchronized EngineResultSection findEngineResult( |
| EngineDescriptor ed) { |
| for (int i = 0; i < results.size(); i++) { |
| EngineResultSection er = results.get(i); |
| if (er.matches(ed)) |
| return er; |
| } |
| final EngineResultSection er = new EngineResultSection(this, ed); |
| Display display = parent.getForm().getToolkit().getColors() |
| .getDisplay(); |
| display.syncExec(() -> { |
| Control c = er.createControl(innerForm.getBody(), innerToolkit); |
| c.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB)); |
| }); |
| results.add(er); |
| return er; |
| } |
| |
| private void add(EngineDescriptor ed) { |
| final EngineResultSection er = new EngineResultSection(this, ed); |
| Control c = er.createControl(innerForm.getBody(), innerToolkit); |
| c.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB)); |
| results.add(er); |
| } |
| |
| void reflow() { |
| innerForm.reflow(true); |
| parent.reflow(); |
| } |
| |
| @Override |
| public boolean setFormInput(Object input) { |
| return false; |
| } |
| |
| void scrollToBeginning() { |
| innerForm.setOrigin(0, 0); |
| } |
| |
| @Override |
| public IAction getGlobalAction(String id) { |
| if (id.equals(ActionFactory.COPY.getId())) |
| return parent.getCopyAction(); |
| return null; |
| } |
| |
| FormToolkit getToolkit() { |
| return innerToolkit; |
| } |
| |
| @Override |
| public void stop() { |
| } |
| |
| @Override |
| public void toggleRoleFilter() { |
| updateResultSections(); |
| } |
| |
| @Override |
| public void refilter() { |
| updateResultSections(); |
| } |
| |
| @Override |
| public void saveState(IMemento memento) { |
| } |
| } |