Java tutorial
/******************************************************************************* * Copyright (c) 2004, 2009 Jingwen Ou 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: * Jingwen Ou - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.internal.sandbox.ui.editors; import java.util.ArrayList; import java.util.List; import java.util.Set; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ControlContribution; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.FindReplaceDocumentAdapter; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.TextViewer; import org.eclipse.mylyn.commons.ui.CommonImages; import org.eclipse.mylyn.commons.workbench.editors.CommonTextSupport; import org.eclipse.mylyn.commons.workbench.forms.CommonFormUtil; import org.eclipse.mylyn.internal.bugzilla.ui.editor.BugzillaTaskEditorPage; import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPage; import org.eclipse.mylyn.tasks.ui.editors.AbstractTaskEditorPart; import org.eclipse.mylyn.tasks.ui.editors.TaskEditor; import org.eclipse.mylyn.tasks.ui.editors.TaskEditorPartDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.RowData; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.editor.IFormPage; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; /** * A bugzilla task editor page that has wiki facilities. * * @author Jingwen Ou */ public class ExtensibleBugzillaTaskEditorPage extends BugzillaTaskEditorPage { private Action toggleFindAction; private static final Color HIGHLIGHTER_YELLOW = new Color(Display.getDefault(), 255, 238, 99); private static final StyleRange HIGHLIGHT_STYLE_RANGE = new StyleRange(0, 0, null, HIGHLIGHTER_YELLOW); public ExtensibleBugzillaTaskEditorPage(TaskEditor editor) { super(editor); } private void addFindAction(IToolBarManager toolBarManager) { if (toggleFindAction != null && toggleFindAction.isChecked()) { ControlContribution findTextboxControl = new ControlContribution("Find") { @Override protected Control createControl(Composite parent) { FormToolkit toolkit = getTaskEditor().getHeaderForm().getToolkit(); Composite findComposite = toolkit.createComposite(parent); findComposite.setLayout(new RowLayout()); findComposite.setBackground(null); final Text findText = toolkit.createText(findComposite, "", SWT.FLAT); findText.setLayoutData(new RowData(100, SWT.DEFAULT)); findText.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER); findText.setFocus(); toolkit.adapt(findText, false, false); findText.addSelectionListener(new SelectionAdapter() { @Override public void widgetDefaultSelected(SelectionEvent event) { try { setReflow(false); findAndHighlight(ExtensibleBugzillaTaskEditorPage.this, findText.getText()); // always toggle attachment part close after every search, since all ExpandableComposites are open AbstractTaskEditorPart attachmentsPart = getPart( AbstractTaskEditorPage.ID_PART_ATTACHMENTS); CommonFormUtil.setExpanded((ExpandableComposite) attachmentsPart.getControl(), false); } finally { setReflow(true); } reflow(); } }); toolkit.paintBordersFor(findComposite); return findComposite; } }; toolBarManager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, findTextboxControl); } if (toggleFindAction == null) { toggleFindAction = new Action("", SWT.TOGGLE) { @Override public void run() { getTaskEditor().updateHeaderToolBar(); } }; toggleFindAction.setImageDescriptor(CommonImages.FIND); toggleFindAction.setToolTipText("Find"); //getManagedForm().getForm().setData(TaskEditorFindHandler.KEY_FIND_ACTION, toggleFindAction); } toolBarManager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, toggleFindAction); } @Override public boolean canPerformAction(String actionId) { if (actionId.equals(ActionFactory.FIND.getId())) { return true; } return super.canPerformAction(actionId); } @Override protected Set<TaskEditorPartDescriptor> createPartDescriptors() { Set<TaskEditorPartDescriptor> descriptors = super.createPartDescriptors(); boolean hasPartNewComment = false; for (TaskEditorPartDescriptor taskEditorPartDescriptor : descriptors) { if (taskEditorPartDescriptor.getId().equals(ID_PART_NEW_COMMENT)) { descriptors.remove(taskEditorPartDescriptor); hasPartNewComment = true; break; } } if (hasPartNewComment) { descriptors.add(new TaskEditorPartDescriptor(ID_PART_NEW_COMMENT) { @Override public AbstractTaskEditorPart createPart() { return new ExtensibleTaskEditorNewCommentPart(); } }.setPath(PATH_COMMENTS)); } return descriptors; } @Override public void doAction(String actionId) { if (actionId.equals(ActionFactory.FIND.getId())) { if (toggleFindAction != null) { toggleFindAction.setChecked(!toggleFindAction.isChecked()); toggleFindAction.run(); } } super.doAction(actionId); } @Override public void fillToolBar(IToolBarManager toolBarManager) { super.fillToolBar(toolBarManager); addFindAction(toolBarManager); } private static void findTextViewerControl(Composite composite, List<TextViewer> found) { if (!composite.isDisposed()) { for (Control child : composite.getChildren()) { TextViewer viewer = CommonTextSupport.getTextViewer(child); if (viewer != null && viewer.getDocument().get().length() > 0) { found.add(viewer); } // have to do this since TaskEditorCommentPart.expendComment(..) will dispose the TextViewer when the ExpandableComposite is close if (child instanceof ExpandableComposite) { CommonFormUtil.setExpanded((ExpandableComposite) child, true); } if (child instanceof Composite) { findTextViewerControl((Composite) child, found); } } } } private static boolean findAndHighlightTextViewer(TextViewer viewer, FindReplaceDocumentAdapter adapter, String findString, int startOffset) throws BadLocationException { IRegion matchRegion = adapter.find(startOffset, findString, true, false, false, false); if (matchRegion != null) { int widgetOffset = matchRegion.getOffset(); int length = matchRegion.getLength(); HIGHLIGHT_STYLE_RANGE.start = widgetOffset; HIGHLIGHT_STYLE_RANGE.length = length; viewer.getTextWidget().setStyleRange(HIGHLIGHT_STYLE_RANGE); findAndHighlightTextViewer(viewer, adapter, findString, widgetOffset + length); return true; } return false; } public static void findAndHighlight(IFormPage page, String findString) { IManagedForm form = page.getManagedForm(); if (form == null) { return; } ScrolledForm scrolledForm = form.getForm(); if (scrolledForm == null) { return; } List<TextViewer> found = new ArrayList<TextViewer>(); findTextViewerControl(scrolledForm.getBody(), found); for (TextViewer viewer : found) { try { // Wiping previous highlighted element viewer.setRedraw(false); viewer.refresh(); viewer.setRedraw(true); FindReplaceDocumentAdapter adapter = new FindReplaceDocumentAdapter(viewer.getDocument()); if (!findAndHighlightTextViewer(viewer, adapter, findString, -1)) { // toggle close if can't match the keyword Composite comp = viewer.getControl().getParent(); while (comp != null) { if (comp instanceof ExpandableComposite) { ExpandableComposite ex = (ExpandableComposite) comp; CommonFormUtil.setExpanded(ex, false); break; } comp = comp.getParent(); } } } catch (BadLocationException e) { //ignore } } } }