blob: e874783ad338f284e62f3e5ed29dd43eed3e04ab [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2013, 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.ltk.ui.sourceediting.actions;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.menus.IWorkbenchContribution;
import org.eclipse.ui.services.IServiceLocator;
import org.eclipse.statet.ecommons.text.core.sections.DocContentSections;
import org.eclipse.statet.ecommons.ui.actions.ListContributionItem;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
/**
* Contribution item for element search (menu) supporting separate implementations for each
* document content section type.
*
* Implement {@link #createItem(String)} for lazy initialization of the contribution items of the
* section types.
*
* @see DocContentSections
*/
public class MultiContentSectionElementSearchContributionItem extends ListContributionItem
implements IWorkbenchContribution, IExecutableExtension {
private static final Object NULL= new Object();
private final DocContentSections sections;
private final Map<String, Object> items= new IdentityHashMap<>(8);
private String commandId;
private IServiceLocator serviceLocator;
public MultiContentSectionElementSearchContributionItem(final DocContentSections sections) {
super();
if (sections == null) {
throw new NullPointerException("sections"); //$NON-NLS-1$
}
this.sections= sections;
}
public MultiContentSectionElementSearchContributionItem(final DocContentSections sections,
final String sectionType1, final ListContributionItem item1) {
this(sections, sectionType1, item1, null, null);
}
public MultiContentSectionElementSearchContributionItem(final DocContentSections sections,
final String sectionType1, final ListContributionItem item1,
final String sectionType2, final ListContributionItem item2) {
this(sections);
if (sectionType1 != null) {
registerItem(sectionType1, item1);
}
if (sectionType2 != null) {
registerItem(sectionType2, item2);
}
}
@Override
public void setInitializationData(final IConfigurationElement config,
final String propertyName, final Object data) throws CoreException {
if (this.commandId != null) {
return;
}
final String s= config.getAttribute("id"); //$NON-NLS-1$
if (s != null) {
this.commandId= s.intern();
}
}
public String getCommandId() {
return this.commandId;
}
@Override
public void initialize(final IServiceLocator serviceLocator) {
this.serviceLocator= serviceLocator;
for (final Object item : this.items.values()) {
if (item != NULL && item instanceof IWorkbenchContribution) {
((IWorkbenchContribution) item).initialize(serviceLocator);
}
}
}
protected final DocContentSections getSections() {
return this.sections;
}
@Override
public void dispose() {
super.dispose();
for (final Object item : this.items.values()) {
if (item != NULL) {
((ListContributionItem) item).dispose();
}
}
this.items.clear();
}
protected void registerItem(final String sectionType, final ListContributionItem item) {
if (sectionType == null) {
throw new NullPointerException("sectionType"); //$NON-NLS-1$
}
this.items.put(sectionType, (item != null) ? item : NULL);
}
protected final ListContributionItem getItem(final String sectionType) {
if (sectionType == DocContentSections.ERROR) {
return null;
}
Object item= this.items.get(sectionType);
if (item == null) {
item= NULL;
try {
final ListContributionItem newItem= createItem(sectionType);
if (newItem != null) {
if (newItem instanceof IWorkbenchContribution) {
((IWorkbenchContribution) newItem).initialize(this.serviceLocator);
}
item= newItem;
}
}
finally {
this.items.put(sectionType, item);
}
}
return (item != NULL) ? (ListContributionItem) item : null;
}
protected ListContributionItem createItem(final String sectionType) {
return null;
}
@Override
public void createContributionItems(final List<IContributionItem> items) {
final IWorkbenchPart part= UIAccess.getActiveWorkbenchPart(true);
if (part instanceof ISourceEditor) {
final ISourceEditor editor= (ISourceEditor) part;
final SourceViewer viewer= editor.getViewer();
final ListContributionItem item= getItem(
this.sections.getType(viewer.getDocument(), viewer.getSelectedRange().x) );
if (item != null) {
createContributionItems(items, item);
}
}
}
}