/* * Copyright 2016 Nokia Solutions and Networks * Licensed under the Apache License, Version 2.0, * see license.txt file for details. */ package org.robotframework.ide.eclipse.main.plugin.tableeditor; import static com.google.common.collect.Lists.newArrayList; import java.util.Collection; import java.util.List; import javax.inject.Inject; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.e4.core.di.annotations.Optional; import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.e4.ui.di.UIEventTopic; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.window.DefaultToolTip; import org.eclipse.jface.window.ToolTip; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; import org.robotframework.ide.eclipse.main.plugin.RedImages; import org.robotframework.red.graphics.ColorsManager; import org.robotframework.red.graphics.ImagesManager; /** * @author Michal Anglart * */ class HeaderFilterSupport { private final Collection<HeaderFilterMatchesCollector> collectors; private Text filter; private Job notifyingJob = null; private final Form form; private final FormToolkit toolkit; private final IEventBroker broker; private final String sectionId; HeaderFilterSupport(final Form form, final FormToolkit toolkit, final IEventBroker broker, final String sectionId, final List<? extends HeaderFilterMatchesCollector> collectors) { this.form = form; this.toolkit = toolkit; this.broker = broker; this.sectionId = sectionId; this.collectors = newArrayList(collectors); } void enableFilter() { filter = toolkit.createText(form.getHead(), ""); filter.setData(FormToolkit.KEY_DRAW_BORDER, Boolean.FALSE); form.setHeadClient(filter); filter.addPaintListener(new PaintListener() { @Override public void paintControl(final PaintEvent e) { if (filter.getText().isEmpty() && !filter.isFocusControl()) { final Color current = e.gc.getForeground(); e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_GRAY)); e.gc.drawText("filter elements", 3, 1); e.gc.setForeground(current); } } }); filter.addModifyListener(new ModifyListener() { @Override public void modifyText(final ModifyEvent e) { if (notifyingJob != null && notifyingJob.getState() == Job.SLEEPING) { notifyingJob.cancel(); } form.setBusy(true); notifyingJob = new Job("filtering section") { @Override protected IStatus run(final IProgressMonitor monitor) { filter.getDisplay().syncExec(new Runnable() { @Override public void run() { HeaderFilterMatchesCollection matches = null; if (!filter.getText().isEmpty()) { matches = new HeaderFilterMatchesCollection(collectors); for (final HeaderFilterMatchesCollector collector : collectors) { matches.addAll(collector.collectMatches(filter.getText())); } } showProperTooltip(matches); if (matches == null) { broker.send( RobotSuiteEditorEvents.SECTION_FILTERING_DISABLED_TOPIC + "/" + sectionId, collectors); } else { broker.send( RobotSuiteEditorEvents.SECTION_FILTERING_ENABLED_TOPIC + "/" + sectionId, matches); } } }); monitor.done(); return Status.OK_STATUS; } }; notifyingJob.addJobChangeListener(new JobChangeAdapter() { @Override public void done(final IJobChangeEvent event) { form.setBusy(false); } }); notifyingJob.schedule(350); } }); } private void showProperTooltip(final HeaderFilterMatchesCollection matches) { final DefaultToolTip filterTip = new DefaultToolTip(filter, ToolTip.RECREATE, true); if (matches != null) { final int allMatches = matches.getNumberOfAllMatches(); final int rowsMatching = matches.getNumberOfMatchingElement(); final String elementForm = rowsMatching == 1 ? "element" : "elements"; filterTip.setText("Filtering on: found " + allMatches + " match in " + rowsMatching + " " + elementForm); final Color filterSuccessFg = ColorsManager.getColor(0, 200, 0); final Color filterFailureFg = ColorsManager.getColor(255, 0, 0); filter.setForeground(allMatches == 0 ? filterFailureFg : filterSuccessFg); if (form.getMessage() == null) { form.setMessage("Filtering is enabled", IMessageProvider.INFORMATION); } } else { if (form.getMessage() != null && form.getMessage().startsWith("Filtering")) { form.setMessage(null); } filterTip.setText("Filtering off"); } filterTip.setHideDelay(3000); filterTip.setImage(ImagesManager.getImage(RedImages.getFilterImage())); filterTip.show(new Point(0, filter.getSize().y)); } void disableFilter() { filter.dispose(); filter = null; form.setHeadClient(null); broker.send(RobotSuiteEditorEvents.SECTION_FILTERING_DISABLED_TOPIC + "/" + sectionId, collectors); } void addFormMessageIfNeeded() { if (filter != null && !filter.getText().isEmpty() && form.getMessage() == null) { form.setMessage("Filtering is enabled", IMessageProvider.INFORMATION); } } @Inject @Optional private void whenUserRequestedFilterSwitch( @UIEventTopic(RobotSuiteEditorEvents.FORM_FILTER_SWITCH_REQUEST) final FilterSwitchRequest request) throws InterruptedException { if (request.getId().equals(sectionId)) { filter.setText(request.getNewFilter()); if (notifyingJob != null) { notifyingJob.join(); } } } }