| /*=============================================================================# |
| # Copyright (c) 2012, 2019 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.internal.docmlet.tex.ui.editors; |
| |
| import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.action.IContributionItem; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.jface.text.source.SourceViewer; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.MenuItem; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.actions.CompoundContributionItem; |
| import org.eclipse.ui.statushandlers.StatusManager; |
| |
| import org.eclipse.statet.jcommons.lang.NonNull; |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| import org.eclipse.statet.ecommons.text.core.util.TextUtils; |
| import org.eclipse.statet.ecommons.ui.actions.SubMenuContributionItem; |
| import org.eclipse.statet.ecommons.ui.util.UIAccess; |
| |
| import org.eclipse.statet.docmlet.tex.core.TexCore; |
| import org.eclipse.statet.docmlet.tex.core.commands.LtxCommandCategories; |
| import org.eclipse.statet.docmlet.tex.core.commands.LtxCommandCategories.Category; |
| import org.eclipse.statet.docmlet.tex.core.commands.TexCommand; |
| import org.eclipse.statet.docmlet.tex.ui.TexUI; |
| import org.eclipse.statet.docmlet.tex.ui.TexUIResources; |
| import org.eclipse.statet.docmlet.tex.ui.editors.LtxEditor; |
| import org.eclipse.statet.internal.docmlet.tex.ui.editors.LtxCommandCompletionProposal.LtxCommandProposalParameters; |
| import org.eclipse.statet.internal.docmlet.tex.ui.sourceediting.LtxAssistInvocationContext; |
| |
| |
| @NonNullByDefault |
| public class LtxSymbolsMenuContributions extends CompoundContributionItem { |
| |
| |
| private static class CategoryContributions extends SubMenuContributionItem implements SelectionListener { |
| |
| |
| private final Category category; |
| |
| |
| public CategoryContributions(final Category category) { |
| this.category= category; |
| } |
| |
| |
| @Override |
| protected String getLabel() { |
| return this.category.getLabel(); |
| } |
| |
| @Override |
| protected @Nullable Image getImage() { |
| return null; |
| } |
| |
| @Override |
| protected void fillMenu(final Menu menu) { |
| final TexUIResources texResources= TexUIResources.INSTANCE; |
| final List<TexCommand> commands= this.category.getCommands(); |
| for (final TexCommand command : commands) { |
| final MenuItem item= new MenuItem(menu, SWT.PUSH); |
| |
| final Image image= texResources.getCommandImage(command); |
| if (image != null) { |
| item.setImage(image); |
| } |
| item.setText(command.getControlWord()); |
| item.setData(command); |
| |
| item.addSelectionListener(this); |
| } |
| } |
| |
| @Override |
| public void widgetDefaultSelected(final SelectionEvent event) { |
| } |
| |
| @Override |
| public void widgetSelected(final SelectionEvent event) { |
| final TexCommand command= (TexCommand) nonNullAssert(event.widget.getData()); |
| |
| final IEditorPart editor= UIAccess.getActiveWorkbenchPage(true).getActiveEditor(); |
| if (editor instanceof LtxEditor) { |
| final LtxEditor texEditor= (LtxEditor) editor; |
| if (!texEditor.isEditable(true)) { |
| return; |
| } |
| final SourceViewer viewer= ((LtxEditor) editor).getViewer(); |
| Point selection= viewer.getSelectedRange(); |
| if (selection == null || selection.x < 0) { |
| return; |
| } |
| try { |
| final String contentType= TextUtils.getContentType(viewer.getDocument(), |
| texEditor.getDocumentContentInfo(), selection.x, |
| selection.y == 0 ); |
| |
| final LtxAssistInvocationContext context= new LtxAssistInvocationContext(texEditor, |
| selection.x, contentType, |
| true, new NullProgressMonitor() ); |
| final LtxCommandCompletionProposal proposal= new LtxCommandCompletionProposal( |
| new LtxCommandProposalParameters(context, command) ); |
| proposal.apply(viewer, (char) 0, 1, context.getInvocationOffset()); |
| selection= proposal.getSelection(viewer.getDocument()); |
| if (selection != null) { |
| viewer.setSelectedRange(selection.x, selection.y); |
| viewer.revealRange(selection.x, selection.y); |
| } |
| else { |
| viewer.revealRange(context.getInvocationOffset(), 0); |
| } |
| } |
| catch (final Exception e) { |
| StatusManager.getManager().handle(new Status(IStatus.ERROR, TexUI.BUNDLE_ID, |
| "An error occurred when inserting LaTeX symbol.", |
| e )); |
| } |
| } |
| } |
| |
| } |
| |
| |
| private LtxCommandCategories categories; |
| |
| |
| public LtxSymbolsMenuContributions() { |
| } |
| |
| |
| @Override |
| protected IContributionItem[] getContributionItems() { |
| this.categories= new LtxCommandCategories(TexCore.getWorkbenchAccess().getTexCommandSet().getAllLtxCommands()) { |
| @Override |
| protected boolean include(final TexCommand command) { |
| return ((command.getType() & TexCommand.MASK_MAIN) == TexCommand.MATHSYMBOL |
| && (command.getType() & TexCommand.MASK_C3) != TexCommand.C3_MATHSYMBOL_OP_NAMED); |
| } |
| }; |
| final List<Category> categories= this.categories.getCategories(); |
| final List<IContributionItem> items= new ArrayList<>(categories.size()+10); |
| int sep= 0; |
| for (final Category category : categories) { |
| final int current= (category.getCommands().get(0).getType() & TexCommand.MASK_C2); |
| if (sep != current) { |
| sep= current; |
| if (items.size() > 0) { |
| items.add(new Separator()); |
| } |
| } |
| items.add(new CategoryContributions(category)); |
| } |
| return items.toArray(new @NonNull IContributionItem[items.size()]); |
| } |
| |
| } |