blob: c0dbf77811264df400fbda058a5e3523923403bb [file] [log] [blame]
/*******************************************************************************
* 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) {
}
}