/******************************************************************************* * Copyright (c) 2012 xored software, Inc. 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: * xored software, Inc. - initial API and implementation (Yuri Strot) ******************************************************************************/ package com.xored.glance.internal.ui.panels; import com.xored.glance.ui.panels.SearchPanel; import com.xored.glance.ui.sources.Match; import com.xored.glance.ui.utils.UIUtils; import org.eclipse.jface.action.ContributionItem; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.StatusLineLayoutData; import org.eclipse.jface.action.StatusLineManager; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.WorkbenchWindow; import org.eclipse.ui.keys.IBindingService; import org.eclipse.ui.texteditor.IStatusField; import org.eclipse.ui.texteditor.IStatusFieldExtension; /** * @author Yuri Strot */ @SuppressWarnings("restriction") public class SearchStatusLine extends SearchPanel { private class SearchItem extends ContributionItem implements IStatusField, IStatusFieldExtension { @Override public void dispose() { try { fireClose(); } catch (SWTException ex) { // ignore it -- window closing } } @Override public void fill(Composite parent) { Label separator = new Label(parent, SWT.SEPARATOR); createContent(parent); setLayoutData(separator); } public SearchStatusLine getSearchPanel() { return SearchStatusLine.this; } @Override public void setErrorImage(Image image) { setImage(image); } @Override public void setErrorText(String text) { setText(text); } @Override public void setImage(Image image) { } @Override public void setText(String text) { } @Override public void setToolTipText(String string) { setText(string); } } private static final String DEFAULT_MATCH_LABEL = "no matches"; public static SearchStatusLine getSearchLine(IWorkbenchWindow window) { IStatusLineManager manager = getManager(window); if (manager != null) { IContributionItem[] items = manager.getItems(); for (IContributionItem item : items) { if (item instanceof SearchItem) { return ((SearchItem) item).getSearchPanel(); } } } return new SearchStatusLine(window); } public static IWorkbenchWindow getWindow(Control control) { Shell shell = control.getShell(); IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); for (IWorkbenchWindow window : windows) { if (shell.equals(window.getShell())) { return window; } } return null; } private static IStatusLineManager getManager(IWorkbenchWindow window) { if (window != null) { WorkbenchWindow ww = (WorkbenchWindow) window; return ww.getActionBars().getStatusLineManager(); } return null; } private int matchCount; private String matchText = DEFAULT_MATCH_LABEL; private CLabel matchLabel; private int matchIndex; private SearchItem item; private final IWorkbenchWindow window; private SearchStatusLine(IWorkbenchWindow window) { this.window = window; init(); } @Override public void allFound(final Match[] matches) { super.allFound(matches); matchCount = matches.length; updateInfo(); } @Override public void clearStatus() { matchCount = matchIndex = 0; updateInfo(); } @Override public void closePanel() { if (item != null) { fireClose(); IStatusLineManager manager = getManager(); if (manager != null) { manager.remove(item); manager.update(false); } item = null; } } @Override public void createContent(Composite parent) { super.createContent(parent); StatusLineLayoutData data = new StatusLineLayoutData(); data.widthHint = getPreferedWidth(); data.heightHint = getPreferredHeight(); getControl().setLayoutData(data); createMatchLabel(parent); } public IWorkbenchWindow getWindow() { return window; } @Override public boolean isApplicable(Control control) { return window.equals(getWindow(control)); } @Override public void setMatchIndex(int index) { matchIndex = index; updateInfo(); } @Override protected Control createText(Composite parent, int style) { Control textControl = super.createText(parent, style); textControl.addFocusListener(new FocusListener() { @Override public void focusGained(FocusEvent e) { setKeyFilter(false); updateSelection(); } @Override public void focusLost(FocusEvent e) { setKeyFilter(true); } }); textControl.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { setKeyFilter(true); } }); return textControl; } protected void setKeyFilter(boolean enabled) { IBindingService service = (IBindingService) PlatformUI.getWorkbench().getService( IBindingService.class); if (service != null) { service.setKeyFilterEnabled(enabled); } } @Override protected void textEmpty() { super.textEmpty(); matchText = DEFAULT_MATCH_LABEL; matchLabel.setText(matchText); } private void createMatchLabel(Composite parent) { Label separator = new Label(parent, SWT.SEPARATOR); setLayoutData(separator); matchLabel = new CLabel(parent, SWT.SHADOW_NONE); matchLabel.setData("name", "searchStatus"); StatusLineLayoutData data = new StatusLineLayoutData(); data.widthHint = getTextWidth(parent, 10) + 15; data.heightHint = getPreferredHeight(); matchLabel.setLayoutData(data); matchLabel.setText(matchText); } private IStatusLineManager getManager() { return getManager(window); } private void init() { item = new SearchItem(); IStatusLineManager manager = getManager(); if (manager != null) { manager.remove(item); manager.appendToGroup(StatusLineManager.BEGIN_GROUP, item); manager.update(true); } } private void setLayoutData(Label separator) { StatusLineLayoutData data = new StatusLineLayoutData(); data.heightHint = getPreferredHeight(); separator.setLayoutData(data); } private void updateInfo() { StringBuffer buffer = new StringBuffer(); if (matchCount == 0) { buffer.append(DEFAULT_MATCH_LABEL); } else { if (matchIndex > 0) { buffer.append(matchIndex); buffer.append(" / "); } buffer.append(matchCount); } matchText = buffer.toString(); UIUtils.asyncExec(matchLabel, new Runnable() { @Override public void run() { matchLabel.setText(matchText); } }); } }